Posso unire 2 nuove WP_Query($variable)?
Sto gestendo una rete multisite e ho configurato una query SQL che utilizza switch_to_blog(); e interroga i post.
C'è un modo per dichiarare la query all'interno di una nuova WP_Query e unirla effettivamente con un'altra?
In pratica, se faccio questo:
$number1 = new WP_Query($multisitequery);
Posso unirla con:
$number2 = new WP_Query($normalquery);
$normalquery
contiene impostazioni come paginazione, post per pagina, excerpt, titolo ecc... in uno shortcode del portfolio.
Vorrei includere i post interrogati dalla mia nuova query $multisite
.
È possibile farlo? Vorrei solo evitare di creare un'intera nuova configurazione di shortcode
Grazie in anticipo. Rory
MODIFICA========
Quello che ho è:
$portfolio = array();
$portfolio = $settings;
Più avanti nella mia funzione portfolio "dopo tutti i $settings['options']" ho:
$portfolio_query = new WP_Query( $portfolio );
il $portfolio_query
usa un loop su un template di pagina.
Voglio aggiungere una query extra in questo modo:
global $wpdb, $blog_id, $post;
$blogs = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM wp_blogs ORDER BY blog_id" ) );
$globalcontainer = array();
foreach ($blogs as $blog){
switch_to_blog($blog->blog_id);
$globalquery = query_posts($args);
$globalcontainer = array_merge( $globalcontainer, $globalquery );
restore_current_blog();
}
dove presumo che $globalcontainer
sarebbe l'array da unire nella wp_query();
.
Quindi, considerando quanto hai risposto, in teoria potrei semplicemente:
$mergedqueryargs = array_merge($portfolio , $globalcontainer);
$portfolio_query = new WP_query($mergedqueryargs);
Sarebbe corretto?
Secondo, riguardo alla sovrascrittura delle chiavi dell'array con array_merge..... Come posso evitare una sovrascrittura?
Non otterrai molto semplicemente unendo gli argomenti, devi unire l'array dei post risultanti e il conteggio post_count. Questo funziona per me:
//configura le tue query come già fai
$query1 = new WP_Query($args_for_query1);
$query2 = new WP_Query($args_for_query2);
//crea una nuova query vuota e popolala con le altre due
$wp_query = new WP_Query();
$wp_query->posts = array_merge( $query1->posts, $query2->posts );
//popola il conteggio post_count affinché il loop funzioni correttamente
$wp_query->post_count = $query1->post_count + $query2->post_count;

Sembra buono, ma sto cercando una soluzione che possa essere utilizzata con l'hook pre_get_posts - cioè, ho bisogno di modificare un oggetto WP_Query esistente. Ho provato a usare '$wp_query->init();' invece di '$wp_query = new WP_Query();', ma sembra creare problemi. Qualche suggerimento?

Dovresti aggiungere una domanda diversa poiché è una risposta diversa, ma puoi usare questo stesso codice ma solo le parti query2, modificando le parti ->posts e ->post_count dell'oggetto $wp_query per avere la somma della query originale che pre_get_posts ti fornisce e della seconda query che vuoi aggiungere.

Grazie per questo. Avevo un meta_query problematico usando una relazione OR. L'ho suddiviso usando questa tecnica e sono passato da 41s a 0.01s.

@ban-geoengineering Hai mai risolto questo problema? Sono bloccato anche io con lo stesso problema.

@harvey Scusa, non riesco a trovare nessun codice relativo a questo. (È passato qualche anno.) La tua migliore chance potrebbe essere pubblicare una nuova domanda. Buona fortuna. :-)

Se finisci per creare un nuovo array e rimuovere i duplicati utilizzando qualcosa come array_unique()
, dovresti essere in grado di popolare $wp_query->post_count
con count($wp_query->posts)

