Make WordPress Core

Opened 11 years ago

Closed 11 years ago

Last modified 9 years ago

#24351 closed defect (bug) (invalid)

post__not_in is ignored in WP_Query

Reported by: dukessa's profile Dukessa Owned by:
Milestone: Priority: normal
Severity: normal Version: 3.5.1
Component: Query Keywords:
Focuses: Cc:

Description

$excludeposts = get_option('excluded_blogposts');
//echo $excludeposts;
//outputs: 1282,1194,1185

$excludecat = get_cat_ID('My Cat');
//echo $excludecat;
//outputs: 212

$customquery = null;
$customquery = new WP_Query( array(
 'post__not_in' => array($excludeposts),
 'category__not_in' => array($excludecat),
 'post_type' => 'post',
 'posts_per_page' => 4
));

//echo $customquery->request;
/*outputs:
REQUEST:SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.ID NOT IN (1282) AND ( wp_posts.ID NOT IN ( SELECT object_id FROM wp_term_relationships WHERE term_taxonomy_id IN (212) ) ) AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 4
*/

If I add the IDs manually:

post__not_in' => array(1282,1194,1185)

it works perfectly, but if I pass the variable, it breaks before the first comma.

Anyone with a good explanation/solution? is it a bug?

Change History (12)

#1 @Dukessa
11 years ago

I solved the problem in another way.
Instead of generating and passing a string, I generated and passed a full array as var.

$excludeposts = get_option('excluded_blogposts');
//var_export($excludeposts);
//outputs: array ( 'id1' => '1282', 'id2' => '1194', 'id3' => '1185', )  

'post__not_in' => $excludeposts,

This works fine.

However, back to the issue, there is either a bug or something isn't quite right.
A variable passing a string and writing the string manually should work fine either ways.

#2 follow-up: @nacin
11 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to invalid
  • Status changed from new to closed

You need to do one or the other: an array of IDs, or comma-separated IDs. You're trying to pass an array of comma-separated IDs.

#3 in reply to: ↑ 2 @Dukessa
11 years ago

Replying to nacin:

You need to do one or the other: an array of IDs, or comma-separated IDs. You're trying to pass an array of comma-separated IDs.

I'm not trying to pass an array of comma-separated IDs. I'm passing a variable with a string, which is exactly the same one you can manually write, and it works that way.

How is:

// This works.
array(1282,1194,1185)

different from

// This doesnt work.
$excludeposts = '1282,1194,1185';
array($excludeposts)

?

Last edited 11 years ago by Dukessa (previous) (diff)

#4 follow-up: @knutsp
11 years ago

The difference is:

array(1282,1194,1185) is an array of integer values with 3 elements

but

array($excludeposts) is an array containing just one value, even if this one string value contains a list comma separated values

If you pass the string $excludeposts, not array($excludeposts), the functions will understand what you mean. And if you prefer to pass an array, the array must contain exactly one ID pr item. The elements then cannot contain many values.

Last edited 11 years ago by knutsp (previous) (diff)

#5 @SergeyBiryukov
11 years ago

  • Severity changed from major to normal

#6 in reply to: ↑ 4 @Dukessa
11 years ago

Replying to knutsp:

The difference is:

array(1282,1194,1185) is an array of integer values with 3 elements

but

array($excludeposts) is an array containing just one value, even if this one string value contains a list comma separated values

If you pass the string $excludeposts, not array($excludeposts), the functions will understand what you mean. And if you prefer to pass an array, the array must contain exactly one ID pr item. The elements then cannot contain many values.

You're totally right.
However, probably best if it's mentioned in the codex just so that people don't get frustrated :)
Thank you

#7 @Dukessa
11 years ago

  • Severity changed from normal to minor

#8 @Dukessa
11 years ago

  • Keywords needs-codex added

#9 follow-up: @knutsp
11 years ago

  • Keywords needs-codex removed
  • Severity changed from minor to normal

This ticket is closed as invalid, so setting severity and keywords is meaningless unless you reopen it.

I think the codex makes it perfectly clear how to use it, and even says explicitly:

//This will NOT work
$string_variable = '1,2,3';
$query = new WP_Query( array( 'post__not_in' => array( $string_variable ) ) );

The codex content is editable.

#10 in reply to: ↑ 9 @Dukessa
11 years ago

Replying to knutsp:

This ticket is closed as invalid, so setting severity and keywords is meaningless unless you reopen it.

I think the codex makes it perfectly clear how to use it, and even says explicitly:

//This will NOT work
$string_variable = '1,2,3';
$query = new WP_Query( array( 'post__not_in' => array( $string_variable ) ) );

The codex content is editable.

I personally just added that explanation in the Codex, that's why NOW it's clear ;)

Last edited 11 years ago by Dukessa (previous) (diff)

#11 @SergeyBiryukov
11 years ago

  • Keywords needs-codex added

Thanks for adding the note to Codex.

Note that it's not just post__not_in, this applies to other *__in and *__not_in query vars too. They expect a proper array of integers, not a comma-separated string or a mix of both.

Replying to nacin:

You need to do one or the other: an array of IDs, or comma-separated IDs.

Actually, post__not_in and other *__in and *__not_in query vars only accept an array: tags/3.5.1/wp-includes/query.php#L2163.

Last edited 9 years ago by SergeyBiryukov (previous) (diff)

#12 @SergeyBiryukov
11 years ago

  • Keywords needs-codex removed
Note: See TracTickets for help on using tickets.