✅Asignar Productos a Roles (Woocommerce) Sin Plugins

La gestión de acceso a productos en una tienda online es crucial para ofrecer una experiencia personalizada y eficiente. Imagina tener la capacidad de mostrar productos específicos solo a ciertos tipos de usuarios, como mayoristas, distribuidores o clientes VIP. Esto no solo mejora la organización de tu tienda, sino que también permite segmentar y optimizar tus estrategias de venta.

Para crear ROLES PERSONALIZADOS EN WORDPRESS click aquí.

En este artículo, exploraremos una solución sencilla y poderosa para restringir el acceso a productos en WooCommerce según los roles de usuario. Lo mejor de todo es que no necesitarás instalar ningún plugin, ya que implementaremos esta funcionalidad mediante código personalizado. Desde agregar un selector de roles en la ficha de producto hasta bloquear el acceso directo a productos restringidos, cubriremos cada paso para que puedas implementar esta mejora en tu tienda de manera efectiva.

asignar roles productos woocommerce

El siguiente código tienes que agregarlo en el functions.php de tu tema hijo o utilizar un plugin como CODE SNIPPETS.

// 1. Agregar una lista de selección múltiple de roles en la ficha del producto
function agregar_casilla_roles_visibles() {
    global $wp_roles;
    $roles = $wp_roles->roles;

    echo '<div class="options_group">';
    echo '<p class="form-field"><label for="_roles_visibles">Roles Permitidos</label>';
    echo '<select id="_roles_visibles" name="_roles_visibles[]" multiple="multiple" style="width: 100%;">';

    // Obtener los roles guardados
    $roles_guardados = get_post_meta( get_the_ID(), '_roles_visibles', true );
    $roles_guardados = is_array( $roles_guardados ) ? $roles_guardados : array();

    // Añadir la opción "Invitados"
    echo '<option value="guest" ' . selected( in_array( 'guest', $roles_guardados ), true, false ) . '>Invitados</option>';

    foreach ( $roles as $role_slug => $role ) {
        echo '<option value="' . esc_attr( $role_slug ) . '" ' . selected( in_array( $role_slug, $roles_guardados ), true, false ) . '>' . esc_html( $role['name'] ) . '</option>';
    }

    echo '</select>';
    echo '<span class="description">Selecciona los roles que pueden ver este producto. Incluye "Invitados" para usuarios no registrados.</span>';
    echo '</p></div>';
}
add_action( 'woocommerce_product_options_general_product_data', 'agregar_casilla_roles_visibles' );

// 2. Guardar los roles seleccionados en el meta del producto
function guardar_casilla_roles_visibles( $post_id ) {
    $roles_visibles = isset( $_POST['_roles_visibles'] ) ? array_map( 'sanitize_text_field', $_POST['_roles_visibles'] ) : array();
    update_post_meta( $post_id, '_roles_visibles', $roles_visibles );
}
add_action( 'woocommerce_process_product_meta', 'guardar_casilla_roles_visibles' );

// 3. Filtrar productos en el loop (tienda y categorías) según roles
function filtrar_productos_por_rol( $query ) {
    if ( ! is_admin() && $query->is_main_query() && ( is_shop() || is_product_category() || is_product_tag() ) ) {
        $user = wp_get_current_user();
        $user_roles = $user->roles;
        $is_admin = in_array( 'administrator', $user_roles );

        if ( ! $is_admin ) { // Los administradores siempre ven todo
            $meta_query = $query->get( 'meta_query' ) ?: array();

            if ( empty( $user_roles ) ) {
                // Usuario no registrado: buscar productos con rol "guest"
                $meta_query[] = array(
                    'relation' => 'OR',
                    array(
                        'key'     => '_roles_visibles',
                        'value'   => 'guest',
                        'compare' => 'LIKE',
                    ),
                    array(
                        'key'     => '_roles_visibles',
                        'compare' => 'NOT EXISTS', // Mostrar productos sin roles asignados
                    ),
                );
            } else {
                // Usuario registrado: buscar productos con roles coincidentes o sin restricciones
                $meta_query[] = array(
                    'relation' => 'OR',
                    array(
                        'key'     => '_roles_visibles',
                        'value'   => '"' . implode( '","', $user_roles ) . '"',
                        'compare' => 'LIKE',
                    ),
                    array(
                        'key'     => '_roles_visibles',
                        'compare' => 'NOT EXISTS',
                    ),
                );
            }

            $query->set( 'meta_query', $meta_query );
        }
    }
}
add_action( 'pre_get_posts', 'filtrar_productos_por_rol' );

