WordPress.org

Make WordPress Core

Opened 11 months ago

Closed 11 months ago

Last modified 11 months ago

#24351 closed defect (bug) (invalid)

post__not_in is ignored in WP_Query

Reported by: 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)

comment:1 Dukessa11 months 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.

comment:2 follow-up: nacin11 months 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.

comment:3 in reply to: ↑ 2 Dukessa11 months 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 months ago by Dukessa (previous) (diff)

comment:4 follow-up: knutsp11 months 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 is 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.

Version 0, edited 11 months ago by knutsp (next)

comment:5 SergeyBiryukov11 months ago

  • Severity changed from major to normal

comment:6 in reply to: ↑ 4 Dukessa11 months 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

comment:7 Dukessa11 months ago

  • Severity changed from normal to minor

comment:8 Dukessa11 months ago

  • Keywords needs-codex added

comment:9 follow-up: knutsp11 months 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.

comment:10 in reply to: ↑ 9 Dukessa11 months 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 months ago by Dukessa (previous) (diff)

comment:11 SergeyBiryukov11 months ago

  • Keywords needs-codex added

Thanks for adding the note to Codex.

Note that it's not just post__not_in, this applies 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.

comment:12 SergeyBiryukov11 months ago

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