diff --git a/src/wp-admin/includes/ajax-actions.php b/src/wp-admin/includes/ajax-actions.php index 5e86d792dd..dc965d63cc 100644 --- a/src/wp-admin/includes/ajax-actions.php +++ b/src/wp-admin/includes/ajax-actions.php @@ -3345,16 +3345,25 @@ function wp_ajax_install_theme() { wp_send_json_error( $status ); } - $upgrader = new Theme_Upgrader( new Automatic_Upgrader_Skin() ); + $skin = new WP_Ajax_Upgrader_Skin(); + $upgrader = new Theme_Upgrader( $skin ); $result = $upgrader->install( $api->download_link ); if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { - $status['debug'] = $upgrader->skin->get_upgrade_messages(); + $status['debug'] = $skin->get_upgrade_messages(); } if ( is_wp_error( $result ) ) { + $status['errorCode'] = $result->get_error_code(); $status['errorMessage'] = $result->get_error_message(); wp_send_json_error( $status ); + } elseif ( is_wp_error( $skin->result ) ) { + $status['errorCode'] = $skin->result->get_error_code(); + $status['errorMessage'] = $skin->result->get_error_message(); + wp_send_json_error( $status ); + } elseif ( $skin->get_errors()->get_error_code() ) { + $status['errorMessage'] = $skin->get_error_messages(); + wp_send_json_error( $status ); } elseif ( is_null( $result ) ) { global $wp_filesystem; @@ -3437,14 +3446,22 @@ function wp_ajax_update_theme() { wp_update_themes(); } - $upgrader = new Theme_Upgrader( new Automatic_Upgrader_Skin() ); + $skin = new WP_Ajax_Upgrader_Skin(); + $upgrader = new Theme_Upgrader( $skin ); $result = $upgrader->bulk_upgrade( array( $stylesheet ) ); if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { - $status['debug'] = $upgrader->skin->get_upgrade_messages(); + $status['debug'] = $skin->get_upgrade_messages(); } - if ( is_array( $result ) && ! empty( $result[ $stylesheet ] ) ) { + if ( is_wp_error( $skin->result ) ) { + $status['errorCode'] = $skin->result->get_error_code(); + $status['errorMessage'] = $skin->result->get_error_message(); + wp_send_json_error( $status ); + } elseif ( $skin->get_errors()->get_error_code() ) { + $status['errorMessage'] = $skin->get_error_messages(); + wp_send_json_error( $status ); + } elseif ( is_array( $result ) && ! empty( $result[ $stylesheet ] ) ) { // Theme is already at the latest version. if ( true === $result[ $stylesheet ] ) { @@ -3458,10 +3475,6 @@ function wp_ajax_update_theme() { } wp_send_json_success( $status ); - } elseif ( is_wp_error( $upgrader->skin->result ) ) { - $status['errorCode'] = $upgrader->skin->result->get_error_code(); - $status['errorMessage'] = $upgrader->skin->result->get_error_message(); - wp_send_json_error( $status ); } elseif ( false === $result ) { global $wp_filesystem; @@ -3594,16 +3607,25 @@ function wp_ajax_install_plugin() { $status['pluginName'] = $api->name; - $upgrader = new Plugin_Upgrader( new Automatic_Upgrader_Skin() ); + $skin = new WP_Ajax_Upgrader_Skin(); + $upgrader = new Plugin_Upgrader( $skin ); $result = $upgrader->install( $api->download_link ); if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { - $status['debug'] = $upgrader->skin->get_upgrade_messages(); + $status['debug'] = $skin->get_upgrade_messages(); } if ( is_wp_error( $result ) ) { + $status['errorCode'] = $result->get_error_code(); $status['errorMessage'] = $result->get_error_message(); wp_send_json_error( $status ); + } elseif ( is_wp_error( $skin->result ) ) { + $status['errorCode'] = $skin->result->get_error_code(); + $status['errorMessage'] = $skin->result->get_error_message(); + wp_send_json_error( $status ); + } elseif ( $skin->get_errors()->get_error_code() ) { + $status['errorMessage'] = $skin->get_error_messages(); + wp_send_json_error( $status ); } elseif ( is_null( $result ) ) { global $wp_filesystem; @@ -3680,19 +3702,22 @@ function wp_ajax_update_plugin() { wp_update_plugins(); - $skin = new Automatic_Upgrader_Skin(); + $skin = new WP_Ajax_Upgrader_Skin(); $upgrader = new Plugin_Upgrader( $skin ); $result = $upgrader->bulk_upgrade( array( $plugin ) ); if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { - $status['debug'] = $upgrader->skin->get_upgrade_messages(); + $status['debug'] = $skin->get_upgrade_messages(); } - if ( is_array( $result ) && empty( $result[ $plugin ] ) && is_wp_error( $skin->result ) ) { - $result = $skin->result; - } - - if ( is_array( $result ) && ! empty( $result[ $plugin ] ) ) { + if ( is_wp_error( $skin->result ) ) { + $status['errorCode'] = $skin->result->get_error_code(); + $status['errorMessage'] = $skin->result->get_error_message(); + wp_send_json_error( $status ); + } elseif ( $skin->get_errors()->get_error_code() ) { + $status['errorMessage'] = $skin->get_error_messages(); + wp_send_json_error( $status ); + } elseif ( is_array( $result ) && ! empty( $result[ $plugin ] ) ) { $plugin_update_data = current( $result ); /* @@ -3716,9 +3741,6 @@ function wp_ajax_update_plugin() { $status['newVersion'] = sprintf( __( 'Version %s' ), $plugin_data['Version'] ); } wp_send_json_success( $status ); - } elseif ( is_wp_error( $result ) ) { - $status['errorMessage'] = $result->get_error_message(); - wp_send_json_error( $status ); } elseif ( false === $result ) { global $wp_filesystem; diff --git a/src/wp-admin/includes/class-wp-ajax-upgrader-skin.php b/src/wp-admin/includes/class-wp-ajax-upgrader-skin.php new file mode 100644 index 0000000000..8698e20445 --- /dev/null +++ b/src/wp-admin/includes/class-wp-ajax-upgrader-skin.php @@ -0,0 +1,132 @@ +errors = new WP_Error(); + } + + /** + * Retrieves the list of errors. + * + * @since 4.6.0 + * @access public + * + * @return WP_Error Errors during an upgrade. + */ + public function get_errors() { + return $this->errors; + } + + /** + * Retrieves a string for error messages. + * + * @since 4.6.0 + * @access public + * + * @return string Error messages during an upgrade. + */ + public function get_error_messages() { + $messages = array(); + + foreach ( $this->errors->get_error_codes() as $error_code ) { + if ( $this->errors->get_error_data( $error_code ) && is_string( $this->errors->get_error_data( $error_code ) ) ) { + $messages[] = $this->errors->get_error_message( $error_code ) . ' ' . esc_html( strip_tags( $this->errors->get_error_data( $error_code ) ) ); + } else { + $messages[] = $this->errors->get_error_message( $error_code ); + } + } + + return implode( ', ', $messages ); + } + + /** + * Stores a log entry for an error. + * + * @since 4.6.0 + * @access public + * + * @param string|WP_Error $errors Errors. + */ + public function error( $errors ) { + if ( is_string( $errors ) ) { + $string = $errors; + if ( ! empty( $this->upgrader->strings[ $string ] ) ) { + $string = $this->upgrader->strings[ $string ]; + } + + if ( false !== strpos( $string, '%' ) ) { + $args = func_get_args(); + $args = array_splice( $args, 1 ); + if ( ! empty( $args ) ) { + $string = vsprintf( $string, $args ); + } + } + + // Count existing errors to generate an unique error code. + $errors_count = count( $errors->get_error_codes() ); + $this->errors->add( 'unknown_upgrade_error_' . $errors_count + 1 , $string ); + } elseif ( is_wp_error( $errors ) ) { + foreach ( $errors->get_error_codes() as $error_code ) { + $this->errors->add( $error_code, $errors->get_error_message( $error_code ), $errors->get_error_data( $error_code ) ); + } + } + + $args = func_get_args(); + call_user_func_array( array( $this, 'parent::error' ), $args ); + } + + /** + * Stores a log entry. + * + * @since 4.6.0 + * @access public + * + * @param string|array|WP_Error $data Log entry data. + */ + public function feedback( $data ) { + if ( is_wp_error( $data ) ) { + foreach ( $data->get_error_codes() as $error_code ) { + $this->errors->add( $error_code, $data->get_error_message( $error_code ), $data->get_error_data( $error_code ) ); + } + } + + $args = func_get_args(); + call_user_func_array( array( $this, 'parent::feedback' ), $args ); + } +} diff --git a/src/wp-admin/includes/class-wp-upgrader-skins.php b/src/wp-admin/includes/class-wp-upgrader-skins.php index 6b8fbdb735..8b2789da0c 100644 --- a/src/wp-admin/includes/class-wp-upgrader-skins.php +++ b/src/wp-admin/includes/class-wp-upgrader-skins.php @@ -36,3 +36,6 @@ require_once ABSPATH . 'wp-admin/includes/class-language-pack-upgrader-skin.php' /** Automatic_Upgrader_Skin class */ require_once ABSPATH . 'wp-admin/includes/class-automatic-upgrader-skin.php'; + +/** WP_Ajax_Upgrader_Skin class */ +require_once ABSPATH . 'wp-admin/includes/class-wp-ajax-upgrader-skin.php'; diff --git a/src/wp-admin/includes/class-wp-upgrader.php b/src/wp-admin/includes/class-wp-upgrader.php index d5e10c4c64..2276152cc4 100644 --- a/src/wp-admin/includes/class-wp-upgrader.php +++ b/src/wp-admin/includes/class-wp-upgrader.php @@ -39,6 +39,9 @@ require_once ABSPATH . 'wp-admin/includes/class-language-pack-upgrader-skin.php' /** Automatic_Upgrader_Skin class */ require_once ABSPATH . 'wp-admin/includes/class-automatic-upgrader-skin.php'; +/** WP_Ajax_Upgrader_Skin class */ +require_once ABSPATH . 'wp-admin/includes/class-wp-ajax-upgrader-skin.php'; + /** * Core class used for upgrading/installing a local set of files via * the Filesystem Abstraction classes from a Zip file. diff --git a/src/wp-admin/js/updates.js b/src/wp-admin/js/updates.js index d4274fef6a..5df8ded165 100644 --- a/src/wp-admin/js/updates.js +++ b/src/wp-admin/js/updates.js @@ -244,7 +244,7 @@ * @param {string=} response.errorCode Optional. Error code for an error that occurred. */ wp.updates.ajaxAlways = function( response ) { - if ( ! response.errorCode && 'unable_to_connect_to_filesystem' !== response.errorCode ) { + if ( ! response.errorCode || 'unable_to_connect_to_filesystem' !== response.errorCode ) { wp.updates.ajaxLocked = false; wp.updates.queueChecker(); } @@ -1533,7 +1533,7 @@ * @returns {boolean} Whether there is an error that needs to be handled or not. */ wp.updates.maybeHandleCredentialError = function( response, action ) { - if ( response.errorCode && 'unable_to_connect_to_filesystem' === response.errorCode ) { + if ( wp.updates.shouldRequestFilesystemCredentials && response.errorCode && 'unable_to_connect_to_filesystem' === response.errorCode ) { wp.updates.credentialError( response, action ); return true; }