Save and display order custom meta data in Woocomm

2019-07-18 21:58发布

问题:

A while back my partner helped me to add a custom field to our checkout page, we wanted to ask people "How did you hear about us?" when they booked for our events.

We put it together but shortly after we stopped being able to see the results properly.

In the "New Order" emails sent to the admin, the label 'How did you hear about us' appears, but with no answer.

In the order page, it appears in two places:

1) under the Billing info. The label is there. Value is: Array

2) under "Custom Fields" section. The label is there. Value is: Option_0 or Option1 etc

My first question is how can I resolve this so that the option, e.g. "Social Media" appears on the email and order pages.

My second question, is, how can I analyse this data as a whole? We would hopefully like to be able to answer questions like; how many people chose option 1 in 2018?; how many chose option 2 in December?; how many purchased x who chose option 3?; how many purchased y and chose option 4?

Thank you in advance for your help!

/**
* Add the field to the checkout
*/
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );

function my_custom_checkout_field( $checkout ) {

echo '<div id="my_custom_checkout_field"><h2>' . __('Please help us understand our customers so that we can improve future events (Optional)') . '</h2>';

woocommerce_form_field( 'hearaboutus', array(
    'type'          => 'select',
    'class'         => array('my-field-class form-row-wide'),
    'label'         => __('How did you hear about us? &nbsp;'),
    'options'       => array(
 'Option_0' => 'Please select...',
 'option_1' => 'Social Media (e.g Facebook)',
 'option_2' => 'Search Engine (e.g Google)',
 'option_3' => 'Meditation Class',
 'option_4' => 'Leaflets/Flyers/Posters',
 'option_5' => 'Website',
 'option_6' => 'Email Newsletter',
 'option_7' => 'Other',
 )
    ), $checkout->get_value( 'hearaboutus' ));

echo '</div>';

}

/**
* Update the order meta with field value
*/
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );

function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['hearaboutus'] ) ) {
    update_post_meta( $order_id, 'How did you hear about us?', 
sanitize_text_field( $_POST['hearaboutus'] ) );
}
}

/* Add the fields to order email */

add_filter( 'woocommerce_email_order_meta_keys', 'my_custom_checkout_field_order_meta_keys' );
function my_custom_checkout_field_order_meta_keys( $keys ) {
            echo '<h3>How did you hear about us?:</h3>';
    $keys[''] = 'hearaboutus';
    return $keys;
}

/**
* Display field value on the order edit page
*/
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );

function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('How did you hear about us?').':</strong> ' . get_post_meta( $order->id, $key='', 'hearaboutus', true ) . '</p>';
}

回答1:

There are some mistakes and errors in your code… Try the following revisited code:

// get "hearaboutus" select field options data
function wc_get_hearaboutus_options(){
    return array(
        ''          => 'Please select...',
        'option_1'  => 'Social Media (e.g Facebook)',
        'option_2'  => 'Search Engine (e.g Google)',
        'option_3'  => 'Meditation Class',
        'option_4'  => 'Leaflets/Flyers/Posters',
        'option_5'  => 'Website',
        'option_6'  => 'Email Newsletter',
        'option_7'  => 'Other',
    );
}

// Add the field to the checkout
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {

    echo '<div id="my_custom_checkout_field"><h3>' . __('Please help us understand our customers so that we can improve future events (Optional)') . '</h3>';

    woocommerce_form_field( '_hearaboutus', array(
        'type'    => 'select',
        'class'   => array('my-field-class form-row-wide'),
        'label'   => __('How did you hear about us? &nbsp;'),
        'options' => wc_get_hearaboutus_options(),
    ), $checkout->get_value( '_hearaboutus' ) );

    echo '</div>';

}

// Update the order meta with field value
add_action( 'woocommerce_checkout_create_order', 'custom_checkout_field_create_order', 10, 2 );
function custom_checkout_field_create_order( $order, $data ) {
    if ( isset($_POST['_hearaboutus']) && ! empty($_POST['_hearaboutus']) ) {
         $order->update_meta_data( '_hearaboutus', sanitize_text_field($_POST['_hearaboutus']) );
    }
}

// Add the fields to order email
add_action('woocommerce_email_order_details', 'action_after_email_order_details', 25, 4 );
function action_after_email_order_details( $order, $sent_to_admin, $plain_text, $email ) {
    if( $hearaboutus = $order->get_meta('_hearaboutus') ) {
        // The data
        $label = __('How did you hear about us?');
        $value = wc_get_hearaboutus_options()[$hearaboutus];

        // The HTML Structure
        $html_output = '<h2>' . __('Extra data') . '</h2>
        <div class="discount-info"><table cellspacing="0" cellpadding="6"><tr>
        <th>' . $label . '</th><td>' . $value . '</td>
        </tr></tbody></table></div><br>';

        // The CSS styling
        $styles = '<style>
            .discount-info table{width: 100%; font-family: \'Helvetica Neue\', Helvetica, Roboto, Arial, sans-serif;
                color: #737373; border: 2px solid #e4e4e4; margin-bottom:8px;}
            .discount-info table th, table.tracking-info td{ text-align: left; color: #737373; border: none; padding: 12px;}
            .discount-info table td{ text-align: left; color: #737373; border: none; padding: 12px; }
        </style>';

        // The Output CSS + HTML
        echo $styles . $html_output;
    }
}

// Display field value on the order edit page
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta( $order ) {
    if( $hearaboutus = $order->get_meta('_hearaboutus') ) {
        $value = wc_get_hearaboutus_options()[$hearaboutus];
        echo '<p><strong>'.__('How did you hear about us?').'</strong> ' . $value . '</p>';
    }
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.

Email Notifications screenshot: