3.4 KiB
Development and Testing
Source Layout
| Path | Responsibility |
|---|---|
cms/src/NeoCMS/Authentication.php |
Sessions, credentials, roles, capabilities, and CSRF tokens. |
cms/src/NeoCMS/CMSController.php |
API dispatch and all page, draft, revision, schedule, media, menu, and shared-content operations. |
cms/src/NeoCMS/FileStore.php |
Atomic JSON metadata storage and managed directories. |
cms/src/NeoCMS/LoginRateLimiter.php |
Locked, filesystem-backed login throttling. |
cms/src/NeoCMS/Logger.php |
Daily audit logging with field normalisation, size rotation, and retention. |
cms/src/NeoCMS/SecurityHeaders.php |
CSP, anti-framing, cache, transport, and browser-policy headers. |
cms/js/cms.js |
Iframe editing, dialogues, workflow state, and API client. |
cms/index.php |
Authenticated administration shell. |
cms/image_upload.php |
Multipart image upload endpoint. |
cms/publish_scheduled.php |
CLI scheduled-publication worker. |
tests/run.php |
Isolated integration suite. |
TinyMCE 8.6.0 beneath cms/tinymce/ is vendored third-party code and should not be reformatted or documented as first-party
source. Its package metadata, changelog, and licence information remain in that directory.
Documentation Style
Comments use British English and explain intent, constraints, side effects, and security decisions. They should not narrate obvious syntax. A comment saying that a variable is assigned adds little; a comment explaining why a temporary file is renamed atomically earns its tea.
Public and non-obvious private methods use docblocks. Browser workflows use JSDoc-style comments. CSS and HTML comments describe logical regions rather than every individual declaration or tag.
Required Checks
Run the integration suite:
php tests/run.php
Lint all first-party PHP files:
find cms tests -path 'cms/tinymce' -prune -o -name '*.php' -print0 | xargs -0 -n1 php -l
Parse-check the administration client:
node --check cms/js/cms.js
Check patch whitespace before committing:
git diff --check
Adding an API Action
- Add a private method named
<action>Action()toCMSController. - Use
requirePost('<capability>')before every mutation. - Obtain required strings through
requiredPost()orrequiredRequest(). - Constrain paths through the existing URI and page-path helpers.
- Record meaningful mutations with
activity()and create revisions before replacing public content. - Return data through
respond()so headers and JSON encoding remain consistent. - Add an integration assertion to
tests/run.php. - Document user-visible behaviour in
README.mdandcms/welcome.htmlwhen appropriate.
Mutating actions that accept full documents must use requiredContentPost() rather than reading $_POST directly. New
filesystem operations must reuse canonical path helpers, reject symbolic links, and respect the configured count and byte
ceilings. New HTML entry points should use SecurityHeaders before emitting output.
Filesystem Tests
The integration suite creates unique public and metadata directories under the operating system's temporary directory. It
seeds an authenticated administrator session, invokes controller actions directly, and cleans up in a finally block.
Tests must never rely on or modify the repository's public HTML, uploads, logs, or data files.