WooCommerce结账页面上的自定义字段

5

我试图将两个自定义字段放在WooCommerce结账页面的顶部(理想情况下是购物车页面,但我找不到关于这个可能性的在线信息)

我已经成功将这两个自定义字段显示在结账页面上,但由于我对PHP知识非常有限,我尝试创建一个下拉菜单等等。表面上看一切都很好。这些字段出现在结账页面上,但是每当我输入信息并尝试继续下订单以测试这些值是否显示在感谢页面和电子邮件中时,系统要求我填写这些必填字段的信息。由于某种原因,页面无法识别这些字段为空。

我使用了这篇文章... https://www.businessbloomer.com/woocommerce-add-custom-checkout-field-php/

但我不得不进行了相当多的编辑才能达到这一点。我确定有很多错误。

add_action('woocommerce_before_checkout_form', 'custom_add_custom_checkout_fields');

function custom_add_custom_checkout_fields($checkout)
{
    echo '<h3>Event Information</h3>';

    // Get the current user ID
    $user_id = get_current_user_id();

    // Fetch user meta data
    $saved_event_venue = $current_user->event_venue;
    $saved_hall_stand_number = $current_user->hall_stand_number;

    woocommerce_form_field('event_venue', array(
        'type' => 'select',
        'class' => array('form-row-wide'),
        'label' => 'Event/Expo & Venue',
        'options' => array(
            '' => 'Select an option',
            'event1' => 'Event 1 Venue',
            'event2' => 'Event 2 Venue',
            'event3' => 'Event 3 Venue'
            // Add more options as needed
        ),
        'required' => true,
        'default' => $saved_event_venue,
    ), $checkout->get_value('event_venue'));

    woocommerce_form_field('hall_stand_number', array(
        'type' => 'text',
        'class' => array('form-row-wide'),
        'label' => 'Hall & Stand Number',
        'placeholder' => 'Enter Hall & Stand Number',
        'required' => true,
        'default' => $saved_hall_stand_number,
    ), $checkout->get_value('hall_stand_number'));
}

// Validate custom fields
add_action('woocommerce_checkout_process', 'custom_validate_checkout_fields');

function custom_validate_checkout_fields()
{
    if (!$_POST['event_venue']) {
        wc_add_notice('Please select an Event/Expo & Venue.', 'error');

        if (!$_POST['hall_stand_number']) {
            wc_add_notice('Please enter the Hall & Stand Number.', 'error');
        }
    }
}

// Save custom fields to order
add_action('woocommerce_checkout_update_order_meta', 'custom_save_checkout_fields');

function custom_save_checkout_fields($order_id)
{
    if ($_POST['event_venue'])
        update_post_meta($order_id, '_event_venue', esc_attr($_POST['event_venue']));


    if ($_POST['hall_stand_number'])
        update_post_meta($order_id, '_hall_stand_number', esc_attr($_POST['hall_stand_number']));
}

// Display custom fields on order received page and order emails
add_action('woocommerce_thankyou', 'custom_new_checkout_field_thankyou');

function custom_new_checkout_field_thankyou($order_id)
{
    if (get_post_meta($order_id, 'event_venue', true))
        echo '<p><strong>Event/Expo &Venue:</strong> ' . get_post_meta($order_id, '_Event_venue', true) . '</p>';

    if (get_post_meta($order_id, 'hall_stand_number ', true))
        echo '<p><strong>Hall - Stand Number:</strong> ' . get_post_meta($order_id, '_hall_stand_number', true) . '</p>';
}

add_action('woocommerce_admin_order_data_after_billing_address', 'bbloomer_show_new_checkout_field_order');

function custom_new_checkout_field_order($order)
{
    $order_id = $order->get_id();

    if (get_post_meta($order_id, '_event_venue', true))
        echo '<p><strong>Event/Expo - Venue:</strong> ' . get_post_meta($order_id, '_event_venue', true) . '</p>';

    if (get_post_meta($order_id, '_hall_stand_number', true))
        echo '<p><strong>Hall - Stand Number:</strong> ' . get_post_meta($order_id, '_hall_stand_number', true) . '</p>';
}



