Skip Navigation

[Resolved] list users with access to a custom post type

This support ticket is created 7 years ago. There's a good chance that you are reading advice that it now obsolete.

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.

Sun Mon Tue Wed Thu Fri Sat
- 7:00 – 14:00 7:00 – 14:00 7:00 – 14:00 7:00 – 14:00 7:00 – 14:00 -
- 15:00 – 16:00 15:00 – 16:00 15:00 – 16:00 15:00 – 16:00 15:00 – 16:00 -

Supporter timezone: Europe/London (GMT+00:00)

This topic contains 18 replies, has 2 voices.

Last updated by Ido Angel 7 years ago.

Assisted by: Nigel.

Author
Posts
#585732

hey,
i'm trying to build a membership site with online video course.
i have done everything so far - all well.
i want to try and show in each course all user's who have registered to the course so far - aka - all users with the rolse assigned to this course.
i know i can create a view for each user role, but since i have many courses i was wondering if there's an option to create a view of all users and just filter it by role with access to the current post type (course). meaning - in the "linkedin course" i will have a list of user with access to the linkedin course, with "amazon" course i'll have a list of users with access to the amazon course etc.
also - is it an option to not show the actual user, only the number of users with access to the current cpt?
thanks!
ido

#585998

Nigel
Supporter

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

Timezone: Europe/London (GMT+00:00)

Hi Ido

If you make a View which queries users you must specify the role in the initial content selection.

But. You can then modify it using the wpv_filter_user_query hook (https://toolset.com/documentation/programmer-reference/views-filters/#wpv_filter_user_query) which works much the same way as the wpv_filter_query hook for posts that you may be familiar with.

A query that specifies the editor role, for example, would include an argument like this:

[role__in] => Array
        (
            [0] => editor
        )

Based on the current post you could work out the related role (I'm not sure quite how you have that set up) and modify the query argument for the role as required.

Then, if you don't want to list the actual users and you just want a count of them, in the Loop Output section use the [wpv-found-count] shortcode (https://toolset.com/documentation/user-guides/views-shortcodes/#wpv-found-count) inside the wpv-items-found section but not inside the wpv-loop tags.

#586264

thx nigel!

the [wpv-found-count] works great. i'm still unsure about the 1st question though.
i have assigned user privileges to a course via "post groups" but i guess i can't use this to filter users.
what i'm thinking if the course name is the exact same as the user role for the course, i could create a user list of all users and then apply a manual filter to show only users with the role name of the current course name.

how would i go about that?
thanks!

#586310

an idea!
maybe, since all courses are tied (by cred commerce) to a woocommerce product, i can display the billing names of customers who have purchased them?
would "views" know that the course is related to the woocommerce product because i tied them via cred?
ido

#586407

(update: the "orders" solution didn't work)

trying another approach:

1) i created a custom user field "hidden course".
2) i created a custom field for the course: "allowed user".
3) in the cred commerce form, i added this field as a hidden field with set value like this:

value='[types field='allowed-user' output='raw'][/types]'

this means the field will be always populated with the course's "allowed-user" field (which is filled manually every time a course is created and is the exact name of the user role with access to the specific course.

4) now i just need a view of all users, filtered by the "hidden course" custom field.

what should i put in this user view filter?
The field wpcf-hidden-course-name is a STRING EQUAL TO...??? URL Parameter? SHORTCODE attribute? constant?

I feel we're close... :))

cheers!
ido

#586724

Nigel
Supporter

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

Timezone: Europe/London (GMT+00:00)

Hi Ido

Sorry for the delay getting back to you after the weekend, the queue is very busy.

When a user buys a course you give them a user role whose name is the same as the name of the course, is that correct?

If that's the case then you could use the wpv_filter_user_query hook I described above, and where you set the role you can use the title of the current post (assuming you are displaying this View in a template for a single course) to set the role.

But I'm not sure how much sense that makes. What if a user buys more than one course? You can only assign a single role to them.

Is that the intention? That users will buy only a single course?

#586928

hey nigel,
no worries - i've been working on this myself.
update - there's no option with access to have a user register to 2 roles without the hassle of creating a "new user" form AND an "edit user" form - per each course.
so what i did was turn to woocommerce membership plugin. i had to do some tweaking (well, a lot of tweaking actually) - but now i'm good.
situation now is, all users are "customers", but i create a membership plan for each course, so a customer can purchase many courses, which is great.
i still want to add a view of "all customers who have purchased this course".
i'm still kinda lost here...
thx!

#587273

Nigel
Supporter

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

Timezone: Europe/London (GMT+00:00)

Hi Ido

I'm not familiar with how the membership plugin works, in terms of the post types and other data it sets up.

