From c2c8a6848d861118f1ba8c42c798fe37a9a95021 Mon Sep 17 00:00:00 2001 From: Boone Gorges Date: Mon, 26 Aug 2019 15:18:40 +0000 Subject: [PATCH] Taxonomy: Fix unique-slug check for terms with parents. `wp_unique_term_slug()` appends numeric suffixes when the requested slug is already in use by a sibling term. Changes introduced in [32837] inadvertently caused this suffixing to be skipped in cases where the requested slug is suffixed with the parent slug, so that it became possible to have two terms `childslug-parentslug` underneath to the same `parentslug`. We fix this regression by ensuring that the numeric-suffix routine runs in all cases. Props yashar_hv, saskak, dlh. Fixes #46431. git-svn-id: https://develop.svn.wordpress.org/trunk@45893 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/taxonomy.php | 30 ++++++------- tests/phpunit/tests/term/wpUniqueTermSlug.php | 45 +++++++++++++++++++ 2 files changed, 60 insertions(+), 15 deletions(-) diff --git a/src/wp-includes/taxonomy.php b/src/wp-includes/taxonomy.php index 2db5038ef1..dcfafb2cde 100644 --- a/src/wp-includes/taxonomy.php +++ b/src/wp-includes/taxonomy.php @@ -2745,22 +2745,22 @@ function wp_unique_term_slug( $slug, $term ) { if ( apply_filters( 'wp_unique_term_slug_is_bad_slug', $needs_suffix, $slug, $term ) ) { if ( $parent_suffix ) { $slug .= $parent_suffix; - } else { - if ( ! empty( $term->term_id ) ) { - $query = $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s AND term_id != %d", $slug, $term->term_id ); - } else { - $query = $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s", $slug ); - } + } - if ( $wpdb->get_var( $query ) ) { - $num = 2; - do { - $alt_slug = $slug . "-$num"; - $num++; - $slug_check = $wpdb->get_var( $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s", $alt_slug ) ); - } while ( $slug_check ); - $slug = $alt_slug; - } + if ( ! empty( $term->term_id ) ) { + $query = $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s AND term_id != %d", $slug, $term->term_id ); + } else { + $query = $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s", $slug ); + } + + if ( $wpdb->get_var( $query ) ) { // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared + $num = 2; + do { + $alt_slug = $slug . "-$num"; + $num++; + $slug_check = $wpdb->get_var( $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s", $alt_slug ) ); + } while ( $slug_check ); + $slug = $alt_slug; } } diff --git a/tests/phpunit/tests/term/wpUniqueTermSlug.php b/tests/phpunit/tests/term/wpUniqueTermSlug.php index b81dca5b40..75501edab6 100644 --- a/tests/phpunit/tests/term/wpUniqueTermSlug.php +++ b/tests/phpunit/tests/term/wpUniqueTermSlug.php @@ -127,4 +127,49 @@ class Tests_Term_WpUniqueTermSlug extends WP_UnitTestCase { $actual = wp_unique_term_slug( 'bar', $term2_object ); $this->assertEquals( 'bar-2', $actual ); } + + /** + * @ticket 46431 + */ + public function test_duplicate_parent_suffixed_slug_should_get_numeric_suffix() { + $t1 = self::factory()->term->create( + array( + 'taxonomy' => 'wptests_tax2', + 'name' => 'Animal', + 'slug' => 'animal', + ) + ); + + $t2 = self::factory()->term->create( + array( + 'taxonomy' => 'wptests_tax2', + 'name' => 'Dog', + 'slug' => 'dog', + ) + ); + + $t3 = self::factory()->term->create( + array( + 'taxonomy' => 'wptests_tax2', + 'name' => 'Cat', + 'slug' => 'dog-animal', + 'parent' => $t1, + ) + ); + + $t4 = self::factory()->term->create( + array( + 'taxonomy' => 'wptests_tax2', + 'name' => 'Giraffe', + 'slug' => 'giraffe', + 'parent' => $t1, + ) + ); + + $term = get_term( $t4 ); + + $slug = wp_unique_term_slug( 'dog', $term ); + + $this->assertSame( 'dog-animal-2', $slug ); + } }