A further follow up:

The secret recipe seems to be to use dispatchLoopStartup() rather than preDispatch as in:

class Menu_Controller_Plugin_Auth extends Zend_Controller_Plugin_Abstract
{
    private $_auth;
    private $_acl;

    private $_noauth = array('module' => 'default',
                             'controller' => 'auth',
                             'action' => 'login');

    private $_noacl = array('module' => 'default',
                            'controller' => 'index',
                            'action' => 'index');

    public function __construct( $acl )
    {
        $this->_auth = Zend_Auth::getInstance();
        $this->_acl = $acl;
    }

        public function dispatchLoopStartup()
        {

        if( $this->_auth->hasIdentity() ) {
            $identity = $this->_auth->getIdentity();
            $role = $identity->role;
        } else {
            $role = 'guest';
        }

            $controller = $this->_request->controller;
            $action = $this->_request->action;
        $module = $this->_request->module;
        //echo $module;
                //$resource = $controller;
                $resource = $module;
        
            if (!$this->_acl->has($resource)) {
                $resource = null;
            }

        if (!$this->_acl->isAllowed($role, $resource, $action)) {
            if (!$this->_auth->hasIdentity()) {
                $module = $this->_noauth['module'];
                $controller = $this->_noauth['controller'];
                $action = $this->_noauth['action'];
            } else {
                $module = $this->_noacl['module'];
                $controller = $this->_noacl['controller'];
                $action = $this->_noacl['action'];
            }
        }
        Zend_Debug::dump( $module );
        Zend_Debug::dump( $controller );
        Zend_Debug::dump( $action );
        Zend_Debug::dump( $this->getRequest() );
        $this->_request->setModuleName($module)
                ->setControllerName($controller)
                ->setActionName($action)
                ->setDispatched( TRUE );
    }
}

On 30/03/2007, at 12:53 PM, Nick Lo wrote:

Hi Simon,

I've sussed out where the issue is and have commented it in the following:

The example url; site.com/auth/ goes to default/controllers/ AuthController.php...

AuthController extends Zend_Controller_Action
{
    public function indexAction()
    {
        $this->_forward( 'login', 'auth', 'default' );
    }

     public function loginAction()
    {
        ...setup form stuff...
    }
}

...and will then be sent back through...

class My_Plugin_Auth extends Zend_Controller_Plugin_Abstract
{
    private $_auth;
    private $_acl;

    private $_noauth = array('module' => 'default',
                             'controller' => 'auth',
                             'action' => 'login');

    private $_noacl = array('module' => 'default',
                            'controller' => 'error',
                            'action' => 'privileges');

    public function __construct($auth, $acl)
    {
        $this->_auth = $auth;
        $this->_acl = $acl;
    }

        public function preDispatch($request)
        {
        if ($this->_auth->hasIdentity()) {
            $role = $this->_auth->getIdentity()->getUser()->role;
        } else {
            $role = 'guest';
        }

            $controller = $request->controller;
            $action = $request->action;
            $module = $request->module;
                $resource = $controller;
                
                /*** At this point we have...
                * $module = 'default'
                * $controller =  'auth'
                * $action = 'index'
                * ...which is the original action that _forwards()
                *****/
        
            if (!$this->_acl->has($resource)) {
                $resource = null;
            }

        if (!$this->_acl->isAllowed($role, $resource, $action)) {

/*** Now if we ARE allowed the next if/else will be skipped ***/

            if (!$this->_auth->hasIdentity()) {
                $module = $this->_noauth['module'];
                $controller = $this->_noauth['controller'];
                $action = $this->_noauth['action'];
            } else {
                $module = $this->_noacl['module'];
                $controller = $this->_noacl['controller'];
                $action = $this->_noacl['action'];
            }
        }

                /***
                * So we end up still with...
                * $module = 'default'
                * $controller =  'auth'
                * $action = 'index'
                * ...which is still the original action that _forwards()
                * and we are just resetting the following to what it already is.
                *  There lies the loop.
                *****/

        $request->setModuleName($module);
        $request->setControllerName($controller);
        $request->setActionName($action);
        }
}

Hope that is useful. Now to go sort it in my code.

Thanks for your help,

Nick

Reply via email to