Convert ISOdate to phpdate for ACF custom field query - php

I've built a custom beaver builder (wordpress) module. I'm fetching posts via Ajax. I need to query posts based off an ACF custom field date.
I am posting the date in ISO8601 format (eg 2013-12-01T00:00:00-05:00). Server side, I grab the start and end. I convert them into the format needed for the ACF query https://www.advancedcustomfields.com/resources/date-picker/
$start_date = date('Ymd', strtotime($_POST['start']));
$end_date = date('Ymd', strtotime($_POST['end']));
I run the query, and get nothing. I echo the string out, and they look correct.
If I set the date as per the example in the ACF docs - it works (code below). So I must be converting the ISOdate $_POST['start'] incorrectly. How do I convert the ISODATE so that is it something that I can use in the query?
function get_ajax_event_calendar_posts() {
$today = date('Ymd'); // this works...
$args = array(
'post_type' => array('event'),
'meta_query' => array(
array(
'key' => 'start_date',
'compare' => '<=',
'value' => $today,
),
array(
'key' => 'end_date',
'compare' => '>=',
'value' => $today,
)
),
'post_status' => array('publish'),
'posts_per_page' => 100,
'nopaging' => true,
'order' => 'DESC',
'orderby' => 'date'
);
// The Query
$ajaxposts = get_posts( $args );
//... etc
}
** edit **
.... the date stuff wasn't the problem. I was the problem... switched my compares round the right way and all works...

You haven't said what format you actually need to store the data, however you did say date('Ymd') works. Either way, use the DateTime class:
<?php
$x = new DateTime('2013-12-01T00:00:00-05:00');
echo $x->format('d/m/Y H:i:s') . "\n"; // 01/12/2013 00:00:00
echo $x->format('dmY') . "\n"; // 01122013
Here are the date formats https://www.php.net/manual/en/function.date.php

Related

wordpress Wp_query and meta query issue with date field

I have Projects inserted as posts in my WordPress database. currently on my home, the last 3 published project is displayed. now my purpose is that I want first display the project which is expiring today than the last published project.
for example, there are 2 projects are expiring today than on the home page it will display 2 projects which are expiring today and 1 project which published last. it means a total of 3 projects will display.
please check below WP_query which returns last published project only
$args = array('post_type' => 'ignition_product', 'posts_per_page' => $project_count, 'paged' => $paged);
$newargs = apply_filters('project_query', $args);
$wp_query = new WP_Query($newargs);
the below query I try using meta key & value but no luck. "ign_fund_end" is stored a date as a string so I think that's why not comparing date.
my final goal is I described as above total 3 projects should display. first should be today expiring then after last published.
$args = array(
'post_type' => 'ignition_product',
'posts_per_page' => $project_count,
'paged' => $paged,
'meta_query' => array(// WordPress has all the results, now, return only the events after today's date
array(
'key' => 'ign_fund_end', // Check the start date field
'value' => date('m/d/Y'), // Set today's date (note the similar format)
'compare' => '>=', // Return the ones greater than today's date
'type' => 'DATE' // Let WordPress know we're working with date
)
));
please check the below image for reference.
any solution appreciated.
Since your custom field ign_fund_end is not in MySQL date compatible format so that is the main reason for your WP_Query to not work in the expected way. My recommendation is to save a timestamp of end date in a custom field using save_post and then change the $args for WP_Query to work on that field.
Here is complete solution for your issue:
1: Save Timestampe in a Custom field
add_action( 'save_post', function( $post_id ) {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
if ( $parent_id = wp_is_post_revision( $post_id ) ) {
$post_id = $parent_id;
}
if( isset( $_POST['ign_fund_end'] ) && !empty($_POST['ign_fund_end']) ) {
$end_date = $_POST['ign_fund_end'];
$end_date = strtotime($end_date);
update_post_meta( $post_id, '__end_date', $end_date );
}
} );
2: Modify the $args
$args = array(
'post_type' => 'ignition_product',
'posts_per_page' => $project_count,
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_key' => '__end_date',
'paged' => $paged,
'meta_query' => array(// WordPress has all the results, now, return only the events after today's date
array(
'key' => '__end_date', // Check the start date field
'value' => strtotime('today'), // Set today's timestamp
'compare' => '>=', // Return the ones greater than today's date
'type' => 'NUMERIC'
)
));
You just need to remove type from the array parameters.
$args = array(
'post_type' => 'ignition_product',
'posts_per_page' => $project_count,
'paged' => $paged,
'meta_query' => array(// WordPress has all the results, now, return only the events after today's date
array(
'key' => 'ign_fund_end', // Check the start date field
'value' => date('m/d/Y'), // Set today's date (note the similar format)
'compare' => '>=', // Return the ones greater than today's date
'type' => 'DATE' // Let WordPress know we're working with date
)
));
To:
$args = array(
'post_type' => 'ignition_product',
'posts_per_page' => $project_count,
'paged' => $paged,
'meta_query' => array(// WordPress has all the results, now, return only the events after today's date
array(
'key' => 'ign_fund_end', // Check the start date field
'value' => date('m/d/Y'), // Set today's date (note the similar format)
'compare' => '>=', // Return the ones greater than today's date
//'type' => 'DATE' // Let WordPress know we're working with date
)
));
Note: The reason is that in table meta_value is not DATE type.
In the PHPMyAdmin, the default date type is:
2019-04-16

