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

huangapple go评论71阅读模式
英文:

Add parent name to term list in dropdown (eg. coupon category list)

问题

Sure, here's the translated content:

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

- 男装
  - 衬衫
  - 牛仔裤
  - 特价
- 女装
  - 衬衫
  - 牛仔裤
  - 特价

然而,当我们想要在[WooCommerce › 营销 › 优惠券 › 使用限制]的“排除类别”下拉选项中选择[男装 › 特价]时,列表被扁平化了:

- 牛仔裤
- 男装
- 特价
- 特价
- 衬衫
- 衬衫
- 女装

现在不清楚哪些类别实际上是我们要排除的。请注意,这只是一个非常简化的结构,在实际环境中情况更糟糕。

我原本希望有一个apply_filter,但是在代码中似乎没有get_terms()的筛选器,请参见GitHub上的源代码 »(第233行)

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

由于这没有被筛选,我看不到如何将父类别添加为所需的结果:

- 男装
- 男装 › 牛仔裤
- 男装 › 衬衫
- 男装 › 特价
- 女装
- 女装 › 牛仔裤
- 女装 › 衬衫
- 女装 › 特价

有没有办法在没有代码筛选器的情况下获取该列表的任何想法?

例如,这是我们用于第三方插件的代码,该插件也使用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);
}
英文:

We have a WooCommerce clothing store and want to create coupons that have certain categories excluded. Our category structure is as follows (simplified):

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

However when we want to select [Men » Sale] from the Exclude categories dropdown picker in [WooCommerce » Marketing » Coupons » Usage Restriction] the list is flattened:

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

Now it is not clear which categories are actually the one we want to exclude. Have in min, this is a very simplified structure, in the live environment this is even worse.

I hoped for an apply_filter but the get_terms() apparently does have none in code, see source code on github here » (line #233)

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

Since this is not filtered, I don’t see a way to add a parent category to have this as the desired outcome:

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

Any idea how to get that list now that there is no filter in the code?

For example, this is what we use for a third party plugin that also uses the WooCommerce category terms, but that actually does have a filter on the get_terms and the native WooCommerce code on coupons does not...

Example:

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);
}

</details>


# 答案1
**得分**: 3

为了解决这个问题,你可以克隆 WooCommerce 优惠券产品类别限制部分,自定义类别输出,例如在类别名称中添加父级名称,然后使用 JavaScript 从默认的 WooCommerce 输出中移除相关的 HTML 输出。这样你会得到以下结果:

[![enter image description here][1]][1]

以下是钩子函数的代码:

