Ask your WordPress questions! Pay money and get answers fast! (more info)

Get next event after today WordPress

Trying to patch some issues on an inherited site and can't figure out how to get an event query to show only events forward of today.

Currently looks like this:

http://pastebin.com/fKyGVydc

Echoing the 'bds_event_dates' custom field (at the bottom of the pastebin) gets this:

20130930|a:7:{s:4:"from";s:10:"2013-09-30";s:2:"to";s:10:"2013-09-30";s:5:"multi";i:0;s:9:"recurUnit";s:3:"all";s:10:"recur_days";a:0:{}s:11:"recur_every";s:1:"1";s:15:"recur_every_day";s:3:"Sun";}

I think I just want the first eight characters, but I'm not sure how to get those into the wp_query meta_query.

Thanks,
CW

Answers (2)

2013-04-03

Kyle answers:

So you just want the 20130930 value?


Christopher comments:

I think that what I need is for that value to be the compare value in the meta_query.


Kyle comments:

I think it may be better to filter the posts after you do the query, rather than trying to adjust/filter the custom field in the middle of the query.


Kyle comments:

So strip down your query:

$homeeventquery = new WP_Query( array(
'post_type' => 'event',
'posts_per_page' => '1',
'meta_key' => 'bds_event_dates',
'orderby' => 'meta_value_num',
'order' => 'DESC'
) );

if ($homeeventquery->have_posts()) : while ($homeeventquery->have_posts()) : $homeeventquery->the_post();

$eDates = get_post_meta($post->ID, 'bds_event_dates', true);
$time = get_post_meta($post->ID, 'bds_event_time', true);
$dateInfo = unserializeDate($eDates);
$nextDate = ll_find_next_date($dateInfo);
$month = date('M', strtotime($nextDate));
$day = date('j', strtotime($nextDate));
$year = date('Y', strtotime($nextDate));


Then go ahead and compare the dates, and only display the ones with future dates:

if ($dateInfo > time()){ //check if the event is in the future, if it is then do your stuff

<p><?php the_post_thumbnail( array(60,60), array('class' => 'alignright') ); ?>
<strong><?php the_title(); ?></strong><br />
<a class="answer" href="<?php the_permalink(); ?>">Event details &raquo;</a></p>
<p><?php echo date("M. j, Y",strtotime($dateInfo["from"])); ?></p>

<!-- Test what the custom field spits out -->
<?php echo get_post_meta($post->ID, 'bds_event_dates', true); ?>

}

<?php endwhile; endif; wp_reset_query(); ?>


I'm not sure what some of the variable outputs look like, but as long as you can get a time string from the custom fields, you should be good. Is the unserialize function outputting a clean timestring?


Kyle comments:

If the unserialize is not working, you can clean out $eDates = get_post_meta($post->ID, 'bds_event_dates', true); like this:

$eDates = get_post_meta($post->ID, 'bds_event_dates', true);
$ex_val = explode ("|",$eDates);
$clean_val = $ex_val[0];


That will take only the part of the variable output in front of the "|"

You may need to add this too to compare to time:

$final_val = strtotime($clean_val);


Kyle comments:

Let me know how that goes


Christopher comments:

$dateInfo echoes Array
$nextDate echoes YYYY-MM-DD

Using $dateInfo in that 'if' doesn't seem to have any impact, first post is still shown (Oct. 2012)
Using $nextDate returns nothing at all


Kyle comments:

time() is a string so to compare to it we need to convert the $nextDate timestamp to a string:

$nextDate2 = strtotime($nextDate);

Then put $nextDate2 in the If statement. (You may want to echo it out too to test)


Christopher comments:

Tried every permutation of this I could think of, but I wonder if the 'if dateInfo' will always be true if the query is ordering by DESC date (and thus show the event furthest in the future) and never true if ordering by ASC (because the first, and only, post that the query returns will be in the past).


Kyle comments:

The order shouldn't matter.

Can you echo time() and $nextDate2 and see what is spit out


Christopher comments:

time echoes out 1365019450

$nextDate2 echoes nothing


Kyle comments:

Okay, let's start working backwards then

When you said nextDate echoes YYYY-MM-DD did you mean that is literally what it echoes? or that it echoes a date in that format?


Kyle comments:

I have no idea what ll_find_next_date() is or what it is returning, and we don't really need it so let's skip all the way back and do it properly from the start. Make sure this is still in somewhere:

$ex_val = explode ("|",$eDates);
$clean_val = $ex_val[0];
$final_val = strtotime($clean_val);

Try $final_val in the If statement, and echo it out and let's go from there. There is no reason based on your output for 'bds_event_dates' above that this wouldn't work.


Christopher comments:

It echoes a 0 if the query order is ASC while it echoes a date (the date of the queried post) in that format if the query order is DESC.


Kyle comments:

nextDate or final_val


Christopher comments:

Sorry, those responses got out of order clearly.

Echoing $final_val gives us 1380499200 if I change the query order to DESC. If I leave it as ASC, it returns nothing at all.


Kyle comments:

Was the If statement working with DESC then? Does the order matter much, if the primary goal is to display forward events then DESC would work wouldn't it.

You could also change the query to this only:

$homeeventquery = new WP_Query( array(
'post_type' => 'event',
'posts_per_page' => '1' ));

Trying to order by a value that is half serialized is probably causing problems. Let me know what it echoes for each then.


Christopher comments:

The if statement returns an event, but it's the event with the furthest date (Sept. 2013) away. I need it it to show the next event after today (based on the date in that custom field).

I have to tell it to orderby the custom field or else it will order the posts by their postdate. If I take out those parts of the query, it just shows the most recently published event and final_val echoes 1367020800.

