Tell us what you are trying to do?
We have a custom post type called Companies and under Companies there are Woocommerce products. There are also users of the company.
How can we show the company page and company's products to the users' of the company?
Here is the structure of our website.
(Company) KFC
(Users) KFC's employees
(Products) KFC's products
What is the link to your site?
Localhost
Hi Stanley,
Thank you for contacting us and I'll be happy to assist.
To achieve what you're planning, you can follow these steps:
1. You can create a custom user role for each company and then assign each company's user to that particular role:
https://toolset.com/documentation/user-guides/managing-wordpress-admin-capabilities-access/#creating-custom-roles
2. To link companies and WooCommerce products, you can set a "one-to-many" post-relationship between company and products, post types (i.e. each company can have many products).
https://toolset.com/documentation/post-relationships/
3. After that, you'll be able to limit access to products and/or other content, based on custom company user roles, using the Toolset Access plugin.
Here are some guides on how to restrict/allow access to entire pages or partial content on pages:
https://toolset.com/documentation/user-guides/limiting-read-access-specific-content/
https://toolset.com/documentation/user-guides/access-control-texts-inside-page-content/
I hope this helps and please let me know if you need any further assistance around this.
regards,
Waqar
Hey Waqar,
Based on what you suggested with using custom user roles, if we have 100 companies, wouldn't that result in 100 different user roles?
Is there a more efficient way of handling this?
Hi Stanley,
Thanks for writing back.
An alternate approach will require a connection between a company (post type) and a user.
Since post relationships (ref: https://toolset.com/documentation/post-relationships/ ) can only connect two post types and not a post type and users, you'll need a workaround for this.
You can add a new select type user field "Linked Company" and leave its options empty.
( ref: https://toolset.com/documentation/user-guides/user-fields/ )
To dynamically generate the select options for this field, from the existing company posts, you can use "wpt_field_options" filter:
add_filter( 'wpt_field_options', 'func_to_populate_linked_company', 10, 3);
function func_to_populate_linked_company( $options, $title, $type ){
switch( $title ){
case 'Linked Company':
$options = array();
// add first empty value
$options[] = array('#value' => '', '#title' => '---');
// get all company posts
$args = array( 'post_type' => 'company-post-slug', 'posts_per_page' => -1, 'post_status' => 'publish', 'orderby' => 'title' );
$results = get_posts( $args );
if ( $results ) {
foreach ( $results as $post ) {
$options[] = array('#value' => $post->ID, '#title' => $post->post_title);
}
}
break;
}
return $options;
}
Note: you'll replace "Linked Company" with the actual title of your field and "company-post-slug" with the actual slug of your company post type.
As a result, when a user profile will be added/edited from the admin area or the front-end (CRED form), you'll have the option to select a company for that user.
After that, you'll be able to get the ID of connected company's post from the user's meta and then show only products linked to that particular company (point 2 of my last reply).
I hope this helps.
regards,
Waqar
Thanks for the code, Waqar.
Apologies for this question but where should I place it?
From the front-end point of view, the Linked Company field should appear in the User settings where the admin can assign each user to their company. We don't want users to select the companies themselves as it will give them unauthorised access to companies they don't belong to.
Hi Stanley,
You can add the code snippet at the bottom of your active theme's "functions.php" file.
This and any other user meta fields ( ref: https://toolset.com/documentation/user-guides/user-fields/ ) will be available for the admins, to edit from each user's profile screen ( WP Admin -> Users -> All Users -> {User} ).
If you don't want to allow users to edit this field (Company) themselves, make sure that:
1. This field is not available on any front-end CRED forms and
2. The user field group, which holds this company user field, is only accessible by the users with the "Administrator" role.
( example screenshot: hidden link )
regards,
Waqar
Thanks. That worked!
Now, how do you limit access to Company pages based on the Company field for users?
Hi Stanley,
You can use "types" shortcode to get the ID of the company, attached to the currently logged-in user.
( ref: https://toolset.com/documentation/customizing-sites-using-php/functions/ )
For example:
[types usermeta='linked-company' output='raw' current_user='true'][/types]
You can then use this ID, in a conditional block comparison, to show or hide specific content on a page(s).
( ref: https://toolset.com/documentation/user-guides/conditional-html-output-in-views/using-shortcodes-in-conditions/ )
For example, suppose your website includes a "Company A" with an ID "10". To show or hide some content based on currently logged-in user's link with that company, you can use conditional blocks as:
[wpv-conditional if="( '[types usermeta='linked-company' output='raw' current_user='true'][/types]' eq '10' )"]
Show this content only to user linked to Company A
[/wpv-conditional]
[wpv-conditional if="( '[types usermeta='linked-company' output='raw' current_user='true'][/types]' ne '10' )"]
Show this content to everyone except a user linked to Company A
[/wpv-conditional]
regards,
Waqar
Thanks for this.
This would only be effective for 1 company at a time. How do you do this for 100 different companies?
Btw, we built the View into the content template for Companies. So we didn't manually add the View into each company individually.
Hi Stanley,
The last example was shared to give you an idea around two important points:
1. how to extract the ID of the company attached to the currently logged-in user.
2. how that ID can be used in conditional display shortcodes.
Depending on your specific requirement, you can generate dynamic content for each different company, using a view and the company ID passed to it as an attribute (which means you won't have to repeat same steps for each company).
Here is a guide on the topic:
https://toolset.com/documentation/user-guides/passing-arguments-to-views/
If you could share an example of more specific content that needs to be shown for each company, I'll be happy to explain this further.
regards,
Waqar
We use a content template for our Company pages.
Now we just need to give access to those Company pages to the users of those Companies.
In the content template, I'm thinking a conditional output would be the best way forward.
[wpv-conditional if="( '[types usermeta='linked-company' output='raw' current_user='true'][/types]' eq '799' )"]
[wpv-view name="company-products"]
[wpv-post-body view_template="None"]
[/wpv-conditional]
In the example above, "799" is the ID of the Company page. I'm thinking if we replace this with the user's Company ID then that would solve the issue.
If the user's Company ID matches the ID on the page, show content.
UPDATE:
I think this solved the issue.
[wpv-conditional if="( '[wpv-post-id]' eq '[types usermeta='linked-company' output='raw' current_user='true'][/types]' )"]
[wpv-view name="company-products"]
[wpv-post-body view_template="None"]
[/wpv-conditional]
What do you think? Do you think this is an efficient way of solving the issue?
Hi Stanley,
Yes, your understand and approach is correct and that is a good efficient way to restrict the content of a single company's page, for only the connected/allowed users.
Important note: I'll be on personal day-offs until Wednesday, and won't be able to follow up on any tickets until then. For more timely and efficient support, I'll recommend opening new ticket(s), so that the available team members can guide you accordingly.
regards,
Waqar
My issue is resolved now. Thank you!