[ Index ] |
PHP Cross Reference of WordPress |
[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 * Initialize 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">%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 * Initialize 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">%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 * Check if a child theme is being installed and we need to install its parent. 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 * Upgrade 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 ), 335 ) 336 ); 337 338 remove_action( 'upgrader_process_complete', 'wp_clean_themes_cache', 9 ); 339 remove_filter( 'upgrader_pre_install', array( $this, 'current_before' ) ); 340 remove_filter( 'upgrader_post_install', array( $this, 'current_after' ) ); 341 remove_filter( 'upgrader_clear_destination', array( $this, 'delete_old_theme' ) ); 342 343 if ( ! $this->result || is_wp_error( $this->result ) ) { 344 return $this->result; 345 } 346 347 wp_clean_themes_cache( $parsed_args['clear_update_cache'] ); 348 349 // Ensure any future auto-update failures trigger a failure email by removing 350 // the last failure notification from the list when themes update successfully. 351 $past_failure_emails = get_option( 'auto_plugin_theme_update_emails', array() ); 352 353 if ( isset( $past_failure_emails[ $theme ] ) ) { 354 unset( $past_failure_emails[ $theme ] ); 355 update_option( 'auto_plugin_theme_update_emails', $past_failure_emails ); 356 } 357 358 return true; 359 } 360 361 /** 362 * Upgrade several themes at once. 363 * 364 * @since 3.0.0 365 * @since 3.7.0 The `$args` parameter was added, making clearing the update cache optional. 366 * 367 * @param string[] $themes Array of the theme slugs. 368 * @param array $args { 369 * Optional. Other arguments for upgrading several themes at once. Default empty array. 370 * 371 * @type bool $clear_update_cache Whether to clear the update cache if successful. 372 * Default true. 373 * } 374 * @return array[]|false An array of results, or false if unable to connect to the filesystem. 375 */ 376 public function bulk_upgrade( $themes, $args = array() ) { 377 $defaults = array( 378 'clear_update_cache' => true, 379 ); 380 $parsed_args = wp_parse_args( $args, $defaults ); 381 382 $this->init(); 383 $this->bulk = true; 384 $this->upgrade_strings(); 385 386 $current = get_site_transient( 'update_themes' ); 387 388 add_filter( 'upgrader_pre_install', array( $this, 'current_before' ), 10, 2 ); 389 add_filter( 'upgrader_post_install', array( $this, 'current_after' ), 10, 2 ); 390 add_filter( 'upgrader_clear_destination', array( $this, 'delete_old_theme' ), 10, 4 ); 391 392 $this->skin->header(); 393 394 // Connect to the filesystem first. 395 $res = $this->fs_connect( array( WP_CONTENT_DIR ) ); 396 if ( ! $res ) { 397 $this->skin->footer(); 398 return false; 399 } 400 401 $this->skin->bulk_header(); 402 403 /* 404 * Only start maintenance mode if: 405 * - running Multisite and there are one or more themes specified, OR 406 * - a theme with an update available is currently in use. 407 * @todo For multisite, maintenance mode should only kick in for individual sites if at all possible. 408 */ 409 $maintenance = ( is_multisite() && ! empty( $themes ) ); 410 foreach ( $themes as $theme ) { 411 $maintenance = $maintenance || get_stylesheet() === $theme || get_template() === $theme; 412 } 413 if ( $maintenance ) { 414 $this->maintenance_mode( true ); 415 } 416 417 $results = array(); 418 419 $this->update_count = count( $themes ); 420 $this->update_current = 0; 421 foreach ( $themes as $theme ) { 422 $this->update_current++; 423 424 $this->skin->theme_info = $this->theme_info( $theme ); 425 426 if ( ! isset( $current->response[ $theme ] ) ) { 427 $this->skin->set_result( true ); 428 $this->skin->before(); 429 $this->skin->feedback( 'up_to_date' ); 430 $this->skin->after(); 431 $results[ $theme ] = true; 432 continue; 433 } 434 435 // Get the URL to the zip file. 436 $r = $current->response[ $theme ]; 437 438 $result = $this->run( 439 array( 440 'package' => $r['package'], 441 'destination' => get_theme_root( $theme ), 442 'clear_destination' => true, 443 'clear_working' => true, 444 'is_multi' => true, 445 'hook_extra' => array( 446 'theme' => $theme, 447 ), 448 ) 449 ); 450 451 $results[ $theme ] = $result; 452 453 // Prevent credentials auth screen from displaying multiple times. 454 if ( false === $result ) { 455 break; 456 } 457 } // End foreach $themes. 458 459 $this->maintenance_mode( false ); 460 461 // Refresh the Theme Update information. 462 wp_clean_themes_cache( $parsed_args['clear_update_cache'] ); 463 464 /** This action is documented in wp-admin/includes/class-wp-upgrader.php */ 465 do_action( 466 'upgrader_process_complete', 467 $this, 468 array( 469 'action' => 'update', 470 'type' => 'theme', 471 'bulk' => true, 472 'themes' => $themes, 473 ) 474 ); 475 476 $this->skin->bulk_footer(); 477 478 $this->skin->footer(); 479 480 // Cleanup our hooks, in case something else does a upgrade on this connection. 481 remove_filter( 'upgrader_pre_install', array( $this, 'current_before' ) ); 482 remove_filter( 'upgrader_post_install', array( $this, 'current_after' ) ); 483 remove_filter( 'upgrader_clear_destination', array( $this, 'delete_old_theme' ) ); 484 485 // Ensure any future auto-update failures trigger a failure email by removing 486 // the last failure notification from the list when themes update successfully. 487 $past_failure_emails = get_option( 'auto_plugin_theme_update_emails', array() ); 488 489 foreach ( $results as $theme => $result ) { 490 // Maintain last failure notification when themes failed to update manually. 491 if ( ! $result || is_wp_error( $result ) || ! isset( $past_failure_emails[ $theme ] ) ) { 492 continue; 493 } 494 495 unset( $past_failure_emails[ $theme ] ); 496 } 497 498 update_option( 'auto_plugin_theme_update_emails', $past_failure_emails ); 499 500 return $results; 501 } 502 503 /** 504 * Checks that the package source contains a valid theme. 505 * 506 * Hooked to the {@see 'upgrader_source_selection'} filter by Theme_Upgrader::install(). 507 * 508 * @since 3.3.0 509 * 510 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. 511 * @global string $wp_version The WordPress version string. 512 * 513 * @param string $source The path to the downloaded package source. 514 * @return string|WP_Error The source as passed, or a WP_Error object on failure. 515 */ 516 public function check_package( $source ) { 517 global $wp_filesystem, $wp_version; 518 519 $this->new_theme_data = array(); 520 521 if ( is_wp_error( $source ) ) { 522 return $source; 523 } 524 525 // Check that the folder contains a valid theme. 526 $working_directory = str_replace( $wp_filesystem->wp_content_dir(), trailingslashit( WP_CONTENT_DIR ), $source ); 527 if ( ! is_dir( $working_directory ) ) { // Sanity check, if the above fails, let's not prevent installation. 528 return $source; 529 } 530 531 // A proper archive should have a style.css file in the single subdirectory. 532 if ( ! file_exists( $working_directory . 'style.css' ) ) { 533 return new WP_Error( 534 'incompatible_archive_theme_no_style', 535 $this->strings['incompatible_archive'], 536 sprintf( 537 /* translators: %s: style.css */ 538 __( 'The theme is missing the %s stylesheet.' ), 539 '<code>style.css</code>' 540 ) 541 ); 542 } 543 544 // All these headers are needed on Theme_Installer_Skin::do_overwrite(). 545 $info = get_file_data( 546 $working_directory . 'style.css', 547 array( 548 'Name' => 'Theme Name', 549 'Version' => 'Version', 550 'Author' => 'Author', 551 'Template' => 'Template', 552 'RequiresWP' => 'Requires at least', 553 'RequiresPHP' => 'Requires PHP', 554 ) 555 ); 556 557 if ( empty( $info['Name'] ) ) { 558 return new WP_Error( 559 'incompatible_archive_theme_no_name', 560 $this->strings['incompatible_archive'], 561 sprintf( 562 /* translators: %s: style.css */ 563 __( 'The %s stylesheet does not contain a valid theme header.' ), 564 '<code>style.css</code>' 565 ) 566 ); 567 } 568 569 // If it's not a child theme, it must have at least an index.php to be legit. 570 if ( empty( $info['Template'] ) && ! file_exists( $working_directory . 'index.php' ) ) { 571 return new WP_Error( 572 'incompatible_archive_theme_no_index', 573 $this->strings['incompatible_archive'], 574 sprintf( 575 /* translators: %s: index.php */ 576 __( 'The theme is missing the %s file.' ), 577 '<code>index.php</code>' 578 ) 579 ); 580 } 581 582 $requires_php = isset( $info['RequiresPHP'] ) ? $info['RequiresPHP'] : null; 583 $requires_wp = isset( $info['RequiresWP'] ) ? $info['RequiresWP'] : null; 584 585 if ( ! is_php_version_compatible( $requires_php ) ) { 586 $error = sprintf( 587 /* translators: 1: Current PHP version, 2: Version required by the uploaded theme. */ 588 __( 'The PHP version on your server is %1$s, however the uploaded theme requires %2$s.' ), 589 phpversion(), 590 $requires_php 591 ); 592 593 return new WP_Error( 'incompatible_php_required_version', $this->strings['incompatible_archive'], $error ); 594 } 595 if ( ! is_wp_version_compatible( $requires_wp ) ) { 596 $error = sprintf( 597 /* translators: 1: Current WordPress version, 2: Version required by the uploaded theme. */ 598 __( 'Your WordPress version is %1$s, however the uploaded theme requires %2$s.' ), 599 $wp_version, 600 $requires_wp 601 ); 602 603 return new WP_Error( 'incompatible_wp_required_version', $this->strings['incompatible_archive'], $error ); 604 } 605 606 $this->new_theme_data = $info; 607 608 return $source; 609 } 610 611 /** 612 * Turn on maintenance mode before attempting to upgrade the active theme. 613 * 614 * Hooked to the {@see 'upgrader_pre_install'} filter by Theme_Upgrader::upgrade() and 615 * Theme_Upgrader::bulk_upgrade(). 616 * 617 * @since 2.8.0 618 * 619 * @param bool|WP_Error $response The installation response before the installation has started. 620 * @param array $theme Theme arguments. 621 * @return bool|WP_Error The original `$response` parameter or WP_Error. 622 */ 623 public function current_before( $response, $theme ) { 624 if ( is_wp_error( $response ) ) { 625 return $response; 626 } 627 628 $theme = isset( $theme['theme'] ) ? $theme['theme'] : ''; 629 630 // Only run if active theme. 631 if ( get_stylesheet() !== $theme ) { 632 return $response; 633 } 634 635 // Change to maintenance mode. Bulk edit handles this separately. 636 if ( ! $this->bulk ) { 637 $this->maintenance_mode( true ); 638 } 639 640 return $response; 641 } 642 643 /** 644 * Turn off maintenance mode after upgrading the active theme. 645 * 646 * Hooked to the {@see 'upgrader_post_install'} filter by Theme_Upgrader::upgrade() 647 * and Theme_Upgrader::bulk_upgrade(). 648 * 649 * @since 2.8.0 650 * 651 * @param bool|WP_Error $response The installation response after the installation has finished. 652 * @param array $theme Theme arguments. 653 * @return bool|WP_Error The original `$response` parameter or WP_Error. 654 */ 655 public function current_after( $response, $theme ) { 656 if ( is_wp_error( $response ) ) { 657 return $response; 658 } 659 660 $theme = isset( $theme['theme'] ) ? $theme['theme'] : ''; 661 662 // Only run if active theme. 663 if ( get_stylesheet() !== $theme ) { 664 return $response; 665 } 666 667 // Ensure stylesheet name hasn't changed after the upgrade: 668 if ( get_stylesheet() === $theme && $theme !== $this->result['destination_name'] ) { 669 wp_clean_themes_cache(); 670 $stylesheet = $this->result['destination_name']; 671 switch_theme( $stylesheet ); 672 } 673 674 // Time to remove maintenance mode. Bulk edit handles this separately. 675 if ( ! $this->bulk ) { 676 $this->maintenance_mode( false ); 677 } 678 return $response; 679 } 680 681 /** 682 * Delete the old theme during an upgrade. 683 * 684 * Hooked to the {@see 'upgrader_clear_destination'} filter by Theme_Upgrader::upgrade() 685 * and Theme_Upgrader::bulk_upgrade(). 686 * 687 * @since 2.8.0 688 * 689 * @global WP_Filesystem_Base $wp_filesystem Subclass 690 * 691 * @param bool $removed 692 * @param string $local_destination 693 * @param string $remote_destination 694 * @param array $theme 695 * @return bool 696 */ 697 public function delete_old_theme( $removed, $local_destination, $remote_destination, $theme ) { 698 global $wp_filesystem; 699 700 if ( is_wp_error( $removed ) ) { 701 return $removed; // Pass errors through. 702 } 703 704 if ( ! isset( $theme['theme'] ) ) { 705 return $removed; 706 } 707 708 $theme = $theme['theme']; 709 $themes_dir = trailingslashit( $wp_filesystem->wp_themes_dir( $theme ) ); 710 if ( $wp_filesystem->exists( $themes_dir . $theme ) ) { 711 if ( ! $wp_filesystem->delete( $themes_dir . $theme, true ) ) { 712 return false; 713 } 714 } 715 716 return true; 717 } 718 719 /** 720 * Get the WP_Theme object for a theme. 721 * 722 * @since 2.8.0 723 * @since 3.0.0 The `$theme` argument was added. 724 * 725 * @param string $theme The directory name of the theme. This is optional, and if not supplied, 726 * the directory name from the last result will be used. 727 * @return WP_Theme|false The theme's info object, or false `$theme` is not supplied 728 * and the last result isn't set. 729 */ 730 public function theme_info( $theme = null ) { 731 if ( empty( $theme ) ) { 732 if ( ! empty( $this->result['destination_name'] ) ) { 733 $theme = $this->result['destination_name']; 734 } else { 735 return false; 736 } 737 } 738 739 $theme = wp_get_theme( $theme ); 740 $theme->cache_delete(); 741 742 return $theme; 743 } 744 745 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Nov 21 01:00:03 2024 | Cross-referenced by PHPXref 0.7.1 |