Hi all and Happy New Year to the team,
I am trying to create a custom Woocommerce Shop page/archive that shows different product categories depending on the user role (e.g: user with Role 1 can see/buy products of category A, B and C, user with Role 2 can see/buy products in categories A, D, E, etc.)
After reading your tutorials I created the custom products archive and tried to use conditionals but the loop is just one and I couldn't achieve the result, could you please advise a solution if any ?
Also, I have noticed that in the WP archive/loop selection if I select one or more terms in the "Select specific terms" option all products for all categories are always displayed, no matter what term is selected, is this a bug ?
Many thanks in advance.
Nicola
Hi Nicola,
A very Happy New Year to you too.
To troubleshoot and suggest the best way to achieve this, I'll need to see how Toolset and WooCommerce are set up.
Can you please share temporary admin login details, along with the exact steps to see the archives that you're working on?
Note: Your next reply will be private and making a complete backup copy is recommended before sharing the access details.
regards,
Waqar
Hello Waqar
FYI since yesterday my site is off due to a fatal error by Woocommerce.
Uncaught Error: Using $this when not in object context in /home/xxxxxxxxxx/public_html/wp-content/plugins/woocommerce/src/Internal/Features/FeaturesController.php
If yu try to access the site you get this:
Fatal error: Uncaught Error: Call to undefined function WooViews\Templates\is_shop() in /home/MY SITE/public_html/wp-content/plugins/woocommerce-views/application/Templates/Loader.php:97 Stack trace: #0 /home/MY SITE/public_html/wp-content/plugins/woocommerce-views/application/Templates/Loader.php(58): WooViews\Templates\Loader->is_product_archive() #1 /home/MY SITE/public_html/wp-includes/class-wp-hook.php(324): WooViews\Templates\Loader->override('') #2 /home/MY SITE/public_html/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters(NULL, Array) #3 /home/MY SITE/public_html/wp-includes/plugin.php(517): WP_Hook->do_action(Array) #4 /home/MY SITE/public_html/wp-includes/template-loader.php(13): do_action('template_redire…') #5 /home/MY SITE/public_html/wp-blog-header.php(19): require_once('/home/MY SITE/…') #6 /home/MY SITE/public_html/index.php(17): require('/home/MY SITE/…') #7 {main} thrown in /home/MY SITE/public_html/wp-content/plugins/woocommerce-views/application/Templates/Loader.php on line 97
is WooViews a Toolset component ?
I wasn't doing anything at the time and I didn't receive any automatic updates warning email yesterday. I also didn't receive any email warning about you accessing the site, so I suppose you didn't do anything yet.
I don't know why this happened, I could just restore the backup of Jan 8th. For now I have deleted the custom archive and deactivated Woocommerce that won't restart.
I provided you the link for accessing the site in Recovery Mode in the previous private message.
Please advise, thanks
Regards
Nicola
Thank you for sharing these details.
I tried to use the recovery mode link, but it also showed another error screen:
Notice: Function is_embed was called incorrectly. Conditional query tags do not work before the query is run. Before then, they always return false. Please see Debugging in WordPress for more information. (This message was added in version 3.1.0.) in /home/musicain/public_html/wp-includes/functions.php on line 6031
Notice: Function is_search was called incorrectly. Conditional query tags do not work before the query is run. Before then, they always return false. Please see Debugging in WordPress for more information. (This message was added in version 3.1.0.) in /home/musicain/public_html/wp-includes/functions.php on line 6031
Recovery Mode not initialized.
Looks like the most appropriate action is to restore the website to the last working backup.
The missing function 'is_shop' reported by the original error message, is part of the WooCommerce core plugin. It is also called/used by our 'Toolset WooCommerce Blocks' plugin.
If a core WooCommerce function is missing, the most likely cause would be missing/corrupt file(s), as a result of some failed/incomplete WooCommerce plugin update.
Let me know once the website has been restored and we'll continue on the original question about the archives.
regards,
Waqar
Hello Waqar,
following your suggestion I restored the site, it works now, thanks.
BTW - the custom shop archive is back too, pls feel free to edit/delete it. Please note also that only users with shop_manager role can see the complete shop page, use Balabala user.
regards,
Nicola
Hi Nicola,
Thank you for this update.
I'm currently performing some tests on my website with a similar setup and will share the findings, as soon as this testing completes.
Thank you for your patience.
regards,
Waqar
Thank you for waiting.
During testing on my website, I was able to limit the product queries to particular product category terms, based on the user role, by using the 'pre_get_posts' hook:
https://developer.wordpress.org/reference/hooks/pre_get_posts/
For example:
function custom_products_archive_function( $query ) {
// skip if admin side or not main query
if ( is_admin() || ! $query->is_main_query() ) return;
// check if the query is for a specific post type
if ( in_array ( $query->get('post_type'), array('product') ) ) {
$user = wp_get_current_user();
// check if user is logged in
if ( $user->ID != 0 ) {
// get current user's primary role
$user_role = $user->roles[0];
// if the user role is 'Role A'
if($user_role == 'role-a') {
// set the target term IDs for 'Role A'
$allowed_terms = array( 123, 789 );
}
// if the user role is 'Role B'
else if ($user_role == 'role-b') {
// set the target term IDs for 'Role B'
$allowed_terms = array( 456, 789 );
}
// set the taxonomy query to limit the results from only allowed terms
$taxquery = array(
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $allowed_terms,
'operator'=> 'IN'
)
);
$query->set( 'tax_query', $taxquery );
}
}
}
add_action( 'pre_get_posts', 'custom_products_archive_function' );
As explained in the comments in the function, it checks if the main query is for the 'products' post type and if the user is logged in.
After that, it gets the current user's role and sets the target term IDs for the allowed 'product categories' separately for user role A and user role B.
Feel free to adjust the user role slugs and the target term IDs, as used on your website.
Hi Waqar,
many thanks for this, I think it could be useful to other users too. Just a couple of questions:
1. should I create a Toolset custom snippet with this code ?
2. $allowed_terms = array( 456, 789 ); -> should I replace 456 etc with the term slug or ID ? I know the slug, but not the ID ...
thanks
Regards
Glad I could help.
> 1. should I create a Toolset custom snippet with this code ?
- Yes, that code snippet can be included through either Toolset's custom code feature ( ref: https://toolset.com/documentation/adding-custom-code/using-toolset-to-add-custom-code/ ) or through the active child theme's "functions.php" file.
> 2. $allowed_terms = array( 456, 789 ); -> should I replace 456 etc with the term slug or ID ? I know the slug, but not the ID ...
- Here is a useful guide to checking the term IDs:
hidden link
Alternatively, you can set the terms slugs in the '$allowed_terms' arrays like this:
$allowed_terms = array( 'cat-slug-1', 'cat-slug-2' );
And in the code, change the 'field' attribute to use 'slug', instead of 'term_id'
Hello Waqar,
the snippet works great with slugs, many thanks ! I just had to remove the admin/return line and add an admin specific "if " with all categories because the admin shop page was showing "no products found" and consequently a warning of undefined $allowed_terms variable. No problem. Great support as always !
Best Regards
Nicola