Диагностика проблемы: зачем удалять файлы после отмены заказа
В WooCommerce часто используются загрузки цифровых товаров — документы, лицензии, архивы. При отмене заказа такие файлы обычно остаются на сервере, занимая место и создавая риск утечки. Особенно это критично, если к загрузкам есть ограниченный доступ или они связаны с личными данными. Чтобы избежать накопления ненужных файлов, полезно автоматизировать их удаление после отмены заказа.
Как определить, какие файлы нужно удалять
По умолчанию WooCommerce хранит файлы цифровых товаров в папке uploads и привязывает их к продуктам. Нужно понимать:
- Файлы, загруженные продавцом, или сгенерированные системой (например, лицензии).
- Типы файлов: PDF, ZIP, DOCX и т.п.
- Связь файлов с конкретным заказом — через метаданные заказа или объект товара.
Без корректной идентификации есть риск удалить чужие файлы или оставить ненужные.
Пошаговое решение: удаление файлов после отмены заказа по типу
1. Добавляем хук на смену статуса заказа
add_action('woocommerce_order_status_cancelled', 'wpupload_delete_files_on_cancelled', 10, 1);
function wpupload_delete_files_on_cancelled( $order_id ) {
if ( ! $order_id ) {
return;
}
$order = wc_get_order( $order_id );
if ( ! $order ) {
return;
}
// Обработка каждого товара в заказе
foreach ( $order->get_items() as $item_id => $item ) {
$product = $item->get_product();
if ( ! $product ) {
continue;
}
// Проверяем тип продукта, например только цифровые
if ( $product->is_downloadable() ) {
wpupload_delete_product_files( $product->get_id() );
}
}
}
2. Функция удаления файлов по ID продукта
В этой функции реализуем удаление файлов определенного типа или по шаблону из загрузок.
function wpupload_delete_product_files( $product_id ) {
// Получаем список файлов для загрузок
$downloads = get_post_meta( $product_id, '_downloadable_files', true );
if ( empty( $downloads ) || ! is_array( $downloads ) ) {
return;
}
foreach ( $downloads as $file_key => $file ) {
if ( empty( $file['file'] ) ) {
continue;
}
// Проверяем тип файла по расширению, например удаляем только PDF и ZIP
$file_path = str_replace( home_url('/'), ABSPATH, $file['file'] );
$ext = pathinfo( $file_path, PATHINFO_EXTENSION );
if ( in_array( strtolower($ext), ['pdf', 'zip'] ) && file_exists( $file_path ) ) {
unlink( $file_path );
}
}
}
Проверка результата после внедрения
Чтобы убедиться, что файлы удаляются корректно:
- Создайте тестовый продукт с цифровыми загрузками (PDF, ZIP).
- Сделайте заказ и оплатите.
- Отмените заказ через админку WooCommerce.
- Проверьте, что файлы в папке загрузок, связанные с заказанным продуктом, удалились.
- Проверьте логи ошибок PHP на наличие проблем с правами доступа.
Частые ошибки и как их исправить
- Файлы не удаляются: проверьте права на папку uploads и сам файл, PHP должен иметь право на удаление.
- Удаляются не те файлы: убедитесь, что функция правильно формирует путь к файлу, не удаляя сторонние данные.
- Ошибка с неверным путём: иногда URL заменяется на абсолютный путь некорректно — используйте
wp_normalize_pathиABSPATHдля точности. - Удаление не срабатывает для вариативных товаров: расширьте логику для получения файлов из вариаций.
Практические советы по безопасности и производительности
- Перед удалением файла проверьте, что заказ действительно отменён, чтобы избежать потери данных.
- Используйте транзакции или очереди задач для удаления больших объёмов файлов, чтобы не блокировать сервер.
- Логируйте успешные и неудачные попытки удаления для аудита.
- Резервное копирование загрузок перед автоматическим удалением поможет избежать потерь.
Сравнение вариантов решения
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
| Код через хуки WooCommerce | Автоматическое удаление файлов по событию отмены заказа | Полный контроль, без лишних плагинов | Требует навыков разработки, риск ошибок |
| Использование плагинов очистки | Плагины для управления медиа и очистки файлов | Простота установки и настройки | Может быть избыточно, нагрузка на сайт |
| Ручное удаление | Удаление файлов через FTP или админку | Простота для небольших объемов | Неавтоматично, риск забыть |