How to sort multiple wordpress custom field values? - wordpress

Display posts with 'Product' type ordered by 'Price' custom field:
$query = new WP_Query(
array ( 'post_type' => 'product',
'orderby' => 'meta_value',
'meta_key' => 'price' )
);
Which code should I use if also want to order by 'Size'?
Another example on which I need multiple sort on custom fields:
Display posts with 'Event' type ordered by 'Start_Hour' and then by 'Start_Minute'.

Thanks to Bainternet I found the solution:
function orderbyreplace($orderby) {
return str_replace('menu_order', 'mt1.meta_value, mt2.meta_value', $orderby);
}
and...
$args = array(
'post_type'=>'Events',
'orderby' => 'menu_order',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => 'Start_Hour',
'value' => '',
'compare' => 'LIKE'
),
array(
'key' => 'Start_Minute',
'value' => '',
'compare' => 'LIKE'
)
)
);
add_filter('posts_orderby','orderbyreplace');
$loop = new WP_Query( $args );
remove_filter('posts_orderby','orderbyreplace');

I think this changed slightly in Wordpress 3.7.
I had to change
return str_replace('menu_order', 'mt2.meta_value, mt1.meta_value', $orderby);
into
return str_replace('wp_posts.menu_order', 'mt2.meta_value, mt1.meta_value', $orderby);
Thanks for the initial solution! [Edited]

Here's an example of using more than one meta_key and orderby that I believe should work:
$params = array(
'post_type' => 'product',
'meta_query' => array(
array(
'key' => 'price',
'value' => '',
'compare' => 'LIKE'
),
array(
'key' => 'size',
'value' => '',
'compare' => 'LIKE'
)
),
'orderby' => 'price size',
'order' => 'ASC'
);
$query = new WP_Query;
$resulting_obj = $query->query($params);
You'll need to play with the meta_query items a bit more, especially the 'value' parameter. Please have a good look at http://codex.wordpress.org/Class_Reference/WP_Query in the 'Custom Field Parameters' section.

You don't need any filter or hooks to sort multiple custom fields, if your one of custom field is meta_key and other one is normal column of table, than use these parameters/arguments in your query.
'meta_key' => 'KEY_NAME',
'orderby' => 'meta_value_num SECOND_COLUMN_NAME',
'order' => 'ASC' or 'order' => 'DESC'
Here the order of meta_value_num and SECOND_COLUMN_NAME matter, you may see different-2 result based on the order.

Related

WordPress: WP_Query with posts from a category and meta_query or only another meta_query

I have some trouble with WordPress and the WP_Query.
I would like to get posts filtered by meta_query and/or category, but I have the following problem:
The first type of posts has a custom field named "type" which must be filled with "exercise" and the post has to be in a category named "Level" (this will be set before).
The second type of posts has only the custom field named "type" which must be filled with "test".
I don't know how to get these two conditions together.
Because of that I've tried to split it into two Queries, and merge it afterward, like this:
$firstArgs = array(
'posts_per_page'=> -1,
'category_name' => $level,
'meta_key' => 'duration',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'meta_query' => array(
'key' => 'type',
'value' => 'exercise'
)
);
$secondArgs = array(
'posts_per_page' => -1,
'meta_key' => 'duration',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'meta_query' => array(
'key' => 'type',
'value' => 'test'
)
);
$first_query = new WP_Query( $firstArgs );
$second_query = new WP_Query( $secondArgs );
$result = new WP_Query();
$result->posts = array_merge($first_query->posts, $second_query->posts);
The Problem with this method is, that I would like to sort the posts by the custom field "duration" DESC. If I merge these two arrays, the sorting isn't that way I would like to.
Does anyone know a better way of doing this? If it would be one query, the sorting would work and I think it is more efficient.
Thanks for your help!
$firstArgs = array(
'posts_per_page'=> -1,
'category_name' => $level,
'meta_key' => 'duration',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'meta_query' => array(
'key' => 'type',
'value' => 'exercise'
)
);
$secondArgs = array(
'posts_per_page' => -1,
'meta_key' => 'duration',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'meta_query' => array(
'key' => 'type',
'value' => 'test'
)
);
$firstArgs = get_posts($firstArgs);
$secondArgs = get_posts($secondArgs);
$your_posts = array_unique(array_merge($firstArgs,$secondArgs),SORT_REGULAR);
_e('<pre>');
print_r($your_posts);
_e('</pre>');
For your better understanding visit here
I found an answer that worked for me.
First of all, I retrieve the data as Dhruv told me and then, I sorted the result with the usort-function, but with an anonymous function.
usort($your_posts, function($a, $b)
{
$val1 = get_post_meta($a->ID, 'duration', true );
$val2 = get_post_meta($b->ID, 'duration', true );
return -1*($val1 - $val2); // sort desc
});
Maybe it is not the best method, but it worked for me. :-)

WP Query: How to get posts from a specific author OR those with a specific meta value

