wp/wp-includes/taxonomy.php
changeset 18 be944660c56a
parent 16 a86126ab1dd4
child 19 3d72ae0968f4
equal deleted inserted replaced
17:34716fd837a4 18:be944660c56a
   137 				'add_new_item'               => __( 'Add New Link Category' ),
   137 				'add_new_item'               => __( 'Add New Link Category' ),
   138 				'new_item_name'              => __( 'New Link Category Name' ),
   138 				'new_item_name'              => __( 'New Link Category Name' ),
   139 				'separate_items_with_commas' => null,
   139 				'separate_items_with_commas' => null,
   140 				'add_or_remove_items'        => null,
   140 				'add_or_remove_items'        => null,
   141 				'choose_from_most_used'      => null,
   141 				'choose_from_most_used'      => null,
   142 				'back_to_items'              => __( '← Back to Link Categories' ),
   142 				'back_to_items'              => __( '← Go to Link Categories' ),
   143 			),
   143 			),
   144 			'capabilities' => array(
   144 			'capabilities' => array(
   145 				'manage_terms' => 'manage_links',
   145 				'manage_terms' => 'manage_links',
   146 				'edit_terms'   => 'manage_links',
   146 				'edit_terms'   => 'manage_links',
   147 				'delete_terms' => 'manage_links',
   147 				'delete_terms' => 'manage_links',
   170 			'show_ui'           => false,
   170 			'show_ui'           => false,
   171 			'_builtin'          => true,
   171 			'_builtin'          => true,
   172 			'show_in_nav_menus' => current_theme_supports( 'post-formats' ),
   172 			'show_in_nav_menus' => current_theme_supports( 'post-formats' ),
   173 		)
   173 		)
   174 	);
   174 	);
       
   175 
       
   176 	register_taxonomy(
       
   177 		'wp_theme',
       
   178 		array( 'wp_template' ),
       
   179 		array(
       
   180 			'public'            => false,
       
   181 			'hierarchical'      => false,
       
   182 			'labels'            => array(
       
   183 				'name'          => __( 'Themes' ),
       
   184 				'singular_name' => __( 'Theme' ),
       
   185 			),
       
   186 			'query_var'         => false,
       
   187 			'rewrite'           => false,
       
   188 			'show_ui'           => false,
       
   189 			'_builtin'          => true,
       
   190 			'show_in_nav_menus' => false,
       
   191 			'show_in_rest'      => false,
       
   192 		)
       
   193 	);
   175 }
   194 }
   176 
   195 
   177 /**
   196 /**
   178  * Retrieves a list of registered taxonomy names or objects.
   197  * Retrieves a list of registered taxonomy names or objects.
   179  *
   198  *
   342  * @param string       $taxonomy    Taxonomy key, must not exceed 32 characters.
   361  * @param string       $taxonomy    Taxonomy key, must not exceed 32 characters.
   343  * @param array|string $object_type Object type or array of object types with which the taxonomy should be associated.
   362  * @param array|string $object_type Object type or array of object types with which the taxonomy should be associated.
   344  * @param array|string $args        {
   363  * @param array|string $args        {
   345  *     Optional. Array or query string of arguments for registering a taxonomy.
   364  *     Optional. Array or query string of arguments for registering a taxonomy.
   346  *
   365  *
   347  *     @type array         $labels                An array of labels for this taxonomy. By default, Tag labels are
   366  *     @type string[]      $labels                An array of labels for this taxonomy. By default, Tag labels are
   348  *                                                used for non-hierarchical taxonomies, and Category labels are used
   367  *                                                used for non-hierarchical taxonomies, and Category labels are used
   349  *                                                for hierarchical taxonomies. See accepted values in
   368  *                                                for hierarchical taxonomies. See accepted values in
   350  *                                                get_taxonomy_labels(). Default empty array.
   369  *                                                get_taxonomy_labels(). Default empty array.
   351  *     @type string        $description           A short descriptive summary of what the taxonomy is for. Default empty.
   370  *     @type string        $description           A short descriptive summary of what the taxonomy is for. Default empty.
   352  *     @type bool          $public                Whether a taxonomy is intended for use publicly either via
   371  *     @type bool          $public                Whether a taxonomy is intended for use publicly either via
   380  *                                                post_tags_meta_box() is used for non-hierarchical. If false, no meta
   399  *                                                post_tags_meta_box() is used for non-hierarchical. If false, no meta
   381  *                                                box is shown.
   400  *                                                box is shown.
   382  *     @type callable      $meta_box_sanitize_cb  Callback function for sanitizing taxonomy data saved from a meta
   401  *     @type callable      $meta_box_sanitize_cb  Callback function for sanitizing taxonomy data saved from a meta
   383  *                                                box. If no callback is defined, an appropriate one is determined
   402  *                                                box. If no callback is defined, an appropriate one is determined
   384  *                                                based on the value of `$meta_box_cb`.
   403  *                                                based on the value of `$meta_box_cb`.
   385  *     @type array         $capabilities {
   404  *     @type string[]      $capabilities {
   386  *         Array of capabilities for this taxonomy.
   405  *         Array of capabilities for this taxonomy.
   387  *
   406  *
   388  *         @type string $manage_terms Default 'manage_categories'.
   407  *         @type string $manage_terms Default 'manage_categories'.
   389  *         @type string $edit_terms   Default 'manage_categories'.
   408  *         @type string $edit_terms   Default 'manage_categories'.
   390  *         @type string $delete_terms Default 'manage_categories'.
   409  *         @type string $delete_terms Default 'manage_categories'.
   412  *
   431  *
   413  *         @type string $name         Name of default term.
   432  *         @type string $name         Name of default term.
   414  *         @type string $slug         Slug for default term. Default empty.
   433  *         @type string $slug         Slug for default term. Default empty.
   415  *         @type string $description  Description for default term. Default empty.
   434  *         @type string $description  Description for default term. Default empty.
   416  *     }
   435  *     }
       
   436  *     @type bool          $sort                  Whether terms in this taxonomy should be sorted in the order they are
       
   437  *                                                provided to `wp_set_object_terms()`. Default null which equates to false.
       
   438  *     @type array         $args                  Array of arguments to automatically use inside `wp_get_object_terms()`
       
   439  *                                                for this taxonomy.
   417  *     @type bool          $_builtin              This taxonomy is a "built-in" taxonomy. INTERNAL USE ONLY!
   440  *     @type bool          $_builtin              This taxonomy is a "built-in" taxonomy. INTERNAL USE ONLY!
   418  *                                                Default false.
   441  *                                                Default false.
   419  * }
   442  * }
   420  * @return WP_Taxonomy|WP_Error The registered taxonomy object on success, WP_Error object on failure.
   443  * @return WP_Taxonomy|WP_Error The registered taxonomy object on success, WP_Error object on failure.
   421  */
   444  */
   485  *
   508  *
   486  * @global WP    $wp            Current WordPress environment instance.
   509  * @global WP    $wp            Current WordPress environment instance.
   487  * @global array $wp_taxonomies List of taxonomies.
   510  * @global array $wp_taxonomies List of taxonomies.
   488  *
   511  *
   489  * @param string $taxonomy Taxonomy name.
   512  * @param string $taxonomy Taxonomy name.
   490  * @return bool|WP_Error True on success, WP_Error on failure or if the taxonomy doesn't exist.
   513  * @return true|WP_Error True on success, WP_Error on failure or if the taxonomy doesn't exist.
   491  */
   514  */
   492 function unregister_taxonomy( $taxonomy ) {
   515 function unregister_taxonomy( $taxonomy ) {
   493 	if ( ! taxonomy_exists( $taxonomy ) ) {
   516 	if ( ! taxonomy_exists( $taxonomy ) ) {
   494 		return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) );
   517 		return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) );
   495 	}
   518 	}
   531  *
   554  *
   532  * @since 3.0.0
   555  * @since 3.0.0
   533  * @since 4.3.0 Added the `no_terms` label.
   556  * @since 4.3.0 Added the `no_terms` label.
   534  * @since 4.4.0 Added the `items_list_navigation` and `items_list` labels.
   557  * @since 4.4.0 Added the `items_list_navigation` and `items_list` labels.
   535  * @since 4.9.0 Added the `most_used` and `back_to_items` labels.
   558  * @since 4.9.0 Added the `most_used` and `back_to_items` labels.
       
   559  * @since 5.7.0 Added the `filter_by_item` label.
       
   560  * @since 5.8.0 Added the `item_link` and `item_link_description` labels.
   536  *
   561  *
   537  * @param WP_Taxonomy $tax Taxonomy object.
   562  * @param WP_Taxonomy $tax Taxonomy object.
   538  * @return object {
   563  * @return object {
   539  *     Taxonomy labels object. The first default value is for non-hierarchical taxonomies
   564  *     Taxonomy labels object. The first default value is for non-hierarchical taxonomies
   540  *     (like tags) and the second one is for hierarchical taxonomies (like categories).
   565  *     (like tags) and the second one is for hierarchical taxonomies (like categories).
   563  *                                              'Choose from the most used tags', used in the meta box.
   588  *                                              'Choose from the most used tags', used in the meta box.
   564  *     @type string $not_found                  Default 'No tags found'/'No categories found', used in
   589  *     @type string $not_found                  Default 'No tags found'/'No categories found', used in
   565  *                                              the meta box and taxonomy list table.
   590  *                                              the meta box and taxonomy list table.
   566  *     @type string $no_terms                   Default 'No tags'/'No categories', used in the posts and media
   591  *     @type string $no_terms                   Default 'No tags'/'No categories', used in the posts and media
   567  *                                              list tables.
   592  *                                              list tables.
       
   593  *     @type string $filter_by_item             This label is only used for hierarchical taxonomies. Default
       
   594  *                                              'Filter by category', used in the posts list table.
   568  *     @type string $items_list_navigation      Label for the table pagination hidden heading.
   595  *     @type string $items_list_navigation      Label for the table pagination hidden heading.
   569  *     @type string $items_list                 Label for the table hidden heading.
   596  *     @type string $items_list                 Label for the table hidden heading.
   570  *     @type string $most_used                  Title for the Most Used tab. Default 'Most Used'.
   597  *     @type string $most_used                  Title for the Most Used tab. Default 'Most Used'.
   571  *     @type string $back_to_items              Label displayed after a term has been updated.
   598  *     @type string $back_to_items              Label displayed after a term has been updated.
       
   599  *     @type string $item_link                  Used in the block editor. Title for a navigation link block variation.
       
   600  *                                              Default 'Tag Link'/'Category Link'.
       
   601  *     @type string $item_link_description      Used in the block editor. Description for a navigation link block
       
   602  *                                              variation. Default 'A link to a tag'/'A link to a category'.
   572  * }
   603  * }
   573  */
   604  */
   574 function get_taxonomy_labels( $tax ) {
   605 function get_taxonomy_labels( $tax ) {
   575 	$tax->labels = (array) $tax->labels;
   606 	$tax->labels = (array) $tax->labels;
   576 
   607 
   598 		'separate_items_with_commas' => array( __( 'Separate tags with commas' ), null ),
   629 		'separate_items_with_commas' => array( __( 'Separate tags with commas' ), null ),
   599 		'add_or_remove_items'        => array( __( 'Add or remove tags' ), null ),
   630 		'add_or_remove_items'        => array( __( 'Add or remove tags' ), null ),
   600 		'choose_from_most_used'      => array( __( 'Choose from the most used tags' ), null ),
   631 		'choose_from_most_used'      => array( __( 'Choose from the most used tags' ), null ),
   601 		'not_found'                  => array( __( 'No tags found.' ), __( 'No categories found.' ) ),
   632 		'not_found'                  => array( __( 'No tags found.' ), __( 'No categories found.' ) ),
   602 		'no_terms'                   => array( __( 'No tags' ), __( 'No categories' ) ),
   633 		'no_terms'                   => array( __( 'No tags' ), __( 'No categories' ) ),
       
   634 		'filter_by_item'             => array( null, __( 'Filter by category' ) ),
   603 		'items_list_navigation'      => array( __( 'Tags list navigation' ), __( 'Categories list navigation' ) ),
   635 		'items_list_navigation'      => array( __( 'Tags list navigation' ), __( 'Categories list navigation' ) ),
   604 		'items_list'                 => array( __( 'Tags list' ), __( 'Categories list' ) ),
   636 		'items_list'                 => array( __( 'Tags list' ), __( 'Categories list' ) ),
   605 		/* translators: Tab heading when selecting from the most used terms. */
   637 		/* translators: Tab heading when selecting from the most used terms. */
   606 		'most_used'                  => array( _x( 'Most Used', 'tags' ), _x( 'Most Used', 'categories' ) ),
   638 		'most_used'                  => array( _x( 'Most Used', 'tags' ), _x( 'Most Used', 'categories' ) ),
   607 		'back_to_items'              => array( __( '← Back to Tags' ), __( '← Back to Categories' ) ),
   639 		'back_to_items'              => array( __( '← Go to Tags' ), __( '← Go to Categories' ) ),
       
   640 		'item_link'                  => array(
       
   641 			_x( 'Tag Link', 'navigation link block title' ),
       
   642 			_x( 'Category Link', 'navigation link block description' ),
       
   643 		),
       
   644 		'item_link_description'      => array(
       
   645 			_x( 'A link to a tag.', 'navigation link block description' ),
       
   646 			_x( 'A link to a category.', 'navigation link block description' ),
       
   647 		),
   608 	);
   648 	);
       
   649 
   609 	$nohier_vs_hier_defaults['menu_name'] = $nohier_vs_hier_defaults['name'];
   650 	$nohier_vs_hier_defaults['menu_name'] = $nohier_vs_hier_defaults['name'];
   610 
   651 
   611 	$labels = _get_custom_object_labels( $tax, $nohier_vs_hier_defaults );
   652 	$labels = _get_custom_object_labels( $tax, $nohier_vs_hier_defaults );
   612 
   653 
   613 	$taxonomy = $tax->name;
   654 	$taxonomy = $tax->name;
   616 
   657 
   617 	/**
   658 	/**
   618 	 * Filters the labels of a specific taxonomy.
   659 	 * Filters the labels of a specific taxonomy.
   619 	 *
   660 	 *
   620 	 * The dynamic portion of the hook name, `$taxonomy`, refers to the taxonomy slug.
   661 	 * The dynamic portion of the hook name, `$taxonomy`, refers to the taxonomy slug.
       
   662 	 *
       
   663 	 * Possible hook names include:
       
   664 	 *
       
   665 	 *  - `taxonomy_labels_category`
       
   666 	 *  - `taxonomy_labels_post_tag`
   621 	 *
   667 	 *
   622 	 * @since 4.4.0
   668 	 * @since 4.4.0
   623 	 *
   669 	 *
   624 	 * @see get_taxonomy_labels() for the full list of taxonomy labels.
   670 	 * @see get_taxonomy_labels() for the full list of taxonomy labels.
   625 	 *
   671 	 *
   722 //
   768 //
   723 
   769 
   724 /**
   770 /**
   725  * Retrieve object_ids of valid taxonomy and term.
   771  * Retrieve object_ids of valid taxonomy and term.
   726  *
   772  *
   727  * The strings of $taxonomies must exist before this function will continue. On
   773  * The strings of $taxonomies must exist before this function will continue.
   728  * failure of finding a valid taxonomy, it will return an WP_Error class, kind
   774  * On failure of finding a valid taxonomy, it will return a WP_Error class,
   729  * of like Exceptions in PHP 5, except you can't catch them. Even so, you can
   775  * kind of like Exceptions in PHP 5, except you can't catch them. Even so,
   730  * still test for the WP_Error class and get the error message.
   776  * you can still test for the WP_Error class and get the error message.
   731  *
   777  *
   732  * The $terms aren't checked the same as $taxonomies, but still need to exist
   778  * The $terms aren't checked the same as $taxonomies, but still need to exist
   733  * for $object_ids to be returned.
   779  * for $object_ids to be returned.
   734  *
   780  *
   735  * It is possible to change the order that object_ids is returned by either
   781  * It is possible to change the order that object_ids is returned by either
   741  * @global wpdb $wpdb WordPress database abstraction object.
   787  * @global wpdb $wpdb WordPress database abstraction object.
   742  *
   788  *
   743  * @param int|array    $term_ids   Term ID or array of term IDs of terms that will be used.
   789  * @param int|array    $term_ids   Term ID or array of term IDs of terms that will be used.
   744  * @param string|array $taxonomies String of taxonomy name or Array of string values of taxonomy names.
   790  * @param string|array $taxonomies String of taxonomy name or Array of string values of taxonomy names.
   745  * @param array|string $args       Change the order of the object_ids, either ASC or DESC.
   791  * @param array|string $args       Change the order of the object_ids, either ASC or DESC.
   746  * @return WP_Error|array If the taxonomy does not exist, then WP_Error will be returned. On success.
   792  * @return array|WP_Error An array of $object_ids on success, WP_Error if the taxonomy does not exist.
   747  *  the array can be empty meaning that there are no $object_ids found or it will return the $object_ids found.
       
   748  */
   793  */
   749 function get_objects_in_term( $term_ids, $taxonomies, $args = array() ) {
   794 function get_objects_in_term( $term_ids, $taxonomies, $args = array() ) {
   750 	global $wpdb;
   795 	global $wpdb;
   751 
   796 
   752 	if ( ! is_array( $term_ids ) ) {
   797 	if ( ! is_array( $term_ids ) ) {
   883 	// Ensure for filters that this is not empty.
   928 	// Ensure for filters that this is not empty.
   884 	$taxonomy = $_term->taxonomy;
   929 	$taxonomy = $_term->taxonomy;
   885 
   930 
   886 	/**
   931 	/**
   887 	 * Filters a taxonomy term object.
   932 	 * Filters a taxonomy term object.
       
   933 	 *
       
   934 	 * The {@see 'get_$taxonomy'} hook is also available for targeting a specific
       
   935 	 * taxonomy.
   888 	 *
   936 	 *
   889 	 * @since 2.3.0
   937 	 * @since 2.3.0
   890 	 * @since 4.4.0 `$_term` is now a `WP_Term` object.
   938 	 * @since 4.4.0 `$_term` is now a `WP_Term` object.
   891 	 *
   939 	 *
   892 	 * @param WP_Term $_term    Term object.
   940 	 * @param WP_Term $_term    Term object.
  1043 function get_term_children( $term_id, $taxonomy ) {
  1091 function get_term_children( $term_id, $taxonomy ) {
  1044 	if ( ! taxonomy_exists( $taxonomy ) ) {
  1092 	if ( ! taxonomy_exists( $taxonomy ) ) {
  1045 		return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) );
  1093 		return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) );
  1046 	}
  1094 	}
  1047 
  1095 
  1048 	$term_id = intval( $term_id );
  1096 	$term_id = (int) $term_id;
  1049 
  1097 
  1050 	$terms = _get_term_hierarchy( $taxonomy );
  1098 	$terms = _get_term_hierarchy( $taxonomy );
  1051 
  1099 
  1052 	if ( ! isset( $terms[ $term_id ] ) ) {
  1100 	if ( ! isset( $terms[ $term_id ] ) ) {
  1053 		return array();
  1101 		return array();
  1127 
  1175 
  1128 	return sanitize_term( $term, $taxonomy, 'edit' );
  1176 	return sanitize_term( $term, $taxonomy, 'edit' );
  1129 }
  1177 }
  1130 
  1178 
  1131 /**
  1179 /**
  1132  * Retrieve the terms in a given taxonomy or list of taxonomies.
  1180  * Retrieves the terms in a given taxonomy or list of taxonomies.
  1133  *
  1181  *
  1134  * You can fully inject any customizations to the query before it is sent, as
  1182  * You can fully inject any customizations to the query before it is sent, as
  1135  * well as control the output with a filter.
  1183  * well as control the output with a filter.
       
  1184  *
       
  1185  * The return type varies depending on the value passed to `$args['fields']`. See
       
  1186  * WP_Term_Query::get_terms() for details. In all cases, a `WP_Error` object will
       
  1187  * be returned if an invalid taxonomy is requested.
  1136  *
  1188  *
  1137  * The {@see 'get_terms'} filter will be called when the cache has the term and will
  1189  * The {@see 'get_terms'} filter will be called when the cache has the term and will
  1138  * pass the found term along with the array of $taxonomies and array of $args.
  1190  * pass the found term along with the array of $taxonomies and array of $args.
  1139  * This filter is also called before the array of terms is passed and will pass
  1191  * This filter is also called before the array of terms is passed and will pass
  1140  * the array of terms, along with the $taxonomies and $args.
  1192  * the array of terms, along with the $taxonomies and $args.
  1168  * @since 4.8.0 Introduced 'suppress_filter' parameter.
  1220  * @since 4.8.0 Introduced 'suppress_filter' parameter.
  1169  *
  1221  *
  1170  * @internal The `$deprecated` parameter is parsed for backward compatibility only.
  1222  * @internal The `$deprecated` parameter is parsed for backward compatibility only.
  1171  *
  1223  *
  1172  * @param array|string $args       Optional. Array or string of arguments. See WP_Term_Query::__construct()
  1224  * @param array|string $args       Optional. Array or string of arguments. See WP_Term_Query::__construct()
  1173  *                                 for information on accepted arguments. Default empty.
  1225  *                                 for information on accepted arguments. Default empty array.
  1174  * @param array|string $deprecated Argument array, when using the legacy function parameter format. If present,
  1226  * @param array|string $deprecated Optional. Argument array, when using the legacy function parameter format.
  1175  *                                 this parameter will be interpreted as `$args`, and the first function parameter
  1227  *                                 If present, this parameter will be interpreted as `$args`, and the first
  1176  *                                 will be parsed as a taxonomy or array of taxonomies.
  1228  *                                 function parameter will be parsed as a taxonomy or array of taxonomies.
  1177  * @return WP_Term[]|int|WP_Error Array of WP_Term instances, a count thereof,
  1229  *                                 Default empty.
  1178  *                                or WP_Error if any of the taxonomies do not exist.
  1230  * @return WP_Term[]|int[]|string[]|string|WP_Error Array of terms, a count thereof as a numeric string,
       
  1231  *                                                  or WP_Error if any of the taxonomies do not exist.
       
  1232  *                                                  See the function description for more information.
  1179  */
  1233  */
  1180 function get_terms( $args = array(), $deprecated = '' ) {
  1234 function get_terms( $args = array(), $deprecated = '' ) {
  1181 	$term_query = new WP_Term_Query();
  1235 	$term_query = new WP_Term_Query();
  1182 
  1236 
  1183 	$defaults = array(
  1237 	$defaults = array(
  1287  *
  1341  *
  1288  * @param int    $term_id Term ID.
  1342  * @param int    $term_id Term ID.
  1289  * @param string $key     Optional. The meta key to retrieve. By default,
  1343  * @param string $key     Optional. The meta key to retrieve. By default,
  1290  *                        returns data for all keys. Default empty.
  1344  *                        returns data for all keys. Default empty.
  1291  * @param bool   $single  Optional. Whether to return a single value.
  1345  * @param bool   $single  Optional. Whether to return a single value.
  1292  *                        This parameter has no effect if $key is not specified.
  1346  *                        This parameter has no effect if `$key` is not specified.
  1293  *                        Default false.
  1347  *                        Default false.
  1294  * @return mixed An array if $single is false. The value of the meta field
  1348  * @return mixed An array of values if `$single` is false.
  1295  *               if $single is true. False for an invalid $term_id.
  1349  *               The value of the meta field if `$single` is true.
       
  1350  *               False for an invalid `$term_id` (non-numeric, zero, or negative value).
       
  1351  *               An empty string if a valid but non-existing term ID is passed.
  1296  */
  1352  */
  1297 function get_term_meta( $term_id, $key = '', $single = false ) {
  1353 function get_term_meta( $term_id, $key = '', $single = false ) {
  1298 	return get_metadata( 'term', $term_id, $key, $single );
  1354 	return get_metadata( 'term', $term_id, $key, $single );
  1299 }
  1355 }
  1300 
  1356 
  1503 
  1559 
  1504 	return term_is_ancestor_of( $term1, get_term( $term2->parent, $taxonomy ), $taxonomy );
  1560 	return term_is_ancestor_of( $term1, get_term( $term2->parent, $taxonomy ), $taxonomy );
  1505 }
  1561 }
  1506 
  1562 
  1507 /**
  1563 /**
  1508  * Sanitize Term all fields.
  1564  * Sanitize all term fields.
  1509  *
  1565  *
  1510  * Relies on sanitize_term_field() to sanitize the term. The difference is that
  1566  * Relies on sanitize_term_field() to sanitize the term. The difference is that
  1511  * this function will sanitize <strong>all</strong> fields. The context is based
  1567  * this function will sanitize **all** fields. The context is based
  1512  * on sanitize_term_field().
  1568  * on sanitize_term_field().
  1513  *
  1569  *
  1514  * The $term is expected to be either an array or an object.
  1570  * The `$term` is expected to be either an array or an object.
  1515  *
  1571  *
  1516  * @since 2.3.0
  1572  * @since 2.3.0
  1517  *
  1573  *
  1518  * @param array|object $term     The term to check.
  1574  * @param array|object $term     The term to check.
  1519  * @param string       $taxonomy The taxonomy name to use.
  1575  * @param string       $taxonomy The taxonomy name to use.
  1520  * @param string       $context  Optional. Context in which to sanitize the term. Accepts 'edit', 'db',
  1576  * @param string       $context  Optional. Context in which to sanitize the term.
  1521  *                               'display', 'attribute', or 'js'. Default 'display'.
  1577  *                               Accepts 'raw', 'edit', 'db', 'display', 'rss',
       
  1578  *                               'attribute', or 'js'. Default 'display'.
  1522  * @return array|object Term with all fields sanitized.
  1579  * @return array|object Term with all fields sanitized.
  1523  */
  1580  */
  1524 function sanitize_term( $term, $taxonomy, $context = 'display' ) {
  1581 function sanitize_term( $term, $taxonomy, $context = 'display' ) {
  1525 	$fields = array( 'term_id', 'name', 'description', 'slug', 'count', 'parent', 'term_group', 'term_taxonomy_id', 'object_id' );
  1582 	$fields = array( 'term_id', 'name', 'description', 'slug', 'count', 'parent', 'term_group', 'term_taxonomy_id', 'object_id' );
  1526 
  1583 
  1566  *
  1623  *
  1567  * @param string $field    Term field to sanitize.
  1624  * @param string $field    Term field to sanitize.
  1568  * @param string $value    Search for this term value.
  1625  * @param string $value    Search for this term value.
  1569  * @param int    $term_id  Term ID.
  1626  * @param int    $term_id  Term ID.
  1570  * @param string $taxonomy Taxonomy Name.
  1627  * @param string $taxonomy Taxonomy Name.
  1571  * @param string $context  Context in which to sanitize the term field. Accepts 'edit', 'db', 'display',
  1628  * @param string $context  Context in which to sanitize the term field.
  1572  *                         'attribute', or 'js'.
  1629  *                         Accepts 'raw', 'edit', 'db', 'display', 'rss',
       
  1630  *                         'attribute', or 'js'. Default 'display'.
  1573  * @return mixed Sanitized field.
  1631  * @return mixed Sanitized field.
  1574  */
  1632  */
  1575 function sanitize_term_field( $field, $value, $term_id, $taxonomy, $context ) {
  1633 function sanitize_term_field( $field, $value, $term_id, $taxonomy, $context ) {
  1576 	$int_fields = array( 'parent', 'term_id', 'count', 'term_group', 'term_taxonomy_id', 'object_id' );
  1634 	$int_fields = array( 'parent', 'term_id', 'count', 'term_group', 'term_taxonomy_id', 'object_id' );
  1577 	if ( in_array( $field, $int_fields, true ) ) {
  1635 	if ( in_array( $field, $int_fields, true ) ) {
  1719 	if ( 'attribute' === $context ) {
  1777 	if ( 'attribute' === $context ) {
  1720 		$value = esc_attr( $value );
  1778 		$value = esc_attr( $value );
  1721 	} elseif ( 'js' === $context ) {
  1779 	} elseif ( 'js' === $context ) {
  1722 		$value = esc_js( $value );
  1780 		$value = esc_js( $value );
  1723 	}
  1781 	}
       
  1782 
       
  1783 	// Restore the type for integer fields after esc_attr().
       
  1784 	if ( in_array( $field, $int_fields, true ) ) {
       
  1785 		$value = (int) $value;
       
  1786 	}
       
  1787 
  1724 	return $value;
  1788 	return $value;
  1725 }
  1789 }
  1726 
  1790 
  1727 /**
  1791 /**
  1728  * Count how many terms are in Taxonomy.
  1792  * Count how many terms are in Taxonomy.
  1729  *
  1793  *
  1730  * Default $args is 'hide_empty' which can be 'hide_empty=true' or array('hide_empty' => true).
  1794  * Default $args is 'hide_empty' which can be 'hide_empty=true' or array('hide_empty' => true).
  1731  *
  1795  *
  1732  * @since 2.3.0
  1796  * @since 2.3.0
  1733  *
  1797  * @since 5.6.0 Changed the function signature so that the `$args` array can be provided as the first parameter.
  1734  * @param string       $taxonomy Taxonomy name.
  1798  *
  1735  * @param array|string $args     Optional. Array of arguments that get passed to get_terms().
  1799  * @internal The `$deprecated` parameter is parsed for backward compatibility only.
  1736  *                               Default empty array.
  1800  *
  1737  * @return array|int|WP_Error Number of terms in that taxonomy or WP_Error if the taxonomy does not exist.
  1801  * @param array|string $args       Optional. Array of arguments that get passed to get_terms().
  1738  */
  1802  *                                 Default empty array.
  1739 function wp_count_terms( $taxonomy, $args = array() ) {
  1803  * @param array|string $deprecated Optional. Argument array, when using the legacy function parameter format.
  1740 	$defaults = array(
  1804  *                                 If present, this parameter will be interpreted as `$args`, and the first
  1741 		'taxonomy'   => $taxonomy,
  1805  *                                 function parameter will be parsed as a taxonomy or array of taxonomies.
  1742 		'hide_empty' => false,
  1806  *                                 Default empty.
  1743 	);
  1807  * @return string|WP_Error Numeric string containing the number of terms in that
  1744 	$args     = wp_parse_args( $args, $defaults );
  1808  *                         taxonomy or WP_Error if the taxonomy does not exist.
       
  1809  */
       
  1810 function wp_count_terms( $args = array(), $deprecated = '' ) {
       
  1811 	$use_legacy_args = false;
       
  1812 
       
  1813 	// Check whether function is used with legacy signature: `$taxonomy` and `$args`.
       
  1814 	if ( $args
       
  1815 		&& ( is_string( $args ) && taxonomy_exists( $args )
       
  1816 			|| is_array( $args ) && wp_is_numeric_array( $args ) )
       
  1817 	) {
       
  1818 		$use_legacy_args = true;
       
  1819 	}
       
  1820 
       
  1821 	$defaults = array( 'hide_empty' => false );
       
  1822 
       
  1823 	if ( $use_legacy_args ) {
       
  1824 		$defaults['taxonomy'] = $args;
       
  1825 		$args                 = $deprecated;
       
  1826 	}
       
  1827 
       
  1828 	$args = wp_parse_args( $args, $defaults );
  1745 
  1829 
  1746 	// Backward compatibility.
  1830 	// Backward compatibility.
  1747 	if ( isset( $args['ignore_empty'] ) ) {
  1831 	if ( isset( $args['ignore_empty'] ) ) {
  1748 		$args['hide_empty'] = $args['ignore_empty'];
  1832 		$args['hide_empty'] = $args['ignore_empty'];
  1749 		unset( $args['ignore_empty'] );
  1833 		unset( $args['ignore_empty'] );
  1903 	$deleted_term = get_term( $term, $taxonomy );
  1987 	$deleted_term = get_term( $term, $taxonomy );
  1904 
  1988 
  1905 	$object_ids = (array) $wpdb->get_col( $wpdb->prepare( "SELECT object_id FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $tt_id ) );
  1989 	$object_ids = (array) $wpdb->get_col( $wpdb->prepare( "SELECT object_id FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d", $tt_id ) );
  1906 
  1990 
  1907 	foreach ( $object_ids as $object_id ) {
  1991 	foreach ( $object_ids as $object_id ) {
       
  1992 		if ( ! isset( $default ) ) {
       
  1993 			wp_remove_object_terms( $object_id, $term, $taxonomy );
       
  1994 			continue;
       
  1995 		}
       
  1996 
  1908 		$terms = wp_get_object_terms(
  1997 		$terms = wp_get_object_terms(
  1909 			$object_id,
  1998 			$object_id,
  1910 			$taxonomy,
  1999 			$taxonomy,
  1911 			array(
  2000 			array(
  1912 				'fields'  => 'ids',
  2001 				'fields'  => 'ids',
  1913 				'orderby' => 'none',
  2002 				'orderby' => 'none',
  1914 			)
  2003 			)
  1915 		);
  2004 		);
       
  2005 
  1916 		if ( 1 === count( $terms ) && isset( $default ) ) {
  2006 		if ( 1 === count( $terms ) && isset( $default ) ) {
  1917 			$terms = array( $default );
  2007 			$terms = array( $default );
  1918 		} else {
  2008 		} else {
  1919 			$terms = array_diff( $terms, array( $term ) );
  2009 			$terms = array_diff( $terms, array( $term ) );
  1920 			if ( isset( $default ) && isset( $force_default ) && $force_default ) {
  2010 			if ( isset( $default ) && isset( $force_default ) && $force_default ) {
  1921 				$terms = array_merge( $terms, array( $default ) );
  2011 				$terms = array_merge( $terms, array( $default ) );
  1922 			}
  2012 			}
  1923 		}
  2013 		}
       
  2014 
  1924 		$terms = array_map( 'intval', $terms );
  2015 		$terms = array_map( 'intval', $terms );
  1925 		wp_set_object_terms( $object_id, $terms, $taxonomy );
  2016 		wp_set_object_terms( $object_id, $terms, $taxonomy );
  1926 	}
  2017 	}
  1927 
  2018 
  1928 	// Clean the relationship caches for all object types using this term.
  2019 	// Clean the relationship caches for all object types using this term.
  1964 	clean_term_cache( $term, $taxonomy );
  2055 	clean_term_cache( $term, $taxonomy );
  1965 
  2056 
  1966 	/**
  2057 	/**
  1967 	 * Fires after a term is deleted from the database and the cache is cleaned.
  2058 	 * Fires after a term is deleted from the database and the cache is cleaned.
  1968 	 *
  2059 	 *
       
  2060 	 * The {@see 'delete_$taxonomy'} hook is also available for targeting a specific
       
  2061 	 * taxonomy.
       
  2062 	 *
  1969 	 * @since 2.5.0
  2063 	 * @since 2.5.0
  1970 	 * @since 4.5.0 Introduced the `$object_ids` argument.
  2064 	 * @since 4.5.0 Introduced the `$object_ids` argument.
  1971 	 *
  2065 	 *
  1972 	 * @param int     $term         Term ID.
  2066 	 * @param int     $term         Term ID.
  1973 	 * @param int     $tt_id        Term taxonomy ID.
  2067 	 * @param int     $tt_id        Term taxonomy ID.
  1974 	 * @param string  $taxonomy     Taxonomy slug.
  2068 	 * @param string  $taxonomy     Taxonomy slug.
  1975 	 * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
  2069 	 * @param WP_Term $deleted_term Copy of the already-deleted term.
  1976 	 *                              by the parent function. WP_Error otherwise.
       
  1977 	 * @param array   $object_ids   List of term object IDs.
  2070 	 * @param array   $object_ids   List of term object IDs.
  1978 	 */
  2071 	 */
  1979 	do_action( 'delete_term', $term, $tt_id, $taxonomy, $deleted_term, $object_ids );
  2072 	do_action( 'delete_term', $term, $tt_id, $taxonomy, $deleted_term, $object_ids );
  1980 
  2073 
  1981 	/**
  2074 	/**
  1982 	 * Fires after a term in a specific taxonomy is deleted.
  2075 	 * Fires after a term in a specific taxonomy is deleted.
  1983 	 *
  2076 	 *
  1984 	 * The dynamic portion of the hook name, `$taxonomy`, refers to the specific
  2077 	 * The dynamic portion of the hook name, `$taxonomy`, refers to the specific
  1985 	 * taxonomy the term belonged to.
  2078 	 * taxonomy the term belonged to.
  1986 	 *
  2079 	 *
       
  2080 	 * Possible hook names include:
       
  2081 	 *
       
  2082 	 *  - `delete_category`
       
  2083 	 *  - `delete_post_tag`
       
  2084 	 *
  1987 	 * @since 2.3.0
  2085 	 * @since 2.3.0
  1988 	 * @since 4.5.0 Introduced the `$object_ids` argument.
  2086 	 * @since 4.5.0 Introduced the `$object_ids` argument.
  1989 	 *
  2087 	 *
  1990 	 * @param int     $term         Term ID.
  2088 	 * @param int     $term         Term ID.
  1991 	 * @param int     $tt_id        Term taxonomy ID.
  2089 	 * @param int     $tt_id        Term taxonomy ID.
  1992 	 * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
  2090 	 * @param WP_Term $deleted_term Copy of the already-deleted term.
  1993 	 *                              by the parent function. WP_Error otherwise.
       
  1994 	 * @param array   $object_ids   List of term object IDs.
  2091 	 * @param array   $object_ids   List of term object IDs.
  1995 	 */
  2092 	 */
  1996 	do_action( "delete_{$taxonomy}", $term, $tt_id, $deleted_term, $object_ids );
  2093 	do_action( "delete_{$taxonomy}", $term, $tt_id, $deleted_term, $object_ids );
  1997 
  2094 
  1998 	return true;
  2095 	return true;
  2022  * @since 4.7.0 Refactored to use WP_Term_Query, and to support any WP_Term_Query arguments.
  2119  * @since 4.7.0 Refactored to use WP_Term_Query, and to support any WP_Term_Query arguments.
  2023  *
  2120  *
  2024  * @param int|int[]       $object_ids The ID(s) of the object(s) to retrieve.
  2121  * @param int|int[]       $object_ids The ID(s) of the object(s) to retrieve.
  2025  * @param string|string[] $taxonomies The taxonomy names to retrieve terms from.
  2122  * @param string|string[] $taxonomies The taxonomy names to retrieve terms from.
  2026  * @param array|string    $args       See WP_Term_Query::__construct() for supported arguments.
  2123  * @param array|string    $args       See WP_Term_Query::__construct() for supported arguments.
  2027  * @return array|WP_Error The requested term data or empty array if no terms found.
  2124  * @return WP_Term[]|WP_Error Array of terms or empty array if no terms found.
  2028  *                        WP_Error if any of the taxonomies don't exist.
  2125  *                            WP_Error if any of the taxonomies don't exist.
  2029  */
  2126  */
  2030 function wp_get_object_terms( $object_ids, $taxonomies, $args = array() ) {
  2127 function wp_get_object_terms( $object_ids, $taxonomies, $args = array() ) {
  2031 	if ( empty( $object_ids ) || empty( $taxonomies ) ) {
  2128 	if ( empty( $object_ids ) || empty( $taxonomies ) ) {
  2032 		return array();
  2129 		return array();
  2033 	}
  2130 	}
  2048 	$object_ids = array_map( 'intval', $object_ids );
  2145 	$object_ids = array_map( 'intval', $object_ids );
  2049 
  2146 
  2050 	$args = wp_parse_args( $args );
  2147 	$args = wp_parse_args( $args );
  2051 
  2148 
  2052 	/**
  2149 	/**
  2053 	 * Filter arguments for retrieving object terms.
  2150 	 * Filters arguments for retrieving object terms.
  2054 	 *
  2151 	 *
  2055 	 * @since 4.9.0
  2152 	 * @since 4.9.0
  2056 	 *
  2153 	 *
  2057 	 * @param array    $args       An array of arguments for retrieving terms for the given object(s).
  2154 	 * @param array    $args       An array of arguments for retrieving terms for the given object(s).
  2058 	 *                             See {@see wp_get_object_terms()} for details.
  2155 	 *                             See {@see wp_get_object_terms()} for details.
  2099 	/**
  2196 	/**
  2100 	 * Filters the terms for a given object or objects.
  2197 	 * Filters the terms for a given object or objects.
  2101 	 *
  2198 	 *
  2102 	 * @since 4.2.0
  2199 	 * @since 4.2.0
  2103 	 *
  2200 	 *
  2104 	 * @param array    $terms      Array of terms for the given object or objects.
  2201 	 * @param WP_Term[] $terms      Array of terms for the given object or objects.
  2105 	 * @param int[]    $object_ids Array of object IDs for which terms were retrieved.
  2202 	 * @param int[]     $object_ids Array of object IDs for which terms were retrieved.
  2106 	 * @param string[] $taxonomies Array of taxonomy names from which terms were retrieved.
  2203 	 * @param string[]  $taxonomies Array of taxonomy names from which terms were retrieved.
  2107 	 * @param array    $args       Array of arguments for retrieving terms for the given
  2204 	 * @param array     $args       Array of arguments for retrieving terms for the given
  2108 	 *                             object(s). See wp_get_object_terms() for details.
  2205 	 *                              object(s). See wp_get_object_terms() for details.
  2109 	 */
  2206 	 */
  2110 	$terms = apply_filters( 'get_object_terms', $terms, $object_ids, $taxonomies, $args );
  2207 	$terms = apply_filters( 'get_object_terms', $terms, $object_ids, $taxonomies, $args );
  2111 
  2208 
  2112 	$object_ids = implode( ',', $object_ids );
  2209 	$object_ids = implode( ',', $object_ids );
  2113 	$taxonomies = "'" . implode( "', '", array_map( 'esc_sql', $taxonomies ) ) . "'";
  2210 	$taxonomies = "'" . implode( "', '", array_map( 'esc_sql', $taxonomies ) ) . "'";
  2118 	 * The `$taxonomies` parameter passed to this filter is formatted as a SQL fragment. The
  2215 	 * The `$taxonomies` parameter passed to this filter is formatted as a SQL fragment. The
  2119 	 * {@see 'get_object_terms'} filter is recommended as an alternative.
  2216 	 * {@see 'get_object_terms'} filter is recommended as an alternative.
  2120 	 *
  2217 	 *
  2121 	 * @since 2.8.0
  2218 	 * @since 2.8.0
  2122 	 *
  2219 	 *
  2123 	 * @param array    $terms      Array of terms for the given object or objects.
  2220 	 * @param WP_Term[] $terms      Array of terms for the given object or objects.
  2124 	 * @param int[]    $object_ids Array of object IDs for which terms were retrieved.
  2221 	 * @param string    $object_ids Comma separated list of object IDs for which terms were retrieved.
  2125 	 * @param string[] $taxonomies Array of taxonomy names from which terms were retrieved.
  2222 	 * @param string    $taxonomies SQL fragment of taxonomy names from which terms were retrieved.
  2126 	 * @param array    $args       Array of arguments for retrieving terms for the given
  2223 	 * @param array     $args       Array of arguments for retrieving terms for the given
  2127 	 *                             object(s). See wp_get_object_terms() for details.
  2224 	 *                              object(s). See wp_get_object_terms() for details.
  2128 	 */
  2225 	 */
  2129 	return apply_filters( 'wp_get_object_terms', $terms, $object_ids, $taxonomies, $args );
  2226 	return apply_filters( 'wp_get_object_terms', $terms, $object_ids, $taxonomies, $args );
  2130 }
  2227 }
  2131 
  2228 
  2132 /**
  2229 /**
  2159  * @since 2.3.0
  2256  * @since 2.3.0
  2160  *
  2257  *
  2161  * @param string       $term     The term name to add.
  2258  * @param string       $term     The term name to add.
  2162  * @param string       $taxonomy The taxonomy to which to add the term.
  2259  * @param string       $taxonomy The taxonomy to which to add the term.
  2163  * @param array|string $args {
  2260  * @param array|string $args {
  2164  *     Optional. Array or string of arguments for inserting a term.
  2261  *     Optional. Array or query string of arguments for inserting a term.
  2165  *
  2262  *
  2166  *     @type string $alias_of    Slug of the term to make this term an alias of.
  2263  *     @type string $alias_of    Slug of the term to make this term an alias of.
  2167  *                               Default empty string. Accepts a term slug.
  2264  *                               Default empty string. Accepts a term slug.
  2168  *     @type string $description The term description. Default empty string.
  2265  *     @type string $description The term description. Default empty string.
  2169  *     @type int    $parent      The id of the parent term. Default 0.
  2266  *     @type int    $parent      The id of the parent term. Default 0.
  2170  *     @type string $slug        The term slug to use. Default empty string.
  2267  *     @type string $slug        The term slug to use. Default empty string.
  2171  * }
  2268  * }
  2172  * @return array|WP_Error An array containing the `term_id` and `term_taxonomy_id`,
  2269  * @return array|WP_Error {
  2173  *                        WP_Error otherwise.
  2270  *     An array of the new term data, WP_Error otherwise.
       
  2271  *
       
  2272  *     @type int        $term_id          The new term ID.
       
  2273  *     @type int|string $term_taxonomy_id The new term taxonomy ID. Can be a numeric string.
       
  2274  * }
  2174  */
  2275  */
  2175 function wp_insert_term( $term, $taxonomy, $args = array() ) {
  2276 function wp_insert_term( $term, $taxonomy, $args = array() ) {
  2176 	global $wpdb;
  2277 	global $wpdb;
  2177 
  2278 
  2178 	if ( ! taxonomy_exists( $taxonomy ) ) {
  2279 	if ( ! taxonomy_exists( $taxonomy ) ) {
  2207 		'parent'      => 0,
  2308 		'parent'      => 0,
  2208 		'slug'        => '',
  2309 		'slug'        => '',
  2209 	);
  2310 	);
  2210 	$args     = wp_parse_args( $args, $defaults );
  2311 	$args     = wp_parse_args( $args, $defaults );
  2211 
  2312 
  2212 	if ( $args['parent'] > 0 && ! term_exists( (int) $args['parent'] ) ) {
  2313 	if ( (int) $args['parent'] > 0 && ! term_exists( (int) $args['parent'] ) ) {
  2213 		return new WP_Error( 'missing_parent', __( 'Parent term does not exist.' ) );
  2314 		return new WP_Error( 'missing_parent', __( 'Parent term does not exist.' ) );
  2214 	}
  2315 	}
  2215 
  2316 
  2216 	$args['name']     = $term;
  2317 	$args['name']     = $term;
  2217 	$args['taxonomy'] = $taxonomy;
  2318 	$args['taxonomy'] = $taxonomy;
  2405 	}
  2506 	}
  2406 
  2507 
  2407 	/**
  2508 	/**
  2408 	 * Fires immediately after a new term is created, before the term cache is cleaned.
  2509 	 * Fires immediately after a new term is created, before the term cache is cleaned.
  2409 	 *
  2510 	 *
       
  2511 	 * The {@see 'create_$taxonomy'} hook is also available for targeting a specific
       
  2512 	 * taxonomy.
       
  2513 	 *
  2410 	 * @since 2.3.0
  2514 	 * @since 2.3.0
  2411 	 *
  2515 	 *
  2412 	 * @param int    $term_id  Term ID.
  2516 	 * @param int    $term_id  Term ID.
  2413 	 * @param int    $tt_id    Term taxonomy ID.
  2517 	 * @param int    $tt_id    Term taxonomy ID.
  2414 	 * @param string $taxonomy Taxonomy slug.
  2518 	 * @param string $taxonomy Taxonomy slug.
  2419 	 * Fires after a new term is created for a specific taxonomy.
  2523 	 * Fires after a new term is created for a specific taxonomy.
  2420 	 *
  2524 	 *
  2421 	 * The dynamic portion of the hook name, `$taxonomy`, refers
  2525 	 * The dynamic portion of the hook name, `$taxonomy`, refers
  2422 	 * to the slug of the taxonomy the term was created for.
  2526 	 * to the slug of the taxonomy the term was created for.
  2423 	 *
  2527 	 *
       
  2528 	 * Possible hook names include:
       
  2529 	 *
       
  2530 	 *  - `create_category`
       
  2531 	 *  - `create_post_tag`
       
  2532 	 *
  2424 	 * @since 2.3.0
  2533 	 * @since 2.3.0
  2425 	 *
  2534 	 *
  2426 	 * @param int $term_id Term ID.
  2535 	 * @param int $term_id Term ID.
  2427 	 * @param int $tt_id   Term taxonomy ID.
  2536 	 * @param int $tt_id   Term taxonomy ID.
  2428 	 */
  2537 	 */
  2440 
  2549 
  2441 	clean_term_cache( $term_id, $taxonomy );
  2550 	clean_term_cache( $term_id, $taxonomy );
  2442 
  2551 
  2443 	/**
  2552 	/**
  2444 	 * Fires after a new term is created, and after the term cache has been cleaned.
  2553 	 * Fires after a new term is created, and after the term cache has been cleaned.
       
  2554 	 *
       
  2555 	 * The {@see 'created_$taxonomy'} hook is also available for targeting a specific
       
  2556 	 * taxonomy.
  2445 	 *
  2557 	 *
  2446 	 * @since 2.3.0
  2558 	 * @since 2.3.0
  2447 	 *
  2559 	 *
  2448 	 * @param int    $term_id  Term ID.
  2560 	 * @param int    $term_id  Term ID.
  2449 	 * @param int    $tt_id    Term taxonomy ID.
  2561 	 * @param int    $tt_id    Term taxonomy ID.
  2455 	 * Fires after a new term in a specific taxonomy is created, and after the term
  2567 	 * Fires after a new term in a specific taxonomy is created, and after the term
  2456 	 * cache has been cleaned.
  2568 	 * cache has been cleaned.
  2457 	 *
  2569 	 *
  2458 	 * The dynamic portion of the hook name, `$taxonomy`, refers to the taxonomy slug.
  2570 	 * The dynamic portion of the hook name, `$taxonomy`, refers to the taxonomy slug.
  2459 	 *
  2571 	 *
       
  2572 	 * Possible hook names include:
       
  2573 	 *
       
  2574 	 *  - `created_category`
       
  2575 	 *  - `created_post_tag`
       
  2576 	 *
  2460 	 * @since 2.3.0
  2577 	 * @since 2.3.0
  2461 	 *
  2578 	 *
  2462 	 * @param int $term_id Term ID.
  2579 	 * @param int $term_id Term ID.
  2463 	 * @param int $tt_id   Term taxonomy ID.
  2580 	 * @param int $tt_id   Term taxonomy ID.
  2464 	 */
  2581 	 */
  2465 	do_action( "created_{$taxonomy}", $term_id, $tt_id );
  2582 	do_action( "created_{$taxonomy}", $term_id, $tt_id );
  2466 
  2583 
  2467 	/**
  2584 	/**
  2468 	 * Fires after a term has been saved, and the term cache has been cleared.
  2585 	 * Fires after a term has been saved, and the term cache has been cleared.
       
  2586 	 *
       
  2587 	 * The {@see 'saved_$taxonomy'} hook is also available for targeting a specific
       
  2588 	 * taxonomy.
  2469 	 *
  2589 	 *
  2470 	 * @since 5.5.0
  2590 	 * @since 5.5.0
  2471 	 *
  2591 	 *
  2472 	 * @param int    $term_id  Term ID.
  2592 	 * @param int    $term_id  Term ID.
  2473 	 * @param int    $tt_id    Term taxonomy ID.
  2593 	 * @param int    $tt_id    Term taxonomy ID.
  2479 	/**
  2599 	/**
  2480 	 * Fires after a term in a specific taxonomy has been saved, and the term
  2600 	 * Fires after a term in a specific taxonomy has been saved, and the term
  2481 	 * cache has been cleared.
  2601 	 * cache has been cleared.
  2482 	 *
  2602 	 *
  2483 	 * The dynamic portion of the hook name, `$taxonomy`, refers to the taxonomy slug.
  2603 	 * The dynamic portion of the hook name, `$taxonomy`, refers to the taxonomy slug.
       
  2604 	 *
       
  2605 	 * Possible hook names include:
       
  2606 	 *
       
  2607 	 *  - `saved_category`
       
  2608 	 *  - `saved_post_tag`
  2484 	 *
  2609 	 *
  2485 	 * @since 5.5.0
  2610 	 * @since 5.5.0
  2486 	 *
  2611 	 *
  2487 	 * @param int  $term_id Term ID.
  2612 	 * @param int  $term_id Term ID.
  2488 	 * @param int  $tt_id   Term taxonomy ID.
  2613 	 * @param int  $tt_id   Term taxonomy ID.
  2652 				$values[] = $wpdb->prepare( '(%d, %d, %d)', $object_id, $tt_id, ++$term_order );
  2777 				$values[] = $wpdb->prepare( '(%d, %d, %d)', $object_id, $tt_id, ++$term_order );
  2653 			}
  2778 			}
  2654 		}
  2779 		}
  2655 
  2780 
  2656 		if ( $values ) {
  2781 		if ( $values ) {
  2657 			if ( false === $wpdb->query( "INSERT INTO $wpdb->term_relationships (object_id, term_taxonomy_id, term_order) VALUES " . join( ',', $values ) . ' ON DUPLICATE KEY UPDATE term_order = VALUES(term_order)' ) ) {
  2782 			if ( false === $wpdb->query( "INSERT INTO $wpdb->term_relationships (object_id, term_taxonomy_id, term_order) VALUES " . implode( ',', $values ) . ' ON DUPLICATE KEY UPDATE term_order = VALUES(term_order)' ) ) {
  2658 				return new WP_Error( 'db_insert_error', __( 'Could not insert term relationship into the database.' ), $wpdb->last_error );
  2783 				return new WP_Error( 'db_insert_error', __( 'Could not insert term relationship into the database.' ), $wpdb->last_error );
  2659 			}
  2784 			}
  2660 		}
  2785 		}
  2661 	}
  2786 	}
  2662 
  2787 
  2667 	 * Fires after an object's terms have been set.
  2792 	 * Fires after an object's terms have been set.
  2668 	 *
  2793 	 *
  2669 	 * @since 2.8.0
  2794 	 * @since 2.8.0
  2670 	 *
  2795 	 *
  2671 	 * @param int    $object_id  Object ID.
  2796 	 * @param int    $object_id  Object ID.
  2672 	 * @param array  $terms      An array of object terms.
  2797 	 * @param array  $terms      An array of object term IDs or slugs.
  2673 	 * @param array  $tt_ids     An array of term taxonomy IDs.
  2798 	 * @param array  $tt_ids     An array of term taxonomy IDs.
  2674 	 * @param string $taxonomy   Taxonomy slug.
  2799 	 * @param string $taxonomy   Taxonomy slug.
  2675 	 * @param bool   $append     Whether to append new terms to the old terms.
  2800 	 * @param bool   $append     Whether to append new terms to the old terms.
  2676 	 * @param array  $old_tt_ids Old array of term taxonomy IDs.
  2801 	 * @param array  $old_tt_ids Old array of term taxonomy IDs.
  2677 	 */
  2802 	 */
  2966 
  3091 
  2967 	if ( '' === trim( $name ) ) {
  3092 	if ( '' === trim( $name ) ) {
  2968 		return new WP_Error( 'empty_term_name', __( 'A name is required for this term.' ) );
  3093 		return new WP_Error( 'empty_term_name', __( 'A name is required for this term.' ) );
  2969 	}
  3094 	}
  2970 
  3095 
  2971 	if ( $parsed_args['parent'] > 0 && ! term_exists( (int) $parsed_args['parent'] ) ) {
  3096 	if ( (int) $parsed_args['parent'] > 0 && ! term_exists( (int) $parsed_args['parent'] ) ) {
  2972 		return new WP_Error( 'missing_parent', __( 'Parent term does not exist.' ) );
  3097 		return new WP_Error( 'missing_parent', __( 'Parent term does not exist.' ) );
  2973 	}
  3098 	}
  2974 
  3099 
  2975 	$empty_slug = false;
  3100 	$empty_slug = false;
  2976 	if ( empty( $args['slug'] ) ) {
  3101 	if ( empty( $args['slug'] ) ) {
  3073 		$slug = sanitize_title( $name, $term_id );
  3198 		$slug = sanitize_title( $name, $term_id );
  3074 		$wpdb->update( $wpdb->terms, compact( 'slug' ), compact( 'term_id' ) );
  3199 		$wpdb->update( $wpdb->terms, compact( 'slug' ), compact( 'term_id' ) );
  3075 	}
  3200 	}
  3076 
  3201 
  3077 	/**
  3202 	/**
  3078 	 * Fires immediately after the given terms are edited.
  3203 	 * Fires immediately after a term is updated in the database, but before its
       
  3204 	 * term-taxonomy relationship is updated.
  3079 	 *
  3205 	 *
  3080 	 * @since 2.9.0
  3206 	 * @since 2.9.0
  3081 	 *
  3207 	 *
  3082 	 * @param int    $term_id  Term ID
  3208 	 * @param int    $term_id  Term ID
  3083 	 * @param string $taxonomy Taxonomy slug.
  3209 	 * @param string $taxonomy Taxonomy slug.
  3106 	 */
  3232 	 */
  3107 	do_action( 'edited_term_taxonomy', $tt_id, $taxonomy );
  3233 	do_action( 'edited_term_taxonomy', $tt_id, $taxonomy );
  3108 
  3234 
  3109 	/**
  3235 	/**
  3110 	 * Fires after a term has been updated, but before the term cache has been cleaned.
  3236 	 * Fires after a term has been updated, but before the term cache has been cleaned.
       
  3237 	 *
       
  3238 	 * The {@see 'edit_$taxonomy'} hook is also available for targeting a specific
       
  3239 	 * taxonomy.
  3111 	 *
  3240 	 *
  3112 	 * @since 2.3.0
  3241 	 * @since 2.3.0
  3113 	 *
  3242 	 *
  3114 	 * @param int    $term_id  Term ID.
  3243 	 * @param int    $term_id  Term ID.
  3115 	 * @param int    $tt_id    Term taxonomy ID.
  3244 	 * @param int    $tt_id    Term taxonomy ID.
  3121 	 * Fires after a term in a specific taxonomy has been updated, but before the term
  3250 	 * Fires after a term in a specific taxonomy has been updated, but before the term
  3122 	 * cache has been cleaned.
  3251 	 * cache has been cleaned.
  3123 	 *
  3252 	 *
  3124 	 * The dynamic portion of the hook name, `$taxonomy`, refers to the taxonomy slug.
  3253 	 * The dynamic portion of the hook name, `$taxonomy`, refers to the taxonomy slug.
  3125 	 *
  3254 	 *
       
  3255 	 * Possible hook names include:
       
  3256 	 *
       
  3257 	 *  - `edit_category`
       
  3258 	 *  - `edit_post_tag`
       
  3259 	 *
  3126 	 * @since 2.3.0
  3260 	 * @since 2.3.0
  3127 	 *
  3261 	 *
  3128 	 * @param int $term_id Term ID.
  3262 	 * @param int $term_id Term ID.
  3129 	 * @param int $tt_id   Term taxonomy ID.
  3263 	 * @param int $tt_id   Term taxonomy ID.
  3130 	 */
  3264 	 */
  3135 
  3269 
  3136 	clean_term_cache( $term_id, $taxonomy );
  3270 	clean_term_cache( $term_id, $taxonomy );
  3137 
  3271 
  3138 	/**
  3272 	/**
  3139 	 * Fires after a term has been updated, and the term cache has been cleaned.
  3273 	 * Fires after a term has been updated, and the term cache has been cleaned.
       
  3274 	 *
       
  3275 	 * The {@see 'edited_$taxonomy'} hook is also available for targeting a specific
       
  3276 	 * taxonomy.
  3140 	 *
  3277 	 *
  3141 	 * @since 2.3.0
  3278 	 * @since 2.3.0
  3142 	 *
  3279 	 *
  3143 	 * @param int    $term_id  Term ID.
  3280 	 * @param int    $term_id  Term ID.
  3144 	 * @param int    $tt_id    Term taxonomy ID.
  3281 	 * @param int    $tt_id    Term taxonomy ID.
  3149 	/**
  3286 	/**
  3150 	 * Fires after a term for a specific taxonomy has been updated, and the term
  3287 	 * Fires after a term for a specific taxonomy has been updated, and the term
  3151 	 * cache has been cleaned.
  3288 	 * cache has been cleaned.
  3152 	 *
  3289 	 *
  3153 	 * The dynamic portion of the hook name, `$taxonomy`, refers to the taxonomy slug.
  3290 	 * The dynamic portion of the hook name, `$taxonomy`, refers to the taxonomy slug.
       
  3291 	 *
       
  3292 	 * Possible hook names include:
       
  3293 	 *
       
  3294 	 *  - `edited_category`
       
  3295 	 *  - `edited_post_tag`
  3154 	 *
  3296 	 *
  3155 	 * @since 2.3.0
  3297 	 * @since 2.3.0
  3156 	 *
  3298 	 *
  3157 	 * @param int $term_id Term ID.
  3299 	 * @param int $term_id Term ID.
  3158 	 * @param int $tt_id   Term taxonomy ID.
  3300 	 * @param int $tt_id   Term taxonomy ID.
  3448 
  3590 
  3449 	// Backward compatibility for if a plugin is putting objects into the cache, rather than IDs.
  3591 	// Backward compatibility for if a plugin is putting objects into the cache, rather than IDs.
  3450 	$term_ids = array();
  3592 	$term_ids = array();
  3451 	foreach ( $_term_ids as $term_id ) {
  3593 	foreach ( $_term_ids as $term_id ) {
  3452 		if ( is_numeric( $term_id ) ) {
  3594 		if ( is_numeric( $term_id ) ) {
  3453 			$term_ids[] = intval( $term_id );
  3595 			$term_ids[] = (int) $term_id;
  3454 		} elseif ( isset( $term_id->term_id ) ) {
  3596 		} elseif ( isset( $term_id->term_id ) ) {
  3455 			$term_ids[] = intval( $term_id->term_id );
  3597 			$term_ids[] = (int) $term_id->term_id;
  3456 		}
  3598 		}
  3457 	}
  3599 	}
  3458 
  3600 
  3459 	// Fill the term objects.
  3601 	// Fill the term objects.
  3460 	_prime_term_caches( $term_ids );
  3602 	_prime_term_caches( $term_ids );
  3484  *
  3626  *
  3485  * @since 2.3.0
  3627  * @since 2.3.0
  3486  *
  3628  *
  3487  * @param string|int[]    $object_ids  Comma-separated list or array of term object IDs.
  3629  * @param string|int[]    $object_ids  Comma-separated list or array of term object IDs.
  3488  * @param string|string[] $object_type The taxonomy object type or array of the same.
  3630  * @param string|string[] $object_type The taxonomy object type or array of the same.
  3489  * @return void|false False if all of the terms in `$object_ids` are already cached.
  3631  * @return void|false Void on success or if the `$object_ids` parameter is empty,
       
  3632  *                    false if all of the terms in `$object_ids` are already cached.
  3490  */
  3633  */
  3491 function update_object_term_cache( $object_ids, $object_type ) {
  3634 function update_object_term_cache( $object_ids, $object_type ) {
  3492 	if ( empty( $object_ids ) ) {
  3635 	if ( empty( $object_ids ) ) {
  3493 		return;
  3636 		return;
  3494 	}
  3637 	}
  3698  * @access private
  3841  * @access private
  3699  * @since 2.3.0
  3842  * @since 2.3.0
  3700  *
  3843  *
  3701  * @global wpdb $wpdb WordPress database abstraction object.
  3844  * @global wpdb $wpdb WordPress database abstraction object.
  3702  *
  3845  *
  3703  * @param array  $terms    List of term objects (passed by reference).
  3846  * @param object[]|WP_Term[] $terms    List of term objects (passed by reference).
  3704  * @param string $taxonomy Term context.
  3847  * @param string             $taxonomy Term context.
  3705  */
  3848  */
  3706 function _pad_term_counts( &$terms, $taxonomy ) {
  3849 function _pad_term_counts( &$terms, $taxonomy ) {
  3707 	global $wpdb;
  3850 	global $wpdb;
  3708 
  3851 
  3709 	// This function only works for hierarchical taxonomies like post categories.
  3852 	// This function only works for hierarchical taxonomies like post categories.
  3780 function _prime_term_caches( $term_ids, $update_meta_cache = true ) {
  3923 function _prime_term_caches( $term_ids, $update_meta_cache = true ) {
  3781 	global $wpdb;
  3924 	global $wpdb;
  3782 
  3925 
  3783 	$non_cached_ids = _get_non_cached_ids( $term_ids, 'terms' );
  3926 	$non_cached_ids = _get_non_cached_ids( $term_ids, 'terms' );
  3784 	if ( ! empty( $non_cached_ids ) ) {
  3927 	if ( ! empty( $non_cached_ids ) ) {
  3785 		$fresh_terms = $wpdb->get_results( sprintf( "SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE t.term_id IN (%s)", join( ',', array_map( 'intval', $non_cached_ids ) ) ) );
  3928 		$fresh_terms = $wpdb->get_results( sprintf( "SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE t.term_id IN (%s)", implode( ',', array_map( 'intval', $non_cached_ids ) ) ) );
  3786 
  3929 
  3787 		update_term_cache( $fresh_terms, $update_meta_cache );
  3930 		update_term_cache( $fresh_terms, $update_meta_cache );
  3788 
  3931 
  3789 		if ( $update_meta_cache ) {
  3932 		if ( $update_meta_cache ) {
  3790 			update_termmeta_cache( $non_cached_ids );
  3933 			update_termmeta_cache( $non_cached_ids );
  3829 
  3972 
  3830 	if ( $object_types ) {
  3973 	if ( $object_types ) {
  3831 		$object_types = esc_sql( array_filter( $object_types, 'post_type_exists' ) );
  3974 		$object_types = esc_sql( array_filter( $object_types, 'post_type_exists' ) );
  3832 	}
  3975 	}
  3833 
  3976 
       
  3977 	$post_statuses = array( 'publish' );
       
  3978 
       
  3979 	/**
       
  3980 	 * Filters the post statuses for updating the term count.
       
  3981 	 *
       
  3982 	 * @since 5.7.0
       
  3983 	 *
       
  3984 	 * @param string[]    $post_statuses List of post statuses to include in the count. Default is 'publish'.
       
  3985 	 * @param WP_Taxonomy $taxonomy      Current taxonomy object.
       
  3986 	 */
       
  3987 	$post_statuses = esc_sql( apply_filters( 'update_post_term_count_statuses', $post_statuses, $taxonomy ) );
       
  3988 
  3834 	foreach ( (array) $terms as $term ) {
  3989 	foreach ( (array) $terms as $term ) {
  3835 		$count = 0;
  3990 		$count = 0;
  3836 
  3991 
  3837 		// Attachments can be 'inherit' status, we need to base count off the parent's status if so.
  3992 		// Attachments can be 'inherit' status, we need to base count off the parent's status if so.
  3838 		if ( $check_attachments ) {
  3993 		if ( $check_attachments ) {
  3839 			$count += (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts p1 WHERE p1.ID = $wpdb->term_relationships.object_id AND ( post_status = 'publish' OR ( post_status = 'inherit' AND post_parent > 0 AND ( SELECT post_status FROM $wpdb->posts WHERE ID = p1.post_parent ) = 'publish' ) ) AND post_type = 'attachment' AND term_taxonomy_id = %d", $term ) );
  3994 			// phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.QuotedDynamicPlaceholderGeneration
       
  3995 			$count += (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts p1 WHERE p1.ID = $wpdb->term_relationships.object_id AND ( post_status IN ('" . implode( "', '", $post_statuses ) . "') OR ( post_status = 'inherit' AND post_parent > 0 AND ( SELECT post_status FROM $wpdb->posts WHERE ID = p1.post_parent ) IN ('" . implode( "', '", $post_statuses ) . "') ) ) AND post_type = 'attachment' AND term_taxonomy_id = %d", $term ) );
  3840 		}
  3996 		}
  3841 
  3997 
  3842 		if ( $object_types ) {
  3998 		if ( $object_types ) {
  3843 			// phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.QuotedDynamicPlaceholderGeneration
  3999 			// phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.QuotedDynamicPlaceholderGeneration
  3844 			$count += (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts WHERE $wpdb->posts.ID = $wpdb->term_relationships.object_id AND post_status = 'publish' AND post_type IN ('" . implode( "', '", $object_types ) . "') AND term_taxonomy_id = %d", $term ) );
  4000 			$count += (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts WHERE $wpdb->posts.ID = $wpdb->term_relationships.object_id AND post_status IN ('" . implode( "', '", $post_statuses ) . "') AND post_type IN ('" . implode( "', '", $object_types ) . "') AND term_taxonomy_id = %d", $term ) );
  3845 		}
  4001 		}
  3846 
  4002 
  3847 		/** This action is documented in wp-includes/taxonomy.php */
  4003 		/** This action is documented in wp-includes/taxonomy.php */
  3848 		do_action( 'edit_term_taxonomy', $term, $taxonomy->name );
  4004 		do_action( 'edit_term_taxonomy', $term, $taxonomy->name );
  3849 		$wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $term ) );
  4005 		$wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $term ) );
  3906 function _split_shared_term( $term_id, $term_taxonomy_id, $record = true ) {
  4062 function _split_shared_term( $term_id, $term_taxonomy_id, $record = true ) {
  3907 	global $wpdb;
  4063 	global $wpdb;
  3908 
  4064 
  3909 	if ( is_object( $term_id ) ) {
  4065 	if ( is_object( $term_id ) ) {
  3910 		$shared_term = $term_id;
  4066 		$shared_term = $term_id;
  3911 		$term_id     = intval( $shared_term->term_id );
  4067 		$term_id     = (int) $shared_term->term_id;
  3912 	}
  4068 	}
  3913 
  4069 
  3914 	if ( is_object( $term_taxonomy_id ) ) {
  4070 	if ( is_object( $term_taxonomy_id ) ) {
  3915 		$term_taxonomy    = $term_taxonomy_id;
  4071 		$term_taxonomy    = $term_taxonomy_id;
  3916 		$term_taxonomy_id = intval( $term_taxonomy->term_taxonomy_id );
  4072 		$term_taxonomy_id = (int) $term_taxonomy->term_taxonomy_id;
  3917 	}
  4073 	}
  3918 
  4074 
  3919 	// If there are no shared term_taxonomy rows, there's nothing to do here.
  4075 	// If there are no shared term_taxonomy rows, there's nothing to do here.
  3920 	$shared_tt_count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_taxonomy tt WHERE tt.term_id = %d AND tt.term_taxonomy_id != %d", $term_id, $term_taxonomy_id ) );
  4076 	$shared_tt_count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_taxonomy tt WHERE tt.term_id = %d AND tt.term_taxonomy_id != %d", $term_id, $term_taxonomy_id ) );
  3921 
  4077 
  4078 	wp_schedule_single_event( time() + ( 2 * MINUTE_IN_SECONDS ), 'wp_split_shared_term_batch' );
  4234 	wp_schedule_single_event( time() + ( 2 * MINUTE_IN_SECONDS ), 'wp_split_shared_term_batch' );
  4079 
  4235 
  4080 	// Rekey shared term array for faster lookups.
  4236 	// Rekey shared term array for faster lookups.
  4081 	$_shared_terms = array();
  4237 	$_shared_terms = array();
  4082 	foreach ( $shared_terms as $shared_term ) {
  4238 	foreach ( $shared_terms as $shared_term ) {
  4083 		$term_id                   = intval( $shared_term->term_id );
  4239 		$term_id                   = (int) $shared_term->term_id;
  4084 		$_shared_terms[ $term_id ] = $shared_term;
  4240 		$_shared_terms[ $term_id ] = $shared_term;
  4085 	}
  4241 	}
  4086 	$shared_terms = $_shared_terms;
  4242 	$shared_terms = $_shared_terms;
  4087 
  4243 
  4088 	// Get term taxonomy data for all shared terms.
  4244 	// Get term taxonomy data for all shared terms.
  4092 	// Split term data recording is slow, so we do it just once, outside the loop.
  4248 	// Split term data recording is slow, so we do it just once, outside the loop.
  4093 	$split_term_data    = get_option( '_split_terms', array() );
  4249 	$split_term_data    = get_option( '_split_terms', array() );
  4094 	$skipped_first_term = array();
  4250 	$skipped_first_term = array();
  4095 	$taxonomies         = array();
  4251 	$taxonomies         = array();
  4096 	foreach ( $shared_tts as $shared_tt ) {
  4252 	foreach ( $shared_tts as $shared_tt ) {
  4097 		$term_id = intval( $shared_tt->term_id );
  4253 		$term_id = (int) $shared_tt->term_id;
  4098 
  4254 
  4099 		// Don't split the first tt belonging to a given term_id.
  4255 		// Don't split the first tt belonging to a given term_id.
  4100 		if ( ! isset( $skipped_first_term[ $term_id ] ) ) {
  4256 		if ( ! isset( $skipped_first_term[ $term_id ] ) ) {
  4101 			$skipped_first_term[ $term_id ] = 1;
  4257 			$skipped_first_term[ $term_id ] = 1;
  4102 			continue;
  4258 			continue;
  4322 	$taxonomy = $term->taxonomy;
  4478 	$taxonomy = $term->taxonomy;
  4323 
  4479 
  4324 	$termlink = $wp_rewrite->get_extra_permastruct( $taxonomy );
  4480 	$termlink = $wp_rewrite->get_extra_permastruct( $taxonomy );
  4325 
  4481 
  4326 	/**
  4482 	/**
  4327 	 * Filters the permalink structure for a terms before token replacement occurs.
  4483 	 * Filters the permalink structure for a term before token replacement occurs.
  4328 	 *
  4484 	 *
  4329 	 * @since 4.9.0
  4485 	 * @since 4.9.0
  4330 	 *
  4486 	 *
  4331 	 * @param string  $termlink The permalink structure for the term's taxonomy.
  4487 	 * @param string  $termlink The permalink structure for the term's taxonomy.
  4332 	 * @param WP_Term $term     The term object.
  4488 	 * @param WP_Term $term     The term object.
  4344 		} else {
  4500 		} else {
  4345 			$termlink = "?taxonomy=$taxonomy&term=$slug";
  4501 			$termlink = "?taxonomy=$taxonomy&term=$slug";
  4346 		}
  4502 		}
  4347 		$termlink = home_url( $termlink );
  4503 		$termlink = home_url( $termlink );
  4348 	} else {
  4504 	} else {
  4349 		if ( $t->rewrite['hierarchical'] ) {
  4505 		if ( ! empty( $t->rewrite['hierarchical'] ) ) {
  4350 			$hierarchical_slugs = array();
  4506 			$hierarchical_slugs = array();
  4351 			$ancestors          = get_ancestors( $term->term_id, $taxonomy, 'taxonomy' );
  4507 			$ancestors          = get_ancestors( $term->term_id, $taxonomy, 'taxonomy' );
  4352 			foreach ( (array) $ancestors as $ancestor ) {
  4508 			foreach ( (array) $ancestors as $ancestor ) {
  4353 				$ancestor_term        = get_term( $ancestor, $taxonomy );
  4509 				$ancestor_term        = get_term( $ancestor, $taxonomy );
  4354 				$hierarchical_slugs[] = $ancestor_term->slug;
  4510 				$hierarchical_slugs[] = $ancestor_term->slug;
  4430 		'after'  => '',
  4586 		'after'  => '',
  4431 	);
  4587 	);
  4432 
  4588 
  4433 	$parsed_args = wp_parse_args( $args, $defaults );
  4589 	$parsed_args = wp_parse_args( $args, $defaults );
  4434 
  4590 
  4435 	echo $parsed_args['before'] . join( $parsed_args['sep'], get_the_taxonomies( $parsed_args['post'], $parsed_args ) ) . $parsed_args['after'];
  4591 	echo $parsed_args['before'] . implode( $parsed_args['sep'], get_the_taxonomies( $parsed_args['post'], $parsed_args ) ) . $parsed_args['after'];
  4436 }
  4592 }
  4437 
  4593 
  4438 /**
  4594 /**
  4439  * Retrieve all taxonomies associated with a post.
  4595  * Retrieve all taxonomies associated with a post.
  4440  *
  4596  *
  4524  * Terms given as integers will only be checked against the object's terms' term_ids.
  4680  * Terms given as integers will only be checked against the object's terms' term_ids.
  4525  * If no terms are given, determines if object is associated with any terms in the given taxonomy.
  4681  * If no terms are given, determines if object is associated with any terms in the given taxonomy.
  4526  *
  4682  *
  4527  * @since 2.7.0
  4683  * @since 2.7.0
  4528  *
  4684  *
  4529  * @param int              $object_id ID of the object (post ID, link ID, ...).
  4685  * @param int                       $object_id ID of the object (post ID, link ID, ...).
  4530  * @param string           $taxonomy  Single taxonomy name.
  4686  * @param string                    $taxonomy  Single taxonomy name.
  4531  * @param int|string|array $terms     Optional. Term term_id, name, slug or array of said. Default null.
  4687  * @param int|string|int[]|string[] $terms     Optional. Term ID, name, slug, or array of such
       
  4688  *                                             to check against. Default null.
  4532  * @return bool|WP_Error WP_Error on input error.
  4689  * @return bool|WP_Error WP_Error on input error.
  4533  */
  4690  */
  4534 function is_object_in_term( $object_id, $taxonomy, $terms = null ) {
  4691 function is_object_in_term( $object_id, $taxonomy, $terms = null ) {
  4535 	$object_id = (int) $object_id;
  4692 	$object_id = (int) $object_id;
  4536 	if ( ! $object_id ) {
  4693 	if ( ! $object_id ) {
  4669  *
  4826  *
  4670  * @since 3.1.0
  4827  * @since 3.1.0
  4671  *
  4828  *
  4672  * @param int    $term_id  Term ID.
  4829  * @param int    $term_id  Term ID.
  4673  * @param string $taxonomy Taxonomy name.
  4830  * @param string $taxonomy Taxonomy name.
  4674  * @return int|false False on error.
  4831  * @return int|false Parent term ID on success, false on failure.
  4675  */
  4832  */
  4676 function wp_get_term_taxonomy_parent_id( $term_id, $taxonomy ) {
  4833 function wp_get_term_taxonomy_parent_id( $term_id, $taxonomy ) {
  4677 	$term = get_term( $term_id, $taxonomy );
  4834 	$term = get_term( $term_id, $taxonomy );
  4678 	if ( ! $term || is_wp_error( $term ) ) {
  4835 	if ( ! $term || is_wp_error( $term ) ) {
  4679 		return false;
  4836 		return false;