Диагностика проблемы с неактивными вариантами товаров
В крупных магазинах на WooCommerce часто накапливаются устаревшие или неактивные вариации товаров, которые не имеют запаса или не продаются длительное время. Это приводит к засорению базы данных, усложняет администрирование и может негативно влиять на производительность сайта. Встроенных инструментов для автоматического удаления таких вариантов нет, поэтому приходится решать задачу программно.
Как определить неактивные варианты товаров?
- Отсутствие остатков на складе (
_stock= 0 или меньше) - Статус варианта — «черновик» или «приватный» (если используется)
- Вариант не обновлялся или не покупался в течение длительного времени — дополнительный критерий, если есть кастомные метаполя с датами
Чаще всего достаточно ограничиться проверкой наличия на складе.
Пошаговое решение: код для автоматического удаления неактивных вариантов по расписанию
Реализуем wp-cron задачу, которая раз в сутки будет находить и удалять вариации с нулевым запасом.
1. Регистрация wp-cron события
add_action('wp', function() {
if (!wp_next_scheduled('wpb_delete_inactive_variations')) {
wp_schedule_event(time(), 'daily', 'wpb_delete_inactive_variations');
}
});2. Функция удаления неактивных вариаций
add_action('wpb_delete_inactive_variations', function() {
$args = [
'post_type' => 'product_variation',
'posts_per_page' => -1,
'meta_query' => [
[
'key' => '_stock',
'value' => 0,
'compare' => '<=',
'type' => 'NUMERIC'
]
],
'fields' => 'ids',
'post_status' => 'publish'
];
$query = new WP_Query($args);
if ($query->have_posts()) {
foreach ($query->posts as $variation_id) {
wp_delete_post($variation_id, true); // Полное удаление из базы
}
}
});3. Очистка расписания при деактивации плагина или темы
register_deactivation_hook(__FILE__, function() {
$timestamp = wp_next_scheduled('wpb_delete_inactive_variations');
if ($timestamp) {
wp_unschedule_event($timestamp, 'wpb_delete_inactive_variations');
}
});Проверка результата после внедрения
Для проверки работы решения:
- Создайте несколько вариаций товаров с запасом 0 и выше.
- Запустите задачу вручную, вызвав хук через WP-CLI:
wp cron event run wpb_delete_inactive_variations - Проверьте, что вариации с запасом 0 удалились из базы (в админке или через запрос к базе
SELECT * FROM wp_posts WHERE post_type = 'product_variation';). - Убедитесь, что остальные вариации остались без изменений.
Частые ошибки и как их исправить
- Задача не запускается: убедитесь, что WP-Cron включен (константа
DISABLE_WP_CRONне установлена в true), или запустите cron вручную. - Вариации не удаляются: проверьте правильность мета ключа
_stockи типы данных, попробуйте вывестиvar_dump($query->posts)для диагностики. - Удаление не полное: используйте
wp_delete_post($id, true)с параметромtrueдля полного удаления без помещения в корзину. - Конфликты с плагинами кеширования: отключите кеширование на время теста, чтобы видеть актуальные результаты.
Практические советы по безопасности и производительности
- Для крупных магазинов с тысячами вариаций разбивайте удаление на пачки по 50-100, чтобы избежать превышения лимита памяти и времени выполнения. Пример кода с пагинацией:
function wpb_delete_inactive_variations_batch($paged = 1) {
$args = [
'post_type' => 'product_variation',
'posts_per_page' => 100,
'paged' => $paged,
'meta_query' => [
[
'key' => '_stock',
'value' => 0,
'compare' => '<=',
'type' => 'NUMERIC'
]
],
'fields' => 'ids',
'post_status' => 'publish'
];
$query = new WP_Query($args);
if ($query->have_posts()) {
foreach ($query->posts as $variation_id) {
wp_delete_post($variation_id, true);
}
if ($paged < $query->max_num_pages) {
wpb_delete_inactive_variations_batch($paged + 1);
}
}
}
add_action('wpb_delete_inactive_variations', function() {
wpb_delete_inactive_variations_batch();
});- Регулярно создавайте резервные копии базы перед автоматическими удалениями.
- Логируйте удалённые ID вариаций в файл для аудита:
function wpb_log_deleted_variations($variation_id) {
$log_file = WP_CONTENT_DIR . '/deleted_variations.log';
file_put_contents($log_file, date('Y-m-d H:i:s') . " - Удален вариант: {$variation_id}\n", FILE_APPEND);
}
add_action('wp_delete_post', function($postid) {
$post = get_post($postid);
if ($post && $post->post_type === 'product_variation') {
wpb_log_deleted_variations($postid);
}
});Сравнение вариантов автоматического удаления
| Метод | Плюсы | Минусы |
|---|---|---|
| Плагин очистки (например, WP Cleaner) | Простота использования, интерфейс | Может быть тяжеловесным, не всегда гибкий |
| Ручное удаление через админку | Полный контроль | Трудоемко, не подходит для больших магазинов |
| Автоматизация через WP-Cron и кастомный код | Гибкость, интеграция в бизнес-процессы | Требует навыков разработки и тестирования |