[wp-trac] [WordPress Trac] #43271: Issue with term duplicate check in wp_insert_term
WordPress Trac
noreply at wordpress.org
Fri Feb 9 16:31:39 UTC 2018
#43271: Issue with term duplicate check in wp_insert_term
-------------------------+-----------------------------
Reporter: strategio | Owner:
Type: enhancement | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Taxonomy | Version: 4.9.4
Severity: normal | Keywords:
Focuses: |
-------------------------+-----------------------------
In WPML, we assume that a term can be duplicated in the same taxonomy in a
secondary language. This means that it will have the same 'slug' as the
one in the primary language.
Here's a practical example of 2 term links from the same taxonomy with the
same slug:
- http://example.org/city/paris/
- http://example.org/fr/city/paris/
In `wp_insert_term` we have several checks to ensure that a term is unique
in its taxonomy. All these checks can be overpassed with the standard WP
API '''except the last one''' which makes a direct call to the database:
{{{
/*
* Sanity check: if we just created a term with the same parent + taxonomy
+ slug but a higher term_id than
* an existing term, then we have unwittingly created a duplicate term.
Delete the dupe, and use the term_id
* and term_taxonomy_id of the older term instead. Then return out of the
function so that the "create" hooks
* are not fired.
*/
$duplicate_term = $wpdb->get_row( $wpdb->prepare( "SELECT t.term_id,
tt.term_taxonomy_id FROM $wpdb->terms t INNER JOIN $wpdb->term_taxonomy tt
ON ( tt.term_id = t.term_id ) WHERE t.slug = %s AND tt.parent = %d AND
tt.taxonomy = %s AND t.term_id < %d AND tt.term_taxonomy_id != %d", $slug,
$parent, $taxonomy, $term_id, $tt_id ) );
if ( $duplicate_term ) {
$wpdb->delete( $wpdb->terms, array( 'term_id' => $term_id ) );
$wpdb->delete( $wpdb->term_taxonomy, array( 'term_taxonomy_id' =>
$tt_id ) );
$term_id = (int) $duplicate_term->term_id;
$tt_id = (int) $duplicate_term->term_taxonomy_id;
clean_term_cache( $term_id, $taxonomy );
return array( 'term_id' => $term_id, 'term_taxonomy_id' => $tt_id
);
}
}}}
The above data validation is only performed in `wp_insert_term` and not in
`wp_update_term` which makes the data validation inconsistent between the
two function. This also allowed us to demonstrate that two terms with the
same slug can live together in the same taxonomy.
As a suggestion, this last check could be either:
- '''removed''': since we already have several checks before and it's not
performed when a term is updated.
- '''filterable''': by using `get_term_by` to fetch the potential existing
term, or having a specific filter hook (e.g.
`wp_bypass_term_duplication_check`).
--
Ticket URL: <https://core.trac.wordpress.org/ticket/43271>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list