1

I am trying to get only one post and this needs to be the latest one so here is what I am doing:

$basic_args = $wp_query->query_vars;
$basic_args['tax_query'] = $wp_query->tax_query;

$aditional_args = array(
    'post__in' => get_option('sticky_posts'),
    'ignore_sticky_posts' => 1,
    'order' => 'desc',
    'post_status' => 'publish',
    'posts_per_page' => 1
);

$normal_args = array_merge($basic_args, $aditional_args);
$normal_query = new WP_Query($normal_args);

$prev_post_ids = array();

if (!$normal_query->have_posts()) {
    $normal_args = array_merge($basic_args, array('posts_per_page' => 1));
    $normal_query = new WP_Query($normal_args);
}

echo $normal_query->post_count; // returns 25

if ($normal_query->have_posts()) {
    while ($normal_query->have_posts()) {
        ....
        // here I got 25 results instead of just one
    }
}

I know that posts_per_page should be limit how many post I will get but is not working for me and don't know why. As you can read I am getting 25 post on the loop instead of one. Can any give me some advice around this topic? I have read this and this but isn't helping at all.

Update1

I debug the $normal_query->request as suggested by @pieter-goosen and I am getting this wrong SQL query:

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) INNER JOIN wp_term_relationships AS tt1 ON (wp_posts.ID = tt1.object_id) WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (6) AND tt1.term_taxonomy_id IN (6) ) AND wp_posts.post_type IN ('opinion', 'post', 'especiales') AND ((wp_posts.post_status = 'publish')) GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 25

Where the LIMIT is modified?

Update2

I have debug also the $basic_args which have $wp_query->query_vars and also $normal_args and here is the result:

echo '<pre>';
print_r($basic_args);
echo '</pre>';

Array
(
    [category_name] => internacionales
    [error] => 
    [m] => 
    [p] => 0
    [post_parent] => 
    [subpost] => 
    [subpost_id] => 
    [attachment] => 
    [attachment_id] => 0
    [name] => 
    [static] => 
    [pagename] => 
    [page_id] => 0
    [second] => 
    [minute] => 
    [hour] => 
    [day] => 0
    [monthnum] => 0
    [year] => 0
    [w] => 0
    [tag] => 
    [cat] => 409
    [tag_id] => 
    [author] => 
    [author_name] => 
    [feed] => 
    [tb] => 
    [paged] => 0
    [comments_popup] => 
    [meta_key] => 
    [meta_value] => 
    [preview] => 
    [s] => 
    [sentence] => 
    [title] => 
    [fields] => 
    [menu_order] => 
    [category__in] => Array
        (
        )

    [category__not_in] => Array
        (
        )

    [category__and] => Array
        (
        )

    [post__in] => Array
        (
        )

    [post__not_in] => Array
        (
        )

    [post_name__in] => Array
        (
        )

    [tag__in] => Array
        (
        )

    [tag__not_in] => Array
        (
        )

    [tag__and] => Array
        (
        )

    [tag_slug__in] => Array
        (
        )

    [tag_slug__and] => Array
        (
        )

    [post_parent__in] => Array
        (
        )

    [post_parent__not_in] => Array
        (
        )

    [author__in] => Array
        (
        )

    [author__not_in] => Array
        (
        )

    [ignore_sticky_posts] => 
    [suppress_filters] => 
    [cache_results] => 1
    [update_post_term_cache] => 1
    [update_post_meta_cache] => 1
    [post_type] => 
    [posts_per_page] => 10
    [nopaging] => 
    [comments_per_page] => 50
    [no_found_rows] => 
    [order] => DESC
    [tax_query] => WP_Tax_Query Object
        (
            [queries] => Array
                (
                    [0] => Array
                        (
                            [taxonomy] => category
                            [terms] => Array
                                (
                                    [0] => internacionales
                                )

                            [field] => slug
                            [operator] => IN
                            [include_children] => 1
                        )

                )

            [relation] => AND
            [table_aliases:protected] => Array
                (
                    [0] => wp_term_relationships
                )

            [queried_terms] => Array
                (
                    [category] => Array
                        (
                            [terms] => Array
                                (
                                    [0] => internacionales
                                )

                            [field] => slug
                        )

                )

            [primary_table] => wp_posts
            [primary_id_column] => ID
        )

)


echo '<pre>';
print_r($normal_args);
echo '</pre>';

