2

This seems like a fairly common problem, but I'm posting this as I've yet to find a solution to my problem here on WP Answers - any help is HUGELY appreciated!

Ok - so I have a custom post type of 'events' where I capture the date of the event using a custom field and store it as a unix timestamp. Filtering posts on the front end is not a problem using the following code to show future events only:

$events = new WP_Query( 'post_type=events&posts_per_page=-1&meta_key=date_value&orderby=meta_value&meta_compare=>=&meta_value='.time().'&order=ASC' );

I've tried to filter the results in the admin in the same way using a pre_get_posts filter:

function events_pre_get_posts($query) {
  if (is_admin()) {
    if (isset($query->query_vars['post_type'])) {
      if ($query->query_vars['post_type'] == 'events') {
          $query->set('meta_key', 'date_value');
          $query->set('orderby', 'meta_value');
          $query->set('meta_compare', '>=');
          $query->set('meta_value', time());
          $query->set('order', 'ASC');
      }
    }
  }
}
add_filter('pre_get_posts' , 'events_pre_get_posts');

But in the admin this code just makes all my posts disappear!

I'm also trying to find a way to show past events in the back end and I'm really stuck there too! I not sure the best way to do this - perhaps a toggle on the 'events' posts page to view past / future events.

Help!!

2 Answers 2

2

Second try: ;-)

pre_get_posts runs AFTER parse_query(). parse_query() transforms 'meta_key' etc. into 'meta_query'. get_posts() doesn't seem to react on 'meta_key' etc. directly. So try adding $query->parse_query() after your $query->set() calls or use filter that runs before parse_query (edited, the parse_query() filter doesn't work, either - it runs too late).

Edit: to do the switch:

function my_timeswitch() {
    $operators = array(
        '>=' => 'future',
        '<=' => 'past'
    );
    ?>
    <select name='meta_compare'>
        <?php
            foreach ($operators as $k => $v) {
                printf( "<option %s value='%s'>%s</option>\n", selected($_GET['meta_compare'], $k, false), esc_attr($k), __($v));
            }
        ?>
    </select>
    <?php
}
add_action('restrict_manage_posts', 'my_timeswitch');

This may work just on it's own. If not, you'll have to change the name to something else, then register a new public query variable via the query_vars filter and then react on it via the parse_query filter.

13
  • 1
    Why not just add that to the original answer?
    – t31os
    Commented Feb 26, 2011 at 13:07
  • Hang on - it does work! I add $query->parse_query() after all the other query stuff and it now only displays event that have yet to occur! Wicked - thanks so much @wyrfel! --- BTW, any idea if it's possible to toggle the query on the admin side between past and upcoming events?! Commented Feb 26, 2011 at 13:53
  • @t31os I wasn't sure how to best go about it. What's wrong with two answers if they are truely distinct answers? Basically, i decided for a second rather than editing, because it was a very distinct answer and it left the 'comment-story' on the first one intact.
    – wyrfel
    Commented Feb 26, 2011 at 15:09
  • @Richard Sweeney: Sure you can build a switch that applies a different filter. All depends on how and when you're adding the filter. You can also do both at the same time, i think, if you depend on the new 'meta_query' query value of 3.1, as that allows several meta queries at once, if i get it right.
    – wyrfel
    Commented Feb 26, 2011 at 15:13
  • @wyrfel I find stack exchange confusing - I'm sure there must be a better way to present different answers or edits and these comments (rather than 'answers') kinda suck! I keep hitting enter by force of pure habit! Might you have time and/or energy to point me in the right direction regarding how to go about constructing a switch statement to toggle views? I'm rather a php/WordPress noob I'm afraid to say! Cheers Commented Feb 26, 2011 at 15:43
0

Use current_time('mysql') instead of time().

time() returns a unix timestamp (that is an integer), current_time('mysql') returns a mysql timestamp.

2
  • Cheers @wyrfel, the value is in fact stored as a unix timestamp, so time() works ok actually. Commented Feb 26, 2011 at 11:40
  • @Richard Sweeney: I see, was jumping to conclusions...see second answer.
    – wyrfel
    Commented Feb 26, 2011 at 12:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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