Skip Navigation

[Resolved] Views sorted by 2 custom fields

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

Problem:

The issue here is that the user wanted to sort her view by multiple custom fields.

Solution:

This can be done by using the custom hook below.

add_filter('wpv_filter_query', 'add_custom_fields_to_view_query', 99, 3);
function add_custom_fields_to_view_query($query_args, $view_settings, $view_id ) {
        if ( $view_id == 16257 ){
         
  
       $meta_query = array();
       $meta_query[] = array('key' => 'acf_directory_sort_order');
       $meta_query[] = array('key' => 'acf_shipping_city');
       if ( !isset($query_args['meta_query']) ){
            $query_args['meta_query'] = array();
       }
       $query_args['meta_query'] = array_merge($meta_query, $query_args['meta_query']);
       add_filter('posts_orderby', 'custom_order');
   }
  
   return $query_args;
}
function custom_order($orderby) {
   global $wpdb;
   return $wpdb->postmeta.'.meta_value ASC, mt1.meta_value ASC';
}

Where you simply need to chance the names of the custom fields in the code that you want to sort by.

This support ticket is created 6 years, 9 months 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
- 9:00 – 12:00 9:00 – 12:00 9:00 – 12:00 9:00 – 12:00 9:00 – 12:00 -
- 13:00 – 18:00 13:00 – 18:00 13:00 – 18:00 14:00 – 18:00 13:00 – 18:00 -

Supporter timezone: America/Jamaica (GMT-05:00)

Tagged: 

This topic contains 25 replies, has 2 voices.

Last updated by Pat 6 years, 9 months ago.

Assisted by: Shane.

Author
Posts
#619610

Pat

Hello,

I'm trying to create a Views and need to use 2 custom fields for the sorting (1 primary and 1 secondary)
I have seen that we have a possibility to define a secondary sorting field, but it is only based on the standard post parameter (date, title ...).
Is there a way to use here another custom field or do we need to make a nested Views ?

Regards
Pat

#619693

Pat

Hello,

Just some complementory informaiton :

My custom fields apply to product and are like this :

Day : Monday, Tuesday, Wednesday ...
Hour : 6, 7, 8, 9, 10 ...
Minuts : 00, 15, 30, 45

Now, I want to list all events thanks to :
1. Days
2. Hours
3. Minuts

Let me know how this could be achieved
Regards
Pat

#619729

Shane
Supporter

Languages: English (English )

Timezone: America/Jamaica (GMT-05:00)

Hi Pat,

Thank you for contacting our support forum.

Unfortunately no its not possible to perform a secondary sorting through the use of custom fields.

Any secondary sorting with custom fields will need to be done using a custom hook to achieve.

Please let me know if this helps.
Thanks,
Shane

#619732

Pat

Hi Shane,

In the meantime, I discovered that the nested Views worked only for parent or taxonomies, which is not the case here !
What kind of hook do I need to create for this?

Regards
Pat

#619827

Shane
Supporter

Languages: English (English )

Timezone: America/Jamaica (GMT-05:00)

Hi Pat,

Thank you for contacting our support forum.

Take a look at the link below from the ACF forum.
hidden link

This should be able to assist you.
Also it can be combined with our view hook below to pass the sort options into the view.
https://toolset.com/documentation/programmer-reference/views-filters/#wpv_filter_query

If you're unsure how to proceed with this please let me know and i'll be more than happy to assist.

Thanks,
Shane

#620102

Pat

Hi Shane,

I started using the wpv_filter_query
Can you help defining the arguments :

array $query_args Τhe query arguments as in WP_Query => sound OK
array $view_settings The View settings => how can I use this parameter (is it something that comes from Views in order to give all settings or is it something we can use to specify some settings to Views, and what is the format to use?)
int $view_id The View ID => Can I use the Views ID in my function to restrict the wpv_filter_query only to specific Views?

Regards
Pat

#620284

Shane
Supporter

Languages: English (English )

Timezone: America/Jamaica (GMT-05:00)

Hi Pat,

Yes you can specify the view ID.

Take at the example below.

