[UP] Pimp my WordPress menu part 2 :
access granted to authorized personnel only !

wp-tattoo-banner-color

Today’s goal is to hide specific menus and grant an access only if the user have the correct WordPress user role.
This is quite useful if you want to restrict a part of your site and make it an extranet.
As we saw in the previous article, we can add this kind of capabilities by creating a new set of functions for the walker class and go further in the menu enhancement.
I strongly advise you to have a look at “fixing the menu” as I Will use somes techniques described there.
I also invite you to use the Twenty ten Theme and download the source code at the bottom of this page to have a look at the code.

Finally, this method is totally open to discussion, you know what to do ;)

1. setting up the engine

First of all, you have to create a menu and pages attached to it.
As an example I created 3 pages : About, Events and sample and create a “main menu” zone in my header.php file.
To set up the access we need 2 kinds of data, a trigger which will allow us to easily deactivate the restrictions and an array which will store all the pages ID we want to restrict (sorted by WP role).
You will find something like this in the source code :

define("_USE_RESTRICTED_ACCESS", true); // main trigger
$menu_restricted_access_array['subscriber'] = array( '23', '21'); // restriction for subscribers
$menu_restricted_access_array['contributor'] = array( '2','23' ); // restriction for constributors

Note : you can look at your status bar to find the pages ID.
In this example, only the subscribers can access the About and Events pages.
The contributors, on the other hand, will have access to the Events and Sample page.
Which leave absolutely no menu item to display in the header.
As far as the administrator is concerned, he will have access to everything ! ;)

2. adding few functions

As part of the menu walker extension I will create 4 new functions.
The name should be speaking by itself but I will explain how they work.

  • getCurrentUserRole will access the current user object to get his role, the result wil be stored in a private role of the object :

    private function getCurrentUserRole()
    {
        global $current_user;
    
        if ( $this->current_user_role == "" )
        {
            $this->current_user_role = $current_user->roles[0];
        }
        return $this->current_user_role;
    }
    
  • isAdmin will just check if we can grant access to everything :
    private function isAdmin()
    {
        $current_role = $this->getCurrentUserRole();
    
        if ( $current_role == "administrator" )
        {
            return true;
        }
        else
        {
            return false;
        }
    }
  • getAllRestrictions will examine the entire restrictions array, merge all IDs and return the result to provide a way to hide all restricted menus :
    private function getAllRestrictions()
    {
        global $menu_restricted_access_array;
    
        $all_restrictions_array = array();
    
        foreach ( $menu_restricted_access_array as $one_restriction )
        {
            $all_restrictions_array = array_merge($all_restrictions_array, $one_restriction);
        }
        $all_restrictions_array = array_unique($all_restrictions_array);
    
        return $all_restrictions_array;
    }
  • isAccessGranted will analyze the restriction array to allow acces (or not).
    This one needs a little more explanation as its the core function of this tutorial.

    First of all, if the user is the admin, we always grant the access on the item (line 5).
    If not we check if the current role has limitations (line 9), if it’s the case we check if the current menu item is in the role restrictions (line 13)
    And finally if none of these conditions are verified we always grant access (line 24).

    private function isAccessGranted( $id_menu_item )
    {
        global $menu_restricted_access_array;
    
        if ( $this->isAdmin() )
        {
            return true;
        }
        else if ( isset($menu_restricted_access_array[$this->current_user_role]) )
        {
            $restricted_access = $menu_restricted_access_array[$this->current_user_role];
    
            if ( in_array($id_menu_item, $restricted_access) )
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            return true;
        }
    }

3. menu final render

All these functions are triggered when the final render of the menu happen.
I modified a little bit the start_el function to still take care about the publication issue (cf. my previous article) like this :

$is_item_published = ( $item_data->post_status == "publish" ) ? true : false;

This creates a new flag which will be combined to the restriction process.
And now, let the party started with this bit of code :

if ( _USE_RESTRICTED_ACCESS )
{
    $restrictions_array = $this->getAllRestrictions();

    if ( is_user_logged_in() )
    {
        $item_to_display = ( $is_item_published && $this->isAccessGranted($item->object_id) ) ? true : false ;
    }
    else if ( in_array($item->object_id, $restrictions_array) )
    {
        $item_to_display = false;
    }
    else
    {
        $item_to_display = $is_item_published;
    }
}
else
{
    $item_to_display = $is_item_published;
}

This needs a little explanation :
If the system is activated (line 1) and the user is logged (line 5) then I check the access and check the publication status.
If the user is not logged in I just check if the item is part of the rectriction (line 9) previously gathered (line 3).
If none of above conditions are verified I just check the published status (line 15).

Final thoughts

This is it !

With a few hacks we can do a clean coding that suits our needs. You have the right to try this @ home ;)
I developped this technique using WordPress 3.1 RC-4 so it will be totally up to date when 3.1 will be out !
Hope this will help you to set up your extranet menus.
To be continued…

Cheers,
jeFFF


DOWNLOAD : WordPress restrict by role script (PHP file, 2Ko)
credits – WordPress tattoo found on Edward T. Morita website : www.edmorita.com

[UPDATE] — Big up for Tejas who modified the source code to use the nav item description to set up the aurthorized roles, his modifications can be found here : http://pastebin.com/hQnShaxA

2 comments
  1. tejas says: May 12, 20119:00 pm

    Man, this works like a charm!! You rock!!

  2. tejas says: May 16, 20116:31 am

    Hey Boss,

    I modified some of your code to use the nav item description for adding which user role gets access to which menu tab. My code is posted here – http://pastebin.com/hQnShaxA

    I hope people visiting your site can be benefited from this as well.

    Thanks,
    -tejas

Submit comment