Filtrare per un campo personalizzato e ordinare per un altro?
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"

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

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.

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?

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

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 :)

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

@בניית אתרים - 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 - di solito lo faccio ma non quando rispondo dal mio cellulare.

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

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

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