views:

50

answers:

2

I am currently figuring out a way to the the above.

My current application structure is as follows:

/modules
 / modulename
  /controllers
    /ProjectController.php

The application has 3 different user roles, each with functionality contained within these modules. I'd like to prevent having multiple actions for each user role in one controller as I think it makes my code less readable and ugly. So, I was thinking about a structure like this:

/modules
 / modulename
  /controllers
    /ProjectController.php
    /EmployeeProjectController.php
    /ExecutiveProjectController.php

This should work as follows:

  • Projectcontroller.php should be loaded for admin users
  • EmployeeProjectController.php should be loaded for employees
  • ExecutiveProjectController.php should be loaded for executives

Of course, I could relatively easy a different URL scheme to provide for this for each user role, but I do not want this. I want a uniform URL scheme.

Next step would then be to create routes for each of the controllers to rewrite them to another controller. I'd like to prevent this as well.

I want a way to globally tell the router to prefix controllers with 'Executive' or 'Employee' or whatever, based on the user role.

What would be the best way to this?

+1  A: 

Sounds like you could use a front controller plugin with a routeStartup() method that examines the Zend_Auth instance and adds the role-specific routes (from INI or XML file, for example).

Something like this:

class My_Controller_Plugin_RouteByAuth extends Zend_Controller_Plugin_Abstract
{
    public function routeStartup()
    {
        $auth = Zend_Auth::getInstance();
        if (!$auth->hasIdentity()){
            return;
        }
        $identity = $auth->getIdentity();
        if ($identity->isAdmin()){
            $this->_addRoutes('routes_admin.ini');
        } else if ($identity->isEmployee()){
            $this->_addRoutes('routes_employee.ini');
        } else if ($identity->isExecutive()){
            $this->_addRoutes('routes_executive.ini');
        } else {
            return;
        }
    }

    protected function _addRoutes($file)
    {
        $front = Zend_Controller_Front::getInstance();
        $router = $front->getRouter();
        $routes = new Zend_Config_Ini(APPLICATION_PATH . '/configs/ ' . $file);
        $router->addConfig($routes);
    }
}

Not tested, but I hope this conveys a core of a workable idea.

David Weinraub
Thank you for the answer. This is going in the right direction but it is not exactly what I mean. My actual question starts with the part *after* this code example: would it be possible to extend the router (or use it's default functionality) to create a global rewrite pattern for controllers?
Aron Rotteveel
Aaah, I think I see. There is certainly a `Zend_Auth` aspect of this, right? Gotta detect whether the user is employee or not, etc. A custom router sounds do-able. But let me suggest one alternative direction for consideration. I believe this kind of stuff is done typically with `Zend_Acl`, using the same controller for all roles, but allowing the Acl to modify their behavior. I guess the question is: how different is the processing for each of the roles you need to support? Does it really warrant separate controllers?
David Weinraub
Thanks again for the answer, I appreciate it. The application is pretty extensive and for the sake of seperation, I prefer to use different controllers for each role. Each of the roles differ quite a bit, which is why I'd rather not have all of these functions contained in one controller. I have now come up with a working solution. Upvoted your answer for the effort you put into it, though :)
Aron Rotteveel
Thanks for the upvote. ;-) OK, that's the point I wanted to raise: is the processing for each role really is different enough to justify separate controllers? Since it sounds like they are sufficiently different, it feels like a `Zend_Auth`-aware router might be the way to go. I would imagine that the router would employ the controller-name prefixing scheme you suggested. Probably needs some exceptions to the prefixing scheme for things that are not role-dependent, like login/logout. See what I mean?
David Weinraub
On further reflection, maybe not a complete router, just a role-aware route. Maybe with route-chaining? The standard route, folllowed by your role-aware route. The standard route can do the standard stuff, your role-aware route can do the controller prefixing. Es posible?
David Weinraub
Perhaps I am not understanding it correctly, but isn't that exactly what I did? :)
Aron Rotteveel
D'oh! I missed your answer. Sorry. Hey, at least great minds think alike. ;-)
David Weinraub
+1  A: 
Aron Rotteveel