update.php 22.1 KB
Newer Older
godog's avatar
godog committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
<?php
/**
 * A simple set of functions to check our version 1.0 update service.
 *
 * @package WordPress
 * @since 2.3.0
 */

/**
 * Check WordPress version against the newest version.
 *
 * The WordPress version, PHP version, and Locale is sent. Checks against the
 * WordPress server at api.wordpress.org server. Will only check if WordPress
 * isn't installing.
 *
 * @since 2.3.0
 * @uses $wp_version Used to check against the newest WordPress version.
 *
lucha's avatar
lucha committed
19
 * @param array $extra_stats Extra statistics to report to the WordPress.org API.
lucha's avatar
lucha committed
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.
godog's avatar
godog committed
21 22
 * @return mixed Returns null if update is unsupported. Returns false if check is too soon.
 */
lucha's avatar
lucha committed
23
function wp_version_check( $extra_stats = array(), $force_check = false ) {
godog's avatar
godog committed
24 25 26
	if ( defined('WP_INSTALLING') )
		return;

shammash's avatar
shammash committed
27 28
	global $wpdb, $wp_local_package;
	include ABSPATH . WPINC . '/version.php'; // include an unmodified $wp_version
godog's avatar
godog committed
29 30 31
	$php_version = phpversion();

	$current = get_site_transient( 'update_core' );
lucha's avatar
lucha committed
32 33
	$translations = wp_get_installed_translations( 'core' );

lucha's avatar
lucha committed
34 35 36 37
	// Invalidate the transient when $wp_version changes
	if ( is_object( $current ) && $wp_version != $current->version_checked )
		$current = false;

godog's avatar
godog committed
38 39 40 41 42 43
	if ( ! is_object($current) ) {
		$current = new stdClass;
		$current->updates = array();
		$current->version_checked = $wp_version;
	}

lucha's avatar
lucha committed
44 45 46
	if ( ! empty( $extra_stats ) )
		$force_check = true;

lechuck's avatar
lechuck committed
47 48 49
	// Wait 60 seconds between multiple version check requests
	$timeout = 60;
	$time_not_changed = isset( $current->last_checked ) && $timeout > ( time() - $current->last_checked );
lucha's avatar
lucha committed
50
	if ( ! $force_check && $time_not_changed )
lechuck's avatar
lechuck committed
51 52
		return false;

lucha's avatar
lucha committed
53 54 55 56 57 58 59 60 61
	$locale = get_locale();
	/**
	 * Filter the locale requested for WordPress core translations.
	 *
	 * @since 2.8.0
	 *
	 * @param string $locale Current locale.
	 */
	$locale = apply_filters( 'core_version_check_locale', $locale );
godog's avatar
godog committed
62 63 64 65 66 67 68 69 70 71

	// Update last_checked for current to prevent multiple blocking requests if request hangs
	$current->last_checked = time();
	set_site_transient( 'update_core', $current );

	if ( method_exists( $wpdb, 'db_version' ) )
		$mysql_version = preg_replace('/[^0-9.].*/', '', $wpdb->db_version());
	else
		$mysql_version = 'N/A';

lechuck's avatar
lechuck committed
72 73 74 75
	if ( is_multisite() ) {
		$user_count = get_user_count();
		$num_blogs = get_blog_count();
		$wp_install = network_site_url();
godog's avatar
godog committed
76
		$multisite_enabled = 1;
root's avatar
root committed
77
	} else {
lechuck's avatar
lechuck committed
78
		$user_count = count_users();
lechuck's avatar
lechuck committed
79
		$user_count = $user_count['total_users'];
root's avatar
root committed
80 81 82
		$multisite_enabled = 0;
		$num_blogs = 1;
		$wp_install = home_url( '/' );
godog's avatar
godog committed
83 84
	}

root's avatar
root committed
85 86 87 88 89 90 91
	$query = array(
		'version'           => $wp_version,
		'php'               => $php_version,
		'locale'            => $locale,
		'mysql'             => $mysql_version,
		'local_package'     => isset( $wp_local_package ) ? $wp_local_package : '',
		'blogs'             => $num_blogs,
lechuck's avatar
lechuck committed
92
		'users'             => $user_count,
lucha's avatar
lucha committed
93 94 95 96 97
		'multisite_enabled' => $multisite_enabled,
	);

	$post_body = array(
		'translations' => json_encode( $translations ),
root's avatar
root committed
98 99
	);

lucha's avatar
lucha committed
100
	if ( is_array( $extra_stats ) )
lucha's avatar
lucha committed
101 102 103 104 105
		$post_body = array_merge( $post_body, $extra_stats );

	$url = $http_url = 'http://api.wordpress.org/core/version-check/1.7/?' . http_build_query( $query, null, '&' );
	if ( $ssl = wp_http_supports( array( 'ssl' ) ) )
		$url = set_url_scheme( $url, 'https' );
godog's avatar
godog committed
106 107 108 109 110 111 112

	$options = array(
		'timeout' => ( ( defined('DOING_CRON') && DOING_CRON ) ? 30 : 3 ),
		'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url( '/' ),
		'headers' => array(
			'wp_install' => $wp_install,
			'wp_blog' => home_url( '/' )
lucha's avatar
lucha committed
113 114
		),
		'body' => $post_body,
godog's avatar
godog committed
115 116
	);

lucha's avatar
lucha committed
117 118
	$response = wp_remote_post( $url, $options );
	if ( $ssl && is_wp_error( $response ) ) {
lechuck's avatar
lechuck committed
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 );
lucha's avatar
lucha committed
120 121
		$response = wp_remote_post( $http_url, $options );
	}
