Работа с префиксами и 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 имя параметра