How to control wordpress blogs for specific user roles ?

Did you ever think to post a wordpress blog specific to user roles? Can we select user role who can only view the specific post? Can blog be post to specific user role?  There are many organisations who wants to limit the view of blogs to specific users. e.g. If organisation have buyers, sellers and reseller and they want to limit the rendering of the content to specific user roles. WordPress does not support blogs or posts privacy for specific user roles.

We have done an extensive search for a plugin which can provide this feature, but did not find which fullfil our requirement. We decided to create new plugin which can do the task for us.  We read some blogs which explains about custom meta data of blog. We also go through with some articles explaining how to add custom field at blog add/edit form.

Lets start implementing controlling wordpress blogs for user roles

First of all we need to create a function which add meta box to blog post form. We create a class rolemetasClass.

class rolemetasClass {

	/**
	 * Hook into the appropriate actions when the class is constructed.
	 */
	public function __construct() {
		add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
		add_action( 'save_post', array( $this, 'save' ) );
	}

	/**
	 * Adds the meta box container.
	 */
	public function form_content_box( $post_type ) {
            $post_types = array('post', 'page');
            if ( in_array( $post_type, $post_types )) {
				form_content_box(
					'User Filter form'
					,'Select User Roles'
					,array( $this, 'render_meta_box_content' )
					,$post_type
					,'advanced'
					,'high'
				);
            }
	}

	/**
	 * Save the custom data when the post is saved.
	 */
	public function save( $post_id ) {
	
		$roles = implode(',', $_POST['roles']);

		// Update the meta field.
		
		update_post_meta( $post_id, 'blog_roles_meta', $roles );
		
		$all_roles = $wp_roles->roles;
		$editable_roles = apply_filters('editable_roles', $all_roles);
		 
		foreach ($editable_roles as $rl){
			delete_post_meta($post_id, 'blog_role_meta_'.$rl['name']);
		}
		
		foreach($_POST['roles'] as $role){
			update_post_meta( $post_id, 'blog_role_meta_'.$role, $role );
		}
	}


	/**
	 * Render Meta Box content.
	 */
	public function render_meta_box_content( $post ) {
	
		//render the view
		$content = metaRolesWidgetView::render( ) . $content ;
		
		//return the result
		return $content;
	}
	
}

roleMataClass have one constructor which add hooks for adding content to blog post screen and save field value to database. We have a function add_meta_box which add custom box at post screen. It call render_meta_box_content function which fetch widget content.

We have added new class metaRolesWidgetView for creating view which show all editable roles available in wordpress.

<?php
  class metaRolesWidgetView
    {
        public static function render()
        {
        	global $wp_roles;
        	
        	$all_roles = $wp_roles->roles;
        	$editable_roles = apply_filters('editable_roles', $all_roles);
        	
        	echo '<label for="myplugin_new_field">';
        	_e( 'Select user roles who can view this post', 'myplugin_textdomain' );
        	echo '</label> <br />';
        	
        	foreach($editable_roles as $role){
        		echo '<input type="checkbox" id="myplugin_new_field" name="roles[]"';
        		echo ' value="' . esc_attr( $role['name'] ) . '" size="25" />'. $role['name'] .'<br />';
        	}
      
        }
    }
?>

This function create simple widget with heading and multi-checkbox fields with name roles. RolemetasClass have a save function which get values from this meta box and save in database with custom meta data  blog_role_meta_$roleName. $roleName is role name user selected at the time saving post. We add multiple custom meta field depends on user select at the time of saving the blog. Suppose user select subscriber and author at the time saving, it will save three meta fields (blog_role_meta_Subscriber, blog_role_meta_Author,blog_role_meta) in post meta table with post id.

Now we need to add function which filter query from user view.

   class filterRole(){
      function filter_posts_role( $query ) {
		
		global $current_user, $wpdb;
		$role = $wpdb->prefix . 'capabilities';
		$current_user->role = array_keys($current_user->$role);
		$role = $current_user->role[0];
		
		$query->set( 'meta_key','blog_role_meta_'.$role );
		return $query;
       }
	
       function exclude_single_posts_home($query) {
		global $current_user, $wpdb;
		$role = $wpdb->prefix . 'capabilities';
		$current_user->role = array_keys($current_user->$role);
		$role = $current_user->role[0];
		
		$query->set( 'meta_key','blog_role_meta_'.$role );
                return $query;		
       }
  }

 


Now we need to call this class and function in our main plugin file.

require_once( 'meta-roles-widget.php' );

require_once( 'controller/rolemetas.php' );

function call_rolemetasClass() {
    new rolemetasClass();
}

if ( is_admin() ) {
    add_action( 'load-post.php', 'call_rolemetasClass' );
    add_action( 'load-post-new.php', 'call_rolemetasClass' );
}

$role_oblect = new filterRole();
add_action('pre_get_posts',array($role_object,'filter_posts_role'));
add_action('pre_get_posts',array($role_object,'exclude_single_posts_home'));

Conclusion

This will help organisation or bloggers to restrict the blog as per user role. Feel free to contact us if you have any query.

Leave a Comment

Scroll to Top