/**
  * Update an item, if appropriate.
  *
  * @since 3.7.0
  *
  * @param string $type The type of update being checked: 'core', 'theme', 'plugin', 'translation'.
  * @param object $item The update offer.
  */
 public function update($type, $item)
 {
     $skin = new Automatic_Upgrader_Skin();
     switch ($type) {
         case 'core':
             // The Core upgrader doesn't use the Upgrader's skin during the actual main part of the upgrade, instead, firing a filter.
             add_filter('update_feedback', array($skin, 'feedback'));
             $upgrader = new Core_Upgrader($skin);
             $context = ABSPATH;
             break;
         case 'plugin':
             $upgrader = new Plugin_Upgrader($skin);
             $context = WP_PLUGIN_DIR;
             // We don't support custom Plugin directories, or updates for WPMU_PLUGIN_DIR
             break;
         case 'theme':
             $upgrader = new Theme_Upgrader($skin);
             $context = get_theme_root($item->theme);
             break;
         case 'translation':
             $upgrader = new Language_Pack_Upgrader($skin);
             $context = WP_CONTENT_DIR;
             // WP_LANG_DIR;
             break;
     }
     // Determine whether we can and should perform this update.
     if (!$this->should_update($type, $item, $context)) {
         return false;
     }
     $upgrader_item = $item;
     switch ($type) {
         case 'core':
             $skin->feedback(__('Updating to WordPress %s'), $item->version);
             $item_name = sprintf(__('WordPress %s'), $item->version);
             break;
         case 'theme':
             $upgrader_item = $item->theme;
             $theme = wp_get_theme($upgrader_item);
             $item_name = $theme->Get('Name');
             $skin->feedback(__('Updating theme: %s'), $item_name);
             break;
         case 'plugin':
             $upgrader_item = $item->plugin;
             $plugin_data = get_plugin_data($context . '/' . $upgrader_item);
             $item_name = $plugin_data['Name'];
             $skin->feedback(__('Updating plugin: %s'), $item_name);
             break;
         case 'translation':
             $language_item_name = $upgrader->get_name_for_update($item);
             $item_name = sprintf(__('Translations for %s'), $language_item_name);
             $skin->feedback(sprintf(__('Updating translations for %1$s (%2$s)…'), $language_item_name, $item->language));
             break;
     }
     $allow_relaxed_file_ownership = false;
     if ('core' == $type && isset($item->new_files) && !$item->new_files) {
         $allow_relaxed_file_ownership = true;
     }
     // Boom, This sites about to get a whole new splash of paint!
     $upgrade_result = $upgrader->upgrade($upgrader_item, array('clear_update_cache' => false, 'pre_check_md5' => false, 'attempt_rollback' => true, 'allow_relaxed_file_ownership' => $allow_relaxed_file_ownership));
     // If the filesystem is unavailable, false is returned.
     if (false === $upgrade_result) {
         $upgrade_result = new WP_Error('fs_unavailable', __('Could not access filesystem.'));
     }
     // Core doesn't output this, so let's append it so we don't get confused.
     if ('core' == $type) {
         if (is_wp_error($upgrade_result)) {
             $skin->error(__('Installation Failed'), $upgrade_result);
         } else {
             $skin->feedback(__('WordPress updated successfully'));
         }
     }
     $this->update_results[$type][] = (object) array('item' => $item, 'result' => $upgrade_result, 'name' => $item_name, 'messages' => $skin->get_upgrade_messages());
     return $upgrade_result;
 }
