【问题标题】:Get nested custom fields meta data on admin order edit pages in Woocommerce在 Woocommerce 的管理订单编辑页面上获取嵌套的自定义字段元数据
【发布时间】:2018-10-30 14:03:29
【问题描述】:

在 woocommerce 中,我根据购物车数量在结帐页面上添加了自定义字段。

// Adding Custom Fields based on Cart Count

add_action( 'woocommerce_before_checkout_billing_form', 'srd_custom_einstiegswahl');

function srd_custom_einstiegswahl($checkout){

global $woocommerce;
$items = $woocommerce->cart->get_cart();

$i = 1;

foreach($items as $item => $values) { 
    $_product = $values['data']->post;
    $quantity = $values['quantity'];
    $x = 1;

    while ($x <= $quantity) {
            // Add fields here
            echo '<h6>Reiseteilnehmer '.$x . '</h6>';
            woocommerce_form_field( 'attendee_surname_'.$x, array(
                    'type'          => 'text',
                     'class'         => array('checkout_vorname'),
                    'label'         => __('Vorame'),
                    'placeholder'   => __(''),
                    'required'      => true
              ), $checkout->get_value( 'attendee_surname_'.$x ));
            woocommerce_form_field( 'attendee_name_'.$x, array(
                    'type'          => 'text',
                    'class'         => array('checkout_nachname'),
                    'label'         => __('Nachname'),
                    'placeholder'       => __(''),
                    'required'      => true
              ), $checkout->get_value( 'attendee_name_'.$x ));
            echo '<select name=einstiegswahl'.$x .'>';
            // Select field populated by Custom Product Meta
            echo '<option value="" style="display:none"> Bitte wählen Sie Ihren Einstiegsort </option>';

            // Loop through cart items
             foreach ( WC()->cart->get_cart() as $cart_item ) {
            // Get the custom field data
             $einstiegsorte = get_post_meta( $cart_item[ 'product_id' ], '_einstiegsorte', true );
            if( ! empty($einstiegsorte) ){
            // if it's multiline we split it in an array
            $select_field_items = explode( "\n", $einstiegsorte );
            // If the array has more than one item
                if( sizeof( $select_field_items ) > 1 ){
                     foreach( $select_field_items as $value )
                         echo '<option value="'. $value .'">' . $value . '</option>';
                } 
            // If there is only one line
                else {
                // we clean it
                $value = str_replace('\n', '', $einstiegsorte);
                echo '<option value="'. $value .'">' . $value . '</option>';
                    }
                }
            }

            echo '</select>'; $checkout->get_value( 'einstiegswahl'.$x );
        $x++;
    }

    $i++;
}   
}


// Process the checkout

add_action('woocommerce_checkout_process', 'srd_teilnehmer_fields_process');

function srd_teilnehmer_fields_process() {
global $woocommerce;
$items = $woocommerce->cart->get_cart();

$i = 1;

foreach($items as $item => $values) { 
    $_product = $values['data']->post;
    $quantity = $values['quantity'];
    $x = 1;

    for($x = 1; $x <= $quantity; $x++ ) {
    //while ($x <= $quantity) {
            if (!$_POST['attendee_surname_'.$x] || !$_POST['attendee_name_'.$x] || !$_POST['einstiegswahl'.$x]) wc_add_notice( __( 'Bitte wählen Sie Ihren Einstiegsort', 'woocommerce' ), 'error' );

        }
    }
}

// Update the order meta with field value

add_action('woocommerce_checkout_update_order_meta', 'srd_teilnehmer_update_order_meta');

function srd_teilnehmer_update_order_meta( $order_id ) {

global $woocommerce;
$items = $woocommerce->cart->get_cart();

$i = 1;

foreach($items as $item => $values) { 
    $_product = $values['data']->post;
    $quantity = $values['quantity'];
    $x = 1;

    for($x = 1; $x <= $quantity; $x++ ) {
            if ( $_POST['attendee_name_'.$x] ) update_post_meta( $order_id, 'attendee_surname_'.$x , sanitize_text_field($_POST['attendee_name_'.$x]) );
            if ($_POST['attendee_surname_'.$x]) update_post_meta( $order_id, 'attendee_name_'.$x, esc_attr($_POST['attendee_surname_'.$x]));
            if ($_POST['einstiegswahl'.$x]) update_post_meta( $order_id, ' Teilnehmer Einstiegsort' .$x, esc_attr($_POST['einstiegswahl'.$x]));


  }}}

