우커머스: 사용자 역할에 따라 특정 상품의 구입 제한하기

Last Updated: 2023년 07월 17일 | | 댓글 남기기

워드프레스 우커머스 쇼핑몰에서 특정 상품은 특정 사용자 역할의 사용자만 구입할 수 있고 일반 고객이나 게스트는 구입할 수 없도록 제한하고 싶은 경우가 있을 수 있습니다.

이 경우 우커머스 멤버십 플러그인을 사용할 수 있습니다. 우커머스 멤버십 플러그인을 사용하면 플랜을 만들어(예: 브론즈 플랜, 실버 플랜, 골드 플랜 등) 사용자 등급에 따라 제한할 수 있습니다.

정교한 회원제 사이트를 운영할 필요가 없고 플러그인 사용 없이 특정 사용자 역할에 따라 특정 상품의 구입을 제한하고 싶은 경우 아래에 제시된 코드를 응용해보시기 바랍니다.

우커머스: 사용자 역할에 따라 특정 상품의 구입 제한하기

특정 상품들은 특정 사용자 역할의 회원들만 구입할 수 있도록 제한하고 싶은 경우 아래의 코드를 사용할 수 있습니다. 아래의 코드는 Limit product to specific user role 문서에 제시된 코드를 응용한 것입니다.

알림판에서 제한할 상품들의 ID를 입력할 수 있도록 기능을 추가했습니다.

// How to Restrict WooCommerce Products By User Roles
// Add settings page under the WooCommerce menu

<?php

function theme_enqueue_styles() {
    wp_enqueue_style( 'child-style', get_stylesheet_directory_uri() . '/style.css', [] );
}
add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles', 20 );

function avada_lang_setup() {
	$lang = get_stylesheet_directory() . '/languages';
	load_child_theme_textdomain( 'Avada', $lang );
}
add_action( 'after_setup_theme', 'avada_lang_setup' );

/**
 * @snippet       Simplify Checkout if Only Virtual Products
 * @how-to        Get CustomizeWoo.com FREE
 * @sourcecode    https://businessbloomer.com/?p=78351
 * @author        Rodolfo Melogli
 * @compatible    WooCommerce 3.5.4
 * @donate $9     https://businessbloomer.com/bloomer-armada/
 */
 
// Add settings page under the WooCommerce menu
function yourprefix_wpf_add_settings_page() {
    add_submenu_page(
        'woocommerce',
        'Restricted Products',
        'Restricted Products',
        'manage_options',
        'restricted-products',
        'yourprefix_wpf_settings_page_callback'
    );
}
add_action('admin_menu', 'yourprefix_wpf_add_settings_page');

// Render the settings page
function yourprefix_wpf_settings_page_callback() {
    // Check if the current user has the 'manage_options' capability
    if (!current_user_can('manage_options')) {
        wp_die(__('You do not have sufficient permissions to access this page.', 'textdomain'));
    }

    ?>
    <div class="wrap">
        <h1><?php echo esc_html(get_admin_page_title()); ?></h1>
        <form action="options.php" method="post">
            <?php
            settings_fields('wpf_settings');
            do_settings_sections('wpf_settings');
            submit_button('Save Changes');
            ?>
        </form>
    </div>
    <?php
}

// Register settings, sections, and fields
function yourprefix_wpf_register_settings() {
    register_setting('wpf_settings', 'wpf_restricted_products', array(
        'type' => 'string',
        'sanitize_callback' => 'yourprefix_wpf_sanitize_restricted_products'
    ));

    add_settings_section('wpf_main_section', 'Main Settings', null, 'wpf_settings');

    add_settings_field('wpf_restricted_products', 'Restricted Product IDs', 'yourprefix_wpf_restricted_products_callback', 'wpf_settings', 'wpf_main_section');
}
add_action('admin_init', 'yourprefix_wpf_register_settings');

// Render the input field for restricted products
function yourprefix_wpf_restricted_products_callback() {
    $restricted_products = get_option('wpf_restricted_products', '');
    echo '<input name="wpf_restricted_products" id="wpf_restricted_products" type="text" value="' . esc_attr($restricted_products) . '" class="regular-text" placeholder="123,567" />';
    echo '<p class="description">Enter the restricted product IDs separated by commas.</p>';
}

