Make WordPress Core

Ticket #34676: 34676.2.patch

File 34676.2.patch, 49.1 KB (added by jipmoors, 4 years ago)

Refreshed patch

  • src/js/_enqueues/admin/common.js

    diff --git src/js/_enqueues/admin/common.js src/js/_enqueues/admin/common.js
    index 2fc0c38828..84208a0268 100644
    $document.ready( function() { 
    15691569                 * notice. Make sure it gets moved just the first time.
    15701570                 */
    15711571                if ( ! $progressDiv.hasClass( 'update-details-moved' ) ) {
    1572                         $progressDiv.insertAfter( $updateNotice ).addClass( 'update-details-moved' );
     1572                        $progressDiv.appendTo( $updateNotice ).addClass( 'update-details-moved' );
    15731573                }
    15741574
    15751575                // Toggle the progress div visibility.
  • src/wp-admin/css/common.css

    diff --git src/wp-admin/css/common.css src/wp-admin/css/common.css
    index 868978d55f..e475c0aa54 100644
    code { 
    554554        margin-left: 0;
    555555}
    556556
     557.update-php .update-maintenance-start {
     558        margin-top: 30px;
     559}
     560.update-php .update-maintenance-content {
     561        border-left: 2px dashed #aaa;
     562        padding: 1px 0 20px 20px;
     563        margin: -10px 0;
     564}
     565.update-php .update-maintenance-end {
     566        margin-bottom: 30px;
     567}
     568
    557569.no-js .widefat thead .check-column input,
    558570.no-js .widefat tfoot .check-column input {
    559571        display: none;
  • src/wp-admin/includes/class-bulk-plugin-upgrader-skin.php

    diff --git src/wp-admin/includes/class-bulk-plugin-upgrader-skin.php src/wp-admin/includes/class-bulk-plugin-upgrader-skin.php
    index a568d6b107..9e8fe2f69b 100644
    class Bulk_Plugin_Upgrader_Skin extends Bulk_Upgrader_Skin { 
    2222                parent::add_strings();
    2323                /* translators: 1: name of plugin being updated, 2: number of updating plugin, 3: total number of plugins being updated */
    2424                $this->upgrader->strings['skin_before_update_header'] = __( 'Updating Plugin %1$s (%2$d/%3$d)' );
     25                $this->upgrader->strings['bulk_download']             = __( 'Downloading plugin installers.' );
    2526        }
    2627
    2728        /**
    28          * @param string $title
     29         * Outputs copy before workload output.
     30         *
     31         * @param string $title Title or string identifier to use.
     32         *
     33         * @return void
    2934         */
    3035        public function before( $title = '' ) {
    31                 parent::before( $this->plugin_info['Title'] );
     36                $title = ( $title === '' ) ? $this->plugin_info['Title'] : $title;
     37                parent::before( $title );
    3238        }
    3339
    3440        /**
    35          * @param string $title
     41         * Outputs copy after workload output.
     42         *
     43         * @param string $title Title or string identifier to use.
     44         *
     45         * @return void
    3646         */
    3747        public function after( $title = '' ) {
    38                 parent::after( $this->plugin_info['Title'] );
     48                $title = ( $title === '' ) ? $this->plugin_info['Title'] : $title;
     49                parent::after( $title );
    3950                $this->decrement_update_count( 'plugin' );
    4051        }
    4152
    4253        /**
     54         * Outputs copy after bulk actions are all done.
     55         *
     56         * @return void
    4357         */
    4458        public function bulk_footer() {
    4559                parent::bulk_footer();
  • src/wp-admin/includes/class-bulk-theme-upgrader-skin.php

    diff --git src/wp-admin/includes/class-bulk-theme-upgrader-skin.php src/wp-admin/includes/class-bulk-theme-upgrader-skin.php
    index ce426e0154..3c4d69ffe6 100644
     
    1616 * @see Bulk_Upgrader_Skin
    1717 */
    1818class Bulk_Theme_Upgrader_Skin extends Bulk_Upgrader_Skin {
    19         public $theme_info = array(); // Theme_Upgrader::bulk_upgrade() will fill this in.
     19        /**
     20         * Theme information, which will be filled by Theme_Upgrader::bulk_upgrade()
     21         * @var array
     22         */
     23        public $theme_info = array();
    2024
     25        /**
     26         * Registers strings that will be used.
     27         *
     28         * @return void
     29         */
    2130        public function add_strings() {
    2231                parent::add_strings();
    2332                /* translators: 1: name of theme being updated, 2: number of updating themes, 3: total number of themes being updated */
    2433                $this->upgrader->strings['skin_before_update_header'] = __( 'Updating Theme %1$s (%2$d/%3$d)' );
     34                $this->upgrader->strings['bulk_download']             = __( 'Downloading theme installers.' );
    2535        }
    2636
    2737        /**
    28          * @param string $title
     38         * Outputs copy before workload output.
     39         *
     40         * @param string $title Title or string identifier to use.
     41         *
     42         * @return void
    2943         */
    3044        public function before( $title = '' ) {
    31                 parent::before( $this->theme_info->display( 'Name' ) );
     45                $title = ( $title === '' ) ? $this->theme_info->display( 'Name' ) : $title;
     46                parent::before( $title );
    3247        }
    3348
    3449        /**
    35          * @param string $title
     50         * Outputs copy after workload output.
     51         *
     52         * @param string $title Title or string identifier to use.
     53         *
     54         * @return void
    3655         */
    3756        public function after( $title = '' ) {
    38                 parent::after( $this->theme_info->display( 'Name' ) );
     57                $title = ( $title === '' ) ? $this->theme_info->display( 'Name' ) : $title;
     58                parent::after( $title );
    3959                $this->decrement_update_count( 'theme' );
    4060        }
    4161
    4262        /**
     63         * Outputs copy after bulk actions are all done.
     64         *
     65         * @return void
    4366         */
    4467        public function bulk_footer() {
    4568                parent::bulk_footer();
  • new file src/wp-admin/includes/class-bulk-upgrade-element-base.php

    diff --git src/wp-admin/includes/class-bulk-upgrade-element-base.php src/wp-admin/includes/class-bulk-upgrade-element-base.php
    new file mode 100644
    index 0000000000..b950d94c71
    - +  
     1<?php
     2
     3/**
     4 * Abstract base class for Bulk Upgrade Elements
     5 *
     6 * @since x.x
     7 */
     8abstract class WP_Bulk_Upgrade_Element_Base {
     9        /**
     10         * Is this element already up-to-date
     11         *
     12         * @var bool
     13         */
     14        protected $up_to_date = false;
     15        /**
     16         * Has the package been downloaded
     17         *
     18         * @var bool
     19         */
     20        protected $downloaded = false;
     21        /**
     22         * Was the package unpacked properly
     23         *
     24         * @var bool
     25         */
     26        protected $unpacked = false;
     27        /**
     28         * Has the package been installed
     29         *
     30         * @var bool
     31         */
     32        protected $installed = false;
     33
     34        /**
     35         * The verification status of a download
     36
     37         * @var bool|WP_Error
     38         */
     39        protected $download_verification_result = false;
     40
     41        /**
     42         * Identifier for this element (source)
     43         *
     44         * @var mixed
     45         */
     46        protected $name;
     47        /**
     48         * Upgrader to use
     49         *
     50         * @var WP_Upgrader
     51         */
     52        protected $upgrader;
     53
     54        /**
     55         * Options of current element, used throughout the process
     56         *
     57         * @var array
     58         */
     59        protected $options;
     60        /**
     61         * Info about the current element, used by the upgrader
     62         *
     63         * @var mixed
     64         */
     65        protected $info;
     66        /**
     67         * Name of the download
     68         *
     69         * @var string
     70         */
     71        protected $download;
     72        /**
     73         * Working dir for the unpacked package
     74         *
     75         * @var string
     76         */
     77        protected $working_dir;
     78
     79        /**
     80         * Final result of installation (via upgrader)
     81         *
     82         * @var mixed
     83         */
     84        protected $result;
     85
     86        /**
     87         * WP_Bulk_Upgrader_Element constructor.
     88         *
     89         * @param WP_Upgrader $upgrader
     90         * @param mixed       $name
     91         *
     92         * @since x.x
     93         * @access public
     94         */
     95        public function __construct( $name, WP_Upgrader $upgrader ) {
     96                $this->name     = $name;
     97                $this->upgrader = $upgrader;
     98        }
     99
     100        /**
     101         * Retrievs the original identifier data.
     102         *
     103         * @return mixed
     104         *
     105         * @since x.x
     106         * @access public
     107         */
     108        public function get_name() {
     109                return $this->name;
     110        }
     111
     112        /**
     113         * Retrieves the cummulated result of the upgrade.
     114         *
     115         * @return bool
     116         *
     117         * @since x.x
     118         * @access public
     119         */
     120        public function get_result() {
     121                return isset( $this->result ) ? $this->result : $this->installed;
     122        }
     123
     124        /**
     125         * Retrieves the result index for the current result.
     126         *
     127         * @return bool|int
     128         *
     129         * @since x.x
     130         * @access public
     131         */
     132        public function get_result_index() {
     133                return false;
     134        }
     135
     136        /**
     137         * Determines if it is active in the system.
     138         *
     139         * @return boolean
     140         *
     141         * @since x.x
     142         * @access public
     143         */
     144        abstract public function is_active();
     145
     146        /**
     147         * Determines if it is downloaded correctly.
     148         *
     149         * @return bool
     150         *
     151         * @since x.x
     152         * @access public
     153         */
     154        public function is_downloaded() {
     155                return $this->downloaded;
     156        }
     157
     158        /**
     159         * Determines if it is unpacked succesfully.
     160         *
     161         * @return bool
     162         *
     163         * @since x.x
     164         * @access public
     165         */
     166        public function is_unpacked() {
     167                return $this->unpacked;
     168        }
     169
     170        /**
     171         * Determines if it is installed succesfully.
     172         *
     173         * @return bool
     174         *
     175         * @since x.x
     176         * @access public
     177         */
     178        public function is_installed() {
     179                return $this->installed;
     180        }
     181
     182        /**
     183         * Determines if it is already up-to-date.
     184         *
     185         * @return bool
     186         *
     187         * @since x.x
     188         * @access public
     189         */
     190        public function is_up_to_date() {
     191                return $this->up_to_date;
     192        }
     193
     194        /**
     195         * Retrieves element info.
     196         *
     197         * @return mixed
     198         *
     199         * @since x.x
     200         * @access public
     201         */
     202        public function get_info() {
     203                return $this->info;
     204        }
     205
     206        /**
     207         * Applies defaults and filter to options.
     208         *
     209         * @param array $options Options to use.
     210         * @retun void
     211         *
     212         * @since x.x
     213         * @access protected
     214         */
     215        protected function set_options( $options ) {
     216                $defaults = array(
     217                        'package'                     => '',
     218                        // Please always pass this.
     219                        'destination'                 => '',
     220                        // And this
     221                        'clear_destination'           => false,
     222                        'abort_if_destination_exists' => true,
     223                        // Abort if the Destination directory exists, Pass clear_destination as false please
     224                        'clear_working'               => true,
     225                        'is_multi'                    => false,
     226                        'hook_extra'                  => array()
     227                        // Pass any extra $hook_extra args here, this will be passed to any hooked filters.
     228                );
     229
     230                $options = wp_parse_args( $options, $defaults );
     231
     232                /** This filter is documented in wp-admin/includes/class-wp-upgrader.php */
     233                $this->options = apply_filters( 'upgrader_package_options', $options );
     234        }
     235
     236        /**
     237         * Download this element.
     238         *
     239         * @return bool|string|WP_Error
     240         *
     241         * @since x.x
     242         * @access public
     243         */
     244        public function download() {
     245                if ( $this->is_up_to_date() ) {
     246                        return false;
     247                }
     248
     249                // Connect to the Filesystem first.
     250                $result = $this->upgrader->fs_connect( array( WP_CONTENT_DIR, $this->options['destination'] ) );
     251                // Mainly for non-connected filesystem.
     252                if ( ! $result || is_wp_error( $result ) ) {
     253                        return $result;
     254                }
     255
     256                $this->download_verification_result = true;
     257
     258                /*
     259                 * Download the package (Note, This just returns the filename
     260                 * of the file if the package is a local file)
     261                 */
     262                $result = $this->upgrader->download_package( $this->options['package'], true );
     263
     264                if ( ! is_wp_error( $result ) ) {
     265                        $this->downloaded = true;
     266                        $this->download   = $result;
     267                } else {
     268                        $filename = $result->get_error_data( 'softfail-filename' );
     269                        if ( $filename ) {
     270                                $this->download_verification_result = $result;
     271
     272                                $result = $filename;
     273
     274                                $this->downloaded = true;
     275                                $this->download   = $result;
     276                        }
     277                }
     278
     279                return $result;
     280        }
     281
     282        /**
     283         * Unpacks this element.
     284         *
     285         * @return bool|string|WP_Error
     286         *
     287         * @since x.x
     288         * @access public
     289         */
     290        public function unpack() {
     291                if ( ! $this->is_downloaded() ) {
     292                        return false;
     293                }
     294
     295                // Do not delete a "local" file
     296                $delete_package = ( $this->download !== $this->options['package'] );
     297
     298                // Unzips the file into a temporary directory.
     299                $result = $this->upgrader->unpack_package( $this->download, $delete_package );
     300                if ( ! is_wp_error( $result ) ) {
     301                        $this->unpacked    = true;
     302                        $this->working_dir = $result;
     303                }
     304
     305                return $result;
     306        }
     307
     308        /**
     309         * Installs this element.
     310         *
     311         * @return array|bool|WP_Error
     312         *
     313         * @since x.x
     314         * @access public
     315         */
     316        public function install() {
     317                if ( ! $this->is_unpacked() ) {
     318                        return false;
     319                }
     320
     321                // With the given options, this installs it to the destination directory.
     322                $result = $this->upgrader->install_package( array(
     323                        'source'                      => $this->working_dir,
     324                        'destination'                 => $this->options['destination'],
     325                        'clear_destination'           => $this->options['clear_destination'],
     326                        'abort_if_destination_exists' => $this->options['abort_if_destination_exists'],
     327                        'clear_working'               => $this->options['clear_working'],
     328                        'hook_extra'                  => $this->options['hook_extra']
     329                ) );
     330
     331                $this->result = $this->upgrader->result;
     332
     333                return $result;
     334        }
     335
     336        /**
     337         * Retrieves the verification result status.
     338         *
     339         * @return bool|WP_Error
     340         *
     341         * @since  x.x
     342         * @access public
     343         */
     344        public function get_verification_result() {
     345                return $this->download_verification_result;
     346        }
     347}
  • new file src/wp-admin/includes/class-bulk-upgrade-repository-element-base.php

    diff --git src/wp-admin/includes/class-bulk-upgrade-repository-element-base.php src/wp-admin/includes/class-bulk-upgrade-repository-element-base.php
    new file mode 100644
    index 0000000000..7fe211574c
    - +  
     1<?php
     2
     3/**
     4 * Abstract base class for Bulk Upgrade Elements that are formatted as Plugin/Theme
     5 *
     6 * @since x.x
     7 */
     8abstract class WP_Bulk_Upgrade_Repository_Element_Base extends WP_Bulk_Upgrade_Element_Base {
     9        /**
     10         * Cache for current element type information.
     11         *
     12         * @var object
     13         */
     14        protected static $current;
     15
     16        /**
     17         * Current element response information from repository.
     18         *
     19         * @var object
     20         */
     21        protected $response;
     22
     23        /**
     24         * Retrieves the result index for the current item.
     25         *
     26         * @return mixed
     27         *
     28         * @since  x.x
     29         * @access public
     30         */
     31        public function get_result_index() {
     32                return $this->name;
     33        }
     34
     35        /**
     36         * Retrieves the current item.
     37         *
     38         * @return mixed
     39         *
     40         * @since x.x
     41         * @access protected
     42         */
     43        abstract protected function get_current();
     44
     45        /**
     46         * Retrieves plugin repository response.
     47         *
     48         * @return bool|object Response from the respository as stdClass
     49         *
     50         * @since  x.x
     51         * @access protected
     52         */
     53        protected function get_response() {
     54                $current = $this->get_current();
     55
     56                if ( is_object( $current ) && is_array( $current->response ) ) {
     57                        return $this->response = isset( $current->response[ $this->name ] ) ? $current->response[ $this->name ] : false;
     58                }
     59
     60                return false;
     61        }
     62}
  • new file src/wp-admin/includes/class-bulk-upgrader-base.php

    diff --git src/wp-admin/includes/class-bulk-upgrader-base.php src/wp-admin/includes/class-bulk-upgrader-base.php
    new file mode 100644
    index 0000000000..2926167749
    - +  
     1<?php
     2
     3/**
     4 * Abstract base class for Bulk Upgrades
     5 *
     6 * @since x.x
     7 */
     8abstract class WP_Bulk_Upgrader_Base {
     9        /**
     10         * Upgrader to use.
     11         *
     12         * @var WP_Upgrader
     13         */
     14        protected $upgrader;
     15
     16        /**
     17         * Elements to upgrade.
     18         *
     19         * @var WP_Bulk_Upgrade_Element_Base[]
     20         */
     21        protected $elements = array();
     22
     23        /**
     24         * WP_Bulk_Upgrader_Composite constructor.
     25         *
     26         * @param WP_Upgrader $upgrader     Upgrader to report back to
     27         * @param array       $elements     List of elements to be bulked.
     28         * @param string      $elementClass Class name to wrap elements in. Extended of WP_Bulk_Upgrader_Element.
     29         *
     30         * @since  x.x
     31         * @access public
     32         */
     33        public function __construct( WP_Upgrader $upgrader, array $elements, $elementClass ) {
     34                if ( ! is_string( $elementClass ) ) {
     35                        throw new InvalidArgumentException( 'Expected element class to be string, got ' . gettype( $elementClass ) );
     36                }
     37
     38                if ( ! class_exists( $elementClass ) ) {
     39                        throw new InvalidArgumentException( sprintf( 'Element class "%s" does not exist.', $elementClass ) );
     40                }
     41
     42                $this->upgrader = $upgrader;
     43
     44                if ( array() !== $elements ) {
     45                        foreach ( $elements as $element ) {
     46                                $this->elements[] = new $elementClass( $element, $upgrader );
     47                        }
     48                }
     49
     50                $this->upgrader->update_count   = count( $this->elements );
     51                $this->upgrader->update_current = 0;
     52        }
     53
     54        /**
     55         * Runs the bulk upgrade.
     56         *
     57         * @return array List of results.
     58         *
     59         * @since x.x
     60         * @access public
     61         */
     62        public function run() {
     63                $this->upgrader->clean_upgrade_folder();
     64
     65                $this->check_up_to_date( $this->elements );
     66
     67                // Get all elements that have an upgrade.
     68                $upgradable_elements = $this->get_upgradable_elements( $this->elements );
     69
     70                // Download and unpack all items with upgrades.
     71                $this->prepare_upgrade( $upgradable_elements );
     72
     73                // On multisite it is hard to determine if a plugin is active on a sub-site or not - assume all are active.
     74                if ( is_multisite() ) {
     75                        $this->upgrade( $upgradable_elements, true );
     76                }
     77
     78                if ( ! is_multisite() ) {
     79                        // Get all non-active elements - these don't need maintenance mode enabled.
     80                        $inactive_elements = $this->get_inactive_elements( $upgradable_elements );
     81                        if ( $inactive_elements ) {
     82                                $this->upgrade( $inactive_elements, false );
     83                        }
     84
     85                        // Get all active elements - these need maintenance mode enabled.
     86                        $active_elements = $this->get_active_elements( $upgradable_elements );
     87                        if ( $active_elements ) {
     88                                $this->upgrade( $active_elements, true );
     89                        }
     90                }
     91
     92                $this->upgrader->update_current = false;
     93
     94                return $this->get_results();
     95        }
     96
     97        /**
     98         * Prepare download and unpack before installing.
     99         *
     100         * @param WP_Bulk_Upgrade_Element_Base[] $elements List of elements to prepare.
     101         *
     102         * @return void
     103         *
     104         * @since  x.x
     105         * @access protected
     106         */
     107        protected function prepare_upgrade( $elements ) {
     108                $skin = $this->get_skin();
     109
     110                $skin->before( 'bulk_download' );
     111                $this->download( $elements );
     112                $skin->set_result(true);
     113                $skin->after( 'bulk_download' );
     114
     115                $skin->before( 'bulk_unpack' );
     116                $this->unpack( $elements );
     117                $skin->after( 'bulk_unpack' );
     118        }
     119
     120        /**
     121         * Upgrades a list of elements.
     122         *
     123         * @param WP_Bulk_Upgrade_Element_Base[] $elements         Elements to upgrade.
     124         * @param boolean                        $maintenance_mode Enable maintenance mode.
     125         *
     126         * @return void
     127         *
     128         * @since  x.x
     129         * @access protected
     130         */
     131        protected function upgrade( $elements, $maintenance_mode ) {
     132                if ( $maintenance_mode ) {
     133                        $this->upgrader->maintenance_mode( true );
     134                }
     135
     136                $this->install( $elements );
     137
     138                if ( $maintenance_mode ) {
     139                        $this->upgrader->maintenance_mode( false );
     140                }
     141        }
     142
     143        /**
     144         * Downloads all the elements.
     145         *
     146         * @param WP_Bulk_Upgrade_Element_Base[] $elements
     147         *
     148         * @return void
     149         *
     150         * @since  x.x
     151         * @access protected
     152         */
     153        protected function download( array $elements ) {
     154                /** @var $element WP_Bulk_Upgrade_Element_Base */
     155                foreach ( $elements as $element ) {
     156                        $this->set_current_element( $element );
     157
     158                        $result = $element->download();
     159                        if ( is_wp_error( $result ) ) {
     160                                $this->show_error( $result, $element );
     161                                break;
     162                        }
     163
     164                        if ( is_wp_error( $element->get_verification_result() ) ) {
     165                                $this->show_warning( $element->get_verification_result(), $element );
     166                        }
     167                }
     168        }
     169
     170        /**
     171         * Unpacks downloaded elements.
     172         *
     173         * @param WP_Bulk_Upgrade_Element_Base[] $elements Elements to unpack.
     174         *
     175         * @return void
     176         *
     177         * @since  x.x
     178         * @access protected
     179         */
     180        protected function unpack( array $elements ) {
     181                /** @var $element WP_Bulk_Upgrade_Element_Base */
     182                foreach ( $elements as $element ) {
     183                        $this->set_current_element( $element );
     184
     185                        $result = $element->unpack();
     186                        if ( is_wp_error( $result ) ) {
     187                                $this->show_error( $result, $element );
     188                        }
     189                }
     190        }
     191
     192        /**
     193         * Installs elements.
     194         *
     195         * @param WP_Bulk_Upgrade_Element_Base[] $elements Elements to install.
     196         *
     197         * @return void
     198         *
     199         * @since  x.x
     200         * @access protected
     201         */
     202        protected function install( array $elements ) {
     203                foreach ( $elements as $element ) {
     204                        $this->set_current_element( $element );
     205
     206                        $skin = $this->get_skin();
     207                        $skin->before();
     208
     209                        $result = $element->install();
     210
     211                        $skin->set_result( $result );
     212                        if ( is_wp_error( $result ) ) {
     213                                $skin->error( $result );
     214                                $skin->feedback( 'process_failed' );
     215                        } else {
     216                                // Install succeeded.
     217                                $skin->feedback( 'process_success' );
     218                        }
     219                        $skin->after();
     220
     221                        if ( is_wp_error( $result ) && $this->abort_on_error() ) {
     222                                break;
     223                        }
     224                }
     225
     226                $this->clear_current_element();
     227        }
     228
     229        /**
     230         * Retrieves the elements that have an upgrade available.
     231         *
     232         * @param WP_Bulk_Upgrade_Element_Base[] $elements List of elements to filter.
     233         *
     234         * @return array Filtered list of elements with an upgrade.
     235         *
     236         * @since  x.x
     237         * @access protected
     238         */
     239        protected function get_upgradable_elements( array $elements ) {
     240                return array_filter( $elements, array( $this, 'is_upgradable' ) );
     241        }
     242
     243        /**
     244         * Determines if an element has an update.
     245         *
     246         * @param WP_Bulk_Upgrade_Element_Base $element Element to check.
     247         *
     248         * @return bool True if an upgrade is available, otherwise False.
     249         *
     250         * @since  x.x
     251         * @access protected
     252         */
     253        protected function is_upgradable( WP_Bulk_Upgrade_Element_Base $element ) {
     254                return ! $element->is_up_to_date();
     255        }
     256
     257        /**
     258         * Retrieves the elements that are not active.
     259         *
     260         * @param WP_Bulk_Upgrade_Element_Base[] $elements Elements to check.
     261         *
     262         * @return array Filtered list of elements that are not active.
     263         *
     264         * @since  x.x
     265         * @access protected
     266         */
     267        protected function get_inactive_elements( array $elements ) {
     268                return array_filter( $elements, array( $this, 'is_inactive') );
     269        }
     270
     271        /**
     272         * Determines if an element is active.
     273         *
     274         * @param WP_Bulk_Upgrade_Element_Base $element Element to check.
     275         *
     276         * @return bool True if the element is not active, False otherwise.
     277         *
     278         * @since  x.x
     279         * @access protected
     280         */
     281        protected function is_inactive( WP_Bulk_Upgrade_Element_Base $element ) {
     282                return ! $element->is_active();
     283        }
     284
     285        /**
     286         * Retrieves a list of active elements.
     287         *
     288         * @param WP_Bulk_Upgrade_Element_Base[] $elements Elements to check.
     289         *
     290         * @return array Filtered list of elements that are active.
     291         *
     292         * @since  x.x
     293         * @access protected
     294         */
     295        protected function get_active_elements( array $elements ) {
     296                return array_filter( $elements, array( $this, 'is_active' ) );
     297        }
     298
     299        /**
     300         * Determines if an element is active.
     301         *
     302         * @param WP_Bulk_Upgrade_Element_Base $element Element to check.
     303         *
     304         * @return bool True if the element is active, False otherwise.
     305         *
     306         * @since  x.x
     307         * @access protected
     308         */
     309        protected function is_active( WP_Bulk_Upgrade_Element_Base $element ) {
     310                return $element->is_active();
     311        }
     312
     313        /**
     314         * Set the current element as active on the upgrader
     315         *
     316         * @param mixed $element
     317         *
     318         * @return int Current index.
     319         *
     320         * @since  x.x
     321         * @access protected
     322         */
     323        protected function set_current_element( $element ) {
     324                $index = array_search( $element, $this->elements, true );
     325
     326                if ( false === $index ) {
     327                        $this->upgrader->update_current = false;
     328                }
     329
     330                if ( false !== $index ) {
     331                        $this->upgrader->update_current = $index + 1;
     332                }
     333
     334                return $this->upgrader->update_current;
     335        }
     336
     337        /**
     338         * Removes the current element.
     339         *
     340         * @return void
     341         *
     342         * @since  x.x
     343         * @access protected
     344         */
     345        protected function clear_current_element() {
     346                $this->upgrader->update_current = false;
     347        }
     348
     349        /**
     350         * Checks if any of the elements is already up to date.
     351         *
     352         * @param WP_Bulk_Upgrade_Element_Base[] $elements Elements to check.
     353         *
     354         * @return void
     355         *
     356         * @since  x.x
     357         * @access protected
     358         */
     359        protected function check_up_to_date( array $elements ) {
     360                /** @var $element WP_Bulk_Upgrade_Element_Base */
     361                foreach ( $elements as $element ) {
     362                        if ( $element->is_up_to_date() ) {
     363                                $this->set_current_element( $element );
     364
     365                                $this->handle_up_to_date( $element );
     366
     367                                $skin = $this->get_skin();
     368                                $skin->feedback( 'up_to_date' );
     369                                $skin->after();
     370                        }
     371                }
     372        }
     373
     374        /**
     375         * Handles what to do when an element is already up to date.
     376         *
     377         * @param WP_Bulk_Upgrade_Element_Base $element Relevant element.
     378         *
     379         * @return void
     380         *
     381         * @since x.x
     382         * @access protected
     383         */
     384        abstract protected function handle_up_to_date( WP_Bulk_Upgrade_Element_Base $element );
     385
     386        /**
     387         * Retrieves the results of the upgrade process.
     388         *
     389         * @return array List of results.
     390         *
     391         * @since  x.x
     392         * @access protected
     393         */
     394        protected function get_results() {
     395                $results = array();
     396
     397                /** @var $element WP_Bulk_Upgrade_Element_Base */
     398                foreach ( $this->elements as $element ) {
     399                        $index = $element->get_result_index();
     400                        if ( false === $index ) {
     401                                $results[] = $element->get_result();
     402                        } else {
     403                                $results[ $index ] = $element->get_result();
     404                        }
     405                }
     406
     407                return $results;
     408        }
     409
     410        /**
     411         * Passes an error to the skin.
     412         *
     413         * @param string                       $error
     414         * @param WP_Bulk_Upgrade_Element_Base $element
     415         *
     416         * @return void
     417         *
     418         * @since  x.x
     419         * @access protected
     420         */
     421        protected function show_error( $error, WP_Bulk_Upgrade_Element_Base $element ) {
     422                $this->set_current_element( $element );
     423
     424                $skin = $this->get_skin();
     425                if ( $skin ) {
     426                        $skin->error( $error );
     427                        $skin->after();
     428                }
     429        }
     430
     431        /**
     432         * Passes a warning to the skin.
     433         *
     434         * @param WP_Error                     $warning Warning to show.
     435         * @param WP_Bulk_Upgrade_Element_Base $element Relevant element.
     436         *
     437         * @return void
     438         *
     439         * @since  x.x
     440         * @access protected
     441         */
     442        protected function show_warning( WP_Error $warning, WP_Bulk_Upgrade_Element_Base $element ) {
     443                $this->set_current_element( $element );
     444
     445                $skin = $this->get_skin();
     446                if ( $skin ) {
     447                        foreach ( $warning->get_error_messages() as $message ) {
     448                                if ( $warning->get_error_data() && is_string( $warning->get_error_data() ) ) {
     449                                        $skin->feedback( $message . ' ' . esc_html( strip_tags( $warning->get_error_data() ) ) );
     450                                } else {
     451                                        $skin->feedback( $message );
     452                                }
     453                        }
     454                }
     455        }
     456
     457        /**
     458         * Determines if we should abort when encountering an error.
     459         *
     460         * @return bool
     461         *
     462         * @since  x.x
     463         * @access protected
     464         */
     465        protected function abort_on_error() {
     466                // Prevent credentials auth screen from displaying multiple times.
     467                return true;
     468        }
     469
     470        /**
     471         * Shorthand retrieval of upgrader skin.
     472         *
     473         * @return WP_Upgrader_Skin
     474         *
     475         * @since  x.x
     476         * @access protected
     477         */
     478        protected function get_skin() {
     479                return $this->upgrader->get_skin();
     480        }
     481}
  • src/wp-admin/includes/class-bulk-upgrader-skin.php

    diff --git src/wp-admin/includes/class-bulk-upgrader-skin.php src/wp-admin/includes/class-bulk-upgrader-skin.php
    index c1454e62f1..16028a5f34 100644
     
    1616 * @see WP_Upgrader_Skin
    1717 */
    1818class Bulk_Upgrader_Skin extends WP_Upgrader_Skin {
     19        /**
     20         * Are we in an install/upgrade loop.
     21         *
     22         * @var bool
     23         */
    1924        public $in_loop = false;
     25
    2026        /**
     27         * Did we encounter an error while installing/upgrading.
     28         *
    2129         * @var string|false
    2230         */
    2331        public $error = false;
    2432
    2533        /**
    26          * @param array $args
     34         * @param array $args Arguments used for this skin.
    2735         */
    2836        public function __construct( $args = array() ) {
    2937                $defaults = array(
    class Bulk_Upgrader_Skin extends WP_Upgrader_Skin { 
    3644        }
    3745
    3846        /**
     47         * Register the strings that we need.
     48         *
     49         * @return void
    3950         */
    4051        public function add_strings() {
    4152                $this->upgrader->strings['skin_upgrade_start'] = __( 'The update process is starting. This process may take a while on some hosts, so please be patient.' );
    class Bulk_Upgrader_Skin extends WP_Upgrader_Skin { 
    4657                /* translators: %s: Title of an update */
    4758                $this->upgrader->strings['skin_update_successful'] = __( '%s updated successfully.' );
    4859                $this->upgrader->strings['skin_upgrade_end']       = __( 'All updates have been completed.' );
     60                $this->upgrader->strings['bulk_download']          = __( 'Downloading items.' );
     61                $this->upgrader->strings['bulk_unpack']            = __( 'Unpacking downloaded installers.' );
    4962        }
    5063
    5164        /**
    52          * @param string $string
     65         * Outputs feedback.
     66         *
     67         * @param string $string Text to show.
     68         *
     69         * @return void
    5370         */
    5471        public function feedback( $string ) {
     72                $original_string = $string;
     73
    5574                if ( isset( $this->upgrader->strings[ $string ] ) ) {
    5675                        $string = $this->upgrader->strings[ $string ];
    5776                }
    class Bulk_Upgrader_Skin extends WP_Upgrader_Skin { 
    6584                                $string = vsprintf( $string, $args );
    6685                        }
    6786                }
     87
    6888                if ( empty( $string ) ) {
    6989                        return;
    7090                }
    71                 if ( $this->in_loop ) {
    72                         echo "$string<br />\n";
     91
     92                if ( $original_string === 'maintenance_start' ) {
     93                        printf( '<p class="update-maintenance-start"><strong>%s</strong></p><div class="update-maintenance-content">', $string );
     94                } elseif( $original_string === 'maintenance_end' ) {
     95                        printf( '</div><p class="update-maintenance-end"><strong>%s</strong></p>', $string );
    7396                } else {
    74                         echo "<p>$string</p>\n";
     97                        if ( $this->in_loop ) {
     98                                $string = "$string<br/>";
     99                        } else {
     100                                $string = "<p>$string</p>";
     101                        }
     102
     103                        echo "$string\n";
    75104                }
     105
     106                $this->flush_output();
    76107        }
    77108
    78109        /**
     110         * Outputs nothing, this will be displayed within a iframe.
     111         *
     112         * @return void
    79113         */
    80114        public function header() {
    81115                // Nothing, This will be displayed within a iframe.
    82116        }
    83117
    84118        /**
     119         * Outputs nothing, this will be displayed within a iframe.
     120         *
     121         * @return void
    85122         */
    86123        public function footer() {
    87124                // Nothing, This will be displayed within a iframe.
    88125        }
    89126
    90127        /**
    91          * @param string|WP_Error $error
     128         * Showns an error.
     129         *
     130         * @param string|WP_Error $error Error that will be shown.
    92131         */
    93132        public function error( $error ) {
    94133                if ( is_string( $error ) && isset( $this->upgrader->strings[ $error ] ) ) {
    class Bulk_Upgrader_Skin extends WP_Upgrader_Skin { 
    110149        }
    111150
    112151        /**
     152         * Shows the bulk header copy.
     153         *
     154         * @return void
    113155         */
    114156        public function bulk_header() {
    115157                $this->feedback( 'skin_upgrade_start' );
    116158        }
    117159
    118160        /**
     161         * Shows the bulk footer copy.
     162         *
     163         * @return void
    119164         */
    120165        public function bulk_footer() {
    121166                $this->feedback( 'skin_upgrade_end' );
    122167        }
    123168
    124169        /**
    125          * @param string $title
     170         * Shows an header for an element.
     171         * side-effect: Flushes the output buffer
     172         *
     173         * @param string $title Copy or string identifier to use.
     174         *
     175         * @return void
    126176         */
    127177        public function before( $title = '' ) {
    128178                $this->in_loop = true;
    129                 printf( '<h2>' . $this->upgrader->strings['skin_before_update_header'] . ' <span class="spinner waiting-' . $this->upgrader->update_current . '"></span></h2>', $title, $this->upgrader->update_current, $this->upgrader->update_count );
    130                 echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js( $this->upgrader->update_current ) . '\').css("display", "inline-block");</script>';
     179
     180                $format = $this->upgrader->strings['skin_before_update_header'];
     181
     182                $identifier = $this->upgrader->update_current;
     183                if ( isset( $this->upgrader->strings[ $title ] ) ) {
     184                        $identifier = $title;
     185                        $format = $this->upgrader->strings[ $title ];
     186                }
     187
     188                printf(
     189                        '<h2>' . $format . ' <span class="' . esc_attr( 'spinner waiting-' . $identifier ) . '"></span></h2>',
     190                        $title,
     191                        $this->upgrader->update_current,
     192                        $this->upgrader->update_count
     193                );
     194
     195                echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js( $identifier ) . '\').css("display", "inline-block");</script>';
    131196                // This progress messages div gets moved via JavaScript when clicking on "Show details.".
    132                 echo '<div class="update-messages hide-if-js" id="progress-' . esc_attr( $this->upgrader->update_current ) . '"><p>';
     197                echo '<div class="update-messages hide-if-js" id="' . esc_attr( 'progress-' . $identifier ) . '"><p>';
    133198                $this->flush_output();
    134199        }
    135200
    136201        /**
    137          * @param string $title
     202         * Shows a footer for an element.
     203         * side-effect: Flushes the output buffer
     204         *
     205         * @param string $title Copy or string identifier to use.
     206         *
     207         * @return void
    138208         */
    139209        public function after( $title = '' ) {
     210                $success_format = $this->upgrader->strings['skin_update_successful'];
     211                $error_format = $this->upgrader->strings['skin_update_failed_error'];
     212                $failed_format = $this->upgrader->strings['skin_update_failed'];
     213
     214                $identifier = $this->upgrader->update_current;
     215                if ( isset( $this->upgrader->strings[ $title ] ) ) {
     216                        $identifier = $title;
     217                        $title = $this->upgrader->strings[ $title ];
     218
     219                        $success_format = '';
     220                        $error_format = '%2$s';
     221                        $failed_format = '%s';
     222                }
     223
    140224                echo '</p></div>';
     225
    141226                if ( $this->error || ! $this->result ) {
    142227                        if ( $this->error ) {
    143                                 echo '<div class="error"><p>' . sprintf( $this->upgrader->strings['skin_update_failed_error'], $title, '<strong>' . $this->error . '</strong>' ) . '</p></div>';
     228                                echo '<div class="error"><p>' . sprintf( $error_format, $title, '<strong>' . $this->error . '</strong>' ) . '</p></div>';
    144229                        } else {
    145                                 echo '<div class="error"><p>' . sprintf( $this->upgrader->strings['skin_update_failed'], $title ) . '</p></div>';
     230                                echo '<div class="error"><p>' . sprintf( $failed_format, $title ) . '</p></div>';
    146231                        }
    147232
    148                         echo '<script type="text/javascript">jQuery(\'#progress-' . esc_js( $this->upgrader->update_current ) . '\').show();</script>';
     233                        echo '<script type="text/javascript">jQuery(\'#progress-' . esc_js( $identifier ) . '\').show();</script>';
    149234                }
     235
    150236                if ( $this->result && ! is_wp_error( $this->result ) ) {
    151237                        if ( ! $this->error ) {
    152                                 echo '<div class="updated js-update-details" data-update-details="progress-' . esc_attr( $this->upgrader->update_current ) . '">' .
    153                                         '<p>' . sprintf( $this->upgrader->strings['skin_update_successful'], $title ) .
     238                                echo '<div class="updated js-update-details" data-update-details="' . esc_attr( 'progress-' . $identifier ) . '">' .
     239                                        '<p>' . sprintf( $success_format, $title ) .
    154240                                        ' <button type="button" class="hide-if-no-js button-link js-update-details-toggle" aria-expanded="false">' . __( 'Show details.' ) . '</button>' .
    155241                                        '</p></div>';
    156242                        }
    class Bulk_Upgrader_Skin extends WP_Upgrader_Skin { 
    163249        }
    164250
    165251        /**
     252         * Resets the state of this class.
     253         *
     254         * @return void
    166255         */
    167256        public function reset() {
    168257                $this->in_loop = false;
    class Bulk_Upgrader_Skin extends WP_Upgrader_Skin { 
    170259        }
    171260
    172261        /**
     262         * Flushes the output buffer.
     263         *
     264         * @return void
    173265         */
    174266        public function flush_output() {
    175267                wp_ob_end_flush_all();
  • new file src/wp-admin/includes/class-plugin-bulk-upgrade-element.php

    diff --git src/wp-admin/includes/class-plugin-bulk-upgrade-element.php src/wp-admin/includes/class-plugin-bulk-upgrade-element.php
    new file mode 100644
    index 0000000000..a73d5b549e
    - +  
     1<?php
     2
     3/**
     4 * Plugin implementation of the Bulk Upgrade Element
     5 *
     6 * @since x.x
     7 */
     8class WP_Plugin_Bulk_Upgrade_Element extends WP_Bulk_Upgrade_Repository_Element_Base {
     9        /**
     10         * WP_Bulk_Upgrader_Plugin_Element constructor.
     11         *
     12         * @param string          $plugin   Current plugin
     13         * @param Plugin_Upgrader $upgrader Upgrader to use.
     14         *
     15         * @since  x.x
     16         * @access public
     17         */
     18        public function __construct( $plugin, Plugin_Upgrader $upgrader ) {
     19                parent::__construct( $plugin, $upgrader );
     20
     21                $this->info = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin, false, true );
     22
     23                $response = $this->get_response();
     24                if ( false === $response ) {
     25                        $this->up_to_date = true;
     26
     27                        return;
     28                }
     29
     30                $options = array(
     31                        'package'           => $response->package,
     32                        'destination'       => WP_PLUGIN_DIR,
     33                        'clear_destination' => true,
     34                        'clear_working'     => true,
     35                        'is_multi'          => true,
     36                        'hook_extra'        => array(
     37                                'plugin' => $plugin
     38                        )
     39                );
     40
     41                $this->set_options( $options );
     42        }
     43
     44        /**
     45         * Determines if this plugin is activated.
     46         *
     47         * @return bool
     48         *
     49         * @since  x.x
     50         * @access public
     51         */
     52        public function is_active() {
     53                return is_plugin_active( $this->name );
     54        }
     55
     56        /**
     57         * Retrieves information for the plugin from the `update_plugins` transient.
     58         *
     59         * @return mixed
     60         *
     61         * @since x.x
     62         * @access protected
     63         */
     64        protected function get_current() {
     65                if ( ! isset( self::$current ) ) {
     66                        self::$current = get_site_transient( 'update_plugins' );
     67                }
     68
     69                return self::$current;
     70        }
     71}
  • new file src/wp-admin/includes/class-plugin-bulk-upgrader.php

    diff --git src/wp-admin/includes/class-plugin-bulk-upgrader.php src/wp-admin/includes/class-plugin-bulk-upgrader.php
    new file mode 100644
    index 0000000000..27a2c8d24c
    - +  
     1<?php
     2
     3/**
     4 * Plugin Bulk Upgrader implementation
     5 *
     6 * @since x.x
     7 */
     8class WP_Plugin_Bulk_Upgrader extends WP_Bulk_Upgrader_Base {
     9        /**
     10         * WP_Plugin_Bulk_Upgrader constructor.
     11         *
     12         * @param Plugin_Upgrader $upgrader Upgrader to use.
     13         * @param array           $elements Elements to use.
     14         *
     15         * @since x.x
     16         * @access public
     17         */
     18        public function __construct( Plugin_Upgrader $upgrader, array $elements = array() ) {
     19                parent::__construct( $upgrader, $elements, 'WP_Plugin_Bulk_Upgrade_Element' );
     20        }
     21
     22        /**
     23         * Communicates result to skin.
     24         *
     25         * @param WP_Bulk_Upgrade_Element_Base $element Relevant element.
     26         *
     27         * @return void
     28         *
     29         * @since  x.x
     30         * @access public
     31         */
     32        public function handle_up_to_date( WP_Bulk_Upgrade_Element_Base $element ) {
     33                $skin = $this->get_skin();
     34                if ( $skin instanceof WP_Upgrader_Skin ) {
     35                        $skin->set_result( 'up_to_date' );
     36                }
     37        }
     38
     39        /**
     40         * Communicate plugin info to skin
     41         *
     42         * @param mixed $element
     43         *
     44         * @return void
     45         *
     46         * @since  x.x
     47         * @access protected
     48         */
     49        protected function set_current_element( $element ) {
     50                parent::set_current_element( $element );
     51
     52                if ( ! $this->upgrader->update_current ) {
     53                        return;
     54                }
     55
     56                $skin = $this->get_skin();
     57                $skin->plugin_info = $element->get_info();
     58        }
     59}
  • src/wp-admin/includes/class-plugin-upgrader.php

    diff --git src/wp-admin/includes/class-plugin-upgrader.php src/wp-admin/includes/class-plugin-upgrader.php
    index c80c9c4c97..97e2b8afe0 100644
    class Plugin_Upgrader extends WP_Upgrader { 
    228228                $this->bulk = true;
    229229                $this->upgrade_strings();
    230230
    231                 $current = get_site_transient( 'update_plugins' );
    232 
    233231                add_filter( 'upgrader_clear_destination', array( $this, 'delete_old_plugin' ), 10, 4 );
    234232
    235233                $this->skin->header();
    class Plugin_Upgrader extends WP_Upgrader { 
    243241
    244242                $this->skin->bulk_header();
    245243
    246                 /*
    247                  * Only start maintenance mode if:
    248                  * - running Multisite and there are one or more plugins specified, OR
    249                  * - a plugin with an update available is currently active.
    250                  * @TODO: For multisite, maintenance mode should only kick in for individual sites if at all possible.
    251                  */
    252                 $maintenance = ( is_multisite() && ! empty( $plugins ) );
    253                 foreach ( $plugins as $plugin ) {
    254                         $maintenance = $maintenance || ( is_plugin_active( $plugin ) && isset( $current->response[ $plugin ] ) );
    255                 }
    256                 if ( $maintenance ) {
    257                         $this->maintenance_mode( true );
    258                 }
    259 
    260                 $results = array();
    261 
    262                 $this->update_count   = count( $plugins );
    263                 $this->update_current = 0;
    264                 foreach ( $plugins as $plugin ) {
    265                         $this->update_current++;
    266                         $this->skin->plugin_info = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin, false, true );
    267 
    268                         if ( ! isset( $current->response[ $plugin ] ) ) {
    269                                 $this->skin->set_result( 'up_to_date' );
    270                                 $this->skin->before();
    271                                 $this->skin->feedback( 'up_to_date' );
    272                                 $this->skin->after();
    273                                 $results[ $plugin ] = true;
    274                                 continue;
    275                         }
    276 
    277                         // Get the URL to the zip file.
    278                         $r = $current->response[ $plugin ];
    279 
    280                         $this->skin->plugin_active = is_plugin_active( $plugin );
    281 
    282                         $result = $this->run(
    283                                 array(
    284                                         'package'           => $r->package,
    285                                         'destination'       => WP_PLUGIN_DIR,
    286                                         'clear_destination' => true,
    287                                         'clear_working'     => true,
    288                                         'is_multi'          => true,
    289                                         'hook_extra'        => array(
    290                                                 'plugin' => $plugin,
    291                                         ),
    292                                 )
    293                         );
    294 
    295                         $results[ $plugin ] = $this->result;
    296 
    297                         // Prevent credentials auth screen from displaying multiple times
    298                         if ( false === $result ) {
    299                                 break;
    300                         }
    301                 } //end foreach $plugins
    302 
    303                 $this->maintenance_mode( false );
     244                $plugin_bulk_upgrader = new WP_Plugin_Bulk_Upgrader( $this, $plugins );
     245                $results = $plugin_bulk_upgrader->run();
    304246
    305247                // Force refresh of plugin update information.
    306248                wp_clean_plugins_cache( $parsed_args['clear_update_cache'] );
  • new file src/wp-admin/includes/class-theme-bulk-upgrade-element.php

    diff --git src/wp-admin/includes/class-theme-bulk-upgrade-element.php src/wp-admin/includes/class-theme-bulk-upgrade-element.php
    new file mode 100644
    index 0000000000..05cab0e440
    - +  
     1<?php
     2
     3/**
     4 * Theme implementation of the Bulk Upgrade Element
     5 *
     6 * @since x.x
     7 */
     8class WP_Theme_Bulk_Upgrade_Element extends WP_Bulk_Upgrade_Repository_Element_Base {
     9        /**
     10         * WP_Bulk_Upgrader_Theme_Element constructor.
     11         *
     12         * @param string         $theme    Theme to use.
     13         * @param Theme_Upgrader $upgrader Upgrader to use.
     14         *
     15         * @since x.x
     16         * @access public
     17         */
     18        public function __construct( $theme, Theme_Upgrader $upgrader ) {
     19                parent::__construct( $theme, $upgrader );
     20
     21                $this->info = $upgrader->theme_info( $theme );
     22
     23                $response = $this->get_response();
     24                if ( false === $response ) {
     25                        $this->up_to_date = true;
     26
     27                        return;
     28                }
     29
     30                $options = array(
     31                        'package'           => $this->response['package'],
     32                        'destination'       => get_theme_root( $theme ),
     33                        'clear_destination' => true,
     34                        'clear_working'     => true,
     35                        'is_multi'          => true,
     36                        'hook_extra'        => array(
     37                                'theme' => $theme
     38                        )
     39                );
     40
     41                $this->set_options( $options );
     42        }
     43
     44        /**
     45         * Determines if this theme is active.
     46         *
     47         * @return bool
     48         *
     49         * @since x.x
     50         * @access public
     51         */
     52        public function is_active() {
     53                return $this->name === get_stylesheet() || $this->name === get_template();
     54        }
     55
     56        /**
     57         * Retrieves information about the theme from the `update_themes` transient.
     58         *
     59         * @return mixed
     60         *
     61         * @since x.x
     62         * @access protected
     63         */
     64        protected function get_current() {
     65                if ( ! isset( self::$current ) ) {
     66                        self::$current = get_site_transient( 'update_themes' );
     67                }
     68
     69                return self::$current;
     70        }
     71}
  • new file src/wp-admin/includes/class-theme-bulk-upgrader.php

    diff --git src/wp-admin/includes/class-theme-bulk-upgrader.php src/wp-admin/includes/class-theme-bulk-upgrader.php
    new file mode 100644
    index 0000000000..45ff6cd8a9
    - +  
     1<?php
     2
     3/**
     4 * Theme Bulk Upgrader implementation
     5 *
     6 * @since x.x
     7 */
     8class WP_Theme_Bulk_Upgrader extends WP_Bulk_Upgrader_Base {
     9        /**
     10         * WP_Theme_Bulk_Upgrader constructor.
     11         *
     12         * @param Theme_Upgrader                 $upgrader Upgrader to use.
     13         * @param WP_Bulk_Upgrade_Element_Base[] $elements Elements to use.
     14         *
     15         * @since  x.x
     16         * @access public
     17         */
     18        public function __construct( Theme_Upgrader $upgrader, array $elements = array() ) {
     19                parent::__construct( $upgrader, $elements, 'WP_Theme_Bulk_Upgrade_Element' );
     20        }
     21
     22        /**
     23         * Handles what to do for an up-to-date theme.
     24         *
     25         * @param WP_Bulk_Upgrade_Element_Base $element Element to use.
     26         *
     27         * @return void
     28         *
     29         * @since  x.x
     30         * @access public
     31         */
     32        public function handle_up_to_date( WP_Bulk_Upgrade_Element_Base $element ) {
     33                $skin = $this->get_skin();
     34                if ( $skin instanceof WP_Upgrader_Skin ) {
     35                        $skin->set_result( true );
     36                }
     37        }
     38
     39        /**
     40         * Sets the current element on the skin.
     41         *
     42         * @param WP_Bulk_Upgrade_Element_Base $element Element to set as current.
     43         *
     44         * @return void
     45         *
     46         * @since  x.x
     47         * @access protected
     48         */
     49        protected function set_current_element( $element ) {
     50                parent::set_current_element( $element );
     51
     52                if ( ! $this->upgrader->update_current ) {
     53                        return;
     54                }
     55
     56                $skin = $this->get_skin();
     57                if ( $skin instanceof Bulk_Theme_Upgrader_Skin ) {
     58                        $skin->theme_info = $element->get_info();
     59                }
     60        }
     61}
  • src/wp-admin/includes/class-theme-upgrader.php

    diff --git src/wp-admin/includes/class-theme-upgrader.php src/wp-admin/includes/class-theme-upgrader.php
    index 7b521063f8..a9d0a44beb 100644
    class Theme_Upgrader extends WP_Upgrader { 
    358358
    359359                $this->skin->bulk_header();
    360360
    361                 // Only start maintenance mode if:
    362                 // - running Multisite and there are one or more themes specified, OR
    363                 // - a theme with an update available is currently in use.
    364                 // @TODO: For multisite, maintenance mode should only kick in for individual sites if at all possible.
    365                 $maintenance = ( is_multisite() && ! empty( $themes ) );
    366                 foreach ( $themes as $theme ) {
    367                         $maintenance = $maintenance || $theme == get_stylesheet() || $theme == get_template();
    368                 }
    369                 if ( $maintenance ) {
    370                         $this->maintenance_mode( true );
    371                 }
    372 
    373                 $results = array();
    374 
    375                 $this->update_count   = count( $themes );
    376                 $this->update_current = 0;
    377                 foreach ( $themes as $theme ) {
    378                         $this->update_current++;
    379 
    380                         $this->skin->theme_info = $this->theme_info( $theme );
    381 
    382                         if ( ! isset( $current->response[ $theme ] ) ) {
    383                                 $this->skin->set_result( true );
    384                                 $this->skin->before();
    385                                 $this->skin->feedback( 'up_to_date' );
    386                                 $this->skin->after();
    387                                 $results[ $theme ] = true;
    388                                 continue;
    389                         }
    390 
    391                         // Get the URL to the zip file
    392                         $r = $current->response[ $theme ];
    393 
    394                         $result = $this->run(
    395                                 array(
    396                                         'package'           => $r['package'],
    397                                         'destination'       => get_theme_root( $theme ),
    398                                         'clear_destination' => true,
    399                                         'clear_working'     => true,
    400                                         'is_multi'          => true,
    401                                         'hook_extra'        => array(
    402                                                 'theme' => $theme,
    403                                         ),
    404                                 )
    405                         );
    406 
    407                         $results[ $theme ] = $this->result;
    408 
    409                         // Prevent credentials auth screen from displaying multiple times
    410                         if ( false === $result ) {
    411                                 break;
    412                         }
    413                 } //end foreach $plugins
    414 
    415                 $this->maintenance_mode( false );
     361                $theme_bulk_upgrader = new WP_Theme_Bulk_Upgrader( $this, $themes );
     362                $results = $theme_bulk_upgrader->run();
    416363
    417364                // Refresh the Theme Update information
    418365                wp_clean_themes_cache( $parsed_args['clear_update_cache'] );
  • new file src/wp-admin/includes/class-wp-upgrader-bulk.php

    diff --git src/wp-admin/includes/class-wp-upgrader-bulk.php src/wp-admin/includes/class-wp-upgrader-bulk.php
    new file mode 100644
    index 0000000000..6e1c43828c
    - +  
     1<?php
     2/**
     3 * The Bulk handlers for the WordPress Upgrader
     4 *
     5 * @package    WordPress
     6 * @subpackage Upgrader
     7 * @since      x.x
     8 */
     9
     10require_once 'class-bulk-upgrade-element-base.php';
     11require_once 'class-bulk-upgrade-repository-element-base.php';
     12
     13require_once 'class-bulk-upgrader-base.php';
     14
     15require_once 'class-plugin-bulk-upgrade-element.php';
     16require_once 'class-plugin-bulk-upgrader.php';
     17
     18require_once 'class-theme-bulk-upgrade-element.php';
     19require_once 'class-theme-bulk-upgrader.php';
  • src/wp-admin/includes/class-wp-upgrader-skin.php

    diff --git src/wp-admin/includes/class-wp-upgrader-skin.php src/wp-admin/includes/class-wp-upgrader-skin.php
    index ddcfd19f18..5b110fb0ff 100644
     
    1515 */
    1616class WP_Upgrader_Skin {
    1717
     18        /**
     19         * Holds the Upgrader to use.
     20         *
     21         * @var WP_Upgrader
     22         */
    1823        public $upgrader;
    1924        public $done_header = false;
    2025        public $done_footer = false;
    class WP_Upgrader_Skin { 
    4247        }
    4348
    4449        /**
    45          * @param WP_Upgrader $upgrader
     50         * Sets the upgrader to use internally.
     51         *
     52         * @param WP_Upgrader $upgrader Upgrader to use.
    4653         */
    4754        public function set_upgrader( &$upgrader ) {
    4855                if ( is_object( $upgrader ) ) {
  • src/wp-admin/includes/class-wp-upgrader.php

    diff --git src/wp-admin/includes/class-wp-upgrader.php src/wp-admin/includes/class-wp-upgrader.php
    index b8258d4bc2..9858bf3095 100644
     
    99 * @since 2.8.0
    1010 */
    1111
     12/** WP_Upgrader_Bulk class */
     13require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader-bulk.php';
     14
    1215/** WP_Upgrader_Skin class */
    1316require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader-skin.php';
    1417
    class WP_Upgrader { 
    6467         * @since 2.8.0
    6568         * @var Automatic_Upgrader_Skin|WP_Upgrader_Skin $skin
    6669         */
    67         public $skin = null;
     70        public $skin;
    6871
    6972        /**
    7073         * The result of the installation.
    class WP_Upgrader { 
    120123         *                               instance.
    121124         */
    122125        public function __construct( $skin = null ) {
    123                 if ( null == $skin ) {
     126                if ( $skin === null ) {
    124127                        $this->skin = new WP_Upgrader_Skin();
    125128                } else {
    126129                        $this->skin = $skin;
    class WP_Upgrader { 
    304307
    305308                $upgrade_folder = $wp_filesystem->wp_content_dir() . 'upgrade/';
    306309
    307                 //Clean up contents of upgrade directory beforehand.
    308                 $upgrade_files = $wp_filesystem->dirlist( $upgrade_folder );
    309                 if ( ! empty( $upgrade_files ) ) {
    310                         foreach ( $upgrade_files as $file ) {
    311                                 $wp_filesystem->delete( $upgrade_folder . $file['name'], true );
    312                         }
    313                 }
    314 
    315310                // We need a working directory - Strip off any .tmp or .zip suffixes
    316311                $working_dir = $upgrade_folder . basename( basename( $package, '.tmp' ), '.zip' );
    317312
    class WP_Upgrader { 
    702697                 */
    703698                $options = apply_filters( 'upgrader_package_options', $options );
    704699
    705                 if ( ! $options['is_multi'] ) { // call $this->header separately if running multiple times
    706                         $this->skin->header();
    707                 }
     700                $this->skin->header();
    708701
    709702                // Connect to the Filesystem first.
    710703                $res = $this->fs_connect( array( WP_CONTENT_DIR, $options['destination'] ) );
    class WP_Upgrader { 
    727720                        return $res;
    728721                }
    729722
     723                $this->clean_upgrade_folder();
     724
    730725                /*
    731726                 * Download the package (Note, This just returns the filename
    732727                 * of the file if the package is a local file)
    class WP_Upgrader { 
    925920                return delete_option( $lock_name . '.lock' );
    926921        }
    927922
     923        /**
     924         * Clears optional remnants of previous upgrades
     925         *
     926         * @since x.x
     927         * @access public
     928         *
     929         * @global WP_Filesystem_Base $wp_filesystem Subclass
     930         */
     931        public function clean_upgrade_folder() {
     932                /** @var WP_Filesystem_Base $wp_filesystem */
     933                global $wp_filesystem;
     934
     935                //Clean up contents of upgrade directory.
     936                $upgrade_folder = $wp_filesystem->wp_content_dir() . 'upgrade/';
     937                $upgrade_files  = $wp_filesystem->dirlist( $upgrade_folder );
     938                if ( ! empty( $upgrade_files ) ) {
     939                        foreach ( $upgrade_files as $file ) {
     940                                $wp_filesystem->delete( $upgrade_folder . $file['name'], true );
     941                        }
     942                }
     943        }
     944
     945        /**
     946         * Retrieves the used skin.
     947         *
     948         * @return WP_Upgrader_Skin The used skin.
     949         *
     950         * @since  x.x
     951         * @access public
     952         */
     953        public function get_skin() {
     954                return $this->skin;
     955        }
    928956}
    929957
    930958/** Plugin_Upgrader class */