From eadc17c4f9e059fd5a838f2567009e5d25f52edc Mon Sep 17 00:00:00 2001 From: Scott Taylor Date: Wed, 11 Jun 2014 02:27:36 +0000 Subject: [PATCH] In `wp_insert_term()`, when no slug is provided, check for an existing term by name. If it exists, use that slug instead of calling `sanitize_title( $name )`. Prevents creating an endless number of terms like `A+` or `$$$$` in any given taxonomy. Props wonderboymusic, SergeyBiryukov, aaroncampbell. Fixes #17689. git-svn-id: https://develop.svn.wordpress.org/trunk@28733 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/taxonomy.php | 8 ++++- tests/phpunit/tests/taxonomy.php | 62 ++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/taxonomy.php b/src/wp-includes/taxonomy.php index ae0ef81dd3..1c48934ae9 100644 --- a/src/wp-includes/taxonomy.php +++ b/src/wp-includes/taxonomy.php @@ -2436,7 +2436,13 @@ function wp_insert_term( $term, $taxonomy, $args = array() ) { $slug_provided = ! empty( $args['slug'] ); if ( ! $slug_provided ) { - $slug = sanitize_title($name); + $_name = trim( $name ); + $existing_term = get_term_by( 'name', $_name, $taxonomy ); + if ( $existing_term ) { + $slug = $existing_term->slug; + } else { + $slug = sanitize_title( $name ); + } } else { $slug = $args['slug']; } diff --git a/tests/phpunit/tests/taxonomy.php b/tests/phpunit/tests/taxonomy.php index 979cca14b8..7d5bff4588 100644 --- a/tests/phpunit/tests/taxonomy.php +++ b/tests/phpunit/tests/taxonomy.php @@ -232,4 +232,66 @@ class Tests_Taxonomy extends WP_UnitTestCase { ); $this->assertEquals( 0, wp_insert_category( $cat, false ) ); } + + /** + * @ticket 17689 + */ + function test_duplicate_name() { + $term = $this->factory->tag->create_and_get( array( 'name' => 'Bozo' ) ); + $this->assertFalse( is_wp_error( $term ) ); + $this->assertTrue( empty( $term->errors ) ); + + // Test existing term name with unique slug + $term1 = $this->factory->tag->create( array( 'name' => 'Bozo', 'slug' => 'bozo1' ) ); + $this->assertFalse( is_wp_error( $term1 ) ); + $this->assertTrue( empty($term1->errors ) ); + + // Test an existing term name + $term2 = $this->factory->tag->create( array( 'name' => 'Bozo' ) ); + $this->assertTrue( is_wp_error( $term2 ) ); + $this->assertNotEmpty( $term2->errors ); + + // Test named terms ending in special characters + $term3 = $this->factory->tag->create( array( 'name' => 'T$' ) ); + $term4 = $this->factory->tag->create( array( 'name' => 'T$$' ) ); + $term5 = $this->factory->tag->create( array( 'name' => 'T$$$' ) ); + $term6 = $this->factory->tag->create( array( 'name' => 'T$$$$' ) ); + $term7 = $this->factory->tag->create( array( 'name' => 'T$$$$' ) ); + $this->assertTrue( is_wp_error( $term7 ) ); + $this->assertNotEmpty( $term7->errors ); + $this->assertEquals( $term6, $term7->error_data['term_exists'] ); + + $terms = array_map( 'get_tag', array( $term3, $term4, $term5, $term6 ) ); + $this->assertCount( 4, array_unique( wp_list_pluck( $terms, 'slug' ) ) ); + + // Test named terms with only special characters + $term8 = $this->factory->tag->create( array( 'name' => '$' ) ); + $term9 = $this->factory->tag->create( array( 'name' => '$$' ) ); + $term10 = $this->factory->tag->create( array( 'name' => '$$$' ) ); + $term11 = $this->factory->tag->create( array( 'name' => '$$$$' ) ); + $term12 = $this->factory->tag->create( array( 'name' => '$$$$' ) ); + $this->assertTrue( is_wp_error( $term12 ) ); + $this->assertNotEmpty( $term12->errors ); + $this->assertEquals( $term11, $term12->error_data['term_exists'] ); + + $terms = array_map( 'get_tag', array( $term8, $term9, $term10, $term11 ) ); + $this->assertCount( 4, array_unique( wp_list_pluck( $terms, 'slug' ) ) ); + + $term13 = $this->factory->tag->create( array( 'name' => 'A' ) ); + $this->assertFalse( is_wp_error( $term13 ) ); + $term14 = $this->factory->tag->create( array( 'name' => 'A' ) ); + $this->assertTrue( is_wp_error( $term14 ) ); + $term15 = $this->factory->tag->create( array( 'name' => 'A+', 'slug' => 'a' ) ); + $this->assertFalse( is_wp_error( $term15 ) ); + $term16 = $this->factory->tag->create( array( 'name' => 'A+' ) ); + $this->assertTrue( is_wp_error( $term16 ) ); + $term17 = $this->factory->tag->create( array( 'name' => 'A++' ) ); + $this->assertFalse( is_wp_error( $term17 ) ); + $term18 = $this->factory->tag->create( array( 'name' => 'A-', 'slug' => 'a' ) ); + $this->assertFalse( is_wp_error( $term18 ) ); + $term19 = $this->factory->tag->create( array( 'name' => 'A-' ) ); + $this->assertTrue( is_wp_error( $term19 ) ); + $term20 = $this->factory->tag->create( array( 'name' => 'A--' ) ); + $this->assertFalse( is_wp_error( $term20 ) ); + } }