ACE-CM
ACE-CM

Reputation: 59

Add billing_first_name Inside Recent Orders Widget (Woocommerce)

My widget displays recent Woocommerce orders within the wordpress admin dashboard. It works correctly when I remove the billing_first_name field, but when I add this field it creates an error within the code.

How can I add the billing_first_name field to work correctly within my admin widget so it displays all values.

  /**
 * Add a widget to the dashboard.
 *
 */
function wc_orders_dashboard_widgets() {
    wp_add_dashboard_widget(
                 'wc_order_widget_id',         // Widget slug.
                 'Cartlog Orders',         // Title.
                 'wc_orders_dashboard_widget_function' // Display function.
        );  
}
add_action( 'wp_dashboard_setup', 'wc_orders_dashboard_widgets' );

/**
 * Pulls the order information to the dashboard widget.
 */
function wc_orders_dashboard_widget_function() {    
    $args   = array( 
            'post_type'         => 'shop_order',
            'post_status'       => 'All',  //Other options available choose one only: 'wc-pending', 'wc-processing', 'wc-on-hold', 'wc-cancelled', 'wc-refunded', 'wc-failed'
            'posts_per_page'    => 10     //Change this number to display how many orders you want to see 
          );
    $orders = get_posts( $args );
    if( count( $orders ) > 0 ) {
        ?>      
        <table width="100%">
            <tr>
                <th><?php _e( 'Order Id', 'woocommerce' ); ?></th>
                <th><?php _e( 'Total', 'woocommerce' ); ?></th>
                <th><?php _e( 'Billing Name', 'woocommerce' ); ?></th>
                <th><?php _e( 'Status', 'woocommerce' ); ?></th>
            </tr>
        <?php       
        foreach ( $orders as $key => $value ) {
            
            ?>
            <tr>
                <td>
                <?php
                
                $order   =   new WC_Order( $value->ID );
                // 1. Get the order ID
                if ( $order ) {             
                          echo '<a href="'. admin_url( 'post.php?post=' . absint( $order->id ) . '&action=edit' ) .'" >' . $order->get_order_number() . '</a>';
                ?>
                
                </td>
                <td>    
                
                <?php
                    // 2. Get the order total
                    echo esc_html( wc_get_order_status_name( $order->get_total() ) );
                }
                ?>
                </td>
                <td>    
                
                <?php
                    // 3. Get the billing name
                    echo esc_html(wc_get_order_status_name($order>get_billing_first_name() ) );
                }
                ?>
                </td>
                <td>                
                
                <?php
                    // 4. Get the order status
                    echo esc_html( wc_get_order_status_name( $order->get_status() ) );
                }
                ?>
                </td>                   
            </tr>
            <?php           
        }
        ?></table>
<?php

}

Upvotes: 1

Views: 81

Answers (1)

Nathan Dawson
Nathan Dawson

Reputation: 19328

You're closing the if statement after you've displayed the order total and then have closing braces duplicated for 3 and 4. You're also passing all of your display values through wc_get_order_status_name() which is only appropriate for the order status.

Getting the latest orders

Before fixing the issues highlighted above, it's worth starting with your method for retrieving the latest orders. You're using get_posts() which may work at the moment but isn't advisable. WooCommerce is moving to custom tables so any code that assumes orders are a post will break in the future. You're better off using the functionality that WooCommerce provides.

$orders = wc_get_orders([
    'limit' => 10,
    'orderby' => 'date',
    'order' => 'DESC',
]);

https://github.com/woocommerce/woocommerce/wiki/wc_get_orders-and-WC_Order_Query

A nice benefit of this approach is that you get back an array of WC_Order objects as opposed to posts which then need to be converted.

Displaying orders

foreach ( $orders as $order ) { ?>
    <tr>
        <td>
            <?php printf( 
                '<a href="%1$s">%2$s</a>',
                $order->get_edit_order_url(),
                $order->get_order_number()
            ); ?>
        </td>
        <td><?php echo $order->get_total(); ?></td>
        <td><?php echo $order->get_billing_first_name(); ?></td>
        <td><?php echo wc_get_order_status_name( $order->get_status() ); ?></td>
    </tr>
<?php }

Upvotes: 1

Related Questions