A WordPress administrator previously inherited the studio-admin capabilities but not `manage_availability`, so the studio owner running as an admin had no way to reach "My Availability" or act as the instructor — breaking single-instructor businesses. Grant the instructor capabilities to administrators as well (via the existing `user_has_cap` filter), and make both grants — studio-admin and instructor — independently toggleable from a new Access admin page. - RoleManager: extract `INSTRUCTOR_CAPS`; apply studio and instructor cap sets to administrators, each gated on a stored toggle (default on). - AccessSettings + templates/admin/access.php: two options (`us_admin_grant_studio` / `us_admin_grant_instructor`), gated on the core `manage_options` capability so disabling a grant can never lock an administrator out of re-enabling it. - AdminMenu: register the Access page after Studio Settings; keep the studio sidebar separator visible for any administrator. - Tests for the toggles and the new settings reader; docs updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
5.0 KiB
Feature: User Roles
Overview
Three custom WordPress user roles control access to all scheduling features: a studio admin who runs the business, instructors who teach, and students who book.
Roles
Studio Admin (us_studio_admin)
Runs the studio. Logs in via standard wp-admin. Can:
- Create instructor accounts and set/revoke each instructor's capabilities
- Manage offerings, intake questions, and policies
- Configure Stripe credentials and per-student billing overrides (card / e-transfer / comp)
- View the studio-wide scheduler (all upcoming lessons across instructors)
- View the all-instructor payments report and export it
Capabilities: read, manage_instructors, manage_offerings, manage_questions, manage_policies, manage_billing, view_all_lessons, view_all_payments, export_payments
Any WordPress administrator (
manage_options) implicitly holds every studio-admin capability above and the instructor capabilities (notablymanage_availability), so a single-instructor studio owner can run the business and teach — managing their own availability and lessons — from one account, without being assigned theus_studio_adminorus_instructorrole. This is applied dynamically via theuser_has_capfilter (RoleManager::grantStudioCapsToAdministrators()) — it persists nothing and is removed when the plugin is deactivated. Theus_studio_adminrole exists for non-administrator staff who manage the studio.Both grants can be turned off independently on the Access admin page (
AccessSettings, optionsus_admin_grant_studio/us_admin_grant_instructor, both default on) — for example, when dedicatedus_studio_adminorus_instructoraccounts run the studio and administrators should not appear as studio staff. That page is gated on the coremanage_optionscapability (which the plugin never grants or revokes), so an administrator can always reach it to re-enable a grant; disabling one can never lock them out.
Instructor (us_instructor)
Created by the studio admin. Logs in via standard wp-admin. Can:
- Manage their own availability slots (add/delete), including weekly-recurring windows
- Manage their own offerings and intake questions
- View their upcoming confirmed/pending lessons and group enrolments
- View and export their own payments
Capabilities: read, manage_availability, manage_offerings, manage_questions, view_own_lessons, view_own_payments, export_payments
Student (us_student)
Logs in via the front-end [us_student_login] shortcode. Can:
- Browse available lesson slots and offerings from all instructors
- Book a private lesson (single or weekly) and enrol in group classes
Capabilities: read, book_lesson, view_own_lessons
Capability Matrix
| Capability | Studio Admin | Instructor | Student | Used by |
|---|---|---|---|---|
manage_instructors |
✓ | Instructor management | ||
manage_availability |
✓ | Availability | ||
manage_offerings |
✓ | ✓ (own) | Offerings | |
manage_questions |
✓ | ✓ (own) | Registration questions | |
manage_policies |
✓ | Policies | ||
manage_billing |
✓ | Payments (Stripe + overrides) | ||
book_lesson |
✓ | Lesson booking / enrolment | ||
view_all_lessons |
✓ | Scheduler dashboard | ||
view_own_lessons |
✓ | ✓ | Lesson + group views | |
view_own_payments |
✓ | Payment reporting | ||
view_all_payments |
✓ | Payment reporting | ||
export_payments |
✓ | ✓ (own) | Payment reporting export |
Instructor Management
The studio admin gets an Instructors admin page (gated by manage_instructors)
to add an instructor — creating the WP user with the us_instructor role — and to
toggle that instructor's per-capability access (e.g. whether they may manage their
own offerings/questions or export payments). The studio admin cannot grant a
capability it does not itself hold.
Implementation
- Class:
Unsupervised\Schedular\Auth\RoleManager - Instructor management controller:
Unsupervised\Schedular\Auth\InstructorController - Roles are created on
plugins_loaded → initand on plugin activation viaInstaller. - Permissions are checked with
current_user_can()against the capability string, not the role name.
Tests
tests/Unit/Auth/RoleManagerTest.phptests/Unit/Auth/InstructorControllerTest.php