diff --git a/wp-admin/includes/update.php b/wp-admin/includes/update.php index 4343c6c1ba..1debecdc53 100644 --- a/wp-admin/includes/update.php +++ b/wp-admin/includes/update.php @@ -8,11 +8,79 @@ // The admin side of our 1.1 update system +/** + * Selects the first update version from the update_core option + * + * @return object the response from the API + */ +function get_preferred_from_update_core() { + $updates = get_core_updates(); + if ( !is_array( $updates ) ) + return false; + if ( empty( $updates ) ) + return (object)array('response' => 'latest'); + return $updates[0]; +} + +/** + * Get available core updates + * + * @param array $options Set $options['dismissed'] to true to show dismissed upgrades too, + * set $options['available'] to false to skip not-dimissed updates. + * @return array Array of the update objects + */ +function get_core_updates( $options = array() ) { + $options = array_merge( array('available' => true, 'dismissed' => false ), $options ); + $dismissed = get_option( 'dismissed_update_core' ); + if ( !is_array( $dismissed ) ) $dismissed = array(); + $from_api = get_option( 'update_core' ); + if ( !is_array( $from_api ) ) return false; + $result = array(); + foreach($from_api as $update) { + if ( array_key_exists( $update->current.'|'.$update->locale, $dismissed ) ) { + if ( $options['dismissed'] ) { + $update->dismissed = true; + $result[]= $update; + } + } else { + if ( $options['available'] ) { + $update->dismissed = false; + $result[]= $update; + } + } + } + return $result; +} + +function dismiss_core_update( $update ) { + $dismissed = get_option( 'dismissed_update_core' ); + $dismissed[ $update->current.'|'.$update->locale ] = true; + return update_option( 'dismissed_update_core', $dismissed ); +} + +function undismiss_core_update( $version, $locale ) { + $dismissed = get_option( 'dismissed_update_core' ); + $key = $version.'|'.$locale; + if ( !isset( $dismissed[$key] ) ) return false; + unset( $dismissed[$key] ); + return update_option( 'dismissed_update_core', $dismissed ); +} + +function find_core_update( $version, $locale ) { + $from_api = get_option( 'update_core' ); + if ( !is_array( $from_api ) ) return false; + foreach($from_api as $update) { + if ( $update->current == $version && $update->locale == $locale ) + return $update; + } + return false; +} + function core_update_footer( $msg = '' ) { if ( !current_user_can('manage_options') ) return sprintf( '| '.__( 'Version %s' ), $GLOBALS['wp_version'] ); - $cur = get_option( 'update_core' ); + $cur = get_preferred_from_update_core(); if ( ! isset( $cur->current ) ) $cur->current = ''; @@ -39,7 +107,7 @@ function core_update_footer( $msg = '' ) { add_filter( 'update_footer', 'core_update_footer' ); function update_nag() { - $cur = get_option( 'update_core' ); + $cur = get_preferred_from_update_core(); if ( ! isset( $cur->response ) || $cur->response != 'upgrade' ) return false; @@ -55,7 +123,7 @@ function update_nag() { // Called directly from dashboard function update_right_now_message() { - $cur = get_option( 'update_core' ); + $cur = get_preferred_from_update_core(); $msg = sprintf( __('You are using WordPress %s.'), $GLOBALS['wp_version'] ); if ( isset( $cur->response ) && $cur->response == 'upgrade' && current_user_can('manage_options') ) @@ -320,7 +388,7 @@ function wp_update_theme($theme, $feedback = '') { } -function wp_update_core($feedback = '') { +function wp_update_core($current, $feedback = '') { global $wp_filesystem; @set_time_limit( 300 ); @@ -329,7 +397,6 @@ function wp_update_core($feedback = '') { add_filter('update_feedback', $feedback); // Is an update available? - $current = get_option( 'update_core' ); if ( !isset( $current->response ) || $current->response == 'latest' ) return new WP_Error('up_to_date', __('WordPress is at the latest version.')); diff --git a/wp-admin/menu.php b/wp-admin/menu.php index 23e6982b5e..ddf69e0727 100644 --- a/wp-admin/menu.php +++ b/wp-admin/menu.php @@ -86,6 +86,7 @@ $menu[45] = array( __('Tools'), 'manage_options', 'import.php', '', '', 'menu-to $submenu['import.php'][10] = array( __('Export'), 'import', 'export.php' ); if ( ! $is_opera ) $submenu['import.php'][20] = array( __('Turbo'), 'read', 'turbo.php' ); + $submenu['import.php'][30] = array( __('Update'), 'read', wp_nonce_url('update.php?action=upgrade-core', 'upgrade-core')); $menu[50] = array( __('Settings'), 'manage_options', 'options-general.php', '', 'menu-top-last', 'menu-settings', 'images/menu/settings.png' ); $submenu['options-general.php'][10] = array(__('General'), 'manage_options', 'options-general.php'); diff --git a/wp-admin/update.php b/wp-admin/update.php index 5f5846a24c..4ecb837175 100644 --- a/wp-admin/update.php +++ b/wp-admin/update.php @@ -122,6 +122,64 @@ function do_theme_upgrade($theme) { echo ''; } +function list_core_update( $update ) { + $version_string = 'en_US' == $update->locale? + $update->current : sprintf("%s–%s", $update->current, $update->locale); + if ( 'development' == $update->response ) { + $message = __('You are using a development version of WordPress. You can upgrade to the latest nightly build automatically or download the nightly build and install it manually:'); + $submit = __('Download nightly build'); + } else { + $message = sprintf(__('You can upgrade to version %s automatically or download the package and install it manually:'), $version_string); + $submit = sprintf(__('Download %s'), $version_string); + } + + echo '