add_filter( 'wpv_filter_query', 'sort_view', 99, 3 );
function sort_view( $args, $view_settings, $view_id) {
   
    if ( $view_id == 4114 ) {
        // Query Arguments
$args = array( 
	'post_type'       => 'review',
	'posts_per_page'  => 10,
	'paged'           => get_query_var( 'paged', false ),
	'meta_query'      => array(
		'relation'    => 'AND',
		'be_top_pick' => array(
			'key'     => 'be_top_pick',
			'compare' => 'EXISTS',
		),
		'be_price'    => array(
			'key'     => 'be_price',
			'type'    => 'NUMERIC',
			'compare' => 'EXISTS',
		),
		'be_rating'   => array(
			'key'     => 'be_rating',
			'type'    => 'NUMERIC',
			'compare' => 'EXISTS',
		),
	)
);
// Sort Results
$current_sort = isset( $_GET['hosting-sort'] ) ? esc_attr( $_GET['hosting-sort'] ) : 'most-recent';	
switch( $current_sort ) {
	case 'most-recent':
		$args['orderby']  = array( 
			'be_top_pick' => 'DESC',
			'post_date'   => 'DESC',
		);
		break;
		
	case 'price-high':
		$args['orderby'] = array(
			'be_top_pick' => 'DESC',
			'be_price'    => 'DESC',
		);
		break;
		
	case 'price-low':
		$args['orderby'] = array(
			'be_top_pick' => 'DESC',
			'be_price'    => 'ASC',
		);
		break;
		
	case 'rating-high':
		$args['orderby'] = array(
			'be_top_pick' => 'DESC',
			'be_rating'   => 'DESC',
		);
		break;
		
	case 'rating-low':
		$args['orderby'] = array(
			'be_top_pick' => 'DESC',
			'be_rating'   => 'ASC',
		);
		break;
}
    }
    return $query_args;
}

I got this code from the link below. I'm not sure 100% that it will work but some adoption would be needed for your case.

Please let me know if this helps.
Thanks,
Shane

#620333

Pat

Hi Shane,

Thanks for your answer
I'm OK for making the adoptions, no problem.
My last question concerns the Views combined with this function.
What if I already placed some conditions (sorting, displaying ...) inside the Views. Does that mean Views parameters will be kept until I place a new condition inside the function (let say here for example 'posts_per_page' => 10), or do I need to rebuild completely all Views parameter inside the function ?

Regards
Pat

#620356

Pat

Hi Shane,

I tried to modify the function with my own parameters but did not succeed to make it work. Here is the code :

add_filter( 'wpv_filter_query', 'sort_view', 99, 3 );
function sort_view( $query_args, $view_settings, $view_id) {
// Views ID
if ( $view_id == 98 ) {
// Query Arguments
$args = array(
'post_type' => 'product',
'key' => 'wpcf-jour-cours',

'meta_query' => array(
'relation' => 'AND',
'jour_clause' => array(
'key' => 'wpcf-jour-cours',
'compare' => 'EXISTS',
),
'heure_clause' => array(
'key' => 'wpcf-heure-debut-cours',
'compare' => 'EXISTS',
),
'minute_clause' => array(
'key' => 'wpcf-minute-debut-cours',
'compare' => 'EXISTS',
),

),

array(
'key' => 'wpcf-type-de-produit',
'value' => 'Cours',
'compare' => 'LIKE',
)
);

// Sort results
$args['orderby'] = array(
'jour_clause' => 'ASC',
'heure_clause' => 'ASC',
'minute_clause' => 'ASC'

);
}
return $query_args;
}

If I look at the debug, only the sorting parameter integrated inside the Views is taken into account (wpcf-jour-cours). All other parameters are not seen (wpcf-heure-debut-cours and wpcf-minute-debut-cours). The display is fine in terms of posts and HTML, but not in terms of sorting.

Can you any mistake I could have done ?

Regards
Pat

#620571

Shane
Supporter

Languages: English (English )

Timezone: America/Jamaica (GMT-05:00)

Hi Pat,

If you add 'posts_per_page' => 10, to the function then this will take priority.

