9

I've registered a custom post type called "node".

When I create a basic WP_Query to get posts of that type, it works just fine. Example:

$args = array(  
'post_status' => 'publish',
'post_type' => 'node');

$query = new WP_Query($args);       

This will get all published posts of type "node".

However, as soon as I combine this with a search, nothing is returned. Example:

$args = array(  
'post_status' => 'publish',
'post_type' => 'node',
's' => 'My search term');

$query = new WP_Query($args);

This will get nothing, although it should get several posts of type 'node' that contain 'My search term'.

As far as I can see, the post types are automatically set to "post" and "page" as soon as I include the "s" parameter in $args. If I print out a var_dump of $query, it shows the following:

Without "s":

object(WP_Query)
  public 'query' => 
    array (size=2)
      'post_status' => string 'publish' (length=7)
      'post_type' => string 'node' (length=4)
  public 'query_vars' => 
    array (size=63)
      'post_status' => string 'publish' (length=7)
      'post_type' => string 'node' (length=4)
...

With "s":

object(WP_Query)
  public 'query' => 
    array (size=2)
      'post_status' => string 'publish' (length=7)
      's' => string 'My search term' (length=14)
      'post_type' => string 'node' (length=4)
  public 'query_vars' => 
    array (size=66)
      'post_status' => string 'publish' (length=7)
      's' => string 'My search term' (length=14)
      'post_type' => 
        array (size=2)
          0 => string 'post' (length=4)
          1 => string 'page' (length=4)
...

So Wordpress seems to override the post types as soon as a search is involved.

How can I fix that?

4
  • 1
    I cannot confirm this. I just tested something very similar - successfully. Have you tried without any plugin and/or using a default theme? Even the search (i.e., the main search, using the search form) includes all custom post types that are not explicitly excluded from search.
    – tfrommen
    Commented Feb 13, 2014 at 18:57
  • 2
    I actually wrote a search this morning that used post_type (a cpt), post_status (publish) and s and it's working fine. You almost certainly have a filter or something in a plugin/theme as suggested by @tf. Commented Feb 13, 2014 at 21:36
  • I have not been able to test this but I am about 95% sure I have don something similar and had it work. I agree with the speculation about action of filter interference.
    – s_ha_dum
    Commented Feb 13, 2014 at 22:02
  • 1
    You are right, I tried it in a clean Wordpress install and it works. Seems like one of the plugins I use in my environment is hooking itself in one of the pre-query events. Thanks!
    – Sebastian
    Commented Feb 17, 2014 at 14:57

4 Answers 4

5

You are right, I tried it in a clean Wordpress install and it works.

Seems like one of the plugins I use in my environment is hooking itself in one of the pre-query events.

Thanks!

1
  • 2
    Do you know which plugin caused this problem?
    – stefano1
    Commented Oct 9, 2014 at 16:21
1

On a stock WordPress installation, WP_Query will default to post_type = 'post'.

Consider this simple example:

$args = array(
  "posts_per_page"=>5,
  "ignore_sticky_posts"=>true
);

$itposts = new WP_Query( $args );

It will result in the following query to be executed:

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 0, 5

THE BEST SOLUTION

The solution is to add a post_type argument set to 'any'. This way WordPress will automaticaly search among all types except revisions and types with exclude_from_search set to true. Problem, by default, attachments are not excluded from search. As long as you don't have a post_status argument set to 'inherit', you should not be annoyed because attachments always have post_status set to 'inherit'.

This way the query will change to:

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type IN ('post', 'page', 'attachment') AND (wp_posts.post_status = 'publish' OR wp_posts.post_author = 1 AND wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 0, 5

If needed, you can exclude attachments from search by using this code:

add_action('init', 'exclude_attachments_from_search');

function exclude_attachments_from_search() {
  global $wp_post_types;

  $wp_post_types['attachment']->exclude_from_search = true;
}
0

I've just stepped in this, and such solution worked for me:

instead of 'post_type' => 'node' try 'post_type' => ['node']

-2

I know this is a really old question but I came across this because I had the same problem. I can't comment because of reputation, but I want to help people like @Stefano so you don't have to go through all your plugins and check which one causes the change to the query.

For me it was a plugin called "Custom Search by BestWebSoft". But it wasn't the plugins fault, I just hadn't ticked the box for my custom post type in its settings.

Your Answer

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

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