wp/wp-admin/includes/update.php
changeset 16 a86126ab1dd4
parent 9 177826044cd9
child 18 be944660c56a
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
     6  * @subpackage Administration
     6  * @subpackage Administration
     7  */
     7  */
     8 
     8 
     9 /**
     9 /**
    10  * Selects the first update version from the update_core option.
    10  * Selects the first update version from the update_core option.
       
    11  *
       
    12  * @since 2.7.0
    11  *
    13  *
    12  * @return object|array|false The response from the API on success, false on failure.
    14  * @return object|array|false The response from the API on success, false on failure.
    13  */
    15  */
    14 function get_preferred_from_update_core() {
    16 function get_preferred_from_update_core() {
    15 	$updates = get_core_updates();
    17 	$updates = get_core_updates();
    21 	}
    23 	}
    22 	return $updates[0];
    24 	return $updates[0];
    23 }
    25 }
    24 
    26 
    25 /**
    27 /**
    26  * Get available core updates.
    28  * Gets available core updates.
       
    29  *
       
    30  * @since 2.7.0
    27  *
    31  *
    28  * @param array $options Set $options['dismissed'] to true to show dismissed upgrades too,
    32  * @param array $options Set $options['dismissed'] to true to show dismissed upgrades too,
    29  *                       set $options['available'] to false to skip not-dismissed updates.
    33  *                       set $options['available'] to false to skip not-dismissed updates.
    30  * @return array|false Array of the update objects on success, false on failure.
    34  * @return array|false Array of the update objects on success, false on failure.
    31  */
    35  */
    50 	}
    54 	}
    51 
    55 
    52 	$updates = $from_api->updates;
    56 	$updates = $from_api->updates;
    53 	$result  = array();
    57 	$result  = array();
    54 	foreach ( $updates as $update ) {
    58 	foreach ( $updates as $update ) {
    55 		if ( $update->response == 'autoupdate' ) {
    59 		if ( 'autoupdate' === $update->response ) {
    56 			continue;
    60 			continue;
    57 		}
    61 		}
    58 
    62 
    59 		if ( array_key_exists( $update->current . '|' . $update->locale, $dismissed ) ) {
    63 		if ( array_key_exists( $update->current . '|' . $update->locale, $dismissed ) ) {
    60 			if ( $options['dismissed'] ) {
    64 			if ( $options['dismissed'] ) {
    70 	}
    74 	}
    71 	return $result;
    75 	return $result;
    72 }
    76 }
    73 
    77 
    74 /**
    78 /**
    75  * Gets the best available (and enabled) Auto-Update for WordPress Core.
    79  * Gets the best available (and enabled) Auto-Update for WordPress core.
    76  *
    80  *
    77  * If there's 1.2.3 and 1.3 on offer, it'll choose 1.3 if the installation allows it, else, 1.2.3
    81  * If there's 1.2.3 and 1.3 on offer, it'll choose 1.3 if the installation allows it, else, 1.2.3.
    78  *
    82  *
    79  * @since 3.7.0
    83  * @since 3.7.0
    80  *
    84  *
    81  * @return array|false False on failure, otherwise the core update offering.
    85  * @return object|false The core update offering on success, false on failure.
    82  */
    86  */
    83 function find_core_auto_update() {
    87 function find_core_auto_update() {
    84 	$updates = get_site_transient( 'update_core' );
    88 	$updates = get_site_transient( 'update_core' );
    85 	if ( ! $updates || empty( $updates->updates ) ) {
    89 	if ( ! $updates || empty( $updates->updates ) ) {
    86 		return false;
    90 		return false;
    87 	}
    91 	}
    88 
    92 
    89 	include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
    93 	require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
    90 
    94 
    91 	$auto_update = false;
    95 	$auto_update = false;
    92 	$upgrader    = new WP_Automatic_Updater;
    96 	$upgrader    = new WP_Automatic_Updater;
    93 	foreach ( $updates->updates as $update ) {
    97 	foreach ( $updates->updates as $update ) {
    94 		if ( 'autoupdate' != $update->response ) {
    98 		if ( 'autoupdate' !== $update->response ) {
    95 			continue;
    99 			continue;
    96 		}
   100 		}
    97 
   101 
    98 		if ( ! $upgrader->should_update( 'core', $update, ABSPATH ) ) {
   102 		if ( ! $upgrader->should_update( 'core', $update, ABSPATH ) ) {
    99 			continue;
   103 			continue;
   111  *
   115  *
   112  * @since 3.7.0
   116  * @since 3.7.0
   113  *
   117  *
   114  * @param string $version Version string to query.
   118  * @param string $version Version string to query.
   115  * @param string $locale  Locale to query.
   119  * @param string $locale  Locale to query.
   116  * @return bool|array False on failure. An array of checksums on success.
   120  * @return array|false An array of checksums on success, false on failure.
   117  */
   121  */
   118 function get_core_checksums( $version, $locale ) {
   122 function get_core_checksums( $version, $locale ) {
   119 	$url = $http_url = 'http://api.wordpress.org/core/checksums/1.0/?' . http_build_query( compact( 'version', 'locale' ), null, '&' );
   123 	$http_url = 'http://api.wordpress.org/core/checksums/1.0/?' . http_build_query( compact( 'version', 'locale' ), null, '&' );
   120 
   124 	$url      = $http_url;
   121 	if ( $ssl = wp_http_supports( array( 'ssl' ) ) ) {
   125 
       
   126 	$ssl = wp_http_supports( array( 'ssl' ) );
       
   127 	if ( $ssl ) {
   122 		$url = set_url_scheme( $url, 'https' );
   128 		$url = set_url_scheme( $url, 'https' );
   123 	}
   129 	}
   124 
   130 
   125 	$options = array(
   131 	$options = array(
   126 		'timeout' => wp_doing_cron() ? 30 : 3,
   132 		'timeout' => wp_doing_cron() ? 30 : 3,
   128 
   134 
   129 	$response = wp_remote_get( $url, $options );
   135 	$response = wp_remote_get( $url, $options );
   130 	if ( $ssl && is_wp_error( $response ) ) {
   136 	if ( $ssl && is_wp_error( $response ) ) {
   131 		trigger_error(
   137 		trigger_error(
   132 			sprintf(
   138 			sprintf(
   133 				/* translators: %s: support forums URL */
   139 				/* translators: %s: Support forums URL. */
   134 				__( '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>.' ),
   140 				__( '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>.' ),
   135 				__( 'https://wordpress.org/support/' )
   141 				__( 'https://wordpress.org/support/forums/' )
   136 			) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ),
   142 			) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ),
   137 			headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE
   143 			headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE
   138 		);
   144 		);
   139 		$response = wp_remote_get( $http_url, $options );
   145 		$response = wp_remote_get( $http_url, $options );
   140 	}
   146 	}
   152 
   158 
   153 	return $body['checksums'];
   159 	return $body['checksums'];
   154 }
   160 }
   155 
   161 
   156 /**
   162 /**
       
   163  * Dismisses core update.
       
   164  *
       
   165  * @since 2.7.0
       
   166  *
   157  * @param object $update
   167  * @param object $update
   158  * @return bool
   168  * @return bool
   159  */
   169  */
   160 function dismiss_core_update( $update ) {
   170 function dismiss_core_update( $update ) {
   161 	$dismissed = get_site_option( 'dismissed_update_core' );
   171 	$dismissed = get_site_option( 'dismissed_update_core' );
   162 	$dismissed[ $update->current . '|' . $update->locale ] = true;
   172 	$dismissed[ $update->current . '|' . $update->locale ] = true;
   163 	return update_site_option( 'dismissed_update_core', $dismissed );
   173 	return update_site_option( 'dismissed_update_core', $dismissed );
   164 }
   174 }
   165 
   175 
   166 /**
   176 /**
       
   177  * Undismisses core update.
       
   178  *
       
   179  * @since 2.7.0
       
   180  *
   167  * @param string $version
   181  * @param string $version
   168  * @param string $locale
   182  * @param string $locale
   169  * @return bool
   183  * @return bool
   170  */
   184  */
   171 function undismiss_core_update( $version, $locale ) {
   185 function undismiss_core_update( $version, $locale ) {
   179 	unset( $dismissed[ $key ] );
   193 	unset( $dismissed[ $key ] );
   180 	return update_site_option( 'dismissed_update_core', $dismissed );
   194 	return update_site_option( 'dismissed_update_core', $dismissed );
   181 }
   195 }
   182 
   196 
   183 /**
   197 /**
   184  * @param string $version
   198  * Finds the available update for WordPress core.
   185  * @param string $locale
   199  *
   186  * @return object|false
   200  * @since 2.7.0
       
   201  *
       
   202  * @param string $version Version string to find the update for.
       
   203  * @param string $locale  Locale to find the update for.
       
   204  * @return object|false The core update offering on success, false on failure.
   187  */
   205  */
   188 function find_core_update( $version, $locale ) {
   206 function find_core_update( $version, $locale ) {
   189 	$from_api = get_site_transient( 'update_core' );
   207 	$from_api = get_site_transient( 'update_core' );
   190 
   208 
   191 	if ( ! isset( $from_api->updates ) || ! is_array( $from_api->updates ) ) {
   209 	if ( ! isset( $from_api->updates ) || ! is_array( $from_api->updates ) ) {
   200 	}
   218 	}
   201 	return false;
   219 	return false;
   202 }
   220 }
   203 
   221 
   204 /**
   222 /**
       
   223  * @since 2.3.0
       
   224  *
   205  * @param string $msg
   225  * @param string $msg
   206  * @return string
   226  * @return string
   207  */
   227  */
   208 function core_update_footer( $msg = '' ) {
   228 function core_update_footer( $msg = '' ) {
   209 	if ( ! current_user_can( 'update_core' ) ) {
   229 	if ( ! current_user_can( 'update_core' ) ) {
       
   230 		/* translators: %s: WordPress version. */
   210 		return sprintf( __( 'Version %s' ), get_bloginfo( 'version', 'display' ) );
   231 		return sprintf( __( 'Version %s' ), get_bloginfo( 'version', 'display' ) );
   211 	}
   232 	}
   212 
   233 
   213 	$cur = get_preferred_from_update_core();
   234 	$cur = get_preferred_from_update_core();
   214 	if ( ! is_object( $cur ) ) {
   235 	if ( ! is_object( $cur ) ) {
   227 		$cur->response = '';
   248 		$cur->response = '';
   228 	}
   249 	}
   229 
   250 
   230 	switch ( $cur->response ) {
   251 	switch ( $cur->response ) {
   231 		case 'development':
   252 		case 'development':
   232 			/* translators: 1: WordPress version number, 2: WordPress updates admin screen URL */
   253 			return sprintf(
   233 			return sprintf( __( 'You are using a development version (%1$s). Cool! Please <a href="%2$s">stay updated</a>.' ), get_bloginfo( 'version', 'display' ), network_admin_url( 'update-core.php' ) );
   254 				/* translators: 1: WordPress version number, 2: URL to WordPress Updates screen. */
       
   255 				__( 'You are using a development version (%1$s). Cool! Please <a href="%2$s">stay updated</a>.' ),
       
   256 				get_bloginfo( 'version', 'display' ),
       
   257 				network_admin_url( 'update-core.php' )
       
   258 			);
   234 
   259 
   235 		case 'upgrade':
   260 		case 'upgrade':
   236 			return '<strong><a href="' . network_admin_url( 'update-core.php' ) . '">' . sprintf( __( 'Get Version %s' ), $cur->current ) . '</a></strong>';
   261 			return sprintf(
       
   262 				'<strong><a href="%s">%s</a></strong>',
       
   263 				network_admin_url( 'update-core.php' ),
       
   264 				/* translators: %s: WordPress version. */
       
   265 				sprintf( __( 'Get Version %s' ), $cur->current )
       
   266 			);
   237 
   267 
   238 		case 'latest':
   268 		case 'latest':
   239 		default:
   269 		default:
       
   270 			/* translators: %s: WordPress version. */
   240 			return sprintf( __( 'Version %s' ), get_bloginfo( 'version', 'display' ) );
   271 			return sprintf( __( 'Version %s' ), get_bloginfo( 'version', 'display' ) );
   241 	}
   272 	}
   242 }
   273 }
   243 
   274 
   244 /**
   275 /**
       
   276  * @since 2.3.0
       
   277  *
   245  * @global string $pagenow
   278  * @global string $pagenow
   246  * @return false|void
   279  * @return void|false
   247  */
   280  */
   248 function update_nag() {
   281 function update_nag() {
   249 	if ( is_multisite() && ! current_user_can( 'update_core' ) ) {
   282 	if ( is_multisite() && ! current_user_can( 'update_core' ) ) {
   250 		return false;
   283 		return false;
   251 	}
   284 	}
   252 
   285 
   253 	global $pagenow;
   286 	global $pagenow;
   254 
   287 
   255 	if ( 'update-core.php' == $pagenow ) {
   288 	if ( 'update-core.php' === $pagenow ) {
   256 		return;
   289 		return;
   257 	}
   290 	}
   258 
   291 
   259 	$cur = get_preferred_from_update_core();
   292 	$cur = get_preferred_from_update_core();
   260 
   293 
   261 	if ( ! isset( $cur->response ) || $cur->response != 'upgrade' ) {
   294 	if ( ! isset( $cur->response ) || 'upgrade' !== $cur->response ) {
   262 		return false;
   295 		return false;
   263 	}
   296 	}
   264 
   297 
   265 	$version_url = sprintf(
   298 	$version_url = sprintf(
   266 		/* translators: %s: WordPress version */
   299 		/* translators: %s: WordPress version. */
   267 		esc_url( __( 'https://wordpress.org/support/wordpress-version/version-%s/' ) ),
   300 		esc_url( __( 'https://wordpress.org/support/wordpress-version/version-%s/' ) ),
   268 		sanitize_title( $cur->current )
   301 		sanitize_title( $cur->current )
   269 	);
   302 	);
   270 
   303 
   271 	if ( current_user_can( 'update_core' ) ) {
   304 	if ( current_user_can( 'update_core' ) ) {
   272 		$msg = sprintf(
   305 		$msg = sprintf(
   273 			/* translators: 1: URL to WordPress release notes, 2: new WordPress version, 3: URL to network admin, 4: accessibility text */
   306 			/* translators: 1: URL to WordPress release notes, 2: New WordPress version, 3: URL to network admin, 4: Accessibility text. */
   274 			__( '<a href="%1$s">WordPress %2$s</a> is available! <a href="%3$s" aria-label="%4$s">Please update now</a>.' ),
   307 			__( '<a href="%1$s">WordPress %2$s</a> is available! <a href="%3$s" aria-label="%4$s">Please update now</a>.' ),
   275 			$version_url,
   308 			$version_url,
   276 			$cur->current,
   309 			$cur->current,
   277 			network_admin_url( 'update-core.php' ),
   310 			network_admin_url( 'update-core.php' ),
   278 			esc_attr__( 'Please update WordPress now' )
   311 			esc_attr__( 'Please update WordPress now' )
   279 		);
   312 		);
   280 	} else {
   313 	} else {
   281 		$msg = sprintf(
   314 		$msg = sprintf(
   282 			/* translators: 1: URL to WordPress release notes, 2: new WordPress version */
   315 			/* translators: 1: URL to WordPress release notes, 2: New WordPress version. */
   283 			__( '<a href="%1$s">WordPress %2$s</a> is available! Please notify the site administrator.' ),
   316 			__( '<a href="%1$s">WordPress %2$s</a> is available! Please notify the site administrator.' ),
   284 			$version_url,
   317 			$version_url,
   285 			$cur->current
   318 			$cur->current
   286 		);
   319 		);
   287 	}
   320 	}
   288 	echo "<div class='update-nag'>$msg</div>";
   321 
   289 }
   322 	echo "<div class='update-nag notice notice-warning inline'>$msg</div>";
   290 
   323 }
   291 // Called directly from dashboard
   324 
       
   325 /**
       
   326  * Displays WordPress version and active theme in the 'At a Glance' dashboard widget.
       
   327  *
       
   328  * @since 2.5.0
       
   329  */
   292 function update_right_now_message() {
   330 function update_right_now_message() {
   293 	$theme_name = wp_get_theme();
   331 	$theme_name = wp_get_theme();
   294 	if ( current_user_can( 'switch_themes' ) ) {
   332 	if ( current_user_can( 'switch_themes' ) ) {
   295 		$theme_name = sprintf( '<a href="themes.php">%1$s</a>', $theme_name );
   333 		$theme_name = sprintf( '<a href="themes.php">%1$s</a>', $theme_name );
   296 	}
   334 	}
   298 	$msg = '';
   336 	$msg = '';
   299 
   337 
   300 	if ( current_user_can( 'update_core' ) ) {
   338 	if ( current_user_can( 'update_core' ) ) {
   301 		$cur = get_preferred_from_update_core();
   339 		$cur = get_preferred_from_update_core();
   302 
   340 
   303 		if ( isset( $cur->response ) && $cur->response == 'upgrade' ) {
   341 		if ( isset( $cur->response ) && 'upgrade' === $cur->response ) {
   304 			$msg .= '<a href="' . network_admin_url( 'update-core.php' ) . '" class="button" aria-describedby="wp-version">' . sprintf( __( 'Update to %s' ), $cur->current ? $cur->current : __( 'Latest' ) ) . '</a> ';
   342 			$msg .= sprintf(
   305 		}
   343 				'<a href="%s" class="button" aria-describedby="wp-version">%s</a> ',
   306 	}
   344 				network_admin_url( 'update-core.php' ),
   307 
   345 				/* translators: %s: WordPress version number, or 'Latest' string. */
   308 	/* translators: 1: version number, 2: theme name */
   346 				sprintf( __( 'Update to %s' ), $cur->current ? $cur->current : __( 'Latest' ) )
       
   347 			);
       
   348 		}
       
   349 	}
       
   350 
       
   351 	/* translators: 1: Version number, 2: Theme name. */
   309 	$content = __( 'WordPress %1$s running %2$s theme.' );
   352 	$content = __( 'WordPress %1$s running %2$s theme.' );
   310 
   353 
   311 	/**
   354 	/**
   312 	 * Filters the text displayed in the 'At a Glance' dashboard widget.
   355 	 * Filters the text displayed in the 'At a Glance' dashboard widget.
   313 	 *
   356 	 *
   353 
   396 
   354 	$plugins = get_site_transient( 'update_plugins' );
   397 	$plugins = get_site_transient( 'update_plugins' );
   355 	if ( isset( $plugins->response ) && is_array( $plugins->response ) ) {
   398 	if ( isset( $plugins->response ) && is_array( $plugins->response ) ) {
   356 		$plugins = array_keys( $plugins->response );
   399 		$plugins = array_keys( $plugins->response );
   357 		foreach ( $plugins as $plugin_file ) {
   400 		foreach ( $plugins as $plugin_file ) {
   358 			add_action( "after_plugin_row_$plugin_file", 'wp_plugin_update_row', 10, 2 );
   401 			add_action( "after_plugin_row_{$plugin_file}", 'wp_plugin_update_row', 10, 2 );
   359 		}
   402 		}
   360 	}
   403 	}
   361 }
   404 }
   362 
   405 
   363 /**
   406 /**
   364  * Displays update information for a plugin.
   407  * Displays update information for a plugin.
       
   408  *
       
   409  * @since 2.3.0
   365  *
   410  *
   366  * @param string $file        Plugin basename.
   411  * @param string $file        Plugin basename.
   367  * @param array  $plugin_data Plugin information.
   412  * @param array  $plugin_data Plugin information.
   368  * @return false|void
   413  * @return void|false
   369  */
   414  */
   370 function wp_plugin_update_row( $file, $plugin_data ) {
   415 function wp_plugin_update_row( $file, $plugin_data ) {
   371 	$current = get_site_transient( 'update_plugins' );
   416 	$current = get_site_transient( 'update_plugins' );
   372 	if ( ! isset( $current->response[ $file ] ) ) {
   417 	if ( ! isset( $current->response[ $file ] ) ) {
   373 		return false;
   418 		return false;
   389 
   434 
   390 	$plugin_name = wp_kses( $plugin_data['Name'], $plugins_allowedtags );
   435 	$plugin_name = wp_kses( $plugin_data['Name'], $plugins_allowedtags );
   391 	$details_url = self_admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . $response->slug . '&section=changelog&TB_iframe=true&width=600&height=800' );
   436 	$details_url = self_admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . $response->slug . '&section=changelog&TB_iframe=true&width=600&height=800' );
   392 
   437 
   393 	/** @var WP_Plugins_List_Table $wp_list_table */
   438 	/** @var WP_Plugins_List_Table $wp_list_table */
   394 	$wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
   439 	$wp_list_table = _get_list_table(
       
   440 		'WP_Plugins_List_Table',
       
   441 		array(
       
   442 			'screen' => get_current_screen(),
       
   443 		)
       
   444 	);
   395 
   445 
   396 	if ( is_network_admin() || ! is_multisite() ) {
   446 	if ( is_network_admin() || ! is_multisite() ) {
   397 		if ( is_network_admin() ) {
   447 		if ( is_network_admin() ) {
   398 			$active_class = is_plugin_active_for_network( $file ) ? ' active' : '';
   448 			$active_class = is_plugin_active_for_network( $file ) ? ' active' : '';
   399 		} else {
   449 		} else {
   402 
   452 
   403 		$requires_php   = isset( $response->requires_php ) ? $response->requires_php : null;
   453 		$requires_php   = isset( $response->requires_php ) ? $response->requires_php : null;
   404 		$compatible_php = is_php_version_compatible( $requires_php );
   454 		$compatible_php = is_php_version_compatible( $requires_php );
   405 		$notice_type    = $compatible_php ? 'notice-warning' : 'notice-error';
   455 		$notice_type    = $compatible_php ? 'notice-warning' : 'notice-error';
   406 
   456 
   407 		echo '<tr class="plugin-update-tr' . $active_class . '" id="' . esc_attr( $response->slug . '-update' ) . '" data-slug="' . esc_attr( $response->slug ) . '" data-plugin="' . esc_attr( $file ) . '"><td colspan="' . esc_attr( $wp_list_table->get_column_count() ) . '" class="plugin-update colspanchange"><div class="update-message notice inline ' . $notice_type . ' notice-alt"><p>';
   457 		printf(
       
   458 			'<tr class="plugin-update-tr%s" id="%s" data-slug="%s" data-plugin="%s">' .
       
   459 			'<td colspan="%s" class="plugin-update colspanchange">' .
       
   460 			'<div class="update-message notice inline %s notice-alt"><p>',
       
   461 			$active_class,
       
   462 			esc_attr( $response->slug . '-update' ),
       
   463 			esc_attr( $response->slug ),
       
   464 			esc_attr( $file ),
       
   465 			esc_attr( $wp_list_table->get_column_count() ),
       
   466 			$notice_type
       
   467 		);
   408 
   468 
   409 		if ( ! current_user_can( 'update_plugins' ) ) {
   469 		if ( ! current_user_can( 'update_plugins' ) ) {
   410 			/* translators: 1: plugin name, 2: details URL, 3: additional link attributes, 4: version number */
       
   411 			printf(
   470 			printf(
       
   471 				/* translators: 1: Plugin name, 2: Details URL, 3: Additional link attributes, 4: Version number. */
   412 				__( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a>.' ),
   472 				__( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a>.' ),
   413 				$plugin_name,
   473 				$plugin_name,
   414 				esc_url( $details_url ),
   474 				esc_url( $details_url ),
   415 				sprintf(
   475 				sprintf(
   416 					'class="thickbox open-plugin-details-modal" aria-label="%s"',
   476 					'class="thickbox open-plugin-details-modal" aria-label="%s"',
   417 					/* translators: 1: plugin name, 2: version number */
   477 					/* translators: 1: Plugin name, 2: Version number. */
   418 					esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $plugin_name, $response->new_version ) )
   478 					esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $plugin_name, $response->new_version ) )
   419 				),
   479 				),
   420 				esc_attr( $response->new_version )
   480 				esc_attr( $response->new_version )
   421 			);
   481 			);
   422 		} elseif ( empty( $response->package ) ) {
   482 		} elseif ( empty( $response->package ) ) {
   423 			/* translators: 1: plugin name, 2: details URL, 3: additional link attributes, 4: version number */
       
   424 			printf(
   483 			printf(
       
   484 				/* translators: 1: Plugin name, 2: Details URL, 3: Additional link attributes, 4: Version number. */
   425 				__( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a>. <em>Automatic update is unavailable for this plugin.</em>' ),
   485 				__( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a>. <em>Automatic update is unavailable for this plugin.</em>' ),
   426 				$plugin_name,
   486 				$plugin_name,
   427 				esc_url( $details_url ),
   487 				esc_url( $details_url ),
   428 				sprintf(
   488 				sprintf(
   429 					'class="thickbox open-plugin-details-modal" aria-label="%s"',
   489 					'class="thickbox open-plugin-details-modal" aria-label="%s"',
   430 					/* translators: 1: plugin name, 2: version number */
   490 					/* translators: 1: Plugin name, 2: Version number. */
   431 					esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $plugin_name, $response->new_version ) )
   491 					esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $plugin_name, $response->new_version ) )
   432 				),
   492 				),
   433 				esc_attr( $response->new_version )
   493 				esc_attr( $response->new_version )
   434 			);
   494 			);
   435 		} else {
   495 		} else {
   436 			if ( $compatible_php ) {
   496 			if ( $compatible_php ) {
   437 				/* translators: 1: plugin name, 2: details URL, 3: additional link attributes, 4: version number, 5: update URL, 6: additional link attributes */
       
   438 				printf(
   497 				printf(
       
   498 					/* translators: 1: Plugin name, 2: Details URL, 3: Additional link attributes, 4: Version number, 5: Update URL, 6: Additional link attributes. */
   439 					__( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a> or <a href="%5$s" %6$s>update now</a>.' ),
   499 					__( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a> or <a href="%5$s" %6$s>update now</a>.' ),
   440 					$plugin_name,
   500 					$plugin_name,
   441 					esc_url( $details_url ),
   501 					esc_url( $details_url ),
   442 					sprintf(
   502 					sprintf(
   443 						'class="thickbox open-plugin-details-modal" aria-label="%s"',
   503 						'class="thickbox open-plugin-details-modal" aria-label="%s"',
   444 						/* translators: 1: plugin name, 2: version number */
   504 						/* translators: 1: Plugin name, 2: Version number. */
   445 						esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $plugin_name, $response->new_version ) )
   505 						esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $plugin_name, $response->new_version ) )
   446 					),
   506 					),
   447 					esc_attr( $response->new_version ),
   507 					esc_attr( $response->new_version ),
   448 					wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $file, 'upgrade-plugin_' . $file ),
   508 					wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $file, 'upgrade-plugin_' . $file ),
   449 					sprintf(
   509 					sprintf(
   450 						'class="update-link" aria-label="%s"',
   510 						'class="update-link" aria-label="%s"',
   451 						/* translators: %s: plugin name */
   511 						/* translators: %s: Plugin name. */
   452 						esc_attr( sprintf( __( 'Update %s now' ), $plugin_name ) )
   512 						esc_attr( sprintf( _x( 'Update %s now', 'plugin' ), $plugin_name ) )
   453 					)
   513 					)
   454 				);
   514 				);
   455 			} else {
   515 			} else {
   456 				/* translators: 1: plugin name, 2: details URL, 3: additional link attributes, 4: version number 5: Update PHP page URL */
       
   457 				printf(
   516 				printf(
       
   517 					/* translators: 1: Plugin name, 2: Details URL, 3: Additional link attributes, 4: Version number 5: URL to Update PHP page. */
   458 					__( 'There is a new version of %1$s available, but it doesn&#8217;t work with your version of PHP. <a href="%2$s" %3$s>View version %4$s details</a> or <a href="%5$s">learn more about updating PHP</a>.' ),
   518 					__( 'There is a new version of %1$s available, but it doesn&#8217;t work with your version of PHP. <a href="%2$s" %3$s>View version %4$s details</a> or <a href="%5$s">learn more about updating PHP</a>.' ),
   459 					$plugin_name,
   519 					$plugin_name,
   460 					esc_url( $details_url ),
   520 					esc_url( $details_url ),
   461 					sprintf(
   521 					sprintf(
   462 						'class="thickbox open-plugin-details-modal" aria-label="%s"',
   522 						'class="thickbox open-plugin-details-modal" aria-label="%s"',
   463 						/* translators: 1: plugin name, 2: version number */
   523 						/* translators: 1: Plugin name, 2: Version number. */
   464 						esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $plugin_name, $response->new_version ) )
   524 						esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $plugin_name, $response->new_version ) )
   465 					),
   525 					),
   466 					esc_attr( $response->new_version ),
   526 					esc_attr( $response->new_version ),
   467 					esc_url( wp_get_update_php_url() )
   527 					esc_url( wp_get_update_php_url() )
   468 				);
   528 				);
   503 		 *     @type string $new_version New plugin version.
   563 		 *     @type string $new_version New plugin version.
   504 		 *     @type string $url         Plugin URL.
   564 		 *     @type string $url         Plugin URL.
   505 		 *     @type string $package     Plugin update package URL.
   565 		 *     @type string $package     Plugin update package URL.
   506 		 * }
   566 		 * }
   507 		 */
   567 		 */
   508 		do_action( "in_plugin_update_message-{$file}", $plugin_data, $response );
   568 		do_action( "in_plugin_update_message-{$file}", $plugin_data, $response ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
   509 
   569 
   510 		echo '</p></div></td></tr>';
   570 		echo '</p></div></td></tr>';
   511 	}
   571 	}
   512 }
   572 }
   513 
   573 
   514 /**
   574 /**
       
   575  * @since 2.9.0
       
   576  *
   515  * @return array
   577  * @return array
   516  */
   578  */
   517 function get_theme_updates() {
   579 function get_theme_updates() {
   518 	$current = get_site_transient( 'update_themes' );
   580 	$current = get_site_transient( 'update_themes' );
   519 
   581 
   541 	$themes = get_site_transient( 'update_themes' );
   603 	$themes = get_site_transient( 'update_themes' );
   542 	if ( isset( $themes->response ) && is_array( $themes->response ) ) {
   604 	if ( isset( $themes->response ) && is_array( $themes->response ) ) {
   543 		$themes = array_keys( $themes->response );
   605 		$themes = array_keys( $themes->response );
   544 
   606 
   545 		foreach ( $themes as $theme ) {
   607 		foreach ( $themes as $theme ) {
   546 			add_action( "after_theme_row_$theme", 'wp_theme_update_row', 10, 2 );
   608 			add_action( "after_theme_row_{$theme}", 'wp_theme_update_row', 10, 2 );
   547 		}
   609 		}
   548 	}
   610 	}
   549 }
   611 }
   550 
   612 
   551 /**
   613 /**
   552  * Displays update information for a theme.
   614  * Displays update information for a theme.
       
   615  *
       
   616  * @since 3.1.0
   553  *
   617  *
   554  * @param string   $theme_key Theme stylesheet.
   618  * @param string   $theme_key Theme stylesheet.
   555  * @param WP_Theme $theme     Theme object.
   619  * @param WP_Theme $theme     Theme object.
   556  * @return false|void
   620  * @return void|false
   557  */
   621  */
   558 function wp_theme_update_row( $theme_key, $theme ) {
   622 function wp_theme_update_row( $theme_key, $theme ) {
   559 	$current = get_site_transient( 'update_themes' );
   623 	$current = get_site_transient( 'update_themes' );
   560 
   624 
   561 	if ( ! isset( $current->response[ $theme_key ] ) ) {
   625 	if ( ! isset( $current->response[ $theme_key ] ) ) {
   576 	/** @var WP_MS_Themes_List_Table $wp_list_table */
   640 	/** @var WP_MS_Themes_List_Table $wp_list_table */
   577 	$wp_list_table = _get_list_table( 'WP_MS_Themes_List_Table' );
   641 	$wp_list_table = _get_list_table( 'WP_MS_Themes_List_Table' );
   578 
   642 
   579 	$active = $theme->is_allowed( 'network' ) ? ' active' : '';
   643 	$active = $theme->is_allowed( 'network' ) ? ' active' : '';
   580 
   644 
   581 	echo '<tr class="plugin-update-tr' . $active . '" id="' . esc_attr( $theme->get_stylesheet() . '-update' ) . '" data-slug="' . esc_attr( $theme->get_stylesheet() ) . '"><td colspan="' . $wp_list_table->get_column_count() . '" class="plugin-update colspanchange"><div class="update-message notice inline notice-warning notice-alt"><p>';
   645 	$requires_wp  = isset( $response['requires'] ) ? $response['requires'] : null;
   582 	if ( ! current_user_can( 'update_themes' ) ) {
   646 	$requires_php = isset( $response['requires_php'] ) ? $response['requires_php'] : null;
   583 		/* translators: 1: theme name, 2: details URL, 3: additional link attributes, 4: version number */
   647 
   584 		printf(
   648 	$compatible_wp  = is_wp_version_compatible( $requires_wp );
   585 			__( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a>.' ),
   649 	$compatible_php = is_php_version_compatible( $requires_php );
   586 			$theme['Name'],
   650 
   587 			esc_url( $details_url ),
   651 	printf(
   588 			sprintf(
   652 		'<tr class="plugin-update-tr%s" id="%s" data-slug="%s">' .
   589 				'class="thickbox open-plugin-details-modal" aria-label="%s"',
   653 		'<td colspan="%s" class="plugin-update colspanchange">' .
   590 				/* translators: 1: theme name, 2: version number */
   654 		'<div class="update-message notice inline notice-warning notice-alt"><p>',
   591 				esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $theme['Name'], $response['new_version'] ) )
   655 		$active,
   592 			),
   656 		esc_attr( $theme->get_stylesheet() . '-update' ),
   593 			$response['new_version']
   657 		esc_attr( $theme->get_stylesheet() ),
   594 		);
   658 		$wp_list_table->get_column_count()
   595 	} elseif ( empty( $response['package'] ) ) {
   659 	);
   596 		/* translators: 1: theme name, 2: details URL, 3: additional link attributes, 4: version number */
   660 
   597 		printf(
   661 	if ( $compatible_wp && $compatible_php ) {
   598 			__( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a>. <em>Automatic update is unavailable for this theme.</em>' ),
   662 		if ( ! current_user_can( 'update_themes' ) ) {
   599 			$theme['Name'],
   663 			printf(
   600 			esc_url( $details_url ),
   664 				/* translators: 1: Theme name, 2: Details URL, 3: Additional link attributes, 4: Version number. */
   601 			sprintf(
   665 				__( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a>.' ),
   602 				'class="thickbox open-plugin-details-modal" aria-label="%s"',
   666 				$theme['Name'],
   603 				/* translators: 1: theme name, 2: version number */
   667 				esc_url( $details_url ),
   604 				esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $theme['Name'], $response['new_version'] ) )
   668 				sprintf(
   605 			),
   669 					'class="thickbox open-plugin-details-modal" aria-label="%s"',
   606 			$response['new_version']
   670 					/* translators: 1: Theme name, 2: Version number. */
   607 		);
   671 					esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $theme['Name'], $response['new_version'] ) )
       
   672 				),
       
   673 				$response['new_version']
       
   674 			);
       
   675 		} elseif ( empty( $response['package'] ) ) {
       
   676 			printf(
       
   677 				/* translators: 1: Theme name, 2: Details URL, 3: Additional link attributes, 4: Version number. */
       
   678 				__( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a>. <em>Automatic update is unavailable for this theme.</em>' ),
       
   679 				$theme['Name'],
       
   680 				esc_url( $details_url ),
       
   681 				sprintf(
       
   682 					'class="thickbox open-plugin-details-modal" aria-label="%s"',
       
   683 					/* translators: 1: Theme name, 2: Version number. */
       
   684 					esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $theme['Name'], $response['new_version'] ) )
       
   685 				),
       
   686 				$response['new_version']
       
   687 			);
       
   688 		} else {
       
   689 			printf(
       
   690 				/* translators: 1: Theme name, 2: Details URL, 3: Additional link attributes, 4: Version number, 5: Update URL, 6: Additional link attributes. */
       
   691 				__( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a> or <a href="%5$s" %6$s>update now</a>.' ),
       
   692 				$theme['Name'],
       
   693 				esc_url( $details_url ),
       
   694 				sprintf(
       
   695 					'class="thickbox open-plugin-details-modal" aria-label="%s"',
       
   696 					/* translators: 1: Theme name, 2: Version number. */
       
   697 					esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $theme['Name'], $response['new_version'] ) )
       
   698 				),
       
   699 				$response['new_version'],
       
   700 				wp_nonce_url( self_admin_url( 'update.php?action=upgrade-theme&theme=' ) . $theme_key, 'upgrade-theme_' . $theme_key ),
       
   701 				sprintf(
       
   702 					'class="update-link" aria-label="%s"',
       
   703 					/* translators: %s: Theme name. */
       
   704 					esc_attr( sprintf( _x( 'Update %s now', 'theme' ), $theme['Name'] ) )
       
   705 				)
       
   706 			);
       
   707 		}
   608 	} else {
   708 	} else {
   609 		/* translators: 1: theme name, 2: details URL, 3: additional link attributes, 4: version number, 5: update URL, 6: additional link attributes */
   709 		if ( ! $compatible_wp && ! $compatible_php ) {
   610 		printf(
   710 			printf(
   611 			__( 'There is a new version of %1$s available. <a href="%2$s" %3$s>View version %4$s details</a> or <a href="%5$s" %6$s>update now</a>.' ),
   711 				/* translators: %s: Theme name. */
   612 			$theme['Name'],
   712 				__( 'There is a new version of %s available, but it doesn&#8217;t work with your versions of WordPress and PHP.' ),
   613 			esc_url( $details_url ),
   713 				$theme['Name']
   614 			sprintf(
   714 			);
   615 				'class="thickbox open-plugin-details-modal" aria-label="%s"',
   715 			if ( current_user_can( 'update_core' ) && current_user_can( 'update_php' ) ) {
   616 				/* translators: 1: theme name, 2: version number */
   716 				printf(
   617 				esc_attr( sprintf( __( 'View %1$s version %2$s details' ), $theme['Name'], $response['new_version'] ) )
   717 					/* translators: 1: URL to WordPress Updates screen, 2: URL to Update PHP page. */
   618 			),
   718 					' ' . __( '<a href="%1$s">Please update WordPress</a>, and then <a href="%2$s">learn more about updating PHP</a>.' ),
   619 			$response['new_version'],
   719 					self_admin_url( 'update-core.php' ),
   620 			wp_nonce_url( self_admin_url( 'update.php?action=upgrade-theme&theme=' ) . $theme_key, 'upgrade-theme_' . $theme_key ),
   720 					esc_url( wp_get_update_php_url() )
   621 			sprintf(
   721 				);
   622 				'class="update-link" aria-label="%s"',
   722 				wp_update_php_annotation( '</p><p><em>', '</em>' );
   623 				/* translators: %s: theme name */
   723 			} elseif ( current_user_can( 'update_core' ) ) {
   624 				esc_attr( sprintf( __( 'Update %s now' ), $theme['Name'] ) )
   724 				printf(
   625 			)
   725 					/* translators: %s: URL to WordPress Updates screen. */
   626 		);
   726 					' ' . __( '<a href="%s">Please update WordPress</a>.' ),
       
   727 					self_admin_url( 'update-core.php' )
       
   728 				);
       
   729 			} elseif ( current_user_can( 'update_php' ) ) {
       
   730 				printf(
       
   731 					/* translators: %s: URL to Update PHP page. */
       
   732 					' ' . __( '<a href="%s">Learn more about updating PHP</a>.' ),
       
   733 					esc_url( wp_get_update_php_url() )
       
   734 				);
       
   735 				wp_update_php_annotation( '</p><p><em>', '</em>' );
       
   736 			}
       
   737 		} elseif ( ! $compatible_wp ) {
       
   738 			printf(
       
   739 				/* translators: %s: Theme name. */
       
   740 				__( 'There is a new version of %s available, but it doesn&#8217;t work with your version of WordPress.' ),
       
   741 				$theme['Name']
       
   742 			);
       
   743 			if ( current_user_can( 'update_core' ) ) {
       
   744 				printf(
       
   745 					/* translators: %s: URL to WordPress Updates screen. */
       
   746 					' ' . __( '<a href="%s">Please update WordPress</a>.' ),
       
   747 					self_admin_url( 'update-core.php' )
       
   748 				);
       
   749 			}
       
   750 		} elseif ( ! $compatible_php ) {
       
   751 			printf(
       
   752 				/* translators: %s: Theme name. */
       
   753 				__( 'There is a new version of %s available, but it doesn&#8217;t work with your version of PHP.' ),
       
   754 				$theme['Name']
       
   755 			);
       
   756 			if ( current_user_can( 'update_php' ) ) {
       
   757 				printf(
       
   758 					/* translators: %s: URL to Update PHP page. */
       
   759 					' ' . __( '<a href="%s">Learn more about updating PHP</a>.' ),
       
   760 					esc_url( wp_get_update_php_url() )
       
   761 				);
       
   762 				wp_update_php_annotation( '</p><p><em>', '</em>' );
       
   763 			}
       
   764 		}
   627 	}
   765 	}
   628 
   766 
   629 	/**
   767 	/**
   630 	 * Fires at the end of the update message container in each
   768 	 * Fires at the end of the update message container in each
   631 	 * row of the themes list table.
   769 	 * row of the themes list table.
   642 	 *     @type string $new_version New theme version.
   780 	 *     @type string $new_version New theme version.
   643 	 *     @type string $url         Theme URL.
   781 	 *     @type string $url         Theme URL.
   644 	 *     @type string $package     Theme update package URL.
   782 	 *     @type string $package     Theme update package URL.
   645 	 * }
   783 	 * }
   646 	 */
   784 	 */
   647 	do_action( "in_theme_update_message-{$theme_key}", $theme, $response );
   785 	do_action( "in_theme_update_message-{$theme_key}", $theme, $response ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
   648 
   786 
   649 	echo '</p></div></td></tr>';
   787 	echo '</p></div></td></tr>';
   650 }
   788 }
   651 
   789 
   652 /**
   790 /**
       
   791  * @since 2.7.0
       
   792  *
   653  * @global int $upgrading
   793  * @global int $upgrading
   654  * @return false|void
   794  * @return void|false
   655  */
   795  */
   656 function maintenance_nag() {
   796 function maintenance_nag() {
   657 	include( ABSPATH . WPINC . '/version.php' ); // include an unmodified $wp_version
   797 	// Include an unmodified $wp_version.
       
   798 	require ABSPATH . WPINC . '/version.php';
   658 	global $upgrading;
   799 	global $upgrading;
   659 	$nag = isset( $upgrading );
   800 	$nag = isset( $upgrading );
   660 	if ( ! $nag ) {
   801 	if ( ! $nag ) {
   661 		$failed = get_site_option( 'auto_core_update_failed' );
   802 		$failed = get_site_option( 'auto_core_update_failed' );
   662 		/*
   803 		/*
   668 		 * OK if they are now running the latest.
   809 		 * OK if they are now running the latest.
   669 		 *
   810 		 *
   670 		 * This flag is cleared whenever a successful update occurs using Core_Upgrader.
   811 		 * This flag is cleared whenever a successful update occurs using Core_Upgrader.
   671 		 */
   812 		 */
   672 		$comparison = ! empty( $failed['critical'] ) ? '>=' : '>';
   813 		$comparison = ! empty( $failed['critical'] ) ? '>=' : '>';
   673 		if ( version_compare( $failed['attempted'], $wp_version, $comparison ) ) {
   814 		if ( isset( $failed['attempted'] ) && version_compare( $failed['attempted'], $wp_version, $comparison ) ) {
   674 			$nag = true;
   815 			$nag = true;
   675 		}
   816 		}
   676 	}
   817 	}
   677 
   818 
   678 	if ( ! $nag ) {
   819 	if ( ! $nag ) {
   679 		return false;
   820 		return false;
   680 	}
   821 	}
   681 
   822 
   682 	if ( current_user_can( 'update_core' ) ) {
   823 	if ( current_user_can( 'update_core' ) ) {
   683 		$msg = sprintf( __( 'An automated WordPress update has failed to complete - <a href="%s">please attempt the update again now</a>.' ), 'update-core.php' );
   824 		$msg = sprintf(
       
   825 			/* translators: %s: URL to WordPress Updates screen. */
       
   826 			__( 'An automated WordPress update has failed to complete - <a href="%s">please attempt the update again now</a>.' ),
       
   827 			'update-core.php'
       
   828 		);
   684 	} else {
   829 	} else {
   685 		$msg = __( 'An automated WordPress update has failed to complete! Please notify the site administrator.' );
   830 		$msg = __( 'An automated WordPress update has failed to complete! Please notify the site administrator.' );
   686 	}
   831 	}
   687 
   832 
   688 	echo "<div class='update-nag'>$msg</div>";
   833 	echo "<div class='update-nag notice notice-warning inline'>$msg</div>";
   689 }
   834 }
   690 
   835 
   691 /**
   836 /**
   692  * Prints the JavaScript templates for update admin notices.
   837  * Prints the JavaScript templates for update admin notices.
   693  *
   838  *
   714 			<p>
   859 			<p>
   715 				<# if ( data.successes ) { #>
   860 				<# if ( data.successes ) { #>
   716 					<# if ( 1 === data.successes ) { #>
   861 					<# if ( 1 === data.successes ) { #>
   717 						<# if ( 'plugin' === data.type ) { #>
   862 						<# if ( 'plugin' === data.type ) { #>
   718 							<?php
   863 							<?php
   719 							/* translators: %s: Number of plugins */
   864 							/* translators: %s: Number of plugins. */
   720 							printf( __( '%s plugin successfully updated.' ), '{{ data.successes }}' );
   865 							printf( __( '%s plugin successfully updated.' ), '{{ data.successes }}' );
   721 							?>
   866 							?>
   722 						<# } else { #>
   867 						<# } else { #>
   723 							<?php
   868 							<?php
   724 							/* translators: %s: Number of themes */
   869 							/* translators: %s: Number of themes. */
   725 							printf( __( '%s theme successfully updated.' ), '{{ data.successes }}' );
   870 							printf( __( '%s theme successfully updated.' ), '{{ data.successes }}' );
   726 							?>
   871 							?>
   727 						<# } #>
   872 						<# } #>
   728 					<# } else { #>
   873 					<# } else { #>
   729 						<# if ( 'plugin' === data.type ) { #>
   874 						<# if ( 'plugin' === data.type ) { #>
   730 							<?php
   875 							<?php
   731 							/* translators: %s: Number of plugins */
   876 							/* translators: %s: Number of plugins. */
   732 							printf( __( '%s plugins successfully updated.' ), '{{ data.successes }}' );
   877 							printf( __( '%s plugins successfully updated.' ), '{{ data.successes }}' );
   733 							?>
   878 							?>
   734 						<# } else { #>
   879 						<# } else { #>
   735 							<?php
   880 							<?php
   736 							/* translators: %s: Number of themes */
   881 							/* translators: %s: Number of themes. */
   737 							printf( __( '%s themes successfully updated.' ), '{{ data.successes }}' );
   882 							printf( __( '%s themes successfully updated.' ), '{{ data.successes }}' );
   738 							?>
   883 							?>
   739 						<# } #>
   884 						<# } #>
   740 					<# } #>
   885 					<# } #>
   741 				<# } #>
   886 				<# } #>
   742 				<# if ( data.errors ) { #>
   887 				<# if ( data.errors ) { #>
   743 					<button class="button-link bulk-action-errors-collapsed" aria-expanded="false">
   888 					<button class="button-link bulk-action-errors-collapsed" aria-expanded="false">
   744 						<# if ( 1 === data.errors ) { #>
   889 						<# if ( 1 === data.errors ) { #>
   745 							<?php
   890 							<?php
   746 							/* translators: %s: Number of failed updates */
   891 							/* translators: %s: Number of failed updates. */
   747 							printf( __( '%s update failed.' ), '{{ data.errors }}' );
   892 							printf( __( '%s update failed.' ), '{{ data.errors }}' );
   748 							?>
   893 							?>
   749 						<# } else { #>
   894 						<# } else { #>
   750 							<?php
   895 							<?php
   751 							/* translators: %s: Number of failed updates */
   896 							/* translators: %s: Number of failed updates. */
   752 							printf( __( '%s updates failed.' ), '{{ data.errors }}' );
   897 							printf( __( '%s updates failed.' ), '{{ data.errors }}' );
   753 							?>
   898 							?>
   754 						<# } #>
   899 						<# } #>
   755 						<span class="screen-reader-text"><?php _e( 'Show more details' ); ?></span>
   900 						<span class="screen-reader-text"><?php _e( 'Show more details' ); ?></span>
   756 						<span class="toggle-indicator" aria-hidden="true"></span>
   901 						<span class="toggle-indicator" aria-hidden="true"></span>
   809 		<tr class="plugin-deleted-tr inactive deleted" id="{{ data.slug }}-deleted" data-slug="{{ data.slug }}" <# if ( data.plugin ) { #>data-plugin="{{ data.plugin }}"<# } #>>
   954 		<tr class="plugin-deleted-tr inactive deleted" id="{{ data.slug }}-deleted" data-slug="{{ data.slug }}" <# if ( data.plugin ) { #>data-plugin="{{ data.plugin }}"<# } #>>
   810 			<td colspan="{{ data.colspan }}" class="plugin-update colspanchange">
   955 			<td colspan="{{ data.colspan }}" class="plugin-update colspanchange">
   811 				<# if ( data.plugin ) { #>
   956 				<# if ( data.plugin ) { #>
   812 					<?php
   957 					<?php
   813 					printf(
   958 					printf(
   814 						/* translators: %s: Plugin name */
   959 						/* translators: %s: Plugin name. */
   815 						_x( '%s was successfully deleted.', 'plugin' ),
   960 						_x( '%s was successfully deleted.', 'plugin' ),
   816 						'<strong>{{{ data.name }}}</strong>'
   961 						'<strong>{{{ data.name }}}</strong>'
   817 					);
   962 					);
   818 					?>
   963 					?>
   819 				<# } else { #>
   964 				<# } else { #>
   820 					<?php
   965 					<?php
   821 					printf(
   966 					printf(
   822 						/* translators: %s: Theme name */
   967 						/* translators: %s: Theme name. */
   823 						_x( '%s was successfully deleted.', 'theme' ),
   968 						_x( '%s was successfully deleted.', 'theme' ),
   824 						'<strong>{{{ data.name }}}</strong>'
   969 						'<strong>{{{ data.name }}}</strong>'
   825 					);
   970 					);
   826 					?>
   971 					?>
   827 				<# } #>
   972 				<# } #>
   848 	?>
   993 	?>
   849 	<div class="notice notice-info">
   994 	<div class="notice notice-info">
   850 		<p>
   995 		<p>
   851 			<?php
   996 			<?php
   852 			printf(
   997 			printf(
   853 				/* translators: %s: Recovery Mode exit link */
   998 				/* translators: %s: Recovery Mode exit link. */
   854 				__( 'You are in recovery mode. This means there may be an error with a theme or plugin. To exit recovery mode, log out or use the Exit button. <a href="%s">Exit Recovery Mode</a>' ),
   999 				__( 'You are in recovery mode. This means there may be an error with a theme or plugin. To exit recovery mode, log out or use the Exit button. <a href="%s">Exit Recovery Mode</a>' ),
   855 				esc_url( $url )
  1000 				esc_url( $url )
   856 			);
  1001 			);
   857 			?>
  1002 			?>
   858 		</p>
  1003 		</p>
   859 	</div>
  1004 	</div>
   860 	<?php
  1005 	<?php
   861 }
  1006 }
       
  1007 
       
  1008 /**
       
  1009  * Checks whether auto-updates are enabled.
       
  1010  *
       
  1011  * @since 5.5.0
       
  1012  *
       
  1013  * @param string $type The type of update being checked: 'theme' or 'plugin'.
       
  1014  * @return bool True if auto-updates are enabled for `$type`, false otherwise.
       
  1015  */
       
  1016 function wp_is_auto_update_enabled_for_type( $type ) {
       
  1017 	if ( ! class_exists( 'WP_Automatic_Updater' ) ) {
       
  1018 		require_once ABSPATH . 'wp-admin/includes/class-wp-automatic-updater.php';
       
  1019 	}
       
  1020 
       
  1021 	$updater = new WP_Automatic_Updater();
       
  1022 	$enabled = ! $updater->is_disabled();
       
  1023 
       
  1024 	switch ( $type ) {
       
  1025 		case 'plugin':
       
  1026 			/**
       
  1027 			 * Filters whether plugins auto-update is enabled.
       
  1028 			 *
       
  1029 			 * @since 5.5.0
       
  1030 			 *
       
  1031 			 * @param bool $enabled True if plugins auto-update is enabled, false otherwise.
       
  1032 			 */
       
  1033 			return apply_filters( 'plugins_auto_update_enabled', $enabled );
       
  1034 		case 'theme':
       
  1035 			/**
       
  1036 			 * Filters whether themes auto-update is enabled.
       
  1037 			 *
       
  1038 			 * @since 5.5.0
       
  1039 			 *
       
  1040 			 * @param bool $enabled True if themes auto-update is enabled, false otherwise.
       
  1041 			 */
       
  1042 			return apply_filters( 'themes_auto_update_enabled', $enabled );
       
  1043 	}
       
  1044 
       
  1045 	return false;
       
  1046 }
       
  1047 
       
  1048 /**
       
  1049  * Determines the appropriate auto-update message to be displayed.
       
  1050  *
       
  1051  * @since 5.5.0
       
  1052  *
       
  1053  * @return string The update message to be shown.
       
  1054  */
       
  1055 function wp_get_auto_update_message() {
       
  1056 	$next_update_time = wp_next_scheduled( 'wp_version_check' );
       
  1057 
       
  1058 	// Check if the event exists.
       
  1059 	if ( false === $next_update_time ) {
       
  1060 		$message = __( 'Automatic update not scheduled. There may be a problem with WP-Cron.' );
       
  1061 	} else {
       
  1062 		$time_to_next_update = human_time_diff( intval( $next_update_time ) );
       
  1063 
       
  1064 		// See if cron is overdue.
       
  1065 		$overdue = ( time() - $next_update_time ) > 0;
       
  1066 
       
  1067 		if ( $overdue ) {
       
  1068 			$message = sprintf(
       
  1069 				/* translators: %s: Duration that WP-Cron has been overdue. */
       
  1070 				__( 'Automatic update overdue by %s. There may be a problem with WP-Cron.' ),
       
  1071 				$time_to_next_update
       
  1072 			);
       
  1073 		} else {
       
  1074 			$message = sprintf(
       
  1075 				/* translators: %s: Time until the next update. */
       
  1076 				__( 'Automatic update scheduled in %s.' ),
       
  1077 				$time_to_next_update
       
  1078 			);
       
  1079 		}
       
  1080 	}
       
  1081 
       
  1082 	return $message;
       
  1083 }