Query month in date custom field on wordpress

I need a query to get all posts that date custom field are before a month sended by URL var. Custom field saves data like YYYYMMDD (20150330). I want to get all post before this year/month (201503).
I try this but it doesn't works, because date_added content it isn't YYYYMM. It contains day too.
$year = $_GET['year'];
$month = $_GET['mes'];
$yearmonth = $month." ".$year;
$args = array (
'post_type' => 'clients',
'posts_per_page' => -1,
'order' => 'ASC',
'orderby' => 'post_title',
'meta_query' => array(
array(
'key' => 'client_type',
'compare' => '=',
'value' => 'Si',
),
array(
'key' => 'date_added',
'compare' => '<=',
'value' => date("Ym", strtotime($yearmonth)),
)
));
$posts = get_posts($args);
Anyone can help me with this?
Thanks
If the date is stored in the database as an integer, then look where date less than date("Ym00", strtotime($yearmonth)) (zeros for day) for everything before March-1 or if you wanted the month of march use "Ym99" to signify a date in march that is greater than the last day but still less than the following month. The date 20150301 as an integer translates to 20,150,301 (twenty million, one hundred fifty thousand, three hundred and one). No date will be below 201,503 so you need to add the day numbers to make them in the same scale.

Wordpress Query by Custom Field with date type

I want to create a query where all posts should be displayed where the custom field "expiration_date' is larger than the date from today.
Short form: if the expiration date of the post is reached, it should no longer displayed in the query
I tried with this snippet:
<?php
$today = date("Y-m-d");
$args= array(
'tag' => 'Pinnwand',
'meta_query' => array(
'key' => 'expiration_date',
'type' => 'DATE',
'value' => $today,
'compare' => '>'
)
);
$my_query = new WP_Query($args); ?>
the expiration date is in the format (2014-10-04) for example.
But I tried also the format "Ymd" on both sides, change the compare type, or set the type as "NUMERIC" and nothing helps. The result is, that the post will always be displayed.
It would be great if somebody could help me!
Okay I found the mistake!
The correct query needs one more array(). I don't know exactly why, but in other cases the query couldn't work with it. So here is the code
$args= array(
'tag' => 'Pinnwand',
'meta_query' => array(
array(
'key' => 'expiration',
'type' => 'DATE',
'value' => $today,
'compare' => '>'
),
),
);
$my_query = new WP_Query($args); ?>
You could do a two-query exclusion. First query finds all the posts you want to exclude, then loop through those and store the post IDs in an array, then call second query excluding them using 'post__not_in' with the ID array as the argument.
I would use the $wpdb object for this because it's very efficient.
For reference material:
http://codex.wordpress.org/Class_Reference/WP_Query and
http://codex.wordpress.org/Class_Reference/wpdb
This chunk of code SHOULD do what you're trying to do or get you close to it, and I kept your tag part of the query in there too.
// first query to find exclusions
$today = date("Y-m-d");
$exclusions = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE expiration_date < ".$today);
if ( $exclusions ) {
foreach ( $exclusions as $exclusion ) {
$excludeIDs[] = $exclusion->ID;
}
}
// second query using exclusion array
$args= array(
'tag' => 'Pinnwand',
'post__not_in' => $excludeIDs,
);
$my_query = new WP_Query($args);
You can do it simpler, as stated on http://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters:
$args= array(
'tag' => 'Pinnwand',
'meta_key' => 'expiration',
'meta_type' => 'DATE',
'meta_value' => $today,
'meta_compare' => '>'
);

Dynamic date variables for custom post type query

