Erhalten Sie Metadaten zu verschachtelten benutzerdefinierten Feldern auf Bearbeitungsseiten für Administratoraufträge in Woocommerce

Lesezeit: 8 Minuten

Benutzer-Avatar
Sir_Nik

In Woocommerce habe ich benutzerdefinierte Felder auf der Checkout-Seite basierend auf der Anzahl der Einkaufswagen hinzugefügt.

// 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]));


  }}}

Alles funktioniert gut und Felder werden validiert und gespeichert.

Das Problem: Ich bin nicht in der Lage, die Werte auf den Seiten zur Bearbeitung von Admin-Bestellungen abzurufen und anzuzeigen.

Da ich an dieser Stelle nicht weiß, wie viele Felder aufgrund der bestellten Menge erstellt wurden, muss ich zuerst die Anzahl der bestellten Artikel abrufen.

Hier ist der zugehörige Code:

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>';
}
}}    

Wie kann ich diese benutzerdefinierten Feldwerte auf den Bearbeitungsseiten für Bestellungen abrufen und anzeigen?
Wie werden diese benutzerdefinierten Feldwerte in E-Mail-Benachrichtigungen angezeigt?

Jede Hilfe wird geschätzt.

Benutzer-Avatar
LoicTheAztec

Sie komplizieren ein bisschen Dinge und es gibt einige Fehler in Ihrem Code.

Es sollte viel besser sein, die Buchungsdaten der Teilnehmer als benutzerdefinierte Metabox auf den Bearbeitungsseiten der Admin-Shop-Bestellungen anzuzeigen (Hier in der rechten Spalte).

Also habe ich Ihren Code komplett überarbeitet:

// 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++;
    }
}

Der Code wird in die function.php-Datei Ihres aktiven untergeordneten Designs (oder aktiven Designs) eingefügt. Getestet und funktioniert.

Geben Sie hier die Bildbeschreibung ein

Um dies in E-Mails und auf den Seiten “Bestellung erhalten” und “Bestellansicht” im Frontend anzuzeigen, müssen Sie eine neue Frage stellen, da sie einfach zu allgemein ist, um sie in einer Antwort zu beantworten.

  • @Sir_Nik Dies ist keine gute Idee, da Sie keine Datenübermittlung vornehmen können (oder möglicherweise mit etwas viel Komplizierterem mit Ajax). Auf der Warenkorbseite gibt es keine Formulare, es wird nichts übermittelt. Es gibt nur Woocommerce Ajax-Aktionen für Warenkorbartikel, Gutscheincodes und einige Versandfelder für den Versandrechner.

    – LoicTheAztec

    23. Mai 2018 um 13:01 Uhr


  • OK ich verstehe. Danke =)

    – Sir_Nik

    23. Mai 2018 um 13:09 Uhr

  • @Sir_Nik Danke… Ich habe Ihre neue Frage gesehen und sie für Ihren großen Programmieraufwand positiv bewertet. Aber das wird sehr kompliziert, irgendwie fortgeschritten und zu breit für StackOverFlow. Sie sollten “anders denken”, wie jemand sagte. Ich glaube nicht, dass jemand in StackOverFlow diese Frage beantworten wird.

    – LoicTheAztec

    23. Mai 2018 um 16:22 Uhr

  • Warum ist zu breit? Ich denke, die Frage ist ziemlich speziell? Wo soll ich stattdessen fragen? =)

    – Sir_Nik

    23. Mai 2018 um 16:31 Uhr


1016560cookie-checkErhalten Sie Metadaten zu verschachtelten benutzerdefinierten Feldern auf Bearbeitungsseiten für Administratoraufträge in Woocommerce

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy