Поиск пользовательского типа записей по метаданным
У меня есть пользовательский тип записи 'Property', который пользователи должны иметь возможность искать по метаданным.
У меня есть 3 функции поиска - 2 на фронтенде и 1 в админке - две из них работают как ожидалось, а одна вообще не фильтрует результаты.
Я думаю, проблема может быть либо в определении, либо в использовании пользовательских query_vars.
В моем functions.php у меня следующее:
function add_query_vars($public_query_vars) {
$public_query_vars[] = 'bedrooms'; // спальни
$public_query_vars[] = 'type'; // тип
$public_query_vars[] = 'location'; // местоположение
return $public_query_vars;
}
add_filter('query_vars', 'add_query_vars');
function meta_search_query($query) {
$query_args_code = array(
'posts_per_page' => 5,
'post_type' => 'nc_property',
'meta_key' => 'nc_code',
'meta_value' => $query->query_vars['s'],
'meta_compare' => 'LIKE'
);
$query_args_meta = array(
'posts_per_page' => -1,
'post_type' => 'nc_property',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'nc_bedrooms',
'value' => $query->query_vars['bedrooms'],
'compare' => 'LIKE'
),
array(
'key' => 'nc_type',
'value' => $query->query_vars['type'],
'compare' => 'LIKE'
),
array(
'key' => 'nc_location',
'value' => $query->query_vars['location'],
'compare' => 'LIKE'
)
)
);
if (is_admin() && $query->is_search ) {
query_posts($query_args_code);
} elseif (!is_admin() && $query->is_search ) {
if ($_REQUEST["which_form"] == 'meta_form') {
query_posts($query_args_meta);
} elseif ($_REQUEST["which_form"] == 'code_form'){
query_posts($query_args_code);
}
}
}
add_filter( 'pre_get_posts', 'meta_search_query');
Поиск по коду свойства работает без проблем как на фронтенде, так и в админке. Однако попытки фильтровать результаты по пользовательским query_vars - location, type и bedrooms - каждый раз терпят неудачу.
Пример строки запроса, которая создается:
/property/?post_type=nc_property&which_form=meta_form&bedrooms=Two&type=Apartment&location=Bahceli
На сайте есть одно свойство, соответствующее этим параметрам, но WordPress каждый раз возвращает все результаты.
Может я что-то упустил?
РЕДАКТИРОВАНИЕ: Оказалось, что поскольку моя форма поиска для мета-запросов не использовала элемент с именем 's', условие $query->is_search
в моем операторе if возвращало false, что означало, что мой meta_query просто не вызывался.
Спасибо fischi за то, что заметил это для меня! :D

В данном случае, так как вы совмещаете красивые постоянные ссылки с параметрами запроса, я бы использовал переменные $_GET
в вашем запросе.
$query_args_meta = array(
'posts_per_page' => -1,
'post_type' => 'nc_property',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'nc_bedrooms',
'value' => sanitize_text_field( $_GET['bedrooms'] ),
'compare' => 'LIKE'
),
array(
'key' => 'nc_type',
'value' => sanitize_text_field( $_GET['type'] ),
'compare' => 'LIKE'
),
array(
'key' => 'nc_location',
'value' => sanitize_text_field( $_GET['location'] ),
'compare' => 'LIKE'
)
)
);
Обязательно используйте правильную санацию в зависимости от ваших потребностей или функцию, которая проверяет разрешенные значения данных $_GET
.
Также проверьте ваши условные функции — изменяйте запрос только если это поисковый запрос (используя параметр s
для поиска) или измените оператор if
.

Я внес рекомендованные изменения, однако результаты поиска по-прежнему не фильтруются, хотя я знаю, что переменные $_GET
корректно определяются, когда я делаю var_dump
...

Можешь посмотреть, какой запрос выполняет твой WordPress? <?php echo $GLOBALS['wp_query']->request; ?>

Запрос выглядит следующим образом: SELECT SQL_CALC_FOUND_ROWS north_posts.ID FROM north_posts WHERE 1=1 AND north_posts.post_type = 'nc_property' AND (north_posts.post_status = 'publish' OR north_posts.post_status = 'private') ORDER BY north_posts.post_date DESC LIMIT 0, 10
Похоже, что мой meta-query просто игнорируется? :/

упс, заметил ещё кое-что - если вы не используете параметр s
, ваше условие if (!is_admin() && $query->is_search )
не выполняется, так как WordPress не понимает, что это поиск. Попробуйте изменить и это.

Вы герой WordPress! То, что одно из полей поиска получило имя 's', решило проблему!