I'd be happy to take a look for you to see if it is something you can use a View to generate the count of bought courses, but I'd need a copy of your site to inspect.

Do you want to make a duplicate I can install locally for testing and then I'll see what I can do.

https://toolset.com/faq/provide-supporters-copy-site/

I'll mark your next reply as private so you can share login credentials and the location of the duplicator packages.

#587302

hey nigel,
thanks!
before you dive in, let's see if we can figure this out.
i'm feeling we're close...

basically what we have now is:

a woo product is a child of a course.
on the course page, i want to show users who have purchased the child product.

i tried using this tutorial:

https://toolset.com/learn/create-an-ecommerce-wordpress-site/displaying-more-information-from-woocommerce/how-to-display-customers-who-also-bought-the-product/

i thought of creating a view for a product listing the orders belonging to it (actually the users who have placed these orders), and then place this view inside the view/layout of the course, with product being child of the post with url parameter of the course.

the only problem is that apparently the "wpv_woo_product_belongs_to_this_order" function is missing from the conditional output. it's just not there, maybe deprecated?

oh and 1 other thing. i am trying to list "related courses" in the course page (according to mutual taxonomy). but since it's not really the course page (it's a layout in a page which is the dump page for restricted content. this layout shows a course "teaser" with "add to cart" button to purchase the course. works great), i can't use "don't include current page" and always get all courses with mutual taxonomy, including the current one i'm "viewing". when i tried filtering by url parameter (the layout page has the id of the course stored so it's easy), i saw that i can only filter this one sided - meaning, only INCLUDE posts according to it, and not EXCLUDE.

i can exclude by post id by url parameter, but it somehow doesn't work, because the url parameter has to be of a parent course (as this teaser page is a child of a course).

thanks for all the help!
ido

#587522

Nigel
Supporter

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

Timezone: Europe/London (GMT+00:00)

Hi Ido

You have me at something of an advantage when thinking about this in that you can see when using the membership plugin the different post types and how they are connected.

Regarding the specific issues in your last post, looking at the source code for the WooCommerce Views plugin I see that the function wpv_woo_product_belongs_to_this_order is still registered.

If you want to use it in a conditional, don't forget that you need to register it on the page Toolset > Settings > Front-end Content in the section "Functions inside conditional evaluations", otherwise it will not work.

I think I understand your next issue.

The "don't include the current page" setting uses the wrong ID, but you have the required ID available as a URL parameter, right?

You could use the wpv_filter_query filter and manually modify the post__not_in argument, replacing it with the required ID that you can get from the $_GET object.

I suggest you add the following code to get started, editing the View ID as required (50 in this sample):

function invert_taxonomy_filter( $query_args, $view_settings, $view_id ){

	if ( 50 == $view_id ) {
		error_log(print_r($_GET, true));
		error_log(print_r($query_args, true));

		// add code to get the required url param from $_GET
		// e.g. $target_id = $_GET['my_param'];

		// add code to update the post__not_in argument with this id
		// e.g. $query_args['post__not_in'] = array( $target_id );
	}

	return $query_args;
}
add_filter( 'wpv_filter_query', 'invert_taxonomy_filter', 101, 3);

This will dump $_GET and $query_args to your debug log file so you can confirm the required formats and update the code accordingly.

#587620

hey nigel,
thanks for all the efforts 🙂

still not working, both issues.
let's start with related posts.

it's a bit complicated, but here goes:

we have a course. the course is restricted until someone buys a product which is a child of the course.
until purchasing the product, when a user presses the course link, he is redirected to a single page on the site, called "restricted content". the page is a single page, but its url parameter changes according to the link directing to it, e.g - the course. for example, if i'm trying to reach course with id 294, the page url will be:

hidden link

if i'm trying to to reach course with id 595, the url will change to:

hidden link

what i did was have this page present a layout, and inside the layout i entered views of elements from a child of "courses", called "course teasers".
the views for each element know how to show the right course teaser each time, because i've set the filter to show child of post with url parameter "r", e.g: eg. hidden link - or in my case, hidden link.

this is great for custom fields of the course teaser. so far so good.

the issue with "related courses" is that i can't show courses, as they are restricted. i can only show "related course teasers".
but this brings another issue, because the only way to know which course-teaser is presented is by the url parameter of the parent course, e.g: hidden link

so theoretically i summon into the loop the current "course-teaser". but this will only show me the current course-teaser, not the related course-teasers.
and when i try to show "related course teasers by taxonomy", the taxonomy filter has no way to know that the current page (with course id in the url) is the parent of the desired course teaser:

