Created
November 7, 2025 23:01
-
-
Save rickalday/1a9baff2500927784e2c32f1466b0839 to your computer and use it in GitHub Desktop.
Restrict Editor role to Give Campaing Pages only
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Allow editors to edit/delete ONLY pages that have the give_campaign_id meta key. | |
| */ | |
| /** | |
| * Map meta caps so editors may only edit/delete posts that have give_campaign_id. | |
| * | |
| * @param array $caps Mapped capabilities to return. | |
| * @param string $cap Capability being checked. | |
| * @param int $user_id User ID. | |
| * @param array $args Additional args (for edit_post/delete_post, $args[0] is post ID). | |
| * @return array | |
| */ | |
| function allow_editors_only_give_campaign_map_meta_cap( $caps, $cap, $user_id, $args ) { | |
| // Only care about edit/delete capabilities for posts/pages. | |
| $targets = array( 'edit_post', 'delete_post', 'edit_page', 'delete_page' ); | |
| if ( ! in_array( $cap, $targets, true ) ) { | |
| return $caps; | |
| } | |
| // Need a post ID to decide. | |
| $post_id = isset( $args[0] ) ? intval( $args[0] ) : 0; | |
| if ( ! $post_id ) { | |
| return $caps; | |
| } | |
| // Allow administrators and other high-cap users to behave normally. | |
| if ( user_can( $user_id, 'manage_options' ) ) { | |
| return $caps; | |
| } | |
| // Load the user and check for the editor role. | |
| $user = get_userdata( $user_id ); | |
| if ( ! $user ) { | |
| return $caps; | |
| } | |
| // If the user is an editor, enforce restriction: only allow when meta exists. | |
| if ( in_array( 'editor', (array) $user->roles, true ) ) { | |
| $val = get_post_meta( $post_id, 'give_campaign_id', true ); | |
| if ( $val === '' || $val === null ) { | |
| // No campaign meta — deny. | |
| return array( 'do_not_allow' ); | |
| } | |
| // Meta exists — allow. Return original $caps (no change). | |
| } | |
| return $caps; | |
| } | |
| add_filter( 'map_meta_cap', 'allow_editors_only_give_campaign_map_meta_cap', 10, 4 ); | |
| /** | |
| * Prevent editors from opening the edit screen for pages that do NOT have give_campaign_id. | |
| * (Extra guard for direct URL access.) | |
| */ | |
| function allow_editors_only_give_campaign_block_edit_screen() { | |
| if ( ! is_admin() ) { | |
| return; | |
| } | |
| // Only run for the post edit screen (post.php). We intentionally allow post-new.php. | |
| $pagenow = basename( $_SERVER['PHP_SELF'] ); | |
| if ( 'post.php' !== $pagenow ) { | |
| return; | |
| } | |
| if ( ! is_user_logged_in() ) { | |
| return; | |
| } | |
| $current_user = wp_get_current_user(); | |
| if ( ! in_array( 'editor', (array) $current_user->roles, true ) ) { | |
| return; | |
| } | |
| $post_id = isset( $_GET['post'] ) ? intval( $_GET['post'] ) : 0; | |
| if ( ! $post_id ) { | |
| return; | |
| } | |
| $val = get_post_meta( $post_id, 'give_campaign_id', true ); | |
| if ( $val === '' || $val === null ) { | |
| // Redirect back to the pages list with a notice. | |
| $redirect = add_query_arg( | |
| array( | |
| 'post_type' => get_post_type( $post_id ), | |
| 'restricted_by' => 'give_campaign_only', | |
| ), | |
| admin_url( 'edit.php' ) | |
| ); | |
| wp_safe_redirect( $redirect ); | |
| exit; | |
| } | |
| } | |
| add_action( 'admin_init', 'allow_editors_only_give_campaign_block_edit_screen' ); | |
| /** | |
| * Admin notice when redirected due to restriction. | |
| */ | |
| function allow_editors_only_give_campaign_admin_notice() { | |
| if ( ! current_user_can( 'editor' ) ) { | |
| return; | |
| } | |
| if ( isset( $_GET['restricted_by'] ) && 'give_campaign_only' === $_GET['restricted_by'] ) { | |
| echo '<div class="notice notice-error is-dismissible"><p>'; | |
| echo esc_html__( 'You can only edit pages that are associated with a campaign.', 'your-textdomain' ); | |
| echo '</p></div>'; | |
| } | |
| } | |
| add_action( 'admin_notices', 'allow_editors_only_give_campaign_admin_notice' ); | |
| /** | |
| * Optional: restrict the Pages list so editors only see pages that have give_campaign_id. | |
| * Remove this function if you prefer editors to still see the full list but be blocked when they attempt edits. | |
| */ | |
| function allow_editors_only_give_campaign_pre_get_posts( $query ) { | |
| if ( ! is_admin() || ! $query->is_main_query() ) { | |
| return; | |
| } | |
| // Only apply on the Pages admin list. | |
| $pagenow = basename( $_SERVER['PHP_SELF'] ); | |
| if ( 'edit.php' !== $pagenow || $query->get( 'post_type' ) !== 'page' ) { | |
| return; | |
| } | |
| if ( ! current_user_can( 'editor' ) ) { | |
| return; | |
| } | |
| // Only show pages that have the meta key give_campaign_id. | |
| $meta_query = array( | |
| array( | |
| 'key' => 'give_campaign_id', | |
| 'compare' => 'EXISTS', | |
| ), | |
| ); | |
| $query->set( 'meta_query', $meta_query ); | |
| } | |
| add_action( 'pre_get_posts', 'allow_editors_only_give_campaign_pre_get_posts' ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment