/**
  * Download and install a plugin update.
  *
  * @since  4.0.0
  * @param  int  $pid The project ID.
  * @param  bool $die_on_error Default is true. Otherwise function will
  *              return false on error.
  * @return bool True on success.
  */
 public function update_project($pid, $die_on_error = true)
 {
     // Refresh local project cache before the update starts.
     WPMUDEV_Dashboard::$site->set_option('refresh_local_flag', true);
     $local_projects = WPMUDEV_Dashboard::$site->get_cached_projects();
     // Now make sure that the project is updated, no matter what!
     WPMUDEV_Dashboard::$api->calculate_upgrades($local_projects, $pid);
     if (!$this->is_project_installed($pid)) {
         if ($die_on_error) {
             wp_send_json_error(array('message' => __('Project not installed', 'wdpmudev')));
         } else {
             error_log('WPMU DEV error: Update failed - project not installed');
             return false;
         }
     }
     $project = WPMUDEV_Dashboard::$site->get_project_infos($pid);
     // Upfront special: If updating a child theme first update parent.
     if ($project->need_upfront) {
         $upfront = WPMUDEV_Dashboard::$site->get_project_infos($this->id_upfront);
         // Time condition to avoid repeated UF checks if there was an error.
         $check = (int) WPMUDEV_Dashboard::$site->get_option('last_check_upfront');
         if (!$upfront->is_installed) {
             if (time() > $check + 3 * MINUTE_IN_SECONDS) {
                 WPMUDEV_Dashboard::$site->set_option('last_check_upfront', time());
                 $this->install_project($upfront->pid, $error, false);
             }
         } elseif ($upfront->version_installed != $upfront->version_latest) {
             if (time() > $check + 3 * MINUTE_IN_SECONDS) {
                 WPMUDEV_Dashboard::$site->set_option('last_check_upfront', time());
                 $this->update_project($upfront->pid, false);
             }
         }
     }
     // For plugins_api..
     include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
     include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
     // Save on a bit of bandwidth.
     $api = plugins_api('plugin_information', array('slug' => 'wpmudev_install-' . $pid, 'fields' => array('sections' => false)));
     if (is_wp_error($api)) {
         if ($die_on_error) {
             wp_send_json_error(array('message' => __('No data found', 'wpmudev')));
         } else {
             error_log('WPMU DEV error: Update failed - no upgrade data found');
             return false;
         }
     }
     ob_start();
     $skin = new Automatic_Upgrader_Skin();
     $result = false;
     $success = false;
     $update_file = $project->filename;
     /*
      * Set before the update:
      * WP will refresh local cache via action-hook before the install()
      * method is finished. That refresh call must scan the FS again.
      */
     $this->flush_fs_cache = true;
     $this->flush_info_cache = true;
     switch ($project->type) {
         case 'plugin':
             wp_update_plugins();
             $upgrader = new Plugin_Upgrader($skin);
             $result = $upgrader->bulk_upgrade(array($update_file));
             break;
         case 'theme':
             wp_update_themes();
             $upgrader = new Theme_Upgrader($skin);
             $update_file = dirname($update_file);
             $result = $upgrader->upgrade($update_file);
             break;
     }
     // Check for errors.
     if (is_array($result) && empty($result[$update_file]) && is_wp_error($skin->result)) {
         $result = $skin->result;
     }
     $details = ob_get_clean();
     $err_data = array('error_code' => 'U000', 'message' => __('Update failed', 'wpmudev'), 'details' => $details, 'pid' => $pid);
     if (is_array($result) && !empty($result[$update_file])) {
         $plugin_update_data = current($result);
         if (true === $plugin_update_data) {
             $err_data['error_code'] = 'U001';
             $err_data['message'] = implode('<br>', $skin->get_upgrade_messages());
             error_log('WPMU DEV error: Update failed | ' . json_encode($err_data));
             if ($die_on_error) {
                 $this->send_json_error($err_data);
             } else {
                 return false;
             }
         }
     } elseif (is_wp_error($result)) {
         $err_data['error_code'] = 'U002';
         $err_data['message'] = $result->get_error_message();
         error_log('WPMU DEV error: Update failed | ' . json_encode($err_data));
         if ($die_on_error) {
             $this->send_json_error($err_data);
         } else {
             return false;
         }
     } elseif (is_bool($result) && !$result) {
         // $upgrader->upgrade() returned false.
         // Possibly because WordPress did not find an update for the project.
         $err_data['error_code'] = 'U003';
         $err_data['message'] = __('Could not find update source', 'wpmudev');
         error_log('WPMU DEV error: Update failed | ' . json_encode($err_data));
         if ($die_on_error) {
             $this->send_json_error($err_data);
         } else {
             return false;
         }
     }
     // API call to inform wpmudev site about the change.
     $this->refresh_local_projects('remote');
     // Check if the update was successful.
     $project = WPMUDEV_Dashboard::$site->get_project_infos($pid);
     if ($project->version_installed != $project->version_latest) {
         if ($die_on_error) {
             wp_send_json_error(array('message' => __('Update failed. Maybe wrong folder permissions.', 'wdpmudev')));
         } else {
             error_log('WPMU DEV error: Upgrade failed - Maybe wrong folder permissions.');
             return false;
         }
     }
     return true;
 }
