From 4649b2345da12801ea1a29a5e929ccf11dc42b63 Mon Sep 17 00:00:00 2001 From: Boone Gorges Date: Wed, 17 Jun 2015 01:47:52 +0000 Subject: [PATCH] Performance enhancements for `_split_shared_term()`. * Introduce a `$record` parameter, which defaults to true. When set to false, `_split_shared_term()` will not keep a record of split term data in wp_options. The judicious use of this flag can greatly improve performance when processing shared terms in batches. * Allow term/tt objects to be passed to the `$term_id` and `$term_taxonomy_id` parameters. This has the potential to save database queries when the objects are already available. See #30261. git-svn-id: https://develop.svn.wordpress.org/trunk@32813 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/taxonomy.php | 49 ++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/src/wp-includes/taxonomy.php b/src/wp-includes/taxonomy.php index 70c465a8ad..6043550a65 100644 --- a/src/wp-includes/taxonomy.php +++ b/src/wp-includes/taxonomy.php @@ -4188,18 +4188,35 @@ function _update_generic_term_count( $terms, $taxonomy ) { * * @ignore * @since 4.2.0 + * @since 4.3.0 Introduced `$record` parameter. `$term_id` and `$term_taxonomy_id` can now accept objects. * * @global wpdb $wpdb * - * @param int $term_id ID of the shared term. - * @param int $term_taxonomy_id ID of the term_taxonomy item to receive a new term. + * @param int|object $term_id ID of the shared term, or the shared term object. + * @param int|object $term_taxonomy_id ID of the term_taxonomy item to receive a new term, or the term_taxonomy object + * (corresponding to a row from the term_taxonomy table). + * @param bool $record Whether to record data about the split term in the options table. The recording + * process has the potential to be resource-intensive, so during batch operations + * it can be beneficial to skip inline recording and do it just once, after the + * batch is processed. Only set this to `false` if you know what you are doing. + * Default: true. * @return int|WP_Error When the current term does not need to be split (or cannot be split on the current * database schema), `$term_id` is returned. When the term is successfully split, the * new term_id is returned. A WP_Error is returned for miscellaneous errors. */ -function _split_shared_term( $term_id, $term_taxonomy_id ) { +function _split_shared_term( $term_id, $term_taxonomy_id, $record = true ) { global $wpdb; + if ( is_object( $term_id ) ) { + $shared_term = $term_id; + $term_id = intval( $shared_term->term_id ); + } + + if ( is_object( $term_taxonomy_id ) ) { + $term_taxonomy = $term_taxonomy_id; + $term_taxonomy_id = intval( $term_taxonomy->term_taxonomy_id ); + } + // Don't try to split terms if database schema does not support shared slugs. $current_db_version = get_option( 'db_version' ); if ( $current_db_version < 30133 ) { @@ -4208,12 +4225,15 @@ function _split_shared_term( $term_id, $term_taxonomy_id ) { // If there are no shared term_taxonomy rows, there's nothing to do here. $shared_tt_count = $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 ) ); + if ( ! $shared_tt_count ) { return $term_id; } // Pull up data about the currently shared slug, which we'll use to populate the new one. - $shared_term = $wpdb->get_row( $wpdb->prepare( "SELECT t.* FROM $wpdb->terms t WHERE t.term_id = %d", $term_id ) ); + if ( empty( $shared_term ) ) { + $shared_term = $wpdb->get_row( $wpdb->prepare( "SELECT t.* FROM $wpdb->terms t WHERE t.term_id = %d", $term_id ) ); + } $new_term_data = array( 'name' => $shared_term->name, @@ -4234,9 +4254,11 @@ function _split_shared_term( $term_id, $term_taxonomy_id ) { ); // Reassign child terms to the new parent. - $term_taxonomy = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %d", $term_taxonomy_id ) ); - $children_tt_ids = $wpdb->get_col( $wpdb->prepare( "SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = %s AND parent = %d", $term_taxonomy->taxonomy, $term_id ) ); + if ( empty( $term_taxonomy ) ) { + $term_taxonomy = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %d", $term_taxonomy_id ) ); + } + $children_tt_ids = $wpdb->get_col( $wpdb->prepare( "SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE parent = %d AND taxonomy = %s", $term_id, $term_taxonomy->taxonomy ) ); if ( ! empty( $children_tt_ids ) ) { foreach ( $children_tt_ids as $child_tt_id ) { $wpdb->update( $wpdb->term_taxonomy, @@ -4259,15 +4281,16 @@ function _split_shared_term( $term_id, $term_taxonomy_id ) { } // Keep a record of term_ids that have been split, keyed by old term_id. See {@see wp_get_split_term()}. - $split_term_data = get_option( '_split_terms', array() ); - if ( ! isset( $split_term_data[ $term_id ] ) ) { - $split_term_data[ $term_id ] = array(); + if ( $record ) { + $split_term_data = get_option( '_split_terms', array() ); + if ( ! isset( $split_term_data[ $term_id ] ) ) { + $split_term_data[ $term_id ] = array(); + } + + $split_term_data[ $term_id ][ $term_taxonomy->taxonomy ] = $new_term_id; + update_option( '_split_terms', $split_term_data ); } - $split_term_data[ $term_id ][ $term_taxonomy->taxonomy ] = $new_term_id; - - update_option( '_split_terms', $split_term_data ); - /** * Fires after a previously shared taxonomy term is split into two separate terms. *