From 302e3d1116b0baaaea47f8037bab96f773845cb0 Mon Sep 17 00:00:00 2001 From: Boone Gorges Date: Wed, 16 Sep 2015 19:04:57 +0000 Subject: [PATCH] Allow taxonomies to be non-public. [13216] introduced the 'public' argument for `register_taxonomy()`. This param was used to set defaults for 'show_ui' and a number of other params, but it never did anything itself. With this changeset, taxonomies registered with `public=false` will no longer be queryable on the front end, ie via taxonomy archive queries. Props wpsmith, ocean90, nacin, ericlewis, boonebgorges. Fixes #21949. git-svn-id: https://develop.svn.wordpress.org/trunk@34247 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-wp.php | 15 ++++++++++ src/wp-includes/taxonomy-functions.php | 2 +- tests/phpunit/tests/taxonomy.php | 40 ++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp.php b/src/wp-includes/class-wp.php index 84111bca9f..6d008c87da 100644 --- a/src/wp-includes/class-wp.php +++ b/src/wp-includes/class-wp.php @@ -300,6 +300,21 @@ class WP { if ( $t->query_var && isset( $this->query_vars[$t->query_var] ) ) $this->query_vars[$t->query_var] = str_replace( ' ', '+', $this->query_vars[$t->query_var] ); + // 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. + if ( isset( $this->query_vars['taxonomy'] ) && $taxonomy === $this->query_vars['taxonomy'] ) { + unset( $this->query_vars['taxonomy'], $this->query_vars['term'] ); + } + } + } + // Limit publicly queried post_types to those that are publicly_queryable if ( isset( $this->query_vars['post_type']) ) { $queryable_post_types = get_post_types( array('publicly_queryable' => true) ); diff --git a/src/wp-includes/taxonomy-functions.php b/src/wp-includes/taxonomy-functions.php index eee37bc8a3..280f440775 100644 --- a/src/wp-includes/taxonomy-functions.php +++ b/src/wp-includes/taxonomy-functions.php @@ -278,7 +278,7 @@ function is_taxonomy_hierarchical($taxonomy) { * * By default tag labels are used for non-hierarchical types and category labels for hierarchical ones. * * You can see accepted values in {@link get_taxonomy_labels()}. * - description - A short descriptive summary of what the taxonomy is for. Defaults to blank. - * - public - If the taxonomy should be publicly queryable; //@TODO not implemented. + * - public - If the taxonomy should be publicly queryable. * * Defaults to true. * - hierarchical - Whether the taxonomy is hierarchical (e.g. category). Defaults to false. * - show_ui - Whether to generate a default UI for managing this taxonomy in the admin. diff --git a/tests/phpunit/tests/taxonomy.php b/tests/phpunit/tests/taxonomy.php index 8db5bfe31a..5a6af2e935 100644 --- a/tests/phpunit/tests/taxonomy.php +++ b/tests/phpunit/tests/taxonomy.php @@ -442,4 +442,44 @@ class Tests_Taxonomy extends WP_UnitTestCase { $this->assertEqualSets( array( $t1 ), get_ancestors( $t2, 'wptests_conflict' ) ); _unregister_post_type( 'wptests_pt' ); } + + /** + * @ticket 21949 + */ + public function test_nonpublic_taxonomy_should_not_be_queryable_using_taxname_query_var() { + 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' ); + + $this->go_to( '/?wptests_tax=' . $t->slug ); + + $this->assertFalse( is_tax( 'wptests_tax' ) ); + } + + /** + * @ticket 21949 + */ + public function test_nonpublic_taxonomy_should_not_be_queryable_using_taxonomy_and_term_vars() { + 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' ); + + $this->go_to( '/?taxonomy=wptests_tax&term=' . $t->slug ); + + $this->assertFalse( is_tax( 'wptests_tax' ) ); + } }