使特定产品仅供WooCommerce中的用户角色访问

时间:2019-04-13 作者:plonknimbuzz

我正在制作一个插件,只为用户角色隐藏特定的产品类别。

add_action( \'woocommerce_product_query\', \'wcpp_hide_product\' );
function wcpp_hide_product( $q ) {
    //if main query, skip
    if ( ! $q->is_main_query() ) return;
    //jika admin, skip
    if(is_admin()) return;
    //if user is not logged in, or dont have PRIVATE_MEMBER roles hide the product
    $current_user = wp_get_current_user();
    if(!isset($current_user->roles) || !in_array(\'PRIVATE_MEMBER\', $current_user->roles)){ 
        $tax_query = (array) $q->get( \'tax_query\' );
        $tax_query[] = array(
           \'taxonomy\' => \'product_cat\',
           \'field\' => \'id\',
           \'terms\' => \'PRIVATE_CATEGORY\',
           \'operator\' => \'NOT IN\'
        );
        $q->set( \'tax_query\', $tax_query );
    }

}
这段代码将在搜索中隐藏产品。但其他用户仍然可以通过直接链接访问产品详细信息页面。

下面是隐藏产品单页的代码(不起作用):

add_action( \'woocommerce_before_single_product\', \'wcpp_hide_product_detail\' );
//add_action( \'pre_get_posts\', \'wcpp_hide_product_detail\' );

function wcpp_hide_product_detail() {
    if(is_admin()) return;
    global $post;
    $terms = get_the_terms( $post->ID, \'product_cat\' );
    if(empty($terms)) return;
    $is_private=false;
    foreach($terms as $term){
        if(\'PRIVATE_CATEGORY\'==$term->term_id){
            $is_private = true;
            break;
        } 
    }
    if(!$is_private) return;
    $current_user = wp_get_current_user();
    if(!isset($current_user->roles) || !in_array(\'PRIVATE_MEMBER\', $current_user->roles)){ 
        //need do something here, but not works
        //maybe redirect
        //wp_redirect(home_url());
        /* or like set 404
        global $wp_query;
        $wp_query->set_404();
        status_header(404);
        */
    }
}
如果我设置重定向脚本,它会显示:“无法修改标题信息-标题已由…发送”

如果我可以将产品查询修改为负ID号,这将触发“找不到产品”页面,我认为这将起作用。但我不知道该用哪个动作钩的名字来做。那么我的代码可以使用wp 动作钩状add_action( \'wp\', \'wcpp_hide_product_detail\' );. 但我不知道该怎么做。

非常感谢您的帮助。

1 个回复
最合适的回答,由SO网友:LoicTheAztec 整理而成

我重新查看了您的代码,因为有一些错误(代码中的所有内容都有注释)。此外:

您可以使用current_user_can() 检查当前用户的用户角色。

您可以使用has_term() 用于检查任何分类法的post术语的条件函数。

以下代码将对没有特定用户角色的用户隐藏属于特定产品类别的产品。如果他们试图访问特定的产品,他们将被重定向到带有自定义通知的购物页面…

此外,在特定产品的所有产品循环中,ajax添加到购物车按钮或“阅读更多”按钮被禁用的灰色按钮替换(仅在前端)。

代码如下:

// Hide specific products from shop and archives pages
add_action( \'woocommerce_product_query\', \'wcpp_hide_product\' );
function wcpp_hide_product( $q ) {
    // skip for main query and  on admin
    if ( ! $q->is_main_query() || is_admin() )
        return;

    // Hide specific products for unlogged users or users without PRIVATE_MEMBER user role
    if ( is_user_logged_in() || ! current_user_can(\'PRIVATE_MEMBER\') ) {
        $tax_query = (array) $q->get( \'tax_query\' );
        $tax_query[] = array(
           \'taxonomy\' => \'product_cat\',
           \'field\' => \'term_id\', // it\'s not \'id\' but \'term_id\' (or \'name\' or \'slug\')
           \'terms\' => \'PRIVATE_CATEGORY\',
           \'operator\' => \'NOT IN\'
        );
        $q->set( \'tax_query\', $tax_query );
    }
}

// Replace add to cart button by a disabled button on specific products in Shop and archives pages
add_filter( \'woocommerce_loop_add_to_cart_link\', \'wcpp_replace_loop_add_to_cart_button\', 10, 2 );
function wcpp_replace_loop_add_to_cart_button( $button, $product  ) {
    if ( ( is_user_logged_in() || ! current_user_can(\'PRIVATE_MEMBER\') )
    && has_term( \'PRIVATE_CATEGORY\', \'product_cat\', $product->get_id() ) ) {;
        $button = \'<a class="button alt disabled">\' . __( "Private", "woocommerce" ) . \'</a>\';
    }
    return $button;
}

// On single product pages, redirect to shop and display a custom notice for specific products
add_action( \'template_redirect\', \'wcpp_redirect_hiding_product_detail\' );
function wcpp_redirect_hiding_product_detail() {
    if ( ( is_user_logged_in() || ! current_user_can(\'PRIVATE_MEMBER\') )
    && has_term( \'PRIVATE_CATEGORY\', \'product_cat\' ) && is_product() ) {
        // Add a notice (optional)
        wc_add_notice(__("Sorry, but you are not allowed yet to see this product."), \'notice\' );

        // Shop redirection url
        $redirect_url = get_permalink( get_option(\'woocommerce_shop_page_id\') );
        wp_redirect($redirect_url); // Redirect to shop

        exit(); // Always exit
    }
}
代码进入功能。活动子主题(或活动主题)的php文件,或在插件文件中。

已测试并正常工作。

相关推荐

如何在PHP标记内使用带有do_Action函数的参数

我正在使用一个WordPress插件,它允许集成操作将其集成到一个主题中。使用GeneratePress的元素特性,我将动作添加为挂钩。目前我使用的代码是:<?php do_action(webcomic_integrate_landing_page); ?> 操作本身有一些布尔参数列在this website. 我最感兴趣的是webcomic_meta.如何将webcomic\\u元参数(设置为false)合并到PHP标记中以运行此操作?