Проблема: накопление старых товаров в истории просмотров и избранном WooCommerce
В WooCommerce многие сайты используют расширения или кастомные решения для хранения истории просмотров товаров и списка понравившихся товаров (wishlist). Со временем эти списки становятся громоздкими и содержат товары, которые пользователь давно не просматривал или которые более неактуальны. Это приводит к ухудшению пользовательского опыта и замедлению работы сайта.
Диагностика проблемы
Для начала нужно понять, как именно реализована история просмотров и список понравившихся товаров на вашем сайте:
- Проверить, какой плагин отвечает за избранное (например, YITH WooCommerce Wishlist, TI WooCommerce Wishlist, или кастомный функционал).
- Понять, где и как хранятся данные: в пользовательских мета данных, в сессиях, в куках или в отдельной таблице базы данных.
- Оценить, сколько товаров содержится в этих списках у активных пользователей.
Для просмотра количества товаров в истории просмотров можно использовать отладчик или запросы к базе данных, например, если история хранится в user meta:
$viewed_products = get_user_meta($user_id, 'viewed_products', true); // массив ID товаров
$count = is_array($viewed_products) ? count($viewed_products) : 0;
echo 'Просмотрено товаров: ' . $count;
Пошаговое решение: автоматическое удаление старых товаров из истории и избранного
1. Добавляем хранение метки времени просмотра товара
Чтобы автоматически удалять старые товары, необходимо сохранять дату последнего просмотра товара. Если у вас нет этой функциональности, можно добавить ее с помощью хука template_redirect и set_user_meta:
add_action('template_redirect', function() {
if (is_singular('product') && is_user_logged_in()) {
$user_id = get_current_user_id();
$product_id = get_the_ID();
$viewed = get_user_meta($user_id, 'viewed_products', true);
if (!is_array($viewed)) {
$viewed = [];
}
// Сохраняем ID товара с меткой времени
$viewed[$product_id] = time();
update_user_meta($user_id, 'viewed_products', $viewed);
}
});
2. Удаляем товары старше заданного периода
Создаем функцию, которая будет очищать историю от товаров, просмотренных более 30 дней назад:
function clean_old_viewed_products() {
$users = get_users(['fields' => ['ID']]);
$threshold = time() - 30 * DAY_IN_SECONDS; // 30 дней
foreach ($users as $user) {
$viewed = get_user_meta($user->ID, 'viewed_products', true);
if (is_array($viewed)) {
$changed = false;
foreach ($viewed as $product_id => $timestamp) {
if ($timestamp < $threshold) {
unset($viewed[$product_id]);
$changed = true;
}
}
if ($changed) {
update_user_meta($user->ID, 'viewed_products', $viewed);
}
}
}
}
Рекомендуется запускать эту функцию по крону или через WP-Cron:
if (!wp_next_scheduled('clean_viewed_products_cron')) {
wp_schedule_event(time(), 'daily', 'clean_viewed_products_cron');
}
add_action('clean_viewed_products_cron', 'clean_old_viewed_products');
3. Аналогично удаляем старые товары из списка избранного
Если используется плагин избранного с хранением даты добавления, можно применить похожий механизм. Например, для кастомного хранения в user meta 'wishlist_products' с форматом ['product_id' => timestamp]:
function clean_old_wishlist_products() {
$users = get_users(['fields' => ['ID']]);
$threshold = time() - 60 * DAY_IN_SECONDS; // 60 дней
foreach ($users as $user) {
$wishlist = get_user_meta($user->ID, 'wishlist_products', true);
if (is_array($wishlist)) {
$changed = false;
foreach ($wishlist as $product_id => $timestamp) {
if ($timestamp < $threshold) {
unset($wishlist[$product_id]);
$changed = true;
}
}
if ($changed) {
update_user_meta($user->ID, 'wishlist_products', $wishlist);
}
}
}
}
if (!wp_next_scheduled('clean_wishlist_products_cron')) {
wp_schedule_event(time(), 'weekly', 'clean_wishlist_products_cron');
}
add_action('clean_wishlist_products_cron', 'clean_old_wishlist_products');
Проверка результата после внедрения
- Войдите под пользователем, у которого есть история просмотров и избранное.
- Просмотрите страницу профиля или используйте отладчик, чтобы вывести содержимое user meta
viewed_productsиwishlist_products. - Проверьте, что товары старше заданного периода удаляются после запуска WP-Cron (можно запустить вручную через WP-CLI:
wp cron event run clean_viewed_products_cron). - Убедитесь, что новые товары добавляются и сохраняются с текущей меткой времени.
Частые ошибки и их исправление
- Неправильный формат хранения данных: Если в user meta хранится просто массив ID без меток времени, автоматическое удаление по дате невозможно. Нужно изменить логику сбора данных, добавив время.
- Отсутствие запуска WP-Cron: Если на сайте мало трафика, WP-Cron может не запускаться регулярно. Для решения — настроить системный cron или запускать задачи вручную.
- Плагин избранного не поддерживает метки времени: В этом случае автоматизация невозможна без кастомизации плагина или перехода на другой плагин с нужным функционалом.
- Проблемы с правами доступа: Убедитесь, что функции работают для всех пользователей, а не только для администратора.
Практические советы по оптимизации и безопасности
- Не храните слишком большие массивы в user meta — это замедляет доступ к базе данных. При большом объеме данных лучше использовать отдельные таблицы.
- Для очистки данных используйте лимитированное количество пользователей за один запуск, чтобы избежать перегрузки сервера.
- При работе с пользовательскими мета данными всегда проверяйте наличие и тип данных перед модификацией.
- Регулярно проверяйте логи cron задач и ошибки PHP, чтобы быстро выявлять сбои.
- Если сайт использует кэширование, убедитесь, что оно не мешает отображению актуальной информации об истории просмотров и избранном.
Сравнение вариантов реализации автоматической очистки истории и избранного
| Метод | Плюсы | Минусы | Компромисс |
|---|---|---|---|
| Кастомный код с user meta и WP-Cron | Гибко, под контролем, не требует сторонних плагинов | Нужно писать и поддерживать код, возможны ошибки | Использовать готовые библиотеки для работы с мета |
| Использование готовых плагинов Wishlist с очисткой | Удобно, поддержка, интерфейс | Может не быть функции удаления по времени, нагрузка на БД | Выбирать плагины с регулярной поддержкой |
| Хранение данных в куках/сессиях | Не нагружает БД | Данные теряются, нельзя удалять по времени на сервере | Использовать для временного хранения, не для истории |