Array
(
    [category_name] => internacionales
    [error] => 
    [m] => 
    [p] => 0
    [post_parent] => 
    [subpost] => 
    [subpost_id] => 
    [attachment] => 
    [attachment_id] => 0
    [name] => 
    [static] => 
    [pagename] => 
    [page_id] => 0
    [second] => 
    [minute] => 
    [hour] => 
    [day] => 0
    [monthnum] => 0
    [year] => 0
    [w] => 0
    [tag] => 
    [cat] => 409
    [tag_id] => 
    [author] => 
    [author_name] => 
    [feed] => 
    [tb] => 
    [paged] => 0
    [comments_popup] => 
    [meta_key] => 
    [meta_value] => 
    [preview] => 
    [s] => 
    [sentence] => 
    [title] => 
    [fields] => 
    [menu_order] => 
    [category__in] => Array
        (
        )

    [category__not_in] => Array
        (
        )

    [category__and] => Array
        (
        )

    [post__in] => Array
        (
        )

    [post__not_in] => Array
        (
        )

    [post_name__in] => Array
        (
        )

    [tag__in] => Array
        (
        )

    [tag__not_in] => Array
        (
        )

    [tag__and] => Array
        (
        )

    [tag_slug__in] => Array
        (
        )

    [tag_slug__and] => Array
        (
        )

    [post_parent__in] => Array
        (
        )

    [post_parent__not_in] => Array
        (
        )

    [author__in] => Array
        (
        )

    [author__not_in] => Array
        (
        )

    [ignore_sticky_posts] => 1
    [suppress_filters] => 
    [cache_results] => 1
    [update_post_term_cache] => 1
    [update_post_meta_cache] => 1
    [post_type] => 
    [posts_per_page] => 1
    [nopaging] => 
    [comments_per_page] => 50
    [no_found_rows] => 
    [order] => desc
    [tax_query] => WP_Tax_Query Object
        (
            [queries] => Array
                (
                    [0] => Array
                        (
                            [taxonomy] => category
                            [terms] => Array
                                (
                                    [0] => internacionales
                                )

                            [field] => slug
                            [operator] => IN
                            [include_children] => 1
                        )

                )

            [relation] => AND
            [table_aliases:protected] => Array
                (
                    [0] => wp_term_relationships
                )

            [queried_terms] => Array
                (
                    [category] => Array
                        (
                            [terms] => Array
                                (
                                    [0] => internacionales
                                )

                            [field] => slug
                        )

                )

            [primary_table] => wp_posts
            [primary_id_column] => ID
        )

    [post_status] => publish
)

As you can see post_per_page is set to 1 here so why it's taking those 25?

Update 3

Apparently this is the problematic code at functions.php:

function change_wp_search_size($query)
{
    if ($query->is_search) {
        $query->query_vars['posts_per_page'] = 25;
    } // Change 25 to the number of posts you would like to show
    return $query; // Return our modified query variables
}

add_filter('pre_get_posts', 'change_wp_search_size');

Shouldn't this works for search only? Why is acting over all query_vars all the time?

10
  • Couple of things to check: what is the value of $normal_args['posts_per_page'] prior to your first creation of WP_Query, and how many posts get returned from just a simple WP_Query (without the array_merges you have going on)? Jan 5, 2016 at 16:48
  • @morganestes echo 'posts_per_page: ', $normal_args['posts_per_page']; returns 1; $normal_query = new WP_Query($basic_args); echo 'post_count: ', $normal_query->post_count; returns 25
    – ReynierPM
    Jan 5, 2016 at 17:02
  • @ReynierPM: Please check my answer, this will may help you Jan 6, 2016 at 11:53
  • I get the feeling that you have a bad filter somewhere. If $normal_args['posts_per_page'] returns 1, but you get 25 posts back, then the value of posts_per_page is altered inside the WP_Query class. I would start by looking at pre_get_posts that is badly formulated. You should look at the generated SQL query, simply do echo $normal_query->request. This should give you an idea if posts_per_page is altered right before the SQL query is build Jan 6, 2016 at 12:11
  • 1
    pre_get_posts alters all queries, back end and front end regardless. There are two very important checks that a large amount of people misses, that is the !is_admin() check to only target the front end, and then the most important check is_main_query() to only alter the main query and not custom queries. So you statement should be if ( !is_admin() && $query->is_main_query() && $query->is_search() ) Jan 6, 2016 at 12:59

2 Answers 2

3

pre_get_posts alters all queries, back end and front end regardless.

There are two very important checks that a large amount of people misses, that is the !is_admin() check which only targets the front end, and then the most important check, is_main_query() which will only alter the main query and not custom queries.

You statement should look something like the follwoing

if (    !is_admin() 
     && $query->is_main_query()  
     && $query->is_search()  
) {
    // Your arguments to set
}
0

Ok, after the suggestions from @pieter-goosen I have found a solution, just adding this remove_all_filters( 'pre_get_posts' ) before run that WP_Query fix the issue, hope it helps to others

2
  • You should correct the issue as in my last comment Jan 6, 2016 at 13:00
  • Great post this as an answer and I will accept since this seems to be a better way than mine, thanks
    – ReynierPM
    Jan 6, 2016 at 13:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.