Sauter la navigation

[Résolu] OR Condition in Views Filter

Ce fil est résolu. Voici une description du problème et la solution proposée.

Problem: I would like to use Views to display posts by the current logged-in User, as well as some system-generated posts that everyone should see. I tried a post author filter with a taxonomy filter, but they are combined using "AND" instead of "OR".

Solution: Create a System User that will be the author of those system posts. Create a View that is filtered by author, and apply this custom code snippet:

add_filter( 'wpv_filter_query', 'views_viewable_by', 101,3);
function views_viewable_by( $query_args, $view_settings, $view_id ) {
  global $current_user;
  
  // Super-user can see everything!
  if ( $current_user->ID == 1 ) { return $query_args; } 
    
  // Don't apply to specific Views
  if ( $view_id == 82 // View of Assets CPT
      ) { return $query_args; } 
    
  $query_args['author__in'] = array( 1, $current_user->ID );
  $query_args['author'] = null;
    
  return $query_args;
}

Relevant Documentation:
https://toolset.com/documentation/programmer-reference/views-filters/#wpv_filter_query

0% of people find this useful.

This support ticket is created Il y a 5 années et 9 mois. 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
8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 - -
13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 - -

Supporter timezone: America/New_York (GMT-04:00)

Marqué : 

Ce sujet contient 8 réponses, a 3 voix.

Dernière mise à jour par alexG-4 Il y a 5 années et 9 mois.

Assisté par: Christian Cox.

Auteur
Publications
#1211615

I'm creating a membership site where users will be creating and managing their own data in a database structure which I am defining.

So I'll be using Filters on Views so they only see the records created by the logged-in user. That works fine.

However, I want to make some "system" records available in read-only form to all users. My idea is to "tag" those records in a taxonomy and then ensure users can't edit/delete those records.

My problem is how to display them.

I tried creating two filters - one for "Display Records created by logged-in user" and another for "Tagged as Read-Only" but Views treats these as AND conditions: both must be true to display the record.

I want them to be OR conditions: if either is true, the record gets displayed.

Is there a way round this - perhaps using an approach I've not thought of?

Thanks.

#1212615

I don't think there is a way to do this type of "OR" query in WordPress. I can think of a few other options here:
1. Create a User specifically to be the author of System posts. When filtering by post author ID, use a shortcode attribute so you can add a comma-separated list of author IDs to the View shortcode. Manually set the System author's ID, and use another shortcode to set the current User's ID.
2. Create two Views using the "List with Separators" option in the Loop Wizard. Use the first View to produce a comma-separated list of results filtered by post author. Use the second View to produce a comma-separated list of results filtered by the taxonomy term that represents system posts. Create a third View filtered by post ID, set by a shortcode attribute. Use the two other Views in the shortcode attribute to set the post ID filter using the results of the two other Views.
3. Make a Member's own posts private, but do not make Systems posts private. No Member will be able to see any other Member's posts, except for those created by the System.

#1212666

Suggestion #3 is a brilliantly simple solution.

Proves it's always worth asking how to solve a problem that may seem imposible!

Thanks so much Christian.

My issue is resolved now!

#1212803

Hi Christian

I've now implemented your suggestion, and it all works fine - except Views is not showing the Private posts to the author of those posts. I can't believe this is a bug in Views - but I can't see where my setup is wrong,

Here's a video showing how I've set things up and demonstrating this issue:

lien caché

And here's a follow-up video with additional evidence that my set up is (seems to be!) correct:

lien caché

Thanks

Alex

#1212870

On a follow-up related note - I have definitely determined that Private posts do not appear in the Lookup values of a relationship - even for a logged-in Admin user who created the posts.

#1213194

Nigel
Supporter

Les langues: Anglais (English ) Espagnol (Español )

Fuseau horaire: Europe/London (GMT+00:00)

Hi Alex

Christian is sick, let me step in here.

For a View to display private posts you need to add a Query Filter for post_status and specify that private posts should be included.

Private posts would then be included, regardless of who is looking, even if a guest user were visiting the page where the View is inserted.

I'm not sure how this helps with the question you originally asked, i.e. how to include posts authored by the current user or posts which are "system" posts.

I think if you take Christian's suggestion to make some specific user the author of the system posts then you can get this to work with a little custom code using the wpv_filter_query hook.

Say I am user with id=88, and the author of the systems posts is user id=1.

If I understand the requirement, you would then want to display a list of posts authored by id=1 or id=88.

If you inspect the $view_args available with the wpv_filter_query filter you should see that it has

$view_args['author'] == 88

To set multiple authors you need to set them using the author__in parameter instead (https://developer.wordpress.org/reference/classes/wp_query/#author-parameters).

So you would do something like:

$view_args['author__in'] = array( 1, $view_args['author'] );
$view_args['author'] = null;

Here's the documentation for the filter: https://toolset.com/documentation/programmer-reference/views-filters/#wpv_filter_query

#1213357

Hi Nigel

Thanks for picking this up.

You're right - the Private Post method isn't going to work, for the reasons you mentioned.

So I've worked on applying the method you expanded on. This is the code that gives me the right results:

add_filter( 'wpv_filter_query', 'views_viewable_by', 101,3);
function views_viewable_by( $query_args, $view_settings, $view_id ) {
  global $current_user;

  // Super-user can see everything!
  if ( $current_user->ID == 1 ) { return $query_args; } 
  
  // Don't apply to specific Views
  if ( $view_id == 82 // View of Assets CPT
      ) { return $query_args; } 
  
  $view_settings['author__in'] = array( 1, $current_user->ID );
  $view_settings['author'] = null;
  
  return $view_settings;
}

I used a bit of trial-and-error, so I'm not sure whether I just got lucky but may hit problems later.

Specifically:

A) I'm using $current_user->ID rather than $view_args['author'] (or $view_settings['author'] in my case) - which didn't work.
and
B) I'm returning $view_settings rather than $query_args, which is what the documentation says - but again didn't work.

Should I be OK with that moving forward? And am I right in thinking that the reason my code works is because both $view_settings and $query_args are in a suitable format for use by the WP_Query class? Or am I off the mark?

#1213818

Hi I think there's some confusion because of how Nigel's parameter values were named "view_args" instead of "query_args". You should return $query_args, the first parameter, including any necessary adjustments there.

add_filter( 'wpv_filter_query', 'views_viewable_by', 101,3);
function views_viewable_by( $query_args, $view_settings, $view_id ) {
  global $current_user;
 
  // Super-user can see everything!
  if ( $current_user->ID == 1 ) { return $query_args; } 
   
  // Don't apply to specific Views
  if ( $view_id == 82 // View of Assets CPT
      ) { return $query_args; } 
   
  $query_args['author__in'] = array( 1, $current_user->ID );
  $query_args['author'] = null;
   
  return $query_args;
}
#1213934

Thanks for that clarification, Christian. It all works fine, and my issue is resolved now. Thank you!