Топаем в:
components/com_search/views/search/tmpl/default_form.php
С первых строк в нем описывается форма, туда нужно добавить необходимые Вам поля.
В своем примере я буду использовать два поля типа TEXT и именами param1 и param2.
<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>
После того, как поля были добавлены, Вам необходимо получить значения, введенные в эти поля.
Топаем в:
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);
теперь конструктор выглядит так:
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()).
Изменяем заголовок функции:
function setSearch($keyword, $arrParams = array(), $match = 'all', $ordering = 'newest')
Добавляем дополнительный блок для обработки Вашего массива с параметрами:
if(count($arrParams))
$this->setState('arrParams', $arrParams);
Получаем модифицированную функцию setSearch():
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, которое, в свою очередь, перехватывают плагины, которые расположены в папке:
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. В противном случае вы получите фатал при запросе.
Также использование оператора "=" не принципиально, используете любой подходящий Вам оператор.
Вот в принципе и все, в этой статье я не ставил перед собой цель создать какой то шаблон, я пытался раскрыть принципы работы и принципы передачи данных между классами, используемых для поиска контента на вашем сайте.