WordPress Version: 6.4
/**
* Makes term slug unique, if it isn't already.
*
* The `$slug` has to be unique global to every taxonomy, meaning that one
* taxonomy term can't have a matching slug with another taxonomy term. Each
* slug has to be globally unique for every taxonomy.
*
* The way this works is that if the taxonomy that the term belongs to is
* hierarchical and has a parent, it will append that parent to the $slug.
*
* If that still doesn't return a unique slug, then it tries to append a number
* until it finds a number that is truly unique.
*
* The only purpose for `$term` is for appending a parent, if one exists.
*
* @since 2.3.0
*
* @global wpdb $wpdb WordPress database abstraction object.
*
* @param string $slug The string that will be tried for a unique slug.
* @param object $term The term object that the `$slug` will belong to.
* @return string Will return a true unique slug.
*/
function wp_unique_term_slug($slug, $term)
{
global $wpdb;
$needs_suffix = true;
$original_slug = $slug;
// As of 4.1, duplicate slugs are allowed as long as they're in different taxonomies.
if (!term_exists($slug) || get_option('db_version') >= 30133 && !get_term_by('slug', $slug, $term->taxonomy)) {
$needs_suffix = false;
}
/*
* If the taxonomy supports hierarchy and the term has a parent, make the slug unique
* by incorporating parent slugs.
*/
$parent_suffix = '';
if ($needs_suffix && is_taxonomy_hierarchical($term->taxonomy) && !empty($term->parent)) {
$the_parent = $term->parent;
while (!empty($the_parent)) {
$parent_term = get_term($the_parent, $term->taxonomy);
if (is_wp_error($parent_term) || empty($parent_term)) {
break;
}
$parent_suffix .= '-' . $parent_term->slug;
if (!term_exists($slug . $parent_suffix)) {
break;
}
if (empty($parent_term->parent)) {
break;
}
$the_parent = $parent_term->parent;
}
}
// If we didn't get a unique slug, try appending a number to make it unique.
/**
* Filters whether the proposed unique term slug is bad.
*
* @since 4.3.0
*
* @param bool $needs_suffix Whether the slug needs to be made unique with a suffix.
* @param string $slug The slug.
* @param object $term Term object.
*/
if (apply_filters('wp_unique_term_slug_is_bad_slug', $needs_suffix, $slug, $term)) {
if ($parent_suffix) {
$slug .= $parent_suffix;
}
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;
}
}
/**
* Filters the unique term slug.
*
* @since 4.3.0
*
* @param string $slug Unique term slug.
* @param object $term Term object.
* @param string $original_slug Slug originally passed to the function for testing.
*/
return apply_filters('wp_unique_term_slug', $slug, $term, $original_slug);
}