Диагностика проблемы с пустыми вариантами WooCommerce
Пустые варианты товаров в WooCommerce – это варианты, которые не содержат атрибутов, цены или изображения, либо неактивны. Они создают путаницу в админке и на сайте, могут влиять на UX и SEO. Чтобы найти пустые варианты, зайдите в редактирование товара и проверьте все вариации. Однако при большом количестве товаров делать это вручную неудобно.
Как проверить наличие пустых вариантов программно
Используйте следующий SQL-запрос в базе данных WordPress (через phpMyAdmin или WP CLI) для поиска пустых вариаций:
SELECT p.ID, p.post_parent FROM wp_posts p
LEFT JOIN wp_postmeta pm_price ON (p.ID = pm_price.post_id AND pm_price.meta_key = '_price')
WHERE p.post_type = 'product_variation'
AND (pm_price.meta_value = '' OR pm_price.meta_value IS NULL);
Этот запрос возвращает ID вариаций без цены – частый признак пустого варианта.
Пошаговое решение: удаление пустых вариантов через код
Для удаления пустых вариантов без плагинов можно написать скрипт на PHP, который проверит все вариации на наличие цены, атрибутов и активности, а потом удалит пустые:
function delete_empty_variations() {
$args = [
'post_type' => 'product_variation',
'posts_per_page' => -1,
'post_status' => ['publish', 'private', 'draft']
];
$variations = get_posts($args);
foreach ($variations as $variation_post) {
$variation = new WC_Product_Variation($variation_post->ID);
$price = $variation->get_price();
$attributes = $variation->get_attributes();
$status = $variation_post->post_status;
// Условие пустого варианта: нет цены, атрибутов или не опубликован
if (empty($price) || empty($attributes) || $status !== 'publish') {
wp_delete_post($variation_post->ID, true); // принудительно удалить
}
}
}
add_action('init', 'delete_empty_variations');Важное: после запуска скрипта удалите вызов функции, чтобы не удалять варианты при каждом обращении к сайту.
Альтернативный вариант: удаление пустых вариантов выборочно
Если хотите сначала вывести список пустых вариантов для проверки, используйте такой код:
function list_empty_variations() {
$args = [
'post_type' => 'product_variation',
'posts_per_page' => -1,
'post_status' => ['publish', 'private', 'draft']
];
$variations = get_posts($args);
foreach ($variations as $variation_post) {
$variation = new WC_Product_Variation($variation_post->ID);
$price = $variation->get_price();
$attributes = $variation->get_attributes();
if (empty($price) || empty($attributes)) {
error_log('Empty variation ID: ' . $variation_post->ID . ' for product ID: ' . $variation_post->post_parent);
}
}
}
add_action('init', 'list_empty_variations');Проверка результата после удаления
После запуска удаления выполните следующие проверки:
- В админке WooCommerce откройте товары с вариациями – пустых вариаций не должно быть.
- Повторите SQL-запрос для проверки наличия вариаций с пустой ценой – запрос должен вернуть пустой результат.
- Проверьте фронтенд сайта, чтобы убедиться, что вариации корректно отображаются и не показываются пустые варианты.
Частые ошибки и как их исправить
- Удаление активных вариаций: Скрипт может удалить нужные варианты, если условие проверки слишком строгое. Проверьте логи и убедитесь, что фильтры по цене и атрибутам корректны.
- Повторное удаление при каждом заходе: Если функция не удалена из
functions.phpпосле выполнения, она будет запускаться постоянно. Уберите или закомментируйте вызов после одного успешного запуска. - Проблемы с правами: Если скрипт не удаляет варианты, проверьте права пользователя и возможность вызова
wp_delete_post.
Практические советы по безопасности и производительности
- Запускайте удаление на стадии
initтолько один раз, либо через WP-CLI скрипт, чтобы не нагружать сайт. - Перед массовым удалением сделайте резервную копию базы данных.
- Для сайтов с большим количеством товаров используйте пакетную обработку, чтобы избежать таймаутов:
function batch_delete_empty_variations($offset = 0, $batch_size = 50) {
$args = [
'post_type' => 'product_variation',
'posts_per_page' => $batch_size,
'offset' => $offset,
'post_status' => ['publish', 'private', 'draft']
];
$variations = get_posts($args);
if (empty($variations)) return false;
foreach ($variations as $variation_post) {
$variation = new WC_Product_Variation($variation_post->ID);
$price = $variation->get_price();
$attributes = $variation->get_attributes();
if (empty($price) || empty($attributes)) {
wp_delete_post($variation_post->ID, true);
}
}
return true;
}
// Запускайте с разным offset через WP-CLI или cron
| Метод | Плюсы | Минусы |
|---|---|---|
| Удаление через плагин | Удобно, интерфейс, дополнительные проверки | Нагрузка, зависимость от плагина |
| Код в functions.php | Контроль, без лишних плагинов | Риск ошибок, нужно удалять после выполнения |
| WP-CLI скрипт | Безопасно, пакетная обработка, быстро | Требует доступа к серверу, навыки командной строки |