My current query looks like this.
$tag_id = 276;
$tag = get_tag($tag_id);
$today = date( "Y-m-d" );
$args = array(
'post_type' => array(
'post',
'review',
'cardguide'
),
'taxonomy' => 'post_tag',
'tag_id' => $tag_id,
'posts_per_page'=> - 1,
'orderby' => 'id',
'order' => 'DESC',
'meta_key' => 'event_end_date',
'meta_query' => array(
'relation'=> 'AND',
array(
'key' => 'event_start_date',
'value' => $today,
'compare'=> '<=',
'type' => 'DATE'
),
array(
'key' => 'event_end_date',
'value' => $today,
'compare'=> '>=',
'type' => 'DATE'
)
)
);
$my_query = new Wp_query( $args );
I want to include a single post (can use post id) into this query. The post may not obey each of the rules I defined inside $args. And also would like to have it always on top of the list (featured item).
If you are looking to get the same post by id for this query every time, then just do a separate get_post() call like:
$featured_item = get_post( 123 ); // replace 123 with your id
This will prevent you from having to worry about "obeying each of the rules" you've defined above. Plus, if you always want it "on top", then you can pump out the values of $featured_item before you run your query loop.
Related
I'm using the plugin Code Snippets and Advance Custom Fields. I'm using a code snippet with a WP_QUERY to get posts from the database. I'm trying to get a value from a repeater field. This is not my project so I can't really change the repeater field. So I'll have to deal with. This is the query.
$args = array(
'numberposts' => $limit,
'post_type' => 'opleidingen',
'orderby' => 'meta_value',
'suppress_filters' => 'false',
'meta_query' => array(
array(
'key' => 'data_$_startdatum',
'value' => $today,
'compare' => '>',
),
),
'order' => $order,
);
$the_query = new WP_Query( $args );
What I am trying to do is do a comparison with a the date of today with data_$_startdatum where startdatum is a subfield. I've read here https://www.advancedcustomfields.com/resources/query-posts-custom-fields/ that this is the way to do a where comparison on a subfield. But if I run the query I get back 0 posts.
I've tested if the query works by replacing the $ with a 0 and that works. But only for the first index of the repeater field. If I use a OR operator and add in arrays with data_0_startdatum to data_10_startdatum it works for the first 10 indexes. So like this
$args = array(
'numberposts' => $limit,
'post_type' => 'opleidingen',
'orderby' => 'meta_value',
'suppress_filters' => 'false',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'data_0_startdatum',
'value' => $today,
'compare' => '>',
),
array(
'key' => 'data_1_startdatum',
'value' => $today,
'compare' => '>',
),
array(
'key' => 'data_2_startdatum',
'value' => $today,
'compare' => '>',
),
array(
'key' => 'data_3_startdatum',
'value' => $today,
'compare' => '>',
),
array(
'key' => 'data_4_startdatum',
'value' => $today,
'compare' => '>',
),
array(
'key' => 'data_5_startdatum',
'value' => $today,
'compare' => '>',
),
array(
'key' => 'data_6_startdatum',
'value' => $today,
'compare' => '>',
),
array(
'key' => 'data_7_startdatum',
'value' => $today,
'compare' => '>',
),
array(
'key' => 'data_8_startdatum',
'value' => $today,
'compare' => '>',
),
array(
'key' => 'data_9_startdatum',
'value' => $today,
'compare' => '>',
)
),
'order' => $order,
);
But I would like it to work for the entire array length. Since Wordpress 4.8.3 you can't use the % and you'll have to use a post_where filter to replace % with LIKE. I tried doing this by implementing the following code in my functions.php
function my_posts_where( $where ) {
echo($where);
$where = str_replace("meta_key = 'data_$", "meta_key LIKE 'data_%", $where);
return $where;
}
add_filter('posts_where', 'my_posts_where');
This did not work. So I tried to make a snippet with the code snippets plugin and give it a high priority and this also did not work. I also tried to give it a low priorit and this did also not work. I put a echo in the filter and get back the following when viewing the post in the browser
AND (wp_posts.ID = '610') AND wp_posts.post_type = 'page' AND wp_posts.post_type = 'wpmm_theme' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'acf-disabled' OR wp_posts.post_author = 6 AND wp_posts.post_status = 'private') AND (wp_posts.ID = '610') AND wp_posts.post_type = 'page' AND (wp_posts.ID = '610') AND wp_posts.post_type = 'page'
My query is not in there? I get this result when I put the filter in my functions.php or in a seperate snippet with high or low priority.
It would be way better to compose the WP_Query() dynamically. Modifying the where clause on the fly with str_replace is a bad practice and may easily cause bugs.
Try the following:
$nrOfFieldsToCheck = 20; // Find the number of fields to check or use a constant
$buf = ['relation' => 'OR'];
// Compose the array of conditions
for($i=0;$i < $nrOfFieldsToCheck; $i++)
{
$buf[] = [
'key' => sprintf('data_%d_startdatum',$i),
'value' => $today,
'compare' => '>'
];
}
$args = [
'numberposts' => $limit,
'post_type' => 'opleidingen',
'orderby' => 'meta_value',
'suppress_filters' => 'false',
'meta_query' => $buf,
'order' => $order
];
$the_query = new WP_Query( $args );
Furthermore, I am not aware that str_replace supports the use of wildcards. Your filter isn't working because it does not find the $needle in the $haystack string value.
Ok, so I am querying events made by The Events Calendar, using Advanced Custom Fields. I have a plugin that converts the serialized data to standard under a new meta_key. That said, I am able to query events by the meta_key and meta_value individually. i.e
$args = array(
'numberposts' => -1,
'post_type' => 'tribe_events',
'meta_key' => 'display_override',
'meta_value' => 'Arkansas Literary Festival'
);
and also
// args
$args = array(
'numberposts' => -1,
'post_type' => 'tribe_events',
'meta_key' => 'display_global',
'meta_value' => 'Enabled'
);
However, I can not get them to work simultaneously, i.e
// args
$args = array(
'numberposts' => -1,
'post_type' => 'tribe_events',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'display_override',
'value' => 'Arkansas Literary Festival',
'compare' => '='
),
array(
'key' => 'display_global',
'value' => 'Enabled',
'compare' => '='
)
)
);
When I experiment with this, by using 'OR' or 'AND', and 'LIKE' instead of '=', I either get no posts, or I get the master list of unfiltered posts....
In wp_query, is it possible to build a complex query so I can order by a conditional or calculated fields?
what I'm trying to do is something like the next query in MySql:
SELECT *, field1, field2
case when field1+field2 > some_value then 1 else 2 end as my_alias
FROM my_table
ORDER BY my_alias ASC
I want to build queries like this one using wp_query, is this possible? if yes, how can I accomplish that?
Yeah, you need to
add custom field using
https://developer.wordpress.org/reference/hooks/posts_fields/
add custom order by using
https://developer.wordpress.org/reference/hooks/posts_orderby/
I don't see any way to do this with a single WP_Query as meta_query doesn't allow you such flexibility, though you can do three distinct queries then merge them (untested code):
// Get ongoing events
$ongoing = new WP_Query(array(
'post_type' => 'event',
'meta_key' => 'date_from',
'orderby' => 'meta_value',
'order' => 'ASC',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'date_from',
'value' => date('Y-m-d'),
'compare' => '<=',
'type' => 'DATE'
),
array(
'key' => 'date_to',
'value' => date('Y-m-d'),
'compare' => '>=',
'type' => 'DATE'
)
)
));
foreach($ongoing as $key => $ongoing_post) {
$ongoing_post->event_status = 'ongoing';
$ongoing[$key] = $ongoing_post;
}
// Get upcoming events
$upcoming = new WP_Query(array(
'post_type' => 'event',
'meta_key' => 'date_from',
'orderby' => 'meta_value',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => 'date_from',
'value' => date('Y-m-d'),
'compare' => '>',
'type' => 'DATE'
)
)
));
foreach($upcoming as $key => $upcoming_post) {
$upcoming_post->event_status = 'upcoming';
$upcoming[$key] = $upcoming_post;
}
// Get past events
$past = new WP_Query(array(
'post_type' => 'event',
'meta_key' => 'date_from',
'orderby' => 'meta_value',
'order' => 'DESC',
'meta_query' => array(
array(
'key' => 'date_to',
'value' => date('Y-m-d'),
'compare' => '<',
'type' => 'DATE'
)
)
));
foreach($past as $key => $past_post) {
$past_post->past_status = 'past';
$past[$key] = $past_post;
}
// Merge'em all
$events = array_merge($ongoing, $upcoming, $past);
The thing is to use meta_query to compare the meta values with the actual date (you may want to change the date format depending of how they are stored in date_from and date_to fields), and do a little loop right after to add a property to all post object with the right event_status which you can work with when displaying posts.
Maybe there is a clever way to achieve this through WP_Query filters but it would need more in-depth investigation inside WP_Query source code as it is not really documented inside the codex.
I thing You use, and try this,
<?php
global $wpdb;
$result = $wpdb->get_results("SELECT *, field1, field2 case when field1+field2 > some_value then 1 else 2 end as my_alias FROM my_table ORDER BY my_alias ASC");
print_r($result);
?>
Look at this Click Here
I am trying to query the database and ordering the result by the date and then by time. But with the query below it only orders by the start time. When I remove the start time it orders the result by date.
So far I have tried changing the order and multiple solutions throughout the web but nothing works.
$args = array(
'numberposts' => -1,
'post_type' => 'reservation',
'cat' => $categorie,
'meta_key' => 'start_time',
'orderby' => array( 'start_date' => 'ASC', 'meta_value_num' => 'ASC' ),
'posts_per_page' => 10,
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'start_date',
'compare' => '>=',
'value' => $date,
),
array(
'key' => 'reservation_status',
'compare' => '<',
'value' => 3,
)
)
);
// query
$the_query = new WP_Query( $args );
Please help.
Thanks
How about something like this:
order => 'start_date start_time',
orderby => 'ASC',
I have some posts with a custom filed named "event_end_date". I am using Advanced custom fields for that. How can I get the posts which have end_date older than today? I was trying with this, but could not get through.
$args = array(
'cat' => '6, -33',
'numberposts' => -1,
'post_type' => 'post',
'meta_query' => array(
array(
'key' => 'event_end_date',
'value' => date('y-m-d'),
'type' => 'DATE',
'compare' => '>'
)
)
);
//get results
$the_query = new WP_Query( $args );
Here I wanted those posts which have category '6' and does not have category '33'. In the backend, the field - 'event_end_date' has these:
Field Type: Date Picker
Display format: 10/11/2014
Return format: 20141110
I think if you were too look more closely at the data being stored in that actual custom/meta field, you'd find that it's stored as a unix timestamp, not in the return or display format, and because of that, your problem is that your format's don't match up.
You can account for that difference by using the U code for unix timestamp with date('U') instead of date('y-m-d').
In that case your code would look like this:
$args = array(
'cat' => '6,-33',
'numberposts' => -1,
'post_type' => 'post',
'meta_query' => array(
array(
'key' => 'event_end_date',
'value' => date('U'),
'type' => 'DATE',
'compare' => '>'
)
)
);
//get results
$the_query = new WP_Query( $args );
Using date('Y-m-d', time()) solved the problem for me.
$args = array(
'category__and' => array(6),
'category__not_in' => array(33),
'numberposts' => -1,
'post_type' => 'post',
'post_status' => 'publish',
'meta_query' => array(
array(
'key' => 'event_end_date',
'value' => date('Y-m-d', time()),
'type' => 'DATE',
'compare' => '<'
)
)
);