diff --git a/bin/console b/bin/console index 8a73b4088c..fde0803660 100755 --- a/bin/console +++ b/bin/console @@ -33,7 +33,7 @@ use Alchemy\Phrasea\Command\Setup\XSendFileMappingDumper; require_once __DIR__ . '/../lib/autoload.php'; try { - $app = new CLI(" + $cli = new CLI(" _____ _ _ _____ _____ ______ _ _ ______ _______ | __ \| | | | __ \ /\ / ____| ____| /\ | \ | | ____|__ __| | |__) | |__| | |__) | / \ | (___ | |__ / \ | \| | |__ | | @@ -51,55 +51,59 @@ try { under certain conditions; type `about:license' for details.\n\n" . ' KONSOLE KOMMANDER', Version::getName() . ' ' . Version::getNumber()); - if (!$app['phraseanet.configuration-tester']->isInstalled()) { + if (!$cli['phraseanet.configuration-tester']->isInstalled()) { throw new \RuntimeException('Phraseanet is not installed, use setup command instead'); } - if (!$app['phraseanet.configuration-tester']->isUpToDate()) { + if (!$cli['phraseanet.configuration-tester']->isUpToDate()) { throw new \RuntimeException('Phraseanet is not up-to-date, use setup command instead'); } - $app->command(new \module_console_aboutAuthors('about:authors')); - $app->command(new \module_console_aboutLicense('about:license')); + $cli->command(new \module_console_aboutAuthors('about:authors')); + $cli->command(new \module_console_aboutLicense('about:license')); - $app->command(new \module_console_checkExtension('check:extension')); - $app->command(new CheckConfig('check:config')); + $cli->command(new \module_console_checkExtension('check:extension')); + $cli->command(new CheckConfig('check:config')); - $app->command(new UpgradeDBDatas('system:upgrade-datas')); + $cli->command(new UpgradeDBDatas('system:upgrade-datas')); - $app->command(new \module_console_sphinxGenerateSuggestion('sphinx:generate-suggestions')); + $cli->command(new \module_console_sphinxGenerateSuggestion('sphinx:generate-suggestions')); - $app->command(new \module_console_systemMailCheck('system:mail-check')); - $app->command(new \module_console_systemBackupDB('system:backup-db')); - $app->command(new \module_console_systemClearCache('system:clear-cache')); - $app->command(new \module_console_systemTemplateGenerator('system:template-generator')); - $app->command(new \module_console_systemExport('system:export')); + $cli->command(new \module_console_systemMailCheck('system:mail-check')); + $cli->command(new \module_console_systemBackupDB('system:backup-db')); + $cli->command(new \module_console_systemClearCache('system:clear-cache')); + $cli->command(new \module_console_systemTemplateGenerator('system:template-generator')); + $cli->command(new \module_console_systemExport('system:export')); - $app->command(new \module_console_taskrun('task:run')); - $app->command(new \module_console_tasklist('task:list')); - $app->command(new \module_console_taskState('task:state')); - $app->command(new \module_console_schedulerState('scheduler:state')); - $app->command(new \module_console_schedulerStop('scheduler:stop')); - $app->command(new \module_console_schedulerStart('scheduler:start')); + $cli->command(new \module_console_taskrun('task:run')); + $cli->command(new \module_console_tasklist('task:list')); + $cli->command(new \module_console_taskState('task:state')); + $cli->command(new \module_console_schedulerState('scheduler:state')); + $cli->command(new \module_console_schedulerStop('scheduler:stop')); + $cli->command(new \module_console_schedulerStart('scheduler:start')); - $app->command(new Mailtest('mail:test')); + $cli->command(new Mailtest('mail:test')); - $app->command(new \module_console_fieldsList('fields:list')); - $app->command(new \module_console_fieldsDelete('fields:delete')); - $app->command(new \module_console_fieldsRename('fields:rename')); - $app->command(new \module_console_fieldsMerge('fields:merge')); + $cli->command(new \module_console_fieldsList('fields:list')); + $cli->command(new \module_console_fieldsDelete('fields:delete')); + $cli->command(new \module_console_fieldsRename('fields:rename')); + $cli->command(new \module_console_fieldsMerge('fields:merge')); - $app->command(new CreateCollection('collection:create')); + $cli->command(new CreateCollection('collection:create')); - $app->command(new RecordAdd('records:add')); - $app->command(new RescanTechnicalDatas('records:rescan-technical-datas')); - $app->command(new BuildMissingSubdefs('records:build-missing-subdefs')); + $cli->command(new RecordAdd('records:add')); + $cli->command(new RescanTechnicalDatas('records:rescan-technical-datas')); + $cli->command(new BuildMissingSubdefs('records:build-missing-subdefs')); - $app->command(new AddPlugin()); - $app->command(new RemovePlugin()); - $app->command(new Configuration()); - $app->command(new XSendFileMappingDumper()); + $cli->command(new AddPlugin()); + $cli->command(new RemovePlugin()); + $cli->command(new Configuration()); + $cli->command(new XSendFileMappingDumper()); - $result_code = is_int($app->run()) ? : 1; + call_user_func(function ($cli) { + require $cli['plugins.directory'] . '/commands.php'; + }, $cli); + + $result_code = is_int($cli->run()) ? : 1; } catch (\Exception $e) { $result_code = 1; echo sprintf("\nAn error occured :\n\n\t\033[0;31m%s\033[0;37m\n\n", $e->getMessage()); diff --git a/lib/Alchemy/Phrasea/CLI.php b/lib/Alchemy/Phrasea/CLI.php index dd9edb294a..821c08caf3 100644 --- a/lib/Alchemy/Phrasea/CLI.php +++ b/lib/Alchemy/Phrasea/CLI.php @@ -11,6 +11,7 @@ namespace Alchemy\Phrasea; +use Alchemy\Phrasea\Command\CommandInterface; use Symfony\Component\Console; /** @@ -73,9 +74,9 @@ class CLI extends Application * * If a command with the same name already exists, it will be overridden. * - * @param \Cilex\Command\Command $command A Command object + * @param CommandInterface $command A Command object */ - public function command(Command\Command $command) + public function command(CommandInterface $command) { $command->setContainer($this); $this['console']->add($command); diff --git a/lib/Alchemy/Phrasea/Command/Command.php b/lib/Alchemy/Phrasea/Command/Command.php index fcbb840e62..bef04eb73a 100644 --- a/lib/Alchemy/Phrasea/Command/Command.php +++ b/lib/Alchemy/Phrasea/Command/Command.php @@ -23,7 +23,7 @@ use Symfony\Component\Console\Output\OutputInterface; * @license http://opensource.org/licenses/gpl-3.0 GPLv3 * @link www.phraseanet.com */ -abstract class Command extends SymfoCommand +abstract class Command extends SymfoCommand implements CommandInterface { /** * @var Application @@ -120,4 +120,12 @@ abstract class Command extends SymfoCommand return $duration; } + + /** + * {@inheritdoc} + */ + public static function create() + { + return new static(); + } } diff --git a/lib/Alchemy/Phrasea/Command/CommandInterface.php b/lib/Alchemy/Phrasea/Command/CommandInterface.php new file mode 100644 index 0000000000..1e7ac92fd2 --- /dev/null +++ b/lib/Alchemy/Phrasea/Command/CommandInterface.php @@ -0,0 +1,29 @@ +doWrite('autoload.php', $this->createLoader($manifests)) - ->doWrite('services.php', $this->createServices($manifests)); + ->doWrite('services.php', $this->createServices($manifests)) + ->doWrite('commands.php', $this->createCommands($manifests)); return $this; } @@ -100,6 +101,39 @@ EOF; return \$app; }, \$app); +EOF; + + return $buffer; + } + + private function createCommands($manifests) + { + $buffer = <<getCommands() as $command) { + $class = $command['class']; + $buffer .= <<command($class::create()); +EOF; + } + } + + $buffer .= <<get('services'); } + public function getCommands() + { + return $this->get('commands') ? : array(); + } + public function getExtra() { return $this->get('extra'); diff --git a/lib/Alchemy/Phrasea/Plugin/resources/example.json b/lib/Alchemy/Phrasea/Plugin/resources/example.json index 5f0116601e..fe19f0a71e 100644 --- a/lib/Alchemy/Phrasea/Plugin/resources/example.json +++ b/lib/Alchemy/Phrasea/Plugin/resources/example.json @@ -14,6 +14,11 @@ "version" : "0.1", "minimum-phraseanet-version": "3.8", "maximum-phraseanet-version": "3.9", + "Commands" : [ + { + "class": "Vendor\\Connector\\CustomCommand" + } + ], "services" : [ { "class": "Vendor\\Connector\\PluginServiceInterface" diff --git a/lib/conf.d/plugin-schema.json b/lib/conf.d/plugin-schema.json index bd772efede..07f094e766 100644 --- a/lib/conf.d/plugin-schema.json +++ b/lib/conf.d/plugin-schema.json @@ -70,6 +70,20 @@ "type": "string", "description": "The maximum phraseanet version for the plugin, excluding the one provided" }, + "commands": { + "type": "array", + "description": "An array of commands to register.", + "items": { + "type": "object", + "description": "A command", + "properties": { + "class": { + "type": "string", + "description": "The plugin command name" + } + } + } + }, "services": { "type": "array", "description": "An array of services to register.", diff --git a/plugins/commands.php b/plugins/commands.php new file mode 100644 index 0000000000..5f8282cdac --- /dev/null +++ b/plugins/commands.php @@ -0,0 +1,7 @@ +write('Hello World'); + + return 0; + } +} diff --git a/tests/Alchemy/Tests/Phrasea/Plugin/Fixtures/PluginDirInstalled/TestPlugin/manifest.json b/tests/Alchemy/Tests/Phrasea/Plugin/Fixtures/PluginDirInstalled/TestPlugin/manifest.json index f8cf0c90b3..f7705fc653 100644 --- a/tests/Alchemy/Tests/Phrasea/Plugin/Fixtures/PluginDirInstalled/TestPlugin/manifest.json +++ b/tests/Alchemy/Tests/Phrasea/Plugin/Fixtures/PluginDirInstalled/TestPlugin/manifest.json @@ -18,5 +18,10 @@ { "class": "Vendor\\PluginService" } + ], + "commands" : [ + { + "class": "Vendor\\CustomCommand" + } ] } diff --git a/tests/Alchemy/Tests/Phrasea/Plugin/Fixtures/PluginDirInstalled/TestPlugin/src/Vendor/CustomCommand.php b/tests/Alchemy/Tests/Phrasea/Plugin/Fixtures/PluginDirInstalled/TestPlugin/src/Vendor/CustomCommand.php new file mode 100644 index 0000000000..94c0c245b9 --- /dev/null +++ b/tests/Alchemy/Tests/Phrasea/Plugin/Fixtures/PluginDirInstalled/TestPlugin/src/Vendor/CustomCommand.php @@ -0,0 +1,22 @@ +write('Hello World'); + + return 0; + } +} diff --git a/tests/Alchemy/Tests/Phrasea/Plugin/Management/AutoloaderGeneratorTest.php b/tests/Alchemy/Tests/Phrasea/Plugin/Management/AutoloaderGeneratorTest.php index 4b38bed599..28b5a913f1 100644 --- a/tests/Alchemy/Tests/Phrasea/Plugin/Management/AutoloaderGeneratorTest.php +++ b/tests/Alchemy/Tests/Phrasea/Plugin/Management/AutoloaderGeneratorTest.php @@ -3,6 +3,7 @@ namespace Alchemy\Tests\Phrasea\Plugin\Management; use Alchemy\Phrasea\Application; +use Alchemy\Phrasea\CLI; use Alchemy\Phrasea\Plugin\Management\AutoloaderGenerator; use Alchemy\Phrasea\Plugin\Schema\Manifest; use Symfony\Component\Process\ProcessBuilder; @@ -15,7 +16,11 @@ class AutoloaderGeneratorTest extends \PHPUnit_Framework_TestCase $pluginDir = __DIR__ . '/../Fixtures/PluginDirInstalled/TestPlugin'; $pluginsDir = __DIR__ . '/../Fixtures/PluginDirInstalled'; - $files = array($pluginsDir . '/services.php', $pluginsDir . '/autoload.php'); + $files = array( + $pluginsDir . '/services.php', + $pluginsDir . '/autoload.php', + $pluginsDir . '/commands.php', + ); $this->cleanup($files); @@ -49,6 +54,13 @@ class AutoloaderGeneratorTest extends \PHPUnit_Framework_TestCase $this->assertSame($app, $retrievedApp); $this->assertEquals('hello world', $app['plugin-test']); + // load services + $cli = new CLI('test'); + $retrievedCli = require $pluginsDir . '/commands.php'; + + $this->assertSame($cli, $retrievedCli); + $this->assertInstanceOf('Vendor\CustomCommand', $cli['console']->find('hello:world')); + $this->cleanup($files); } diff --git a/tests/Alchemy/Tests/Phrasea/Plugin/Schema/ManifestTest.php b/tests/Alchemy/Tests/Phrasea/Plugin/Schema/ManifestTest.php index 07bdc72495..601b041a3f 100644 --- a/tests/Alchemy/Tests/Phrasea/Plugin/Schema/ManifestTest.php +++ b/tests/Alchemy/Tests/Phrasea/Plugin/Schema/ManifestTest.php @@ -24,6 +24,7 @@ class ManifestTest extends \PHPUnit_Framework_TestCase $this->assertEquals('0.1', $manifest->getVersion()); $this->assertEquals('3.8', $manifest->getMinimumPhraseanetVersion()); $this->assertEquals('3.9', $manifest->getMaximumPhraseanetVersion()); + $this->assertEquals(array(array('class' => 'Vendor\CustomCommand')), $manifest->getCommands()); $this->assertEquals(array(array('class' => 'Vendor\PluginService')), $manifest->getServices()); $this->assertEquals(array('property' => 'value'), $manifest->getExtra()); }