I am having problem with adding custom routing into my application. Zend Framework 1:
I have already working application with default Zend routing. I have a lot of controllers and for some of them I want to use friendly urls, for example: domain.com/cities/edit/id/3 to domain.com/cities/edit/abu-dhabi
There are some controllers to switch into that url (in that format).
I tried to configure it by ini file:
resources.router.routes.slugurl.route = /:controller/:action/:slug
And also by Bootstrap method:
protected function _initSlugRouter()
{
$this->bootstrap('FrontController');
$router = $this->frontController->getRouter();
$route = new Zend_Controller_Router_Route('/:controller/:action/:slug/',
array(
'controller' => 'slug',
'action' => 'forward',
'slug' => ':slug'
)
);
$router->addRoute('slug',$route);
}
The main problem - with ini configuration - request goes directly to controller city (not slug). Second one (bootstrap) - also executes the city controller, but the default routing not working as it was, I am not able to execute: domain.com/cities/ but domain.com/cities/index/ works. The error without action defined:
Action "forward" does not exist and was not trapped in __call()
I can monitor the "slug" in controllers/move check into some library, but I would like to do it only with routing - that way looks much better for me.. Please, how to solve that issue?
edit with summary of solution Thank you Max P. for interesting. I solved it at last - in last 2 minutes:) I had wrong rules at application.ini with routing. Right now it is defined that:
resources.router.routes.slugurl.route = /:controller/:action/:slug
resources.router.routes.slugurl.defaults.controller = :controller
resources.router.routes.slugurl.defaults.action = :action
resources.router.routes.slugurl.defaults.slug = :slug
The controller is defined like that:
class CitiesController extends Crm_Abstract
The Crm_Abstract has code:
<?php
class Crm_Abstract extends Zend_Controller_Action {
public function __construct(\Zend_Controller_Request_Abstract $request, \Zend_Controller_Response_Abstract $response, array $invokeArgs = array()) {
$params = $request->getParams();
if (!empty($params['slug'])) {
$modelSlug = Crm_Helper_Slug::getInstance();
$parameters = $modelSlug->redirectRequest($request);
if ($parameters !== false) {
foreach ($parameters as $key => $value) {
$request->setParam($key, $value);
}
}
}
parent::__construct($request, $response, $invokeArgs);
}
public function __call($methodName, $args) {
parent::__call($methodName, $args);
}
}
The slug helper get parameters for slug at defined controller. The url to access the slug is defined/calculated in place of $this->url - to $this->slug and there rest of code is done in slug helper. I am not sure if my solution is 100% sure, because that is my first time with routing.
The major thing is that - I just needed to change Zend_Controller_Action to Crm_Abstract which extends the Zend_Controller_Action. Single line - no additional custom code in each controller.
resources.router.routes.slugurl.route = /:controller/:action/:slugresources.router.routes.slugurl.defaults.controller = :controllerresources.router.routes.slugurl.defaults.action = :actionresources.router.routes.slugurl.defaults.slug = :slugI am unable to access url: domain.com/developers/ - error code: Action "action" does not exist and was not trapped in __call() - It looks like adding that route rule - destroys default routing, but I want it keep. - Mik