CakePHP - построение поиска - как включить переменные URL в запрос - PullRequest
0 голосов
/ 10 апреля 2011

Я создаю страницу поиска, которая будет иметь много различных параметров поиска, по которым пользователь может щелкнуть, и которые передадут переменные в URL.

$this->Restaurant->recursive = 1;
$this->paginate = array(
    'conditions' => array(
        'City.name' => $this->params['url']['city'],
        'Cuisine.name' => $this->params['url']['cuisine'],
    ),
);
$data = $this->paginate('Restaurant');
$this->set('data', $data);

Это прекрасно работает, если в URL есть? City = newyork & kitchen = pizza - но если нет, то это выдает ошибку * Если бы это был обычный PHP, я бы выстроил запрос в виде строки и добавил бы условия, только если переменные существовали ... и т. д. Но с Cake я не уверен, с чего начать или как лучше всего с этим справиться.

EDIT:

* Если я не передаю 'city' или 'kitchen' в качестве переменных URL, я получаю следующее:

<code><b>Notice</b> (8)</a>: Undefined index:  city [<b>APP/controllers
/restaurants_controller.php</b>, line <b>18</b>

...

City.name'&nbsp;=&gt;&nbsp;$this-&gt;params['url']['city'],
</span></code></span>
RestaurantsController::search() - APP/controllers/restaurants_controller.php
, line 18
Dispatcher::_invoke() - CORE/cake/dispatcher.php, line 204
Dispatcher::dispatch() - CORE/cake/dispatcher.php, line 171
[main] - APP/webroot/index.php, line 83

Не было бы проблем, если бы у меня были только «город» и «кухня» - но если я планирую, чтобы еще 20 вариантов поиска передавались таким же образом, я бы хотел их пропустить или не по моему усмотрению вместо того, чтобы заставлять их ВСЕ в URL каждый раз.

Ответы [ 2 ]

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

торт использует шаблон MVC, означает, что URL-адрес, как http://localhost/controller/action/param1/param2 преобразовать в index.php? Controller = controller & action = action¶m1 = pararm1 ...

если вы не можете получить запросстрока из исходного url (http://localhost/controller.../?a=3&b=2) вы должны добавить параметр QSA в ваш .htaccess, он должен выглядеть примерно так

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [**QSA**,L]
</IfModule>

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

если вы не хотите использовать этот способ, вы можете получить параметры через действие контроллера, используя

$arg_list = func_get_args();

вместо строки запроса

это будет выглядеть примерно такчто

Controller Pages{
  public function search(){
    $args = func_get_args();
    foreach($args as $arg){
       // build query string for the search, depending on the params you got
    }
    // do search
  }

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

Что вы имеете в виду errors out?

Обычно добавление $this->Paginator->options(array('url' => $this->passedArgs)); перед вызовом разбиения на страницы в представлении заставит торт добавить все переданные параметры URL к URL, который он генерирует

EDIT

То, что вы ищете, это именованные параметры: http://book.cakephp.org/view/947/Named-parameters

Если вы посмотрите на последний пример, то увидите, что маршрут отображается на ContentsController->view();, и все параметры, которые вы (необязательно) выбрали для отправки, доступны в массиве passedArgs.

URL: /contents/view/chapter:models/section:associations
Mapping: ContentsController->view();
$this->passedArgs['chapter'] = 'models';
$this->passedArgs['section'] = 'associations';
$this->params['named']['chapter'] = 'models';
$this->params['named']['section'] = 'associations';

РЕДАКТИРОВАТЬ 2

Ваша проблема в том, что у вас есть переменный набор критериев поиска. Ваша система должна в основном пройти критерии поиска и построить поисковый запрос в зависимости от того, какие фильтры были выбраны. Есть несколько способов решить эту проблему. Проще всего было бы пройти через них.

$allowsFilters = array('city' => 'Model.city', 'name' => 'Model.name', 'price' => 'Model.price'); //list of allowed keys to search on. 
$opts  = array();
foreach ($this->params['named'] as $filter => $value)  {
    if (isset($allowsFilters[$filter])) {
         $opts[$allowsFilters[$filter]] = $value; 
    }
}
$findOpts = array('conditions' => $opts)
$this->Model->find('all', $findOpts);

Таким образом, вы вносите в белый список набор фильтров, которые можно применить. И вы перебираете параметры и создаете массив conditions. Вам придется немного изменить это, если вам нужны условия ИЛИ или другой MYSQL. Но это позволит вам иметь переменное количество фильтров.

...