filicious / core

Filicious is a high level object oriented filesystem abstraction for PHP.
https://filicious.github.io/
31 stars 9 forks source link

Rework plugin system #79

Open tristanlins opened 10 years ago

tristanlins commented 10 years ago

I'm not fully satisfied with the current plugin system.

The main problem I see is that each plugin has is fixed name. That means it is impossible to have multiple plugins for the same behavior. A good example is a image resize plugin.

There could be multiple implementations:

Another feature could be native plugins. Plugins that are provided by the adapter to support adapter specific features. For a dropbox adapter this could be a build-in dropbox plugin.

So I wan't to do the following changes:

PluginManager::listPlugins($name, Adapter $adapter, File $file = null) {
    if (isset($this->plugins[$name])) {
        $sortedPlugins = array();
        $nativePlugins = $adapter->getPlugins();
        $priorizedPlugins = array_merge($this->plugins[$name]);
        $priorizedPlugins[0] = array_merge($nativePlugins, $plugins[0]);
        $plugins = call_user_func_array('array_merge', $priorizedPlugins);
        $plugins = array_filter(
            function ($plugin) use ($adapter, $file) {
                if ($file) {
                    return $plugin->supportsFile($file);
                }
                return $plugin->supportsAdapter($adapter);
            },
            $plugins
        }

        if (count($plugins)) {
            return $plugins;
        }
    }

    throw new \PluginException('Plugin ' . $name . ' does not exists');
}

PluginManager::getPlugin($name, Adapter $adapter, File $file = null) {
    $plugins = $this->listPlugins($name, $adapter, $file);
    return array_shift($plugins);
}

Instead of returning exactly one plugin object, it could be possible to pass a magic plugin, that ask each plugin in the list.

class PluginsPlugin implements PluginInterface {
    function __call($name, $arguments) {
        foreach ($this->plugins as $plugin) {
            try {
                return call_user_func_array(array($plugin, $name), $arguments);
            } catch (UnsupportedPluginMethodException $e) {
                continue;
            }
        }
        throw new UnsupportedPluginMethodException($name);
    }
}

I'm also not happy with the Filesystem Adapter and File Adapter alienation. I'm not sure if this is really necessary.

@discordier any hints?

discordier commented 10 years ago

Just to let you know, I did not miss this ticket, I simply did not find any time yet to get to it. :(