diff --git a/app/Console/PluginInstallCommand.php b/app/Console/PluginInstallCommand.php
index 1c6e14b3f..a82f00697 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 c645e03f4..487221306 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 839124b12..6c66e9170 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 725bd7c04..7b4462e23 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 000000000..55c2712bd
--- /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 e73d3a64d..72be36037 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 4b6e85c00..37540f296 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 0121f8dd1..3d8140af2 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);