Sort on Presence of Custom Field, Field value, then Date

In order to sort on the presence of a Custom Field, you must use filters to modify the query created by query_posts().

We must join a new instance of the post_meta table, add fields for the sort_key (accounting for NULL) and the new meta_value, and add a new order by.

The code below is sample code and the display of the results must be altered to fit your theme and output needs.

<?php
   // Sort posts in order on presence of a custom field,
   // value of custom field, then date
   $meta_key = 'auteur';  // The meta_key

   // NOTE: The functions and add_filter() calls should really go in functions.php,
   //       but they will work here and are included here for convenience.
   function mam_posts_fields ($fields) {
       global $mam_global_fields;
       // Make sure there is a leading comma
       if ($mam_global_fields) $fields .= (preg_match('/^(\s+)?,/',$mam_global_fields)) ? $mam_global_fields : ", $mam_global_fields";
       return $fields;
    }
    function mam_posts_join ($join) {
       global $mam_global_join;
       if ($mam_global_join) $join .= " $mam_global_join";
       return $join;
    }
    function mam_posts_where ($where) {
       global $mam_global_where;
       if ($mam_global_where) $where .= " $mam_global_where";
       return $where;
    }
    function mam_posts_orderby ($orderby) {
       global $mam_global_orderby;
       if ($mam_global_orderby) $orderby = $mam_global_orderby;
       return $orderby;
    }
    add_filter('posts_fields','mam_posts_fields');
    add_filter('posts_join','mam_posts_join');
    add_filter('posts_where','mam_posts_where');
    add_filter('posts_orderby','mam_posts_orderby');

    global $wpdb,$wp_query;
    $mam_global_fields = ', IF(ISNULL(pm.meta_id),9,1) as sort_key, pm.meta_value';
    $mam_global_join = " LEFT JOIN $wpdb->postmeta pm ON ($wpdb->posts.ID = pm.post_id AND pm.meta_key = '$meta_key')";
    $mam_global_orderby = "sort_key, pm.meta_value, $wpdb->posts.post_date DESC";
    query_posts('posts_per_page=-1&ignore_sticky_posts=1');
    $mam_global_fields = $mam_global_join = $mam_global_orderby = ''; // Turn off filters
    // print_r("REQUEST:$wp_query->request");

   if (have_posts()) {
      while (have_posts()) {
         the_post();
              echo "<br />"; the_title(); echo ' '; the_time('Y-m-d');  echo " $post->sort_key, $post->meta_value";
      }
   }

?>

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>