```php
// 在术语名称输出之前添加父级术语名称
function prepend_parent_term_name( $term, $sep = ' &gt; ' ) {
    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 );
    }
}

// 用自定义内容替换 WooCommerce 管理员优惠券产品类别限制部分
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">';

    // 类别。
    ?>
    <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 // 排除类别。 ?>
    <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 // 移除默认产品类别限制的 HTML 输出。 ?>
    <script>
    jQuery(function($){
        $('#product_categories').parent().parent().remove();
    });
    </script>
    <?php 
    echo '</div>';
}

将这段代码添加到你的活动子主题(或活动主题)的 functions.php 文件中,经过测试可行。

英文:

To solve this issue, what you can do is to clone WooCommerce coupon product categories restrictions section, customizing the categories output as you like *(here I add the parent term name to the category name), removing with JavaScript the related HTML output from the default WooCommerce ones.

So you will get the following:

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

Here is the hooked function code:

// Prepend the parent term name to the term name output
function prepend_parent_term_name( $term, $sep = &#39; &gt; &#39; ) {
if (isset($term-&gt;parent) &amp;&amp; $term-&gt;parent &gt; 0) {
$parent_name = get_term_by(&#39;id&#39;, $term-&gt;parent, $term-&gt;taxonomy)-&gt;name;
return esc_html( $parent_name ) . $sep . esc_html( $term-&gt;name );
} else {
return esc_html( $term-&gt;name );
}
}
// Replace WooCommerce Admin Coupon product categories restictions section with a custom one
add_action( &#39;woocommerce_coupon_options_usage_restriction&#39;, &#39;action_coupon_options_usage_restriction&#39;, 10, 2 );
function action_coupon_options_usage_restriction( $coupon_id, $coupon ) {
echo &#39;&lt;div class=&quot;options_group&quot;&gt;&#39;;
// Categories.
?&gt;
&lt;p class=&quot;form-field&quot;&gt;
&lt;label for=&quot;product_categories2&quot;&gt;&lt;?php _e( &#39;Product categories&#39;, &#39;woocommerce&#39; ); ?&gt;&lt;/label&gt;
&lt;select id=&quot;product_categories2&quot; name=&quot;product_categories[]&quot; style=&quot;width: 50%;&quot;  class=&quot;wc-enhanced-select&quot; multiple=&quot;multiple&quot; data-placeholder=&quot;&lt;?php esc_attr_e( &#39;Any category&#39;, &#39;woocommerce&#39; ); ?&gt;&quot;&gt;
&lt;?php
$category_ids = $coupon-&gt;get_product_categories( &#39;edit&#39; );
$categories   = get_terms( &#39;product_cat&#39;, &#39;orderby=name&amp;hide_empty=0&#39; );
if ( $categories ) {
foreach ( $categories as $cat ) {
echo &#39;&lt;option value=&quot;&#39; . esc_attr( $cat-&gt;term_id ) . &#39;&quot;&#39; . wc_selected( $cat-&gt;term_id, $category_ids ) . &#39;&gt;&#39; . prepend_parent_term_name( $cat ) . &#39;&lt;/option&gt;&#39;;
}
}
?&gt;
&lt;/select&gt; &lt;?php echo wc_help_tip( __( &#39;Product categories that the coupon will be applied to, or that need to be in the cart in order for the &quot;Fixed cart discount&quot; to be applied.&#39;, &#39;woocommerce&#39; ) ); ?&gt;
&lt;/p&gt;
&lt;?php // Exclude Categories. ?&gt;
&lt;p class=&quot;form-field&quot;&gt;
&lt;label for=&quot;exclude_product_categories2&quot;&gt;&lt;?php _e( &#39;Exclude categories&#39;, &#39;woocommerce&#39; ); ?&gt;&lt;/label&gt;
&lt;select id=&quot;exclude_product_categories2&quot; name=&quot;exclude_product_categories[]&quot; style=&quot;width: 50%;&quot;  class=&quot;wc-enhanced-select&quot; multiple=&quot;multiple&quot; data-placeholder=&quot;&lt;?php esc_attr_e( &#39;No categories&#39;, &#39;woocommerce&#39; ); ?&gt;&quot;&gt;
&lt;?php
$category_ids = $coupon-&gt;get_excluded_product_categories( &#39;edit&#39; );
$categories   = get_terms( &#39;product_cat&#39;, &#39;orderby=name&amp;hide_empty=0&#39; );
if ( $categories ) {
foreach ( $categories as $cat ) {
echo &#39;&lt;option value=&quot;&#39; . esc_attr( $cat-&gt;term_id ) . &#39;&quot;&#39; . wc_selected( $cat-&gt;term_id, $category_ids ) . &#39;&gt;&#39; . prepend_parent_term_name( $cat ) . &#39;&lt;/option&gt;&#39;;
}
}
?&gt;
&lt;/select&gt;
&lt;?php echo wc_help_tip( __( &#39;Product categories that the coupon will not be applied to, or that cannot be in the cart in order for the &quot;Fixed cart discount&quot; to be applied.&#39;, &#39;woocommerce&#39; ) ); ?&gt;
&lt;/p&gt;
&lt;?php // Removing default product categories restrictions html  ?&gt;
&lt;script&gt;
jQuery(function($){
$(&#39;#product_categories&#39;).parent().parent().remove();
});
&lt;/script&gt;
&lt;?php 
echo &#39;&lt;/div&gt;&#39;;
}

Code goes in functions.php file of your active child theme (or active theme). Tested and works.

答案2

得分: 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');
}

这是之前的样子。

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

这是之后的样子。

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

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

英文:

This was an interesting feature to solve, seems kind of strange Woocommerce doesn't have hierarchy names in the coupons categories.
So I did some digging and found that the only appropriate filter seems to be get_terms, after some trial and error I came up with this.

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

	add_filter(&#39;get_terms&#39;, &#39;btAddHierarchyNameToCouponsCat&#39;);
}

Here is the before.

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

And here is the after.

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

The general idea of this filter is to specifically work only when creating or editing a coupon on the dashboard.
Then it updates the category name to contain the whole hierarchy of the categories names.
This might not be perfect but it's a starting point

huangapple
  • 本文由 发表于 2023年6月12日 15:50:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76454557.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定