Ticket #34878: 34878.diff
File 34878.diff, 15.4 KB (added by , 9 years ago) |
---|
-
src/wp-admin/includes/class-wp-upgrader.php
class Language_Pack_Upgrader extends WP_ 2156 2156 * 2157 2157 * @since 2.8.0 2158 2158 * 2159 2159 * @see WP_Upgrader 2160 2160 */ 2161 2161 class Core_Upgrader extends WP_Upgrader { 2162 2162 2163 2163 /** 2164 2164 * Initialize the upgrade strings. 2165 2165 * 2166 2166 * @since 2.8.0 2167 2167 * @access public 2168 2168 */ 2169 2169 public function upgrade_strings() { 2170 2170 $this->strings['up_to_date'] = __('WordPress is at the latest version.'); 2171 $this->strings['locked'] = __('Another update is currently in progress.'); 2171 2172 $this->strings['no_package'] = __('Update package not available.'); 2172 2173 $this->strings['downloading_package'] = __('Downloading update from <span class="code">%s</span>…'); 2173 2174 $this->strings['unpack_package'] = __('Unpacking the update…'); 2174 2175 $this->strings['copy_failed'] = __('Could not copy files.'); 2175 2176 $this->strings['copy_failed_space'] = __('Could not copy files. You may have run out of disk space.' ); 2176 2177 $this->strings['start_rollback'] = __( 'Attempting to roll back to previous version.' ); 2177 2178 $this->strings['rollback_was_required'] = __( 'Due to an error during updating, WordPress has rolled back to your previous version.' ); 2178 2179 } 2179 2180 2180 2181 /** 2181 2182 * Upgrade WordPress core. 2182 2183 * 2183 2184 * @since 2.8.0 2184 2185 * @access public 2185 2186 * … … class Core_Upgrader extends WP_Upgrader 2240 2241 * the new_bundled zip. Don't though if the constant is set to skip bundled items. 2241 2242 * If the API returns a no_content zip, go with it. Finally, default to the full zip. 2242 2243 */ 2243 2244 if ( $parsed_args['do_rollback'] && $current->packages->rollback ) 2244 2245 $to_download = 'rollback'; 2245 2246 elseif ( $current->packages->partial && 'reinstall' != $current->response && $wp_version == $current->partial_version && $partial ) 2246 2247 $to_download = 'partial'; 2247 2248 elseif ( $current->packages->new_bundled && version_compare( $wp_version, $current->new_bundled, '<' ) 2248 2249 && ( ! defined( 'CORE_UPGRADE_SKIP_NEW_BUNDLED' ) || ! CORE_UPGRADE_SKIP_NEW_BUNDLED ) ) 2249 2250 $to_download = 'new_bundled'; 2250 2251 elseif ( $current->packages->no_content ) 2251 2252 $to_download = 'no_content'; 2252 2253 else 2253 2254 $to_download = 'full'; 2254 2255 2256 // Lock to prevent multiple Core Updates occuring 2257 $lock = wp_create_lock( 'core_updater', 15 * MINUTE_IN_SECONDS ); 2258 if ( ! $lock ) { 2259 return new WP_Error( 'locked', $this->strings['locked'] ); 2260 } 2261 2255 2262 $download = $this->download_package( $current->packages->$to_download ); 2256 if ( is_wp_error($download) ) 2263 if ( is_wp_error( $download ) ) { 2264 wp_release_lock( 'core_updater' ); 2257 2265 return $download; 2266 } 2258 2267 2259 2268 $working_dir = $this->unpack_package( $download ); 2260 if ( is_wp_error($working_dir) ) 2269 if ( is_wp_error( $working_dir ) ) { 2270 wp_release_lock( 'core_updater' ); 2261 2271 return $working_dir; 2272 } 2262 2273 2263 2274 // Copy update-core.php from the new version into place. 2264 2275 if ( !$wp_filesystem->copy($working_dir . '/wordpress/wp-admin/includes/update-core.php', $wp_dir . 'wp-admin/includes/update-core.php', true) ) { 2265 2276 $wp_filesystem->delete($working_dir, true); 2277 wp_release_lock( 'core_updater' ); 2266 2278 return new WP_Error( 'copy_failed_for_update_core_file', __( 'The update cannot be installed because we will be unable to copy some files. This is usually due to inconsistent file permissions.' ), 'wp-admin/includes/update-core.php' ); 2267 2279 } 2268 2280 $wp_filesystem->chmod($wp_dir . 'wp-admin/includes/update-core.php', FS_CHMOD_FILE); 2269 2281 2270 2282 require_once( ABSPATH . 'wp-admin/includes/update-core.php' ); 2271 2283 2272 if ( ! function_exists( 'update_core' ) ) 2284 if ( ! function_exists( 'update_core' ) ) { 2285 wp_release_lock( 'core_updater' ); 2273 2286 return new WP_Error( 'copy_failed_space', $this->strings['copy_failed_space'] ); 2287 } 2274 2288 2275 2289 $result = update_core( $working_dir, $wp_dir ); 2276 2290 2277 2291 // In the event of an issue, we may be able to roll back. 2278 2292 if ( $parsed_args['attempt_rollback'] && $current->packages->rollback && ! $parsed_args['do_rollback'] ) { 2279 2293 $try_rollback = false; 2280 2294 if ( is_wp_error( $result ) ) { 2281 2295 $error_code = $result->get_error_code(); 2282 2296 /* 2283 2297 * Not all errors are equal. These codes are critical: copy_failed__copy_dir, 2284 2298 * mkdir_failed__copy_dir, copy_failed__copy_dir_retry, and disk_full. 2285 2299 * do_rollback allows for update_core() to trigger a rollback if needed. 2286 2300 */ 2287 2301 if ( false !== strpos( $error_code, 'do_rollback' ) ) 2288 2302 $try_rollback = true; … … class Core_Upgrader extends WP_Upgrader 2333 2347 // Was the rollback successful? If not, collect its error too. 2334 2348 $stats['rollback'] = ! is_wp_error( $rollback_result ); 2335 2349 if ( is_wp_error( $rollback_result ) ) { 2336 2350 $stats['rollback_code'] = $rollback_result->get_error_code(); 2337 2351 $stats['rollback_data'] = $rollback_result->get_error_data(); 2338 2352 } 2339 2353 } else { 2340 2354 $stats['error_code'] = $result->get_error_code(); 2341 2355 $stats['error_data'] = $result->get_error_data(); 2342 2356 } 2343 2357 } 2344 2358 2345 2359 wp_version_check( $stats ); 2346 2360 } 2347 2361 2362 wp_release_lock( 'core_updater' ); 2363 2348 2364 return $result; 2349 2365 } 2350 2366 2351 2367 /** 2352 2368 * Determines if this WordPress Core version should update to an offered version or not. 2353 2369 * 2354 2370 * @since 3.7.0 2355 2371 * @access public 2356 2372 * 2357 2373 * @static 2358 2374 * 2359 2375 * @param string $offered_ver The offered version, of the format x.y.z. 2360 2376 * @return bool True if we should update to the offered version, otherwise false. 2361 2377 */ 2362 2378 public static function should_update_to_version( $offered_ver ) { … … class WP_Automatic_Updater { 2926 2942 $upgrade_result = $upgrader->upgrade( $upgrader_item, array( 2927 2943 'clear_update_cache' => false, 2928 2944 // Always use partial builds if possible for core updates. 2929 2945 'pre_check_md5' => false, 2930 2946 // Only available for core updates. 2931 2947 'attempt_rollback' => true, 2932 2948 // Allow relaxed file ownership in some scenarios 2933 2949 'allow_relaxed_file_ownership' => $allow_relaxed_file_ownership, 2934 2950 ) ); 2935 2951 2936 2952 // If the filesystem is unavailable, false is returned. 2937 2953 if ( false === $upgrade_result ) { 2938 2954 $upgrade_result = new WP_Error( 'fs_unavailable', __( 'Could not access filesystem.' ) ); 2939 2955 } 2940 2956 2941 // Core doesn't output this, so let's append it so we don't get confused.2942 2957 if ( 'core' == $type ) { 2958 if ( is_wp_error( $upgrade_result ) && ( 'up_to_date' == $upgrade_result->get_error_code() || 'locked' == $upgrade_result->get_error_code() ) ) { 2959 // These aren't actual errors, treat it as a skipped-update instead to avoid triggering the post-core update failure routines. 2960 return false; 2961 } 2962 2963 // Core doesn't output this, so let's append it so we don't get confused. 2943 2964 if ( is_wp_error( $upgrade_result ) ) { 2944 2965 $skin->error( __( 'Installation Failed' ), $upgrade_result ); 2945 2966 } else { 2946 2967 $skin->feedback( __( 'WordPress updated successfully' ) ); 2947 2968 } 2948 2969 } 2949 2970 2950 2971 $this->update_results[ $type ][] = (object) array( 2951 2972 'item' => $item, 2952 2973 'result' => $upgrade_result, 2953 2974 'name' => $item_name, 2954 2975 'messages' => $skin->get_upgrade_messages() 2955 2976 ); 2956 2977 2957 2978 return $upgrade_result; … … class WP_Automatic_Updater { 2963 2984 * @since 3.7.0 2964 2985 * @access public 2965 2986 * 2966 2987 * @global wpdb $wpdb 2967 2988 * @global string $wp_version 2968 2989 */ 2969 2990 public function run() { 2970 2991 global $wpdb, $wp_version; 2971 2992 2972 2993 if ( $this->is_disabled() ) 2973 2994 return; 2974 2995 2975 2996 if ( ! is_main_network() || ! is_main_site() ) 2976 2997 return; 2977 2998 2978 $lock_name = 'auto_updater.lock'; 2979 2980 // Try to lock 2981 $lock_result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO `$wpdb->options` ( `option_name`, `option_value`, `autoload` ) VALUES (%s, %s, 'no') /* LOCK */", $lock_name, time() ) ); 2982 2983 if ( ! $lock_result ) { 2984 $lock_result = get_option( $lock_name ); 2985 2986 // If we couldn't create a lock, and there isn't a lock, bail 2987 if ( ! $lock_result ) 2988 return; 2989 2990 // Check to see if the lock is still valid 2991 if ( $lock_result > ( time() - HOUR_IN_SECONDS ) ) 2992 return; 2993 } 2994 2995 // Update the lock, as by this point we've definitely got a lock, just need to fire the actions 2996 update_option( $lock_name, time() ); 2999 if ( ! wp_create_lock( 'auto_updater' ) ) 3000 return; 2997 3001 2998 3002 // Don't automatically run these thins, as we'll handle it ourselves 2999 3003 remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 ); 3000 3004 remove_action( 'upgrader_process_complete', 'wp_version_check' ); 3001 3005 remove_action( 'upgrader_process_complete', 'wp_update_plugins' ); 3002 3006 remove_action( 'upgrader_process_complete', 'wp_update_themes' ); 3003 3007 3004 3008 // Next, Plugins 3005 3009 wp_update_plugins(); // Check for Plugin updates 3006 3010 $plugin_updates = get_site_transient( 'update_plugins' ); 3007 3011 if ( $plugin_updates && !empty( $plugin_updates->response ) ) { 3008 3012 foreach ( $plugin_updates->response as $plugin ) { 3009 3013 $this->update( 'plugin', $plugin ); 3010 3014 } 3011 3015 // Force refresh of plugin update information … … class WP_Automatic_Updater { 3080 3084 $this->send_debug_email(); 3081 3085 3082 3086 if ( ! empty( $this->update_results['core'] ) ) 3083 3087 $this->after_core_update( $this->update_results['core'][0] ); 3084 3088 3085 3089 /** 3086 3090 * Fires after all automatic updates have run. 3087 3091 * 3088 3092 * @since 3.8.0 3089 3093 * 3090 3094 * @param array $update_results The results of all attempted updates. 3091 3095 */ 3092 3096 do_action( 'automatic_updates_complete', $this->update_results ); 3093 3097 } 3094 3098 3095 // Clear the lock 3096 delete_option( $lock_name ); 3099 wp_release_lock( 'core_updater' ); 3097 3100 } 3098 3101 3099 3102 /** 3100 3103 * If we tried to perform a core update, check if we should send an email, 3101 3104 * and if we need to avoid processing future updates. 3102 3105 * 3103 3106 * @since Unknown 3104 3107 * @access protected 3105 3108 * 3106 3109 * @global string $wp_version 3107 3110 * 3108 3111 * @param object|WP_Error $update_result The result of the core update. Includes the update offer and result. 3109 3112 */ 3110 3113 protected function after_core_update( $update_result ) { 3111 3114 global $wp_version; … … class WP_Automatic_Updater { 3151 3154 return; 3152 3155 } 3153 3156 3154 3157 /* 3155 3158 * Any other WP_Error code (like download_failed or files_not_writable) occurs before 3156 3159 * we tried to copy over core files. Thus, the failures are early and graceful. 3157 3160 * 3158 3161 * We should avoid trying to perform a background update again for the same version. 3159 3162 * But we can try again if another version is released. 3160 3163 * 3161 3164 * For certain 'transient' failures, like download_failed, we should allow retries. 3162 3165 * In fact, let's schedule a special update for an hour from now. (It's possible 3163 3166 * the issue could actually be on WordPress.org's side.) If that one fails, then email. 3164 3167 */ 3165 3168 $send = true; 3166 $transient_failures = array( 'incompatible_archive', 'download_failed', 'insane_distro' );3169 $transient_failures = array( 'incompatible_archive', 'download_failed', 'insane_distro', 'locked' ); 3167 3170 if ( in_array( $error_code, $transient_failures ) && ! get_site_option( 'auto_core_update_failed' ) ) { 3168 3171 wp_schedule_single_event( time() + HOUR_IN_SECONDS, 'wp_maybe_auto_update' ); 3169 3172 $send = false; 3170 3173 } 3171 3174 3172 3175 $n = get_site_option( 'auto_core_update_notified' ); 3173 3176 // Don't notify if we've already notified the same email address of the same version of the same notification type. 3174 3177 if ( $n && 'fail' == $n['type'] && $n['email'] == get_site_option( 'admin_email' ) && $n['version'] == $core_update->current ) 3175 3178 $send = false; 3176 3179 3177 3180 update_site_option( 'auto_core_update_failed', array( 3178 3181 'attempted' => $core_update->current, 3179 3182 'current' => $wp_version, 3180 3183 'error_code' => $error_code, 3181 3184 'error_data' => $result->get_error_data(), -
src/wp-admin/update-core.php
function do_core_upgrade( $reinstall = f 472 472 return; 473 473 } 474 474 475 475 if ( $reinstall ) 476 476 $update->response = 'reinstall'; 477 477 478 478 add_filter( 'update_feedback', 'show_message' ); 479 479 480 480 $upgrader = new Core_Upgrader(); 481 481 $result = $upgrader->upgrade( $update, array( 482 482 'allow_relaxed_file_ownership' => $allow_relaxed_file_ownership 483 483 ) ); 484 484 485 485 if ( is_wp_error($result) ) { 486 486 show_message($result); 487 if ( 'up_to_date' != $result->get_error_code() )487 if ( 'up_to_date' != $result->get_error_code() && 'locked' != $result->get_error_code() ) 488 488 show_message( __('Installation Failed') ); 489 489 echo '</div>'; 490 490 return; 491 491 } 492 492 493 493 show_message( __('WordPress updated successfully') ); 494 494 show_message( '<span class="hide-if-no-js">' . sprintf( __( 'Welcome to WordPress %1$s. You will be redirected to the About WordPress screen. If not, click <a href="%2$s">here</a>.' ), $result, esc_url( self_admin_url( 'about.php?updated' ) ) ) . '</span>' ); 495 495 show_message( '<span class="hide-if-js">' . sprintf( __( 'Welcome to WordPress %1$s. <a href="%2$s">Learn more</a>.' ), $result, esc_url( self_admin_url( 'about.php?updated' ) ) ) . '</span>' ); 496 496 ?> 497 497 </div> 498 498 <script type="text/javascript"> 499 499 window.location = '<?php echo self_admin_url( 'about.php?updated' ); ?>'; 500 500 </script> 501 501 <?php 502 502 } -
src/wp-includes/option.php
function set_site_transient( $transient, 1667 1667 do_action( 'set_site_transient_' . $transient, $value, $expiration, $transient ); 1668 1668 1669 1669 /** 1670 1670 * Fires after the value for a site transient has been set. 1671 1671 * 1672 1672 * @since 3.0.0 1673 1673 * 1674 1674 * @param string $transient The name of the site transient. 1675 1675 * @param mixed $value Site transient value. 1676 1676 * @param int $expiration Time until expiration in seconds. 1677 1677 */ 1678 1678 do_action( 'setted_site_transient', $transient, $value, $expiration ); 1679 1679 } 1680 1680 return $result; 1681 1681 } 1682 1683 /** 1684 * Create a Lock using WordPress options. 1685 * 1686 * @since 4.5.0 1687 * @param $lock_name string The name of this unique lock. 1688 * @param $release_timeout int The duration in seconds to respect an existing lock. Default: 1 hour. 1689 * @return bool 1690 */ 1691 function wp_create_lock( $lock_name, $release_timeout = null ) { 1692 global $wpdb; 1693 if ( ! $release_timeout ) { 1694 $release_timeout = HOUR_IN_SECONDS; 1695 } 1696 /** 1697 * Filter doc TODO 1698 */ 1699 if ( null !== ( $result = apply_filters( 'create_lock', null, $lock_name, $release_timeout ) ) ) { 1700 return $reslt; 1701 } 1702 1703 $lock_option = $lock_name . '.lock'; 1704 1705 // Try to lock 1706 $lock_result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO `$wpdb->options` ( `option_name`, `option_value`, `autoload` ) VALUES (%s, %s, 'no') /* LOCK */", $lock_option, time() ) ); 1707 1708 if ( ! $lock_result ) { 1709 $lock_result = get_option( $lock_option ); 1710 1711 // If we couldn't create a lock, and there isn't a lock, bail 1712 if ( ! $lock_result ) { 1713 return false; 1714 } 1715 1716 // Check to see if the lock is still valid 1717 if ( $lock_result > ( time() - $release_timeout ) ) { 1718 return false; 1719 } 1720 1721 // There must exist an expired lock, clear it and re-gain it. 1722 wp_release_lock( $lock_name ); 1723 1724 return wp_create_lock( $lock_name, $release_timeout ); 1725 } 1726 1727 // Update the lock, as by this point we've definitely got a lock, just need to fire the actions 1728 update_option( $lock_option, time() ); 1729 1730 return true; 1731 } 1732 1733 /** 1734 * Release a lock created by `wp_create_lock()` 1735 * 1736 * @since 4.5.0 1737 * @param $lock_name string The name of this unique lock. 1738 * @return bool 1739 */ 1740 function wp_release_lock( $lock_name ) { 1741 /** 1742 * Filter doc TODO 1743 */ 1744 if ( null !== ( $result = apply_filters( 'release_lock', null, $lock_name ) ) ) { 1745 return $reslt; 1746 } 1747 $lock_option = $lock_name . '.lock'; 1748 return delete_option( $lock_option ); 1749 } 1750 No newline at end of file