-- Laurent Melmoux <[EMAIL PROTECTED]> wrote
(on Tuesday, 18 December 2007, 01:36 PM +0100):
> I’m using the preDispatch() method in a controller to detect if the 
> action is called from a _forward() .
>
> public function preDispatch()
> {
> if ($this->getRequest()->isDispatched()) {
> $this->_isForward = true;
> }
> }
>
>
> But no matter from where I’m calling the action, directly or via 
> _forward(), $this->getRequest()->isDispatched() always return true.

That's correct -- because the flag is toggled prior to preDispatch()
being called.

The dispatch loop is a do/while loop -- it is meant to run at least
once, and checks at the end of each iteration to determine if another
iteration is necessary. It does so by checking to see if isDispatched()
is false. At the top of the loop, it then sets the flag to true -- which
allows plugin and controller preDispatch() methods to toggle the flag
and skip the current action.

> What is strange, is that it seems it was working a few svn versions ago… 
> But now I’m not sure.

Nope -- this has been this way since the request object was introduced;
if you had it working, you must have introduced something in your
dispatch cycle that was toggling it.

> Is there a bug? Or am I not using a good strategy to detect a
> _forward()?

At this point, there's no way to detect if an action is called as the
result of a _forward(); each iteration of the loop is basically
autonomous.

What you *can* do, however, is to use a plugin that runs at
dispatchLoopStartup() to store the original request state into the
registry; you could then check against that to see if the current
request matches the original; if it doesn't, you'd have detected a
_forward() condition.

As an example:

    class ForwardDetection extends Zend_Controller_Plugin_Abstract
    {
        protected static $_request;

        public function dispatchLoopStartup(Zend_Controller_Request_Abstract 
$request)
        {
            self::$_request = clone $request;
        }

        public static function isForward(Zend_Controller_Request_Abstract 
$request)
        {
            if ((self::$_request->getModuleName() != $request->getModuleName())
                || (self::$_request->getControllerName() != 
$request->getControllerName())
                || (self::$_request->getActionName() != 
$request->getActionName()))
            {
                return true;
            }

            return false;
        }
    }

Then, in your preDispatch() actions, you could do this code:

    if (ForwardDetection::isForward($this->getRequest()) {
        // _forward detected
    }

Hope that helps. :-)

-- 
Matthew Weier O'Phinney
PHP Developer            | [EMAIL PROTECTED]
Zend - The PHP Company   | http://www.zend.com/

Reply via email to