'; + echo $message; + echo '

'; + echo '
'; + wp_nonce_field('upgrade-core'); + echo '

'; + echo ' '; + echo ''; + echo ''; + echo '' . $submit . ' '; + if ( 'en_US' != $update->locale ) + if ( !isset( $update->dismissed ) || !$update->dismissed ) + echo ''; + else + echo ''; + echo '

'; + echo '
'; + +} + +function dismissed_updates() { + $dismissed = get_core_updates( array( 'dismissed' => true, 'available' => false ) ); + if ( $dismissed ) { + + $show_text = js_escape(__('Show hidden updates')); + $hide_text = js_escape(__('Hide hidden updates')); + ?> + + '.__('Show hidden updates').'

'; + echo ''; + } +} + /** * Display upgrade WordPress for downloading latest or upgrading automatically form. * @@ -130,43 +188,42 @@ function do_theme_upgrade($theme) { * @return null */ function core_upgrade_preamble() { - $update = get_option('update_core'); - + $updates = get_core_updates(); + echo '
'; echo '

' . __('Upgrade WordPress') . '

'; - if ( !isset($update->response) || 'latest' == $update->response ) { - _e('You have the latest version of WordPress. You do not need to upgrade.'); + if ( !isset($updates[0]->response) || 'latest' == $updates[0]->response ) { + echo '

'; + _e('You have the latest version of WordPress. You do not need to upgrade'); + echo '

'; + dismissed_updates(); echo '
'; return; } - echo '

'; - _e('A new version of WordPress is available for upgrade. Before upgrading, please backup your database and files.'); - echo '

'; - - if ( 'development' == $update->response ) { - $message = __('You are using a development version of WordPress. You can upgrade to the latest nightly build automatically or download the nightly build and install it manually. Which would you like to do?'); - $submit = __('Download nightly build'); - } else { - $message = sprintf(__('You can upgrade to version %s automatically or download the package and install it manually. Which would you like to do?'), $update->current); - $submit = sprintf(__('Download %s'), $update->current); + echo '

'; + _e('Important: before upgrading, please backup your database and files.'); + echo '

'; + + echo '

'; + _e( 'There is a new version of WordPress available for upgrade' ); + echo '

