ZF-1734: Incorrect redirecting with $redirector->goto(null,null,'modulename');

Description

I have a $this->_redirector->goto(null,null,'admin'); inside my Admin_ClassController->viewAction() ... What is expected to happen here is for the page to redirect to http://example.com/admin but it goes to http://example.com/admin/class instead. Granted, you can do a $this->_redirector->goto(null,'index','admin'); but then you get http://example.com/admin/index (I'd prefer to not have the extra /index on the end).

Looks like a problem in Zend_Controller_Action_Helper_Redirector->setGoto(); ...


if (null === $controller) {
    $controller = $request->getControllerName();
    if (empty($controller)) {
        $controller = $dispatcher->getDefaultControllerName();
    }
}

should be:


if (null === $controller) {
    if (null !== $action) {
        $controller = $request->getControllerName();
        if (empty($controller)) {
            $controller = $dispatcher->getDefaultControllerName();
        }
    }
}

The addition checks to see if the $action was set, THEN we can get the controller name if $controller was not set - otherwise leave $controller as null. I tested this change in my application and the problem was solved.

This also keeps the functionality consistent as you can now do $this->_redirector->goto(null); and be redirected to the current module index rather than the controller you are currently in.

UPDATE: I have found another problem here... When doing a $this->_redirector->goto(null,null,'default'); you end up with the URL http://example.com/default instead of the plain old http://example.com/. This is also the case when doing something like $this->_redirector->goto('login','account','default'); you will end up getting the URL http://example.com/default/account/login instead of http://example.com/account/login.

Here is the change to fix this issue (separate from the issue above). This code:


if (null === $module) {
    $module = $request->getModuleName();
    if ($module == $dispatcher->getDefaultModule()) {
        $module = '';
    }
}

Should be:


if (null === $module) {
    $module = $request->getModuleName();
}
        
if ($module == $dispatcher->getDefaultModule()) {
    $module = '';
}

This fixes the issues I am having with it. Comments anyone?

Comments

Assigning to [~matthew] to initiate issue review.

The redirector helper does not support null values for the $action parameter; you need to provide the action.

The problem is exists even if you don't use null.

Say, for example, that you want to redirect to /default/index/index. If you want to write the redirection so it works from other modules also, you will write:

 
$this->_helper->redirector('index', 'index', 'default');

(as opposed to leaving out the third argument)

This will cause a redirection to "/default" instead of to "/" (redundant action and controller names get hidden, but the redundant module remains).

Please change:

 
        if (null === $module) {
            $module = $request->getModuleName();
            if ($module == $dispatcher->getDefaultModule()) {
                $module = '';
            }
        }

to:

 
        if (null === $module) {
            $module = $request->getModuleName();
        }
        if ($module == $dispatcher->getDefaultModule()) {
            $module = '';
        }

since assigning the current module if it's null, and omitting the redundant module name (whether determined automatically or specified explicitly) are two separate actions.

Jaka

Fixed in trunk and merged to 1.6 release branch.

Updating for the 1.6.0 release.