[Resolved] Grant/revoke access to image visibility based on user

This thread is resolved. Here is a description of the problem and solution.

Problem: I want to grant or revoke access to certain content on a single post and user basis. Is this possible using Toolset?

Solution: Partially it is natively possible using Access, but for example, to allow or disallow access to single fields by posts by users, you'll need some custom code.

The core idea of this code is explained here: https://toolset.com/forums/topic/grant-revoke-access-to-image-visibility-based-on-user/page/2/#post-1489243

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

This topic contains 32 replies, has 2 voices.

Last updated by Silvia 2 months ago.

Assigned support staff: Beda.

Author
Posts
#1464085

I have a client that manufactures textile products with a catalog of over 1200 different fabrics divided into 8 categories. I have created a cpt TEXTILES with a bunch of fields that describe the fabric characteristics, one of them being the fabric image.
In the custom template on the front end all these infos but the fabric image are available to the general public. In order to be able to view the fabric image the user has to send a specific request.
My client would like to be able to grant access to the whole Textile detail page, including fabric image (only on the screen and with ctrl-c or right click disabled!) only to specific clients. He would also like to revoke access for the same clients as easily. I cannot wrap my head around a way to obtain this, the solution seems there but I cannot fully grasp it, so I am asking for a suggestion on the best way to approach this.
Key thing to this is that the whole giving/revoking access to one/multiple textiles is fuss-free and easy for someone that doesn’t like WordPress back-end. If it’s not possible to do it on a fabric basis, he would be ok with granting access to a whole category. Can this even be done with Toolset? Can you suggest an efficient way to achieve this?

#1465455

Beda
Supporter

Languages: English (English ) Spanish (Español ) German (Deutsch )

Timezone: Asia/Ho_Chi_Minh (GMT+07:00)

Depending on whether you need to grant access to only ONE specific post (depending on the request) or an ENTIRE post type, this will be relatively easy, or more complex.

1. If you have "clients" that visit your site, and not all should see the images and eventual add-on data of single entries, you could simply use roles.
So, for example, you'd have a role A and role B set up in Toolset Access > Custom Roles, or you can even use the inbuilt roles if you have no special requirements to the user's control in the backend.
Based on those roles you can then hide/show entire Post Types, fields or even single pages or more detailed, single words or images by wrapping them in Access ShortCodes or altering the Access settings in Toolset > Access.

That means, once set up, your Website will not require any interaction but to let users create accounts on the site at different roles depending on what they request.
Most of this is explained here:
https://toolset.com/documentation/user-guides/access-control/access-control-texts-inside-page-content/
https://toolset.com/documentation/user-guides/access-control/

To let users create new accounts you'd use Toolset Forms:
https://toolset.com/documentation/getting-started-with-toolset/publish-content-from-the-front-end/forms-for-registering-users/

2. If you need to control on a Per Post basis who can see what, it's more complex.
You'd need a way to store this information:
WHO can see WHAT, on every single post.

There are different approaches how to create such a system, but until it's not clear if this is the requirement it is overwork to elaborate on all possible approaches.
So, for example, you could save the Page/post ID in the User profile who has access to it, or you could save the user against the post where that user has access to or other methods.
Most of these will include some need for custom code, likely.

Your best bet would be to go as broad as possible on the access control, meaning the easiest for you to set up is a site with 2 types of User role:
Guest (see only amount X of the content, no images, for example)
Special Custom User Role (sees also images and other content but on ALL posts)

You could of course always fine-tune this a little, like you say to sub-divide all posts by categories and apply different "rules" to each post depending on the category it is in.
That is also possible, it will eventually require a few more steps in creating proper Content Templates and use the right ShortCodes (HTML conditional in this case) to check on the current post/category/user to show the content or not.

I suggest, clarify what the precise need is (single post based control or broader) so we can start working on the first steps after.

#1466153

Beda thank you for your answer. Unfortunately, what I need is indeed the more complex solution, because my client
a) doesn't want his clients to have free access to the fabric catalog by simply registering on the website; b) Wants to grant access to selected clients and the fabrics they picked.

Ideally this is what he would like : Client A asks for details on, say, 3 fabrics by filling the cred form at the end of every fabric content template. Client B asks for details on 4 fabrics, one of them being the same fabric of Client A.

