wp/wp-includes/update.php
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
    12  * The WordPress version, PHP version, and Locale is sent. Checks against the
    12  * The WordPress version, PHP version, and Locale is sent. Checks against the
    13  * WordPress server at api.wordpress.org server. Will only check if WordPress
    13  * WordPress server at api.wordpress.org server. Will only check if WordPress
    14  * isn't installing.
    14  * isn't installing.
    15  *
    15  *
    16  * @since 2.3.0
    16  * @since 2.3.0
    17  * @uses $wp_version Used to check against the newest WordPress version.
    17  * @global string $wp_version Used to check against the newest WordPress version.
       
    18  * @global wpdb   $wpdb
       
    19  * @global string $wp_local_package
    18  *
    20  *
    19  * @param array $extra_stats Extra statistics to report to the WordPress.org API.
    21  * @param array $extra_stats Extra statistics to report to the WordPress.org API.
    20  * @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.
    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.
    21  * @return null|false Returns null if update is unsupported. Returns false if check is too soon.
       
    22  */
    23  */
    23 function wp_version_check( $extra_stats = array(), $force_check = false ) {
    24 function wp_version_check( $extra_stats = array(), $force_check = false ) {
    24 	if ( defined('WP_INSTALLING') )
    25 	if ( wp_installing() ) {
    25 		return;
    26 		return;
       
    27 	}
    26 
    28 
    27 	global $wpdb, $wp_local_package;
    29 	global $wpdb, $wp_local_package;
    28 	include( ABSPATH . WPINC . '/version.php' ); // include an unmodified $wp_version
    30 	// include an unmodified $wp_version
       
    31 	include( ABSPATH . WPINC . '/version.php' );
    29 	$php_version = phpversion();
    32 	$php_version = phpversion();
    30 
    33 
    31 	$current = get_site_transient( 'update_core' );
    34 	$current = get_site_transient( 'update_core' );
    32 	$translations = wp_get_installed_translations( 'core' );
    35 	$translations = wp_get_installed_translations( 'core' );
    33 
    36 
    45 		$force_check = true;
    48 		$force_check = true;
    46 
    49 
    47 	// Wait 60 seconds between multiple version check requests
    50 	// Wait 60 seconds between multiple version check requests
    48 	$timeout = 60;
    51 	$timeout = 60;
    49 	$time_not_changed = isset( $current->last_checked ) && $timeout > ( time() - $current->last_checked );
    52 	$time_not_changed = isset( $current->last_checked ) && $timeout > ( time() - $current->last_checked );
    50 	if ( ! $force_check && $time_not_changed )
    53 	if ( ! $force_check && $time_not_changed ) {
    51 		return false;
    54 		return;
    52 
    55 	}
    53 	$locale = get_locale();
    56 
    54 	/**
    57 	/**
    55 	 * Filter the locale requested for WordPress core translations.
    58 	 * Filters the locale requested for WordPress core translations.
    56 	 *
    59 	 *
    57 	 * @since 2.8.0
    60 	 * @since 2.8.0
    58 	 *
    61 	 *
    59 	 * @param string $locale Current locale.
    62 	 * @param string $locale Current locale.
    60 	 */
    63 	 */
    61 	$locale = apply_filters( 'core_version_check_locale', $locale );
    64 	$locale = apply_filters( 'core_version_check_locale', get_locale() );
    62 
    65 
    63 	// Update last_checked for current to prevent multiple blocking requests if request hangs
    66 	// Update last_checked for current to prevent multiple blocking requests if request hangs
    64 	$current->last_checked = time();
    67 	$current->last_checked = time();
    65 	set_site_transient( 'update_core', $current );
    68 	set_site_transient( 'update_core', $current );
    66 
    69 
    81 		$num_blogs = 1;
    84 		$num_blogs = 1;
    82 		$wp_install = home_url( '/' );
    85 		$wp_install = home_url( '/' );
    83 	}
    86 	}
    84 
    87 
    85 	$query = array(
    88 	$query = array(
    86 		'version'           => $wp_version,
    89 		'version'            => $wp_version,
    87 		'php'               => $php_version,
    90 		'php'                => $php_version,
    88 		'locale'            => $locale,
    91 		'locale'             => $locale,
    89 		'mysql'             => $mysql_version,
    92 		'mysql'              => $mysql_version,
    90 		'local_package'     => isset( $wp_local_package ) ? $wp_local_package : '',
    93 		'local_package'      => isset( $wp_local_package ) ? $wp_local_package : '',
    91 		'blogs'             => $num_blogs,
    94 		'blogs'              => $num_blogs,
    92 		'users'             => $user_count,
    95 		'users'              => $user_count,
    93 		'multisite_enabled' => $multisite_enabled,
    96 		'multisite_enabled'  => $multisite_enabled,
       
    97 		'initial_db_version' => get_site_option( 'initial_db_version' ),
    94 	);
    98 	);
       
    99 
       
   100 	/**
       
   101 	 * Filter the query arguments sent as part of the core version check.
       
   102 	 *
       
   103 	 * WARNING: Changing this data may result in your site not receiving security updates.
       
   104 	 * Please exercise extreme caution.
       
   105 	 *
       
   106 	 * @since 4.9.0
       
   107 	 *
       
   108 	 * @param array $query {
       
   109 	 *     Version check query arguments. 
       
   110 	 *
       
   111 	 *     @type string $version            WordPress version number.
       
   112 	 *     @type string $php                PHP version number.
       
   113 	 *     @type string $locale             The locale to retrieve updates for.
       
   114 	 *     @type string $mysql              MySQL version number.
       
   115 	 *     @type string $local_package      The value of the $wp_local_package global, when set.
       
   116 	 *     @type int    $blogs              Number of sites on this WordPress installation.
       
   117 	 *     @type int    $users              Number of users on this WordPress installation.
       
   118 	 *     @type int    $multisite_enabled  Whether this WordPress installation uses Multisite.
       
   119 	 *     @type int    $initial_db_version Database version of WordPress at time of installation.
       
   120 	 * }
       
   121 	 */
       
   122 	$query = apply_filters( 'core_version_check_query_args', $query );
    95 
   123 
    96 	$post_body = array(
   124 	$post_body = array(
    97 		'translations' => wp_json_encode( $translations ),
   125 		'translations' => wp_json_encode( $translations ),
    98 	);
   126 	);
    99 
   127 
   102 
   130 
   103 	$url = $http_url = 'http://api.wordpress.org/core/version-check/1.7/?' . http_build_query( $query, null, '&' );
   131 	$url = $http_url = 'http://api.wordpress.org/core/version-check/1.7/?' . http_build_query( $query, null, '&' );
   104 	if ( $ssl = wp_http_supports( array( 'ssl' ) ) )
   132 	if ( $ssl = wp_http_supports( array( 'ssl' ) ) )
   105 		$url = set_url_scheme( $url, 'https' );
   133 		$url = set_url_scheme( $url, 'https' );
   106 
   134 
       
   135 	$doing_cron = wp_doing_cron();
       
   136 
   107 	$options = array(
   137 	$options = array(
   108 		'timeout' => ( ( defined('DOING_CRON') && DOING_CRON ) ? 30 : 3 ),
   138 		'timeout' => $doing_cron ? 30 : 3,
   109 		'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url( '/' ),
   139 		'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url( '/' ),
   110 		'headers' => array(
   140 		'headers' => array(
   111 			'wp_install' => $wp_install,
   141 			'wp_install' => $wp_install,
   112 			'wp_blog' => home_url( '/' )
   142 			'wp_blog' => home_url( '/' )
   113 		),
   143 		),
   114 		'body' => $post_body,
   144 		'body' => $post_body,
   115 	);
   145 	);
   116 
   146 
   117 	$response = wp_remote_post( $url, $options );
   147 	$response = wp_remote_post( $url, $options );
   118 	if ( $ssl && is_wp_error( $response ) ) {
   148 	if ( $ssl && is_wp_error( $response ) ) {
   119 		trigger_error( __( '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="https://wordpress.org/support/">support forums</a>.' ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE );
   149 		trigger_error(
       
   150 			sprintf(
       
   151 				/* translators: %s: support forums URL */
       
   152 				__( '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>.' ),
       
   153 				__( 'https://wordpress.org/support/' )
       
   154 			) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ),
       
   155 			headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE
       
   156 		);
   120 		$response = wp_remote_post( $http_url, $options );
   157 		$response = wp_remote_post( $http_url, $options );
   121 	}
   158 	}
   122 
   159 
   123 	if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) )
   160 	if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) ) {
   124 		return false;
   161 		return;
       
   162 	}
   125 
   163 
   126 	$body = trim( wp_remote_retrieve_body( $response ) );
   164 	$body = trim( wp_remote_retrieve_body( $response ) );
   127 	$body = json_decode( $body, true );
   165 	$body = json_decode( $body, true );
   128 
   166 
   129 	if ( ! is_array( $body ) || ! isset( $body['offers'] ) )
   167 	if ( ! is_array( $body ) || ! isset( $body['offers'] ) ) {
   130 		return false;
   168 		return;
       
   169 	}
   131 
   170 
   132 	$offers = $body['offers'];
   171 	$offers = $body['offers'];
   133 
   172 
   134 	foreach ( $offers as &$offer ) {
   173 	foreach ( $offers as &$offer ) {
   135 		foreach ( $offer as $offer_key => $value ) {
   174 		foreach ( $offer as $offer_key => $value ) {
   161 			// Queue an event to re-run the update check in $ttl seconds.
   200 			// Queue an event to re-run the update check in $ttl seconds.
   162 			wp_schedule_single_event( time() + $ttl, 'wp_version_check' );
   201 			wp_schedule_single_event( time() + $ttl, 'wp_version_check' );
   163 		}
   202 		}
   164 	}
   203 	}
   165 
   204 
   166 	// Trigger a background updates check if running non-interactively, and we weren't called from the update handler.
   205 	// Trigger background updates if running non-interactively, and we weren't called from the update handler.
   167 	if ( defined( 'DOING_CRON' ) && DOING_CRON && ! doing_action( 'wp_maybe_auto_update' ) ) {
   206 	if ( $doing_cron && ! doing_action( 'wp_maybe_auto_update' ) ) {
   168 		do_action( 'wp_maybe_auto_update' );
   207 		do_action( 'wp_maybe_auto_update' );
   169 	}
   208 	}
   170 }
   209 }
   171 
   210 
   172 /**
   211 /**
   175  * The WordPress version, PHP version, and Locale is sent along with a list of
   214  * The WordPress version, PHP version, and Locale is sent along with a list of
   176  * all plugins installed. Checks against the WordPress server at
   215  * all plugins installed. Checks against the WordPress server at
   177  * api.wordpress.org. Will only check if WordPress isn't installing.
   216  * api.wordpress.org. Will only check if WordPress isn't installing.
   178  *
   217  *
   179  * @since 2.3.0
   218  * @since 2.3.0
   180  * @uses $wp_version Used to notify the WordPress version.
   219  * @global string $wp_version Used to notify the WordPress version.
   181  *
   220  *
   182  * @param array $extra_stats Extra statistics to report to the WordPress.org API.
   221  * @param array $extra_stats Extra statistics to report to the WordPress.org API.
   183  * @return false|null Returns null if update is unsupported. Returns false if check is too soon.
       
   184  */
   222  */
   185 function wp_update_plugins( $extra_stats = array() ) {
   223 function wp_update_plugins( $extra_stats = array() ) {
   186 	include( ABSPATH . WPINC . '/version.php' ); // include an unmodified $wp_version
   224 	if ( wp_installing() ) {
   187 
   225 		return;
   188 	if ( defined('WP_INSTALLING') )
   226 	}
   189 		return false;
   227 
       
   228 	// include an unmodified $wp_version
       
   229 	include( ABSPATH . WPINC . '/version.php' );
   190 
   230 
   191 	// If running blog-side, bail unless we've not checked in the last 12 hours
   231 	// If running blog-side, bail unless we've not checked in the last 12 hours
   192 	if ( !function_exists( 'get_plugins' ) )
   232 	if ( !function_exists( 'get_plugins' ) )
   193 		require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
   233 		require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
   194 
   234 
   200 	if ( ! is_object($current) )
   240 	if ( ! is_object($current) )
   201 		$current = new stdClass;
   241 		$current = new stdClass;
   202 
   242 
   203 	$new_option = new stdClass;
   243 	$new_option = new stdClass;
   204 	$new_option->last_checked = time();
   244 	$new_option->last_checked = time();
       
   245 
       
   246 	$doing_cron = wp_doing_cron();
   205 
   247 
   206 	// Check for update on a different schedule, depending on the page.
   248 	// Check for update on a different schedule, depending on the page.
   207 	switch ( current_filter() ) {
   249 	switch ( current_filter() ) {
   208 		case 'upgrader_process_complete' :
   250 		case 'upgrader_process_complete' :
   209 			$timeout = 0;
   251 			$timeout = 0;
   214 		case 'load-plugins.php' :
   256 		case 'load-plugins.php' :
   215 		case 'load-update.php' :
   257 		case 'load-update.php' :
   216 			$timeout = HOUR_IN_SECONDS;
   258 			$timeout = HOUR_IN_SECONDS;
   217 			break;
   259 			break;
   218 		default :
   260 		default :
   219 			if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
   261 			if ( $doing_cron ) {
   220 				$timeout = 0;
   262 				$timeout = 2 * HOUR_IN_SECONDS;
   221 			} else {
   263 			} else {
   222 				$timeout = 12 * HOUR_IN_SECONDS;
   264 				$timeout = 12 * HOUR_IN_SECONDS;
   223 			}
   265 			}
   224 	}
   266 	}
   225 
   267 
   242 				}
   284 				}
   243 			}
   285 			}
   244 		}
   286 		}
   245 
   287 
   246 		// Bail if we've checked recently and if nothing has changed
   288 		// Bail if we've checked recently and if nothing has changed
   247 		if ( ! $plugin_changed )
   289 		if ( ! $plugin_changed ) {
   248 			return false;
   290 			return;
       
   291 		}
   249 	}
   292 	}
   250 
   293 
   251 	// Update last_checked for current to prevent multiple blocking requests if request hangs
   294 	// Update last_checked for current to prevent multiple blocking requests if request hangs
   252 	$current->last_checked = time();
   295 	$current->last_checked = time();
   253 	set_site_transient( 'update_plugins', $current );
   296 	set_site_transient( 'update_plugins', $current );
   254 
   297 
   255 	$to_send = compact( 'plugins', 'active' );
   298 	$to_send = compact( 'plugins', 'active' );
   256 
   299 
   257 	$locales = array( get_locale() );
   300 	$locales = array_values( get_available_languages() );
       
   301 
   258 	/**
   302 	/**
   259 	 * Filter the locales requested for plugin translations.
   303 	 * Filters the locales requested for plugin translations.
   260 	 *
   304 	 *
   261 	 * @since 3.7.0
   305 	 * @since 3.7.0
   262 	 *
   306 	 * @since 4.5.0 The default value of the `$locales` parameter changed to include all locales.
   263 	 * @param array $locales Plugin locale. Default is current locale of the site.
   307 	 *
       
   308 	 * @param array $locales Plugin locales. Default is all available locales of the site.
   264 	 */
   309 	 */
   265 	$locales = apply_filters( 'plugins_update_check_locales', $locales );
   310 	$locales = apply_filters( 'plugins_update_check_locales', $locales );
   266 
   311 	$locales = array_unique( $locales );
   267 	if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
   312 
       
   313 	if ( $doing_cron ) {
   268 		$timeout = 30;
   314 		$timeout = 30;
   269 	} else {
   315 	} else {
   270 		// Three seconds, plus one extra second for every 10 plugins
   316 		// Three seconds, plus one extra second for every 10 plugins
   271 		$timeout = 3 + (int) ( count( $plugins ) / 10 );
   317 		$timeout = 3 + (int) ( count( $plugins ) / 10 );
   272 	}
   318 	}
   277 			'plugins'      => wp_json_encode( $to_send ),
   323 			'plugins'      => wp_json_encode( $to_send ),
   278 			'translations' => wp_json_encode( $translations ),
   324 			'translations' => wp_json_encode( $translations ),
   279 			'locale'       => wp_json_encode( $locales ),
   325 			'locale'       => wp_json_encode( $locales ),
   280 			'all'          => wp_json_encode( true ),
   326 			'all'          => wp_json_encode( true ),
   281 		),
   327 		),
   282 		'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' )
   328 		'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url( '/' )
   283 	);
   329 	);
   284 
   330 
   285 	if ( $extra_stats ) {
   331 	if ( $extra_stats ) {
   286 		$options['body']['update_stats'] = wp_json_encode( $extra_stats );
   332 		$options['body']['update_stats'] = wp_json_encode( $extra_stats );
   287 	}
   333 	}
   290 	if ( $ssl = wp_http_supports( array( 'ssl' ) ) )
   336 	if ( $ssl = wp_http_supports( array( 'ssl' ) ) )
   291 		$url = set_url_scheme( $url, 'https' );
   337 		$url = set_url_scheme( $url, 'https' );
   292 
   338 
   293 	$raw_response = wp_remote_post( $url, $options );
   339 	$raw_response = wp_remote_post( $url, $options );
   294 	if ( $ssl && is_wp_error( $raw_response ) ) {
   340 	if ( $ssl && is_wp_error( $raw_response ) ) {
   295 		trigger_error( __( '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="https://wordpress.org/support/">support forums</a>.' ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE );
   341 		trigger_error(
       
   342 			sprintf(
       
   343 				/* translators: %s: support forums URL */
       
   344 				__( '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>.' ),
       
   345 				__( 'https://wordpress.org/support/' )
       
   346 			) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ),
       
   347 			headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE
       
   348 		);
   296 		$raw_response = wp_remote_post( $http_url, $options );
   349 		$raw_response = wp_remote_post( $http_url, $options );
   297 	}
   350 	}
   298 
   351 
   299 	if ( is_wp_error( $raw_response ) || 200 != wp_remote_retrieve_response_code( $raw_response ) )
   352 	if ( is_wp_error( $raw_response ) || 200 != wp_remote_retrieve_response_code( $raw_response ) ) {
   300 		return false;
   353 		return;
       
   354 	}
   301 
   355 
   302 	$response = json_decode( wp_remote_retrieve_body( $raw_response ), true );
   356 	$response = json_decode( wp_remote_retrieve_body( $raw_response ), true );
   303 	foreach ( $response['plugins'] as &$plugin ) {
   357 	foreach ( $response['plugins'] as &$plugin ) {
   304 		$plugin = (object) $plugin;
   358 		$plugin = (object) $plugin;
   305 	}
   359 		if ( isset( $plugin->compatibility ) ) {
   306 	unset( $plugin );
   360 			$plugin->compatibility = (object) $plugin->compatibility;
       
   361 			foreach ( $plugin->compatibility as &$data ) {
       
   362 				$data = (object) $data;
       
   363 			}
       
   364 		}
       
   365 	}
       
   366 	unset( $plugin, $data );
   307 	foreach ( $response['no_update'] as &$plugin ) {
   367 	foreach ( $response['no_update'] as &$plugin ) {
   308 		$plugin = (object) $plugin;
   368 		$plugin = (object) $plugin;
   309 	}
   369 	}
   310 	unset( $plugin );
   370 	unset( $plugin );
   311 
   371 
   329  * A list of all themes installed in sent to WP. Checks against the
   389  * A list of all themes installed in sent to WP. Checks against the
   330  * WordPress server at api.wordpress.org. Will only check if WordPress isn't
   390  * WordPress server at api.wordpress.org. Will only check if WordPress isn't
   331  * installing.
   391  * installing.
   332  *
   392  *
   333  * @since 2.7.0
   393  * @since 2.7.0
   334  * @uses $wp_version Used to notify the WordPress version.
       
   335  *
   394  *
   336  * @param array $extra_stats Extra statistics to report to the WordPress.org API.
   395  * @param array $extra_stats Extra statistics to report to the WordPress.org API.
   337  * @return false|null Returns null if update is unsupported. Returns false if check is too soon.
       
   338  */
   396  */
   339 function wp_update_themes( $extra_stats = array() ) {
   397 function wp_update_themes( $extra_stats = array() ) {
   340 	include( ABSPATH . WPINC . '/version.php' ); // include an unmodified $wp_version
   398 	if ( wp_installing() ) {
   341 
   399 		return;
   342 	if ( defined( 'WP_INSTALLING' ) )
   400 	}
   343 		return false;
   401 
       
   402 	// include an unmodified $wp_version
       
   403 	include( ABSPATH . WPINC . '/version.php' );
   344 
   404 
   345 	$installed_themes = wp_get_themes();
   405 	$installed_themes = wp_get_themes();
   346 	$translations = wp_get_installed_translations( 'themes' );
   406 	$translations = wp_get_installed_translations( 'themes' );
   347 
   407 
   348 	$last_update = get_site_transient( 'update_themes' );
   408 	$last_update = get_site_transient( 'update_themes' );
   365 			'Author URI' => $theme->get('AuthorURI'),
   425 			'Author URI' => $theme->get('AuthorURI'),
   366 			'Template'   => $theme->get_template(),
   426 			'Template'   => $theme->get_template(),
   367 			'Stylesheet' => $theme->get_stylesheet(),
   427 			'Stylesheet' => $theme->get_stylesheet(),
   368 		);
   428 		);
   369 	}
   429 	}
       
   430 
       
   431 	$doing_cron = wp_doing_cron();
   370 
   432 
   371 	// Check for update on a different schedule, depending on the page.
   433 	// Check for update on a different schedule, depending on the page.
   372 	switch ( current_filter() ) {
   434 	switch ( current_filter() ) {
   373 		case 'upgrader_process_complete' :
   435 		case 'upgrader_process_complete' :
   374 			$timeout = 0;
   436 			$timeout = 0;
   379 		case 'load-themes.php' :
   441 		case 'load-themes.php' :
   380 		case 'load-update.php' :
   442 		case 'load-update.php' :
   381 			$timeout = HOUR_IN_SECONDS;
   443 			$timeout = HOUR_IN_SECONDS;
   382 			break;
   444 			break;
   383 		default :
   445 		default :
   384 			if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
   446 			if ( $doing_cron ) {
   385 				$timeout = 0;
   447 				$timeout = 2 * HOUR_IN_SECONDS;
   386 			} else {
   448 			} else {
   387 				$timeout = 12 * HOUR_IN_SECONDS;
   449 				$timeout = 12 * HOUR_IN_SECONDS;
   388 			}
   450 			}
   389 	}
   451 	}
   390 
   452 
   405 				}
   467 				}
   406 			}
   468 			}
   407 		}
   469 		}
   408 
   470 
   409 		// Bail if we've checked recently and if nothing has changed
   471 		// Bail if we've checked recently and if nothing has changed
   410 		if ( ! $theme_changed )
   472 		if ( ! $theme_changed ) {
   411 			return false;
   473 			return;
       
   474 		}
   412 	}
   475 	}
   413 
   476 
   414 	// Update last_checked for current to prevent multiple blocking requests if request hangs
   477 	// Update last_checked for current to prevent multiple blocking requests if request hangs
   415 	$last_update->last_checked = time();
   478 	$last_update->last_checked = time();
   416 	set_site_transient( 'update_themes', $last_update );
   479 	set_site_transient( 'update_themes', $last_update );
   417 
   480 
   418 	$request['themes'] = $themes;
   481 	$request['themes'] = $themes;
   419 
   482 
   420 	$locales = array( get_locale() );
   483 	$locales = array_values( get_available_languages() );
       
   484 
   421 	/**
   485 	/**
   422 	 * Filter the locales requested for theme translations.
   486 	 * Filters the locales requested for theme translations.
   423 	 *
   487 	 *
   424 	 * @since 3.7.0
   488 	 * @since 3.7.0
   425 	 *
   489 	 * @since 4.5.0 The default value of the `$locales` parameter changed to include all locales.
   426 	 * @param array $locales Theme locale. Default is current locale of the site.
   490 	 *
       
   491 	 * @param array $locales Theme locales. Default is all available locales of the site.
   427 	 */
   492 	 */
   428 	$locales = apply_filters( 'themes_update_check_locales', $locales );
   493 	$locales = apply_filters( 'themes_update_check_locales', $locales );
   429 
   494 	$locales = array_unique( $locales );
   430 	if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
   495 
       
   496 	if ( $doing_cron ) {
   431 		$timeout = 30;
   497 		$timeout = 30;
   432 	} else {
   498 	} else {
   433 		// Three seconds, plus one extra second for every 10 themes
   499 		// Three seconds, plus one extra second for every 10 themes
   434 		$timeout = 3 + (int) ( count( $themes ) / 10 );
   500 		$timeout = 3 + (int) ( count( $themes ) / 10 );
   435 	}
   501 	}
   439 		'body' => array(
   505 		'body' => array(
   440 			'themes'       => wp_json_encode( $request ),
   506 			'themes'       => wp_json_encode( $request ),
   441 			'translations' => wp_json_encode( $translations ),
   507 			'translations' => wp_json_encode( $translations ),
   442 			'locale'       => wp_json_encode( $locales ),
   508 			'locale'       => wp_json_encode( $locales ),
   443 		),
   509 		),
   444 		'user-agent'	=> 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' )
   510 		'user-agent'	=> 'WordPress/' . $wp_version . '; ' . home_url( '/' )
   445 	);
   511 	);
   446 
   512 
   447 	if ( $extra_stats ) {
   513 	if ( $extra_stats ) {
   448 		$options['body']['update_stats'] = wp_json_encode( $extra_stats );
   514 		$options['body']['update_stats'] = wp_json_encode( $extra_stats );
   449 	}
   515 	}
   452 	if ( $ssl = wp_http_supports( array( 'ssl' ) ) )
   518 	if ( $ssl = wp_http_supports( array( 'ssl' ) ) )
   453 		$url = set_url_scheme( $url, 'https' );
   519 		$url = set_url_scheme( $url, 'https' );
   454 
   520 
   455 	$raw_response = wp_remote_post( $url, $options );
   521 	$raw_response = wp_remote_post( $url, $options );
   456 	if ( $ssl && is_wp_error( $raw_response ) ) {
   522 	if ( $ssl && is_wp_error( $raw_response ) ) {
   457 		trigger_error( __( '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="https://wordpress.org/support/">support forums</a>.' ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE );
   523 		trigger_error(
       
   524 			sprintf(
       
   525 				/* translators: %s: support forums URL */
       
   526 				__( '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>.' ),
       
   527 				__( 'https://wordpress.org/support/' )
       
   528 			) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ),
       
   529 			headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE
       
   530 		);
   458 		$raw_response = wp_remote_post( $http_url, $options );
   531 		$raw_response = wp_remote_post( $http_url, $options );
   459 	}
   532 	}
   460 
   533 
   461 	if ( is_wp_error( $raw_response ) || 200 != wp_remote_retrieve_response_code( $raw_response ) )
   534 	if ( is_wp_error( $raw_response ) || 200 != wp_remote_retrieve_response_code( $raw_response ) ) {
   462 		return false;
   535 		return;
       
   536 	}
   463 
   537 
   464 	$new_update = new stdClass;
   538 	$new_update = new stdClass;
   465 	$new_update->last_checked = time();
   539 	$new_update->last_checked = time();
   466 	$new_update->checked = $checked;
   540 	$new_update->checked = $checked;
   467 
   541 
   490 
   564 
   491 /**
   565 /**
   492  * Retrieves a list of all language updates available.
   566  * Retrieves a list of all language updates available.
   493  *
   567  *
   494  * @since 3.7.0
   568  * @since 3.7.0
       
   569  *
       
   570  * @return array
   495  */
   571  */
   496 function wp_get_translation_updates() {
   572 function wp_get_translation_updates() {
   497 	$updates = array();
   573 	$updates = array();
   498 	$transients = array( 'update_core' => 'core', 'update_plugins' => 'plugin', 'update_themes' => 'theme' );
   574 	$transients = array( 'update_core' => 'core', 'update_plugins' => 'plugin', 'update_themes' => 'theme' );
   499 	foreach ( $transients as $transient => $type ) {
   575 	foreach ( $transients as $transient => $type ) {
   500 
       
   501 		$transient = get_site_transient( $transient );
   576 		$transient = get_site_transient( $transient );
   502 		if ( empty( $transient->translations ) )
   577 		if ( empty( $transient->translations ) )
   503 			continue;
   578 			continue;
   504 
   579 
   505 		foreach ( $transient->translations as $translation ) {
   580 		foreach ( $transient->translations as $translation ) {
   506 			$updates[] = (object) $translation;
   581 			$updates[] = (object) $translation;
   507 		}
   582 		}
   508 	}
   583 	}
   509 
       
   510 	return $updates;
   584 	return $updates;
   511 }
   585 }
   512 
   586 
   513 /**
   587 /**
   514  * Collect counts and UI strings for available updates
   588  * Collect counts and UI strings for available updates
   541 	if ( ( $core || $plugins || $themes ) && wp_get_translation_updates() )
   615 	if ( ( $core || $plugins || $themes ) && wp_get_translation_updates() )
   542 		$counts['translations'] = 1;
   616 		$counts['translations'] = 1;
   543 
   617 
   544 	$counts['total'] = $counts['plugins'] + $counts['themes'] + $counts['wordpress'] + $counts['translations'];
   618 	$counts['total'] = $counts['plugins'] + $counts['themes'] + $counts['wordpress'] + $counts['translations'];
   545 	$titles = array();
   619 	$titles = array();
   546 	if ( $counts['wordpress'] )
   620 	if ( $counts['wordpress'] ) {
       
   621 		/* translators: 1: Number of updates available to WordPress */
   547 		$titles['wordpress'] = sprintf( __( '%d WordPress Update'), $counts['wordpress'] );
   622 		$titles['wordpress'] = sprintf( __( '%d WordPress Update'), $counts['wordpress'] );
   548 	if ( $counts['plugins'] )
   623 	}
       
   624 	if ( $counts['plugins'] ) {
       
   625 		/* translators: 1: Number of updates available to plugins */
   549 		$titles['plugins'] = sprintf( _n( '%d Plugin Update', '%d Plugin Updates', $counts['plugins'] ), $counts['plugins'] );
   626 		$titles['plugins'] = sprintf( _n( '%d Plugin Update', '%d Plugin Updates', $counts['plugins'] ), $counts['plugins'] );
   550 	if ( $counts['themes'] )
   627 	}
       
   628 	if ( $counts['themes'] ) {
       
   629 		/* translators: 1: Number of updates available to themes */
   551 		$titles['themes'] = sprintf( _n( '%d Theme Update', '%d Theme Updates', $counts['themes'] ), $counts['themes'] );
   630 		$titles['themes'] = sprintf( _n( '%d Theme Update', '%d Theme Updates', $counts['themes'] ), $counts['themes'] );
   552 	if ( $counts['translations'] )
   631 	}
       
   632 	if ( $counts['translations'] ) {
   553 		$titles['translations'] = __( 'Translation Updates' );
   633 		$titles['translations'] = __( 'Translation Updates' );
       
   634 	}
   554 
   635 
   555 	$update_title = $titles ? esc_attr( implode( ', ', $titles ) ) : '';
   636 	$update_title = $titles ? esc_attr( implode( ', ', $titles ) ) : '';
   556 
   637 
   557 	$update_data = array( 'counts' => $counts, 'title' => $update_title );
   638 	$update_data = array( 'counts' => $counts, 'title' => $update_title );
   558 	/**
   639 	/**
   559 	 * Filter the returned array of update data for plugins, themes, and WordPress core.
   640 	 * Filters the returned array of update data for plugins, themes, and WordPress core.
   560 	 *
   641 	 *
   561 	 * @since 3.5.0
   642 	 * @since 3.5.0
   562 	 *
   643 	 *
   563 	 * @param array $update_data {
   644 	 * @param array $update_data {
   564 	 *     Fetched update data.
   645 	 *     Fetched update data.
   569 	 * @param array $titles An array of update counts and UI strings for available updates.
   650 	 * @param array $titles An array of update counts and UI strings for available updates.
   570 	 */
   651 	 */
   571 	return apply_filters( 'wp_get_update_data', $update_data, $titles );
   652 	return apply_filters( 'wp_get_update_data', $update_data, $titles );
   572 }
   653 }
   573 
   654 
       
   655 /**
       
   656  * Determines whether core should be updated.
       
   657  *
       
   658  * @since 2.8.0
       
   659  *
       
   660  * @global string $wp_version
       
   661  */
   574 function _maybe_update_core() {
   662 function _maybe_update_core() {
   575 	include( ABSPATH . WPINC . '/version.php' ); // include an unmodified $wp_version
   663 	// include an unmodified $wp_version
       
   664 	include( ABSPATH . WPINC . '/version.php' );
   576 
   665 
   577 	$current = get_site_transient( 'update_core' );
   666 	$current = get_site_transient( 'update_core' );
   578 
   667 
   579 	if ( isset( $current->last_checked ) &&
   668 	if ( isset( $current->last_checked, $current->version_checked ) &&
   580 		12 * HOUR_IN_SECONDS > ( time() - $current->last_checked ) &&
   669 		12 * HOUR_IN_SECONDS > ( time() - $current->last_checked ) &&
   581 		isset( $current->version_checked ) &&
   670 		$current->version_checked == $wp_version ) {
   582 		$current->version_checked == $wp_version )
   671 		return;
   583 		return;
   672 	}
   584 
       
   585 	wp_version_check();
   673 	wp_version_check();
   586 }
   674 }
   587 /**
   675 /**
   588  * Check the last time plugins were run before checking plugin versions.
   676  * Check the last time plugins were run before checking plugin versions.
   589  *
   677  *
   612  */
   700  */
   613 function _maybe_update_themes() {
   701 function _maybe_update_themes() {
   614 	$current = get_site_transient( 'update_themes' );
   702 	$current = get_site_transient( 'update_themes' );
   615 	if ( isset( $current->last_checked ) && 12 * HOUR_IN_SECONDS > ( time() - $current->last_checked ) )
   703 	if ( isset( $current->last_checked ) && 12 * HOUR_IN_SECONDS > ( time() - $current->last_checked ) )
   616 		return;
   704 		return;
   617 
       
   618 	wp_update_themes();
   705 	wp_update_themes();
   619 }
   706 }
   620 
   707 
   621 /**
   708 /**
   622  * Schedule core, theme, and plugin update checks.
   709  * Schedule core, theme, and plugin update checks.
   623  *
   710  *
   624  * @since 3.1.0
   711  * @since 3.1.0
   625  */
   712  */
   626 function wp_schedule_update_checks() {
   713 function wp_schedule_update_checks() {
   627 	if ( !wp_next_scheduled('wp_version_check') && !defined('WP_INSTALLING') )
   714 	if ( ! wp_next_scheduled( 'wp_version_check' ) && ! wp_installing() )
   628 		wp_schedule_event(time(), 'twicedaily', 'wp_version_check');
   715 		wp_schedule_event(time(), 'twicedaily', 'wp_version_check');
   629 
   716 
   630 	if ( !wp_next_scheduled('wp_update_plugins') && !defined('WP_INSTALLING') )
   717 	if ( ! wp_next_scheduled( 'wp_update_plugins' ) && ! wp_installing() )
   631 		wp_schedule_event(time(), 'twicedaily', 'wp_update_plugins');
   718 		wp_schedule_event(time(), 'twicedaily', 'wp_update_plugins');
   632 
   719 
   633 	if ( !wp_next_scheduled('wp_update_themes') && !defined('WP_INSTALLING') )
   720 	if ( ! wp_next_scheduled( 'wp_update_themes' ) && ! wp_installing() )
   634 		wp_schedule_event(time(), 'twicedaily', 'wp_update_themes');
   721 		wp_schedule_event(time(), 'twicedaily', 'wp_update_themes');
   635 
       
   636 	if ( ! wp_next_scheduled( 'wp_maybe_auto_update' ) && ! defined( 'WP_INSTALLING' ) ) {
       
   637 		// Schedule auto updates for 7 a.m. and 7 p.m. in the timezone of the site.
       
   638 		$next = strtotime( 'today 7am' );
       
   639 		$now = time();
       
   640 		// Find the next instance of 7 a.m. or 7 p.m., but skip it if it is within 3 hours from now.
       
   641 		while ( ( $now + 3 * HOUR_IN_SECONDS ) > $next ) {
       
   642 			$next += 12 * HOUR_IN_SECONDS;
       
   643 		}
       
   644 		$next = $next - get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
       
   645 		// Add a random number of minutes, so we don't have all sites trying to update exactly on the hour
       
   646 		$next = $next + rand( 0, 59 ) * MINUTE_IN_SECONDS;
       
   647 		wp_schedule_event( $next, 'twicedaily', 'wp_maybe_auto_update' );
       
   648 	}
       
   649 }
   722 }
   650 
   723 
   651 /**
   724 /**
   652  * Clear existing update caches for plugins, themes, and core.
   725  * Clear existing update caches for plugins, themes, and core.
   653  *
   726  *
   661 	}
   734 	}
   662 	wp_clean_themes_cache();
   735 	wp_clean_themes_cache();
   663 	delete_site_transient( 'update_core' );
   736 	delete_site_transient( 'update_core' );
   664 }
   737 }
   665 
   738 
   666 if ( ( ! is_main_site() && ! is_network_admin() ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
   739 if ( ( ! is_main_site() && ! is_network_admin() ) || wp_doing_ajax() ) {
   667 	return;
   740 	return;
   668 }
   741 }
   669 
   742 
   670 add_action( 'admin_init', '_maybe_update_core' );
   743 add_action( 'admin_init', '_maybe_update_core' );
   671 add_action( 'wp_version_check', 'wp_version_check' );
   744 add_action( 'wp_version_check', 'wp_version_check' );
   672 add_action( 'upgrader_process_complete', 'wp_version_check', 10, 0 );
       
   673 
   745 
   674 add_action( 'load-plugins.php', 'wp_update_plugins' );
   746 add_action( 'load-plugins.php', 'wp_update_plugins' );
   675 add_action( 'load-update.php', 'wp_update_plugins' );
   747 add_action( 'load-update.php', 'wp_update_plugins' );
   676 add_action( 'load-update-core.php', 'wp_update_plugins' );
   748 add_action( 'load-update-core.php', 'wp_update_plugins' );
   677 add_action( 'admin_init', '_maybe_update_plugins' );
   749 add_action( 'admin_init', '_maybe_update_plugins' );
   678 add_action( 'wp_update_plugins', 'wp_update_plugins' );
   750 add_action( 'wp_update_plugins', 'wp_update_plugins' );
   679 add_action( 'upgrader_process_complete', 'wp_update_plugins', 10, 0 );
       
   680 
   751 
   681 add_action( 'load-themes.php', 'wp_update_themes' );
   752 add_action( 'load-themes.php', 'wp_update_themes' );
   682 add_action( 'load-update.php', 'wp_update_themes' );
   753 add_action( 'load-update.php', 'wp_update_themes' );
   683 add_action( 'load-update-core.php', 'wp_update_themes' );
   754 add_action( 'load-update-core.php', 'wp_update_themes' );
   684 add_action( 'admin_init', '_maybe_update_themes' );
   755 add_action( 'admin_init', '_maybe_update_themes' );
   685 add_action( 'wp_update_themes', 'wp_update_themes' );
   756 add_action( 'wp_update_themes', 'wp_update_themes' );
   686 add_action( 'upgrader_process_complete', 'wp_update_themes', 10, 0 );
       
   687 
   757 
   688 add_action( 'update_option_WPLANG', 'wp_clean_update_cache' , 10, 0 );
   758 add_action( 'update_option_WPLANG', 'wp_clean_update_cache' , 10, 0 );
   689 
   759 
   690 add_action( 'wp_maybe_auto_update', 'wp_maybe_auto_update' );
   760 add_action( 'wp_maybe_auto_update', 'wp_maybe_auto_update' );
   691 
   761