Filtra per un campo personalizzato, ordina per un altro?


10

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

Query 1 (ordina per posizione):

                $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 del campo personalizzato! = Sì):

                $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 cercato il codice per aiuto con questo, 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 facendo di sbagliato con la query combinata?

[AGGIORNAMENTO]: ora che 3.1 è stato rilasciato, la query combinata sopra non funziona ancora. Ottengo risultati, ma non ordinati correttamente.

[AGGIORNAMENTO]: var_dump($wp_query->request)fornisce 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
Stai usando WordPress 3.1? Il meta_queryparametro è nuovo in 3.1, dovrebbe essere rilasciato molto presto, ma l'attuale versione stabile è ancora 3.0.5, senza questo parametro.
Jan Fabry,

Ehm ... giusto, probabilmente sarebbe per questo allora. Un modo per farlo funzionare in 3.0.5?
Gillespieza,

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

Risposte:


9

È possibile utilizzare la query per filtrare il contenuto come desiderato utilizzando "meta_query" con le opzioni di filtro e, per la parte dell'ordine, è sufficiente aggiungere / modificare 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',            // this means we will be using a selected 
                                               // meta field to order
    
        'meta_key' => 'location_level1_value', // this states which meta field 
                                               // will be used in the ordering, 
                                               // regardless of the filters
        'order'    => 'ASC',
        'paged'    => $paged
        )
    );
    

2

Proprio come ha detto Jan nel nuovo WordPress 3.1 che puoi usare meta_queryma fino a quando non verrà pubblicato puoi usare la tua Prima query per ordinare e filtrare all'interno del tuo ciclo 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();
              //do your loop stuff
} 

e aggiungi questo codice al tuo function.php

   //join filter
         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;
            }
         }
         //where filter
         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.


Grazie per questo. Funziona, tranne che ho questo strano effetto collaterale che il mio paging non funziona più correttamente. Invece di 9 per pagina, ho "spazi vuoti" nella mia griglia in cui i post personalizzati gateway_value == "Yes"sarebbero stati senza il condizionale ... Qualche idea su come risolverlo?
Gillespieza,

sì, ciò rovinerebbe il paging, quindi immagino che l'unico modo per aggirarlo sarebbe una query sql personalizzata, dammi qualche minuto.
Bainternet,

Non preoccuparti: userò solo la seconda query e userò il plugin wordpress.org/extend/plugins/post-types-order fino al rilascio di 3.1 :)
gillespieza,

dam, sono tornato proprio ora per vedere il tuo commento dopo aver trovato una soluzione. comunque è qui per i futuri richiedenti.
Bainternet,

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

1

Scuse per aver risposto alla mia domanda:

Guardando [http://core.trac.wordpress.org/ticket/15031 lasting[1], sembra che questo sia un problema noto. Ho risolto (hackerato?) Per funzionare usando post_filter, in questo modo (solo per riferimento di chiunque potrebbe essere alla ricerca della stessa risposta):

In 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;
}

Wp_query modificato nel file modello ###

$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
    ));
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.