From fb642b76bb3d84b38c09f5d9dff8b51369eedaf2 Mon Sep 17 00:00:00 2001 From: Frederic Guillot Date: Sun, 29 May 2016 20:33:48 -0400 Subject: Make console commands pluggable --- app/Console/PluginInstallCommand.php | 3 +- app/Console/PluginUninstallCommand.php | 3 +- app/Console/PluginUpgradeCommand.php | 3 +- app/Core/Base.php | 1 + app/ServiceProvider/CommandProvider.php | 62 +++++++++++++++++++++++++++++++++ app/common.php | 1 + doc/plugin-registration.markdown | 41 +++++++++++++++++++--- kanboard | 41 +--------------------- 8 files changed, 107 insertions(+), 48 deletions(-) create mode 100644 app/ServiceProvider/CommandProvider.php diff --git a/app/Console/PluginInstallCommand.php b/app/Console/PluginInstallCommand.php index 1c6e14b3..a82f0069 100644 --- a/app/Console/PluginInstallCommand.php +++ b/app/Console/PluginInstallCommand.php @@ -4,6 +4,7 @@ namespace Kanboard\Console; use Kanboard\Core\Plugin\Installer; use Kanboard\Core\Plugin\PluginInstallerException; +use LogicException; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -21,7 +22,7 @@ class PluginInstallCommand extends BaseCommand protected function execute(InputInterface $input, OutputInterface $output) { if (!Installer::isConfigured()) { - $output->writeln('Kanboard is not configured to install plugins itself'); + throw new LogicException('Kanboard is not configured to install plugins itself'); } try { diff --git a/app/Console/PluginUninstallCommand.php b/app/Console/PluginUninstallCommand.php index c645e03f..48722130 100644 --- a/app/Console/PluginUninstallCommand.php +++ b/app/Console/PluginUninstallCommand.php @@ -4,6 +4,7 @@ namespace Kanboard\Console; use Kanboard\Core\Plugin\Installer; use Kanboard\Core\Plugin\PluginInstallerException; +use LogicException; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -21,7 +22,7 @@ class PluginUninstallCommand extends BaseCommand protected function execute(InputInterface $input, OutputInterface $output) { if (!Installer::isConfigured()) { - $output->writeln('Kanboard is not configured to remove plugins itself'); + throw new LogicException('Kanboard is not configured to install plugins itself'); } try { diff --git a/app/Console/PluginUpgradeCommand.php b/app/Console/PluginUpgradeCommand.php index 839124b1..6c66e917 100644 --- a/app/Console/PluginUpgradeCommand.php +++ b/app/Console/PluginUpgradeCommand.php @@ -5,6 +5,7 @@ namespace Kanboard\Console; use Kanboard\Core\Plugin\Base as BasePlugin; use Kanboard\Core\Plugin\Directory; use Kanboard\Core\Plugin\Installer; +use LogicException; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -21,7 +22,7 @@ class PluginUpgradeCommand extends BaseCommand protected function execute(InputInterface $input, OutputInterface $output) { if (!Installer::isConfigured()) { - $output->writeln('Kanboard is not configured to upgrade plugins itself'); + throw new LogicException('Kanboard is not configured to install plugins itself'); } $installer = new Installer($this->container); diff --git a/app/Core/Base.php b/app/Core/Base.php index 725bd7c0..7b4462e2 100644 --- a/app/Core/Base.php +++ b/app/Core/Base.php @@ -140,6 +140,7 @@ use Pimple\Container; * @property \Psr\Log\LoggerInterface $logger * @property \PicoDb\Database $db * @property \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher + * @property \Symfony\Component\Console\Application $cli * @property \JsonRPC\Server $api */ abstract class Base diff --git a/app/ServiceProvider/CommandProvider.php b/app/ServiceProvider/CommandProvider.php new file mode 100644 index 00000000..55c2712b --- /dev/null +++ b/app/ServiceProvider/CommandProvider.php @@ -0,0 +1,62 @@ +add(new TaskOverdueNotificationCommand($container)); + $application->add(new SubtaskExportCommand($container)); + $application->add(new TaskExportCommand($container)); + $application->add(new ProjectDailyStatsCalculationCommand($container)); + $application->add(new ProjectDailyColumnStatsExportCommand($container)); + $application->add(new TransitionExportCommand($container)); + $application->add(new LocaleSyncCommand($container)); + $application->add(new LocaleComparatorCommand($container)); + $application->add(new TaskTriggerCommand($container)); + $application->add(new CronjobCommand($container)); + $application->add(new WorkerCommand($container)); + $application->add(new ResetPasswordCommand($container)); + $application->add(new ResetTwoFactorCommand($container)); + $application->add(new PluginUpgradeCommand($container)); + $application->add(new PluginInstallCommand($container)); + $application->add(new PluginUninstallCommand($container)); + + $container['cli'] = $application; + return $container; + } +} diff --git a/app/common.php b/app/common.php index e73d3a64..72be3603 100644 --- a/app/common.php +++ b/app/common.php @@ -48,4 +48,5 @@ $container->register(new Kanboard\ServiceProvider\AvatarProvider()); $container->register(new Kanboard\ServiceProvider\FilterProvider()); $container->register(new Kanboard\ServiceProvider\QueueProvider()); $container->register(new Kanboard\ServiceProvider\ApiProvider()); +$container->register(new Kanboard\ServiceProvider\CommandProvider()); $container->register(new Kanboard\ServiceProvider\PluginProvider()); diff --git a/doc/plugin-registration.markdown b/doc/plugin-registration.markdown index 4b6e85c0..37540f29 100644 --- a/doc/plugin-registration.markdown +++ b/doc/plugin-registration.markdown @@ -110,8 +110,8 @@ public function getClasses() { return array( 'Plugin\Budget\Model' => array( - 'HourlyRate', - 'Budget', + 'HourlyRateModel', + 'BudgetModel', ) ); } @@ -120,11 +120,42 @@ public function getClasses() Now, if you use a class that extends from `Core\Base`, you can access directly to those class instance: ```php -$this->hourlyRate->remove(123); -$this->budget->getDailyBudgetBreakdown(456); +$this->hourlyRateModel->remove(123); +$this->budgetModel->getDailyBudgetBreakdown(456); // It's the same thing as using the container: -$this->container['hourlyRate']->getAll(); +$this->container['hourlyRateModel']->getAll(); ``` Keys of the containers are unique across the application. If you override an existing class, you will change the default behavior. + +Add new API methods +------------------- + +Kanboard use this library [JSON-RPC](https://github.com/fguillot/JsonRPC) to handle API calls. + +To add a new method you can do something like that from your plugin: + +```php +$this->api->getProcedureHandler()->withCallback('my_method', function() { + return 'foobar'; +}); +``` + +`$this->container['api']` or `$this->api` expose an instance of the object `JsonRPC\Server`. + +Read the library documentation for more information. + +Add new console commands +------------------------ + +Kanboard use the library [Symfony Console](http://symfony.com/doc/current/components/console/introduction.html) to handle local command lines. + +Kanboard expose an instance of the object `Symfony\Component\Console\Application` via `$this->cli`. +You can add new commands from your plugin: + +```php +$this->cli->add(new MyCommand()); +``` + +Read the library documentation for more information. diff --git a/kanboard b/kanboard index 0121f8dd..3d8140af 100755 --- a/kanboard +++ b/kanboard @@ -1,51 +1,12 @@ #!/usr/bin/env php dispatch('app.bootstrap', new Event); - - $application = new Application('Kanboard', APP_VERSION); - $application->add(new TaskOverdueNotificationCommand($container)); - $application->add(new SubtaskExportCommand($container)); - $application->add(new TaskExportCommand($container)); - $application->add(new ProjectDailyStatsCalculationCommand($container)); - $application->add(new ProjectDailyColumnStatsExportCommand($container)); - $application->add(new TransitionExportCommand($container)); - $application->add(new LocaleSyncCommand($container)); - $application->add(new LocaleComparatorCommand($container)); - $application->add(new TaskTriggerCommand($container)); - $application->add(new CronjobCommand($container)); - $application->add(new WorkerCommand($container)); - $application->add(new ResetPasswordCommand($container)); - $application->add(new ResetTwoFactorCommand($container)); - $application->add(new PluginUpgradeCommand($container)); - $application->add(new PluginInstallCommand($container)); - $application->add(new PluginUninstallCommand($container)); - $application->run(); - + $container['cli']->run(); } catch (Exception $e) { echo $e->getMessage().PHP_EOL; exit(255); -- cgit v1.2.3