diff --git a/lib/Alchemy/Phrasea/Command/Plugin/AddPlugin.php b/lib/Alchemy/Phrasea/Command/Plugin/AddPlugin.php index cd223e22b0..b3da2e4604 100644 --- a/lib/Alchemy/Phrasea/Command/Plugin/AddPlugin.php +++ b/lib/Alchemy/Phrasea/Command/Plugin/AddPlugin.php @@ -58,6 +58,10 @@ class AddPlugin extends AbstractPluginCommand $this->container['filesystem']->remove($temporaryDir); $output->writeln(" OK"); + $output->write("Activating plugin..."); + $this->container['conf']->set(['plugins', $manifest->getName(), 'enabled'], true); + $output->writeln(" OK"); + $this->updateConfigFiles($input, $output); return 0; diff --git a/lib/Alchemy/Phrasea/Command/Plugin/RemovePlugin.php b/lib/Alchemy/Phrasea/Command/Plugin/RemovePlugin.php index 0c3147f2a8..db089df083 100644 --- a/lib/Alchemy/Phrasea/Command/Plugin/RemovePlugin.php +++ b/lib/Alchemy/Phrasea/Command/Plugin/RemovePlugin.php @@ -24,8 +24,7 @@ class RemovePlugin extends AbstractPluginCommand $this ->setDescription('Removes a plugin given its name') - ->addArgument('name', InputArgument::REQUIRED, 'The name of the plugin') - ->addOption('keep-config', 'k', InputOption::VALUE_NONE, 'Use this flag to keep configuration'); + ->addArgument('name', InputArgument::REQUIRED, 'The name of the plugin'); } protected function doExecutePluginAction(InputInterface $input, OutputInterface $output) @@ -50,11 +49,7 @@ class RemovePlugin extends AbstractPluginCommand $this->updateConfigFiles($input, $output); - if (!$input->getOption('keep-config')) { - $conf = $this->container['phraseanet.configuration']->getConfig(); - unset($conf['plugins'][$name]); - $this->container['phraseanet.configuration']->setConfig($conf); - } + $this->container['conf']->remove(['plugins', $name]); return 0; } diff --git a/lib/Alchemy/Phrasea/Core/CLIProvider/PluginServiceProvider.php b/lib/Alchemy/Phrasea/Core/CLIProvider/PluginServiceProvider.php index df9ffb936c..d8c849185c 100644 --- a/lib/Alchemy/Phrasea/Core/CLIProvider/PluginServiceProvider.php +++ b/lib/Alchemy/Phrasea/Core/CLIProvider/PluginServiceProvider.php @@ -30,24 +30,6 @@ class PluginServiceProvider implements ServiceProviderInterface { public function register(Application $app) { - $app['plugins.schema'] = realpath(__DIR__ . '/../../../../conf.d/plugin-schema.json'); - - $app['plugins.manager'] = $app->share(function (Application $app) { - return new PluginManager($app['plugins.directory'], $app['plugins.plugins-validator']); - }); - - $app['plugins.json-validator'] = $app->share(function (Application $app) { - return new JsonValidator(); - }); - - $app['plugins.manifest-validator'] = $app->share(function (Application $app) { - return ManifestValidator::create($app); - }); - - $app['plugins.plugins-validator'] = $app->share(function (Application $app) { - return new PluginValidator($app['plugins.manifest-validator']); - }); - $app['plugins.import-strategy'] = $app->share(function (Application $app) { return new ImportStrategy(); }); diff --git a/lib/Alchemy/Phrasea/Core/Provider/PluginServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/PluginServiceProvider.php index 94fc454d5f..1a9d2e7693 100644 --- a/lib/Alchemy/Phrasea/Core/Provider/PluginServiceProvider.php +++ b/lib/Alchemy/Phrasea/Core/Provider/PluginServiceProvider.php @@ -11,6 +11,10 @@ namespace Alchemy\Phrasea\Core\Provider; +use Alchemy\Phrasea\Plugin\PluginManager; +use Alchemy\Phrasea\Plugin\Schema\ManifestValidator; +use Alchemy\Phrasea\Plugin\Schema\PluginValidator; +use JsonSchema\Validator as JsonValidator; use Silex\Application; use Silex\ServiceProviderInterface; @@ -18,6 +22,23 @@ class PluginServiceProvider implements ServiceProviderInterface { public function register(Application $app) { + $app['plugins.schema'] = realpath(__DIR__ . '/../../../../conf.d/plugin-schema.json'); + + $app['plugins.json-validator'] = $app->share(function (Application $app) { + return new JsonValidator(); + }); + + $app['plugins.manifest-validator'] = $app->share(function (Application $app) { + return ManifestValidator::create($app); + }); + + $app['plugins.plugins-validator'] = $app->share(function (Application $app) { + return new PluginValidator($app['plugins.manifest-validator']); + }); + + $app['plugins.manager'] = $app->share(function (Application $app) { + return new PluginManager($app['plugins.directory'], $app['plugins.plugins-validator'], $app['conf']); + }); } public function boot(Application $app) diff --git a/lib/Alchemy/Phrasea/Plugin/PluginManager.php b/lib/Alchemy/Phrasea/Plugin/PluginManager.php index f3c014a0f4..4a784c63fc 100644 --- a/lib/Alchemy/Phrasea/Plugin/PluginManager.php +++ b/lib/Alchemy/Phrasea/Plugin/PluginManager.php @@ -11,6 +11,7 @@ namespace Alchemy\Phrasea\Plugin; +use Alchemy\Phrasea\Core\Configuration\PropertyAccess; use Alchemy\Phrasea\Plugin\Schema\PluginValidator; use Alchemy\Phrasea\Plugin\Exception\PluginValidationException; use Symfony\Component\Finder\Finder; @@ -19,11 +20,13 @@ class PluginManager { private $pluginDir; private $validator; + private $conf; - public function __construct($pluginDir, PluginValidator $validator) + public function __construct($pluginDir, PluginValidator $validator, PropertyAccess $conf) { $this->pluginDir = $pluginDir; $this->validator = $validator; + $this->conf = $conf; } /** @@ -31,20 +34,13 @@ class PluginManager */ public function listPlugins() { - $finder = new Finder(); - $finder - ->depth(0) - ->in($this->pluginDir) - ->directories(); - $plugins = []; - foreach ($finder as $pluginDir) { + foreach ($this->conf->get('plugins') as $name => $config) { $manifest = $error = null; - $name = $pluginDir->getBasename(); try { - $manifest = $this->validator->validatePlugin((string) $pluginDir); + $manifest = $this->validator->validatePlugin($this->pluginDir.'/'.$name); } catch (PluginValidationException $e) { $error = $e; } @@ -57,8 +53,29 @@ class PluginManager public function hasPlugin($name) { - $plugins = $this->listPlugins(); + return array_key_exists($name, $this->conf->get('plugins')); + } - return isset($plugins[$name]); + public function enable($name) + { + $this->conf->set(['plugins', $name, 'enabled'], true); + + return $this; + } + + public function disable($name) + { + $this->conf->set(['plugins', $name, 'enabled'], false); + + return $this; + } + + public function isEnabled($name) + { + if (!$this->hasPlugin($name)) { + return false; + } + + return $this->conf->get(['plugins', $name, 'enabled'], false); } } diff --git a/lib/classes/patch/390alpha12a.php b/lib/classes/patch/390alpha12a.php new file mode 100644 index 0000000000..6da861fb6d --- /dev/null +++ b/lib/classes/patch/390alpha12a.php @@ -0,0 +1,92 @@ +release; + } + + /** + * {@inheritdoc} + */ + public function require_all_upgrades() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function concern() + { + return $this->concern; + } + + /** + * {@inheritdoc} + */ + public function getDoctrineMigrations() + { + return []; + } + + /** + * {@inheritdoc} + */ + public function apply(base $appbox, Application $app) + { + foreach ($this->listPlugins($app) as $name => $plugin) { + $app['conf']->set(['plugins', $name, 'enabled'], true); + } + } + + private function listPlugins(Application $app) + { + $finder = new Finder(); + $finder + ->depth(0) + ->in($app['plugins.directory']) + ->directories(); + + $plugins = []; + + foreach ($finder as $pluginDir) { + $manifest = $error = null; + $name = $pluginDir->getBasename(); + + try { + $manifest = $app['plugins.plugins-validator']->validatePlugin((string) $pluginDir); + } catch (PluginValidationException $e) { + $error = $e; + } + + $plugins[$name] = new Plugin($name, $manifest, $error); + } + + return $plugins; + } +} diff --git a/tests/Alchemy/Tests/Phrasea/Plugin/PluginManagerTest.php b/tests/Alchemy/Tests/Phrasea/Plugin/PluginManagerTest.php index 6bbe410a2e..eb36ab2353 100644 --- a/tests/Alchemy/Tests/Phrasea/Plugin/PluginManagerTest.php +++ b/tests/Alchemy/Tests/Phrasea/Plugin/PluginManagerTest.php @@ -9,27 +9,41 @@ class PluginManagerTest extends PluginTestCase { public function testListGoodPlugins() { - $manager = new PluginManager(__DIR__ . '/Fixtures/PluginDirInstalled', self::$DI['cli']['plugins.plugins-validator']); + $prevPlugins = self::$DI['cli']['conf']->get('plugins'); + self::$DI['cli']['conf']->set('plugins', []); + self::$DI['cli']['conf']->set(['plugins', 'test-plugin', 'enabled'], true); + + $manager = new PluginManager(__DIR__ . '/Fixtures/PluginDirInstalled', self::$DI['cli']['plugins.plugins-validator'], self::$DI['cli']['conf']); $plugins = $manager->listPlugins(); $this->assertCount(1, $plugins); $plugin = array_pop($plugins); $this->assertFalse($plugin->isErroneous()); + + self::$DI['cli']['conf']->set('plugins', $prevPlugins); } public function testListWrongPlugins() { - $manager = new PluginManager(__DIR__ . '/Fixtures/WrongPlugins', self::$DI['cli']['plugins.plugins-validator']); + $prevPlugins = self::$DI['cli']['conf']->get('plugins'); + self::$DI['cli']['conf']->set('plugins', []); + self::$DI['cli']['conf']->set(['plugins', 'plugin-test', 'enabled'], true); + self::$DI['cli']['conf']->set(['plugins', 'plugin-test2', 'enabled'], true); + self::$DI['cli']['conf']->set(['plugins', 'plugin-test3', 'enabled'], true); + + $manager = new PluginManager(__DIR__ . '/Fixtures/WrongPlugins', self::$DI['cli']['plugins.plugins-validator'], self::$DI['cli']['conf']); $plugins = $manager->listPlugins(); - $this->assertCount(8, $plugins); + $this->assertCount(3, $plugins); $plugin = array_pop($plugins); $this->assertTrue($plugin->isErroneous()); + + self::$DI['cli']['conf']->set('plugins', $prevPlugins); } public function testHasPlugin() { - $manager = new PluginManager(__DIR__ . '/Fixtures/PluginDirInstalled', self::$DI['cli']['plugins.plugins-validator']); + $manager = new PluginManager(__DIR__ . '/Fixtures/PluginDirInstalled', self::$DI['cli']['plugins.plugins-validator'], self::$DI['cli']['conf']); $this->assertTrue($manager->hasPlugin('test-plugin')); $this->assertFalse($manager->hasPlugin('test-plugin2')); }