Jump to content


Photo
* * * * * 1 votes

Улучшаем поиск по материалам в панели управления Zoo (хак)

рецепт поиск zoo хак панель управления

6 replies to this topic

#1 SmetDenis

SmetDenis
  • Administrators
  • User rate: 139.4
  • posts: 16232
  • topics: 200

Posted 04 June 2014 - 15:04

*
POPULAR

Обсуждение из этого топика сподвигло меня написать этот небольшой хак.

Как оказалось, одинаковые (или очень похожие) названия материалов - это частое явление.
Ок, попробуем сделать мир лучше.

Далее мы будем обсуждать как сделать так, чтобы вот эта форма поиска, могла найти что-нибудь не только в имени материала, но и в свойствах. По умолчанию, компонент Zoo будет искать только в Названии, псевдониме и теге, причем ищет текст "как есть".
vlh.png


Какова наша цель?
  • Хотим искать во всех дополнительных полях.
  • "Аддон" - если указываем несколько слов через пробел, то поиск будет работать по каждому слово отдельно и покажет общий результат. Например, фраза "Nexus 1Gb" сможет найти материал у которого в названии есть Nexus и одно из полей заполнено "1Gb". Штуковина экспериментальная, далеко не всем пригодится.
Почему это хак и нет в комплекте JBZoo?
Поисковый запрос создается прямо в одном из системных файлов и я не могу повлиять на него никаким расширением через API. Поэтому берем и аккуратно меняем как написано ниже.


Что делать?
Открываем файл administrator\components\com_zoo\controllers\item.php
И находим этот кусок кода (строки могут не совпадать, это не страшно)
duu_1280x0.png

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

1 вариант - ищет фразу "как есть" во всех полях материалов

if ($search) {

    $from .= ' LEFT JOIN ' . ZOO_TABLE_TAG . ' AS t ON a.id = t.item_id';
    $from .= ' LEFT JOIN ' . ZOO_TABLE_SEARCH . ' AS s ON a.id = s.item_id';

    $where[] = '(LOWER(a.name) LIKE ' . $this->db->Quote('%' . $this->db->escape($search, true) . '%', false)
        . ' OR LOWER(t.name) LIKE ' . $this->db->Quote('%' . $this->db->escape($search, true) . '%', false)
        . ' OR LOWER(s.value) LIKE ' . $this->db->Quote('%' . $this->db->escape($search, true) . '%', false)
        . ' OR LOWER(a.alias) LIKE ' . $this->db->Quote('%' . $this->db->escape($search, true) . '%', false) . ')';
}
2 вариант - делит фразу по пробелам и ищет любые совпадения искомых строк

if ($search) {

    $searchData  = explode(' ', $search);
    $searchWhere = array();

    $from .= ' LEFT JOIN ' . ZOO_TABLE_TAG . ' AS t ON a.id = t.item_id';
    $from .= ' LEFT JOIN ' . ZOO_TABLE_SEARCH . ' AS s ON a.id = s.item_id';

    foreach ($searchData as $searchWord) {

        $searchWord = JString::trim($searchWord);

        $searchWhere[] = implode(' OR ', array(
            'LOWER(a.name) LIKE ' . $this->db->Quote('%' . $this->db->escape($searchWord, true) . '%', false),
            'LOWER(t.name) LIKE ' . $this->db->Quote('%' . $this->db->escape($searchWord, true) . '%', false),
            'LOWER(a.alias) LIKE ' . $this->db->Quote('%' . $this->db->escape($searchWord, true) . '%', false),
            'LOWER(s.value) LIKE ' . $this->db->Quote('%' . $this->db->escape($searchWord, true) . '%', false)
        ));
    }

    $where[] = '((' . implode(') OR (', $searchWhere) . '))';
}
3 вариант - Так же делит по пробелам, но поиск более точный

if ($search) {
    $searchData  = explode(' ', $search);
    $searchWhere = array();

    $from .= ' LEFT JOIN ' . ZOO_TABLE_SEARCH . ' AS s ON a.id = s.item_id';

    foreach ($searchData as $searchWord) {

        $searchWord = JString::trim($searchWord);

        $searchWhere[] = implode(' AND ', array(
            'LOWER(a.name) LIKE ' . $this->db->Quote('%' . $this->db->escape($searchWord, true) . '%', false),
            'LOWER(s.value) LIKE ' . $this->db->Quote('%' . $this->db->escape($searchWord, true) . '%', false)
        ));
    }

    $where[] = '((' . implode(') OR (', $searchWhere) . '))';
}
4 вариант - поиск только по кастомным полям

