From 683db28b4c4eadd1cedcfa9eb27a6a9290d1d7ba Mon Sep 17 00:00:00 2001 From: ryan Date: Sat, 22 Sep 2007 18:01:08 +0000 Subject: [PATCH] Term with slug that conflicts with existing term with different parent gets a new term entry with a unique slug. see #5034 git-svn-id: http://svn.automattic.com/wordpress/trunk@6157 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/includes/taxonomy.php | 17 +++------- wp-includes/taxonomy.php | 59 +++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 14 deletions(-) diff --git a/wp-admin/includes/taxonomy.php b/wp-admin/includes/taxonomy.php index b382262c5c..3f70f45b8d 100644 --- a/wp-admin/includes/taxonomy.php +++ b/wp-admin/includes/taxonomy.php @@ -73,18 +73,6 @@ function wp_insert_category($catarr) { $slug = $category_nicename; $parent = $category_parent; - $name = apply_filters('pre_category_name', $name); - - if ( empty ($slug) ) - $slug = sanitize_title($name); - else - $slug = sanitize_title($slug); - $slug = apply_filters('pre_category_nicename', $slug); - - if ( empty ($description) ) - $description = ''; - $description = apply_filters('pre_category_description', $description); - $parent = (int) $parent; if ( empty($parent) || !category_exists( $parent ) || ($cat_ID && cat_is_ancestor_of($cat_ID, $parent) ) ) $parent = 0; @@ -96,6 +84,9 @@ function wp_insert_category($catarr) { else $cat_ID = wp_insert_term($cat_name, 'category', $args); + if ( is_wp_error($cat_ID) ) + return 0; + return $cat_ID['term_id']; } @@ -104,7 +95,7 @@ function wp_update_category($catarr) { $cat_ID = (int) $catarr['cat_ID']; - if( $cat_ID == $catarr['category_parent'] ) + if ( $cat_ID == $catarr['category_parent'] ) return false; // First, get all of the original fields diff --git a/wp-includes/taxonomy.php b/wp-includes/taxonomy.php index b23552c207..b484754aaa 100644 --- a/wp-includes/taxonomy.php +++ b/wp-includes/taxonomy.php @@ -707,6 +707,10 @@ function sanitize_term_field($field, $value, $term_id, $taxonomy, $context) { } else if ( 'db' == $context ) { $value = apply_filters("pre_term_$field", $value, $taxonomy); $value = apply_filters("pre_${taxonomy}_$field", $value); + // Back compat filters + if ( 'slug' == $field ) + $value = apply_filters('pre_category_nicename', $value); + } else if ( 'rss' == $context ) { $value = apply_filters("term_${field}_rss", $value, $taxonomy); $value = apply_filters("${taxonomy}_$field_rss", $value); @@ -914,6 +918,7 @@ function wp_insert_term( $term, $taxonomy, $args = array() ) { $defaults = array( 'alias_of' => '', 'description' => '', 'parent' => 0, 'slug' => ''); $args = wp_parse_args($args, $defaults); $args['name'] = $term; + $args['taxonomy'] = $taxonomy; $args = sanitize_term($args, $taxonomy, 'db'); extract($args, EXTR_SKIP); @@ -936,6 +941,12 @@ function wp_insert_term( $term, $taxonomy, $args = array() ) { if ( ! $term_id = is_term($slug) ) { $wpdb->query("INSERT INTO $wpdb->terms (name, slug, term_group) VALUES ('$name', '$slug', '$term_group')"); $term_id = (int) $wpdb->insert_id; + } else if ( is_taxonomy_hierarchical($taxonomy) && !empty($parent) ) { + // If the taxonomy supports hierarchy and the term has a parent, make the slug unique + // by incorporating parent slugs. + $slug = wp_unique_term_slug($slug, (object) $args); + $wpdb->query("INSERT INTO $wpdb->terms (name, slug, term_group) VALUES ('$name', '$slug', '$term_group')"); + $term_id = (int) $wpdb->insert_id; } if ( empty($slug) ) { @@ -1019,6 +1030,38 @@ function wp_set_object_terms($object_id, $terms, $taxonomy, $append = false) { return $tt_ids; } +function wp_unique_term_slug($slug, $term) { + global $wpdb; + + // If the taxonomy supports hierarchy and the term has a parent, make the slug unique + // by incorporating parent slugs. + if ( 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; + $slug .= '-' . $parent_term->slug; + 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. + if ( $wpdb->get_var("SELECT slug FROM $wpdb->terms WHERE slug = '$slug'") ) { + $num = 2; + do { + $alt_slug = $slug . "-$num"; + $num++; + $slug_check = $wpdb->get_var("SELECT slug FROM $wpdb->terms WHERE slug = '$alt_slug'"); + } while ( $slug_check ); + $slug = $alt_slug; + } + + return $slug; +} + function wp_update_term( $term, $taxonomy, $args = array() ) { global $wpdb; @@ -1041,8 +1084,11 @@ function wp_update_term( $term, $taxonomy, $args = array() ) { $args = sanitize_term($args, $taxonomy, 'db'); extract($args, EXTR_SKIP); - if ( empty($slug) ) + $empty_slug = false; + if ( empty($slug) ) { + $empty_slug = true; $slug = sanitize_title($name); + } if ( $alias_of ) { $alias = $wpdb->fetch_row("SELECT term_id, term_group FROM $wpdb->terms WHERE slug = '$alias_of'"); @@ -1056,6 +1102,17 @@ function wp_update_term( $term, $taxonomy, $args = array() ) { } } + // Check for duplicate slug + $id = $wpdb->get_var("SELECT term_id FROM $wpdb->terms WHERE slug = '$slug'"); + if ( $id && ($id != $term_id) ) { + // If an empty slug was passed, reset the slug to something unique. + // Otherwise, bail. + if ( $empty_slug ) + $slug = wp_unique_term_slug($slug, (object) $args); + else + return new WP_Error('duplicate_term_slug', sprintf(__('The slug "%s" is already in use by another term'), $slug)); + } + $wpdb->query("UPDATE $wpdb->terms SET name = '$name', slug = '$slug', term_group = '$term_group' WHERE term_id = '$term_id'"); if ( empty($slug) ) {