Wordpress query_posts orderby meta queries - wordpress

This should be simple, but I just can't pinned down a good example of the correct syntax to do this.
I want to filter my posts by the meta_queries but order them by the specified meta_key.
When I run the code as is it results an infinite loop. I only included the problem code the other code is your basic Loop code that the query_post runs in.
Also all the PHP variables are correct and are not the problem.
$args2 = array(
'meta_key' => '_count-views_all',
//'meta_value' => $id,
'orderby' => 'meta_value_num',
'order' => $sortOrder,
'posts_per_page' => 9,
'paged' => $paged,
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'contributorid1',
'value' => $id,
'compare' => '='
),
array(
'key' => 'contributorid2',
'value' => $id,
'compare' => '='
)
)
);
$posts = query_posts($args2);
}
Here is another query that works completely without issue to cross reference. The two run on the same page but the are nested in an if else statement
$args1 = array(
//'meta_key' => 'contributorid1',
//'meta_value' => $id,
'order' => $sortOrder,
'orderby' => 'title',
'posts_per_page' => 9,
'paged' => $paged,
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'contributorid1',
'value' => $id,
'compare' => '='
),
array(
'key' => 'contributorid2',
'value' => $id,
'compare' => '='
)
)
);
$posts = query_posts($args1);

The query looks reasonable to me. The only method by which I see this running into an infinite loop is if this query runs within the post loop. When you use query_posts as you are, it will change the state of the global $wp_query, which is used for the pointer in the main posts loop.
If it kept hitting query_posts within the loop, it would continually change the state of the global $wp_query object, and reset the pointer for the current post to the first post of that new query, which would ultimately create the infinite loop.
If this code is being used within the loop, I'd recommend instead using something like
$query = new WP_Query($args2);
if ($query->have_posts()) { ... etc; }
If you need to then set up global post data within it, be sure to use wp_setup_postdata or $query->the_post() and wp_reset_postdata or wp_reset_query appropriately when you are finished using that post as the global post information.

Related

Wordpress get_posts not working as expected

I'm trying to retrieve posts in Wordpress using the get_posts function, trying to filter by a custom field named cegep_region but the method is returning posts with any value in this field. My query below:
$cegep = get_posts(array(
'post_type' => 'cegep',
'orderby' => 'rand',
'posts_per_page' => -1,
'meta_query' => array(
'key' => 'cegep_region',
'value' => '386',
'compare' => '='
)
));
When I look into the database, 386 is not what there is in the meta_value.
select * from wp_postmeta where post_id=577 and meta_key='cegep_region'
What can I possibly be doing wrong?
Try without using compare and add one more array inside in meta_query
$args = array(
post_type' => 'cegep',
'meta_query' => array(
array(
'key' => 'cegep_region',
'value' => 386,
)
)
);
$postslist = get_posts( $args );
its work fine with me

Multiple custom field sorting on wordpress archive page