"set by the page where this is shown" get's nothing, because the page is a course, not a course-teaser, and the course teaser is the one with the taxonomy.
same for "set by the current post in the loop" and "parent taxonomy view", "url parameter" etc.

when i tried to add the taxonomy to the COURSE instead of the teaser - i didn't get the taxonomy filter to show at all in the course teaser view (again, i can't show courses, they are restricted).

when i try to filter by post ID, it still doesn't work. your question was:

"The "don't include the current page" setting uses the wrong ID, but you have the required ID available as a URL parameter, right?"

but the answer is "no" 🙂 - it get's the PARENT post ID, and the parent filter let's me only include the current post, but exclude.

This means i can't even get to the point i'm actually displaying ONLY teasers with the right taxonomy, because it can't be determined by anything, let alone exclude the current course teaser.

I even tried binding the view output by condition:

[wpv-conditional if="( '[wpv-taxonomy-slug]' eq 'wpvrelatedcourseidentifier' )"], but that didn't work either for some reason. maybe i'm doing it wrong?

So - damn 🙂

---- BREATH ----

regarding the original USERS issue:

same bug, i guess.
i created a view for orders and have applied the condition with custom function "wpv_woo_product_belongs_to_this_order" (after registering it like you suggested). i also filtered it with "wc_complete".
then i created a product view, and i inserted the previous "orders" view into it. i filtered this view according to the parent url parameter, as it's inserted into the layout of the "restricted" page. this works well with another product view, which is the one i'm using to produce an "add to cart" shortcode for the course (here i created a product view, filtered it by url parameter of the parent, and in the layout section i added the short code [add_to_cart id="[wpv-post-id]"] - works perfectly).
but for some reason, i'm getting nothing, "no orders found". even if i remove all conditions - nothing. and the orders are there, with billing names and everything.
maybe i need to be able to show them as public somewhere?

---- BREATH ----

i'm sorry for this novel of a comment... really appreciate your attention and help.
if you wanna, you can check the site yourself now 🙂

thanks!
Ido

#587763

Nigel
Supporter

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

Timezone: Europe/London (GMT+00:00)

Hi Ido

Gosh. I read through that, though, tbh, it's the end of the day and solutions aren't leaping to the fore.

It will be easier if I can try testing some things out myself, so let me make a copy of the site locally.

You can either create the duplicator packages yourself and share a link to them, or just give me access to your site and I can create them myself.

I'll get on it in the morning when my brain is a little fresher.

#588107

Nigel
Supporter

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

Timezone: Europe/London (GMT+00:00)

Hi Ido

This is trickier than I expected because, although I have the site language switched to English, the content, including names of post types, taxonomies etc. are all in Hebrew.

But... Let's start with the related courses View.

You have a taxonomy for related courses, e.g. marketing.

You want to display related course teasers so you can use the taxonomy query filter, the problem being that "set by the current post in the loop" doesn't work because the current post isn't a course teaser.

So nest Views.

Make an outer View which gets the course teaser based on the URL attribute. Then in the Loop Output section of this View insert your related courses View, which now has the correct context for the "set by the current post in the loop" filter to work.

Is that a viable option?

#588121

hey nigel,
i've tried this before and this works great - but solves only half the issue, as it still doesn't exclude the current teaser from the display...
SO!!!! what i did was this:

1. in the inner view, i added a class to each course teaser with the id of the parent course, like this:

<div class="onecourse id-[wpv-post-id id='$course']">

2. in the outer view (the one in which the inner view is nested), i've added this code inside the loop itself:

      <style>
        .id-[wpv-post-id id="$course"] {display: none;}
      </style>

since we're displaying this view according to url parameter, this means ONLY THE TEASER WITH CURRENT CLASS will be hidden.

and... it works!!!!!!!!

---- PARTY -----

now... users? 🙂

#588303

Nigel
Supporter

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

Timezone: Europe/London (GMT+00:00)

Hey Ido

That's great.

My follow-up was going to be that if that worked you could then try wpv-filter-query to exclude the current teaser, but your solution is nice and simple.

Regarding the Users, you have a fundamental problem here.

WooCommerce registers the Order post type with publicly_queryable = false and exclude_from_search = true, meaning that any standard WP post query (such as made by a View) won't find any orders.

It is a long-standing complaint about WC.

Looking at the source code that registers the post type they include a filter 'woocommerce_register_post_type_shop_order' where you can modify the arguments.

I just tried changing that so that orders can be queried, but it didn't work. (Even editing the plugin file—woocommerce/includes/class-wc-post-types.php—directly didn't fix it. I don't recommend that, but that's where to look if you want to understand what's involved.)

So, unless you manage to get that to work, you'll need a different solution that doesn't rely on querying orders.