*/ public const STUDIO_ADMIN_CAPS = [ self::CAP_MANAGE_INSTRUCTORS, self::CAP_MANAGE_STUDENTS, self::CAP_MANAGE_OFFERINGS, self::CAP_MANAGE_QUESTIONS, self::CAP_MANAGE_POLICIES, self::CAP_MANAGE_BILLING, self::CAP_VIEW_ALL_LESSONS, self::CAP_VIEW_ALL_PAYMENTS, self::CAP_EXPORT_PAYMENTS, ]; /** * Capabilities granted to the `us_instructor` role, and implicitly to any * WordPress administrator (see {@see grantStudioCapsToAdministrators()}) so a * single-instructor studio owner can both run the business and teach from one * account — managing their own availability and lessons without being assigned * a separate `us_instructor` role. * * @var list */ public const INSTRUCTOR_CAPS = [ self::CAP_MANAGE_AVAILABILITY, self::CAP_MANAGE_OFFERINGS, self::CAP_MANAGE_QUESTIONS, self::CAP_VIEW_LESSONS, self::CAP_VIEW_OWN_PAYMENTS, self::CAP_EXPORT_PAYMENTS, ]; public function __construct( private AccessSettings $access = new AccessSettings() ) {} public function register(): void { add_action( 'init', [ $this, 'createRoles' ] ); add_filter( 'user_has_cap', [ $this, 'grantStudioCapsToAdministrators' ], 10, 1 ); } public function createRoles(): void { if ( get_role( self::STUDIO_ADMIN ) === null ) { $studioCaps = [ 'read' => true ]; foreach ( self::STUDIO_ADMIN_CAPS as $cap ) { $studioCaps[ $cap ] = true; } add_role( self::STUDIO_ADMIN, __( 'Studio Admin', 'unsupervised-schedular' ), $studioCaps ); } if ( get_role( self::INSTRUCTOR ) === null ) { $instructorCaps = [ 'read' => true ]; foreach ( self::INSTRUCTOR_CAPS as $cap ) { $instructorCaps[ $cap ] = true; } add_role( self::INSTRUCTOR, __( 'Instructor', 'unsupervised-schedular' ), $instructorCaps ); } if ( get_role( self::STUDENT ) === null ) { add_role( self::STUDENT, __( 'Student', 'unsupervised-schedular' ), [ 'read' => true, self::CAP_BOOK_LESSON => true, self::CAP_VIEW_LESSONS => true, ] ); } } /** * Grant every studio-admin capability to WordPress administrators. * * The studio owner runs the site as an administrator (`manage_options`) and * should manage offerings, questions, policies, billing, and reports without * being assigned the separate `us_studio_admin` role. The instructor * capabilities are granted too, so a single-instructor studio owner can manage * their own availability and lessons and act as the instructor from the same * account. Applied dynamically via the `user_has_cap` filter, so nothing is * persisted and the grant disappears when the plugin is deactivated. * * Both grants are independently toggleable from the Access settings page (see * {@see AccessSettings}); they default on, preserving the single-account setup. * * @param array $allcaps All capabilities currently held by the user. * @return array */ public function grantStudioCapsToAdministrators( array $allcaps ): array { if ( empty( $allcaps['manage_options'] ) ) { return $allcaps; } if ( $this->access->adminsAreStudioAdmins() ) { foreach ( self::STUDIO_ADMIN_CAPS as $cap ) { $allcaps[ $cap ] = true; } } if ( $this->access->adminsAreInstructors() ) { foreach ( self::INSTRUCTOR_CAPS as $cap ) { $allcaps[ $cap ] = true; } } return $allcaps; } }