web-dev-qa-db-fra.com

Combinaison de requêtes avec différents arguments par type de publication

Je construis une section sur un site où je fusionne deux types de publication différents dans une boucle, puis je les affiche au hasard. Le problème, c’est que j’ai du mal à trouver le moyen de limiter le nombre de posts per type.

Voici ce que j'ai essayé:

  • Une requête avec plusieurs types de publication peut être réalisée avec un tableau:

    $args = array( 'post_type' => array( 'photos', 'quotes' ), ...
    

    ... mais ne peut pas se limiter à un certain nombre de messages par type.

  • Fusion de deux tableaux d’arguments de requête avant d’exécuter WP_Query dessus:

    $photos = array( 'post_type' => 'photos', 'posts_per_page' => 15, 'orderby' => 'Rand' );
    $quotes = array( 'post_type' => 'quotes', 'posts_per_page' => 5, 'orderby' => 'Rand' );
    
    $args = $photos + $quotes;
    // Also tried array_merge( $photos, $quotes );
    

    Pas de chance à ce sujet. Qu'est-ce qui se passe est la dernière variable $quotes remplace $photos et affiche uniquement les guillemets.

  • Fusion de deux WP_Query objets ensemble par conversion de type:

    $photos_query = new WP_Query( $photos );
    $quotes_query = new WP_Query( $quotes );
    $result = (object)array_merge( (array)$photos_query, (array)$quotes_query );
    

... etc.

Je pourrais probablement utiliser une requête SQL directement dans la base de données, mais I need pour pouvoir combiner ces deux types de publication distincts pour une boucle, disposés de manière aléatoire, ET limités à un certain nombre de publications par type.

Merci de votre aide!

11
Andy Merskin

Une solution consiste à personnaliser la requête SQL exécutée à l'aide de posts_clauses ou d'autres filtres similaires. Pour les trouver, cherchez posts_clauses dans "wp-includes/query.php" et voyez la série de filtres juste avant cette ligne. Ensemble, ils sont capables de personnaliser n’importe quelle partie de la requête

Une autre chose que vous pouvez faire est de fusionner manuellement les articles demandés dans les objets.

$photos_query = new WP_Query( $photos );
$quotes_query = new WP_Query( $quotes );
$result = new WP_Query();

// start putting the contents in the new object
$result->posts = array_merge( $photos_query->posts, $quotes_query->posts );

// here you might wanna apply some sort of sorting on $result->posts

// we also need to set post count correctly so as to enable the looping
$result->post_count = count( $result->posts );
16
Mridul Aggarwal

@mridual aggarwal, votre réponse est très très bonne mais malheureusement elle ne combine pas vraiment le 2 wp_query mais ne montre que les messages des deux en même temps, je veux dire 5 messages du premier et 5 du second mais pas triés dans un cette solution et elle a exactement atteint l'objectif pour moi au moins

<?php
$term = get_term_by( 'slug', get_query_var( 'tag' ), "post_tag" );
$tagslug = $term->slug;
$post_types = get_post_types('','names');
?>
<?php
//first query
$blogposts = get_posts(array(
    'tag' => $tagslug, //first taxonomy
    'post_type' => $post_types,
    'post_status' => 'publish',
    ));
//second query
$authorposts = get_posts(array(
    'bookauthor' => $tagslug, //second taxonomy
    'post_type' => $post_types,
    'post_status' => 'publish',
    ));
$mergedposts = array_merge( $blogposts, $authorposts ); //combine queries

$postids = array();
foreach( $mergedposts as $item ) {
$postids[]=$item->ID; //create a new query only of the post ids
}
$uniqueposts = array_unique($postids); //remove duplicate post ids

$posts = get_posts(array(
        //new query of only the unique post ids on the merged queries from above
    'post__in' => $uniqueposts,  
    'post_type' => $post_types,
    'post_status' => 'publish',
    ));
foreach( $posts as $post ) :
setup_postdata($post);
?>
// posts layout
<?php endforeach; ?>
<?php wp_reset_postdata();?>
7
adnan