My client wants to be able to grant access to Client A and Client B respectively ONLY to the fabrics they asked details about (one fabric is being accessed by two clients in this example). He needs the simplest way possible to bind a fabric to a client and then interrupt access again when he desires.

He is going to be creating the wordpress user manually and then sending the credentials to his clients. It's important for him to be able to revoke access to the images at a moment's notice. These are technical fabrics we're talking about and there is a lot of industrial espionage in this field. That's why my client doesn't want people to be able to register freely on the website. He wants to be the one in control of whoever wants to have access to his products. I hope I made myself sufficiently clear for you to suggest me a solution, if there is one with toolset. Thank u again!

#1470709

Beda
Supporter

Languages: English (English ) Spanish (Español ) German (Deutsch )

Timezone: Asia/Ho_Chi_Minh (GMT+07:00)

b) means, you need to store the fabric for the user or the user for the fabric, there is no way around it.

This means, whenever you want to display to a user a specific fabric, either the fabric post or the user must have the other's information saved in some field for example.

This means you can, for example, create a select field (manually) that holds all user names or IDs
Then you can add that field to the fabric posts (maybe as a repeating field or in a repeatable field group) and for each user who shall see this fabric, the user ID should be selected or else added to the field of that fabric post.

Later, when displaying the fabric post you can then check if the current users' ID is within the ID's saved for the post, and display or hide accordingly the fabric post.

That would also allow revoking access, by removing that user ID from the fabric post.

However, it is probably requiring custom code to do all of that. You mention the user will first *request*, then the admin will *grant* access.

Will this be done manually, or is the requirement here to be automatic/semi-automatic?

For example, you can have a very simple solution.

1. A Toolset Form where the user can add the fabrics they want access to. This could be anything from a Form creating a child post to fabric (requests), or even just a form that has a repeatable URL field so the user can just add URLs to the fabrics they want access to and submit that

2. The admin then either reads those URLs and in each, adds the User ID to the previously discussed field, or, if we use Child Posts (requests) the admin could use those to then grant access to the Fabric manually.

I suggest, starting on a staging site, creating the fabric posts and a few users, then we can proceed over to the form that lets users request.
I suggest here using a simple form that lets users request access to many posts a time.

For example, you could have a form that creates a requests post, and in it a field that the user can fill with each of the fabrics URLs, or if this needs to be more sophisticated, a relationship, where the user will then pick available fabrics to connect to his request.

From there, the admin can then add the User ID to the very fabric posts (or the fabric post IDs to the user, depending on which way you choose)
This data will be saved in a custom field of either select or single input against either user or post and hence then allow you to display data only if the current user is equal to the ID allowed for a specific fabric post.

Please let me know if you need more help or examples, I suggest starting on a staging site so you can go back and forth between different solutions and approaches (different field types, forms and especially, where to store the data: user or post).
This will ultimately require your decision depending on what you need to do with that data.

It is generally simpler to query posts, so its always better to keep the data in the post, however sometimes (for example if you want to list users and display the posts that they are having access to) it may be simpler to store the data in the user instead.

#1473041

hi Beda, whoa, that's a lot to process.... sorry for the delay but I am currently home with a high fever and very low tolerance to monitor brightness.
Since, as you suggest, i cannot do this on a production site, if you agree I will proceed to copy the production website to a staging website and we can go from there. I need to do this one step at a time because it looks fairly complicated.
I will get back to you as soon as the website is up and running.

#1474485

Beda
Supporter

Languages: English (English ) Spanish (Español ) German (Deutsch )

Timezone: Asia/Ho_Chi_Minh (GMT+07:00)

Yes, I strongly suggest starting on a staging site.
Then, you can later just either use Module Manager to import the built structures to your client's site or migrate the whole site back.

I'll open a private reply so you can add access, once ready.

Get well soon!

#1477967

Beda
Supporter

Languages: English (English ) Spanish (Español ) German (Deutsch )

Timezone: Asia/Ho_Chi_Minh (GMT+07:00)

I can see the CPT "Tessuti" on the site you shared, with 1776 Posts in it.
I also see it has two taxonomies, Composizioni Tessuti and Famiglie Tessuti.
As well I see the field you mention in the Dettagli Tessuto group, Immagine.

