Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

What I've been attempting to write is a function that will allow me to sort a list of WordPress posts by their meta values start date, end date and all dates in between.

I've set up a custom metabox with three fields:

  • Name of the event (ID evenement-name)
  • Start date of event (ID evenement-datum-start), stored as YY-mm-dd
  • End date of the event (ID evenement-datum-end), stored as YY-mm-dd

What I'd like to have is a list of events that would take place in the future, grouped by year, month and day.

Example:

  • Event A takes place from 2013/11/24 till 2013/11/26
  • Event B takes place on 2013/11/25

Example result:

2013

November

24

Event A

25

Event A

Event B

26

Event A

Unfortunately, that all sounds so much easier in theory.

I did manage to get the metaboxes working and run query to return a list of posts of which the meta value evenement-datum-end is today or in the future. I even managed to get a list of all dates between evenement-datum-start and evenement-datum-end, so what I now have is this:

2013/11/24 - Event A

2013/11/25 - Event A

2013/11/26 - Event A

2013/11/25 - Event B

My code:

//This is the function I use to get all the dates between the start date and the end date:
function getDateRange($startDate, $endDate, $format="Y-m-d"){
    //Create output variable
    $datesArray = array();
    //Calculate number of days in the range
    $total_days = round(abs(strtotime($endDate) - strtotime($startDate)) / 86400, 0) + 1;

    //Populate array of weekdays and counts
    for($day=0; $day<$total_days; $day++)
    {
        $datesArray[] = date($format, strtotime("{$startDate} + {$day} days"));
    }
    //Return results array: de inhoud van de array wordt uitgelezen 
    return $datesArray;
}


//Query
$args = array ( 
    'cat'               => '1,6',
    'post_type'         => 'post', 
    'meta_key'          => 'evenement-datum-start',
    'posts_per_page'    => -1,
    'meta_query'        => array(
        array(
            'key'       => 'evenement-datum-end',
            'value'     => date('Y-m-d'),
            'compare'   => '>=',
            'type'      => 'DATE'
        )
    ),
 );

$agenda_query_full = new WP_Query ( $args );


if ( $agenda_query_full->have_posts() ) {
echo '<ul>';

    while ( $agenda_query_full->have_posts() ) {
        $agenda_query_full->the_post();

        $meta_event_name    = get_post_meta( get_the_ID(), 'evenement-name', true );
        $meta_event_start   = get_post_meta( get_the_ID(), 'evenement-datum-start', true );
        $meta_event_end     = get_post_meta( get_the_ID(), 'evenement-datum-end', true );
        $dateRange      = getDateRange($meta_event_start, $meta_event_end); 

        asort($dateRange);
        $today              = date('Y-m-d');

        foreach ($dateRange as $key => $val) {
            $datum      = date("d-m-Y", strtotime($val));   

            if($val>=$today) {

                if(in_category( 'acties' ) ){
                    echo '<li>'.$datum.' - <a href="' . get_page_link() . '">' . $meta_event_name . '</a></li>';
                }
                else {
                    echo '<li>'.$datum.' - ' . $meta_event_name . '</li>';
                };
            };
        }
    }
    echo '</ul>';
} else {
    echo 'No events found.';
}

wp_reset_postdata();

As I understand it, and I'm only a beginner at PHP, is that I can't query for a list of dates before I run the loop. But when I do run the loop, I can't get the dates to be sorted chronologically, because I've already retrieved a single post. Impasse reached.

I've been working on this for several days now and getting desperate... Any help?

share|improve this question
    
A couple of possible hints- you can order your query by start or end date so you get them in chronological order, and you can run and rewind a loop as many times as you want. –  Milo Nov 11 '13 at 15:53
    
I had no idea such a thing as rewind_posts() existed. Will remember this for the next project. –  Yvonne Nov 14 '13 at 14:46

1 Answer 1

up vote 0 down vote accepted

I think you can do the trick running 2 loops, in the first you prepare an helper array of posts ordered by date, in the second you display this array:

Something like this (completely untested):

if ( $agenda_query_full->have_posts() ) {
  $date_events = array(); // helper array
  $today = date('Y-m-d');
  while ( $agenda_query_full->have_posts() ) {
    $agenda_query_full->the_post();
    global $post;
    $metas = get_post_custom();
    // save event name in the post object
    $post->ename = array_pop( $metas['evenement-name'] ); 
    $meta_event_start = array_pop( $metas['evenement-datum-start'] );
    $meta_event_end = array_pop( $metas['evenement-datum-end'] );
    $dateRange = getDateRange( $meta_event_start, $meta_event_end ); 
    asort($dateRange);
    foreach ( $dateRange as $date ) {
      if( $date < $today ) continue; // skip past events
      if ( ! isset($date_events[$date]) ) $date_events[$date] = array();
      $date_events[$date][] = $post; // put post in helper array that is keyed by date
    }
  }
  if ( ! empty($date_events) ) {
    foreach ( $date_events as $date => $events ) {
      $datum = date( "d-m-Y", strtotime($date) );
      echo '<h3>' . $datum . '</h3>';
      echo '<ul>'; 
      foreach ( $events as $event ) {
        if( in_category( 'acties', $event ) ){
        echo '<li><a href="' . get_page_link( $event->ID ) . '">' . $event->ename . '</a></li>';
        } else {
        echo '<li>' . $event->ename . '</li>';
        };
      }
      echo '</ul>';
    }
  } else {
    echo 'No events found.';
  }
} else {
    echo 'No events found.';
}
wp_reset_postdata();
share|improve this answer
    
I ended up using this suggestion and it worked almost perfectly! :D The only things that I ended up changing were replacing asort($dateRange); with ksort($date_events); and moving it to right after if ( ! empty($date_events) ) {. Thanks! –  Yvonne Nov 14 '13 at 14:45
    
You're welcome, @Yvonne –  G. M. Nov 14 '13 at 15:16

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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