Диагностика проблемы: почему нужно исключать товары по метаданным
В стандартном WooCommerce связанные товары подбираются на основе категорий, тегов или атрибутов, но иногда требуется исключить из этих списков определённые товары — например, товары с метаданными «скрыть из связанных» или товары, у которых закончился срок акции. Без фильтрации такие товары будут показываться клиентам, что снижает качество рекомендаций и может негативно влиять на конверсию.
Как проверить, какие товары нужно исключить
Для начала убедитесь, что у товаров, которые хотите исключить, есть уникальное мета-значение. Например, мета-поле _exclude_from_related со значением yes. Проверить это можно так:
global $wpdb;
$results = $wpdb->get_results("SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_exclude_from_related' AND meta_value = 'yes'");
print_r($results);Если этот запрос возвращает товары, вы можете использовать это мета-значение для исключения.
Пошаговое решение: исключаем товары из связанных по метаданным
Для исключения товаров по метаданным используйте фильтр WooCommerce woocommerce_related_products. Он позволяет изменить массив ID связанных товаров перед выводом. Вот пример кода, который исключает товары с метаполем _exclude_from_related равным yes:
add_filter('woocommerce_related_products', 'exclude_products_by_meta_from_related', 10, 3);
function exclude_products_by_meta_from_related($related_posts, $product_id, $args) {
$filtered = [];
foreach ($related_posts as $related_id) {
$exclude = get_post_meta($related_id, '_exclude_from_related', true);
if ($exclude !== 'yes') {
$filtered[] = $related_id;
}
}
return $filtered;
}Добавьте этот код в файл functions.php вашей темы или в кастомный плагин.
Расширение: исключение по нескольким метаданным
Если нужно исключать товары по нескольким метаполям, например, и _exclude_from_related и _hide_from_cross_sell, можно расширить функцию:
add_filter('woocommerce_related_products', 'exclude_products_multiple_meta', 10, 3);
function exclude_products_multiple_meta($related_posts, $product_id, $args) {
$filtered = [];
foreach ($related_posts as $related_id) {
$exclude1 = get_post_meta($related_id, '_exclude_from_related', true);
$exclude2 = get_post_meta($related_id, '_hide_from_cross_sell', true);
if ($exclude1 !== 'yes' && $exclude2 !== 'yes') {
$filtered[] = $related_id;
}
}
return $filtered;
}Проверка результата после внедрения
Чтобы проверить, что исключение работает:
- Создайте или отредактируйте товар, добавьте метаданные
_exclude_from_relatedсо значениемyes. - Откройте страницу другого товара, чтобы увидеть блок связанных товаров.
- Убедитесь, что товар с мета-данными не отображается в списке связанных.
Если хотите убедиться программно, можно вывести ID связанных товаров до и после фильтрации:
add_filter('woocommerce_related_products', function($related_posts, $product_id, $args) {
error_log('До фильтра: ' . implode(',', $related_posts));
$filtered = [];
foreach ($related_posts as $related_id) {
$exclude = get_post_meta($related_id, '_exclude_from_related', true);
if ($exclude !== 'yes') {
$filtered[] = $related_id;
}
}
error_log('После фильтра: ' . implode(',', $filtered));
return $filtered;
}, 10, 3);Частые ошибки и как их исправить
- Ошибка: Товары не исключаются.
Причина: Метаполе указано неверно, или значение отличается от «yes».
Решение: Проверьте метаданные через админку или базу, убедитесь в точности ключа и значений. - Ошибка: Пустой список связанных товаров.
Причина: Все связанные товары имеют мета «exclude», либо фильтр возвращает пустой массив.
Решение: Добавьте fallback в функцию, чтобы если массив пуст, вернуть оригинальный список. - Ошибка: Функция не срабатывает.
Причина: Код не загружается (не в functions.php или нет плагина).
Решение: Проверьте подключение кода, используйтеerror_logили var_dump для отладки.
Практические советы по безопасности и производительности
- Используйте
get_post_metaс третьим параметромtrueдля получения одиночного значения — это быстрее. - Кэшируйте результаты, если исключение применяется часто, чтобы не дергать базу лишний раз.
- Не используйте тяжелые запросы внутри фильтров, чтобы не замедлять вывод страницы товара.
- Добавляйте проверки на существование поста и тип товара, если фильтр может применяться к разным типам записей.
Сравнение методов исключения товаров из связанных
| Метод | Плюсы | Минусы |
|---|---|---|
Фильтр woocommerce_related_products | Простота, гибкость, не требует изменений в базе | Зависит от количества связанных товаров, может замедлить страницу при большом числе |
| SQL-запросы в кастомном плагине | Более точечный контроль, можно оптимизировать под базу | Сложнее писать, риск ошибок в запросах, требует навыков SQL |
| Использование плагина для управления метаданными | Удобство работы с метаполями через админку | Потенциально лишний плагин, может конфликтовать с другими |