Skip Navigation

[Resolved] Filter by many fields in the Views API

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

Problem:
How can we add Fields filters to a given View using the API code?

Solution:
It's subject to custom code, however here there is a elaborated explanation on how you'd approach this:
https://toolset.com/forums/topic/alter-view-query-for-custom-fields-with-views-api-filters/#post-1203704

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

This support ticket is created 6 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
- - 14:00 – 20:00 14:00 – 20:00 14:00 – 20:00 14:00 – 20:00 14:00 – 20:00
- - - - - - -

Supporter timezone: Asia/Ho_Chi_Minh (GMT+07:00)

This topic contains 5 replies, has 2 voices.

Last updated by morganC-2 5 years, 11 months ago.

Assisted by: Beda.

Author
Posts
#1202997

Okay, lol I made it SOOO far with this route without asking for help again but I got stuck. It was coming along beautifully.

I logged in to that site and checked it out, I think the only way it seems to work is if you know the recipients the CC & BCC ends up working, but to do it by a user ID from a generic field doesn't appear to work out. So I am happy to stick with multiple recipient fields if I get past a couple hurdles.

There were a few other elements to this where I had to make additional fields for each recipient, so 10 recipients = 10 extra fields across the board, no big deal, I got that semi-working, to something I know I can elaborate on.

Then I realized after all that, when it comes to the Views, showing a listing of all messages, that I cannot use query filters in the search & pagination area along with the query required in the top query section.

Specifically, because I cannot use the appropriate AND / OR configuration with the recipients and the custom field types filters matching a URL param (ie 'buildingname' )

So I need to show all results if X =( ( recipient1 or recipient2 or recipient3 or recipient 4.... ) AND ( buildingname LIKE urlparam ) )

But with the GUI I can only query like:

(recipient1 = x) OR (recipient2 = x) OR (recipient3 = x) OR (recipient4 = x) OR (buildingname LIKE urlparam )

If I omit the recipients in the query, the filters work beautifully, so I thought of showing only matching posts using conditional output but this was too slow and causing the website to timeout. Too heavy on the database I assume.

Bottom line is I can continue with this if I can inject a few other conditions to the query.

I have combed your documentation and forum and the best idea that seems to work is if I create a custom query in the functions.php

I have pieced together one that successfully limits the query to only show the author's own posts and figured it would adaptable to change 'author' to the 10 recipient fields.

Example with author:

add_filter( 'wpv_filter_query', 'prefix_show_only_current_author' );
function prefix_show_only_current_author( $query_args ) {
 if( $view_id == 1234 ) {
     global $current_user;
     $testuser = '240';
    $types = (array) $query_args['post_type'];
    print_r($query_args);
    if ( !is_admin() && in_array( 'quotes', $types ) ) {
        $query_args['author'] = empty( $current_user->ID ) ? -1 : $testuser;
    }
    return $query_args;
}
}

My failed attempts: ( Syntax obviously wrong I am not a coder, but hopefully you get what I am after )


add_filter( 'wpv_filter_query', 'prefix_show_only_current_author' );
function prefix_show_only_current_author( $query_args ) {
 if( $view_id == 1234 ) {
     global $current_user;
     $testuser1 = '240'; //will make these dynamic later once these fields match
     $testuser2 = '241';
     $testuser3 = '242';
    $types = (array) $query_args['post_type'];
    print_r($query_args);
    if ( !is_admin() && in_array( 'quotes', $types ) ) {
        $query_args['wpcf-recipient1'] = empty( $current_user->ID ) ? -1 : $testuser1;
        $query_args['wpcf-recipient2'] = empty( $current_user->ID ) ? -1 : $testuser2;
        $query_args['wpcf-recipient3'] = empty( $current_user->ID ) ? -1 : $testuser3;
    }
    return $query_args;
}
}

I feel like I am close but have been spinning my wheels for days and would greatly appreciate any guidance.
Thank you

#1203003

I am almost sure to understand but need to clarify:

1. You have a Post Type with some fields (wpcf-recipient1, wpcf-recipient2, wpcf-recipient3)
2. You want the View to only show posts where those above fields are equal to some hardcoded value as an Email/Username

Is this correct?
In this case, you can just set up a Query Filter and filter those out that you do not want to appear.

If the input, however, should be dynamic you need a way to determine the values first.
How do you plan to determine those values first?
This is only possible if you'd have a query that gets some values from somewhere (maybe a view or code, but it needs the data to be present somewhere first).

#1203369
toolset-capture1.jpg

Thanks for responding, forgive my ignorance if I am misunderstanding but I think we're either reading too far into it or not far enough. From what I read, I think your theory would work but only if were queried the other way around

