2

I'm a bit stuck with a WP_Query code. Here it is :

$args = array(
      'post_type' => 'post',
      'meta_query'=> array(
          'key' => 'karma',
          'compare' => '>=',
          'value' => 0,
          'type' => 'numeric'),
        'posts_per_page' => 9,
        'meta_key' => 'karma',
        'orderby' => 'meta_value_num', 
        'order' => 'DESC',
        'post__not_in' => $dont_show_me
    );

What I want to do :

Show all posts with karma >= 0 (it works fine with this code). BUT if there are posts with karma = 100 only show 3 of them + the rest of posts.

Examples : 9 posts with karma = 150, 133, 100, 100, 100, 100, 100, 33, 11.

I want to show: 150, 133, 100, 100, 100, 33, 11. (Only 3 posts with karma = 100 are allowed).

Do you have any idea how to achieve this? Maybe a add_filter('posts_where'); ?

UPDATE: Okay I got it working, based on @s_ha_dum answer. It's a bit tricky, but the result works ;)

$args = array(
       // Check for 9 last posts with karma = 100
       'post_type' => 'post',
       'meta_query'=> array(
          array(
              'key' => 'karma',
              'compare' => '=', 
              'value' => 100,
              'type' => 'numeric'
           )
        ),
       'posts_per_page' => 9,
       'meta_key' => 'karma',
       'orderby' => 'meta_value_num', 
       'order' => 'DESC',
       'post__not_in' => $dont_show_me
    );
    $karma_qry = new WP_Query($args);

    if (!empty($karma_qry->posts)) {
        $i = 0;
        foreach ($karma_qry->posts as $p) {
            $i++;
            // Check for more than 3 posts with karma = 100
            // Add them in the $dont_show_me array 
            if($i > 3){
                $dont_show_me[] = $p->ID;
            }
        }
    }

    // Setup the final query that excluded addional posts with karma = 100
    $args['meta_query'][0]['compare'] = '>=';
    $args['meta_query'][0]['value'] = 0;
    $args['post__not_in'] = $dont_show_me;

    $wp_query = new WP_Query($args);
4

A meta_query is an array of arrays. Look at the examples in the the Codex.

 $args = array(
   'post_type' => 'my_custom_post_type',
   'meta_key' => 'age',
   'orderby' => 'meta_value_num',
   'order' => 'ASC',
   'meta_query' => array(
       array(
           'key' => 'age',
           'value' => array(3, 4),
           'compare' => 'IN',
       )
   )
 );
 $query = new WP_Query($args);

What you have is just an array. That could be causing trouble. What you want to do is this:

$args = array(
   'post_type' => 'post',
   'meta_query'=> array(
      array(
          'key' => 'karma',
          'compare' => '>=', // limit to "karma value = 100"
          'value' => 0, // limit to "karma value = 100"
          'type' => 'numeric'
       )
    ),
   'posts_per_page' => 9,
   'meta_key' => 'karma',
   'orderby' => 'meta_value_num', 
   'order' => 'DESC',
   'post__not_in' => $dont_show_me
);

However, to get to the question itself, you can't do logic as complicated as you need ...

Show all posts with karma >= 0 (it works fine with this code). BUT if there are posts with karma = 100 only show 3 of them + the rest of posts.

... with a single WP_Query. That sounds like you want to pull 3, and only 3, posts with karma greater than 100, and fill in the rest with anything else. That would be tricky with pure SQL. I think it is possible in SQL but I would have to think a lot to be sure, much less to make it work.

I would suggest two queries-- one to get the "greater than 100" and a second to get the rest.

$dont_show_me = array(1);
$args = array(
   'post_type' => 'post',
   'meta_query'=> array(
      array(
          'key' => 'karma',
          'compare' => '>=', 
          'value' => 100,
          'type' => 'numeric'
       )
    ),
   'posts_per_page' => 3,
   'meta_key' => 'karma',
   'orderby' => 'meta_value_num', 
   'order' => 'DESC',
   'post__not_in' => $dont_show_me
);
$karma_qry = new WP_Query($args);

if (!empty($karma_qry->posts)) {
  $args['posts_per_page'] = 9 - $karma_qry->found_posts;
  $args['meta_query'][0]['value'] = 0;
  foreach ($karma_qry->posts as $p) {
      // assuming $dont_show_me is an array
      $dont_show_me[] = $p->ID;
  }
  $args['post__not_in'] = $dont_show_me;
} else {
  $args['posts_per_page'] = 9;
  $args['meta_query'][0]['value'] = 0;
}

$the_rest_qry = new WP_Query($args);

I can't test that as I don't have your karma data on my server, but I am fairly sure that is correct. It ought to get you most of the way, at least.

  • Think you for your answer. But your code only show posts with karma = 100. I want to show all posts with karma >= 0 BUT if the post got karma = 100 only show 3 of them. (I'll edit my question). – hawkidoki May 5 '13 at 19:12
  • @hawkidoki : see the edit. – s_ha_dum May 5 '13 at 21:12
  • Really interesting solution! For others people, there is an error near the end of your code $args['post__no_in'] (it's post__not_in). Your solution seems to work, I got to tweak it a bit BTW, but the idea is great :) Think you very much! – hawkidoki May 5 '13 at 22:23
  • @hawkidoki : I'll fix that error. Thanks. Both questions and answers are community edited here, like wiki. You can fix mistakes like that yourself. – s_ha_dum May 5 '13 at 23:39

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.