WordPress.org

Make WordPress Core

Opened 4 years ago

Closed 3 years ago

#14892 closed enhancement (fixed)

minor improvement on category__in

Reported by: sboisvert Owned by: scribu
Milestone: 3.1 Priority: normal
Severity: minor Version: 3.1
Component: Query Keywords:
Focuses: Cc:

Description (last modified by scribu)

if categoryin is only provided an int, it will fail (relatively silently). I find this to be "not friendly"

If I may suggest changing lines 1371-1372 in /wp-includes/query.php to this:

if ( !is_array($qv['category__in']) || empty($qv['category__in']) ) {
	if (is_long($qv['category__in']) || is_int($qv['category__in'])){
		$qv['category__in'] = array($qv['category__in']);
	} else{
		$qv['category__in'] = array();	
	}

I would in the same vein implement the change for categorynot_in

if ( !is_array($qv['category__not_in']) || empty($qv['category__not_in']) ) {
				if (is_long($qv['category__not_in']) || is_int($qv['category__not_in'])){
					$qv['category__not_in'] = array($qv['category__not_in']);
				} else{
					$qv['category__not_in'] = array();	
				}

I would also suggest implementing for tagin and etc etc

Change History (16)

comment:1 nacin4 years ago

We can just cast it to an array, then run absint() on it using array_map().

comment:2 sboisvert4 years ago

That would be even better! Thank you.

comment:3 scribu4 years ago

  • Description modified (diff)

comment:4 scribu4 years ago

  • Milestone changed from Awaiting Review to 3.1
  • Owner set to scribu
  • Status changed from new to accepted

comment:5 scribu4 years ago

  • Resolution set to fixed
  • Status changed from accepted to closed

(In [15626]) Don't require categoryin, tagin etc. to be arrays necessarily. Fixes #14892

comment:6 scribu4 years ago

I also noticed that $is_category was set for tagand instead of $is_tag. This is also fixed in [15626].

comment:7 nacin4 years ago

(In [15627]) Fix logic inversion in r15626. see #14892. Also note that r15626 fixed a s/is_category/is_tag/ typo introduced in r6011, on line 1340.

comment:8 follow-up: linuxologos3 years ago

  • Resolution fixed deleted
  • Status changed from closed to reopened
  • Version changed from 3.0.1 to 3.1

I'm testing 3.1-RC2-17229 and it seems to me that this fix is not working as described. In my case, category_in still requires an array. Tag_in/tag_not_in are working fine with integers though.

comment:9 in reply to: ↑ 8 westi3 years ago

  • Keywords reporter-feedback added

Replying to linuxologos:

I'm testing 3.1-RC2-17229 and it seems to me that this fix is not working as described. In my case, category_in still requires an array. Tag_in/tag_not_in are working fine with integers though.

How are you testing?

An example piece of code that shows the issue will be really helpful in debugging this.

comment:10 westi3 years ago

Reproduced with this:

function query_tests() {
	query_test_one();
	query_test_two();
}

function query_test_one() {
	$one = new WP_Query();
	$one->query( array( 'category__in' => array( 1 ) ) );
}
function query_test_two() {
	$one = new WP_Query();
	$one->query( array( 'category__in' => 1 ) );
}

add_action( 'wp_footer', 'query_tests' , 1);

The first produces a valid query.

The second produces a notice:

WARNING: wp-includes/query.php:1695 - array_unique() expects parameter 1 to be array, integer given

Seeing as this was added in 3.1 and then removed again I think we can move this to 3.2 as an enhancement.

comment:11 linuxologos3 years ago

And even simplier:

The code below should be working according to [15626]:

query_posts( array( 'category__in' => 1 ) )

but it does not, returning unexpected posts and the already mentioned warning:

array_unique() expects parameter 1 to be array, integer given in ...\wp-includes\query.php on line 1695

The code works as expected only if category_in is provided an array (just like in the past), for example:

query_posts( array( 'category__in' => (array)1 ) ) or
query_posts( array( 'category__in' => array(1) ) )

Tag_in/tag_not_in (and possibly other parameters too) are working fine with integers, as they should according to [15626].

Last edited 3 years ago by linuxologos (previous) (diff)

comment:12 sboisvert3 years ago

Just to make it easier for someone else who can actually fix the problem, it seems to be related to the fact that

parse_tax_query()

parses categories differently than tags/tax, the logic that was added for this in line 1695 is as follows:

$qcategory__in? = array_unique( $qcategory__in? );

Which seems to be different than the one in [15626], in that the one in [15626] casts as an array and then traverses and casts the values of the array as ints:
$qvcategory__in? = array_map('absint', (array) $qvcategory__in?);

I suspect the behavior in [15626] might be the better one, but I wouldn't be able to say anything with any certainty if there is any valid reason why it was not implemented this way.

Thank you,

Version 1, edited 3 years ago by sboisvert (previous) (next) (diff)

comment:13 linuxologos3 years ago

Replying to westi:

Seeing as this was added in 3.1 and then removed again I think we can move this to 3.2 as an enhancement.

What is a bit annoying is that other parameters of query_posts() (I have not tested them all) are now accepting integers and category_in (only?) is making an odd exception. It seems like an inconsistency.

Last edited 3 years ago by linuxologos (previous) (diff)

comment:14 ocean903 years ago

  • Keywords query reporter-feedback removed

comment:15 linuxologos3 years ago

Take into consideration this patch by SergeyBiryukov here. It works for me and fixes both tickets (#14892, #16152).

comment:16 ryan3 years ago

  • Resolution set to fixed
  • Status changed from reopened to closed

(In [17245]) Cast category and tag query args to array to allow passing a single ID or slug. Props SergeyBiryukov. fixes #14892

Note: See TracTickets for help on using tickets.