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