I have been through several topics on sorting taxonomies and custom fields, including some that were promising. However, I am still not constructing my query args correctly it seems.
I am "fixing" someone else's code in a custom theme that is used in a multisite configuration, but I am able to override/filter the query on a per-site basis.
The query is called via the theme with the following:
return apply_filters( 'theme_query_args_filter', $args);
I have custom fields in the "role" taxonomy that include:
last_name
first_name
Pretty common I think.
However, when the args are executed, the following filter args are sorting only by last name (key part is the else clause):
function my_args_filter( $args ) {
if (is_home() && !is_search()) {
$args['meta_key'] = 'event_date';
$args['orderby'] = 'event_date';
$args['order'] = 'DESC';
}
else {
$tax = $args['taxonomy'];
$theterm = $args['term'];
$args = array (
'taxonomy' => $tax,
'term' => $theterm,
'meta_key' => 'last_name',
'orderby' => 'meta_value',
'order' => 'ASC'
);
}
add_filter( 'theme_query_args_filter', 'my_args_filter' );
I've tried to modify the orderby as indicated in https://make.wordpress.org/core/2014/08/29/a-more-powerful-order-by-in-wordpress-4-0/ to use an array to do a multisort, but I'm hitting my head up against the wall. I think the problem is that the code is written using a mixture of old ways of doing things and new ways.
Any advice is appreciated. According to the example on in the docs above, I SHOULD be able to pass in multiple meta key/value/orders via an array, but I'm just not getting it.
Thanks for any leads you might have. (long-time listener, first-time caller)
(I also looked at https://wordpress.stackexchange.com/questions/109849/order-by-desc-asc-in-custom-wp-query but I couldn't extrapolate that example to this one either)
Figured it out on my most recent try. Hat tip to this solution https://wordpress.stackexchange.com/questions/249881/multiple-custom-fields-for-orderby-in-wp-query by Nath. if there is a more elegant way to do it, please let me know.
$tax = $args['taxonomy'];
$theterm = $args['term'];
$paged = $args['paged'];
$args = array (
'taxonomy' => $tax,
'term' => $theterm,
'paged' => $paged,
'posts_per_page' => '10',
'meta_query' => array(
array(
'relation' => 'AND',
'last_name' =>
array(
'key' => 'last_name',
'compare' => 'EXISTS',
),
'first_name' =>
array(
'key' => 'first_name',
'compare' => 'EXISTS',
),
),
),
'orderby' => array (
'last_name' => 'ASC',
'first_name' => 'ASC',
)
);
}

WordPress Query with Array using LIKE

I have a query that looks like this:
$data = get_posts( array(
'post_type' => 'custom_type',
'post_status' => 'any',
'posts_per_page' => 200,
'order' => 'ASC',
'meta_key' =>'_customer_start',
'orderby' => 'meta_value',
'meta_query' => array(
array(
'key' => '_customer_id',
'value' => $customer_id,
'compare' => 'IN'
),
array(
'key' => '_customer_start',
'value' => $_customer_start,
'compare' => 'LIKE'
)
)
)
);
The input to this query is two arrays:
$customer_id = array(2808,2814);
$_customer_start = array('20170212','20170224');
My issue is, this generates the following error:
Warning: trim() expects parameter 1 to be string, array given in ..../wp-includes/class-wp-meta-query.php on line 597
I have troubleshot this and it would appear the issue is the second array, passing in a group of dates for a LIKE comparison. I cannot use an IN comparison (As is recommend for arrays) as the dates stored include times. Hence if I use an IN or EQUALS, I will not find them.
Is there a way of passing an array for LIKE comparison, without dynamically expanding the query?

Wordpress output links to previous and next posts from custom query

I'm using the advanced custom fields plugin for wordpress to create a group of custom post types that have a date set within them.
I'm trying to show the previous post, and the next post, based on the date stored in the custom field. The links need to link to posts that have a date set in the future (so don't show links to posts with dates that have gone by)/
I can get a list of all the posts that are in the future, and out put these using the following code;
<?php
$rightnow = current_time('Ymd');
$args = array(
'post_type' => 'Courses',
'posts_per_page' => '25',
'meta_query' => array(
array(
'key' => 'date_of_the_course_single_day',
'compare' => '>=',
'value' => $rightnow,
)
),
'meta_key' => 'date_of_the_course_single_day',
'orderby' => 'meta_value',
'order' => 'ASC',
'post_status' => 'publish'
);
$posts = get_posts($args);
foreach ( $posts as $post ) {
?>
Output details of post here....
<?php
}
?>
What I thought I could do, is the get the current post's position in the array, to then get details of the posts one before and one after... but I haven't got a clue how to do this.
I've experimented with the wordpress next_post_link and previous_post_link functions, but these seem to work based on when the post was added to wordpress, rather than based on my custom date field.
Am I going about this the complete wrong way? Any tips or pointers would be much appreciated!
Use WP_Query plus paginate_links
$rightnow = current_time('Ymd');
// Query Args
$args = array(
'post_type' => 'Courses',
'posts_per_page' => '25',
'meta_query' => array( array(
'key' => 'date_of_the_course_single_day',
'compare' => '>=',
'value' => $rightnow,
) ),
'meta_key' => 'date_of_the_course_single_day',
'orderby' => 'meta_value',
'order' => 'ASC',
'post_status' => 'publish'
);
$query = new WP_QUery( $arg );
$posts = $query->get_posts();
// Paginate Args
$page_args = array(
'base' => 'your_custom_page_url'.'%_%', // Make sure you got this current depending on your setup
'format' => '/%#%', // requires pretty permalinks
'total' => $query->max_num_pages,
'current' => 0,
'prev_text' => __('«'),
'next_text' => __('»'),
);
foreach ( $posts as $post ) {
// Output
}
echo paginate_links( $page_args );
You have to verify that the base and format of paginate args are correct of it won't properly worked.

