Commit Graph
3 Commits
Author SHA1 Message Date
thatguygriffandClaude Opus 5 3a954bac57 View a policy version's content, and make policy text readable
CI / Tests (PHP 8.1) (pull_request) Successful in 50s
CI / Tests (PHP 8.2) (pull_request) Successful in 1m12s
CI / No Debug Code (pull_request) Successful in 3s
CI / Coding Standards (pull_request) Successful in 2m50s
CI / PHPStan (pull_request) Successful in 3m4s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m42s
CI / Build Plugin Zip (pull_request) Skipped
The Policies admin page listed versions but never showed what any of them
said, so revising a policy meant retyping it blind into an empty draft box.
Each version row now has a View action that renders that version's text on
the page, editable in place. A draft is saved back to itself; editing a
published or archived version branches a new draft and leaves the original
alone, because acceptances are recorded against policy_version_id and text a
student agreed to must stay exactly as they saw it.

That viewer also exposed why a studio reported the acceptance box as
unreadable — one squashed line, overlapping words, a horizontal scrollbar.
Bodies are typed into a bare textarea, so most carry no markup, and the raw
text was emitted with its blank lines intact but nothing to turn them into
paragraphs. PolicyVersion::bodyHtml() now renders every body the way
WordPress renders post content (kses, then wpautop) and feeds all three
consumers: the booking/enrolment JSON, the signup form, and the new viewer.
Bodies written with markup are unaffected.

The other half was that .us-policy-body had no CSS whatsoever and inherited
whatever the theme did with an unstyled block in a form. It is now a bounded
reading box that scrolls vertically and breaks long tokens, so a pasted URL
cannot force the page sideways and a long policy cannot push the accept
checkbox out of view. RegistrationPage was also never enqueueing the plugin
stylesheet, which is why the signup gate looked worst of all.

Closes #126
Closes #127

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-07-28 17:05:00 -03:00
thatguygriffandClaude Fable 5 1d6ac46ba3 Upgrade PHPStan to 2.x and raise analysis level from 6 to 10
CI / No Debug Code (pull_request) Successful in 3s
CI / Tests (PHP 8.2) (pull_request) Successful in 48s
CI / Tests (PHP 8.3) (pull_request) Successful in 52s
CI / Coding Standards (pull_request) Successful in 57s
CI / Tests (PHP 8.1) (pull_request) Successful in 1m1s
CI / PHPStan (pull_request) Successful in 1m11s
CI / Build Plugin Zip (pull_request) Has been skipped
- Bump phpstan/phpstan ^2.0 and szepeviktor/phpstan-wordpress ^2.0
- Move the analysis level into phpstan.neon (single source) and raise it to 10
- Add Val, a runtime coercion helper that narrows untyped WordPress boundary
  values (wpdb rows, REST params, superglobals, options) with explicit checks
  instead of blind casts, plus unit tests
- Type value-object fromRow() params as stdClass (what wpdb returns) and map
  columns through Val so unexpected shapes degrade safely
- Use %i identifier placeholders for table names in all wpdb::prepare() calls
  so every query string is a literal and identifiers are escaped by WordPress;
  raises the minimum WordPress version to 6.2 where %i was introduced
- Guard wpdb::prepare() null result before wpdb::query() in updateTax()
- Fix nullable get_permalink()/strtotime() handling, list types at REST and
  capability call sites, dead null-coalescing on checked superglobals, and
  narrow get_users() results before mapping
- Register Val method names with the ValidatedSanitizedInput sniff so it
  validates the real sanitizer around each superglobal read
- Update repository unit tests for the %i placeholder arguments

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-12 13:42:50 -03:00
thatguygriffandClaude Opus 4.8 6225e772f8 Add Policies domain (drafting, versioning, tracked acceptance)
CI / Coding Standards (pull_request) Successful in 1m0s
CI / PHPStan (pull_request) Successful in 1m4s
CI / Tests (PHP 8.1) (pull_request) Successful in 59s
CI / Tests (PHP 8.2) (pull_request) Successful in 56s
CI / Tests (PHP 8.3) (pull_request) Successful in 57s
CI / No Debug Code (pull_request) Successful in 3s
CI / Build Plugin Zip (pull_request) Has been skipped
Implements #6: studio admins draft, version, and publish policies; the
public registration gate reads the current published version of each, and
acceptance is recorded against the exact version so a new version must be
re-accepted at the next booking.

- src/Policy/: Policy, PolicyVersion, PolicyAcceptance value objects;
  PolicyRepository, PolicyVersionRepository, AcceptanceRepository;
  PolicyService (orchestrates create/add-draft/publish across the policies
  and versions tables); PolicyEndpoint (REST); PolicyController +
  templates/admin/policies.php (Policies admin menu, manage_policies)
- us_policies, us_policy_versions, us_policy_acceptances tables in Schema
- REST: public GET /policies (current published versions); manage_policies
  for create, add version, edit draft, and publish
- Wiring in Plugin, RestRegistrar, AdminMenu

AcceptanceRepository is built now and consumed by the booking/enrolment
gate in #3/#4.

Also bump PHPStan to --memory-limit=1G in the composer lint script; the
default 128M now crashes the analysis as the codebase has grown.

Tests: tests/Unit/Policy/ (value objects, repositories, service).
composer test (90 total), cs, and PHPStan level 6 all pass.

Refs #6

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-05 15:00:54 -03:00