Запрос $wpdb для цены в значении настраиваемого поля

Вопрос или проблема

Сайт объявлений имеет только 3 критерия при поиске продуктов: общий поиск, категорию и регион (по ZIP, городу или полному адресу). Этого недостаточно, и мне действительно нужно включить базовую ценовую систему, чтобы пользователи могли установить ценовой диапазон перед поиском.

Изучая файлы темы, я нашел функцию для разных запросов на основе одного или нескольких из этих критериев. Самый простой – это запрос только по категории, поэтому я возьму его в качестве примера:

elseif ($s_for == '' && $s_cat !== '' && $s_to == '') {
$query = "SELECT $wpdb->posts.*
FROM
$wpdb->posts
INNER JOIN $wpdb->term_relationships
ON $wpdb->posts.ID = $wpdb->term_relationships.object_id
WHERE
$wpdb->posts.post_type="$cc_post_type"
AND ($wpdb->postmeta.meta_key = '$cc_price' AND $wpdb->postmeta.meta_value LIKE '%$s_prc%')
AND $wpdb->posts.post_status="$cc_post_status"
AND ($wpdb->term_relationships.term_taxonomy_id = {$s_cat})
GROUP BY ID {$limit}";
}

Цены на продукты хранятся в пользовательских полях (cc_price), поэтому я попробовал…

AND ($wpdb->postmeta.meta_key = '$cc_price' AND $wpdb->postmeta.meta_value LIKE '%$s_prc%')

…с помощью простого флажка ($s_prc добавлен в функции) со значением (только для тестирования), но он не работает, “запрос без результатов”. Правильный ли запрос и в чём-то другом я ошибся?

Вы можете попробовать следующее:

AND ($wpdb->postmeta.meta_key = 'cc_price' AND $wpdb->postmeta.meta_value LIKE '%$s_prc%')

(Используйте cc_price вместо $cc_price)

Ответ или решение

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

Теория

WordPress хранит данные в нескольких таблицах в базе данных. Разделение на таблицы позволяет более эффективно управлять данными. В случае использования кастомных полей, значимые данные часто хранятся в таблице postmeta, где каждое поле состоит из трех ключевых параметров: post_id (ID поста), meta_key (ключ метаполя) и meta_value (значение метаполя). Часто эти значения хранятся в текстовом формате, включая числовые данные, что требует дополнительных манипуляций для корректного выполнения числовых сравнений.

Пример

В представленной задаче, вы хотите отфильтровать посты на основании цен, которые хранятся в кастомном поле с ключом cc_price. Исходная попытка фильтрации через LIKE не подходит для цен — это оператор для строковых шаблонов, что не дает возможности использовать его для числовых сравнений. Вместо этого, необходимо разбить вашу задачу на отдельные шаги обработки данных и использовать SQL-операторы BETWEEN, >=, или <=.

Применение

Ниже приведен корректный пример запроса для получения постов в заданном ценовом диапазоне, с учетом специфики работы WordPress:

$min_price = 100; // минимальная цена
$max_price = 1000; // максимальная цена

$query = $wpdb->prepare(
    "SELECT $wpdb->posts.*
    FROM $wpdb->posts
    INNER JOIN $wpdb->term_relationships
    ON $wpdb->posts.ID = $wpdb->term_relationships.object_id
    INNER JOIN $wpdb->postmeta
    ON $wpdb->posts.ID = $wpdb->postmeta.post_id
    WHERE $wpdb->posts.post_type = %s
    AND $wpdb->posts.post_status = %s
    AND $wpdb->term_relationships.term_taxonomy_id = %d
    AND $wpdb->postmeta.meta_key = %s
    AND CAST($wpdb->postmeta.meta_value AS DECIMAL) BETWEEN %d AND %d
    GROUP BY $wpdb->posts.ID
    {$limit}",
    $cc_post_type, $cc_post_status, $s_cat, 'cc_price', $min_price, $max_price
);
$results = $wpdb->get_results($query);

В этом запросе, вы используете CAST для преобразования текстового значения цены в числовой формат, что позволяет корректно использовать SQL-оператор BETWEEN для выбора записей в заданном диапазоне. Это подходящее решение для фильтрации по числовым значениям в WordPress.

Оценив структуру вашей базы данных и корректно используя операторы SQL, вы сможете реализовать нужную функциональность поиска по ценовому диапазону.

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

Капча загружается...