Диагностика проблемы: зачем удалять старые товары и отсутствующие варианты
В магазинах на WooCommerce с течением времени накапливаются товары, которые устарели, сняты с производства или имеют отсутствующие варианты (вариации). Они не только создают хаос в админке, но и замедляют работу сайта, увеличивают размер базы данных и снижают удобство для покупателей. Ручное удаление таких товаров — трудоемкий и ошибочно-опасный процесс. Автоматизация удаления помогает поддерживать каталог в актуальном состоянии без лишних затрат времени.
Как определить товары и варианты для удаления
Сценарии для удаления:
- Товары со статусом «Черновик» или «Ожидает проверки» старше N дней.
- Товары, у которых нет активных вариаций или все вариации имеют статус «нет в наличии».
- Товары, не продававшиеся или не обновлявшиеся в течение длительного времени (например, 6 месяцев).
Пример SQL-запроса для поиска товаров без вариаций
SELECT p.ID, p.post_title FROM wp_posts p LEFT JOIN wp_posts v ON v.post_parent = p.ID AND v.post_type = 'product_variation' WHERE p.post_type = 'product' AND v.ID IS NULL AND p.post_status = 'publish';Этот запрос вернет опубликованные товары без вариаций.
Пошаговое решение: автоматизация удаления через WP-Cron и пользовательскую функцию
1. Создаем функцию для удаления товаров и вариаций
function wpmonitor_delete_old_and_missing_products() {
$days_threshold = 180; // 6 месяцев
$date_threshold = date('Y-m-d H:i:s', strtotime('-' . $days_threshold . ' days'));
// 1. Получаем товары, не обновлявшиеся более 6 месяцев
$args = [
'post_type' => 'product',
'post_status' => 'publish',
'date_query' => [
'column' => 'post_modified',
'before' => $date_threshold,
],
'fields' => 'ids',
'posts_per_page' => -1,
];
$old_products = get_posts($args);
foreach ($old_products as $product_id) {
$product = wc_get_product($product_id);
if (!$product) continue;
// Проверяем наличие вариаций
if ($product->is_type('variable')) {
$variations = $product->get_children();
// Проверяем, есть ли вариации в наличии
$has_available_variation = false;
foreach ($variations as $variation_id) {
$variation = wc_get_product($variation_id);
if ($variation && $variation->is_in_stock()) {
$has_available_variation = true;
break;
}
}
// Если нет доступных вариаций — удаляем товар
if (!$has_available_variation) {
wp_delete_post($product_id, true);
}
} else {
// Для простых товаров проверяем наличие
if (!$product->is_in_stock()) {
wp_delete_post($product_id, true);
}
}
}
// 2. Удаляем товары без вариаций вообще
$args_no_variations = [
'post_type' => 'product',
'post_status' => 'publish',
'fields' => 'ids',
'posts_per_page' => -1,
'meta_query' => [],
];
$products = get_posts($args_no_variations);
foreach ($products as $p_id) {
$variations = wc_get_product($p_id)->get_children();
if (empty($variations)) {
wp_delete_post($p_id, true);
}
}
}2. Регистрируем WP-Cron задачу
add_action('wpmonitor_delete_old_products_hook', 'wpmonitor_delete_old_and_missing_products');
if (!wp_next_scheduled('wpmonitor_delete_old_products_hook')) {
wp_schedule_event(time(), 'daily', 'wpmonitor_delete_old_products_hook');
}3. Добавляем отмену задачи при деактивации плагина или темы
function wpmonitor_deactivate_cleanup() {
$timestamp = wp_next_scheduled('wpmonitor_delete_old_products_hook');
if ($timestamp) {
wp_unschedule_event($timestamp, 'wpmonitor_delete_old_products_hook');
}
}
register_deactivation_hook(__FILE__, 'wpmonitor_deactivate_cleanup');Проверка результата после внедрения
- Проверьте наличие товаров, которые должны были удалиться (старше 6 месяцев и отсутствующие варианты).
- Посмотрите лог событий (можно добавить логирование в функцию удаления с помощью
error_logили плагина для логов). - Убедитесь, что удаление происходит корректно без удаления нужных товаров.
Частые ошибки и как их исправить
- Удаляются нужные товары. Проверьте логику условий — возможно, стоит увеличить порог времени или добавить дополнительные проверки.
- WP-Cron не запускается. Убедитесь, что на сайте есть посещения (WP-Cron запускается по ним) или настройте системный cron для вызова
wp-cron.php. - Функция не удаляет вариации. Проверьте, что используете правильные методы WooCommerce для получения вариаций и их статусов.
Практические советы по безопасности и производительности
- Добавляйте проверку прав пользователя, если планируете запускать функцию вручную из админки.
- Используйте транзиенты или кеш, чтобы избежать повторного запуска удаления в течение дня.
- Перед удалением создавайте резервные копии базы данных, особенно на больших магазинах.
- Для отчетности можно интегрировать отправку уведомлений на email после каждого запуска скрипта.
Сравнение подходов к автоматизации удаления старых товаров
| Метод | Плюсы | Минусы | Когда применять |
|---|---|---|---|
| Ручное удаление через админку | Просто, без кода | Трудозатратно, риск ошибок | Небольшие магазины, редко |
| Пользовательская функция с WP-Cron (как в статье) | Автоматизация, гибкие условия | Нужны знания PHP, потенциальные ошибки | Средние и крупные магазины |
| Плагины очистки и оптимизации (напр. Clearfy Pro) | Удобно, поддержка, доп. функции | Платные, ограниченная кастомизация | Если нужны комплексные решения |