Пользовательские поля динамического оформления заказа для людей и товаров в Woocommerce - PullRequest
0 голосов
/ 25 мая 2018

Для веб-сайта бронирования я пытаюсь создать функцию, которая позволяет добавлять список участников на основе количества человек.Я уже получил код для одного бронирования, благодаря LoicTheAztec.Эта часть работает нормально.

Мне также нужны те же функции для нескольких заказов.Как мне этого добиться?

Вот код:

//* Add a new checkout field
add_filter( 'woocommerce_checkout_fields', 'ppp_filter_checkout_fields' );
function ppp_filter_checkout_fields($fields){
    $fields['extra_fields'] = array(
    'participant_details' => array(
        'type' => 'participant_details',
        'required'      => false,
        'label' => __( 'Participant Details' )
        ),
    );

    // Add a "persons" hidden input field
    foreach( WC()->cart->get_cart() as $cart_item ) {
        $persons = $cart_item['booking']['_persons'][0];
    }
    echo '<input type="hidden" name="persons" value="' . $persons . '">';

    return $fields;
}

//* Add the field to the checkout
add_filter( 'woocommerce_form_field_participant_details', 'ppp_filter_checkout_field_group', 10, 4 );
function ppp_filter_checkout_field_group( $field, $key, $args, $value ){
    $op_cart_count = WC()->cart->get_cart_contents_count();

    $items = WC()->cart->get_cart();

    foreach($items as $item) {
        $person = $item['booking']['_persons'][0];
    }

    if ($person > 1) {

        $html = '';

        $html .= "<h3>Deelnemers</h3>";

        for ( $i = 1; $i < $person; $i++) {
            $counter = $i + 1;

            $html .= "Deelnemer ". $counter . "<br>";

            $html .= woocommerce_form_field( "participant_details[$i][full_name]", array(
                "type" => "text",
                "return" => true,
                "value" => "",
                "required"      => true,
                "label" => __( "Naam" )
                )
            );
            $html .= woocommerce_form_field( "participant_details[$i][email_address]", array(
                "type" => "email",
                "return" => true,
                "value" => "",
                "required"      => true,
                "label" => __( "Emailadres" )
                )
            );

        }
        return $html;
    }
}

//* display the extra field on the checkout form
add_action( 'woocommerce_checkout_after_customer_details' ,'ppp_extra_checkout_fields' );
function ppp_extra_checkout_fields(){

    $checkout = WC()->checkout();

    foreach ( $checkout->checkout_fields['extra_fields'] as $key => $field ) :

        woocommerce_form_field( $key, $field, $checkout->get_value( $key ) );

    endforeach;
}

//* Validate custom checkout fields
add_action( 'woocommerce_after_checkout_validation', 'ppp_checkout_field_participant_details_validation', 20, 2 );
function ppp_checkout_field_participant_details_validation( $data, $errors ){
    if ( isset( $_POST['persons'] ) && $_POST['persons'] > 1 ){

        for ( $i = 1, $j = 2; $i < esc_attr( $_POST['persons'] ); $i++, $j++ ) {
            if ( empty( $_POST['participant_details'][$i]['full_name'] ) )
                $errors->add( 'participant_'.$i.'_full_name',  __( "Please fill in the participant $j full name" ), 'error' );

            if ( empty( $_POST['participant_details'][$i]['email_address'] ) )
                $errors->add( 'participant_'.$i.'_email_address',  __( "Please fill in the participant $j email address" ), 'error' );
        }
    }
}


//* Sanitize our custom field
function ppp_custom_process_checkout_field_participant_details( $posted ){

    $clean = array();

    foreach( $posted as $participant ){
        $details = ppp_custom_checkout_clean_participant_details( $participant );

        if( ! empty( $details ) ){
            $clean[] = $details;
        }
    }

    return $clean;
}
add_filter( 'woocommerce_process_checkout_participant_details_field', 'ppp_custom_process_checkout_field_participant_details' );

