Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In with Facebook Sign In with Google Sign In with OpenID Sign In with Twitter
Support for Vanilla Forums Cloud product

In this Discussion

Follow Us


Plugin inheritance

TiGRTiGR New
edited August 2011 in Developers
Currently Vanilla does not support plugin inheritance. If you try to use it, you start getting all kind of bugs (quite unexpected), that spoil everything.

Let's say, I would like to have some common functionality, that could be inherited then. So, you create some abstract class _baseBlahPlugin which extends Gdn_Plugin. You put it somewhere in your plugin dir, carefully naming it not as "default.php" or "*plugin.php", so that plugin manager would not try to load it as plugins.

Then, you create some implementation plugin, _BlahBoxPlugin which extends _base_BlahPlugin, and Boom! you get it broken. Since plugin manager has this magic:
   public function RegisterPlugins() {

// Loop through all declared classes looking for ones that implement Gdn_iPlugin.
foreach (get_declared_classes() as $ClassName) {

// Only register the plugin if it implements the Gdn_IPlugin interface
if (in_array('Gdn_IPlugin', class_implements($ClassName))) {

// If this plugin was already indexed, skip it.
if (array_key_exists($ClassName, $this->RegisteredPlugins))
continue;

// Register this plugin's methods
$this->RegisterPlugin($ClassName);
}
}
}
So, if there is any class loaded that implements Gdn_IPlugin, Vanilla tries to instantiate it as plugin, even if it is abstract. The simple fix looks like this:
            // Register only non abstract classes.
$Reflection = new ReflectionClass($ClassName);
if (!$Reflection->isAbstract())
// Register this plugin's methods
$this->RegisterPlugin($ClassName);
But the question is - is this a proper way to go? Would such patch be committed?

Currently in my local branch I have AuthCore plugin that does nothing, but holds several core authentication plugin base classes for varions protocols: for openid, oauth2.

So, creating new plugins for such services take only around 30 lines of code, instead of 350 in existing Auth plugins.

Comments

  • LincolnLincoln Community Instigator Vanilla Staff
    edited August 2011
    Couldn't this be accomplished by creating a normal AuthCore plugin and simply having the others extend the AuthCore plugin and list that as a 'RequiredPlugin' for the others? I don't see why the "hidden" abstract class is needed.

    Sr Developer at Vanilla Forums [GitHub, Twitter]

  • I have AuthCore, with very basic functions. Then I have AuthCore_oAuth2 and AuthCore_openid which extend AuthCore. All these classes are located in AuthCore plugin directory. AuthCore_oAuth2 cannot be plugin by itself - it misses getProfile code, which is specific for every service.

    That is, the part of connection process is fetching user data, which is being accomplished not with oAuth API, but with service specific one. Facebook has it's own API, Vkontakte - it's own.

    There just cannot be working oAuth dummy plugin. That's why it is supposed to be abstract.

    But as I said, if I leave it out somewhere in plugin directory Vanilla will attempt to run this plugin. Even if it is not complete.

    And yes, AuthCore is listed as RequiredPlugin in plugins for specific services.

    And I could bear with non abstract class if Vanilla wouldn't have been trying to initiate it.

  • So, if there is any class loaded that implements Gdn_IPlugin, Vanilla tries to instantiate it as plugin, even if it is abstract. The simple fix looks like this:
                // Register only non abstract classes.
    $Reflection = new ReflectionClass($ClassName);
    if (!$Reflection->isAbstract())
    // Register this plugin's methods
    $this->RegisterPlugin($ClassName);
    But the question is - is this a proper way to go? Would such patch be committed?
    This seems like a reasonable (and safe) thing to be doing in any case. Why don't you put up a pull request, link it here and pull a dev into the discussion?

    My addons: NillaBlog | Vanoogle

  • LincolnLincoln Community Instigator Vanilla Staff
    In WordPress, I found a group of plugins that all required 1 core "meta" plugin that provided base functionality for all the other plugins in the group. The meta plugin didn't do anything on its own, it just provided a cleaner way for all the others to work.

    I understand that an abstract class would be the good-and-proper PHP approach, but I'm concerned about creating some corner case of plugin extensibility we need to support from now until the end of time, and wonder if that will be hard to communicate to plugin developers anyway.

    Is it *possible* to create a plugin that simply provides a framework/inheritance for your other plugins and then list that as a RequiredPlugin for the others?

    Sr Developer at Vanilla Forums [GitHub, Twitter]

Sign In or Register to comment.