Wordpress orderby meta values in array - php

I'm trying to get sorted list of posts using get_posts by meta value and the order of meta value is given in array.
This is what I currently have.
$stores = get_posts(array(
'post_type' => 'stores',
'post_status' => 'publish',
'posts_per_page' => -1,
'fields' => 'ids', // I only need the ID's of posts
'orderby' => 'meta_value',
'meta_key' => 'state',
'order' => 'ASC'
));
This returns the array of posts sorted by meta_value in ASCENDING alphabetical order.
I have an array of possible values for 'meta_key' => 'state', i.e. array('State1', 'State2', 'State3')
I want to set order so that all stores which has meta value State1 appears first, then from State2 and after that State3
I can't use order by numeric value and alphabetical value as state names are gonna be random.
I found one post here, it is using mera_query_orderby. I can't find any documentation for this and tried it, but it's not working. It returns posts ordered by ID.
Any help would be appreciated. Thanks
EDIT:
I added the meta_query_orderby filters in functions.php
And the updated code I used from EXAMPLE 2, is like:
$stores = get_posts(array(
'post_type' => 'stores',
'post_status' => 'publish',
'posts_per_page' => -1,
'fields' => 'ids',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => 'state', // Custom field key.
'value' => array("CState1", "AState2", "BState3")
)
),
'meta_query_orderby' => array(
array(
'key' => 'state', // (required) Custom field key.
'value' => array("CState1", "AState2", "BState3")
)
)
));

I have an array of possible values for 'meta_key' => 'state', i.e.
array('State1', 'State2', 'State3')
If you want to sort the posts by the meta value in the exact order as in the above array, you can use a custom WP_Query parameter (to set the meta/sort values) and the posts_orderby filter to customize the ORDER BY clause, and in that clause, you would be using the FIELD() function in MySQL.
Step 1
Add this code to your plugin or theme (if theme, you'd add the code to the theme functions file):
add_filter( 'posts_orderby', 'posts_orderby_meta_value_list', 10, 2 );
function posts_orderby_meta_value_list( $orderby, $query ) {
$key = 'meta_value_list';
if ( $key === $query->get( 'orderby' ) &&
( $list = $query->get( $key ) ) ) {
global $wpdb;
$list = "'" . implode( wp_parse_list( $list ), "', '" ) . "'";
return "FIELD( $wpdb->postmeta.meta_value, $list )";
}
return $orderby;
}
Step 2
When making your post queries, set the orderby to meta_value_list and add meta_value_list to the query parameters — if you're using get_posts(), make sure suppress_filters is set to false:
$stores = get_posts( array(
'post_type' => 'stores',
'post_status' => 'publish',
'posts_per_page' => -1,
'fields' => 'ids', // get just the ID's of posts
'meta_key' => 'state',
'orderby' => 'meta_value_list',
'meta_value_list' => array( 'State1', 'State2', 'State3', '' ),
'suppress_filters' => false,
) );
PS: I the added '' to the array so that posts where the metadata is ('') (i.e. exists in the database, but the value is empty) would be placed at the bottom of the results.
Tried and tested working, but note that the above solution is only for single orderby, which means array is not supported.

/*Display posts of type 'stores', ordered by 'state', and filtered to show only states.*/
$args = array(
'post_type' => 'stores',
'meta_key' => 'state',
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => 'state',
'value' => array( 'State1', 'State2', 'State3'),
'compare' => 'IN',
),
),
);
$query = new WP_Query( $args );

Related

How to query posts by ACF field but then also order by a separate ACF field?

I am using WP_Query to get posts that have a specific value in one of the ACF fields. I also need to order them by a separate ACF field. I am not sure how to accomplish this. Everything I've read says to use 'orderby' => 'meta_value' but I believe thats the value of the field I'm filtering the posts by, which is not what I want.
This is what I have right now..
$args = array(
'post_type' => 'contacts',
'posts_per_page' => -1,
'meta_key' => 'department',
'meta_value' => 'Transportation',
'orderby' => 'meta_value'
);
$the_query = new WP_Query( $args );
I need to orderby an ACF field named last_name.
It's possible to assign a name to a meta query, and then refer to that name in your orderby. Something like this.
$args = array (
'post_type' => 'contacts',
'post_status' => 'publish',
'nopaging' => true,
'posts_per_page' => -1,
'meta_query' => array( 'main_query' => array(
'key' => 'department',
'value' => 'Transportation'
), 'orderby_query' => array(
'key' => 'last_name',
)
),
'orderby' => array(
'orderby_query' => 'ASC',
),
);
$the_query = new WP_Query( $args );

WP Query - Order by metavalue and keep other posts

