在WooCommerce的wc_get_products中获取自定义分类brand_heirarchy关联ID
问题描述
我通过init动作注册了自定义分类brand_heirarchy,代码如下:
add_action( 'init', 'product_brand_order_taxonomy' ); function product_brand_order_taxonomy() { $labels = array( 'name' => 'Brand Heirarchy', 'singular_name' => 'Brand Heirarchy', 'menu_name' => 'Brand Heirarchy', 'all_items' => 'All Brand Heirarchies', 'parent_item' => 'Parent Brand Heirarchy', 'parent_item_colon' => 'Parent Brand Heirarchy:', 'new_item_name' => 'New Brand Heirarchy Name', 'add_new_item' => 'Add New Brand Heirarchy', 'edit_item' => 'Edit Brand Heirarchy', 'update_item' => 'Update Brand Heirarchy', 'separate_items_with_commas' => 'Separate Brand Heirarchy with commas', 'search_items' => 'Search Brand Heirarchies', 'add_or_remove_items' => 'Add or remove Brand Heirarchies', 'choose_from_most_used' => 'Choose from the most used Brand Heirarchies', ); $args = array( 'labels' => $labels, 'hierarchical' => true, 'public' => true, 'show_ui' => true, 'show_admin_column' => true, 'show_in_nav_menus' => true, 'show_tagcloud' => true, ); register_taxonomy( 'brand_heirarchy', 'product', $args ); register_taxonomy_for_object_type( 'brand_heirarchy', 'product' ); }
现在使用wc_get_products获取产品时,希望返回结果中包含产品关联的brand_heirarchy分类ID,当前获取代码如下:
$product_args = array( 'post_status' => 'publish', 'limit' => -1, 'category' => $parent_brand_slugs ); $products = wc_get_products($product_args);
目前返回的产品对象仅包含category_ids,但我需要同时获取关联的brand_heirarchy分类ID。已知WooCommerce原生不支持该功能,尝试过woocommerce_product_object_query_args过滤器但未成功,不想用循环调用wp_get_object_terms这种低效方式,求更高效的实现方法。
高效解决方案
以下两种方法都能避免循环查询的性能损耗,一次性获取所需分类ID:
方法一:通过查询子句关联分类表
直接修改WooCommerce产品查询的SQL语句,关联分类关系表,把brand_heirarchy的ID拼接后附加到产品对象上:
add_filter( 'woocommerce_product_query_post_clauses', 'attach_brand_hierarchy_ids', 10, 2 ); function attach_brand_hierarchy_ids( $clauses, $query ) { global $wpdb; // 仅针对产品类型的查询生效 if ( isset( $query->query_vars['post_type'] ) && $query->query_vars['post_type'] === 'product' ) { // 关联term关系表和分类表 $clauses['join'] .= " LEFT JOIN {$wpdb->term_relationships} tr ON {$wpdb->posts}.ID = tr.object_id"; $clauses['join'] .= " LEFT JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id AND tt.taxonomy = 'brand_heirarchy'"; // 按产品ID分组,避免重复结果 $clauses['groupby'] = "{$wpdb->posts}.ID"; // 用GROUP_CONCAT拼接多个分类ID(支持产品关联多个分类的场景) $clauses['fields'] .= ", GROUP_CONCAT(tt.term_id SEPARATOR ',') AS brand_hierarchy_ids"; } return $clauses; } add_action( 'woocommerce_product_query_posts_found', 'map_brand_ids_to_product', 10, 2 ); function map_brand_ids_to_product( $products, $query ) { if ( empty( $products ) ) return $products; foreach ( $products as $product ) { if ( isset( $product->brand_hierarchy_ids ) ) { // 把拼接的字符串转为ID数组,过滤空值 $brand_ids = array_filter( explode( ',', $product->brand_hierarchy_ids ) ); $product->brand_hierarchy_ids = $brand_ids; } } return $products; }
使用时无需修改原有查询代码,获取到的$products对象会直接带有brand_hierarchy_ids属性,值为分类ID数组。
方法二:扩展产品查询参数
添加自定义查询参数,让wc_get_products支持按需返回brand_heirarchy分类ID:
add_filter( 'woocommerce_product_query_args', 'add_brand_hierarchy_support', 10, 2 ); function add_brand_hierarchy_support( $args, $query ) { // 当查询参数中包含include_brand_hierarchy时,执行关联查询 if ( $query->get('include_brand_hierarchy') ) { global $wpdb; $args['fields'] = "{$wpdb->posts}.*, GROUP_CONCAT(tt.term_id SEPARATOR ',') AS brand_hierarchy_ids"; $args['join'] .= " LEFT JOIN {$wpdb->term_relationships} tr ON {$wpdb->posts}.ID = tr.object_id"; $args['join'] .= " LEFT JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id AND tt.taxonomy = 'brand_heirarchy'"; $args['groupby'] = "{$wpdb->posts}.ID"; } return $args; } add_filter( 'woocommerce_product_object_query_result', 'assign_brand_ids_to_product', 10, 2 ); function assign_brand_ids_to_product( $product, $post ) { if ( isset( $post->brand_hierarchy_ids ) ) { $brand_ids = array_filter( explode( ',', $post->brand_hierarchy_ids ) ); $product->brand_hierarchy_ids = $brand_ids; } return $product; }
然后修改产品查询代码,添加自定义参数:
$product_args = array( 'post_status' => 'publish', 'limit' => -1, 'category' => $parent_brand_slugs, 'include_brand_hierarchy' => true // 新增参数,触发分类ID查询 ); $products = wc_get_products($product_args);
获取到的每个产品对象都会带有brand_hierarchy_ids属性,包含关联的分类ID数组。
内容的提问来源于stack exchange,提问作者Senica Gonzalez
相关产品推荐
相关产品推荐

