Как запретить удаление товаров в WooCommerce после покупки

Диагностика проблемы: зачем запрещать удаление товаров после продажи

В WooCommerce администраторы и менеджеры магазина могут случайно удалить товары, которые уже были куплены клиентами. Это приводит к ошибкам в отчетах, нарушению работы заказов и плохому пользовательскому опыту, когда ссылки на купленные товары становятся нерабочими. Чтобы избежать подобных проблем, полезно запретить удаление товаров, у которых есть выполненные заказы.

Пошаговое решение: как запретить удалять товары с покупками

1. Проверка связей товара с заказами

Для начала нужно определить, есть ли у конкретного товара завершённые заказы. В WooCommerce для этого можно использовать класс WC_Order_Item_Product и запросы через WC_Order_Query.

2. Блокировка удаления товаров через хук WordPress

Основной способ запретить удаление поста (товара — тип записи product) — использовать хук before_delete_post. В нем проверим наличие покупок и отменим удаление при необходимости.

add_action('before_delete_post', function($post_id) {
    // Проверяем, что это товар
    if (get_post_type($post_id) !== 'product') {
        return;
    }

    global $wpdb;

    // Ищем заказы со статусом completed, processing, которые содержат этот товар
    $order_ids = $wpdb->get_col($wpdb->prepare(
        "SELECT DISTINCT order_id FROM {$wpdb->prefix}woocommerce_order_items woi
        JOIN {$wpdb->prefix}woocommerce_order_itemmeta woim ON woi.order_item_id = woim.order_item_id
        JOIN {$wpdb->prefix}posts p ON woi.order_id = p.ID
        WHERE woim.meta_key = '_product_id' AND woim.meta_value = %d
        AND p.post_type = 'shop_order'
        AND p.post_status IN ('wc-completed', 'wc-processing')",
        $post_id
    ));

    if (!empty($order_ids)) {
        // Отменяем удаление
        wp_die('Удаление товара невозможно: товар уже был приобретён в заказах.');
    }
});

3. Предупреждение в админке при попытке удаления

Чтобы улучшить UX, можно добавить предупреждение в интерфейсе админки при попытке удалить такой товар через JavaScript, используя AJAX для проверки заказов. Ниже пример простейшей проверки при загрузке списка товаров.

add_action('admin_footer-edit.php', function() {
    $screen = get_current_screen();
    if ($screen->post_type !== 'product') return;
    ?>
    <script>
    jQuery(document).ready(function($){
        $('.delete a').click(function(e){
            var postId = $(this).closest('tr').attr('id').replace('post-', '');
            var link = $(this);
            e.preventDefault();
            $.post(ajaxurl, {
                action: 'check_product_orders',
                product_id: postId
            }, function(response){
                if(response.hasOrders) {
                    alert('Удаление невозможно: товар уже был куплен.');
                } else {
                    window.location = link.attr('href');
                }
            });
        });
    });
    </script>
    <?php
});

add_action('wp_ajax_check_product_orders', function() {
    $product_id = intval($_POST['product_id']);
    global $wpdb;
    $order_ids = $wpdb->get_col($wpdb->prepare(
        "SELECT DISTINCT order_id FROM {$wpdb->prefix}woocommerce_order_items woi
        JOIN {$wpdb->prefix}woocommerce_order_itemmeta woim ON woi.order_item_id = woim.order_item_id
        JOIN {$wpdb->prefix}posts p ON woi.order_id = p.ID
        WHERE woim.meta_key = '_product_id' AND woim.meta_value = %d
        AND p.post_type = 'shop_order'
        AND p.post_status IN ('wc-completed', 'wc-processing')",
        $product_id
    ));
    wp_send_json(['hasOrders' => !empty($order_ids)]);
});

Проверка результата после внедрения

  • Попробуйте удалить товар с завершённым заказом — система должна блокировать удаление с сообщением.
  • Если удалить товар без заказов — удаление должно пройти без ошибок.
  • В списке товаров нажатие на ссылку удаления товара с заказами должно показывать предупреждение и отменять действие.

Частые ошибки и как их исправить

  • Удаление не блокируется: Проверьте, что код подключён и что тип поста действительно product. Возможно, код не загружается в админке.
  • Проблемы с запросом к базе: Убедитесь, что таблицы WooCommerce имеют стандартные префиксы, и используйте $wpdb->prefix правильно.
  • Админ-скрипт не работает: Проверьте консоль браузера на ошибки JS, убедитесь, что jQuery загружен.
  • Конфликты с другими плагинами: Отключите другие плагины, которые могут вмешиваться в удаление товаров.

Практические советы по безопасности и производительности

  • Используйте кеширование результатов проверки заказов, если на сайте много товаров, чтобы уменьшить нагрузку на базу.
  • Не показывайте детальные ошибки в wp_die на продакшене — лучше логировать и показывать общие сообщения.
  • Регулярно обновляйте WooCommerce и WordPress до последних версий, чтобы избежать уязвимостей и несовместимостей.
  • Для улучшения UX рассмотрите интеграцию с плагинами типа Clearfy Pro (https://wpshop.ru/plugins/clearfy?utm_source=wp3.ru&utm_medium=article&utm_campaign=woocommerce-zapret-udaleniya-tovarov-posle-pokupki) для оптимизации и управления функционалом магазина.

Таблица сравнения способов блокировки удаления товара с покупками

МетодОписаниеПлюсыМинусы
Хук before_delete_post (PHP)Запрет удаления на уровне сервера, блокирует процессНадёжно, невозможно обойтиНет пользовательского предупреждения, только сообщение об ошибке
AJAX-проверка и JS-предупреждениеПоказывает предупреждение в админке перед удалениемУлучшает UX, предупреждает заранееМожно обойти через прямой запрос к базе или CLI
Плагин безопасности WooCommerceГотовые решения с настройкамиПростота установкиМожет влиять на производительность, зависит от стороннего кода
Как использовать WPRemark для автоматического модерирования комментариев в WordPress
31.12.2025
Как использовать WP-Cron для автоматического удаления старого контента в WordPress
07.05.2026
Как избежать проблем с кешированием AJAX-запросов в WooCommerce
23.04.2026
Как создать свой виджет в WordPress с примерами кода
04.12.2025
Как использовать хуки WordPress для расширения функциональности сайта
30.11.2025