Save and display order item custom meta data in Woocommerce

别说谁变了你拦得住时间么 提交于 2021-02-07 09:51:47

问题


I have some custom code was working perfectly and since I have updated Woocommerce to version 3.5.2 it is not working anymore, not sure if it is because I changed the wordpress theme or because because plugin updates.

My problem is that the value of the custom fields doesn't appear on the order page from woocommerce or even on the order email.

Here is the related code:

// Display Fields using WooCommerce Action Hook
 add_action('woocommerce_product_options_general_product_data', 'woocom_general_product_data_custom_field');
function woocom_general_product_data_custom_field()
{
    // FieldName1
    woocommerce_wp_text_input(array('id' => 'FieldName1', 'label' => __('FieldName1', 'woocommerce'), 'placeholder' => '', 'desc_tip' => 'false', 'description' => __('', 'woocommerce')));

    // FieldType1
    woocommerce_wp_text_input(array('id' => 'FieldType1', 'label' => __('FieldType1', 'woocommerce'), 'placeholder' => '', 'desc_tip' => 'false', 'description' => __('', 'woocommerce')));

    // FieldLenght1
    woocommerce_wp_text_input(array('id' => 'FieldLenght1', 'label' => __('FieldLenght1', 'woocommerce'), 'placeholder' => '', 'desc_tip' => 'false', 'description' => __('', 'woocommerce')));

    // Dropdown1
    woocommerce_wp_text_input(array('id' => 'Dropdown1', 'label' => __('Dropdown1', 'woocommerce'), 'placeholder' => '', 'desc_tip' => 'false', 'description' => __('', 'woocommerce')));       
}

// Hook to save the data value from the custom fields
add_action('woocommerce_process_product_meta', 'woocom_save_general_proddata_custom_field');
function woocom_save_general_proddata_custom_field($post_id)
{
    // Save Label Option 1
    update_post_meta($post_id, 'FieldName1', esc_attr($_POST['FieldName1']));

     // Save Label Option 1
    update_post_meta($post_id, 'FieldType1', esc_attr($_POST['FieldType1']));

    // Save Label Option 1
    update_post_meta($post_id, 'FieldLenght1', esc_attr($_POST['FieldLenght1']));

    // Save Dropdown1
    update_post_meta($post_id, 'Dropdown1', esc_attr($_POST['Dropdown1']));
}

/**
 * Register the 'Custom Column' column in the importer.
 *
 * @param array $options
 * @return array $options
 */
function add_column_to_importer($options)
{

    // column slug => column name
    $options['FieldName1'] = 'FieldName1';
    $options['FieldType1'] = 'FieldType1';
    $options['FieldLenght1'] = 'FieldLenght1';
    $options['Dropdown1'] = 'Dropdown1';

    return $options;
}
add_filter('woocommerce_csv_product_import_mapping_options', 'add_column_to_importer');

/**
 * Process the data read from the CSV file.
 * This just saves the value in meta data, but you can do anything you want here with the data.
 *
 * @param WC_Product $object - Product being imported or updated.
 * @param array $data - CSV data read for the product.
 * @return WC_Product $object
 */
function process_import( $object, $data ) {


    if ( ! empty( $data['FieldName1'] ) ) {
        $object->update_meta_data( 'FieldName1', $data['FieldName1'] );
    }
    if ( ! empty( $data['FieldType1'] ) ) {
        $object->update_meta_data( 'FieldType1', $data['FieldType1'] );
    }
    if ( ! empty( $data['FieldLenght1'] ) ) {
        $object->update_meta_data( 'FieldLenght1', $data['FieldLenght1'] );
    }
    if ( ! empty( $data['Dropdown1'] ) ) {
        $object->update_meta_data( 'Dropdown1', $data['Dropdown1'] );
    }

    return $object;
}
add_filter( 'woocommerce_product_import_pre_insert_product_object', 'process_import', 10, 2 );

// Add the field to the product
add_action('woocommerce_before_add_to_cart_button', 'my_custom_checkout_field');
function my_custom_checkout_field() {
    global $product;

    $product_id = $product->get_id();

    // Get the field name of InputText1
    $FieldType1 = get_post_meta($product_id, 'FieldType1', true);
    $FieldName1 = get_post_meta($product_id, 'FieldName1', true);
    $FieldLenght1 = get_post_meta($product_id, 'FieldLenght1', true);
    $Dropdown1 = get_post_meta($product_id, 'Dropdown1', true);
    $Dropdown1Content = explode(", ", $Dropdown1);

    echo '<table class="extravariations" cellspacing="0">
                        <tbody>';
    // Field 1

    if( ! empty( $FieldType1 ) ){
        if( $FieldType1 == "TEXT AREA"){

            echo '

                    <tr>
                        <td class="label">
                            <label for="'.$FieldName1.'" id="label1">'.$FieldName1.':</label><br> 
                        </td>
                        <td class="value">
                            <textarea id="'.$FieldName1.'" class="inputfield1" name="FieldTypeValue1" maxlength="'.$FieldLenght1.'" rows="2" cols="80" placeholder="" required></textarea>
                        </td>                       
                    </tr>';
        }

        if( $FieldType1 == "TEXT BOX"){
        echo '<tr>
                        <td class="label">
                            <label for="'.$FieldName1.'" id="label1">'.$FieldName1.':</label>
                        </td>
                        <td class="value">
                            <input  id="'.$FieldName1.'" class="inputfield1" type="text"  maxlength="'.$FieldLenght1.'" name="FieldTypeValue1" value="" required>
                        </td>                       
                    </tr>';
        }


        if( $FieldType1 == "DROP DOWN"){


             echo ' <tr>
                            <td class="label">
                                <label for="'.$FieldName1.'" id="label1">'.$FieldName1.':</label>
                            </td>
                            <td class="value">';
            echo'<select id="'.$FieldName1.'" class="inputfield1"             name="FieldTypeValue1" >';
                                foreach ($Dropdown1Content as $Dropdown1IndividualContent) {
                                echo '<option     value="'.$Dropdown1IndividualContent.'">';
                                echo $Dropdown1IndividualContent;
                                echo '</option>';
                                }
            echo'</td></tr>';

        }

    }

    echo'               </tbody>
            </table>';
}

