From 472f94efee77d8f47ece4ead7d36ee02e5df3e56 Mon Sep 17 00:00:00 2001 From: Frederic Guillot Date: Sat, 17 Oct 2015 12:30:05 -0400 Subject: Move webhook to project notification type --- app/Core/Csv.php | 2 +- app/Model/NotificationType.php | 36 ++++++++++++++-- app/Model/OverdueNotification.php | 2 - app/Model/ProjectNotification.php | 29 +++++++++++++ app/Model/ProjectNotificationType.php | 57 +++++++++++++++++++++++++ app/Model/Webhook.php | 34 --------------- app/Notification/Webhook.php | 55 ++++++++++++++++++++++++ app/Schema/Mysql.php | 16 ++++++- app/Schema/Postgres.php | 15 ++++++- app/Schema/Sqlite.php | 15 ++++++- app/ServiceProvider/ClassProvider.php | 15 +++++-- app/ServiceProvider/EventDispatcherProvider.php | 2 - app/Subscriber/NotificationSubscriber.php | 12 +++++- app/Subscriber/ProjectActivitySubscriber.php | 4 +- app/Subscriber/WebhookSubscriber.php | 45 ------------------- 15 files changed, 240 insertions(+), 99 deletions(-) create mode 100644 app/Model/ProjectNotification.php create mode 100644 app/Model/ProjectNotificationType.php delete mode 100644 app/Model/Webhook.php create mode 100644 app/Notification/Webhook.php delete mode 100644 app/Subscriber/WebhookSubscriber.php (limited to 'app') diff --git a/app/Core/Csv.php b/app/Core/Csv.php index 7c6a4620..bec400ed 100644 --- a/app/Core/Csv.php +++ b/app/Core/Csv.php @@ -131,7 +131,7 @@ class Csv * * @access public * @param string $filename - * @param \Closure $callback Example: function(array $row, $line_number) + * @param callable $callback Example: function(array $row, $line_number) * @return Csv */ public function read($filename, $callback) diff --git a/app/Model/NotificationType.php b/app/Model/NotificationType.php index 50d6080f..e05cc686 100644 --- a/app/Model/NotificationType.php +++ b/app/Model/NotificationType.php @@ -13,7 +13,7 @@ use Pimple\Container; abstract class NotificationType extends Base { /** - * Mail transport instances + * Container * * @access private * @var \Pimple\Container @@ -21,13 +21,21 @@ abstract class NotificationType extends Base private $classes; /** - * Mail transport instances + * Notification type labels * * @access private * @var array */ private $labels = array(); + /** + * Hidden notification types + * + * @access private + * @var array + */ + private $hiddens = array(); + /** * Constructor * @@ -47,15 +55,24 @@ abstract class NotificationType extends Base * @param string $type * @param string $label * @param string $class + * @param boolean $hidden + * @return NotificationType */ - public function setType($type, $label, $class) + public function setType($type, $label, $class, $hidden = false) { $container = $this->container; - $this->labels[$type] = $label; + + if ($hidden) { + $this->hiddens[] = $type; + } else { + $this->labels[$type] = $label; + } $this->classes[$type] = function () use ($class, $container) { return new $class($container); }; + + return $this; } /** @@ -80,4 +97,15 @@ abstract class NotificationType extends Base { return $this->labels; } + + /** + * Get all hidden notification types + * + * @access public + * @return array + */ + public function getHiddenTypes() + { + return $this->hiddens; + } } diff --git a/app/Model/OverdueNotification.php b/app/Model/OverdueNotification.php index d8c2fef4..84565548 100644 --- a/app/Model/OverdueNotification.php +++ b/app/Model/OverdueNotification.php @@ -20,8 +20,6 @@ class OverdueNotification extends Base $tasks = $this->taskFinder->getOverdueTasks(); foreach ($this->groupByColumn($tasks, 'project_id') as $project_id => $project_tasks) { - - // Get the list of users that should receive notifications for each projects $users = $this->userNotification->getUsersWithNotificationEnabled($project_id); foreach ($users as $user) { diff --git a/app/Model/ProjectNotification.php b/app/Model/ProjectNotification.php new file mode 100644 index 00000000..49fcc61d --- /dev/null +++ b/app/Model/ProjectNotification.php @@ -0,0 +1,29 @@ +project->getById($project_id); + + foreach ($this->projectNotificationType->getSelectedTypes($project_id) as $type) { + $this->projectNotificationType->getType($type)->notifyProject($project, $event_name, $event_data); + } + } +} diff --git a/app/Model/ProjectNotificationType.php b/app/Model/ProjectNotificationType.php new file mode 100644 index 00000000..d8568589 --- /dev/null +++ b/app/Model/ProjectNotificationType.php @@ -0,0 +1,57 @@ +db + ->table(self::TABLE) + ->eq('project_id', $project_id) + ->asc('notification_type') + ->findAllByColumn('notification_type'); + + return array_merge($this->getHiddenTypes(), $selectedTypes); + } + + /** + * Save notification types for a given project + * + * @access public + * @param integer $project_id + * @param string[] $types + * @return boolean + */ + public function saveSelectedTypes($project_id, array $types) + { + $results = array(); + $this->db->table(self::TABLE)->eq('project_id', $project_id)->remove(); + + foreach ($types as $type) { + $results[] = $this->db->table(self::TABLE)->insert(array('project_id' => $project_id, 'notification_type' => $type)); + } + + return ! in_array(false, $results); + } +} diff --git a/app/Model/Webhook.php b/app/Model/Webhook.php deleted file mode 100644 index 7c17e61e..00000000 --- a/app/Model/Webhook.php +++ /dev/null @@ -1,34 +0,0 @@ -config->get('webhook_url'); - $token = $this->config->get('webhook_token'); - - if (! empty($url)) { - if (strpos($url, '?') !== false) { - $url .= '&token='.$token; - } else { - $url .= '?token='.$token; - } - - return $this->httpClient->postJson($url, $values); - } - } -} diff --git a/app/Notification/Webhook.php b/app/Notification/Webhook.php new file mode 100644 index 00000000..feeee5d6 --- /dev/null +++ b/app/Notification/Webhook.php @@ -0,0 +1,55 @@ +config->get('webhook_url'); + $token = $this->config->get('webhook_token'); + + if (! empty($url)) { + if (strpos($url, '?') !== false) { + $url .= '&token='.$token; + } else { + $url .= '?token='.$token; + } + + $payload = array( + 'event_name' => $event_name, + 'event_data' => $event_data, + ); + + return $this->httpClient->postJson($url, $payload); + } + } +} diff --git a/app/Schema/Mysql.php b/app/Schema/Mysql.php index edf63919..852dca92 100644 --- a/app/Schema/Mysql.php +++ b/app/Schema/Mysql.php @@ -6,7 +6,21 @@ use PDO; use Kanboard\Core\Security; use Kanboard\Model\Link; -const VERSION = 91; +const VERSION = 92; + +function version_92($pdo) +{ + $pdo->exec(" + CREATE TABLE project_has_notification_types ( + id INT NOT NULL AUTO_INCREMENT, + project_id INT NOT NULL, + notification_type VARCHAR(50), + PRIMARY KEY(id), + FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE + UNIQUE(project_id, notification_type), + ) ENGINE=InnoDB CHARSET=utf8 + "); +} function version_91($pdo) { diff --git a/app/Schema/Postgres.php b/app/Schema/Postgres.php index 0cc31616..ac8b15ee 100644 --- a/app/Schema/Postgres.php +++ b/app/Schema/Postgres.php @@ -6,7 +6,20 @@ use PDO; use Kanboard\Core\Security; use Kanboard\Model\Link; -const VERSION = 71; +const VERSION = 72; + +function version_72($pdo) +{ + $pdo->exec(" + CREATE TABLE project_has_notification_types ( + id SERIAL PRIMARY KEY, + project_id INTEGER NOT NULL, + notification_type VARCHAR(50), + FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, + UNIQUE(project_id, notification_type) + ) + "); +} function version_71($pdo) { diff --git a/app/Schema/Sqlite.php b/app/Schema/Sqlite.php index 70b9d160..a1d5ee86 100644 --- a/app/Schema/Sqlite.php +++ b/app/Schema/Sqlite.php @@ -6,7 +6,20 @@ use Kanboard\Core\Security; use PDO; use Kanboard\Model\Link; -const VERSION = 86; +const VERSION = 87; + +function version_87($pdo) +{ + $pdo->exec(" + CREATE TABLE project_has_notification_types ( + id INTEGER PRIMARY KEY, + project_id INTEGER NOT NULL, + notification_type TEXT, + FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE, + UNIQUE(project_id, notification_type) + ) + "); +} function version_86($pdo) { diff --git a/app/ServiceProvider/ClassProvider.php b/app/ServiceProvider/ClassProvider.php index dde3cf10..182ecf26 100644 --- a/app/ServiceProvider/ClassProvider.php +++ b/app/ServiceProvider/ClassProvider.php @@ -2,6 +2,9 @@ namespace Kanboard\ServiceProvider; +use Pimple\Container; +use Pimple\ServiceProviderInterface; +use League\HTMLToMarkdown\HtmlConverter; use Kanboard\Core\Plugin\Loader; use Kanboard\Core\Mail\Client as EmailClient; use Kanboard\Core\ObjectStorage\FileStorage; @@ -9,9 +12,7 @@ use Kanboard\Core\Paginator; use Kanboard\Core\OAuth2; use Kanboard\Core\Tool; use Kanboard\Model\UserNotificationType; -use Pimple\Container; -use Pimple\ServiceProviderInterface; -use League\HTMLToMarkdown\HtmlConverter; +use Kanboard\Model\ProjectNotificationType; class ClassProvider implements ServiceProviderInterface { @@ -39,6 +40,7 @@ class ClassProvider implements ServiceProviderInterface 'ProjectDailyStats', 'ProjectIntegration', 'ProjectPermission', + 'ProjectNotification', 'Subtask', 'SubtaskExport', 'SubtaskTimeTracking', @@ -65,7 +67,6 @@ class ClassProvider implements ServiceProviderInterface 'UserNotificationType', 'UserNotificationFilter', 'UserUnreadNotification', - 'Webhook', ), 'Formatter' => array( 'TaskFilterGanttFormatter', @@ -135,6 +136,12 @@ class ClassProvider implements ServiceProviderInterface return $type; }; + $container['projectNotificationType'] = function ($container) { + $type = new ProjectNotificationType($container); + $type->setType('webhook', t('Webhook'), '\Kanboard\Notification\Webhook', true); + return $type; + }; + $container['pluginLoader'] = new Loader($container); $container['cspRules'] = array('style-src' => "'self' 'unsafe-inline'", 'img-src' => '* data:'); diff --git a/app/ServiceProvider/EventDispatcherProvider.php b/app/ServiceProvider/EventDispatcherProvider.php index 353d607b..3c9404d0 100644 --- a/app/ServiceProvider/EventDispatcherProvider.php +++ b/app/ServiceProvider/EventDispatcherProvider.php @@ -11,7 +11,6 @@ use Kanboard\Subscriber\NotificationSubscriber; use Kanboard\Subscriber\ProjectActivitySubscriber; use Kanboard\Subscriber\ProjectDailySummarySubscriber; use Kanboard\Subscriber\ProjectModificationDateSubscriber; -use Kanboard\Subscriber\WebhookSubscriber; use Kanboard\Subscriber\SubtaskTimeTrackingSubscriber; use Kanboard\Subscriber\TaskMovedDateSubscriber; use Kanboard\Subscriber\TransitionSubscriber; @@ -27,7 +26,6 @@ class EventDispatcherProvider implements ServiceProviderInterface $container['dispatcher']->addSubscriber(new ProjectActivitySubscriber($container)); $container['dispatcher']->addSubscriber(new ProjectDailySummarySubscriber($container)); $container['dispatcher']->addSubscriber(new ProjectModificationDateSubscriber($container)); - $container['dispatcher']->addSubscriber(new WebhookSubscriber($container)); $container['dispatcher']->addSubscriber(new NotificationSubscriber($container)); $container['dispatcher']->addSubscriber(new SubtaskTimeTrackingSubscriber($container)); $container['dispatcher']->addSubscriber(new TaskMovedDateSubscriber($container)); diff --git a/app/Subscriber/NotificationSubscriber.php b/app/Subscriber/NotificationSubscriber.php index 07ce00a1..394573e4 100644 --- a/app/Subscriber/NotificationSubscriber.php +++ b/app/Subscriber/NotificationSubscriber.php @@ -32,17 +32,25 @@ class NotificationSubscriber extends \Kanboard\Core\Base implements EventSubscri public function execute(GenericEvent $event, $event_name) { - $this->userNotification->sendNotifications($event_name, $this->getEventData($event)); + $event_data = $this->getEventData($event); + + if (! empty($event_data)) { + $this->userNotification->sendNotifications($event_name, $event_data); + $this->projectNotification->sendNotifications($event_data['task']['project_id'], $event_name, $event_data); + } } public function getEventData(GenericEvent $event) { $values = array(); + if (! empty($event['changes'])) { + $values['changes'] = $event['changes']; + } + switch (get_class($event)) { case 'Kanboard\Event\TaskEvent': $values['task'] = $this->taskFinder->getDetails($event['task_id']); - $values['changes'] = isset($event['changes']) ? $event['changes'] : array(); break; case 'Kanboard\Event\SubtaskEvent': $values['subtask'] = $this->subtask->getById($event['id'], true); diff --git a/app/Subscriber/ProjectActivitySubscriber.php b/app/Subscriber/ProjectActivitySubscriber.php index a66bbc5a..a49a00ed 100644 --- a/app/Subscriber/ProjectActivitySubscriber.php +++ b/app/Subscriber/ProjectActivitySubscriber.php @@ -61,10 +61,10 @@ class ProjectActivitySubscriber extends \Kanboard\Core\Base implements EventSubs $values['changes'] = isset($event['changes']) ? $event['changes'] : array(); switch (get_class($event)) { - case 'Event\SubtaskEvent': + case 'Kanboard\Event\SubtaskEvent': $values['subtask'] = $this->subtask->getById($event['id'], true); break; - case 'Event\CommentEvent': + case 'Kanboard\Event\CommentEvent': $values['comment'] = $this->comment->getById($event['id']); break; } diff --git a/app/Subscriber/WebhookSubscriber.php b/app/Subscriber/WebhookSubscriber.php deleted file mode 100644 index 8a2bd080..00000000 --- a/app/Subscriber/WebhookSubscriber.php +++ /dev/null @@ -1,45 +0,0 @@ - array('execute', 0), - Task::EVENT_UPDATE => array('execute', 0), - Task::EVENT_CLOSE => array('execute', 0), - Task::EVENT_OPEN => array('execute', 0), - Task::EVENT_MOVE_COLUMN => array('execute', 0), - Task::EVENT_MOVE_POSITION => array('execute', 0), - Task::EVENT_ASSIGNEE_CHANGE => array('execute', 0), - Task::EVENT_MOVE_PROJECT => array('execute', 0), - Task::EVENT_MOVE_SWIMLANE => array('execute', 0), - Comment::EVENT_CREATE => array('execute', 0), - Comment::EVENT_UPDATE => array('execute', 0), - File::EVENT_CREATE => array('execute', 0), - Subtask::EVENT_CREATE => array('execute', 0), - Subtask::EVENT_UPDATE => array('execute', 0), - ); - } - - public function execute(GenericEvent $event, $event_name) - { - $payload = array( - 'event_name' => $event_name, - 'event_data' => $event->getAll(), - ); - - $this->webhook->notify($payload); - } -} -- cgit v1.2.3