Пробуем и тестируем

Рецепты на все случаи жизни

Поиск Joomla и ZOO + jbZOO. Как поженить умный поиск с каталогом?

Много лет я являюсь приверженцем joomla. Наверное это от лени и привычки. Мне легко с ней работать. Особенно в связке с ZOO +jbZOO. Выходит очень удобный конструктор контента. Но у него ест ьсвои недостатки. И один из них - ужасный вывод результатов поиска на сайте. И хотя у Joomla есть свой неплохой компонент "Умный поиск" - результат этого самого умного поиска вызывает печаль.

Хотелось бы получить результаты поиска по каталогу в виде тизеров с картинками и полями. А в идеале и возможность искать по типам товара. Групировать результаты поиска.. мечта - мечта.. 

Но по факту ведь нет ни чего не возможного. Я решил покопаться в умном поиске и вывести хотя бы криво, с г-но годом, но более или менее читаемый поиск.

Два дня колупания и копания и вот что вышло.

Сразу предупреждаю случайного читателя - квест не из простых. Но результат - стоит того.

Прежде всего у вас на сайте должен юбыть включен и настроен первоначально умный поиск. И активированы минимум два плагина:

  1. Умный Поиск - Содержимое
  2. Smart Search - ZOO

Далее описываем модель контролера. Но этот шаг можно пропустить и не применять, если в поиске участие принимает только один тип товара и не надо его группировать.

administrator\components\com_finder\config.xml

 Правим добавляя в конфиг дополнительный параметр для выбора сортировки. На самом деле он будет работать для группировки типов.

             
                        
                        
                        
                        
                

 получаем выбор сортировки по типу ZOO в настройках умного поиска. Если кто забыл где это - то это кнопочка настройка справа вверху на странице компонента умного поиска :)

Выбираем и сохраняем сортировку. И правим следующий файл:

administrator\components\com_finder\helpers\indexer\driver\mysql.php

