【问题标题】:WooCommerce: Filter Admin orders by product attribute termWooCommerce:按产品属性术语过滤管理员订单
【发布时间】:2021-05-20 20:23:12
【问题描述】:

我的商店有许多可变产品。所有订单都是专门为客户定制的。这意味着当我们在仓库中收到产品时,我们需要找到具体产品的订单。现在我们只需要手动检查大多数订单。

我们希望通过自定义属性词搜索订单来节省宝贵的时间。例如:我们为自定义订单使用属性“size”。我们有 24 个“尺寸”词(例如“12cm”、:16cm 等)。我们想根据尺寸词查找订单。例如:查找所有尺寸为“48cm”的订单。

基于Extending search in backend orders list for product items by id or by sku,这是我的代码尝试:

add_filter( 'woocommerce_shop_order_search_fields', function ($search_fields ) {
    $orders = get_posts( array( 'post_type' => 'shop_order' ) );

    foreach ($orders as $order_post) {
        $order_id = $order_post->ID;
        $order = new WC_Order($order_id);
        $items = $order->get_items();
    
        foreach( $order->get_items() as $item_id => $item_values ) {
            if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
                $product_id = $item_values['product_id'];
            } else {
                $product_id = $item_values->get_product_id();
            }
             $attribute = $item_values->get_data();
             
            // attribute value
            $value = $attribute['value'];
            
            // attribute slug
            $slug = $attribute['size'];
            
            add_post_meta($order_id, $slug, $value, true); //
        }
    }
    return array_merge($search_fields, array($slug));
}); 

但它没有用。任何帮助表示赞赏。

【问题讨论】:

  • 你说的是custom made,但你却引用了尺寸……每种产品有什么独特之处吗?
  • 我想知道 - 刚刚尝试在我的商店中按属性值搜索,它似乎返回了正确的订单,比如当我输入“黑色”(颜色的自定义属性)时。我想知道“12cm”是否对您产生任何结果?就像订单搜索中的关键字...
  • 你好!请对以下答案提供一些反馈。
  • @LoicTheAztec - 你能回复我对你的回答的评论吗?谢谢!

标签: php wordpress woocommerce orders taxonomy-terms


【解决方案1】:

您正在尝试做的事情在您的情况下无法真正发挥作用,这是一个非常繁重的过程,可能会导致管理员崩溃或整个网站变慢。

您可以做的是显示所有现有尺寸值的下拉列表,以过滤您的订单:

请注意,每个产品属性分类都以pa_ + 产品属性的后缀开头。我在代码中将“尺寸”的产品属性分类设置为pa_size

下面的代码使用了一个非常简单的 SQL 自定义查询。

// Custom function where metakeys / labels pairs are defined
function get_product_attribute_size_terms(){
    $taxonomy = 'pa_size';
    $options  = array();

    foreach ( get_terms( array('taxonomy' => 'pa_size' ) ) as $term ) {
        $options[$term->slug] = $term->name;
    }
    return $options;
}

// Add a dropdown to filter orders by variations size
add_action( 'restrict_manage_posts', 'display_admin_shop_order_by_meta_filter' );
function display_admin_shop_order_by_meta_filter(){
    global $pagenow, $typenow;

    if( 'shop_order' === $typenow && 'edit.php' === $pagenow ) {
        $domain    = 'woocommerce';
        $filter_id = 'by_size';
        $current   = isset($_GET[$filter_id])? $_GET[$filter_id] : '';

        echo '<select name="'.$filter_id.'">
        <option value="">' . __('Filter by Size…', $domain) . '</option>';

        $options = get_product_attribute_size_terms();

        foreach ( $options as $key => $label ) {
            printf( '<option value="%s"%s>%s</option>', $key,
                $key === $current ? '" selected="selected"' : '', $label );
        }
        echo '</select>';
    }
}

add_action( 'pre_get_posts', 'process_admin_shop_order_product_type_filter' );
function process_admin_shop_order_product_type_filter( $query ) {
    global $pagenow, $post_type, $wpdb;

    $filter_id = 'by_size';
    $taxonomy  = 'pa_size';

    if ( $query->is_admin && 'edit.php' === $pagenow && 'shop_order' === $post_type
         && isset( $_GET[$filter_id] ) && $_GET[$filter_id] != '' ) {

        $attribute_taxonomy = 'attribute_'.$taxonomy;

        $order_ids = $wpdb->get_col( $wpdb->prepare("
            SELECT DISTINCT opl.order_id
            FROM {$wpdb->prefix}wc_order_product_lookup opl
            INNER JOIN {$wpdb->prefix}postmeta pm
                ON opl.variation_id = pm.post_id
            WHERE pm.meta_key = %s
                AND pm.meta_value = '%s'
        ", $attribute_taxonomy, esc_attr($_GET[$filter_id]) ) );

        $query->set( 'post__in', count($order_ids) > 1 ? $order_ids : array(0) ); // Set queried order ids

        $query->set( 'posts_per_page', 25 ); // Set "posts per page"

        $query->set( 'paged', ( get_query_var('paged') ? get_query_var('paged') : 1 ) ); // Set "paged"
    }
}

代码位于活动子主题(或活动主题)的functions.php 文件中。经过测试并且可以工作。

相关:Filter orders by product post type in WooCommerce admin orders list page

【讨论】:

  • 好吧,由于某种原因,这似乎不起作用。每次它都会过滤所有不匹配的订单。我尝试了不同的属性,例如 pa_size / pa_color。你能仔细检查一下吗?我尝试了不同的方法来完成这项工作,但它只会过滤所有订单,不显示任何订单!重要的是要注意:我已经尝试过包含两个可变产品的订单。
  • @JohnSmith 不是 2 个可变产品,而是 2 个产品变体,因为商品中从来没有任何可变产品,而是产品变体(来自可变产品)。
  • 对不起,我的错误。我的意思是两种产品变体。因此,当订单包含产品 B 时,订单中有两种不同的产品变体 - 它不会找到任何匹配项。你能检查一下吗?谢谢!
  • 我决定现在尝试使用全新安装的 WooCommerce,在我的订单中使用多种产品变体,但它不起作用。永远不会返回。
  • 在最后第三行,它应该检查大于0而不是1的订单,否则如果列表中只有一个符合条件的订单,它不会显示任何结果。
猜你喜欢
  • 2021-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多