diff options
-rw-r--r-- | app/Console/Base.php | 53 | ||||
-rw-r--r-- | app/Console/OverdueNotification.php | 69 | ||||
-rw-r--r-- | app/Console/TaskExport.php | 35 | ||||
-rw-r--r-- | app/Core/Cli.php | 75 | ||||
-rw-r--r-- | composer.json | 3 | ||||
-rw-r--r-- | composer.lock | 62 | ||||
-rwxr-xr-x | kanboard | 73 |
7 files changed, 224 insertions, 146 deletions
diff --git a/app/Console/Base.php b/app/Console/Base.php new file mode 100644 index 00000000..bf93aec4 --- /dev/null +++ b/app/Console/Base.php @@ -0,0 +1,53 @@ +<?php + +namespace Console; + +use Core\Tool; +use Pimple\Container; +use Symfony\Component\Console\Command\Command; + +/** + * Base command class + * + * @package console + * @author Frederic Guillot + * + * @property \Model\Notification $notification + * @property \Model\Task $task + * @property \Model\TaskExport $taskExport + * @property \Model\TaskFinder $taskFinder + */ +abstract class Base extends Command +{ + /** + * Container instance + * + * @access protected + * @var \Pimple\Container + */ + protected $container; + + /** + * Constructor + * + * @access public + * @param \Pimple\Container $container + */ + public function __construct(Container $container) + { + parent::__construct(); + $this->container = $container; + } + + /** + * Load automatically models + * + * @access public + * @param string $name Model name + * @return mixed + */ + public function __get($name) + { + return Tool::loadModel($this->container, $name); + } +} diff --git a/app/Console/OverdueNotification.php b/app/Console/OverdueNotification.php new file mode 100644 index 00000000..0987bf2a --- /dev/null +++ b/app/Console/OverdueNotification.php @@ -0,0 +1,69 @@ +<?php + +namespace Console; + +use Symfony\Component\Console\Helper\Table; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +class OverdueNotification extends Base +{ + protected function configure() + { + $this + ->setName('notification:overdue-tasks') + ->setDescription('Send notifications for overdue tasks') + ->addOption('show', null, InputOption::VALUE_NONE, 'Show sent overdue tasks'); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $projects = array(); + $tasks = $this->taskFinder->getOverdueTasks(); + + // Group tasks by project + foreach ($tasks as $task) { + $projects[$task['project_id']][] = $task; + } + + // Send notifications for each project + foreach ($projects as $project_id => $project_tasks) { + + $users = $this->notification->getUsersList($project_id); + + $this->notification->sendEmails( + 'task_due', + $users, + array('tasks' => $project_tasks, 'project' => $project_tasks[0]['project_name']) + ); + } + + if ($input->getOption('show')) { + $this->showTable($output, $tasks); + } + } + + public function showTable(OutputInterface $output, array $tasks) + { + $rows = array(); + + foreach ($tasks as $task) { + $rows[] = array( + $task['id'], + $task['title'], + date('Y-m-d', $task['date_due']), + $task['project_id'], + $task['project_name'], + $task['assignee_name'] ?: $task['assignee_username'], + ); + } + + $table = new Table($output); + $table + ->setHeaders(array('Id', 'Title', 'Due date', 'Project Id', 'Project name', 'Assignee')) + ->setRows($rows) + ->render(); + } +} diff --git a/app/Console/TaskExport.php b/app/Console/TaskExport.php new file mode 100644 index 00000000..b9f151fb --- /dev/null +++ b/app/Console/TaskExport.php @@ -0,0 +1,35 @@ +<?php + +namespace Console; + +use Core\Tool; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +class TaskExport extends Base +{ + protected function configure() + { + $this + ->setName('export:tasks') + ->setDescription('Tasks export (CSV)') + ->addArgument('project_id', InputArgument::REQUIRED, 'Project id') + ->addArgument('start_date', InputArgument::REQUIRED, 'Start date (YYYY-MM-DD)') + ->addArgument('end_date', InputArgument::REQUIRED, 'End date (YYYY-MM-DD)'); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $data = $this->taskExport->export( + $input->getArgument('project_id'), + $input->getArgument('start_date'), + $input->getArgument('end_date') + ); + + if (is_array($data)) { + Tool::csv($data); + } + } +} diff --git a/app/Core/Cli.php b/app/Core/Cli.php deleted file mode 100644 index 13533b9a..00000000 --- a/app/Core/Cli.php +++ /dev/null @@ -1,75 +0,0 @@ -<?php - -namespace Core; - -use Closure; - -/** - * CLI class - * - * @package core - * @author Frederic Guillot - */ -class Cli -{ - /** - * Default command name - * - * @access public - * @var string - */ - public $default_command = 'help'; - - /** - * List of registered commands - * - * @access private - * @var array - */ - private $commands = array(); - - /** - * - * - * @access public - * @param string $command Command name - * @param Closure $callback Command callback - */ - public function register($command, Closure $callback) - { - $this->commands[$command] = $callback; - } - - /** - * Execute a command - * - * @access public - * @param string $command Command name - */ - public function call($command) - { - if (isset($this->commands[$command])) { - $this->commands[$command](); - exit; - } - } - - /** - * Determine which command to execute - * - * @access public - */ - public function execute() - { - if (php_sapi_name() !== 'cli') { - die('This script work only from the command line.'); - } - - if ($GLOBALS['argc'] === 1) { - $this->call($this->default_command); - } - - $this->call($GLOBALS['argv'][1]); - $this->call($this->default_command); - } -} diff --git a/composer.json b/composer.json index 6c6f10fa..e62150ff 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,8 @@ "erusev/parsedown": "1.1.1", "lusitanian/oauth": "0.3.5", "pimple/pimple": "~3.0", - "monolog/monolog": "1.11.0" + "monolog/monolog": "1.11.0", + "symfony/console": "@stable" }, "autoload": { "psr-0": {"": "app/"}, diff --git a/composer.lock b/composer.lock index e06de45b..04108203 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "2057eedc0ff404a75ab43f197dd41bb9", + "hash": "0e4e7b65c1a5eb4ab8bd2fc051c9dc3d", "packages": [ { "name": "erusev/parsedown", @@ -464,6 +464,63 @@ "mailer" ], "time": "2014-10-04 05:53:18" + }, + { + "name": "symfony/console", + "version": "v2.6.0", + "target-dir": "Symfony/Component/Console", + "source": { + "type": "git", + "url": "https://github.com/symfony/Console.git", + "reference": "d3bac228fd7a2aac9193e241b239880b3ba39a10" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Console/zipball/d3bac228fd7a2aac9193e241b239880b3ba39a10", + "reference": "d3bac228fd7a2aac9193e241b239880b3ba39a10", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1", + "symfony/process": "~2.1" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Console\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Console Component", + "homepage": "http://symfony.com", + "time": "2014-11-20 13:24:23" } ], "packages-dev": [], @@ -473,7 +530,8 @@ "fguillot/simple-validator": 20, "swiftmailer/swiftmailer": 0, "fguillot/json-rpc": 20, - "fguillot/picodb": 20 + "fguillot/picodb": 20, + "symfony/console": 0 }, "prefer-stable": false, "platform": [], @@ -3,72 +3,9 @@ require __DIR__.'/app/common.php'; -use Core\Cli; -use Core\Tool; -use Model\Config; -use Model\Task; -use Model\TaskFinder; -use Model\TaskExport; -use Model\Notification; +use Symfony\Component\Console\Application; -$config = new Config($container); -$config->setupTranslations(); -$config->setupTimezone(); - -// Setup CLI -$cli = new Cli; - -// Usage -$cli->register('help', function() { - echo 'Kanboard command line interface'.PHP_EOL.'==============================='.PHP_EOL.PHP_EOL; - echo '- Task export to stdout (CSV format): '.$GLOBALS['argv'][0].' export-csv <project_id> <start_date> <end_date>'.PHP_EOL; - echo '- Send notifications for due tasks: '.$GLOBALS['argv'][0].' send-notifications-due-tasks'.PHP_EOL; -}); - -// CSV Export -$cli->register('export-csv', function() use ($cli, $container) { - - if ($GLOBALS['argc'] !== 5) { - $cli->call($cli->default_command); - } - - $project_id = $GLOBALS['argv'][2]; - $start_date = $GLOBALS['argv'][3]; - $end_date = $GLOBALS['argv'][4]; - - $taskExport = new TaskExport($container); - $data = $taskExport->export($project_id, $start_date, $end_date); - - if (is_array($data)) { - Tool::csv($data); - } -}); - -// Send notification for tasks due -$cli->register('send-notifications-due-tasks', function() use ($cli, $container) { - - $notificationModel = new Notification($container); - $taskModel = new TaskFinder($container); - $tasks = $taskModel->getOverdueTasks(); - - // Group tasks by project - $projects = array(); - - foreach ($tasks as $task) { - $projects[$task['project_id']][] = $task; - } - - // Send notifications for each project - foreach ($projects as $project_id => $project_tasks) { - - $users = $notificationModel->getUsersList($project_id); - - $notificationModel->sendEmails( - 'notification_task_due', - $users, - array('tasks' => $project_tasks, 'project' => $project_tasks[0]['project_name']) - ); - } -}); - -$cli->execute(); +$application = new Application('Kanboard', APP_VERSION); +$application->add(new Console\OverdueNotification($container)); +$application->add(new Console\TaskExport($container)); +$application->run(); |