On an existing Zend Framework website with few controllers and no modules I need to add some prefixes to the default routes.
For example, I currently have :
/products
/products/id/1
/training
/commonpage
I want to add a product line level, without duplicating my controllers in x modules (I'll just request the right product line inside my controllers with _getParam
).
So my new paths will be :
/line1/products
/line1/products/id/1
/line2/training
/commonpage
What I tried so far is this route (located in my Bootstrap file) :
protected function _initRoutes()
{
$router = Zend_Controller_Front::getInstance()->getRouter();
$router->addRoute('productLineRoute', new Zend_Controller_Router_Route(
':line/:controller/:action',
array('module' => 'default'),
array('line' => '(' . implode('|', Zend_Registry::getInstance()->constants->lines) . ')')
));
}
But without any success (it gives me a 404). How can I build a single route that match all uri under those conditions :
- The prefix of the uri match a value in my product lines array
- The route is valid only if the controller requested is allowed to be accessed in a "product line way" - by an array containing the names of my controllers for example
UPDATE
Ok I managed to get really close of what I'm trying to do with this code :
protected function _initConstants()
{
$registry = Zend_Registry::getInstance();
$registry->constants = new Zend_Config( $this->getApplication()->getOption('constants') );
$uri = ltrim($_SERVER['REQUEST_URI'], '/');
$product_line = substr($uri, 0, strpos($uri, '/'));
if(!empty($product_line) && in_array($product_line, Zend_Registry::getInstance()->constants->lines->toArray()) &&
$product_line != Zend_Registry::getInstance()->constants->lines->get(0)) {
$registry->product_line = $product_line;
} elseif(!isset($registry->gamme)) {
$registry->product_line = Zend_Registry::getInstance()->constants->lines->get(0);
}
}
protected function _initRoutes()
{
$router = Zend_Controller_Front::getInstance()->getRouter();
$registry = Zend_Registry::getInstance();
$router->addRoute('productLineRoute', new Zend_Controller_Router_Route(
':line/:controller/:action/*',
array(
'module' => 'default', 'action' => 'index',
'line' => (isset($registry->product_line)) ? $registry->product_line : Zend_Registry::getInstance()->constants->lines->get(0)
),
array(
'line' => '(' . implode('|', Zend_Registry::getInstance()->constants->lines->toArray()) . ')',
'controller' => '(' . implode('|', array('products', 'training')) . ')'
)
));
}
With that I can access /line1/products
but not /line1/commonpage
, which is what I want - so the controller constraint is working great. As you can see I add the product line name in the Zend Registry, so it is saved when I use the URL View Helper in templates (that way I don't have to edit all my templates to add the product line parameter in my helper calls).
The problem I have now is about this helper : it seems that my controller constraint is just get ignored. When I do this in my template:
<a href="<?php echo $this->url(array('controller'=> 'commonpage', 'action'=>'index'),null, true) ; ?>">My link</a>
I end up with this :
<a href="/line1/commonpage">My link</a>
So the product line is added, despite of the fact that this is not allowed by the controller constraint of my route.