Created
November 4, 2011 04:44
Page by page editting permissions for WordPress
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: Restrict Page Access | |
Plugin URI: https://gist.github.com/1338673 | |
Description: Allows administrators to give editors permission to edit only certain posts | |
Author: Christopher Davis | |
Author URI: http://christopherdavis.me | |
License: GPL2 | |
*/ | |
add_action( 'edit_user_profile', 'wpse30211_user_profile' ); | |
/** | |
* Adds an additional multi select on user profile pages | |
*/ | |
function wpse30211_user_profile( $user ) | |
{ | |
// only show this on editor pages | |
if( ! in_array( 'editor', $user->roles ) ) return; | |
// get the pages. | |
$pages = get_posts( | |
array( | |
'post_type' => 'page', | |
'numberposts' => -1, | |
'post_status' => 'any', | |
) | |
); | |
// Bail if we don't have pages. | |
if( ! $pages ) return; | |
// Which pages can our user edit? | |
$allowed = get_user_meta( $user->ID, 'wpse30211_pages', true ); | |
if( ! is_array( $allowed ) || empty( $allowed ) ) $allowed = array(); | |
// nonce-i-fy things | |
wp_nonce_field( 'wpse30211_nonce', 'wpse30211_nonce' ); | |
// section heading... | |
echo '<h3>' . __( 'Grant this User permission to edit...' ) . '</h3>'; | |
echo '<select multiple="multiple" name="wpse30211[]">'; | |
echo '<option value="0">None</option>'; | |
foreach( $pages as $p ) | |
{ | |
// for use in checked() later... | |
$selected = in_array( $p->ID, $allowed ) ? 'on' : 'off'; | |
echo '<option ' . selected( 'on', $selected, false ) . ' value="' . esc_attr( $p->ID ) . '">' . esc_html( $p->post_title ) . '</option>'; | |
} | |
echo '</select>'; | |
} | |
add_action( 'edit_user_profile_update', 'wpse30211_user_save' ); | |
/** | |
* Saves the newly added multi select box that restricts posts | |
*/ | |
function wpse30211_user_save( $user_id ) | |
{ | |
// verify our nonce | |
if( ! isset( $_POST['wpse30211_nonce'] ) || ! wp_verify_nonce( $_POST['wpse30211_nonce'], 'wpse30211_nonce' ) ) | |
return; | |
// make sure our fields are set | |
if( ! isset( $_POST['wpse30211'] ) ) | |
return; | |
$save = array(); | |
foreach( $_POST['wpse30211'] as $p ) | |
{ | |
$save[] = absint( $p ); | |
} | |
update_user_meta( $user_id, 'wpse30211_pages', $save ); | |
} | |
add_action( 'load-post.php', 'wpse30211_kill_edit' ); | |
/** | |
* Don't allow users to load just any page for editing | |
*/ | |
function wpse30211_kill_edit() | |
{ | |
$post_id = isset( $_REQUEST['post'] ) ? absint( $_REQUEST['post'] ) : 0; | |
if( ! $post_id ) return; | |
// bail if this isn't a page | |
if( 'page' !== get_post_type( $post_id ) ) return; | |
$user = wp_get_current_user(); | |
// If the user is an admin, bail. | |
if( in_array( 'administrator', $user->roles ) ) return; | |
$allowed = get_user_meta( $user->ID, 'wpse30211_pages', true ); | |
if( ! is_array( $allowed ) || empty( $allowed ) ) $allowed = array(); | |
// if the user can't edit this page, stop the loading... | |
if( ! in_array( $post_id, $allowed ) ) | |
{ | |
wp_die( | |
__( 'User cannot edit this page' ), | |
__( "You can't edit this post" ), | |
array( 'response' => 403 ) | |
); | |
} | |
} | |
add_action( 'pre_post_update', 'wpse30211_stop_update' ); | |
/** | |
* Prevents users without permission from updating pages | |
*/ | |
function wpse30211_stop_update( $post_id ) | |
{ | |
// not a page? bail. | |
if( 'page' !== get_post_type( $post_id ) ) return; | |
$user = wp_get_current_user(); | |
// not an editor? bail. | |
if( in_array( 'administrator', $user->roles ) ) return; | |
$allowed = get_user_meta( $user->ID, 'wpse30211_pages', true ); | |
if( ! is_array( $allowed ) || empty( $allowed ) ) $allowed = array(); | |
if( ! in_array( $post_id, $allowed ) ) | |
{ | |
wp_die( | |
__( 'User cannot edit this page' ), | |
__( "You can't edit this post" ), | |
array( 'response' => 403 ) | |
); | |
} | |
} | |
add_action( 'load-edit.php', 'wpse30211_load_edit' ); | |
/** | |
* Might add a filter to the `parse_query` if a user lands on the page | |
* list table and their roll is anything but administrator | |
*/ | |
function wpse30211_load_edit() | |
{ | |
$user = wp_get_current_user(); | |
// allow admins to see everything | |
if( in_array( 'administrator', $user->roles ) ) return; | |
$post_type = isset( $_GET['post_type'] ) ? $_GET['post_type'] : 'post'; | |
if( 'page' != $post_type ) return; | |
add_filter( 'parse_query', 'wpse30211_parse_query' ); | |
} | |
/** | |
* Filters page list to include only pages users can edit | |
*/ | |
function wpse30211_parse_query( $wp ) | |
{ | |
$user = wp_get_current_user(); | |
$pages = get_user_meta( $user->ID, 'wpse30211_pages', true ); | |
if( empty( $pages ) || ! is_array( $pages ) ) $pages = array(); | |
$wp->query_vars['post__in'] = $pages; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
I know this Plugin is a bit old but It came in the clutch to help solve a problem.
Would you know of a way to add a return URL in the 403 error page that comes up if a user try's to edit a page.
The script section is
wp_die(
__( 'User cannot edit this page' ),
__( "You can't edit this post" ),
array( 'response' => 403 )
);
I just need to add a URL so the user can return home. Thanks!