rAVi
rAVi

Reputation: 164

Dispatch a Controller's Action on ZF2 route not found exception

I want want dispatch another controller action when Zf2 raise route not found exception to display my custom page ( i dont want to display a custom error page). I am working on dynamic url from database in Zf2 which will occur only when route not found. i added a event in bootstrap function

$event->attach('route', array($this, 'loadConfiguration'), 2);

in loadConfiguration function i added to load

public function loadConfiguration(MvcEvent $e){
    $application   = $e->getApplication();
    $sm = $application->getServiceManager();
    $router = $sm->get('router');
    $request = $sm->get('request');
    $matchedRoute = $router->match($request);
if (null == $matchedRoute) { 
        $request_uri = $e->getRequest()->getrequestUri();
        $dbAdaptor = $e->getApplication()->getServiceManager()->get('Zend\Db\Adapter\Adapter');
        $url_table = new UrlMappingTable($dbAdaptor);
        $url_data = $url_table->find($request_uri);
        $controller = $url_data['controller'];
        $action = $url_data['action'];
        $id = $url_data['post_id'];
        $original_url = $url_data['original_url'];
        $alias = $sm->get('Application\Router\Alias');

            $alias->setNavigation($original_url);

        if(isset($url_data)){
        $url = $e->getRouter ()->assemble (array('controller' => $controller,
                                                     'action' => $action ,
                                                      'id' => $id,
                                              ), array (
                                            'name' => 'myurl'
                                            ) );
       }

 print 'no route match';
 }
}

after getting the controller and action i just want the dispatcher to forward this controller.

Upvotes: 0

Views: 1781

Answers (2)

lawrenceshen
lawrenceshen

Reputation: 61

I needed something similar for my project. I ended up just adding a 'catchall' rule in module.config.php

i.e.

'router' => array(
    'routes' => array(
         'catchAll' => array(
            'type' => 'regex',
            'options' => array(
                'regex' => '/(?<page>.+)',
                'defaults' => array(
                    'controller' => 'Project\Controller\MyController',
                    'action' => 'customPage',
                ),
                'spec' => '/%page%',
            ), 
        ),
        //Other route items ...
    ),
    //Other stuff ...
)

Place this as the first item in the routes array so it has the lowest precedence. Then you can have your customePageAction to do whatever you want!

Upvotes: 1

Jurian Sluiman
Jurian Sluiman

Reputation: 13558

Just something not really answering your question:

I am working on dynamic url from database in Zf2 which will occur only when route not found.

There are two ways you can achieve this much more efficiently. If there aren't much routes, you can load them before the route event. For example, you query on bootstrap all your database routes and inject them into the route stack.

Another way is creating a "catch all" route which always will match after all routes failed. Then you don't have a "route not found" but your default route is matched. This will then look for a matching database record. If none found, you just return a 404 response.

In case #1, the controller mapped by your database route is directly dispatched. In the second case, you are in your "database controller" and want to dispatch your controller mapped by the database route, you use the forward plugin:

public function matchAction()
{
    // Fetch route from db here

    if (!$match) {
        $this->getResponse()->setStatusCode(404);
        return;
    }

    return $this->forward($match->getController, array(
        'action' => $match->getAction()
    ));
}

Upvotes: 0

Related Questions