web-dev-qa-db-fra.com

WP_query: meta_key avec une règle personnalisée pour une valeur spécifique

Je suis un peu coincé avec un code WP_Query. C'est ici :

$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
    );

Ce que je veux faire :

Afficher tous les messages avec karma> = 0 (cela fonctionne bien avec ce code). MAIS s'il y a des messages avec le karma = 100, seulement 3 d'entre eux + le reste des messages.

Exemples: 9 postes avec karma = 150, 133, 100, 100, 100, 100, 100, 33, 11.

Je veux montrer: 150, 133, 100, 100, 100, 33, 11. (Seuls 3 messages avec du karma = 100 sont autorisés).

Avez-vous une idée de comment y parvenir? Peut-être une add_filter('posts_where');?

UPDATE: D'accord, je l'ai fait fonctionner, basé sur la réponse @s_ha_dum. C'est un peu délicat, mais le résultat fonctionne;)

$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);
2
hawkidoki

Un meta_query est un tableau de tableaux. Regardez le exemples dans le 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);

Ce que vous avez est juste un tableau. Cela pourrait causer des problèmes. Ce que vous voulez faire est ceci:

$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
);

Cependant, pour en arriver à la question elle-même, vous ne pouvez pas faire la logique aussi compliquée qu'il vous faut ...

Afficher tous les messages avec karma> = 0 (cela fonctionne bien avec ce code). MAIS s'il y a des messages avec le karma = 100, seulement 3 d'entre eux + le reste des messages.

... avec un seul WP_Query. Cela ressemble à ce que vous voulez tirer 3, et seulement 3, postes avec un karma supérieur à 100, et compléter le reste avec autre chose. Ce serait délicat avec du SQL pur. Je pense que c'est possible en SQL mais je devrais penser à un lot pour en être sûr, encore moins pour que cela fonctionne.

Je suggérerais deux requêtes - une pour obtenir le "supérieur à 100" et une seconde pour obtenir le reste.

$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);

Je ne peux pas tester cela car je n'ai pas vos données karma sur mon serveur, mais je suis à peu près sûr que c'est correct. Au moins, cela devrait vous aider.

3
s_ha_dum