Okay
  Public Ticket #3961123
Products visibility based on attribute
Closed

Comments

  •  2
    Ran started the conversation

    Hello, as the subject suggests, I am looking to set visibility rules ( just like products ) based on a certin attribut.

    I know there must be some code involved, perhaps you could help me with that, if possible

  •  2,406
    WebWizards replied

    Hello Ran,

    It's generally possible to change visibility so that instead of being based on product categories, it is based on a custom taxonomy. You would do that with this code: https://pastecode.io/s/v8obq3eh

    Specifically for attributes I am not completely sure - technically an attribute is a taxonomy, so I guess that could work.

    I think it would be helpful if you shared a specific example of what attribute you're looking to use, with what options, and generally how you wish for that to work - so I can better guide you and assess how feasible this is for your setup.

     

    Kind regards,

    Stefan

  •  2
    Ran replied

    Hey Stefan!

    Thanks for the reply.

    I will try to explain my situatuion:

    I have around 250 products, which are divided to 2 series  (you can look at it as a BRAND, though they are from the same brand) the series are END USER and PROFESSIONAL

    and the products also share categories, for example:

    Category - DETERGENTS

    and then I have product 1 and product 2 which are both from the same brand - X 

    but product 1 is from serie END USER and product 2 is from serie PROFESSIONAL.

    Today, since there is not visibility control based on attribute, I need to create 2 categories for those 2 prdocuts in order to control the visibility, or to set the visibility of each product individualy, which would have been applicable if I didnt have 200+ products, so category control is all I am left with, which leaves me to create 2 categories - DETERGENT END USER and DETERGENT PROFESSIONAL you can see how inefficient that is.

    If I could control the visibility based on the attribute "SERIE" where I would only have 2 terms that would make our life much more easier.

    I read the code you have sent, from what I understand, it removs the visibility control based on category and replaces it with taxonomy, am I correct? what will happen if a product does not have this attribute? will it be shown to all? or will it be hidden from all? or perhaps the individual visibility setting that we will set for a product that does not contain the attribute, will have a higher priority?

    Thanks

  •  2
    Ran replied

    Hey Stefan, The code does not function. 

    It does remove the visibility control from the category, but it does not add it to the attribute.

    do you want access to the site to check it?

  •  2,406
    WebWizards replied

    Hi Ran,

    Thank you for the clarifications,

    Sorry, I should have been clearer: That code adds visibility to a different taxonomy, specifically to TAGS (visibility is then available when editing each tag).

     

    Based on what you described, I don't think you actually need that code or need to change the taxonomy. I think you can just use categories.

    Here's what's important to keep in mind: if you have multiple categories assigned to a product and just 1 of those categories is visible, the product will be visible.

    So I think it's fairly straightforward to set up:

    (1) Go to B2BKing -> Tools and choose "all categories not visible to all" and click 'set all categories':

    9125199554.png

    This will edit all categories in bulk and set them as not visible. 

    At this point nobody can see any products.

     

    (2) Go to Products -> Categories and create 2 categories: Professional and End User, setting visibility accordingly:

    8496732253.png

    1481519130.png

     

    (3) Now edit each product and give each product one of these 2 categories, either end user (only retail customers will see it), professional (only b2b customers will see it),

    Or if you want everybody to see the product you can give it both categories (if at least 1 category is visible to the customer, the product will be visible)

    So you can then simply control visibility by giving one of these categories, and it does not matter what other categories the product has.

    You can then set product categories in bulk, either via bulk actions or product import/export.

     

     

    Does that make sense?

     

  •  2
    Ran replied

    Hi Stefan, this is not quite what I needed since it still make me edit each product individually.

    with what you suggest I would also need to create double categories so for example

    END USER -> DETERGENTS

    PROFESSIONAL -> DETERGENTS 

    Because DETERGENTS can't be both a child of END USER and PROFESSIONAL, right?


    in any case, I have solved the issue with categories eventually and controlling the visibility in bulk edit with a snippet

    for anyone who needs this

    //code to bulk edit product visibiity based on the groups you have created

    <?php
    /**
    * B2BKing Bulk Visibility Changer Snippet
    * * Add this code to your theme's functions.php file or as a simple plugin.
    * This will add a bulk edit action to the WooCommerce products list.
    */

    // Don't execute directly
    if (!defined('ABSPATH')) {
    exit;
    }

    /**
    * Add bulk action to WooCommerce products list
    */
    add_filter('bulk_actions-edit-product', 'add_b2bking_bulk_actions');
    function add_b2bking_bulk_actions($bulk_actions) {
    // Get all B2BKing groups
    $b2bking_groups = get_b2bking_groups();
    // Add bulk visibility options
    $bulk_actions['b2bking_visibility_all'] = 'B2BKing: Set visibility to ALL';
    $bulk_actions['b2bking_visibility_b2b'] = 'B2BKing: Set visibility to B2B only';
    $bulk_actions['b2bking_visibility_b2c'] = 'B2BKing: Set visibility to B2C only';
    $bulk_actions['b2bking_visibility_hidden'] = 'B2BKing: Set visibility to HIDDEN';
    // Add visibility options for each B2BKing group
    if (!empty($b2bking_groups)) {
    foreach ($b2bking_groups as $group_id => $group_name) {
    $bulk_actions['b2bking_visibility_group_' . $group_id] = sprintf('B2BKing: Visible only to "%s" group', $group_name);
    }
    }
    return $bulk_actions;
    }

    /**
    * Handle the bulk action
    */
    add_action('handle_bulk_actions-edit-product', 'handle_b2bking_bulk_actions', 10, 3);
    function handle_b2bking_bulk_actions($redirect_to, $action, $post_ids) {
    if (strpos($action, 'b2bking_visibility_') !== 0) {
    return $redirect_to; // Not our action
    }
    $processed = 0;
    // Process all selected products
    foreach ($post_ids as $post_id) {
    if (strpos($action, 'b2bking_visibility_group_') === 0) {
    // Extract group ID from action
    $group_id = str_replace('b2bking_visibility_group_', '', $action);
    // Set visibility to specific group
    update_post_meta($post_id, 'b2bking_group_' . $group_id, '1');
    // Reset other visibility options
    update_post_meta($post_id, 'b2bking_visibility', 'restricted');
    update_post_meta($post_id, 'b2bking_all_users', '0');
    update_post_meta($post_id, 'b2bking_b2c_users', '0');
    // Reset visibility for other groups
    $all_groups = get_b2bking_groups();
    foreach ($all_groups as $other_group_id => $group_name) {
    if ($other_group_id != $group_id) {
    update_post_meta($post_id, 'b2bking_group_' . $other_group_id, '0');
    }
    }
    } else {
    // Handle standard visibility options
    $visibility = str_replace('b2bking_visibility_', '', $action);
    switch ($visibility) {
    case 'all':
    update_post_meta($post_id, 'b2bking_visibility', '');
    update_post_meta($post_id, 'b2bking_all_users', '1');
    update_post_meta($post_id, 'b2bking_b2c_users', '1');
    reset_group_visibility($post_id);
    break;
    case 'b2b':
    update_post_meta($post_id, 'b2bking_visibility', 'b2b');
    update_post_meta($post_id, 'b2bking_all_users', '0');
    update_post_meta($post_id, 'b2bking_b2c_users', '0');
    reset_group_visibility($post_id, '1'); // Make visible to all B2B groups
    break;
    case 'b2c':
    update_post_meta($post_id, 'b2bking_visibility', 'b2c');
    update_post_meta($post_id, 'b2bking_all_users', '0');
    update_post_meta($post_id, 'b2bking_b2c_users', '1');
    reset_group_visibility($post_id, '0'); // Hide from all B2B groups
    break;
    case 'hidden':
    update_post_meta($post_id, 'b2bking_visibility', 'hidden');
    update_post_meta($post_id, 'b2bking_all_users', '0');
    update_post_meta($post_id, 'b2bking_b2c_users', '0');
    reset_group_visibility($post_id, '0'); // Hide from all B2B groups
    break;
    }
    }
    $processed++;
    }
    // Add query args for admin notice
    $redirect_to = add_query_arg(array(
    'b2bking_visibility_changed' => '1',
    'changed' => $processed,
    ), $redirect_to);
    return $redirect_to;
    }

    /**
    * Display admin notice after bulk action
    */
    add_action('admin_notices', 'b2bking_visibility_admin_notice');
    function b2bking_visibility_admin_notice() {
    if (!empty($_GET['b2bking_visibility_changed'])) {
    $count = intval($_GET['changed']);
    printf(
    '<div class="updated notice is-dismissible"><p>' . _n(
    'Updated B2BKing visibility for %s product.',
    'Updated B2BKing visibility for %s products.',
    $count,
    'woocommerce'
    ) . '</p></div>',
    $count
    );
    }
    }

    /**
    * Helper function to get all B2BKing groups
    */
    function get_b2bking_groups() {
    $groups = array();
    // Get all B2BKing groups from custom post type
    $args = array(
    'post_type' => 'b2bking_group',
    'post_status' => 'publish',
    'numberposts' => -1
    );
    $group_posts = get_posts($args);
    foreach ($group_posts as $group) {
    $groups[$group->ID] = $group->post_title;
    }
    return $groups;
    }

    /**
    * Helper function to reset group visibility
    */
    function reset_group_visibility($post_id, $value = '0') {
    $groups = get_b2bking_groups();
    foreach ($groups as $group_id => $group_name) {
    update_post_meta($post_id, 'b2bking_group_' . $group_id, $value);
    }
    }

    Thanks Stefan 

  •  2,406
    WebWizards replied

    Great to hear you already solved that,

    With the method I suggested, you would not need to create double categories. In your example Detergents does not need to be a child of either End User or Professional. The 2 categories End user and Professional would be 2 categories completely separate from the other categories (neither parent nor child)

    The way that works is that since visibility is disabled for all other categories than those 2, basically all other categories have no effect whatsoever on visibility.