WooCommerce-Kundenauftragsdetails in BS Modal

Lesezeit: 9 Minuten

Yuris Benutzeravatar
Yuri

Auf einer WordPress-Website, auf der WooCommerce ausgeführt wird, kann sich der Benutzer in seinem (standardmäßigen) persönlichen Bereich anmelden und Informationen anzeigen wie:

  • Bestellhistorie
  • Download
  • Adressen
  • Bearbeitungs Information
  • Ausloggen

In dem orders Registerkarte wird standardmäßig eine Tabelle mit einer Liste aller Bestellungen angezeigt, mit a View Schaltfläche, die zur vollständigen Detailseite dieser Bestellung weiterleitet.

Ich versuche, diese Tabellenansicht in einem modalen Fenster anzuzeigen.

Ich habe kein Problem damit, das Modal mit der darin geladenen Ziel-URL anzuzeigen. Das eigentliche Problem ist, dass die Ziel-URL die der ganzen Seite ist, die wie in einer angezeigt wird <iframe>und ist nicht das, was ich will.

Ich denke, es gibt einen Shortcode, der es ermöglicht, nur diese Tabelle zu laden, oder vielleicht eine Woocommerce-Funktion wie load_order_content_by_id($id)?

Kann mich jemand in die richtige Richtung weisen?

Vielen Dank

===GELÖST===

Danke an Raunak Gupta für den Hinweis auf die richtige Funktion. Ich überschreibe die Orders.php-Vorlage, fügte Modal Window HTML hinzu und bearbeitete sie $actions:

'view'   => array(
    'url'  => 'javascript:;',
    'data' => [
        'order-number' => $order->get_order_number()
    ],
    'name' => __( 'View', 'woocommerce' )
),

und in derselben Datei:

foreach ( $actions as $key => $action ) {
    echo '<a href="' . esc_url( $action['url'] ) . '" class="button ' . sanitize_html_class( $key ) . '"';
    if(isset($action['data']) && is_array($action['data'])){
        foreach($action['data'] AS $data_attr=>$data_value){
            echo 'data-' . sanitize_html_class($data_attr) .'="' .esc_html($data_value) . '" ';
        }
    }
    echo '>' . esc_html( $action['name'] ) . '</a>';
}

Ein bisschen JS

$('.woocommerce-MyAccount-orders .button.view').on('click', function(e){
    e.preventDefault();
    var data = {};
    data.action = 'modal_order';
    data.order_number = $(this).data('order-number');

    $.get( ajax_script.ajax_url, data, function(response) {
        $('#modalOrderDetail').modal('show').find('.modal-body').html(response);
    });
});

und in WordPress eingehakt von function.php

function modal_order() {
    if(is_user_logged_in()) {
        $order_number = $_GET['order_number'];
        woocommerce_order_details_table($order_number);
    }
}