godog's avatar
godog committed
122

shammash's avatar
shammash committed
123
	if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) )
godog's avatar
godog committed
124 125
		return false;

shammash's avatar
shammash committed
126
	$body = trim( wp_remote_retrieve_body( $response ) );
lucha's avatar
lucha committed
127
	$body = json_decode( $body, true );
lechuck's avatar
lechuck committed
128 129

	if ( ! is_array( $body ) || ! isset( $body['offers'] ) )
shammash's avatar
shammash committed
130
		return false;
lechuck's avatar
lechuck committed
131

shammash's avatar
shammash committed
132 133 134 135 136 137
	$offers = $body['offers'];

	foreach ( $offers as &$offer ) {
		foreach ( $offer as $offer_key => $value ) {
			if ( 'packages' == $offer_key )
				$offer['packages'] = (object) array_intersect_key( array_map( 'esc_url', $offer['packages'] ),
lucha's avatar
lucha committed
138
					array_fill_keys( array( 'full', 'no_content', 'new_bundled', 'partial', 'rollback' ), '' ) );
shammash's avatar
shammash committed
139 140 141 142 143 144
			elseif ( 'download' == $offer_key )
				$offer['download'] = esc_url( $value );
			else
				$offer[ $offer_key ] = esc_html( $value );
		}
		$offer = (object) array_intersect_key( $offer, array_fill_keys( array( 'response', 'download', 'locale',
lechuck's avatar
lechuck committed
145
			'packages', 'current', 'version', 'php_version', 'mysql_version', 'new_bundled', 'partial_version', 'notify_email', 'support_email' ), '' ) );
godog's avatar
godog committed
146 147 148
	}

	$updates = new stdClass();
shammash's avatar
shammash committed
149
	$updates->updates = $offers;
godog's avatar
godog committed
150 151
	$updates->last_checked = time();
	$updates->version_checked = $wp_version;
lucha's avatar
lucha committed
152 153 154 155

	if ( isset( $body['translations'] ) )
		$updates->translations = $body['translations'];

lechuck's avatar
lechuck committed
156 157 158 159 160 161 162 163 164 165 166 167 168 169
	set_site_transient( 'update_core', $updates );

	if ( ! empty( $body['ttl'] ) ) {
		$ttl = (int) $body['ttl'];
		if ( $ttl && ( time() + $ttl < wp_next_scheduled( 'wp_version_check' ) ) ) {
			// Queue an event to re-run the update check in $ttl seconds.
			wp_schedule_single_event( time() + $ttl, 'wp_version_check' );
		}
	}

	// Trigger a background updates check if running non-interactively, and we weren't called from the update handler.
	if ( defined( 'DOING_CRON' ) && DOING_CRON && ! doing_action( 'wp_maybe_auto_update' ) ) {
		do_action( 'wp_maybe_auto_update' );
	}
godog's avatar
godog committed
170 171 172 173 174 175 176 177 178 179
}

/**
 * Check plugin versions against the latest versions hosted on WordPress.org.
 *
 * The WordPress version, PHP version, and Locale is sent along with a list of
 * all plugins installed. Checks against the WordPress server at
 * api.wordpress.org. Will only check if WordPress isn't installing.
 *
 * @since 2.3.0
root's avatar
root committed
180
 * @uses $wp_version Used to notify the WordPress version.
godog's avatar
godog committed
181
 *
lechuck's avatar
lechuck committed
182
 * @param array $extra_stats Extra statistics to report to the WordPress.org API.
godog's avatar
godog committed
183 184
 * @return mixed Returns null if update is unsupported. Returns false if check is too soon.
 */
lechuck's avatar
lechuck committed
185
function wp_update_plugins( $extra_stats = array() ) {
shammash's avatar
shammash committed
186
	include ABSPATH . WPINC . '/version.php'; // include an unmodified $wp_version
godog's avatar
godog committed
187 188 189 190 191 192 193 194 195

	if ( defined('WP_INSTALLING') )
		return false;

	// If running blog-side, bail unless we've not checked in the last 12 hours
	if ( !function_exists( 'get_plugins' ) )
		require_once( ABSPATH . 'wp-admin/includes/plugin.php' );

	$plugins = get_plugins();
lucha's avatar
lucha committed
196 197
	$translations = wp_get_installed_translations( 'plugins' );

godog's avatar
godog committed
198 199 200 201 202 203 204 205
	$active  = get_option( 'active_plugins', array() );
	$current = get_site_transient( 'update_plugins' );
	if ( ! is_object($current) )
		$current = new stdClass;

	$new_option = new stdClass;
	$new_option->last_checked = time();

lechuck's avatar
lechuck committed
206 207
	// Check for update on a different schedule, depending on the page.
	switch ( current_filter() ) {
lucha's avatar
lucha committed
208 209 210
		case 'upgrader_process_complete' :
			$timeout = 0;
			break;
lechuck's avatar
lechuck committed
211
		case 'load-update-core.php' :
lechuck's avatar
lechuck committed
212
			$timeout = MINUTE_IN_SECONDS;
lechuck's avatar
lechuck committed
213 214 215
			break;
		case 'load-plugins.php' :
		case 'load-update.php' :
lechuck's avatar
lechuck committed
216
			$timeout = HOUR_IN_SECONDS;
lechuck's avatar
lechuck committed
217 218
			break;
		default :
lechuck's avatar
lechuck committed
219 220 221 222 223
			if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
				$timeout = 0;
			} else {
				$timeout = 12 * HOUR_IN_SECONDS;
			}
godog's avatar
godog committed
224 225
	}

lechuck's avatar
lechuck committed
226 227
	$time_not_changed = isset( $current->last_checked ) && $timeout > ( time() - $current->last_checked );

lechuck's avatar
lechuck committed
228
	if ( $time_not_changed && ! $extra_stats ) {
lechuck's avatar
lechuck committed
229 230 231 232 233
		$plugin_changed = false;
		foreach ( $plugins as $file => $p ) {
			$new_option->checked[ $file ] = $p['Version'];

			if ( !isset( $current->checked[ $file ] ) || strval($current->checked[ $file ]) !== strval($p['Version']) )
godog's avatar
godog committed
234
				$plugin_changed = true;
lechuck's avatar
lechuck committed
235 236 237 238 239 240 241 242
		}

		if ( isset ( $current->response ) && is_array( $current->response ) ) {
			foreach ( $current->response as $plugin_file => $update_details ) {
				if ( ! isset($plugins[ $plugin_file ]) ) {
					$plugin_changed = true;
					break;
				}
godog's avatar
godog committed
243 244 245
			}
		}

lechuck's avatar
lechuck committed
246 247 248 249
		// Bail if we've checked recently and if nothing has changed
		if ( ! $plugin_changed )
			return false;
	}