В нем добавляем обработку нового поля в индексе базы данных и загоняем в него тип соответствующего материала:

                        $query->clear()
                                ->insert($db->quoteName('#__finder_links'))
                                ->columns($columnsArray)
                                ->values(
                                        $db->quote($item->url) . ', '
                                        . $db->quote($item->route) . ', '
                                        . $db->quote($item->title) . ', '
                                        . $db->quote($item->description) . ', '
                                        . $query->currentTimestamp() . ', '
                                        . '1, '
                                        . (int) $item->state . ', '
                                        . (int) $item->access . ', '
                                        . $db->quote($item->language) . ', '
                                        . (int) $item->type_id . ', '
                                        . $db->quote(key($item->getTaxonomy()['Type'])) . ', '
                                        . $db->quote(serialize($item)) . ', '
                                        . $db->quote($item->publish_start_date) . ', '
                                        . $db->quote($item->publish_end_date) . ', '
                                        . $db->quote($item->start_date) . ', '
                                        . $db->quote($item->end_date) . ', '
                                        . (double) ($item->list_price ?: 0) . ', '
                                        . (double) ($item->sale_price ?: 0)
                                );
                        $db->setQuery($query);
                        $db->execute();

                        // Get the link id.
                        $linkId = (int) $db->insertid();
                }
                else
                {
                        // Update the link.
                        $query->clear()
                                ->update($db->quoteName('#__finder_links'))
                                ->set($db->quoteName('route') . ' = ' . $db->quote($item->route))
                                ->set($db->quoteName('title') . ' = ' . $db->quote($item->title))
                                ->set($db->quoteName('description') . ' = ' . $db->quote($item->description))
                                ->set($db->quoteName('indexdate') . ' = ' . $query->currentTimestamp())
                                ->set($db->quoteName('state') . ' = ' . (int) $item->state)
                                ->set($db->quoteName('access') . ' = ' . (int) $item->access)
                                ->set($db->quoteName('language') . ' = ' . $db->quote($item->language))
                                ->set($db->quoteName('type_id') . ' = ' . (int) $item->type_id)
                ->set($db->quoteName('itemtype_id') . ' = ' . key($item->getTaxonomy()['Type'])
                                ->set($db->quoteName('object') . ' = ' . $db->quote(serialize($item)))
                                ->set($db->quoteName('publish_start_date') . ' = ' . $db->quote($item->publish_start_date))
                                ->set($db->quoteName('publish_end_date') . ' = ' . $db->quote($item->publish_end_date))
                                ->set($db->quoteName('start_date') . ' = ' . $db->quote($item->start_date))
                                ->set($db->quoteName('end_date') . ' = ' . $db->quote($item->end_date))
                                ->set($db->quoteName('list_price') . ' = ' . (double) ($item->list_price ?: 0))
                                ->set($db->quoteName('sale_price') . ' = ' . (double) ($item->sale_price ?: 0))
                                ->where('link_id = ' . (int) $linkId);
                        $db->setQuery($query);
                        $db->execute();
                }

Здесь в табличке #__finder_links добавляется дополнительное поле type_id в которое при индексации будет запихнут тип материала. К сожалению я не стал сильно морочится и для ZOO запихивается тип как есть. А не его альяс и не ID.. Стыдоба конечно. Но когда делал было настроение - не догоню, так согреюсь. То есть забил и не морочился.

Как факт у нас в индексе появилось поле в котором хранятся название типа материала и по нему можно будет сортировать и группировать.

Далее идем по пути:

components\com_finder\models\search.php

Это моделька поиска. В нем в блок сортировок добавляем нашу сортировку из конфига:

$order = $input->getWord('filter_order', $params->get('sort_order', 'relevance'));
                $order = StringHelper::strtolower($order);

                $order = StringHelper::strtolower('itemzootype');
        //dump($order);

                switch ($order)
                {
                        case 'date':
                                $this->setState('list.ordering', 'l.start_date');
                                break;

                        case 'price':
                                $this->setState('list.ordering', 'l.list_price');
                                break;

            case 'itemzootype':
                                $this->setState('list.ordering', 'l.itemtype_id');
                                break;

                        case ($order === 'relevance' && !empty($this->includedTerms)) :
                                $this->setState('list.ordering', 'm.weight');
                                break;

                        // Custom field that is indexed and might be required for ordering
                        case 'title':
                                $this->setState('list.ordering', 'l.title');
                                break;

                        default:
                                $this->setState('list.ordering', 'l.link_id');
                                break;
                }

Рядышком лежит моделька suggestions.php... задумка на подсказки. По идее можно и подсказхки оформить красочно..  Это мысля на будущее. С этими светлыми мыслями заканчиваю ломать и начинаю переопределять. Тоже какакодом.

emplates\showers\html\com_finder\search\

переопределять будем:

  1. default_result.php
  2. default_results.php

Самый треш происходит в этом файле default_result.php. Сложность понимания и реализации требует напряга от непосвященного. И перезаписать все просто из архивчика прикрепленного не выйдет. Так как будут подтягиваться значения элементов из вашего набора.

Так как у нас много типов, то я обрабатывал каждый тип по отдельности. Смысл состоит в том, что вы берете из каждого типа элементы которые хотите вывести в тизере результата и по их ID получаете значение. Как картинки, так и цены или что там еще придет в голову.

Я выдирал только картинки. И так как у некоторых типов товара они не вертикальные, у некоторых горизонтальные, я просто поверял наличие элемента картинки у текущего выводимого итема и если картинка типа есть - присваиваю ее элементу и делаю резайз через хелпер jbzoo в соответствиями с требованиями типа. Получаю ссылку к кадрированной картинке в кеше. До кучи выдергиваю серию товара если таковая есть.

    $app = App::getInstance('zoo');

    $thumb = '';
    $image = '';

    $item = $app->table->item->get($this->result->id);

    //if (empty ($thumb)) {$thumb = $app->jbimage->resize($item->elements['f2e7a0d6-7622-4093-9778-c5621fe33aa4'][0]['file'], 400, 600);}
    if (!empty($item->elements['f2e7a0d6-7622-4093-9778-c5621fe33aa4'][0]['file'])) $thumb = $app->jbimage->resize($item->elements['f2e7a0d6-7622-4093-9778-c5621fe33aa4'][0]['file'], 360, 540); //кабина душевая
    if (!empty($item->elements['3db2d590-1f96-4370-b6c7-cf21ef7b0ece'][0]['file'])) $thumb = $app->jbimage->resize($item->elements['3db2d590-1f96-4370-b6c7-cf21ef7b0ece'][0]['file'], 360, 540); //дверь в нишу
    if (!empty($item->elements['18537563-02b1-4110-b4b8-0b4a0d1d044e'][0]['file'])) $thumb = $app->jbimage->resize($item->elements['18537563-02b1-4110-b4b8-0b4a0d1d044e'][0]['file'], 360, 540); //Шторка для ванной
    if (!empty($item->elements['c5cd0f4f-94a4-4bd1-bcfb-5a0169ed6bf6'][0]['file'])) $thumb = $app->jbimage->resize($item->elements['c5cd0f4f-94a4-4bd1-bcfb-5a0169ed6bf6'][0]['file'], 400, 300); //
    if (!empty($item->elements['424520f0-f345-4e51-b20c-946ea6877319'][0]['file'])) $thumb = $app->jbimage->resize($item->elements['424520f0-f345-4e51-b20c-946ea6877319'][0]['file'], 400, 280); //Линейный трап
    if (!empty($item->elements['0dfa0f78-c0ce-486f-8136-6b51085e6800'][0]['file'])) $thumb = $app->jbimage->resize($item->elements['0dfa0f78-c0ce-486f-8136-6b51085e6800'][0]['file'], 400, 'auto');
    if (!empty($item->elements['1dc6f028-3970-4675-9a92-d49f9bfe9688'][0]['file'])) $thumb = $app->jbimage->resize($item->elements['1dc6f028-3970-4675-9a92-d49f9bfe9688'][0]['file'], 400, 'auto'); //гидроизол
    if (!empty($item->elements['6aacc249-283e-4417-bd35-ec0c40aca6e1'][0]['file'])) $thumb = $app->jbimage->resize($item->elements['6aacc249-283e-4417-bd35-ec0c40aca6e1'][0]['file'], 400, 'auto');
    if (!empty($item->elements['2b54a6ca-78dc-4260-9eb5-96f5cb22126f'][0]['file'])) $thumb = $app->jbimage->resize($item->elements['2b54a6ca-78dc-4260-9eb5-96f5cb22126f'][0]['file'], 400, 300); //Плита с компактным трапом
    if (!empty($item->elements['d8de4cb8-6174-4bfa-8249-fa6890fe9f6e'][0]['file'])) $thumb = $app->jbimage->resize($item->elements['d8de4cb8-6174-4bfa-8249-fa6890fe9f6e'][0]['file'], 400, 300); //Плита с линейным трапом
    if (!empty($item->elements['56ff85d6-7cda-46b3-b41b-4997da278a80'][0]['file'])) $thumb = $app->jbimage->resize($item->elements['56ff85d6-7cda-46b3-b41b-4997da278a80'][0]['file'], 400, 'auto'); //Расширительный профиль
    if (!empty($item->elements['f9314c50-74b3-4545-8b93-b0c7b65a7a5c'][0]['file'])) $thumb = $app->jbimage->resize($item->elements['f9314c50-74b3-4545-8b93-b0c7b65a7a5c'][0]['file'], 400, 'auto'); //сифон

    //$thumb = $app->jbimage->resize($image, 300, 'auto');
    $thumb = $thumb->rel;
    $seria = $item->elements['eafecb6d-e7cf-44e1-833f-d6c17b2c9cc7']['option'][0];

Кратце я подключаю ZOO, выдергиваю объект материала по его ID которая идет в комплекте с результатами поиска, и выбираю из него нужные мне элементы с их значениями по их ID.

Далее формирую вывод полученного в виде тизера каталога:

Здесь все сугубо индивидуально.

Далее default_results.php в блоке вывода списка результатов я добавил условие выводящее тип материла один раз при каждой смене типа. Получается визуально будет разделять список найденных товаров. А с учетом того, что мы сделал возможность сортировать найденное по типам - то выведет сначала один, потом второй тип.. и так далее.

$typeitem = "";
    foreach ($this->results as $result) : ?>
        getTaxonomy('Type'));
        if ($typeitem_curr != $typeitem) {
            $typeitem = key($result->getTaxonomy('Type'));
            print('

'.$typeitem_curr.'

'); } ?> result = &$result; ?> getLayoutFile($this->result->layout); ?> loadTemplate($layout); ?>

В итоге можно сильно упростить если не делать хак контроллера для разделения на типы. Тогда правка default_results не потребуется. Достаточно будет в default_result.php подключив ZOO и повытаскивав только необходимые элементы из него. Так выйдет на много проще и не надо будет делать хака поиска. Хватит только простого переопределеия.

 Свои Файлы прикрепляю архивом без каких либо правок, с комментами или дампами. Можете экспериментировать с ними как хотите. Работать без корректировок у вас это все дело не сможет.

Комментарии (0)

    Оставить комментарий

    Пожалуйста, войдите, чтобы комментировать.

    Статус материала

    • 2019-04-18
    • 878
    • Требования: ZOO, JbZOO, Joomla
    • Версия JBZoo: 2.2.x
    • Раздел: Песочница
    • Скачать
    • Размер: 24.73 KB
    • Обновлён: 2019-04-19
    • Версия: 1,1
    • Скачали: 67
    • jomla
    • jbzoo
    • css3
    • html5
    • Java script
    • jquery
    • bootstrap
    Мы находимся в Минске
    работаем по всей РБ