[wp-trac] [WordPress Trac] #55432: The $plugin parameter of the "plugin_loaded" action can be polluted by individual plugins

WordPress Trac noreply at wordpress.org
Tue Mar 22 13:35:27 UTC 2022


#55432: The $plugin parameter of the "plugin_loaded" action can be polluted by
individual plugins
----------------------------+------------------------------
 Reporter:  stevegrunwell   |       Owner:  (none)
     Type:  defect (bug)    |      Status:  new
 Priority:  normal          |   Milestone:  Awaiting Review
Component:  Bootstrap/Load  |     Version:
 Severity:  normal          |  Resolution:
 Keywords:  close           |     Focuses:
----------------------------+------------------------------

Comment (by stevegrunwell):

 The issue isn't so much with what the ''plugin'' could do so much as that
 the "plugin_loaded" hook does not behave in a predictable or consistent
 manner.

 Consider the following example callback that simply logs plugins as
 they're loaded:

 {{{
 add_action('plugin_loaded', function ($plugin) {
     Logger::info(sprintf('Plugin %s was loaded', $plugin));
 });
 }}}

 Depending on what a third-party plugin does (or does not do) to the
 `$plugin` variable, this will either log "Plugin some-plugin/some-
 plugin.php was loaded" or throw an error (e.g. "Object of class SomePlugin
 cannot be converted to string").

 This puts the onus of type-checking the value from the hook on each and
 every callback:

 {{{
 add_action('plugin_loaded', function ($plugin) {
     if (! is_scalar($plugin)) {
         Logger::info('Some plugin was loaded, but we can\'t tell which
 one!');
     } else {
         Logger::info(sprintf('Plugin %s was loaded', $plugin));
     }
 });
 }}}

 The problem only becomes more apparent once scalar typehints are
 introduced (PHP 7.0+):

 {{{
 add_action('plugin_loaded', function (string $plugin) {
     Logger::info(sprintf('Plugin %s was loaded', $plugin));
 });
 }}}

   Uncaught TypeError: {closure}(): Argument #1 ($plugin) must be of type
 string, SomePlugin given

 Not to raise problems without solutions, there are a few ways this could
 be addressed:

 1. Wrap the `include_once` call in a closure to isolate its variable
 scope:
 {{{
 ( function () use ( $plugin ) {
     include_once $plugin;
 } )();
 }}}

 2. (Probably more "The WordPress Way™") Create a named function that
 includes the given file in an isolated scope, then call that within the
 `foreach ( wp_get_active_and_valid_plugins() as $plugin )` loop:
 {{{
 function load_plugin_file( $plugin ) {
     include_once $plugin;
 }
 }}}
 3. Update the DocBlock to indicate that this argument has type "mixed" and
 cannot be relied upon.

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/55432#comment:3>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list