godog's avatar
godog committed
250 251 252 253 254

	// Update last_checked for current to prevent multiple blocking requests if request hangs
	$current->last_checked = time();
	set_site_transient( 'update_plugins', $current );

lucha's avatar
lucha committed
255 256 257 258 259 260 261 262 263 264 265
	$to_send = compact( 'plugins', 'active' );

	$locales = array( get_locale() );
	/**
	 * Filter the locales requested for plugin translations.
	 *
	 * @since 3.7.0
	 *
	 * @param array $locales Plugin locale. Default is current locale of the site.
	 */
	$locales = apply_filters( 'plugins_update_check_locales', $locales );
godog's avatar
godog committed
266 267 268

	$options = array(
		'timeout' => ( ( defined('DOING_CRON') && DOING_CRON ) ? 30 : 3),
lucha's avatar
lucha committed
269 270 271 272 273
		'body' => array(
			'plugins'      => json_encode( $to_send ),
			'translations' => json_encode( $translations ),
			'locale'       => json_encode( $locales ),
		),
godog's avatar
godog committed
274 275 276
		'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' )
	);

lechuck's avatar
lechuck committed
277 278 279 280
	if ( $extra_stats ) {
		$options['body']['update_stats'] = json_encode( $extra_stats );
	}

lucha's avatar
lucha committed
281 282 283 284 285 286
	$url = $http_url = 'http://api.wordpress.org/plugins/update-check/1.1/';
	if ( $ssl = wp_http_supports( array( 'ssl' ) ) )
		$url = set_url_scheme( $url, 'https' );

	$raw_response = wp_remote_post( $url, $options );
	if ( $ssl && is_wp_error( $raw_response ) ) {
lechuck's avatar
lechuck committed
287
		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 );
lucha's avatar
lucha committed
288 289
		$raw_response = wp_remote_post( $http_url, $options );
	}
godog's avatar
godog committed
290

shammash's avatar
shammash committed
291
	if ( is_wp_error( $raw_response ) || 200 != wp_remote_retrieve_response_code( $raw_response ) )
godog's avatar
godog committed
292 293
		return false;

lucha's avatar
lucha committed
294 295 296 297 298
	$response = json_decode( wp_remote_retrieve_body( $raw_response ), true );
	foreach ( $response['plugins'] as &$plugin ) {
		$plugin = (object) $plugin;
	}
	unset( $plugin );
godog's avatar
godog committed
299

lucha's avatar
lucha committed
300 301 302 303
	if ( is_array( $response ) ) {
		$new_option->response = $response['plugins'];
		$new_option->translations = $response['translations'];
	} else {
godog's avatar
godog committed
304
		$new_option->response = array();
lucha's avatar
lucha committed
305 306
		$new_option->translations = array();
	}
godog's avatar
godog committed
307 308 309 310 311 312 313 314 315 316 317 318

	set_site_transient( 'update_plugins', $new_option );
}

/**
 * Check theme versions against the latest versions hosted on WordPress.org.
 *
 * A list of all themes installed in sent to WP. Checks against the
 * WordPress server at api.wordpress.org. Will only check if WordPress isn't
 * installing.
 *
 * @since 2.7.0
root's avatar
root committed
319
 * @uses $wp_version Used to notify the WordPress version.
godog's avatar
godog committed
320
 *
lechuck's avatar
lechuck committed
321
 * @param array $extra_stats Extra statistics to report to the WordPress.org API.
godog's avatar
godog committed
322 323
 * @return mixed Returns null if update is unsupported. Returns false if check is too soon.
 */
