Поиск по произвольным полям.


Я рассчитываю на аудиторию, которая уже понимает как работают операторы MySQL и как строить GET или POST запрос.
Прежде чем начинать работать с поиском его надо включить в админке плагина есть галочка.

Поиск можно осуществлять либо через GET запрос, то есть сформировать соответствующий URL (ссылку), либо по средствам POST – отправив данные через форму поиска.
Фильтр обработчик запросов находится в файле ads_filters.php – строка 167 function ads_queryfilter($query) и function ads_wp_request($query_vars) строка 321.

Общий синтаксис запроса:
имя_переменной[оператор] = значение
оператор в квадратных скобках может отсутствует
имя_переменной = значение

Список операторов:

оператора нет LIKE ‘%$value%’ (ищет вхождение строки)
more > (больше)
less < (меньше)
moe >= (больше или равно)
loe <= (меньше или равно)
ne ( не равно )
isnull ISNULL ( если пусто )
notnull NOT ISNULL( если не пусто )
between BETWEEN (проверка диапазона)
in IN (принадлежность к множеству)
rlike rlike (регулярные выражения)

Простейший пример:
http://wp.od.ua/test/?ads_name=петр
Результат получим не совсем то, что ожидали, тоесть найдутся все записи в которых есть вхождение петр, причем регистр не учитывается. Это есть не что иное как SQL оператор LIKE, причем выражение взято в проценты вот так:
ads_name LIKE ‘%петр%’
В предыдущих версиях плагина я решил, что от простого знака равно толку мало и поставил LIKE, ну так оно и осталось пока – жалоб не поступало, и практика показала, что так намного функциональные. Теперь, когда мы знаем про оператор LIKE давайте найдем все объявления с почтой @gmail.com:
http://wp.od.ua/test/?ads_email=gmail.com

Рас уж начали с поиска строк то попробуем усложнить – используем регулярные выражения SQL оператор rlike.
Найдем объявления от автора Петр, чтобы было именно такое имя а не вхождение строки :
http://wp.od.ua/test/?ads_name[rlike]=(^| )Петр($| )
Url в браузере будет преобразован в http://wp.od.ua/test/?ads_name[rlike]=(^|%20)%D0%9F%D0%B5%D1%82%D1%80($|%20)
А сам патерн такой : (^| )Петр($| )

Найдем записи у которых поле цена ads_price больше 1000:
http://wp.od.ua/test/?ads_price[more]=1000
Объявления где цена меньше либо равно 1000:
http://wp.od.ua/test/?ads_price[loe]=1000

ОТ и ДО – диапазон от 1000 до 5000 :
http://wp.od.ua/test/?ads_price[between][0]=1000&ads_price[between][1]=5000
ads_price[between][0]=1000 – задаем нижнюю границу
ads_price[between][1]=5000 – задаем верхнюю границу
Как вариант можно сделать и так:
http://wp.od.ua/test/?ads_price[moe]=200&ads_price[loe]=5000
но по производительности between лучше.

Объявления у которых не указан телефон:
http://wp.od.ua/test/?ads_phones[isnull]=1

Пример с IN (принадлежность к множеству):
http://wp.od.ua/test/?ads_price[in][]=200&ads_price[in][]=750&ads_price[in][]=1000
Найдет все об. у которых цена равна 200 либо 750 либо 1000 – пример немного надуманный, но для иллюстрации механизма пойдет.

Комбинирование условий

Найдем записи у которых цена в диапазоне от 1000 до 5000 и есть в наличии телефон:
http://wp.od.ua/test/?ads_price[moe]=200&ads_price[loe]=5000&ads_phones[notnull]=1

Из определенной категории например куплю продам:
http://wp.od.ua/test/?ads_price[moe]=200&ads_price[loe]=5000&ads_phones[notnull]=1&category_name=kuplyu-prodam

Можно подключить стандартный поиск WordPress. Если мы хотим найти какую-то фразу в заголовке или основном тексте используем переменную s. Найдем записи в которых есть слово Путин и цена меньше 4000:
http://wp.od.ua/test/?ads_price[loe]=4000&s=Путин

