Viewed   313 times

How can I get an array with Order IDs by Product ID?

I mean receive all orders where specific product is presented.

I know how to do this by MySQL, but is there a way to do this by WP_Query function?

 Answers

3

Updates:

  • 2017 - SQL query changed to "SELECT DISTINCT" instead of "SELECT" to avoid duplicated Order IDs in the array (then no need of array_unique() to filter duplicates…).

  • 2019 - Enabled product variation type support in the SQL Query

Then you can embed this in a custom function with $product_id as argument.
You will have to set inside it, the order statuses that you are targeting.

So here is the function that will do the job:

function get_orders_ids_by_product_id( $product_id ) {
    global $wpdb;
    
    // Define HERE the orders status to include in  <==  <==  <==  <==  <==  <==  <==
    $orders_statuses = "'wc-completed', 'wc-processing', 'wc-on-hold'";

    # Get All defined statuses Orders IDs for a defined product ID (or variation ID)
    return $wpdb->get_col( "
        SELECT DISTINCT woi.order_id
        FROM {$wpdb->prefix}woocommerce_order_itemmeta as woim, 
             {$wpdb->prefix}woocommerce_order_items as woi, 
             {$wpdb->prefix}posts as p
        WHERE  woi.order_item_id = woim.order_item_id
        AND woi.order_id = p.ID
        AND p.post_status IN ( $orders_statuses )
        AND woim.meta_key IN ( '_product_id', '_variation_id' )
        AND woim.meta_value LIKE '$product_id'
        ORDER BY woi.order_item_id DESC"
    );
}

This code goes in any php file.

This code is tested and works for WooCommerce version 2.5+, 2.6+ and 3+


USAGE EXAMPLES:

## This will display all orders containing this product ID in a coma separated string ##

// A defined product ID: 40
$product_id = 40;

// We get all the Orders for the given product ID in an arrray
$orders_ids_array = get_orders_ids_by_product_id( $product_id );

// We display the orders in a coma separated list
echo '<p>' . implode( ', ', $orders_ids_array ) . '</p>';
Monday, October 17, 2022
5

To get all ancestors of a product category, you can use the Wordpress get_ancestors() function

The following custom shortcode function will output for each product category of a given product, the ancestors with the product category in a string as defined in your question:

add_shortcode( 'product_cat_list', 'list_product_categories' )
function list_product_categories( $atts ){
    $atts = shortcode_atts( array(
        'id' => get_the_id(),
    ), $atts, 'product_cat_list' );

    $output    = []; // Initialising
    $taxonomy  = 'product_cat'; // Taxonomy for product category

    // Get the product categories terms ids in the product:
    $terms_ids = wp_get_post_terms( $atts['id'], $taxonomy, array('fields' => 'ids') );

    // Loop though terms ids (product categories)
    foreach( $terms_ids as $term_id ) {
        $term_names = []; // Initialising category array

        // Loop through product category ancestors
        foreach( get_ancestors( $term_id, $taxonomy ) as $ancestor_id ){
            // Add the ancestors term names to the category array
            $term_names[] = get_term( $ancestor_id, $taxonomy )->name;
        }
        // Add the product category term name to the category array
        $term_names[] = get_term( $term_id, $taxonomy )->name;

        // Add the formatted ancestors with the product category to main array
        $output[] = implode(' > ', $term_names);
    }
    // Output the formatted product categories with their ancestors
    return '"' . implode('" | "', $output) . '"';
}

Code goes in function.php file of your active child theme (active theme). Tested and works.


USAGE:

1) In the php code of product page:

echo do_shortcode( "[product_cat_list]" );

2) In php code with a given product ID (here the product ID is 37 for example):

echo do_shortcode( "[product_cat_list id='37']" );

I think that the product name is not needed in your output as it is repetitive (on each product category). So you will get something like this:

"Cat1" | "Cat2>subcat1" | "Cat3>subcat1>subcat2"
Sunday, October 23, 2022
 