//*
function ppp_custom_checkout_clean_participant_details( $participant = array() ){
    $details = array();
    if( isset( $participant["full_name"] ) ){
        $details['full_name'] = sanitize_text_field( $participant["full_name"] );
    }
    if( isset( $participant["email_address"] ) ){
        $details['email_address'] = sanitize_text_field( $participant["email_address"] );
    }
    return $details;
}


//* Update_post_meta
add_action( 'woocommerce_checkout_update_order_meta', 'ppp_custom_checkout_field_update_order_meta', 10, 2 );
function ppp_custom_checkout_field_update_order_meta( $order_id, $posted ){

    if( ! empty( $posted["participant_details"] ) ){
        update_post_meta( $order_id, "_participant_details", $posted["participant_details"] );
    } else {
        delete_post_meta( $order_id, "_participant_details" );
    }

}
add_action( 'woocommerce_checkout_update_order_meta', 'ppp_custom_checkout_field_update_order_meta', 10, 2 );

1 Ответ

0 голосов
/ 25 мая 2018

Вы пропустили дополнительный цикл (цикл элементов корзины)… Я полностью пересмотрел ваш код, чтобы он работал для нескольких элементов (разных элементов).

Таким образом, поля теперь динамически генерируются элементами и персонами каждого элемента:

// Conditional function: Check if at least there is more than one person in cart items
function ppp_check_persons(){
    $enabled    = array();

    foreach( WC()->cart->get_cart() as $cart_item) {
        if( isset($cart_item['booking']['_persons'][0])
        && $cart_item['booking']['_persons'][0] > 1 )
        {
            $enabled = true;
            break;
        }
    }
    return $enabled;
}

// Add a new checkout field
add_filter( 'woocommerce_checkout_fields', 'ppp_filter_checkout_fields' );
function ppp_filter_checkout_fields($fields){

    $fields['extra_fields'] = array( 'participant' => array(
        'type' => 'participant',
        'required'      => false,
        'label' => __( 'Participant Details' )
    ) );

    $cart_items = WC()->cart->get_cart();
    $count      = 1;

    echo '<input type="hidden" name="items_count" value="' . sizeof($cart_items) . '">';

    if( ! ppp_check_persons() ) return $fields; // Exit (not enough persons)

    // Add "persons" hidden input fields for each cart_item
    foreach( WC()->cart->get_cart() as $cart_item ) {
        $persons = $cart_item['booking']['_persons'][0];
        echo '<input type="hidden" name="persons_'.$count.'" value="' . $persons . '">';
        $count++;
    }

    return $fields;
}

// Add the field to the checkout
add_filter( 'woocommerce_form_field_participant', 'ppp_filter_checkout_field_group', 10, 4 );
function ppp_filter_checkout_field_group( $field, $key, $args, $value ){
    if( ! ppp_check_persons() ) return $fields; // Exit (not enough persons)

    ob_start();

    echo "<h3>Deelnemers</h3>";

    $cart_items = WC()->cart->get_cart();
    $nb_items   = sizeof($cart_items);
    $count      = 1;

    // Loop through cart items;
    foreach( $cart_items as $cart_item) {
        $persons = $cart_item['booking']['_persons'][0];

        if ( $persons > 1  && $persons != 1 ) {
            echo '<h4 style="font-size:135%;">Item'.$count.'</h4>';

            for ( $i = 1, $j = 2; $i < $persons; $i++, $j++)
            {
                echo '<span style="margin-bottom:12px;display:inline-block;font-size:112%;">' . __("Deelnemer") . ' ' . $j . '</span>';

                echo woocommerce_form_field( "participant[$count][$j][fname]", array(
                    "type" => "text",
                    "return" => true,
                    "value" => "",
                    "required"      => true,
                    "label" => __( "Naam" )
                ) );

                echo woocommerce_form_field( "participant[$count][$j][email]", array(
                    "type" => "email",
                    "return" => true,
                    "value" => "",
                    "required"      => true,
                    "label" => __( "Emailadres" )
                ) );

            }
            echo '<br>';
        }
        $count++;
    }
    return ob_get_clean();
}

