diff options
author | Frederic Guillot <fred@kanboard.net> | 2015-10-17 09:51:15 -0400 |
---|---|---|
committer | Frederic Guillot <fred@kanboard.net> | 2015-10-17 09:51:15 -0400 |
commit | 73a5b9bc75d40a30e7c9674b292957657ac01f63 (patch) | |
tree | ff5bb8a90452a2ff1351c192575e5d241a8b4417 /app | |
parent | 98b203fe691ec1ea9d6d19e916827185b575b05a (diff) |
Make user notifications pluggable
Diffstat (limited to 'app')
18 files changed, 258 insertions, 120 deletions
diff --git a/app/Controller/App.php b/app/Controller/App.php index 50ac1d32..3f3f0176 100644 --- a/app/Controller/App.php +++ b/app/Controller/App.php @@ -198,7 +198,7 @@ class App extends Base $this->response->html($this->layout('app/notifications', array( 'title' => t('My notifications'), - 'notifications' => $this->webNotification->getAll($user['id']), + 'notifications' => $this->userUnreadNotification->getAll($user['id']), 'user' => $user, ))); } diff --git a/app/Controller/User.php b/app/Controller/User.php index 15e9a0ee..7444ed82 100644 --- a/app/Controller/User.php +++ b/app/Controller/User.php @@ -96,7 +96,7 @@ class User extends Base $this->projectPermission->addMember($project_id, $user_id); if (! empty($values['notifications_enabled'])) { - $this->notificationType->saveUserSelectedTypes($user_id, array(NotificationType::TYPE_EMAIL)); + $this->userNotificationType->saveSelectedTypes($user_id, array(NotificationType::TYPE_EMAIL)); } $this->session->flash(t('User created successfully.')); @@ -201,16 +201,16 @@ class User extends Base if ($this->request->isPost()) { $values = $this->request->getValues(); - $this->notification->saveSettings($user['id'], $values); + $this->userNotification->saveSettings($user['id'], $values); $this->session->flash(t('User updated successfully.')); $this->response->redirect($this->helper->url->to('user', 'notifications', array('user_id' => $user['id']))); } $this->response->html($this->layout('user/notifications', array( 'projects' => $this->projectPermission->getMemberProjects($user['id']), - 'notifications' => $this->notification->readSettings($user['id']), - 'types' => $this->notificationType->getTypes(), - 'filters' => $this->notificationFilter->getFilters(), + 'notifications' => $this->userNotification->readSettings($user['id']), + 'types' => $this->userNotificationType->getTypes(), + 'filters' => $this->userNotificationFilter->getFilters(), 'user' => $user, ))); } diff --git a/app/Controller/Webnotification.php b/app/Controller/WebNotification.php index 52e3f266..dca5cb46 100644 --- a/app/Controller/Webnotification.php +++ b/app/Controller/WebNotification.php @@ -8,7 +8,7 @@ namespace Kanboard\Controller; * @package controller * @author Frederic Guillot */ -class Webnotification extends Base +class WebNotification extends Base { /** * Mark all notifications as read @@ -17,9 +17,9 @@ class Webnotification extends Base */ public function flush() { - $user_id = $this->userSession->getId(); + $user_id = $this->getUserId(); - $this->webNotification->markAllAsRead($user_id); + $this->userUnreadNotification->markAllAsRead($user_id); $this->response->redirect($this->helper->url->to('app', 'notifications', array('user_id' => $user_id))); } @@ -30,10 +30,21 @@ class Webnotification extends Base */ public function remove() { - $user_id = $this->userSession->getId(); + $user_id = $this->getUserId(); $notification_id = $this->request->getIntegerParam('notification_id'); - $this->webNotification->markAsRead($user_id, $notification_id); + $this->userUnreadNotification->markAsRead($user_id, $notification_id); $this->response->redirect($this->helper->url->to('app', 'notifications', array('user_id' => $user_id))); } + + private function getUserId() + { + $user_id = $this->request->getIntegerParam('user_id'); + + if (! $this->userSession->isAdmin() && $user_id != $this->userSession->getId()) { + $user_id = $this->userSession->getId(); + } + + return $user_id; + } } diff --git a/app/Core/Base.php b/app/Core/Base.php index 76723e8f..c542cd47 100644 --- a/app/Core/Base.php +++ b/app/Core/Base.php @@ -49,11 +49,11 @@ use Pimple\Container; * @property \Kanboard\Model\File $file * @property \Kanboard\Model\LastLogin $lastLogin * @property \Kanboard\Model\Link $link - * @property \Kanboard\Model\Notification $notification - * @property \Kanboard\Model\NotificationType $notificationType - * @property \Kanboard\Model\NotificationFilter $notificationFilter + * @property \Kanboard\Model\UserNotification $userNotification + * @property \Kanboard\Model\UserNotificationType $userNotificationType + * @property \Kanboard\Model\UserNotificationFilter $userNotificationFilter + * @property \Kanboard\Model\UserUnreadNotification $userUnreadNotification * @property \Kanboard\Model\OverdueNotification $overdueNotification - * @property \Kanboard\Model\WebNotification $webNotification * @property \Kanboard\Model\Project $project * @property \Kanboard\Model\ProjectActivity $projectActivity * @property \Kanboard\Model\ProjectAnalytic $projectAnalytic diff --git a/app/Core/NotificationInterface.php b/app/Core/NotificationInterface.php deleted file mode 100644 index b6cd1781..00000000 --- a/app/Core/NotificationInterface.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php - -namespace Kanboard\Core; - -/** - * Notification Interface - * - * @package core - * @author Frederic Guillot - */ -interface NotificationInterface -{ - /** - * Send notification to someone - * - * @access public - * @param array $user - * @param string $event_name - * @param array $event_data - */ - public function send(array $user, $event_name, array $event_data); -} diff --git a/app/Helper/User.php b/app/Helper/User.php index dc394738..9cd39bd9 100644 --- a/app/Helper/User.php +++ b/app/Helper/User.php @@ -18,7 +18,7 @@ class User extends \Kanboard\Core\Base */ public function hasNotifications() { - return $this->webNotification->hasNotifications($this->userSession->getId()); + return $this->userUnreadNotification->hasNotifications($this->userSession->getId()); } /** diff --git a/app/Model/NotificationType.php b/app/Model/NotificationType.php index b0514b19..9ec250ab 100644 --- a/app/Model/NotificationType.php +++ b/app/Model/NotificationType.php @@ -2,72 +2,82 @@ namespace Kanboard\Model; +use Pimple\Container; + /** - * Notification Type model + * Notification Type * * @package model * @author Frederic Guillot */ -class NotificationType extends Base +abstract class NotificationType extends Base { /** - * SQL table name + * Mail transport instances * - * @var string + * @access private + * @var \Pimple\Container */ - const TABLE = 'user_has_notification_types'; + private $classes; /** - * Types + * Mail transport instances * - * @var string + * @access private + * @var array */ - const TYPE_WEB = 'web'; - const TYPE_EMAIL = 'email'; + private $labels = array(); /** - * Get all notification types + * Constructor * * @access public - * @return array + * @param \Pimple\Container $container */ - public function getTypes() + public function __construct(Container $container) { - return array( - self::TYPE_EMAIL => t('Email'), - self::TYPE_WEB => t('Web'), - ); + parent::__construct($container); + $this->classes = new Container; } /** - * Get selected notification types for a given user + * Add a new notification type * * @access public - * @param integer $user_id - * @return array + * @param string $type + * @param string $label + * @param string $class */ - public function getUserSelectedTypes($user_id) + public function setType($type, $label, $class) { - return $this->db->table(self::TABLE)->eq('user_id', $user_id)->asc('notification_type')->findAllByColumn('notification_type'); + $container = $this->container; + $this->labels[$type] = $label; + + $this->classes[$type] = function() use ($class, $container) { + return new $class($container); + }; } /** - * Save notification types for a given user + * Get mail notification type instance * * @access public - * @param integer $user_id - * @param string[] $types - * @return boolean + * @param string $type + * @return NotificationInterface */ - public function saveUserSelectedTypes($user_id, array $types) + public function getType($type) { - $results = array(); - $this->db->table(self::TABLE)->eq('user_id', $user_id)->remove(); - - foreach ($types as $type) { - $results[] = $this->db->table(self::TABLE)->insert(array('user_id' => $user_id, 'notification_type' => $type)); - } + return $this->classes[$type]; + } - return ! in_array(false, $results); + /** + * Get all notification types with labels + * + * @access public + * @return array + */ + public function getTypes() + { + return $this->labels; } } diff --git a/app/Model/OverdueNotification.php b/app/Model/OverdueNotification.php index f44c8dd7..d8c2fef4 100644 --- a/app/Model/OverdueNotification.php +++ b/app/Model/OverdueNotification.php @@ -22,7 +22,7 @@ class OverdueNotification extends Base 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->notification->getUsersWithNotificationEnabled($project_id); + $users = $this->userNotification->getUsersWithNotificationEnabled($project_id); foreach ($users as $user) { $this->sendUserOverdueTaskNotifications($user, $project_tasks); @@ -44,13 +44,13 @@ class OverdueNotification extends Base $user_tasks = array(); foreach ($tasks as $task) { - if ($this->notificationFilter->shouldReceiveNotification($user, array('task' => $task))) { + if ($this->userNotificationFilter->shouldReceiveNotification($user, array('task' => $task))) { $user_tasks[] = $task; } } if (! empty($user_tasks)) { - $this->notification->sendUserNotification( + $this->userNotification->sendUserNotification( $user, Task::EVENT_OVERDUE, array('tasks' => $user_tasks, 'project_name' => $tasks[0]['project_name']) diff --git a/app/Model/Notification.php b/app/Model/UserNotification.php index 692f37a7..b4ee77a9 100644 --- a/app/Model/Notification.php +++ b/app/Model/UserNotification.php @@ -5,12 +5,12 @@ namespace Kanboard\Model; use Kanboard\Core\Translator; /** - * Notification model + * User Notification * * @package model * @author Frederic Guillot */ -class Notification extends Base +class UserNotification extends Base { /** * Send notifications to people @@ -22,12 +22,11 @@ class Notification extends Base public function sendNotifications($event_name, array $event_data) { $logged_user_id = $this->userSession->isLogged() ? $this->userSession->getId() : 0; - $users = $this->notification->getUsersWithNotificationEnabled($event_data['task']['project_id'], $logged_user_id); + $users = $this->getUsersWithNotificationEnabled($event_data['task']['project_id'], $logged_user_id); if (! empty($users)) { - foreach ($users as $user) { - if ($this->notificationFilter->shouldReceiveNotification($user, $event_data)) { + if ($this->userNotificationFilter->shouldReceiveNotification($user, $event_data)) { $this->sendUserNotification($user, $event_name, $event_data); } } @@ -57,9 +56,8 @@ class Notification extends Base Translator::load($this->config->get('application_language', 'en_US')); } - foreach ($this->notificationType->getUserSelectedTypes($user['id']) as $type) { - $className = strtolower($type).'Notification'; - $this->$className->send($user, $event_name, $event_data); + foreach ($this->userNotificationType->getSelectedTypes($user['id']) as $type) { + $this->userNotificationType->getType($type)->notifyUser($user, $event_name, $event_data); } } @@ -118,13 +116,13 @@ class Notification extends Base if (isset($values['notifications_enabled']) && $values['notifications_enabled'] == 1) { $this->enableNotification($user_id); - $filter = empty($values['notifications_filter']) ? NotificationFilter::FILTER_BOTH : $values['notifications_filter']; + $filter = empty($values['notifications_filter']) ? UserNotificationFilter::FILTER_BOTH : $values['notifications_filter']; $projects = empty($values['notification_projects']) ? array() : array_keys($values['notification_projects']); $types = empty($values['notification_types']) ? array() : array_keys($values['notification_types']); - $this->notificationFilter->saveUserFilter($user_id, $filter); - $this->notificationFilter->saveUserSelectedProjects($user_id, $projects); - $this->notificationType->saveUserSelectedTypes($user_id, $types); + $this->userNotificationFilter->saveFilter($user_id, $filter); + $this->userNotificationFilter->saveSelectedProjects($user_id, $projects); + $this->userNotificationType->saveSelectedTypes($user_id, $types); } else { $this->disableNotification($user_id); @@ -143,8 +141,8 @@ class Notification extends Base public function readSettings($user_id) { $values = $this->db->table(User::TABLE)->eq('id', $user_id)->columns('notifications_enabled', 'notifications_filter')->findOne(); - $values['notification_types'] = $this->notificationType->getUserSelectedTypes($user_id); - $values['notification_projects'] = $this->notificationFilter->getUserSelectedProjects($user_id); + $values['notification_types'] = $this->userNotificationType->getSelectedTypes($user_id); + $values['notification_projects'] = $this->userNotificationFilter->getSelectedProjects($user_id); return $values; } diff --git a/app/Model/NotificationFilter.php b/app/Model/UserNotificationFilter.php index f1ad367b..d4afd278 100644 --- a/app/Model/NotificationFilter.php +++ b/app/Model/UserNotificationFilter.php @@ -3,12 +3,12 @@ namespace Kanboard\Model; /** - * Notification Filter model + * User Notification Filter * * @package model * @author Frederic Guillot */ -class NotificationFilter extends Base +class UserNotificationFilter extends Base { /** * SQL table name @@ -50,7 +50,7 @@ class NotificationFilter extends Base * @param integer $user_id * @return integer */ - public function getUserSelectedFilter($user_id) + public function getSelectedFilter($user_id) { return $this->db->table(User::TABLE)->eq('id', $user_id)->findOneColumn('notifications_filter'); } @@ -62,7 +62,7 @@ class NotificationFilter extends Base * @param integer $user_id * @param string $filter */ - public function saveUserFilter($user_id, $filter) + public function saveFilter($user_id, $filter) { $this->db->table(User::TABLE)->eq('id', $user_id)->update(array( 'notifications_filter' => $filter, @@ -76,7 +76,7 @@ class NotificationFilter extends Base * @param integer $user_id * @return array */ - public function getUserSelectedProjects($user_id) + public function getSelectedProjects($user_id) { return $this->db->table(self::PROJECT_TABLE)->eq('user_id', $user_id)->findAllByColumn('project_id'); } @@ -88,7 +88,7 @@ class NotificationFilter extends Base * @param integer $user_id * @param integer[] $project_ids */ - public function saveUserSelectedProjects($user_id, array $project_ids) + public function saveSelectedProjects($user_id, array $project_ids) { $this->db->table(self::PROJECT_TABLE)->eq('user_id', $user_id)->remove(); @@ -188,7 +188,7 @@ class NotificationFilter extends Base */ public function filterProject(array $user, array $event_data) { - $projects = $this->getUserSelectedProjects($user['id']); + $projects = $this->getSelectedProjects($user['id']); if (! empty($projects)) { return in_array($event_data['task']['project_id'], $projects); diff --git a/app/Model/UserNotificationType.php b/app/Model/UserNotificationType.php new file mode 100644 index 00000000..d2613440 --- /dev/null +++ b/app/Model/UserNotificationType.php @@ -0,0 +1,51 @@ +<?php + +namespace Kanboard\Model; + +/** + * User Notification Type + * + * @package model + * @author Frederic Guillot + */ +class UserNotificationType extends NotificationType +{ + /** + * SQL table name + * + * @var string + */ + const TABLE = 'user_has_notification_types'; + + /** + * Get selected notification types for a given user + * + * @access public + * @param integer $user_id + * @return array + */ + public function getSelectedTypes($user_id) + { + return $this->db->table(self::TABLE)->eq('user_id', $user_id)->asc('notification_type')->findAllByColumn('notification_type'); + } + + /** + * Save notification types for a given user + * + * @access public + * @param integer $user_id + * @param string[] $types + * @return boolean + */ + public function saveSelectedTypes($user_id, array $types) + { + $results = array(); + $this->db->table(self::TABLE)->eq('user_id', $user_id)->remove(); + + foreach ($types as $type) { + $results[] = $this->db->table(self::TABLE)->insert(array('user_id' => $user_id, 'notification_type' => $type)); + } + + return ! in_array(false, $results); + } +} diff --git a/app/Model/WebNotification.php b/app/Model/UserUnreadNotification.php index 02bcc956..98a337a2 100644 --- a/app/Model/WebNotification.php +++ b/app/Model/UserUnreadNotification.php @@ -2,15 +2,13 @@ namespace Kanboard\Model; -use Kanboard\Core\NotificationInterface; - /** - * Web Notification model + * User Unread Notification * * @package model * @author Frederic Guillot */ -class WebNotification extends Base implements NotificationInterface +class UserUnreadNotification extends Base { /** * SQL table name @@ -23,14 +21,14 @@ class WebNotification extends Base implements NotificationInterface * Add unread notification to someone * * @access public - * @param array $user + * @param integer $user_id * @param string $event_name * @param array $event_data */ - public function send(array $user, $event_name, array $event_data) + public function create($user_id, $event_name, array $event_data) { $this->db->table(self::TABLE)->insert(array( - 'user_id' => $user['id'], + 'user_id' => $user_id, 'date_creation' => time(), 'event_name' => $event_name, 'event_data' => json_encode($event_data), diff --git a/app/Model/EmailNotification.php b/app/Notification/Mail.php index 312828e4..69b8888d 100644 --- a/app/Model/EmailNotification.php +++ b/app/Notification/Mail.php @@ -1,26 +1,30 @@ <?php -namespace Kanboard\Model; +namespace Kanboard\Notification; -use Kanboard\Core\NotificationInterface; +use Kanboard\Core\Base; +use Kanboard\Model\Task; +use Kanboard\Model\File; +use Kanboard\Model\Comment; +use Kanboard\Model\Subtask; /** - * Email Notification model + * Email Notification * - * @package model + * @package notification * @author Frederic Guillot */ -class EmailNotification extends Base implements NotificationInterface +class Mail extends Base implements NotificationInterface { /** - * Send email notification to someone + * Send notification to a user * * @access public * @param array $user * @param string $event_name * @param array $event_data */ - public function send(array $user, $event_name, array $event_data) + public function notifyUser(array $user, $event_name, array $event_data) { if (! empty($user['email'])) { $this->emailClient->send( @@ -33,6 +37,19 @@ class EmailNotification extends Base implements NotificationInterface } /** + * Send notification to a project + * + * @access public + * @param array $project + * @param string $event_name + * @param array $event_data + */ + public function notifyProject(array $project, $event_name, array $event_data) + { + + } + + /** * Get the mail content for a given template name * * @access public diff --git a/app/Notification/NotificationInterface.php b/app/Notification/NotificationInterface.php new file mode 100644 index 00000000..8431a77c --- /dev/null +++ b/app/Notification/NotificationInterface.php @@ -0,0 +1,32 @@ +<?php + +namespace Kanboard\Notification; + +/** + * Notification Interface + * + * @package core + * @author Frederic Guillot + */ +interface NotificationInterface +{ + /** + * Send notification to a user + * + * @access public + * @param array $user + * @param string $event_name + * @param array $event_data + */ + public function notifyUser(array $user, $event_name, array $event_data); + + /** + * Send notification to a project + * + * @access public + * @param array $project + * @param string $event_name + * @param array $event_data + */ + public function notifyProject(array $project, $event_name, array $event_data); +} diff --git a/app/Notification/Web.php b/app/Notification/Web.php new file mode 100644 index 00000000..989ae06e --- /dev/null +++ b/app/Notification/Web.php @@ -0,0 +1,39 @@ +<?php + +namespace Kanboard\Notification; + +use Kanboard\Core\Base; + +/** + * Web Notification + * + * @package notification + * @author Frederic Guillot + */ +class Web extends Base implements NotificationInterface +{ + /** + * Send notification to a user + * + * @access public + * @param array $user + * @param string $event_name + * @param array $event_data + */ + public function notifyUser(array $user, $event_name, array $event_data) + { + $this->userUnreadNotification->create($user['id'], $event_name, $event_data); + } + + /** + * Send notification to a project + * + * @access public + * @param array $project + * @param string $event_name + * @param array $event_data + */ + public function notifyProject(array $project, $event_name, array $event_data) + { + } +} diff --git a/app/ServiceProvider/ClassProvider.php b/app/ServiceProvider/ClassProvider.php index 9df2dede..322c1a9b 100644 --- a/app/ServiceProvider/ClassProvider.php +++ b/app/ServiceProvider/ClassProvider.php @@ -8,9 +8,7 @@ use Kanboard\Core\ObjectStorage\FileStorage; use Kanboard\Core\Paginator; use Kanboard\Core\OAuth2; use Kanboard\Core\Tool; -use Kanboard\Model\Config; -use Kanboard\Model\Project; -use Kanboard\Model\Webhook; +use Kanboard\Model\UserNotificationType; use Pimple\Container; use Pimple\ServiceProviderInterface; use League\HTMLToMarkdown\HtmlConverter; @@ -32,12 +30,7 @@ class ClassProvider implements ServiceProviderInterface 'File', 'LastLogin', 'Link', - 'Notification', - 'NotificationType', - 'NotificationFilter', 'OverdueNotification', - 'WebNotification', - 'EmailNotification', 'Project', 'ProjectActivity', 'ProjectAnalytic', @@ -68,6 +61,10 @@ class ClassProvider implements ServiceProviderInterface 'User', 'UserImport', 'UserSession', + 'UserNotification', + 'UserNotificationType', + 'UserNotificationFilter', + 'UserUnreadNotification', 'Webhook', ), 'Formatter' => array( @@ -131,6 +128,13 @@ class ClassProvider implements ServiceProviderInterface return $mailer; }; + $container['userNotificationType'] = function($container) { + $type = new UserNotificationType($container); + $type->setType('email', t('Email'), '\Kanboard\Notification\Mail'); + $type->setType('web', t('Web'), '\Kanboard\Notification\Web'); + return $type; + }; + $container['pluginLoader'] = new Loader($container); $container['cspRules'] = array('style-src' => "'self' 'unsafe-inline'", 'img-src' => '* data:'); diff --git a/app/Subscriber/NotificationSubscriber.php b/app/Subscriber/NotificationSubscriber.php index 610fbadb..07ce00a1 100644 --- a/app/Subscriber/NotificationSubscriber.php +++ b/app/Subscriber/NotificationSubscriber.php @@ -32,7 +32,7 @@ class NotificationSubscriber extends \Kanboard\Core\Base implements EventSubscri public function execute(GenericEvent $event, $event_name) { - $this->notification->sendNotifications($event_name, $this->getEventData($event)); + $this->userNotification->sendNotifications($event_name, $this->getEventData($event)); } public function getEventData(GenericEvent $event) diff --git a/app/Template/app/notifications.php b/app/Template/app/notifications.php index 4f7dd353..511f377b 100644 --- a/app/Template/app/notifications.php +++ b/app/Template/app/notifications.php @@ -8,7 +8,7 @@ <ul> <li> <i class="fa fa-check-square-o fa-fw"></i> - <?= $this->url->link(t('Mark all as read'), 'webnotification', 'flush', array('user_id' => $user['id'])) ?> + <?= $this->url->link(t('Mark all as read'), 'webNotification', 'flush', array('user_id' => $user['id'])) ?> </li> </ul> </div> @@ -53,7 +53,7 @@ </td> <td> <i class="fa fa-check fa-fw"></i> - <?= $this->url->link(t('Mark as read'), 'webnotification', 'remove', array('user_id' => $user['id'], 'notification_id' => $notification['id'])) ?> + <?= $this->url->link(t('Mark as read'), 'webNotification', 'remove', array('user_id' => $user['id'], 'notification_id' => $notification['id'])) ?> </td> </tr> <?php endforeach ?> |