WP_query: meta_key cu regulă personalizată pentru o valoare specifică

5 mai 2013, 20:59:11
Vizualizări: 22.6K
Voturi: 2

Am rămas blocat cu un cod WP_Query. Iată-l:

$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 vreau să fac:

Să afișez toate postările cu karma >= 0 (funcționează bine cu acest cod). DAR dacă există postări cu karma = 100, să afișez doar 3 dintre ele + restul postărilor.

Exemple: 9 postări cu karma = 150, 133, 100, 100, 100, 100, 100, 33, 11.

Vreau să afișez: 150, 133, 100, 100, 100, 33, 11. (Sunt permise doar 3 postări cu karma = 100).

Aveți vreo idee cum să realizez acest lucru? Poate un add_filter('posts_where');?

ACTUALIZARE: Ok, am reușit să-l fac să funcționeze, bazat pe răspunsul lui @s_ha_dum. Este puțin complicat, dar rezultatul funcționează ;)

$args = array(
       // Verifică ultimele 9 postări cu 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++;
            // Verifică dacă sunt mai mult de 3 postări cu karma = 100
            // Adaugă-le în array-ul $dont_show_me
            if($i > 3){
                $dont_show_me[] = $p->ID;
            }
        }
    }

    // Configurează interogarea finală care exclude postările adiționale cu 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);
0
Toate răspunsurile la întrebare 1
4

Un meta_query este un array de array-uri. Vezi exemplele din 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);

Ceea ce ai tu este doar un array. Asta ar putea cauza probleme. Ce vrei să faci este asta:

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

Totuși, pentru a ajunge la întrebarea în sine, nu poți face o logică atât de complicată precum ai nevoie...

Afișează toate postările cu karma >= 0 (funcționează bine cu acest cod). DAR dacă există postări cu karma = 100 afișează doar 3 dintre ele + restul postărilor.

...cu un singur WP_Query. Sună de parcă vrei să obții 3, și doar 3, postări cu karma mai mare de 100, și să completezi restul cu orice altceva. Asta ar fi complicat cu SQL pur. Cred că e posibil în SQL dar ar trebui să mă gândesc mult să fiu sigur, darămite să o fac să funcționeze.

Aș sugera două interogări— una pentru a obține "mai mare de 100" și a doua pentru 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) {
      // presupunând că $dont_show_me este un 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);

Nu pot testa asta deoarece nu am datele tale despre karma pe serverul meu, dar sunt destul de sigur că e corect. Ar trebui să te ajute să ajungi cel puțin aproape de soluție.

5 mai 2013 21:40:22
Comentarii

Mulțumesc pentru răspuns. Dar codul tău afișează doar postările cu karma = 100. Eu vreau să afișez toate postările cu karma >= 0 DAR dacă o postare are karma = 100, să afișez doar 3 dintre ele. (Voi edita întrebarea mea).

hawkidoki hawkidoki
5 mai 2013 22:12:37

@hawkidoki : vezi editarea.

s_ha_dum s_ha_dum
6 mai 2013 00:12:49

Soluție foarte interesantă! Pentru ceilalți, există o eroare aproape de sfârșitul codului tău $args['post__no_in'] (corect este post__not_in).

Soluția ta pare să funcționeze, trebuie să o ajustez puțin totuși, dar ideea este minunată :) Mulțumesc foarte mult!

hawkidoki hawkidoki
6 mai 2013 01:23:41

@hawkidoki : Voi repara acea eroare. Mulțumesc. Atât întrebările cât și răspunsurile sunt editate de comunitate aici, ca pe un wiki. Poți să corectezi singur astfel de greșeli.

s_ha_dum s_ha_dum
6 mai 2013 02:39:11