如何根据用户角色隐藏具有给定类别的 WooCommerce 产品

Posted

技术标签:

【中文标题】如何根据用户角色隐藏具有给定类别的 WooCommerce 产品【英文标题】:How do I hide WooCommerce products with a given category based on user role 【发布时间】:2016-12-24 14:14:48 【问题描述】:

我有一个客户遇到以下问题:

我需要能够将他们的 WooCommerce WordPress 网站基本上分为两类。如果用户以 "Wholeseller" 身份登录,则只会从数据库中提取 "Wholesale" 类别 中的产品。

但是,如果用户未登录或已登录但不是 "Wholeseller",则只有没有 "Wholesale" 类别的产品会从数据库中提取.

我想我会在主题的functions.php 文件中添加类似的内容:

add_filter("some_woocommerce_hook", "wholeseller_filter");

function wholeseller_filter() 
    if (current_user->role == "Wholeseller")
        //omit products without "wholesale" category while browsing whole site
     else  
        //omit products with "wholesale" in the category while browsing whole site.
    

我浏览过 ***,但没有找到我要查找的内容,也不知道应该使用哪些关键字进行搜索。

你能指出我正确的方向吗?

【问题讨论】:

【参考方案1】:
function exclude_categories_for_vendors( $query ) 

    // Get the current user
    $current_user = wp_get_current_user();
     $ARRAY_OF_PRODUCT_CATEGORIES_IDS_YOU_WANT_HIDDEN = array(26,23,20);

    if( is_user_logged_in() )

        if ( $query->is_main_query() ) 
           
            if ( in_array( 'editor', (array) $current_user->roles ) ) 
                
                //echo "editor";
                //below query will hide categories for Vendor user in Admin Panel
                
                   $query->set( 'tax_query', array(
                    array(
                        'taxonomy' => 'product_cat',
                        'field' => 'term_id',
                        'terms' => $ARRAY_OF_PRODUCT_CATEGORIES_IDS_YOU_WANT_HIDDEN, // your category ID
                        'operator' => 'NOT IN'
                    )
                ) ); 

             else
                //no changes
            
        
    

add_action( 'pre_get_posts', 'exclude_categories_for_vendors' );

【讨论】:

请在您的答案中添加一些解释,以便其他人可以从中学习【参考方案2】:

是的,这是可能的。有两种方式:

1) 使用 pre_get_posts wordpress 挂钩,该挂钩在创建查询变量对象之后但在运行实际查询之前调用。所以它非常适合这种情况。我们在这里假设'Wholesale'类别的ID是'123'

这是自定义代码:

function wholeseller_role_cat( $query ) 

    // Get the current user
    $current_user = wp_get_current_user();

    if ( $query->is_main_query() ) 
        // Displaying only "Wholesale" category products to "whole seller" user role
        if ( in_array( 'wholeseller', $current_user->roles ) ) 
            // Set here the ID for Wholesale category 
            $query->set( 'cat', '123' ); 

        // Displaying All products (except "Wholesale" category products) 
        // to all other users roles (except "wholeseller" user role)
        // and to non logged user.
         else 
            // Set here the ID for Wholesale category (with minus sign before)
            $query->set( 'cat', '-123' ); // negative number
        
    

add_action( 'pre_get_posts', 'wholeseller_role_cat' );

此代码在您的活动子主题或主题的 function.php 文件中,或者在自定义插件中更好。


2) 使用 woocommerce_product_query WooCommerce 挂钩。 (我们这里仍然假设'Wholesale'类别的ID是'123'

这是自定义代码:

function wholeseller_role_cat( $q ) 

    // Get the current user
    $current_user = wp_get_current_user();

    // Displaying only "Wholesale" category products to "whole seller" user role
    if ( in_array( 'wholeseller', $current_user->roles ) ) 
        // Set here the ID for Wholesale category 
        $q->set( 'tax_query', array(
            array(
                'taxonomy' => 'product_cat',
                'field' => 'term_id',
                'terms' => '123', // your category ID
            )
        ) ); 

    // Displaying All products (except "Wholesale" category products) 
    // to all other users roles (except "wholeseller" user role)
    // and to non logged user.
     else 
        // Set here the ID for Wholesale category
        $q->set( 'tax_query', array(
            array(
                'taxonomy' => 'product_cat',
                'field' => 'term_id',
                'terms' => '123', // your category ID
                'operator' => 'NOT IN'
            )
        ) ); 
    

add_action( 'woocommerce_product_query', 'wholeseller_role_cat' );

此代码在您的活动子主题或主题的 function.php 文件中,或者在自定义插件中更好。

如果您想使用类别 slug 而不是类别 ID,则必须将部分(两个数组)替换为:

            array(
                'taxonomy' => 'product_cat',
                'field' => 'slug',
                'terms' => 'wholesale', // your category slug (to use the slug see below)

如果您愿意和需要,可以在 if statements 中添加some woocommerce conditionals tags 以进一步限制这一点。

参考文献:

Modifying the WooCommerce Product Query I can't fetch WooCommerce products by category id WordPress Class Reference - WP Query

【讨论】:

pre_get_posts 所有的东西!!尽管我建议不要将其保留在您主题的 functions.php 中,而是将其移至插件中。 functions.php 是删除 sn-ps 以进行快速测试的最简单的地方,但我始终建议将您的主题用于与显示相关的功能并在插件中保留任何特定于功能的代码。 您不应该在 pre_get_posts 上运行它,除非您希望在每个查询中运行它。 Woocommerce 挂钩“woocommerce_product_query”将允许您仅在 woocommerce 查询上运行它。 @NicholasKoskowski 我在我的答案中添加了一个使用woocommerce_product_query 的变体...您的建议是一个有趣的选项,就好像您进入woocommerce 核心代码相关功能一样,他们使用太pre_get_posts钩子和类似的......还是谢谢 @LoicTheAztec 仅供参考,第一种方法阻碍了管理部分,并从编辑器中隐藏了所有产品。我已将其嵌套在 if 语句中:if (!in_array('administrator', $current_user->roles) ... 【参考方案3】:

为了提高性能并且只对 woocommerce 查询有效,请使用以下函数和钩子。

function exclude_product_from_wholesale( $q )

 $current_user = wp_get_current_user();
 $ARRAY_OF_PRODUCT_IDS_YOU_WANT_HIDDEN = array();

 if ( in_array( 'wholeseller', $current_user->roles ) ) 
  $q->set( 'post__not_in', $ARRAY_OF_PRODUCT_IDS_YOU_WANT_HIDDEN );
 



add_action( 'woocommerce_product_query', 'exclude_product_from_wholesale' );

你可以把这个简单的函数放到你的functions.php中。

【讨论】:

以上是关于如何根据用户角色隐藏具有给定类别的 WooCommerce 产品的主要内容,如果未能解决你的问题,请参考以下文章

如何通过上下文更改 Spring Security 角色?

根据用户角色隐藏一些 React 组件子项

如何根据用户角色在后台隐藏操作按钮?

Rails,使用隐藏字段设置用户角色

如何根据用户的角色创建具有不同显示的视图?

kohana orm 选择具有所有给定角色的用户