0

I've tried every combination of examples here on the boards and nothing seems to get me what I need. I have an events post type with multiple fields in a custom meta box, one of which is a date field that saves in the form yyyymmdd. I need to query only the events that occur today and in the future, and sort in ASC order by date field. This will be used in a custom post type archive page.

Metabox function:

function events_metabox() {
global $post;
$typename = 'events';

$meta = get_post_meta($post->ID, $typename, true);

$date = ( !empty( $meta['date'] ) ) ? $meta['date'] : '';
$start = ( !empty( $meta['start'] ) ) ? $meta['start'] : '';
$end = ( !empty( $meta['end'] ) ) ? $meta['end'] : '';
$location = ( !empty( $meta['location'] ) ) ? $meta['location'] : '';
$form = ( !empty( $meta['form'] ) ) ? $meta['form'] : '';

wp_nonce_field( $typename, $typename . "-nonce" );
?>
<script type="text/javascript">
    jQuery(document).ready(function() {
        jQuery('#events_date').datepicker({
        dateFormat : 'yymmdd'
        });
    });

</script>
<div class="field">
    <label for="<?php echo $typename; ?>_address">Location:</label>
    <textarea id="<?php echo $typename; ?>_address" name="<?php echo $typename; ?>[location]" class="widefat"><?php echo $location; ?></textarea>
    <em class="field-summary summary">Event location.</em>
</div>
<div class="field">
    <label for="<?php echo $typename; ?>_phone">Event Date:</label>
    <input type="text" id="<?php echo $typename; ?>_date" name="<?php echo $typename; ?>[date]" value="<?php echo $date; ?>" />
    <em class="field-summary summary">Event date.</em>
</div>
<div class="field">
    <label for="<?php echo $typename; ?>_email">Start Time:</label>
    <input type="text" id="<?php echo $typename; ?>_start" name="<?php echo $typename; ?>[start]" value="<?php echo $start; ?>" />
    <em class="field-summary summary">Start time of event.</em>
</div>
<div class="field">
    <label for="<?php echo $typename; ?>_email">End Time:</label>
    <textarea id="<?php echo $typename; ?>_end" name="<?php echo $typename; ?>[end]"><?php echo $end; ?></textarea>
    <em class="field-summary summary">End time of event.</em>
</div>
<div class="field">
    <label for="<?php echo $typename; ?>_form">Web Form:</label>
    <textarea id="<?php echo $typename; ?>_form" name="<?php echo $typename; ?>[form]" class="widefat"><?php echo $form; ?></textarea>
    <em class="field-summary summary">Web Form.</em>
</div>
<?php } ?>

Function saving the custom meta fields:

function events_save_meta($post_id, $post) {
$typename = 'events';
$id = $post->ID;    

if(!isset($_POST[$typename])){
    return $id;
}

$meta = $_POST[$typename];

if (!wp_verify_nonce($_POST[$typename . "-nonce"], $typename)) return $id;

if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE )
    return $id;

if( $typename != $_POST['post_type'] )
    return $id;

update_post_meta($id, $typename, $meta);
}

Post Query:

 $args = array(
 'post_type'   => 'events',
 'meta_key' => 'date',
 'orderby' => 'meta_value_num',
 'order' => 'ASC',
 'meta_query' => array(
  array(
     'key' => 'date',
     'value' => date('Ymd'),
     'compare' => '>=',
     'type' => 'NUMERIC'
  )
 )
);

$events_query = new WP_Query( $args );
  • 2
    What have you tried to order the posts by this meta value? If you're 100% sure that your meta_key is saving the date in a YYYYMMDD format, then the meta_query should be fairly simple and we would need to see that. – Howdy_McGee Apr 25 '14 at 15:25
  • What Howdy_McGee said was right. Have you tried using custom field query from the codex? codex.wordpress.org/Class_Reference/… – sri Apr 25 '14 at 15:29
  • I'd guess you need to switch the type to numeric. You can't do >= comparisons on strings. – helgatheviking Apr 29 '14 at 15:14
  • 1
    you can't store the date in an array under a single key if you want to query on it. the date has to be stored under its own key. – Milo Apr 29 '14 at 16:11
  • 1
    @Howdy_McGee, yes that was my mistake copying something from another post I was looking at. I have corrected the code per your suggestions but still have the same result. I guess I'll have to date to its own key. – user50806 Apr 29 '14 at 16:27
1

You are not querying/saving the correct meta_key. For example, looking at your code, you pass $typename variable to update_post_meta() as meta_key and $typename = 'events'. But later in the query you are querying for meta_key = date. Also, you pass $meta as meta_value and in your actual code $meta is an array containing multiple values (location, date, start, etc).

 $typename = 'events';
 //$_POST[$typename] is actually an array
 $meta = $_POST[$typename];
 ......
 .....
 update_post_meta($id, $typename, $meta);

If you don't touch the HTML of the meta box, you have to change the saving code and the query. For example:

add_action('save_post', 'events_save_meta');
function events_save_meta($post_id) {

    $typename = 'events';

    if ( isset($_POST['post_type']) && 'events' == $_POST['post_type'] ) {
            //You may need to change 'edit_post' for the correct capability set when register 'events' post type
        if ( !current_user_can( 'edit_post', $post_id ) ) {
                 return;
            }
    }

    if( !isset( $_POST[$typename . "-nonce"] ) || !wp_verify_nonce($_POST[$typename . "-nonce"], $typename) ) {
            return;
    }

    if( isset($_POST[$typename]['date']) ) {
         update_post_meta($post_id, 'date', $_POST[$typename]['date']);
    } else {
         delete_post_meta($post_id, 'date');
    }

 }

Now you have a meta field with meta_key = 'date' and you can query for this meta_key:

 $args = array(
      'post_type'   => 'events',
      'meta_key' => 'date',
      'meta_value' => current_time('Ymd'),
      'meta_compare' => '>=',
      'orderby' => 'meta_value_num',
      'order' => 'ASC'
      );

 $events_query = new WP_Query( $args );

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.