Filtrare per un campo personalizzato e ordinare per un altro?

17 feb 2011, 16:19:15
Visualizzazioni: 20.3K
Voti: 11

Ho un tipo di post personalizzato "Listing" e voglio ottenere tutti i Listing che hanno un campo personalizzato gateway_value != 'Yes', e ordinare i risultati per un altro campo personalizzato, location_level1_value. Riesco a far funzionare le query separatamente, ma non riesco a combinarle:

Query 1 (ordinamento per location):

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

Query 2 (valore campo personalizzato != 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
                    )
                );

Query combinata:

Ho consultato il codex per aiuto, ma la seguente query non funziona:

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

Cosa sto sbagliando nella query combinata?

[AGGIORNAMENTO]: Ora che è stata rilasciata la versione 3.1, la query combinata sopra ancora non funziona. Ottengo dei risultati, ma non ordinati correttamente.

[AGGIORNAMENTO]: var_dump($wp_query->request) restituisce quanto segue:
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
Commenti

Stai utilizzando WordPress 3.1? Il parametro meta_query è nuovo nella versione 3.1, che verrà rilasciata molto presto, ma la versione stabile attuale è ancora la 3.0.5, senza questo parametro.

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

Ehm... giusto, probabilmente è per questo allora. C'è un modo per farlo funzionare in 3.0.5?

gillespieza gillespieza
17 feb 2011 18:11:25

Miljenko ha la risposta migliore, dovresti accettare la sua invece della tua.

Hugo Hugo
3 apr 2012 08:24:38
Tutte le risposte alla domanda 3
0

Puoi utilizzare la query per filtrare il contenuto come desiderato usando 'meta_query' con opzioni di filtraggio, e per la parte dell'ordinamento, aggiungi/modifica i seguenti 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'     => 'Yes',
                'compare'   => '!='
            )
        ),
        'orderby'  => 'meta_value',            // significa che useremo un campo meta selezionato 
                                               // per l'ordinamento
    
        'meta_key' => 'location_level1_value', // specifica quale campo meta 
                                               // verrà utilizzato per l'ordinamento, 
                                               // indipendentemente dai filtri
        'order'    => 'ASC',
        'paged'    => $paged
        )
    );
    
14 ott 2011 00:39:00
11

Come ha detto Jan, nella nuova versione di WordPress 3.1 potrai usare meta_query, ma fino a quando non sarà rilasciata puoi usare la tua prima query per ordinare e filtrare all'interno del tuo loop in questo modo:

 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();
              //fai le tue operazioni all'interno del loop
} 

e aggiungi questo codice al tuo functions.php

   //filtro 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;
            }
         }
         //filtro 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;
            }
         }

Ora dovrebbe funzionare.

17 feb 2011 18:12:57
Commenti

Grazie per questo. Funziona, tranne per lo strano effetto collaterale che la mia impaginazione non funziona più correttamente. Invece di 9 per pagina, ho "spazi vuoti" nella mia griglia dove sarebbero stati i post personalizzati con gateway_value == "Yes" senza il condizionale... Hai qualche idea su come risolvere?

gillespieza gillespieza
17 feb 2011 18:53:40

sì, questo scombussolerebbe l'impaginazione, quindi immagino che l'unico modo per aggirarlo sarebbe una query SQL personalizzata, dammi qualche minuto.

Bainternet Bainternet
17 feb 2011 19:10:27

Non ti preoccupare - userò semplicemente la seconda query e il plugin http://wordpress.org/extend/plugins/post-types-order finché non verrà rilasciato la 3.1 :)

gillespieza gillespieza
17 feb 2011 19:20:55

dannazione, sono appena tornato per vedere il tuo commento dopo aver trovato una soluzione. comunque è qui per chi farà domande in futuro.

Bainternet Bainternet
17 feb 2011 20:01:31

@בניית אתרים - Se indentate tutto il vostro codice sarà più facile incollarlo nelle risposte. Es. Mettetelo nel vostro editor preferito, selezionatelo tutto, poi indentatelo una volta, ora copiate e incollate, ed eviterete di dover aggiungere 4 spazi prima di ogni riga del codice (dovrebbe andare tutto in un blocco di codice senza bisogno di armeggiare).

t31os t31os
17 feb 2011 20:18:37

@t31os - di solito lo faccio ma non quando rispondo dal mio cellulare.

Bainternet Bainternet
17 feb 2011 20:20:38

Hai scritto da un telefono... rispetto!.. io non proverei neanche a scrivere codice su un telefono.. :) +1 per le tue abilità da telefono! ;)

t31os t31os
17 feb 2011 20:39:09

t31os: LOL , HTC desire spacca!!

Bainternet Bainternet
17 feb 2011 20:40:23

Ho provato a incollare blocchi di codice con tab dal mio editor di testo e non funziona mai - devo sempre aggiungere gli spazi manualmente

gillespieza gillespieza
17 feb 2011 23:07:48

Il copia e incolla da Notepad++ a Firefox funziona correttamente.

Bainternet Bainternet
17 feb 2011 23:11:27

Proverò così (al momento sto usando PsPad e Chrome)

gillespieza gillespieza
19 feb 2011 20:37:23
Mostra i restanti 6 commenti
0

Scusate se rispondo alla mia stessa domanda:

Guardando [http://core.trac.wordpress.org/ticket/15031][1], sembra che si tratti di un problema noto. L'ho risolto (aggirato?) facendolo funzionare utilizzando post_filter, in questo modo (solo per riferimento di chiunque stia cercando la stessa risposta):

Nel file 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;
}

Query WP modificata nel file 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