Я создал специальный плагин для своего клиента, но столкнулся с некоторыми проблемами. Я протестировал плагин на своем собственном сайте-песочнице, прежде чем отправить его клиенту, и он работал отлично. Однако на их сайте, который устроен по-другому, я столкнулся с парой проблем.
Один из файлов запускает функции, используя распространенные хуки Woocommerce.
<?php
if (!defined('ABSPATH')) {
exit;
}
class WC_PM_Checkout_Fields {
public function __construct() {
add_action('woocommerce_after_order_notes', array($this, 'add_patient_dropdown_and_custom_fields_to_checkout'), 999);
add_action('woocommerce_checkout_update_order_meta', array($this, 'save_or_create_patient_on_checkout'), 999);
add_action('woocommerce_thankyou', array($this, 'display_patient_information_on_thank_you_page'), 999);
add_action('woocommerce_email_order_meta', array($this, 'add_patient_info_to_order_email'), 999, 3);
add_action('woocommerce_admin_order_data_after_billing_address', array($this, 'display_patient_fields_in_admin_order'), 999, 1);
}
public function add_patient_dropdown_and_custom_fields_to_checkout($checkout) {
if ( !is_checkout() ) {
return;
}
$args = array(
'post_type' => 'patient',
'author' => get_current_user_id(),
'posts_per_page' => -1,
);
$patients = new WP_Query($args);
echo '<div id = "patient_dropdown"><h3>' . __('Select Existing Patient') . '</h3>';
echo '<select name = "selected_patient_id" id = "selected_patient_id">';
echo '<option value = "">' . __('Select a patient or enter new details below') . '</option>';
if ($patients->have_posts()) :
while ($patients->have_posts()) : $patients->the_post();
echo '<option value = "' . get_the_ID() . '">' . get_the_title() . '</option>';
endwhile;
wp_reset_postdata();
endif;
echo '</select></div>';
echo '<div id = "custom_patient_checkout_fields"><h3>' . __('Or Enter New Patient Information') . '</h3>';
if (function_exists('woocommerce_form_field')) {
// First Name field
woocommerce_form_field('wcpm_patient_first_name', array(
'type' => 'text',
'class' => array('form-row-wide'),
'label' => __('Patient First Name'),
'required' => true,
'placeholder' => __('Enter patient first name'),
), $checkout->get_value('wcpm_patient_first_name'));
// Last Name field
woocommerce_form_field('wcpm_patient_last_name', array(
'type' => 'text',
'class' => array('form-row-wide'),
'label' => __('Patient Last Name'),
'required' => true,
'placeholder' => __('Enter patient last name'),
), $checkout->get_value('wcpm_patient_last_name'));
// Date of Birth field
woocommerce_form_field('wcpm_patient_dob', array(
'type' => 'text',
'class' => array('form-row-wide'),
'label' => __('Date of Birth'),
'required' => true,
'placeholder' => __('Select date of birth'),
'input_class' => array('datepicker'),
), $checkout->get_value('wcpm_patient_dob'));
// Prescription Dosage field
woocommerce_form_field('wcpm_patient_dosage', array(
'type' => 'text',
'class' => array('form-row-wide'),
'label' => __('Prescription Dosage'),
'required' => true,
'placeholder' => __('Enter prescription dosage'),
), $checkout->get_value('wcpm_patient_dosage'));
// Prescription Date field
woocommerce_form_field('wcpm_patient_prescription_date', array(
'type' => 'text',
'class' => array('form-row-wide'),
'label' => __('Prescription Date'),
'required' => true,
'placeholder' => __('Select prescription date'),
'input_class' => array('datepicker'),
), $checkout->get_value('wcpm_patient_prescription_date'));
}
echo '</div>';
}
public function save_or_create_patient_on_checkout($order_id) {
$selected_patient_id = !empty($_POST['selected_patient_id']) ? intval($_POST['selected_patient_id']) : null;
$patient_first_name = sanitize_text_field($_POST['wcpm_patient_first_name']);
$patient_last_name = sanitize_text_field($_POST['wcpm_patient_last_name']);
$patient_dob = !empty($_POST['wcpm_patient_dob']) ? date('Y-m-d', strtotime(str_replace('/', '-', $_POST['wcpm_patient_dob']))) : '';
$patient_dosage = sanitize_text_field($_POST['wcpm_patient_dosage']);
$patient_prescription_date = !empty($_POST['wcpm_patient_prescription_date']) ? date('Y-m-d', strtotime(str_replace('/', '-', $_POST['wcpm_patient_prescription_date']))) : '';
if ($selected_patient_id) {
// An existing patient was selected
$patient_id = $selected_patient_id;
} else {
// Create a new patient post
$patient_title = $patient_first_name . ' ' . $patient_last_name;
$current_user_id = get_current_user_id();
$existing_patient = get_posts(array(
'post_type' => 'patient',
'author' => $current_user_id,
'post_status'=> 'publish',
'meta_query' => array(
array(
'key' => 'wcpm_patient_first_name',
'value' => ucwords($patient_first_name),
'compare' => '='
),
array(
'key' => 'wcpm_patient_last_name',
'value' => ucwords($patient_last_name),
'compare' => '='
)
)
));
if ($existing_patient) {
$patient_id = $existing_patient[0]->ID;
} else {
$patient_post = array(
'post_title' => $patient_title,
'post_type' => 'patient',
'post_status' => 'publish',
'post_author' => $current_user_id,
);
$patient_id = wp_insert_post($patient_post);
// Save the custom fields for the new patient
update_post_meta($patient_id, 'wcpm_patient_first_name', ucwords($patient_first_name));
update_post_meta($patient_id, 'wcpm_patient_last_name', ucwords($patient_last_name));
update_post_meta($patient_id, 'wcpm_patient_dob', $patient_dob);
}
}
// Save patient information to the order meta
update_post_meta($order_id, '_selected_patient_id', $patient_id);
update_post_meta($order_id, 'wcpm_patient_first_name', ucwords($patient_first_name));
update_post_meta($order_id, 'wcpm_patient_last_name', ucwords($patient_last_name));
update_post_meta($order_id, 'wcpm_patient_dob', $patient_dob);
update_post_meta($order_id, 'wcpm_patient_dosage', $patient_dosage);
update_post_meta($order_id, 'wcpm_patient_prescription_date', $patient_prescription_date);
}
public function display_patient_information_on_thank_you_page($order_id) {
$selected_patient_id = get_post_meta($order_id, '_selected_patient_id', true);
if ($selected_patient_id) {
$patient_first_name = get_post_meta($selected_patient_id, 'wcpm_patient_first_name', true);
$patient_last_name = get_post_meta($selected_patient_id, 'wcpm_patient_last_name', true);
$patient_dob = get_post_meta($selected_patient_id, 'wcpm_patient_dob', true);
} else {
$patient_first_name = get_post_meta($order_id, 'wcpm_patient_first_name', true);
$patient_last_name = get_post_meta($order_id, 'wcpm_patient_last_name', true);
$patient_dob = get_post_meta($order_id, 'wcpm_patient_dob', true);
}
$patient_dosage = get_post_meta($order_id, 'wcpm_patient_dosage', true);
$patient_prescription_date = get_post_meta($order_id, 'wcpm_patient_prescription_date', true);
$dob_formatted = !empty($patient_dob) ? date('d/m/Y', strtotime($patient_dob)) : '';
$prescription_date_formatted = !empty($patient_prescription_date) ? date('d/m/Y', strtotime($patient_prescription_date)) : '';
echo '<h2>' . __('Patient Information') . '</h2>';
echo '<p><strong>' . __('First Name') . ':</strong> ' . esc_html(ucwords($patient_first_name)) . '</p>';
echo '<p><strong>' . __('Last Name') . ':</strong> ' . esc_html(ucwords($patient_last_name)) . '</p>';
echo '<p><strong>' . __('Date of Birth') . ':</strong> ' . esc_html($dob_formatted) . '</p>';
echo '<p><strong>' . __('Prescription Dosage') . ':</strong> ' . esc_html($patient_dosage) . '</p>';
echo '<p><strong>' . __('Prescription Date') . ':</strong> ' . esc_html($prescription_date_formatted) . '</p>';
}
public function add_patient_info_to_order_email($order, $sent_to_admin, $plain_text) {
$this->display_patient_information_on_thank_you_page($order->get_id());
}
public function display_patient_fields_in_admin_order($order) {
$this->display_patient_information_on_thank_you_page($order->get_id());
}
}
new WC_PM_Checkout_Fields();
Первая функция добавляет дополнительные поля, которые можно заполнить либо путем ввода новой информации, либо с помощью раскрывающегося списка, который извлекает информацию из пользовательского типа сообщения.
После отправки заказа создается новый пациент, если он еще не существует, и все эти дополнительные поля добавляются на страницу подтверждения, в электронное письмо и метаданные заказа. Однако метаданные заказа, похоже, не обновляются, поэтому отображаются имена полей, но не значения.
Я создал тестовую функцию, которая работает только с «admin_init», и добавил свой собственный order_id, и это сработало отлично. Что-то вызывает конфликт, но причину найти не удается.
Плагины на сайте:
Я проверил фрагменты кода, но не нашел там ничего, что могло бы вызвать проблемы. Я раньше не пользовался Авадой.
🤔 А знаете ли вы, что...
PHP можно использовать для создания API и веб-служб.
Прежде всего обратите внимание, что Высокопроизводительное хранилище заказов (HPOS) теперь включено по умолчанию в WooCommerce и требует использования некоторых других перехватчиков с методами получения и установки объектов CRUD вместо метафункций WordPress Post.
Кроме того, убедитесь, что ваш клиент не использует новые блоки оформления заказа, которые не позволяют выполнять подобные настройки.
Для начала попробуйте заменить старый крючок woocommerce_checkout_update_order_meta
из:
add_action('woocommerce_checkout_update_order_meta', array($this, 'save_or_create_patient_on_checkout'), 999);
с:
add_action('woocommerce_checkout_create_order', array($this, 'save_or_create_patient_on_checkout'), 10, 1 );
Затем замените связанную функцию чем-то вроде (аргументом функции теперь является $order
, который является объектом WC_order):
public function save_or_create_patient_on_checkout( $order ) {
$selected_patient_id = !empty($_POST['selected_patient_id']) ? intval($_POST['selected_patient_id']) : null;
$patient_first_name = sanitize_text_field($_POST['wcpm_patient_first_name']);
$patient_last_name = sanitize_text_field($_POST['wcpm_patient_last_name']);
$patient_dob = !empty($_POST['wcpm_patient_dob']) ? date('Y-m-d', strtotime(str_replace('/', '-', $_POST['wcpm_patient_dob']))) : '';
$patient_dosage = sanitize_text_field($_POST['wcpm_patient_dosage']);
$patient_prescription_date = !empty($_POST['wcpm_patient_prescription_date']) ? date('Y-m-d', strtotime(str_replace('/', '-', $_POST['wcpm_patient_prescription_date']))) : '';
if ($selected_patient_id) {
// An existing patient was selected
$patient_id = $selected_patient_id;
} else {
// Create a new patient post
$patient_title = $patient_first_name . ' ' . $patient_last_name;
$current_user_id = get_current_user_id();
$existing_patient = get_posts(array(
'post_type' => 'patient',
'author' => $current_user_id,
'post_status'=> 'publish',
'meta_query' => array(
array(
'key' => 'wcpm_patient_first_name',
'value' => ucwords($patient_first_name),
'compare' => '='
),
array(
'key' => 'wcpm_patient_last_name',
'value' => ucwords($patient_last_name),
'compare' => '='
)
)
));
if ($existing_patient) {
$patient_id = $existing_patient[0]->ID;
} else {
$patient_post = array(
'post_title' => $patient_title,
'post_type' => 'patient',
'post_status' => 'publish',
'post_author' => $current_user_id,
);
$patient_id = wp_insert_post($patient_post);
// Save the custom fields for the new patient
update_post_meta($patient_id, 'wcpm_patient_first_name', ucwords($patient_first_name));
update_post_meta($patient_id, 'wcpm_patient_last_name', ucwords($patient_last_name));
update_post_meta($patient_id, 'wcpm_patient_dob', $patient_dob);
}
}
// Save patient information as order metadata (compatible with HPOS)
$order->update_meta_data('_selected_patient_id', $patient_id);
$order->update_meta_data('wcpm_patient_first_name', ucwords($patient_first_name));
$order->update_meta_data('wcpm_patient_last_name', ucwords($patient_last_name));
$order->update_meta_data('wcpm_patient_dob', $patient_dob);
$order->update_meta_data('wcpm_patient_dosage', $patient_dosage);
$order->update_meta_data('wcpm_patient_prescription_date', $patient_prescription_date);
}
Чтобы сделать отображение страницы благодарности совместимым с HPOS, замените соответствующую функцию на:
public function display_patient_information_on_thank_you_page($order_id) {
$order = wc_get_order($order_id); // Get the WC_Order object
$selected_patient_id = $order->get_meta('_selected_patient_id'); // HPOS compatible
if ($selected_patient_id) {
$patient_first_name = get_post_meta($selected_patient_id, 'wcpm_patient_first_name', true);
$patient_last_name = get_post_meta($selected_patient_id, 'wcpm_patient_last_name', true);
$patient_dob = get_post_meta($selected_patient_id, 'wcpm_patient_dob', true);
} else {
$patient_first_name = $order->get_meta('wcpm_patient_first_name'); // HPOS compatible
$patient_last_name = $order->get_meta('wcpm_patient_last_name'); // HPOS compatible
$patient_dob = $order->get_meta('wcpm_patient_dob'); // HPOS compatible
}
$patient_dosage = $order->get_meta('wcpm_patient_dosage'); // HPOS compatible
$patient_prescription_date = $order->get_meta('wcpm_patient_prescription_date'); // HPOS compatible
$dob_formatted = !empty($patient_dob) ? date('d/m/Y', strtotime($patient_dob)) : '';
$prescription_date_formatted = !empty($patient_prescription_date) ? date('d/m/Y', strtotime($patient_prescription_date)) : '';
echo '<h2>' . __('Patient Information') . '</h2>';
echo '<p><strong>' . __('First Name') . ':</strong> ' . esc_html(ucwords($patient_first_name)) . '</p>';
echo '<p><strong>' . __('Last Name') . ':</strong> ' . esc_html(ucwords($patient_last_name)) . '</p>';
echo '<p><strong>' . __('Date of Birth') . ':</strong> ' . esc_html($dob_formatted) . '</p>';
echo '<p><strong>' . __('Prescription Dosage') . ':</strong> ' . esc_html($patient_dosage) . '</p>';
echo '<p><strong>' . __('Prescription Date') . ':</strong> ' . esc_html($prescription_date_formatted) . '</p>';
}
Теперь ваш код совместим с высокопроизводительным хранилищем заказов и должен работать как с включенным HPOS, так и без него.
Итак, подведем итог: метаданные заказов WooCommerce:
get_meta()
из объекта WC_Order.update_meta_data()
из объекта WC_Order.При обновлении метаданных заказа требуется метод save()
, за исключением:
woocommerce_checkout_create_order
крюк действия, как он будет включен позже.