- Timestamp:
- 11/30/2017 11:09:33 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-admin/includes/class-wp-automatic-updater.php
r41914 r42343 30 30 public function is_disabled() { 31 31 // Background updates are disabled if you don't want file changes. 32 if ( ! wp_is_file_mod_allowed( 'automatic_updater' ) ) 32 if ( ! wp_is_file_mod_allowed( 'automatic_updater' ) ) { 33 33 return true; 34 35 if ( wp_installing() ) 34 } 35 36 if ( wp_installing() ) { 36 37 return true; 38 } 37 39 38 40 // More fine grained control can be done through the WP_AUTO_UPDATE_CORE constant and filters. … … 72 74 public function is_vcs_checkout( $context ) { 73 75 $context_dirs = array( untrailingslashit( $context ) ); 74 if ( $context !== ABSPATH ) 76 if ( $context !== ABSPATH ) { 75 77 $context_dirs[] = untrailingslashit( ABSPATH ); 76 77 $vcs_dirs = array( '.svn', '.git', '.hg', '.bzr' ); 78 } 79 80 $vcs_dirs = array( '.svn', '.git', '.hg', '.bzr' ); 78 81 $check_dirs = array(); 79 82 … … 84 87 85 88 // Once we've hit '/' or 'C:\', we need to stop. dirname will keep returning the input here. 86 if ( $context_dir == dirname( $context_dir ) ) 89 if ( $context_dir == dirname( $context_dir ) ) { 87 90 break; 88 89 // Continue one level at a time. 91 } 92 93 // Continue one level at a time. 90 94 } while ( $context_dir = dirname( $context_dir ) ); 91 95 } … … 96 100 foreach ( $vcs_dirs as $vcs_dir ) { 97 101 foreach ( $check_dirs as $check_dir ) { 98 if ( $checkout = @is_dir( rtrim( $check_dir, '\\/' ) . "/$vcs_dir" ) ) 102 if ( $checkout = @is_dir( rtrim( $check_dir, '\\/' ) . "/$vcs_dir" ) ) { 99 103 break 2; 104 } 100 105 } 101 106 } … … 132 137 $skin = new Automatic_Upgrader_Skin; 133 138 134 if ( $this->is_disabled() ) 139 if ( $this->is_disabled() ) { 135 140 return false; 141 } 136 142 137 143 // Only relax the filesystem checks when the update doesn't include new files … … 143 149 // If we can't do an auto core update, we may still be able to email the user. 144 150 if ( ! $skin->request_filesystem_credentials( false, $context, $allow_relaxed_file_ownership ) || $this->is_vcs_checkout( $context ) ) { 145 if ( 'core' == $type ) 151 if ( 'core' == $type ) { 146 152 $this->send_core_update_notification_email( $item ); 153 } 147 154 return false; 148 155 } 149 156 150 157 // Next up, is this an item we can update? 151 if ( 'core' == $type ) 158 if ( 'core' == $type ) { 152 159 $update = Core_Upgrader::should_update_to_version( $item->current ); 153 else160 } else { 154 161 $update = ! empty( $item->autoupdate ); 162 } 155 163 156 164 /** … … 176 184 177 185 if ( ! $update ) { 178 if ( 'core' == $type ) 186 if ( 'core' == $type ) { 179 187 $this->send_core_update_notification_email( $item ); 188 } 180 189 return false; 181 190 } … … 186 195 187 196 $php_compat = version_compare( phpversion(), $item->php_version, '>=' ); 188 if ( file_exists( WP_CONTENT_DIR . '/db.php' ) && empty( $wpdb->is_mysql ) ) 197 if ( file_exists( WP_CONTENT_DIR . '/db.php' ) && empty( $wpdb->is_mysql ) ) { 189 198 $mysql_compat = true; 190 else199 } else { 191 200 $mysql_compat = version_compare( $wpdb->db_version(), $item->mysql_version, '>=' ); 192 193 if ( ! $php_compat || ! $mysql_compat ) 201 } 202 203 if ( ! $php_compat || ! $mysql_compat ) { 194 204 return false; 205 } 195 206 } 196 207 … … 209 220 210 221 // Don't notify if we've already notified the same email address of the same version. 211 if ( $notified && $notified['email'] == get_site_option( 'admin_email' ) && $notified['version'] == $item->current ) 222 if ( $notified && $notified['email'] == get_site_option( 'admin_email' ) && $notified['version'] == $item->current ) { 212 223 return false; 224 } 213 225 214 226 // See if we need to notify users of a core update. … … 234 246 * @param object $item The update offer. 235 247 */ 236 if ( ! apply_filters( 'send_core_update_notification_email', $notify, $item ) ) 248 if ( ! apply_filters( 'send_core_update_notification_email', $notify, $item ) ) { 237 249 return false; 250 } 238 251 239 252 $this->send_email( 'manual', $item ); … … 276 289 277 290 // Determine whether we can and should perform this update. 278 if ( ! $this->should_update( $type, $item, $context ) ) 291 if ( ! $this->should_update( $type, $item, $context ) ) { 279 292 return false; 293 } 280 294 281 295 /** … … 299 313 case 'theme': 300 314 $upgrader_item = $item->theme; 301 $theme = wp_get_theme( $upgrader_item );302 $item_name = $theme->Get( 'Name' );315 $theme = wp_get_theme( $upgrader_item ); 316 $item_name = $theme->Get( 'Name' ); 303 317 $skin->feedback( __( 'Updating theme: %s' ), $item_name ); 304 318 break; 305 319 case 'plugin': 306 320 $upgrader_item = $item->plugin; 307 $plugin_data = get_plugin_data( $context . '/' . $upgrader_item );308 $item_name = $plugin_data['Name'];321 $plugin_data = get_plugin_data( $context . '/' . $upgrader_item ); 322 $item_name = $plugin_data['Name']; 309 323 $skin->feedback( __( 'Updating plugin: %s' ), $item_name ); 310 324 break; 311 325 case 'translation': 312 326 $language_item_name = $upgrader->get_name_for_update( $item ); 313 $item_name = sprintf( __( 'Translations for %s' ), $language_item_name );327 $item_name = sprintf( __( 'Translations for %s' ), $language_item_name ); 314 328 $skin->feedback( sprintf( __( 'Updating translations for %1$s (%2$s)…' ), $language_item_name, $item->language ) ); 315 329 break; … … 322 336 323 337 // Boom, This sites about to get a whole new splash of paint! 324 $upgrade_result = $upgrader->upgrade( $upgrader_item, array( 325 'clear_update_cache' => false, 326 // Always use partial builds if possible for core updates. 327 'pre_check_md5' => false, 328 // Only available for core updates. 329 'attempt_rollback' => true, 330 // Allow relaxed file ownership in some scenarios 331 'allow_relaxed_file_ownership' => $allow_relaxed_file_ownership, 332 ) ); 338 $upgrade_result = $upgrader->upgrade( 339 $upgrader_item, array( 340 'clear_update_cache' => false, 341 // Always use partial builds if possible for core updates. 342 'pre_check_md5' => false, 343 // Only available for core updates. 344 'attempt_rollback' => true, 345 // Allow relaxed file ownership in some scenarios 346 'allow_relaxed_file_ownership' => $allow_relaxed_file_ownership, 347 ) 348 ); 333 349 334 350 // If the filesystem is unavailable, false is returned. … … 355 371 'result' => $upgrade_result, 356 372 'name' => $item_name, 357 'messages' => $skin->get_upgrade_messages() 373 'messages' => $skin->get_upgrade_messages(), 358 374 ); 359 375 … … 367 383 */ 368 384 public function run() { 369 if ( $this->is_disabled() ) 385 if ( $this->is_disabled() ) { 370 386 return; 371 372 if ( ! is_main_network() || ! is_main_site() ) 387 } 388 389 if ( ! is_main_network() || ! is_main_site() ) { 373 390 return; 374 375 if ( ! WP_Upgrader::create_lock( 'auto_updater' ) ) 391 } 392 393 if ( ! WP_Upgrader::create_lock( 'auto_updater' ) ) { 376 394 return; 395 } 377 396 378 397 // Don't automatically run these thins, as we'll handle it ourselves … … 385 404 wp_update_plugins(); // Check for Plugin updates 386 405 $plugin_updates = get_site_transient( 'update_plugins' ); 387 if ( $plugin_updates && ! empty( $plugin_updates->response ) ) {406 if ( $plugin_updates && ! empty( $plugin_updates->response ) ) { 388 407 foreach ( $plugin_updates->response as $plugin ) { 389 408 $this->update( 'plugin', $plugin ); … … 396 415 wp_update_themes(); // Check for Theme updates 397 416 $theme_updates = get_site_transient( 'update_themes' ); 398 if ( $theme_updates && ! empty( $theme_updates->response ) ) {417 if ( $theme_updates && ! empty( $theme_updates->response ) ) { 399 418 foreach ( $theme_updates->response as $theme ) { 400 419 $this->update( 'theme', (object) $theme ); … … 408 427 $core_update = find_core_auto_update(); 409 428 410 if ( $core_update ) 429 if ( $core_update ) { 411 430 $this->update( 'core', $core_update ); 431 } 412 432 413 433 // Clean up, and check for any pending translations … … 457 477 * Return false to avoid the email. 458 478 */ 459 if ( apply_filters( 'automatic_updates_send_debug_email', $development_version ) ) 479 if ( apply_filters( 'automatic_updates_send_debug_email', $development_version ) ) { 460 480 $this->send_debug_email(); 461 462 if ( ! empty( $this->update_results['core'] ) ) 481 } 482 483 if ( ! empty( $this->update_results['core'] ) ) { 463 484 $this->after_core_update( $this->update_results['core'][0] ); 485 } 464 486 465 487 /** … … 504 526 } elseif ( $error_code === 'rollback_was_required' && is_wp_error( $result->get_error_data()->rollback ) ) { 505 527 // A rollback is only critical if it failed too. 506 $critical = true;528 $critical = true; 507 529 $rollback_result = $result->get_error_data()->rollback; 508 530 } elseif ( false !== strpos( $error_code, 'do_rollback' ) ) { … … 539 561 * the issue could actually be on WordPress.org's side.) If that one fails, then email. 540 562 */ 541 $send = true;542 543 544 545 546 547 548 563 $send = true; 564 $transient_failures = array( 'incompatible_archive', 'download_failed', 'insane_distro', 'locked' ); 565 if ( in_array( $error_code, $transient_failures ) && ! get_site_option( 'auto_core_update_failed' ) ) { 566 wp_schedule_single_event( time() + HOUR_IN_SECONDS, 'wp_maybe_auto_update' ); 567 $send = false; 568 } 569 570 $n = get_site_option( 'auto_core_update_notified' ); 549 571 // Don't notify if we've already notified the same email address of the same version of the same notification type. 550 if ( $n && 'fail' == $n['type'] && $n['email'] == get_site_option( 'admin_email' ) && $n['version'] == $core_update->current ) 572 if ( $n && 'fail' == $n['type'] && $n['email'] == get_site_option( 'admin_email' ) && $n['version'] == $core_update->current ) { 551 573 $send = false; 552 553 update_site_option( 'auto_core_update_failed', array( 554 'attempted' => $core_update->current, 555 'current' => $wp_version, 556 'error_code' => $error_code, 557 'error_data' => $result->get_error_data(), 558 'timestamp' => time(), 559 'retry' => in_array( $error_code, $transient_failures ), 560 ) ); 561 562 if ( $send ) 574 } 575 576 update_site_option( 577 'auto_core_update_failed', array( 578 'attempted' => $core_update->current, 579 'current' => $wp_version, 580 'error_code' => $error_code, 581 'error_data' => $result->get_error_data(), 582 'timestamp' => time(), 583 'retry' => in_array( $error_code, $transient_failures ), 584 ) 585 ); 586 587 if ( $send ) { 563 588 $this->send_email( 'fail', $core_update, $result ); 589 } 564 590 } 565 591 … … 574 600 */ 575 601 protected function send_email( $type, $core_update, $result = null ) { 576 update_site_option( 'auto_core_update_notified', array( 577 'type' => $type, 578 'email' => get_site_option( 'admin_email' ), 579 'version' => $core_update->current, 580 'timestamp' => time(), 581 ) ); 602 update_site_option( 603 'auto_core_update_notified', array( 604 'type' => $type, 605 'email' => get_site_option( 'admin_email' ), 606 'version' => $core_update->current, 607 'timestamp' => time(), 608 ) 609 ); 582 610 583 611 $next_user_core_update = get_preferred_from_update_core(); 584 612 // If the update transient is empty, use the update we just performed 585 if ( ! $next_user_core_update ) 613 if ( ! $next_user_core_update ) { 586 614 $next_user_core_update = $core_update; 615 } 587 616 $newer_version_available = ( 'upgrade' == $next_user_core_update->response && version_compare( $next_user_core_update->version, $core_update->version, '>' ) ); 588 617 … … 598 627 * @param mixed $result The result for the core update. Can be WP_Error. 599 628 */ 600 if ( 'manual' !== $type && ! apply_filters( 'auto_core_update_send_email', true, $type, $core_update, $result ) ) 629 if ( 'manual' !== $type && ! apply_filters( 'auto_core_update_send_email', true, $type, $core_update, $result ) ) { 601 630 return; 631 } 602 632 603 633 switch ( $type ) { 604 case 'success' 634 case 'success': // We updated. 605 635 /* translators: 1: Site name, 2: WordPress version number. */ 606 636 $subject = __( '[%1$s] Your site has updated to WordPress %2$s' ); 607 637 break; 608 638 609 case 'fail' 610 case 'manual' 639 case 'fail': // We tried to update but couldn't. 640 case 'manual': // We can't update (and made no attempt). 611 641 /* translators: 1: Site name, 2: WordPress version number. */ 612 642 $subject = __( '[%1$s] WordPress %2$s is available. Please update!' ); 613 643 break; 614 644 615 case 'critical' 645 case 'critical': // We tried to update, started to copy files, then things went wrong. 616 646 /* translators: 1: Site name. */ 617 647 $subject = __( '[%1$s] URGENT: Your site may be down due to a failed update' ); 618 648 break; 619 649 620 default 650 default: 621 651 return; 622 652 } … … 629 659 630 660 switch ( $type ) { 631 case 'success' 661 case 'success': 632 662 $body .= sprintf( __( 'Howdy! Your site at %1$s has been updated automatically to WordPress %2$s.' ), home_url(), $core_update->current ); 633 663 $body .= "\n\n"; 634 if ( ! $newer_version_available ) 664 if ( ! $newer_version_available ) { 635 665 $body .= __( 'No further action is needed on your part.' ) . ' '; 666 } 636 667 637 668 // Can only reference the About screen if their update was successful. 638 669 list( $about_version ) = explode( '-', $core_update->current, 2 ); 639 $body .= sprintf( __( "For more on version %s, see the About WordPress screen:"), $about_version );640 $body .= "\n" . admin_url( 'about.php' );670 $body .= sprintf( __( 'For more on version %s, see the About WordPress screen:' ), $about_version ); 671 $body .= "\n" . admin_url( 'about.php' ); 641 672 642 673 if ( $newer_version_available ) { … … 648 679 break; 649 680 650 case 'fail' 651 case 'manual' 681 case 'fail': 682 case 'manual': 652 683 $body .= sprintf( __( 'Please update your site at %1$s to WordPress %2$s.' ), home_url(), $next_user_core_update->current ); 653 684 … … 656 687 // Don't show this message if there is a newer version available. 657 688 // Potential for confusion, and also not useful for them to know at this point. 658 if ( 'fail' == $type && ! $newer_version_available ) 689 if ( 'fail' == $type && ! $newer_version_available ) { 659 690 $body .= __( 'We tried but were unable to update your site automatically.' ) . ' '; 691 } 660 692 661 693 $body .= __( 'Updating is easy and only takes a few moments:' ); … … 663 695 break; 664 696 665 case 'critical' 666 if ( $newer_version_available ) 697 case 'critical': 698 if ( $newer_version_available ) { 667 699 $body .= sprintf( __( 'Your site at %1$s experienced a critical failure while trying to update WordPress to version %2$s.' ), home_url(), $core_update->current ); 668 else700 } else { 669 701 $body .= sprintf( __( 'Your site at %1$s experienced a critical failure while trying to update to the latest version of WordPress, %2$s.' ), home_url(), $core_update->current ); 702 } 670 703 671 704 $body .= "\n\n" . __( "This means your site may be offline or broken. Don't panic; this can be fixed." ); … … 679 712 if ( $critical_support ) { 680 713 // Support offer if available. 681 $body .= "\n\n" . sprintf( __( "The WordPress team is willing to help you. Forward this email to %s and the team will work with you to make sure your site is working."), $core_update->support_email );714 $body .= "\n\n" . sprintf( __( 'The WordPress team is willing to help you. Forward this email to %s and the team will work with you to make sure your site is working.' ), $core_update->support_email ); 682 715 } else { 683 716 // Add a note about the support forums. … … 692 725 693 726 if ( $critical_support ) { 694 $body .= " ". __( "If you reach out to us, we'll also ensure you'll never have this problem again." );727 $body .= ' ' . __( "If you reach out to us, we'll also ensure you'll never have this problem again." ); 695 728 } 696 729 … … 711 744 // If we had a rollback and we're still critical, then the rollback failed too. 712 745 // Loop through all errors (the main WP_Error, the update result, the rollback result) for code, data, etc. 713 if ( 'rollback_was_required' == $result->get_error_code() ) 746 if ( 'rollback_was_required' == $result->get_error_code() ) { 714 747 $errors = array( $result, $result->get_error_data()->update, $result->get_error_data()->rollback ); 715 else748 } else { 716 749 $errors = array( $result ); 750 } 717 751 718 752 foreach ( $errors as $error ) { 719 if ( ! is_wp_error( $error ) ) 753 if ( ! is_wp_error( $error ) ) { 720 754 continue; 755 } 721 756 $error_code = $error->get_error_code(); 722 $body .= "\n\n" . sprintf( __( "Error code: %s"), $error_code );723 if ( 'rollback_was_required' == $error_code ) 757 $body .= "\n\n" . sprintf( __( 'Error code: %s' ), $error_code ); 758 if ( 'rollback_was_required' == $error_code ) { 724 759 continue; 725 if ( $error->get_error_message() ) 760 } 761 if ( $error->get_error_message() ) { 726 762 $body .= "\n" . $error->get_error_message(); 763 } 727 764 $error_data = $error->get_error_data(); 728 if ( $error_data ) 765 if ( $error_data ) { 729 766 $body .= "\n" . implode( ', ', (array) $error_data ); 767 } 730 768 } 731 769 $body .= "\n"; 732 770 } 733 771 734 $to = get_site_option( 'admin_email' );772 $to = get_site_option( 'admin_email' ); 735 773 $headers = ''; 736 774 … … 768 806 protected function send_debug_email() { 769 807 $update_count = 0; 770 foreach ( $this->update_results as $type => $updates ) 808 foreach ( $this->update_results as $type => $updates ) { 771 809 $update_count += count( $updates ); 772 773 $body = array(); 810 } 811 812 $body = array(); 774 813 $failures = 0; 775 814 … … 790 829 // Plugins, Themes, Translations 791 830 foreach ( array( 'plugin', 'theme', 'translation' ) as $type ) { 792 if ( ! isset( $this->update_results[ $type ] ) ) 831 if ( ! isset( $this->update_results[ $type ] ) ) { 793 832 continue; 833 } 794 834 $success_items = wp_list_filter( $this->update_results[ $type ], array( 'result' => true ) ); 795 835 if ( $success_items ) { … … 826 866 $site_title = wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ); 827 867 if ( $failures ) { 828 $body[] = trim( __( 829 "BETA TESTING? 868 $body[] = trim( 869 __( 870 "BETA TESTING? 830 871 ============= 831 872 … … 836 877 * Or, if you're comfortable writing a bug report: https://core.trac.wordpress.org/ 837 878 838 Thanks! -- The WordPress Team" ) ); 879 Thanks! -- The WordPress Team" 880 ) 881 ); 839 882 $body[] = ''; 840 883 … … 844 887 } 845 888 846 $body[] = trim( __( 847 'UPDATE LOG 848 ==========' ) ); 889 $body[] = trim( 890 __( 891 'UPDATE LOG 892 ==========' 893 ) 894 ); 849 895 $body[] = ''; 850 896 851 897 foreach ( array( 'core', 'plugin', 'theme', 'translation' ) as $type ) { 852 if ( ! isset( $this->update_results[ $type ] ) ) 898 if ( ! isset( $this->update_results[ $type ] ) ) { 853 899 continue; 900 } 854 901 foreach ( $this->update_results[ $type ] as $update ) { 855 902 $body[] = $update->name; 856 903 $body[] = str_repeat( '-', strlen( $update->name ) ); 857 foreach ( $update->messages as $message ) 858 $body[] = " " . html_entity_decode( str_replace( '…', '...', $message ) ); 904 foreach ( $update->messages as $message ) { 905 $body[] = ' ' . html_entity_decode( str_replace( '…', '...', $message ) ); 906 } 859 907 if ( is_wp_error( $update->result ) ) { 860 908 $results = array( 'update' => $update->result ); 861 909 // If we rolled back, we want to know an error that occurred then too. 862 if ( 'rollback_was_required' === $update->result->get_error_code() ) 910 if ( 'rollback_was_required' === $update->result->get_error_code() ) { 863 911 $results = (array) $update->result->get_error_data(); 912 } 864 913 foreach ( $results as $result_type => $result ) { 865 if ( ! is_wp_error( $result ) ) 914 if ( ! is_wp_error( $result ) ) { 866 915 continue; 916 } 867 917 868 918 if ( 'rollback' === $result_type ) { … … 874 924 } 875 925 876 if ( $result->get_error_data() ) 926 if ( $result->get_error_data() ) { 877 927 $body[] = ' ' . implode( ', ', (array) $result->get_error_data() ); 928 } 878 929 } 879 930 } … … 886 937 'subject' => $subject, 887 938 'body' => implode( "\n", $body ), 888 'headers' => '' 939 'headers' => '', 889 940 ); 890 941
Note: See TracChangeset
for help on using the changeset viewer.