// Store custom field label and value in cart item data
add_action( 'woocommerce_add_cart_item_data','save_my_custom_checkout_field', 20, 2 );
function save_my_custom_checkout_field( $cart_item_data, $product_id ) {
    $label1 = get_post_meta( $product_id, 'FieldName1', true );

    if( isset( $_REQUEST['FieldTypeValue1'] ) && ! empty( $label1 ) )
        $cart_item_data['custom_data']['1'] = array(
            'label' => $label1,
            'value' => sanitize_text_field( $_REQUEST['FieldTypeValue1'] ),
        );


    if( count($cart_item_data['custom_data']) > 0 )
        $cart_item_data['custom_data']['key'] = md5( microtime().rand() );

    return $cart_item_data;
}


// Display items custom fields label and value in cart and checkout pages
add_filter( 'woocommerce_get_item_data', 'render_meta_on_cart_and_checkout', 20, 2 );
function render_meta_on_cart_and_checkout( $cart_data, $cart_item ){
    $custom_items = array();

    if( !empty( $cart_data ) )
        $custom_items = $cart_data;

    if( isset( $cart_item['custom_data'] ) ) {
        foreach( $cart_item['custom_data'] as $key => $custom_data ){
            if( $key != 'key' ){
                $custom_items[] = array(
                    'name' => $custom_data['label'],
                    'value' => $custom_data['value'],
                );
            }
        }

    }
    return $custom_items;
}

// Save item custom fields label and value as order item meta data
add_action('woocommerce_add_order_item_meta','save_in_order_item_meta', 10, 3 );
function save_in_order_item_meta( $item_id, $values, $cart_item_key ) {
    if( isset( $values['custom_data'] ) ) {
        wc_add_order_item_meta( $item_id, $values['custom_data']['label'], $values['custom_data']['value'] );
    }
}

I have been looking for hours and i have no idea how to solve it or what the problem is. Any help or tips will be really helpful. Thanks a lot.


回答1:


The first main problem is $cart_item_data['custom_data']['1'] = array( that should be instead:

$cart_item_data['custom_data'] = array(
    'label' => $label1,
    'value' => sanitize_text_field( $_REQUEST['FieldTypeValue1'] ),
);

Then the 2nd main problem is the last function where woocommerce_get_item_data is obsolete and replaced by woocommerce_checkout_create_order_line_item already answered in your last question.

So here below I have revisited your 3 last functions:

// Store custom field label and value in cart item data
add_action( 'woocommerce_add_cart_item_data','add_custom_data_as_custom_cart_item_data', 10, 3 );
function add_custom_data_as_custom_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
    if( isset( $_REQUEST['FieldTypeValue1'] ) ) {

        // Get an instance of the WC_Product object
        $product = wc_get_product( $variation_id > 0 ? $variation_id : $product_id );

        if( $label = $product->get_meta('FieldName1') ){
            $cart_item_data['custom_data'] = array(
                'label' => $product->get_meta('FieldName1'),
                'value' => sanitize_text_field( $_REQUEST['FieldTypeValue1'] ),
                'unique_key' => md5( microtime().rand() ),
            );
        }
    }
    return $cart_item_data;
}

// Display cart item custom data in cart and checkout pages
add_filter( 'woocommerce_get_item_data', 'display_cart_item_custom_on_cart_and_checkout', 10, 2 );
function display_cart_item_custom_on_cart_and_checkout( $cart_item_data, $cart_item ){
    if( isset($cart_item['custom_data']['label']) && isset($cart_item['custom_data']['value']) ) {
        $cart_item_data[] = array(
            'name' => $cart_item['custom_data']['label'],
            'value' => $cart_item['custom_data']['value'],
        );
    }
    return $cart_item_data;
}

// Save cart item custom data as order item meta data and display it everywhere in Orders and email notifications
add_action('woocommerce_checkout_create_order_line_item', 'save_custom_order_item_meta_data', 10, 4 );
function save_custom_order_item_meta_data( $item, $cart_item_key, $values, $order ) {
    if( isset( $values['custom_data']['label'] ) && isset( $values['custom_data']['value'] ) ) {
       $item->update_meta_data( $values['custom_data']['label'], $values['custom_data']['value'] );
    }
}

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



来源:https://stackoverflow.com/questions/53687705/save-and-display-order-item-custom-meta-data-in-woocommerce

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!