I see the issue with your code. You should be returning the variable $args instead of $query_args. I would recommend replacing all the $query_args with $args .

Please let me know if this helps.
Thanks,
Shane

#620646

Pat

Hi Shane,

I tried the 'posts_per_page' => 10 and it's working fine.

On the other hand, I'm stuck on the sorting. Only the sorting defined in the Views is working. The function does not change anything !
Here's what I'm getting in the Toolset debug :

Filter arguments before the query using wpv_filter_query
wpv_filter_query
Array
(
[post_type] => product
[meta_query] => Array
(
[relation] => AND
[jour_clause] => Array
(
[key] => wpcf-jour-cours
[compare] => EXISTS
)

[heure_clause] => Array
(
[key] => wpcf-heure-debut-cours
[compare] => EXISTS
)

[minute_clause] => Array
(
[key] => wpcf-minute-debut-cours
[compare] => EXISTS
)

)

[0] => Array
(
[key] => wpcf-type-de-produit
[value] => Cours
[compare] => LIKE
)

[orderby] => meta_value
[meta_key] => wpcf-jour-cours => Sorting defined in the Views
[order] => ASC
)

Filter the returned query using wpv_filter_query_post_process
wpv_filter_query_post_process
WP_Query Object
(
[query] => Array
(
[post_type] => product
[meta_query] => Array
(
[relation] => AND
[jour_clause] => Array
(
[key] => wpcf-jour-cours
[compare] => EXISTS
)

[heure_clause] => Array
(
[key] => wpcf-heure-debut-cours
[compare] => EXISTS
)

[minute_clause] => Array
(
[key] => wpcf-minute-debut-cours
[compare] => EXISTS
)

)

[0] => Array
(
[key] => wpcf-type-de-produit
[value] => Cours
[compare] => LIKE
)

[orderby] => meta_value
[meta_key] => wpcf-jour-cours
[order] => ASC
)

[query_vars] => Array
(
[post_type] => product
[meta_query] => Array
(
[relation] => AND
[jour_clause] => Array
(
[key] => wpcf-jour-cours
[compare] => EXISTS
)

[heure_clause] => Array
(
[key] => wpcf-heure-debut-cours
[compare] => EXISTS
)

[minute_clause] => Array
(
[key] => wpcf-minute-debut-cours
[compare] => EXISTS
)

)

[0] => Array
(
[key] => wpcf-type-de-produit
[value] => Cours
[compare] => LIKE
)

[orderby] => meta_value
[meta_key] => wpcf-jour-cours
[order] => ASC
[error] =>
[m] =>
[p] => 0
[post_parent] =>
[subpost] =>
[subpost_id] =>
[attachment] =>
[attachment_id] => 0
[name] =>
[static] =>
[pagename] =>
[page_id] => 0
[second] =>
[minute] =>
[hour] =>
[day] => 0
[monthnum] => 0
[year] => 0
[w] => 0
[category_name] =>
[tag] =>
[cat] =>
[tag_id] =>
[author] =>
[author_name] =>
[feed] =>
[tb] =>
[paged] => 0
[meta_value] =>
[preview] =>
[s] =>
[sentence] =>
[title] =>
[fields] =>
[menu_order] =>
[embed] =>
[category__in] => Array
(
)

[category__not_in] => Array
(
)

[category__and] => Array
(
)

[post__in] => Array
(
)

[post__not_in] => Array
(
)

[post_name__in] => Array
(
)

[tag__in] => Array
(
)

[tag__not_in] => Array
(
)

[tag__and] => Array
(
)

[tag_slug__in] => Array
(
)

[tag_slug__and] => Array
(
)

[post_parent__in] => Array
(
)

[post_parent__not_in] => Array
(
)

[author__in] => Array
(
)

[author__not_in] => Array
(
)

[ignore_sticky_posts] =>
[suppress_filters] =>
[cache_results] => 1
[update_post_term_cache] => 1
[lazy_load_term_meta] => 1
[update_post_meta_cache] => 1
[posts_per_page] => 10
[nopaging] =>
[comments_per_page] => 50
[no_found_rows] =>
)

[tax_query] => WP_Tax_Query Object
(
[queries] => Array
(
)

[relation] => AND
[table_aliases:protected] => Array
(
)

[queried_terms] => Array
(
)

[primary_table] => wp_posts
[primary_id_column] => ID
)

[meta_query] => WP_Meta_Query Object
(
[queries] => Array
(
[0] => Array
(
[key] => wpcf-jour-cours
)

[1] => Array
(
[jour_clause] => Array
(
[key] => wpcf-jour-cours
[compare] => EXISTS
)

[heure_clause] => Array
(
[key] => wpcf-heure-debut-cours
[compare] => EXISTS
)

[minute_clause] => Array
(
[key] => wpcf-minute-debut-cours
[compare] => EXISTS
)

[relation] => AND
)

[relation] => AND
)

[relation] => AND
[meta_table] => wp_postmeta
[meta_id_column] => post_id
[primary_table] => wp_posts
[primary_id_column] => ID
[table_aliases:protected] => Array
(
[0] => wp_postmeta
[1] => mt1
[2] => mt2
[3] => mt3
)

[clauses:protected] => Array
(
[wp_postmeta] => Array
(
[key] => wpcf-jour-cours
[compare] => =
[alias] => wp_postmeta
[cast] => CHAR
)

[jour_clause] => Array
(
[key] => wpcf-jour-cours
[compare] => EXISTS
[alias] => mt1
[cast] => CHAR
)

[heure_clause] => Array
(
[key] => wpcf-heure-debut-cours
[compare] => EXISTS
[alias] => mt2
[cast] => CHAR
)

[minute_clause] => Array
(
[key] => wpcf-minute-debut-cours
[compare] => EXISTS
[alias] => mt3
[cast] => CHAR
)

)

[has_or_relation:protected] =>
)

[date_query] =>
[request] => SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts 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 ) INNER JOIN wp_postmeta AS mt2 ON ( wp_posts.ID = mt2.post_id ) INNER JOIN wp_postmeta AS mt3 ON ( wp_posts.ID = mt3.post_id ) WHERE 1=1 AND (
wp_postmeta.meta_key = 'wpcf-jour-cours'
AND
(
mt1.meta_key = 'wpcf-jour-cours'
AND
mt2.meta_key = 'wpcf-heure-debut-cours'
AND
mt3.meta_key = 'wpcf-minute-debut-cours'
)
) AND wp_posts.post_type = 'product' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'wc-pending' OR wp_posts.post_status = 'wc-processing' OR wp_posts.post_status = 'wc-on-hold' OR wp_posts.post_status = 'wc-completed' OR wp_posts.post_status = 'wc-cancelled' OR wp_posts.post_status = 'wc-refunded' OR wp_posts.post_status = 'wc-failed' OR wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY wp_postmeta.meta_value ASC LIMIT 0, 10

Let me know
Regards
Pat

#620695

Shane
Supporter

Languages: English (English )

Timezone: America/Jamaica (GMT-05:00)

Hi Pat,

I'm attempting to get this to work.

Try changing the line

return $args;

To

$loop = new WP_Query( $args );

return $loop;

Try this and let me know what the result is.

For reference you can have a look at the link below .
hidden link

Thanks,
Shane

#620749

Pat

Hi Shane,

Just tried it and I'm getting this error :
Fatal error: Cannot use object of type WP_Query as array in my_site.com/wp-content/plugins/wp-views/embedded/inc/wpv-filter-order-by-embedded.php on line 291

Any idea?
Regards
Pat

#620750

Shane
Supporter

Languages: English (English )

Timezone: America/Jamaica (GMT-05:00)

Hi Pat,

Would you mind providing me with admin and ftp access to the site so that I can try to see if I can help better with this ?

The private fields will be enabled for your next response.

Thanks,
Shane

#620820

Pat

Sorry Shane,

I did not put the relevant info :

Used Views : [wpv-view name="liste-des-cours"]
Page where the Views is inserted : AAA

The list of products should be sorted in this order :
1. 'jour-cours'
2. 'heure-debut-cours'
3. 'heure-fin-cours'

Regards
Pat