From f492a81d709719a175bc18321fee308b74e25cf1 Mon Sep 17 00:00:00 2001 From: Boone Gorges Date: Wed, 21 Oct 2015 16:53:51 +0000 Subject: [PATCH] Prevent non-public taxonomies from registering aquery var. [34247] made the 'public' paramater of `register_taxonomy()` work by blocking requests for non-public taxonomy archives during `parse_request()`. Blocking taxonomy archive requests this late means that it's impossible to register an independent query var that matches the slug of a non-public taxonomy. By moving the block to `register_taxonomy()` - not allowing these taxonomies to register their query vars in the first place - we free up the slug for other use. In addition, we free up a bit of processing (no need to look for the query var in `parse_request()` and better parallel the way non-public post types work. See `register_post_type()`. Non-public taxonomy archives that are requested using `?taxonomy=tax_name` are still blocked during `parse_request`. It's only custom query vars - `?tax_name=term` - that are affected by this change. Props mboynes. Fixes #21949. git-svn-id: https://develop.svn.wordpress.org/trunk@35333 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-wp.php | 10 +++----- src/wp-includes/taxonomy-functions.php | 2 +- tests/phpunit/includes/utils.php | 2 +- tests/phpunit/tests/taxonomy.php | 35 ++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/wp-includes/class-wp.php b/src/wp-includes/class-wp.php index 4a3b42c795..0f86251676 100644 --- a/src/wp-includes/class-wp.php +++ b/src/wp-includes/class-wp.php @@ -311,12 +311,10 @@ class WP { // Don't allow non-public taxonomies to be queried from the front-end. if ( ! is_admin() ) { foreach ( get_taxonomies( array( 'public' => false ), 'objects' ) as $taxonomy => $t ) { - // Check first for taxonomy-specific query_var. - if ( $t->query_var && isset( $this->query_vars[ $t->query_var ] ) ) { - unset( $this->query_vars[ $t->query_var ] ); - } - - // Next, check the 'taxonomy' query_var. + /* + * Disallow when set to the 'taxonomy' query var. + * Non-public taxonomies cannot register custom query vars. See register_taxonomy(). + */ if ( isset( $this->query_vars['taxonomy'] ) && $taxonomy === $this->query_vars['taxonomy'] ) { unset( $this->query_vars['taxonomy'], $this->query_vars['term'] ); } diff --git a/src/wp-includes/taxonomy-functions.php b/src/wp-includes/taxonomy-functions.php index 6c4a0b5b7e..891951bb9e 100644 --- a/src/wp-includes/taxonomy-functions.php +++ b/src/wp-includes/taxonomy-functions.php @@ -384,7 +384,7 @@ function register_taxonomy( $taxonomy, $object_type, $args = array() ) { return new WP_Error( 'taxonomy_length_invalid', __( 'Taxonomy names must be between 1 and 32 characters in length.' ) ); } - if ( false !== $args['query_var'] && ! empty( $wp ) ) { + if ( false !== $args['query_var'] && false !== $args['public'] && ! empty( $wp ) ) { if ( true === $args['query_var'] ) $args['query_var'] = $taxonomy; else diff --git a/tests/phpunit/includes/utils.php b/tests/phpunit/includes/utils.php index 1b3686ebcd..0a6dfc13a4 100644 --- a/tests/phpunit/includes/utils.php +++ b/tests/phpunit/includes/utils.php @@ -357,7 +357,7 @@ function _cleanup_query_vars() { unset( $GLOBALS[$v] ); foreach ( get_taxonomies( array() , 'objects' ) as $t ) { - if ( ! empty( $t->query_var ) ) + if ( $t->public && ! empty( $t->query_var ) ) $GLOBALS['wp']->add_query_var( $t->query_var ); } diff --git a/tests/phpunit/tests/taxonomy.php b/tests/phpunit/tests/taxonomy.php index 7f49fc2384..2063bbe333 100644 --- a/tests/phpunit/tests/taxonomy.php +++ b/tests/phpunit/tests/taxonomy.php @@ -463,6 +463,41 @@ class Tests_Taxonomy extends WP_UnitTestCase { $this->assertFalse( is_tax( 'wptests_tax' ) ); } + /** + * @ticket 21949 + */ + public function test_it_should_be_possible_to_register_a_query_var_that_matches_the_name_of_a_nonpublic_taxonomy() { + global $wp; + + register_taxonomy( 'wptests_tax', 'post', array( + 'public' => false, + ) ); + $t = $this->factory->term->create_and_get( array( + 'taxonomy' => 'wptests_tax', + ) ); + + $p = $this->factory->post->create(); + wp_set_object_terms( $p, $t->slug, 'wptests_tax' ); + + add_filter( 'do_parse_request', array( $this, 'register_query_var' ) ); + $this->go_to( '/?wptests_tax=foo' ); + remove_filter( 'do_parse_request', array( $this, 'register_query_var' ) ); + + // Not a taxonomy... + $this->assertFalse( is_tax( 'wptests_tax' ) ); + + // ...but query var works. + $this->assertSame( 'foo', $wp->query_vars['wptests_tax'] ); + } + + public static function register_query_var( $r ) { + global $wp; + + $wp->add_query_var( 'wptests_tax' ); + + return $r; + } + /** * @ticket 21949 */