'; + echo ''; + dismissed_updates(); echo ''; } + /** * Upgrade WordPress core display. * @@ -176,10 +233,17 @@ function core_upgrade_preamble() { */ function do_core_upgrade() { global $wp_filesystem; - + $url = wp_nonce_url('update.php?action=do-core-upgrade', 'upgrade-core'); if ( false === ($credentials = request_filesystem_credentials($url)) ) return; + + $version = isset( $_POST['version'] )? $_POST['version'] : false; + $locale = isset( $_POST['locale'] )? $_POST['locale'] : 'en_US'; + $update = find_core_update( $version, $locale ); + if ( !$update ) + return; + if ( ! WP_Filesystem($credentials) ) { request_filesystem_credentials($url, '', true); //Failed to connect, Error and request again @@ -195,7 +259,7 @@ function do_core_upgrade() { return; } - $result = wp_update_core('show_message'); + $result = wp_update_core($update, 'show_message'); if ( is_wp_error($result) ) { show_message($result); @@ -207,6 +271,26 @@ function do_core_upgrade() { echo ''; } +function do_dismiss_core_update() { + $version = isset( $_POST['version'] )? $_POST['version'] : false; + $locale = isset( $_POST['locale'] )? $_POST['locale'] : 'en_US'; + $update = find_core_update( $version, $locale ); + if ( !$update ) + return; + dismiss_core_update( $update ); + wp_redirect( wp_nonce_url('update.php?action=upgrade-core', 'upgrade-core') ); +} + +function do_undismiss_core_update() { + $version = isset( $_POST['version'] )? $_POST['version'] : false; + $locale = isset( $_POST['locale'] )? $_POST['locale'] : 'en_US'; + $update = find_core_update( $version, $locale ); + if ( !$update ) + return; + undismiss_core_update( $version, $locale ); + wp_redirect( wp_nonce_url('update.php?action=upgrade-core', 'upgrade-core') ); +} + if ( isset($_GET['action']) ) { $plugin = isset($_GET['plugin']) ? trim($_GET['plugin']) : ''; $theme = isset($_REQUEST['theme']) ? urldecode($_REQUEST['theme']) : ''; @@ -248,8 +332,15 @@ if ( isset($_GET['action']) ) { check_admin_referer('upgrade-core'); $title = __('Upgrade WordPress'); $parent_file = 'index.php'; + // do the (un)dismiss actions before headers, + // so that they can redirect + if ( isset( $_POST['dismiss'] ) ) + do_dismiss_core_update(); + elseif ( isset( $_POST['undismiss'] ) ) + do_undismiss_core_update(); require_once('admin-header.php'); - do_core_upgrade(); + if ( isset( $_POST['upgrade'] ) ) + do_core_upgrade(); include('admin-footer.php'); } elseif ( 'upgrade-theme' == $action ) { check_admin_referer('upgrade-theme_' . $theme); diff --git a/wp-admin/wp-admin.css b/wp-admin/wp-admin.css index 3594eaf622..03c7925fb6 100644 --- a/wp-admin/wp-admin.css +++ b/wp-admin/wp-admin.css @@ -2914,3 +2914,12 @@ abbr.required { .setting-description { font-style: italic; } +ul#dismissed-updates { + display: none; +} +ul.core-updates li { + padding: 12px; +} +form.upgrade { + margin-top: 8px; +} \ No newline at end of file diff --git a/wp-includes/update.php b/wp-includes/update.php index 24521c6e03..bf46c61624 100644 --- a/wp-includes/update.php +++ b/wp-includes/update.php @@ -23,19 +23,17 @@ function wp_version_check() { if ( defined('WP_INSTALLING') ) return; - global $wp_version, $wpdb; + global $wp_version, $wpdb, $wp_local_package; $php_version = phpversion(); $current = get_option( 'update_core' ); $locale = get_locale(); - if ( isset( $current->last_checked ) && 43200 > ( time() - $current->last_checked ) && $current->version_checked == $wp_version ) return false; - $new_option = ''; $new_option->last_checked = time(); // this gets set whether we get a response or not, so if something is down or misconfigured it won't delay the page load for more than 3 seconds, twice a day $new_option->version_checked = $wp_version; @@ -44,8 +42,8 @@ function wp_version_check() { $mysql_version = preg_replace('/[^0-9.].*/', '', $wpdb->db_version($wpdb->users)); else $mysql_version = 'N/A'; - - $url = "http://api.wordpress.org/core/version-check/1.2/?version=$wp_version&php=$php_version&locale=$locale&mysql=$mysql_version"; + $local_package = isset( $wp_local_package )? $wp_local_package : ''; + $url = "http://api.wordpress.org/core/version-check/1.3/?version=$wp_version&php=$php_version&locale=$locale&mysql=$mysql_version&local_package=$local_package"; $options = array('timeout' => 3); $options['headers'] = array( @@ -63,19 +61,23 @@ function wp_version_check() { $body = trim( $response['body'] ); $body = str_replace(array("\r\n", "\r"), "\n", $body); - $returns = explode("\n", $body); + $new_options = array(); + foreach( explode( "\n\n", $body ) as $entry) { + $returns = explode("\n", $entry); + $new_option = new stdClass(); + $new_option->response = attribute_escape( $returns[0] ); + if ( isset( $returns[1] ) ) + $new_option->url = clean_url( $returns[1] ); + if ( isset( $returns[2] ) ) + $new_option->package = clean_url( $returns[2] ); + if ( isset( $returns[3] ) ) + $new_option->current = attribute_escape( $returns[3] ); + if ( isset( $returns[4] ) ) + $new_option->locale = attribute_escape( $returns[4] ); + $new_options[] = $new_option; + } - $new_option->response = attribute_escape( $returns[0] ); - if ( isset( $returns[1] ) ) - $new_option->url = clean_url( $returns[1] ); - if ( isset( $returns[2] ) ) - $new_option->package = clean_url( $returns[2] ); - if ( isset( $returns[3] ) ) - $new_option->current = attribute_escape( $returns[3] ); - if ( isset( $returns[4] ) ) - $new_option->locale = attribute_escape( $returns[4] ); - - update_option( 'update_core', $new_option ); + update_option( 'update_core', $new_options ); } add_action( 'init', 'wp_version_check' );