Make WordPress Core

Ticket #51928: 51928.6.diff

File 51928.6.diff, 7.4 KB (added by afragen, 4 years ago)

zip and unzip of rollback now working

  • wp-admin/includes/class-wp-upgrader.php

    diff --git a/wp-admin/includes/class-wp-upgrader.php b/wp-admin/includes/class-wp-upgrader.php
    index 5faac56213..2eac664c96 100644
    a b class WP_Upgrader { 
    594594                // Copy new version of item into place.
    595595                $result = copy_dir( $source, $remote_destination );
    596596                if ( is_wp_error( $result ) ) {
     597                        $this->extract_rollback( $destination, $args['hook_extra'], $result );
    597598                        if ( $args['clear_working'] ) {
    598599                                $wp_filesystem->delete( $remote_source, true );
    599600                        }
    class WP_Upgrader { 
    666667         *                              or false if unable to connect to the filesystem.
    667668         */
    668669        public function run( $options ) {
     670                $start_time = time();
    669671
    670672                $defaults = array(
    671673                        'package'                     => '', // Please always pass this.
    class WP_Upgrader { 
    728730                $this->skin->before();
    729731
    730732                if ( is_wp_error( $res ) ) {
     733                        $this->send_error_data( $res, $start_time, 'fs_connect' );
    731734                        $this->skin->error( $res );
    732735                        $this->skin->after();
    733736                        if ( ! $options['is_multi'] ) {
    class WP_Upgrader { 
    765768                }
    766769
    767770                if ( is_wp_error( $download ) ) {
     771                        $this->send_error_data( $download, $start_time, 'download_package' );
    768772                        $this->skin->error( $download );
    769773                        $this->skin->after();
    770774                        if ( ! $options['is_multi'] ) {
    class WP_Upgrader { 
    778782                // Unzips the file into a temporary directory.
    779783                $working_dir = $this->unpack_package( $download, $delete_package );
    780784                if ( is_wp_error( $working_dir ) ) {
     785                        $this->send_error_data( $working_dir, $start_time, 'unpack_package' );
    781786                        $this->skin->error( $working_dir );
    782787                        $this->skin->after();
    783788                        if ( ! $options['is_multi'] ) {
    class WP_Upgrader { 
    786791                        return $working_dir;
    787792                }
    788793
     794                // Zip plugin/theme being updated to rollback directory.
     795                add_filter( 'upgrader_pre_install', array( $this, 'zip_to_rollback_dir' ), 15, 2 );
     796
    789797                // With the given options, this installs it to the destination directory.
    790798                $result = $this->install_package(
    791799                        array(
    class WP_Upgrader { 
    800808
    801809                $this->skin->set_result( $result );
    802810                if ( is_wp_error( $result ) ) {
     811                        $this->send_error_data( $result, $start_time, 'install_package' );
    803812                        $this->skin->error( $result );
    804813
    805814                        if ( ! method_exists( $this->skin, 'hide_process_failed' ) || ! $this->skin->hide_process_failed( $result ) ) {
    class WP_Upgrader { 
    937946                return delete_option( $lock_name . '.lock' );
    938947        }
    939948
     949        /**
     950         * Send upgrade WP_Error data to WordPress.org.
     951         *
     952         * @since 5.7.0
     953         *
     954         * @global string             $wp_version    The WordPress version string.
     955         * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
     956         * @param  WP_Error           $result        WP_Error data from failed upgrade process.
     957         * @param  int                $start_time    Time that run() started.
     958         * @param  string             $method        Name of method sending data.
     959         *
     960         * @return void
     961         */
     962        public function send_error_data( $result, $start_time, $method = null ) {
     963                global $wp_version, $wp_filesystem;
     964
     965                if ( ! is_wp_error( $result ) ) {
     966                        return;
     967                }
     968                $stats = array(
     969                        'process'          => $method,
     970                        'update_type'      => null,
     971                        'name'             => null,
     972                        'update_version'   => null,
     973                        'success'          => false,
     974                        'fs_method'        => $wp_filesystem->method,
     975                        'fs_method_forced' => defined( 'FS_METHOD' ) || has_filter( 'filesystem_method' ),
     976                        'fs_method_direct' => ! empty( $GLOBALS['_wp_filesystem_direct_method'] ) ? $GLOBALS['_wp_filesystem_direct_method'] : '',
     977                        'time_taken'       => time() - $start_time,
     978                        'wp_version'       => $wp_version,
     979                        'error_code'       => $result->get_error_code(),
     980                        'error_message'    => $result->get_error_message(),
     981                        'error_data'       => $result->get_error_data(),
     982                );
     983                if ( $this instanceof Plugin_Upgrader ) {
     984                        if ( isset( $this->skin->plugin_info ) ) {
     985                                $stats['update_type']    = 'manual_plugin_update';
     986                                $stats['name']           = $this->skin->plugin_info['Name'];
     987                                $stats['update_version'] = $this->skin->plugin_info['Version'];
     988                        } else {
     989                                $stats['update_type'] = 'automatic_plugin_update';
     990                        }
     991                        wp_update_plugins( $stats );
     992                }
     993                if ( $this instanceof Theme_Upgrader ) {
     994                        if ( isset( $this->skin->theme_info )) {
     995                                $stats['update_type']    = 'manual_theme_update';
     996                                $stats['name']           = $this->skin->theme_info->get('Name');
     997                                $stats['update_version'] = $this->skin->theme_info->get('Version');
     998                        } else {
     999                                $stats['update_type'] = 'automatic_theme_update';
     1000                        }
     1001                        wp_update_themes( $stats );
     1002                }
     1003        }
     1004
     1005        /**
     1006         * Create a zip archive of the plugin/theme being upgraded into a rollback directory.
     1007         *
     1008         * @since 5.7.0
     1009         * @uses 'upgrader_pre_install' filter.
     1010         *
     1011         * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
     1012         * @param  bool               $true          Boolean response to 'upgrader_pre_install' filter.
     1013         *                                           Default is true.
     1014         * @param  array              $hook_extra    Array of data for plugin/theme being updated.
     1015         *
     1016         * @return bool
     1017         */
     1018        public function zip_to_rollback_dir( $true, $hook_extra ) {
     1019                global $wp_filesystem;
     1020
     1021                $rollback_dir = $wp_filesystem->wp_content_dir() . 'upgrade/rollback/';
     1022                $type         = key( $hook_extra );
     1023                $slug         = 'plugin' === $type ? dirname( $hook_extra['plugin'] ) : $hook_extra['theme'];
     1024                $src          = 'plugin' === $type ? WP_PLUGIN_DIR . "/{$slug}" : get_theme_root(). "/{$slug}";
     1025                if ( $wp_filesystem->mkdir( $rollback_dir ) ) {
     1026                        $path_prefix = strlen( $src ) + 1;
     1027                        $zip         = new ZipArchive();
     1028
     1029                        if ( true === $zip->open( "{$rollback_dir}{$slug}.zip", ZipArchive::CREATE | ZipArchive::OVERWRITE ) ) {
     1030                                $files = new RecursiveIteratorIterator(
     1031                                        new RecursiveDirectoryIterator( $src ),
     1032                                        RecursiveIteratorIterator::LEAVES_ONLY
     1033                                );
     1034
     1035                                foreach ( $files as $name => $file ) {
     1036                                        // Skip directories (they would be added automatically).
     1037                                        if ( ! $file->isDir() ) {
     1038                                                // Get real and relative path for current file.
     1039                                                $file_path     = $file->getRealPath();
     1040                                                $relative_path = substr( $file_path, $path_prefix );
     1041
     1042                                                // Add current file to archive.
     1043                                                $zip->addFile( $file_path, $relative_path );
     1044                                        }
     1045                                }
     1046
     1047                                $zip->close();
     1048                        }
     1049                }
     1050
     1051                return $true;
     1052        }
     1053
     1054        /**
     1055         * Extract zipped rollback to original location.
     1056         *
     1057         * @since 5.7.0
     1058         *
     1059         * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
     1060         * @param string              $destination   File path of plugin/theme.
     1061         * @param  array              $hook_extra    Array of data for plugin/theme being updated.
     1062         * @param WP_Error            $error         WP_Error object.
     1063         *
     1064         * @return bool
     1065         */
     1066        public function extract_rollback( $destination, $hook_extra, $error ) {
     1067                global $wp_filesystem;
     1068
     1069                $rollback_dir = $wp_filesystem->wp_content_dir() . 'upgrade/rollback/';
     1070                $type         = key( $hook_extra );
     1071                $slug         = 'plugin' === $type ? dirname( $hook_extra['plugin'] ) : $hook_extra['theme'];
     1072                $src          = 'plugin' === $type ? WP_PLUGIN_DIR . "/{$slug}" : get_theme_root() . "/{$slug}";
     1073                $rollback     = $rollback_dir . "{$slug}.zip";
     1074
     1075                $zip = new \ZipArchive();
     1076                if ( true === $zip->open( "$rollback", ZipArchive::CHECKCONS ) ) {
     1077                        $zip->extractTo( "$destination" );
     1078                        $zip->close();
     1079
     1080                        return true;
     1081                }
     1082
     1083                return false;
     1084        }
    9401085}
    9411086
    9421087/** Plugin_Upgrader class */