Adds multi-select removal of availability slots to the My Availability list view:
Checkbox per slot row — rendered only for unbooked slots (booked slots remain undeletable)
Select-all checkbox in the table header (handled by WP core's admin JS)
Delete selected button with a confirmation prompt, submitting a new bulk_delete form action behind the existing usc_availability_action nonce
How
AvailabilityController: new bulk_delete branch; single and bulk delete now share a deleteOwnSlot() helper that ownership-checks each id. AvailabilityRepository::delete()'s existing is_booked = 0 guard refuses booked slots as a second layer even for forged ids.
templates/admin/availability.php: the row checkboxes attach to a separate bulk form via the HTML form attribute, since the table already contains the per-row delete forms and forms cannot nest.
New tests/Unit/Availability/AvailabilityControllerTest.php: bulk delete removes only owned existing slots (skips other instructors' slots, junk ids, missing ids), non-array slot_ids is ignored, single delete still enforces ownership, checkboxes render only for unbooked slots.
Feature doc updated.
Testing
composer test (290 tests), composer lint (PHPStan level 10), and composer cs all pass.
Closes #57
## What
Adds multi-select removal of availability slots to the **My Availability** list view:
- Checkbox per slot row — rendered only for unbooked slots (booked slots remain undeletable)
- Select-all checkbox in the table header (handled by WP core's admin JS)
- **Delete selected** button with a confirmation prompt, submitting a new `bulk_delete` form action behind the existing `usc_availability_action` nonce
## How
- `AvailabilityController`: new `bulk_delete` branch; single and bulk delete now share a `deleteOwnSlot()` helper that ownership-checks each id. `AvailabilityRepository::delete()`'s existing `is_booked = 0` guard refuses booked slots as a second layer even for forged ids.
- `templates/admin/availability.php`: the row checkboxes attach to a separate bulk form via the HTML `form` attribute, since the table already contains the per-row delete forms and forms cannot nest.
- New `tests/Unit/Availability/AvailabilityControllerTest.php`: bulk delete removes only owned existing slots (skips other instructors' slots, junk ids, missing ids), non-array `slot_ids` is ignored, single delete still enforces ownership, checkboxes render only for unbooked slots.
- Feature doc updated.
## Testing
`composer test` (290 tests), `composer lint` (PHPStan level 10), and `composer cs` all pass.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The list view of Current Slots gets a checkbox per unbooked slot, a
select-all header checkbox, and a Delete selected button submitting a
new bulk_delete form action. Each id is ownership-checked through the
same path as single delete; the repository's is_booked guard refuses
booked slots as a second layer. Row checkboxes attach to the bulk form
via the HTML form attribute because the table already contains the
per-row delete forms and forms cannot nest.
Closes#57
Co-Authored-By: Claude Fable 5 <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #57
What
Adds multi-select removal of availability slots to the My Availability list view:
bulk_deleteform action behind the existingusc_availability_actionnonceHow
AvailabilityController: newbulk_deletebranch; single and bulk delete now share adeleteOwnSlot()helper that ownership-checks each id.AvailabilityRepository::delete()'s existingis_booked = 0guard refuses booked slots as a second layer even for forged ids.templates/admin/availability.php: the row checkboxes attach to a separate bulk form via the HTMLformattribute, since the table already contains the per-row delete forms and forms cannot nest.tests/Unit/Availability/AvailabilityControllerTest.php: bulk delete removes only owned existing slots (skips other instructors' slots, junk ids, missing ids), non-arrayslot_idsis ignored, single delete still enforces ownership, checkboxes render only for unbooked slots.Testing
composer test(290 tests),composer lint(PHPStan level 10), andcomposer csall pass.🤖 Generated with Claude Code