lechuck's avatar
lechuck committed
324
function wp_update_themes( $extra_stats = array() ) {
shammash's avatar
shammash committed
325
	include ABSPATH . WPINC . '/version.php'; // include an unmodified $wp_version
godog's avatar
godog committed
326 327 328 329

	if ( defined( 'WP_INSTALLING' ) )
		return false;

lechuck's avatar
lechuck committed
330
	$installed_themes = wp_get_themes();
lucha's avatar
lucha committed
331 332
	$translations = wp_get_installed_translations( 'themes' );

godog's avatar
godog committed
333 334 335 336
	$last_update = get_site_transient( 'update_themes' );
	if ( ! is_object($last_update) )
		$last_update = new stdClass;

lucha's avatar
lucha committed
337
	$themes = $checked = $request = array();
godog's avatar
godog committed
338 339

	// Put slug of current theme into request.
lucha's avatar
lucha committed
340
	$request['active'] = get_option( 'stylesheet' );
godog's avatar
godog committed
341

lechuck's avatar
lechuck committed
342 343 344 345 346 347 348 349 350 351 352 353 354
	foreach ( $installed_themes as $theme ) {
		$checked[ $theme->get_stylesheet() ] = $theme->get('Version');

		$themes[ $theme->get_stylesheet() ] = array(
			'Name'       => $theme->get('Name'),
			'Title'      => $theme->get('Name'),
			'Version'    => $theme->get('Version'),
			'Author'     => $theme->get('Author'),
			'Author URI' => $theme->get('AuthorURI'),
			'Template'   => $theme->get_template(),
			'Stylesheet' => $theme->get_stylesheet(),
		);
	}
godog's avatar
godog committed
355

lechuck's avatar
lechuck committed
356 357
	// Check for update on a different schedule, depending on the page.
	switch ( current_filter() ) {
lucha's avatar
lucha committed
358 359 360
		case 'upgrader_process_complete' :
			$timeout = 0;
			break;
lechuck's avatar
lechuck committed
361
		case 'load-update-core.php' :
lechuck's avatar
lechuck committed
362
			$timeout = MINUTE_IN_SECONDS;
lechuck's avatar
lechuck committed
363 364 365
			break;
		case 'load-themes.php' :
		case 'load-update.php' :
lechuck's avatar
lechuck committed
366
			$timeout = HOUR_IN_SECONDS;
lechuck's avatar
lechuck committed
367 368
			break;
		default :
lechuck's avatar
lechuck committed
369 370 371 372 373
			if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
				$timeout = 0;
			} else {
				$timeout = 12 * HOUR_IN_SECONDS;
			}
godog's avatar
godog committed
374 375
	}

lechuck's avatar
lechuck committed
376
	$time_not_changed = isset( $last_update->last_checked ) && $timeout > ( time() - $last_update->last_checked );
godog's avatar
godog committed
377

lechuck's avatar
lechuck committed
378
	if ( $time_not_changed && ! $extra_stats ) {
lechuck's avatar
lechuck committed
379 380 381
		$theme_changed = false;
		foreach ( $checked as $slug => $v ) {
			if ( !isset( $last_update->checked[ $slug ] ) || strval($last_update->checked[ $slug ]) !== strval($v) )
godog's avatar
godog committed
382
				$theme_changed = true;
lechuck's avatar
lechuck committed
383 384 385 386 387 388 389 390
		}

		if ( isset ( $last_update->response ) && is_array( $last_update->response ) ) {
			foreach ( $last_update->response as $slug => $update_details ) {
				if ( ! isset($checked[ $slug ]) ) {
					$theme_changed = true;
					break;
				}
godog's avatar
godog committed
391 392 393
			}
		}

lechuck's avatar
lechuck committed
394 395 396 397
		// Bail if we've checked recently and if nothing has changed
		if ( ! $theme_changed )
			return false;
	}
godog's avatar
godog committed
398 399 400 401 402

	// Update last_checked for current to prevent multiple blocking requests if request hangs
	$last_update->last_checked = time();
	set_site_transient( 'update_themes', $last_update );

lucha's avatar
lucha committed
403 404 405 406 407 408 409 410 411 412 413 414
	$request['themes'] = $themes;

	$locales = array( get_locale() );
	/**
	 * Filter the locales requested for theme translations.
	 *
	 * @since 3.7.0
	 *
	 * @param array $locales Theme locale. Default is current locale of the site.
	 */
	$locales = apply_filters( 'themes_update_check_locales', $locales );

