Диагностика проблемы: зачем менять статус товара при обновлении заказа
В стандартном WooCommerce нет возможности автоматически изменять статус товара (продукта) при изменении статуса связанного с ним заказа. Такая задача актуальна, если вы ведёте складской учёт или хотите блокировать продажу товара при оформлении заказа, например, при переходе заказа в статус "обработан" или "завершён".
Без автоматизации администратору приходится вручную менять статусы товаров, что неудобно и приводит к ошибкам.
Пошаговое решение: автоматическое изменение статуса товара с помощью кода
1. Определение действия при обновлении статуса заказа
WooCommerce предоставляет хук woocommerce_order_status_changed, который вызывается при изменении статуса заказа. Используем его, чтобы отследить нужные изменения.
add_action('woocommerce_order_status_changed', 'custom_change_product_status_on_order_update', 10, 4);2. Функция для изменения статуса товара
В примере ниже при смене статуса заказа на "completed" мы переводим все товары из заказа в статус "private" (скрываем с витрины). При смене на любой другой статус — возвращаем статус "publish".
function custom_change_product_status_on_order_update($order_id, $old_status, $new_status, $order) {
// Получаем все позиции заказа
foreach ($order->get_items() as $item) {
$product_id = $item->get_product_id();
if (!$product_id) continue;
// Получаем объект продукта
$product = wc_get_product($product_id);
if (!$product) continue;
// Меняем статус продукта в зависимости от статуса заказа
if ($new_status === 'completed') {
// Переводим в private
$post = array(
'ID' => $product_id,
'post_status' => 'private'
);
wp_update_post($post);
} else {
// Возвращаем в publish
$post = array(
'ID' => $product_id,
'post_status' => 'publish'
);
wp_update_post($post);
}
}
}3. Добавление кода в тему или плагин
Добавьте этот код в файл functions.php вашей дочерней темы или создайте свой небольшой плагин. Проверьте, чтобы не было конфликтов с другими плагинами, которые изменяют статусы товаров.
Проверка результата после внедрения
- Создайте тестовый заказ с несколькими товарами.
- Перейдите в админку WooCommerce, измените статус заказа на
completed. - Проверьте в разделе «Товары», что соответствующие товары стали иметь статус
private(исчезли из каталога). - Измените статус заказа обратно, например, в
processingи проверьте, что товары снова доступны (publish).
Частые ошибки и способы их исправления
- Код не срабатывает при изменении статуса заказа: проверьте, что ваш код подключён и нет синтаксических ошибок. Используйте
error_logдля отладки внутри функции. - Статус товара не меняется: убедитесь, что у вас есть права на изменение постов и что ID товара корректно получен через
$item->get_product_id(). - Товары исчезают с сайта, но не должны: используйте условие для фильтрации каких товаров менять, например, по категории или меткам, чтобы не скрывать все подряд.
Практические советы по безопасности и производительности
- Избегайте массового обновления статусов всех товаров в каждом заказе, если заказ содержит много позиций — может нагрузить базу.
- Добавьте проверку на необходимость изменения статуса, чтобы не вызывать
wp_update_postбез причины. - Для контроля доступа к функциям используйте возможности WooCommerce и WordPress, чтобы код срабатывал только для администраторов или нужных ролей.
Сравнение вариантов реализации
| Способ | Плюсы | Минусы |
|---|---|---|
| Ручное изменение статусов товаров | Простота | Ручной труд, ошибки, время |
Код на хуке woocommerce_order_status_changed | Автоматизация, гибкость, без плагинов | Требуется разработка, риски ошибок |
| Специализированный плагин для складского учёта | Готовое решение, поддержка | Стоимость, лишний функционал |