示例#1
0
 /**
  * Toggle maintenance mode for the site.
  *
  * Creates/deletes the maintenance file to enable/disable maintenance mode.
  *
  * @since 2.8.0
  * @access public
  *
  * @global WP_Filesystem_Base $wp_filesystem Subclass
  *
  * @param bool $enable True to enable maintenance mode, false to disable.
  */
 public function maintenance_mode($enable = false)
 {
     global $wp_filesystem;
     $file = $wp_filesystem->abspath() . '.maintenance';
     if ($enable) {
         $this->skin->feedback('maintenance_start');
         // Create maintenance file to signal that we are upgrading
         $maintenance_string = '<?php $upgrading = ' . time() . '; ?>';
         $wp_filesystem->delete($file);
         $wp_filesystem->put_contents($file, $maintenance_string, FS_CHMOD_FILE);
     } elseif (!$enable && $wp_filesystem->exists($file)) {
         $this->skin->feedback('maintenance_end');
         $wp_filesystem->delete($file);
     }
 }
 /**
  * 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;
 }
 static function get_possible_failures()
 {
     $result = array();
     // Lets check some reasons why it might not be working as expected
     include_once ABSPATH . '/wp-admin/includes/admin.php';
     include_once ABSPATH . '/wp-admin/includes/class-wp-upgrader.php';
     $upgrader = new WP_Automatic_Updater();
     if ($upgrader->is_disabled()) {
         $result[] = 'autoupdates-disabled';
     }
     if (!is_main_site()) {
         $result[] = 'is-not-main-site';
     }
     if (!is_main_network()) {
         $result[] = 'is-not-main-network';
     }
     if ($upgrader->is_vcs_checkout(ABSPATH)) {
         $result[] = 'site-on-vcs';
     }
     if ($upgrader->is_vcs_checkout(WP_PLUGIN_DIR)) {
         $result[] = 'plugin-directory-on-vcs';
     }
     if ($upgrader->is_vcs_checkout(WP_CONTENT_DIR)) {
         $result[] = 'content-directory-on-vcs';
     }
     $lock = get_option('auto_updater.lock');
     if ($lock > time() - HOUR_IN_SECONDS) {
         $result[] = 'lock-is-set';
     }
     $skin = new Automatic_Upgrader_Skin();
     include_once ABSPATH . 'wp-admin/includes/file.php';
     include_once ABSPATH . 'wp-admin/includes/template.php';
     if (!$skin->request_filesystem_credentials(false, ABSPATH, false)) {
         $result[] = 'no-system-write-access';
     }
     if (!$skin->request_filesystem_credentials(false, WP_PLUGIN_DIR, false)) {
         $result[] = 'no-plugin-directory-write-access';
     }
     if (!$skin->request_filesystem_credentials(false, WP_CONTENT_DIR, false)) {
         $result[] = 'no-wp-content-directory-write-access';
     }
     return $result;
 }
 /**
  * Overwrites the set_upgrader to be able to tell if we e ven have the ability to write to the files.
  *
  * @param WP_Upgrader $upgrader
  *
  */
 public function set_upgrader(&$upgrader)
 {
     parent::set_upgrader($upgrader);
     // Check if we even have permission to.
     $result = $upgrader->fs_connect(array(WP_CONTENT_DIR, WP_PLUGIN_DIR));
     if (!$result) {
         // set the string here since they are not available just yet
         $upgrader->generic_strings();
         $this->feedback('fs_unavailable');
     }
 }
 static function can_auto_update($context, $skin = false)
 {
     if (!$skin) {
         $skin = new Automatic_Upgrader_Skin();
     }
     return (bool) $skin->request_filesystem_credentials(false, $context);
 }
 /**
  * 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;
 }
 /**
  * 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;
 }
示例#8
0
 /**
  * Tests to see if we can and should update a specific item.
  *
  * @since 3.7.0
  * @access public
  *
  * @global wpdb $wpdb WordPress database abstraction object.
  *
  * @param string $type    The type of update being checked: 'core', 'theme',
  *                        'plugin', 'translation'.
  * @param object $item    The update offer.
  * @param string $context The filesystem context (a path) against which filesystem
  *                        access and status should be checked.
  */
 public function should_update($type, $item, $context)
 {
     // Used to see if WP_Filesystem is set up to allow unattended updates.
     $skin = new Automatic_Upgrader_Skin();
     if ($this->is_disabled()) {
         return false;
     }
     // Only relax the filesystem checks when the update doesn't include new files
     $allow_relaxed_file_ownership = false;
     if ('core' == $type && isset($item->new_files) && !$item->new_files) {
         $allow_relaxed_file_ownership = true;
     }
     // If we can't do an auto core update, we may still be able to email the user.
     if (!$skin->request_filesystem_credentials(false, $context, $allow_relaxed_file_ownership) || $this->is_vcs_checkout($context)) {
         if ('core' == $type) {
             $this->send_core_update_notification_email($item);
         }
         return false;
     }
     // Next up, is this an item we can update?
     if ('core' == $type) {
         $update = Core_Upgrader::should_update_to_version($item->current);
     } else {
         $update = !empty($item->autoupdate);
     }
     /**
      * Filter whether to automatically update core, a plugin, a theme, or a language.
      *
      * The dynamic portion of the hook name, `$type`, refers to the type of update
      * being checked. Can be 'core', 'theme', 'plugin', or 'translation'.
      *
      * Generally speaking, plugins, themes, and major core versions are not updated
      * by default, while translations and minor and development versions for core
      * are updated by default.
      *
      * See the {@see 'allow_dev_auto_core_updates', {@see 'allow_minor_auto_core_updates'},
      * and {@see 'allow_major_auto_core_updates'} filters for a more straightforward way to
      * adjust core updates.
      *
      * @since 3.7.0
      *
      * @param bool   $update Whether to update.
      * @param object $item   The update offer.
      */
     $update = apply_filters('auto_update_' . $type, $update, $item);
     if (!$update) {
         if ('core' == $type) {
             $this->send_core_update_notification_email($item);
         }
         return false;
     }
     // If it's a core update, are we actually compatible with its requirements?
     if ('core' == $type) {
         global $wpdb;
         $php_compat = version_compare(phpversion(), $item->php_version, '>=');
         if (file_exists(WP_CONTENT_DIR . '/db.php') && empty($wpdb->is_mysql)) {
             $mysql_compat = true;
         } else {
             $mysql_compat = version_compare($wpdb->db_version(), $item->mysql_version, '>=');
         }
         if (!$php_compat || !$mysql_compat) {
             return false;
         }
     }
     return true;
 }
 /**
  * Constructor.
  *
  * @since 4.6.0
  * @access public
  *
  * @param array $args Options for the upgrader, see WP_Upgrader_Skin::__construct().
  */
 public function __construct($args = array())
 {
     parent::__construct($args);
     $this->errors = new WP_Error();
 }