// 4. Restringir acceso directo a la ficha de producto
function restringir_acceso_ficha_producto() {
    if ( is_singular( 'product' ) ) {
        global $post;
        $user = wp_get_current_user();
        $user_roles = $user->roles;
        $is_admin = in_array( 'administrator', $user_roles );
        $roles_visibles = get_post_meta( $post->ID, '_roles_visibles', true );
        $roles_visibles = is_array( $roles_visibles ) ? $roles_visibles : array();

        // Los administradores siempre pueden acceder
        if ( ! $is_admin ) {
            if ( empty( $user_roles ) ) {
                // Usuario no registrado
                if ( ! in_array( 'guest', $roles_visibles ) && ! empty( $roles_visibles ) ) {
                    wp_die(
                        '<div style="max-width: 600px; margin: 50px auto; padding: 30px; border: 1px solid #ddd; border-radius: 10px; text-align: center; font-family: Arial, sans-serif;">
                            <h1 style="color: #0073aa; font-size: 2rem; margin-bottom: 20px;">Acceso Restringido</h1>
                            <p style="font-size: 1.2rem; color: #555; line-height: 1.5;">
                                Este producto está disponible únicamente para usuarios registrados o con permisos específicos.<br><br>
                                Si crees que esto es un error, por favor <a href="' . esc_url( wc_get_page_permalink( 'myaccount' ) ) . '" style="color: #0073aa; text-decoration: none; font-weight: bold;">inicia sesión</a> o <a href="' . esc_url( wc_get_page_permalink( 'myaccount' ) ) . '" style="color: #0073aa; text-decoration: none; font-weight: bold;">regístrate</a>.
                            </p>
                            <a href="' . esc_url( wc_get_page_permalink( 'shop' ) ) . '" style="display: inline-block; margin-top: 30px; padding: 10px 20px; background-color: #0073aa; color: #fff; border-radius: 5px; text-decoration: none; font-size: 1.1rem; font-weight: bold;">
                                Volver a la Tienda
                            </a>
                        </div>',
                        'Acceso Restringido'
                    );
                }
            } else {
                // Usuario registrado
                if ( ! empty( $roles_visibles ) && empty( array_intersect( $roles_visibles, $user_roles ) ) ) {
                    wp_die(
                        '<div style="max-width: 600px; margin: 50px auto; padding: 30px; border: 1px solid #ddd; border-radius: 10px; text-align: center; font-family: Arial, sans-serif;">
                            <h1 style="color: #0073aa; font-size: 2rem; margin-bottom: 20px;">Acceso Restringido</h1>
                            <p style="font-size: 1.2rem; color: #555; line-height: 1.5;">
                                Este producto está disponible únicamente para usuarios con roles específicos.<br><br>
                                Si crees que esto es un error, por favor <a href="' . esc_url( wc_get_page_permalink( 'myaccount' ) ) . '" style="color: #0073aa; text-decoration: none; font-weight: bold;">inicia sesión</a>.
                            </p>
                            <a href="' . esc_url( wc_get_page_permalink( 'shop' ) ) . '" style="display: inline-block; margin-top: 30px; padding: 10px 20px; background-color: #0073aa; color: #fff; border-radius: 5px; text-decoration: none; font-size: 1.1rem; font-weight: bold;">
                                Volver a la Tienda
                            </a>
                        </div>',
                        'Acceso Restringido'
                    );
                }
            }
        }
    }
}
add_action( 'template_redirect', 'restringir_acceso_ficha_producto' );

