Issues

ZF-8830: Zend_Navigation_Page_Mvc::isActive() produces false-negatives when coupled with custom routes

Description

According to [http://framework.zend.com/manual/en/…], navigation items using custom routes should include the module, controller, and action so that Zend_Navigation_Page_Mvc::isActive() can tell if a page is active or not. The problem that occurs from this is that the router's assemble() method will break the route by unnecessarily appending the module, controller, and action, even if the route is not supposed to display them.

For example, a route like:


new Zend_Controller_Router_Route(':uniqueId/edit/:level',
    array(
        'controller'    => 'users',
        'action'        => 'edit',
        'module'        => 'admin'
    ), array(
        'uniqueId'      => (\d+),
        'level'         => '(admin|user|editor|foo)'
    ))

And a navigation page like:


$config['admin']['pages'][$uniqueId] = array(
    'label'         => 'Editing ' . $userName,
    'module'        => 'admin',
    'controller'    => 'users',
    'action'        => 'edit',
    'route'         => 'adminEditUser',
    'params'        => array(
        'uniqueId'      => $uniqueId,
        'level'         => $level,
    )
)

Would produce a url:


/12345/edit/foo/module/admin/controller/users/action/edit

When the expected url should be:


/12345/edit/foo

Attached is a patch that looks at the route provided to the navigation page, checks to see if the front controller's router has the route, and if it does it will use the module, controller, and action from that route if the module, controller, and action were not provided as part of the configuration for the navigation page. This takes care of Zend_Navigation_Page_Mvc::isActive() not being able to recognize a page as active, and it removes the requirement of having to provide the module, controller, and action to the navigation configuration.

Comments

A unit-test for this bug is here: http://pastie.org/1886460 The patch fixes the problem.

I did not expect a 16 month old issue to be a duplicate of my issue (ZF-11359), but at close inspection, it is. However, I think ZF-8438 is not a duplicate, and I think it is already fixed, but I'm not sure about this.

It is the same problem and the current issue (ZF-8830) is not solved. Your unit test is a plus and always welcome! :-)

Tests:


public function testHrefGeneratedIsRouteAwareWithVariablePrefix()
{
    $page = new Zend_Navigation_Page_Mvc(array(
        'label'  => 'foo',
        'route'  => 'myroute',
        'params' => array(
            'id'   => 1337,
            'page' => 'baz',
        )
    ));

    $this->_front->getRouter()->addRoute(
        'myroute',
        new Zend_Controller_Router_Route(
            ':id/foobar/:page',
            array(
                'module'     => 'default',
                'controller' => 'foobar',
                'action'     => 'bazbat',
                'id'         => 1,
                'page'       => 'foo',
            ),
            array(
                'id'   => '(\d+)',
                'page' => '(foo|bar|baz|bat)'
            )
        )
    );

    $this->assertEquals('/1337/foobar/baz', $page->getHref());
}

public function testHrefGeneratedIsRouteAwareWithVariablePrefixWithoutParams()
{
    $page = new Zend_Navigation_Page_Mvc(array(
        'label' => 'foo',
        'route' => 'myroute',
    ));

    $this->_front->getRouter()->addRoute(
        'myroute',
        new Zend_Controller_Router_Route(
            ':id/foobar/:page',
            array(
                'module'     => 'default',
                'controller' => 'foobar',
                'action'     => 'bazbat',
                'id'         => 1,
                'page'       => 'foo',
            ),
            array(
                'id'   => '(\d+)',
                'page' => '(foo|bar|baz|bat)'
            )
        )
    );

    $this->assertEquals('/1/foobar', $page->getHref());
}