一切正常,字段得到验证和保存。

问题:我无法在管理订单编辑页面中获取和显示值。

由于此时我不知道根据订购的数量创建了多少个字段,所以我首先需要获取订购商品的数量。

这是相关代码:

add_action( 'woocommerce_admin_order_data_after_billing_address', 'srd_teilnehmer_checkout_field_display_admin_order_meta', 10, 1 );
//add_action( 'woocommerce_email_order_meta', 'srd_teilnehmer_checkout_field_display_admin_order_meta', 10, 3 );

function srd_teilnehmer_checkout_field_display_admin_order_meta($order) {  

$order = wc_get_order( $order_id );

$items = $item_data->get_quantity();

  foreach($items as $item => $values) { 
    $order_quantity = $values['quantity'];
    $x = 1;

    while ($x <= $order_quantity) { 
        echo '<p><strong>'.__('Nachname'.$x).':</strong> ' . get_post_meta( $order->id, 'attendee_name_'.$x, true ) . '</p>';
}
}}    

如何在管理订单编辑页面中获取和显示这些自定义字段值?
如何在电子邮件通知中显示该自定义字段值?

任何帮助将不胜感激。

【问题讨论】:

    标签: php wordpress woocommerce checkout orders


    【解决方案1】:

    你把事情复杂化了,你的代码有一些错误。

    在管理商店订单编辑页面中将与会者预订数据显示为自定义元框应该会更好(在右侧列)

    所以我完全重新审视了你的代码:

    // Adding Custom Fields based on Cart Count
    add_action( 'woocommerce_before_checkout_billing_form', 'srd_custom_einstiegswahl');
    function srd_custom_einstiegswahl( $checkout ){
    
        $count = 1;
    
        // Loop through cart items
        foreach( WC()->cart->get_cart() as $cart_item ) {
            $options       = array( '' => __("Bitte wählen Sie Ihren Einstiegsort") ); 
            $einstiegsorte = get_post_meta( $cart_item[ 'product_id' ], '_einstiegsorte', true );
    
            if( ! empty($einstiegsorte) ){
                $option_items = explode( "\n", $einstiegsorte );
                if( sizeof( $option_items ) > 1 ){
                    foreach( $option_items as $value )
                        $options[$value] = $value;
                } else {
                    $value = str_replace('\n', '', $einstiegsorte);
                    $options[$value] = $value;
                }
            }
    
            // Loop through cart item quantity
            for($i = 1; $i <= $cart_item['quantity']; $i++ ) {
    
                $j = $count.'_'.$i;
    
                echo '<h6>Reiseteilnehmer '.$i . '</h6>';
    
                woocommerce_form_field( '_teilnehmer_vorame_'.$j, array(
                        'type'          => 'text',
                         'class'         => array('checkout_vorname'),
                        'label'         => __('Vorame'),
                        'required'      => true,
                ), $checkout->get_value( '_teilnehmer_vorame_'.$j ));
    
                woocommerce_form_field( '_teilnehmer_nachname_'.$j, array(
                        'type'          => 'text',
                        'class'         => array('checkout_nachname'),
                        'label'         => __('Nachname'),
                        'required'      => true,
                ), $checkout->get_value( '_teilnehmer_nachname_'.$j ));
    
                woocommerce_form_field( '_teilnehmer_einstiegswahl_'.$j, array(
                    'type'          => 'select',
                    'class'         => array('checkout_einstiegswahl'),
                    'label'         => __('Einstiegswahl'),
                    'required'      => true,
                    'options'       => $options,
                ), $checkout->get_value( '_teilnehmer_einstiegswahl_'.$j ));
            }
            $count++;
        }
    }
    
    // Custom checkout fields validation
    add_action('woocommerce_checkout_process', 'srd_teilnehmer_fields_process');
    function srd_teilnehmer_fields_process() {
        $count = 1;
    
        // Loop through cart items
        foreach( WC()->cart->get_cart() as $cart_item ) {
    
            // Loop through cart item quantity
            for($i = 1; $i <= $cart_item['quantity']; $i++ ) {
    
                $j = $count.'_'.$i;
    
                if (!$_POST['_teilnehmer_vorame_'.$j] || !$_POST['_teilnehmer_nachname_'.$j] || !$_POST['_teilnehmer_einstiegswahl_'.$j])
                    wc_add_notice( __( 'Bitte wählen Sie Ihren Einstiegsort', 'woocommerce' ), 'error' );
            }
            $count++;
        }
    }
    
    // Update the order meta data with checkout custom fields values
    add_action('woocommerce_checkout_create_order', 'srd_teilnehmer_checkout_create_order', 20, 2 );
    function srd_teilnehmer_checkout_create_order( $order, $data ) {
        $count = 1;
    
        // Loop through cart item quantity
        foreach( WC()->cart->get_cart() as $cart_item ) {
    
            // Loop through item quantity
            for($i = 1; $i <= $cart_item['quantity']; $i++ ) {
    
                $j = $count.'_'.$i;
    
                if ( isset($_POST['_teilnehmer_vorame_'.$j]) )
                    $order->update_meta_data( '_teilnehmer_vorame_'.$j , sanitize_text_field($_POST['_teilnehmer_vorame_'.$j]) );
    
                if ( isset($_POST['_teilnehmer_nachname_'.$j]) )
                    $order->update_meta_data( '_teilnehmer_nachname_'.$j, sanitize_text_field($_POST['_teilnehmer_nachname_'.$j]) );
    
                if ( isset($_POST['_teilnehmer_einstiegswahl_'.$j]) )
                    $order->update_meta_data( '_teilnehmer_einstiegswahl_'.$j, sanitize_text_field($_POST['_teilnehmer_einstiegswahl_'.$j]) );
            }
            $count++;
        }
    }
    
    // Adding Custom metabox in admin orders edit pages (on the right column)
    add_action( 'add_meta_boxes', 'add_reiseteilnehmer_metabox' );
    function add_reiseteilnehmer_metabox(){
        add_meta_box(
            'attendees',
            __('Reiseteilnehmer'),
            'reiseteilnehmer_inhalt',
            'shop_order',
            'side', // or 'normal'
            'default' // or 'high'
        );
    }
    
    // Adding the content for the custom metabox
    function reiseteilnehmer_inhalt() {
        $order = wc_get_order(get_the_id());
    
        $count = 1;
    
        $key_labels = array( 'vorame', 'nachname', 'einstiegswahl' );
    
        // Loop through order items
        foreach ( $order->get_items() as $item ){
    
            echo '<h4 style="margin:1em 0 .5em;">Order item '.$count.'</h4>';
    
            // Loop through item quantity
            for($i = 1; $i <= $item->get_quantity(); $i++ ) {
    
                echo '<div style="background-color:#eee;padding:2px;margin-bottom:.4em;">
                <h4 style="margin:.5em 0;padding:2px;">Reiseteilnehmer '.$i.'</h4>
                <table style="text-align:left;margin-bottom:.7em;" cellpadding="2"><tbody>';
    
                $style = ' style="padding:2px 0;"';
    
                // Loop through attendee fields
                foreach( $key_labels as $key ){
                    $value = get_post_meta( $order->get_id(), '_teilnehmer_'.$key.'_'.$count.'_'.$i, true );
                    echo '<tr><th>'.ucfirst($key).':</th><td>'.$value.'</td></tr>';
                }
    
                echo '</tbody></table></div>';
            }
            $count++;
        }
    }
    

    代码进入您的活动子主题(或活动主题)的 function.php 文件中。经过测试并且可以工作。

    要在电子邮件和前端“已收到订单”和“我的帐户”“订单视图”页面中显示这一点,您必须提出一个新问题,因为它太宽泛,无法在一个答案中回答。

    【讨论】:

    • @Sir_Nik 这不是一个好主意,因为您将无法提交任何数据(或者可能使用 Ajax 进行更复杂的操作)。在购物车页面中没有表格,没有提交任何内容。只有 Woocommerce Ajax 对购物车商品、优惠券代码和运费计算器的某些运费字段进行操作。
    • 好的,我明白了。谢谢=)
    • @Sir_Nik 谢谢……我看到了你的新问题,并为你的编码工作点赞。但这对于 StackOverFlow 来说变得非常复杂、高级且过于宽泛。正如有人所说,您应该“思考不同”。我不认为 StackOverFlow 中的某个人会回答这个问题。
    • 为什么太宽泛了?我觉得这个问题很特别?我应该在哪里问? =)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-14
    • 2018-10-01
    • 2018-08-25
    • 2021-11-10
    • 2018-07-02
    相关资源
    最近更新 更多