Question

Currently I have a REST route working for an Event controller (/event). I would like to handle Event SignUps in an EventSignUp controller, and map this controller to a /event/signups route.

The Zend Framework documentation states that the URL /event/signup/:id should map to an Event_SignupController. But this does not work for me.

I set up the default REST route for all controllers in my Bootstrap class:

$front = Zend_Controller_Front::getInstance();
$router = $front->getRouter();

// Specifying all controllers as RESTful:
$restRoute = new Zend_Rest_Route($front);
$router->addRoute('default', $restRoute);

Am I missing something or is the documentation just wrong? If the documentation is wrong, what approach should I take to achieve my desired goal?

As a side note, a lot of existing controllers rely on the default REST route, so it would be nice if there is a solution that does not require to implement new routes for all existing controllers.

Edit: The documentation states that /product/ratings will be translated to the Product_RatingsController, which means the RatingsController in the Products module. Because all my controllers are placed in the default module, my desired behavior is not supported by the Rest Route.

So this changes my question, is it possible to achieve my desired behavior without affecting the existing controllers dependency on the default Rest route? If so, how? And if not, what would be the best approach for me to take?

Was it helpful?

Solution

Based on the comments of Haim Evgi I created a controller plugin that adds Zend_Controller_Router_Route routes based on the request method. This is the code of that controller plugin:

class TW_Webservice_Controller_Plugin_RestRoutes extends Zend_Controller_Plugin_Abstract
{

    /**
     *
     * @var Zend_Controller_Router_Interface
     */
    public $router;

    /**
     * Setup Rest routes that are not handled by the default Zend_Rest_Route object.
     *
     * @param Zend_Controller_Request_Abstract $request
     */
    public function routeStartup(Zend_Controller_Request_Abstract $request)
    {
        $front = Zend_Controller_Front::getInstance();
        $this->router = $front->getRouter();

        $method = strtolower($request->getMethod());
        $restRoutes = array(
            '/event/signup' => 'event-signup'
        );

        $this->addRoutes($method, $restRoutes);
    }

    /**
     *
     * @param string $method The request method
     * @param array $restRoutes Router pattern => Controller name pairs
     */
    public function addRoutes($method, $restRoutes)
    {
        foreach ($restRoutes as $routePattern => $controllerName) {
            switch ($method) {
                case "get":
                    $this->addGetRoutes($routePattern, $controllerName);
                    break;
                case "post":
                    $this->addPostRoute($routePattern, $controllerName);
                    break;
                case "put":
                    $this->addPutRoute($routePattern, $controllerName);
                    break;
                case "delete";
                    $this->addDeleteRoute($routePattern, $controllerName);
                    break;
            }
        }
    }

    /**
     *
     * @param string $routePattern
     * @param string $controllerName 
     */
    public function addGetRoutes($routePattern, $controllerName)
    {
        $this->addRestRoute($routePattern, $controllerName, 'index');

        $routePattern = $routePattern . '/:id';
        $this->addRestRoute($routePattern, $controllerName, 'get');
    }

    /**
     *
     * @param string $routePattern
     * @param string $controllerName 
     */
    public function addPostRoute($routePattern, $controllerName)
    {
        $this->addRestRoute($routePattern, $controllerName, 'post');
    }

    /**
     *
     * @param string $routePattern
     * @param string $controllerName 
     */
    public function addPutRoute($routePattern, $controllerName)
    {
        $routePattern = $routePattern . '/:id';
        $this->addRestRoute($routePattern, $controllerName, 'put');
    }

    /**
     *
     * @param string $routePattern
     * @param string $controllerName 
     */
    public function addDeleteRoute($routePattern, $controllerName)
    {
        $routePattern = $routePattern . '/:id';
        $this->addRestRoute($routePattern, $controllerName, 'delete');
    }

    /**
     *
     * @param string $routePattern
     * @param string $controllerName
     * @param string $action
     */
    public function addRestRoute($routePattern, $controllerName, $action)
    {
        $route = new Zend_Controller_Router_Route($routePattern, array(
            'controller' => $controllerName,
            'action' => $action
        ));

        $this->router->addRoute($controllerName . '-' . $action, $route);
    }

}

It would be nicer if the $restRoutes array is retrieved from a config file, but for now this works.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top