5

I have made some changes in your SQL and set the code in an utility function:

function get_active_members_for_membership($memberships){
    global $wpdb;

    // Getting all User IDs and data for a membership plan
    return $wpdb->get_results( "
        SELECT DISTINCT um.user_id, u.user_email, u.display_name, p2.post_title, p2.post_type
        FROM {$wpdb->prefix}posts AS p
        LEFT JOIN {$wpdb->prefix}posts AS p2 ON p2.ID = p.post_parent
        LEFT JOIN {$wpdb->prefix}users AS u ON u.id = p.post_author
        LEFT JOIN {$wpdb->prefix}usermeta AS um ON u.id = um.user_id
        WHERE p.post_type = 'wc_user_membership'
        AND p.post_status IN ('wcm-active')
        AND p2.post_type = 'wc_membership_plan'
        AND p2.post_title LIKE '$memberships'
    ");
}

This code goes on function.php file of your active child theme (or theme). Tested and works.

USAGE:

// Replace 'My Membership' by your targeted membership name.
$users_data = get_active_members_for_membership('My Membership');

// Test raw output
echo '<pre>'; print_r( $users_data ); echo '</pre>';
Monday, August 15, 2022
 
zabbala
 
4

I have Just set the loop for products names, but i haven't test it. You will have to search for thumbnails (see the link at the end).

For the products loop, i have use the code from Sandeep Kumar: WooCommerce display order product name in my account

foreach($order->get_items() as $item) {
    $product_name = $item['name'];
}

The code of your custom template is here below:

.my_product_name {
    display: block;
}
<?php
/**
 * My Orders
 *
 * Shows recent orders on the account page
 *
 * @author  WooThemes
 * @package WooCommerce/Templates
 * @version 2.3.10
 */
 
if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly
}
 
$customer_orders = get_posts( apply_filters( 'woocommerce_my_account_my_orders_query', array(
    'numberposts' => $order_count,
    'meta_key'    => '_customer_user',
    'meta_value'  => get_current_user_id(),
    'post_type'   => wc_get_order_types( 'view-orders' ),
    'post_status' => array_keys( wc_get_order_statuses() )
) ) );
 
$user_id = get_current_user_id();
 