Поиск по категориям

WordPress позволяет задавать очень сложные запросы оперирую таксономиями http://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters в плагине я добавил обработчик параметра category__and таким образом мы можем затребовать записи из разных категорий объедения условия через логическое И.
Получить записи из категории Москва(id:5) И Куплю\продам(id:10)
http://wp.od.ua/test/?category__and[]=5&category__and[]=10
Этот параметр обрабатывает фильтр function ads_wp_request.

И еще больше расширений

Если вам перечисленных возможностей недостаточно то для каждой переменной можно назначить свою пользовательскую функцию, имя функции должно начинаться с названия переменной и суффикса _query. Так для переменной ads_quality можно назначить свою функцию которая должна вернуть правильный SQL текст с условием поиска и обязательное условие в тексте должен первым идти оператор AND:

Организуем продвинутый поиск по дате post_date стандартное поле WP.
Если указан ключ dmoe ищем объявления начиная от этой даты и старше.
Если указан ключ day ищем записи за этот день.
В ads_config.php добавляем наш обработчик:

‘;
if(is_array($var) )
list($key, $val) = each($var);
if($key==’dmoe’)
return ” AND $wpdb->posts.post_date >= STR_TO_DATE( $val, ‘%Y-%m-%d’) “;
elseif($key==’day’)
return ” AND TO_DAYS($wpdb->posts.post_date) = TO_DAYS( “.$var['day'].”) “;
}
[/crayon]
Теперь можно проверить – ищем объявления за 2013-06-08 (формат даты соблюдать!) и цена от 750:
http://wp.od.ua/test/?post_date[day]=2013-06-08&ads_price[moe]=750

Вариант 2 найдем записи из категории Москва:5 И продам:18 начиная с марта 2013:
http://wp.od.ua/test/?category__and[]=5&category__and[]=18&post_date[dmoe]=2013-03-01

Диапазон по возрасту

Еще пример – поиск в диапазоне по возрасту пример с сайта http://musme.ru/musicians в качестве элемента управления используется слайдер ion.rangeSlider, как он подключается это вопрос отдельный, нам же надо знать, что этот элемент пришлет на сервер в переменой ads_old двойное значение например 20;30 то есть искать музыканта от 20 до 30 лет например.
В ads_old у нас хранится дата рождения в формате 1974-03-31 – хороший формат позволяет сравнивать строку с годом(число) без лишних преобразований и форматирований.
Теперь нам надо обработать двойное значение от слайдера:

Сортировка

Чтобы задать сортировку записей по какому либо полю используйте след синтаксис:
ads_order[ads_name_var]=sort где
ads_name_var имя поля по которому вы хотите задать сортировку;
sort указание типа сортировки может принимать след значения :

  • asc по возрастанию
  • desc по убыванию
  • iasc по возрастанию с конвертацией в число
  • idesc по убыванию с конвертацией в число

Например найдем записи у которых указано имя и отсортируем записи по алфавиту
http://wp.od.ua/test/?ads_order[ads_name]=asc&ads_name[notnull]=1
SQL: ORDER BY ads_name.meta_value ASC

Как я уже говорил выше, кроме простой сортировки есть сортировка с принудительной конвертацией значений к числу. Дело в том, что в мета полях, если вы записываете число, то оно сохраняется как строка т.к. тип столбца строковый, поэтому, если в мета поле хранится число то надо использовать вместо asc iasc.
Найдем записи у которых есть цена и отсортируем по возрастанию:
http://wp.od.ua/test/?ads_order[ads_price]=iasc&ads_price[notnull]=1
SQL: ORDER BY ads_price.meta_value+0 ASC
Сортировку можно комбинировать в этом случае имеет значение порядок переменных первый получает высший приоритет.

З.Ы.
Ну и напоследок, хочу обратить выше внимание на замечательную функцию worpdpress add_query_arg() при конструировании url ссылок может сильно облегчить вашу задачу.

