Wp_query фильтровать по одному полю, а сортировать по-другому?

Ссылка скопирована
API
1 ответ

Всем привет.
Столкнулся с проблемой.
У поста есть 2 custom fields.
loop_event_date - дата, когда произойдет мероприятие.
featured - Закрепить как первое в списке.

add_action('rest_api_init', 'eventsApiPosts'); function eventsApiPostsFunc($data) {   $term_slug = $data['term_slug'] ?? null;   $date = $data['date'];   $now = date('Y-m-d');   $current_page = $data['current_page'];   $lang = $data['lang'];    if ($date) {     if ($date === 'coming-soon') {       $meta_query = array(         array(           'key' => 'loop_event_date',           'value' => $now,           'compare' => '>',           'type' => 'DATE'         )       );     } else if ($date === 'past-events') {       $meta_query = array(         array(           'key' => 'loop_event_date',           'value' => $now,           'compare' => '<',           'type' => 'DATE'         )       );     } else {       $meta_query = array(         array(           'key' => 'loop_event_date',           'value' => $date,           'compare' => 'LIKE'         )       );     }   }    $tax_query = [];   if ($term_slug) {     $tax_query = array(       array(         'taxonomy' => 'events_category',         'field' => 'slug',         'terms' => [$term_slug],       )     );   }     $post_type = 'events';   $posts_per_page = 3;   $offset = ($current_page * $posts_per_page) - $posts_per_page;    $post_events = new WP_Query(array(     'post_type' => $post_type,     'order' => 'ASC',     'posts_per_page' => $posts_per_page,     'offset' => $offset,     'tax_query' => $tax_query,     'meta_key'       => 'loop_event_date', // Meta key for filtering     'orderby'        => 'meta_value', // Order by meta value     'order'          => 'ASC', // Order direction, you can change this t     'meta_query' => $meta_query,     'meta_key' => 'featured', // Meta key for sorting     'orderby' => 'meta_value', // Order by meta value as numeric     'order' => 'ASC',   ));   $total_posts = $post_events->found_posts;   $pages = ceil($total_posts / $posts_per_page);   $events_array = $post_events->get_posts();   $events_array = array_map(function ($event) use ($lang) {     $id = $event->ID;     $title = get_the_title($id);     $term = get_the_terms($id, 'events_category')[0];     if ($lang === 'ro') {       $location = get_field('title_ro', $term);     } else {       $location =  $term->name;     }     $loop = get_field('loop', $id);     $event_date = $loop['event_date'];     $short_description = $loop['short_description'];     $image = get_the_post_thumbnail_url($id);     return [       'id' => $id,       'title' => $title,       'location' => $location,       'event_date' => $event_date,       'featured' => get_field('featured', $id),       'short_description' => $short_description,       'image' => $image,       'lang' => $lang,       'term_name' => $term->name,       'permalink' => get_the_permalink($id),     ];   }, $events_array);   $count = count($events_array);   return [     'lang' => $lang,     'total' => $total_posts,     'count' => $count,     'pages' => $pages,     'current_page' => $current_page,     'events' => $events_array,     'offset' => $offset,     'current_page' => $current_page,     'posts_per_page' => $posts_per_page,   ]; }

add_action('rest_api_init', 'eventsApiPosts'); function eventsApiPostsFunc($data) { $term_slug = $data['term_slug'] ?? null; $date = $data['date']; $now = date('Y-m-d'); $current_page = $data['current_page']; $lang = $data['lang']; if ($date) { if ($date === 'coming-soon') { $meta_query = array( array( 'key' => 'loop_event_date', 'value' => $now, 'compare' => '>', 'type' => 'DATE' ) ); } else if ($date === 'past-events') { $meta_query = array( array( 'key' => 'loop_event_date', 'value' => $now, 'compare' => '<', 'type' => 'DATE' ) ); } else { $meta_query = array( array( 'key' => 'loop_event_date', 'value' => $date, 'compare' => 'LIKE' ) ); } } $tax_query = []; if ($term_slug) { $tax_query = array( array( 'taxonomy' => 'events_category', 'field' => 'slug', 'terms' => [$term_slug], ) ); } $post_type = 'events'; $posts_per_page = 3; $offset = ($current_page * $posts_per_page) - $posts_per_page; $post_events = new WP_Query(array( 'post_type' => $post_type, 'order' => 'ASC', 'posts_per_page' => $posts_per_page, 'offset' => $offset, 'tax_query' => $tax_query, 'meta_key' => 'loop_event_date', // Meta key for filtering 'orderby' => 'meta_value', // Order by meta value 'order' => 'ASC', // Order direction, you can change this t 'meta_query' => $meta_query, 'meta_key' => 'featured', // Meta key for sorting 'orderby' => 'meta_value', // Order by meta value as numeric 'order' => 'ASC', )); $total_posts = $post_events->found_posts; $pages = ceil($total_posts / $posts_per_page); $events_array = $post_events->get_posts(); $events_array = array_map(function ($event) use ($lang) { $id = $event->ID; $title = get_the_title($id); $term = get_the_terms($id, 'events_category')[0]; if ($lang === 'ro') { $location = get_field('title_ro', $term); } else { $location = $term->name; } $loop = get_field('loop', $id); $event_date = $loop['event_date']; $short_description = $loop['short_description']; $image = get_the_post_thumbnail_url($id); return [ 'id' => $id, 'title' => $title, 'location' => $location, 'event_date' => $event_date, 'featured' => get_field('featured', $id), 'short_description' => $short_description, 'image' => $image, 'lang' => $lang, 'term_name' => $term->name, 'permalink' => get_the_permalink($id), ]; }, $events_array); $count = count($events_array); return [ 'lang' => $lang, 'total' => $total_posts, 'count' => $count, 'pages' => $pages, 'current_page' => $current_page, 'events' => $events_array, 'offset' => $offset, 'current_page' => $current_page, 'posts_per_page' => $posts_per_page, ]; }

Так отоображаются 6 постов, но при добавлении

'meta_key' => 'featured', // Meta key for sorting     'orderby' => 'meta_value', // Order by meta value as numeric     'order' => 'ASC',

'meta_key' => 'featured', // Meta key for sorting 'orderby' => 'meta_value', // Order by meta value as numeric 'order' => 'ASC',

Только 3.

Дополнительные вопросы

Ответы:

Во первых у вас повторяются ключи в аргументах wp query
Второе - вы уверены что ваш код располагается где надо ?
Отображается три потому что у трех других вероятно отсутствует мета featured. Вам надо compare exists

  • Я его немного поменял
    function eventsApiPosts() {   register_rest_route('events/v1', 'posts', [     'methods' => WP_REST_SERVER::READABLE,     'callback' => 'eventsApiPostsFunc',   ]); }  add_action('rest_api_init', 'eventsApiPosts'); function eventsApiPostsFunc($data) {   $term_slug = $data['term_slug'] ?? null;   $date = $data['date'];   $now = date('Y-m-d');   $current_page = $data['current_page'];   $lang = $data['lang'];    if ($date) {     if ($date === 'coming-soon') {       $meta_query = array(         array(           'key' => 'loop_event_date',           'value' => $now,           'compare' => '>',           'type' => 'DATE'         )       );     } else if ($date === 'past-events') {       $meta_query = array(         array(           'key' => 'loop_event_date',           'value' => $now,           'compare' => '<',           'type' => 'DATE'         )       );     } else {       $meta_query = array(         array(           'key' => 'loop_event_date',           'value' => $date,           'compare' => 'LIKE'         )       );     }   }    $tax_query = [];   if ($term_slug) {     $tax_query = array(       array(         'taxonomy' => 'events_category',         'field' => 'slug',         'terms' => [$term_slug],       )     );   }     $post_type = 'events';   $posts_per_page = 3;   $offset = ($current_page * $posts_per_page) - $posts_per_page;    $post_events = new WP_Query(array(     'post_type' => $post_type,     'posts_per_page' => $posts_per_page,     'offset' => $offset,     'tax_query' => $tax_query,     'meta_query' => $meta_query,     // 'orderby' => 'meta_value', // Order by meta value as numeric     // 'meta_key' => 'featured', // Meta key for sorting     // 'meta_type' => 'DATE', // Meta type     // 'order' => 'DESC',   ));   $total_posts = $post_events->found_posts;   $pages = ceil($total_posts / $posts_per_page);   $events_array = $post_events->get_posts();   $events_array = array_map(function ($event) use ($lang) {     $id = $event->ID;     $title = get_the_title($id);     $term = get_the_terms($id, 'events_category')[0];     if ($lang === 'ro') {       $location = get_field('title_ro', $term);     } else {       $location =  $term->name;     }     $loop = get_field('loop', $id);     $event_date = $loop['event_date'];     $short_description = $loop['short_description'];     $image = get_the_post_thumbnail_url($id);     return [       'id' => $id,       'title' => $title,       'location' => $location,       'event_date' => $event_date,       'featured' => get_field('featured', $id),       'short_description' => $short_description,       'image' => $image,       'lang' => $lang,       'term_name' => $term->name,       'permalink' => get_the_permalink($id),     ];   }, $events_array);   $count = count($events_array);   return [     'lang' => $lang,     'total' => $total_posts,     'count' => $count,     'pages' => $pages,     'current_page' => $current_page,     'events' => $events_array,     'offset' => $offset,     'current_page' => $current_page,     'posts_per_page' => $posts_per_page,   ]; }

    function eventsApiPosts() { register_rest_route('events/v1', 'posts', [ 'methods' => WP_REST_SERVER::READABLE, 'callback' => 'eventsApiPostsFunc', ]); } add_action('rest_api_init', 'eventsApiPosts'); function eventsApiPostsFunc($data) { $term_slug = $data['term_slug'] ?? null; $date = $data['date']; $now = date('Y-m-d'); $current_page = $data['current_page']; $lang = $data['lang']; if ($date) { if ($date === 'coming-soon') { $meta_query = array( array( 'key' => 'loop_event_date', 'value' => $now, 'compare' => '>', 'type' => 'DATE' ) ); } else if ($date === 'past-events') { $meta_query = array( array( 'key' => 'loop_event_date', 'value' => $now, 'compare' => '<', 'type' => 'DATE' ) ); } else { $meta_query = array( array( 'key' => 'loop_event_date', 'value' => $date, 'compare' => 'LIKE' ) ); } } $tax_query = []; if ($term_slug) { $tax_query = array( array( 'taxonomy' => 'events_category', 'field' => 'slug', 'terms' => [$term_slug], ) ); } $post_type = 'events'; $posts_per_page = 3; $offset = ($current_page * $posts_per_page) - $posts_per_page; $post_events = new WP_Query(array( 'post_type' => $post_type, 'posts_per_page' => $posts_per_page, 'offset' => $offset, 'tax_query' => $tax_query, 'meta_query' => $meta_query, // 'orderby' => 'meta_value', // Order by meta value as numeric // 'meta_key' => 'featured', // Meta key for sorting // 'meta_type' => 'DATE', // Meta type // 'order' => 'DESC', )); $total_posts = $post_events->found_posts; $pages = ceil($total_posts / $posts_per_page); $events_array = $post_events->get_posts(); $events_array = array_map(function ($event) use ($lang) { $id = $event->ID; $title = get_the_title($id); $term = get_the_terms($id, 'events_category')[0]; if ($lang === 'ro') { $location = get_field('title_ro', $term); } else { $location = $term->name; } $loop = get_field('loop', $id); $event_date = $loop['event_date']; $short_description = $loop['short_description']; $image = get_the_post_thumbnail_url($id); return [ 'id' => $id, 'title' => $title, 'location' => $location, 'event_date' => $event_date, 'featured' => get_field('featured', $id), 'short_description' => $short_description, 'image' => $image, 'lang' => $lang, 'term_name' => $term->name, 'permalink' => get_the_permalink($id), ]; }, $events_array); $count = count($events_array); return [ 'lang' => $lang, 'total' => $total_posts, 'count' => $count, 'pages' => $pages, 'current_page' => $current_page, 'events' => $events_array, 'offset' => $offset, 'current_page' => $current_page, 'posts_per_page' => $posts_per_page, ]; }

  • Сергей Бурдужа, делайте ассоциативные мета запросы и потом сортируйте по ним
    если у вас featured поле может отсутвутвовать для записей - делайте для него OR запрос с EXISTS
Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
2
Мария Код Ответ

В WP_Query можно фильтровать по одному custom field, а сортировать по другому. Для этого используйте именованные условия в meta_query и указывайте нужное условие в orderby. В вашем случае, например, можно отфильтровать мероприятия по дате, а закреплённые выводить выше через поле featured.

Общий пример:

$query = new WP_Query([
    'post_type'      => 'events',
    'posts_per_page' => 10,
    'meta_query'     => [
        'relation' => 'AND',
        'event_date_clause' => [
            'key'     => 'loop_event_date',
            'value'   => date('Y-m-d'),
            'compare' => '>=',
            'type'    => 'DATE',
        ],
        'featured_clause' => [
            'key'     => 'featured',
            'compare' => 'EXISTS',
            'type'    => 'NUMERIC',
        ],
    ],
    'orderby' => [
        'featured_clause'   => 'DESC',
        'event_date_clause' => 'ASC',
    ],
]);

$query = new WP_Query([ 'post_type' => 'events', 'posts_per_page' => 10, 'meta_query' => [ 'relation' => 'AND', 'event_date_clause' => [ 'key' => 'loop_event_date', 'value' => date('Y-m-d'), 'compare' => '>=', 'type' => 'DATE', ], 'featured_clause' => [ 'key' => 'featured', 'compare' => 'EXISTS', 'type' => 'NUMERIC', ], ], 'orderby' => [ 'featured_clause' => 'DESC', 'event_date_clause' => 'ASC', ], ]);

Если поле featured есть не у всех записей, сортировка может вести себя неожиданно. Тогда лучше при сохранении записи всегда записывать туда 0 или 1, а не оставлять поле пустым.

Для REST API не забывайте чистить входные параметры:

$date = isset($data['date']) ? sanitize_text_field($data['date']) : '';
$current_page = max(1, (int) ($data['current_page'] ?? 1));

$date = isset($data['date']) ? sanitize_text_field($data['date']) : ''; $current_page = max(1, (int) ($data['current_page'] ?? 1));

Если нужно показывать будущие мероприятия, фильтруйте дату через meta_query. Если нужно дополнительно закреплять некоторые записи сверху, сортируйте сначала по featured, потом по дате. Главное — указывать правильный type: для дат DATE, для чисел NUMERIC. Иначе WordPress будет сортировать значения как строки.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

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

Вам также может быть интересно