Want more features on Pastebin? Sign Up, it's FREE!
Guest

WP - Get posts that don't have a particular meta key

By: a guest on Nov 2nd, 2010  |  syntax: PHP  |  size: 3.15 KB  |  views: 901  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. <?php
  2. /*
  3.         $meta_key    - What meta key to check against (required)
  4.         $post_type   - What post type to check (default - post)
  5.         $post_status - What post status to check (default - publish)
  6.         $fields      - Whether to query all the post table columns, or just a select one ... all, titles, ids, or guids (all returns an array of objects, others return an array of values)
  7. */
  8. function posts_without_meta( $meta_key = '', $post_type = 'post', $post_status = 'publish', $fields = 'all' ) {
  9.         global $wpdb;
  10.        
  11.         if( !isset( $meta_key ) || !isset( $post_type ) || !isset( $post_status ) || !isset( $fields ) )
  12.                 return false;
  13.        
  14.         // Meta key is required
  15.         if( empty( $meta_key ) )
  16.                 return false;
  17.        
  18.         // All parameters are expected to be strings
  19.         if( !is_string( $meta_key ) || !is_string( $post_type ) || !is_string( $post_status ) || !is_string( $fields ) )
  20.                 return false;
  21.        
  22.         if( empty( $post_type ) )
  23.                 $post_type = 'post';
  24.        
  25.         if( empty( $post_status ) )
  26.                 $post_status = 'publish';
  27.  
  28.         if( empty( $fields ) )
  29.                 $fields = 'all';
  30.        
  31.         // Since all parameters are strings, bind them into one for a cheaper preg match (rather then doing one for each)
  32.         $possibly_unsafe_text = $meta_key . $post_type . $post_status . $fields;
  33.        
  34.         // Simply die if anything not a letter, number, underscore or hyphen is present
  35.         if( preg_match( '/([^a-zA-Z0-9_-]+)/', $possibly_unsafe_text ) ) {
  36.                 wp_die( 'Invalid characters present in call to function (valid chars are a-z, 0-9, A-Z, underscores and hyphens).' );
  37.                 exit;
  38.         }
  39.        
  40.         switch( $fields ) :
  41.                 case 'ids':
  42.                         $cols = 'p.ID';
  43.                         break;
  44.                 case 'titles':
  45.                         $cols = 'p.post_title';
  46.                         break;
  47.                 case 'guids':
  48.                         $cols = 'p.guid';
  49.                         break;
  50.                 case 'all':
  51.                 default:
  52.                         $cols = 'p.*';
  53.                         break;
  54.         endswitch;
  55.        
  56.         if( 'all' == $fields )
  57.                 $result = $wpdb->get_results( $wpdb->prepare( "
  58.                         SELECT $cols FROM {$wpdb->posts} p
  59.                         WHERE NOT EXISTS
  60.                         (
  61.                                 SELECT pm.* FROM {$wpdb->postmeta} pm
  62.                                 WHERE p.ID = pm.post_id
  63.                                 AND pm.meta_key = '%s'
  64.                         )
  65.                         AND p.post_type = '%s'
  66.                         AND p.post_status = '%s'
  67.                         ",
  68.                         $meta_key,
  69.                         $post_type,
  70.                         $post_status
  71.                 ) );
  72.         // get_col is nicer for single column selection (less data to traverse)
  73.         else
  74.                 $result = $wpdb->get_col( $wpdb->prepare( "
  75.                         SELECT $cols FROM {$wpdb->posts} p
  76.                         WHERE NOT EXISTS
  77.                         (
  78.                                 SELECT pm.* FROM {$wpdb->postmeta} pm
  79.                                 WHERE p.ID = pm.post_id
  80.                                 AND pm.meta_key = '%s'
  81.                         )
  82.                         AND p.post_type = '%s'
  83.                         AND p.post_status = '%s'
  84.                         ",
  85.                         $meta_key,
  86.                         $post_type,
  87.                         $post_status
  88.                 ) );
  89.        
  90.         return $result;
  91. }
  92. /*
  93.         Example - fetch posts with given meta, then pass to get_posts
  94.         -----------------
  95.         <?php
  96.         // Find posts without a meta entry for the fruit custom field
  97.         $posts_without_fruit = posts_without_meta( 'fruit', '', '', 'ids' );
  98.        
  99.         // If the result didn't come back false
  100.         if( $posts_without_fruit )
  101.        
  102.                 // Pass the IDs returned into get_posts
  103.                 $posts_without_meta = get_posts( 'include=' . implode( ',', $posts_without_fruit) );
  104.        
  105.         // Basic get_posts loop
  106.         foreach( $posts_without_meta as $post ) :
  107.                 setup_postdata( $post );
  108.                
  109.                 the_title();
  110.                 echo '<br />';
  111.                
  112.         endforeach;
  113.        
  114.         wp_reset_query();
  115.         ?>
  116. */
  117. ?>
clone this paste RAW Paste Data