Meta_query annidata con più chiavi di relazione
Mi chiedo se WordPress sia in grado di eseguire una meta_query
annidata, con ciascuna query avente diverse chiavi di relazione. Da WordPress 3.0, tax_query
è in grado di eseguire questa funzione; mi domando se esista un equivalente con meta_query
.
$results = query_posts( array(
'post_type' => 'event_id',
'meta_query' => array(
'relation' => 'AND',
array(
'relation' => 'OR',
array(
'key' => 'primary_user_id',
'value' => $user_id
),
array(
'key' => 'secondary_user_id',
'value' => $user_id
)
),
array(
'key' => 'date',
'value' => array( $start_date, $end_date ),
'type' => 'DATETIME',
'compare' => 'BETWEEN'
)
)
) );
Riferimenti:

La domanda era relativa a WordPress 3.0, ma nel caso qualcuno avesse la stessa domanda per una versione più recente, dal Codex di WordPress:
"A partire dalla versione 4.1, le clausole meta_query possono essere annidate per costruire query complesse."
https://developer.wordpress.org/reference/classes/wp_query/#custom-field-post-meta-parameters Quindi, quella query dovrebbe funzionare nella versione attuale di WordPress.

Nel frattempo questo è possibile, vedi la documentazione con esempio e spiegazione:
Vecchio link: https://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters Aggiornamento 2021, nuovo link: https://developer.wordpress.org/reference/classes/wp_query/#custom-field-post-meta-parameters
e un altro esempio https://wordpress.org/support/topic/wp_query-with-multiple-meta_query/#post-9410992
'meta_query' => array(
'relation' => 'OR',
array(
'relation' => 'AND',
array(
'key' => '_price',
'value' => 1,
'compare' => '>=',
'type' => 'DECIMAL',
),
array(
'key' => '_price',
'value' => 3000,
'compare' => '<=',
'type' => 'DECIMAL',
),
),
array(
'relation' => 'AND',
array(
'key' => '_price',
'value' => 3001,
'compare' => '>=',
'type' => 'DECIMAL',
),
array(
'key' => '_price',
'value' => 6000, //corretto <= in =>
'compare' => '<=',
'type' => 'DECIMAL',
),
)
),

Anche questo è un buon riferimento ma apprezzo anche la descrizione completa qui https://developer.wordpress.org/reference/classes/wp_query/#custom-field-post-meta-parameters

Il codex.wp sta venendo spostato su developer.wp quindi sì, ho aggiunto il riferimento corretto all'epoca. Al momento attuale è effettivamente https://developer.wordpress.org/reference/classes/wp_query/#custom-field-post-meta-parameters i

Sembra essere impossibile. Per favore, qualcuno mi corregga se sbaglio.
Il parametro meta_query
verrà effettivamente trasformato in un oggetto WP_Meta_Query
, e la verifica della relation
non andrà più in profondità in wp-includes/meta.php
, ma avverrà solo una volta al livello superiore:
if ( isset( $meta_query['relation'] ) && strtoupper( $meta_query['relation'] ) == 'OR' ) {
$this->relation = 'OR';
} else {
$this->relation = 'AND';
}
Una possibile soluzione per questo è costruire il proprio JOIN per questa query.
$query = new WP_Query( array(
...
'my_meta_query' => true,
'suppress_filters' => false
) );
add_filter( 'posts_join', 'my_meta_query_posts_join', 10, 2 );
function my_meta_query_posts_join( $join, $query ) {
if ( empty( $query->query_vars['my_meta_query'] ) )
return $join;
global $wpdb;
$new_join = "
INNER JOIN {$wpdb->postmeta} pm1 ON 1=1
AND pm1.post_id = {$wpdb->posts}.ID
AND pm1.meta_key = '_some_meta_key'
AND pm1.meta_value = 'some_value'
";
return $join . ' ' . $new_join;
}
E se hai bisogno di ulteriori verifiche e regole, puoi anche utilizzare il filtro posts_where
.

Sembra essere lo stesso approccio che @scribu consiglia su Core Trac: https://core.trac.wordpress.org/ticket/20312