godog's avatar
godog committed
415 416
	$options = array(
		'timeout' => ( ( defined('DOING_CRON') && DOING_CRON ) ? 30 : 3),
lucha's avatar
lucha committed
417 418 419 420 421
		'body' => array(
			'themes'       => json_encode( $request ),
			'translations' => json_encode( $translations ),
			'locale'       => json_encode( $locales ),
		),
godog's avatar
godog committed
422 423 424
		'user-agent'	=> 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' )
	);

lechuck's avatar
lechuck committed
425 426 427 428
	if ( $extra_stats ) {
		$options['body']['update_stats'] = json_encode( $extra_stats );
	}

lucha's avatar
lucha committed
429 430 431 432 433 434
	$url = $http_url = 'http://api.wordpress.org/themes/update-check/1.1/';
	if ( $ssl = wp_http_supports( array( 'ssl' ) ) )
		$url = set_url_scheme( $url, 'https' );

	$raw_response = wp_remote_post( $url, $options );
	if ( $ssl && is_wp_error( $raw_response ) ) {
lechuck's avatar
lechuck committed
435
		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 );
lucha's avatar
lucha committed
436 437
		$raw_response = wp_remote_post( $http_url, $options );
	}
godog's avatar
godog committed
438

shammash's avatar
shammash committed
439
	if ( is_wp_error( $raw_response ) || 200 != wp_remote_retrieve_response_code( $raw_response ) )
godog's avatar
godog committed
440 441 442
		return false;

	$new_update = new stdClass;
lechuck's avatar
lechuck committed
443
	$new_update->last_checked = time();
shammash's avatar
shammash committed
444 445
	$new_update->checked = $checked;

lucha's avatar
lucha committed
446 447 448 449 450 451
	$response = json_decode( wp_remote_retrieve_body( $raw_response ), true );

	if ( is_array( $response ) ) {
		$new_update->response     = $response['themes'];
		$new_update->translations = $response['translations'];
	}
godog's avatar
godog committed
452 453 454 455

	set_site_transient( 'update_themes', $new_update );
}

lucha's avatar
lucha committed
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490
/**
 * Performs WordPress automatic background updates.
 *
 * @since 3.7.0
 */
function wp_maybe_auto_update() {
	include_once ABSPATH . '/wp-admin/includes/admin.php';
	include_once ABSPATH . '/wp-admin/includes/class-wp-upgrader.php';

	$upgrader = new WP_Automatic_Updater;
	$upgrader->run();
}

/**
 * Retrieves a list of all language updates available.
 *
 * @since 3.7.0
 */
function wp_get_translation_updates() {
	$updates = array();
	$transients = array( 'update_core' => 'core', 'update_plugins' => 'plugin', 'update_themes' => 'theme' );
	foreach ( $transients as $transient => $type ) {

		$transient = get_site_transient( $transient );
		if ( empty( $transient->translations ) )
			continue;

		foreach ( $transient->translations as $translation ) {
			$updates[] = (object) $translation;
		}
	}

	return $updates;
}

lucha's avatar
lucha committed
491
/**
root's avatar
root committed
492 493 494 495 496 497 498
 * Collect counts and UI strings for available updates
 *
 * @since 3.3.0
 *
 * @return array
 */