if ( $customer_orders ) : ?>
 
    <h2><?php echo apply_filters( 'woocommerce_my_account_my_orders_title', __( 'Recent Orders', 'woocommerce' ) ); ?></h2>
 
    <table class="shop_table shop_table_responsive my_account_orders">
 
        <thead>
            <tr>
                <th class="order-number"><span class="nobr"><?php _e( 'Order', 'woocommerce' ); ?></span></th>
                <th class="order-date"><span class="nobr"><?php _e( 'Date', 'woocommerce' ); ?></span></th>
                <th class="shipping-name"><span class="nobr"><?php _e( 'Customer name', 'woocommerce' ); ?></span></th>
                <th class="products-names"><span class="nobr"><?php _e( 'Products names', 'woocommerce' ); ?></span></th>
                <th class="order-status"><span class="nobr"><?php _e( 'Status', 'woocommerce' ); ?></span></th>
                <th class="order-total"><span class="nobr"><?php _e( 'Total', 'woocommerce' ); ?></span></th>
                <th class="order-actions">&nbsp;</th>
            </tr>
        </thead>
 
        <tbody><?php
            foreach ( $customer_orders as $customer_order ) {
                $order = wc_get_order( $customer_order );
                $order->populate( $customer_order );
                $item_count = $order->get_item_count();
 
                ?><tr class="order">
                    <td class="order-number" data-title="<?php esc_attr_e( 'Order Number', 'woocommerce' ); ?>">
                        <a href="<?php echo esc_url( $order->get_view_order_url() ); ?>">
                            <?php echo _x( '#', 'hash before order number', 'woocommerce' ) . $order->get_order_number(); ?>
                        </a>
                    </td>
                    <td class="order-date" data-title="<?php esc_attr_e( 'Date', 'woocommerce' ); ?>">
                        <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>
                    </td>
                    <td class="shipping-name" data-title="<?php esc_attr_e( 'Customer name', 'woocommerce' ); ?>">
                        <span><?php echo get_the_author_meta( 'billing_first_name', $user_id ).' '.get_the_author_meta( 'billing_last_name', $user_id ); ?></span>
                    </td>
                    <td class="products-names" data-title="<?php esc_attr_e( 'Products names', 'woocommerce' ); ?>">
                    <?php 
                        foreach($order->get_items() as $item) {
                            $product_name = $item['name'];
                    ?>
                        <span class="my_product_name"><?php echo $product_name; ?></span>
                     <?php } ?>
                    </td>
                    <td class="order-status" data-title="<?php _e( 'Status', 'woocommerce' ); ?>" style="text-align:left; white-space:nowrap;">
                        <?php
                        if($order->get_status()=='completed')
                        {
                            echo 'Dispatched';
                        }
                        else{
                         echo wc_get_order_status_name( $order->get_status() );
                         }
                          ?>
                    </td>
                    <td class="order-total" data-title="<?php esc_attr_e( 'Total', 'woocommerce' ); ?>">
                        <?php echo sprintf( _n( '%s for %s item', '%s for %s items', $item_count, 'woocommerce' ), $order->get_formatted_order_total(), $item_count ); ?>
                    </td>
                    <td class="order-actions">
                        <?php
                            $actions = array();
 
                            if ( in_array( $order->get_status(), apply_filters( 'woocommerce_valid_order_statuses_for_payment', array( 'pending', 'failed' ), $order ) ) ) {
                                $actions['pay'] = array(
                                    'url'  => $order->get_checkout_payment_url(),
                                    'name' => __( 'Pay', 'woocommerce' )
                                );
                            }
 
                            if ( in_array( $order->get_status(), apply_filters( 'woocommerce_valid_order_statuses_for_cancel', array( 'pending', 'failed' ), $order ) ) ) {
                                $actions['cancel'] = array(
                                    'url'  => $order->get_cancel_order_url( wc_get_page_permalink( 'myaccount' ) ),
                                    'name' => __( 'Cancel', 'woocommerce' )
                                );
                            }
 
                            $actions['view'] = array(
                                'url'  => $order->get_view_order_url(),
                                'name' => __( 'View', 'woocommerce' )
                            );
 
                            $actions = apply_filters( 'woocommerce_my_account_my_orders_actions', $actions, $order );
 
                            if ( $actions ) {
                                foreach ( $actions as $key => $action ) {
                                    echo '<a href="' . esc_url( $action['url'] ) . '" class="button ' . sanitize_html_class( $key ) . '">' . esc_html( $action['name'] ) . '</a>';
                                }
                            }
                        ?>
                    </td>
                </tr><?php
            }
        ?></tbody>
 
    </table>
 
<?php endif; ?>

For your products thumbnails, please have a look to this thread with the solution of helgatheviking: Echo woocommerce product thumbnail?

Tuesday, December 6, 2022
 
3

I have revisited the original code answer a bit and I have enabled the display of those parent products linked names on orders and email notifications:

// Adding the grouped product ID custom hidden field data in Cart object
add_filter( 'woocommerce_add_cart_item_data', 'save_custom_fields_data_to_cart', 20, 2 );
function save_custom_fields_data_to_cart( $cart_item_data, $product_id ) {
    if( ! empty($_REQUEST['add-to-cart']) && $product_id != $_REQUEST['add-to-cart']
    && is_numeric($_REQUEST['add-to-cart']) ){
        $group_prod = wc_get_product($_REQUEST['add-to-cart']);
        if ( ! $group_prod->is_type( 'grouped' ) )
            return $cart_item_data; // Exit

        $cart_item_data['grouped_product'] = array(
            'id' => $_REQUEST['add-to-cart'],
            'name' => $group_prod->get_name(),
            'link' => $group_prod->get_permalink(),
            'visible' => $group_prod->is_visible(),
        );

        // Below statement make sure every add to cart action as unique line item
        $cart_item_data['grouped_product']['unique_key'] = md5( microtime().rand() );
    }
    return $cart_item_data;
}


