CMB2 sort data by date on CPT with WP_Query

1.2k views Asked by At

Hi Im trying to sort Workshop events by date of event? I'm able to sort data by other meta_key as town, leader, country ect. but not by date of event.

There is meta "country" but because they are next to each other there is no difference in UTC.

In CBM2 function I have set field "date" that is part of meta box function.php

<!-- language: lang-php -->
        $cmb_data->add_field( array(
            'name'        => __( 'Event Date', 'workshops' ),
            'desc'        => __( 'Event Date', 'workshops' ),
            'id'          => $prefix . 'event_date',
            'type'        => 'text_date',
            'date_format' => 'd-m-Y',
    ) ) ;

And here is CPT template workshops.php

<!-- language: lang-php -->
      <section id="" class="">
                    <div class="">
                        <?php
                        $args = array(
                            'post_type'      => 'workshops',
                            'posts_per_page' => 10,
                            'meta_key'       => 'workshop_data_event_date',
                            'orderby'        => 'meta_value',
                            'order'          => 'DESC'
                        );

                        $articles = new WP_Query( $args );

                        if ( $articles->have_posts() ) : $articles->the_post();
                            echo '<div class="cptul-stripe-2 article-post__stats">';
                            foreach ( $articles->posts as $article ) {
    //                            var_dump($article);
                                echo '<div class="cptli-stripe-2__wrap">
                                <div class="cptli-stripe-2--header">
                                <div><span class="name">'
                                     . get_post_meta( $article->ID, 'workshop_data_leader', true )
                                     . '</span>
                                <span class="nameWhat"> povede workshop</span>
                                </div>
                                        <a class="stripe-title-mid" href="' . get_permalink( $article->ID ) . '">'
                                     . $article->post_title . '</a> 
                                         <ul>
                                            <li id="event-date" class="article-post__event-date"><span 
                                            class="article-post__stats-icon">'
                                     . webovkar_get_svg( array( 'icon' => 'calendar' ) ) . '</span>'
                                     . get_post_meta( $article->ID, 'workshop_data_event_date', true ) .

                                     '</li><li class="article-post__event-town"><span class="article-post__stats-icon"> '
                                     . webovkar_get_svg( array( 'icon' => 'mmarker' ) ) . '</span>'
                                     . get_post_meta( $article->ID, 'workshop_data_town', true ) . ' | '
                                     . get_post_meta( $article->ID, 'workshop_data_country', true ) .
                                     '</li></ul> </div>


                                     <div class="cptli-stripe-2--data">'
                                     . apply_filters( 'the_content', get_post_meta( $article->ID, 'workshop_data_excerpt',
                                        true ) ) .
                                     '</div>
                                    </div>';
                            }
                            echo '</div>';
                        endif; ?>
                        <?php wp_reset_postdata(); ?>
                    </div>
                </section> 
2

There are 2 answers

0
Stan Skrivanek On BEST ANSWER

After playing with code a bit I have find solution that is working for me but I don't know if it's right code style. I had to move to timestamp land to make it work.

$args = array(
    'post_type' => 'workshops',
    'meta_query' => array(
        array(
            'key' => 'workshop_data_event_date',
            'value' => current_time('timestamp'),
            'compare' => '>'
        )
    ),
    'meta_type' => 'text_date_timestamp',
    'orderby'   => 'meta_value_num',
    'order'     => 'DESC'
);

In foreach loop is

$datum = get_post_meta( $article->ID, 'workshop_data_event_date', true );

and Im using date() to convert UNIX to date format for front-end by echoing

date('d-m-Y', $datum)

EDIT: Because I need to show on front page events that will happened in upcoming 30 days I have add this Query to front page.

$today = current_time('timestamp');
$featuremonth = current_time('timestamp') + 2629743 ; // num = UNIX 30 days
$meta_query = array(
    'value' => array( $today, $featuremonth),
    'compare'   => 'BETWEEN',
    'type'      => 'NUMERIC'
);
    $args = array(
        'post_type'      => 'workshops',
        'posts_per_page' => -1,
        'meta_key'       => 'workshop_data_event_date',
        'orderby'        => 'meta_value',
        'order'          => 'DESC',
        'meta_query'     => array( $meta_query )
    );

$articles = new WP_Query( $args );
0
John Ellmore On

I don't remember offhand how CMB2 stores date fields in the database, but you can use WP_Query's advanced meta_query options to specify the type of the custom field as a date.

From the docs (emphasis mine):

meta_query also contains one or more arrays with the following keys:

  • key (string) - Custom field key.
  • value (string|array) - Custom field value. [...]
  • compare (string) - Operator to test. [...]
  • type (string) - Custom field type. Possible values are 'NUMERIC', 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED'. Default value is 'CHAR'. You can also specify precision and scale for the 'DECIMAL' and 'NUMERIC' types (for example, 'DECIMAL(10,5)' or 'NUMERIC(10)' are valid).

The 'type' DATE works with the 'compare' value BETWEEN only if the date is stored at the format YYYY-MM-DD and tested with this format.

If your dates are stored as Unix timestamps, compare with them numerically. If they're stored as date values, use DATE or DATETIME.