[wp-trac] [WordPress Trac] #57249: plugin_folder parameter in get_plugins returns empty array

WordPress Trac noreply at wordpress.org
Fri Dec 2 15:47:55 UTC 2022


#57249: plugin_folder parameter in get_plugins returns empty array
--------------------------+------------------------------
 Reporter:  antonynz      |       Owner:  (none)
     Type:  defect (bug)  |      Status:  new
 Priority:  normal        |   Milestone:  Awaiting Review
Component:  Plugins       |     Version:  trunk
 Severity:  minor         |  Resolution:
 Keywords:                |     Focuses:
--------------------------+------------------------------

Comment (by petitphp):

 Hi, Welcome back to WordPress Trac.

 >WordPress 2.6 added a caching mechanism for the get_plugins function.
 However this change would have stopped the plugin_folder parameter
 returning the desired result for a chosen plugin.
 >
 >i.e get_plugins('classic-editor/classic-editor.php') returns empty when
 that plugin is installed.
 It doesn't seem to be the way the parameter `$plugin_folder` is intended
 to be used.

 Looking at usage in Core, `$plugin_folder` expect a relative path to a
 plugin folder : `get_plugins('/classic-editor');`.

 This will only return plugin data for this plugin.

 >Looking at the code, the wp_plugins data is added to the cache inside of
 an additional array, with the key matching the plugin_folder passed to the
 function:
 >
 >{{{
 >$cache_plugins[ $plugin_folder ] = $wp_plugins;
 >}}}
 >
 >When no plugin_folder is passed it will be set to "", and the plugins
 data will be nested inside of an empty key array.
 >
 >Which means the parameter check earlier on wouldn't be able to check the
 nested array and only returns true if empty
 >
 >{{{
 >if ( isset($cache_plugins[ $plugin_folder ]) )
 >return $cache_plugins[ $plugin_folder ];
 >}}}
 >
 >
 >This means the cache is probably inadvertently working, since leaving the
 plugin_parameter empty >will match the empty parent array key of the cache
 i.e $cache_plugins[""] returns the cached array >of the plugins.
 >
 >As a fix I suggest removing the parent array of the cache and replacing:
 >
 >{{{
 >$cache_plugins['plugin_folder'] = $wp_plugins;
 >}}}
 >
 >with:
 >
 >{{{
 >$cache_plugins = $wp_plugins;
 >}}}
 >
 >And replacing the following the following:
 >
 >{{{
 >if ( ! $cache_plugins = wp_cache_get('plugins', 'plugins') )
 >               $cache_plugins = array();
 >}}}
 >with something similar to return the full cached results if the
 plugin_parameter is empty:
 >
 >{{{
 >if ( ! $cache_plugins = wp_cache_get('plugins', 'plugins') ) {
 >       $cache_plugins = array();
 >} else if($plugin_folder == ""){
 >       return $cache_plugins;
 >}
 >}}}
 There might be ways to optimize further this function by refactoring how
 the cache is used. However, it should be done in a way that preserve the
 current array shape when for each case (for all plugins and for a specific
 plugin).

 >This also means that anytime the parameter changes in the same request
 the cache will be bypassed, >and the full function run as the parent key
 changes: eg on the same request:
 >get_plugins() - cached
 >get_plugins('test') - bypassed
 >get_plugins() - bypassed
 >get_plugins() - cached
 I couldn't reproduce the issue locally.

 Doing multiple calls to `get_plugins`, the cache behaved as expected :
 {{{
 wp_cache_flush();
 get_plugins(); //miss cache
 get_plugins('/classic-editor'); //miss cache
 get_plugins(); //hit cache
 get_plugins(); //hit cache
 get_plugins('/classic-editor'); //hit cache
 }}}

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


More information about the wp-trac mailing list