Make WordPress Core


Ignore:
Timestamp:
09/22/2017 01:35:09 AM (7 years ago)
Author:
westonruter
Message:

Plugin Editor: Improve reliability of detecting PHP fatal errors when editing an active plugin.

  • Invalidate PHP opcache after file is updated to ensure include will include the written changes.
  • Define WP_ADMIN when activating plugin in sandbox so plugin code targeting admin will be loaded.
  • Do actions that get triggered when loading the admin to ensure plugin code runs that could cause errors on plugin editor screen (and lock out access).
  • Fix ability to re-activate a plugin after editing a PHP file other than the main plugin file, and ensure PHP fatal error will be displayed in such cases.
  • Consolidate duplicated code into plugin_sandbox_scrape() and re-use in activate_plugin().
  • Show an error notice instead of a success notice when a file is updated but a plugin was deactivated due to a fatal error.
  • Update style of warning when editing an active plugin to be styled as an actual warning notice.

See #12423, #21622.
Fixes #39766.

File:
1 edited

Legend:

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

    r41289 r41560  
    556556            wp_redirect(add_query_arg('_error_nonce', wp_create_nonce('plugin-activation-error_' . $plugin), $redirect)); // we'll override this later if the plugin can be included without fatal error
    557557        ob_start();
    558         wp_register_plugin_realpath( WP_PLUGIN_DIR . '/' . $plugin );
    559         $_wp_plugin_file = $plugin;
    560         include_once( WP_PLUGIN_DIR . '/' . $plugin );
    561         $plugin = $_wp_plugin_file; // Avoid stomping of the $plugin variable in a plugin.
     558
     559        plugin_sandbox_scrape( $plugin );
    562560
    563561        if ( ! $silent ) {
     
    18821880
    18831881/**
    1884  * @param string $plugin
     1882 * Simulate loading the WordPress admin with a given plugin active to attempt to generate errors.
     1883 *
     1884 * Actions are re-triggered in the WP bootstrap process for the WP Admin, and the WP_ADMIN constant is defined.
     1885 *
     1886 * @since 3.0.0
     1887 * @since 4.4.0 Function was moved into the `wp-admin/includes/plugin.php` file.
     1888 * @since 4.9.0 Add defining of WP_ADMIN and triggering admin WP bootstrap actions.
     1889 *
     1890 * @global array $wp_actions
     1891 * @param string $plugin Plugin file to load.
    18851892 */
    18861893function plugin_sandbox_scrape( $plugin ) {
     1894    global $wp_actions;
    18871895    wp_register_plugin_realpath( WP_PLUGIN_DIR . '/' . $plugin );
     1896
     1897    if ( ! defined( 'WP_ADMIN' ) ) {
     1898        define( 'WP_ADMIN', true );
     1899    }
     1900
     1901    $tested_actions = array(
     1902        'plugins_loaded' => array(),
     1903        'setup_theme' => array(),
     1904        'after_setup_theme' => array(),
     1905        'init' => array(),
     1906        'wp_loaded' => array(),
     1907        'admin_init' => array(),
     1908    );
     1909    $old_wp_actions = $wp_actions;
     1910    array_map( 'remove_all_actions', array_keys( $tested_actions ) );
     1911
    18881912    include( WP_PLUGIN_DIR . '/' . $plugin );
    1889 }
     1913
     1914    // Trigger key actions that are done on the plugin editor to cause the relevant plugin hooks to fire and potentially cause errors.
     1915    foreach ( $tested_actions as $action => $args ) {
     1916        do_action_ref_array( $action, $args );
     1917    }
     1918
     1919    $wp_actions = $old_wp_actions; // Restore actions.
     1920}
Note: See TracChangeset for help on using the changeset viewer.