[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-admin/includes/ -> class-plugin-upgrader.php (source)

   1  <?php
   2  /**
   3   * Upgrade API: Plugin_Upgrader class
   4   *
   5   * @package WordPress
   6   * @subpackage Upgrader
   7   * @since 4.6.0
   8   */
   9  
  10  /**
  11   * Core class used for upgrading/installing plugins.
  12   *
  13   * It is designed to upgrade/install plugins from a local zip, remote zip URL,
  14   * or uploaded zip file.
  15   *
  16   * @since 2.8.0
  17   * @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader.php.
  18   *
  19   * @see WP_Upgrader
  20   */
  21  class Plugin_Upgrader extends WP_Upgrader {
  22  
  23      /**
  24       * Plugin upgrade result.
  25       *
  26       * @since 2.8.0
  27       * @var array|WP_Error $result
  28       *
  29       * @see WP_Upgrader::$result
  30       */
  31      public $result;
  32  
  33      /**
  34       * Whether a bulk upgrade/installation is being performed.
  35       *
  36       * @since 2.9.0
  37       * @var bool $bulk
  38       */
  39      public $bulk = false;
  40  
  41      /**
  42       * New plugin info.
  43       *
  44       * @since 5.5.0
  45       * @var array $new_plugin_data
  46       *
  47       * @see check_package()
  48       */
  49      public $new_plugin_data = array();
  50  
  51      /**
  52       * Initializes the upgrade strings.
  53       *
  54       * @since 2.8.0
  55       */
  56  	public function upgrade_strings() {
  57          $this->strings['up_to_date'] = __( 'The plugin is at the latest version.' );
  58          $this->strings['no_package'] = __( 'Update package not available.' );
  59          /* translators: %s: Package URL. */
  60          $this->strings['downloading_package']  = sprintf( __( 'Downloading update from %s&#8230;' ), '<span class="code pre">%s</span>' );
  61          $this->strings['unpack_package']       = __( 'Unpacking the update&#8230;' );
  62          $this->strings['remove_old']           = __( 'Removing the old version of the plugin&#8230;' );
  63          $this->strings['remove_old_failed']    = __( 'Could not remove the old plugin.' );
  64          $this->strings['process_failed']       = __( 'Plugin update failed.' );
  65          $this->strings['process_success']      = __( 'Plugin updated successfully.' );
  66          $this->strings['process_bulk_success'] = __( 'Plugins updated successfully.' );
  67      }
  68  
  69      /**
  70       * Initializes the installation strings.
  71       *
  72       * @since 2.8.0
  73       */
  74  	public function install_strings() {
  75          $this->strings['no_package'] = __( 'Installation package not available.' );
  76          /* translators: %s: Package URL. */
  77          $this->strings['downloading_package'] = sprintf( __( 'Downloading installation package from %s&#8230;' ), '<span class="code pre">%s</span>' );
  78          $this->strings['unpack_package']      = __( 'Unpacking the package&#8230;' );
  79          $this->strings['installing_package']  = __( 'Installing the plugin&#8230;' );
  80          $this->strings['remove_old']          = __( 'Removing the current plugin&#8230;' );
  81          $this->strings['remove_old_failed']   = __( 'Could not remove the current plugin.' );
  82          $this->strings['no_files']            = __( 'The plugin contains no files.' );
  83          $this->strings['process_failed']      = __( 'Plugin installation failed.' );
  84          $this->strings['process_success']     = __( 'Plugin installed successfully.' );
  85          /* translators: 1: Plugin name, 2: Plugin version. */
  86          $this->strings['process_success_specific'] = __( 'Successfully installed the plugin <strong>%1$s %2$s</strong>.' );
  87  
  88          if ( ! empty( $this->skin->overwrite ) ) {
  89              if ( 'update-plugin' === $this->skin->overwrite ) {
  90                  $this->strings['installing_package'] = __( 'Updating the plugin&#8230;' );
  91                  $this->strings['process_failed']     = __( 'Plugin update failed.' );
  92                  $this->strings['process_success']    = __( 'Plugin updated successfully.' );
  93              }
  94  
  95              if ( 'downgrade-plugin' === $this->skin->overwrite ) {
  96                  $this->strings['installing_package'] = __( 'Downgrading the plugin&#8230;' );
  97                  $this->strings['process_failed']     = __( 'Plugin downgrade failed.' );
  98                  $this->strings['process_success']    = __( 'Plugin downgraded successfully.' );
  99              }
 100          }
 101      }
 102  
 103      /**
 104       * Install a plugin package.
 105       *
 106       * @since 2.8.0
 107       * @since 3.7.0 The `$args` parameter was added, making clearing the plugin update cache optional.
 108       *
 109       * @param string $package The full local path or URI of the package.
 110       * @param array  $args {
 111       *     Optional. Other arguments for installing a plugin package. Default empty array.
 112       *
 113       *     @type bool $clear_update_cache Whether to clear the plugin updates cache if successful.
 114       *                                    Default true.
 115       * }
 116       * @return bool|WP_Error True if the installation was successful, false or a WP_Error otherwise.
 117       */
 118  	public function install( $package, $args = array() ) {
 119          $defaults    = array(
 120              'clear_update_cache' => true,
 121              'overwrite_package'  => false, // Do not overwrite files.
 122          );
 123          $parsed_args = wp_parse_args( $args, $defaults );
 124  
 125          $this->init();
 126          $this->install_strings();
 127  
 128          add_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
 129  
 130          if ( $parsed_args['clear_update_cache'] ) {
 131              // Clear cache so wp_update_plugins() knows about the new plugin.
 132              add_action( 'upgrader_process_complete', 'wp_clean_plugins_cache', 9, 0 );
 133          }
 134  
 135          $this->run(
 136              array(
 137                  'package'           => $package,
 138                  'destination'       => WP_PLUGIN_DIR,
 139                  'clear_destination' => $parsed_args['overwrite_package'],
 140                  'clear_working'     => true,
 141                  'hook_extra'        => array(
 142                      'type'   => 'plugin',
 143                      'action' => 'install',
 144                  ),
 145              )
 146          );
 147  
 148          remove_action( 'upgrader_process_complete', 'wp_clean_plugins_cache', 9 );
 149          remove_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
 150  
 151          if ( ! $this->result || is_wp_error( $this->result ) ) {
 152              return $this->result;
 153          }
 154  
 155          // Force refresh of plugin update information.
 156          wp_clean_plugins_cache( $parsed_args['clear_update_cache'] );
 157  
 158          if ( $parsed_args['overwrite_package'] ) {
 159              /**
 160               * Fires when the upgrader has successfully overwritten a currently installed
 161               * plugin or theme with an uploaded zip package.
 162               *
 163               * @since 5.5.0
 164               *
 165               * @param string  $package      The package file.
 166               * @param array   $data         The new plugin or theme data.
 167               * @param string  $package_type The package type ('plugin' or 'theme').
 168               */
 169              do_action( 'upgrader_overwrote_package', $package, $this->new_plugin_data, 'plugin' );
 170          }
 171  
 172          return true;
 173      }
 174  
 175      /**
 176       * Upgrades a plugin.
 177       *
 178       * @since 2.8.0
 179       * @since 3.7.0 The `$args` parameter was added, making clearing the plugin update cache optional.
 180       *
 181       * @param string $plugin Path to the plugin file relative to the plugins directory.
 182       * @param array  $args {
 183       *     Optional. Other arguments for upgrading a plugin package. Default empty array.
 184       *
 185       *     @type bool $clear_update_cache Whether to clear the plugin updates cache if successful.
 186       *                                    Default true.
 187       * }
 188       * @return bool|WP_Error True if the upgrade was successful, false or a WP_Error object otherwise.
 189       */
 190  	public function upgrade( $plugin, $args = array() ) {
 191          $defaults    = array(
 192              'clear_update_cache' => true,
 193          );
 194          $parsed_args = wp_parse_args( $args, $defaults );
 195  
 196          $this->init();
 197          $this->upgrade_strings();
 198  
 199          $current = get_site_transient( 'update_plugins' );
 200          if ( ! isset( $current->response[ $plugin ] ) ) {
 201              $this->skin->before();
 202              $this->skin->set_result( false );
 203              $this->skin->error( 'up_to_date' );
 204              $this->skin->after();
 205              return false;
 206          }
 207  
 208          // Get the URL to the zip file.
 209          $r = $current->response[ $plugin ];
 210  
 211          add_filter( 'upgrader_pre_install', array( $this, 'deactivate_plugin_before_upgrade' ), 10, 2 );
 212          add_filter( 'upgrader_pre_install', array( $this, 'active_before' ), 10, 2 );
 213          add_filter( 'upgrader_clear_destination', array( $this, 'delete_old_plugin' ), 10, 4 );
 214          add_filter( 'upgrader_post_install', array( $this, 'active_after' ), 10, 2 );
 215          /*
 216           * There's a Trac ticket to move up the directory for zips which are made a bit differently, useful for non-.org plugins.
 217           * 'source_selection' => array( $this, 'source_selection' ),
 218           */
 219          if ( $parsed_args['clear_update_cache'] ) {
 220              // Clear cache so wp_update_plugins() knows about the new plugin.
 221              add_action( 'upgrader_process_complete', 'wp_clean_plugins_cache', 9, 0 );
 222          }
 223  
 224          $this->run(
 225              array(
 226                  'package'           => $r->package,
 227                  'destination'       => WP_PLUGIN_DIR,
 228                  'clear_destination' => true,
 229                  'clear_working'     => true,
 230                  'hook_extra'        => array(
 231                      'plugin'      => $plugin,
 232                      'type'        => 'plugin',
 233                      'action'      => 'update',
 234                      'temp_backup' => array(
 235                          'slug' => dirname( $plugin ),
 236                          'src'  => WP_PLUGIN_DIR,
 237                          'dir'  => 'plugins',
 238                      ),
 239                  ),
 240              )
 241          );
 242  
 243          // Cleanup our hooks, in case something else does an upgrade on this connection.
 244          remove_action( 'upgrader_process_complete', 'wp_clean_plugins_cache', 9 );
 245          remove_filter( 'upgrader_pre_install', array( $this, 'deactivate_plugin_before_upgrade' ) );
 246          remove_filter( 'upgrader_pre_install', array( $this, 'active_before' ) );
 247          remove_filter( 'upgrader_clear_destination', array( $this, 'delete_old_plugin' ) );
 248          remove_filter( 'upgrader_post_install', array( $this, 'active_after' ) );
 249  
 250          if ( ! $this->result || is_wp_error( $this->result ) ) {
 251              return $this->result;
 252          }
 253  
 254          // Force refresh of plugin update information.
 255          wp_clean_plugins_cache( $parsed_args['clear_update_cache'] );
 256  
 257          /*
 258           * Ensure any future auto-update failures trigger a failure email by removing
 259           * the last failure notification from the list when plugins update successfully.
 260           */
 261          $past_failure_emails = get_option( 'auto_plugin_theme_update_emails', array() );
 262  
 263          if ( isset( $past_failure_emails[ $plugin ] ) ) {
 264              unset( $past_failure_emails[ $plugin ] );
 265              update_option( 'auto_plugin_theme_update_emails', $past_failure_emails );
 266          }
 267  
 268          return true;
 269      }
 270  
 271      /**
 272       * Upgrades several plugins at once.
 273       *
 274       * @since 2.8.0
 275       * @since 3.7.0 The `$args` parameter was added, making clearing the plugin update cache optional.
 276       *
 277       * @global string $wp_version The WordPress version string.
 278       *
 279       * @param string[] $plugins Array of paths to plugin files relative to the plugins directory.
 280       * @param array    $args {
 281       *     Optional. Other arguments for upgrading several plugins at once.
 282       *
 283       *     @type bool $clear_update_cache Whether to clear the plugin updates cache if successful. Default true.
 284       * }
 285       * @return array|false An array of results indexed by plugin file, or false if unable to connect to the filesystem.
 286       */
 287  	public function bulk_upgrade( $plugins, $args = array() ) {
 288          global $wp_version;
 289  
 290          $defaults    = array(
 291              'clear_update_cache' => true,
 292          );
 293          $parsed_args = wp_parse_args( $args, $defaults );
 294  
 295          $this->init();
 296          $this->bulk = true;
 297          $this->upgrade_strings();
 298  
 299          $current = get_site_transient( 'update_plugins' );
 300  
 301          add_filter( 'upgrader_clear_destination', array( $this, 'delete_old_plugin' ), 10, 4 );
 302  
 303          $this->skin->header();
 304  
 305          // Connect to the filesystem first.
 306          $res = $this->fs_connect( array( WP_CONTENT_DIR, WP_PLUGIN_DIR ) );
 307          if ( ! $res ) {
 308              $this->skin->footer();
 309              return false;
 310          }
 311  
 312          $this->skin->bulk_header();
 313  
 314          /*
 315           * Only start maintenance mode if:
 316           * - running Multisite and there are one or more plugins specified, OR
 317           * - a plugin with an update available is currently active.
 318           * @todo For multisite, maintenance mode should only kick in for individual sites if at all possible.
 319           */
 320          $maintenance = ( is_multisite() && ! empty( $plugins ) );
 321          foreach ( $plugins as $plugin ) {
 322              $maintenance = $maintenance || ( is_plugin_active( $plugin ) && isset( $current->response[ $plugin ] ) );
 323          }
 324          if ( $maintenance ) {
 325              $this->maintenance_mode( true );
 326          }
 327  
 328          $results = array();
 329  
 330          $this->update_count   = count( $plugins );
 331          $this->update_current = 0;
 332          foreach ( $plugins as $plugin ) {
 333              ++$this->update_current;
 334              $this->skin->plugin_info = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin, false, true );
 335  
 336              if ( ! isset( $current->response[ $plugin ] ) ) {
 337                  $this->skin->set_result( 'up_to_date' );
 338                  $this->skin->before();
 339                  $this->skin->feedback( 'up_to_date' );
 340                  $this->skin->after();
 341                  $results[ $plugin ] = true;
 342                  continue;
 343              }
 344  
 345              // Get the URL to the zip file.
 346              $r = $current->response[ $plugin ];
 347  
 348              $this->skin->plugin_active = is_plugin_active( $plugin );
 349  
 350              if ( isset( $r->requires ) && ! is_wp_version_compatible( $r->requires ) ) {
 351                  $result = new WP_Error(
 352                      'incompatible_wp_required_version',
 353                      sprintf(
 354                          /* translators: 1: Current WordPress version, 2: WordPress version required by the new plugin version. */
 355                          __( 'Your WordPress version is %1$s, however the new plugin version requires %2$s.' ),
 356                          $wp_version,
 357                          $r->requires
 358                      )
 359                  );
 360  
 361                  $this->skin->before( $result );
 362                  $this->skin->error( $result );
 363                  $this->skin->after();
 364              } elseif ( isset( $r->requires_php ) && ! is_php_version_compatible( $r->requires_php ) ) {
 365                  $result = new WP_Error(
 366                      'incompatible_php_required_version',
 367                      sprintf(
 368                          /* translators: 1: Current PHP version, 2: PHP version required by the new plugin version. */
 369                          __( 'The PHP version on your server is %1$s, however the new plugin version requires %2$s.' ),
 370                          PHP_VERSION,
 371                          $r->requires_php
 372                      )
 373                  );
 374  
 375                  $this->skin->before( $result );
 376                  $this->skin->error( $result );
 377                  $this->skin->after();
 378              } else {
 379                  add_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
 380                  $result = $this->run(
 381                      array(
 382                          'package'           => $r->package,
 383                          'destination'       => WP_PLUGIN_DIR,
 384                          'clear_destination' => true,
 385                          'clear_working'     => true,
 386                          'is_multi'          => true,
 387                          'hook_extra'        => array(
 388                              'plugin'      => $plugin,
 389                              'temp_backup' => array(
 390                                  'slug' => dirname( $plugin ),
 391                                  'src'  => WP_PLUGIN_DIR,
 392                                  'dir'  => 'plugins',
 393                              ),
 394                          ),
 395                      )
 396                  );
 397                  remove_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
 398              }
 399  
 400              $results[ $plugin ] = $result;
 401  
 402              // Prevent credentials auth screen from displaying multiple times.
 403              if ( false === $result ) {
 404                  break;
 405              }
 406          } // End foreach $plugins.
 407  
 408          $this->maintenance_mode( false );
 409  
 410          // Force refresh of plugin update information.
 411          wp_clean_plugins_cache( $parsed_args['clear_update_cache'] );
 412  
 413          /** This action is documented in wp-admin/includes/class-wp-upgrader.php */
 414          do_action(
 415              'upgrader_process_complete',
 416              $this,
 417              array(
 418                  'action'  => 'update',
 419                  'type'    => 'plugin',
 420                  'bulk'    => true,
 421                  'plugins' => $plugins,
 422              )
 423          );
 424  
 425          $this->skin->bulk_footer();
 426  
 427          $this->skin->footer();
 428  
 429          // Cleanup our hooks, in case something else does an upgrade on this connection.
 430          remove_filter( 'upgrader_clear_destination', array( $this, 'delete_old_plugin' ) );
 431  
 432          /*
 433           * Ensure any future auto-update failures trigger a failure email by removing
 434           * the last failure notification from the list when plugins update successfully.
 435           */
 436          $past_failure_emails = get_option( 'auto_plugin_theme_update_emails', array() );
 437  
 438          foreach ( $results as $plugin => $result ) {
 439              // Maintain last failure notification when plugins failed to update manually.
 440              if ( ! $result || is_wp_error( $result ) || ! isset( $past_failure_emails[ $plugin ] ) ) {
 441                  continue;
 442              }
 443  
 444              unset( $past_failure_emails[ $plugin ] );
 445          }
 446  
 447          update_option( 'auto_plugin_theme_update_emails', $past_failure_emails );
 448  
 449          return $results;
 450      }
 451  
 452      /**
 453       * Checks that the source package contains a valid plugin.
 454       *
 455       * Hooked to the {@see 'upgrader_source_selection'} filter by Plugin_Upgrader::install().
 456       *
 457       * @since 3.3.0
 458       *
 459       * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
 460       * @global string             $wp_version    The WordPress version string.
 461       *
 462       * @param string $source The path to the downloaded package source.
 463       * @return string|WP_Error The source as passed, or a WP_Error object on failure.
 464       */
 465  	public function check_package( $source ) {
 466          global $wp_filesystem, $wp_version;
 467  
 468          $this->new_plugin_data = array();
 469  
 470          if ( is_wp_error( $source ) ) {
 471              return $source;
 472          }
 473  
 474          $working_directory = str_replace( $wp_filesystem->wp_content_dir(), trailingslashit( WP_CONTENT_DIR ), $source );
 475          if ( ! is_dir( $working_directory ) ) { // Confidence check, if the above fails, let's not prevent installation.
 476              return $source;
 477          }
 478  
 479          // Check that the folder contains at least 1 valid plugin.
 480          $files = glob( $working_directory . '*.php' );
 481          if ( $files ) {
 482              foreach ( $files as $file ) {
 483                  $info = get_plugin_data( $file, false, false );
 484                  if ( ! empty( $info['Name'] ) ) {
 485                      $this->new_plugin_data = $info;
 486                      break;
 487                  }
 488              }
 489          }
 490  
 491          if ( empty( $this->new_plugin_data ) ) {
 492              return new WP_Error( 'incompatible_archive_no_plugins', $this->strings['incompatible_archive'], __( 'No valid plugins were found.' ) );
 493          }
 494  
 495          $requires_php = isset( $info['RequiresPHP'] ) ? $info['RequiresPHP'] : null;
 496          $requires_wp  = isset( $info['RequiresWP'] ) ? $info['RequiresWP'] : null;
 497  
 498          if ( ! is_php_version_compatible( $requires_php ) ) {
 499              $error = sprintf(
 500                  /* translators: 1: Current PHP version, 2: Version required by the uploaded plugin. */
 501                  __( 'The PHP version on your server is %1$s, however the uploaded plugin requires %2$s.' ),
 502                  PHP_VERSION,
 503                  $requires_php
 504              );
 505  
 506              return new WP_Error( 'incompatible_php_required_version', $this->strings['incompatible_archive'], $error );
 507          }
 508  
 509          if ( ! is_wp_version_compatible( $requires_wp ) ) {
 510              $error = sprintf(
 511                  /* translators: 1: Current WordPress version, 2: Version required by the uploaded plugin. */
 512                  __( 'Your WordPress version is %1$s, however the uploaded plugin requires %2$s.' ),
 513                  $wp_version,
 514                  $requires_wp
 515              );
 516  
 517              return new WP_Error( 'incompatible_wp_required_version', $this->strings['incompatible_archive'], $error );
 518          }
 519  
 520          return $source;
 521      }
 522  
 523      /**
 524       * Retrieves the path to the file that contains the plugin info.
 525       *
 526       * This isn't used internally in the class, but is called by the skins.
 527       *
 528       * @since 2.8.0
 529       *
 530       * @return string|false The full path to the main plugin file, or false.
 531       */
 532  	public function plugin_info() {
 533          if ( ! is_array( $this->result ) ) {
 534              return false;
 535          }
 536          if ( empty( $this->result['destination_name'] ) ) {
 537              return false;
 538          }
 539  
 540          // Ensure to pass with leading slash.
 541          $plugin = get_plugins( '/' . $this->result['destination_name'] );
 542          if ( empty( $plugin ) ) {
 543              return false;
 544          }
 545  
 546          // Assume the requested plugin is the first in the list.
 547          $pluginfiles = array_keys( $plugin );
 548  
 549          return $this->result['destination_name'] . '/' . $pluginfiles[0];
 550      }
 551  
 552      /**
 553       * Deactivates a plugin before it is upgraded.
 554       *
 555       * Hooked to the {@see 'upgrader_pre_install'} filter by Plugin_Upgrader::upgrade().
 556       *
 557       * @since 2.8.0
 558       * @since 4.1.0 Added a return value.
 559       *
 560       * @param bool|WP_Error $response The installation response before the installation has started.
 561       * @param array         $plugin   Plugin package arguments.
 562       * @return bool|WP_Error The original `$response` parameter or WP_Error.
 563       */
 564  	public function deactivate_plugin_before_upgrade( $response, $plugin ) {
 565  
 566          if ( is_wp_error( $response ) ) { // Bypass.
 567              return $response;
 568          }
 569  
 570          // When in cron (background updates) don't deactivate the plugin, as we require a browser to reactivate it.
 571          if ( wp_doing_cron() ) {
 572              return $response;
 573          }
 574  
 575          $plugin = isset( $plugin['plugin'] ) ? $plugin['plugin'] : '';
 576          if ( empty( $plugin ) ) {
 577              return new WP_Error( 'bad_request', $this->strings['bad_request'] );
 578          }
 579  
 580          if ( is_plugin_active( $plugin ) ) {
 581              // Deactivate the plugin silently, Prevent deactivation hooks from running.
 582              deactivate_plugins( $plugin, true );
 583          }
 584  
 585          return $response;
 586      }
 587  
 588      /**
 589       * Turns on maintenance mode before attempting to background update an active plugin.
 590       *
 591       * Hooked to the {@see 'upgrader_pre_install'} filter by Plugin_Upgrader::upgrade().
 592       *
 593       * @since 5.4.0
 594       *
 595       * @param bool|WP_Error $response The installation response before the installation has started.
 596       * @param array         $plugin   Plugin package arguments.
 597       * @return bool|WP_Error The original `$response` parameter or WP_Error.
 598       */
 599  	public function active_before( $response, $plugin ) {
 600          if ( is_wp_error( $response ) ) {
 601              return $response;
 602          }
 603  
 604          // Only enable maintenance mode when in cron (background update).
 605          if ( ! wp_doing_cron() ) {
 606              return $response;
 607          }
 608  
 609          $plugin = isset( $plugin['plugin'] ) ? $plugin['plugin'] : '';
 610  
 611          // Only run if plugin is active.
 612          if ( ! is_plugin_active( $plugin ) ) {
 613              return $response;
 614          }
 615  
 616          // Change to maintenance mode. Bulk edit handles this separately.
 617          if ( ! $this->bulk ) {
 618              $this->maintenance_mode( true );
 619          }
 620  
 621          return $response;
 622      }
 623  
 624      /**
 625       * Turns off maintenance mode after upgrading an active plugin.
 626       *
 627       * Hooked to the {@see 'upgrader_post_install'} filter by Plugin_Upgrader::upgrade().
 628       *
 629       * @since 5.4.0
 630       *
 631       * @param bool|WP_Error $response The installation response after the installation has finished.
 632       * @param array         $plugin   Plugin package arguments.
 633       * @return bool|WP_Error The original `$response` parameter or WP_Error.
 634       */
 635  	public function active_after( $response, $plugin ) {
 636          if ( is_wp_error( $response ) ) {
 637              return $response;
 638          }
 639  
 640          // Only disable maintenance mode when in cron (background update).
 641          if ( ! wp_doing_cron() ) {
 642              return $response;
 643          }
 644  
 645          $plugin = isset( $plugin['plugin'] ) ? $plugin['plugin'] : '';
 646  
 647          // Only run if plugin is active.
 648          if ( ! is_plugin_active( $plugin ) ) {
 649              return $response;
 650          }
 651  
 652          // Time to remove maintenance mode. Bulk edit handles this separately.
 653          if ( ! $this->bulk ) {
 654              $this->maintenance_mode( false );
 655          }
 656  
 657          return $response;
 658      }
 659  
 660      /**
 661       * Deletes the old plugin during an upgrade.
 662       *
 663       * Hooked to the {@see 'upgrader_clear_destination'} filter by
 664       * Plugin_Upgrader::upgrade() and Plugin_Upgrader::bulk_upgrade().
 665       *
 666       * @since 2.8.0
 667       *
 668       * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
 669       *
 670       * @param bool|WP_Error $removed            Whether the destination was cleared.
 671       *                                          True on success, WP_Error on failure.
 672       * @param string        $local_destination  The local package destination.
 673       * @param string        $remote_destination The remote package destination.
 674       * @param array         $plugin             Extra arguments passed to hooked filters.
 675       * @return bool|WP_Error
 676       */
 677  	public function delete_old_plugin( $removed, $local_destination, $remote_destination, $plugin ) {
 678          global $wp_filesystem;
 679  
 680          if ( is_wp_error( $removed ) ) {
 681              return $removed; // Pass errors through.
 682          }
 683  
 684          $plugin = isset( $plugin['plugin'] ) ? $plugin['plugin'] : '';
 685          if ( empty( $plugin ) ) {
 686              return new WP_Error( 'bad_request', $this->strings['bad_request'] );
 687          }
 688  
 689          $plugins_dir     = $wp_filesystem->wp_plugins_dir();
 690          $this_plugin_dir = trailingslashit( dirname( $plugins_dir . $plugin ) );
 691  
 692          if ( ! $wp_filesystem->exists( $this_plugin_dir ) ) { // If it's already vanished.
 693              return $removed;
 694          }
 695  
 696          /*
 697           * If plugin is in its own directory, recursively delete the directory.
 698           * Base check on if plugin includes directory separator AND that it's not the root plugin folder.
 699           */
 700          if ( strpos( $plugin, '/' ) && $this_plugin_dir !== $plugins_dir ) {
 701              $deleted = $wp_filesystem->delete( $this_plugin_dir, true );
 702          } else {
 703              $deleted = $wp_filesystem->delete( $plugins_dir . $plugin );
 704          }
 705  
 706          if ( ! $deleted ) {
 707              return new WP_Error( 'remove_old_failed', $this->strings['remove_old_failed'] );
 708          }
 709  
 710          return true;
 711      }
 712  }


Generated : Fri Apr 26 08:20:02 2024 Cross-referenced by PHPXref