// display the extra field on the checkout form
add_action( 'woocommerce_checkout_after_customer_details' ,'ppp_extra_checkout_fields' );
function ppp_extra_checkout_fields(){
    $checkout = WC()->checkout();

    foreach ( $checkout->checkout_fields['extra_fields'] as $key => $field )
    {
        woocommerce_form_field( $key, $field, $checkout->get_value( $key ) );
    }
}

// Validate custom checkout fields
add_action( 'woocommerce_after_checkout_validation', 'ppp_checkout_field_participant_details_validation', 20, 2 );
function ppp_checkout_field_participant_details_validation( $data, $errors ){
    if ( !( isset($_POST['items_count']) && ! empty($_POST['items_count']) ) ) return; // Exit

    for ( $h = 1; $h <= esc_attr( $_POST['items_count'] ); $h++ )
    {
        if ( isset( $_POST['persons_'.$h] ) && $_POST['persons_'.$h] > 1 )
        {
            for ( $i = 1, $j = 2; $i < esc_attr( $_POST['persons_'.$h] ); $i++, $j++ )
            {
                if ( isset( $data['participant'][$h][$j]['fname'] ) && empty( $data['participant'][$h][$j]['fname'] ) )
                    $errors->add( 'participant_'.$h.'_'.$j.'_fname',  __( "Please fill in the participant $j full name (Item $h)" ), 'error' );

                if ( isset( $data['participant'][$h][$j]['email'] ) && empty( $data['participant'][$h][$j]['email'] ) )
                    $errors->add( 'participant_'.$h.'_'.$j.'_email',  __( "Please fill in the participant $j email address (Item $h)" ), 'error' );
            }
        }
    }
}


// Save custom fields values in the order as meta data
add_action( 'woocommerce_checkout_create_order', 'ppp_custom_fields_checkout_create_order', 20, 2 );
function ppp_custom_fields_checkout_create_order( $order, $data ){
    if ( !( isset($_POST['items_count']) && ! empty($_POST['items_count']) ) ) return; // Exit

    // Save number of different items in cart
    $order->update_meta_data( '_items_count', esc_attr( $_POST['items_count'] ) );

    for ( $h = 1; $h <= esc_attr( $_POST['items_count'] ); $h++ )
    {
        if ( isset( $_POST['persons_'.$h] ) && $_POST['persons_'.$h] > 1 )
        {
            // Save number of persons for each item in cart
            $order->update_meta_data( '_item_'.$h.'_persons', esc_attr( $_POST['persons_'.$h] ) );

            for ( $i = 1, $j = 2; $i < esc_attr( $_POST['persons_'.$h] ); $i++, $j++ )
            {
                // Save number of persons for each item in cart
                if ( isset( $data['participant'][$h][$j]['fname'] ) ){
                    $full_name = sanitize_text_field( $data['participant'][$h][$j]['fname'] );
                    $order->update_meta_data( '_participant_'.$h.'_'.$j.'_fname', $full_name );
                }

                if ( isset( $data['participant'][$h][$j]['email'] ) ){
                    $email_address = sanitize_text_field( $data['participant'][$h][$j]['email'] );
                    $order->update_meta_data( '_participant_'.$h.'_'.$j.'_email', $email_address );
                }
            }
        }
    }
}

Код помещается в файл function.php вашей активной дочерней темы (или активной темы)).Протестировано и работает.

Отображение данных в интерфейсных и серверных уведомлениях заказов и / или по электронной почте слишком широки для этого ответа, который обрабатывает все остальное.Отображать эти данные на страницах редактирования заказа администратора под сведениями о клиенте не очень хорошая идея, и вместо этого следует сделать это в пользовательском метабоксе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...