Support

Account

Home Forums General Issues Sorting using ACF Date field Reply To: Sorting using ACF Date field

  • You can only order the posts a specific field once.

    The only way you can accomplish what you want to do, having past events after current future events would be to do 2 queries.

    
    // current and future
    $meta_query = array(
      'relation' => 'OR',
      'event_start' => array(
        'key' => 'start_date',
        'value' => $now,
        'compare' => '>=',
        'type' => 'DATETIME'
      ),
      'event_end' => array(
        'key' => 'end_date',
        'value' => $now,
        'compare' => '>=',
        'type' => 'DATETIME'
      )
    );
    $orderby = array(
      'event_start' => 'ASC',
      'event_end' => 'ASC'
    );//
    
    
    // past events
    $meta_query = array(
      'event_end' => array(
        'key' => 'end_date',
        'value' => $now,
        'compare' => '<',
        'type' => 'DATETIME'
      )
    );
    $orderby = array(
      'event_end' => 'ASC'
    )
    

    I’m not sure how else to explain this. “start_date” and “end_date” is each one field. It does not matter how many clauses you add to the meta query, the posts can only be ordered by the field once. Your query is basically returning ALL event posts, no matter what the dates are and ordering them by the first 2 clauses in your orderby. The second 2 clauses have no effect because the posts have already been ordered by the fields that they refer to.

    In the end you cannot get the order that you want based on a single query and to be quire honest, I do not believe that what you want can be achieved without a significant amount of work.

    There is one way that I can see this being done but it means that your main query would need to do 3 queries. I am assuming this is on the main query and in a pre_get_posts filter because you are using query->set()

    
    // $post__in will collect the post IDs in the order to display
    $post__in = array();
    
    // query all current and future posts
    // returning only an array of ID values
    $current_future_args = array(
      'post_type' => 'event',
      'posts_per_page' => -1,
      'fields' => 'ids',
      'meta_query' => array(
        'relation' => 'OR',
        'event_start' => array(
          'key' => 'start_date',
          'value' => $now,
          'compare' => '>=',
          'type' => 'DATETIME'
        ),
        'event_end' => array(
          'key' => 'end_date',
          'value' => $now,
          'compare' => '>=',
          'type' => 'DATETIME'
        )
      ),
      // order current => future posts how you want them
      'orderby' => array(
        'event_start' => 'ASC',
        'event_end' => 'ASC'
      )
    );
    $current_future = new WP_Query($current_future_args);
    if (count($current_future_args->posts)) {
      $post__in = $current_future_args->posts;
    }
    
    // query past events returning IDs
    $past_args = array(
      'post_type' => 'event',
      'posts_per_page' => -1,
      'fields' => 'ids',
      'meta_query' => array(
        'relation' => 'OR',
        'event_start' => array(
          'key' => 'start_date',
          'compare' => 'EXISTS'
        ),
        'event_end' => array(
          'key' => 'end_date',
          'value' => $now,
          'compare' => '<',
          'type' => 'DATETIME'
        )
      ),
      // order past posts how you want them
      'orderby' => array(
        'event_start' => 'DESC',
        'event_end' => 'DESC'
      )
    );
    $past = new WP_Query($past_args);
    if (count($past->posts)) {
      // mergs past events in post__in
      $post__in = array_merge($post__in, $past->posts);
    }
    
    // set post__in and orderby for main query
    if (!empty($post__in)) {
      $query->set('post__in', $post__in);
      $quert->set('orderby', 'post__in');
    }