update_post_meta() 在提交订单时无法在 WooCommerce 结账上工作

问题描述 投票:0回答:1

我为我的客户创建了一个定制插件,但遇到了一些问题。在将插件发送给客户端之前,我在自己的沙箱网站上测试了该插件,它运行得很好。然而,在他们的网站上,由于其构建方式不同,我遇到了一些问题。

其中一个文件使用常见的 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,效果非常好。有一些东西引起了冲突,但似乎无法找到原因。

网站上的插件:

  • 高级自定义字段 PRO
  • 高级货运追踪专业版
  • Avada 生成器
  • 阿瓦达核心
  • 代码片段
  • WooCommerce 的自定义用户注册字段
  • Woocommerce 的数字签名结帐
  • 复印机
  • WooCommerce 身份验证
  • 重定向
  • 停止用户枚举
  • WooCommerce 的 TrackShip
  • 用户角色编辑器
  • 登录用户的 WooCommerce
  • WooCommerce Opayo 支付套件
  • WooCommerce 扎皮尔
  • WooCommerce 的 Worldpay 电子商务
  • WP 最快的缓存
  • WP 邮件 SMTP
  • 酵母SEO

我已经检查了代码片段,但没有发现其中有任何会导致问题的内容。我以前没用过 Avada。

php wordpress woocommerce metadata orders
1个回答
1
投票

首先请注意,高性能订单存储 (HPOS) 现在在 WooCommerce 中默认启用,并且需要使用带有 CRUD 对象 getter 和 setter 方法的其他挂钩,而不是 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 订单元数据:

  • 读取元数据,请使用 WC_Order 对象中的
    get_meta()
    方法。
  • 更新元数据,请使用 WC_Order 对象中的
    update_meta_data()
    方法。

更新订单元数据时,需要

save()
方法,但以下情况除外:

  • woocommerce_checkout_create_order
    动作挂钩,因为它包含在后面。
© www.soinside.com 2019 - 2024. All rights reserved.