Make WordPress Core

Opened 6 years ago

Last modified 6 years ago

#42164 new defect (bug)

Conditional Tags not working when using ugly URL

Reported by: petersplugins's profile petersplugins Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 4.8.2
Component: Query Keywords: needs-patch needs-unit-tests needs-testing
Focuses: template Cc:

Description

When accessing a category archive via its pretty URL e.g.

example.com/category/whatever

the conditional tag

is_category()

returns true.

Accessing the same category archive via its ugly URL

example.com?cat=whatever

the conditional tag

is_category()

returns false.

I'm pretty sure this concerns other conditional tags too. This is not only a cosmetic flaw because it causes WP to use the wrong template. I've tested it with Twenty Seventeen and the homepage template was used in case of using an ugly URL.

Due tue the ugly URL always work independently of permalink settings this is a bug in my opinion.

Change History (3)

#1 follow-up: @jdgrimes
6 years ago

It looks like this is because in parse_query(), is_category is only set if the $tax_query has an 'operator' specified:

<?php
                        $this->parse_tax_query( $qv );

                        foreach ( $this->tax_query->queries as $tax_query ) {
                                if ( ! is_array( $tax_query ) ) {
                                        continue;
                                }

                                if ( isset( $tax_query['operator'] ) && 'NOT IN' != $tax_query['operator'] ) {
                                        switch ( $tax_query['taxonomy'] ) {
                                                case 'category':
                                                        $this->is_category = true;
                                                        break;
                                                case 'post_tag':
                                                        $this->is_tag = true;
                                                        break;
                                                default:
                                                        $this->is_tax = true;
                                        }
                                }
                        }

And in parse_tax_query(), the 'cat' query arg doesn't end up using an operator:

<?php
                // Category stuff
                if ( ! empty( $q['cat'] ) && ! $this->is_singular ) {
                        $cat_in = $cat_not_in = array();

                        // snip

                        foreach ( $cat_array as $cat ) {
                                if ( $cat > 0 )
                                        $cat_in[] = $cat;
                                elseif ( $cat < 0 )
                                        $cat_not_in[] = abs( $cat );
                        }

                        if ( ! empty( $cat_in ) ) {
                                $tax_query[] = array(
                                        'taxonomy' => 'category',
                                        'terms' => $cat_in,
                                        'field' => 'term_id',
                                        'include_children' => true
                                );
                        }

                        // snip
                }

I don't know if this is expected behavior or not. Looking at the history of the isset( $tax_query['operator'] ) condition might tell the tale.

#2 @swissspidy
6 years ago

  • Keywords needs-patch needs-unit-tests needs-testing added

Should if ( isset( $tax_query['operator'] ) && 'NOT IN' != $tax_query['operator'] ) be changed to if ( ! isset( $tax_query['operator'] ) || 'NOT IN' !== $tax_query['operator'] )? Seems like this would fix it.

#3 in reply to: ↑ 1 @petersplugins
6 years ago

Replying to jdgrimes:

I don't know if this is expected behavior or not

I came across the same and this is exactly what I thought...

Note: See TracTickets for help on using tickets.