—»     —»   Joomla 1.5.x. Мануал о том, как модифицировать поиск под свои нужды
  Раздел: CMS-ы   Комментариев: 5  

Joomla 1.5.x. Мануал о том, как модифицировать поиск под свои нужды



Все начинается с того, что Вам необходимо модифицировать стандартную форму поиска, а точнее добавить туда нужные Вам поля.
Топаем в:

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. В противном случае вы получите фатал при запросе.

Также использование оператора "=" не принципиально, используете любой подходящий Вам оператор.

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

Обнаружили ошибку или мёртвую ссылку?
Выделите проблемный фрагмент мышкой и нажмите CTRL+ENTER.
В появившемся окне опишите проблему и отправьте уведомление Администрации ресурса.
Нужна органическая вечная ссылка из данной статьи? Постовой?
Подробности здесь
Вам понравился материал? Поблагодарить легко!
Будем весьма признательны, если поделитесь этой статьей в социальных сетях:

Ключевые тэги: Joomla
Опубликовал omfgpanda   Прочитано (раз): 12283   |   Оставлено комментариев: 5
Источник материала / оригинал статьи   Распечатать
Другие статьи и новости по теме:
Комментарий #1: 1 августа 2010 @ 09:12
Написал: Марат — группа: Гости  
На сайте с: --   |   Публикаций: 0   |   Комментариев: 0
ICQ: --- не указано ---
Ай спасибо дарагой! =)
Навел меня на сердце поиска! Щас будем ковыряеть, хехе.

А вообще был неприятно удивлен, когда обнаружил, что в результатах нельзя отдельно вывести id или catid статьи =\ Либо я плохо искал. Как вариант конечно можно вытащить из ссылки эти данные, но решил покопать поглубже.

В общем, спасибо!
Комментарий #2: 3 августа 2011 @ 07:32
Написал: satory — группа: Гости  
На сайте с: --   |   Публикаций: 0   |   Комментариев: 0
ICQ: --- не указано ---
Благодарю!
Комментарий #3: 12 ноября 2011 @ 16:15
Написал: ch — группа: Гости  
На сайте с: --   |   Публикаций: 0   |   Комментариев: 0
ICQ: --- не указано ---
Спасибо! Очень полезная статья!
Комментарий #4: 23 декабря 2011 @ 06:36
Написал: Иван — группа: Гости  
На сайте с: --   |   Публикаций: 0   |   Комментариев: 0
ICQ: --- не указано ---
Интересно! А как сделать чтоб в интерент магазине когда в результатах больше одного товара, выводилось не рписание а список из одного товра?
Комментарий #5: 5 июня 2012 @ 21:06
Написал: Nick — группа: Гости  
На сайте с: --   |   Публикаций: 0   |   Комментариев: 0
ICQ: --- не указано ---
А как сделать сортировку поиска по умолчанию не newest, а oldest ?
Добавление комментария
Уважаемые пользователи!
При добавлении комментариев на сайт Вам следует учитывать следующее - все комментарии проверяются Администрацией на предмет отсутствия спама. При обнаружении признаков спама, в оставленном Вами комментарии, сам комментарий будет незамедлительно удалён, а Ваш IP-адрес будет забанен без предупреждения! Учётные записи пользователей, рассылающих спам, блокируются/удаляются без права последующего восстановления.

С уважением, Администрация сайта.
* = поля обязательны к заполнению
Полужирный Наклонный текст Подчеркнутый текст Зачеркнутый текст | Выравнивание по левому краю По центру Выравнивание по правому краю | Вставка смайликов Выбор цвета | Скрытый текст Вставка цитаты Преобразовать выбранный текст из транслитерации в кириллицу Вставка спойлера
Вопрос : Назовите месяц December по-русски
Подтверждение кода безопасности :

Включите эту картинку для отображения кода безопасности
обновить, если не виден код


Популярные публикации


















Свежие шаблоны сайтов каждый день
С миру по нитке
«    Июль 2017    »
ПнВтСрЧтПтСбВс
 12
3456789
10111213141516
17181920212223
24252627282930
31