wp_insert_term

Add a new term to the database.

Description

(array|WP_Error) wp_insert_term( (string) $term, (string) $taxonomy, (array) $args = array() ); 

A non-existent term is inserted in the following sequence: 1. The term is added to the term table, then related to the taxonomy. 2. If everything is correct, several actions are fired. 3. The term_id_filter is evaluated. 4. The term cache is cleaned. 5. Several more actions are fired. 6. An array is returned containing the term_id and term_taxonomy_id.

If the slug argument is not empty, then it is checked to see if the term is invalid. If it is not a valid, existing term, it is added and the term_id is given.

If the taxonomy is hierarchical, and the parent argument is not empty, the term is inserted and the term_id will be given.

Error handling: If $taxonomy does not exist or $term is empty, a WP_Error object will be returned.

If the term already exists on the same hierarchical level, or the term slug and name are not unique, a WP_Error object will be returned.

Returns (array|WP_Error)

An array containing the `term_id` and `term_taxonomy_id`, WP_Error otherwise.

Parameters (3)

0. $term (string)
The term to add or update.
1. $taxonomy (string)
The taxonomy to which to add the term.
2. $args — Optional. (array) => array()
Array or string of arguments for inserting a term.

Options

  • alias_of (string) => ''

    Slug of the term to make this term an alias of. Default empty string. Accepts a term slug.

  • description (string) => string

    The term description.

  • parent (int) => 0

    The id of the parent term.

array(

    /**
     * Slug of the term to make this term an alias of. Default empty string. Accepts a term slug.
     *
     * @type string
     * @default ''
     */
    'alias_of' => '',

    /**
     * The term description.
     *
     * @type string
     * @default string
     */
    'description' => string,

    /**
     * The id of the parent term.
     *
     * @type int
     */
    'parent' => 0
);        


