Multiple Admin Levels in CakePHP

Usually when building a website that has a content management system (CMS) you will need a control panel that will be accessed via a login page so that only administrators with a username and password can login and change the site. CakePHP comes equipped with "Admin Routing" that will automatically re route URLs such as http://cakephp/admin/posts/add to a controller action called admin_add this is extremely useful for admin panels.

The only drawback of using Admin Routing is that by default it can only accommodate a single admin user, recently I've been working on a project that requires multiple levels of users e.g. admins, members, and general visitors and I wanted a way of doing this in CakePHP. Luckily I found this solution in the bakery and I've slightly modified it to meet my needs.

Research

After a quick search on google I came across this article in the bakery which pretty much does the job. The initial function is quite basic but other CakePHP users have commented on the article to beef it up. The solution is a piece of code that's located in the bootstrap.php file and loaded every time a URL is requested.

The function works as follows:

  • Takes an array of user types
  • Process' and splits the URL of page
  • If the first part of the URL is one of the usertypes it will dynamically assign it the 'CAKE_ADMIN'
  • If no match is found a quick test is run to make sure the user isn't trying to access the action without the admin routing

Implementation

I've used a lot of the code from the bakery article however I've slightly modified the error checking process, initially the function was open to a few security concerns. If a user tried to access an admin function directly e.g. http://site/controller/admin_action without using the admin routing in the URL e.g. http://site/admin/controller/action then the action was processed as normal. My modified function takes this into account, users trying to access /controller/admin_action will be redirected to /admin/controller/action so that checks can be done to allow or deny access to the user.

// file: /app/config/bootstrap.php

/*
 * adminHack()
 * allows multiple admin users e.g. admin/posts/ and member/posts/
 */
function adminHack($admin_types)
{
    // get the bits of the url
    $bits = explode('/', $_GET['url'], 3);
   
    // if a usertype is requested
    if(in_array($bits[0], $admin_types)) {
        // define usertype as an admin
        define('CAKE_ADMIN', $bits[0]);
    } else {
        // init
        $matches = array();
       
        // explode the url that contains '_' e.g. /admin_index/
        $morebits = explode('_', $bits[1]);
       
        // check for this: url /controller/admin_action
        if (preg_match('/^(' . implode('|', $admin_types) . ')\_/', $bits[1], $matches)) {
            // redirect to this: /admin/controller/action
            $url = $matches[1].'/'.$bits[0].'/'.$morebits[1];
            header('Location: /'.$url);
        }
    }
}
// setup admin and member users
adminHack(array('admin', 'member'));

Controller Checks

Now that our system can accept multiple levels of users we can do a simple check in any controller by using the beforeFilter() method and checking the params array:

/*
 * beforeFilter()
 * before any action is done
 */
function beforeFilter() {
	// if an admin route
	if(isset($this->params['admin'])) {
		// change the layout file
		$this->layout = 'admin';
		// check that the user has admin access
		$this->checkAccess('admin');
	}
	
	// if a member route
	if(isset($this->params['member'])) {
		// change the layout file
		$this->layout = 'member';
		// check that the user has member access
		$this->checkAccess('member');
	}
}

For the project I'm working on I have created a simple function checkAccess() that will check user access depending on their user type and either allow them access to the action or redirect them to the login page with an error message, for more details on creating such a function check out my article on creating an admin section. If you are building a system with more user levels then you can just add another check of the params array like above.

Wrapping Up

So there you have it, multiple admin levels in CakePHP, just something that I came across for a project I'm currently working on and I thought I'd share how I implemented it in my code. If you have any problems or questions just let me know via a comment or by email and I'll try and help you out.

Posted on 25th March 2008
6 years, 3 weeks, 1 day ago