Can't figure out this problem. Goal: I want to show all posts and order them by a post meta value, but not all posts have that meta key.
Problem: Not all posts are shown, only the ones that have that meta key (and meta value).
$args = array(
'post_type' => 'post',
'meta_key' => 'post_custom_field_1',
'orderby' => 'meta_value',
'order' => 'ASC',
'paged' => $paged,'post_type' => 'post' );
Question: How can I show all posts and sort them by a meta_key? Posts that have the meta_key are shown first and ordered by name and posts that don't have the meta_key follow and are sorted by title.
You'll have to use EXISTS for compare. There are plenty of examples in the docs for WP_Query, you can adapt it to your case:
function orderby_fieldifexists($orderby) {
return "mt1.post_id IS NOT NULL DESC, wp_postmeta.meta_value ASC";
}
add_filter("posts_orderby", "orderby_fieldifexists", 10, 1);
$query = new WP_Query(
array(
'post_type' => 'post',
'meta_query' => array(
"relation" => "or",
'custom_field_value' => array(
'key' => 'post_custom_field_1',
),
'custom_field' => array(
'key' => 'post_custom_field_1',
'compare' => 'NOT EXISTS',
),
),
'orderby' => array(
'custom_field' => 'ASC'
),
'posts_per_page' => 5,
)
);
I've initially had a simpler version in here, but then remembered that it would be silly to sort numerically if some values will be NULL. This version will find all posts, but get the value as well, and sort descending on "does it exist?" and then ascending on the actual values, so a post with a custom field value of -1 will be listed before those without that custom field value.

Sort post meta data using meta_key?

I'm trying to get the post, meta datas on table wp_postmeta. I need to get the post id, meta keys and meta value by using the meta_key and post id. The meta key stored is date. eg,. 2014-01-02, 2014-02-03, I have to query them based on the year or month.
$args = array(
'post_type' => 'calendar_holiday',
'ID' => $id;
'meta_query' => array(
array(
'key' => ,
'value' => ,
'compare' => 'LIKE'
),
)
);
$query = new WP_Query( $args );
I'm not sure what to put on key and value.. any idea?? thanks
// 'orderby' => 'meta_value_num', // it's a numeric value
$args = array(
'orderby' => 'meta_value',
'post_type' => 'calendar_holiday',
'meta_query' => array(
array(
'key' => 'over-make',
'value' => 'Doral',
'compare' => 'LIKE'
)
)
);
$query = new WP_Query( $args );

Ordering the output of a loop by a custom field containing a datestamp

I'm using a custom field that stores the timestamp of a date entered by the user. I want to display posts sorted by that custom date, but they refuse to order by custom field.
Here I register the custom field using this custom meta boxes tool - https://github.com/jaredatch/Custom-Metaboxes-and-Fields-for-WordPress
// the prefix is _cmb_
array(
'name' => 'Start Time',
'id' => $prefix . 'start_time',
'type' => 'text_datetime_timestamp',
),
Then I use WP_Query to loop through the posts with the following arguments:
$args = array(
'post_type' => 'talks',
'posts_per_page' => -1,
'orderby' => '_cmb_start_time',
'order' => 'ASC'
); // show talks ordered by start time
$custom_query = new WP_Query($args);
This prints out the posts in the order they were added and not in the order of the custom field date.
Update
I was also trying to filter by another custom field type "room" with a value equal to "room 1":
$args = array(
'post_type' => 'talks',
'posts_per_page' => -1,
'orderby' => '_cmb_start_time',
'order' => 'ASC',
'meta_key' => 'room',
'meta_value' => 'room 1'
);
Solution:
With #joebuckle 's solution I ended up with this version that works great:
$args = array(
'post_type' => 'talks',
'posts_per_page' => -1,
'meta_key' => '_cmb_start_time',
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => 'room',
'value' => 'room 1',
'compare' => '='
)
));
try it like this instead (ref WP_Query)
$args = array(
'post_type' => 'talks',
'posts_per_page' => -1,
'meta_key' => '_cmb_start_time',
'orderby' => 'meta_value_num',
'order' => 'ASC'
); // show talks ordered by start time
$custom_query = new WP_Query($args);

Wordpress query by multiple metaboxes and order by date

So here is my query:
$args = array(
'post_type' => 'Event',
'posts_per_page' => 1000,
'meta_key' => 'event_informations_show_on_the_homepage',
'meta_value' => 'Show on the homepage',
'meta_compare' => '==',
'meta_key' => 'event_informations_date',
'orderby' => 'meta_value_num',
'order' => 'ASC'
);
$loop = new WP_Query( $args );
I want to select all posts that have the metabox event_informations_show_on_the_homepage and the value of the metabox event_informations_show_on_the_homepage and order by the date metabox which is stored as a timestamp and is called event_informations_date.
What am I doing wrong?
Hopefully I'm not barking up the wrong tree here.
You can use the key 'meta_query' to filter posts by multiple meta keys like so:
$args = array(
'post_type' => 'Event',
'posts_per_page' => 1000,
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'event_informations_show_on_the_homepage',
'value' => 'yes',
),
array(
'key' => 'event_informations_date',
'value' => 'yes',
)
)
);
$query = new WP_Query( $args );
What WordPress is doing here is creating multiple wheres against the same column by using innerjoins on the same table, each time using a different alias. It's pretty cool & is probably the fastest way to query like that.
For more information see here: http://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters
Hope this helps :)

Categories