[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Upgrade API: Theme_Upgrader class 4 * 5 * @package WordPress 6 * @subpackage Upgrader 7 * @since 4.6.0 8 */ 9 10 /** 11 * Core class used for upgrading/installing themes. 12 * 13 * It is designed to upgrade/install themes 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 Theme_Upgrader extends WP_Upgrader { 22 23 /** 24 * Result of the theme upgrade offer. 25 * 26 * @since 2.8.0 27 * @var array|WP_Error $result 28 * @see WP_Upgrader::$result 29 */ 30 public $result; 31 32 /** 33 * Whether multiple themes are being upgraded/installed in bulk. 34 * 35 * @since 2.9.0 36 * @var bool $bulk 37 */ 38 public $bulk = false; 39 40 /** 41 * New theme info. 42 * 43 * @since 5.5.0 44 * @var array $new_theme_data 45 * 46 * @see check_package() 47 */ 48 public $new_theme_data = array(); 49 50 /** 51 * Initializes the upgrade strings. 52 * 53 * @since 2.8.0 54 */ 55 public function upgrade_strings() { 56 $this->strings['up_to_date'] = __( 'The theme is at the latest version.' ); 57 $this->strings['no_package'] = __( 'Update package not available.' ); 58 /* translators: %s: Package URL. */ 59 $this->strings['downloading_package'] = sprintf( __( 'Downloading update from %s…' ), '<span class="code pre">%s</span>' ); 60 $this->strings['unpack_package'] = __( 'Unpacking the update…' ); 61 $this->strings['remove_old'] = __( 'Removing the old version of the theme…' ); 62 $this->strings['remove_old_failed'] = __( 'Could not remove the old theme.' ); 63 $this->strings['process_failed'] = __( 'Theme update failed.' ); 64 $this->strings['process_success'] = __( 'Theme updated successfully.' ); 65 } 66 67 /** 68 * Initializes the installation strings. 69 * 70 * @since 2.8.0 71 */ 72 public function install_strings() { 73 $this->strings['no_package'] = __( 'Installation package not available.' ); 74 /* translators: %s: Package URL. */ 75 $this->strings['downloading_package'] = sprintf( __( 'Downloading installation package from %s…' ), '<span class="code pre">%s</span>' ); 76 $this->strings['unpack_package'] = __( 'Unpacking the package…' ); 77 $this->strings['installing_package'] = __( 'Installing the theme…' ); 78 $this->strings['remove_old'] = __( 'Removing the old version of the theme…' ); 79 $this->strings['remove_old_failed'] = __( 'Could not remove the old theme.' ); 80 $this->strings['no_files'] = __( 'The theme contains no files.' ); 81 $this->strings['process_failed'] = __( 'Theme installation failed.' ); 82 $this->strings['process_success'] = __( 'Theme installed successfully.' ); 83 /* translators: 1: Theme name, 2: Theme version. */ 84 $this->strings['process_success_specific'] = __( 'Successfully installed the theme <strong>%1$s %2$s</strong>.' ); 85 $this->strings['parent_theme_search'] = __( 'This theme requires a parent theme. Checking if it is installed…' ); 86 /* translators: 1: Theme name, 2: Theme version. */ 87 $this->strings['parent_theme_prepare_install'] = __( 'Preparing to install <strong>%1$s %2$s</strong>…' ); 88 /* translators: 1: Theme name, 2: Theme version. */ 89 $this->strings['parent_theme_currently_installed'] = __( 'The parent theme, <strong>%1$s %2$s</strong>, is currently installed.' ); 90 /* translators: 1: Theme name, 2: Theme version. */ 91 $this->strings['parent_theme_install_success'] = __( 'Successfully installed the parent theme, <strong>%1$s %2$s</strong>.' ); 92 /* translators: %s: Theme name. */ 93 $this->strings['parent_theme_not_found'] = sprintf( __( '<strong>The parent theme could not be found.</strong> You will need to install the parent theme, %s, before you can use this child theme.' ), '<strong>%s</strong>' ); 94 /* translators: %s: Theme error. */ 95 $this->strings['current_theme_has_errors'] = __( 'The active theme has the following error: "%s".' ); 96 97 if ( ! empty( $this->skin->overwrite ) ) { 98 if ( 'update-theme' === $this->skin->overwrite ) { 99 $this->strings['installing_package'] = __( 'Updating the theme…' ); 100 $this->strings['process_failed'] = __( 'Theme update failed.' ); 101 $this->strings['process_success'] = __( 'Theme updated successfully.' ); 102 } 103 104 if ( 'downgrade-theme' === $this->skin->overwrite ) { 105 $this->strings['installing_package'] = __( 'Downgrading the theme…' ); 106 $this->strings['process_failed'] = __( 'Theme downgrade failed.' ); 107 $this->strings['process_success'] = __( 'Theme downgraded successfully.' ); 108 } 109 } 110 } 111 112 /** 113 * Checks if a child theme is being installed and its parent also needs to be installed. 114 * 115 * Hooked to the {@see 'upgrader_post_install'} filter by Theme_Upgrader::install(). 116 * 117 * @since 3.4.0 118 * 119 * @param bool $install_result 120 * @param array $hook_extra 121 * @param array $child_result 122 * @return bool 123 */ 124 public function check_parent_theme_filter( $install_result, $hook_extra, $child_result ) { 125 // Check to see if we need to install a parent theme. 126 $theme_info = $this->theme_info(); 127 128 if ( ! $theme_info->parent() ) { 129 return $install_result; 130 } 131 132 $this->skin->feedback( 'parent_theme_search' ); 133 134 if ( ! $theme_info->parent()->errors() ) { 135 $this->skin->feedback( 'parent_theme_currently_installed', $theme_info->parent()->display( 'Name' ), $theme_info->parent()->display( 'Version' ) ); 136 // We already have the theme, fall through. 137 return $install_result; 138 } 139 140 // We don't have the parent theme, let's install it. 141 $api = themes_api( 142 'theme_information', 143 array( 144 'slug' => $theme_info->get( 'Template' ), 145 'fields' => array( 146 'sections' => false, 147 'tags' => false, 148 ), 149 ) 150 ); // Save on a bit of bandwidth. 151 152 if ( ! $api || is_wp_error( $api ) ) { 153 $this->skin->feedback( 'parent_theme_not_found', $theme_info->get( 'Template' ) ); 154 // Don't show activate or preview actions after installation. 155 add_filter( 'install_theme_complete_actions', array( $this, 'hide_activate_preview_actions' ) ); 156 return $install_result; 157 } 158 159 // Backup required data we're going to override: 160 $child_api = $this->skin->api; 161 $child_success_message = $this->strings['process_success']; 162 163 // Override them. 164 $this->skin->api = $api; 165 166 $this->strings['process_success_specific'] = $this->strings['parent_theme_install_success']; 167 168 $this->skin->feedback( 'parent_theme_prepare_install', $api->name, $api->version ); 169 170 add_filter( 'install_theme_complete_actions', '__return_false', 999 ); // Don't show any actions after installing the theme. 171 172 // Install the parent theme. 173 $parent_result = $this->run( 174 array( 175 'package' => $api->download_link, 176 'destination' => get_theme_root(), 177 'clear_destination' => false, // Do not overwrite files. 178 'clear_working' => true, 179 ) 180 ); 181 182 if ( is_wp_error( $parent_result ) ) { 183 add_filter( 'install_theme_complete_actions', array( $this, 'hide_activate_preview_actions' ) ); 184 } 185 186 // Start cleaning up after the parent's installation. 187 remove_filter( 'install_theme_complete_actions', '__return_false', 999 ); 188 189 // Reset child's result and data. 190 $this->result = $child_result; 191 $this->skin->api = $child_api; 192 $this->strings['process_success'] = $child_success_message; 193 194 return $install_result; 195 } 196 197 /** 198 * Don't display the activate and preview actions to the user. 199 * 200 * Hooked to the {@see 'install_theme_complete_actions'} filter by 201 * Theme_Upgrader::check_parent_theme_filter() when installing 202 * a child theme and installing the parent theme fails. 203 * 204 * @since 3.4.0 205 * 206 * @param array $actions Preview actions. 207 * @return array 208 */ 209 public function hide_activate_preview_actions( $actions ) { 210 unset( $actions['activate'], $actions['preview'] ); 211 return $actions; 212 } 213 214 /** 215 * Install a theme package. 216 * 217 * @since 2.8.0 218 * @since 3.7.0 The `$args` parameter was added, making clearing the update cache optional. 219 * 220 * @param string $package The full local path or URI of the package. 221 * @param array $args { 222 * Optional. Other arguments for installing a theme package. Default empty array. 223 * 224 * @type bool $clear_update_cache Whether to clear the updates cache if successful. 225 * Default true. 226 * } 227 * 228 * @return bool|WP_Error True if the installation was successful, false or a WP_Error object otherwise. 229 */ 230 public function install( $package, $args = array() ) { 231 $defaults = array( 232 'clear_update_cache' => true, 233 'overwrite_package' => false, // Do not overwrite files. 234 ); 235 $parsed_args = wp_parse_args( $args, $defaults ); 236 237 $this->init(); 238 $this->install_strings(); 239 240 add_filter( 'upgrader_source_selection', array( $this, 'check_package' ) ); 241 add_filter( 'upgrader_post_install', array( $this, 'check_parent_theme_filter' ), 10, 3 ); 242 243 if ( $parsed_args['clear_update_cache'] ) { 244 // Clear cache so wp_update_themes() knows about the new theme. 245 add_action( 'upgrader_process_complete', 'wp_clean_themes_cache', 9, 0 ); 246 } 247 248 $this->run( 249 array( 250 'package' => $package, 251 'destination' => get_theme_root(), 252 'clear_destination' => $parsed_args['overwrite_package'], 253 'clear_working' => true, 254 'hook_extra' => array( 255 'type' => 'theme', 256 'action' => 'install', 257 ), 258 ) 259 ); 260 261 remove_action( 'upgrader_process_complete', 'wp_clean_themes_cache', 9 ); 262 remove_filter( 'upgrader_source_selection', array( $this, 'check_package' ) ); 263 remove_filter( 'upgrader_post_install', array( $this, 'check_parent_theme_filter' ) ); 264 265 if ( ! $this->result || is_wp_error( $this->result ) ) { 266 return $this->result; 267 } 268 269 // Refresh the Theme Update information. 270 wp_clean_themes_cache( $parsed_args['clear_update_cache'] ); 271 272 if ( $parsed_args['overwrite_package'] ) { 273 /** This action is documented in wp-admin/includes/class-plugin-upgrader.php */ 274 do_action( 'upgrader_overwrote_package', $package, $this->new_theme_data, 'theme' ); 275 } 276 277 return true; 278 } 279 280 /** 281 * Upgrades a theme. 282 * 283 * @since 2.8.0 284 * @since 3.7.0 The `$args` parameter was added, making clearing the update cache optional. 285 * 286 * @param string $theme The theme slug. 287 * @param array $args { 288 * Optional. Other arguments for upgrading a theme. Default empty array. 289 * 290 * @type bool $clear_update_cache Whether to clear the update cache if successful. 291 * Default true. 292 * } 293 * @return bool|WP_Error True if the upgrade was successful, false or a WP_Error object otherwise. 294 */ 295 public function upgrade( $theme, $args = array() ) { 296 $defaults = array( 297 'clear_update_cache' => true, 298 ); 299 $parsed_args = wp_parse_args( $args, $defaults ); 300 301 $this->init(); 302 $this->upgrade_strings(); 303 304 // Is an update available? 305 $current = get_site_transient( 'update_themes' ); 306 if ( ! isset( $current->response[ $theme ] ) ) { 307 $this->skin->before(); 308 $this->skin->set_result( false ); 309 $this->skin->error( 'up_to_date' ); 310 $this->skin->after(); 311 return false; 312 } 313 314 $r = $current->response[ $theme ]; 315 316 add_filter( 'upgrader_pre_install', array( $this, 'current_before' ), 10, 2 ); 317 add_filter( 'upgrader_post_install', array( $this, 'current_after' ), 10, 2 ); 318 add_filter( 'upgrader_clear_destination', array( $this, 'delete_old_theme' ), 10, 4 ); 319 if ( $parsed_args['clear_update_cache'] ) { 320 // Clear cache so wp_update_themes() knows about the new theme. 321 add_action( 'upgrader_process_complete', 'wp_clean_themes_cache', 9, 0 ); 322 } 323 324 $this->run( 325 array( 326 'package' => $r['package'], 327 'destination' => get_theme_root( $theme ), 328 'clear_destination' => true, 329 'clear_working' => true, 330 'hook_extra' => array( 331 'theme' => $theme, 332 'type' => 'theme', 333 'action' => 'update', 334 'temp_backup' => array( 335 'slug' => $theme, 336 'src' => get_theme_root( $theme ), 337 'dir' => 'themes', 338 ), 339 ), 340 ) 341 ); 342 343 remove_action( 'upgrader_process_complete', 'wp_clean_themes_cache', 9 ); 344 remove_filter( 'upgrader_pre_install', array( $this, 'current_before' ) ); 345 remove_filter( 'upgrader_post_install', array( $this, 'current_after' ) ); 346 remove_filter( 'upgrader_clear_destination', array( $this, 'delete_old_theme' ) ); 347 348 if ( ! $this->result || is_wp_error( $this->result ) ) { 349 return $this->result; 350 } 351 352 wp_clean_themes_cache( $parsed_args['clear_update_cache'] ); 353 354 /* 355 * Ensure any future auto-update failures trigger a failure email by removing 356 * the last failure notification from the list when themes update successfully. 357 */ 358 $past_failure_emails = get_option( 'auto_plugin_theme_update_emails', array() ); 359 360 if ( isset( $past_failure_emails[ $theme ] ) ) { 361 unset( $past_failure_emails[ $theme ] ); 362 update_option( 'auto_plugin_theme_update_emails', $past_failure_emails ); 363 } 364 365 return true; 366 } 367 368 /** 369 * Upgrades several themes at once. 370 * 371 * @since 3.0.0 372 * @since 3.7.0 The `$args` parameter was added, making clearing the update cache optional. 373 * 374 * @param string[] $themes Array of the theme slugs. 375 * @param array $args { 376 * Optional. Other arguments for upgrading several themes at once. Default empty array. 377 * 378 * @type bool $clear_update_cache Whether to clear the update cache if successful. 379 * Default true. 380 * } 381 * @return array[]|false An array of results, or false if unable to connect to the filesystem. 382 */ 383 public function bulk_upgrade( $themes, $args = array() ) { 384 $wp_version = wp_get_wp_version(); 385 $defaults = array( 386 'clear_update_cache' => true, 387 ); 388 $parsed_args = wp_parse_args( $args, $defaults ); 389 390 $this->init(); 391 $this->bulk = true; 392 $this->upgrade_strings(); 393 394 $current = get_site_transient( 'update_themes' ); 395 396 add_filter( 'upgrader_pre_install', array( $this, 'current_before' ), 10, 2 ); 397 add_filter( 'upgrader_post_install', array( $this, 'current_after' ), 10, 2 ); 398 add_filter( 'upgrader_clear_destination', array( $this, 'delete_old_theme' ), 10, 4 ); 399 400 $this->skin->header(); 401 402 // Connect to the filesystem first. 403 $res = $this->fs_connect( array( WP_CONTENT_DIR ) ); 404 if ( ! $res ) { 405 $this->skin->footer(); 406 return false; 407 } 408 409 $this->skin->bulk_header(); 410 411 /* 412 * Only start maintenance mode if: 413 * - running Multisite and there are one or more themes specified, OR 414 * - a theme with an update available is currently in use. 415 * @todo For multisite, maintenance mode should only kick in for individual sites if at all possible. 416 */ 417 $maintenance = ( is_multisite() && ! empty( $themes ) ); 418 foreach ( $themes as $theme ) { 419 $maintenance = $maintenance || get_stylesheet() === $theme || get_template() === $theme; 420 } 421 if ( $maintenance ) { 422 $this->maintenance_mode( true ); 423 } 424 425 $results = array(); 426 427 $this->update_count = count( $themes ); 428 $this->update_current = 0; 429 foreach ( $themes as $theme ) { 430 ++$this->update_current; 431 432 $this->skin->theme_info = $this->theme_info( $theme ); 433 434 if ( ! isset( $current->response[ $theme ] ) ) { 435 $this->skin->set_result( true ); 436 $this->skin->before(); 437 $this->skin->feedback( 'up_to_date' ); 438 $this->skin->after(); 439 $results[ $theme ] = true; 440 continue; 441 } 442 443 // Get the URL to the zip file. 444 $r = $current->response[ $theme ]; 445 446 if ( isset( $r['requires'] ) && ! is_wp_version_compatible( $r['requires'] ) ) { 447 $result = new WP_Error( 448 'incompatible_wp_required_version', 449 sprintf( 450 /* translators: 1: Current WordPress version, 2: WordPress version required by the new theme version. */ 451 __( 'Your WordPress version is %1$s, however the new theme version requires %2$s.' ), 452 $wp_version, 453 $r['requires'] 454 ) 455 ); 456 457 $this->skin->before( $result ); 458 $this->skin->error( $result ); 459 $this->skin->after(); 460 } elseif ( isset( $r['requires_php'] ) && ! is_php_version_compatible( $r['requires_php'] ) ) { 461 $result = new WP_Error( 462 'incompatible_php_required_version', 463 sprintf( 464 /* translators: 1: Current PHP version, 2: PHP version required by the new theme version. */ 465 __( 'The PHP version on your server is %1$s, however the new theme version requires %2$s.' ), 466 PHP_VERSION, 467 $r['requires_php'] 468 ) 469 ); 470 471 $this->skin->before( $result ); 472 $this->skin->error( $result ); 473 $this->skin->after(); 474 } else { 475 add_filter( 'upgrader_source_selection', array( $this, 'check_package' ) ); 476 $result = $this->run( 477 array( 478 'package' => $r['package'], 479 'destination' => get_theme_root( $theme ), 480 'clear_destination' => true, 481 'clear_working' => true, 482 'is_multi' => true, 483 'hook_extra' => array( 484 'theme' => $theme, 485 'temp_backup' => array( 486 'slug' => $theme, 487 'src' => get_theme_root( $theme ), 488 'dir' => 'themes', 489 ), 490 ), 491 ) 492 ); 493 remove_filter( 'upgrader_source_selection', array( $this, 'check_package' ) ); 494 } 495 496 $results[ $theme ] = $result; 497 498 // Prevent credentials auth screen from displaying multiple times. 499 if ( false === $result ) { 500 break; 501 } 502 } // End foreach $themes. 503 504 $this->maintenance_mode( false ); 505 506 // Refresh the Theme Update information. 507 wp_clean_themes_cache( $parsed_args['clear_update_cache'] ); 508 509 /** This action is documented in wp-admin/includes/class-wp-upgrader.php */ 510 do_action( 511 'upgrader_process_complete', 512 $this, 513 array( 514 'action' => 'update', 515 'type' => 'theme', 516 'bulk' => true, 517 'themes' => $themes, 518 ) 519 ); 520 521 $this->skin->bulk_footer(); 522 523 $this->skin->footer(); 524 525 // Cleanup our hooks, in case something else does an upgrade on this connection. 526 remove_filter( 'upgrader_pre_install', array( $this, 'current_before' ) ); 527 remove_filter( 'upgrader_post_install', array( $this, 'current_after' ) ); 528 remove_filter( 'upgrader_clear_destination', array( $this, 'delete_old_theme' ) ); 529 530 /* 531 * Ensure any future auto-update failures trigger a failure email by removing 532 * the last failure notification from the list when themes update successfully. 533 */ 534 $past_failure_emails = get_option( 'auto_plugin_theme_update_emails', array() ); 535 536 foreach ( $results as $theme => $result ) { 537 // Maintain last failure notification when themes failed to update manually. 538 if ( ! $result || is_wp_error( $result ) || ! isset( $past_failure_emails[ $theme ] ) ) { 539 continue; 540 } 541 542 unset( $past_failure_emails[ $theme ] ); 543 } 544 545 update_option( 'auto_plugin_theme_update_emails', $past_failure_emails ); 546 547 return $results; 548 } 549 550 /** 551 * Checks that the package source contains a valid theme. 552 * 553 * Hooked to the {@see 'upgrader_source_selection'} filter by Theme_Upgrader::install(). 554 * 555 * @since 3.3.0 556 * 557 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. 558 * 559 * @param string $source The path to the downloaded package source. 560 * @return string|WP_Error The source as passed, or a WP_Error object on failure. 561 */ 562 public function check_package( $source ) { 563 global $wp_filesystem; 564 565 $wp_version = wp_get_wp_version(); 566 $this->new_theme_data = array(); 567 568 if ( is_wp_error( $source ) ) { 569 return $source; 570 } 571 572 // Check that the folder contains a valid theme. 573 $working_directory = str_replace( $wp_filesystem->wp_content_dir(), trailingslashit( WP_CONTENT_DIR ), $source ); 574 if ( ! is_dir( $working_directory ) ) { // Confidence check, if the above fails, let's not prevent installation. 575 return $source; 576 } 577 578 // A proper archive should have a style.css file in the single subdirectory. 579 if ( ! file_exists( $working_directory . 'style.css' ) ) { 580 return new WP_Error( 581 'incompatible_archive_theme_no_style', 582 $this->strings['incompatible_archive'], 583 sprintf( 584 /* translators: %s: style.css */ 585 __( 'The theme is missing the %s stylesheet.' ), 586 '<code>style.css</code>' 587 ) 588 ); 589 } 590 591 // All these headers are needed on Theme_Installer_Skin::do_overwrite(). 592 $info = get_file_data( 593 $working_directory . 'style.css', 594 array( 595 'Name' => 'Theme Name', 596 'Version' => 'Version', 597 'Author' => 'Author', 598 'Template' => 'Template', 599 'RequiresWP' => 'Requires at least', 600 'RequiresPHP' => 'Requires PHP', 601 ) 602 ); 603 604 if ( empty( $info['Name'] ) ) { 605 return new WP_Error( 606 'incompatible_archive_theme_no_name', 607 $this->strings['incompatible_archive'], 608 sprintf( 609 /* translators: %s: style.css */ 610 __( 'The %s stylesheet does not contain a valid theme header.' ), 611 '<code>style.css</code>' 612 ) 613 ); 614 } 615 616 /* 617 * Parent themes must contain an index file: 618 * - classic themes require /index.php 619 * - block themes require /templates/index.html or block-templates/index.html (deprecated 5.9.0). 620 */ 621 if ( 622 empty( $info['Template'] ) && 623 ! file_exists( $working_directory . 'index.php' ) && 624 ! file_exists( $working_directory . 'templates/index.html' ) && 625 ! file_exists( $working_directory . 'block-templates/index.html' ) 626 ) { 627 return new WP_Error( 628 'incompatible_archive_theme_no_index', 629 $this->strings['incompatible_archive'], 630 sprintf( 631 /* translators: 1: templates/index.html, 2: index.php, 3: Documentation URL, 4: Template, 5: style.css */ 632 __( 'Template is missing. Standalone themes need to have a %1$s or %2$s template file. <a href="%3$s">Child themes</a> need to have a %4$s header in the %5$s stylesheet.' ), 633 '<code>templates/index.html</code>', 634 '<code>index.php</code>', 635 __( 'https://developer.wordpress.org/themes/advanced-topics/child-themes/' ), 636 '<code>Template</code>', 637 '<code>style.css</code>' 638 ) 639 ); 640 } 641 642 $requires_php = isset( $info['RequiresPHP'] ) ? $info['RequiresPHP'] : null; 643 $requires_wp = isset( $info['RequiresWP'] ) ? $info['RequiresWP'] : null; 644 645 if ( ! is_php_version_compatible( $requires_php ) ) { 646 $error = sprintf( 647 /* translators: 1: Current PHP version, 2: Version required by the uploaded theme. */ 648 __( 'The PHP version on your server is %1$s, however the uploaded theme requires %2$s.' ), 649 PHP_VERSION, 650 $requires_php 651 ); 652 653 return new WP_Error( 'incompatible_php_required_version', $this->strings['incompatible_archive'], $error ); 654 } 655 if ( ! is_wp_version_compatible( $requires_wp ) ) { 656 $error = sprintf( 657 /* translators: 1: Current WordPress version, 2: Version required by the uploaded theme. */ 658 __( 'Your WordPress version is %1$s, however the uploaded theme requires %2$s.' ), 659 $wp_version, 660 $requires_wp 661 ); 662 663 return new WP_Error( 'incompatible_wp_required_version', $this->strings['incompatible_archive'], $error ); 664 } 665 666 $this->new_theme_data = $info; 667 668 return $source; 669 } 670 671 /** 672 * Turns on maintenance mode before attempting to upgrade the active theme. 673 * 674 * Hooked to the {@see 'upgrader_pre_install'} filter by Theme_Upgrader::upgrade() and 675 * Theme_Upgrader::bulk_upgrade(). 676 * 677 * @since 2.8.0 678 * 679 * @param bool|WP_Error $response The installation response before the installation has started. 680 * @param array $theme Theme arguments. 681 * @return bool|WP_Error The original `$response` parameter or WP_Error. 682 */ 683 public function current_before( $response, $theme ) { 684 if ( is_wp_error( $response ) ) { 685 return $response; 686 } 687 688 $theme = isset( $theme['theme'] ) ? $theme['theme'] : ''; 689 690 // Only run if active theme. 691 if ( get_stylesheet() !== $theme ) { 692 return $response; 693 } 694 695 // Change to maintenance mode. Bulk edit handles this separately. 696 if ( ! $this->bulk ) { 697 $this->maintenance_mode( true ); 698 } 699 700 return $response; 701 } 702 703 /** 704 * Turns off maintenance mode after upgrading the active theme. 705 * 706 * Hooked to the {@see 'upgrader_post_install'} filter by Theme_Upgrader::upgrade() 707 * and Theme_Upgrader::bulk_upgrade(). 708 * 709 * @since 2.8.0 710 * 711 * @param bool|WP_Error $response The installation response after the installation has finished. 712 * @param array $theme Theme arguments. 713 * @return bool|WP_Error The original `$response` parameter or WP_Error. 714 */ 715 public function current_after( $response, $theme ) { 716 if ( is_wp_error( $response ) ) { 717 return $response; 718 } 719 720 $theme = isset( $theme['theme'] ) ? $theme['theme'] : ''; 721 722 // Only run if active theme. 723 if ( get_stylesheet() !== $theme ) { 724 return $response; 725 } 726 727 // Ensure stylesheet name hasn't changed after the upgrade: 728 if ( get_stylesheet() === $theme && $theme !== $this->result['destination_name'] ) { 729 wp_clean_themes_cache(); 730 $stylesheet = $this->result['destination_name']; 731 switch_theme( $stylesheet ); 732 } 733 734 // Time to remove maintenance mode. Bulk edit handles this separately. 735 if ( ! $this->bulk ) { 736 $this->maintenance_mode( false ); 737 } 738 return $response; 739 } 740 741 /** 742 * Deletes the old theme during an upgrade. 743 * 744 * Hooked to the {@see 'upgrader_clear_destination'} filter by Theme_Upgrader::upgrade() 745 * and Theme_Upgrader::bulk_upgrade(). 746 * 747 * @since 2.8.0 748 * 749 * @global WP_Filesystem_Base $wp_filesystem Subclass 750 * 751 * @param bool $removed 752 * @param string $local_destination 753 * @param string $remote_destination 754 * @param array $theme 755 * @return bool 756 */ 757 public function delete_old_theme( $removed, $local_destination, $remote_destination, $theme ) { 758 global $wp_filesystem; 759 760 if ( is_wp_error( $removed ) ) { 761 return $removed; // Pass errors through. 762 } 763 764 if ( ! isset( $theme['theme'] ) ) { 765 return $removed; 766 } 767 768 $theme = $theme['theme']; 769 $themes_dir = trailingslashit( $wp_filesystem->wp_themes_dir( $theme ) ); 770 if ( $wp_filesystem->exists( $themes_dir . $theme ) ) { 771 if ( ! $wp_filesystem->delete( $themes_dir . $theme, true ) ) { 772 return false; 773 } 774 } 775 776 return true; 777 } 778 779 /** 780 * Gets the WP_Theme object for a theme. 781 * 782 * @since 2.8.0 783 * @since 3.0.0 The `$theme` argument was added. 784 * 785 * @param string $theme The directory name of the theme. This is optional, and if not supplied, 786 * the directory name from the last result will be used. 787 * @return WP_Theme|false The theme's info object, or false `$theme` is not supplied 788 * and the last result isn't set. 789 */ 790 public function theme_info( $theme = null ) { 791 if ( empty( $theme ) ) { 792 if ( ! empty( $this->result['destination_name'] ) ) { 793 $theme = $this->result['destination_name']; 794 } else { 795 return false; 796 } 797 } 798 799 $theme = wp_get_theme( $theme ); 800 $theme->cache_delete(); 801 802 return $theme; 803 } 804 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Thu Nov 21 08:20:01 2024 | Cross-referenced by PHPXref |