Я пытаюсь выполнить поиск по номеру заказа или идентификатору позиции на странице администрирования заказов Woocommerce. Что я нашел / сделал до сих пор, но безуспешно, так это в файле functions.php.
add_filter( 'woocommerce_shop_order_search_fields', 'woocommerce_shop_order_search_sku' );
function woocommerce_shop_order_search_sku( $search_fields ) {
$args = array(
'post_type' => 'shop_order'
);
$orders = new WP_Query($args);
if($orders->have_posts()) {
while($orders->have_posts()) {
$post = $orders->the_post();
$order_id = get_the_ID();
$order = new WC_Order($order_id);
$items = $order->get_items();
foreach($items as $item) {
$search_order_item_sku = wp_get_post_terms( $item['product_id'], 'search_sku' );
foreach($search_order_item_sku as $search_sku) {
add_post_meta($order_id, "_search_sku", $search_sku->sku);
}
}
}
};
$search_fields[] = '_search_sku';
return $search_fields;
}
Я предполагаю, что проблема заключается в значении $ search_sku в строке с «add_post_meta». Я также попробовал это с get_sku (), $ item [‘sku’] без удачи.
Какие-либо предложения?
У вас есть правильное представление о сохранении дополнительных метаданных в заказе. Как предполагают jbby и helgatheviking, в api woocommerce orders нет встроенного постмета для product_id или sku, доступного по умолчанию. Однако ваша методология доступа к метаданным и их сохранения была не совсем правильной. wp_get_post_terms
получит доступ к пользовательской информации о таксономии, а не к метаданным (используйте get_post_meta
для этого). Вы сможете сделать то, что пытались сделать с помощью этого фильтра:
add_filter( 'woocommerce_shop_order_search_fields', function ($search_fields ) {
$posts = get_posts(array('post_type' => 'shop_order'));
foreach ($posts as $post) {
$order_id = $post->ID;
$order = new WC_Order($order_id);
$items = $order->get_items();
foreach($items as $item) {
$product_id = $item['product_id'];
$search_sku = get_post_meta($product_id, "_sku", true);
add_post_meta($order_id, "_product_sku", $search_sku);
add_post_meta($order_id, "_product_id", $product_id);
}
}
return array_merge($search_fields, array('_product_sku', '_product_id'));
});
Строго говоря, вы, вероятно, должны перевести вызовы на add_post_meta
в ловушку, которая запускается, когда заказ первоначально сохраняется в базе данных — это предотвратит ненужную работу, когда вы будете искать в заказе.
@blacksquare, @jibby, @helgatheviking вы мужчины! Это код, который работает, благодаря вашей помощи.
//Search by product SKU in Admin Woocommerce Orders
add_filter( 'woocommerce_shop_order_search_fields', function ($search_fields ) {
$posts = get_posts(array('post_type' => 'shop_order'));
foreach ($posts as $post) {
$order_id = $post->ID;
$order = new WC_Order($order_id);
$items = $order->get_items();
foreach($items as $item) {
$product_id = $item['product_id'];
$search_sku = get_post_meta($product_id, "_sku", true);
add_post_meta($order_id, "_product_sku", $search_sku);
}
}
return array_merge($search_fields, array('_product_sku'));
});
В то время как ответы @Nikos и @blacksquare работают, новые почтовые метасы добавляются к каждому заказу при каждом поиске. Если у вас 100 заказов и 10 поисков, будет как минимум 100 * 10 = 1000 _product_sku
записи в wp_postmeta
Таблица. Если некоторые заказы содержат несколько продуктов, их будет еще больше.
Как подсказал @blacksquare, add_post_meta
должен быть вызван при сохранении заказа. Тем не менее, если сайт небольшой и производительность бэкэнда не представляет особой проблемы, следующий код будет работать без создания избыточного _product_sku
записей.
add_filter( 'woocommerce_shop_order_search_fields', 'my_shop_order_search_fields') );
public function my_shop_order_search_fields( $search_fields ) {
$orders = get_posts( array(
'post_type' => 'shop_order',
'post_status' => wc_get_order_statuses(), //get all available order statuses in an array
'posts_per_page' => 999999, // query all orders
'meta_query' => array(
array(
'key' => '_product_sku',
'compare' => 'NOT EXISTS'
)
) // only query orders without '_product_sku' postmeta
) );
foreach ($orders as $order) {
$order_id = $order->ID;
$wc_order = new WC_Order($order_id);
$items = $wc_order->get_items();
foreach($items as $item) {
$product_id = $item['product_id'];
$search_sku = get_post_meta($product_id, '_sku', true);
add_post_meta( $order_id, '_product_sku', $search_sku );
}
}
return array_merge($search_fields, array('_product_sku')); // make '_product_sku' one of the meta keys we are going to search for.
}
Хотя лучшим решением может быть вызов add_post_meta
при создании заказа требуются дополнительные усилия для создания _product_sku
для существующих заказов, и вы должны создать _product_sku
для заказов, пока код не активирован. Для простоты я бы просто воспользовался предложенным выше решением.
постскриптум Решение @Nikos «ы есть один (спорно) преимущество — если изменить SKU продукта, после того, как заказы сделаны, решение Никоса найдет те заказы, используя новый SKU, в то время как выше решение не будет. Тем не менее, SKU или иной продукт не должен быть изменен в любом случае, и это спорно ли поиск новых артикулов должны показывать старые заказы.
Вы также можете посмотреть в https://uk.wordpress.org/plugins/woo-search-order-by-sku/ которая не перегружает post meta, но изменяет предложение where.