I understand that everything of the CPT Tessuti (fields, taxonomy, etc) shall be seen on the front end when viewing such a post.
Unless that Immagine field

In order to be able to view the fabric image, the user has to send a specific request.
For each post, for each user.

That means we need to wrap the ShortCode which displays that Immagine in a HTML condition, there is no other way to hide fields in such dynamic "per user" base.
I see you build the Content Template for Tessuti in Scheda Tessuto, so that is where we need to conditionally display the Immagine.

I see right now you did add the field visible only to Admins and Editors and Clients role, no matter what

<!-- SE SEI EDITORE O AMMINISTRATORE VEDI NORMALMENTE L'IMMAGINE DEL TESSUTO -->
[toolset_access role="Administrator,Editor,Cliente" operator="allow"]
<a href="[types field='immagine' size='full' output="raw"][/types]"><img src="[types field='immagine' size='medium' url='true' resize='crop'][/types]"/></a><hr>
[/toolset_access]

Now you would like Clients to see this only if they requested (and got granted) the rights to see it.
Each client can request many images, and one image could be requested by many clients.

This means you need either a field in the User (to store the images or posts to which they have access to) or a field in the post, storing the clients which have access to this data.

This needs custom code that we cannot provide as such here, I think.

Now, before we move on to that part (which eventually involves custom code), I need to know:
1. once the client requested access, does someone need to grant them the access?
2. does that access as well need to be removed from specific users/images again later?
3. if someone needs to first approve the clients to see images, what should happen right after a client requests access? Something like a success message, or else?

#1478277

Hi Beda, here are the answers you need:

1. once the client requested access, does someone need to grant them the access?
Yes. The owner of the company has to examine the data provided and decide if he wants to grant access to the client.
2. does that access as well need to be removed from specific users/images again later? Yes, at the Owner's convenience.
3. if someone needs to first approve the clients to see images, what should happen right after a client requests access? Something like a success message, or else? It's not relevant, as the notification of the access is not going to be provided by WordPress user system, but by email, manually, by the owner. The client will then get to know his login data. I hope I providede all the info you needed in order to help me, if possible. Thank you again!

#1482425

Beda
Supporter

Languages: English (English ) Spanish (Español ) German (Deutsch )

Timezone: Asia/Ho_Chi_Minh (GMT+07:00)

I apologise for the delay, I was on my weekend.

I see that "The client will then get to know his login data."

This means they will be WordPress users after that.
But still, each user will only have access to specific posts images, not all, right?

1. So to create the request I would create a Post Type "Requests", make it a Child to the parent post Tessuti, so that many Child Requests can be added to each one Tessuti.
That post type should feature a title and an email (custom) field, it doesn't need anything else.

2. Then create a Toolset Form to add such new Request posts:
https://toolset.com/documentation/getting-started-with-toolset/publish-content-from-the-front-end/forms-for-creating-content/

3. Add the link to create new child posts to your Tesssuti Posts template.
For this, I suggest this approach https://toolset.com/documentation/post-relationships/selecting-parent-posts-using-forms-create-child-items/#creating-forms-when-a-parent-post-is-preselected

4. Now a visitor can submit a request when visiting the Tessuti post for that specific post. He will have to submit the email but the Tessuti post can be automatically saved for the request.

5. The admin now can handle the request and add a user (or let the user visit a Toolset form to create a user) for that email.

6. When granting access, we have several options, but I think the easiest is since the admin is going to manually approve access, to have a user Field in the User profile to store the Tessuti (post IDs) that user has access to.
Here we will need some custom code to evaluate the array of Post IDs that will be in that field (probably comma separated) against the current post.
What we can also do is - if they will have access to just ONE Tessuti A TIME, then we simply use a numeric field to add the ID of he post they have access to - and will need no custom code.

I suggest implementing things until #5, and then we check the stage of custom code to implement a small snippet to evaluate that field properly.
Unless of course, you spot something we need to change in above end-results, as conforming to your requirements.

#1482509

