Упорядочить WP_Query по порядку массива в Tax_Query

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

У меня есть wp_query, который использует tax_query, которому я передаю массив идентификаторов терминов таксономии. Я хотел бы упорядочить свои результаты в соответствии с порядком этого массива, но не могу заставить это работать, и поиск нигде не привел. Пример кода ниже для справки. Таким образом, этот код фактически сортирует результаты по терминам таксономии (счастливая случайность?), но термины таксономии не в том же порядке, что и $term_array. Я пробовал все логические варианты для параметра ‘orderby’, но ничего не сработало, что я нашел.

Думаю, я мог бы сделать foreach на $term_array, но это кажется не самым производительным способом сделать это. Есть ли лучший способ?

Какие-либо идеи?

$term_array = array(3,5,1,4,2);

$args = array(
                'post_type'      => 'product',
                'post_status'    => 'publish',
                'posts_per_page' => -1,
                'orderby'        => 'menu_order',
                'order'          => 'ASC',
              'tax_query' => array(
                array(
                  'taxonomy' => 'product-brands',
                  'field' => 'term_id',
                  'terms' => $term_array,
                  'operator' => 'IN'
                ), 
                array(
                  'taxonomy' => 'product_cat',
                  'field' => 'term_id',
                  'terms' => $main_product_cats
                ), 
              ), 
              'post__not_in' => $not_sold,
            );

      
            $loop = new WP_Query( $args );
            
            if ( $loop->have_posts() ) { ... stuff ... }

Результаты 1,2,3,4,5, а не 3,5,1,4,2 в порядке $term_array

У вас есть

'orderby' => 'menu_order',
'order' => 'ASC',

эти строки определяют порядок постов.

'terms' => $term_array

это просто определяет посты, у которых есть эта таксономия, порядок не имеет значения.

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

Для решения проблемы сортировки результатов WP_Query в том порядке, в котором указаны ID терминов налогономии (taxonomy term IDs) в массиве $term_array, необходимо принимать во внимание, что стандартный WP_Query не поддерживает порядок терминов из переданного массива при использовании tax_query. Давайте разберем, как можно обойти это ограничение и привести результаты в желаемый порядок.

Контекст проблемы

Существует запрос, который используется для получения постов типа ‘product’, но порядок, в котором возвращаются результаты, не соответствует порядку ID терминов в массиве $term_array. Такие параметры, как ‘orderby’ и ‘order’ не могут помочь в этом случае, поскольку они не влияют на порядок термов.

Решение проблемы

Для сортировки постов в зависимости от порядкового номера терминов в массиве, необходимо применить кастомное решение. Ниже рассматривается один из возможных подходов:

Шаг 1: Получение результатов в произвольном порядке

Первоначально создайте обычный WP_Query, который вернет все требуемые посты без учета порядка термов:

$args = array(
    'post_type'      => 'product',
    'post_status'    => 'publish',
    'posts_per_page' => -1,
    'tax_query' => array(
        array(
            'taxonomy' => 'product-brands',
            'field' => 'term_id',
            'terms' => $term_array,
            'operator' => 'IN'
        ),
        array(
            'taxonomy' => 'product_cat',
            'field' => 'term_id',
            'terms' => $main_product_cats
        ),
    ),
    'post__not_in' => $not_sold,
);

$loop = new WP_Query($args);

Шаг 2: Постобработка результатов

После получения результатов необходимо отсортировать их вручную с помощью PHP. Создайте вспомогательную функцию, которая отсортирует массив постов в соответствии с порядком термов в $term_array. Пример может выглядеть следующим образом:

function sort_posts_by_term_order($posts, $term_order, $taxonomy) {
    $sorted_posts = array();

    foreach ($term_order as $term_id) {
        foreach ($posts as $key => $post) {
            $terms = get_the_terms($post->ID, $taxonomy);
            if ($terms && !is_wp_error($terms)) {
                foreach ($terms as $term) {
                    if ($term->term_id == $term_id) {
                        $sorted_posts[] = $post;
                        unset($posts[$key]);
                        break;
                    }
                }
            }
        }
    }
    return $sorted_posts;
}

if ($loop->have_posts()) {
    $post_array = $loop->posts;
    $sorted_posts = sort_posts_by_term_order($post_array, $term_array, 'product-brands');

    // Используйте $sorted_posts для вывода или дальнейшего использования
}

Заключение

Это решение позволяет обойти ограничение стандартного WP_Query и сортировать результаты в соответствии с порядком, заданным пользователем. И хотя такой подход может потребовать дополнительных вычислительных ресурсов, он обеспечивает контроль над порядком вывода данных, что может быть критично для некоторых проектов.

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

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

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