Home › Toolset Professional Support › [Resolved] Views sorted by 2 custom fields
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 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: Views plugin
This topic contains 25 replies, has 2 voices.
Last updated by Pat 6 years, 9 months ago.
Assisted by: Shane.
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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