Lenguaje del código: PHP (php)

Entendiendo el código

1. agregar_casilla_roles_visibles

Propósito:
Añade un campo en la pestaña de «Datos del producto» en el panel de administración de WooCommerce.
Detalles:

  • Utiliza las funciones de WordPress para recuperar todos los roles de usuario disponibles.
  • Genera una lista de selección múltiple que permite al administrador seleccionar los roles que pueden ver el producto.
  • Recupera los roles previamente guardados para mostrarlos como seleccionados cuando el producto se edita.

2. guardar_casilla_roles_visibles

Propósito:
Guarda los roles seleccionados en el meta dato personalizado _roles_visibles del producto.
Detalles:

  • Recupera los datos enviados desde el formulario de la ficha del producto.
  • Limpia y valida los datos antes de guardarlos en la base de datos.
  • Usa la función update_post_meta para actualizar o crear el meta dato asociado al producto.

3. filtrar_productos_por_rol

Propósito:
Controla qué productos son visibles en la tienda y las páginas de categorías según los roles del usuario actual.
Detalles:

  • Se ejecuta en las consultas principales de WooCommerce (is_shop, is_product_category, etc.).
  • Obtiene los roles del usuario actual mediante la función wp_get_current_user.
  • Genera una meta consulta (meta_query) para:
    • Mostrar productos sin restricciones de roles.
    • Mostrar productos cuyos roles visibles coincidan con el rol del usuario actual.
  • Asegura que los administradores puedan ver todos los productos.

4. restringir_acceso_ficha_producto

Propósito:
Bloquea el acceso directo a la página de un producto si el usuario no tiene un rol permitido.
Detalles:

  • Verifica si el usuario está intentando acceder a un producto específico (is_singular('product')).
  • Recupera los roles permitidos del meta dato _roles_visibles del producto.
  • Comprueba si el usuario actual tiene alguno de los roles permitidos.
  • Si el acceso está restringido, utiliza la función wp_die para mostrar un mensaje de error personalizado con un diseño amigable.

En conclusión, este código ofrece una solución flexible y personalizable para gestionar la visibilidad de productos en WooCommerce según los roles de usuario. Es ideal para tiendas que necesitan segmentar su catálogo y controlar el acceso de sus clientes de manera eficiente.

Nos vemos en el siguiente tutorial. Un saludo.

5/5 - (3 votos)
Compartir Artículo

Un comentario

  1. Fran Salas Master WP 1 año atrás

    Deja tus opiniones o dudas en los comentarios.

¿Tienes una duda o sugerencia sobre este artículo?

Puedes dejar un comentario de forma anónima, sin necesidad de registrarte ni proporcionar ningún dato personal. Tu mensaje se publicará como “Usuario Anónimo No Premium”, un perfil que agrupa a todos los visitantes no registrados.

Importante: para evitar el spam automático, todos los comentarios anónimos deben comenzar con el símbolo #. Ejemplo: # Tengo una duda sobre los shortcodes personalizados...

Este espacio está destinado exclusivamente a preguntas concretas, dudas o sugerencias relacionadas con el contenido del artículo. Por respeto a los demás lectores, no se publicarán temas sin relación.

Privacidad y normas:
  • No tienes que agregar tu nombre, correo ni ningún otro dato identificativo.
  • No se permiten enlaces en comentarios anónimos.
  • No se permiten símbolos especiales como < o > (menor y mayor que), ya que se consideran intentos de insertar código y serán bloqueados.
  • Todos los comentarios anónimos pasan por revisión antes de ser publicados y solo se aprobarán si aportan valor al contenido del artículo.
¿Quieres comentar con tu nombre y que tu mensaje se publique al instante? Inicia sesión o regístrate.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

0%