Диагностика проблемы: почему WC_Order не работает в вашем хукe
Разработчики WooCommerce часто сталкиваются с ситуацией, когда в хукe, например woocommerce_order_status_changed или woocommerce_thankyou, объект WC_Order не передается или не работает должным образом. В результате попытки получить данные заказа через $order = wc_get_order($order_id); приводят к ошибкам или пустым значениям.
Основные причины:
- Неправильно передан ID заказа или объект заказа в функцию обратного вызова.
- Использование хуков, в которых объект заказа еще не инициализирован.
- Ошибки в порядке подключения функций, например, слишком ранний вызов.
Пошаговое решение: корректное получение и использование WC_Order в хуках WooCommerce
1. Определите правильный хук и параметры
Для работы с заказом используйте хуки, которые передают ID заказа или объект заказа. Например:
woocommerce_order_status_changed— передает ID заказа, старый и новый статус.woocommerce_thankyou— передает ID заказа.
Пример правильного подключения к хуку woocommerce_order_status_changed:
add_action('woocommerce_order_status_changed', 'my_custom_order_status_changed', 10, 4);
function my_custom_order_status_changed($order_id, $old_status, $new_status, $order) {
if (!$order) {
$order = wc_get_order($order_id);
}
// Теперь $order — объект WC_Order
// Ваш код здесь
}2. Получите объект заказа из ID внутри функции
Если хук передает только ID, вызовите wc_get_order() для получения объекта:
$order = wc_get_order($order_id);Далее можно работать с методами объекта:
$order->get_billing_email()— email покупателя$order->get_status()— статус заказа$order->get_items()— список товаров
3. Пример функции для отправки кастомного уведомления при смене статуса заказа
add_action('woocommerce_order_status_changed', 'send_custom_email_on_status_change', 10, 4);
function send_custom_email_on_status_change($order_id, $old_status, $new_status, $order) {
if (!$order) {
$order = wc_get_order($order_id);
}
if ($new_status === 'completed') {
$to = $order->get_billing_email();
$subject = 'Ваш заказ #'. $order_id .' выполнен';
$message = 'Спасибо за покупку! Ваш заказ выполнен и готов к отправке.';
wp_mail($to, $subject, $message);
}
}Проверка результата: как убедиться, что WC_Order используется корректно
1. Включите режим отладки WordPress (define('WP_DEBUG', true); в wp-config.php) для выявления ошибок.
2. Добавьте логирование для проверки объекта заказа:
error_log(print_r($order, true));3. Проверьте, что функция вызывается и переменная $order — это объект WC_Order, а не null или false.
4. Для проверки email уведомления можно использовать плагин WP Mail Logging или аналогичный.
Частые ошибки и как их исправить
- Ошибка:
Call to a member function get_billing_email() on null
Причина: объект$orderне получен (null).
Решение: убедитесь, что вызываетеwc_get_order($order_id)внутри функции, если объект не передан. - Ошибка: Функция не вызывается при смене статуса заказа.
Причина: неправильное количество аргументов вadd_action.
Решение: укажите правильное число аргументов, например,10, 4дляwoocommerce_order_status_changed. - Ошибка: Использование хуков до инициализации WooCommerce.
Решение: подключайте свои функции после загрузки WooCommerce, например, вplugins_loadedили позднее.
Практические советы по безопасности и производительности
- Не храните в сессии или опциях объекты WC_Order — это увеличит нагрузку и может вызвать ошибки сериализации.
- Используйте кэширование при частом обращении к данным заказа, например,
wp_cache_get/set. - При отправке писем используйте встроенные функции WooCommerce для email, чтобы избежать проблем с форматированием и совместимостью.
- Проверяйте права пользователя, если функция связана с пользовательскими действиями, чтобы избежать уязвимостей.
Сравнение способов получения объекта WC_Order
| Способ | Плюсы | Минусы |
|---|---|---|
| Использовать объект, переданный в хук | Быстро, без дополнительного запроса к БД | Не во всех хуках доступен |
Получить объект через wc_get_order($order_id) | Работает везде, где есть ID | Дополнительный запрос к базе |