Диагностика задачи: зачем исключать товары по атрибутам
В интернет-магазинах на WooCommerce часто возникает необходимость исключить из корзины и из результатов поиска товары с определёнными атрибутами. Например, если товар является подарочным, бесплатным или же требует особых условий продажи. В стандартном WooCommerce таких настроек нет, поэтому приходится вмешиваться программно.
Как проверить атрибуты товаров в WooCommerce
Атрибуты товаров хранятся в таксономиях в формате pa_имя_атрибута. Например, атрибут "Цвет" — это таксономия pa_color. Чтобы проверить, какие атрибуты есть у товара, используйте следующий код:
global $product;
$attributes = $product->get_attributes();
foreach ( $attributes as $attribute ) {
if ( $attribute->is_taxonomy() ) {
$terms = wp_get_post_terms( $product->get_id(), $attribute->get_name() );
foreach ( $terms as $term ) {
echo $term->slug . ' ';
}
}
}Этот код можно использовать в шаблоне single-product.php или в кастомном плагине для проверки.
Исключение товаров с определённым атрибутом из корзины
Для запрета добавления в корзину товаров с заданным атрибутом используйте фильтр woocommerce_add_to_cart_validation. Например, исключим товары с атрибутом "pa_gift" со значением "yes":
add_filter( 'woocommerce_add_to_cart_validation', 'block_gift_products_from_cart', 10, 3 );
function block_gift_products_from_cart( $passed, $product_id, $quantity ) {
$terms = wp_get_post_terms( $product_id, 'pa_gift', array( 'fields' => 'slugs' ) );
if ( in_array( 'yes', $terms ) ) {
wc_add_notice( 'Товар с атрибутом "Подарок" нельзя добавить в корзину.', 'error' );
return false;
}
return $passed;
}Пояснение
Фильтр проверяет атрибуты и запрещает добавление товара в корзину с ошибкой для пользователя.
Исключение товаров с атрибутом из результатов поиска WooCommerce
По умолчанию WooCommerce выводит все продукты, попадающие под запрос поиска. Чтобы исключить товары по атрибуту, изменим параметры основного запроса на странице поиска с помощью хука pre_get_posts:
add_action( 'pre_get_posts', 'exclude_products_by_attribute_from_search' );
function exclude_products_by_attribute_from_search( $query ) {
if ( ! is_admin() && $query->is_main_query() && $query->is_search() && is_post_type_archive( 'product' ) || is_search() ) {
// Идентификатор термина атрибута для исключения
$term_slug = 'yes';
$taxonomy = 'pa_gift';
$tax_query = array(
array(
'taxonomy' => $taxonomy,
'field' => 'slug',
'terms' => $term_slug,
'operator' => 'NOT IN',
),
);
$query->set( 'tax_query', $tax_query );
}
}Пояснение
Мы добавляем таксономический фильтр, который исключает из результатов поиска товары с атрибутом "pa_gift" = "yes".
Проверка результата после внедрения кода
1. Попробуйте добавить в корзину товар с запрещённым атрибутом; должно появиться сообщение об ошибке, и товар не добавится.
2. Выполните поиск на сайте, включающий эти товары; они не должны отображаться в результатах.
3. Для проверки атрибутов используйте отладочный вывод атрибутов товара (описанный в разделе диагностики).
Частые ошибки и как их исправить
- Неправильное имя таксономии атрибута. Атрибуты всегда имеют префикс
pa_, убедитесь, что используете правильное имя. Ошибка приводит к тому, что товары не фильтруются. - Конфликт с другими плагинами, которые изменяют запросы WooCommerce. В таком случае попробуйте проверить работу на чистой установке или отключить другие плагины.
- Ошибка в логике проверки атрибутов при добавлении в корзину. Используйте
wp_get_post_termsс параметромfields => 'slugs'для корректной проверки.
Практические советы по производительности и безопасности
- Не добавляйте тяжелые операции в фильтры, вызываемые при каждом запросе. Получение терминов всегда кешируется WordPress.
- Для масштабных магазинов лучше реализовывать исключения на уровне SQL через
tax_query, а не дополнительной логикой PHP. - Сообщения для пользователя всегда выводите через
wc_add_notice, чтобы поддерживать UX WooCommerce.
Сравнение вариантов решения задачи
| Метод | Преимущества | Недостатки | Когда использовать |
|---|---|---|---|
| Фильтр добавления в корзину | Простая реализация, контролирует добавление | Не исключает товары из поиска и каталога | Когда нужно только запретить добавление |
| Изменение запроса поиска (tax_query) | Исключает товары из поиска и архива | Не запрещает добавление в корзину | Когда нужно скрыть товары из каталога и поиска |
| Комбинация обоих методов | Полный контроль: исключение из поиска и запрет в корзине | Требует поддержки двух решений | Оптимальный вариант для большинства случаев |