0

I've been breaking my head over this for days now and can't seem to figure it out (with the limited knowledge I have). I want to achieve the following:

I have a custom post type 'Events'. Each event can take place multiple times per year, so I have custom fields for the dates, let's say 'dateA', 'dateB', 'dateC'. I want to display all the event-date combinations on a page chronologically after checking if the date is in the future.

There are a couple of easy ways to do this, but they have major flaws:

  1. Create separate events for each date, but this would be a nightmare to maintain.

  2. Loop through the events multiple times, first loop displaying the events with dateA, second loop displaying events with dateB etc. This requires all dateB's to be after the last dateA.

So basically what I need to (somehow) do is:

  1. Create unique date event combinations

  2. Compare the dates to the currentdate

  3. Display the future events chronologically by the event date.

Can this be done, and if so, how would I approach it. Any pointers would be greatly appreciated!

  • What format are your dates in? You just want a flat list of all the dates in order, linked to their "single" ? – GhostToast Aug 20 '13 at 19:45
  • The date meta_key is stored as a Unix timestamp. I would like to display a list of events, with event name and aditional meta information (price, etc) ordered by the date. This 'event summary'would indeed link to their 'single'. – Erik Aug 20 '13 at 19:56
  • One sec I will prep something. Have done something similar. – GhostToast Aug 20 '13 at 19:57
1

Here you go, explanations as comments

// setup array to store things in while we loop
$events_out = array();

// assume you already have your loop built the way you want
while($loop->have_posts()) : $loop->the_post();
    $instances = array();
    // grab meta dates
    $instances[] = get_post_meta($post->ID, 'dateA', true);
    $instances[] = get_post_meta($post->ID, 'dateB', true);
    $instances[] = get_post_meta($post->ID, 'dateC', true);

    foreach($instances as $instance){
        if(!empty($instance)){
            // save into outter array with post_id so we can ref more data
            $events_out[] = array(
                'timestamp' => $instance,
                'post_id' => $post->ID,
            );
        }
    }

endwhile;

// use array_msort to sort by date! defined below
$events_sorted = array_msort($events_out, array('timestamp' => SORT_ASC));

// output in order, with whatever meta/stuff you want
foreach($events_sorted as $event){
    echo '<div>';
    echo '<h2>'.get_the_title($event['post_id']).'</h2>';
    echo '<h3>'.date('m/d/Y', $event['timestamp']).'</h3>';
    echo get_post_meta($event['post_id'], 'some_meta_stuff', true);
    echo '<a href="'.get_permalink($event['post_id']).'">Read More</a>';
    echo '</div>';
}

/**
 * array_msort: array_multisort variant
 * use: array_msort($array, array('name'=>SORT_DESC, 'cat'=>SORT_ASC));
 */
function array_msort($array, $cols)
{
    $colarr = array();
    foreach ($cols as $col => $order) {
        $colarr[$col] = array();
        foreach ($array as $k => $row) { $colarr[$col]['_'.$k] = strtolower($row[$col]); }
    }
    $eval = 'array_multisort(';
    foreach ($cols as $col => $order) {
        $eval .= '$colarr[\''.$col.'\'],'.$order.',';
    }
    $eval = substr($eval,0,-1).');';
    eval($eval);
    $ret = array();
    foreach ($colarr as $col => $arr) {
        foreach ($arr as $k => $v) {
            $k = substr($k,1);
            if (!isset($ret[$k])) $ret[$k] = $array[$k];
            $ret[$k][$col] = $array[$k][$col];
        }
    }
    return $ret;
}
  • You are a genius, it works like a charm! Posts are in perfect order. One thing I didn't mention though is that the 'Event summary' should display the eventdate as well, would this be possible? – Erik Aug 20 '13 at 20:22
  • Sure, inside that <div> just do something like echo date('r', $event['timestamp']); where r is replaced with your date format of choice – GhostToast Aug 20 '13 at 20:26
  • i added example in answer. if this works for you, please select this answer as correct. thanks – GhostToast Aug 20 '13 at 20:32
  • You have made me one happy camper, thanks a million for your help. Totally solved it for me! – Erik Aug 20 '13 at 20:35
  • When I add the excerpt to the 'Event Summary' I get the same excerpt for each event. The titles and all other meta info works fine, but the excerpt / content doesn't work. Any idea why this is? – Erik Aug 21 '13 at 9:45
1

Plug-in recommendations are off-topic here, but (and at the risk of bias), I've developed Event Organiser which allows you select arbitrary dates / recurring events, and list them. While not all event management plug-in support arbitrary date, most will have the other features.

But any case, if you wanted to roll your own I strongly recommend against using post meta. Architecturally its just messy, and you'll suffer performance wise. And you've already listed a flaw with this approach. In addition if you edit/remove date this may mean you need to readjust the key-value pairings of the later dates.

I would recommend approach creating a separate table for events, of the form:

date ID   |   post ID    |   timestamp
---------------------------------------
    1     |      1       |      ...
    2     |      1       |      ...   
    3     |      2       |      ...   
    4     |      3       |      ...   
    5     |      3       |      ...   
    6     |      3       |      ...   

you'll then need to alter the SQL query to LEFT JOIN this table onto the posts table using the post ID and wp_posts.ID columns. This is, in a nutshell, what Event Organiser does.

The benefits of this approach is performance (index the columns) - particular for complex date queries. Dates do not have to be entered in order (but when you next edit the event it probably should be presented in order).

  • Creating a separate table makes perfect sense (something I was thinking about), however my knowledge is slightly lacking in this department. I had a look at a number of event plugins, but none had the possibility to add multiple dates (not in a recurring pattern) to an event. I will have a look at your plugin! – Erik Aug 20 '13 at 20:26
  • Your plugin seems to do what I want. I will experiment with the various ways of going about this and have a read through your tutorial on creating tables over on WPTuts+. – Erik Aug 20 '13 at 22:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.