Make WordPress Core


Ignore:
Timestamp:
09/13/2013 06:18:16 AM (13 years ago)
Author:
dd32
Message:

WordPress Core Automatic Updates: Add the first slice of Automatic Upgrades, This is presently disabled, and requires a filter to enable ( 'auto_upgrade_core' ). See #22704

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/class-wp-upgrader.php

    r25370 r25421  
    11381138        }
    11391139
     1140        // Determines if this WordPress Core version should update to $offered_ver or not
     1141        static function should_upgrade_to_version( $offered_ver /* x.y.z */ ) {
     1142                include ABSPATH . WPINC . '/version.php'; // $wp_version; // x.y.z
     1143
     1144                $current_branch = implode( '.', array_slice( preg_split( '/[.-]/', $wp_version  ), 0, 2 ) ); // x.y
     1145                $new_branch     = implode( '.', array_slice( preg_split( '/[.-]/', $offered_ver ), 0, 2 ) ); // x.y
     1146                $current_is_development_version = (bool) strpos( $wp_version, '-' );
     1147
     1148                // Defaults:
     1149                $upgrade_dev   = false;
     1150                $upgrade_minor = false; // @TODO: Update for release by toggling to true.
     1151                $upgrade_major = false;
     1152
     1153                // WP_AUTO_UPDATE_CORE = true (all), 'minor', false.
     1154                if ( defined( 'WP_AUTO_UPDATE_CORE' ) ) {
     1155                        if ( false === WP_AUTO_UPDATE_CORE ) {
     1156                                // Defaults to turned off, unless a filter allows it
     1157                                $upgrade_dev = $upgrade_minor = $upgrade_major = false;
     1158                        } elseif ( true === WP_AUTO_UPDATE_CORE ) {
     1159                                // ALL updates for core
     1160                                $upgrade_dev = $upgrade_minor = $upgrade_major = true;
     1161                        } elseif ( 'minor' === WP_AUTO_UPDATE_CORE ) {
     1162                                // Only minor updates for core
     1163                                $upgrade_dev = $upgrade_major = false;
     1164                                $upgrade_minor = true;
     1165                        }
     1166                }
     1167
     1168                // 1: If we're already on that version, not much point in updating?
     1169                if ( $offered_ver == $wp_version )
     1170                        return false;
     1171
     1172                // 2: If we're running a newer version, that's a nope
     1173                if ( version_compare( $wp_version, $offered_ver, '>=' ) )
     1174                        return false;
     1175
     1176                // 3: 3.7-alpha-25000 -> 3.7-alpha-25678 -> 3.7-beta1 -> 3.7-beta2
     1177                if ( $current_is_development_version ) {
     1178                        if ( ! apply_filters( 'allow_dev_auto_core_updates', $upgrade_dev ) )
     1179                                return false;
     1180                        // else fall through to minor + major branches below
     1181                }
     1182
     1183                // 4: Minor In-branch updates (3.7.0 -> 3.7.1 -> 3.7.2 -> 3.7.4)
     1184                if ( $current_branch == $new_branch )
     1185                        return apply_filters( 'allow_minor_auto_core_updates', $upgrade_minor );
     1186
     1187                // 5: Major version updates (3.7.0 -> 3.8.0 -> 3.9.1)
     1188                if ( version_compare( $new_branch, $current_branch, '>' ) )
     1189                        return apply_filters( 'allow_major_auto_core_updates', $upgrade_major );
     1190
     1191                // If we're not sure, we don't want it
     1192                return false;
     1193        }
     1194
    11401195}
    11411196
     
    12131268        }
    12141269}
     1270
     1271/**
     1272 * WordPress Automatic Upgrader helper class
     1273 *
     1274 * @since 3.7.0
     1275 */
     1276class WP_Automatic_Upgrader {
     1277
     1278        static $skin;
     1279
     1280        static function upgrader_disabled() {
     1281                // That's a no if you don't want files changes
     1282                if ( defined( 'DISABLE_FILE_MODS' ) && DISABLE_FILE_MODS )
     1283                        return true;
     1284
     1285                // More fine grained control can be done through the WP_AUTO_UPDATE_CORE constant and filters
     1286                if ( defined( 'AUTOMATIC_UPDATER_DISABLED' ) && AUTOMATIC_UPDATER_DISABLED )
     1287                        return true;
     1288
     1289                if ( defined( 'WP_INSTALLING' ) )
     1290                        return true;
     1291
     1292                return apply_filters( 'auto_upgrader_disabled', false );
     1293        }
     1294
     1295        /**
     1296         * Tests to see if we should upgrade a specific item, does not test to see if we CAN update the item.
     1297         */
     1298        static function should_auto_update( $type, $item, $context ) {
     1299
     1300                if ( self::upgrader_disabled() )
     1301                        return false;
     1302
     1303                // ..and also check for GIT/SVN checkouts
     1304                if ( ! apply_filters( 'auto_upgrade_ignore_checkout_status', false ) ) {
     1305                        $stop_dirs = array(
     1306                                ABSPATH,
     1307                                untrailingslashit( $context ),
     1308                        );
     1309                        if ( ! file_exists( ABSPATH . '/wp-config.php' ) ) // wp-config.php up one folder in a deployment situation
     1310                                $stop_dirs[] = dirname( ABSPATH );
     1311                        foreach ( array_unique( $stop_dirs ) as $dir ) {
     1312                                if ( file_exists( $dir . '/.svn' ) || file_exists( $dir . '/.git' ) )
     1313                                        return false;
     1314                        }
     1315                }
     1316
     1317                // Next up, do we actually have it enabled for this type of update?
     1318                switch ( $type ) {
     1319                        case 'core':
     1320                                $upgrade = Core_Upgrader::should_upgrade_to_version( $item->current );
     1321                                break;
     1322                        default:
     1323                        case 'plugin':
     1324                        case 'theme':
     1325                                $upgrade = false;
     1326                                break;
     1327                }
     1328
     1329                // And does the user / plugins want it?
     1330                // Plugins may filter on 'auto_upgrade_plugin', and check the 2nd param, $item, to only enable it for certain Plugins/Themes
     1331                if ( ! apply_filters( 'auto_upgrade_' . $type, $upgrade, $item ) )
     1332                        return false;
     1333
     1334                // If it's a core update, are we actually compatible with it's requirements?
     1335                if ( 'core' == $type ) {
     1336                        global $wpdb;
     1337
     1338                        $php_compat = version_compare( phpversion(), $item->php_version, '>=' );
     1339                        if ( file_exists( WP_CONTENT_DIR . '/db.php' ) && empty( $wpdb->is_mysql ) )
     1340                                $mysql_compat = true;
     1341                        else
     1342                                $mysql_compat = version_compare( $wpdb->db_version(), $item->mysql_version, '>=' );
     1343
     1344                        if ( ! $php_compat || ! $mysql_compat )
     1345                                return false;
     1346                }
     1347
     1348                return true;
     1349        }
     1350
     1351        // Checks to see if WP_Filesystem is setup to allow unattended upgrades
     1352        static function can_auto_update( $context ) {
     1353                if ( ! self::$skin )
     1354                        self::$skin = new Automatic_Upgrader_Skin();
     1355                return (bool) self::$skin->request_filesystem_credentials();
     1356        }
     1357
     1358        static function upgrade( $type, $item ) {
     1359
     1360                self::$skin = new Automatic_Upgrader_Skin();
     1361
     1362                switch ( $type ) {
     1363                        case 'core':
     1364                                // The Core upgrader doesn't use the Upgrader's skin during the actual main part of the upgrade, instead, firing a filter
     1365                                add_filter( 'update_feedback', function( $message ) {
     1366                                        WP_Background_Upgrader::$skin->feedback( $message );
     1367                                        return $message;
     1368                                } );
     1369                                $upgrader = new Core_Upgrader( self::$skin );
     1370                                $context  = ABSPATH;
     1371                                break;
     1372                        case 'plugin':
     1373                                $upgrader = new Plugin_Upgrader( self::$skin );
     1374                                $context  = WP_PLUGIN_DIR; // We don't support custom Plugin directories, or updates for WPMU_PLUGIN_DIR
     1375                                break;
     1376                        case 'theme':
     1377                                $upgrader = new Theme_Upgrader( self::$skin );
     1378                                $context  = get_theme_root( $item );
     1379                                break;
     1380                }
     1381
     1382                // Determine if we can perform this upgrade or not
     1383                if ( ! self::should_auto_update( $type, $item, $context )  || ! self::can_auto_update( $context ) )
     1384                        return false;
     1385
     1386                /*wp_mail(
     1387                        get_site_option( 'admin_email' ),
     1388                        __METHOD__,
     1389                        "Starting an upgrade for:\n\n" . var_export( compact( 'type', 'item' ), true ) . "\n\n" . wp_debug_backtrace_summary()
     1390                );*/
     1391
     1392                // Boom, This sites about to get a whole new splash of paint!
     1393                $upgrade_result = $upgrader->upgrade( $item, array(
     1394                        'clear_update_cache' => false,
     1395                ) );
     1396
     1397                // Core doesn't output this, so lets append it so we don't get confused
     1398                if ( 'core' == $type ) {
     1399                        if ( is_wp_error( $upgrade_result ) ) {
     1400                                self::$skin->error( __( 'Installation Failed' ), $upgrade_result );
     1401                        } else {
     1402                                self::$skin->feedback( __( 'WordPress updated successfully' ) );
     1403                        }
     1404                }
     1405
     1406                // Clear cache's and transients
     1407                switch ( $type ) {
     1408                        case 'core':
     1409                                delete_site_transient( 'update_core' );
     1410                                break;
     1411                        case 'theme':
     1412                                wp_clean_themes_cache();
     1413                                break;
     1414                        case 'plugin':
     1415                                wp_clean_plugins_cache();
     1416                                break;
     1417                }
     1418
     1419                //var_dump( compact( 'type', 'item', 'upgrader', 'upgrade_result' ) );
     1420
     1421                wp_mail(
     1422                        get_site_option( 'admin_email' ),
     1423                        __METHOD__,
     1424                        var_export( array(
     1425                                $upgrade_result,
     1426                                $upgrader,
     1427                                self::$skin,
     1428                        ), true )
     1429                );
     1430
     1431                return $upgrade_result;
     1432        }
     1433
     1434        /**
     1435         * Kicks off a upgrade request for each item in the upgrade "queue"
     1436         */
     1437        static function perform_auto_updates() {
     1438
     1439                $lock_name = 'auto_upgrader.lock';
     1440                if ( get_site_transient( $lock_name ) ) {
     1441                        // Test to see if it was set more than an hour ago, if so, cleanup.
     1442                        if ( true || get_site_transient( $lock_name ) < ( time() - HOUR_IN_SECONDS ) )
     1443                                delete_site_transient( $lock_name );
     1444                        else // Recent lock
     1445                                return;
     1446                }
     1447                // Lock upgrades for us for half an hour
     1448                if ( ! set_site_transient( $lock_name, microtime( true ), HOUR_IN_SECONDS / 2 ) )
     1449                        return;
     1450
     1451                // Next, Plugins
     1452                wp_update_plugins(); // Check for Plugin updates
     1453                $plugin_updates = get_site_transient( 'update_plugins' );
     1454                if ( $plugin_updates && !empty( $plugin_updates->response ) ) {
     1455                        foreach ( array_keys( $plugin_updates->response ) as $plugin ) {
     1456                                self::upgrade( 'plugin', $plugin );
     1457                        }
     1458                        // Force refresh of plugin update information
     1459                        wp_clean_plugins_cache();
     1460                }
     1461
     1462                // Next, those themes we all love
     1463                wp_update_themes();  // Check for Theme updates
     1464                $theme_updates = get_site_transient( 'update_themes' );
     1465                if ( $theme_updates && !empty( $theme_updates->response ) ) {
     1466                        foreach ( array_keys( $theme_updates->response ) as $theme ) {
     1467                                self::upgrade( 'theme', $theme );
     1468                        }
     1469                        // Force refresh of theme update information
     1470                        wp_clean_themes_cache();
     1471                }
     1472
     1473                // Finally, Process any core upgrade
     1474                wp_version_check(); // Check for Core updates
     1475                $core_update = find_core_auto_update();
     1476                if ( $core_update )
     1477                        self::upgrade( 'core', $core_update );
     1478
     1479                // Cleanup, These won't trigger any updates this time due to the locking transient
     1480                wp_version_check();  // check for Core updates
     1481                wp_update_themes();  // Check for Theme updates
     1482                wp_update_plugins(); // Check for Plugin updates
     1483
     1484                // TODO The core database upgrade has already cleared this transient..
     1485                delete_site_transient( $lock_name );
     1486
     1487        }
     1488
     1489}
Note: See TracChangeset for help on using the changeset viewer.