Комментарии 48 к “Поиск по произвольным полям.”

  1. Евгений:

    Выключил и включил функцию “Включить ads_queryfilte – поиск по метаполям” в админке плагина и она перестала работать. Теперь при ее включении, происходит какой-то странный редирект на страницу поиска, вообще не понимаю как это происходит… Раньше она была включена и поиск по метаполям работал. Дадите совет?

  2. Евгений:

    Версия 4.0.0. По-моему не в версии дело, раньше же все нормально работало. А тут вдруг слетело. Перезапускал плагин, ничего…

  3. Александр:

    Здравствуйте. С помощью шорткодов на статичной странице организовал форму для обьявлений. Скажите, а как можно организовать на другой странице поиск по полям объявлений, а так же по мета полям? Где и как нужно использовать ваши фильтры обработчики запросов? Поясните, пожалуйста, вкратце или ссылочку дайте, в какую сторону копать?

  4. Sophi:

    Здравствуйте, я хотела бы сделать такой же поиск как указан у вас на сайте http://irent.com.ua/?s=, вроде бы сделала все как указано: и searchform.php b searchpage.php создала, все критерии поиска показывает, но одна беда- не ищет. Как это все связать?

  5. Александр:

    Здравствуйте.

    А как отсортировать список записей по произвольному полю ads_price?

  6. Сергей:

    Здравствуйте.
    Не могли бы вы более подробно объяснить, как организовать поиск по произвольным полям?
    То есть как я представляю, нужно создать html форму для поиска и поместить ее, скажем, на отдельной странице. Но как сделать так, чтобы поиск заработал? Можно хотя бы ссылку на примеры “оживления формы поиска”…
    С программированием почти не знаком, изучаю все на ходу, так сказать…

  7. Асхат:

    Еще раз Привет из Казахстана!!!
    Спасибо за плагин Ads-Wordpress!!!
    Создаю шаблоны с нуля для WordPress
    Как организовать поиск по рубрикам , по произвольным полям, сортировка по ценам, диапазон цен … ?
    также есть шаблон search.php
    Мучаюсь уже вторую неделю (((

    • admin:

      в комплекте плагина идет виджет поиска – он сделан в качестве примера, вот смотри как там сделано. в плагинах надо активировать виджеты Ads-Widgets, и у тебя появится виджет Ads_Search_Form
      правила поисковых запросов описаны в статье ну уже не знаю чем еще помочь…

  8. Христофор:

    Доброго дня!
    У вас бита ссилка: http://wp.od.ua/test/?ads_name=%D0%BF%D0%B5%D1%82%D1%80 і ця,
    http://wp.od.ua/test/?ads_email=gmail.com Це так задумано?

    Детально перечитав саттю, але відповіді не знайшов. В налаштування плагіна є “Исключить рубрики id через запятую ads_exclude exemple:” що успішно працює, але при пошуку обяв шукає із категорій які я виключив. Як заборонити пошук з таких категорій? Дякую!

  9. Marlen:

    А как отправить запрос вроде

    SELECT * FROM testdb.wp_postmeta WHERE meta_key LIKE ‘ads_dokname%’ AND meta_value=’документ’

    Дело в том что я хочу сделать поиск по нескольким “мета полям” где значение например равен документ.

    Запрос ?ads_dokname1=документ выводит только те записи где мета поле ads_dokname1
    а у меня они могут быть ads_dokname1 ads_dokname2 ads_dokname3 ads_dokname4…

    • admin:

      с именами полей ничего не выйдет, так как ты хочешь,
      только так
      Запрос ?ads_dokname1=документ&ads_dokname2=документ&ads_dokname3=документ…

      вообще такого быть не должно ты неправильно спроектировал структуры данных
      опиши подробнее что надо попробую помочь

  10. Добрый день!
    Воспользовался виджетом для поиска в сайдбаре – ads_widgets.php.
    При этом вылетает ошибка в виджете – Warning: Illegal string offset ‘ads_base_category’ in /home/bh56385/public_html/wp-content/plugins/ads-wordpress/ads_widgets.php on line 113
    Так-же Ошибка в line 123.
    Это ошибка в функции -$ads_base_category = slug_to_term_id($ads_options['ads_base_category'],’category’);
    и $ads_location_root = slug_to_term_id($ads_options['ads_location_root'],’category’);

    Разбираясь обнаружил, что в таблице wp_options не прописаны ‘ads_base_category’ и ‘ads_location_root’.
    Подскажите что я должен сделать что-бы эти значения прописать. Понимаю, что я что-то упустил в настройках плагина.

    • В админ панели “Родительская рубрика ее подкатегории будут доступны в объявлении для выбора рубрики ads_base_category” родительская рублика выбрана.

    • admin:

      зайти в настройки плагина и установить эти опции, также можно это сделать на странице формы прописать их как атрибуnы шоткода AdsForm

      • В настройках плагина в разделе “рублики”
        ads_base_category = 13
        ads_location_root = 100
        установлены.
        При заходе на сайт – все работает. Но стоит мне зайти в меню выбора категории. В виджете вылетает вышеназванная ошибка.
        В базе данных эти параметры прописаны. (Первый раз не заметил).
        Полазил по кодам в функциях ads_widget, ads_init, ads_function. Все нормально и все должно работать, но однако не работает.
        Может посмотрите – http://reklama-24.su/. (Нажать – дать объявление)

        • admin:

          странное поведение однако, уже исправил в след обновлении,
          пока для вас в этом же файле строка 111
          global $ads_options;
          заменить
          $ads_options = get_option(‘ads_options’);

          • Спасибо за помощь! Ошибка в виджете исчезла.
            Однако, виджет стал неработоспособен в следующем:
            Теперь в виджете в полях “рублики” и “район” (использую пример classfields) выпадают все рублики сайта. Т.е похоже не видно также функцию slug_to_term_id().
            Для информации: если в переменную $ads_base_category пишу непосредственно значение все работает.
            P.S. Вашу строчку 114 раскомментировал – в этом поле пусто.
            P.P.S. У остальных работает?

          • admin:

            так еще раз, в админке плагина вы установили значение ads_base_category и ads_location_root?

  11. king:

    Добрый вечер! Как в виджет поиска добавить выбор “действие”, ну как в примере – Ильичевск – доска объявлений. Я ставил готовый вариант доски, как “Ильичевск” classfields, но оказалось, что вижджет-поиск косячный, так как сначала нормально ищет, а потом, если продолжить поиск, перестает работать (искать).
    В общем решил в стандартный ваш виджет-поиск добавить подобное – выбор “действие”, но не получается вывести только рубрики – actions, выводятся сразу все рубрики, а надо только в actions! // select Действие
    $ actions = slug_to_term_id($ ads_options['actions'],’category’);
    //echo ‘;print_r($ actions);echo ‘';
    $select_act = wp_dropdown_categories(
    array('child_of' =>$actions,
    'hide_empty' => 0, 'hierarchical' => 1,
    'name'=>'category__and[]','echo'=>0)
    );
    $ select_act = preg_replace('~]+>~',
    '-----',$select_act);

    ?php _e('Действие', 'ads-wordpress')?:
    ?=$select_act; ?

    • king:

      Вопрос снят, до самого дошло как сделать. )) Теперь возникла проблема поворотом фотографий, один раз поворачивается, а потом зависает, при этом фото в полном размере показывается (оригинал).

      • admin:

        да это такой страный глюк он то есть то нет, на одних сайтах работает нормально, на других глючит, я думаю это мало памяти у php вот он не может поворот сделать и нарезать тумбочки, а попробуй маленькую картинку загрузить 400х400 примерно

    • admin:

      а что глючит -то ? вот эта сборка стоит и виджет от нее http://irent.com.ua/?cat=119 сколько не искал все на месте

      • king:

        Виснет выбор рубрики, как я понял, то есть выбрал одну рубрику и только в ней поиск идет, потом, что не выбираю из рубрик, все-равно остается только поиск в той рубрике, которую изначально выбрал. Решил, что может чего накосячил сам я, но вернув все файлы стандартные(мною измененные полностью убрал), но всё по-прежнему. А вот стандартный виджет-поиск в плагине отлично работает.

        • admin:

          а какой виснет ?

          • king:

            Виснут рубрики в виджете Ads_Classfields расширенный поиск, который в конфиге прописан. В общем, вот что еще заметил, если искать с главной страницы сайта, то расширенный поиск-виджет работает нормально, но если сначала выбрать рубрику и тут начать искать, то зависает на этой рубрике. И еще, если объявления выводятся на главную страницу сайта, и в пагинации выбрать другую страницу, то вообще при поиске выдало 404 – не найдена страница.

          • admin:

            можно ссылку посмотреть, что там

          • Алексей:

            Присоединяюсь к предыдущему вопросу у меня такая же ерунда получается. С главной страницы поиск работает нормально, но со страницы записи (объявления) искать перестает. Например, я захожу на объявление “продажа комнаты”, в этом случае в форме поиска выбрано: рубрика – “комнаты”, тип объявления – “продажа” – все правильно! Но, если поменять “комнаты” на “2 комнатные”, то показывается страница с результатом поиска, но только с этим же объявлением (“продажа комнаты”), а значения из формы поиска остаются первоначальными (рубрика – “комнаты”, тип объявления – “продажа”). При этом адрес страницы с результатом поиска выглядит так:
            САЙТ.РУ/ПРОДАЖА_КОМНАТЫ.ХТМЛ?category__and%5Bads%5D=199&category__and%5Bads_location…
            Если в ручную удалить из адресной строки: “ПРОДАЖА_КОМНАТЫ.ХТМЛ”, то все работает как надо!
            Помогите, пожалуйста!

          • admin:

            кириллический домен или это просто просто пример?

          • admin:

            я понял в чем дело, в форме поиска атрибут action устанавливается равным текущей записи

          • admin:

            а вообще у меня нормально работает странно вот попробуй поиск http://wp.od.ua/classfields/

          • Алексей:

            Спасибо! Разобрался: у меня почему-то в форме ads_searchform отсутствовал атрибут action=”"

  12. Андрей:

    Здравствуйте, Юрий!
    Заметил, что в результатах поиска вместе с записями выводятся все страницы (в указанном вами сайте _irent.com.ua тоже: “Дать объявление”, “Контакты”). Как сделать, чтобы выводились только записи?

  13. Юлия Р.:

    Добрый день!

    Подскажите, пожалуйста, как сделать так, чтобы при применении ads_order внутри категории не выводилась страница Архив, а выводилась именно страница с категорией?
    Сейчас у меня урл example.com/category1/ выводится как страница категории, т.е. вверху шаблон темы показывает название категории, всё как надо. А урл example.com/category1/?ads_order[ads_name]=iasc выводит абсолютно те же самые записи, но на странице Архив (т.е. тема подтягивает шаблон архива). Как этого избежать?

  14. admin:

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

    в берем шаблон архива
    и там в самом начале втыкаем: проверяем если есть ads_order

  15. Роман:

    Как сделать чтобы выводило при поиске статьи как в архиве? С картинками? То есть по шаблону Index.php

  16. Антон:

    Подскажите пожалуйста, как на главной страничке WP вывести посты с учетом сортировки.
    http://сайт/?ads_orderads_lastdate=desc
    Что и куда нужно прописать?
    Пробовал добавить в functions.php эту функцию:

    function wpdocs_five_posts_on_homepage( $query ) {
    if ( $query->is_home() ) {
    $query->set( ‘ads_order[ads_lastdate]‘, ‘desc’ );
    }
    }
    add_action( ‘pre_get_posts’, ‘wpdocs_five_posts_on_homepage’ );

    Результат нулевой.

Добавить комментарий для Геннадий Отменить ответ

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url=""> [php]…[/php] [html]…[/html] [css]…[/css] [text]…[/text] [code]…[/code]