A Content Management System for x.x.x, a collection of 100-word stories. https://xxx.org.za/
  • PHP 92%
  • JavaScript 6.1%
  • CSS 1.9%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-11-02 16:13:26 +02:00
fonts Ensure scripts work without PHP short tags. 2018-11-14 00:20:05 +02:00
graphics Serve stored images safely and drop committed uploads. 2026-09-25 21:48:17 +02:00
lib Replace TinyMCE 4.2.8 with a small local editor. 2026-09-25 22:58:05 +02:00
publish Fix favicon links 2026-09-26 15:27:51 +02:00
tests Add DB_SOCKET for the MySQL socket path. 2026-11-02 16:13:26 +02:00
.env.example Add DB_SOCKET for the MySQL socket path. 2026-11-02 16:13:26 +02:00
.gitignore Add PHP unit tests and page tests. 2026-09-26 03:48:09 +02:00
.htaccess Add a README for the tests, and block the development files. 2026-09-26 15:27:51 +02:00
about.php Fix favicon links 2026-09-26 15:27:51 +02:00
article.php Fix favicon links 2026-09-26 15:27:51 +02:00
bottombar.inc.php Remove Google Analytics. 2026-09-26 15:27:51 +02:00
captcha.lib.php Use the reCAPTCHA Enterprise API. 2026-09-26 15:27:51 +02:00
composer.json Add PHP unit tests and page tests. 2026-09-26 03:48:09 +02:00
composer.lock Add PHP unit tests and page tests. 2026-09-26 03:48:09 +02:00
config.lib.php Take the site address from SITE_URL. 2026-09-26 15:27:51 +02:00
display.php Refuse session ids that PHP did not make. 2026-09-26 15:27:51 +02:00
favicon.ico Initial commit. 2013-05-17 23:38:44 +02:00
favicon.png Initial commit. 2013-05-17 23:38:44 +02:00
feed.php Give the feed of an empty site the current date. 2026-09-26 15:27:51 +02:00
get_data.lib.php Show no date for a story without one. 2026-09-26 15:27:51 +02:00
html.lib.php Take the site address from SITE_URL. 2026-09-26 15:27:51 +02:00
index.html-maintenance Initial commit. 2013-05-17 23:38:44 +02:00
index.php Fix favicon links 2026-09-26 15:27:51 +02:00
navigation.lib.php Write the pager page size in words without PEAR. 2026-09-25 22:32:11 +02:00
open_db.lib.php Add DB_SOCKET for the MySQL socket path. 2026-11-02 16:13:26 +02:00
package-lock.json Add JavaScript tests. 2026-09-26 03:48:09 +02:00
package.json Add JavaScript tests. 2026-09-26 03:48:09 +02:00
phpunit.xml.dist Add PHP unit tests and page tests. 2026-09-26 03:48:09 +02:00
README.md Use the reCAPTCHA Enterprise API. 2026-09-26 15:27:51 +02:00
robots.txt Initial commit. 2013-05-17 23:38:44 +02:00
session.lib.php Hash the password for an unknown username at login. 2026-09-26 15:27:51 +02:00
sidebar.inc.php Log out with a POST form. 2026-09-26 15:27:51 +02:00
style.css Log out with a POST form. 2026-09-26 15:27:51 +02:00
utilities.js Rework the layout for small screens. 2026-09-25 23:32:08 +02:00

xxx.org.za

A Content Management System for x.x.x, a collection of 100-word stories.

This code was mostly written between 2004 and 2008, although the git history doesn't stretch that far. If you're wondering why some core ports don't use fancy new PHP features... that's probably why.

The site reads its configuration from .env. Copy .env.example to .env, and set the values in it.

reCAPTCHA

To enable reCAPTCHA, set up the Google Cloud credentials:

  1. Enable the reCAPTCHA Enterprise API in the project that owns your checkbox key.
  2. Set RECAPTCHA_SITE_KEY to that checkbox key in .env.
  3. Set RECAPTCHA_PROJECT_ID to the Google Cloud project ID.
  4. Create a Google Cloud API key for server requests.
  5. Restrict the API key to the reCAPTCHA Enterprise API.
  6. If the server has a fixed outbound IP address, restrict the API key to that address too.
  7. Set RECAPTCHA_API_KEY to the API key in .env.
  8. Set SITE_URL to the site's HTTPS address.

Tests

The repository has three sets of tests:

  • The PHP unit tests (tests/php/Unit) run the functions of the site against a fake database. They do not need MySQL or the network.
  • The PHP page tests (tests/php/Pages) run the pages on the PHP built-in web server, and send HTTP requests to them.
  • The JavaScript tests (tests/js) run the story editor and the other scripts in jsdom, a browser document for Node.js.

No test uses the real database, the real .env file, Google, or a mail server. The tests use tests/php/fixtures/test.env for the configuration, and they write only to the system temporary directory.

Requirements

  • PHP 8.4.1 or later on the command line, with the dom, filter, json, libxml, mbstring, simplexml and xmlwriter extensions. The mysqli extension is not necessary.
  • Composer.
  • Node.js 20.19, 22.13, or 24 or later, with npm.

Run the PHP tests

Install PHPUnit and the other development packages into vendor/:

composer install

Run all the PHP tests:

composer test

Run the JavaScript tests

Install jsdom into node_modules/, then run the tests:

npm install
npm test

To run one file:

node --test tests/js/editor.test.js

Development files on the live site

Do not install the development packages on the live server. The site itself does not use them.

If the tests or the packages are on the server, .htaccess stops Apache from serving tests/, vendor/, node_modules/ and the Composer, npm and PHPUnit files. This needs AllowOverride AuthConfig, as the other rules in .htaccess do.