Users running a non-download version of Vanilla (pulled from github), on branch release/2019.016 or master from the last 2 weeks should upgrade to release/2019.017 or latest master for security reasons. Downloaded official open sources releases are not affected.

Enabling plugins via code

businessdadbusinessdad Stealth contributor MVP

I'm finalizing some scripts to automate testing of Vanilla Plugins, but I stumbled upon an odd behaviour: if a plugin depends on another, enabling them one after the other via EnablePlugin() doesn't work as expected. To be more specific, the following code will generate an error:

// This will work
Gdn::PluginManager()->EnablePlugin('SomePlugin', $Validation);

// This will not work if, while being enabled, the plugin uses anything  from SomePlugin. 
// In my case, ChildPlugin uses SomePlugin, who, in turn, needs one of its models to carry 
// on. In such case, the error "Class not found" is returned
Gdn::PluginManager()->EnablePlugin('ChildPlugin', $Validation); 

If the same tests are run immediately after the first fail, they will succeed. In short:
phpunit sometests.php // This will fail with "class not found"
phpunit sometests.php // This will run correctly

It seems, to me, that EnablePlugin() doesn't expose the plugin to the various classes until next bootstrap. However, this is a speculation, as I haven't found an explanation for such behaviour.

If anyone has any suggestion, it would be very welcome. Thanks. :)

Tagged:

Comments

  • This is a perfect subject for the 'developers' category. Anyone object if I move it?

  • businessdadbusinessdad Stealth contributor MVP
    via Email
    Not at all! Sorry for not having put it there in first place. I should get
    the habit of sleeping at 4 am, rather than posting on forums...
  • businessdadbusinessdad Stealth contributor MVP

    Sleep brought me inspiration, I think I found a solution. The issue is that, when one calls EnablePlugin(), the plugin is indeed flagged as enabled, but the Autoloader is not aware of it. Clearly, after another bootstrap, the Autoloader becomes aware of the changes, therefore I analysed it, and I found what I was missing. Here's the code that works.

    if(Gdn::PluginManager()->EnablePlugin($PluginName, $Validation)) {
        Gdn_LibraryMap::ClearCache();
    
        // Reload plugin configuration
        Gdn::PluginManager()->Start(true);
        Gdn_Autoloader::Attach(Gdn_Autoloader::CONTEXT_PLUGIN);
    }
    
Sign In or Register to comment.