Usage

  1. if ( !function_exists( 'wp_insert_term' ) ) { 
  2. require_once ABSPATH . WPINC . '/taxonomy.php'; 
  3.  
  4. // The term to add or update. 
  5. $term = ''; 
  6.  
  7. // The taxonomy to which to add the term. 
  8. $taxonomy = ''; 
  9.  
  10. // Optional. Array or string of arguments for inserting a term. 
  11. $args = array( 
  12. 'alias_of' => '', 
  13. 'description' => string, 
  14. 'parent' => 0 
  15. ); 
  16.  
  17. // NOTICE! Understand what this does before running. 
  18. $result = wp_insert_term($term, $taxonomy, $args); 
  19.  

Defined (1)

The function is defined in the following location(s).

/wp-includes/taxonomy.php  
  1. function wp_insert_term( $term, $taxonomy, $args = array() ) { 
  2. global $wpdb; 
  3.  
  4. if ( ! taxonomy_exists($taxonomy) ) { 
  5. return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) ); 
  6. /** 
  7. * Filters a term before it is sanitized and inserted into the database. 
  8. * @since 3.0.0 
  9. * @param string $term The term to add or update. 
  10. * @param string $taxonomy Taxonomy slug. 
  11. */ 
  12. $term = apply_filters( 'pre_insert_term', $term, $taxonomy ); 
  13. if ( is_wp_error( $term ) ) { 
  14. return $term; 
  15. if ( is_int( $term ) && 0 == $term ) { 
  16. return new WP_Error( 'invalid_term_id', __( 'Invalid term ID.' ) ); 
  17. if ( '' == trim( $term ) ) { 
  18. return new WP_Error( 'empty_term_name', __( 'A name is required for this term.' ) ); 
  19. $defaults = array( 'alias_of' => '', 'description' => '', 'parent' => 0, 'slug' => ''); 
  20. $args = wp_parse_args( $args, $defaults ); 
  21.  
  22. if ( $args['parent'] > 0 && ! term_exists( (int) $args['parent'] ) ) { 
  23. return new WP_Error( 'missing_parent', __( 'Parent term does not exist.' ) ); 
  24.  
  25. $args['name'] = $term; 
  26. $args['taxonomy'] = $taxonomy; 
  27.  
  28. // Coerce null description to strings, to avoid database errors. 
  29. $args['description'] = (string) $args['description']; 
  30.  
  31. $args = sanitize_term($args, $taxonomy, 'db'); 
  32.  
  33. // expected_slashed ($name) 
  34. $name = wp_unslash( $args['name'] ); 
  35. $description = wp_unslash( $args['description'] ); 
  36. $parent = (int) $args['parent']; 
  37.  
  38. $slug_provided = ! empty( $args['slug'] ); 
  39. if ( ! $slug_provided ) { 
  40. $slug = sanitize_title( $name ); 
  41. } else { 
  42. $slug = $args['slug']; 
  43.  
  44. $term_group = 0; 
  45. if ( $args['alias_of'] ) { 
  46. $alias = get_term_by( 'slug', $args['alias_of'], $taxonomy ); 
  47. if ( ! empty( $alias->term_group ) ) { 
  48. // The alias we want is already in a group, so let's use that one. 
  49. $term_group = $alias->term_group; 
  50. } elseif ( ! empty( $alias->term_id ) ) { 
  51. /** 
  52. * The alias is not in a group, so we create a new one 
  53. * and add the alias to it. 
  54. */ 
  55. $term_group = $wpdb->get_var("SELECT MAX(term_group) FROM $wpdb->terms") + 1; 
  56.  
  57. wp_update_term( $alias->term_id, $taxonomy, array( 
  58. 'term_group' => $term_group,  
  59. ) ); 
  60.  
  61. /** 
  62. * Prevent the creation of terms with duplicate names at the same level of a taxonomy hierarchy,  
  63. * unless a unique slug has been explicitly provided. 
  64. */ 
  65. $name_matches = get_terms( $taxonomy, array( 
  66. 'name' => $name,  
  67. 'hide_empty' => false,  
  68. ) ); 
  69.  
  70. /** 
  71. * The `name` match in `get_terms()` doesn't differentiate accented characters,  
  72. * so we do a stricter comparison here. 
  73. */ 
  74. $name_match = null; 
  75. if ( $name_matches ) { 
  76. foreach ( $name_matches as $_match ) { 
  77. if ( strtolower( $name ) === strtolower( $_match->name ) ) { 
  78. $name_match = $_match; 
  79. break; 
  80.  
  81. if ( $name_match ) { 
  82. $slug_match = get_term_by( 'slug', $slug, $taxonomy ); 
  83. if ( ! $slug_provided || $name_match->slug === $slug || $slug_match ) { 
  84. if ( is_taxonomy_hierarchical( $taxonomy ) ) { 
  85. $siblings = get_terms( $taxonomy, array( 'get' => 'all', 'parent' => $parent ) ); 
  86.  
  87. $existing_term = null; 
  88. if ( $name_match->slug === $slug && in_array( $name, wp_list_pluck( $siblings, 'name' ) ) ) { 
  89. $existing_term = $name_match; 
  90. } elseif ( $slug_match && in_array( $slug, wp_list_pluck( $siblings, 'slug' ) ) ) { 
  91. $existing_term = $slug_match; 
  92.  
  93. if ( $existing_term ) { 
  94. return new WP_Error( 'term_exists', __( 'A term with the name provided already exists with this parent.' ), $existing_term->term_id ); 
  95. } else { 
  96. return new WP_Error( 'term_exists', __( 'A term with the name provided already exists in this taxonomy.' ), $name_match->term_id ); 
  97.  
  98. $slug = wp_unique_term_slug( $slug, (object) $args ); 
  99.  
  100. if ( false === $wpdb->insert( $wpdb->terms, compact( 'name', 'slug', 'term_group' ) ) ) { 
  101. return new WP_Error( 'db_insert_error', __( 'Could not insert term into the database' ), $wpdb->last_error ); 
  102.  
  103. $term_id = (int) $wpdb->insert_id; 
  104.  
  105. // Seems unreachable, However, Is used in the case that a term name is provided, which sanitizes to an empty string. 
  106. if ( empty($slug) ) { 
  107. $slug = sanitize_title($slug, $term_id); 
  108.  
  109. /** This action is documented in wp-includes/taxonomy.php */ 
  110. do_action( 'edit_terms', $term_id, $taxonomy ); 
  111. $wpdb->update( $wpdb->terms, compact( 'slug' ), compact( 'term_id' ) ); 
  112.  
  113. /** This action is documented in wp-includes/taxonomy.php */ 
  114. do_action( 'edited_terms', $term_id, $taxonomy ); 
  115.  
  116. $tt_id = $wpdb->get_var( $wpdb->prepare( "SELECT tt.term_taxonomy_id FROM $wpdb->term_taxonomy AS tt INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = %s AND t.term_id = %d", $taxonomy, $term_id ) ); 
  117.  
  118. if ( !empty($tt_id) ) { 
  119. return array('term_id' => $term_id, 'term_taxonomy_id' => $tt_id); 
  120. $wpdb->insert( $wpdb->term_taxonomy, compact( 'term_id', 'taxonomy', 'description', 'parent') + array( 'count' => 0 ) ); 
  121. $tt_id = (int) $wpdb->insert_id; 
  122.  
  123. /** 
  124. * Sanity check: if we just created a term with the same parent + taxonomy + slug but a higher term_id than 
  125. * an existing term, then we have unwittingly created a duplicate term. Delete the dupe, and use the term_id 
  126. * and term_taxonomy_id of the older term instead. Then return out of the function so that the "create" hooks 
  127. * are not fired. 
  128. */ 
  129. $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 ) ); 
  130. if ( $duplicate_term ) { 
  131. $wpdb->delete( $wpdb->terms, array( 'term_id' => $term_id ) ); 
  132. $wpdb->delete( $wpdb->term_taxonomy, array( 'term_taxonomy_id' => $tt_id ) ); 
  133.  
  134. $term_id = (int) $duplicate_term->term_id; 
  135. $tt_id = (int) $duplicate_term->term_taxonomy_id; 
  136.  
  137. clean_term_cache( $term_id, $taxonomy ); 
  138. return array( 'term_id' => $term_id, 'term_taxonomy_id' => $tt_id ); 
  139.  
  140. /** 
  141. * Fires immediately after a new term is created, before the term cache is cleaned. 
  142. * @since 2.3.0 
  143. * @param int $term_id Term ID. 
  144. * @param int $tt_id Term taxonomy ID. 
  145. * @param string $taxonomy Taxonomy slug. 
  146. */ 
  147. do_action( "create_term", $term_id, $tt_id, $taxonomy ); 
  148.  
  149. /** 
  150. * Fires after a new term is created for a specific taxonomy. 
  151. * The dynamic portion of the hook name, `$taxonomy`, refers 
  152. * to the slug of the taxonomy the term was created for. 
  153. * @since 2.3.0 
  154. * @param int $term_id Term ID. 
  155. * @param int $tt_id Term taxonomy ID. 
  156. */ 
  157. do_action( "create_$taxonomy", $term_id, $tt_id ); 
  158.  
  159. /** 
  160. * Filters the term ID after a new term is created. 
  161. * @since 2.3.0 
  162. * @param int $term_id Term ID. 
  163. * @param int $tt_id Taxonomy term ID. 
  164. */ 
  165. $term_id = apply_filters( 'term_id_filter', $term_id, $tt_id ); 
  166.  
  167. clean_term_cache($term_id, $taxonomy); 
  168.  
  169. /** 
  170. * Fires after a new term is created, and after the term cache has been cleaned. 
  171. * @since 2.3.0 
  172. * @param int $term_id Term ID. 
  173. * @param int $tt_id Term taxonomy ID. 
  174. * @param string $taxonomy Taxonomy slug. 
  175. */ 
  176. do_action( 'created_term', $term_id, $tt_id, $taxonomy ); 
  177.  
  178. /** 
  179. * Fires after a new term in a specific taxonomy is created, and after the term 
  180. * cache has been cleaned. 
  181. * The dynamic portion of the hook name, `$taxonomy`, refers to the taxonomy slug. 
  182. * @since 2.3.0 
  183. * @param int $term_id Term ID. 
  184. * @param int $tt_id Term taxonomy ID. 
  185. */ 
  186. do_action( "created_$taxonomy", $term_id, $tt_id ); 
  187.  
  188. return array('term_id' => $term_id, 'term_taxonomy_id' => $tt_id);