Данную статью я решил написать вод воздействием ... нет, ни грибов ))) ... а много численных постов в асю и личку. Перед началом работы хочу предупредить - ВСЕ манипуляции вы делаете на свой страх и риск! Если вы новичек НЕ ЗАБУДЬТЕ сделать бекапы. Протестировано на J1.5.11. И так, приступим Все начинается с того, что Вам необходимо модифицировать стандартную форму поиска, а точнее добавить туда нужные Вам поля. Топаем в: Код (CODE): components/com_search/views/search/tmpl/default_form.php С первых строк в нем описывается форма, туда нужно добавить необходимые Вам поля. В своем примере я буду использовать два поля типа TEXT и именами param1 и param2. Код (html): <td nowrap="nowrap"> <input type="text" name="param1" id="search_param1" size="10" maxlength="20" value="<?php echo JRequest::getInt('param1'); ?>" class="inputbox" /> </td> <td nowrap="nowrap"> <input type="text" name="param2" id="search_param2" size="10" maxlength="20" value="<?php echo JRequest::getInt('param2'); ?>" class="inputbox" /> </td> После того, как поля были добавлены, Вам необходимо получить значения, введенные в эти поля. Топаем в Код (CODE): components/com_search/controller.php Строка 41, function search(): В теле функции необходимо получить значения, переданные из формы. Я передаю два числа, поэтому и обрабатываю с помощью метода getInt класса JRequest. getString - строка, getVar - общий тип данных, если так можно выразиться... Для получения других типов данных рекомендую почитать документацию. Код (PHP): $post["param1"] = JRequest::getInt('param1'); $post["param2"] = JRequest::getInt('param2'); В ассоциативном массиве $post накапливаются пары "ключ" - "значение" для формирования строки GET-запроса. Теперь настало время получить данные и сформировать sql-запрос для выборки. Топаем в Код (CODE): component/com_search/models/search.php строка 62, конструктор (function __construct()), получаем наши параметры Код (PHP): $arrParams["param1"] = JRequest::getInt('param1'); $arrParams["param2"] = JRequest::getInt('param2'); и модифицируем вызов функции setSearch(): Код (PHP): $this->setSearch($keyword, $arrParams, $match, $ordering); теперь конструктор выглядит так: Код (PHP): function __construct() { parent::__construct(); global $mainframe; //Get configuration $config = JFactory::getConfig(); // Get the pagination request variables $this->setState('limit', $mainframe->getUserStateFromRequest('com_search.limit', 'limit', $config->getValue('config.list_limit'), 'int')); $this->setState('limitstart', JRequest::getVar('limitstart', 0, '', 'int')); // Set the search parameters $arrParams = array(); $keyword = urldecode(JRequest::getString('searchword')); $match = JRequest::getWord('searchphrase', 'all'); $arrParams["param1"] = JRequest::getInt('param1'); $arrParams["param2"] = JRequest::getInt('param2'); // print_r($arrParams); $ordering = JRequest::getWord('ordering', 'newest'); $this->setSearch($keyword, $arrParams, $match, $ordering); //Set the search areas $areas = JRequest::getVar('areas'); $this->setAreas($areas); } Было принято решение использовать массив для хранения дополнительных параметров, массивы очень удобны для динамических структур - за ранее количество параметров не известно, и что бы постоянно не модифицировать функции - используем массив параметров. Далее нужно модифицировать саму функцию(строка 98 - function setSearch()). Изменяем заголовок функции: Код (PHP): function setSearch($keyword, $arrParams = array(), $match = 'all', $ordering = 'newest') Добавляем дополнительный блок для обработки Вашего массива с параметрами: Код (PHP): if(count($arrParams)) $this->setState('arrParams', $arrParams); Получаем модифицированную функцию setSearch(): Код (PHP): function setSearch($keyword, $arrParams = array(), $match = 'all', $ordering = 'newest') { if(isset($keyword)) { $this->setState('keyword', $keyword); } if(isset($keyword)) { $this->setState('keyword', $keyword); } if(isset($match)) { $this->setState('match', $match); } if(isset($ordering)) { $this->setState('ordering', $ordering); } if(count($arrParams)) $this->setState('arrParams', $arrParams); // print_r($arrParams); } Немного прервусь и объясню логику этой замечательной конструкции.... Дело в том, что поиск в джумле устроен по очень хитрому механизму: 1. Модуль - используется для вывода упрощенной формы поиска на сайте. После отправки формы модуль передает управление компоненту. 2. Компонент(com_search) - используется для вывода полноценной формы поиска и вывода результатов поиска. Компонент сам не обладает механизмом обработки запроса, вместо этого он инициализирует событие OnSearch, которое, в свою очередь, перехватывают плагины, которые расположены в папке Код (CODE): plugins/search/ Так вот, к чему я все это... метод "setState" позволяет передавать параметры внутри классов, которые используются при обработке результатов запроса. Вернемся к search.php, строка 141, функция getData(): В данной функции управление передается плагинам поиска и обрабатывается результат запроса, который нас, в данной ситуации не интересует. Строка 148 Код (PHP): JPluginHelper::importPlugin( 'search'); $dispatcher =& JDispatcher::getInstance(); $results = $dispatcher->trigger( 'onSearch', array( $this->getState('keyword'), $this->getState('match'), $this->getState('ordering'), $areas['active']) ); Нам нужно передать наш массив с дополнительными параметрами, получим: Код (PHP): JPluginHelper::importPlugin( 'search'); $dispatcher =& JDispatcher::getInstance(); $results = $dispatcher->trigger( 'onSearch', array( $this->getState('keyword'), $this->getState('arrParams'), $this->getState('match'), $this->getState('ordering'), $areas['active']) ); Работа с компонентом завершена и теперь переходим к работе с плагином. Топаем в Код (CODE): plugins/search/content.php Этот плагин отвечает за поиск по таблице jos_content. Строка 42, функция plgSearchContent(), меняем заголовок функции: Код (PHP): function plgSearchContent( $text, $arrParams = array(),$phrase='', $ordering='', $areas=null ) Теперь, в теле функции нам доступен массив с дополнительными параметрами. Осталось модифицировать sql-запрос. Строка 82, блок, отвечающий за формирование куска запроса с условиями выборки, его то нам и нужно ) Код (PHP): switch ($phrase) { case 'exact': $text = $db->Quote( '%'.$db->getEscaped( $text, true ).'%', false ); $wheres2 = array(); $wheres2[] = 'a.title LIKE '.$text; $wheres2[] = 'a.introtext LIKE '.$text; $wheres2[] = 'a.fulltext LIKE '.$text; $wheres2[] = 'a.metakey LIKE '.$text; $wheres2[] = 'a.metadesc LIKE '.$text; $where = '(' . implode( ') OR (', $wheres2 ) . ')'; break; case 'all': case 'any': default: $words = explode( ' ', $text ); $wheres = array(); foreach ($words as $word) { $word = $db->Quote( '%'.$db->getEscaped( $word, true ).'%', false ); $wheres2 = array(); $wheres2[] = 'a.title LIKE '.$word; $wheres2[] = 'a.introtext LIKE '.$word; $wheres2[] = 'a.fulltext LIKE '.$word; $wheres2[] = 'a.metakey LIKE '.$word; $wheres2[] = 'a.metadesc LIKE '.$word; $wheres[] = implode( ' OR ', $wheres2 ); } $where = '(' . implode( ($phrase == 'all' ? ') AND (' : ') OR ('), $wheres ) . ')'; break; } Добавляем наши параметры и получаем: Код (PHP): switch ($phrase) { case 'exact': $text = $db->Quote( '%'.$db->getEscaped( $text, true ).'%', false ); $wheres2 = array(); $wheres2[] = 'a.title LIKE '.$text; $wheres2[] = 'a.introtext LIKE '.$text; $wheres2[] = 'a.fulltext LIKE '.$text; $wheres2[] = 'a.metakey LIKE '.$text; $wheres2[] = 'a.metadesc LIKE '.$text; $wheres2[] = 'a.field_name1 LIKE '.$arrParams["param1"]; $wheres2[] = 'a.field_name2 LIKE '.$arrParams["param2"]; $where = '(' . implode( ') OR (', $wheres2 ) . ')'; break; case 'all': case 'any': default: $words = explode( ' ', $text ); $wheres = array(); foreach ($words as $word) { $word = $db->Quote( '%'.$db->getEscaped( $word, true ).'%', false ); $wheres2 = array(); $wheres2[] = 'a.title LIKE '.$word; $wheres2[] = 'a.introtext LIKE '.$word; $wheres2[] = 'a.fulltext LIKE '.$word; $wheres2[] = 'a.metakey LIKE '.$word; $wheres2[] = 'a.metadesc LIKE '.$word; $wheres2[] = 'a.field_name1 = '.$arrParams["param1"]; $wheres2[] = 'a.field_name2 = '.$arrParams["param2"]; $wheres[] = implode( ' OR ', $wheres2 ); } $where = '(' . implode( ($phrase == 'all' ? ') AND (' : ') OR ('), $wheres ) . ')'; break; } Тут очень важно, что бы имена полей, которые Вы используете в условиях присутствовали в таблице, в нашем случае - jos_content. В противном случае вы получите фатал при запросе. Также использование оператора "=" не принципиально, используете любой подходящий Вам оператор. Вот в принципе и все, в этой статье я не ставил перед собой цель создать какой то шаблон, я пытался раскрыть принципы работы и принципы передачи данных между классами, используемых для поиска контента на вашем сайте. Любая адекватная критика приветствуется
хорошо расписали, спасибо большое, я бы скрины добавил результата, что-бы можно было увидеть результат того что получится, но задачи разные, хотя бы для вашего примера
Gronpipmaster, скрины...хммм... а скрины чего Вас интересуют ? ) кода ? или внешнего вида самой формы поиска ? botanist, спс, исправлю )
Так визуально меняется только форма, Код (PHP): <td nowrap="nowrap"> <input type="text" name="param1" id="search_param1" size="10" maxlength="20" value="" class="inputbox" /> </td> <td nowrap="nowrap"> <input type="text" name="param2" id="search_param2" size="10" maxlength="20" value="" class="inputbox" /> </td> все остальное не визуально. Даже вывод результатов поиска внешне не меняется.
Да, не хватает примеров, хотя бы что требовалось сделать, тем более, что в форму добавляются простые текстовые поля, а в запросе знак =. Это ж еще надо угадать.
просто за последнее время я столкнулся с массой пользователей, которые с трудом могут описать массив в пхп, не то что там где то запросы править )
Panda, отлично! Теперь я думаю у многих вопросы отпадут сами собой! Сделал еще вот так: Код (CODE): <input type="text" name="param1" id="search_param1" size="10" maxlength="20" value="<?php echo JRequest::getInt('param1'); ?>" class="inputbox" />
Хотим сделать что бы искалось ЛИБО по "ключевым словам" ЛИБО по "созданному полю". *примечание: сейчас поиск осуществляется обязательно по полю "ключевые слова" и дополнительно по "созданному полю" Лезем в plugins/search/content.php Строка 73 Убираем: Код (CODE): if ($text == '') { return array(); }
раз уж вы решили убрать строку дефолтную строку поиска таким способом, так потрудитесь и изменить блоки "WHERE".
в Джумле если нет плагина поиска для какого либо компонента можно свой по аналогии написать (если конечно метод получения записей из БД позволяет использовать множество условий, переданных постом с моделя поиска), недовно пришлось для lyftenbloggie накатать , правда пришлось подпатчить процедуры выборки немного
День добрый. Помогите пожалуйста. Нужно организовать поиск по 3 полям одновреммено. 1 поля - текст. Два остальных - выпадающие списки. Пробывал следовать примеру - не получилось. Может кто сталкивался? И сможет мне помочь? Очень срочно надо. Эта единственная тема которую я нашёл в nete. Помогите, пожалуйста. Заранее спасибо.