Получить все идентификаторы заказов из идентификатора продукта
Как я могу получить массив с идентификаторами заказа по идентификатору продукта?
Я имею в виду получать все заказы, где представлен конкретный продукт.
Я знаю, как это сделать с помощью MySQL, но есть ли способ сделать это с помощью WP_Query
функционировать?
3 ответа
ОБНОВЛЕНО: изменен SQL-запрос на
"SELECT DISTINCT"
вместо просто"SELECT"
чтобы избежать дублирования идентификаторов заказа в массиве (тогда нет необходимостиarray_unique()
отфильтровать дубликаты…).
С WP Query это невозможно, как я знаю, но используя WordPress class wpdb
Вы можете легко сделать это, включая запрос SQL.
Затем вы можете встроить это в пользовательскую функцию с $product_id
в качестве аргумента.
Вы должны будете установить в нем статусы заказа, на которые вы нацеливаетесь.
Итак, вот функция, которая сделает эту работу:
function retrieve_orders_ids_from_a_product_id( $product_id ) {
global $wpdb;
// Define HERE the orders status to include in <== <== <== <== <== <== <==
$orders_statuses = "'wc-completed', 'wc-processing', 'wc-on-hold'";
# Requesting All defined statuses Orders IDs for a defined product ID
$orders_ids = $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 LIKE '_product_id'
AND woim.meta_value LIKE '$product_id'
ORDER BY woi.order_item_id DESC"
);
// Return an array of Orders IDs for the given product ID
return $orders_ids;
}
Этот код входит в любой файл PHP.
Этот код протестирован и работает для WooCommerce версии 2.5+, 2.6+ и 3.0+.
ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ:
## 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 = retrieve_orders_ids_from_a_product_id( $product_id );
// We display the orders in a coma separated list
echo '<p>' . implode( ', ', $orders_ids_array ) . '</p>';
Если вы хотите, чтобы ваш код работал в будущих обновлениях WC, лучше использовать функции, предоставляемые WC, для получения деталей из БД, поскольку WC часто изменяет структуру БД. Я бы попробовал что-то вроде:
function get_orders_id_from_product_id($product_id, $args = array() ) {
//first get all the order ids
$query = new WC_Order_Query( $args );
$order_ids = $query->get_orders();
//iterate through order
foreach ($order_ids as $order_id) {
$filtered_order_ids = array();
$order = wc_get_order($order_id);
$order_items = $order->get_items();
//iterate through an order's items
foreach ($order_items as $item) {
//if one item has the product id, add it to the array and exit the loop
if ($item->get_product_id() == $product_id) {
array_push($filtered_order_ids, $order_id);
break;
}
}
}
return $filtered_order_ids;
}
Пример использования:
$product_id = '2094';
// NOTE: With 'limit' => 10 you only search in the last 10 orders
$args = array(
'limit' => 10,
'orderby' => 'date',
'order' => 'DESC',
'return' => 'ids',
);
$filtered_order_ids = get_orders_id_from_product_id($product_id, $args);
print_r($filtered_order_ids);
Я хотел бы отметить, что приведенный выше ответ вернет дубликат order_id, если в заказе есть несколько элементов.
Например
Если был продукт под названием "яблоки" с product_id=>1036
Клиент кладет "яблоки" 3 раза в свою корзину и покупает их, создавая order_id=>555
Если я сделаю запрос product_id->1036, я получу массив (555 555 555).
Вероятно, есть способ SQL сделать это, который может быть быстрее (был бы признателен всем, кто мог бы добавить к этому), в противном случае я использовал: array_unqiue() для объединения дубликатов.
function retrieve_orders_ids_from_a_product_id( $product_id )
{
global $wpdb;
$table_posts = $wpdb->prefix . "posts";
$table_items = $wpdb->prefix . "woocommerce_order_items";
$table_itemmeta = $wpdb->prefix . "woocommerce_order_itemmeta";
// Define HERE the orders status to include in <== <== <== <== <== <== <==
$orders_statuses = "'wc-completed', 'wc-processing', 'wc-on-hold'";
# Requesting All defined statuses Orders IDs for a defined product ID
$orders_ids = $wpdb->get_col( "
SELECT $table_items.order_id
FROM $table_itemmeta, $table_items, $table_posts
WHERE $table_items.order_item_id = $table_itemmeta.order_item_id
AND $table_items.order_id = $table_posts.ID
AND $table_posts.post_status IN ( $orders_statuses )
AND $table_itemmeta.meta_key LIKE '_product_id'
AND $table_itemmeta.meta_value LIKE '$product_id'
ORDER BY $table_items.order_item_id DESC"
);
// return an array of Orders IDs for the given product ID
$orders_ids = array_unique($orders_ids);
return $orders_ids;
}
Модифицированная функция для получения определенных пользовательских идентификаторов продукта
function retrieve_orders_ids_from_a_product_id( $product_id,$user_id )
{
global $wpdb;
$table_posts = $wpdb->prefix . "posts";
$table_postmeta = $wpdb->prefix . "postmeta";
$table_items = $wpdb->prefix . "woocommerce_order_items";
$table_itemmeta = $wpdb->prefix . "woocommerce_order_itemmeta";
// Define HERE the orders status to include in <== <== <== <== <== <== <==
$orders_statuses = "'wc-completed', 'wc-processing', 'wc-on-hold'";
# Requesting All defined statuses Orders IDs for a defined product ID
$orders_ids = $wpdb->get_col( "
SELECT DISTINCT $table_items.order_id
FROM $table_itemmeta, $table_items, $table_posts , $table_postmeta
WHERE $table_items.order_item_id = $table_itemmeta.order_item_id
AND $table_items.order_id = $table_posts.ID
AND $table_posts.post_status IN ( $orders_statuses )
AND $table_postmeta.meta_key LIKE '_customer_user'
AND $table_postmeta.meta_value LIKE '$user_id '
AND $table_itemmeta.meta_key LIKE '_product_id'
AND $table_itemmeta.meta_value LIKE '$product_id'
ORDER BY $table_items.order_item_id DESC"
);
// return an array of Orders IDs for the given product ID
return $orders_ids;
}
Пример использования
## This will display all orders containing this product ID in a coma separated string ##
// A defined product ID: 40
$product_id = 40;
// Current User
$current_user = wp_get_current_user();
// We get all the Orders for the given product ID of current user in an arrray
$orders_ids_array = retrieve_orders_ids_from_a_product_id( $product_id, $current_user->ID );
// We display the orders in a coma separated list
echo '<p>' . implode( ', ', $orders_ids_array ) . '</p>';