I would like to retrieve all those posts whose author (post table field) is a given one OR those which has a given meta value (postmeda table field).
If "author" was a meta value, I know I could use a meta_query to achieve it. The thing here is that it is not... so I think I cannot use the "author" field within a meta_query and use the "relation" key.
I'm looking for something like:
$args = array(
'post_type' => array('post'),
'orderby' => 'ASC',
'order' => 'date',
'meta_query' => array(
'relation' => 'OR',
array(
'relation' => 'AND',
array(
'field' => 'author',
'value' => $author_id,
'compare' => '==',
),
array(
'key' => '_meta_field_name',
'compare' => 'NOT EXISTS',
),
),
array(
'relation' => 'AND',
array(
'key' => '_meta_field_name',
'compare' => 'EXISTS',
),
array(
'key' => '_meta_field_name',
'value' => $meta_field_value,
'compare' => '==',
),
),
),
);
$data = new WP_Query( $args );
Any suggestion on how to achieve that using WP_Query?
Thanks!
You might like to try an approach like this one instead. The idea is to query the two conditions you want to search for, then merge the two queries into one finished product.
//Get posts with the author you're looking for
$args1 = array(
'author_name' => 'testuser', //or 'author' => $author_id or something else
);
$data1 = get_posts( $args1 );
//Get posts with the meta data you're looking for
$args2 = array(
'meta_query' => array(
array(
'key' => 'meta_field_name',
'compare' => 'EXISTS',
),
array(
'key' => 'meta_field_name',
'value' => $meta_field_value,
'compare' => '==',
),
),
);
$data2 = get_posts( $args2 );
//Merge both arrays
$allData = array_merge( $data1, $data2 );
//Get just the IDs of all the posts found, while also dropping any duplicates
$postIDs = array_unique( wp_list_pluck( $allData, 'ID' ) );
//Do a new query with these IDs to get a properly sorted array of post objects
$args3 = array(
'post__in' => $postIDs,
'order' => 'ASC',
'orderby' => 'date',
);
$finalAnswer = get_posts( $args3 ); //This is your array of post objects. Ta-Da!

Sort posts by custom field number

I'm using this query do get some posts.
$args = array(
'post_type' => 'spaces',
'post_per_page' => '500',
'orderby' => 'rand',
'meta_key' => 'space-city',
'meta_value' => $search,
);
$query = new WP_query($args);
Now I need to order the results by total of comments on each post. I've a custom field with this number called "space-comments", but I've no idea how to sort this posts with this second meta_key.
I made some tests, but I only was able to get post when "space-comments" has a value. When there is no value, the post don't show up.
Any ideia how can I start?
The WP_Query can accept a meta_query argument that is populated as an array of sub-arguments. That array can have sub arrays that are each their own meta query, so you can create some nice compound searches across meta data.
See the example from https://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters below.
$args = array(
'post_type' => 'product',
'meta_query' => array(
array(
'key' => 'color',
'value' => 'blue',
'compare' => 'NOT LIKE',
),
array(
'key' => 'price',
'value' => array( 20, 100 ),
'type' => 'numeric',
'compare' => 'BETWEEN',
),
),
);
$query = new WP_Query( $args );

Ordering by two custom fields values

I have custom post type called "lawyer" and I want to query lawyers ordered by custom field "surname" and then ordered by custom field "name". My query looks like this:
query_posts( array ( 'post_type' => 'lawyer', 'posts_per_page' => -1, 'meta_query' => array(array('key' => 'surname', 'orderby' => 'meta_value', 'order' => ASC), array('key' => 'name', 'orderby' => 'meta_value', 'order' => ASC) )) );
But it's not working. I get results, but they are not ordered the way I want them to. Any idea what is wrong here?
Don't use query_posts() ever.
Reference When should you use WP_Query vs query_posts() vs get_posts()?
You can do it by using WP_QUERY and adding filter to posts_orderby
function custom_orderby($orderby) {
global $wpdb;
return str_replace($wpdb->prefix.'postmeta.meta_value', 'mt1.meta_value, mt2.meta_value ASC', $orderby);
}
Then Prepare your arguments.
$args = array(
'post_type'=>'lawyer',
'orderby' => 'meta_value',
'meta_key' => 'surname',
'meta_query' => array(
array(
'key' => 'surname',
'value' => '',
),
array(
'key' => 'name',
'value' => '',
)
)
);
And add your custom order by filter just before the query execute.
add_filter('posts_orderby','custom_orderby');
$loop = new WP_Query( $args );
remove_filter('posts_orderby','custom_orderby');
Finally made it work with this code:
function double_meta_posts_orderby($orderby) {
remove_filter('posts_orderby', 'double_meta_posts_orderby');
global $wpdb;
return " {$wpdb->postmeta}.meta_value, mt1.meta_value";
}
$args = array(
'post_type'=>'lawyer',
'post_per_page' => -1,
'meta_query' => array(
array(
'key' => 'surname',
),
array(
'key' => 'name',
)
),
'orderby' => 'meta_value',
'order' => ASC,
);
add_filter('posts_orderby', 'double_meta_posts_orderby');
$loop = new WP_Query( $args );
// the Loop
while ($loop->have_posts()) : $loop->the_post();
...

Multiples meta_key and order by specific meta_value

I am trying to get the posts order by a meta_value that i put in a sortable list of posts, i have an extra meta_key and meta_value to give extra info to the query, but i can't make the WP_Query return the post order, do you have any idea that whats is worng?
This is my WP_QUery code:
$args = array(
'meta_query' => array(
array(
'key' => 'portada',
'value' => 'on'
), array(
'key' => 'pos',
'type' => 'numeric'
)
),
'meta_key' => 'pos',
'orderby' => 'meta_value_num');
$loop = new WP_Query($args);
i use the follow code to solve my problem:
$args = array(
'meta_query' => array(
array(
'meta_key' =>'destacados',
'meta_value' => 'on'
)
),
'orderby' => 'meta_value_num',
'category__in' => $category->cat_ID,
'meta_key' => 'pos'
);
$loop = new WP_Query($args);
Thank you all :)
Note that
'meta_query' => array(
array(
'key' =>'destacados',
'value' => 'on'
)
)
instead of
'meta_query' => array(
array(
'meta_key' =>'destacados',
'meta_value' => 'on'
)
)

Resources