748478f2f1c630532c2b58086040851f062c7777
8
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
434fe801ba
|
Ask some registration questions of students only
CI / Tests (PHP 8.2) (pull_request) Successful in 58s
CI / Tests (PHP 8.1) (pull_request) Successful in 58s
CI / No Debug Code (pull_request) Successful in 3s
CI / Coding Standards (pull_request) Successful in 2m53s
CI / PHPStan (pull_request) Successful in 3m0s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m42s
CI / Build Plugin Zip (pull_request) Skipped
Every account-signup question was asked of everybody who registered, on the same terms: "school and grade" had to be put to an adult signing themselves up, and a question a studio needed answered for each student could only be made required by demanding it of everyone. A question now carries an audience — everyone, or only the students someone registers on behalf of — and its own required flag for each side, so optional for you and required for every student you enrol is expressible. Both settings are account-scope only: an offering asks its questions once, about the student being booked, so there is no second audience to differ from, and an offering question mirrors its single "required" into both columns. Every caller reads askedOfSelf()/isRequiredForSelf()/isRequiredForChild() rather than the raw flags, so a students-only question can neither block the account holder nor have an answer filed against them by a crafted post. The family screen, which only ever adds a student, is held to the students' rule. is_required_child arrives from dbDelta defaulting to 0, which would quietly stop every existing required question being required of the students a guardian registers — the case it most likely existed for. A one-time backfill copies is_required across, guarded by its own option so a question later made optional for students stays that way. Closes #163 Co-Authored-By: Claude Opus 5 <[email protected]> |
||
|
|
721c4be1d6
|
Fix field-length saves, student wp-admin access, and empty instructor picker
CI / Tests (PHP 8.1) (pull_request) Successful in 49s
CI / Tests (PHP 8.2) (pull_request) Successful in 49s
CI / No Debug Code (pull_request) Successful in 2s
CI / Coding Standards (pull_request) Successful in 2m47s
CI / PHPStan (pull_request) Successful in 3m16s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m41s
CI / Build Plugin Zip (pull_request) Skipped
Three bug fixes for the 1.2.1 section: - Fixed-size fields (question labels, offering titles/notes/e-transfer email, policy titles/slugs) no longer silently fail to save when the value exceeds its column length. The REST endpoints reject over-long values with a 400, the admin controllers refuse to insert them, and the form inputs carry a maxlength so the browser blocks over-long entry. Limits are MAX_* constants on the value objects, kept in lockstep with the schema columns. - Students are kept out of wp-admin entirely. New StudentAdminGuard redirects front-end-only users (no back-office capability) away from the dashboard and hides the admin bar for them, while administrators, studio admins, and instructors keep full access. - The Add/Edit Offering instructor picker now includes WordPress administrators when they act as instructors (the default single-account setup), so a solo studio owner is selectable instead of the dropdown being empty. composer test (618), composer lint, composer cs all pass. Co-Authored-By: Claude Opus 4.8 <[email protected]> |
||
|
|
242150569b
|
Fix invite sign-in persistence, add invite-only text option, repair account questions
CI / Tests (PHP 8.1) (pull_request) Successful in 47s
CI / Tests (PHP 8.2) (pull_request) Successful in 46s
CI / No Debug Code (pull_request) Successful in 3s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m37s
CI / PHPStan (pull_request) Successful in 2m52s
CI / Coding Standards (pull_request) Successful in 3m6s
CI / Build Plugin Zip (pull_request) Skipped
Three registration fixes reported from live use:
- Accepting an invite now keeps the student signed in. The form was
processed inside render() during the_content, so wp_set_auth_cookie()
ran after headers were sent and the cookie never persisted — the new
student was bounced back to the logged-out registration page. The
submission is now handled on template_redirect (before output) with a
post/redirect/get, so the cookie sticks and the student lands logged in.
- The "registration is by invitation only" message is now customisable via
a new block attribute (inviteOnlyMessage / shortcode invite_only_message),
falling back to the default wording when blank.
- Account-registration questions save again. dbDelta does not reliably
relax a column from NOT NULL to NULL, so sites created before account-
scope questions kept us_questions.offering_id NOT NULL and rejected
account inserts ("Column 'offering_id' cannot be null"). A one-time,
self-healing migration (guarded by its own option, not the version gate)
re-applies the nullable definition on next load.
composer test, composer lint, composer cs all pass.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
|
||
|
|
49c59a950c
|
Add studio-defined account-registration questions
CI / Tests (PHP 8.2) (pull_request) Successful in 44s
CI / Tests (PHP 8.1) (pull_request) Successful in 45s
CI / No Debug Code (pull_request) Successful in 2s
CI / Coding Standards (pull_request) Successful in 2m46s
CI / PHPStan (pull_request) Successful in 2m58s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m41s
CI / Build Plugin Zip (pull_request) Skipped
Studio admins can now define registration questions that every new student answers as a required second step during signup, with each student's answers shown under a "Registration Information" section in the admin. Extends the existing Registration domain: us_questions gains a scope column (offering | account) and a nullable offering_id, and account answers reuse us_question_answers with registration_type = 'account'. Authoring reuses the Offerings -> Questions page via an "Account signup" scope (studio-admin only). The registration form becomes two steps (progressive enhancement via assets/js/register.js; works without JS); required answers are validated before the account is created and apply to all signup paths (invite, group link, self-approval). StudentHistory::registrationInfo() powers the admin section. Bumps the plugin version to 1.1.0 so dbDelta runs the schema migration. Closes #90 Co-Authored-By: Claude Opus 4.8 <[email protected]> |
||
|
|
c49171695a
|
Add policy, intake, and payment history to the admin student detail view
CI / Coding Standards (pull_request) Successful in 2m47s
CI / PHPStan (pull_request) Successful in 2m56s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m39s
CI / Build Plugin Zip (pull_request) Skipped
CI / Tests (PHP 8.2) (pull_request) Successful in 43s
CI / Tests (PHP 8.1) (pull_request) Successful in 44s
CI / No Debug Code (pull_request) Successful in 2s
The student-administration spec deferred three detail-view sections until Payments landed. Adds them now: policy-acceptance history (title, version, context, date), intake answers (label, answer, context), and — gated on manage_billing — payment history with HST breakdown and receipt numbers. New Auth\StudentHistory builds the display rows from per-student queries added to AcceptanceRepository, AnswerRepository, and PaymentRepository; the Payment model now carries created_at so unpaid rows still have a date. Closes #69 Co-Authored-By: Claude Fable 5 <[email protected]> |
||
|
|
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]> |
||
|
|
6d163e5d0e
|
Add lesson booking registration flow (offering, questions, policies)
CI / Coding Standards (pull_request) Successful in 1m51s
CI / PHPStan (pull_request) Successful in 2m17s
CI / Tests (PHP 8.1) (pull_request) Successful in 2m24s
CI / No Debug Code (pull_request) Successful in 2s
CI / Tests (PHP 8.2) (pull_request) Successful in 42s
CI / Tests (PHP 8.3) (pull_request) Successful in 47s
CI / Build Plugin Zip (pull_request) Has been skipped
Implements #3: students register for a private lesson by picking a slot, answering the offering's intake questions, and accepting booking-scoped policies. Payment is a clean seam for #7 (lessons land pending; payment_id null; instructor confirms via PATCH /bookings/{id}/status). - Schema: us_lessons += offering_id, recurrence, series_id, payment_id. - Lesson: new fields + recurrence constants. - BookingRepository::insertSeries() builds a weekly series sharing a series_id; AvailabilityRepository::findUnbookedInGroup() reserves a group. - RegistrationGate (src/Registration/): validate + record intake answers and booking-scoped policy acceptances. Reused by group enrolment (#4). - BookingEndpoint::book(): offering_id, recurrence, answers, accepted_policy_version_ids; single or weekly; records answers/acceptances (type lesson). - GET /policies?scope=booking filter. - Front-end booking.js: slot -> questions + policies -> submit. - Wiring: RegistrationGate built in Plugin, passed via RestRegistrar. - Test-only WP_Error stub in tests/bootstrap.php for gate testing. Refs #3 Co-Authored-By: Claude Opus 4.8 <[email protected]> |
||
|
|
e61d99daed
|
Add Registration Questions domain (per-offering intake forms)
CI / Coding Standards (pull_request) Successful in 51s
CI / PHPStan (pull_request) Successful in 1m0s
CI / Tests (PHP 8.1) (pull_request) Successful in 46s
CI / Tests (PHP 8.2) (pull_request) Successful in 48s
CI / Tests (PHP 8.3) (pull_request) Successful in 47s
CI / No Debug Code (pull_request) Successful in 3s
Implements #5: studio admin / instructors author intake questions scoped per offering; answers are stored against a lesson or group enrolment via a polymorphic registration reference. - src/Registration/: Question + Answer value objects, QuestionRepository and AnswerRepository, QuestionEndpoint (REST), QuestionController + templates/admin/questions.php (Offerings -> Questions submenu) - us_questions and us_question_answers tables in Schema.php - REST: public GET /offerings/{id}/questions; POST/PATCH/DELETE /questions gated by manage_questions + offering ownership (owner or studio admin) - Field types text/textarea/select/checkbox; select options stored as JSON - Wiring in Plugin, RestRegistrar, AdminMenu AnswerRepository is built now and consumed by the booking/enrolment flow in #3/#4. Tests: tests/Unit/Registration/ (19 tests). composer test (63 total), cs, and PHPStan level 6 all pass. Refs #5 Co-Authored-By: Claude Opus 4.8 <[email protected]> |