В настоящее время я успешно добавляю поле на страницы продуктов WooCommerce, которые показывают значение:
Проблема: он не отображается как настраиваемое поле в пользовательских полях администратора «Метабокс» со значением внутри него, а также как текст на странице заказа.
Вот мой рабочий код:
// Add the field to the product add_action('woocommerce_before_add_to_cart_button', 'my_custom_checkout_field'); function my_custom_checkout_field() { echo '<div id="my_custom_checkout_field"><h3>'.__('My Field').'</h3>'; echo '<label>fill in this field</label> <input type="text" name="my_field_name">'; echo '</div>'; } // Store custom field function save_my_custom_checkout_field( $cart_item_data, $product_id ) { if( isset( $_REQUEST['my_field_name'] ) ) { $cart_item_data[ 'my_field_name' ] = $_REQUEST['my_field_name']; /* below statement make sure every add to cart action as unique line item */ $cart_item_data['unique_key'] = md5( microtime().rand() ); } return $cart_item_data; } add_action( 'woocommerce_add_cart_item_data', 'save_my_custom_checkout_field', 10, 2 ); // Render meta on cart and checkout function render_meta_on_cart_and_checkout( $cart_data, $cart_item = null ) { $custom_items = array(); /* Woo 2.4.2 updates */ if( !empty( $cart_data ) ) { $custom_items = $cart_data; } if( isset( $cart_item['my_field_name'] ) ) { $custom_items[] = array( "name" => 'My Field', "value" => $cart_item['my_field_name'] ); } return $custom_items; } add_filter( 'woocommerce_get_item_data', 'render_meta_on_cart_and_checkout', 10, 2 ); // This is what I think needs changing? function subscription_order_meta_handler( $item_id, $values, $cart_item_key ) { if( isset( $values['my_field_name'] ) ) { wc_add_order_item_meta( $item_id, "My Field", $values['my_field_name'] ); } } add_action( 'woocommerce_add_order_item_meta', 'subscription_order_meta_handler', 1, 3 );
Я думаю, что это последний бит кода, который нуждается в изменении. В настоящее время он отображает текст под элементом заказа, поэтому, возможно, мне нужно настроить wc_add_order_item_meta
на что-то еще?
Я пробовал все, но он, похоже, не работает. Я могу заставить его работать, когда мое поле находится на странице проверки, но не тогда, когда я вытаскиваю его со страницы продукта.
Возможно, мне не хватает фрагмента процесса проверки?
ОБНОВЛЕНИЕ 2017/11/02 (отлично работает в Woocommerce 3+)
Сначала у меня есть все, что ожидалось, за исключением получения значения для my_field_name
в конце «Пользовательские поля» Metabox внутри страниц заказа.
Затем, после настоящего кошмара, я нашел довольно приятное рабочее решение , лучше, чем раньше. В конце у вас теперь есть пользовательский метабокс с настраиваемым полем my_field_name
отображающим правильное значение, как на этом скриншоте:
Мой код разделен на 2 части.
1) Бэкэнд Metabox на страницах Order , с редактируемым полем, показывающим правильное значение, поступающее из пользовательского поля на страницах продукта (в лицевой части):
// Adding Meta container admin shop_order pages add_action( 'add_meta_boxes', 'mv_add_meta_boxes' ); if ( ! function_exists( 'mv_add_meta_boxes' ) ) { function mv_add_meta_boxes() { add_meta_box( 'mv_other_fields', __('My Field','woocommerce'), 'mv_add_other_fields_for_packaging', 'shop_order', 'side', 'core' ); } } // Adding Meta field in the meta container admin shop_order pages if ( ! function_exists( 'mv_add_other_fields_for_packaging' ) ) { function mv_add_other_fields_for_packaging() { global $post; $meta_field_data = get_post_meta( $post->ID, '_my_field_slug', true ) ? get_post_meta( $post->ID, '_my_field_slug', true ) : ''; echo '<input type="hidden" name="mv_other_meta_field_nonce" value="' . wp_create_nonce() . '"> <p style="border-bottom:solid 1px #eee;padding-bottom:13px;"> <input type="text" style="width:250px;";" name="my_field_name" placeholder="' . $meta_field_data . '" value="' . $meta_field_data . '"></p>'; } } // Save the data of the Meta field add_action( 'save_post', 'mv_save_wc_order_other_fields', 10, 1 ); if ( ! function_exists( 'mv_save_wc_order_other_fields' ) ) { function mv_save_wc_order_other_fields( $post_id ) { // We need to verify this with the proper authorization (security stuff). // Check if our nonce is set. if ( ! isset( $_POST[ 'mv_other_meta_field_nonce' ] ) ) { return $post_id; } $nonce = $_REQUEST[ 'mv_other_meta_field_nonce' ]; //Verify that the nonce is valid. if ( ! wp_verify_nonce( $nonce ) ) { return $post_id; } // If this is an autosave, our form has not been submitted, so we don't want to do anything. if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return $post_id; } // Check the user's permissions. if ( 'page' == $_POST[ 'post_type' ] ) { if ( ! current_user_can( 'edit_page', $post_id ) ) { return $post_id; } } else { if ( ! current_user_can( 'edit_post', $post_id ) ) { return $post_id; } } // --- Its safe for us to save the data ! --- // // Sanitize user input and update the meta field in the database. update_post_meta( $post_id, '_my_field_slug', $_POST[ 'my_field_name' ] ); } }
2) Передний конец / задний конец:
• Пользовательское поле страницы продукта (передняя часть).
• Отображение этих данных на тележке, страницах проверки и благодарность за заказ (передняя часть).
• Отображение данных на странице заказа (назад)
// Add the field to the product add_action('woocommerce_before_add_to_cart_button', 'my_custom_product_field'); function my_custom_product_field() { echo '<div id="my_custom_field"> <label>' . __( 'My Field') . ' </label> <input type="text" name="my_field_name" value=""> </div><br>'; } // Store custom field add_action( 'woocommerce_add_cart_item_data', 'save_my_custom_product_field', 10, 2 ); function save_my_custom_product_field( $cart_item_data, $product_id ) { if( isset( $_REQUEST['my_field_name'] ) ) { $cart_item_data[ 'my_field_name' ] = $_REQUEST['my_field_name']; // below statement make sure every add to cart action as unique line item $cart_item_data['unique_key'] = md5( microtime().rand() ); WC()->session->set( 'my_order_data', $_REQUEST['my_field_name'] ); } return $cart_item_data; } // Add a hidden field with the correct value to the checkout add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' ); function my_custom_checkout_field( $checkout ) { $value = WC()->session->get( 'my_order_data' ); echo '<div id="my_custom_checkout_field"> <input type="hidden" class="input-hidden" name="my_field_name" id="my_field_name" value="' . $value . '"> </div>'; } // Save the order meta with hidden 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['my_field_name'] ) ) { update_post_meta( $order_id, '_my_field_slug', $_POST['my_field_name'] ); } } // Display field value on the order edit page (not in custom fields metabox) 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){ $my_custom_field = get_post_meta( $order->id, '_my_field_slug', true ); if ( ! empty( $my_custom_field ) ) { echo '<p><strong>'. __("My Field", "woocommerce").':</strong> ' . get_post_meta( $order->id, '_my_field_slug', true ) . '</p>'; } } // Render meta on cart and checkout add_filter( 'woocommerce_get_item_data', 'render_meta_on_cart_and_checkout', 10, 2 ); function render_meta_on_cart_and_checkout( $cart_data, $cart_item = null ) { $custom_items = array(); if( !empty( $cart_data ) ) $custom_items = $cart_data; if( isset( $cart_item['my_field_name'] ) ) $custom_items[] = array( "name" => 'My Field', "value" => $cart_item['my_field_name'] ); return $custom_items; } // Add the information as meta data so that it can be seen as part of the order add_action('woocommerce_add_order_item_meta','add_values_to_order_item_meta', 10, 3 ); function add_values_to_order_item_meta( $item_id, $cart_item, $cart_item_key ) { // lets add the meta data to the order (with a label as key slug) if( ! empty( $cart_item['my_field_name'] ) ) wc_add_order_item_meta($item_id, __('My field label name'), $cart_item['my_field_name'], true); }
Сейчас все работает так, как ожидалось.