Skip to content

Instantly share code, notes, and snippets.

@chrisguitarguy
Created November 4, 2011 04:44
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save chrisguitarguy/1338673 to your computer and use it in GitHub Desktop.
Save chrisguitarguy/1338673 to your computer and use it in GitHub Desktop.
Page by page editting permissions for WordPress
<?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;
}
@Mte90
Copy link

Mte90 commented Jan 8, 2014

In the page list the count of the page are wrong.
The number show are the total page not the page filtered :-/
i have no idea how to fix this problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment