: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* @global wpdb $wpdb WordPress database abstraction object.
* @param int $term_id Term ID.
* @return array|false Array with meta data, or false when the meta table is not installed.
function has_term_meta( $term_id ) {
$check = wp_check_term_meta_support_prefilter( null );
return $wpdb->get_results( $wpdb->prepare( "SELECT meta_key, meta_value, meta_id, term_id FROM $wpdb->termmeta WHERE term_id = %d ORDER BY meta_key,meta_id", $term_id ), ARRAY_A );
* Registers a meta key for terms.
* @param string $taxonomy Taxonomy to register a meta key for. Pass an empty string
* to register the meta key across all existing taxonomies.
* @param string $meta_key The meta key to register.
* @param array $args Data used to describe the meta key when registered. See
* {@see register_meta()} for a list of supported arguments.
* @return bool True if the meta key was successfully registered, false if not.
function register_term_meta( $taxonomy, $meta_key, array $args ) {
$args['object_subtype'] = $taxonomy;
return register_meta( 'term', $meta_key, $args );
* Unregisters a meta key for terms.
* @param string $taxonomy Taxonomy the meta key is currently registered for. Pass
* an empty string if the meta key is registered across all
* @param string $meta_key The meta key to unregister.
* @return bool True on success, false if the meta key was not previously registered.
function unregister_term_meta( $taxonomy, $meta_key ) {
return unregister_meta_key( 'term', $meta_key, $taxonomy );
* Determines whether a taxonomy term exists.
* Formerly is_term(), introduced in 2.3.0.
* For more information on this and similar theme functions, check out
* the {@link https://developer.wordpress.org/themes/basics/conditional-tags/
* Conditional Tags} article in the Theme Developer Handbook.
* @since 6.0.0 Converted to use `get_terms()`.
* @global bool $_wp_suspend_cache_invalidation
* @param int|string $term The term to check. Accepts term ID, slug, or name.
* @param string $taxonomy Optional. The taxonomy name to use.
* @param int $parent_term Optional. ID of parent term under which to confine the exists search.
* @return mixed Returns null if the term does not exist.
* Returns the term ID if no taxonomy is specified and the term ID exists.
* Returns an array of the term ID and the term taxonomy ID if the taxonomy is specified and the pairing exists.
* Returns 0 if term ID 0 is passed to the function.
function term_exists( $term, $taxonomy = '', $parent_term = null ) {
global $_wp_suspend_cache_invalidation;
'update_term_meta_cache' => false,
'suppress_filter' => true,
// Ensure that while importing, queries are not cached.
if ( ! empty( $_wp_suspend_cache_invalidation ) ) {
$defaults['cache_results'] = false;
if ( ! empty( $taxonomy ) ) {
$defaults['taxonomy'] = $taxonomy;
$defaults['fields'] = 'all';
* Filters default query arguments for checking if a term exists.
* @param array $defaults An array of arguments passed to get_terms().
* @param int|string $term The term to check. Accepts term ID, slug, or name.
* @param string $taxonomy The taxonomy name to use. An empty string indicates
* the search is against all taxonomies.
* @param int|null $parent_term ID of parent term under which to confine the exists search.
* Null indicates the search is unconfined.
$defaults = apply_filters( 'term_exists_default_query_args', $defaults, $term, $taxonomy, $parent_term );
$args = wp_parse_args( array( 'include' => array( $term ) ), $defaults );
$terms = get_terms( $args );
$term = trim( wp_unslash( $term ) );
if ( ! empty( $taxonomy ) && is_numeric( $parent_term ) ) {
$defaults['parent'] = (int) $parent_term;
$args = wp_parse_args( array( 'slug' => sanitize_title( $term ) ), $defaults );
$terms = get_terms( $args );
if ( empty( $terms ) || is_wp_error( $terms ) ) {
$args = wp_parse_args( array( 'name' => $term ), $defaults );
$terms = get_terms( $args );
if ( empty( $terms ) || is_wp_error( $terms ) ) {
$_term = array_shift( $terms );
if ( ! empty( $taxonomy ) ) {
'term_id' => (string) $_term->term_id,
'term_taxonomy_id' => (string) $_term->term_taxonomy_id,
* Checks if a term is an ancestor of another term.
* You can use either an ID or the term object for both parameters.
* @param int|object $term1 ID or object to check if this is the parent term.
* @param int|object $term2 The child term.
* @param string $taxonomy Taxonomy name that $term1 and `$term2` belong to.
* @return bool Whether `$term2` is a child of `$term1`.
function term_is_ancestor_of( $term1, $term2, $taxonomy ) {
if ( ! isset( $term1->term_id ) ) {
$term1 = get_term( $term1, $taxonomy );
if ( ! isset( $term2->parent ) ) {
$term2 = get_term( $term2, $taxonomy );
if ( empty( $term1->term_id ) || empty( $term2->parent ) ) {
if ( $term2->parent === $term1->term_id ) {
return term_is_ancestor_of( $term1, get_term( $term2->parent, $taxonomy ), $taxonomy );
* Sanitizes all term fields.
* Relies on sanitize_term_field() to sanitize the term. The difference is that
* this function will sanitize **all** fields. The context is based
* on sanitize_term_field().
* The `$term` is expected to be either an array or an object.
* @param array|object $term The term to check.
* @param string $taxonomy The taxonomy name to use.
* @param string $context Optional. Context in which to sanitize the term.
* Accepts 'raw', 'edit', 'db', 'display', 'rss',
* 'attribute', or 'js'. Default 'display'.
* @return array|object Term with all fields sanitized.
function sanitize_term( $term, $taxonomy, $context = 'display' ) {
$fields = array( 'term_id', 'name', 'description', 'slug', 'count', 'parent', 'term_group', 'term_taxonomy_id', 'object_id' );
$do_object = is_object( $term );
$term_id = $do_object ? $term->term_id : ( isset( $term['term_id'] ) ? $term['term_id'] : 0 );
foreach ( (array) $fields as $field ) {
if ( isset( $term->$field ) ) {
$term->$field = sanitize_term_field( $field, $term->$field, $term_id, $taxonomy, $context );
if ( isset( $term[ $field ] ) ) {
$term[ $field ] = sanitize_term_field( $field, $term[ $field ], $term_id, $taxonomy, $context );
$term->filter = $context;
$term['filter'] = $context;
* Sanitizes the field value in the term based on the context.
* Passing a term field value through the function should be assumed to have
* cleansed the value for whatever context the term field is going to be used.
* If no context or an unsupported context is given, then default filters will
* There are enough filters for each context to support a custom filtering
* without creating your own filter function. Simply create a function that
* hooks into the filter you need.
* @param string $field Term field to sanitize.
* @param string $value Search for this term value.
* @param int $term_id Term ID.
* @param string $taxonomy Taxonomy name.
* @param string $context Context in which to sanitize the term field.
* Accepts 'raw', 'edit', 'db', 'display', 'rss',
* 'attribute', or 'js'. Default 'display'.
* @return mixed Sanitized field.
function sanitize_term_field( $field, $value, $term_id, $taxonomy, $context ) {
$int_fields = array( 'parent', 'term_id', 'count', 'term_group', 'term_taxonomy_id', 'object_id' );
if ( in_array( $field, $int_fields, true ) ) {
$context = strtolower( $context );
if ( 'raw' === $context ) {
if ( 'edit' === $context ) {
* Filters a term field to edit before it is sanitized.
* The dynamic portion of the hook name, `$field`, refers to the term field.
* @param mixed $value Value of the term field.
* @param int $term_id Term ID.
* @param string $taxonomy Taxonomy slug.
$value = apply_filters( "edit_term_{$field}", $value, $term_id, $taxonomy );
* Filters the taxonomy field to edit before it is sanitized.
* The dynamic portions of the filter name, `$taxonomy` and `$field`, refer
* to the taxonomy slug and taxonomy field, respectively.
* @param mixed $value Value of the taxonomy field to edit.
* @param int $term_id Term ID.
$value = apply_filters( "edit_{$taxonomy}_{$field}", $value, $term_id );
if ( 'description' === $field ) {
$value = esc_html( $value ); // textarea_escaped
$value = esc_attr( $value );
} elseif ( 'db' === $context ) {
* Filters a term field value before it is sanitized.
* The dynamic portion of the hook name, `$field`, refers to the term field.
* @param mixed $value Value of the term field.
* @param string $taxonomy Taxonomy slug.
$value = apply_filters( "pre_term_{$field}", $value, $taxonomy );
* Filters a taxonomy field before it is sanitized.
* The dynamic portions of the filter name, `$taxonomy` and `$field`, refer
* to the taxonomy slug and field name, respectively.
* @param mixed $value Value of the taxonomy field.
$value = apply_filters( "pre_{$taxonomy}_{$field}", $value );
if ( 'slug' === $field ) {
* Filters the category nicename before it is sanitized.
* Use the {@see 'pre_$taxonomy_$field'} hook instead.
* @param string $value The category nicename.
$value = apply_filters( 'pre_category_nicename', $value );
} elseif ( 'rss' === $context ) {
* Filters the term field for use in RSS.
* The dynamic portion of the hook name, `$field`, refers to the term field.
* @param mixed $value Value of the term field.
* @param string $taxonomy Taxonomy slug.
$value = apply_filters( "term_{$field}_rss", $value, $taxonomy );
* Filters the taxonomy field for use in RSS.
* The dynamic portions of the hook name, `$taxonomy`, and `$field`, refer
* to the taxonomy slug and field name, respectively.
* @param mixed $value Value of the taxonomy field.
$value = apply_filters( "{$taxonomy}_{$field}_rss", $value );
// Use display filters by default.
* Filters the term field sanitized for display.
* The dynamic portion of the hook name, `$field`, refers to the term field name.
* @param mixed $value Value of the term field.
* @param int $term_id Term ID.
* @param string $taxonomy Taxonomy slug.
* @param string $context Context to retrieve the term field value.
$value = apply_filters( "term_{$field}", $value, $term_id, $taxonomy, $context );
* Filters the taxonomy field sanitized for display.
* The dynamic portions of the filter name, `$taxonomy`, and `$field`, refer
* to the taxonomy slug and taxonomy field, respectively.
* @param mixed $value Value of the taxonomy field.
* @param int $term_id Term ID.
* @param string $context Context to retrieve the taxonomy field value.
$value = apply_filters( "{$taxonomy}_{$field}", $value, $term_id, $context );
if ( 'attribute' === $context ) {
$value = esc_attr( $value );
} elseif ( 'js' === $context ) {
$value = esc_js( $value );
// Restore the type for integer fields after esc_attr().
if ( in_array( $field, $int_fields, true ) ) {
* Counts how many terms are in taxonomy.
* Default $args is 'hide_empty' which can be 'hide_empty=true' or array('hide_empty' => true).
* @since 5.6.0 Changed the function signature so that the `$args` array can be provided as the first parameter.
* @internal The `$deprecated` parameter is parsed for backward compatibility only.
* @param array|string $args Optional. Array or string of arguments. See WP_Term_Query::__construct()
* for information on accepted arguments. Default empty array.
* @param array|string $deprecated Optional. Argument array, when using the legacy function parameter format.
* If present, this parameter will be interpreted as `$args`, and the first
* function parameter will be parsed as a taxonomy or array of taxonomies.
* @return string|WP_Error Numeric string containing the number of terms in that
* taxonomy or WP_Error if the taxonomy does not exist.
function wp_count_terms( $args = array(), $deprecated = '' ) {
$use_legacy_args = false;
// Check whether function is used with legacy signature: `$taxonomy` and `$args`.
&& ( is_string( $args ) && taxonomy_exists( $args )
|| is_array( $args ) && wp_is_numeric_array( $args ) )
$defaults = array( 'hide_empty' => false );
if ( $use_legacy_args ) {
$defaults['taxonomy'] = $args;
$args = wp_parse_args( $args, $defaults );
// Backward compatibility.
if ( isset( $args['ignore_empty'] ) ) {
$args['hide_empty'] = $args['ignore_empty'];
unset( $args['ignore_empty'] );
$args['fields'] = 'count';
return get_terms( $args );
* Unlinks the object from the taxonomy or taxonomies.
* Will remove all relationships between the object and any terms in
* a particular taxonomy or taxonomies. Does not remove the term or
* @param int $object_id The term object ID that refers to the term.
* @param string|array $taxonomies List of taxonomy names or single taxonomy name.
function wp_delete_object_term_relationships( $object_id, $taxonomies ) {
$object_id = (int) $object_id;
if ( ! is_array( $taxonomies ) ) {
$taxonomies = array( $taxonomies );
foreach ( (array) $taxonomies as $taxonomy ) {
$term_ids = wp_get_object_terms( $object_id, $taxonomy, array( 'fields' => 'ids' ) );
$term_ids = array_map( 'intval', $term_ids );
wp_remove_object_terms( $object_id, $term_ids, $taxonomy );
* Removes a term from the database.
* If the term is a parent of other terms, then the children will be updated to
* Metadata associated with the term will be deleted.
* @global wpdb $wpdb WordPress database abstraction object.