Диагностика задачи: когда и зачем удалять товары по мета-полю
В WooCommerce бывают ситуации, когда нужно массово удалить товары, у которых в мета-данных указано конкретное значение. Например, убрать товары с мета-полем _custom_status со значением archived. Стандартный функционал WooCommerce и WP не предусматривает фильтрацию по мета-полям при массовом удалении, а плагины иногда избыточны или не дают нужных условий.
Пошаговое решение: удаляем товары по мета-полю программно
1. Создаём WP-CLI команду для удаления товаров
WP-CLI — самый удобный инструмент для массовых операций. Ниже пример добавления кастомной WP-CLI команды, которая удалит товары, у которых задано мета-поле с определённым значением.
if ( defined('WP_CLI') && WP_CLI ) {
WP_CLI::add_command('wc-delete-products-by-meta', function($args, $assoc_args) {
$meta_key = $assoc_args['meta_key'] ?? '';
$meta_value = $assoc_args['meta_value'] ?? '';
$batch_size = intval($assoc_args['batch_size'] ?? 50);
if (empty($meta_key) || empty($meta_value)) {
WP_CLI::error('Параметры --meta_key и --meta_value обязательны');
}
$offset = 0;
$deleted = 0;
do {
$query = new WP_Query([
'post_type' => 'product',
'post_status' => 'any',
'posts_per_page' => $batch_size,
'offset' => $offset,
'meta_query' => [
[
'key' => $meta_key,
'value' => $meta_value,
'compare' => '='
]
],
'fields' => 'ids'
]);
$ids = $query->posts;
if (empty($ids)) break;
foreach ($ids as $id) {
wp_delete_post($id, true); // true - удаляет без отправки в корзину
$deleted++;
}
$offset += $batch_size;
} while (count($ids) === $batch_size);
WP_CLI::success("Удалено товаров: $deleted");
});
}2. Запуск команды
В терминале из корня сайта запускаем команду:
wp wc-delete-products-by-meta --meta_key=_custom_status --meta_value=archived --batch_size=100Параметр batch_size необязательный, по умолчанию 50. Он ограничивает количество удаляемых товаров за один запрос, чтобы не перегружать сервер.
Проверка результата
После запуска команды:
- Проверьте в админке WooCommerce раздел Товары — товары с указанным значением мета-поля должны исчезнуть.
- Выполните запрос в базе, чтобы убедиться, что посты удалены:
SELECT ID FROM wp_posts WHERE post_type = 'product' AND ID IN (
SELECT post_id FROM wp_postmeta WHERE meta_key = '_custom_status' AND meta_value = 'archived'
);Запрос не должен возвращать результатов.
Частые ошибки и их исправление
- Команда не запускается: убедитесь, что WP-CLI установлен и доступен. Команда должна быть прописана в файле, который загружается в контексте WP-CLI, например, в functions.php темы или в отдельном плагине.
- Ничего не удаляется: проверьте правильность указания
meta_keyиmeta_value. Ошибки в регистре или лишние пробелы приведут к отсутствию совпадений. - Удаляются не все товары: возможно, мета-данные записаны в разном формате. Проверьте тип данных и попробуйте заменить
compareс=наLIKEдля поиска по подстроке.
Практические советы по безопасности и производительности
- Запускайте массовое удаление на тестовом сайте или делайте полную резервную копию перед операцией.
- Не используйте в
wp_delete_postпараметрforce_delete=false, чтобы не создавать «корзину» и не занимать место. - Для больших баз данных разбивайте удаление на небольшие партии (
batch_size) чтобы избежать превышения лимитов памяти и времени выполнения. - При необходимости можно добавить логирование удалённых ID в файл для последующего аудита.
Альтернативы: плагины и их компромиссы
| Метод | Преимущества | Недостатки |
|---|---|---|
| WP-CLI команда | Гибкое, быстродействующее, не требует интерфейса | Требует доступа к SSH и знаний WP-CLI |
| Плагины массового редактирования (например, Bulk Delete) | Удобный интерфейс, подходит для непрофессионалов | Могут быть медленными, не всегда поддерживают сложные условия по мета-полям |
| SQL-запросы напрямую | Очень быстро, можно сделать произвольные сложные выборки | Риск повредить данные, требует глубоких знаний MySQL и структуры WP |