diff -r 7b1b88e27a20 -r 48c4eec2b7e6 wp/wp-includes/taxonomy.php --- a/wp/wp-includes/taxonomy.php Thu Sep 29 08:06:27 2022 +0200 +++ b/wp/wp-includes/taxonomy.php Fri Sep 05 18:40:08 2025 +0200 @@ -222,6 +222,45 @@ 'show_in_rest' => false, ) ); + + register_taxonomy( + 'wp_pattern_category', + array( 'wp_block' ), + array( + 'public' => false, + 'publicly_queryable' => false, + 'hierarchical' => false, + 'labels' => array( + 'name' => _x( 'Pattern Categories', 'taxonomy general name' ), + 'singular_name' => _x( 'Pattern Category', 'taxonomy singular name' ), + 'add_new_item' => __( 'Add New Category' ), + 'add_or_remove_items' => __( 'Add or remove pattern categories' ), + 'back_to_items' => __( '← Go to Pattern Categories' ), + 'choose_from_most_used' => __( 'Choose from the most used pattern categories' ), + 'edit_item' => __( 'Edit Pattern Category' ), + 'item_link' => __( 'Pattern Category Link' ), + 'item_link_description' => __( 'A link to a pattern category.' ), + 'items_list' => __( 'Pattern Categories list' ), + 'items_list_navigation' => __( 'Pattern Categories list navigation' ), + 'new_item_name' => __( 'New Pattern Category Name' ), + 'no_terms' => __( 'No pattern categories' ), + 'not_found' => __( 'No pattern categories found.' ), + 'popular_items' => __( 'Popular Pattern Categories' ), + 'search_items' => __( 'Search Pattern Categories' ), + 'separate_items_with_commas' => __( 'Separate pattern categories with commas' ), + 'update_item' => __( 'Update Pattern Category' ), + 'view_item' => __( 'View Pattern Category' ), + ), + 'query_var' => false, + 'rewrite' => false, + 'show_ui' => true, + '_builtin' => true, + 'show_in_nav_menus' => false, + 'show_in_rest' => true, + 'show_admin_column' => true, + 'show_tagcloud' => false, + ) + ); } /** @@ -233,7 +272,7 @@ * * @param array $args Optional. An array of `key => value` arguments to match against the taxonomy objects. * Default empty array. - * @param string $output Optional. The type of output to return in the array. Accepts either taxonomy 'names' + * @param string $output Optional. The type of output to return in the array. Either 'names' * or 'objects'. Default 'names'. * @param string $operator Optional. The logical operation to perform. Accepts 'and' or 'or'. 'or' means only * one element from the array needs to match; 'and' means all elements must match. @@ -264,26 +303,26 @@ * * @global WP_Taxonomy[] $wp_taxonomies The registered taxonomies. * - * @param string|string[]|WP_Post $object Name of the type of taxonomy object, or an object (row from posts) - * @param string $output Optional. The type of output to return in the array. Accepts either - * 'names' or 'objects'. Default 'names'. + * @param string|string[]|WP_Post $object_type Name of the type of taxonomy object, or an object (row from posts). + * @param string $output Optional. The type of output to return in the array. Accepts either + * 'names' or 'objects'. Default 'names'. * @return string[]|WP_Taxonomy[] The names or objects of all taxonomies of `$object_type`. */ -function get_object_taxonomies( $object, $output = 'names' ) { +function get_object_taxonomies( $object_type, $output = 'names' ) { global $wp_taxonomies; - if ( is_object( $object ) ) { - if ( 'attachment' === $object->post_type ) { - return get_attachment_taxonomies( $object, $output ); + if ( is_object( $object_type ) ) { + if ( 'attachment' === $object_type->post_type ) { + return get_attachment_taxonomies( $object_type, $output ); } - $object = $object->post_type; - } - - $object = (array) $object; + $object_type = $object_type->post_type; + } + + $object_type = (array) $object_type; $taxonomies = array(); foreach ( (array) $wp_taxonomies as $tax_name => $tax_obj ) { - if ( array_intersect( $object, (array) $tax_obj->object_type ) ) { + if ( array_intersect( $object_type, (array) $tax_obj->object_type ) ) { if ( 'names' === $output ) { $taxonomies[] = $tax_name; } else { @@ -337,7 +376,7 @@ function taxonomy_exists( $taxonomy ) { global $wp_taxonomies; - return isset( $wp_taxonomies[ $taxonomy ] ); + return is_string( $taxonomy ) && isset( $wp_taxonomies[ $taxonomy ] ); } /** @@ -390,7 +429,8 @@ * * @global WP_Taxonomy[] $wp_taxonomies Registered taxonomies. * - * @param string $taxonomy Taxonomy key, must not exceed 32 characters. + * @param string $taxonomy Taxonomy key. Must not exceed 32 characters and may only contain + * lowercase alphanumeric characters, dashes, and underscores. See sanitize_key(). * @param array|string $object_type Object type or array of object types with which the taxonomy should be associated. * @param array|string $args { * Optional. Array or query string of arguments for registering a taxonomy. @@ -557,13 +597,14 @@ * * @since 4.5.0 * - * @global WP $wp Current WordPress environment instance. * @global WP_Taxonomy[] $wp_taxonomies List of taxonomies. * * @param string $taxonomy Taxonomy name. * @return true|WP_Error True on success, WP_Error on failure or if the taxonomy doesn't exist. */ function unregister_taxonomy( $taxonomy ) { + global $wp_taxonomies; + if ( ! taxonomy_exists( $taxonomy ) ) { return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) ); } @@ -575,16 +616,9 @@ return new WP_Error( 'invalid_taxonomy', __( 'Unregistering a built-in taxonomy is not allowed.' ) ); } - global $wp_taxonomies; - $taxonomy_object->remove_rewrite_rules(); $taxonomy_object->remove_hooks(); - // Remove custom taxonomy default term option. - if ( ! empty( $taxonomy_object->default_term ) ) { - delete_option( 'default_term_' . $taxonomy_object->name ); - } - // Remove the taxonomy. unset( $wp_taxonomies[ $taxonomy ] ); @@ -611,6 +645,7 @@ * @since 5.8.0 Added the `item_link` and `item_link_description` labels. * @since 5.9.0 Added the `name_field_description`, `slug_field_description`, * `parent_field_description`, and `desc_field_description` labels. + * @since 6.6.0 Added the `template_name` label. * * @param WP_Taxonomy $tax Taxonomy object. * @return object { @@ -645,6 +680,7 @@ * @type string $update_item Default 'Update Tag'/'Update Category'. * @type string $add_new_item Default 'Add New Tag'/'Add New Category'. * @type string $new_item_name Default 'New Tag Name'/'New Category Name'. + * @type string $template_name Default 'Tag Archives'/'Category Archives'. * @type string $separate_items_with_commas This label is only used for non-hierarchical taxonomies. Default * 'Separate tags with commas', used in the meta box. * @type string $add_or_remove_items This label is only used for non-hierarchical taxonomies. Default @@ -685,6 +721,11 @@ $labels = _get_custom_object_labels( $tax, $nohier_vs_hier_defaults ); + if ( ! isset( $tax->labels->template_name ) && isset( $labels->singular_name ) ) { + /* translators: %s: Taxonomy name. */ + $labels->template_name = sprintf( _x( '%s Archives', 'taxonomy template name' ), $labels->singular_name ); + } + $taxonomy = $tax->name; $default_labels = clone $labels; @@ -819,7 +860,11 @@ * * @param int|int[] $term_ids Term ID or array of term IDs of terms that will be used. * @param string|string[] $taxonomies String of taxonomy name or Array of string values of taxonomy names. - * @param array|string $args Change the order of the object IDs, either ASC or DESC. + * @param array|string $args { + * Change the order of the object IDs. + * + * @type string $order Order to retrieve terms. Accepts 'ASC' or 'DESC'. Default 'ASC'. + * } * @return string[]|WP_Error An array of object IDs as numeric strings on success, * WP_Error if the taxonomy does not exist. */ @@ -852,10 +897,10 @@ $last_changed = wp_cache_get_last_changed( 'terms' ); $cache_key = 'get_objects_in_term:' . md5( $sql ) . ":$last_changed"; - $cache = wp_cache_get( $cache_key, 'terms' ); + $cache = wp_cache_get( $cache_key, 'term-queries' ); if ( false === $cache ) { $object_ids = $wpdb->get_col( $sql ); - wp_cache_set( $cache_key, $object_ids, 'terms' ); + wp_cache_set( $cache_key, $object_ids, 'term-queries' ); } else { $object_ids = (array) $cache; } @@ -960,6 +1005,7 @@ // Ensure for filters that this is not empty. $taxonomy = $_term->taxonomy; + $old_term = $_term; /** * Filters a taxonomy term object. * @@ -999,7 +1045,9 @@ } // Sanitize term, according to the specified filter. - $_term->filter( $filter ); + if ( $_term !== $old_term || $_term->filter !== $filter ) { + $_term->filter( $filter ); + } if ( ARRAY_A === $output ) { return $_term->to_array(); @@ -1234,18 +1282,15 @@ * The {@see 'get_terms_orderby'} filter passes the `ORDER BY` clause for the query * along with the $args array. * - * Prior to 4.5.0, the first parameter of `get_terms()` was a taxonomy or list of taxonomies: - * - * $terms = get_terms( 'post_tag', array( + * Taxonomy or an array of taxonomies should be passed via the 'taxonomy' argument + * in the `$args` array: + * + * $terms = get_terms( array( + * 'taxonomy' => 'post_tag', * 'hide_empty' => false, * ) ); * - * Since 4.5.0, taxonomies should be passed via the 'taxonomy' argument in the `$args` array: - * - * $terms = get_terms( array( - * 'taxonomy' => 'post_tag', - * 'hide_empty' => false, - * ) ); + * Prior to 4.5.0, taxonomy was passed as the first parameter of `get_terms()`. * * @since 2.3.0 * @since 4.2.0 Introduced 'name' and 'childless' parameters. @@ -1434,6 +1479,22 @@ return update_meta_cache( 'term', $term_ids ); } + +/** + * Queue term meta for lazy-loading. + * + * @since 6.3.0 + * + * @param array $term_ids List of term IDs. + */ +function wp_lazyload_term_meta( array $term_ids ) { + if ( empty( $term_ids ) ) { + return; + } + $lazyloader = wp_metadata_lazyloader(); + $lazyloader->queue_objects( 'term', $term_ids ); +} + /** * Gets all meta data, including meta IDs, for the given term ID. * @@ -1502,15 +1563,15 @@ * * @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 Optional. ID of parent term under which to confine the exists search. + * @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 = null ) { +function term_exists( $term, $taxonomy = '', $parent_term = null ) { global $_wp_suspend_cache_invalidation; if ( null === $term ) { @@ -1529,8 +1590,7 @@ // Ensure that while importing, queries are not cached. if ( ! empty( $_wp_suspend_cache_invalidation ) ) { - // @todo Disable caching once #52710 is merged. - $defaults['cache_domain'] = microtime(); + $defaults['cache_results'] = false; } if ( ! empty( $taxonomy ) ) { @@ -1543,14 +1603,14 @@ * * @since 6.0.0 * - * @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 ID of parent term under which to confine the exists search. - * Null indicates the search is unconfined. + * @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 ); + $defaults = apply_filters( 'term_exists_default_query_args', $defaults, $term, $taxonomy, $parent_term ); if ( is_int( $term ) ) { if ( 0 === $term ) { @@ -1564,8 +1624,8 @@ return null; } - if ( ! empty( $taxonomy ) && is_numeric( $parent ) ) { - $defaults['parent'] = (int) $parent; + if ( ! empty( $taxonomy ) && is_numeric( $parent_term ) ) { + $defaults['parent'] = (int) $parent_term; } $args = wp_parse_args( array( 'slug' => sanitize_title( $term ) ), $defaults ); @@ -1860,8 +1920,8 @@ * * @internal The `$deprecated` parameter is parsed for backward compatibility only. * - * @param array|string $args Optional. Array of arguments that get passed to get_terms(). - * Default empty array. + * @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. @@ -2162,12 +2222,13 @@ * * @since 2.0.0 * - * @param int $cat_ID Category term ID. + * @param int $cat_id Category term ID. * @return bool|int|WP_Error Returns true if completes delete action; false if term doesn't exist; - * Zero on attempted deletion of default Category; WP_Error object is also a possibility. + * Zero on attempted deletion of default Category; WP_Error object is + * also a possibility. */ -function wp_delete_category( $cat_ID ) { - return wp_delete_term( $cat_ID, 'category' ); +function wp_delete_category( $cat_id ) { + return wp_delete_term( $cat_id, 'category' ); } /** @@ -2179,12 +2240,15 @@ * @since 4.4.0 Introduced `$meta_query` and `$update_term_meta_cache` arguments. When `$fields` is 'all' or * 'all_with_object_id', an array of `WP_Term` objects will be returned. * @since 4.7.0 Refactored to use WP_Term_Query, and to support any WP_Term_Query arguments. + * @since 6.3.0 Passing `update_term_meta_cache` argument value false by default resulting in get_terms() to not + * prime the term meta cache. * * @param int|int[] $object_ids The ID(s) of the object(s) to retrieve. * @param string|string[] $taxonomies The taxonomy names to retrieve terms from. * @param array|string $args See WP_Term_Query::__construct() for supported arguments. - * @return WP_Term[]|WP_Error Array of terms or empty array if no terms found. - * WP_Error if any of the taxonomies don't exist. + * @return WP_Term[]|int[]|string[]|string|WP_Error Array of terms, a count thereof as a numeric string, + * or WP_Error if any of the taxonomies do not exist. + * See WP_Term_Query::get_terms() for more information. */ function wp_get_object_terms( $object_ids, $taxonomies, $args = array() ) { if ( empty( $object_ids ) || empty( $taxonomies ) ) { @@ -2206,7 +2270,11 @@ } $object_ids = array_map( 'intval', $object_ids ); - $args = wp_parse_args( $args ); + $defaults = array( + 'update_term_meta_cache' => false, + ); + + $args = wp_parse_args( $args, $defaults ); /** * Filters arguments for retrieving object terms. @@ -2248,7 +2316,7 @@ $terms_from_remaining_taxonomies = get_terms( $args ); // Array keys should be preserved for values of $fields that use term_id for keys. - if ( ! empty( $args['fields'] ) && 0 === strpos( $args['fields'], 'id=>' ) ) { + if ( ! empty( $args['fields'] ) && str_starts_with( $args['fields'], 'id=>' ) ) { $terms = $terms + $terms_from_remaining_taxonomies; } else { $terms = array_merge( $terms, $terms_from_remaining_taxonomies ); @@ -2260,11 +2328,11 @@ * * @since 4.2.0 * - * @param WP_Term[] $terms Array of terms for the given object or objects. - * @param int[] $object_ids Array of object IDs for which terms were retrieved. - * @param string[] $taxonomies Array of taxonomy names from which terms were retrieved. - * @param array $args Array of arguments for retrieving terms for the given - * object(s). See wp_get_object_terms() for details. + * @param WP_Term[]|int[]|string[]|string $terms Array of terms or a count thereof as a numeric string. + * @param int[] $object_ids Array of object IDs for which terms were retrieved. + * @param string[] $taxonomies Array of taxonomy names from which terms were retrieved. + * @param array $args Array of arguments for retrieving terms for the given + * object(s). See wp_get_object_terms() for details. */ $terms = apply_filters( 'get_object_terms', $terms, $object_ids, $taxonomies, $args ); @@ -2279,11 +2347,11 @@ * * @since 2.8.0 * - * @param WP_Term[] $terms Array of terms for the given object or objects. - * @param string $object_ids Comma separated list of object IDs for which terms were retrieved. - * @param string $taxonomies SQL fragment of taxonomy names from which terms were retrieved. - * @param array $args Array of arguments for retrieving terms for the given - * object(s). See wp_get_object_terms() for details. + * @param WP_Term[]|int[]|string[]|string $terms Array of terms or a count thereof as a numeric string. + * @param string $object_ids Comma separated list of object IDs for which terms were retrieved. + * @param string $taxonomies SQL fragment of taxonomy names from which terms were retrieved. + * @param array $args Array of arguments for retrieving terms for the given + * object(s). See wp_get_object_terms() for details. */ return apply_filters( 'wp_get_object_terms', $terms, $object_ids, $taxonomies, $args ); } @@ -2346,11 +2414,13 @@ * Filters a term before it is sanitized and inserted into the database. * * @since 3.0.0 + * @since 6.1.0 The `$args` parameter was added. * * @param string|WP_Error $term The term name to add, or a WP_Error object if there's an error. * @param string $taxonomy Taxonomy slug. + * @param array|string $args Array or query string of arguments passed to wp_insert_term(). */ - $term = apply_filters( 'pre_insert_term', $term, $taxonomy ); + $term = apply_filters( 'pre_insert_term', $term, $taxonomy, $args ); if ( is_wp_error( $term ) ) { return $term; @@ -2389,6 +2459,11 @@ $description = wp_unslash( $args['description'] ); $parent = (int) $args['parent']; + // Sanitization could clean the name to an empty string that must be checked again. + if ( '' === $name ) { + return new WP_Error( 'invalid_term_name', __( 'Invalid term name.' ) ); + } + $slug_provided = ! empty( $args['slug'] ); if ( ! $slug_provided ) { $slug = sanitize_title( $name ); @@ -2528,7 +2603,7 @@ $tt_id = (int) $wpdb->insert_id; /* - * Sanity check: if we just created a term with the same parent + taxonomy + slug but a higher term_id than + * Confidence check: if we just created a term with the same parent + taxonomy + slug but a higher term_id than * an existing term, then we have unwittingly created a duplicate term. Delete the dupe, and use the term_id * and term_taxonomy_id of the older term instead. Then return out of the function so that the "create" hooks * are not fired. @@ -2548,7 +2623,7 @@ * @param object $duplicate_term Duplicate term row from terms table, if found. * @param string $term Term being inserted. * @param string $taxonomy Taxonomy name. - * @param array $args Term arguments passed to the function. + * @param array $args Arguments passed to wp_insert_term(). * @param int $tt_id term_taxonomy_id for the newly created term. */ $duplicate_term = apply_filters( 'wp_insert_term_duplicate_term_check', $duplicate_term, $term, $taxonomy, $args, $tt_id ); @@ -2574,12 +2649,14 @@ * taxonomy. * * @since 2.3.0 + * @since 6.1.0 The `$args` parameter was added. * * @param int $term_id Term ID. * @param int $tt_id Term taxonomy ID. * @param string $taxonomy Taxonomy slug. + * @param array $args Arguments passed to wp_insert_term(). */ - do_action( 'create_term', $term_id, $tt_id, $taxonomy ); + do_action( 'create_term', $term_id, $tt_id, $taxonomy, $args ); /** * Fires after a new term is created for a specific taxonomy. @@ -2593,21 +2670,25 @@ * - `create_post_tag` * * @since 2.3.0 + * @since 6.1.0 The `$args` parameter was added. * - * @param int $term_id Term ID. - * @param int $tt_id Term taxonomy ID. + * @param int $term_id Term ID. + * @param int $tt_id Term taxonomy ID. + * @param array $args Arguments passed to wp_insert_term(). */ - do_action( "create_{$taxonomy}", $term_id, $tt_id ); + do_action( "create_{$taxonomy}", $term_id, $tt_id, $args ); /** * Filters the term ID after a new term is created. * * @since 2.3.0 + * @since 6.1.0 The `$args` parameter was added. * - * @param int $term_id Term ID. - * @param int $tt_id Term taxonomy ID. + * @param int $term_id Term ID. + * @param int $tt_id Term taxonomy ID. + * @param array $args Arguments passed to wp_insert_term(). */ - $term_id = apply_filters( 'term_id_filter', $term_id, $tt_id ); + $term_id = apply_filters( 'term_id_filter', $term_id, $tt_id, $args ); clean_term_cache( $term_id, $taxonomy ); @@ -2618,12 +2699,14 @@ * taxonomy. * * @since 2.3.0 + * @since 6.1.0 The `$args` parameter was added. * * @param int $term_id Term ID. * @param int $tt_id Term taxonomy ID. * @param string $taxonomy Taxonomy slug. + * @param array $args Arguments passed to wp_insert_term(). */ - do_action( 'created_term', $term_id, $tt_id, $taxonomy ); + do_action( 'created_term', $term_id, $tt_id, $taxonomy, $args ); /** * Fires after a new term in a specific taxonomy is created, and after the term @@ -2637,11 +2720,13 @@ * - `created_post_tag` * * @since 2.3.0 + * @since 6.1.0 The `$args` parameter was added. * - * @param int $term_id Term ID. - * @param int $tt_id Term taxonomy ID. + * @param int $term_id Term ID. + * @param int $tt_id Term taxonomy ID. + * @param array $args Arguments passed to wp_insert_term(). */ - do_action( "created_{$taxonomy}", $term_id, $tt_id ); + do_action( "created_{$taxonomy}", $term_id, $tt_id, $args ); /** * Fires after a term has been saved, and the term cache has been cleared. @@ -2650,13 +2735,15 @@ * taxonomy. * * @since 5.5.0 + * @since 6.1.0 The `$args` parameter was added. * * @param int $term_id Term ID. * @param int $tt_id Term taxonomy ID. * @param string $taxonomy Taxonomy slug. * @param bool $update Whether this is an existing term being updated. + * @param array $args Arguments passed to wp_insert_term(). */ - do_action( 'saved_term', $term_id, $tt_id, $taxonomy, false ); + do_action( 'saved_term', $term_id, $tt_id, $taxonomy, false, $args ); /** * Fires after a term in a specific taxonomy has been saved, and the term @@ -2670,12 +2757,14 @@ * - `saved_post_tag` * * @since 5.5.0 + * @since 6.1.0 The `$args` parameter was added. * - * @param int $term_id Term ID. - * @param int $tt_id Term taxonomy ID. - * @param bool $update Whether this is an existing term being updated. + * @param int $term_id Term ID. + * @param int $tt_id Term taxonomy ID. + * @param bool $update Whether this is an existing term being updated. + * @param array $args Arguments passed to wp_insert_term(). */ - do_action( "saved_{$taxonomy}", $term_id, $tt_id, false ); + do_action( "saved_{$taxonomy}", $term_id, $tt_id, false, $args ); return array( 'term_id' => $term_id, @@ -2701,7 +2790,7 @@ * @param int $object_id The object to relate to. * @param string|int|array $terms A single term slug, single term ID, or array of either term slugs or IDs. * Will replace all existing related terms in this taxonomy. Passing an - * empty value will remove all related terms. + * empty array will remove all related terms. * @param string $taxonomy The context in which to relate the term to the object. * @param bool $append Optional. If false will delete difference of terms. Default false. * @return array|WP_Error Term taxonomy IDs of the affected terms or WP_Error on failure. @@ -2715,7 +2804,9 @@ return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) ); } - if ( ! is_array( $terms ) ) { + if ( empty( $terms ) ) { + $terms = array(); + } elseif ( ! is_array( $terms ) ) { $terms = array( $terms ); } @@ -2734,7 +2825,6 @@ } $tt_ids = array(); - $term_ids = array(); $new_tt_ids = array(); foreach ( (array) $terms as $term ) { @@ -2757,9 +2847,8 @@ return $term_info; } - $term_ids[] = $term_info['term_id']; - $tt_id = $term_info['term_taxonomy_id']; - $tt_ids[] = $tt_id; + $tt_id = $term_info['term_taxonomy_id']; + $tt_ids[] = $tt_id; if ( $wpdb->get_var( $wpdb->prepare( "SELECT term_taxonomy_id FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id = %d", $object_id, $tt_id ) ) ) { continue; @@ -2848,7 +2937,7 @@ } wp_cache_delete( $object_id, $taxonomy . '_relationships' ); - wp_cache_delete( 'last_changed', 'terms' ); + wp_cache_set_terms_last_changed(); /** * Fires after an object's terms have been set. @@ -2946,7 +3035,7 @@ $deleted = $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id IN ($in_tt_ids)", $object_id ) ); wp_cache_delete( $object_id, $taxonomy . '_relationships' ); - wp_cache_delete( 'last_changed', 'terms' ); + wp_cache_set_terms_last_changed(); /** * Fires immediately after an object-term relationship is deleted. @@ -3052,7 +3141,7 @@ $num = 2; do { $alt_slug = $slug . "-$num"; - $num++; + ++$num; $slug_check = $wpdb->get_var( $wpdb->prepare( "SELECT slug FROM $wpdb->terms WHERE slug = %s", $alt_slug ) ); } while ( $slug_check ); $slug = $alt_slug; @@ -3094,8 +3183,8 @@ * * @param int $term_id The ID of the term. * @param string $taxonomy The taxonomy of the term. - * @param array|string $args { - * Optional. Array or string of arguments for updating a term. + * @param array $args { + * Optional. Array of arguments for updating a term. * * @type string $alias_of Slug of the term to make this term an alias of. * Default empty string. Accepts a term slug. @@ -3201,19 +3290,21 @@ * * @since 3.1.0 * - * @param int $parent ID of the parent term. + * @param int $parent_term ID of the parent term. * @param int $term_id Term ID. * @param string $taxonomy Taxonomy slug. * @param array $parsed_args An array of potentially altered update arguments for the given term. - * @param array $args An array of update arguments for the given term. + * @param array $args Arguments passed to wp_update_term(). */ $parent = (int) apply_filters( 'wp_update_term_parent', $args['parent'], $term_id, $taxonomy, $parsed_args, $args ); // Check for duplicate slug. $duplicate = get_term_by( 'slug', $slug, $taxonomy ); if ( $duplicate && $duplicate->term_id !== $term_id ) { - // If an empty slug was passed or the parent changed, reset the slug to something unique. - // Otherwise, bail. + /* + * If an empty slug was passed or the parent changed, reset the slug to something unique. + * Otherwise, bail. + */ if ( $empty_slug || ( $parent !== (int) $term['parent'] ) ) { $slug = wp_unique_term_slug( $slug, (object) $args ); } else { @@ -3234,11 +3325,13 @@ * Fires immediately before the given terms are edited. * * @since 2.9.0 + * @since 6.1.0 The `$args` parameter was added. * * @param int $term_id Term ID. * @param string $taxonomy Taxonomy slug. + * @param array $args Arguments passed to wp_update_term(). */ - do_action( 'edit_terms', $term_id, $taxonomy ); + do_action( 'edit_terms', $term_id, $taxonomy, $args ); $data = compact( 'name', 'slug', 'term_group' ); @@ -3266,21 +3359,25 @@ * term-taxonomy relationship is updated. * * @since 2.9.0 + * @since 6.1.0 The `$args` parameter was added. * * @param int $term_id Term ID. * @param string $taxonomy Taxonomy slug. + * @param array $args Arguments passed to wp_update_term(). */ - do_action( 'edited_terms', $term_id, $taxonomy ); + do_action( 'edited_terms', $term_id, $taxonomy, $args ); /** * Fires immediate before a term-taxonomy relationship is updated. * * @since 2.9.0 + * @since 6.1.0 The `$args` parameter was added. * * @param int $tt_id Term taxonomy ID. * @param string $taxonomy Taxonomy slug. + * @param array $args Arguments passed to wp_update_term(). */ - do_action( 'edit_term_taxonomy', $tt_id, $taxonomy ); + do_action( 'edit_term_taxonomy', $tt_id, $taxonomy, $args ); $wpdb->update( $wpdb->term_taxonomy, compact( 'term_id', 'taxonomy', 'description', 'parent' ), array( 'term_taxonomy_id' => $tt_id ) ); @@ -3288,11 +3385,13 @@ * Fires immediately after a term-taxonomy relationship is updated. * * @since 2.9.0 + * @since 6.1.0 The `$args` parameter was added. * * @param int $tt_id Term taxonomy ID. * @param string $taxonomy Taxonomy slug. + * @param array $args Arguments passed to wp_update_term(). */ - do_action( 'edited_term_taxonomy', $tt_id, $taxonomy ); + do_action( 'edited_term_taxonomy', $tt_id, $taxonomy, $args ); /** * Fires after a term has been updated, but before the term cache has been cleaned. @@ -3301,12 +3400,14 @@ * taxonomy. * * @since 2.3.0 + * @since 6.1.0 The `$args` parameter was added. * * @param int $term_id Term ID. * @param int $tt_id Term taxonomy ID. * @param string $taxonomy Taxonomy slug. + * @param array $args Arguments passed to wp_update_term(). */ - do_action( 'edit_term', $term_id, $tt_id, $taxonomy ); + do_action( 'edit_term', $term_id, $tt_id, $taxonomy, $args ); /** * Fires after a term in a specific taxonomy has been updated, but before the term @@ -3320,11 +3421,13 @@ * - `edit_post_tag` * * @since 2.3.0 + * @since 6.1.0 The `$args` parameter was added. * - * @param int $term_id Term ID. - * @param int $tt_id Term taxonomy ID. + * @param int $term_id Term ID. + * @param int $tt_id Term taxonomy ID. + * @param array $args Arguments passed to wp_update_term(). */ - do_action( "edit_{$taxonomy}", $term_id, $tt_id ); + do_action( "edit_{$taxonomy}", $term_id, $tt_id, $args ); /** This filter is documented in wp-includes/taxonomy.php */ $term_id = apply_filters( 'term_id_filter', $term_id, $tt_id ); @@ -3338,12 +3441,14 @@ * taxonomy. * * @since 2.3.0 + * @since 6.1.0 The `$args` parameter was added. * * @param int $term_id Term ID. * @param int $tt_id Term taxonomy ID. * @param string $taxonomy Taxonomy slug. + * @param array $args Arguments passed to wp_update_term(). */ - do_action( 'edited_term', $term_id, $tt_id, $taxonomy ); + do_action( 'edited_term', $term_id, $tt_id, $taxonomy, $args ); /** * Fires after a term for a specific taxonomy has been updated, and the term @@ -3357,17 +3462,19 @@ * - `edited_post_tag` * * @since 2.3.0 + * @since 6.1.0 The `$args` parameter was added. * - * @param int $term_id Term ID. - * @param int $tt_id Term taxonomy ID. + * @param int $term_id Term ID. + * @param int $tt_id Term taxonomy ID. + * @param array $args Arguments passed to wp_update_term(). */ - do_action( "edited_{$taxonomy}", $term_id, $tt_id ); + do_action( "edited_{$taxonomy}", $term_id, $tt_id, $args ); /** This action is documented in wp-includes/taxonomy.php */ - do_action( 'saved_term', $term_id, $tt_id, $taxonomy, true ); + do_action( 'saved_term', $term_id, $tt_id, $taxonomy, true, $args ); /** This action is documented in wp-includes/taxonomy.php */ - do_action( "saved_{$taxonomy}", $term_id, $tt_id, true ); + do_action( "saved_{$taxonomy}", $term_id, $tt_id, true, $args ); return array( 'term_id' => $term_id, @@ -3460,7 +3567,7 @@ } else { $object_types = (array) $taxonomy->object_type; foreach ( $object_types as &$object_type ) { - if ( 0 === strpos( $object_type, 'attachment:' ) ) { + if ( str_starts_with( $object_type, 'attachment:' ) ) { list( $object_type ) = explode( ':', $object_type ); } } @@ -3516,7 +3623,7 @@ wp_cache_delete_multiple( $object_ids, "{$taxonomy}_relationships" ); } - wp_cache_delete( 'last_changed', 'terms' ); + wp_cache_set_terms_last_changed(); /** * Fires after the object term cache has been cleaned. @@ -3591,7 +3698,7 @@ do_action( 'clean_term_cache', $ids, $taxonomy, $clean_taxonomy ); } - wp_cache_set( 'last_changed', microtime(), 'terms' ); + wp_cache_set_terms_last_changed(); } /** @@ -3604,7 +3711,7 @@ function clean_taxonomy_cache( $taxonomy ) { wp_cache_delete( 'all_ids', $taxonomy ); wp_cache_delete( 'get', $taxonomy ); - wp_cache_delete( 'last_changed', 'terms' ); + wp_cache_set_terms_last_changed(); // Regenerate cached hierarchy. delete_option( "{$taxonomy}_children" ); @@ -3976,7 +4083,8 @@ * Adds any terms from the given IDs to the cache that do not already exist in cache. * * @since 4.6.0 - * @access private + * @since 6.1.0 This function is no longer marked as "private". + * @since 6.3.0 Use wp_lazyload_term_meta() for lazy-loading of term meta. * * @global wpdb $wpdb WordPress database abstraction object. * @@ -3991,10 +4099,10 @@ $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 ) ) ) ); update_term_cache( $fresh_terms ); - - if ( $update_meta_cache ) { - update_termmeta_cache( $non_cached_ids ); - } + } + + if ( $update_meta_cache ) { + wp_lazyload_term_meta( $term_ids ); } } @@ -4262,7 +4370,7 @@ $lock_name = 'term_split.lock'; // Try to lock. - $lock_result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO `$wpdb->options` ( `option_name`, `option_value`, `autoload` ) VALUES (%s, %s, 'no') /* LOCK */", $lock_name, time() ) ); + $lock_result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO `$wpdb->options` ( `option_name`, `option_value`, `autoload` ) VALUES (%s, %s, 'off') /* LOCK */", $lock_name, time() ) ); if ( ! $lock_result ) { $lock_result = get_option( $lock_name ); @@ -4492,6 +4600,8 @@ * * @since 4.4.0 * + * @global wpdb $wpdb WordPress database abstraction object. + * * @param int $term_id Term ID. * @return bool Returns false if a term is not shared between multiple taxonomies or * if splitting shared taxonomy terms is finished. @@ -4671,7 +4781,7 @@ * @type string $term_template Template for displaying a single term in the list. Default is the term name * linked to its archive. * } - * @return array List of taxonomies. + * @return string[] List of taxonomies. */ function get_the_taxonomies( $post = 0, $args = array() ) { $post = get_post( $post ); @@ -4909,29 +5019,29 @@ * * @since 3.1.0 * - * @param int $parent `term_id` of the parent for the term we're checking. - * @param int $term_id The term we're checking. - * @param string $taxonomy The taxonomy of the term we're checking. + * @param int $parent_term `term_id` of the parent for the term we're checking. + * @param int $term_id The term we're checking. + * @param string $taxonomy The taxonomy of the term we're checking. * @return int The new parent for the term. */ -function wp_check_term_hierarchy_for_loops( $parent, $term_id, $taxonomy ) { +function wp_check_term_hierarchy_for_loops( $parent_term, $term_id, $taxonomy ) { // Nothing fancy here - bail. - if ( ! $parent ) { + if ( ! $parent_term ) { return 0; } // Can't be its own parent. - if ( $parent === $term_id ) { + if ( $parent_term === $term_id ) { return 0; } // Now look for larger loops. - $loop = wp_find_hierarchy_loop( 'wp_get_term_taxonomy_parent_id', $term_id, $parent, array( $taxonomy ) ); + $loop = wp_find_hierarchy_loop( 'wp_get_term_taxonomy_parent_id', $term_id, $parent_term, array( $taxonomy ) ); if ( ! $loop ) { - return $parent; // No loop. - } - - // Setting $parent to the given value causes a loop. + return $parent_term; // No loop. + } + + // Setting $parent_term to the given value causes a loop. if ( isset( $loop[ $term_id ] ) ) { return 0; } @@ -4941,7 +5051,7 @@ wp_update_term( $loop_member, $taxonomy, array( 'parent' => 0 ) ); } - return $parent; + return $parent_term; } /** @@ -4964,12 +5074,32 @@ } /** + * Determines whether a term is publicly viewable. + * + * A term is considered publicly viewable if its taxonomy is viewable. + * + * @since 6.1.0 + * + * @param int|WP_Term $term Term ID or term object. + * @return bool Whether the term is publicly viewable. + */ +function is_term_publicly_viewable( $term ) { + $term = get_term( $term ); + + if ( ! $term ) { + return false; + } + + return is_taxonomy_viewable( $term->taxonomy ); +} + +/** * Sets the last changed time for the 'terms' cache group. * * @since 5.0.0 */ function wp_cache_set_terms_last_changed() { - wp_cache_set( 'last_changed', microtime(), 'terms' ); + wp_cache_set_last_changed( 'terms' ); } /**