Exemple #2
0
 /**
  * Run an upgrade/install.
  *
  * Attempts to download the package (if it is not a local file), unpack it, and
  * install it in the destination folder.
  *
  * @since 2.8.0
  * @access public
  *
  * @param array $options {
  *     Array or string of arguments for upgrading/installing a package.
  *
  *     @type string $package                     The full path or URI of the package to install.
  *                                               Default empty.
  *     @type string $destination                 The full path to the destination folder.
  *                                               Default empty.
  *     @type bool   $clear_destination           Whether to delete any files already in the
  *                                               destination folder. Default false.
  *     @type bool   $clear_working               Whether to delete the files form the working
  *                                               directory after copying to the destination.
  *                                               Default false.
  *     @type bool   $abort_if_destination_exists Whether to abort the installation if the destination
  *                                               folder already exists. When true, `$clear_destination`
  *                                               should be false. Default true.
  *     @type bool   $is_multi                    Whether this run is one of multiple upgrade/install
  *                                               actions being performed in bulk. When true, the skin
  *                                               WP_Upgrader::header() and WP_Upgrader::footer()
  *                                               aren't called. Default false.
  *     @type array  $hook_extra                  Extra arguments to pass to the filter hooks called by
  *                                               WP_Upgrader::run().
  * }
  * @return array|false|WP_error The result from self::install_package() on success, otherwise a WP_Error,
  *                              or false if unable to connect to the filesystem.
  */
 public function run($options)
 {
     $defaults = array('package' => '', 'destination' => '', 'clear_destination' => false, 'abort_if_destination_exists' => true, 'clear_working' => true, 'is_multi' => false, 'hook_extra' => array());
     $options = wp_parse_args($options, $defaults);
     /**
      * Filters the package options before running an update.
      *
      * See also {@see 'upgrader_process_complete'}.
      *
      * @since 4.3.0
      *
      * @param array $options {
      *     Options used by the upgrader.
      *
      *     @type string $package                     Package for update.
      *     @type string $destination                 Update location.
      *     @type bool   $clear_destination           Clear the destination resource.
      *     @type bool   $clear_working               Clear the working resource.
      *     @type bool   $abort_if_destination_exists Abort if the Destination directory exists.
      *     @type bool   $is_multi                    Whether the upgrader is running multiple times.
      *     @type array  $hook_extra {
      *         Extra hook arguments.
      *
      *         @type string $action               Type of action. Default 'update'.
      *         @type string $type                 Type of update process. Accepts 'plugin', 'theme', or 'core'.
      *         @type bool   $bulk                 Whether the update process is a bulk update. Default true.
      *         @type string $plugin               The base plugin path from the plugins directory.
      *         @type string $theme                The stylesheet or template name of the theme.
      *         @type string $language_update_type The language pack update type. Accepts 'plugin', 'theme',
      *                                            or 'core'.
      *         @type object $language_update      The language pack update offer.
      *     }
      * }
      */
     $options = apply_filters('upgrader_package_options', $options);
     if (!$options['is_multi']) {
         // call $this->header separately if running multiple times
         $this->skin->header();
     }
     // Connect to the Filesystem first.
     $res = $this->fs_connect(array(WP_CONTENT_DIR, $options['destination']));
     // Mainly for non-connected filesystem.
     if (!$res) {
         if (!$options['is_multi']) {
             $this->skin->footer();
         }
         return false;
     }
     $this->skin->before();
     if (is_wp_error($res)) {
         $this->skin->error($res);
         $this->skin->after();
         if (!$options['is_multi']) {
             $this->skin->footer();
         }
         return $res;
     }
     /*
      * Download the package (Note, This just returns the filename
      * of the file if the package is a local file)
      */
     $download = $this->download_package($options['package']);
     if (is_wp_error($download)) {
         $this->skin->error($download);
         $this->skin->after();
         if (!$options['is_multi']) {
             $this->skin->footer();
         }
         return $download;
     }
     $delete_package = $download != $options['package'];
     // Do not delete a "local" file
     // Unzips the file into a temporary directory.
     $working_dir = $this->unpack_package($download, $delete_package);
     if (is_wp_error($working_dir)) {
         $this->skin->error($working_dir);
         $this->skin->after();
         if (!$options['is_multi']) {
             $this->skin->footer();
         }
         return $working_dir;
     }
     // With the given options, this installs it to the destination directory.
     $result = $this->install_package(array('source' => $working_dir, 'destination' => $options['destination'], 'clear_destination' => $options['clear_destination'], 'abort_if_destination_exists' => $options['abort_if_destination_exists'], 'clear_working' => $options['clear_working'], 'hook_extra' => $options['hook_extra']));
     $this->skin->set_result($result);
     if (is_wp_error($result)) {
         $this->skin->error($result);
         $this->skin->feedback('process_failed');
     } else {
         // Install succeeded.
         $this->skin->feedback('process_success');
     }
     $this->skin->after();
     if (!$options['is_multi']) {
         /**
          * Fires when the upgrader process is complete.
          *
          * See also {@see 'upgrader_package_options'}.
          *
          * @since 3.6.0
          * @since 3.7.0 Added to WP_Upgrader::run().
          * @since 4.6.0 `$translations` was added as a possible argument to `$hook_extra`.
          *
          * @param WP_Upgrader $this WP_Upgrader instance. In other contexts, $this, might be a
          *                          Theme_Upgrader, Plugin_Upgrader, Core_Upgrade, or Language_Pack_Upgrader instance.
          * @param array       $hook_extra {
          *     Array of bulk item update data.
          *
          *     @type string $action       Type of action. Default 'update'.
          *     @type string $type         Type of update process. Accepts 'plugin', 'theme', 'translation', or 'core'.
          *     @type bool   $bulk         Whether the update process is a bulk update. Default true.
          *     @type array  $plugins      Array of the basename paths of the plugins' main files.
          *     @type array  $themes       The theme slugs.
          *     @type array  $translations {
          *         Array of translations update data.
          *
          *         @type string $language The locale the translation is for.
          *         @type string $type     Type of translation. Accepts 'plugin', 'theme', or 'core'.
          *         @type string $slug     Text domain the translation is for. The slug of a theme/plugin or
          *                                'default' for core translations.
          *         @type string $version  The version of a theme, plugin, or core.
          *     }
          * }
          */
         do_action('upgrader_process_complete', $this, $options['hook_extra']);
         $this->skin->footer();
     }
     return $result;
 }