user1409508
user1409508

Reputation: 623

ZF2 child routes- ajax doesn't return correct route name

I have weird(in my opinion) problem with Zend Framework 2. After I call my ajax function route name is not correct.
Here is a part of my routing:

        'ajax' => array(
            'type'    => 'Literal',
            'options' => array(
                'route'    => '/ajax',
                'defaults' => array(
                    '__NAMESPACE__' => 'Application\Controller',
                    'controller'    => 'Index',
                    'action'        => 'ajax',
                ),
            ),
            'may_terminate' => true,
            'child_routes' => array(
                'subcategory' => array(
                    'type'    => 'Segment',
                    'options' => array(
                        'route'    => '/[:name][/:page]',
                        'constraints' => array(
                            'name' => '[a-zA-Z][a-zA-Z0-9_-]*',
                            'page' => '[0-9]+',
                        ),
                        'defaults' => array(
                        ),
                    ),
                ),
                'category' => array(
                    'type'    => 'Segment',
                    'options' => array(
                        'route'    => '/[:name][/:page]',
                        'constraints' => array(
                            'name' => '[a-zA-Z][a-zA-Z0-9_-]*',
                            'page' => '[0-9]+',
                        ),
                        'defaults' => array(
                        ),
                    ),
                ),
            ),
        ),

Part of my controller code

public function categoryAction()
{
    $route['route_name'] = 'category';
    $view =  new ViewModel($route);
    $view->setTemplate('application/index/category');

    return $view;
}


public function subcategoryAction()
{
    $route['route_name'] = 'subcategory';
    $view =  new ViewModel($route);
    $view->setTemplate('application/index/category');

    return $view;
}


public function ajaxAction()
{
    $route = $this->getEvent()->getRouteMatch()->getMatchedRouteName();

    var_dump($route); // return always last child route from config
}

category.phtml, there is code of my form, I'll show just url of ajax request

<input type="hidden" name="url" value="<?php echo $this->url('ajax/'.$this->route_name, array('name' => $this->route_param , 'page' =>$this->pages['current'])); ?>">

So, as you can see I pass variable with name of child route from action to view, then my url looks like this:

$this->url('ajax/'.$this->route_name, array(...))

When I am at domain.com/category my ajax url is:

$this->url('ajax/category', array(...))

When I am at domain.com/subcategory my ajax url is:

$this->url('ajax/subcategory', array(...))

Here is come the weird part. As you can see above my ajax action get current route name. It doesn't matter if request is send from domain.com/subcategory or from domain.com/category a value is always a last child of route.
In this example value of

$route = $this->getEvent()->getRouteMatch()->getMatchedRouteName();

is always

string 'ajax/category' (length=13)

Shouldn't I get route name depends on $this->url() parameters? If so, how can I get this?
I have read http://framework.zend.com/manual/2.2/en/modules/zend.mvc.routing.html and I don't see any info about returning last child name of child routes.

Upvotes: 0

Views: 481

Answers (1)

SmasherHell
SmasherHell

Reputation: 884

category and subcategory have the same pattern, so the router is unable to find the correct route name when fetching requested url and return always the last entry found (Last In First Out), when calling url plugin to build an url, you do not have this issue because you name the route you want to build.

If you want to have the same url to request category and subcategory you have to find another way to differenciate them, when passing name parameter for example.

By the way you can easily overcome this by setting you conf :

            'subcategory' => array(
                'type'    => 'Segment',
                'options' => array(
                    'route'    => '/subcategoy/[:name][/:page]',
                    'constraints' => array(
                        'name' => '[a-zA-Z][a-zA-Z0-9_-]*',
                        'page' => '[0-9]+',
                    ),
                    'defaults' => array(
                    ),
                ),
            ),
            'category' => array(
                'type'    => 'Segment',
                'options' => array(
                    'route'    => '/category/[:name][/:page]',
                    'constraints' => array(
                        'name' => '[a-zA-Z][a-zA-Z0-9_-]*',
                        'page' => '[0-9]+',
                    ),
                    'defaults' => array(
                    ),
                ),
            ),

In your code current state your url will be generated correctly, and your routes will be correctly detected.

Upvotes: 0

Related Questions