Filtrare după un câmp personalizat, ordonare după altul?

17 feb. 2011, 16:19:15
Vizualizări: 20.3K
Voturi: 11

Am un tip de postare personalizat "Listing" și vreau să obțin toate Listările care au un câmp personalizat gateway_value != 'Yes' și să ordonez rezultatele după un alt câmp personalizat, location_level1_value. Pot face interogările să funcționeze separat, dar nu le pot combina:

Interogarea 1 (sortare după locație):

                $wp_query = new WP_Query( array (
                    'post_type' => 'listing',
                    'post_status' => 'publish',
                    'posts_per_page' => '9',
                    'meta_key' => 'location_level1_value',
                    'orderby' => 'location_level1_value',
                    'order' => 'ASC',
                    'paged' => $paged
                    )
                 );

Interogarea 2 (valoarea câmpului personalizat != Yes):

                $wp_query = new WP_Query( array (
                    'post_type' => 'listing',
                    'posts_per_page' => '9',
                    'post_status' => 'publish',
                    'meta_key' => 'gateway_value',
                    'meta_value' => 'Yes',
                    'meta_compare' => '!=',
                    'paged' => $paged
                    )
                );

Interogare combinată:

M-am uitat în codex pentru ajutor cu aceasta, dar următoarea interogare nu funcționează:

                $wp_query = new WP_Query( array (
                    'post_type' => 'listing',
                    'posts_per_page' => '9',
                    'post_status' => 'publish',
                    'meta_query' => array(
                        array(
                            'key' => 'gateway_value',
                            'value' => 'Yes',
                            'compare' => '!='
                        ),
                        array(
                            'key' => 'location_level1_value'
                        )
                    ),
                    'orderby' => "location_level1_value",
                    'order' => 'ASC',
                    'paged' => $paged
                    )
                );

Ce fac greșit în interogarea combinată?

[ACTUALIZARE]: Acum că versiunea 3.1 a fost lansată, interogarea combinată de mai sus tot nu funcționează. Primesc rezultate, doar că nu sunt sortate corect.

[ACTUALIZARE]: var_dump($wp_query->request) returnează următoarele:
string(527) " SELECT SQL_CALC_FOUND_ROWS wp_7v1oev_posts.* FROM wp_7v1oev_posts INNER JOIN wp_7v1oev_postmeta ON (wp_7v1oev_posts.ID = wp_7v1oev_postmeta.post_id) INNER JOIN wp_7v1oev_postmeta AS mt1 ON (wp_7v1oev_posts.ID = mt1.post_id) WHERE 1=1 AND wp_7v1oev_posts.post_type = 'listing' AND (wp_7v1oev_posts.post_status = 'publish') AND wp_7v1oev_postmeta.meta_key = 'gateway_value' AND CAST(wp_7v1oev_postmeta.meta_value AS CHAR) != 'Yes' AND mt1.meta_key = 'location_level1_value' ORDER BY wp_7v1oev_posts.post_date DESC LIMIT 0, 9"

3
Comentarii

Folosești WordPress 3.1? Parametrul meta_query este nou în versiunea 3.1, care urmează să fie lansată în curând, dar versiunea stabilă actuală este încă 3.0.5, fără acest parametru.

Jan Fabry Jan Fabry
17 feb. 2011 17:08:25

Hm... corect, probabil de aceea nu funcționează. Există vreo modalitate de a-l face să funcționeze în 3.0.5?

gillespieza gillespieza
17 feb. 2011 18:11:25

Miljenko are cel mai bun răspuns, ar trebui să-l accepti pe al lui în locul tău.

Hugo Hugo
3 apr. 2012 08:24:38
Toate răspunsurile la întrebare 3
0

Puteți utiliza interogarea pentru a filtra conținutul conform intenției dumneavoastră folosind 'meta_query' cu opțiuni de filtrare, iar pentru partea de ordonare, adăugați/modificați următorii parametri:

  • 'orderby' => 'meta_value'
  • 'meta_key' => 'location_level1_value'
  • 'order' => 'ASC'

    $wp_query = new WP_Query( array (
        'post_type'      => 'listing',
        'posts_per_page' => '9',
        'post_status'    => 'publish',
        'meta_query'     => array(
            array(
                'key'       => 'gateway_value',
                'value'     => 'Da',
                'compare'   => '!='
            )
        ),
        'orderby'  => 'meta_value',            // aceasta înseamnă că vom folosi un câmp meta 
                                               // selectat pentru ordonare
    
        'meta_key' => 'location_level1_value', // acesta specifică care câmp meta 
                                               // va fi utilizat în ordonare, 
                                               // indiferent de filtre
        'order'    => 'ASC',
        'paged'    => $paged
        )
    );
    
14 oct. 2011 00:39:00
11

Exact cum a menționat Jan în noul WordPress 3.1, poți folosi meta_query, dar până când acea versiune va fi lansată, poți utiliza prima ta interogare pentru a ordona și filtra în interiorul loop-ului tău, astfel:

