I have a custom post type 'events'. Each event (post) can have several dates. The dates (date, time, location) are stored as array. I need a <strong>query that creates a chronological list of all events from the meta data</strong> (The crux: events can occur several times).
This is how the meta-box looks like: [[LINK href="http://i.imgur.com/h5zCd.png"]]Screenshot of meta-box[[/LINK]]
The resulting database entry in wp_postmeta has the metakey _events_termine with the following meta_value (using [[LINK href="http://farinspace.com/wpalchemy-metabox/"]]WPAlchemy[[/LINK]]):
a:1:{s:12:"termin_group";a:2:{i:0;a:3:{s:11:"termin_date";s:10:"2011/03/14";s:11:"termin_time";s:5:"19.30";s:15:"termin_location";s:15:"Max-Reger-Halle";}i:1;a:3:{s:11:"termin_date";s:10:"2011/03/15";s:11:"termin_time";s:5:"20.00";s:15:"termin_location";s:15:"Max-Reger-Halle";}}}
I display the dates for a single event with the following code:
<table>
<?php global $events_meta_termine;
$meta = get_post_meta(get_the_ID(), $events_meta_termine->get_the_id(), TRUE);
foreach ($meta['termin_group'] as $termin)
{ ?>
<tr>
<td><?php echo mysql2date('D', $termin['termin_date'], true); ?></td>
<td><?php echo mysql2date('j. F Y', $termin['termin_date'], true); ?></td>
<td><?php echo $termin['termin_time']; ?> Uhr</td>
<td><?php echo $termin['termin_location']; ?></td>
</tr>
<?php } ?>
</table>
The output looks like this:
<strong>MO</strong> 14. März 2011 19.30 Uhr Max-Reger-Halle
<strong>DI</strong> 15. März 2011 20.00 Uhr Max-Reger-Halle
So everything works fine except i need to create a page that lists all events (title, date, time, location) in chronological order where a single event can occur several times.
The result is a playing schedule for a theatre. Productions play on several dates.
<strong>UPDATE</strong>: The result should look something like this: Screenshot [[LINK href="http://dl.dropbox.com/u/478532/screenshot-playing-schedule.png"]]playing schedule[[/LINK]]
Thank you very much!
Utkarsh Kukreti answers:
Can the same event occur twice in a single day?
http://dl.dropbox.com/u/2164813/clients/wpquestions/1833.php
Christoph comments:
Exactly, i updated the question with a [[LINK href="http://dl.dropbox.com/u/478532/screenshot-playing-schedule.png"]]screenshot of the list[[/LINK]].
Christoph comments:
(Comment above was to previous version of your answer)
The event can occur twice a day, but it is not a requirement that events are sorted by date AND time. I'd be satisfied with just date-sorting.
Utkarsh Kukreti comments:
Please try the code I linked above. There might be some error in it, as I don't have test data.
Could you contact me from my profile, if you want me to try this out directly on your test site?
Hai Bui answers:
Please try this:
<?php
global $events_meta_termine;
$today = getdate();
$my_query = new WP_Query('post_type=event&posts_per_page=-1&monthnum='.$today["mon"]);
$events=array();
while ($my_query->have_posts()) : $my_query->the_post();
$do_not_duplicate = $post->ID;
$meta = get_post_meta(get_the_ID(), $events_meta_termine->get_the_id(), TRUE);
foreach ($meta['termin_group'] as $termin)
{
$event=array();
$event['title']=get_the_title();
$event['date']=$termin['termin_date'];
$event['time']=$termin['termin_time'];
$event['location']=$termin['termin_location'];
$events[]=$event;
}
endwhile;
wp_reset_query();
$i=0;
usort($array, "cmp");
function cmp($a, $b){
return strcmp($a['date'],$b['date']);
}
?>
<table>
<?php foreach ($events as $event){ ?>
<tr>
<td><?php echo $event['title']; ?></td>
<td><?php echo mysql2date('D', $event['date'], true); ?></td>
<td><?php echo mysql2date('j. F Y', $event['date'], true); ?></td>
<td><?php echo $event['time']; ?> Uhr</td>
<td><?php echo $event['location']; ?></td>
</tr>
<?php } ?>
</table>
Christoph comments:
Wow @Hai_Bui, almost there! It has to be usort($events, "cmp");
Could you be so kind as to insert a row with the month name when a new month starts in the table as [[LINK href="http://dl.dropbox.com/u/478532/screenshot-playing-schedule.png"]]shown in the screenshot[[/LINK]]? That would be great! Thank you very much!
Hai Bui comments:
Oh... that was my typo.
Here you go:
<table>
<?php
$current_month='';
foreach ($events as $event){
if ($current_month!=mysql2date('F Y', $event['date'], true))
{
$current_month=mysql2date('F Y', $event['date'], true);
echo '<tr><td colspan="5">'.$current_month.'</td></tr>';
}
?>
<tr>
<td><?php echo $event['title']; ?></td>
<td><?php echo mysql2date('D', $event['date'], true); ?></td>
<td><?php echo mysql2date('j. F Y', $event['date'], true); ?></td>
<td><?php echo $event['time']; ?> Uhr</td>
<td><?php echo $event['location']; ?></td>
</tr>
<?php } ?>
</table>
Christoph comments:
That's it! Thank you very much! I just have seen that Utkarsh above has also a working solution (had a typo too, so it didn't work on copy and paste). His answer was 4 Minutes earlier. What do you expect me to do about the payment?
Hai Bui comments:
I think my solution was more detailed and "completed" :) , considering the post query or the month row... Anyway, it's up to you how to split the prize.
Christoph comments:
That's also my impression. Are you ok with a 60/15 split (60 on your side :)
How can i split the prize?
Hai Bui comments:
That's fair. Thanks ^_^
About splitting the prize: http://www.wpquestions.com/page/static/name/HowToAssignPrizeMoney
Peter Michael answers:
Try to pull (or cast) the date value as timestamp and use PHP's [[LINK href="http://php.net/manual/en/function.asort.php"]]asort[[/LINK]] function on the array.
Christoph comments:
I'm not trying to just sort the dates of one post (event). I need to create a page (custom page template) that lists ALL posts (events) sorted according to the date that's in the date/time/location array. I think i need to create another custom array, pior to listing.
Peter Michael comments:
You want to sort the posts (and events) according to the dates in the 'termin_date' field?
Christoph comments:
Yes, the final list would (simplified) look something like this:
<strong>POST 1</strong> on Feb 3
<strong>POST 2</strong> on Feb 4
<strong>POST 2</strong> on Feb 8
<strong>POST 1</strong> on Feb 13
Peter Michael comments:
Why not set the post date to the earliest event date and sort the event locations like I mentioned before?
Christoph comments:
<strong>(1)</strong> The user should not have to touch the post date.
<strong>(2)</strong> This would give me a list like:
<strong>POST 1</strong> on Feb 3
<strong>POST 1</strong> on Feb 13
<strong>POST 2</strong> on Feb 4
<strong>POST 2</strong> on Feb 8
Peter Michael comments:
You should tell WPAlchemy to store data in [[LINK href="http://farinspace.com/wpalchemy-metabox-data-storage-modes/"]]Extract Mode[[/LINK]].
Also, you need to combine the 'termin_date' and 'termin_time' value and create timestamps. With the post_id/timestamp combination, you can create loops to first order the posts and then the event locations.
Christoph comments:
WPAlchemy 'Extract Mode' does not work with WPAlchemy's have_fields() function, which i use to [[LINK href="http://i.imgur.com/h5zCd.png"]]duplicate the field group[[/LINK]] (date/time/location)
Peter Michael comments:
Use 'have_fields_and_multi($name)' ?
Christoph comments:
Yes, possibility to duplicate the input fields is a requirement.
Peter Michael comments:
You use 'have_fields()' or 'have_fields_and_multi()' ? You should use the latter I think.
Christoph comments:
I use have_fields_and_multi()
Sébastien | French WordpressDesigner answers:
<blockquote>I need to create a page (custom page template) that lists ALL posts (events) sorted according to the date</blockquote>
is it a page for a month ? for a day ?
Christoph comments:
It is a playing schedule for a theatre. Ideally all future posts from custom post type 'event' should be listed, starting with the current month. The date is not the post time stamp but the date from the custom meta box field. That means also one post can occur several times.
Sébastien | French WordpressDesigner comments:
use a query post like this :
$args = array(
'meta_query' => array(
'key' => 'termine_date'
),
'orderby' => 'meta_value_num'
)
query_posts( $args );
Sébastien | French WordpressDesigner comments:
example to display all the posts :
<?php
$args = array(
'meta_query' => array(
'key' => 'termine_date'
),
'orderby' => 'meta_value_num'
)
query_posts( $args );
if (have_posts()) :
while (have_posts()) : the_post();
$termindate = get_post_meta($post->ID, "termine_date", TRUE);
$daytermindate = mysql2date('D', $termin['termin_date'], true);
$datetermindate = mysql2date('j F Y', $termin['termin_date'], true);
$termintime = get_post_meta($post->ID, "termine_time", TRUE);
$terminlocation = get_post_meta($post->ID, "termine_location", TRUE);
if ($daytermindate) {echo $daytermindate;} //if dayterminate exist, echo dayterminedate
if ($datetermindate) {echo $datetermindate;} //if datedayterminate exist, echo datedayterminedate
if ($termintime) {echo $termintime;} //if termintime exist, echo termintime
if ($terminlocation) {echo $terminlocation;} //if $terminlocation exist, echo $terminlocation
<?php
endwhile;
else :
endif;
?>
Christoph comments:
'termin_date' is not stored as individual meta-value. It is in an array with meta_key _events_termine
Sébastien | French WordpressDesigner comments:
a little error above
use this
<?php
$args = array(
'meta_query' => array(
'key' => 'termine_date'
),
'orderby' => 'meta_value_num'
)
query_posts( $args );
if (have_posts()) :
while (have_posts()) : the_post();
$termindate = get_post_meta($post->ID, "termine_date", TRUE);
$daytermindate = mysql2date('D', $termin['termin_date'], true);
$datetermindate = mysql2date('j F Y', $termin['termin_date'], true);
$termintime = get_post_meta($post->ID, "termine_time", TRUE);
$terminlocation = get_post_meta($post->ID, "termine_location", TRUE);
if ($daytermindate) {echo $daytermindate;} //if dayterminate exist, echo dayterminedate
if ($datetermindate) {echo $datetermindate;} //if datedayterminate exist, echo datedayterminedate
if ($termintime) {echo $termintime;} //if termintime exist, echo termintime
if ($terminlocation) {echo $terminlocation;} //if $terminlocation exist, echo $terminlocation
endwhile;
else :
endif;
?>
Christoph comments:
Thank you Sébastien, but as i see it, your query would only work if the dates were stored as individual custom fields with the same meta_key. In fact they are stored as array (see question).
Sébastien | French WordpressDesigner comments:
could i test it ? i need login to your wp-admin
you can send me it at maildeseb @ gmail .com
Sébastien | French WordpressDesigner comments:
It's ok if you create your custom meta bow with 'mode' => WPALCHEMY_MODE_EXTRACT,
There is no problem
Christoph comments:
WPAlchemy 'Extract Mode' does not work with WPAlchemy's have_fields() functions, which i use to [[LINK href="http://i.imgur.com/h5zCd.png"]]duplicate the field group[[/LINK]] (date/time/location)