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.
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?
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':
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:
(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.
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); } }
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.
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
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
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
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?
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':
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:
(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?
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
Thanks Stefan/**
* 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);
}
}
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.