Проблема: необходимость исключить товары из связанных на основе метаданных
В WooCommerce часто возникает задача исключить из блока связанных товаров определённые позиции, например, товары с определённым значением пользовательского поля (метаданных). Это нужно для повышения релевантности рекомендаций, например, чтобы не показывать товары из акции, устаревшие модели или товары с ограничениями.
Диагностика проблемы
Стандартный функционал WooCommerce не предоставляет гибкой настройки исключения товаров из связанных по метаданным. При использовании функции get_related() или виджета «Связанные товары» фильтрация происходит по категориям и тегам, но не по произвольным полям.
Если вы пытались реализовать исключение через стандартные фильтры, но товары по метаданным всё равно показываются, значит, необходимо вмешаться в SQL-запрос или использовать фильтр WooCommerce для построения списка связанных товаров.
Пошаговое решение: исключаем товары по метаданным через фильтр 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) {
// Проверяем, не пустой ли массив связанных товаров
if (empty($related_posts)) {
return $related_posts;
}
foreach ($related_posts as $key => $related_id) {
$exclude = get_post_meta($related_id, '_exclude_from_related', true);
if ($exclude === 'yes') {
unset($related_posts[$key]);
}
}
// Переиндексация массива после удаления
$related_posts = array_values($related_posts);
return $related_posts;
}Добавьте этот код в файл functions.php вашей дочерней темы или в кастомный плагин.
Пояснения
- Метаполе
_exclude_from_related— пример, используйте своё, которое есть на сайте. - Значение
yes— то, по которому исключаем товар. - Функция перебирает массив связанных товаров и исключает нежелательные.
Проверка результата после внедрения
Чтобы проверить, что исключение работает:
- Откройте товар, у которого есть связанные товары.
- Убедитесь, что товары с метаданными
_exclude_from_related = yesне отображаются в блоке связанных товаров. - Для теста можно временно вывести ID связанных товаров через
var_dump($related_posts)внутри фильтра.
Частые ошибки и как исправить
- Пустой массив после фильтрации: Если исключаете слишком много товаров, связанных может не остаться. В этом случае WooCommerce покажет товары из категорий. Проверьте логику исключения.
- Метаданные не считываются: Убедитесь, что метаполе существует у товара и значение строго совпадает с проверяемым.
- Кэширование: Если используете кэширование (например, через плагин), обновите кэш, иначе изменения не отобразятся.
- Неправильное место вставки кода: Код должен быть в
functions.phpдочерней темы или в плагине, не в родительской теме, чтобы не потерять при обновлении.
Практические советы по производительности и безопасности
- Оптимизация запросов: При большом каталоге товаров избегайте сложных SQL-запросов в фильтре. Лучше использовать кеширование результатов.
- Безопасность: Не доверяйте значениям метаданных, полученным извне, и не выводите их напрямую без проверки.
- Кэширование: Для больших сайтов внедрите объектный кеш или кэширование на уровне сервера (Redis, Memcached), чтобы избежать лишних запросов к базе при фильтрации.
- Проверка совместимости: Перед внедрением на продакшн тестируйте на тестовой среде с теми же версиями WooCommerce и PHP.
Альтернативные способы: таблица сравнения
| Метод | Плюсы | Минусы | Использование |
|---|---|---|---|
Фильтр woocommerce_related_products | Простой, гибкий, без изменения SQL | Обрабатывает уже выбранные товары, не влияет на выборку | Лучше для исключения небольшого количества товаров |
Изменение SQL запроса через posts_clauses | Полный контроль над выборкой | Сложнее, риск ошибок, нагрузка на БД | Для сложных условий фильтрации |
| Использование плагинов для кастомизации связанных товаров | Никакого кода, готовые решения | Может влиять на производительность, ограниченная гибкость | Для пользователей без опыта программирования |