Hey Beda, thanks for your answer.
From the beginning I had already created a cpt RICHIESTA INFO (info request) that is child to Tessuti, because at first I thought that for my client it would be enough to know which client wanted to know more about a certain textile and then he would send the requested info via mail to the client. This CPT contains a little more than just the email field, as you had mentioned in your answer, because my client needs to have the most detailed infos in order to be able to identify who is requesting access and decide if he wants to grant it or not.
For some reason the %%PARENT_POST_TITLE%% placeholder doesn't provide the name of the textile that's been requested, in the notification email, tho. If you can tell me why and we solve this, I think I have completed steps up to n. 5 and we can proceed further.
Thanks again!

New threads created by Beda and linked to this one are listed below:

https://toolset.com/forums/topic/parent_post_title-not-working-in-email-send-by-form/

#1482513

Beda
Supporter

Languages: English (English ) Spanish (Español ) German (Deutsch )

Timezone: Asia/Ho_Chi_Minh (GMT+07:00)

Let's separate this to a bug report, then when it is clear how to solve, proceed here.
PARENT_POST_TITLE is reported to https://toolset.com/forums/topic/parent_post_title-not-working-in-email-send-by-form/

Let's once that is clear, continue here.

#1488219

Beda, I am still working on the notification problem ticket you opened for me, it's not yet resolved. Can this ticket stay open until I am done with the other one? Thanks

#1488237

Beda
Supporter

Languages: English (English ) Spanish (Español ) German (Deutsch )

Timezone: Asia/Ho_Chi_Minh (GMT+07:00)

It can, but on the other hand, that issue should not stop us from building the rest around it?

Anyway, please let me know when we are ready to proceed.
You might have to comment here in case the robot wants you to close the ticket, I can't stop that robot 😀 but you can by commenting, in case it needs to stay open longer.

I will then usually comment back, but that would just be to acknowledge that you are still waiting for further details.

#1488243

Hi Beda,
we can indeed proceed with this ticket. I was just following your suggestion in your previous comment "Let's separate this to a bug report, then when it is clear how to solve, proceed here." I thought you wanted to have that solved first.

#1488343

Beda
Supporter

Languages: English (English ) Spanish (Español ) German (Deutsch )

Timezone: Asia/Ho_Chi_Minh (GMT+07:00)

Right, back then I assumed we depend on this, but I do not think we do.

We can proceed here:

https://toolset.com/forums/topic/grant-revoke-access-to-image-visibility-based-on-user/#post-1482425

Since you already have some parts, you can complete the other steps.

Resuming:

1. Make sure RICHIESTA INFO is a Child to the parent post Tessuti, so that many Child RICHIESTA INFO can be added to each one Tessuti.
That post type should feature a title and an email (custom) field, it doesn't need anything else, but if you want to add more information that's fine.

2. Your current form to add RICHIESTA INFO would be the one Christian is investigating for the notification part, right?
Hence we have that, the form should create childs connected to the parent Tessuti.
You would generally insert the "Create child post link" of Toolset Form to a Tessuti post and pass the parent (tessuti) in the URL parameter. Then the Form will automatically assign the RICHIESTA INFO to the right tessuti.
See also steps below.

3. Add the link to create new child posts to your Tesssuti Posts template.
For this, I suggest this approach https://toolset.com/documentation/post-relationships/selecting-parent-posts-using-forms-create-child-items/#creating-forms-when-a-parent-post-is-preselected. If this is done already, you can skip.

4. Now a visitor can submit a request when visiting the Tessuti post for that specific post. He will have to submit the email but the Tessuti post can be automatically saved for the request.

5. The admin now can handle the request and add a user (or let the user visit a Toolset form to create a user) for that email.

Remains hence to do:

6. When granting access, we have several options, but I think the easiest is since the admin is going to manually approve access, to have a user Field in the User profile to store the Tessuti (post IDs) that user has access to.
Here we will need some custom code to evaluate the array of Post IDs that will be in that field (probably comma separated) against the current post.
What we can also do is - if they will have access to just ONE Tessuti A TIME, then we simply use a numeric field to add the ID of the post they have access to - and will need no custom code.

You would have to define the requirements here as described above, create that field and then decide if the Admin will enter the values manually there or if this should somehow happen automatically.
depending on that we will then create an HTML Logic to add view rights to the data requested based on the current logged in uses fields values (where we store the Post id's they have access to see more data)