WordPress.org

Forums

[resolved] Query using custom field for event date not working (20 posts)

  1. TrishaM
    Member
    Posted 11 months ago #

    Searched all the posts here related to using custom event dates in queries and didn't find an answer to my specific problem, hoping someone can help.

    I have a custom post type for events, with custom fields to hold the event start date and end date.

    I have query that finds all matching posts and lists them in order of their start date as long as the start date is a future date (old events don't show), however I have two problems:

    The events drop off on the date that they start even though I'm using <= in my query, not just < (they should display through that date and drop off on the following date); and

    For multi-day events, they should remain in the list until the event has ended (the day after the date the event ends) but they still drop off the list on the date that they start;

    Here's my code:

    global $post;
    
    $eventdate = get_post_meta($post->ID,'event_date_start',true);
    $eventdate2 = get_post_meta($post->ID,'event_date_end',true);
    $eventlocation = get_post_meta($post->ID,'event_location',true);
    $eventaddress = get_post_meta($post->ID,'event_location_address',true);
    $eventdirections = get_post_meta($post->ID,'event_location_directions',true);
    $eventcontact = get_post_meta($post->ID,'event_contact',true);
    $eventcontactph = get_post_meta($post->ID,'event_contact_phone',true);
    $eventcontactem = get_post_meta($post->ID,'event_contact_email',true);
    $eventnumdays = get_post_meta($post->ID,'event_number_of_days',true);
    
    $myposts =           get_posts('post_type=event&meta_key=event_date_start&orderby=meta_value_num&order=ASC&posts_per_page=-1');
    foreach ( $myposts as $post ) : setup_postdata( $post );
    
    $today = time();
      if ( $eventnumdays == "Multiple Days" ) {
            $exp_date = strtotime(get_post_meta($post->ID,'event_date_end',true));
      } else {
            $exp_date = strtotime(get_post_meta($post->ID,'event_date_start',true));
      }
    if ($today <= $exp_date) {

    If the custom field for the event_number_of_days is set to Single Day, then there is no custom field created for the end date, so my attempts to use event_date_end failed, which is why I'm using the custom field for number of days instead to determine if the post should expire after the start date or after the end date.

    This query does display the events correctly, just not >>through<< the date they need to be still on the list….

    For example, I have an event going on this weekend - it should show on the list until after midnight on Sunday, since the event goes through Sunday, but since it started on Friday, it already dropped off the list on Friday morning.

    What am I doing wrong?

  2. vtxyzzy
    Member
    Posted 11 months ago #

    I think the problem is that your event dates are stored as Y-m-d without a time. strtotime will convert these as if they are 'Y-m-d 00:00:00' (zero hour, zero minute, zero seconds), whereas time() provides the actual hour, minute, and second.

    So, if an event date is '2014-07-13', strtotime will give 1405209600. Converting that back to a string will give '2014-07-13 00:00:00'.

    Any actual time on that date will have a greater value. To have the compare work the way you want, try adding ' 23:59:59' to the end of the custom meta date, like this:

    $exp_date = strtotime(get_post_meta($post->ID,'event_date_end',true) . ' 23:59:59');
  3. TrishaM
    Member
    Posted 11 months ago #

    @vtxyzzy - many thanks for the great explanation. I do think your solution *should* work, but doesn't……I think that's because the dates are actually stored as yymmdd (e.g. 20140713 for July 13th, 2014, not as 2014-07-13)

    I'm using Advanced Custom Fields plugin's datepicker field on this custom post type, so as to make it easy for whomever is entering events - they just click on the start and end dates on a calendar. In the ACF settings it says to store this field as yymmdd. I did play around with other jQuery formats but had numerous problems then getting a query to return any results at all or to sort them in the correct date order.

    So I'll test out using a Y-m-d format to see if that makes a difference and will report back my results tomorrow.

  4. vtxyzzy
    Member
    Posted 11 months ago #

    The 'yymmdd' format should work the same as 'yyyy-mm-dd', so there must be another problem. I'll take another look.

  5. vtxyzzy
    Member
    Posted 11 months ago #

    Did you add the ' 23:59:59' to both lines that use strtotime?

  6. vtxyzzy
    Member
    Posted 11 months ago #

    Another possibility; the time() function returns GMT time, not local time. Try replacing time() with current_time('timestamp').

  7. vtxyzzy
    Member
    Posted 11 months ago #

    One more thing, be sure that the Timezone is set correctly in Admin->Settings->General.

  8. TrishaM
    Member
    Posted 11 months ago #

    YAAY! Changing time(); to current_time('timestamp'); did the trick.

    Also, I had to move my query above the variables - not sure why, it worked fine before below the query, but after changing the comparison it was not picking up some custom field data for each post, which moving the variables solved.

    SO in case this will help anyone else, here is my working code (I'm including the HTML of what I do with all the custom field data as an example for someone learning how to display future events):

    <?php global $post;
    
    $myposts = get_posts('post_type=event&meta_key=event_date_start&orderby=meta_value_num&order=ASC&posts_per_page=-1');
    foreach ( $myposts as $post ) : setup_postdata( $post );
    
    $eventdate = get_post_meta($post->ID,'event_date_start',true);
    $eventdateend = get_post_meta($post->ID,'event_date_end',true);
    $eventlocation = get_post_meta($post->ID,'event_location',true);
    $eventaddress = get_post_meta($post->ID,'event_location_address',true);
    $eventdirections = get_post_meta($post->ID,'event_location_directions',true);
    $eventcontact = get_post_meta($post->ID,'event_contact',true);
    $eventcontactph = get_post_meta($post->ID,'event_contact_phone',true);
    $eventcontactem = get_post_meta($post->ID,'event_contact_email',true);
    $eventnumdays = get_post_meta($post->ID,'event_number_of_days',true);
    
    $today = current_time('timestamp');
       if ( $eventnumdays == "Multiple Days" ) {
              $exp_date = strtotime(get_post_meta($post->ID,'event_date_end',true) . ' 23:59:59');
       } else {
              $exp_date = strtotime(get_post_meta($post->ID,'event_date_start',true) . ' 23:59:59');
       }
    if ($today <= $exp_date) {
    
    $eventdatestart = strtotime(get_post_meta($post->ID,'event_date_start',true));
    ?>	
    
    <div class="evententry">
    
    <div class="time">
    // Note: separating each date component lets me style the date so it looks like a calendar page //
      <div class="month"><?php echo date('M', $eventdatestart); ?></div>
      <div class="wkday"><?php echo date('l', $eventdatestart); ?></div>
      <div class="day"><?php echo date('d', $eventdatestart); ?></div>
      <div class="year"><?php echo date('Y', $eventdatestart); ?></div>
    </div>
    
    <div class="eventdata">
    <h4><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></h4>
    <div class="eventmeta">
    <div class="left">
    <span>Contact:</span><?php echo $eventcontact; ?><br />
    <span>Method:</span><a href="mailto:<?php echo antispambot($eventcontactem); ?>"><?php echo antispambot($eventcontactem); ?></a> &nbsp;&nbsp; <?php echo $eventcontactph; ?>
    </div>
    </div>
    <?php the_excerpt(); ?>
    </div>
    </div><!-- end .evententry -->
    <hr>
    <?php } endforeach; wp_reset_postdata();?>

    HUGE thanks again, @vtxyxxy for all your excellent help!!

  9. greencode
    Member
    Posted 1 month ago #

    This is brilliant and just what I was looking for!

    Is there any way of adding the Month for events i.e.

    May:
    Event 1
    Event 2

    June:
    Event 3
    Event 4

    Or does that get really complicated?!

  10. vtxyzzy
    Member
    Posted 1 month ago #

    Try changing this:

    $eventdatestart = strtotime(get_post_meta($post->ID,'event_date_start',true));
    ?>

    to this:

    $eventdatestart = strtotime(get_post_meta($post->ID,'event_date_start',true));
          $startmonth = date('M', $eventdatestart);
          if ( $startmonth != $currmonth ) {
             $currmonth = $startmonth; ?>
             <div class="monthheader"><?php echo $startmonth; ?></div>
          <?php }
    ?>
  11. greencode
    Member
    Posted 1 month ago #

    Amazing! Thanks for this. Works perfectly :-)

  12. greencode
    Member
    Posted 1 month ago #

    What I have just noticed with this is if I have

    'posts_per_page' => '-1'

    Everything works correctly and all events show. However if I use

    'posts_per_page' => '8'

    i.e. to limit the amount of events I'd like to show then this doesn't show any events.

    Any ideas?

  13. vtxyzzy
    Member
    Posted 1 month ago #

    The posts_per_page value should not be in quotes.

  14. greencode
    Member
    Posted 1 month ago #

    Thanks @vtxyzzy but that makes no difference.

  15. vtxyzzy
    Member
    Posted 1 month ago #

    It might help if your complete code could be seen. Please put the code in a pastebin, and post a link to it here.

  16. greencode
    Member
    Posted 1 month ago #

    Sorry for the delay in replying. Here's the code with the infinite amount of posts showing (-1) but if I change that to 8, for example, then no posts show.

    <div class="related-posts p-list cf">
    
    <?php
    // Get the posts
    $myposts = get_posts( array(
    	'post_type' => 'event',
    	'meta_key' => 'event_date_start',
    	'orderby' => 'meta_value_num',
    	'order' => 'ASC',
    	'posts_per_page' => '-1',
    	'post__not_in' => array($post->ID),
    ));
     ?>
    <?php foreach ( $myposts as $post ) : setup_postdata( $post );
    
    $eventdate = get_post_meta($post->ID,'event_date_start',true);
    $eventdateend = get_post_meta($post->ID,'event_date_end',true);
    $eventnumdays = get_post_meta($post->ID,'event_number_of_days',true);
    
    $today = current_time('timestamp');
       if( get_field('event_number_of_days') ) {
              $exp_date = strtotime(get_post_meta($post->ID,'event_date_end',true) . ' 23:59:59');
       } else {
              $exp_date = strtotime(get_post_meta($post->ID,'event_date_start',true) . ' 23:59:59');
       }
    if ($today <= $exp_date) {
    
    $eventdatestart = strtotime(get_post_meta($post->ID,'event_date_start',true));
          $startdate = date('d', $eventdatestart);
          $startmonth = date('F', $eventdatestart);
          $startyear = date('Y', $eventdatestart);
    ?>
    <div class="block">
    <a href="<?php the_permalink() ?>" title="<?php the_title() ?>">
    <div class="image">
    <div class="meta-date">
    <div class="date"><?php echo $startdate; ?> <?php echo $startmonth; ?></div>
    </div>
    <?php the_post_thumbnail('medium', array('class' => 'medium')); ?>
    </div>
    <div class="details">
    <h2 class="title"><?php the_title() ?></h2>
    <?php the_excerpt(); ?>
    </div>
    </a>
    </div>
    <?php } endforeach; wp_reset_postdata();?>
    <?php wp_reset_query(); ?>
    
    </div>
  17. vtxyzzy
    Member
    Posted 1 month ago #

    Sorry, but I can't find anything wrong with the code. It works as expected when I test it (as much as I can).

  18. TrishaM
    Member
    Posted 1 month ago #

    Try using numberposts instead of posts_per_page, no quotes around the -1 since it's an integer, not a varchar.

    'numberposts' => -1,

    ***EDIT**
    Sorry, just noticed that you're trying to limit each subgroup (by month) to 8 (?) - what you're trying to do (above) is limit the TOTAL number of posts to 8 when WP does the initial query, then break that down into Months - that won't work.

    You'll need to do an iterative loop......

    FIRST query for ALL events posts using -1 in your args.

    THEN you break it down into mini-foreach loops (foreach $months as $month -- be sure to define '$months'), using a counter ($i = 1; while( have_posts() && $i < 9 ) { )so that when you get to 8, it stops looping *for that month* and goes to the next month.

    Sorry I can't give you the full code - I'm not a coder, but that should be enough to either get you going, or for @greencode or another coder to help.

  19. greencode
    Member
    Posted 1 month ago #

    I'm not trying to limit each subgroup to 8. I am trying to limit all upcoming events to 8.

    I've tried 'numberposts' and 'posts_per_page' but neither work when limiting the amount of posts to a set number i.e. 8

  20. TrishaM
    Member
    Posted 1 month ago #

    I don't think that you can do that, and THEN say "display them categorized by month".....I think the best you can likely do is to display the 8 posts that get returned (assuming you have at least 8 upcoming events) in a list with the month spelled out first, like so:

    May: 05/01/15 - some cool event
    May: 05/25/15 - another cool event
    June: 06/10/15 - crazy cool event

    That would be no more that calling the 'date' of the event twice, and formatting it so that the first instance displays just the month, then a colon, then the second date formatted (however you like it)....

Reply

You must log in to post.

About this Topic

Tags

No tags yet.