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?
$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)?echo 'posts_per_page: ', $normal_args['posts_per_page'];
returns1
;$normal_query = new WP_Query($basic_args); echo 'post_count: ', $normal_query->post_count;
returns25
$normal_args['posts_per_page']
returns1
, but you get 25 posts back, then the value ofposts_per_page
is altered inside theWP_Query
class. I would start by looking atpre_get_posts
that is badly formulated. You should look at the generated SQL query, simply doecho $normal_query->request
. This should give you an idea ifposts_per_page
is altered right before the SQL query is buildpre_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 checkis_main_query()
to only alter the main query and not custom queries. So you statement should beif ( !is_admin() && $query->is_main_query() && $query->is_search() )