// Add the parent grouped product name to cart items names
add_filter( 'woocommerce_cart_item_name', 'custom_product_title_name', 20, 3 );
function custom_product_title_name( $cart_item_name, $cart_item, $cart_item_key ){
    // The product object from cart item
    $product = $cart_item['data'];
    $product_permalink = $product->is_visible() ? $product->get_permalink( $cart_item ) : '';

    // The parent product name and data
    if( isset( $cart_item['grouped_product'] ) ){
        $group_product = $cart_item['grouped_product'];
        $group_prod_link = $product->is_visible() && is_cart() ? $group_product['link'] : '';

        if ( ! $group_prod_link )
            return $group_product['name'] . ' > ' . $product->get_name();
        else
            return sprintf(
                '<a href="%s">%s</a> > <a href="%s">%s</a>',
                esc_url( $group_prod_link ),
                $group_product['name'],
                esc_url( $product_permalink ),
                $product->get_name()
            );
    }
    else
        return $cart_item_name;
}

// Save grouped product data in order item meta
add_action( 'woocommerce_checkout_create_order_line_item', 'added_grouped_order_item_meta', 20, 4 );
function added_grouped_order_item_meta( $item, $cart_item_key, $values, $order ) {
    if( isset($values['grouped_product']) ){
        $item_id = $item->get_id();
        $grouped_data = $values['grouped_product'];
        unset($grouped_data['unique_key']);
        $item->update_meta_data( '_grouped_product', $grouped_data );
    }
}

// Display grouped product linked names in order items (+ email notifications)
add_filter( 'woocommerce_order_item_name', 'custom_order_item_name', 20, 3 );
function custom_order_item_name( $item_name, $item, $is_visible ) {
    $product = $item->get_product();
    $product_id = $item->get_product_id();
    $product_permalink = $is_visible ? $product->get_permalink( $item ) : '';
    $grouped_data = wc_get_order_item_meta( $item->get_id(), '_grouped_product', true );
    if( empty($grouped_data) ){
        $item_name = $product_permalink ? sprintf(
            '<a href="%s">%s</a>',
            esc_url( $product_permalink),
            $item->get_name()
        ) : $item->get_name();
    } else {
        $item_name = $product_permalink ? sprintf(
            '<a href="%s">%s</a> > <a href="%s">%s</a>',
            $grouped_data['link'],
            $grouped_data['name'],
            esc_url( $product_permalink) ,
            $item->get_name()
        ) : $grouped_data['name'] . ' > ' . $item->get_name();
    }
    return $item_name;
}

// Display on backend order edit pages
add_action( 'woocommerce_before_order_itemmeta', 'backend_order_item_name_grouped', 20, 3 );
function backend_order_item_name_grouped( $item_id, $item, $product ){
    if( ! ( is_admin() && $item->is_type('line_item') ) ) return;

    $grouped_data = wc_get_order_item_meta( $item_id, '_grouped_product', true );
    if( empty($grouped_data) ) return;
    $product_link = admin_url( 'post.php?post=' . $grouped_data['id'] . '&action=edit' );
    $grouped_name_html = '<a href="' . esc_url( $grouped_data['link'] ) . '" class="wc-order-item-name">' . esc_html( $grouped_data['name'] ) . '</a>';
    echo '<br><br><div class="wc-order-item-name">
        <small><strong>'.__('Grouped parent').':</strong></small><br>
        ' . $grouped_name_html . '
    </div>';
}

Code goes in function.php file of your active child theme (or theme);

Tested and works.

Thursday, November 24, 2022
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share