WordPress.org

Make WordPress Core

Ticket #44458: 44458-1.diff

File 44458-1.diff, 4.9 KB (added by schlessera, 20 months ago)

First proof-of-concept implementation (still missing UI integrations)

  • src/wp-includes/load.php

    diff --git src/wp-includes/load.php src/wp-includes/load.php
    index 81014fdde8..c3ef6440fa 100644
    function wp_get_active_and_valid_plugins() { 
    687687                        $plugins[] = WP_PLUGIN_DIR . '/' . $plugin;
    688688                }
    689689        }
     690
     691        /*
     692         * Remove plugins from the list of active plugins when we're on an admin or
     693         * login screen and the plugin appears in the `skip_on_admin` list.
     694         */
     695        if ( 'wp-login.php' === $GLOBALS['pagenow']
     696             || ( is_admin() && ! wp_doing_ajax() ) ) {
     697                $skip_on_admin  = (array) get_option( 'skip_on_admin', array() );
     698
     699                if ( ! array_key_exists( 'plugin', $skip_on_admin ) ) {
     700                        return $plugins;
     701                }
     702
     703                foreach ( $plugins as $index => $plugin ) {
     704                        $parts = explode(
     705                                '/',
     706                                str_replace( WP_CONTENT_DIR . '/', '', $plugin )
     707                        );
     708
     709                        if ( in_array( $parts[1], $skip_on_admin['plugin'], true ) ) {
     710                                unset( $plugins[ $index ] );
     711                                // Store list of skipped plugins for displaying an admin notice.
     712                                $GLOBALS['_skipped_plugin'][] = $plugin;
     713                        }
     714                }
     715        }
     716
    690717        return $plugins;
    691718}
    692719
    function wp_finalize_scraping_edited_file_errors( $scrape_key ) { 
    12501277        }
    12511278        echo "\n###### wp_scraping_result_end:$scrape_key ######\n";
    12521279}
     1280
     1281/**
     1282 * Wrap the shutdown handler function so it can be made pluggable at a later
     1283 * stage.
     1284 *
     1285 * @since 5.0.0
     1286 *
     1287 * @return void
     1288 */
     1289function wp_shutdown_handler_wrapper() {
     1290        if ( defined( 'WP_EXECUTION_SUCCEEDED' ) && WP_EXECUTION_SUCCEEDED ) {
     1291                return;
     1292        }
     1293
     1294        // Load the pluggable shutdown handler in case we found one.
     1295        if ( function_exists( 'wp_handle_shutdown' ) ) {
     1296                $stop_propagation = (bool) wp_handle_shutdown();
     1297
     1298                if ( $stop_propagation ) {
     1299                        return;
     1300                }
     1301        }
     1302
     1303        $error = error_get_last();
     1304
     1305        // No error, just skip the error handling code.
     1306        if ( null === $error ) {
     1307                return;
     1308        }
     1309
     1310        // This is only diagnostic code for the POC.
     1311        echo sprintf(
     1312                '<p>WordPress was shut down because a PHP error of type <strong>%d</strong> occurred in the file <strong><code>%s</code></strong> at line <strong><code>%d</code></strong>:<br><strong>%s</strong>',
     1313                $error['type'],
     1314                $error['file'],
     1315                $error['line'],
     1316                $error['message']
     1317        );
     1318
     1319        // For now, we only trigger our safe mode on parse errors.
     1320        if ( E_PARSE === $error['type'] ) {
     1321                $path = str_replace( WP_CONTENT_DIR . '/', '', $error['file'] );
     1322
     1323                $parts     = explode( '/', $path );
     1324                $type      = rtrim( array_shift( $parts ), 's' );
     1325                $extension = array_shift( $parts );
     1326
     1327                // This is only diagnostic code for the POC.
     1328                echo sprintf(
     1329                        '<p>A <strong>parse-time</strong> error was detected. The likely culprit was the <code>%s</code> %s.',
     1330                        $extension,
     1331                        'mu-plugin' === $type ? 'must-use plugin' : $type
     1332                );
     1333
     1334                $skip_on_admin   = get_option( 'skip_on_admin', array() );
     1335
     1336                if ( ! array_key_exists( $type, $skip_on_admin ) ) {
     1337                        $skip_on_admin[ $type ] = array();
     1338                }
     1339
     1340                if ( ! in_array( $extension, $skip_on_admin[ $type ], true ) ) {
     1341                        $skip_on_admin[ $type ][] = $extension;
     1342                }
     1343
     1344                update_option( 'skip_on_admin', $skip_on_admin );
     1345        }
     1346}
     1347
     1348/**
     1349 * Register the WordPress premature shutdown handler.
     1350 *
     1351 * @since 5.0.0
     1352 *
     1353 * @return void
     1354 */
     1355function wp_register_premature_shutdown_handler() {
     1356        register_shutdown_function( 'wp_shutdown_handler_wrapper' );
     1357}
  • src/wp-settings.php

    diff --git src/wp-settings.php src/wp-settings.php
    index eb632238f0..c633f05b1d 100644
    require( ABSPATH . WPINC . '/load.php' ); 
    2020require( ABSPATH . WPINC . '/default-constants.php' );
    2121require_once( ABSPATH . WPINC . '/plugin.php' );
    2222
     23// Make sure we register the premature shutdown handler as soon as possible.
     24wp_register_premature_shutdown_handler();
     25
    2326/*
    2427 * These can't be directly globalized in version.php. When updating,
    2528 * we're including version.php from another installation and don't want
    global $blog_id; 
    4043// Set initial default constants including WP_MEMORY_LIMIT, WP_MAX_MEMORY_LIMIT, WP_DEBUG, SCRIPT_DEBUG, WP_CONTENT_DIR and WP_CACHE.
    4144wp_initial_constants();
    4245
     46/*
     47 * Allow an optional shutdown handler to be included through a pluggable file.
     48 * This file should register a function `wp_handle_shutdown( $context )` that
     49 * returns a boolean value. If the return value evaluates to false, the default
     50 * shutdown handler will not be executed.
     51 */
     52if ( is_readable( WP_CONTENT_DIR . '/shutdown-handler.php' ) ) {
     53        include WP_CONTENT_DIR . '/shutdown-handler.php';
     54}
     55
    4356// Check for the required PHP version and for the MySQL extension or a database drop-in.
    4457wp_check_php_mysql_versions();
    4558
    if ( is_multisite() ) { 
    482495 * @since 3.0.0
    483496 */
    484497do_action( 'wp_loaded' );
     498
     499/*
     500 * Store the fact that we could successfully execute the entire WordPress
     501 * lifecycle. This is used to skip the premature shutdown handler, as it cannot
     502 * be unregistered.
     503 */
     504if ( ! defined( 'WP_EXECUTION_SUCCEEDED' ) ) {
     505        define( 'WP_EXECUTION_SUCCEEDED', true );
     506}