*/ function tony_sportspress_get_officials_manager_caps() { $caps = array( 'read' => true, 'edit_posts' => true, 'delete_posts' => true, 'edit_published_posts' => true, ); foreach ( tony_sportspress_build_post_type_caps( 'sp_official', 'sp_officials' ) as $cap ) { $caps[ $cap ] = true; } // Allow access to the event list and quick edit for assignments, without full event management. $caps['read_sp_event'] = true; $caps['edit_sp_event'] = true; $caps['edit_sp_events'] = true; $caps['edit_others_sp_events'] = true; $caps['edit_published_sp_events'] = true; $caps['read_private_sp_events'] = true; return $caps; } /** * Get the capabilities managed for the officials manager role. * * @return string[] */ function tony_sportspress_get_officials_manager_managed_caps() { return array_keys( tony_sportspress_get_officials_manager_caps() ); } /** * Grant custom official caps to existing roles that already have matching event caps. * * This preserves existing access after moving officials off the `sp_event` capability type. * * @return void */ function tony_sportspress_sync_official_caps_to_existing_roles() { global $wp_roles; if ( ! class_exists( 'WP_Roles' ) ) { return; } if ( ! isset( $wp_roles ) ) { $wp_roles = wp_roles(); } if ( ! $wp_roles instanceof WP_Roles ) { return; } $cap_map = array( 'edit_sp_event' => 'edit_sp_official', 'read_sp_event' => 'read_sp_official', 'delete_sp_event' => 'delete_sp_official', 'edit_sp_events' => 'edit_sp_officials', 'edit_others_sp_events' => 'edit_others_sp_officials', 'publish_sp_events' => 'publish_sp_officials', 'read_private_sp_events' => 'read_private_sp_officials', 'delete_sp_events' => 'delete_sp_officials', 'delete_private_sp_events' => 'delete_private_sp_officials', 'delete_published_sp_events' => 'delete_published_sp_officials', 'delete_others_sp_events' => 'delete_others_sp_officials', 'edit_private_sp_events' => 'edit_private_sp_officials', 'edit_published_sp_events' => 'edit_published_sp_officials', ); foreach ( $wp_roles->role_objects as $role ) { if ( ! $role instanceof WP_Role ) { continue; } foreach ( $cap_map as $event_cap => $official_cap ) { if ( $role->has_cap( $event_cap ) ) { $role->add_cap( $official_cap ); } } } } /** * Create or update the officials manager role. * * @return void */ function tony_sportspress_sync_officials_manager_roles() { $role = get_role( TONY_SPORTSPRESS_OFFICIALS_MANAGER_ROLE ); if ( ! $role ) { $role = add_role( TONY_SPORTSPRESS_OFFICIALS_MANAGER_ROLE, __( 'Officials Manager', 'tonys-sportspress-enhancements' ), array() ); } if ( ! $role instanceof WP_Role ) { return; } $desired_caps = tony_sportspress_get_officials_manager_caps(); foreach ( tony_sportspress_get_officials_manager_managed_caps() as $cap ) { if ( ! empty( $desired_caps[ $cap ] ) ) { $role->add_cap( $cap ); } else { $role->remove_cap( $cap ); } } tony_sportspress_sync_official_caps_to_existing_roles(); } add_action( 'init', 'tony_sportspress_sync_officials_manager_roles' ); /** * Assign custom capabilities to the officials post type. * * @param array $args Post type registration args. * @return array */ function tony_sportspress_officials_post_type_caps( $args ) { $args['capability_type'] = array( 'sp_official', 'sp_officials' ); $args['map_meta_cap'] = true; $args['capabilities'] = array( 'create_posts' => 'edit_sp_officials', ); return $args; } add_filter( 'sportspress_register_post_type_official', 'tony_sportspress_officials_post_type_caps' ); /** * Determine whether the current user should be restricted to assignment-only event access. * * @return bool */ function tony_sportspress_is_officials_manager_user() { $user = wp_get_current_user(); if ( ! $user instanceof WP_User || empty( $user->roles ) ) { return false; } if ( ! in_array( TONY_SPORTSPRESS_OFFICIALS_MANAGER_ROLE, $user->roles, true ) ) { return false; } if ( current_user_can( 'manage_options' ) || current_user_can( 'manage_sportspress' ) ) { return false; } return true; } /** * Prevent assignment-only users from opening full event edit screens. * * @return void */ function tony_sportspress_lock_event_editor_for_officials_manager() { global $pagenow; if ( ! is_admin() || ! tony_sportspress_is_officials_manager_user() ) { return; } if ( 'post-new.php' === $pagenow ) { $post_type = isset( $_GET['post_type'] ) ? sanitize_key( wp_unslash( $_GET['post_type'] ) ) : 'post'; if ( 'sp_event' === $post_type ) { wp_safe_redirect( admin_url( 'edit.php?post_type=sp_event&tse_event_editor_locked=1' ) ); exit; } } if ( 'post.php' !== $pagenow ) { return; } $post_id = isset( $_GET['post'] ) ? absint( wp_unslash( $_GET['post'] ) ) : 0; if ( $post_id > 0 && 'sp_event' === get_post_type( $post_id ) ) { wp_safe_redirect( admin_url( 'edit.php?post_type=sp_event&tse_event_editor_locked=1' ) ); exit; } } add_action( 'admin_init', 'tony_sportspress_lock_event_editor_for_officials_manager' ); /** * Show an admin notice when event editor access is blocked. * * @return void */ function tony_sportspress_officials_manager_admin_notice() { if ( ! tony_sportspress_is_officials_manager_user() ) { return; } if ( empty( $_GET['tse_event_editor_locked'] ) ) { return; } echo '
' . esc_html__( 'Officials Managers can assign officials from the events list via Quick Edit, but cannot open the full event editor.', 'tonys-sportspress-enhancements' ) . '