Sun Jan 7 23:26:58 UTC 2024
Installation of components (on openbsd)
$ pkg_add vim php mariadb-server php-mysqli php-zip
$ cd /etc
$ cp examples/httpd.conf ./
$ vim httpd.conf
$ vim php-fpm.conf
$ rcctl enable php-fpm
$ rcctl ls all | grep php
$ rcctl enable php82_fpm
$ rcctl start php82_fpm
$ rcctl enable httpd
$ rcctl start httpd
$ cd /var/www/htdocs/
$ vim index.php
$ mysql_install_db
$ rcctl enable mysqld
$ rcctl start mysqld
$ mysql_secure_installation
$ install -d -m -o _mysql -g _mysql /var/www/var/run/mysql
$ vim /etc/my.cnf
$ rcctl restart mysqld
/etc/httpd.conf (no ssl yet):
# $OpenBSD: httpd.conf,v 1.22 2020/11/04 10:34:18 denis Exp $
server "default" {
listen on * port 80
directory index index.php
location "*.php" {
fastcgi socket "/run/php-fpm.sock"
}
}
The import line in /etc/my.conf
:
[client-server]
#socket=/var/run/mysql/mysql.sock
socket = /var/www/var/run/mysql/mysql.sock
The important line in /etc/php-fpm.conf
(this was the default at the time of installation (OpenBSD 7.3));
listen = /var/www/run/php-fpm.sock
Enable mysqli and zip in /etc/php-8.2.ini
:
extension=mysqli
extension=zip
loading/unloading the database
importing:
$ mysql -u root < dbinit.sql
exporting:
$ mysqldump -u root -p www > dbdump.sql
nuke:
$ echo "drop database www" | myqsl
project organization
everything is thrown into/lib
and /assets
. Eventually I will sort /lib
into /bin
(for the do\ script) and into /includes
for the templating components.
page template engine
header file with 3 functions,htmlheader($title)
, htmlbody($content)
, htmlfooter($js)
. The assembly of a document is as simple as building the title, content, and adding whatever js the page requires then executing these scripts in order.
Currently, the login page does not support the htmlbody()
function and instead outputs directly to the page. the doregister.php
file cannot use the htmlbody()
function because I want the script to stop execution as soon as possible in the event of an error.
session configuration
values that need to be checked and set in/etc/php82.ini
:
[Session]
session.save_handler = files
session.use_strict_mode = 1
session.use_cookies = 1
; breaks everything without ssl
;session.cookie_secure = on
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 1
; 0 destorys the on browser exit, 86400 expires the session after a day
session.cookie_lifetime = 86400
session.cookie_path = /
session.cookie_domain = localhost
session.cookie_httponly = true
session.cookie_samesite = "Strict"
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.referer_check =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.sid_length = 26
session.trans_sid_tags = "a=href,area=href,frame=src,form="
session.sid_bits_per_character = 5
Mon Jan 8 16:59:21 UTC 2024
Session debugging.
php locks the session file whensessionstart()
is called. This file will not unlock until sessionwriteclose()
is called. No multithreading. Additionally, the value of $SERVER['SERVERNAME']
must match the name of the vhost in your httpd configuration file. Additionally, the session.cookiedomain
variable in the php.ini
must match the name. On the test server it is wise to set these all to the same ip address, in production all of these should be set to a FQDN.
mysql debugging
- it's probably a syntax error
- it might be a database error
- it was a syntax error
Tue Jan 9 20:41:00 UTC 2024
SQL joins
- inner join: returns records that have matching values in both tables
- left outer join: returns all records from the left table and the matched records from the right table
- right outer join: returns all records from the right table and the matched records from the left table
- full outer join: returns all records when thereis a match in either left or right table
SQL unions
- no
markdown
Does not support:
- nested lists
- tabs in pre blocks (it assumes you want to start another pre)
- syntax highlighting
- nested block quotes
Thu Jan 11 15:51:09 UTC 2024
ROBOT9000
- sha256 hashes of every post are saved into a table
- when creating a new post or editing an existing post, the shasum is checked to assure every post is original
- same system is appplied to comments but it uses a different hash
Voting system
- users can submit a grade from 0 to 100 once
- average is taken from all votes and a grade letter is assigned
Fri Jan 12 22:01:25 UTC 2024
parametrizing everything
Every sql query that that does not take user input has been left as an unprepared query (for marginal performance gains). Every sql query that takes user input as an argument (even from the database itself) has been parameterized.In other words
query with no arguments -> query();query with an argument from the user or database -> prepare(); bindparam(); execute();
fix css
on user creation, default css colors are added to the database
fix page layout
moved half the nav to the bottom page so it won't overflow on mobile
securing the server
move database.sql file and server configuration outside of the document root.
$ mv lib/serverconf.php ../../
$ mv dbinit.sql ../../
Sat Jan 13 23:04:25 UTC 2024
Bug fixes
Browsers do not cache the content of html forms so there was an issue with inserting content. If the post/comment did not satisfy the constraints it would be lost to time. Possible ways around this was JS or AJAX (JS) but I do not like this solution. Instead, my solution is to display a form with the user's input on the submission page if there is some error with the content.
Mon Jan 15 21:04:47 UTC 2024
exporting data
I added two ways to export data: as a .csv and as a .zip. I also added the ability to delete posts
RSS the planet
Added per user rss feeds and sitewide rss feed.
Fri Jan 26 01:41:25 UTC 2024
Licensing system
I added a license chooser. In yourmypage.php
you can choose a default license that will automatically be applied to your pots. Absence of a license is also supported (although copyright is implicit). Currently, creative commons, public domain, copyleft, and copyright are supported.
account deletion
Account deletion involves some amount of spaghetti code but it mostly works (I think?).The process is somewhat complicated because I am an SQLlet
- get all posts for the user
- get all comments for these posts
- delete comment hashes for the comments of the posts
- delete comments for the post
- delete post hashes for posts
- delete ratings for posts
- delete the post
- delete the user
there is probably an easier way but prepared statements work.