I am querying a custom post type called 'events' which has a meta field called 'event_date' which is stored in date format. It is my desire to have three or four separate queries each looking for posts within specific time periods. The first query will be all posts within the current month, then another for the following month, then the month there after, and so on. It is important that they are separate queries and not one.
I am able to query between set dates using the code below but I wish to make these dynamic and be able to add a start date variable and an end date variable based upon the current date. I was thinking of using something similar to this code I came across which does successfully give me the month name but am struggling to use this within my WordPress query.
<?php
$d = new DateTime( 'now' );
$d->modify( 'first day of this month' );
echo $d->format( 'F' ), "\n";
?>
Is there anyway I can integrate dynamic start date date and end date variables which can be current month, +1, +2, +3months, etc as required? I appreciate any help you can provide.
My query code is:
<?php
$args = array(
'post_type' => 'event',
'meta_key' => 'event_date',
'orderby' => 'meta_value_num',
'order' => 'ASC',
'showposts' => 20,
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'event_date',
'value' => '2014-06-01', // Lowest date value
'compare' => '>='
),
array(
'key' => 'event_date',
'value' => '2014-06-31', // Highest date value
'compare' => '<='
)
)
);
$event_posts = new WP_Query($args);
if($event_posts->have_posts()) :
while($event_posts->have_posts()) :
$event_posts->the_post();
?>
POST CONTENT HERE
<?php
endwhile;
else:
?>
Oops, there are no posts.
<?php
endif;
?>
Have a look at http://www.php.net/manual/function.mktime.php.
You can use something like this:
$month_add = 0; // current month, add value for the next months
$low_date = date("Y-m-d", mktime(12, 0, 0, date("n")+$month_add, 1, date("Y")));
$high_date = date("Y-m-d", mktime(12, 0, 0, date("n")+$month_add+1, 1, date("Y")));
Change compare for highest date to:
'compare' => '<'
use this syntax... easy to read and use:
array(
'key' => 'event_date',
'value' => date('Y-m-d',strtotime('+1 month')),
'compare' => '<='
)
have fun playing with it and check out Relative formats for all your possibilities

How do I hide past posts in a custom Wordpress loop AND display X number of upcoming posts?

I'm trying to display a list of posts in Wordpress with dates that are equal to or greater than today - the purpose is to list out upcoming events.
Here's the code I have right now:
// Get the current date
$current_date = date('M d, Y');
$current_date = strtotime( $current_date );
// Get the event date
$post_date = get_the_time('M d, Y');
$post_date = strtotime( $post_date );
query_posts(array('category_name' => 'events',
'meta_query' => array(
array(
'key' => $post_date,
'value'=> $current_date,
'compare'=>'>='
)
),
'showposts' => 4,
'orderby' => 'date',
'order' => ASC));
while (have_posts()) : the_post();
As you can see, I'm grabbing the current date and the date of the post. I know this code works, because I had it functioning mostly in the following format:
// Get the current date
$current_date = date('M d, Y');
$current_date = strtotime( $current_date );
query_posts(array('category_name' => 'events',
'showposts' => 4,
'orderby' => 'date',
'order' => ASC));
while (have_posts()) : the_post();
// Get the date
$post_date = get_the_time('M d, Y');
$post_date = strtotime( $post_date );
// If older than current date, don't show it
if( $post_date >= $current_date ):
But the problem with that is that it finds the posts, then compares them to the current date. So if I want to show 4 of my 10 posts, but 3 are hidden because they're in the past, I'm actually only displaying 1 post here.
I need to compare to the current date then show 4 posts from the result of that calculation.
Any help is greatly appreciated. Thanks!
To do this you can use a date_query as part of your query_posts() call (in place of the meta_query).
This will then eliminate the need to check the date of Posts once a query has been run, so you should always get the four that you are seeking.
$today = getdate();
$args = array(
'date_query' => array(
array(
'year' => $today["year"],
'month' => $today["mon"],
'day' => $today["mday"],
'compare' => '>=',
),
),
'posts_per_page' => 4,
'orderby' => 'date',
'order' => ASC
);
query_posts($args);
Note: I'd strongly recommend reviewing the WP_Query codex for further information as there are some very useful parameters in there. These can help you to further refine the Posts that are returned and include the likes of post_type, post_status and cat. Of course not all of these will be relevant to you in all situations (or possibly at all), but it's still worth a read.
Caution: Please be aware that posts_per_page replaced show_posts some time ago.
Update
You mention in the comments that the above code is working, but only one Post is being retrieved. My initial thoughts are that this is caused by one of two things -
You only have one future Post, and thus there are no more to show.
Something is hooking your query and changing the LIMIT portion.
I suggest viewing the query that was passed to MySQL as soon as it is made. To do this, add the following line directly below query_posts($args) and reload your page. -
global $wpdb;
echo '<pre>'; print_r($wpdb->last_query); echo '<pre>';

Categories