Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One pagination for multiple queries (or how to group a one query)

I have multiple queries in the same page, like this:

$args_1 = array (
    'category_name' => get_query_var( 'category_name' ),
    'post__in'      => $sticky = get_option( 'sticky_posts' );
    'orderby' => 'date',
    'order' => 'DESC'    
);

$sticky_query = new WP_Query ($args_1);

// loop


$args_2 = array(
    'category_name' => get_query_var( 'category_name' ),
    'post__not_in'  => get_option( 'sticky_posts' ),
    'category__not_in' => array(11114),
    'orderby' => 'date',
    'order' => 'DESC'
);

$query_2 = new WP_Query ($args_2);

// loop



$args_3 = array(
    'category_name' => get_query_var( 'category_name' ),
    'post__not_in'  => get_option( 'sticky_posts' ),
    'category__in' => array(11114),
    'orderby' => 'date',
    'order' => 'DESC'
);


$query_3 = new WP_Query($args_3 );

// loop

I would:

1) limit the total of posts per page to 15

2) (I can't do this, I've searched anywhere but I didn't find a solution) Make this "combined" pagination works . Now, and it's logical, the second page is the same as the first page...

Or the solution can be to make only one query and group the posts and order the groups instead?

like image 225
AmintaCode Avatar asked Dec 24 '22 21:12

AmintaCode


2 Answers

Final Solution

  1. you don't need custom pagination if you merge two queries and you don't use "offset", so I've removed

    $big = 999999999; // need an unlikely integer
    
    echo paginate_links( array(
        'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big  ) ) ),
        'format' => '?paged=%#%',
        'current' => max( 1, get_query_var('paged') ),
        'total' => $the_query->max_num_pages
    ) );
    

And added:

    echo paginate_links(); 
  1. You have to set 'order' to 'post__in' value to keep the order given to the posts in the separate queries.

  2. To avoid memory errors (like '"Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 262144 bytes)".') caused by queries that hold many posts, you have to retrive only post ids in the queries. See here.

Here's the final code:

    global $wp_query;



    $paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
    $post_per_page = 35; // How many post per page - setup as you need
    $nr_of_posts_to_be_analyzed_to_include_only_current_events = 100; // How many post to analyze to include only current events, ie events that are not in category id 11114



    $sticky = get_option( 'sticky_posts' );

    // posts in category, limited in number otherwise - if you set '-1' and you have 7.000 posts - you exceed the script time limit execution 
    $category_posts = get_posts(array('category_name' => get_query_var( 'category_name' ), 'posts_per_page' => $nr_of_posts_to_be_analyzed_to_include_only_current_events,'orderby' => 'date', 'order' => 'DESC'));

    $category_posts_ids = array();

    foreach( $category_posts as $post ) {

        $category_posts_ids[]=$post->ID; // Array with posts ID

    }
    // var_dump($category_posts_ids);


   // expired posts in category, limited in number otherwise - if you set '-1' and you have 7.000 posts - you exceed the script time limit execution 
   $expired_posts = get_posts(array('category__and' => array(11114, get_query_var('cat')), 'posts_per_page' => $nr_of_posts_to_be_analyzed_to_include_only_current_events, 'orderby' => 'date', 'order' => 'DESC'));

   $expired_posts_ids = array();

   foreach( $expired_posts as $post ) {

        $expired_posts_ids[]=$post->ID; // Array with posts ID

   }



   // first 100 posts in this category per page - the expired posts that are in 100 first posts in this category gives as result an array of not expired posts
   $array_where_to_get_post =  array_diff( $category_posts_ids, $sticky, $expired_posts_ids );



   // 1/3 only the sticky posts
   $stickies_posts_args = array(
    'category_name' => get_query_var( 'category_name' ),
    'post__in'  => get_option( 'sticky_posts' ),
    'orderby' => 'date',
    'order' => 'DESC',
    'posts_per_page' => -1,
    'fields'         => 'ids' // important: to avoid memory exhausted error we retrieve postids only
    );

   // 2/3 only the not expired and not sticky posts
   $not_expired_posts_args = array(
    'post__in' => $array_where_to_get_post,
    'orderby' => 'date',
    'order' => 'DESC',
    'posts_per_page' => -1,
    'fields'         => 'ids', // important: to avoid memory exhausted error we retrieve postids only,
    'suppress_filters' => false 
   );

   // 3/3 only the expired and not sticky posts
   $expired_posts_args = array(
    'category_name' => get_query_var( 'category_name' ),
    'post__not_in'  => get_option( 'sticky_posts' ), // not sticky posts
    'category__in' => array(11114), // expired posts
    'orderby' => 'date',
    'order' => 'DESC',
    'posts_per_page' => -1,
    'fields'         => 'ids' // important: to avoid memory exhausted error we retrieve postids only
   );


  $firstQuery = get_posts($stickies_posts_args);

  add_filter('posts_join','join_posts_and_events'); // apply some filter
  add_filter('posts_orderby', 'order_posts'); // apply some filter
  $secondQuery = get_posts($not_expired_posts_args);
  remove_filter('posts_join','join_posts_and_events');
  remove_filter('posts_orderby', 'order_posts');

  $thirdQuery = get_posts($expired_posts_args);


  $mergePosts = array_merge( $firstQuery, $secondQuery, $thirdQuery ); // Merge all queries

  $uniquePosts = array_unique($mergePosts); // Create an array with unique posts

   // Final query
   $args = array(
    'post_type' => 'any',   
    'post__in' => $uniquePosts,
    'paged' => $paged,
    'orderby' => 'post__in', // order the posts as they are (already ordered)
    'order' => 'DESC',
    'posts_per_page' => $post_per_page,
    'ignore_sticky_posts' => 1 // otherwise it breaks pagination
   );

  $wp_query = new WP_Query($args);

    if ( $wp_query->have_posts() ) :

       while ( $wp_query->have_posts() ) { $wp_query->the_post();

   // outputs what you want

  endwhile; 

  endif;

  echo paginate_links(); 
like image 148
AmintaCode Avatar answered Dec 26 '22 10:12

AmintaCode


Try this one below, I merge two queries (post and page). Working for me - display all posts/page with pagination.

<?php 

$paged = get_query_var('paged') ? get_query_var('paged') : 1;
$post_per_page = 5; // How many post per page - setup as you need

$firstQuery = new WP_Query('post_type=post'); // First query - you should change args
$secondQuery = new WP_Query('post_type=page'); // Second query - you should change args


$post_ids = array_merge( $firstQuery, $secondQuery ); // Merge all queries

$query = new WP_Query(
    array(
        'post_type'      => array('post', 'page'), // You should change post types as you need
        'post__in'       => $post_ids, 
        'paged'          => $paged,
        'orderby'        => 'date', 
        'order'          => 'DESC',
        'posts_per_page' => $post_per_page
    )
);

$totalPosts = $firstQuery->post_count + $secondQuery->post_count; // Count posts


if( $query->have_posts() ):

    while( $query->have_posts() ): $query->the_post();

        echo the_title()."</br>"; // Content

    endwhile; 

    wp_reset_query();

endif;


$big = 999999999; // need an unlikely integer

echo paginate_links( array(
    'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
    'format' => '?paged=%#%',
    'current' => max( 1, get_query_var('paged') ),
    'total' => $totalPosts / $post_per_page, // Total pages
) );

?>

New Solution - Edit

Just adjust the first and second query

<?php 

global $wp_query;

$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
$post_per_page = 5; // How many post per page - setup as you need

// First query
$firstQuery = get_posts(array(
    'posts_per_page' => -1,
    'category_name' => get_query_var( 'category_name' ),
    'post__in'      => $sticky = get_option( 'sticky_posts' ) 
));

// Second query 
$secondQuery = get_posts(array(
    'posts_per_page' => -1,
    'category_name' => get_query_var( 'category_name' ),
    'post__not_in'  => get_option( 'sticky_posts' ),
));


$mergePosts = array_merge( $firstQuery, $secondQuery ); // Merge all queries

$postIds = array();

foreach( $mergePosts as $post ) {

    $postIds[]=$post->ID; // Array with posts ID

}

$uniquePosts = array_unique($postIds); // Create an array with unigue posts


// Final query
$args = array(
'post_type' => 'any',   
'post__in' => $uniquePosts,
'paged' => $paged,
'orderby' => 'date',
'order' => 'DESC',
'posts_per_page' => $post_per_page,
);


$the_query = new WP_Query($args);

if( $the_query->have_posts() ):

    while( $the_query->have_posts() ): $the_query->the_post();

        echo the_title()."</br>"; // Content

    endwhile; 

    wp_reset_query();

endif;

$big = 999999999; // need an unlikely integer

echo paginate_links( array(
    'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
    'format' => '?paged=%#%',
    'current' => max( 1, get_query_var('paged') ),
    'total' => $the_query->max_num_pages
) );

?>  
like image 45
mattkrupnik Avatar answered Dec 26 '22 10:12

mattkrupnik