将父名称添加到下拉列表中的术语列表(例如优惠券类别列表)

问题描述 投票:0回答:2

我们有一家 WooCommerce 服装店,想要创建排除某些类别的优惠券。我们的类别结构如下(简化):

– Men
– – Shirts
– – Jeans
– – Sale
– Women
– – Shirts
– – Jeans
– – Sale

但是,当我们想要从 [WooCommerce » 营销 » 优惠券 » 使用限制] 中的 排除类别 下拉选择器中选择 [男士 » 促销] 时,列表会变平:

– Jeans
– Men
– Sale
– Sale
– Shirts
– Shirts
– Women

现在还不清楚哪些类别实际上是我们要排除的类别。有分钟,这是一个非常简化的结构,在现场环境中这更糟糕。

我希望有一个

apply_filter
,但
get_terms()
显然在代码中没有,请参阅github上的源代码在这里»(第233行)

$categories = get_terms('product_cat', 'orderby=name&hide_empty=0');

由于这没有被过滤,所以我没有找到添加父类别以使其成为所需结果的方法:

- Men
- Men » Jeans
- Men » Shirts
- Men » Sale
- Women
- Women » Jeans
- Women » Shirts
- Women » Sale

既然代码中没有过滤器,你知道如何获取该列表吗?

例如,这是我们用于也使用 WooCommerce 类别术语的第三方插件的内容,但实际上确实在 get_terms 上有一个过滤器,而优惠券上的本机 WooCommerce 代码没有...

示例:

if (!function_exists('yith_wcbep_add_parent_category_name')) {
    function yith_wcbep_add_parent_category_name($terms, $args) {
        $term_name = '';
        $taxonomy  = isset($args['taxonomy']) ? $args['taxonomy'] : '';
        foreach ($terms as $term_id => $term_name) {
            $term = get_term_by('id', $term_id, $taxonomy);
            $term_name = isset($term->name) ? $term->name : '';
            if (isset($term->parent) && $term->parent > 0) {
                $parent = get_term_by('id', $term->parent, $term->taxonomy);
                $term_name = $parent->name . ' > ' . $term_name;
                $terms[$term_id] = $term_name;
            }
        }
        return $terms;
    }
    add_filter('yith_plugin_fw_json_search_found_terms', 'yith_wcbep_add_parent_category_name', 10, 2);
}
php wordpress woocommerce hook-woocommerce
2个回答
3
投票

要解决此问题,您可以做的是克隆 WooCommerce 优惠券产品类别限制部分,根据需要自定义类别输出*(此处我将父术语名称添加到类别名称),使用 JavaScript 删除相关 HTML默认 WooCommerce 的输出。

所以你会得到以下内容:

这是钩子函数代码:

// Prepend the parent term name to the term name output
function prepend_parent_term_name( $term, $sep = ' > ' ) {
    if (isset($term->parent) && $term->parent > 0) {
        $parent_name = get_term_by('id', $term->parent, $term->taxonomy)->name;
        return esc_html( $parent_name ) . $sep . esc_html( $term->name );
    } else {
        return esc_html( $term->name );
    }
}

// Replace WooCommerce Admin Coupon product categories restictions section with a custom one
add_action( 'woocommerce_coupon_options_usage_restriction', 'action_coupon_options_usage_restriction', 10, 2 );
function action_coupon_options_usage_restriction( $coupon_id, $coupon ) {
    echo '<div class="options_group">';

    // Categories.
    ?>
    <p class="form-field">
        <label for="product_categories2"><?php _e( 'Product categories', 'woocommerce' ); ?></label>
        <select id="product_categories2" name="product_categories[]" style="width: 50%;"  class="wc-enhanced-select" multiple="multiple" data-placeholder="<?php esc_attr_e( 'Any category', 'woocommerce' ); ?>">
            <?php
            $category_ids = $coupon->get_product_categories( 'edit' );
            $categories   = get_terms( 'product_cat', 'orderby=name&hide_empty=0' );

            if ( $categories ) {
                foreach ( $categories as $cat ) {
                    echo '<option value="' . esc_attr( $cat->term_id ) . '"' . wc_selected( $cat->term_id, $category_ids ) . '>' . prepend_parent_term_name( $cat ) . '</option>';
                }
            }
            ?>
        </select> <?php echo wc_help_tip( __( 'Product categories that the coupon will be applied to, or that need to be in the cart in order for the "Fixed cart discount" to be applied.', 'woocommerce' ) ); ?>
    </p>

    <?php // Exclude Categories. ?>
    <p class="form-field">
        <label for="exclude_product_categories2"><?php _e( 'Exclude categories', 'woocommerce' ); ?></label>
        <select id="exclude_product_categories2" name="exclude_product_categories[]" style="width: 50%;"  class="wc-enhanced-select" multiple="multiple" data-placeholder="<?php esc_attr_e( 'No categories', 'woocommerce' ); ?>">
            <?php
            $category_ids = $coupon->get_excluded_product_categories( 'edit' );
            $categories   = get_terms( 'product_cat', 'orderby=name&hide_empty=0' );

            if ( $categories ) {
                foreach ( $categories as $cat ) {
                    echo '<option value="' . esc_attr( $cat->term_id ) . '"' . wc_selected( $cat->term_id, $category_ids ) . '>' . prepend_parent_term_name( $cat ) . '</option>';
                }
            }
            ?>
        </select>
        <?php echo wc_help_tip( __( 'Product categories that the coupon will not be applied to, or that cannot be in the cart in order for the "Fixed cart discount" to be applied.', 'woocommerce' ) ); ?>
    </p>
    <?php // Removing default product categories restrictions html  ?>
    <script>
    jQuery(function($){
        $('#product_categories').parent().parent().remove();
    });
    </script>
    <?php 
    echo '</div>';
}

代码位于活动子主题(或活动主题)的functions.php 文件中。已测试并有效。


2
投票

这是一个需要解决的有趣功能,似乎有点奇怪 Woocommerce 在优惠券类别中没有层次结构名称。
所以我做了一些挖掘,发现唯一合适的过滤器似乎是

get_terms
,经过一番尝试和错误后我想出了这个。

if (!function_exists('btAddHierarchyNameToCouponsCat')) {
    function btAddHierarchyNameToCouponsCat($terms)
    {
        if (!is_admin()) {
            return $terms;
        }
    
        global $pagenow;
    
        if ($pagenow !== 'post-new.php' && $pagenow !== 'post.php') {
            return $terms;
        }
    
        if (
            (
                !empty($_GET['post_type'])
                && $_GET['post_type'] === 'shop_coupon'
            )
            || (
                !empty($_GET['post'])
                && get_post_type($_GET['post']) === 'shop_coupon'
                && !empty($_GET['action'])
                && $_GET['action'] === 'edit'
            )
        ) {
            foreach ($terms as &$term) {
                $term->name = (function ($term) {
                    $fullName = array_map(function ($ancestorId) {
                        $ancestor = get_term_by('term_id', $ancestorId, 'product_cat');
    
                        return $ancestor->name;
                    }, array_reverse(get_ancestors($term->term_id, 'product_cat')));
    
                    $fullName[] = $term->name;
    
                    return implode(' -> ', $fullName);
                })($term);
            }
    
            return $terms;
        }
    
        return $terms;
    }

    add_filter('get_terms', 'btAddHierarchyNameToCouponsCat');
}

这是之前的。

这是之后的事情。

此过滤器的总体思路是仅在仪表板上创建或编辑优惠券时专门起作用。
然后它更新类别名称以包含类别名称的整个层次结构。
这可能并不完美,但它是一个起点

© www.soinside.com 2019 - 2024. All rights reserved.