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

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

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

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

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

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

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

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

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

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

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

search 01

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

administrator\components\com_finder\config.xml

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

		<field
			name="sort_order"
			type="list"
			label="COM_FINDER_CONFIG_SORT_ORDER_LABEL"
			description="COM_FINDER_CONFIG_SORT_ORDER_DESC"
			default="relevance"
			validate="options"
			>
			<option value="relevance">COM_FINDER_CONFIG_SORT_OPTION_RELEVANCE</option>
			<option value="date">COM_FINDER_CONFIG_SORT_OPTION_START_DATE</option>
			<option value="price">COM_FINDER_CONFIG_SORT_OPTION_LIST_PRICE</option>
			<option value="itemzootype">По типу ZOO</option>
		</field>

 получаем выбор сортировки по типу 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.

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

<div class="ias-item">
    <div class="teaserbox item-column col-md-12">
        <div class="item-box">
                <div class="row">
                    <div class="colmd12">
                        <div class="item-image pull-center">
                            <a href="/<?php echo JRoute::_($route); ?>">
                                <img class="jbimage img-responsive" alt="<?= $this->result->title; ?>" src="/<?= $thumb ?>">
                            </a>
                            <?php if (!empty($seria)) : ?>
                            <span class="seriya"><?= $seria ?></span>
                            <?php endif; ?>
                        </div>
                            <h4 class="item-title">
                                <a href="/<?php echo JRoute::_($route); ?>">
                                    <?= $this->result->title; ?>
                                </a>
                            </h4>

                    </div>
                </div>
        </div>
    </div>
</div>

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

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

$typeitem = "";
    foreach ($this->results as $result) : ?>
        <?php
        $typeitem_curr = key($result->getTaxonomy('Type'));
        if ($typeitem_curr != $typeitem) {
            $typeitem = key($result->getTaxonomy('Type'));
            print('<div class="searchrow"><h3>'.$typeitem_curr.'</h3></div>');
        }
        ?>
		<?php $this->result = &$result; ?>
		<?php $layout = $this->getLayoutFile($this->result->layout); ?>
		<?php echo $this->loadTemplate($layout); ?>
	<?php endforeach; ?> 

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

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

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

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

Вы комментируете как Гость.

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

  • 2019-04-18
  • 136
  • Требования: ZOO, JbZOO, Joomla
  • Версия JBZoo: 2.2.x
  • Раздел: Песочница
  • Скачать
  • Размер: 24.73 KB
  • Обновлён: 2019-04-19
  • Версия: 1,1
  • Скачали: 8
  • jomla
  • jbzoo
  • css3
  • html5
  • Java script
  • jquery
  • bootstrap
Мы находимся в Минске
работаем по всей РБ
  • mts+375 29 779-72-95viber
  • vel+375 44 779-72-95
  • email: Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.
  • skype: tirby_kat
Индивидуальный предприниматель
Кулак Сергей Николаевич
УНП: 590816946
зарегистрирован Зельвенским районным исполнительным комитетом
от 01.06.2010
Свяжитесь со мной