Работа с префиксами и Zend_Controller_Router_Route
На существующем веб-сайте Zend Framework с несколькими контроллерами и без модулей мне нужно добавить некоторые префиксы к маршрутам по умолчанию.
Например, у меня в настоящее время есть:
/products
/products/id/1
/training
/commonpage
Я хочу добавить уровень линейки продуктов, не дублируя мои контроллеры в x-модулях (я просто запрошу правильную линейку продуктов внутри моих контроллеров с помощью _getParam
).
Итак, мои новые пути будут:
/line1/products
/line1/products/id/1
/line2/training
/commonpage
То, что я пробовал до сих пор, - это маршрут (расположенный в моем файле Bootstrap):
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) . ')')
));
}
Но без всякого успеха (это дает мне 404).
Как я могу создать один маршрут, соответствующий всем uri в этих условиях:
- Префикс uri соответствует значению в массиве моих продуктов
- Маршрут действителен только в том случае, если запрошенный контроллер разрешен для доступа по "линейке продуктов" - массивом, содержащим имена моих контроллеров, например
UPDATE
Хорошо мне удалось очень близко понять, что я пытаюсь сделать с этим кодом:
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')) . ')'
)
));
}
С этим я могу получить доступ /line1/products
, но не /line1/commonpage
, что я и хочу - поэтому ограничение контроллера работает отлично. Как вы можете видеть, я добавляю имя продуктовой линейки в Zend Registry, поэтому он сохраняется, когда я использую помощник просмотра URL в шаблонах (таким образом мне не нужно редактировать все мои шаблоны, чтобы добавить параметр линейки продуктов в моем помощнике вызовы).
Теперь у меня проблема в этом помощнике: кажется, что ограничение моего контроллера просто игнорируется. Когда я делаю это в своем шаблоне:
<a href="<?php echo $this->url(array('controller'=> 'commonpage', 'action'=>'index'),null, true) ; ?>">My link</a>
В итоге я получаю следующее:
<a href="/line1/commonpage">My link</a>
Итак, добавлена линейка продуктов, несмотря на то, что это ограничение не допускается ограничением контроллера моего маршрута.
Ответы
Ответ 1
Хорошо. Я нашел решение: я изменил URL-помощник, чтобы добавить в него ограничение контроллера. Если контроллер не соответствует массиву "контроллеров линейных рядов", он заставляет assemble
использовать маршрут по умолчанию (не идеально, но он работает для меня):
public function url(array $urlOptions = array(), $name = null, $reset = false, $encode = true, $default = false)
{
$router = Zend_Controller_Front::getInstance()->getRouter();
if(isset($urlOptions['controller']) && !in_array($urlOptions['controller'], array('products', 'training'))) {
$name = 'default';
}
return $router->assemble($urlOptions, $name, $reset, $encode);
}
Ответ 2
вы можете добавить/изменить определенный маршрут с помощью файла ini params:
resources.router.routes.job_en.route = "/prefix/:request-offer"
resources.router.routes.job_en.defaults.module = "core"
resources.router.routes.job_en.defaults.controller = "engine"
resources.router.routes.job_en.defaults.action = "main"
где job_en
- это имя моего маршрута и request-offer
имя параметра