Пример #2
0
 /**
  * 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)&#8230;'), $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;
 }
 /**
  * Download and install a single plugin/theme update.
  *
  * @since  4.0.0
  * @param  int/string $pid The project ID or a plugin slug.
  * @return bool True on success.
  */
 public function upgrade($pid)
 {
     $this->clear_error();
     // Is a WPMU DEV project?
     $is_dev = is_numeric($pid);
     if ($is_dev) {
         $pid = (int) $pid;
         $infos = $this->prepare_dev_upgrade($pid);
         if (!$infos) {
             return false;
         }
         $filename = 'theme' == $infos['type'] ? dirname($infos['filename']) : $infos['filename'];
         $slug = $infos['slug'];
         $type = $infos['type'];
     } elseif (is_string($pid)) {
         // No need to check if the plugin exists/is installed. WP will check it.
         list($type, $filename) = explode(':', $pid);
         $slug = 'plugin' == $type && false !== strpos($filename, '/') ? dirname($filename) : $filename;
     } else {
         $this->set_error($pid, 'UPG.07', __('Invalid upgrade call', 'wdpmudev'));
         return false;
     }
     // For plugins_api/themes_api..
     include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
     include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
     include_once ABSPATH . 'wp-admin/includes/theme-install.php';
     include_once ABSPATH . 'wp-admin/includes/file.php';
     ob_start();
     $skin = new Automatic_Upgrader_Skin();
     $result = false;
     $success = false;
     /*
      * Set before the update:
      * WP will refresh local cache via action-hook before the install()
      * method is finished. That refresh call must scan the FS again.
      */
     WPMUDEV_Dashboard::$site->clear_local_file_cache();
     switch ($type) {
         case 'plugin':
             // Save on a bit of bandwidth.
             $api = plugins_api('plugin_information', array('slug' => $slug, 'fields' => array('sections' => false)));
             if (is_wp_error($api)) {
                 $this->set_error($pid, 'UPG.02', __('No data found', 'wdpmudev'));
                 return false;
             }
             wp_update_plugins();
             $active_blog = is_plugin_active($filename);
             $active_network = is_multisite() && is_plugin_active_for_network($filename);
             $upgrader = new Plugin_Upgrader($skin);
             $result = $upgrader->upgrade($filename);
             /*
              * Note: The following plugin activation is an intended and
              * needed step. During upgrade() WordPress deactivates the
              * plugin network- and site-wide. By default the user would
              * see a upgrade-results page with the option to activate the
              * plugin again. We skip that screen and restore original state.
              */
             if ($active_blog) {
                 activate_plugin($filename, false, false, true);
             }
             if ($active_network) {
                 activate_plugin($filename, false, true, true);
             }
             break;
         case 'theme':
             // Save on a bit of bandwidth.
             $api = themes_api('theme_information', array('slug' => $slug, 'fields' => array('sections' => false)));
             if (is_wp_error($api)) {
                 $this->set_error($pid, 'UPG.02', __('No data found', 'wdpmudev'));
                 return false;
             }
             wp_update_themes();
             $upgrader = new Theme_Upgrader($skin);
             $result = $upgrader->upgrade($filename);
             break;
         default:
             $this->set_error($pid, 'UPG.08', __('Invalid upgrade call', 'wpmudev'));
             return false;
     }
     // Check for errors.
     if (is_array($result) && empty($result[$filename]) && is_wp_error($skin->result)) {
         $result = $skin->result;
     }
     $details = ob_get_clean();
     if (is_array($result) && !empty($result[$filename])) {
         $plugin_update_data = current($result);
         if (true === $plugin_update_data) {
             $this->set_error($pid, 'UPG.03', implode('<br>', $skin->get_upgrade_messages()));
             return false;
         }
     } elseif (is_wp_error($result)) {
         $this->set_error($pid, 'UPG.04', $result->get_error_message());
         return false;
     } elseif (is_bool($result) && !$result) {
         // $upgrader->upgrade() returned false.
         // Possibly because WordPress did not find an update for the project.
         $this->set_error($pid, 'UPG.05', __('Could not find update in transient, or filesystem permissions', 'wpmudev'));
         return false;
     }
     if ($is_dev) {
         // API call to inform wpmudev site about the change, as it's a single we can let it do that at the end to avoid multiple pings
         WPMUDEV_Dashboard::$site->schedule_shutdown_refresh();
         // Check if the update was successful.
         $project = WPMUDEV_Dashboard::$site->get_project_infos($pid);
         if (version_compare($project->version_installed, $project->version_latest, '<')) {
             $this->set_error($pid, 'UPG.06', __('There was an unknown error', 'wpmudev'));
             return false;
         }
     }
     return true;
 }