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