Make WordPress Core

Ticket #30261: 30261.16.diff

File 30261.16.diff, 9.0 KB (added by pento, 9 years ago)
  • src/wp-admin/includes/upgrade.php

     
    15051505                upgrade_430_fix_comments();
    15061506        }
    15071507
     1508        // Shared terms are split in a separate process.
    15081509        if ( $wp_current_db_version < 32814 ) {
    1509                 split_all_shared_terms();
     1510                wp_schedule_single_event( time() + ( 1 * MINUTE_IN_SECONDS ), 'wp_split_shared_term_batch' );
    15101511        }
    15111512
    15121513        if ( $wp_current_db_version < 33055 && 'utf8mb4' === $wpdb->charset ) {
     
    18811882}
    18821883
    18831884/**
    1884  * Splits all shared taxonomy terms.
    1885  *
    1886  * @since 4.3.0
    1887  *
    1888  * @global wpdb $wpdb WordPress database abstraction object.
    1889  */
    1890 function split_all_shared_terms() {
    1891         global $wpdb;
    1892 
    1893         // Get a list of shared terms (those with more than one associated row in term_taxonomy).
    1894         $shared_terms = $wpdb->get_results(
    1895                 "SELECT tt.term_id, t.*, count(*) as term_tt_count FROM {$wpdb->term_taxonomy} tt
    1896                  LEFT JOIN {$wpdb->terms} t ON t.term_id = tt.term_id
    1897                  GROUP BY t.term_id
    1898                  HAVING term_tt_count > 1"
    1899         );
    1900 
    1901         if ( empty( $shared_terms ) ) {
    1902                 return;
    1903         }
    1904 
    1905         // Rekey shared term array for faster lookups.
    1906         $_shared_terms = array();
    1907         foreach ( $shared_terms as $shared_term ) {
    1908                 $term_id = intval( $shared_term->term_id );
    1909                 $_shared_terms[ $term_id ] = $shared_term;
    1910         }
    1911         $shared_terms = $_shared_terms;
    1912 
    1913         // Get term taxonomy data for all shared terms.
    1914         $shared_term_ids = implode( ',', array_keys( $shared_terms ) );
    1915         $shared_tts = $wpdb->get_results( "SELECT * FROM {$wpdb->term_taxonomy} WHERE `term_id` IN ({$shared_term_ids})" );
    1916 
    1917         // Split term data recording is slow, so we do it just once, outside the loop.
    1918         $suspend = wp_suspend_cache_invalidation( true );
    1919         $split_term_data = get_option( '_split_terms', array() );
    1920         $skipped_first_term = $taxonomies = array();
    1921         foreach ( $shared_tts as $shared_tt ) {
    1922                 $term_id = intval( $shared_tt->term_id );
    1923 
    1924                 // Don't split the first tt belonging to a given term_id.
    1925                 if ( ! isset( $skipped_first_term[ $term_id ] ) ) {
    1926                         $skipped_first_term[ $term_id ] = 1;
    1927                         continue;
    1928                 }
    1929 
    1930                 if ( ! isset( $split_term_data[ $term_id ] ) ) {
    1931                         $split_term_data[ $term_id ] = array();
    1932                 }
    1933 
    1934                 // Keep track of taxonomies whose hierarchies need flushing.
    1935                 if ( ! isset( $taxonomies[ $shared_tt->taxonomy ] ) ) {
    1936                         $taxonomies[ $shared_tt->taxonomy ] = 1;
    1937                 }
    1938 
    1939                 // Split the term.
    1940                 $split_term_data[ $term_id ][ $shared_tt->taxonomy ] = _split_shared_term( $shared_terms[ $term_id ], $shared_tt, false );
    1941         }
    1942 
    1943         // Rebuild the cached hierarchy for each affected taxonomy.
    1944         foreach ( array_keys( $taxonomies ) as $tax ) {
    1945                 delete_option( "{$tax}_children" );
    1946                 _get_term_hierarchy( $tax );
    1947         }
    1948 
    1949         wp_suspend_cache_invalidation( $suspend );
    1950         update_option( '_split_terms', $split_term_data );
    1951 }
    1952 
    1953 /**
    19541885 * Retrieve all options as it was for 1.2.
    19551886 *
    19561887 * @since 1.2.0
  • src/wp-includes/default-filters.php

     
    328328add_filter( 'determine_current_user', 'wp_validate_logged_in_cookie', 20 );
    329329
    330330// Split term updates.
     331add_action( 'admin_init',        '_wp_check_for_scheduled_split_terms' );
    331332add_action( 'split_shared_term', '_wp_check_split_default_terms',  10, 4 );
    332333add_action( 'split_shared_term', '_wp_check_split_terms_in_menus', 10, 4 );
    333334add_action( 'split_shared_term', '_wp_check_split_nav_menu_terms', 10, 4 );
     335add_action( 'wp_split_shared_term_batch', '_wp_batch_split_terms' );
    334336
    335337/**
    336338 * Filters formerly mixed into wp-includes
  • src/wp-includes/taxonomy.php

     
    42494249                $term_taxonomy_id = intval( $term_taxonomy->term_taxonomy_id );
    42504250        }
    42514251
    4252         // Don't try to split terms if database schema does not support shared slugs.
    4253         $current_db_version = get_option( 'db_version' );
    4254         if ( $current_db_version < 30133 ) {
    4255                 return $term_id;
    4256         }
    4257 
    42584252        // If there are no shared term_taxonomy rows, there's nothing to do here.
    42594253        $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 ) );
    42604254
     
    42624256                return $term_id;
    42634257        }
    42644258
     4259        /*
     4260         * Verify that the term_taxonomy_id passed to the function is actually associated with the term_id.
     4261         * If there's a mismatch, it may mean that the term is already split. Return the actual term_id from the db.
     4262         */
     4263        $check_term_id = $wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %d", $term_taxonomy_id ) );
     4264        if ( $check_term_id != $term_id ) {
     4265                return $check_term_id;
     4266        }
     4267
    42654268        // Pull up data about the currently shared slug, which we'll use to populate the new one.
    42664269        if ( empty( $shared_term ) ) {
    42674270                $shared_term = $wpdb->get_row( $wpdb->prepare( "SELECT t.* FROM $wpdb->terms t WHERE t.term_id = %d", $term_id ) );
     
    43394342}
    43404343
    43414344/**
     4345 * Splits a batch of shared taxonomy terms.
     4346 *
     4347 * @since 4.3.0
     4348 *
     4349 * @global wpdb $wpdb WordPress database abstraction object.
     4350 */
     4351function _wp_batch_split_terms() {
     4352        global $wpdb;
     4353
     4354        $lock_name = 'term_split.lock';
     4355
     4356        // Try to lock.
     4357        $lock_result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO `$wpdb->options` ( `option_name`, `option_value`, `autoload` ) VALUES (%s, %s, 'no') /* LOCK */", $lock_name, time() ) );
     4358
     4359        if ( ! $lock_result ) {
     4360                $lock_result = get_option( $lock_name );
     4361
     4362                // Bail if we were unable to create a lock, or if the existing lock is still valid.
     4363                if ( ! $lock_result || ( $lock_result > ( time() - HOUR_IN_SECONDS ) ) ) {
     4364                        wp_schedule_single_event( time() + ( 5 * MINUTE_IN_SECONDS ), 'wp_split_shared_term_batch' );
     4365                        return;
     4366                }
     4367        }
     4368
     4369        // Update the lock, as by this point we've definitely got a lock, just need to fire the actions.
     4370        update_option( $lock_name, time() );
     4371
     4372        // Get a list of shared terms (those with more than one associated row in term_taxonomy).
     4373        $shared_terms = $wpdb->get_results(
     4374                "SELECT tt.term_id, t.*, count(*) as term_tt_count FROM {$wpdb->term_taxonomy} tt
     4375                 LEFT JOIN {$wpdb->terms} t ON t.term_id = tt.term_id
     4376                 GROUP BY t.term_id
     4377                 HAVING term_tt_count > 1
     4378                 LIMIT 20"
     4379        );
     4380
     4381        // No more terms, we're done here.
     4382        if ( ! $shared_terms ) {
     4383                update_option( 'finished_splitting_shared_terms', true );
     4384                delete_option( $lock_name );
     4385                return;
     4386        }
     4387
     4388        // Shared terms found? We'll need to run this script again.
     4389        wp_schedule_single_event( time() + ( 2 * MINUTE_IN_SECONDS ), 'wp_split_shared_term_batch' );
     4390
     4391        // Rekey shared term array for faster lookups.
     4392        $_shared_terms = array();
     4393        foreach ( $shared_terms as $shared_term ) {
     4394                $term_id = intval( $shared_term->term_id );
     4395                $_shared_terms[ $term_id ] = $shared_term;
     4396        }
     4397        $shared_terms = $_shared_terms;
     4398
     4399        // Get term taxonomy data for all shared terms.
     4400        $shared_term_ids = implode( ',', array_keys( $shared_terms ) );
     4401        $shared_tts = $wpdb->get_results( "SELECT * FROM {$wpdb->term_taxonomy} WHERE `term_id` IN ({$shared_term_ids})" );
     4402
     4403        // Split term data recording is slow, so we do it just once, outside the loop.
     4404        $suspend = wp_suspend_cache_invalidation( true );
     4405        $split_term_data = get_option( '_split_terms', array() );
     4406        $skipped_first_term = $taxonomies = array();
     4407        foreach ( $shared_tts as $shared_tt ) {
     4408                $term_id = intval( $shared_tt->term_id );
     4409
     4410                // Don't split the first tt belonging to a given term_id.
     4411                if ( ! isset( $skipped_first_term[ $term_id ] ) ) {
     4412                        $skipped_first_term[ $term_id ] = 1;
     4413                        continue;
     4414                }
     4415
     4416                if ( ! isset( $split_term_data[ $term_id ] ) ) {
     4417                        $split_term_data[ $term_id ] = array();
     4418                }
     4419
     4420                // Keep track of taxonomies whose hierarchies need flushing.
     4421                if ( ! isset( $taxonomies[ $shared_tt->taxonomy ] ) ) {
     4422                        $taxonomies[ $shared_tt->taxonomy ] = 1;
     4423                }
     4424
     4425                // Split the term.
     4426                $split_term_data[ $term_id ][ $shared_tt->taxonomy ] = _split_shared_term( $shared_terms[ $term_id ], $shared_tt, false );
     4427        }
     4428
     4429        // Rebuild the cached hierarchy for each affected taxonomy.
     4430        foreach ( array_keys( $taxonomies ) as $tax ) {
     4431                delete_option( "{$tax}_children" );
     4432                _get_term_hierarchy( $tax );
     4433        }
     4434
     4435        wp_suspend_cache_invalidation( $suspend );
     4436        update_option( '_split_terms', $split_term_data );
     4437
     4438        delete_option( $lock_name );
     4439}
     4440
     4441/**
     4442 * In order to avoid the wp_batch_split_terms() job being accidentally removed,
     4443 * check that it's still scheduled while we haven't finished splitting terms.
     4444 *
     4445 * @ignore
     4446 * @since 4.3.0
     4447 */
     4448function _wp_check_for_scheduled_split_terms() {
     4449        if ( ! get_option( 'finished_splitting_shared_terms' ) && ! wp_next_scheduled( 'wp_batch_split_terms' ) ) {
     4450                wp_schedule_single_event( 'wp_batch_split_terms', time() + MINUTE_IN_SECONDS );
     4451        }
     4452}
     4453
     4454/**
    43424455 * Check default categories when a term gets split to see if any of them need to be updated.
    43434456 *
    43444457 * @ignore