add_action('woocommerce_email_after_order_table', 'custom_new_checkout_field_emails', 20, 4);

function bbloomer_show_new_checkout_field_emails($order, $sent_to_admin, $plain_text, $email ) {
    if (get_post_meta($order->get_id(), '_license_no', true))
        echo '<p><strong>Event/Expo - Venue:   </strong> ' . get_post_meta($order->get_id(), '_event_venue', true) . '</p>';

    if (get_post_meta($order->get_id(), '_hall_stand_number', true))
        echo '<p><strong>Hall - Stand Number:</strong> ' . get_post_meta($order->get_id(), '_hall_stand_number', true) . '</p>';
}
1个回答

2

更新

主要错误是在您的第一个函数中未定义$current_user变量。此外,您不能使用woocommerce_before_checkout_form钩子,因为它会在结账表单之外显示您的自定义结账字段,并且它们将无法正常工作。

还有一些其他错误和遗漏的内容。请尝试以下方法:

// Utility function: Get Event venue select field options
function get_event_venue_options() {
    // Add more options as needed to the array
    return array(
        'event1'    => __('Event 1 Venue', 'woocommerce'),
        'event2'    => __('Event 2 Venue', 'woocommerce'),
        'event3'    => __('Event 3 Venue', 'woocommerce'),
    );
}

// Utility function: Get customer selected Event venue data (for display)
function get_customer_event_venue_data( $order ) {
    $options = get_event_venue_options(); // Get event venue options
    $event_data  = []; // Initializing

    if ( $event_venue = $order->get_meta('_event_venue') ) {
        $event_data[__('Event/Expo & Venue', 'woocommerce')] = $options[$event_venue];
    }

    if ( $hall_stand_number = $order->get_meta('_hall_stand_number') ) {
        $event_data[__('Hall - Stand Number', 'woocommerce')] = $hall_stand_number;
    }
    return $event_data;
}

// Utility function: Save customer selected Event venue data 
function save_customer_event_venue_data( $object, $type = 'order' ) {
    $prefix = $type === 'order' ? '_' : '';

    if ( isset($_POST['event_venue']) ) {
        $object->update_meta_data($prefix.'event_venue', esc_attr($_POST['event_venue']));
    }
    if ( isset($_POST['hall_stand_number']) ) {
        $object->update_meta_data($prefix.'hall_stand_number', sanitize_text_field($_POST['hall_stand_number']));
    }
}

// Display the fields in checkout before order notes
add_action( 'woocommerce_before_order_notes', 'display_custom_checkout_fields', 10, 1 );
function display_custom_checkout_fields( $checkout ) {
    $event_venue_options = get_event_venue_options();

    echo '<div class="event-info">
    <h3>' . __('Event Information', 'woocommerce') . '</h3>';

    woocommerce_form_field('event_venue', array(
        'type' => 'select',
        'class' => array('form-row-wide'),
        'label' => __('Event/Expo & Venue', 'woocommerce'),
        'options' => array_merge( ['' => __('Select an option', 'woocommerce')], $event_venue_options ),
        'required' => true,
    ), WC()->customer->get_meta('event_venue') );

    woocommerce_form_field('hall_stand_number', array(
        'type' => 'text',
        'class' => array('form-row-wide'),
        'label' => __('Hall & Stand Number', 'woocommerce'),
        'placeholder' => __('Enter Hall & Stand Number', 'woocommerce'),
        'required' => true,
    ), WC()->customer->get_meta('hall_stand_number') );

    echo '</div>';
}

// Validate custom fields
add_action( 'woocommerce_checkout_process', 'validate_custom_checkout_fields' );
function validate_custom_checkout_fields() {
    if ( isset($_POST['event_venue']) && empty($_POST['event_venue']) ) {
        wc_add_notice('Please select an Event/Expo & Venue.', 'error');
    }
    if ( isset($_POST['hall_stand_number']) && empty($_POST['hall_stand_number']) ) {
        wc_add_notice('Please enter the Hall & Stand Number.', 'error');
    }
}

