Never drop an enrolled class from upcoming lessons; delete a guardian's children with them; pin the panel's line spacing
CI / Tests (PHP 8.2) (pull_request) Successful in 58s
CI / PHPStan (pull_request) Successful in 2m53s
CI / Coding Standards (pull_request) Successful in 2m58s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m47s
CI / Build Plugin Zip (pull_request) Skipped
CI / Tests (PHP 8.1) (pull_request) Successful in 1m1s
CI / No Debug Code (pull_request) Successful in 3s

Three fixes from testing the branch.

A group class was only listed when its schedule resolved to exact
datetimes, which needs a class time *and* a duration — both optional on
the offering form, and the schedule note exists precisely so a studio can
write "Tuesdays 4:00pm" instead. A class configured that way vanished
from the list, which is the one thing this feature must never do. So
Offering::sessionStarts() splits "when does it meet" from "how long does
it run" (sessionWindows() is that plus the duration, unchanged), and
SessionSchedule degrades instead of disappearing: dated rows with an open
end when there is no duration, and a single row carrying
Offering::scheduleLabel() when there is no time to derive dates from.
Only a class whose last day has passed drops out.

Deleting a guardian now deletes the children linked to them, releasing
each one's lessons and enrolments first. A child account is login-less
and exists only so the guardian has somebody to book for; without the
guardian nobody can reach it, book for it, or be billed for it, so it was
left stranded on the roster still holding slots. A `handled` set makes
the re-entrant delete_user each child deletion fires a no-op, and stops a
circular link recursing.

The upcoming panel never stated its own line-height, so a theme setting
line-height: 0 above it — the usual icon-font reset — was inherited
straight through. Below 1 that produces both reported symptoms at once:
stacked lines overlap, and the status pill's background is shorter than
the text in it. Pinned at the same id-level specificity as the rest.

Tests: composer test (863), composer lint, composer cs all pass.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-07-30 12:10:43 -03:00
co-authored by Claude Opus 5
parent cb347ffca0
commit c9a1205fc0
14 changed files with 663 additions and 89 deletions
+4 -1
View File
@@ -14,11 +14,14 @@ each change under the current top section as you work.
## [1.4.1]
### Added
- **Group classes now appear in "Your upcoming lessons".** A class is stored as a term rather than as bookable slots, so nothing that listed lessons could ever show one — a student whose whole term was a group class saw an empty schedule, and an instructor teaching one saw nothing on their My Lessons page. Each remaining session of a class you are enrolled in now sorts in among your lessons by date, labelled **group class**; instructors see every session of the classes they teach, one row per session however many students are in it. A session has no Cancel button, because there is no such thing as cancelling one date of a term — withdrawing from the class is still done from the class page. A class whose date, time or length has not been filled in yields no sessions and is left out rather than shown at a time nobody chose.
- **Group classes now appear in "Your upcoming lessons".** A class is stored as a term rather than as bookable slots, so nothing that listed lessons could ever show one — a student whose whole term was a group class saw an empty schedule, and an instructor teaching one saw nothing on their My Lessons page. Each remaining session of a class you are enrolled in now sorts in among your lessons by date, labelled **group class**; instructors see every session of the classes they teach, one row per session however many students are in it. A session has no Cancel button, because there is no such thing as cancelling one date of a term — withdrawing from the class is still done from the class page.
- A class you are enrolled in shows up **whether or not its schedule is pinned to a clock**. Class time and duration are both optional on the offering form, and the schedule note is there so a studio can simply write "Tuesdays 4:00pm" — so a class with a time but no duration lists its dates and says when each session starts rather than guessing when it ends, and a class with no time at all gets a single row carrying its schedule note (or its term dates) where the time would go. Only a class whose last day has passed drops off the list.
- The same group-class sessions now appear in **Upcoming lessons** on a student's admin detail page, so one table answers "what are they booked into next week?". Only upcoming ones — the **Group-class enrolments** table below already holds the history.
- **A policy can be renamed.** The title was fixed at creation, so a typo or a change of wording meant creating a second policy and re-collecting everyone's acceptance. Renaming changes only what students read above the policy text: the slug stays put, so every version already accepted stays attached.
### Fixed
- **Deleting a parent now removes the students they booked for.** A managed student account has no login of its own and exists only so its parent has somebody to book for — with the parent gone nobody can reach it, book for it, or be billed for it, so it was left stranded on the roster still holding lesson times. Deleting a parent now releases each of their students' upcoming lessons and enrolments on the same terms as their own, and deletes the accounts. Removing a student from the family screen is unchanged and still refuses one with lessons on record.
- **The upcoming-lessons panel no longer collapses onto itself in some themes.** Rows could render on top of one another and the status badge's colour could stop short of the text inside it. Both came from the same thing: the panel never stated its own line spacing, so a theme setting a line height of zero anywhere above it — a common icon-font reset — was inherited straight through, leaving each line of text taller than the space allotted to it. The panel now sets its own.
- **Deleting a student now gives back what they had booked.** WordPress deletes a user without knowing anything about lessons, so their bookings were left behind: the times stayed marked as booked and nobody else could take them, the lessons stayed on the instructor's schedule under a name that no longer resolved, and a group class kept a seat filled by nobody. Deleting an account now cancels each of its upcoming lessons, frees the time for rebooking, cancels its active class enrolments, and voids any payment still pending on them. Past lessons are left exactly as they are — they happened, and the payment report has to keep adding up. A paid lesson is not credited back: a credit could only be spent on the account being deleted, so a refund owed to someone who has left stays the studio's decision to make.
- **A weak password is now caught before the form is submitted, not after.** The strength meter scores the password as you type, but zxcvbn's dictionary arrives a moment after the page loads — so a password typed straight away was never scored at all, and the first you heard of it was the server rejecting the whole form. The password is now re-scored on submit, so the verdict is always the one your password actually earns.