Global $my_query;
$my_query = new WP_Query( array (
                    'post_type' => 'listing',
                    'post_status' => 'publish',
                    'posts_per_page' => '9',
                    'meta_key' => 'location_level1_value',
                    'orderby' => 'location_level1_value',
                    'order' => 'ASC',
                    'paged' => $paged
                    )
                 );
while ($my_query->have_posts){
    $my_query->the_post();
              //fă ce ai nevoie în loop
} 

și adaugă acest cod în functions.php

   //filtru de join
         add_filter('posts_join', 'listing_join_865' );
         function listing_join_865($join){
Global $my_query;            
if ('listing' = $my_query->query['post_type']){
                $restriction1 = 'gateway_value';
                return $join .="
                LEFT JOIN $wpdb->postmeta AS $restriction1 ON(
                $wpdb->posts.ID = $restriction1.post_id
                AND $restriction1.meta_key = '$restriction1'
                )";
             }else {
                return $join;
            }
         }
         //filtru de where
         add_filter('posts_where', 'listing_where_865' );
         function listing_where_865($where){
             global $my_query;
            if ('listing' = $my_query->query['post_type']){
                return $where.= " AND $restriction1.meta_value != 'yes'";
            }else{
                return $where;
            }
         }

Acum ar trebui să funcționeze.

17 feb. 2011 18:12:57
Comentarii

Mulțumesc pentru asta. Funcționează, cu excepția unui efect secundar ciudat: paginarea mea nu mai funcționează corect. În loc de 9 pe pagină, am "spații goale" în grila mea unde ar fi fost postările personalizate care au gateway_value == "Yes" fără condiția... Ai vreo idee cum să rezolv asta?

gillespieza gillespieza
17 feb. 2011 18:53:40

da, asta ar strica paginarea, așa că presupun că singura soluție ar fi o interogare SQL personalizată, dă-mi câteva minute.

Bainternet Bainternet
17 feb. 2011 19:10:27

Nu-ți face griji - voi folosi doar a doua interogare și voi folosi plugin-ul http://wordpress.org/extend/plugins/post-types-order până când va fi lansată versiunea 3.1 :)

gillespieza gillespieza
17 feb. 2011 19:20:55

la naiba, tocmai m-am întors acum să văd comentariul tău după ce am găsit o soluție. oricum, este aici pentru cei care vor întreba în viitor.

Bainternet Bainternet
17 feb. 2011 20:01:31

@בניית אתרים - Dacă indentați tot codul, va fi mai ușor să-l lipiți în răspunsuri. Ex. Puneți-l în editorul ales, selectați tot, apoi indentați-l o dată, acum copiați și lipiți și veți evita nevoia de a adăuga 4 spații înaintea oricărei linii de cod (ar trebui să intre frumos într-un bloc de cod fără să fie nevoie să vă jucați cu el).

t31os t31os
17 feb. 2011 20:18:37

@t31os - de obicei fac asta, dar nu când răspund de pe telefonul meu mobil.

Bainternet Bainternet
17 feb. 2011 20:20:38

Ai scris asta de pe un telefon... respect!.. nici nu aș încerca să scriu cod pe un telefon.. :) +1 pentru skillz-urile pe telefon! ;)

t31os t31os
17 feb. 2011 20:39:09

t31os: LOL , HTC desire rulează!!

Bainternet Bainternet
17 feb. 2011 20:40:23

Am încercat să lipesc blocuri de cod tabulate din editorul meu de text și nu funcționează niciodată - întotdeauna trebuie să adaug spații manual

gillespieza gillespieza
17 feb. 2011 23:07:48

Copierea și lipirea din Notepad++ în Firefox funcționează fără probleme.

Bainternet Bainternet
17 feb. 2011 23:11:27

Voi încerca asta (în prezent folosesc PsPad și Chrome)

gillespieza gillespieza
19 feb. 2011 20:37:23
Arată celelalte 6 comentarii
0

Scuze că răspund la propria întrebare:

Uitându-mă la [http://core.trac.wordpress.org/ticket/15031][1], se pare că aceasta este o problemă cunoscută. Am rezolvat (sau mai degrabă am făcut un hack) să funcționeze folosind post_filter, astfel (pentru oricine care caută același răspuns):

În functions.php###

add_filter('posts_orderby', 'EV_locationl1' );
function EV_locationl1 ($orderby) {
    global $EV_locationl1_orderby;
    if ($EV_locationl1_orderby) $orderby = $EV_locationl1_orderby;
    return $orderby;
}

Modificat wp_query în fișierul template###

$EV_locationl1_orderby = " mt1.meta_value ASC";

$wp_query = new WP_Query( array (
    'post_type' => 'listing',
    'posts_per_page' => '9',
    'post_status' => 'publish',
    'meta_query' => array(
            array(
                    'key' => 'gateway_value',
                    'value' => 'Yes',
                    'compare' => '!='
                    ),
            array(
                    'key' => 'location_level1_value'
            )
        ),
    'order' => $EV_locationl1_orderby,
    'paged' => $paged
    ));
24 feb. 2011 00:38:17