function wp_get_update_data() {
lucha's avatar
lucha committed
499
	$counts = array( 'plugins' => 0, 'themes' => 0, 'wordpress' => 0, 'translations' => 0 );
root's avatar
root committed
500

lucha's avatar
lucha committed
501
	if ( $plugins = current_user_can( 'update_plugins' ) ) {
root's avatar
root committed
502 503 504 505 506
		$update_plugins = get_site_transient( 'update_plugins' );
		if ( ! empty( $update_plugins->response ) )
			$counts['plugins'] = count( $update_plugins->response );
	}

lucha's avatar
lucha committed
507
	if ( $themes = current_user_can( 'update_themes' ) ) {
root's avatar
root committed
508 509 510 511 512
		$update_themes = get_site_transient( 'update_themes' );
		if ( ! empty( $update_themes->response ) )
			$counts['themes'] = count( $update_themes->response );
	}

lucha's avatar
lucha committed
513
	if ( ( $core = current_user_can( 'update_core' ) ) && function_exists( 'get_core_updates' ) ) {
root's avatar
root committed
514 515 516 517 518
		$update_wordpress = get_core_updates( array('dismissed' => false) );
		if ( ! empty( $update_wordpress ) && ! in_array( $update_wordpress[0]->response, array('development', 'latest') ) && current_user_can('update_core') )
			$counts['wordpress'] = 1;
	}

lucha's avatar
lucha committed
519 520 521 522
	if ( ( $core || $plugins || $themes ) && wp_get_translation_updates() )
		$counts['translations'] = 1;

	$counts['total'] = $counts['plugins'] + $counts['themes'] + $counts['wordpress'] + $counts['translations'];
lechuck's avatar
lechuck committed
523
	$titles = array();
root's avatar
root committed
524
	if ( $counts['wordpress'] )
lechuck's avatar
lechuck committed
525
		$titles['wordpress'] = sprintf( __( '%d WordPress Update'), $counts['wordpress'] );
root's avatar
root committed
526
	if ( $counts['plugins'] )
lechuck's avatar
lechuck committed
527
		$titles['plugins'] = sprintf( _n( '%d Plugin Update', '%d Plugin Updates', $counts['plugins'] ), $counts['plugins'] );
root's avatar
root committed
528
	if ( $counts['themes'] )
lechuck's avatar
lechuck committed
529
		$titles['themes'] = sprintf( _n( '%d Theme Update', '%d Theme Updates', $counts['themes'] ), $counts['themes'] );
lucha's avatar
lucha committed
530 531
	if ( $counts['translations'] )
		$titles['translations'] = __( 'Translation Updates' );
root's avatar
root committed
532

lechuck's avatar
lechuck committed
533
	$update_title = $titles ? esc_attr( implode( ', ', $titles ) ) : '';
root's avatar
root committed
534

lucha's avatar
lucha committed
535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
	$update_data = array( 'counts' => $counts, 'title' => $update_title );
	/**
	 * Filter the returned array of update data for plugins, themes, and WordPress core.
	 *
	 * @since 3.5.0
	 *
	 * @param array $update_data {
	 *     Fetched update data.
	 *
	 *     @type array   $counts       An array of counts for available plugin, theme, and WordPress updates.
	 *     @type string  $update_title Titles of available updates.
	 * }
	 * @param array $titles An array of update counts and UI strings for available updates.
	 */
	return apply_filters( 'wp_get_update_data', $update_data, $titles );
root's avatar
root committed
550 551
}

godog's avatar
godog committed
552
function _maybe_update_core() {
shammash's avatar
shammash committed
553
	include ABSPATH . WPINC . '/version.php'; // include an unmodified $wp_version
godog's avatar
godog committed
554 555 556 557

	$current = get_site_transient( 'update_core' );

	if ( isset( $current->last_checked ) &&
lechuck's avatar
lechuck committed
558
		12 * HOUR_IN_SECONDS > ( time() - $current->last_checked ) &&
godog's avatar
godog committed
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
		isset( $current->version_checked ) &&
		$current->version_checked == $wp_version )
		return;

	wp_version_check();
}
/**
 * Check the last time plugins were run before checking plugin versions.
 *
 * This might have been backported to WordPress 2.6.1 for performance reasons.
 * This is used for the wp-admin to check only so often instead of every page
 * load.
 *
 * @since 2.7.0
 * @access private
 */
function _maybe_update_plugins() {
	$current = get_site_transient( 'update_plugins' );
lechuck's avatar
lechuck committed
577
	if ( isset( $current->last_checked ) && 12 * HOUR_IN_SECONDS > ( time() - $current->last_checked ) )
godog's avatar
godog committed
578 579 580 581 582 583 584 585 586 587 588 589 590
		return;
	wp_update_plugins();
}

/**
 * Check themes versions only after a duration of time.
 *
 * This is for performance reasons to make sure that on the theme version
 * checker is not run on every page load.
 *
 * @since 2.7.0
 * @access private
 */
