Make WordPress Core

Opened 6 years ago

#45092 new enhancement

WP_Query->is_category wrongly calculate current category when WP_Term is passed

Reported by: matteowebsolution's profile matteowebsolution Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 4.9.8
Component: Taxonomy Keywords:
Focuses: Cc:

Description

Let's analyze this piece of code, part of class WP_Query, file wp-includes/class-wp-query.php ...

<?php
        public function is_category( $category = '' ) {
                if ( !$this->is_category )
                        return false;

                if ( empty($category) )
                        return true;

                $cat_obj = $this->get_queried_object();

                $category = array_map( 'strval', (array) $category );

                if ( in_array( (string) $cat_obj->term_id, $category ) )
                        return true;
                elseif ( in_array( $cat_obj->name, $category ) )
                        return true;
                elseif ( in_array( $cat_obj->slug, $category ) )
                        return true;

                return false;
        }

now, trying to pass 2 WP_Term, something really funny happens (i know specifications want the $category variable as a single id or slug or term_name, and not as class, but there was nothing blocking the thing to work, so i tried, and i wanted to report results).

$cat_obj value was

<?php
object(WP_Term)#9010 (16) {
  ["term_id"]=>
  int(7)
  ["name"]=>
  string(8) "Consigli"
  ["slug"]=>
  string(8) "consigli"
  ["term_group"]=>
  int(0)
  ["term_taxonomy_id"]=>
  int(7)
  ["taxonomy"]=>
  string(8) "category"
  ["description"]=>
  string(0) ""
  ["parent"]=>
  int(0)
  ["count"]=>
  int(4)
  ["filter"]=>
  string(3) "raw"
  ["cat_ID"]=>
  int(7)
  ["category_count"]=>
  int(4)
  ["category_description"]=>
  string(0) ""
  ["cat_name"]=>
  string(8) "Consigli"
  ["category_nicename"]=>
  string(8) "consigli"
  ["category_parent"]=>
  int(0)
}

the first WP_Term was

<?php
object(WP_Term)#9123 (16) {
  ["term_id"]=>
  int(7)
  ["name"]=>
  string(8) "Consigli"
  ["slug"]=>
  string(8) "consigli"
  ["term_group"]=>
  int(0)
  ["term_taxonomy_id"]=>
  int(7)
  ["taxonomy"]=>
  string(8) "category"
  ["description"]=>
  string(0) ""
  ["parent"]=>
  int(0)
  ["count"]=>
  int(4)
  ["filter"]=>
  string(3) "raw"
  ["cat_ID"]=>
  int(7)
  ["category_count"]=>
  int(4)
  ["category_description"]=>
  string(0) ""
  ["cat_name"]=>
  string(8) "Consigli"
  ["category_nicename"]=>
  string(8) "consigli"
  ["category_parent"]=>
  int(0)
}

The second term was instead:

<?php
object(WP_Term)#9154 (16) {
  ["term_id"]=>
  int(5)
  ["name"]=>
  string(4) "News"
  ["slug"]=>
  string(4) "news"
  ["term_group"]=>
  int(0)
  ["term_taxonomy_id"]=>
  int(5)
  ["taxonomy"]=>
  string(8) "category"
  ["description"]=>
  string(0) ""
  ["parent"]=>
  int(0)
  ["count"]=>
  int(7)
  ["filter"]=>
  string(3) "raw"
  ["cat_ID"]=>
  int(5)
  ["category_count"]=>
  int(7)
  ["category_description"]=>
  string(0) ""
  ["cat_name"]=>
  string(4) "News"
  ["category_nicename"]=>
  string(4) "news"
  ["category_parent"]=>
  int(0)
}

Please be aware that $cat_obj->term_id is 7, first term term_id is 7, and second term category_count is 7.

When the WP_Term object passes into this

<?php
$category = array_map( 'strval', (array) $category );

it becomes an array of value, as it's converted in array, so method

<?php
if ( in_array( (string) $cat_obj->term_id, $category ) )
    return true;

will return true for both searched terms.

More generally, if $cat_obj->term_id or $cat_obj->name or $cat_obj->slug are in some ways contained in searched WP_Term, this method will always return true. I know you need to respect old styled code, but nowadays we're best working with objects, so i'm wondering if you could do a more pointed and precise logging of these kind of errors. For example, you could hook a logger in each is_something method of class WP_Query, when you can check if we passed an instanceof the correct class (WP_Term for is_tag, is_category, is_tax etc) and warn if we passed a wrong class. Or if you have a better way to solve this, my ears are opened :)

Change History (0)

Note: See TracTickets for help on using tickets.