То, что я пытаюсь сделать, – это выполнить поиск по элементу заказа или его идентификатору на странице администрирования заказов 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, встроенная postmeta для product_id или sku доступна по умолчанию в заказах woocommerce api. Однако ваша методология для доступа и сохранения метаданных была не совсем правильной. 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 поисков, в таблице wp_postmeta
будет не менее 100 * 10 = 1000 _product_sku
записей. Если в некоторых заказах содержится несколько продуктов, их будет еще больше.
Как и предлагалось @blacksquare, add_post_meta
следует вызывать, когда заказ сохраняется. Тем не менее, если сайт мал, а производительность бэкэнд-поиска не слишком _product_sku
, следующий код будет работать без создания избыточных записей _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/, который не перегружает почтовую мета, но изменяет предложение where.