lechuck's avatar
lechuck committed
591
function _maybe_update_themes() {
godog's avatar
godog committed
592
	$current = get_site_transient( 'update_themes' );
lechuck's avatar
lechuck committed
593
	if ( isset( $current->last_checked ) && 12 * HOUR_IN_SECONDS > ( time() - $current->last_checked ) )
godog's avatar
godog committed
594 595 596 597 598
		return;

	wp_update_themes();
}

root's avatar
root committed
599 600 601 602 603 604 605 606 607 608 609 610 611 612
/**
 * Schedule core, theme, and plugin update checks.
 *
 * @since 3.1.0
 */
function wp_schedule_update_checks() {
	if ( !wp_next_scheduled('wp_version_check') && !defined('WP_INSTALLING') )
		wp_schedule_event(time(), 'twicedaily', 'wp_version_check');

	if ( !wp_next_scheduled('wp_update_plugins') && !defined('WP_INSTALLING') )
		wp_schedule_event(time(), 'twicedaily', 'wp_update_plugins');

	if ( !wp_next_scheduled('wp_update_themes') && !defined('WP_INSTALLING') )
		wp_schedule_event(time(), 'twicedaily', 'wp_update_themes');
lucha's avatar
lucha committed
613 614 615 616 617 618 619 620 621 622

	if ( ! wp_next_scheduled( 'wp_maybe_auto_update' ) && ! defined( 'WP_INSTALLING' ) ) {
		// Schedule auto updates for 7 a.m. and 7 p.m. in the timezone of the site.
		$next = strtotime( 'today 7am' );
		$now = time();
		// Find the next instance of 7 a.m. or 7 p.m., but skip it if it is within 3 hours from now.
		while ( ( $now + 3 * HOUR_IN_SECONDS ) > $next ) {
			$next += 12 * HOUR_IN_SECONDS;
		}
		$next = $next - get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
lucha's avatar
lucha committed
623 624
		// Add a random number of minutes, so we don't have all sites trying to update exactly on the hour
		$next = $next + rand( 0, 59 ) * MINUTE_IN_SECONDS;
lucha's avatar
lucha committed
625 626
		wp_schedule_event( $next, 'twicedaily', 'wp_maybe_auto_update' );
	}
root's avatar
root committed
627 628
}

lechuck's avatar
lechuck committed
629
if ( ( ! is_main_site() && ! is_network_admin() ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) )
root's avatar
root committed
630 631
	return;

godog's avatar
godog committed
632 633
add_action( 'admin_init', '_maybe_update_core' );
add_action( 'wp_version_check', 'wp_version_check' );
lucha's avatar
lucha committed
634
add_action( 'upgrader_process_complete', 'wp_version_check', 10, 0 );
godog's avatar
godog committed
635 636 637 638 639 640

add_action( 'load-plugins.php', 'wp_update_plugins' );
add_action( 'load-update.php', 'wp_update_plugins' );
add_action( 'load-update-core.php', 'wp_update_plugins' );
add_action( 'admin_init', '_maybe_update_plugins' );
add_action( 'wp_update_plugins', 'wp_update_plugins' );
lechuck's avatar
lechuck committed
641
add_action( 'upgrader_process_complete', 'wp_update_plugins', 10, 0 );
godog's avatar
godog committed
642 643 644 645 646 647

add_action( 'load-themes.php', 'wp_update_themes' );
add_action( 'load-update.php', 'wp_update_themes' );
add_action( 'load-update-core.php', 'wp_update_themes' );
add_action( 'admin_init', '_maybe_update_themes' );
add_action( 'wp_update_themes', 'wp_update_themes' );
lechuck's avatar
lechuck committed
648
add_action( 'upgrader_process_complete', 'wp_update_themes', 10, 0 );
lucha's avatar
lucha committed
649 650

add_action( 'wp_maybe_auto_update', 'wp_maybe_auto_update' );
godog's avatar
godog committed
651

root's avatar
root committed
652
add_action('init', 'wp_schedule_update_checks');