Прошу прощения если дублирую вопрос, но я так и не нашел подобного на форуме.
Как сделать фильтр постов по рейтингу?
На данный момент на сайте есть фильтр по произвольным полям:
<label>Сортировка: <select name="sort_price"> <option value="">Сортировать</option> <option value="1">По цене (сначала дешевые)</option> <option value="2">По цене (сначала дорогие)</option> <option value="3">По рейтингу (* -> ***)</option> <option value="4">По рейтингу (*** -> *)</option> </select> </label>
if ($_GET['sort_price'] != '') { if ($_GET['sort_price'] == 1) { $args['meta_key'] = 'cena_100'; $args['orderby'] = 'meta_value_num'; $args['order'] = 'ASC';} if ($_GET['sort_price'] == 2) { $args['meta_key'] = 'cena_100'; $args['orderby'] = 'meta_value_num'; $args['order'] = 'DESC';} }
Как сюда же прикрутить фильтрацию по рейтингу?
Заранее благодарю за помощь.
попробуйте вставить такой код в файл функций используемой темы:
add_action( 'pre_get_posts', 'pre_get_filter' ); function pre_get_filter($query) { if ( ! is_admin() && $query->is_main_query() ) { if(isset($_GET['sort_price']) && in_array($_GET['sort_price'], array(3,4))){ $rcl_rating = new Rcl_Rating_Totals_Query(); $postIds = $rcl_rating->get_row(array( 'rating_type' => 'post', 'orderby' => 'rating_total', 'order' => ($_GET['sort_price'] == 3)? 'DESC': 'ASC', 'fields' => array( 'object_id' ) )); if($postIds){ $query->set('post__in',$postIds); } } } }
Андрей, благодарю за оперативный ответ
Андрей CS сказал(а)
попробуйте вставить такой код в файл функций используемой темы:
К сожалению, ничего не получилось. Страница ничего не выдает. Либо я не понял как правильно вызвать это событие.
Привожу весь код функции сортировки:
function go_filter() { $args = array(); $args['meta_query'] = array('relation' => 'AND'); global $wp_query; if ($_GET['status_obyavleniya_77'] != '') { $args['meta_query'][] = array( 'key' => 'status_obyavleniya_77', 'value' => $_GET['status_obyavleniya_77'], ); } if ($_GET['price_ot'] != '' || $_GET['price_do'] != '') { if ($_GET['price_ot'] == '') $_GET['price_ot'] = 0; if ($_GET['price_do'] == '') $_GET['price_do'] = 9999999; $args['meta_query'][] = array( 'key' => 'cena_100', 'value' => array( (int)$_GET['price_ot'], (int)$_GET['price_do'] ), 'type' => 'numeric', 'compare' => 'BETWEEN' ); } if ($_GET['photo'] != '') { $args['meta_query'][] = array( 'key' => '_thumbnail_id', ); } if ($_GET['keyword'] != '') { $args['s'] = $_GET['keyword']; } if ($_GET['sort_price'] != '') { if ($_GET['sort_price'] == 1) { $args['meta_key'] = 'cena_100'; $args['orderby'] = 'meta_value_num'; $args['order'] = 'ASC';} if ($_GET['sort_price'] == 2) { $args['meta_key'] = 'cena_100'; $args['orderby'] = 'meta_value_num'; $args['order'] = 'DESC';} do_action('pre_get_posts'); } query_posts(array_merge($args,$wp_query->query)); }
Буду рад, если вы поможете разобраться.
Андрей CS сказал(а)
ну тогда проверяйте, содержится ли что то в $postIds, по идее должен формировать массив ИД публикаций
Теперь я совсем запутался. Андрей, в вашей функции не срабатывает условие $query->is_main_query()
, что, наверное, логично, ведь go_filter выводится перед циклом. Если это условие убрать, то в $postIds передается всего лишь айди одного поста. Если же go_filter вывести внутри цикла, то страница будет очень долго обрабатываться, и в итоге ничего не покажет. Или я не понимаю как вывести функцию внутри цикла...
Андрей CS сказал(а)
точно, вместо get_row надо прописать get_col
Круто! Мы получили массив с айдишниками постов в нужном порядке (правда в массиве нет постов с нулевым рейтингом, зато есть посты из других категорий), но как теперь заставить показывать эти посты в том порядке, который мы получили?
Андрей, спасибо за ответы и что поддерживаете!
Всем спасибо за помощь. Всё примерно работает. Вот только одно но. Для сортировки функция берет rating_total из wp_rcl_rating_totals и, соответственно, при применении рейтинга "звездочками" происходит неверная сортировка. Например, у одного поста количество звезд 3,5, а тотал рейтинг 8, у другого поста звезд на 5, а тотал рейтинг тоже 5. Вот и пост с фактическим низким рейтингом оказывается выше того, что собрал больше звезд.
Как можно сделать, чтобы для сортировки брался средний рейтинг (как для отображения звезд), а не rating_total?