понедельник, 10 декабря 2012 г.

[Ko3.2] Работа метода Request->uri()

В версии 3.2 разработчики поменяли поведение метода Request->uri(). В 3.0-3.1 этот метод позволял получить «соседний» URI с применением небольших изменений, например:




// пусть текущий адрес: /articles/page1/
// мы хотим получить ссылку /articles/page2/
$uri = $this->request->uri(array('page' => 2));

В 3.2+ этот номер уже не прокатит. Сейчас $this->request->uri() игнорирует переданные параметры, и возвращает текущий URI. Разработчики предлагают использовать $this->request->route(), что в принципе логично. Однако есть небольшое НО — этот метод не подставляет текущие параметры объекта Request, он просто о них не знает. Т.е. нам надо передавать туда все параметры явно, а это очень большая конструкция:


$uri = $this->request->uri(
    array('page' => 2) +
    $this->request->param() +
    array(
        'directory' => $this->request->directory(),
        'controller' => $this->request->controller(),
        'action' => $this->request->action(),
    )
);

Помните, что $this->request->param() вернет не все сегменты. Значения directory/controller/action хранятся в отдельных свойствах и имеют свои методы-геттеры.
Громоздко, ага. Давайте воспользуемся возможностями Каскадной Файловой Системы Kohana и сделаем мир удобнее:
1. Копируем файл SYSPATH/classes/request.php в APPPATH/classes/.
2. Добавляем туда новое содержимое метода uri():


public function uri(array $params = null) 
{
    if ($params === NULL)
    {
        return parent::uri();
    }
 
    $params += $this->_params + array(
        'directory'   => $this->_directory,
        'controller'  => $this->_controller,
        'action'      => $this->_action,
    );
 
     return $this->_route->uri($params);
}

Вуаля! Теперь можно использовать $this->request->uri() как для получения текущего URI, так и для быстрого reverse-routing на базе текущих параметров:


$uri = $this->request->uri(); // текущий адрес
$uri = $this->request->uri(array('action' => 'test')); // меняем в URI текущий экшен на action_test()

Обратите внимание, что новый метод uri() применяет ВСЕ текущие значения объекта Request. Таким образом, если мы меняем только экшен, то все остальные параметры останутся прежними, в том числе и те, которые в роуте шли после экшена. Например, при текущем адресе foo/bar/123, вызов $this->request->uri(array('action' => 'baz')) вернет строку ‘foo/baz/123‘, а не ‘foo/baz‘.

Комментариев нет:

Отправить комментарий