Allowing access for posts with multiple categories

Hello,

Based on the five examples linked below, this seems to be a somewhat common use case among the community. The links are available for specific reference but the basic example is category restrictions will override group and post restrictions on a post due to the check to hide the post being whether any category exists in a list of categories the user cannot see.

I’ve hit a wall with the complex SQL query. The full query with standard WordPress tables below is where the restricted posts_where is called with the last AND NOT IN being when the restriction occurs.

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) INNER JOIN wp_postmeta AS mt1 ON ( wp_posts.ID = mt1.post_id ) WHERE 1=1 AND (
wp_term_relationships.term_taxonomy_id IN (89)
) AND (
wp_postmeta.meta_key = 'test_restriction_menu_order'
AND
mt1.meta_key = 'test_restriction_menu_order'
) AND wp_posts.post_type = 'product' AND (wp_posts.post_status = 'publish' OR wp_posts.post_author = 9999 AND wp_posts.post_status = 'private') AND wp_posts.ID IN ( SELECT ID FROM wp_posts WHERE ID NOT IN ( SELECT post_id FROM wp_postmeta WHERE wp_postmeta.meta_key = 'groups-groups_read_post' ) UNION ALL SELECT post_id AS ID FROM wp_postmeta WHERE wp_postmeta.meta_key = 'groups-groups_read_post' AND wp_postmeta.meta_value IN ('read','groups_read_post','test') ) AND wp_posts.ID NOT IN ( SELECT object_id FROM wp_term_relationships LEFT JOIN wp_term_taxonomy ON wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id WHERE term_id = 9991 ) GROUP BY wp_posts.ID ORDER BY wp_postmeta.meta_value+0 ASC LIMIT 0, 12

A possible solution could be to check whether the post belongs to any category the user has the capability to see. I haven’t been able to figure out what the query needs to be and have been trying alternatives in php. This probably isn’t the best course but something like this is what I’ve thought so far.

$terms = wc_get_product_terms( $post->ID, 'product_cat', array( ));
foreach($terms as $term) {
// if the user can read this term, the post should be visible in categories the user can view
if(user_can_read_term($user_id, $term->term_id)
//do something with appropriate hook I haven't found yet
}

I’m not sure if this should go into a hook in archive-product or hook into pre_get_posts somewhere with a meta query after the if statement. I doubt this is the right direction but I’m trying anything I can to solve it.

Is there any chance you could include the option for a post in multiple categories to be accessed if the user has at least one capability within all of that post’s categories? If not I would be grateful for any nudge you could provide in the right direction to solve this specific use case with the SQL query or a php filter. I can certainly appreciate the effort involved in making this possible.

As an aside, I’ve been using the standard Groups plugin for about six months now and it’s been an incredible utility that forms a significant backbone of our site. I really appreciate everyone who has contributed to this plugin and for permitting it to be open and accessible to all. It’s been the most intuitive, friendly, and oddly fun type of content restriction plugin out of the ones I’ve tried.

Thank you.

WooCommerce Product Category not restricted

Groups Restrict Categories

Restrict based on multiple group membership

Restrict Categories by “either/or” instead of “and”

Categories Problem


Comments

One response to “Allowing access for posts with multiple categories”

  1. Hi Lee,

    The best option would be to create a new plugin based on the Group Restrict Categories plugin and change the boolean value when the conditions are met. For example, a good place to start would be user_can_read_term function in class_group_restrict_categories.php.
    Even with the right query, btw your query didn’t give me any results, you will end up with a new plugin.

    Kind regards,
    George

Share