if ($search) {

    $searchData  = explode(' ', $search);
    $searchWhere = array();

    $from .= ' LEFT JOIN ' . ZOO_TABLE_SEARCH . ' AS s ON a.id = s.item_id';

    foreach ($searchData as $searchWord) {

        $searchWord = JString::trim($searchWord);

        $searchWhere[] = implode(' AND ', array(
            'LOWER(s.value) LIKE ' . $this->db->Quote('%' . $this->db->escape($searchWord, true) . '%', false)
        ));
    }

    $where[] = '((' . implode(') OR (', $searchWhere) . '))';
}
Дисклаймер
  • Это хак со всеми вытекающими, т.е после обновления Zoo затрется.
  • Должен подходить практически любым версиям Zoo. 
  • Если сломается, то заметно будет только в админке.
  • Я привел лишь несколько примеров для модификации SQL, если есть со-щие знания, то вы сможете сделать для себя более подходящий вариант.
  • На очень больших сайтах будет тормозить. Надеюсь причины объяснять не нужно =)
  • В JBZoo это не попадет, т.к нет нужного API Zoo. А жаль...

Attached Files

  • Attached File  item.php   29.35KB   181 downloads

  • 8
JBZoo v4.0 и новый чудный мир Open Source GPL
Отключайте проверку лицензий как можно скорее!



— Есть два типа людей: Кто еще не делает бекапы и кто уже делает бекапы.


#2 Vladweb

Vladweb
  • JBZoo User (rus)
  • User rate: -0
  • posts: 85
  • topics: 23

Posted 04 June 2014 - 17:06

Супер! Спасибо огромное!

Не понимаю почему этого нет в самой Zoo...

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

Пока испробовал первый вариант.

 

А вот 4-й вариант это только по каким-то определённым заданным полям или как?


  • 0

#3 Sliapy

Sliapy
  • JBZoo User (rus)
  • User rate: 50.5
  • posts: 6393
  • topics: 15

Posted 04 June 2014 - 17:43

В Zoo этого нет потому, что для него очень много сторонних элементов/расширений (к которым относятся и JBZoo). И у них у каждого свои таблицы в базе - сделать общую выборку здесь "из коробки", как я понимаю, не получится.


  • 0
[color=#aa0000]Не забывайте нажимать кнопку "Вопрос Решён" под сообщением, которое решило Вашу проблему.[/color]

#4 cerber

cerber
  • JBZoo User (rus)
  • User rate: ~
  • posts: 7
  • topics: 0

Posted 05 June 2014 - 12:39

Огромное спасибо!!! 


  • 0

#5 dumitru05

dumitru05
  • JBZoo User (rus)
  • User rate: 0.5
  • posts: 90
  • topics: 18

Posted 17 September 2014 - 13:55

Уважаемый Администратор, покажите пожалуйста как сделать поиск только по ид


  • 0

#6 SmetDenis

SmetDenis
  • Topic Starter
  • Administrators
  • User rate: 139.4
  • posts: 16232
  • topics: 200

Posted 18 September 2014 - 17:18

Должно сработать что-то вроде этого

        if ($search) {
            $search = (int)JString::trim($search);
            $where[] = 'a.id = ' . $search;
        }

  • 1
JBZoo v4.0 и новый чудный мир Open Source GPL
Отключайте проверку лицензий как можно скорее!



— Есть два типа людей: Кто еще не делает бекапы и кто уже делает бекапы.


#7 dumitru05

dumitru05
  • JBZoo User (rus)
  • User rate: 0.5
  • posts: 90
  • topics: 18

Posted 19 September 2014 - 08:05

Должно сработать что-то вроде этого
 

        if ($search) {
            $search = (int)JString::trim($search);
            $where[] = 'a.id = ' . $search;
        }

Спасибо! Работает!!!


  • 0





Also tagged with one or more of these keywords: рецепт, поиск, zoo, хак, панель управления

Click to return to top of page in style!