Simple example:
You could query :
if custom-fieldname = current USER ID
but you can't query:
if current USER ID = custom-fieldname

If you could reverse it like that, this could all work out and I could check if user id is within an array, or a few other options to pull this off. Since you have to start the query with a field first, I don't think this is possible.

I do have the values of wpcf-recipient1,2,3, etc saved in each post (similar to Classifieds Messages, with a new post type field

In the query filters, I am already using AND as a field relationship with other query filters (see attached)

If I add wpcf-recipient1,2,3 etc as a filter it returns 0 results because:

It is searching my existing filters AND

if wpcf-recipient1 = whatever
and
if wpcf-recipient2 = whatever
and
if wpcf-recipient3 = whatever

This doesn't work because the 1 recipient to display will either be in wpcf-recipient1,wpcf-recipient2,wpcf-recipient3

So the query checks if logged-in-user-id matches wpcf-recipient1,wpcf-recipient2,wpcf-recipient3 and the only way for this to work is if I use "OR" as a field relationship.. however this then omits the other query filters I have. I can't seem to do both at the same time

The conditions would be to match any, all, or none of my query filters in the attached image, and also check if the signed in user id matches 1 of those fields

The query filter section would let me check if wpcf-recipient1 is in an array , but I would need the opposite of this

something like if user-id is in wpcf-recipient1,wpcf-recipient2,wpcf-recipient3

So I really don't think I can use the query filters inside the view to execute this and would have to append some query args to the view since it seems to be the other way around

There is a hidden recipient field for each of the 10 recipients I need in the post form. So when this posts, in theory the data should already be there as wpcf-recipient1,2,3. The form has generic fields and cred fields with shortcodes that fill the appropriate recipient to each field.

From what I understand, the data should be there, so I was thinking if I can get it working with 3 hard-coded recipients like in the code above, that it would be adaptable to replace '240' with wpcf-recipient1

ie)
$testuser1 = '240';

would be

$testuser1 = $query_args['wpcf-recipient1'];

or something like that

I hope that makes sense now?

#1203704

I think this should be possible with HTML conditions.
You could simply query by what you can do with AND and then hide with HTML conditions what you can not have in the query.

Or, change the first query to not be a field but a term (so you can use OR within the Field query, but AND to the first query).

Now, if you want to use the code (PHP), from https://toolset.com/documentation/programmer-reference/views-filters/#wpv_filter_query, to check for several users, you can do it by analysing the $query_args of the View.
In case of 2 Field Filters you will see that is a meta query of 2 nested arrays:

'meta_query' => 
    array (size=3)
      0 => 
        array (size=4)
          'key' => string 'wpcf-field-one' (length=13)
          'value' => string '' (length=0)
          'type' => string 'CHAR' (length=4)
          'compare' => string '=' (length=1)
      1 => 
        array (size=4)
          'key' => string 'wpcf-field-two' (length=9)
          'value' => string '' (length=0)
          'type' => string 'CHAR' (length=4)
          'compare' => string '=' (length=1)
      'relation' => string 'AND' (length=3)

So you can customize this and apply it to the filter.
Since this is custom code we do not craft ready to go code but only explain the API and give an example such as it's done on the DOC already.

This is an example altering the Fields query:

//Return only posts from the current author when listing posts of type company:
add_filter( 'wpv_filter_query', 'prefix_show_only_current_author' );
function prefix_show_only_current_author( $query_args ) {

//Assuming an eistent Meta Filter in the Views GUI which will have ['meta_query']['0']:
$query_args['meta_query']['1'] = array( 
  'key' =>  'wpcf-one', 
  'value' =>  'value', 
  'type' =>  'CHAR', 
  'compare' =>  '=',
);
$query_args['meta_query']['2'] = array( 
  'key' =>  'wpcf-two', 
  'value' =>  'value', 
  'type' =>  'CHAR', 
  'compare' =>  '=',
);

//Assuming you want overwrite all meta filter:
$query_args['meta_query'] = array(
	'relation' => 'AND',
	array(
		'key' =>  'wpcf-field-one', 
		'value' =>  'value', 
		'type' =>  'CHAR', 
		'compare' =>  '=',
	),
	array(
		'key' =>  'wpcf-field-two', 
		'value' =>  'value', 
		'type' =>  'CHAR', 
		'compare' =>  '=',
		),
);

//In any case return the query args
return $query_args;
}

Hope that helps!

#1219393

Sorry for the long delay in response, but yes that helps perfectly! Tried HTML Conditions and felt it was just way too slow but a few modifications to your example got us back in business. Thank you very much you are the Hero of the month!

#1219397

My issue is resolved now. Thank you! Finally completed my first project with Toolset and will continue to recommend it to my clients and peers