// Sanitize the input value for restricted products
function yourprefix_wpf_sanitize_restricted_products($input) {
    $input = preg_replace('/[^0-9,]/', '', $input);
    return $input;
}

// restrict products

if (!function_exists('yourprefix_wpf_is_current_user_role')) {
    function yourprefix_wpf_is_current_user_role($roles_to_check) {
        $current_user       = wp_get_current_user();
        $current_user_roles = (empty($current_user->roles) ? array('') : $current_user->roles);
        $roles_intersect    = array_intersect($current_user_roles, $roles_to_check);
        return (!empty($roles_intersect));
    }
}

if (!function_exists('yourprefix_wpf_do_hide_product')) {
    function yourprefix_wpf_do_hide_product($product_id_to_check) {
        $restricted_products_option = get_option('wpf_restricted_products', '');
        $products_to_hide = array_map('intval', array_filter(explode(',', $restricted_products_option)));

        $roles_to_hide_for = array('customer');
        $allowed_roles     = array('practitioner');

        return (
            in_array($product_id_to_check, $products_to_hide) &&
            (!is_user_logged_in() || yourprefix_wpf_is_current_user_role($roles_to_hide_for)) &&
            !yourprefix_wpf_is_current_user_role($allowed_roles)
        );
    }
}

add_filter('woocommerce_is_purchasable', 'yourprefix_wpf_product_purchasable_by_user_role', 10, 2);
if (!function_exists('yourprefix_wpf_product_purchasable_by_user_role')) {
    function yourprefix_wpf_product_purchasable_by_user_role($purchasable, $product) {
        return (yourprefix_wpf_do_hide_product($product->get_id()) ? false : $purchasable);
    }
}

// Display a custom message on the shop page for restricted products
function yourprefix_wpf_display_shop_message() {
    global $product;

    if (yourprefix_wpf_do_hide_product($product->get_id())) {
        echo '<p class="not-purchasable-message">This product is not purchasable.</p>';
        remove_action('woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10);
    }
}
add_action('woocommerce_after_shop_loop_item', 'yourprefix_wpf_display_shop_message', 9);

// Display a custom message on the single product page for restricted products
function yourprefix_wpf_display_single_product_message() {
    global $product;

    if (yourprefix_wpf_do_hide_product($product->get_id())) {
        echo '<p class="not-purchasable-message">This product is not purchasable.</p>';
        remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30);
    }
}
add_action('woocommerce_single_product_summary', 'yourprefix_wpf_display_single_product_message', 29);

위의 코드를 테마(차일드 테마)의 함수 파일에 추가하도록 합니다. 위의 코드를 사용하면 워드프레스 관리자 페이지 » 우커머스 (WooCommerce) » Restricted Products 메뉴 항목이 생성됩니다.

우커머스: 사용자 역할에 따라 특정 상품의 구입 제한하기

Restricted Products IDs에 판매를 제한할 상품 ID를 콤마로 구입하여 입력하도록 합니다.

그러면 practitioner 사용자 역할만 해당 상품들을 구입할 수 있습니다.

우커머스: 사용자 역할에 따라 특정 상품의 구입 제한하기

일반 고객이나 게스트(손님)가 해당 상품에 접근하면 위의 그림과 같이 "This product is not purchasable"이 표시됩니다. 이 문구는 코드에서 변경할 수 있습니다.

이 문구의 컬러 등 스타일은 CSS로 제어할 수 있습니다.

.not-purchasable-message {
    color: #a00;
    font-weight: bold;
    margin-top: 10px;
    margin-bottom: 10px;
}

위의 코드를 Flatsome 테마에서 테스트하니 잘 작동했습니다. 아바다 테마에서 테스트해 보니 장바구니 버튼은 사라지지만 "This product is not purchasable." 텍스트는 표시되지 않네요. 우커머스 후크(hook)를 체크하여 다른 후크로 시도할 수 있을 것입니다.

옵션 상품에서는 위의 코드의 작동 여부를 테스트하지 않았습니다. 옵션 상품에서 작동하지 않을 경우, 옵션 상품을 포함하도록 코드를 수정하여 사용하시기 바랍니다.

참고


댓글 남기기

Leave a Comment