WordPress.org

Make WordPress Core

Ticket #22704: 22704.diff

File 22704.diff, 26.0 KB (added by dd32, 8 months ago)
  • src/wp-admin/includes/class-wp-upgrader.php

     
    166166        function install_package($args = array()) { 
    167167                global $wp_filesystem, $wp_theme_directories; 
    168168 
    169                 $defaults = array( 'source' => '', 'destination' => '', //Please always pass these 
    170                                                 'clear_destination' => false, 'clear_working' => false, 
    171                                                 'abort_if_destination_exists' => true, 
    172                                                 'hook_extra' => array()); 
     169                $defaults = array( 
     170                        'source' => '', // Please always pass these 
     171                        'destination' => '', // and this 
     172                        'clear_destination' => false, 'clear_working' => false, 
     173                        'abort_if_destination_exists' => true, 
     174                        'hook_extra' => array() 
     175                ); 
    173176 
    174177                $args = wp_parse_args($args, $defaults); 
    175178                extract($args); 
     
    277280 
    278281        function run($options) { 
    279282 
    280                 $defaults = array(      'package' => '', //Please always pass this. 
    281                                                         'destination' => '', //And this 
    282                                                         'clear_destination' => false, 
    283                                                         'abort_if_destination_exists' => true, // Abort if the Destination directory exists, Pass clear_destination as false please 
    284                                                         'clear_working' => true, 
    285                                                         'is_multi' => false, 
    286                                                         'hook_extra' => array() //Pass any extra $hook_extra args here, this will be passed to any hooked filters. 
    287                                                 ); 
     283                $defaults = array( 
     284                        'package' => '', // Please always pass this. 
     285                        'destination' => '', // And this 
     286                        'clear_destination' => false, 
     287                        'abort_if_destination_exists' => true, // Abort if the Destination directory exists, Pass clear_destination as false please 
     288                        'clear_working' => true, 
     289                        'is_multi' => false, 
     290                        'hook_extra' => array() // Pass any extra $hook_extra args here, this will be passed to any hooked filters. 
     291                ); 
    288292 
    289293                $options = wp_parse_args($options, $defaults); 
    290294                extract($options); 
     
    324328 
    325329                //With the given options, this installs it to the destination directory. 
    326330                $result = $this->install_package( array( 
    327                                                                                         'source' => $working_dir, 
    328                                                                                         'destination' => $destination, 
    329                                                                                         'clear_destination' => $clear_destination, 
    330                                                                                         'abort_if_destination_exists' => $abort_if_destination_exists, 
    331                                                                                         'clear_working' => $clear_working, 
    332                                                                                         'hook_extra' => $hook_extra 
    333                                                                                 ) ); 
     331                        'source' => $working_dir, 
     332                        'destination' => $destination, 
     333                        'clear_destination' => $clear_destination, 
     334                        'abort_if_destination_exists' => $abort_if_destination_exists, 
     335                        'clear_working' => $clear_working, 
     336                        'hook_extra' => $hook_extra 
     337                ) ); 
     338 
    334339                $this->skin->set_result($result); 
    335340                if ( is_wp_error($result) ) { 
    336341                        $this->skin->error($result); 
     
    398403                $this->strings['process_success'] = __('Plugin installed successfully.'); 
    399404        } 
    400405 
    401         function install($package) { 
     406        function install( $package, $args = array() ) { 
    402407 
     408                $defaults = array( 
     409                        'clear_update_cache' => true, 
     410                ); 
     411                $parsed_args = wp_parse_args( $defaults, $args ); 
     412 
    403413                $this->init(); 
    404414                $this->install_strings(); 
    405415 
    406416                add_filter('upgrader_source_selection', array(&$this, 'check_package') ); 
    407417 
    408                 $this->run(array( 
    409                                         'package' => $package, 
    410                                         'destination' => WP_PLUGIN_DIR, 
    411                                         'clear_destination' => false, //Do not overwrite files. 
    412                                         'clear_working' => true, 
    413                                         'hook_extra' => array() 
    414                                         )); 
     418                $this->run( array( 
     419                        'package' => $package, 
     420                        'destination' => WP_PLUGIN_DIR, 
     421                        'clear_destination' => false, //Do not overwrite files. 
     422                        'clear_working' => true, 
     423                        'hook_extra' => array() 
     424                ) ); 
    415425 
    416426                remove_filter('upgrader_source_selection', array(&$this, 'check_package') ); 
    417427 
    418428                if ( ! $this->result || is_wp_error($this->result) ) 
    419429                        return $this->result; 
    420430 
    421                 // Force refresh of plugin update information 
    422                 delete_site_transient('update_plugins'); 
    423                 wp_cache_delete( 'plugins', 'plugins' ); 
     431                if ( $parsed_args['clear_update_cache'] ) { 
     432                        // Force refresh of plugin update information 
     433                        delete_site_transient('update_plugins'); 
     434                        wp_cache_delete( 'plugins', 'plugins' ); 
     435                } 
     436 
    424437                do_action( 'upgrader_process_complete', $this, array( 'action' => 'install', 'type' => 'plugin' ), $package ); 
    425438 
    426439                return true; 
    427440        } 
    428441 
    429         function upgrade($plugin) { 
     442        function upgrade( $plugin, $args = array() ) { 
    430443 
     444                $defaults = array( 
     445                        'clear_update_cache' => true, 
     446                ); 
     447                $parsed_args = wp_parse_args( $defaults, $args ); 
     448 
    431449                $this->init(); 
    432450                $this->upgrade_strings(); 
    433451 
     
    447465                add_filter('upgrader_clear_destination', array(&$this, 'delete_old_plugin'), 10, 4); 
    448466                //'source_selection' => array(&$this, 'source_selection'), //there's a trac ticket to move up the directory for zip's which are made a bit differently, useful for non-.org plugins. 
    449467 
    450                 $this->run(array( 
    451                                         'package' => $r->package, 
    452                                         'destination' => WP_PLUGIN_DIR, 
    453                                         'clear_destination' => true, 
    454                                         'clear_working' => true, 
    455                                         'hook_extra' => array( 
    456                                                                 'plugin' => $plugin 
    457                                         ) 
    458                                 )); 
     468                $this->run( array( 
     469                        'package' => $r->package, 
     470                        'destination' => WP_PLUGIN_DIR, 
     471                        'clear_destination' => true, 
     472                        'clear_working' => true, 
     473                        'hook_extra' => array( 
     474                                'plugin' => $plugin 
     475                        ), 
     476                ) ); 
    459477 
    460478                // Cleanup our hooks, in case something else does a upgrade on this connection. 
    461479                remove_filter('upgrader_pre_install', array(&$this, 'deactivate_plugin_before_upgrade')); 
     
    464482                if ( ! $this->result || is_wp_error($this->result) ) 
    465483                        return $this->result; 
    466484 
    467                 // Force refresh of plugin update information 
    468                 delete_site_transient('update_plugins'); 
    469                 wp_cache_delete( 'plugins', 'plugins' ); 
     485                if ( $parsed_args['clear_update_cache'] ) { 
     486                        // Force refresh of plugin update information 
     487                        delete_site_transient('update_plugins'); 
     488                        wp_cache_delete( 'plugins', 'plugins' ); 
     489                } 
     490 
    470491                do_action( 'upgrader_process_complete', $this, array( 'action' => 'update', 'type' => 'plugin' ), $plugin ); 
    471492 
    472493                return true; 
    473494        } 
    474495 
    475         function bulk_upgrade($plugins) { 
     496        function bulk_upgrade( $plugins, $args = array() ) { 
    476497 
     498                $defaults = array( 
     499                        'clear_update_cache' => true, 
     500                ); 
     501                $parsed_args = wp_parse_args( $defaults, $args ); 
     502 
    477503                $this->init(); 
    478504                $this->bulk = true; 
    479505                $this->upgrade_strings(); 
     
    525551 
    526552                        $this->skin->plugin_active = is_plugin_active($plugin); 
    527553 
    528                         $result = $this->run(array( 
    529                                                 'package' => $r->package, 
    530                                                 'destination' => WP_PLUGIN_DIR, 
    531                                                 'clear_destination' => true, 
    532                                                 'clear_working' => true, 
    533                                                 'is_multi' => true, 
    534                                                 'hook_extra' => array( 
    535                                                                         'plugin' => $plugin 
    536                                                 ) 
    537                                         )); 
     554                        $result = $this->run( array( 
     555                                'package' => $r->package, 
     556                                'destination' => WP_PLUGIN_DIR, 
     557                                'clear_destination' => true, 
     558                                'clear_working' => true, 
     559                                'is_multi' => true, 
     560                                'hook_extra' => array( 
     561                                        'plugin' => $plugin 
     562                                ) 
     563                        ) ); 
    538564 
    539565                        $results[$plugin] = $this->result; 
    540566 
     
    552578                // Cleanup our hooks, in case something else does a upgrade on this connection. 
    553579                remove_filter('upgrader_clear_destination', array(&$this, 'delete_old_plugin')); 
    554580 
    555                 // Force refresh of plugin update information 
    556                 delete_site_transient('update_plugins'); 
    557                 wp_cache_delete( 'plugins', 'plugins' ); 
     581                if ( $parsed_args['clear_update_cache'] ) { 
     582                        // Force refresh of plugin update information 
     583                        delete_site_transient('update_plugins'); 
     584                        wp_cache_delete( 'plugins', 'plugins' ); 
     585                } 
     586 
    558587                do_action( 'upgrader_process_complete', $this, array( 'action' => 'update', 'type' => 'plugin', 'bulk' => true ), $plugins ); 
    559588 
    560589                return $results; 
     
    755784                return $actions; 
    756785        } 
    757786 
    758         function install($package) { 
     787        function install( $package, $args = array() ) { 
    759788 
     789                $defaults = array( 
     790                        'clear_update_cache' => true, 
     791                ); 
     792                $parsed_args = wp_parse_args( $defaults, $args ); 
     793 
    760794                $this->init(); 
    761795                $this->install_strings(); 
    762796 
    763797                add_filter('upgrader_source_selection', array(&$this, 'check_package') ); 
    764798                add_filter('upgrader_post_install', array(&$this, 'check_parent_theme_filter'), 10, 3); 
    765799 
    766                 $options = array( 
     800                $this->run( array( 
    767801                        'package' => $package, 
    768802                        'destination' => get_theme_root(), 
    769803                        'clear_destination' => false, //Do not overwrite files. 
    770804                        'clear_working' => true 
    771                 ); 
     805                ) ); 
    772806 
    773                 $this->run($options); 
    774  
    775807                remove_filter('upgrader_source_selection', array(&$this, 'check_package') ); 
    776808                remove_filter('upgrader_post_install', array(&$this, 'check_parent_theme_filter')); 
    777809 
    778810                if ( ! $this->result || is_wp_error($this->result) ) 
    779811                        return $this->result; 
    780812 
    781                 // Force refresh of theme update information 
    782                 wp_clean_themes_cache(); 
     813                if ( $parsed_args['clear_update_cache'] ) { 
     814                        // Force refresh of theme update information 
     815                        wp_clean_themes_cache(); 
     816                } 
     817 
    783818                do_action( 'upgrader_process_complete', $this, array( 'action' => 'install', 'type' => 'theme' ), $package ); 
    784819 
    785820                return true; 
    786821        } 
    787822 
    788         function upgrade($theme) { 
     823        function upgrade( $theme, $args = array() ) { 
    789824 
     825                $defaults = array( 
     826                        'clear_update_cache' => true, 
     827                ); 
     828                $parsed_args = wp_parse_args( $defaults, $args ); 
     829 
    790830                $this->init(); 
    791831                $this->upgrade_strings(); 
    792832 
     
    806846                add_filter('upgrader_post_install', array(&$this, 'current_after'), 10, 2); 
    807847                add_filter('upgrader_clear_destination', array(&$this, 'delete_old_theme'), 10, 4); 
    808848 
    809                 $options = array( 
     849                $this->run( array( 
    810850                        'package' => $r['package'], 
    811851                        'destination' => get_theme_root( $theme ), 
    812852                        'clear_destination' => true, 
     
    814854                        'hook_extra' => array( 
    815855                                'theme' => $theme 
    816856                        ), 
    817                 ); 
     857                ) ); 
    818858 
    819                 $this->run($options); 
    820  
    821859                remove_filter('upgrader_pre_install', array(&$this, 'current_before')); 
    822860                remove_filter('upgrader_post_install', array(&$this, 'current_after')); 
    823861                remove_filter('upgrader_clear_destination', array(&$this, 'delete_old_theme')); 
     
    825863                if ( ! $this->result || is_wp_error($this->result) ) 
    826864                        return $this->result; 
    827865 
    828                 // Force refresh of theme update information 
    829                 wp_clean_themes_cache(); 
     866                if ( $parsed_args['clear_update_cache'] ) { 
     867                        // Force refresh of theme update information 
     868                        wp_clean_themes_cache(); 
     869                } 
    830870                do_action( 'upgrader_process_complete', $this, array( 'action' => 'update', 'type' => 'theme' ), $theme ); 
    831871 
    832872                return true; 
    833873        } 
    834874 
    835         function bulk_upgrade($themes) { 
     875        function bulk_upgrade( $themes, $args = array() ) { 
    836876 
     877                $defaults = array( 
     878                        'clear_update_cache' => true, 
     879                ); 
     880                $parsed_args = wp_parse_args( $defaults, $args ); 
     881 
    837882                $this->init(); 
    838883                $this->bulk = true; 
    839884                $this->upgrade_strings(); 
     
    886931                        // Get the URL to the zip file 
    887932                        $r = $current->response[ $theme ]; 
    888933 
    889                         $options = array( 
     934                        $result = $this->run( array( 
    890935                                'package' => $r['package'], 
    891936                                'destination' => get_theme_root( $theme ), 
    892937                                'clear_destination' => true, 
     
    894939                                'hook_extra' => array( 
    895940                                        'theme' => $theme 
    896941                                ), 
    897                         ); 
     942                        ) ); 
    898943 
    899                         $result = $this->run($options); 
    900  
    901944                        $results[$theme] = $this->result; 
    902945 
    903946                        // Prevent credentials auth screen from displaying multiple times 
     
    916959                remove_filter('upgrader_post_install', array(&$this, 'current_after')); 
    917960                remove_filter('upgrader_clear_destination', array(&$this, 'delete_old_theme')); 
    918961 
    919                 // Force refresh of theme update information 
    920                 wp_clean_themes_cache(); 
     962                if ( $parsed_args['clear_update_cache'] ) { 
     963                        // Force refresh of theme update information 
     964                        wp_clean_themes_cache(); 
     965                } 
     966 
    921967                do_action( 'upgrader_process_complete', $this, array( 'action' => 'update', 'type' => 'theme', 'bulk' => true ), $themes ); 
    922968 
    923969                return $results; 
     
    10381084                $this->strings['copy_failed_space'] = __('Could not copy files. You may have run out of disk space.' ); 
    10391085        } 
    10401086 
    1041         function upgrade($current) { 
     1087        function upgrade( $current, $args = array() ) { 
    10421088                global $wp_filesystem, $wp_version; 
    10431089 
     1090                $defaults = array( 
     1091                ); 
     1092                $parsed_args = wp_parse_args( $defaults, $args ); 
     1093 
    10441094                $this->init(); 
    10451095                $this->upgrade_strings(); 
    10461096 
  • src/wp-content/mu-plugins/background-upgrader.php

     
     1<?php 
     2 
     3class WP_Background_Upgrader { 
     4 
     5        static $skin; 
     6 
     7        static function init() { 
     8 
     9                // Detect updates for Core, Plugins, and, Themes 
     10                add_action( 'set_site_transient_' . 'update_core',    array( 'WP_Background_Upgrader', 'queue_updates_check_core' ) ); 
     11                add_action( 'set_site_transient_' . 'update_plugins', array( 'WP_Background_Upgrader', 'queue_updates_check_plugins_themes' ) ); 
     12                add_action( 'set_site_transient_' . 'update_themes',  array( 'WP_Background_Upgrader', 'queue_updates_check_plugins_themes' ) ); 
     13                // Uh.. Yeah, work around for #25213 
     14                add_action( 'set_site_transient_' . '_site_transient_' . 'update_core',    array( 'WP_Background_Upgrader', 'queue_updates_check_core' ) ); 
     15                add_action( 'set_site_transient_' . '_site_transient_' . 'update_plugins', array( 'WP_Background_Upgrader', 'queue_updates_check_plugins_themes' ) ); 
     16                add_action( 'set_site_transient_' . '_site_transient_' . 'update_themes',  array( 'WP_Background_Upgrader', 'queue_updates_check_plugins_themes' ) ); 
     17 
     18                // Cron Updates 
     19                add_action( 'wp_background_upgrader_process', array( 'WP_Background_Upgrader', 'perform_queued_updates' ) ); 
     20 
     21                // Temporary way of testing to see if the install is fataling 
     22                // Used with WP_Background_Upgrader::test_if_site_is_ok() 
     23                add_action( 'template_redirect', array( 'WP_Background_Upgrader','test_if_site_is_ok_callback' ) , 1 ); 
     24 
     25        } 
     26 
     27        /** 
     28         * Loads the WordPress Admin environment for performing the updates. 
     29         * Cron runs as a front-end process 
     30         */ 
     31        static function load_required_admin_includes() { 
     32                error_reporting( E_ALL ); 
     33                // include ABSPATH . 'wp-admin/includes/admin.php'; // Load the whole lot of 'em 
     34                include ABSPATH . 'wp-admin/includes/update.php'; 
     35                include ABSPATH . 'wp-admin/includes/plugin.php'; 
     36                include ABSPATH . 'wp-admin/includes/plugin-install.php'; 
     37                include ABSPATH . 'wp-admin/includes/theme.php'; 
     38                include ABSPATH . 'wp-admin/includes/theme-install.php'; 
     39                include ABSPATH . 'wp-admin/includes/file.php'; 
     40                include ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; 
     41        } 
     42 
     43        static function queue_updates_check_core( $updates ) { 
     44 
     45                if ( self::upgrader_disabled() ) 
     46                        return; 
     47 
     48                if ( ! self::find_core_auto_update() ) 
     49                        return; 
     50 
     51                if ( ! wp_next_scheduled( 'wp_background_upgrader_process' ) ) { 
     52                        // If the transient update was triggered by a user pageview, update in an hours time, else, now. 
     53                        // What if the user is active in an hours time and maintainence mode kicks in? 
     54                        // Schedule it for $user_id_1_timezone midnight? 
     55                        $when_to_update = get_current_user_id() ? time() + HOUR_IN_SECONDS : time(); 
     56                        $when_to_update = apply_filters( 'auto_upgrade_when_to_upgrade', $when_to_update ); 
     57 
     58                        wp_schedule_single_event( $when_to_update, 'wp_background_upgrader_process' ); 
     59                } 
     60        } 
     61 
     62        static function queue_updates_check_plugins_themes( $transient_value ) { 
     63 
     64                if ( self::upgrader_disabled() ) 
     65                        return; 
     66 
     67                if ( ! $transient_value || empty( $transient_value->response ) ) 
     68                        return; 
     69 
     70                if ( ! wp_next_scheduled( 'wp_auto_upgrader_upgrade_all_the_things' ) ) { 
     71                        // If the transient update was triggered by a user pageview, update in an hours time, else, now. 
     72                        $when_to_update = get_current_user_id() ? time() + HOUR_IN_SECONDS : time(); 
     73                        $when_to_update = apply_filters( 'auto_upgrade_when_to_upgrade', $when_to_update ); 
     74 
     75                        wp_schedule_single_event( $when_to_update, 'wp_auto_upgrader_upgrade_all_the_things' ); 
     76                } 
     77 
     78        } 
     79 
     80        static function perform_queued_updates() { 
     81 
     82                $lock_name = 'auto_upgrader.lock'; 
     83                if ( get_site_transient( $lock_name ) ) { 
     84                        // Test to see if it was set more than an hour ago, if so, cleanup. 
     85                        if ( true || get_site_transient( $lock_name ) < ( time() - HOUR_IN_SECONDS ) ) 
     86                                delete_site_transient( $lock_name ); 
     87                        else // Recent lock 
     88                                return; 
     89                } 
     90                // Lock upgrades for us for half an hour 
     91                if ( ! set_site_transient( $lock_name, microtime( true ), HOUR_IN_SECONDS / 2 ) ) 
     92                        return; 
     93         
     94                // Admin-ize ourselves 
     95                self::load_required_admin_includes(); 
     96 
     97                // Next, Plugins 
     98                wp_update_plugins(); // Check for Plugin updates 
     99                $plugin_updates = get_site_transient( 'update_plugins' ); 
     100                if ( $plugin_updates && !empty( $plugin_updates->response ) ) { 
     101                        foreach ( array_keys( $plugin_updates->response ) as $plugin ) { 
     102                                self::upgrade( 'plugin', $plugin ); 
     103                        } 
     104                        // Force refresh of plugin update information 
     105                        delete_site_transient('update_plugins'); 
     106                        wp_cache_delete( 'plugins', 'plugins' ); 
     107                } 
     108 
     109                // Next, those themes we all love 
     110                wp_update_themes();  // Check for Theme updates 
     111                $theme_updates = get_site_transient( 'update_themes' ); 
     112                if ( $theme_updates && !empty( $theme_updates->response ) ) { 
     113                        foreach ( array_keys( $theme_updates->response ) as $theme ) { 
     114                                self::upgrade( 'theme', $theme ); 
     115                        } 
     116                        // Force refresh of theme update information 
     117                        wp_clean_themes_cache(); 
     118                } 
     119 
     120                // Up first, Core. 
     121                wp_version_check(); // Check for Core updates 
     122                $core_update = self::find_core_auto_update(); 
     123                if ( $core_update ) 
     124                        self::upgrade( 'core', $core_update ); 
     125 
     126                // Cleanup, These won't trigger any updates this time due to the locking transient 
     127                wp_version_check();  // check for Core updates 
     128                wp_update_themes();  // Check for Theme updates 
     129                wp_update_plugins(); // Check for Plugin updates 
     130 
     131                delete_site_transient( $lock_name ); 
     132 
     133        } 
     134 
     135        /** 
     136         * Finds the best auto-update available for this site. 
     137         * If there's 1.2.3 and 1.3 on offer, it'll choose 1.3 if the install allows it, else, 1.2.3 
     138         */ 
     139        static function find_core_auto_update() { 
     140                $updates = get_site_transient( 'update_core' ); 
     141                $auto_update = false; 
     142                foreach ( $updates->updates as $update ) { 
     143                        if ( 'autoupdate' != $update->response ) 
     144                                continue; 
     145 
     146                        if ( ! self::should_upgrade( 'core', $update, ABSPATH ) ) 
     147                                continue; 
     148 
     149                        if ( ! $auto_update || version_compare( $update->current, $auto_update->current, '>' ) ) 
     150                                $auto_update = $update; 
     151                } 
     152                return $auto_update; 
     153        } 
     154 
     155        static function upgrader_disabled() { 
     156                // That's a no if you don't want files changes 
     157                if ( defined( 'DISABLE_FILE_MODS' ) && DISABLE_FILE_MODS ) 
     158                        return true; 
     159 
     160                if ( defined( 'AUTOMATIC_UPDATER_DISABLED' ) && AUTOMATIC_UPDATER_DISABLED ) 
     161                        return true; 
     162 
     163                return apply_filters( 'auto_upgrader_disabled', false ); 
     164        } 
     165 
     166        /** 
     167         * Tests to see if we should upgrade a specific item, does not test to see if we CAN update the item. 
     168         */ 
     169        static function should_upgrade( $type, $item, $context ) { 
     170 
     171                if ( self::upgrader_disabled() ) 
     172                        return false; 
     173 
     174                // ..and also check for GIT/SVN checkouts 
     175                if ( ! apply_filters( 'auto_upgrade_ignore_checkout_status', false ) ) { 
     176                        $stop_dirs = array( 
     177                                ABSPATH, 
     178                                untrailingslashit( $context ), 
     179                        ); 
     180                        if ( ! file_exists( ABSPATH . '/wp-config.php' ) ) // wp-config.php up one folder in a deployment situation 
     181                                $stop_dirs[] = dirname( ABSPATH ); 
     182                        foreach ( array_unique( $stop_dirs ) as $dir ) { 
     183                                if ( file_exists( $dir . '/.svn' ) || file_exists( $dir . '/.git' ) ) 
     184                                        return false; 
     185                        } 
     186                } 
     187 
     188                // Next up, do we actually have it enabled for this type of update? 
     189                switch ( $type ) { 
     190                        default:       $upgrade = false; break; 
     191                        case 'core': 
     192                                $upgrade = self::should_upgrade_to_core_version( $item->current ); 
     193                                break; 
     194                        case 'plugin': $upgrade = false; break; 
     195                        case 'theme':  $upgrade = false; break; 
     196                        case 'lang':   $upgrade = false; break; 
     197                } 
     198 
     199                // And does the user / plugins want it? 
     200                if ( ! apply_filters( 'auto_upgrade_' . $type, $upgrade, $item ) ) 
     201                        return false; 
     202 
     203                // If it's a core update, are we actually compatible with it? 
     204                if ( 'core' == $type ) { 
     205                        global $wpdb; 
     206 
     207                        $php_compat = version_compare( phpversion(), $item->php_version, '>=' ); 
     208                        if ( file_exists( WP_CONTENT_DIR . '/db.php' ) && empty( $wpdb->is_mysql ) ) 
     209                                $mysql_compat = true; 
     210                        else 
     211                                $mysql_compat = version_compare( $wpdb->db_version(), $item->mysql_version, '>=' ); 
     212 
     213                        if ( ! $php_compat || ! $mysql_compat ) 
     214                                return false; 
     215                } 
     216 
     217                // Make sure loop-back HTTP requests work, we need to be able to verify everything worked OK and to be able to upgrade the database 
     218                // If this doesn't pass, chances are they don't want auto-updates anyway 
     219                if ( ! self::test_if_site_is_ok() ) 
     220                        return false; 
     221 
     222                return true; 
     223        } 
     224 
     225        // Checks to see if WP_Filesystem is setup to allow unattended upgrades 
     226        static function can_upgrade( $context ) { 
     227                if ( ! self::$skin ) 
     228                        self::$skin = new WP_Background_Upgrader_Skin(); 
     229                return (bool) self::$skin->request_filesystem_credentials(); 
     230        } 
     231 
     232        // Determines if this WordPress Core version should update to $offered_ver or not 
     233        static function should_upgrade_to_core_version( $offered_ver /* x.y.z */ ) { 
     234                include ABSPATH . WPINC . '/version.php'; // $wp_version; // x.y.z 
     235 
     236                $current_branch = implode( '.', array_slice( preg_split( '/[.-]/', $wp_version  ), 0, 2 ) ); // x.y 
     237                $new_branch     = implode( '.', array_slice( preg_split( '/[.-]/', $offered_ver ), 0, 2 ) ); // x.y 
     238                $current_is_development_version = (bool) strpos( $wp_version, '-' ); 
     239 
     240                // Defaults: 
     241                $upgrade_dev   = false; 
     242                $upgrade_minor = true; 
     243                $upgrade_major = false; 
     244 
     245                // WP_AUTO_UPDATE_CORE = true (all), 'minor', false. 
     246                if ( defined( 'WP_AUTO_UPDATE_CORE' ) ) { 
     247                        if ( false === WP_AUTO_UPDATE_CORE ) { 
     248                                // Defaults to turned off, unless a filter allows it 
     249                                $upgrade_dev = $upgrade_minor = $upgrade_major = false; 
     250                        } elseif ( true === WP_AUTO_UPDATE_CORE ) { 
     251                                // ALL updates for core 
     252                                $upgrade_dev = $upgrade_minor = $upgrade_major = true; 
     253                        } elseif ( 'minor' === WP_AUTO_UPDATE_CORE ) { 
     254                                // Only minor updates for core 
     255                                $upgrade_dev = $upgrade_major = false; 
     256                                $upgrade_minor = true; 
     257                        } 
     258                } 
     259 
     260                // 1: If we're already on that version, not much point in updating? 
     261                if ( $offered_ver == $wp_version ) 
     262                        return false; 
     263 
     264                // 2: If we're running a newer version, that's a nope 
     265                if ( version_compare( $wp_version, $offered_ver, '>=' ) ) 
     266                        return false; 
     267 
     268                // 3: 3.7-alpha-25000 -> 3.7-alpha-25678 -> 3.7-beta1 -> 3.7-beta2 
     269                if ( $current_is_development_version ) { 
     270                        if ( ! apply_filters( 'allow_dev_background_core_updates', $upgrade_dev ) ) 
     271                                return false; 
     272                        // else fall through to minor + major branches below 
     273                } 
     274 
     275                // 4: Minor In-branch updates (3.7.0 -> 3.7.1 -> 3.7.2 -> 3.7.4) 
     276                if ( $current_branch == $new_branch ) 
     277                        return apply_filters( 'allow_minor_background_core_updates', $upgrade_minor ); 
     278 
     279                // 5: Major version updates (3.7.0 -> 3.8.0 -> 3.9.1) 
     280                if ( version_compare( $new_branch, $current_branch, '>' ) ) 
     281                        return apply_filters( 'allow_major_background_core_updates', $upgrade_major ); 
     282 
     283                // If we're not sure, we don't want it 
     284                return false; 
     285        } 
     286 
     287        static function upgrade( $type, $item ) { 
     288 
     289                wp_mail( 
     290                        get_site_option( 'admin_email' ), 
     291                        __METHOD__, 
     292                        "Starting an upgrade for:\n\n" . var_export( compact( 'type', 'item' ), true ) . "\n\n" . wp_debug_backtrace_summary() 
     293                ); 
     294 
     295                self::$skin = new Background_Upgrader_Skin(); 
     296 
     297                switch( $type ) { 
     298                        case 'core': 
     299                                // Okay, Why does the Core upgrader not use the Upgrader's skin during the actual main part of the upgrade??? 
     300                                add_filter( 'update_feedback', function( $message ) { 
     301                                        WP_Background_Upgrader::$skin->feedback( $message ); 
     302                                } ); 
     303                                $upgrader = new Core_Upgrader( self::$skin ); 
     304                                $context  = ABSPATH; 
     305                                break; 
     306                        case 'plugin': 
     307                                $upgrader = new Plugin_Upgrader( self::$skin ); 
     308                                $context  = WP_PLUGIN_DIR; // We don't support custom Plugin directories, or updates for WPMU_PLUGIN_DIR 
     309                                break; 
     310                        case 'theme': 
     311                                $upgrader = new Theme_Upgrader( self::$skin ); 
     312                                $context  = get_theme_root( $item ); 
     313                                break; 
     314                        case 'lang': 
     315                                return false; // Not quite yet! 
     316                        //      $upgrader = new Language_Upgrader( self::$skin ); 
     317                                $context  = WP_LANG_DIR; 
     318                                break; 
     319                } 
     320 
     321                // Determine if we can perform this upgrade or not 
     322                if ( ! self::should_upgrade( $type, $item, $context )  || ! self::can_upgrade( $context ) ) 
     323                        return false; 
     324 
     325                // Boom, This sites about to get a whole new splash of paint! 
     326                $upgrade_result = $upgrader->upgrade( $item, array( 
     327                        'clear_update_cache' => false, 
     328                ) ); 
     329 
     330                // Core doesn't output this, so lets append it so we don't get confused 
     331                if ( 'core' == $type ) { 
     332                        if ( is_wp_error( $upgrade_result ) ) { 
     333                                self::$skin->error( __( 'Installation Failed' ), $upgrade_result ); 
     334                        } else { 
     335                                self::$skin->feedback( __( 'WordPress updated successfully' ) ); 
     336                        } 
     337                } 
     338 
     339                var_dump( compact( 'type', 'item', 'upgrader', 'upgrade_result' ) ); 
     340 
     341                wp_mail( 
     342                        get_site_option( 'admin_email' ), 
     343                        __METHOD__, 
     344                        var_export( array( 
     345                                $upgrade_result, 
     346                                $upgrader, 
     347                                self::$skin, 
     348                        ), true ) 
     349                ); 
     350 
     351                return $upgrade_result; 
     352        } 
     353 
     354        static function test_if_site_is_ok() { 
     355                // Is the Admin ajax handler returning what we expect of it?  
     356                $http_result = wp_remote_get( admin_url( 'admin-ajax.php' ), array( 'timeout' => 10 ) ); 
     357                $admin_ok = ! is_wp_error( $http_result ) && ( '0' === wp_remote_retrieve_body( $http_result ) ); 
     358 
     359                // Is the front-end returning what we'd expect of it? (Note, this is a filter on template_redirect + wp_footer outside of this class below) 
     360                // This WILL break with caching plugins, Include a something that can be used to prevent the caching somehow? a GET parameter isn't enough for some caching plugins 
     361                $http_result = wp_remote_get( site_url('?test-upgrade-OK=1'), array( 'timeout' => 10 ) ); 
     362                $front_ok = ! is_wp_error( $http_result ) && ( 'OK' === wp_remote_retrieve_body( $http_result ) ); 
     363 
     364                return $admin_ok && $front_ok; 
     365        } 
     366 
     367        static function test_if_site_is_ok_callback() { 
     368                if ( ! isset( $_GET['test-upgrade-OK'] ) ) 
     369                        return; 
     370 
     371                ob_start(); 
     372                add_action( 'wp_footer', function() { 
     373                        ob_end_clean(); 
     374                        die( 'OK' ); 
     375                }, 999 ); 
     376        } 
     377 
     378        // A static lifestyle is best. Go on, try it, I dare you. 
     379        private function __construct() {} 
     380} 
     381WP_Background_Upgrader::init();