Created
June 12, 2024 18:50
-
-
Save greg-randall/ed0d79c695165637606734147c212f07 to your computer and use it in GitHub Desktop.
WordPress plugin to limit editing of pages and their children to certain user roles.
This file contains 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 | |
/** | |
* Plugin Name: Role-Based Page Editor Limitations | |
* Description: This plugin restricts editing capabilities of specific pages to certain user roles. It dynamically creates roles if they don't exist and assigns them editor capabilities. It then checks if a user with a specific role is trying to edit a page that they're not assigned to, and if so, it removes their editing capabilities for that page. Edit the $role_page_map array to specify which roles can edit which pages. | |
* Version: 1 | |
* Author: Greg R. | |
*/ | |
/* For example you want to make it so that some peolple at your company can edit /subpage/ and all the children under that page, so you can create a user role that restricts them to jus that section of the site. */ | |
global $role_page_map; | |
// user role as key and page path as value | |
// note that the page and any children (and childrens children etc) of the page will be editable by the user with the role | |
$role_page_map = array( | |
'subpage_editor' => 'subpage' | |
); | |
// Loop over the role-page map | |
foreach ($role_page_map as $role => $page_path) { | |
// If the role doesn't exist | |
if (!get_role($role)) { | |
// Get the capabilities of the editor role | |
$editor_capabilities = get_role('editor')->capabilities; | |
// Create a friendly name for the role | |
$friendly_name = ucwords(str_replace('_', ' ', $role)); | |
// Add the new role with the capabilities of the editor role | |
add_role($role, $friendly_name, $editor_capabilities); | |
} | |
} | |
function role_based_edit_map_meta_cap($caps, $cap, $user_id, $args) { | |
global $role_page_map; | |
// If we're checking the 'edit_post' or 'edit_page' capability | |
if ('edit_post' === $cap || 'edit_page' === $cap) { | |
// Get the post | |
$post = get_post($args[0]); | |
// Get the user | |
$user = get_userdata($user_id); | |
// Check each role in the role-page map | |
foreach ($role_page_map as $role => $page_path) { | |
// If the user has the current role | |
if (in_array($role, $user->roles)) { | |
// Get the ID of the page for this role | |
$page_id = get_page_by_path($page_path)->ID; | |
// Check if the post is a descendant of the page | |
$is_descendant = false; | |
$parent_id = $post->post_parent; | |
while ($parent_id != 0) { | |
if ($parent_id == $page_id) { | |
$is_descendant = true; | |
break; | |
} | |
$parent_post = get_post($parent_id); | |
$parent_id = $parent_post->post_parent; | |
} | |
// If the post is not the page or a descendant of the page | |
if ($post->ID != $page_id && !$is_descendant) { | |
// Remove the 'edit_post' or 'edit_page' capability | |
$caps[] = 'do_not_allow'; | |
} | |
} | |
} | |
} | |
return $caps; | |
} | |
add_filter('map_meta_cap', 'role_based_edit_map_meta_cap', 10, 4); | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment