Как исправить ошибку 'Invalid Order' в шаблонах PDF для WooCommerce
Узнайте, как исправить ошибку 'Invalid Order' при создании пользовательских шаблонов PDF в плагине WooCommerce PDF Invoices & Packing Slips с правильной регистрацией и мерами безопасности.
Как исправить ошибку “Invalid Order” при генерации второго пользовательского шаблона PDF в плагине WooCommerce PDF Invoices & Packing Slips?
Я использую плагин WooCommerce PDF Invoices & Packing Slips от WP Overnight и создал второй пользовательский шаблон PDF (версия ваучера без цен). Я добавил кнопку на страницу Thank You для загрузки этого второго шаблона, но при нажатии на кнопку я получаю ошибку “Invalid Order”. Передаваемый ID заказа правильный (я дважды проверил значение и оно соответствует только что завершенному заказу).
Что я сделал:
- Создал второй шаблон в дочерней теме: wp-content/themes/child-theme/woocommerce/pdf/voucher.php
- Зарегистрировал его через фильтр, добавив пользовательскую кнопку на страницу Thank you
Вот мой код:
add_action('woocommerce_thankyou', 'add_voucher_pdf_button', 20);
function add_voucher_pdf_button($order_id) {
if (!$order_id) return;
$order = wc_get_order($order_id);
if (!$order) return;
// Nonce для безопасности, должен соответствовать типу документа (invoice)
$nonce = wp_create_nonce('generate_wpo_wcpdf');
// Построить правильный AJAX URL
$pdf_url = add_query_arg(array(
'action' => 'generate_wpo_wcpdf',
'document' => 'invoice', // оставить как invoice, так как voucher не зарегистрированный тип
'order_ids' => $order->get_id(),
'voucher_pdf' => 1,
'_wpnonce' => $nonce,
), admin_url('admin-ajax.php'));
echo '<a href="' . esc_url($pdf_url) . '" target="_blank" class="button alt" style="margin-top:20px;">Скачать PDF ваучера</a>';
}
add_filter('wpo_wcpdf_template_file', 'load_voucher_template_conditionally', 10, 3);
function load_voucher_template_conditionally($template, $type, $order) {
if (!empty($_GET['voucher_pdf']) && $_GET['voucher_pdf'] == 1) {
$voucher_template = get_stylesheet_directory() . '/woocommerce/pdf/voucher-template/' . basename($template);
if (file_exists($voucher_template)) {
return $voucher_template;
}
}
return $template;
}
Есть ли какие-либо идеи или примеры по правильной реализации второго пользовательского шаблона PDF в плагине WooCommerce PDF Invoices & Packing Slips?
Ошибка “Недействительный заказ” при создании второго пользовательского PDF-шаблона в WooCommerce PDF Invoices & Packing Slips
Ошибка “Недействительный заказ” при создании второго пользовательского PDF-шаблона в WooCommerce PDF Invoices & Packing Slips обычно возникает из-за неправильной регистрации шаблона или отсутствия проверки заказа в процессе загрузки пользовательского шаблона. Проблема часто связана со строгой проверкой заказа в плагине, который не распознает пользовательские типы документов или параметры, передаваемые через AJAX-запрос.
Содержание
- Понимание проблемы
- Решение 1: Правильная регистрация шаблона
- Решение 2: Альтернативный подход с пользовательским типом документа
- Решение 3: Использование хуков плагина для выбора шаблона
- Лучшие практики для пользовательских шаблонов
- Отладка и устранение неполадок
Понимание проблемы
Ошибка “Недействительный заказ” возникает потому, что в плагине WooCommerce PDF Invoices & Packing Slips встроены механизмы проверки, которые определяют, существует ли заказ и может ли быть обработан. При создании пользовательского шаблона и попытке доступа к нему через измененный AJAX-запрос, плагин может не распознать ваши пользовательские параметры или не пройти проверку заказа.
Из обсуждения на Stack Overflow, это известная проблема при попытке создания пользовательских PDF-шаблонов вне стандартного рабочего процесса плагина. Плагин ожидает определенные типы документов и следует конкретному процессу проверки.
Основные причины включают:
- Неправильную регистрацию шаблона
- Неправильную обработку параметров AJAX
- Сбои проверки заказа
- Проблемы с путем к файлу шаблона
Решение 1: Правильная регистрация шаблона
Наиболее надежный подход - правильно зарегистрировать ваш пользовательский шаблон с помощью встроенных хуков плагина. Вместо попытки изменения параметра типа документа, вы должны зарегистрировать вашу квитанцию как пользовательский тип документа.
// Регистрация пользовательского типа документа квитанции
add_filter('wpo_wcpdf_document_types', 'register_voucher_document_type', 10, 1);
function register_voucher_document_type($document_types) {
$document_types['voucher'] = array(
'title' => __('Квитанция', 'woocommerce-pdf-invoices-packing-slips'),
'description' => __('Пользовательский шаблон квитанции без цен', 'woocommerce-pdf-invoices-packing-slips'),
'settings' => array(),
);
return $document_types;
}
// Добавление кнопки квитанции на страницу благодарности
add_action('woocommerce_thankyou', 'add_voucher_pdf_button', 20);
function add_voucher_pdf_button($order_id) {
if (!$order_id) return;
$order = wc_get_order($order_id);
if (!$order) return;
// Создание nonce для безопасности
$nonce = wp_create_nonce('generate_wpo_wcpdf');
// Построение URL AJAX с пользовательским типом документа
$pdf_url = add_query_arg(array(
'action' => 'generate_wpo_wcpdf',
'document' => 'voucher', // Используем зарегистрированный тип документа
'order_ids' => $order->get_id(),
'_wpnonce' => $nonce,
), admin_url('admin-ajax.php'));
echo '<a href="' . esc_url($pdf_url) . '" target="_blank" class="button alt" style="margin-top:20px;">Скачать PDF квитанции</a>';
}
// Загрузка шаблона квитанции при запросе
add_filter('wpo_wcpdf_template_file', 'load_voucher_template', 10, 3);
function load_voucher_template($template, $type, $order) {
if ($type === 'voucher') {
$voucher_template = get_stylesheet_directory() . '/woocommerce/pdf/voucher-template/' . basename($template);
if (file_exists($voucher_template)) {
return $voucher_template;
}
}
return $template;
}
Этот подход следует предполагаемому рабочему процессу плагина путем регистрации квитанции как правильного типа документа, что должно решить проблемы проверки.
Решение 2: Альтернативный подход с пользовательским типом документа
Если первое решение не работает, вы можете реализовать более надежный подход, создав обработчик пользовательского типа документа:
// Регистрация пользовательского типа документа
add_filter('wpo_wcpdf_document_types', 'register_custom_voucher_document', 10, 1);
function register_custom_voucher_document($document_types) {
$document_types['voucher'] = array(
'title' => __('Квитанция', 'woocommerce-pdf-invoices-packing-slips'),
'description' => __('Пользовательский шаблон квитанции', 'woocommerce-pdf-invoices-packing-slips'),
'settings' => array(),
);
return $document_types;
}
// Создание пользовательского обработчика AJAX для квитанции
add_action('wp_ajax_generate_wpo_wcpdf_voucher', 'generate_custom_voucher_pdf');
add_action('wp_ajax_nopriv_generate_wpo_wcpdf_voucher', 'generate_custom_voucher_pdf');
function generate_custom_voucher_pdf() {
check_ajax_referer('generate_wpo_wcpdf', '_wpnonce');
if (!isset($_GET['order_ids']) || empty($_GET['order_ids'])) {
wp_die('Недействительный заказ');
}
$order_ids = is_array($_GET['order_ids']) ? $_GET['order_ids'] : array($_GET['order_ids']);
// Проверка каждого заказа
foreach ($order_ids as $order_id) {
$order = wc_get_order($order_id);
if (!$order) {
wp_die('Недействительный заказ: ' . $order_id);
}
}
// Установка типа документа в квитанцию
$_GET['document'] = 'voucher';
$_GET['order_ids'] = $order_ids;
// Подключение основного файла плагина
if (!defined('WPO_WCPDF_VERSION')) {
wp_die('Плагин PDF Invoices & Packing Slips не найден');
}
// Генерация PDF с помощью основной функции плагина
$pdf = wpo_wcpdf_get_document('voucher', $order_ids);
if (!$pdf) {
wp_die('Не удалось создать PDF-документ');
}
$pdf->output();
}
// Добавление кнопки квитанции на страницу благодарности
add_action('woocommerce_thankyou', 'add_custom_voucher_button', 20);
function add_custom_voucher_button($order_id) {
if (!$order_id) return;
$order = wc_get_order($order_id);
if (!$order) return;
$nonce = wp_create_nonce('generate_wpo_wcpdf');
// Использование пользовательского действия AJAX
$pdf_url = add_query_arg(array(
'action' => 'generate_wpo_wcpdf_voucher',
'order_ids' => $order->get_id(),
'_wpnonce' => $nonce,
), admin_url('admin-ajax.php'));
echo '<a href="' . esc_url($pdf_url) . '" target="_blank" class="button alt" style="margin-top:20px;">Скачать PDF квитанции</a>';
}
// Загрузка шаблона квитанции
add_filter('wpo_wcpdf_template_file', 'load_custom_voucher_template', 10, 3);
function load_custom_voucher_template($template, $type, $order) {
if ($type === 'voucher') {
$voucher_template = get_stylesheet_directory() . '/woocommerce/pdf/voucher-template.php';
if (file_exists($voucher_template)) {
return $voucher_template;
}
}
return $template;
}
Этот подход создает выделенный обработчик AJAX для вашего типа документа квитанции, который обходит некоторые проблемы проверки плагина, сохраняя при этом безопасность и функциональность.
Решение 3: Использование хуков плагина для выбора шаблона
Другой эффективный метод - использование существующих хуков плагина для условного выбора вашего пользовательского шаблона:
// Регистрация пользовательского типа документа
add_filter('wpo_wcpdf_document_types', 'add_voucher_document_type', 10, 1);
function add_voucher_document_type($document_types) {
$document_types['voucher'] = array(
'title' => __('Квитанция', 'woocommerce-pdf-invoices-packing-slips'),
'description' => __('Шаблон квитанции без цен', 'woocommerce-pdf-invoices-packing-slips'),
);
return $document_types;
}
// Добавление логики выбора шаблона
add_filter('wpo_wcpdf_use_external_settings', 'use_external_voucher_settings', 10, 2);
function use_external_voucher_settings($use_external, $document_type) {
if ($document_type === 'voucher') {
return true;
}
return $use_external;
}
// Добавление кнопки квитанции
add_action('woocommerce_thankyou', 'add_voucher_download_button', 20);
function add_voucher_download_button($order_id) {
if (!$order_id) return;
$order = wc_get_order($order_id);
if (!$order) return;
$nonce = wp_create_nonce('generate_wpo_wcpdf');
// Использование типа документа invoice в качестве базы с выбором шаблона квитанции
$pdf_url = add_query_arg(array(
'action' => 'generate_wpo_wcpdf',
'document' => 'invoice', // Использование типа invoice в качестве базы
'order_ids' => $order->get_id(),
'voucher_mode' => 'true',
'_wpnonce' => $nonce,
), admin_url('admin-ajax.php'));
echo '<a href="' . esc_url($pdf_url) . '" target="_blank" class="button alt" style="margin-top:20px;">Скачать PDF квитанции</a>';
}
// Переопределение шаблона на основе пользовательского параметра
add_filter('wpo_wcpdf_template_file', 'get_voucher_template', 10, 3);
function get_voucher_template($template, $type, $order) {
if ($type === 'invoice' && !empty($_GET['voucher_mode']) && $_GET['voucher_mode'] === 'true') {
$voucher_template = get_stylesheet_directory() . '/woocommerce/pdf/voucher-template.php';
if (file_exists($voucher_template)) {
return $voucher_template;
}
}
return $template;
}
// Добавление настроек шаблона для квитанции
add_filter('wpo_wcpdf_get_document_settings', 'add_voucher_settings', 10, 2);
function add_voucher_settings($settings, $document_type) {
if ($document_type === 'invoice' && !empty($_GET['voucher_mode']) && $_GET['voucher_mode'] === 'true') {
$settings['template'] = 'voucher';
}
return $settings;
}
Этот подход использует существующий тип документа invoice в плагине, но переопределяет выбор шаблона на основе пользовательского параметра, что может быть более надежным, чем создание совершенно нового типа документа.
Лучшие практики для пользовательских шаблонов
При работе с пользовательскими PDF-шаблонами в WooCommerce PDF Invoices & Packing Slips, следуйте этим лучшим практикам:
Структура файлов шаблона
ваша-дочерняя-тема/
└── woocommerce/
└── pdf/
├── invoice/
│ └── invoice.php (шаблон по умолчанию)
├── packing-slip/
│ └── packing-slip.php (шаблон по умолчанию)
└── voucher/
└── voucher.php (ваш пользовательский шаблон)
Вопросы безопасности
- Всегда используйте
wp_create_nonce()иcheck_ajax_referer()для безопасности - Проверяйте ID заказов перед обработкой
- Очищайте все пользовательские входные данные и параметры запроса
Оптимизация производительности
- Кэшируйте файлы шаблонов при возможности
- Минимизируйте запросы к базе данных в файлах шаблонов
- Используйте правильный синтаксис PHP и избегайте устаревших функций
Разработка шаблонов
- Копируйте существующие шаблоны в качестве отправной точки
- Тестируйте с разными типами и статусами заказов
- Используйте инструменты отладки плагина для разработки
Отладка и устранение неполадок
Если вы продолжаете испытывать проблемы, вот несколько шагов отладки:
Включение режима отладки
// Добавьте в functions.php вашей темы или пользовательский плагин
add_filter('wpo_wcpdf_debug_mode', '__return_true');
Проверка разрешений файлов шаблона
Убедитесь, что ваши файлы шаблонов доступны для чтения веб-сервером:
chmod 644 wp-content/themes/ваша-дочерняя-тема/woocommerce/pdf/voucher/voucher.php
Проверка объекта заказа
Добавьте код отладки для проверки объекта заказа:
add_action('woocommerce_thankyou', 'debug_order_object', 25);
function debug_order_object($order_id) {
if (!$order_id) return;
$order = wc_get_order($order_id);
if (!$order) {
error_log('Объект заказа равен null для ID: ' . $order_id);
return;
}
error_log('Детали заказа: ' . print_r($order->get_data(), true));
}
Проверка совместимости плагина
Убедитесь, что вы используете совместимую версию плагина WooCommerce PDF Invoices & Packing Slips. Согласно документации плагина, всегда проверяйте наличие обновлений и совместимость с вашей версией WooCommerce.
Просмотр журналов ошибок
Проверьте журналы ошибок WordPress и сервера на наличие предупреждений или уведомлений PHP, которые могут вызывать проблему.
Заключение
Ошибка “Недействительный заказ” при создании второго пользовательского PDF-шаблона в WooCommerce PDF Invoices & Packing Slips обычно возникает из-за неправильной регистрации шаблона или проблем проверки заказа. Наиболее эффективные решения включают:
- Правильную регистрацию вашего пользовательского шаблона в качестве типа документа с помощью хуков плагина
- Создание выделенного обработчика AJAX для вашего пользовательского типа документа
- Использование существующих типов документов с переопределением шаблонов на основе пользовательских параметров
Следуя подходам, описанным выше, и реализуя надлежащие меры безопасности, вы должны успешно создавать и получать доступ к вашему пользовательскому шаблону квитанции без encountering ошибки “Недействительный заказ”. Не забывайте тщательно тестировать с разными типами заказов и убедиться, что ваши файлы шаблонов правильно структурированы и доступны.
Источники
- Stack Overflow - Ошибка “Недействительный заказ” при создании второго пользовательского PDF-шаблона
- WordPress.org - Поддержка плагина PDF Invoices & Packing Slips
- Документация WP Overnight - Создание пользовательского PDF-шаблона
- GitHub - Плагин WooCommerce PDF Invoices & Packing Slips
- Документация WooCommerce - Построитель PDF-накладных и счетов