// Save customer event venue data as order metadata and user meta data
add_action( 'woocommerce_checkout_update_customer', 'save_event_venue_data_as_metadata', 10, 1 );
add_action( 'woocommerce_checkout_create_order', 'save_event_venue_data_as_metadata', 10, 1 );
function save_event_venue_data_as_metadata( $object ) {
    if ( is_a($object, 'WC_Order') ) {
        save_customer_event_venue_data( $object );
    } else {
        save_customer_event_venue_data( $object, 'customer' );
    }
}

// Display Event data on orders, admin orders and email notifications
add_action('woocommerce_after_order_details', 'display_event_data_on_orders', 10, 1);
add_action('woocommerce_admin_order_data_after_shipping_address', 'display_event_data_on_orders', 10, 1 );
function display_event_data_on_orders( $order ) {
    $event_data  = get_customer_event_venue_data( $order );
    $event_title = __('Event details', 'woocommerce');
    if ( ! empty($event_data) ) {
        // On admin orders
        if( is_admin() ) {
            echo '<h3>'.$event_title.'</h3><p>';
            foreach ( $event_data as $label => $value ) {
                echo '<strong>' . $label .':</strong> ' . $value  . '<br>';
            }
            echo '</p>';
        } 
        // On customer orders and thankyou
        else {
            echo '<h2 class="woocommerce-column__title">'.$event_title.'</h2>
            <table class="woocommerce-table woocommerce-table--event-details shop_table event_details"><tfoot>';
            foreach ( $event_data as $label => $value ) {
                echo '<tr class="event-venue"><th>'.$label.'</th><td>'.$value.'</td></tr>';
            }
            echo '</tfoot></table>';
        } 
    }
}

// Display Event data on email notifications
add_action('woocommerce_email_after_order_table', 'display_event_data_on_email_notifications', 10, 1);
function display_event_data_on_email_notifications( $order ) {
    $event_data  = get_customer_event_venue_data( $order );
    $event_title = __('Event details', 'woocommerce');
    if ( ! empty($event_data) ) {
        echo '<style>
        .event-info table{width: 100%; font-family: \'Helvetica Neue\', Helvetica, Roboto, Arial, sans-serif;
            color: #737373; border: 1px solid #e4e4e4; margin-bottom:8px;}
        .event-info table th, table.tracking-info td{text-align: left; border-top-width: 4px;
            color: #737373; border: 1px solid #e4e4e4; padding: 12px; width:58%;}
        .event-info table td{text-align: left; border-top-width: 4px; color: #737373; border: 1px solid #e4e4e4; padding: 12px;}
        </style>';

        echo '<div class="event-info"><h2>'.$event_title.'</h2>';
        echo '<table cellspacing="0" cellpadding="6"><tbody>';
        foreach ( $event_data as $label => $value ) {
            echo '<tr"><th>'.$label.'</th><td>'.$value.'</td></tr>';
        }
        echo '</tbody></table></div><br>';
    }
}

代码放在您的子主题的functions.php文件中(或者插件中)。已经测试并且可行。

你将会得到以下内容(截图):

  • 在结账页面上:

enter image description here


  • 关于客户订单和感谢页面:

enter image description here


根据管理员的指示:

enter image description here


关于电子邮件通知:

enter image description here


相关链接:在Woocommerce中将自定义元数据添加为带标题的HTML样式表格的电子邮件

当我尝试这个时,我收到错误信息“处理结账出错,请重试。” - Kyle
有一个小错误...然后我改进了我的代码,以便在订单和电子邮件通知中获得漂亮的显示(请参见截图)。代码经过测试,完全可用。请查看"当有人回答我的问题时我该怎么办?" - LoicTheAztec

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接