I think Sebastien is probably on the right path in trying to work it through the meta_query function.

CW


Kyle comments:

Sebastians direction is to completely replace the custom field, which is a tall order, if you can get it to work though that's great.

It may be better, since the only issue is orderby to simply make an orderby filter and adding it to before the query

http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_orderby


Kyle comments:

This is one of the best out there, really allows for some great additions to wp_query


Kyle comments:

^ https://gist.github.com/keesiemeijer/4643765

2013-04-03

Sébastien | French WordpressDesigner answers:

which plugin manage the custom fields ?


Christopher comments:

Not a plugin. Previous developer did all the metaboxes custom.


Sébastien | French WordpressDesigner comments:

First, you can populate a custom field 'clean-date' with the first eight characters of your code like this

add_action('publish_page', 'add_custom_field_automatically');
add_action('publish_post', 'add_custom_field_automatically');
function add_custom_field_automatically($post_ID) {
global $wpdb;

$eDates = get_post_meta($post_ID, 'bds_event_dates', true);
$eDates = explode ("|",$eDates);
$eDates = $eDates[0];

if(!wp_is_post_revision($post_ID)) {
add_post_meta($post_ID, 'clean-date', $eDates, true);
}
}

(add this code in your file functions.php)


So, second :
now you can use the custom field "clean-date" to filter your post like this


$homeeventquery = new WP_Query( array(
'post_type' => 'event',
'meta_query' => array(
array(
'key' => 'clean-date',
'value' => date('Ymd'),
'compare' => '>=',
'type' => 'NUMERIC'
)
),
'posts_per_page' => '1',
'meta_key' => 'bds_event_dates',
'orderby' => 'meta_value_num',
'order' => 'DESC'
) );






Christopher comments:

Does that function work on existing posts (400 or so) or custom post types (events)?


Sébastien | French WordpressDesigner comments:

it's possible with a custom function


Christopher comments:

So what you've provided doesn't?


Sébastien | French WordpressDesigner comments:

this function is ok but you need to publish a post to create the custom fiel clean-date.


Christopher comments:

2 questions:

Will it only work on new posts?
Will it work on the events custom post type?


Sébastien | French WordpressDesigner comments:

1-no, it work with old post but you need to update each post
2-yes


Christopher comments:

Should I be able to see the clean-date in the custom fields of that event (in Admin)? It's not showing up there, though bds_event_dates is.

It also doesn't echo anything on the single event post (I added an echo to the template).


Sébastien | French WordpressDesigner comments:

first, you can use this function to update all existing posts and add the custom fields (populated with your 8 characters) automatically :

function slh_update_posts() {
global $wpdb;
/*here the request to display the value of your custom field (8 characters) */
$yourvalue = "";

$sql = "
INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value)
SELECT ID AS post_id, 'clean-date'
AS meta_key, $yourvalue AS meta_value FROM $wpdb->posts
WHERE ID NOT IN (SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'clean-date')";

$wpdb->query($sql);
}

add_action('init', 'slh_update_posts');


Christopher comments:

Am I supposed to be putting something into this code? I don't see any reference to the bds_event_dates field, but maybe I'm supposed to be pasting it somewhere? Or does this just go in functions.php after the previous code?


Sébastien | French WordpressDesigner comments:

you must add the request to return the value of the field "bds_event_dates" and extract the 8 first characters of this value.

You paste this function in function.php, you go in the backoffice => all posts will be udated.
Before you remove this function and add the first code to add the new custom field for each new post.


Sébastien | French WordpressDesigner comments:

Hi, here is all functions you needs :-)

-First : paste this code in your functions.php file

function slh_update_posts() {
global $wpdb;
$ident = $_GET["post"];

$datas = $wpdb->get_results("
SELECT meta_value from $wpdb->postmeta as postmeta,
$wpdb->posts as posts
where postmeta.post_id = posts.ID
AND posts.ID = $ident
AND postmeta.meta_key = 'bds_event_dates'"
);

$array = get_object_vars($datas[0]);
$value = $array['meta_value'];
$value = explode ("|",$value);
$value = $value[0];


$sql = "
INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value)
SELECT ID AS post_id,
'clean-date' AS meta_key,
'$value' AS meta_value
FROM $wpdb->posts
WHERE ID NOT IN (SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'clean-date')";

$wpdb->query($sql);
}

add_action('init', 'slh_update_posts');


Before, go to you backoffice. All posts will be updated with a new custom field "clean-date". This custom field will be populated with the first eight characters of the custom field "bds_event_dates".

2-Second : remove this code from your functions.php file.
Paste this new code now :

add_action('publish_page', 'slh_add_custom_field_automatically');
add_action('publish_post', 'slh_add_custom_field_automatically');
function slh_add_custom_field_automatically($post_ID) {
global $wpdb;

$eDates = get_post_meta($post_ID, 'bds_event_dates', true);
$eDates = explode ("|",$eDates);
$eDates = $eDates[0];
if(!wp_is_post_revision($post_ID)) {
add_post_meta($post_ID, 'clean-date', $eDates, true);
}
}

This code will create a custom field "clean-date", populated with the first eight characters of the custom field "bds_event_dates", for all <strong>new</strong> posts.


Sébastien | French WordpressDesigner comments:

3-third :
now you can use the custom field "clean-date" to filter your post like this
$homeeventquery = new WP_Query( array(
'post_type' => 'event',
'meta_query' => array(
array(
'key' => 'clean-date',
'value' => date('Ymd'),
'compare' => '>=',
'type' => 'NUMERIC'
)
),
'posts_per_page' => '1',
'meta_key' => 'bds_event_dates',
'orderby' => 'meta_value_num',
'order' => 'DESC'
) );