Make WordPress Core

Changeset 34809


Ignore:
Timestamp:
10/03/2015 08:24:09 PM (9 years ago)
Author:
boonebgorges
Message:

When creating terms, avoid false dupe checks due to accented characters.

wp_insert_term() doesn't allow the creation of a term when the term name
is the same as another term in the same hierarchy level of the same taxonomy.
Previously, this duplicate check used get_term_by( 'name' ), which uses the
database collation to determine sameness. But common collations do not
distinguish between accented and non-accented versions of a character. As a
result, it was impossible to create a term 'Foo' if a sibling term with an
accented character existed.

We address this problem by using get_terms() to do the duplicate check. This
query returns all potentially matching terms. We then do a stricter check
for equivalence in PHP, before determining whether one of the matches is
indeed a duplicate.

Props boonebgorges, tyxla, geza.miklo, mehulkaklotar.
Fixes #33864.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/taxonomy-functions.php

    r34787 r34809  
    25172517     * unless a unique slug has been explicitly provided.
    25182518     */
    2519     if ( $name_match = get_term_by( 'name', $name, $taxonomy ) ) {
     2519    $name_matches = get_terms( $taxonomy, array(
     2520        'name' => $name,
     2521        'hide_empty' => false,
     2522    ) );
     2523
     2524    /*
     2525     * The `name` match in `get_terms()` doesn't differentiate accented characters,
     2526     * so we do a stricter comparison here.
     2527     */
     2528    $name_match = null;
     2529    if ( $name_matches ) {
     2530        foreach ( $name_matches as $_match ) {
     2531            if ( strtolower( $name ) === strtolower( $_match->name ) ) {
     2532                $name_match = $_match;
     2533                break;
     2534            }
     2535        }
     2536    }
     2537
     2538    if ( $name_match ) {
    25202539        $slug_match = get_term_by( 'slug', $slug, $taxonomy );
    25212540        if ( ! $slug_provided || $name_match->slug === $slug || $slug_match ) {
  • trunk/tests/phpunit/tests/term/wpInsertTerm.php

    r34720 r34809  
    629629    }
    630630
     631    /**
     632     * @ticket 33864
     633     */
     634    public function test_wp_insert_term_with_and_without_accents() {
     635        register_taxonomy( 'wptests_tax', 'post' );
     636
     637        $t1 = $this->factory->term->create( array(
     638            'name' => 'Foó',
     639            'taxonomy' => 'wptests_tax',
     640        ) );
     641        $t2 = $this->factory->term->create( array(
     642            'name' => 'Foo',
     643            'taxonomy' => 'wptests_tax',
     644        ) );
     645
     646        $this->assertInternalType( 'int', $t1 );
     647        $this->assertInternalType( 'int', $t2 );
     648        $this->assertNotEquals( $t1, $t2 );
     649
     650        $term_2 = get_term( $t2, 'wptests_tax' );
     651        $this->assertSame( $t2, $term_2->term_id );
     652        $this->assertSame( 'Foo', $term_2->name );
     653
     654    }
     655
    631656    /** Helpers **********************************************************/
    632657
Note: See TracChangeset for help on using the changeset viewer.