Posts query including meta and greater than date

I'm struggling to get a working solution with this wp_query. I currently have some custom settings which are assigned to posts, one is whether or not the post is 'featured' and the second is a date and time for the post to end (no longer display in the results). I have the query working with the feature, but just need to work this end date into it, here is the query working find with the 'featured':
WP_Query('meta_key=skyali_feature&showposts=4&orderby=post_date');
The end date is set in the wp_postmeta table where meta_key is 'the_date' and the meta_values look like this '05/16/2013 05:24'. I would like to edit the above query where if 'the_date' has been set posts are only included if the 'the_date' is greater that todays date and time.
Here is my failed attempt:
WP_Query(
'meta_key=skyali_feature&meta_key=the_date&meta_compare=>=&meta_value='
.date('d/m/Y H:i')
.'&showposts=4&orderby=post_date&orderby=the_date'
);
I had to do something very similar recently and ended up needing to use the meta_query property instead. You'll want to do something like this:
$today = date('Ymd');
$args = array(
'post_type' => 'post',
'posts_per_page' => '4',
'meta_key' => 'the_date',
'meta_query' => array(
array(
'key' => 'skyali_feature'
),
array(
'key' => 'the_date',
'value' => $today,
'compare' => '>='
)
),
'orderby' => 'meta_value_num',
'order' => 'ASC'
);
$your_custom_query = new WP_Query($args);
A few notes...
I only needed to filter by date in my example, but it looks like you'll need to do date/time in yours. (You can just adjust the first line for the $today variable using the format you wish).
Use posts_per_page instead of showposts. showposts is deprecated.
Notice that I have included the meta_key twice (once at the top level of the array and once as an element in the meta_query array. There's a known bug where you can't sort your results by the key if you don't include it this way. I fought that one for a while too!
Hope this helps, have fun!
[edit] Forgot to add your skyali_feature key back into the array.
for people using the advanced custom field plugin with a date data type, this is what you need for dates greater or equal than today:
$today = date('Ymd');
$args = array(
'post_type' => 'post',
'meta_key' => 'end-date',
'meta_query' => array(
array(
'key' => 'end-date'
),
array(
'key' => 'end-date',
'value' => $today,
'compare' => '>='
)
),
'orderby' => 'meta_value',
'order' => 'ASC'
);
$your_custom_query = new WP_Query($args);
for people using Custom metadata manager you'll find that a datepicker field is stored as timestamp.
So in a similar case the above example isn't working and you may have php sort out the value you need to compare against. And the timestamp for a day earlier at 23:59:59 it'll do the job:
$yesterday = strtotime('yesterday 23:59:59');
$args = array(
'post_type' => 'post',
'meta_key' => 'end-date',
'meta_query' => array(
array(
'key' => 'end-date'
),
array(
'key' => 'end-date',
'value' => $yesterday,
'compare' => '>='
)
),
'orderby' => 'meta_value',
'order' => 'ASC'
);
$your_custom_query = new WP_Query($args);
If you also want to take account of the timezone setting for the blog use current_time() as in the following example:
$now = current_time('timestamp');
$yesterday = mktime(23, 59, 59, date('n',$now), date('j',$now)-1);

Resources