Generalmente unisco i loro array di ID ed eseguo una terza query. Per mantenere il primo set di query leggero, restituisco solo gli ID utilizzando il parametro fields in questo modo:
//imposta le tue query con il parametro extra fields => ids
$query1 = new WP_Query(array('fields' => 'ids','other_parameters' => 'etc'));
$query2 = new WP_Query(array('fields' => 'ids','other_parameters'=>'etc'));
//ora hai gli ID dei post in $query->posts
$allTheIDs = array_merge($query1->posts,$query2->posts);
//nuova query, utilizzando il parametro post__in
$finalQuery = new WP_Query(array('post__in' => $allTheIDs));
Spero sia utile
---MODIFICA---
Dopo la mia risposta la domanda originale è stata modificata per includere dettagli sul multisite. Nel caso di unione di post su multisite, questo metodo non funziona.

Questa risposta funziona bene e sembra meno un hack rispetto alla soluzione principale. L'ho usata circa un anno fa e sono tornato a utilizzarla di nuovo ora. Grazie.

Come può funzionare correttamente quando i post_ID non sono univoci nell'ambito del multisite (sono univoci per blog, ma diversi post possono avere gli stessi ID nella rete)?

@Adal La domanda originale è stata modificata dopo la mia risposta, quindi la mia risposta è rilevante per l'ambito del sito singolo. Con il multisite non ho mai provato a unire query e in quel caso ovviamente questo non funzionerà, le query devono essere fatte separatamente e poi unite. Dopo l'unione puoi provare a ordinarle con le funzioni di ordinamento di php magari (ordina per data di pubblicazione ecc.).

Puoi preservare l'ordinamento utilizzando 'orderby' => 'post__in'
nell'ultima query.

Questo funziona solo per me quando imposto il post_type nella $finalQuery

per i custom post type, penso che il parametro post_type sia necessario in ogni caso, anche quando si richiede per ID perché è post_type=post di default @RobbTe

Assicurati di verificare se l'array degli ID uniti è vuoto. Perché una query post__in restituisce risultati se è un array vuoto. Un bug che WP si rifiuta di risolvere: https://core.trac.wordpress.org/ticket/28099

Quindi, se hai questo:
$number1 = new WP_Query($multisitequery);
$number2 = new WP_Query($normalquery);
Presumo che tu li abbia definiti da qualche parte precedentemente?
$multisitequery = array();
$normalquery = array();
...in tal caso, per unire le due query, è sufficiente array_merge()
dei due array prima di passarli a new WP_Query()
:
$merged_query_args = array_merge( $normalquery, $multisitequery );
$merged_query = new WP_Query( $merged_query_args );
Nota che l'ordine è importante nella chiamata a array_merge()
. Se entrambi hanno la stessa chiave di array, il secondo array sovrascriverà il primo array.

Quindi, puoi unire due query WP_Query con diversi post_type o altri dati di ordinamento, ad esempio, e poi combinarle per ids in un'unica query WP_Query che funzionerà completamente - per preservare l'ordinamento durante l'unione, è necessario specificare orderby => post__in
Il mio esempio mostra come crea un nuovo ciclo WP_Query e può influenzare qualsiasi altro ciclo per la visualizzazione dei post chiamando new global_change_of_sorting_posts->change_query_posts() => query_posts() che devi chiamare prima di elaborare il ciclo per la visualizzazione dei post!
class global_change_of_sorting_posts
{
public function get_posts_ids()
{
$query1 = new WP_Query([
'fields' => 'ids',
'posts_per_page' => -1,
'post_type' => 'post',
]);
$query2 = new WP_Query([
'posts_per_page' => -1,
'fields' => 'ids',
'post_type' => 'custom-post',
]);
$merge_ids_posts = $query1->posts + $query2->posts;
wp_reset_query();
return $merge_ids_posts;
}
public function get_posts_wp_query()
{
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$posts_per_page = 40;
$wp_query = new WP_Query([
'posts_per_page' => $posts_per_page,
'paged' => $paged,
'post__in' => $this->get_posts_ids(),
'orderby' => 'post__in',
]);
while ($wp_query->have_posts()) {
$wp_query->the_post();
var_dump(get_the_ID());
}
}
public function change_query_posts($query_string)
{
parse_str($query_string, $args);
$args['post__in'] = $this->get_posts_ids();
$args['orderby'] = 'post__in';
query_posts($args); # conversione della query
}
}
