CakePHP - Как добавить / редактировать $ this-> sentArgs - PullRequest
0 голосов
/ 11 апреля 2011

У меня есть поиск с несколькими параметрами, передаваемыми через URL-адрес - город, кухня, функции и на какой странице вы находитесь (спасибо, paginator)

Если пользователь на странице 2 - ...index / page: 2 и нажимает на город "Нью-Йорк", они должны перейти на ... index / page: 2 / city: New York

Затем, если они затем нажимают на Хьюстон, они должны идтиto ... index / page: 2 / city: New York_Houston

Есть ли какой-нибудь простой / сложный способ сделать это?Я начал писать свой код, чтобы разбить $ this-> passArgs и перестроить его - но пока это было мучительно, и кажется, что я пишу кучу кода для чего-то, что, я надеюсь, Cake имеетспособ обработки.


Пример:

Пользователь находится на странице 2 списка ресторанов - индекс / страница: 2

Пользовательнажимает «Нью-Йорк», страница обновляется с индексом / страница: 2 / город: Нью-Йорк

Пользователь нажимает «Сан-Диего» - страница обновляется с индексом / страница: 2 / город: Нью-Йорк_Сан-Диего

Пользователь снова нажимает «Нью-Йорк» (чтобы его отключить), страница обновляется с индексом / страница: 2 / город: Сан-Диего


Моя попытка создатьсписок ссылок на города, которые будут выполнять переключение такого типа:

Самая большая проблема не в том, что я не могу это сделать (код ниже работает), но 1) он не учитываетдля любых других вариантов запросов, таких как страница, кухня, функции ... и т. д. - и 2) мне кажется, что это ТОННА кода, чтобы сделать что-то простое.

Меня меньше беспокоит любойдействительно незначительные ошибки в коде и больше о наилучшем подходе к этой проблеме.(не стесняйтесь комментировать с любыми вопросами - мне всегда нравится слышать лучшие способы сделать что-нибудь / все).

Большое спасибо заранее за любую помощь!

$passedCities = explode("_", $this->passedArgs['city']);

foreach($cities as $city):

    $city_name = trim(ucwords(strtolower($city['City']['name'])));
    $cityExists = in_array($city_name, $passedCities);
    $queryCities = $passedCities;

    if($cityExists) {
        unset($queryCities[array_search($city_name, $queryCities)]);
    } else if($city_name != "") {
        array_unshift($queryCities, $city_name);
    }

    $urlSuffix = "";
    if(count($queryCities) > 0) {
        $urlSuffix = "city:";
        foreach($queryCities as $c) {
            $urlSuffix .= trim($c) . "_";
        }
    }

    $urlSuffix = substr($urlSuffix,0,-1);

    echo "<li>" . $this->Html->link($city_name . 
            " (" . $city[0]['count'] . ")", array($urlSuffix)) . "</li>";

endforeach;

Ответы [ 4 ]

2 голосов
/ 11 апреля 2011

Я бы поработал так, и предположим, что ваша модель называется Ресторан

Я бы сделал форму поиска типа 'Get'

echo $form->create('Restaurant',  array('type' => 'get', 'action' => 'index', 'class' => 'search-form'));
echo $form->input('city'); 
echo $form->input('cuisine');  
echo $form->input('feature');  
echo $form->end('Search'); 

В контроллере ресторана, в действии index

function index() {

    $this->redirectToNamed();
    $conditions = array();
    $params = $this->params['named'];

    if (!empty($params['city'])){
      $conditions['Restaurant.city LIKE'] = '%'.trim($params['city']).'%';
    }
    if (!empty($params['cuisine'])){
      $conditions['Restaurant.cuisine LIKE'] = '%'.trim($params['cuisine']).'%';
    }
    if (!empty($params['background'])){
      $conditions['Restaurant.feature LIKE'] = '%'.trim($params['feature']).'%';
    }
    //refill the form with args
    $this->data['Restaurant'] = $params;

    $restaurants = $this->paginate('Restaurant', $conditions);

}


function redirectToNamed() { 

    $urlArray = $this->params['url'];
    unset($urlArray['url']);

    if( !empty($urlArray) ){
        $this->redirect($urlArray, null, true);
    }
}

Если я ничего не забуду, ваша поисковая форма останется заполненной предыдущими параметрами.

1 голос
/ 11 апреля 2011

Может быть, вы могли бы сохранить массив с выбранными городами в пользовательской сессии. Можно записывать данные в сеанс с использованием компонента сеанса. Загляните в соответствующую главу CakeBook .

Хранение городов в массиве вместо URL имеет то преимущество, что вам не нужно разбивать строку поиска.

0 голосов
/ 11 апреля 2011

Я бы создал Helper, у которого есть функция, которая создает ссылку (я бы назвал их «фильтрами», кажется более подходящим). Для этой функции я бы передал список элементов (города, кухня, особенности и т. Д.) И копию переменной sentArgs (я не совсем уверен, могут ли помощники напрямую обращаться к passArgs):

функция createFilters ($ elements, $ copyPassedArgs, $ filterName) {

идея этой функции заключается в создании ссылок, как вы делали это в своем примере, просто немного измените свой код:

/*$urlSuffix = "";
if(count($queryCities) > 0) {
    $urlSuffix = "city:";
    foreach($queryCities as $c) {
        $urlSuffix .= trim($c) . "_";
    }
    $urlSuffix = substr($urlSuffix,0,-1);
}*/

$filter = implode("_",$queryCities);

echo "<li>" . $this->Html->link($city_name . 
        " (" . $city[0]['count'] . ")", array_merge($copyPassedArgs,array($filterName => $filter)) . "</li>";

вам, вероятно, потребуется изменить этот код, но основная идея:

  • используйте взвод вместо foreach.
  • используйте array_merge, чтобы объединить передаваемые значения и значения, которые вы хочу поменять по ссылке

удачи!

0 голосов
/ 11 апреля 2011

Я отвечу без ответа.

Для меня кажется, что изменение города похоже на выполнение нового поиска, поэтому после этого я покажу страницу 1. Кроме того, потому что, изменяя параметры поиска, вы, вероятно, не будете иметь одинаковое количество страниц. Что будет, если пользователь был на странице 6, изменил параметры, а поиск вернул только 4 страницы?

...