Главная » 2013 » Апрель » 1 » Joomla 1.5.x. Мануал о том, как модифицировать поиск под свои нужды
02:14
Joomla 1.5.x. Мануал о том, как модифицировать поиск под свои нужды
Все начинается с того, что Вам необходимо модифицировать стандартную форму поиска, а точнее добавить туда нужные Вам поля. Топаем в:
components/com_search/views/search/tmpl/default_form.php С первых строк в нем описывается форма, туда нужно добавить необходимые Вам поля. В своем примере я буду использовать два поля типа TEXT и именами param1 и param2.
После того, как поля были добавлены, Вам необходимо получить значения, введенные в эти поля. Топаем в:
components/com_search/controller.php Строка 41, function search(): В теле функции необходимо получить значения, переданные из формы. Я передаю два числа, поэтому и обрабатываю с помощью метода getInt класса JRequest. getString - строка, getVar - общий тип данных, если так можно выразиться... Для получения других типов данных рекомендую почитать документацию.
$post["param1"] = JRequest::getInt('param1'); $post["param2"] = JRequest::getInt('param2'); В ассоциативном массиве $post накапливаются пары "ключ" - "значение" для формирования строки GET-запроса.
Теперь настало время получить данные и сформировать sql-запрос для выборки.
Топаем в:
component/com_search/models/search.php строка 62, конструктор (function __construct()), получаем наши параметры:
$arrParams["param1"] = JRequest::getInt('param1'); $arrParams["param2"] = JRequest::getInt('param2'); и модифицируем вызов функции setSearch():
$this->setSearch($keyword, $arrParams, $match, $ordering); теперь конструктор выглядит так:
//Set the search areas $areas = JRequest::getVar('areas'); $this->setAreas($areas); } Было принято решение использовать массив для хранения дополнительных параметров, массивы очень удобны для динамических структур - за ранее количество параметров не известно, и что бы постоянно не модифицировать функции - используем массив параметров.
Далее нужно модифицировать саму функцию(строка 98 - function setSearch()). Изменяем заголовок функции:
function setSearch($keyword, $arrParams = array(), $match = 'all', $ordering = 'newest') Добавляем дополнительный блок для обработки Вашего массива с параметрами:
// print_r($arrParams); } Немного прервусь и объясню логику этой замечательной конструкции.... Дело в том, что поиск в джумле устроен по очень хитрому механизму: 1. Модуль - используется для вывода упрощенной формы поиска на сайте. После отправки формы модуль передает управление компоненту. 2. Компонент (com_search) - используется для вывода полноценной формы поиска и вывода результатов поиска. Компонент сам не обладает механизмом обработки запроса, вместо этого он инициализирует событие OnSearch, которое, в свою очередь, перехватывают плагины, которые расположены в папке:
plugins/search/ Так вот, к чему я все это... метод "setState" позволяет передавать параметры внутри классов, которые используются при обработке результатов запроса.
Вернемся к search.php, строка 141, функция getData(): В данной функции управление передается плагинам поиска и обрабатывается результат запроса, который нас, в данной ситуации не интересует. Строка 148 :
JPluginHelper::importPlugin( 'search'); $dispatcher =& JDispatcher::getInstance(); $results = $dispatcher->trigger( 'onSearch', array( $this->getState('keyword'), $this->getState('match'), $this->getState('ordering'), $areas['active']) ); Нам нужно передать наш массив с дополнительными параметрами, получим:
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']) ); Работа с компонентом завершена и теперь переходим к работе с плагином. Топаем в:
plugins/search/content.php Этот плагин отвечает за поиск по таблице jos_content. Строка 42, функция plgSearchContent(), меняем заголовок функции:
function plgSearchContent( $text, $arrParams = array(),$phrase='', $ordering='', $areas=null ) Теперь, в теле функции нам доступен массив с дополнительными параметрами. Осталось модифицировать sql-запрос. Строка 82, блок, отвечающий за формирование куска запроса с условиями выборки, его то нам и нужно ):
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; } Добавляем наши параметры и получаем:
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. В противном случае вы получите фатал при запросе.
Также использование оператора "=" не принципиально, используете любой подходящий Вам оператор.
Вот в принципе и все, в этой статье я не ставил перед собой цель создать какой то шаблон, я пытался раскрыть принципы работы и принципы передачи данных между классами, используемых для поиска контента на вашем сайте.