WordPress.org

Forums

[resolved] Multiple Queries Compiling into one Loop (10 posts)

  1. Taylor Baybutt
    Member
    Posted 4 years ago #

    Hello,
    I'm trying to do something interesting but Google is not providing any answers. I thought maybe someone has done this before or perhaps could figure it out.

    I want to run multiple queries and compile them all into one loop. The reason is, I have tags that live in multiple custom taxonomies but are occasionally the same. I want my custom archive.php page to retrieve posts for all post types for the queried taxonomy term, no matter the taxonomies that it lives in.

    For instance, on our blog/database of authors' homes, we have a News posts tagged "Edgar Allan Poe" and we have House Posts with the "author taxonomy" term "Edgar Allan Poe" for the Author sorting feature. In a couple places, I would like all posts with the term "Edgar Allan Poe" to be returned regardless of the taxonomy that holds it.

    I can envision a something like

    <?php
    $posts = get_posts( array(
    		'tag' => $tagslug,
    		'post_type' => $post_types,
    		'post_status' => 'publish',
     		));
    $posts .= get_posts( array(
    		'bookauthor' => $tagslug,
    		'post_type' => $post_types,
    		'post_status' => 'publish',
     		));
    foreach($posts as $post) :
    		setup_postdata($post);
    ?>

    but that is an invalid argument for foreach

    Any idea how one would compile the results of multiple queries, disregard duplicates, and return the results in a loop?

    Thanks!

  2. Taylor Baybutt
    Member
    Posted 4 years ago #

    any ideas?

  3. Curtiss Grymala
    Member
    Posted 4 years ago #

    The get_posts() function returns an array. Using .= in PHP appends one string to the end of another. The correct way to do this would be more like:

    <?php
    $posts = get_posts( array( //first group of stuff ) );
    $moreposts = get_posts( array( //second group of stuff ) );
    $posts = array_merge( $posts, $moreposts );
    foreach( $posts as $post ) :
        setup_postdata( $post );
  4. Taylor Baybutt
    Member
    Posted 4 years ago #

    ohh right, I should have known...does array_merge disregard duplicates?

    Thanks!

  5. Curtiss Grymala
    Member
    Posted 4 years ago #

    If the array items returned by get_posts() are numerically indexed (which I believe they are), duplicates will be included after you perform the array_merge(). The array_merge() function only overwrites items if they share the same non-numeric key.

    To get rid of duplicates, you could try using array_unique().

  6. Taylor Baybutt
    Member
    Posted 4 years ago #

    this is proving very difficult.

    This is probably very inefficient but I have gotten pretty far with my limited php knowledge. my problem is that my $uniqueposts array is in an associative array which, it seems, the post__in query parameter will not accept. Here is my code, any help would be very much appreciated.

    <?php
    $blogposts = get_posts(array(
    		'tag' => $tagslug,
    		'post_type' => $post_types,
    		'post_status' => 'publish',
     		));
    $authorposts = get_posts(array(
    		'bookauthor' => $tagslug,
    		'post_type' => $post_types,
    		'post_status' => 'publish',
     		));
    $mergedposts = array_merge( $blogposts, $authorposts );
    
    $postids = array();
    foreach( $mergedposts as $item ) {
    $postids[]=$item->ID;
    }
    $uniqueposts = array_unique($postids);
    print_r($uniqueposts);
    $posts = get_posts(array(
    		'post__in' => $uniqueposts,
     		));
     		foreach( $posts as $singlepost ) :
        setup_postdata( $post );?>
  7. Curtiss Grymala
    Member
    Posted 4 years ago #

    I don't understand why you're trying to retrieve the posts twice. Why not just do something like the following (not tested, but I think it should work).

    <?php
    $blogposts = get_posts(array(
    		'tag' => $tagslug,
    		'post_type' => $post_types,
    		'post_status' => 'publish',
     		));
    $authorposts = get_posts(array(
    		'bookauthor' => $tagslug,
    		'post_type' => $post_types,
    		'post_status' => 'publish',
     		));
    $mergedposts = array_unique( array_merge( $blogposts, $authorposts ) );
    foreach( $mergedposts as $singlepost ) :
        setup_postdata( $post );?>
  8. Taylor Baybutt
    Member
    Posted 4 years ago #

    I am trying to do this because you can only query one taxonomy at a time. I have a client that sometimes uses one and sometimes uses another, not ideal I know. So I want to return posts that have a given take no matter which taxonomy it is in.

    I had tried your solution but it returned a post with the id 0 that had no content.

    The way I was doing it was to retrieve an array of the unique post IDs and the I tried to query only posts with those IDs. Something went wrong but I am not sure what, it should have worked. Instead, two random posts got returned. I think two queries on the page (one in the sidebar) are conflicting.

  9. Taylor Baybutt
    Member
    Posted 4 years ago #

    ahh, I'm dumb. I got got to put a post_type parameter in my post__in query. My final code is this:

    <?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(
    		'post__in' => $uniqueposts, //new query of only the unique post ids on the merged queries from above
    		'post_type' => $post_types,
    		'post_status' => 'publish',
     		));
    foreach( $posts as $post ) :
    setup_postdata($post);
    ?>

    hope this helps someone else! If anyone can think of a more efficient way to do it, please share!

  10. Andres Richero
    Member
    Posted 3 years ago #

    Thanks a lot for sharing, you code was a great clue to solving some other problems which needed merging queries.
    Great work.

Topic Closed

This topic has been closed to new replies.

About this Topic