add_action('wp_ajax_modal_order', 'modal_order');
add_action('wp_ajax_nopriv_modal_order', 'modal_order');

  • Ich kenne Woocommerce nicht, aber Ihre Frage scheint sehr vage zu sein. Versuchen Sie, mehr Details hinzuzufügen (vielleicht a https://jsfiddle.net/ ) und Sie erhalten möglicherweise mehr Antworten.

    – Ruben Pirotte

    26. August 2016 um 7:15 Uhr

  • Ich würde eine Geige machen, wenn es nur möglich wäre, WordPress darin zu laden 🙂 Ich werde versuchen, meinen Beitrag zu klären

    – Juri

    26. August 2016 um 11:30 Uhr

  • Wenn jemand das Bedürfnis nach einem Downvoting verspürt, fügen Sie zumindest eine Erklärung dafür hinzu

    – Juri

    5. Oktober 2016 um 8:18 Uhr

  • @Yuri Es scheint, dass Sie eine Sicherheitslücke auf Ihrer Website erstellt haben, wenn Sie diesen Code verwendet haben. Dein functions.php nur Schecks is_user_logged_in() nicht, wenn der Benutzer diese Bestellung besitzt. Das bedeutet, dass jede angeforderte Bestell-ID angezeigt wird, solange der Benutzer angemeldet ist – einschließlich der Bestellungen anderer Benutzer. Blick auf den Code Es scheint keine anderen Berechtigungsprüfungen durchzuführen.

    – rtpHarry

    11. Dezember 2019 um 11:20 Uhr

  • @Yuri auch, Sie müssen keine Aktion hinzufügen für wp_ajax_nopriv_modal_order weil dies für Ajax-Anfragen von nicht eingeloggten Benutzern gilt.

    – rtpHarry

    11. Dezember 2019 um 11:21 Uhr

Benutzeravatar von LoicTheAztec
LoicTheAztec

Hier ist der vollständiger Code, um aktuelle Kundenbestellungen in einem modalen Fenster anzuzeigen. Es basiert auf einer klassischen Abfrage, um aktuelle Benutzeraufträge zu erhalten, und auf der Vorlage my-account/orders.php (leicht angepasst)

<?php

if(is_user_logged_in()):

    // The query
    $args = array(
        // WC orders post type
        'post_type'   => 'shop_order',
        'numberposts' => -1,
        // for current user id
        'meta_key'    => '_customer_user',
        'meta_value'  => get_current_user_id(),
        // get orders statuses
        'post_status' => array_keys(wc_get_order_statuses()),
    );

    // Get all customer orders
    $customer_orders = get_posts( $args );
    $count_ord = 0;
    if (!empty($customer_orders))
        foreach ( $customer_orders as $custo_order )
            $count_ord++;

    if ( $count_ord > 0 )
        $has_orders = true;
    else
        $has_orders = false;

    // the template my-account/orders.php  ?>

    <?php do_action( 'woocommerce_before_account_orders', $has_orders ); ?>

    <?php if ( $has_orders ) : ?>

    <table class="woocommerce-MyAccount-orders shop_table shop_table_responsive my_account_orders account-orders-table">
        <thead>
            <tr>
                <?php foreach ( wc_get_account_orders_columns() as $column_id => $column_name ) : ?>
                    <th class="<?php echo esc_attr( $column_id ); ?>"><span class="nobr"><?php echo esc_html( $column_name ); ?></span></th>
                <?php endforeach; ?>
            </tr>
        </thead>

        <tbody>
            <?php foreach ( $customer_orders as $customer_order ) :
                $order      = wc_get_order( $customer_order );
                $item_count = $order->get_item_count();
                ?>
                <tr class="order">
                    <?php foreach ( wc_get_account_orders_columns() as $column_id => $column_name ) : ?>
                        <td class="<?php echo esc_attr( $column_id ); ?>" data-title="<?php echo esc_attr( $column_name ); ?>">
                            <?php if ( has_action( 'woocommerce_my_account_my_orders_column_' . $column_id ) ) : ?>
                                <?php do_action( 'woocommerce_my_account_my_orders_column_' . $column_id, $order ); ?>

                            <?php elseif ( 'order-number' === $column_id ) : ?>
                                <a href="https://stackoverflow.com/questions/39070007/<?php echo esc_url( $order->get_view_order_url() ); ?>">
                                    <?php echo _x( '#', 'hash before order number', 'woocommerce' ) . $order->get_order_number(); ?>
                                </a>

                            <?php elseif ( 'order-date' === $column_id ) : ?>
                                <time datetime="<?php echo date( 'Y-m-d', strtotime( $order->order_date ) ); ?>" title="<?php echo esc_attr( strtotime( $order->order_date ) ); ?>"><?php echo date_i18n( get_option( 'date_format' ), strtotime( $order->order_date ) ); ?></time>

                            <?php elseif ( 'order-status' === $column_id ) : ?>
                                <?php echo wc_get_order_status_name( $order->get_status() ); ?>

                            <?php elseif ( 'order-total' === $column_id ) : ?>
                                <?php echo sprintf( _n( '%s for %s item', '%s for %s items', $item_count, 'woocommerce' ), $order->get_formatted_order_total(), $item_count ); ?>

                            <?php elseif ( 'order-actions' === $column_id ) : ?>
                                <?php
                                    $actions = array(
                                        'pay'    => array(
                                            'url'  => $order->get_checkout_payment_url(),
                                            'name' => __( 'Pay', 'woocommerce' )
                                        ),
                                        'view'   => array(
                                            'url'  => $order->get_view_order_url(),
                                            'name' => __( 'View', 'woocommerce' )
                                        ),
                                        'cancel' => array(
                                            'url'  => $order->get_cancel_order_url( wc_get_page_permalink( 'myaccount' ) ),
                                            'name' => __( 'Cancel', 'woocommerce' )
                                        )
                                    );

                                    if ( ! $order->needs_payment() ) {
                                        unset( $actions['pay'] );
                                    }

                                    if ( ! in_array( $order->get_status(), apply_filters( 'woocommerce_valid_order_statuses_for_cancel', array( 'pending', 'failed' ), $order ) ) ) {
                                        unset( $actions['cancel'] );
                                    }

                                    if ( $actions = apply_filters( 'woocommerce_my_account_my_orders_actions', $actions, $order ) ) {
                                        foreach ( $actions as $key => $action ) {
                                            echo '<a href="' . esc_url( $action['url'] ) . '" class="button ' . sanitize_html_class( $key ) . '">' . esc_html( $action['name'] ) . '</a>';
                                        }
                                    }
                                ?>
                            <?php endif; ?>
                        </td>
                    <?php endforeach; ?>
                </tr>
            <?php endforeach; ?>
        </tbody>
    </table>

    <?php do_action( 'woocommerce_before_account_orders_pagination' ); ?>

    <?php if ( 1 < $customer_orders->max_num_pages ) : ?>
        <div class="woocommerce-Pagination">
            <?php if ( 1 !== $current_page ) : ?>
                <a class="woocommerce-Button woocommerce-Button--previous button" href="<?php echo esc_url( wc_get_endpoint_url( 'orders', $current_page - 1 ) ); ?>"><?php _e( 'Previous', 'woocommerce' ); ?></a>
            <?php endif; ?>

            <?php if ( $current_page !== intval( $customer_orders->max_num_pages ) ) : ?>
                <a class="woocommerce-Button woocommerce-Button--next button" href="<?php echo esc_url( wc_get_endpoint_url( 'orders', $current_page + 1 ) ); ?>"><?php _e( 'Next', 'woocommerce' ); ?></a>
            <?php endif; ?>
        </div>
    <?php endif; ?>

<?php else : ?>
    <div class="woocommerce-Message woocommerce-Message--info woocommerce-info">
        <a class="woocommerce-Button button" href="<?php echo esc_url( apply_filters( 'woocommerce_return_to_shop_redirect', wc_get_page_permalink( 'shop' ) ) ); ?>">
            <?php _e( 'Go Shop', 'woocommerce' ) ?>
        </a>
<?php endif; ?>
        <?php _e( 'No order has been made yet.', 'woocommerce' ); ?>
    </div>

<?php do_action( 'woocommerce_after_account_orders', $has_orders ); ?>

<?php endif; ?>

Sie müssen Ihrem modalen Fenster vorhandene CSS-Regeln hinzufügen und/oder diese CSS-Regeln anpassen.

Dieser Code ist getestet und voll funktionsfähig.

  • Danke für die Antwort, aber mit woocommerce_order_details_table( $order_id ) Ich konnte mit wenigen Codezeilen das gewünschte Ergebnis erzielen.

    – Juri

    31. August 2016 um 14:25 Uhr

  • @Yuri Da du es nicht wirklich erwähnt hast, habe ich daran gearbeitet, das ist die Woocommerce-Vorlage für aktuelle Kundenbestellungen, mit Paginierung und allem, genauso wie “Mein Konto” => “Bestellungen” (aber ohne Navigation, Menü und alles, was Sie nicht wollen)… Dies ist eine komplette Key-Turn-Lösung (Alternative).

    – LoicTheAztec

    31. August 2016 um 14:30 Uhr


  • Ich wollte nur, dass die einzelne Bestelltabelle in einem Modalfenster angezeigt wird, nicht die vollständige Bestellliste.

    – Juri

    31. August 2016 um 14:34 Uhr

woocommerce_order_details_table( $order_id )

Diese WooCommerce-Funktion gibt die vollständigen Bestelldetails in HTML-Form zurück $order_id

  • Nett 🙂 Und ich nehme an, dass die verwendete Vorlage – order/order-details.php ist in einem Thema überschreibbar, falls die Struktur nicht das ist, was benötigt wird. +1

    – William Patton

    30. August 2016 um 13:59 Uhr

  • Ja, Sie können überschreiben order/order-details.php, order/order-details-item.php und order/order-details-customer.php Dateien nach Ihren Wünschen.

    – Raunak Gupta

    30. August 2016 um 14:32 Uhr

  • Abgesehen vom Überschreiben der ursprünglichen Vorlage, welche globalen Variablen sollte ich einschließen, um sie zu verwenden?

    – Juri

    31. August 2016 um 8:30 Uhr

  • Sie müssen keine globalen Variablen schreiben, da diese bereits in dieser Vorlage vorhanden sind. Sie müssen sie nur in Ihr aktives Theam kopieren und entsprechend anpassen. vorausgesetzt, Sie wissen, wer diese Vorlage überschreiben soll

    – Raunak Gupta

    31. August 2016 um 8:39 Uhr

Mir ist keine einzige Funktion bekannt, die alle Bestelldetails, die Sie benötigen, auf einmal abrufen kann, aber Sie können anrufen WC_Order Klasse, um zu bekommen, was Sie brauchen. Durch einige ähnliche Anrufmethoden erhalten Sie die Informationen, die Sie benötigen. Sie müssen wahrscheinlich mehr als nur die Anrufe tätigen get_items() Methode abhängig von den genauen Informationen, die Sie benötigen. Im Allgemeinen geben sie Objekte mit einer ähnlichen Struktur wie Post-Objekte zurück.

$order = new WC_Order($post->ID);
$_order = $order->get_items();

Schauen Sie hier unter dem Abschnitt „geerbte Methoden“, um die Methoden zu finden, die Sie möglicherweise aufrufen müssen, um alle benötigten Informationen zu erhalten. https://docs.woocommerce.com/wc-apidocs/class-WC_Order.html

1393750cookie-checkWooCommerce-Kundenauftragsdetails in BS Modal

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

Privacy policy