How check if action exsist in Controller Plugin preDispatch

1.8k views Asked by At

I have two modules (default and mobile) the module mobile is a rewrite the default portal in jquery mobile but with much less controllers and actions! I thought of write a controller plugin that check if controller and action exist in module mobile, if not I would like overwrite the module mobile to default. I try this:

public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
{
    $dispatcher = Zend_Controller_Front::getInstance()->getDispatcher();
    if ($request->getModuleName() == 'mobile') {      
        if (!$dispatcher->isDispatchable($request)) {
            // Controller or action not exists
            $request->setModuleName('default');
        }
    }
    return $request;
}

but $dispatcher->isDispatchable($request) return always true though the action not exist! :S and i receive "Action foo does not exist and was not trapped in __call()"

How can I do? Thanks

2

There are 2 answers

3
liyakat On

Have you ever wondered how to check if a controller/action exist in zend FM from any side of app ? Here is the code

    $front = Zend_Controller_Front::getInstance();
    $dispatcher = $front->getDispatcher();

    $test = new Zend_Controller_Request_Http();
    $test->setParams(array(
        'action' => 'index',
        'controller' => 'content',

            )
    );

    if($dispatcher->isDispatchable($test)) {
        echo "yes-its a controller";
        //$this->_forward('about-us', 'content'); // Do whatever you want
    } else {
        echo "NO- its not a Controller";
    }

EDIT

Check like this way

$classMethods = get_class_methods($className);
 if(!in_array("__call", $classMethods) &&
 !in_array($this->getActionMethod($request), $classMethods))
 return false;

and also please see detail link

4
Ivan Hušnjak On

I would suggest you make a static or dynamic routes either via config resource manager, bootstrap or via front controller plugin:

Example of defining static routes in Bootstrap.php:

public function _initRoutes()
{
    $front = Zend_Controller_Front::getInstance();
    $router = $front->getRouter(); // default Zend MVC routing will be preserved

    // create first route that will point from nonexistent action in mobile module to existing action in default module
    $route = new Zend_Controller_Router_Route_Static(
        'mobile/some-controller/some-action', // specify url to controller and action that dont exist in "mobile" module
        array(
            'module' => 'default', // redirect to "default" module
            'controller' => 'some-controller',
            'action' => 'some-action', // this action exists in "some-controller" in "default" module
        )
    );
    $router->addRoute('mobile-redirect-1', $route); // first param is the name of route, not url, this allows you to override existing routes like default route

    // repeat process for another route
}

This would effectively route request for /mobile/some-controller/some-action to /default/some-controller/some-action

some-controller and some-action should be replaced with proper controller and action names.

I was using static routing which is ok if you route to exact urls, but since most applications use additional params in url for controller actions to use, it is better to use dynamic routes.
In above example simply change route creation class to Zend_Controller_Router_Route and route url to "mobile/some-controller/some-action/*" and every request will be routed dynamically like in example:

/mobile/some-contoller/some-action/param1/55/param2/66 
will point to 
/default/some-controller/some-action/param1/55/param2/66

For more info about routing in ZF1 check this link