Вопрос или проблема
Я добавил атрибуты для фильтрации продуктов на основе их выбора. Например, у меня есть поле с названием ‘плитка’, которое может быть ‘да’ или ‘нет’. Если человек ставит галочку ‘да’, показываются все продукты с атрибутом ‘да’. Все продукты с атрибутом ‘нет’ не отображаются.
Как я могу отобразить все продукты, которые не отфильтрованы, НИЖЕ отфильтрованного запроса (т.е. показывая все продукты с ‘нет’ под фильтром продукта)?
Внутри моего файла functions.php, я полагаю, что вот как осуществляются запросы отфильтрованных продуктов:
function sort_products_by_positive_attributes($query) {
if (!is_admin() && $query->is_main_query() && is_woocommerce()) {
// Сначала вам нужно получить все продукты вместе с количеством их положительных атрибутов
$products_with_scores = [];
if (!empty($query->posts)) {
foreach ($query->posts as $post) {
$product = wc_get_product($post->ID);
$score = get_product_positive_attributes_count($product);
$products_with_scores[$post->ID] = $score;
}
}else {
}
// Затем вы бы отсортировали продукты по их баллу
uasort($products_with_scores, function($a, $b) {
return $b - $a;
});
// После сортировки измените запрос, чтобы упорядочить по ID в отсортированном порядке
$sorted_ids = array_keys($products_with_scores);
$query->set('orderby', 'post__in');
$query->set('post__in', $sorted_ids);
// Запрос для отображения неотфильтрованных здесь
}
}
//add_action('pre_get_posts', 'sort_products_by_positive_attributes');
function get_product_positive_attributes_count($product) {
// Вы бы реализовали логику здесь для подсчета количества положительных атрибутов
$score = 0;
// для каждого атрибута, если он положительный, увеличьте $score
return $score;
}
Ответ или решение
Чтобы отобразить все продукты, не прошедшие фильтр, ниже отфильтрованного списка на вашем сайте WooCommerce, необходимо внести изменения в функцию sort_products_by_positive_attributes
, чтобы учесть и неотфильтрованные товары. В данной статье мы подробно рассмотрим, как добиться такого поведения в WordPress через отладку и корректировку кода, что обеспечит необходимый функционал.
Шаг 1: Изменение функции фильтрации продуктов
В вашей функции, которая уже отвечает за фильтрацию продуктов, необходимо добавить дополнительный запрос, который будет извлекать продукты, у которых атрибут ‘tiled’ установлен на ‘no’. Для этого воспользуемся особенностями WP_Query.
Вот как можно изменить вашу функцию:
function sort_products_by_positive_attributes($query) {
if (!is_admin() && $query->is_main_query() && is_woocommerce()) {
// Получаем все продукты, которые соответствуют положительным атрибутам
$products_with_scores = [];
if (!empty($query->posts)) {
foreach ($query->posts as $post) {
$product = wc_get_product($post->ID);
$score = get_product_positive_attributes_count($product);
$products_with_scores[$post->ID] = $score;
}
}
// Сортировка продуктов по количеству положительных атрибутов
uasort($products_with_scores, function($a, $b) {
return $b - $a;
});
// Получаем ID отфильтрованных продуктов
$sorted_ids = array_keys($products_with_scores);
$query->set('orderby', 'post__in');
$query->set('post__in', $sorted_ids);
// Запрос на извлечение неотфильтрованных продуктов
$non_filtered_query = new WP_Query([
'post_type' => 'product',
'posts_per_page' => -1, // Выведем все
'tax_query' => [
[
'taxonomy' => 'pa_tiled', // Замените на правильное имя таксономии
'field' => 'slug',
'terms' => 'no', // Запрос продуктов с атрибутом 'no'
'operator' => 'IN'
]
],
'post__not_in' => $sorted_ids // Исключаем уже отфильтрованные товары
]);
// Сохраняем все ID из неотфильтрованных запросов, чтобы позже объединить результаты
if ($non_filtered_query->have_posts()) {
$non_filtered_ids = wp_list_pluck($non_filtered_query->posts, 'ID');
// Объединяем ID отфильтрованных и неотфильтрованных товаров
$final_ids = array_merge($sorted_ids, $non_filtered_ids);
$query->set('post__in', $final_ids);
}
}
}
add_action('pre_get_posts', 'sort_products_by_positive_attributes');
function get_product_positive_attributes_count($product) {
$score = 0;
// Здесь вы можете реализовать логику подсчета положительных атрибутов
return $score;
}
Шаг 2: Объяснение кода
В первой части мы устанавливаем условия, при которых функция будет работать только на сторонних страницах WooCommerce. Затем мы собираем и сортируем ID отфильтрованных продуктов.
Во втором ключевом моменте мы создаем новый запрос WP_Query
, который обращается к тем продуктам, у которых атрибут ‘tiled’ установлен на значение ‘no’. Это позволяет нам извлечь все продукты, не прошедшие фильтрацию.
Используя post__not_in
, мы отфильтровываем уже извлеченные продукты, чтобы избежать дублирования. В конце функция объединяет ID отфильтрованных и неотфильтрованных товаров и обновляет основной запрос.
Заключение
Данная модификация кода обеспечит функционал отображения всех продуктов, у которых атрибут ‘tiled’ равен ‘no’, под уже отфильтрованным списком продуктов. Это улучшит пользовательский опыт на сайте и позволит клиентам легче ориентироваться в вашем товарном предложении.
Также рекомендую вам проверить производительность вашего сайта после внесения изменений, чтобы убедиться, что нагрузка не возросла. Если у вас есть дополнительные вопросы или требуется дальнейшая помощь, не стесняйтесь обращаться.