Как отсортировать товары по просмотрам и по дате публикации?
Добрый день, есть плагин Post Views Counter который генерирует свою БД как я понял.
Можно использовать meta поле post_views - количество просмотров товара
Цель: отсортировать товары по просмотрам и по дате публикации и сделать это сортировкой по-умолчанию на странице товаров.
Сам сайт
У меня получилось лишь вывести сортировку и отобразить товары с просмотрами. Остальные товары из магазина не отображаются так как просмотров у них ещё нет. Как сделать, чтобы допустим вывелся сначала массив товаров с просмотрами и был отсортирован от больших просмотрам к меньшему (+желательно после этого ещё отсортирован от нового к старому)
А затем после вывести стандартный массив с сортировкой нового к старому?
add_filter('posts_orderby', 'orderbyreplace' ); add_filter('woocommerce_catalog_orderby', 'add_custom_sorting_options', 999999 ); function add_custom_sorting_options($options) { $options['post_views'] = 'Popularity'; return $options; } $meta_query = array( 'relation' => 'AND', 'post_views' => array( 'key' => 'post_views', 'compare' => 'EXISTS', ), 'date' => array( 'key' => 'date', 'compare' => 'EXISTS', 'type' => 'NUMERIC' ) ); $args['meta_query'] = $meta_query; $args['orderby'] = array( 'post_views' => 'DESC', 'date' => 'ASC' // Изменено на сортировку по дате от нового к старому ); $loop = new WP_Query($args); remove_filter('posts_orderby', 'orderbyreplace'); |
add_filter('posts_orderby', 'orderbyreplace' ); add_filter('woocommerce_catalog_orderby', 'add_custom_sorting_options', 999999 ); function add_custom_sorting_options($options) { $options['post_views'] = 'Popularity'; return $options; } $meta_query = array( 'relation' => 'AND', 'post_views' => array( 'key' => 'post_views', 'compare' => 'EXISTS', ), 'date' => array( 'key' => 'date', 'compare' => 'EXISTS', 'type' => 'NUMERIC' ) ); $args['meta_query'] = $meta_query; $args['orderby'] = array( 'post_views' => 'DESC', 'date' => 'ASC' // Изменено на сортировку по дате от нового к старому ); $loop = new WP_Query($args); remove_filter('posts_orderby', 'orderbyreplace');
Дополнительно:
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Проблема возникает из-за сортировки по мета-полю: если у товара нет
post_views, он не попадает в выборку или оказывается не там, где ожидаете. Нужно либо присвоить всем товарам значение просмотров0, либо строить запрос так, чтобы показывались товары и с мета-полем, и без него.Самый простой практичный вариант — один раз проставить нулевые просмотры товарам, у которых поля нет:
$products = get_posts([ 'post_type' => 'product', 'posts_per_page' => -1, 'fields' => 'ids', 'meta_query' => [ [ 'key' => 'post_views', 'compare' => 'NOT EXISTS', ], ], ]); foreach ($products as $product_id) { update_post_meta($product_id, 'post_views', 0); }
После этого можно сортировать по просмотрам и дате:
add_action('woocommerce_product_query', function ($query) { if (is_admin() || ! $query->is_main_query()) { return; } $query->set('meta_key', 'post_views'); $query->set('orderby', [ 'meta_value_num' => 'DESC', 'date' => 'DESC', ]); });
Если просмотры хранит именно Post Views Counter в отдельной таблице, а не в post meta, сортировка через
meta_keyне сработает корректно. Тогда нужно смотреть документацию плагина: у него могут быть свои функции или фильтры для сортировки. Для WooCommerce на больших каталогах лучше не делать тяжёлые meta query без индексов, иначе сортировка начнёт тормозить.Для сортировки «сначала популярные, потом новые» иногда удобнее сделать два запроса: первый берёт товары с просмотрами, второй добирает товары без просмотров. Потом массивы объединяются. Это проще контролировать, но хуже для пагинации. Если нужна нормальная пагинация WooCommerce, лучше всё-таки привести данные к единому виду и хранить
post_views = 0у всех товаров.