wp/wp-includes/update.php
changeset 16 a86126ab1dd4
parent 9 177826044cd9
child 18 be944660c56a
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
     7  */
     7  */
     8 
     8 
     9 /**
     9 /**
    10  * Check WordPress version against the newest version.
    10  * Check WordPress version against the newest version.
    11  *
    11  *
    12  * The WordPress version, PHP version, and Locale is sent. Checks against the
    12  * The WordPress version, PHP version, and locale is sent.
    13  * WordPress server at api.wordpress.org server. Will only check if WordPress
    13  *
    14  * isn't installing.
    14  * Checks against the WordPress server at api.wordpress.org. Will only check
       
    15  * if WordPress isn't installing.
    15  *
    16  *
    16  * @since 2.3.0
    17  * @since 2.3.0
    17  * @global string $wp_version Used to check against the newest WordPress version.
    18  *
    18  * @global wpdb   $wpdb
    19  * @global string $wp_version       Used to check against the newest WordPress version.
    19  * @global string $wp_local_package
    20  * @global wpdb   $wpdb             WordPress database abstraction object.
       
    21  * @global string $wp_local_package Locale code of the package.
    20  *
    22  *
    21  * @param array $extra_stats Extra statistics to report to the WordPress.org API.
    23  * @param array $extra_stats Extra statistics to report to the WordPress.org API.
    22  * @param bool  $force_check Whether to bypass the transient cache and force a fresh update check. Defaults to false, true if $extra_stats is set.
    24  * @param bool  $force_check Whether to bypass the transient cache and force a fresh update check. Defaults to false, true if $extra_stats is set.
    23  */
    25  */
    24 function wp_version_check( $extra_stats = array(), $force_check = false ) {
    26 function wp_version_check( $extra_stats = array(), $force_check = false ) {
       
    27 	global $wpdb, $wp_local_package;
       
    28 
    25 	if ( wp_installing() ) {
    29 	if ( wp_installing() ) {
    26 		return;
    30 		return;
    27 	}
    31 	}
    28 
    32 
    29 	global $wpdb, $wp_local_package;
    33 	// Include an unmodified $wp_version.
    30 	// include an unmodified $wp_version
    34 	require ABSPATH . WPINC . '/version.php';
    31 	include( ABSPATH . WPINC . '/version.php' );
       
    32 	$php_version = phpversion();
    35 	$php_version = phpversion();
    33 
    36 
    34 	$current      = get_site_transient( 'update_core' );
    37 	$current      = get_site_transient( 'update_core' );
    35 	$translations = wp_get_installed_translations( 'core' );
    38 	$translations = wp_get_installed_translations( 'core' );
    36 
    39 
    37 	// Invalidate the transient when $wp_version changes
    40 	// Invalidate the transient when $wp_version changes.
    38 	if ( is_object( $current ) && $wp_version != $current->version_checked ) {
    41 	if ( is_object( $current ) && $wp_version !== $current->version_checked ) {
    39 		$current = false;
    42 		$current = false;
    40 	}
    43 	}
    41 
    44 
    42 	if ( ! is_object( $current ) ) {
    45 	if ( ! is_object( $current ) ) {
    43 		$current                  = new stdClass;
    46 		$current                  = new stdClass;
    47 
    50 
    48 	if ( ! empty( $extra_stats ) ) {
    51 	if ( ! empty( $extra_stats ) ) {
    49 		$force_check = true;
    52 		$force_check = true;
    50 	}
    53 	}
    51 
    54 
    52 	// Wait 60 seconds between multiple version check requests
    55 	// Wait 1 minute between multiple version check requests.
    53 	$timeout          = 60;
    56 	$timeout          = MINUTE_IN_SECONDS;
    54 	$time_not_changed = isset( $current->last_checked ) && $timeout > ( time() - $current->last_checked );
    57 	$time_not_changed = isset( $current->last_checked ) && $timeout > ( time() - $current->last_checked );
       
    58 
    55 	if ( ! $force_check && $time_not_changed ) {
    59 	if ( ! $force_check && $time_not_changed ) {
    56 		return;
    60 		return;
    57 	}
    61 	}
    58 
    62 
    59 	/**
    63 	/**
    63 	 *
    67 	 *
    64 	 * @param string $locale Current locale.
    68 	 * @param string $locale Current locale.
    65 	 */
    69 	 */
    66 	$locale = apply_filters( 'core_version_check_locale', get_locale() );
    70 	$locale = apply_filters( 'core_version_check_locale', get_locale() );
    67 
    71 
    68 	// Update last_checked for current to prevent multiple blocking requests if request hangs
    72 	// Update last_checked for current to prevent multiple blocking requests if request hangs.
    69 	$current->last_checked = time();
    73 	$current->last_checked = time();
    70 	set_site_transient( 'update_core', $current );
    74 	set_site_transient( 'update_core', $current );
    71 
    75 
    72 	if ( method_exists( $wpdb, 'db_version' ) ) {
    76 	if ( method_exists( $wpdb, 'db_version' ) ) {
    73 		$mysql_version = preg_replace( '/[^0-9.].*/', '', $wpdb->db_version() );
    77 		$mysql_version = preg_replace( '/[^0-9.].*/', '', $wpdb->db_version() );
   130 
   134 
   131 	if ( is_array( $extra_stats ) ) {
   135 	if ( is_array( $extra_stats ) ) {
   132 		$post_body = array_merge( $post_body, $extra_stats );
   136 		$post_body = array_merge( $post_body, $extra_stats );
   133 	}
   137 	}
   134 
   138 
   135 	$url = $http_url = 'http://api.wordpress.org/core/version-check/1.7/?' . http_build_query( $query, null, '&' );
   139 	$url      = 'http://api.wordpress.org/core/version-check/1.7/?' . http_build_query( $query, null, '&' );
   136 	if ( $ssl = wp_http_supports( array( 'ssl' ) ) ) {
   140 	$http_url = $url;
       
   141 	$ssl      = wp_http_supports( array( 'ssl' ) );
       
   142 
       
   143 	if ( $ssl ) {
   137 		$url = set_url_scheme( $url, 'https' );
   144 		$url = set_url_scheme( $url, 'https' );
   138 	}
   145 	}
   139 
   146 
   140 	$doing_cron = wp_doing_cron();
   147 	$doing_cron = wp_doing_cron();
   141 
   148 
   148 		),
   155 		),
   149 		'body'       => $post_body,
   156 		'body'       => $post_body,
   150 	);
   157 	);
   151 
   158 
   152 	$response = wp_remote_post( $url, $options );
   159 	$response = wp_remote_post( $url, $options );
       
   160 
   153 	if ( $ssl && is_wp_error( $response ) ) {
   161 	if ( $ssl && is_wp_error( $response ) ) {
   154 		trigger_error(
   162 		trigger_error(
   155 			sprintf(
   163 			sprintf(
   156 				/* translators: %s: support forums URL */
   164 				/* translators: %s: Support forums URL. */
   157 				__( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ),
   165 				__( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ),
   158 				__( 'https://wordpress.org/support/' )
   166 				__( 'https://wordpress.org/support/forums/' )
   159 			) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ),
   167 			) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ),
   160 			headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE
   168 			headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE
   161 		);
   169 		);
   162 		$response = wp_remote_post( $http_url, $options );
   170 		$response = wp_remote_post( $http_url, $options );
   163 	}
   171 	}
   164 
   172 
   165 	if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) ) {
   173 	if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
   166 		return;
   174 		return;
   167 	}
   175 	}
   168 
   176 
   169 	$body = trim( wp_remote_retrieve_body( $response ) );
   177 	$body = trim( wp_remote_retrieve_body( $response ) );
   170 	$body = json_decode( $body, true );
   178 	$body = json_decode( $body, true );
   175 
   183 
   176 	$offers = $body['offers'];
   184 	$offers = $body['offers'];
   177 
   185 
   178 	foreach ( $offers as &$offer ) {
   186 	foreach ( $offers as &$offer ) {
   179 		foreach ( $offer as $offer_key => $value ) {
   187 		foreach ( $offer as $offer_key => $value ) {
   180 			if ( 'packages' == $offer_key ) {
   188 			if ( 'packages' === $offer_key ) {
   181 				$offer['packages'] = (object) array_intersect_key(
   189 				$offer['packages'] = (object) array_intersect_key(
   182 					array_map( 'esc_url', $offer['packages'] ),
   190 					array_map( 'esc_url', $offer['packages'] ),
   183 					array_fill_keys( array( 'full', 'no_content', 'new_bundled', 'partial', 'rollback' ), '' )
   191 					array_fill_keys( array( 'full', 'no_content', 'new_bundled', 'partial', 'rollback' ), '' )
   184 				);
   192 				);
   185 			} elseif ( 'download' == $offer_key ) {
   193 			} elseif ( 'download' === $offer_key ) {
   186 				$offer['download'] = esc_url( $value );
   194 				$offer['download'] = esc_url( $value );
   187 			} else {
   195 			} else {
   188 				$offer[ $offer_key ] = esc_html( $value );
   196 				$offer[ $offer_key ] = esc_html( $value );
   189 			}
   197 			}
   190 		}
   198 		}
   222 
   230 
   223 	set_site_transient( 'update_core', $updates );
   231 	set_site_transient( 'update_core', $updates );
   224 
   232 
   225 	if ( ! empty( $body['ttl'] ) ) {
   233 	if ( ! empty( $body['ttl'] ) ) {
   226 		$ttl = (int) $body['ttl'];
   234 		$ttl = (int) $body['ttl'];
       
   235 
   227 		if ( $ttl && ( time() + $ttl < wp_next_scheduled( 'wp_version_check' ) ) ) {
   236 		if ( $ttl && ( time() + $ttl < wp_next_scheduled( 'wp_version_check' ) ) ) {
   228 			// Queue an event to re-run the update check in $ttl seconds.
   237 			// Queue an event to re-run the update check in $ttl seconds.
   229 			wp_schedule_single_event( time() + $ttl, 'wp_version_check' );
   238 			wp_schedule_single_event( time() + $ttl, 'wp_version_check' );
   230 		}
   239 		}
   231 	}
   240 	}
   232 
   241 
   233 	// Trigger background updates if running non-interactively, and we weren't called from the update handler.
   242 	// Trigger background updates if running non-interactively, and we weren't called from the update handler.
   234 	if ( $doing_cron && ! doing_action( 'wp_maybe_auto_update' ) ) {
   243 	if ( $doing_cron && ! doing_action( 'wp_maybe_auto_update' ) ) {
   235 		/**
   244 		/**
   236 		 * Fires during wp_cron, starting the auto update process.
   245 		 * Fires during wp_cron, starting the auto-update process.
   237 		 *
   246 		 *
   238 		 * @since 3.9.0
   247 		 * @since 3.9.0
   239 		 */
   248 		 */
   240 		do_action( 'wp_maybe_auto_update' );
   249 		do_action( 'wp_maybe_auto_update' );
   241 	}
   250 	}
   242 }
   251 }
   243 
   252 
   244 /**
   253 /**
   245  * Check plugin versions against the latest versions hosted on WordPress.org.
   254  * Checks for available updates to plugins based on the latest versions hosted on WordPress.org.
   246  *
   255  *
   247  * The WordPress version, PHP version, and Locale is sent along with a list of
   256  * Despite its name this function does not actually perform any updates, it only checks for available updates.
   248  * all plugins installed. Checks against the WordPress server at
   257  *
   249  * api.wordpress.org. Will only check if WordPress isn't installing.
   258  * A list of all plugins installed is sent to WP, along with the site locale.
       
   259  *
       
   260  * Checks against the WordPress server at api.wordpress.org. Will only check
       
   261  * if WordPress isn't installing.
   250  *
   262  *
   251  * @since 2.3.0
   263  * @since 2.3.0
   252  * @global string $wp_version Used to notify the WordPress version.
   264  *
       
   265  * @global string $wp_version The WordPress version string.
   253  *
   266  *
   254  * @param array $extra_stats Extra statistics to report to the WordPress.org API.
   267  * @param array $extra_stats Extra statistics to report to the WordPress.org API.
   255  */
   268  */
   256 function wp_update_plugins( $extra_stats = array() ) {
   269 function wp_update_plugins( $extra_stats = array() ) {
   257 	if ( wp_installing() ) {
   270 	if ( wp_installing() ) {
   258 		return;
   271 		return;
   259 	}
   272 	}
   260 
   273 
   261 	// include an unmodified $wp_version
   274 	// Include an unmodified $wp_version.
   262 	include( ABSPATH . WPINC . '/version.php' );
   275 	require ABSPATH . WPINC . '/version.php';
   263 
   276 
   264 	// If running blog-side, bail unless we've not checked in the last 12 hours
   277 	// If running blog-side, bail unless we've not checked in the last 12 hours.
   265 	if ( ! function_exists( 'get_plugins' ) ) {
   278 	if ( ! function_exists( 'get_plugins' ) ) {
   266 		require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
   279 		require_once ABSPATH . 'wp-admin/includes/plugin.php';
   267 	}
   280 	}
   268 
   281 
   269 	$plugins      = get_plugins();
   282 	$plugins      = get_plugins();
   270 	$translations = wp_get_installed_translations( 'plugins' );
   283 	$translations = wp_get_installed_translations( 'plugins' );
   271 
   284 
   272 	$active  = get_option( 'active_plugins', array() );
   285 	$active  = get_option( 'active_plugins', array() );
   273 	$current = get_site_transient( 'update_plugins' );
   286 	$current = get_site_transient( 'update_plugins' );
       
   287 
   274 	if ( ! is_object( $current ) ) {
   288 	if ( ! is_object( $current ) ) {
   275 		$current = new stdClass;
   289 		$current = new stdClass;
   276 	}
   290 	}
   277 
   291 
   278 	$new_option               = new stdClass;
   292 	$new_option               = new stdClass;
   302 
   316 
   303 	$time_not_changed = isset( $current->last_checked ) && $timeout > ( time() - $current->last_checked );
   317 	$time_not_changed = isset( $current->last_checked ) && $timeout > ( time() - $current->last_checked );
   304 
   318 
   305 	if ( $time_not_changed && ! $extra_stats ) {
   319 	if ( $time_not_changed && ! $extra_stats ) {
   306 		$plugin_changed = false;
   320 		$plugin_changed = false;
       
   321 
   307 		foreach ( $plugins as $file => $p ) {
   322 		foreach ( $plugins as $file => $p ) {
   308 			$new_option->checked[ $file ] = $p['Version'];
   323 			$new_option->checked[ $file ] = $p['Version'];
   309 
   324 
   310 			if ( ! isset( $current->checked[ $file ] ) || strval( $current->checked[ $file ] ) !== strval( $p['Version'] ) ) {
   325 			if ( ! isset( $current->checked[ $file ] ) || strval( $current->checked[ $file ] ) !== strval( $p['Version'] ) ) {
   311 				$plugin_changed = true;
   326 				$plugin_changed = true;
   319 					break;
   334 					break;
   320 				}
   335 				}
   321 			}
   336 			}
   322 		}
   337 		}
   323 
   338 
   324 		// Bail if we've checked recently and if nothing has changed
   339 		// Bail if we've checked recently and if nothing has changed.
   325 		if ( ! $plugin_changed ) {
   340 		if ( ! $plugin_changed ) {
   326 			return;
   341 			return;
   327 		}
   342 		}
   328 	}
   343 	}
   329 
   344 
   330 	// Update last_checked for current to prevent multiple blocking requests if request hangs
   345 	// Update last_checked for current to prevent multiple blocking requests if request hangs.
   331 	$current->last_checked = time();
   346 	$current->last_checked = time();
   332 	set_site_transient( 'update_plugins', $current );
   347 	set_site_transient( 'update_plugins', $current );
   333 
   348 
   334 	$to_send = compact( 'plugins', 'active' );
   349 	$to_send = compact( 'plugins', 'active' );
   335 
   350 
   347 	$locales = array_unique( $locales );
   362 	$locales = array_unique( $locales );
   348 
   363 
   349 	if ( $doing_cron ) {
   364 	if ( $doing_cron ) {
   350 		$timeout = 30;
   365 		$timeout = 30;
   351 	} else {
   366 	} else {
   352 		// Three seconds, plus one extra second for every 10 plugins
   367 		// Three seconds, plus one extra second for every 10 plugins.
   353 		$timeout = 3 + (int) ( count( $plugins ) / 10 );
   368 		$timeout = 3 + (int) ( count( $plugins ) / 10 );
   354 	}
   369 	}
   355 
   370 
   356 	$options = array(
   371 	$options = array(
   357 		'timeout'    => $timeout,
   372 		'timeout'    => $timeout,
   366 
   381 
   367 	if ( $extra_stats ) {
   382 	if ( $extra_stats ) {
   368 		$options['body']['update_stats'] = wp_json_encode( $extra_stats );
   383 		$options['body']['update_stats'] = wp_json_encode( $extra_stats );
   369 	}
   384 	}
   370 
   385 
   371 	$url = $http_url = 'http://api.wordpress.org/plugins/update-check/1.1/';
   386 	$url      = 'http://api.wordpress.org/plugins/update-check/1.1/';
   372 	if ( $ssl = wp_http_supports( array( 'ssl' ) ) ) {
   387 	$http_url = $url;
       
   388 	$ssl      = wp_http_supports( array( 'ssl' ) );
       
   389 
       
   390 	if ( $ssl ) {
   373 		$url = set_url_scheme( $url, 'https' );
   391 		$url = set_url_scheme( $url, 'https' );
   374 	}
   392 	}
   375 
   393 
   376 	$raw_response = wp_remote_post( $url, $options );
   394 	$raw_response = wp_remote_post( $url, $options );
       
   395 
   377 	if ( $ssl && is_wp_error( $raw_response ) ) {
   396 	if ( $ssl && is_wp_error( $raw_response ) ) {
   378 		trigger_error(
   397 		trigger_error(
   379 			sprintf(
   398 			sprintf(
   380 				/* translators: %s: support forums URL */
   399 				/* translators: %s: Support forums URL. */
   381 				__( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ),
   400 				__( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ),
   382 				__( 'https://wordpress.org/support/' )
   401 				__( 'https://wordpress.org/support/forums/' )
   383 			) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ),
   402 			) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ),
   384 			headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE
   403 			headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE
   385 		);
   404 		);
   386 		$raw_response = wp_remote_post( $http_url, $options );
   405 		$raw_response = wp_remote_post( $http_url, $options );
   387 	}
   406 	}
   388 
   407 
   389 	if ( is_wp_error( $raw_response ) || 200 != wp_remote_retrieve_response_code( $raw_response ) ) {
   408 	if ( is_wp_error( $raw_response ) || 200 !== wp_remote_retrieve_response_code( $raw_response ) ) {
   390 		return;
   409 		return;
   391 	}
   410 	}
   392 
   411 
   393 	$response = json_decode( wp_remote_retrieve_body( $raw_response ), true );
   412 	$response = json_decode( wp_remote_retrieve_body( $raw_response ), true );
       
   413 
   394 	foreach ( $response['plugins'] as &$plugin ) {
   414 	foreach ( $response['plugins'] as &$plugin ) {
   395 		$plugin = (object) $plugin;
   415 		$plugin = (object) $plugin;
       
   416 
   396 		if ( isset( $plugin->compatibility ) ) {
   417 		if ( isset( $plugin->compatibility ) ) {
   397 			$plugin->compatibility = (object) $plugin->compatibility;
   418 			$plugin->compatibility = (object) $plugin->compatibility;
       
   419 
   398 			foreach ( $plugin->compatibility as &$data ) {
   420 			foreach ( $plugin->compatibility as &$data ) {
   399 				$data = (object) $data;
   421 				$data = (object) $data;
   400 			}
   422 			}
   401 		}
   423 		}
   402 	}
   424 	}
       
   425 
   403 	unset( $plugin, $data );
   426 	unset( $plugin, $data );
       
   427 
   404 	foreach ( $response['no_update'] as &$plugin ) {
   428 	foreach ( $response['no_update'] as &$plugin ) {
   405 		$plugin = (object) $plugin;
   429 		$plugin = (object) $plugin;
   406 	}
   430 	}
       
   431 
   407 	unset( $plugin );
   432 	unset( $plugin );
   408 
   433 
   409 	if ( is_array( $response ) ) {
   434 	if ( is_array( $response ) ) {
   410 		$new_option->response     = $response['plugins'];
   435 		$new_option->response     = $response['plugins'];
   411 		$new_option->translations = $response['translations'];
   436 		$new_option->translations = $response['translations'];
   419 
   444 
   420 	set_site_transient( 'update_plugins', $new_option );
   445 	set_site_transient( 'update_plugins', $new_option );
   421 }
   446 }
   422 
   447 
   423 /**
   448 /**
   424  * Check theme versions against the latest versions hosted on WordPress.org.
   449  * Checks for available updates to themes based on the latest versions hosted on WordPress.org.
   425  *
   450  *
   426  * A list of all themes installed in sent to WP. Checks against the
   451  * Despite its name this function does not actually perform any updates, it only checks for available updates.
   427  * WordPress server at api.wordpress.org. Will only check if WordPress isn't
   452  *
   428  * installing.
   453  * A list of all themes installed is sent to WP, along with the site locale.
       
   454  *
       
   455  * Checks against the WordPress server at api.wordpress.org. Will only check
       
   456  * if WordPress isn't installing.
   429  *
   457  *
   430  * @since 2.7.0
   458  * @since 2.7.0
       
   459  *
       
   460  * @global string $wp_version The WordPress version string.
   431  *
   461  *
   432  * @param array $extra_stats Extra statistics to report to the WordPress.org API.
   462  * @param array $extra_stats Extra statistics to report to the WordPress.org API.
   433  */
   463  */
   434 function wp_update_themes( $extra_stats = array() ) {
   464 function wp_update_themes( $extra_stats = array() ) {
   435 	if ( wp_installing() ) {
   465 	if ( wp_installing() ) {
   436 		return;
   466 		return;
   437 	}
   467 	}
   438 
   468 
   439 	// include an unmodified $wp_version
   469 	// Include an unmodified $wp_version.
   440 	include( ABSPATH . WPINC . '/version.php' );
   470 	require ABSPATH . WPINC . '/version.php';
   441 
   471 
   442 	$installed_themes = wp_get_themes();
   472 	$installed_themes = wp_get_themes();
   443 	$translations     = wp_get_installed_translations( 'themes' );
   473 	$translations     = wp_get_installed_translations( 'themes' );
   444 
   474 
   445 	$last_update = get_site_transient( 'update_themes' );
   475 	$last_update = get_site_transient( 'update_themes' );
       
   476 
   446 	if ( ! is_object( $last_update ) ) {
   477 	if ( ! is_object( $last_update ) ) {
   447 		$last_update = new stdClass;
   478 		$last_update = new stdClass;
   448 	}
   479 	}
   449 
   480 
   450 	$themes = $checked = $request = array();
   481 	$themes  = array();
       
   482 	$checked = array();
       
   483 	$request = array();
   451 
   484 
   452 	// Put slug of current theme into request.
   485 	// Put slug of current theme into request.
   453 	$request['active'] = get_option( 'stylesheet' );
   486 	$request['active'] = get_option( 'stylesheet' );
   454 
   487 
   455 	foreach ( $installed_themes as $theme ) {
   488 	foreach ( $installed_themes as $theme ) {
   490 
   523 
   491 	$time_not_changed = isset( $last_update->last_checked ) && $timeout > ( time() - $last_update->last_checked );
   524 	$time_not_changed = isset( $last_update->last_checked ) && $timeout > ( time() - $last_update->last_checked );
   492 
   525 
   493 	if ( $time_not_changed && ! $extra_stats ) {
   526 	if ( $time_not_changed && ! $extra_stats ) {
   494 		$theme_changed = false;
   527 		$theme_changed = false;
       
   528 
   495 		foreach ( $checked as $slug => $v ) {
   529 		foreach ( $checked as $slug => $v ) {
   496 			if ( ! isset( $last_update->checked[ $slug ] ) || strval( $last_update->checked[ $slug ] ) !== strval( $v ) ) {
   530 			if ( ! isset( $last_update->checked[ $slug ] ) || strval( $last_update->checked[ $slug ] ) !== strval( $v ) ) {
   497 				$theme_changed = true;
   531 				$theme_changed = true;
   498 			}
   532 			}
   499 		}
   533 		}
   505 					break;
   539 					break;
   506 				}
   540 				}
   507 			}
   541 			}
   508 		}
   542 		}
   509 
   543 
   510 		// Bail if we've checked recently and if nothing has changed
   544 		// Bail if we've checked recently and if nothing has changed.
   511 		if ( ! $theme_changed ) {
   545 		if ( ! $theme_changed ) {
   512 			return;
   546 			return;
   513 		}
   547 		}
   514 	}
   548 	}
   515 
   549 
   516 	// Update last_checked for current to prevent multiple blocking requests if request hangs
   550 	// Update last_checked for current to prevent multiple blocking requests if request hangs.
   517 	$last_update->last_checked = time();
   551 	$last_update->last_checked = time();
   518 	set_site_transient( 'update_themes', $last_update );
   552 	set_site_transient( 'update_themes', $last_update );
   519 
   553 
   520 	$request['themes'] = $themes;
   554 	$request['themes'] = $themes;
   521 
   555 
   533 	$locales = array_unique( $locales );
   567 	$locales = array_unique( $locales );
   534 
   568 
   535 	if ( $doing_cron ) {
   569 	if ( $doing_cron ) {
   536 		$timeout = 30;
   570 		$timeout = 30;
   537 	} else {
   571 	} else {
   538 		// Three seconds, plus one extra second for every 10 themes
   572 		// Three seconds, plus one extra second for every 10 themes.
   539 		$timeout = 3 + (int) ( count( $themes ) / 10 );
   573 		$timeout = 3 + (int) ( count( $themes ) / 10 );
   540 	}
   574 	}
   541 
   575 
   542 	$options = array(
   576 	$options = array(
   543 		'timeout'    => $timeout,
   577 		'timeout'    => $timeout,
   551 
   585 
   552 	if ( $extra_stats ) {
   586 	if ( $extra_stats ) {
   553 		$options['body']['update_stats'] = wp_json_encode( $extra_stats );
   587 		$options['body']['update_stats'] = wp_json_encode( $extra_stats );
   554 	}
   588 	}
   555 
   589 
   556 	$url = $http_url = 'http://api.wordpress.org/themes/update-check/1.1/';
   590 	$url      = 'http://api.wordpress.org/themes/update-check/1.1/';
   557 	if ( $ssl = wp_http_supports( array( 'ssl' ) ) ) {
   591 	$http_url = $url;
       
   592 	$ssl      = wp_http_supports( array( 'ssl' ) );
       
   593 
       
   594 	if ( $ssl ) {
   558 		$url = set_url_scheme( $url, 'https' );
   595 		$url = set_url_scheme( $url, 'https' );
   559 	}
   596 	}
   560 
   597 
   561 	$raw_response = wp_remote_post( $url, $options );
   598 	$raw_response = wp_remote_post( $url, $options );
       
   599 
   562 	if ( $ssl && is_wp_error( $raw_response ) ) {
   600 	if ( $ssl && is_wp_error( $raw_response ) ) {
   563 		trigger_error(
   601 		trigger_error(
   564 			sprintf(
   602 			sprintf(
   565 				/* translators: %s: support forums URL */
   603 				/* translators: %s: Support forums URL. */
   566 				__( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ),
   604 				__( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ),
   567 				__( 'https://wordpress.org/support/' )
   605 				__( 'https://wordpress.org/support/forums/' )
   568 			) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ),
   606 			) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ),
   569 			headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE
   607 			headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE
   570 		);
   608 		);
   571 		$raw_response = wp_remote_post( $http_url, $options );
   609 		$raw_response = wp_remote_post( $http_url, $options );
   572 	}
   610 	}
   573 
   611 
   574 	if ( is_wp_error( $raw_response ) || 200 != wp_remote_retrieve_response_code( $raw_response ) ) {
   612 	if ( is_wp_error( $raw_response ) || 200 !== wp_remote_retrieve_response_code( $raw_response ) ) {
   575 		return;
   613 		return;
   576 	}
   614 	}
   577 
   615 
   578 	$new_update               = new stdClass;
   616 	$new_update               = new stdClass;
   579 	$new_update->last_checked = time();
   617 	$new_update->last_checked = time();
   581 
   619 
   582 	$response = json_decode( wp_remote_retrieve_body( $raw_response ), true );
   620 	$response = json_decode( wp_remote_retrieve_body( $raw_response ), true );
   583 
   621 
   584 	if ( is_array( $response ) ) {
   622 	if ( is_array( $response ) ) {
   585 		$new_update->response     = $response['themes'];
   623 		$new_update->response     = $response['themes'];
       
   624 		$new_update->no_update    = $response['no_update'];
   586 		$new_update->translations = $response['translations'];
   625 		$new_update->translations = $response['translations'];
   587 	}
   626 	}
   588 
   627 
   589 	set_site_transient( 'update_themes', $new_update );
   628 	set_site_transient( 'update_themes', $new_update );
   590 }
   629 }
   591 
   630 
   592 /**
   631 /**
   593  * Performs WordPress automatic background updates.
   632  * Performs WordPress automatic background updates.
   594  *
   633  *
       
   634  * Updates WordPress core plus any plugins and themes that have automatic updates enabled.
       
   635  *
   595  * @since 3.7.0
   636  * @since 3.7.0
   596  */
   637  */
   597 function wp_maybe_auto_update() {
   638 function wp_maybe_auto_update() {
   598 	include_once( ABSPATH . 'wp-admin/includes/admin.php' );
   639 	include_once ABSPATH . 'wp-admin/includes/admin.php';
   599 	include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
   640 	require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
   600 
   641 
   601 	$upgrader = new WP_Automatic_Updater;
   642 	$upgrader = new WP_Automatic_Updater;
   602 	$upgrader->run();
   643 	$upgrader->run();
   603 }
   644 }
   604 
   645 
   614 	$transients = array(
   655 	$transients = array(
   615 		'update_core'    => 'core',
   656 		'update_core'    => 'core',
   616 		'update_plugins' => 'plugin',
   657 		'update_plugins' => 'plugin',
   617 		'update_themes'  => 'theme',
   658 		'update_themes'  => 'theme',
   618 	);
   659 	);
       
   660 
   619 	foreach ( $transients as $transient => $type ) {
   661 	foreach ( $transients as $transient => $type ) {
   620 		$transient = get_site_transient( $transient );
   662 		$transient = get_site_transient( $transient );
       
   663 
   621 		if ( empty( $transient->translations ) ) {
   664 		if ( empty( $transient->translations ) ) {
   622 			continue;
   665 			continue;
   623 		}
   666 		}
   624 
   667 
   625 		foreach ( $transient->translations as $translation ) {
   668 		foreach ( $transient->translations as $translation ) {
   626 			$updates[] = (object) $translation;
   669 			$updates[] = (object) $translation;
   627 		}
   670 		}
   628 	}
   671 	}
       
   672 
   629 	return $updates;
   673 	return $updates;
   630 }
   674 }
   631 
   675 
   632 /**
   676 /**
   633  * Collect counts and UI strings for available updates
   677  * Collect counts and UI strings for available updates
   642 		'themes'       => 0,
   686 		'themes'       => 0,
   643 		'wordpress'    => 0,
   687 		'wordpress'    => 0,
   644 		'translations' => 0,
   688 		'translations' => 0,
   645 	);
   689 	);
   646 
   690 
   647 	if ( $plugins = current_user_can( 'update_plugins' ) ) {
   691 	$plugins = current_user_can( 'update_plugins' );
       
   692 
       
   693 	if ( $plugins ) {
   648 		$update_plugins = get_site_transient( 'update_plugins' );
   694 		$update_plugins = get_site_transient( 'update_plugins' );
       
   695 
   649 		if ( ! empty( $update_plugins->response ) ) {
   696 		if ( ! empty( $update_plugins->response ) ) {
   650 			$counts['plugins'] = count( $update_plugins->response );
   697 			$counts['plugins'] = count( $update_plugins->response );
   651 		}
   698 		}
   652 	}
   699 	}
   653 
   700 
   654 	if ( $themes = current_user_can( 'update_themes' ) ) {
   701 	$themes = current_user_can( 'update_themes' );
       
   702 
       
   703 	if ( $themes ) {
   655 		$update_themes = get_site_transient( 'update_themes' );
   704 		$update_themes = get_site_transient( 'update_themes' );
       
   705 
   656 		if ( ! empty( $update_themes->response ) ) {
   706 		if ( ! empty( $update_themes->response ) ) {
   657 			$counts['themes'] = count( $update_themes->response );
   707 			$counts['themes'] = count( $update_themes->response );
   658 		}
   708 		}
   659 	}
   709 	}
   660 
   710 
   661 	if ( ( $core = current_user_can( 'update_core' ) ) && function_exists( 'get_core_updates' ) ) {
   711 	$core = current_user_can( 'update_core' );
       
   712 
       
   713 	if ( $core && function_exists( 'get_core_updates' ) ) {
   662 		$update_wordpress = get_core_updates( array( 'dismissed' => false ) );
   714 		$update_wordpress = get_core_updates( array( 'dismissed' => false ) );
   663 		if ( ! empty( $update_wordpress ) && ! in_array( $update_wordpress[0]->response, array( 'development', 'latest' ) ) && current_user_can( 'update_core' ) ) {
   715 
       
   716 		if ( ! empty( $update_wordpress )
       
   717 			&& ! in_array( $update_wordpress[0]->response, array( 'development', 'latest' ), true )
       
   718 			&& current_user_can( 'update_core' )
       
   719 		) {
   664 			$counts['wordpress'] = 1;
   720 			$counts['wordpress'] = 1;
   665 		}
   721 		}
   666 	}
   722 	}
   667 
   723 
   668 	if ( ( $core || $plugins || $themes ) && wp_get_translation_updates() ) {
   724 	if ( ( $core || $plugins || $themes ) && wp_get_translation_updates() ) {
   669 		$counts['translations'] = 1;
   725 		$counts['translations'] = 1;
   670 	}
   726 	}
   671 
   727 
   672 	$counts['total'] = $counts['plugins'] + $counts['themes'] + $counts['wordpress'] + $counts['translations'];
   728 	$counts['total'] = $counts['plugins'] + $counts['themes'] + $counts['wordpress'] + $counts['translations'];
   673 	$titles          = array();
   729 	$titles          = array();
       
   730 
   674 	if ( $counts['wordpress'] ) {
   731 	if ( $counts['wordpress'] ) {
   675 		/* translators: %d: number of updates available to WordPress */
   732 		/* translators: %d: Number of available WordPress updates. */
   676 		$titles['wordpress'] = sprintf( __( '%d WordPress Update' ), $counts['wordpress'] );
   733 		$titles['wordpress'] = sprintf( __( '%d WordPress Update' ), $counts['wordpress'] );
   677 	}
   734 	}
       
   735 
   678 	if ( $counts['plugins'] ) {
   736 	if ( $counts['plugins'] ) {
   679 		/* translators: %d: number of updates available to plugins */
   737 		/* translators: %d: Number of available plugin updates. */
   680 		$titles['plugins'] = sprintf( _n( '%d Plugin Update', '%d Plugin Updates', $counts['plugins'] ), $counts['plugins'] );
   738 		$titles['plugins'] = sprintf( _n( '%d Plugin Update', '%d Plugin Updates', $counts['plugins'] ), $counts['plugins'] );
   681 	}
   739 	}
       
   740 
   682 	if ( $counts['themes'] ) {
   741 	if ( $counts['themes'] ) {
   683 		/* translators: %d: number of updates available to themes */
   742 		/* translators: %d: Number of available theme updates. */
   684 		$titles['themes'] = sprintf( _n( '%d Theme Update', '%d Theme Updates', $counts['themes'] ), $counts['themes'] );
   743 		$titles['themes'] = sprintf( _n( '%d Theme Update', '%d Theme Updates', $counts['themes'] ), $counts['themes'] );
   685 	}
   744 	}
       
   745 
   686 	if ( $counts['translations'] ) {
   746 	if ( $counts['translations'] ) {
   687 		$titles['translations'] = __( 'Translation Updates' );
   747 		$titles['translations'] = __( 'Translation Updates' );
   688 	}
   748 	}
   689 
   749 
   690 	$update_title = $titles ? esc_attr( implode( ', ', $titles ) ) : '';
   750 	$update_title = $titles ? esc_attr( implode( ', ', $titles ) ) : '';
   712 /**
   772 /**
   713  * Determines whether core should be updated.
   773  * Determines whether core should be updated.
   714  *
   774  *
   715  * @since 2.8.0
   775  * @since 2.8.0
   716  *
   776  *
   717  * @global string $wp_version
   777  * @global string $wp_version The WordPress version string.
   718  */
   778  */
   719 function _maybe_update_core() {
   779 function _maybe_update_core() {
   720 	// include an unmodified $wp_version
   780 	// Include an unmodified $wp_version.
   721 	include( ABSPATH . WPINC . '/version.php' );
   781 	require ABSPATH . WPINC . '/version.php';
   722 
   782 
   723 	$current = get_site_transient( 'update_core' );
   783 	$current = get_site_transient( 'update_core' );
   724 
   784 
   725 	if ( isset( $current->last_checked, $current->version_checked ) &&
   785 	if ( isset( $current->last_checked, $current->version_checked )
   726 		12 * HOUR_IN_SECONDS > ( time() - $current->last_checked ) &&
   786 		&& 12 * HOUR_IN_SECONDS > ( time() - $current->last_checked )
   727 		$current->version_checked == $wp_version ) {
   787 		&& $current->version_checked === $wp_version
   728 		return;
   788 	) {
   729 	}
   789 		return;
       
   790 	}
       
   791 
   730 	wp_version_check();
   792 	wp_version_check();
   731 }
   793 }
   732 /**
   794 /**
   733  * Check the last time plugins were run before checking plugin versions.
   795  * Check the last time plugins were run before checking plugin versions.
   734  *
   796  *
   739  * @since 2.7.0
   801  * @since 2.7.0
   740  * @access private
   802  * @access private
   741  */
   803  */
   742 function _maybe_update_plugins() {
   804 function _maybe_update_plugins() {
   743 	$current = get_site_transient( 'update_plugins' );
   805 	$current = get_site_transient( 'update_plugins' );
   744 	if ( isset( $current->last_checked ) && 12 * HOUR_IN_SECONDS > ( time() - $current->last_checked ) ) {
   806 
   745 		return;
   807 	if ( isset( $current->last_checked )
   746 	}
   808 		&& 12 * HOUR_IN_SECONDS > ( time() - $current->last_checked )
       
   809 	) {
       
   810 		return;
       
   811 	}
       
   812 
   747 	wp_update_plugins();
   813 	wp_update_plugins();
   748 }
   814 }
   749 
   815 
   750 /**
   816 /**
   751  * Check themes versions only after a duration of time.
   817  * Check themes versions only after a duration of time.
   756  * @since 2.7.0
   822  * @since 2.7.0
   757  * @access private
   823  * @access private
   758  */
   824  */
   759 function _maybe_update_themes() {
   825 function _maybe_update_themes() {
   760 	$current = get_site_transient( 'update_themes' );
   826 	$current = get_site_transient( 'update_themes' );
   761 	if ( isset( $current->last_checked ) && 12 * HOUR_IN_SECONDS > ( time() - $current->last_checked ) ) {
   827 
   762 		return;
   828 	if ( isset( $current->last_checked )
   763 	}
   829 		&& 12 * HOUR_IN_SECONDS > ( time() - $current->last_checked )
       
   830 	) {
       
   831 		return;
       
   832 	}
       
   833 
   764 	wp_update_themes();
   834 	wp_update_themes();
   765 }
   835 }
   766 
   836 
   767 /**
   837 /**
   768  * Schedule core, theme, and plugin update checks.
   838  * Schedule core, theme, and plugin update checks.
   792 	if ( function_exists( 'wp_clean_plugins_cache' ) ) {
   862 	if ( function_exists( 'wp_clean_plugins_cache' ) ) {
   793 		wp_clean_plugins_cache();
   863 		wp_clean_plugins_cache();
   794 	} else {
   864 	} else {
   795 		delete_site_transient( 'update_plugins' );
   865 		delete_site_transient( 'update_plugins' );
   796 	}
   866 	}
       
   867 
   797 	wp_clean_themes_cache();
   868 	wp_clean_themes_cache();
       
   869 
   798 	delete_site_transient( 'update_core' );
   870 	delete_site_transient( 'update_core' );
   799 }
   871 }
   800 
   872 
   801 if ( ( ! is_main_site() && ! is_network_admin() ) || wp_doing_ajax() ) {
   873 if ( ( ! is_main_site() && ! is_network_admin() ) || wp_doing_ajax() ) {
   802 	return;
   874 	return;