Apart from the use of query_posts
, you have another issue, and that is the local use of global $posts
variable. $posts
is the global used to hold the main query's posts array. Never use global variables as local variables. Changing global variables is really bad as you break their original and intended values, which is really hard to debug. Instead of using $posts
, use a custom variable like $posts_array
.
You most probably also do not need the custom query, but if you do, use WP_Query
or get_posts()
, never use query_posts
. I have discussed everything in detail in this post which also linked to a couple of very important posts.
Just to quickly touch on few other points:
You should really work on your code's indentation and separation. Your code is a bit hard to read and to debug when you cram so many things into one long line.
You should be careful setting post_status
to any
as this will expose private
posts to non logged in users, it will also show future
posts which is not published yet. This might also expose custom statuses that you would not want to show. Rather explicitly set the post statuses you need.
From query.php
if ( in_array( 'any', $q_status ) ) {
foreach ( get_post_stati( array( 'exclude_from_search' => true ) ) as $status ) {
if ( ! in_array( $status, $q_status ) ) {
$e_status[] = "$wpdb->posts.post_status <> '$status'";
}
}
} else {
Note: 'exclude_from_search' => true
means only trash
and auto-draft
are excluded from any
showposts
have been dropped in favor of posts_per_page
. It is not depreciated, but if used, it gets converted into posts_per_page
, so why not use posts_per_page
from the start
if ( isset($q['showposts']) && $q['showposts'] ) {
$q['showposts'] = (int) $q['showposts'];
$q['posts_per_page'] = $q['showposts'];
}
You don't need to set arguments to their default values. You can simply leave that out and save extra space and time
If this is a secondary query, you can probably look at something like the following: (Requires PHP 5.4+)
$args = [
'post_type' => 'book',
'posts_per_page' => -1,
'order' => 'ASC'
'tax_query' => [
[
'taxonomy' => 'book-category',
'terms' => $termid
]
],
];
if ( true == $getpending ) {
if ( is_user_logged_in() ) { // This can be adjusted to match core
$args["post_status"] = ['publish', 'private', 'draft'];
} else {
$args["post_status"] = ['publish', 'draft'];
}
}
$posts_array = WP_Query( $args );
I do believe, looking at the terms
value in you tax_query
, this might be the main query. If so, you should really look into pre_get_posts
to alter the main query
query_posts
modifies WordPress' main loop and is unsuited for pretty much every purpose (wordpress.stackexchange.com/questions/1753/…). There are numerous reasons whyquery_posts
wouldn't work as expected in this case. Have you tried usingget_posts
instead?