diff options
Diffstat (limited to 'app')
56 files changed, 614 insertions, 854 deletions
diff --git a/app/Action/Base.php b/app/Action/Base.php index a2b07e3f..70dd871d 100644 --- a/app/Action/Base.php +++ b/app/Action/Base.php @@ -2,9 +2,8 @@ namespace Action; +use Event\GenericEvent; use Pimple\Container; -use Core\Listener; -use Core\Tool; /** * Base class for automatic actions @@ -21,9 +20,17 @@ use Core\Tool; * @property \Model\TaskFinder $taskFinder * @property \Model\TaskStatus $taskStatus */ -abstract class Base implements Listener +abstract class Base { /** + * Flag for called listener + * + * @access private + * @var boolean + */ + private $called = false; + + /** * Project id * * @access private @@ -114,6 +121,7 @@ abstract class Base implements Listener $this->container = $container; $this->project_id = $project_id; $this->event_name = $event_name; + $this->called = false; } /** @@ -136,7 +144,7 @@ abstract class Base implements Listener */ public function __get($name) { - return Tool::loadModel($this->container, $name); + return $this->container[$name]; } /** @@ -225,12 +233,20 @@ abstract class Base implements Listener * Execute the action * * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed + * @param \Event\GenericEvent $event Event data dictionary + * @return bool True if the action was executed or false when not executed */ - public function execute(array $data) + public function execute(GenericEvent $event) { + // Avoid infinite loop, a listener instance can be called only one time + if ($this->called) { + return false; + } + + $data = $event->getAll(); + if ($this->isExecutable($data)) { + $this->called = true; return $this->doAction($data); } diff --git a/app/Action/TaskAssignCategoryColor.php b/app/Action/TaskAssignCategoryColor.php index 4134b584..ba319a1f 100644 --- a/app/Action/TaskAssignCategoryColor.php +++ b/app/Action/TaskAssignCategoryColor.php @@ -67,7 +67,7 @@ class TaskAssignCategoryColor extends Base 'category_id' => $this->getParam('category_id'), ); - return $this->taskModification->update($values, false); + return $this->taskModification->update($values); } /** diff --git a/app/Action/TaskAssignCategoryLabel.php b/app/Action/TaskAssignCategoryLabel.php index da41a313..19064526 100644 --- a/app/Action/TaskAssignCategoryLabel.php +++ b/app/Action/TaskAssignCategoryLabel.php @@ -67,7 +67,7 @@ class TaskAssignCategoryLabel extends Base 'category_id' => isset($data['category_id']) ? $data['category_id'] : $this->getParam('category_id'), ); - return $this->taskModification->update($values, false); + return $this->taskModification->update($values); } /** diff --git a/app/Action/TaskAssignColorCategory.php b/app/Action/TaskAssignColorCategory.php index 68bca5d0..a362c68f 100644 --- a/app/Action/TaskAssignColorCategory.php +++ b/app/Action/TaskAssignColorCategory.php @@ -67,7 +67,7 @@ class TaskAssignColorCategory extends Base 'color_id' => $this->getParam('color_id'), ); - return $this->taskModification->update($values, false); + return $this->taskModification->update($values); } /** diff --git a/app/Action/TaskAssignColorUser.php b/app/Action/TaskAssignColorUser.php index d419ab4d..6161514d 100644 --- a/app/Action/TaskAssignColorUser.php +++ b/app/Action/TaskAssignColorUser.php @@ -68,7 +68,7 @@ class TaskAssignColorUser extends Base 'color_id' => $this->getParam('color_id'), ); - return $this->taskModification->update($values, false); + return $this->taskModification->update($values); } /** diff --git a/app/Action/TaskAssignCurrentUser.php b/app/Action/TaskAssignCurrentUser.php index 9317bf83..b2015100 100644 --- a/app/Action/TaskAssignCurrentUser.php +++ b/app/Action/TaskAssignCurrentUser.php @@ -62,12 +62,16 @@ class TaskAssignCurrentUser extends Base */ public function doAction(array $data) { + if (! $this->acl->isLogged()) { + return false; + } + $values = array( 'id' => $data['task_id'], 'owner_id' => $this->acl->getUserId(), ); - return $this->taskModification->update($values, false); + return $this->taskModification->update($values); } /** diff --git a/app/Action/TaskAssignSpecificUser.php b/app/Action/TaskAssignSpecificUser.php index c3b979c2..4c96f7f0 100644 --- a/app/Action/TaskAssignSpecificUser.php +++ b/app/Action/TaskAssignSpecificUser.php @@ -68,7 +68,7 @@ class TaskAssignSpecificUser extends Base 'owner_id' => $this->getParam('user_id'), ); - return $this->taskModification->update($values, false); + return $this->taskModification->update($values); } /** diff --git a/app/Action/TaskAssignUser.php b/app/Action/TaskAssignUser.php index d01c4073..f24ff415 100644 --- a/app/Action/TaskAssignUser.php +++ b/app/Action/TaskAssignUser.php @@ -64,7 +64,7 @@ class TaskAssignUser extends Base 'owner_id' => $data['owner_id'], ); - return $this->taskModification->update($values, false); + return $this->taskModification->update($values); } /** diff --git a/app/Action/TaskCreation.php b/app/Action/TaskCreation.php index 0c791688..9b7a0b13 100644 --- a/app/Action/TaskCreation.php +++ b/app/Action/TaskCreation.php @@ -63,7 +63,7 @@ class TaskCreation extends Base 'project_id' => $data['project_id'], 'title' => $data['title'], 'reference' => $data['reference'], - 'description' => $data['description'], + 'description' => isset($data['description']) ? $data['description'] : '', )); } diff --git a/app/Auth/Base.php b/app/Auth/Base.php index 9633af4f..2a3bdce0 100644 --- a/app/Auth/Base.php +++ b/app/Auth/Base.php @@ -2,7 +2,6 @@ namespace Auth; -use Core\Tool; use Pimple\Container; /** @@ -54,6 +53,6 @@ abstract class Base */ public function __get($name) { - return Tool::loadModel($this->container, $name); + return $this->container[$name]; } } diff --git a/app/Console/Base.php b/app/Console/Base.php index f955b428..5927443c 100644 --- a/app/Console/Base.php +++ b/app/Console/Base.php @@ -2,7 +2,6 @@ namespace Console; -use Core\Tool; use Pimple\Container; use Symfony\Component\Console\Command\Command; @@ -52,6 +51,6 @@ abstract class Base extends Command */ public function __get($name) { - return Tool::loadModel($this->container, $name); + return $this->container[$name]; } } diff --git a/app/Controller/Base.php b/app/Controller/Base.php index 5b99e6b8..8330f6d5 100644 --- a/app/Controller/Base.php +++ b/app/Controller/Base.php @@ -3,7 +3,6 @@ namespace Controller; use Pimple\Container; -use Core\Tool; use Core\Security; use Core\Request; use Core\Response; @@ -129,7 +128,7 @@ abstract class Base */ public function __get($name) { - return Tool::loadModel($this->container, $name); + return $this->container[$name]; } /** @@ -156,9 +155,6 @@ abstract class Base $this->response->hsts(); } - $this->config->setupTranslations(); - $this->config->setupTimezone(); - // Authentication if (! $this->authentication->isAuthenticated($controller, $action)) { @@ -173,30 +169,6 @@ abstract class Base if (! $this->acl->isPageAccessAllowed($controller, $action)) { $this->response->redirect('?controller=user&action=forbidden'); } - - // Attach events - $this->attachEvents(); - } - - /** - * Attach events - * - * @access private - */ - private function attachEvents() - { - $models = array( - 'projectActivity', // Order is important - 'projectDailySummary', - 'action', - 'project', - 'webhook', - 'notification', - ); - - foreach ($models as $model) { - $this->$model->attachEvents(); - } } /** diff --git a/app/Core/Event.php b/app/Core/Event.php deleted file mode 100644 index 935f8b9c..00000000 --- a/app/Core/Event.php +++ /dev/null @@ -1,175 +0,0 @@ -<?php - -namespace Core; - -/** - * Event dispatcher class - * - * @package core - * @author Frederic Guillot - */ -class Event -{ - /** - * Contains all listeners - * - * @access private - * @var array - */ - private $listeners = array(); - - /** - * The last listener executed - * - * @access private - * @var string - */ - private $lastListener = ''; - - /** - * The last triggered event - * - * @access private - * @var string - */ - private $lastEvent = ''; - - /** - * Triggered events list - * - * @access private - * @var array - */ - private $events = array(); - - /** - * Attach a listener object to an event - * - * @access public - * @param string $eventName Event name - * @param Listener $listener Object that implements the Listener interface - */ - public function attach($eventName, Listener $listener) - { - if (! isset($this->listeners[$eventName])) { - $this->listeners[$eventName] = array(); - } - - $this->listeners[$eventName][] = $listener; - } - - /** - * Trigger an event - * - * @access public - * @param string $eventName Event name - * @param array $data Event data - */ - public function trigger($eventName, array $data) - { - if (! $this->isEventTriggered($eventName)) { - - $this->events[$eventName] = $data; - - if (isset($this->listeners[$eventName])) { - - foreach ($this->listeners[$eventName] as $listener) { - - $this->lastEvent = $eventName; - - if ($listener->execute($data)) { - $this->lastListener = get_class($listener); - } - } - } - } - } - - /** - * Get the last listener executed - * - * @access public - * @return string Event name - */ - public function getLastListenerExecuted() - { - return $this->lastListener; - } - - /** - * Get the last fired event - * - * @access public - * @return string Event name - */ - public function getLastTriggeredEvent() - { - return $this->lastEvent; - } - - /** - * Get a list of triggered events - * - * @access public - * @return array - */ - public function getTriggeredEvents() - { - return $this->events; - } - - /** - * Get a list of triggered events - * - * @access public - * @return array - */ - public function getEventData($eventName) - { - return isset($this->events[$eventName]) ? $this->events[$eventName] : array(); - } - - /** - * Check if an event have been triggered - * - * @access public - * @param string $eventName Event name - * @return bool - */ - public function isEventTriggered($eventName) - { - return isset($this->events[$eventName]); - } - - /** - * Flush the list of triggered events - * - * @access public - */ - public function clearTriggeredEvents() - { - $this->events = array(); - $this->lastEvent = ''; - } - - /** - * Check if a listener bind to an event - * - * @access public - * @param string $eventName Event name - * @param mixed $instance Instance name or object itself - * @return bool Yes or no - */ - public function hasListener($eventName, $instance) - { - if (isset($this->listeners[$eventName])) { - foreach ($this->listeners[$eventName] as $listener) { - if ($listener instanceof $instance) { - return true; - } - } - } - - return false; - } -} diff --git a/app/Core/Listener.php b/app/Core/Listener.php deleted file mode 100644 index 9c96cd57..00000000 --- a/app/Core/Listener.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php - -namespace Core; - -/** - * Event listener interface - * - * @package core - * @author Frederic Guillot - */ -interface Listener -{ - /** - * Execute the listener - * - * @access public - * @param array $data Event data - * @return boolean - */ - public function execute(array $data); -} diff --git a/app/Core/Tool.php b/app/Core/Tool.php index c010d932..ade99cad 100644 --- a/app/Core/Tool.php +++ b/app/Core/Tool.php @@ -2,8 +2,6 @@ namespace Core; -use Pimple\Container; - /** * Tool class * @@ -33,23 +31,4 @@ class Tool fclose($fp); } } - - /** - * Load and register a model - * - * @static - * @access public - * @param Pimple\Container $container Container instance - * @param string $name Model name - * @return mixed - */ - public static function loadModel(Container $container, $name) - { - if (! isset($container[$name])) { - $class = '\Model\\'.ucfirst($name); - $container[$name] = new $class($container); - } - - return $container[$name]; - } } diff --git a/app/Event/Base.php b/app/Event/Base.php deleted file mode 100644 index 0217fa08..00000000 --- a/app/Event/Base.php +++ /dev/null @@ -1,79 +0,0 @@ -<?php - -namespace Event; - -use Pimple\Container; -use Core\Listener; -use Core\Tool; - -/** - * Base Listener - * - * @package event - * @author Frederic Guillot - * - * @property \Model\Comment $comment - * @property \Model\Project $project - * @property \Model\ProjectActivity $projectActivity - * @property \Model\SubTask $subTask - * @property \Model\Task $task - * @property \Model\TaskFinder $taskFinder - */ -abstract class Base implements Listener -{ - /** - * Container instance - * - * @access protected - * @var \Pimple\Container - */ - protected $container; - - /** - * Constructor - * - * @access public - * @param \Pimple\Container $container - */ - public function __construct(Container $container) - { - $this->container = $container; - } - - /** - * Return class information - * - * @access public - * @return string - */ - public function __toString() - { - return get_called_class(); - } - - /** - * Load automatically models - * - * @access public - * @param string $name Model name - * @return mixed - */ - public function __get($name) - { - return Tool::loadModel($this->container, $name); - } - - /** - * Get event namespace - * - * Event = task.close | Namespace = task - * - * @access public - * @return string - */ - public function getEventNamespace() - { - $event_name = $this->container['event']->getLastTriggeredEvent(); - return substr($event_name, 0, strpos($event_name, '.')); - } -} diff --git a/app/Event/CommentEvent.php b/app/Event/CommentEvent.php new file mode 100644 index 00000000..75a132d7 --- /dev/null +++ b/app/Event/CommentEvent.php @@ -0,0 +1,7 @@ +<?php + +namespace Event; + +class CommentEvent extends GenericEvent +{ +} diff --git a/app/Event/FileEvent.php b/app/Event/FileEvent.php new file mode 100644 index 00000000..81bd83c9 --- /dev/null +++ b/app/Event/FileEvent.php @@ -0,0 +1,7 @@ +<?php + +namespace Event; + +class FileEvent extends GenericEvent +{ +} diff --git a/app/Event/GenericEvent.php b/app/Event/GenericEvent.php new file mode 100644 index 00000000..b29d8f32 --- /dev/null +++ b/app/Event/GenericEvent.php @@ -0,0 +1,45 @@ +<?php + +namespace Event; + +use ArrayAccess; +use Symfony\Component\EventDispatcher\Event as BaseEvent; + +class GenericEvent extends BaseEvent implements ArrayAccess +{ + private $container = array(); + + public function __construct(array $values = array()) + { + $this->container = $values; + } + + public function getAll() + { + return $this->container; + } + + public function offsetSet($offset, $value) + { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->container[$offset] = $value; + } + } + + public function offsetExists($offset) + { + return isset($this->container[$offset]); + } + + public function offsetUnset($offset) + { + unset($this->container[$offset]); + } + + public function offsetGet($offset) + { + return isset($this->container[$offset]) ? $this->container[$offset] : null; + } +} diff --git a/app/Event/NotificationListener.php b/app/Event/NotificationListener.php deleted file mode 100644 index 3c049327..00000000 --- a/app/Event/NotificationListener.php +++ /dev/null @@ -1,83 +0,0 @@ -<?php - -namespace Event; - -/** - * Notification listener - * - * @package event - * @author Frederic Guillot - */ -class NotificationListener extends Base -{ - /** - * Template name - * - * @accesss private - * @var string - */ - private $template = ''; - - /** - * Set template name - * - * @access public - * @param string $template Template name - */ - public function setTemplate($template) - { - $this->template = $template; - } - - /** - * Execute the action - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function execute(array $data) - { - $values = $this->getTemplateData($data); - $users = $this->notification->getUsersList($values['task']['project_id']); - - if ($users) { - $this->notification->sendEmails($this->template, $users, $values); - return true; - } - - return false; - } - - /** - * Fetch data for the mail template - * - * @access public - * @param array $data Event data - * @return array - */ - public function getTemplateData(array $data) - { - $values = array(); - - switch ($this->getEventNamespace()) { - case 'task': - $values['task'] = $this->taskFinder->getDetails($data['task_id']); - break; - case 'subtask': - $values['subtask'] = $this->subtask->getById($data['id'], true); - $values['task'] = $this->taskFinder->getDetails($data['task_id']); - break; - case 'file': - $values['file'] = $data; - $values['task'] = $this->taskFinder->getDetails($data['task_id']); - break; - case 'comment': - $values['comment'] = $this->comment->getById($data['id']); - $values['task'] = $this->taskFinder->getDetails($values['comment']['task_id']); - break; - } - - return $values; - } -} diff --git a/app/Event/ProjectActivityListener.php b/app/Event/ProjectActivityListener.php deleted file mode 100644 index 75efe65d..00000000 --- a/app/Event/ProjectActivityListener.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php - -namespace Event; - -/** - * Project activity listener - * - * @package event - * @author Frederic Guillot - */ -class ProjectActivityListener extends Base -{ - /** - * Execute the action - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function execute(array $data) - { - if (isset($data['task_id'])) { - - $values = $this->getValues($data); - - return $this->projectActivity->createEvent( - $values['task']['project_id'], - $values['task']['id'], - $this->acl->getUserId(), - $this->container['event']->getLastTriggeredEvent(), - $values - ); - } - - return false; - } - - /** - * Get event activity data - * - * @access private - * @param array $data Event data dictionary - * @return array - */ - private function getValues(array $data) - { - $values = array(); - $values['task'] = $this->taskFinder->getDetails($data['task_id']); - - switch ($this->getEventNamespace()) { - case 'subtask': - $values['subtask'] = $this->subTask->getById($data['id'], true); - break; - case 'comment': - $values['comment'] = $this->comment->getById($data['id']); - break; - } - - return $values; - } -} diff --git a/app/Event/ProjectDailySummaryListener.php b/app/Event/ProjectDailySummaryListener.php deleted file mode 100644 index cd593abc..00000000 --- a/app/Event/ProjectDailySummaryListener.php +++ /dev/null @@ -1,28 +0,0 @@ -<?php - -namespace Event; - -/** - * Project daily summary listener - * - * @package event - * @author Frederic Guillot - */ -class ProjectDailySummaryListener extends Base -{ - /** - * Execute the action - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function execute(array $data) - { - if (isset($data['project_id'])) { - return $this->projectDailySummary->updateTotals($data['project_id'], date('Y-m-d')); - } - - return false; - } -} diff --git a/app/Event/ProjectModificationDateListener.php b/app/Event/ProjectModificationDateListener.php deleted file mode 100644 index abc176b0..00000000 --- a/app/Event/ProjectModificationDateListener.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php - -namespace Event; - -/** - * Project modification date listener - * - * Update the "last_modified" field for a project - * - * @package event - * @author Frederic Guillot - */ -class ProjectModificationDateListener extends Base -{ - /** - * Execute the action - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function execute(array $data) - { - if (isset($data['project_id'])) { - return $this->project->updateModificationDate($data['project_id']); - } - - return false; - } -} diff --git a/app/Event/SubtaskEvent.php b/app/Event/SubtaskEvent.php new file mode 100644 index 00000000..229db860 --- /dev/null +++ b/app/Event/SubtaskEvent.php @@ -0,0 +1,7 @@ +<?php + +namespace Event; + +class SubtaskEvent extends GenericEvent +{ +} diff --git a/app/Event/TaskEvent.php b/app/Event/TaskEvent.php new file mode 100644 index 00000000..e2fb30fe --- /dev/null +++ b/app/Event/TaskEvent.php @@ -0,0 +1,7 @@ +<?php + +namespace Event; + +class TaskEvent extends GenericEvent +{ +} diff --git a/app/Event/WebhookListener.php b/app/Event/WebhookListener.php deleted file mode 100644 index f7e23e07..00000000 --- a/app/Event/WebhookListener.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php - -namespace Event; - -/** - * Webhook task events - * - * @package event - * @author Frederic Guillot - */ -class WebhookListener extends Base -{ - /** - * Url to call - * - * @access private - * @var string - */ - private $url = ''; - - /** - * Set webhook url - * - * @access public - * @param string $url URL to call - */ - public function setUrl($url) - { - $this->url = $url; - } - - /** - * Execute the action - * - * @access public - * @param array $data Event data dictionary - * @return bool True if the action was executed or false when not executed - */ - public function execute(array $data) - { - $this->webhook->notify($this->url, $data); - return true; - } -} diff --git a/app/Model/Action.php b/app/Model/Action.php index f8dbd88e..3ed3dc26 100644 --- a/app/Model/Action.php +++ b/app/Model/Action.php @@ -248,7 +248,7 @@ class Action extends Base $listener->setParam($param['name'], $param['value']); } - $this->event->attach($action['event_name'], $listener); + $this->container['dispatcher']->addListener($action['event_name'], array($listener, 'execute')); } } diff --git a/app/Model/Base.php b/app/Model/Base.php index 56a4d8e8..a08bd87c 100644 --- a/app/Model/Base.php +++ b/app/Model/Base.php @@ -2,10 +2,7 @@ namespace Model; -use Core\Event; -use Core\Tool; use Pimple\Container; -use PicoDb\Database; /** * Base model class @@ -52,14 +49,6 @@ abstract class Base protected $db; /** - * Event dispatcher instance - * - * @access public - * @var \Core\Event - */ - public $event; - - /** * Container instance * * @access protected @@ -77,7 +66,6 @@ abstract class Base { $this->container = $container; $this->db = $this->container['db']; - $this->event = $this->container['event']; } /** @@ -89,7 +77,7 @@ abstract class Base */ public function __get($name) { - return Tool::loadModel($this->container, $name); + return $this->container[$name]; } /** diff --git a/app/Model/Comment.php b/app/Model/Comment.php index 3b7dfbc1..a36f2b45 100644 --- a/app/Model/Comment.php +++ b/app/Model/Comment.php @@ -2,6 +2,7 @@ namespace Model; +use Event\CommentEvent; use SimpleValidator\Validator; use SimpleValidator\Validators; @@ -107,7 +108,7 @@ class Comment extends Base $comment_id = $this->persist(self::TABLE, $values); if ($comment_id) { - $this->event->trigger(self::EVENT_CREATE, array('id' => $comment_id) + $values); + $this->container['dispatcher']->dispatch(self::EVENT_CREATE, new CommentEvent(array('id' => $comment_id) + $values)); } return $comment_id; @@ -127,7 +128,7 @@ class Comment extends Base ->eq('id', $values['id']) ->update(array('comment' => $values['comment'])); - $this->event->trigger(self::EVENT_UPDATE, $values); + $this->container['dispatcher']->dispatch(self::EVENT_UPDATE, new CommentEvent($values)); return $result; } diff --git a/app/Model/File.php b/app/Model/File.php index d5a0c7cd..20fba9bf 100644 --- a/app/Model/File.php +++ b/app/Model/File.php @@ -2,6 +2,8 @@ namespace Model; +use Event\FileEvent; + /** * File model * @@ -89,7 +91,10 @@ class File extends Base */ public function create($task_id, $name, $path, $is_image) { - $this->event->trigger(self::EVENT_CREATE, array('task_id' => $task_id, 'name' => $name)); + $this->container['dispatcher']->dispatch( + self::EVENT_CREATE, + new FileEvent(array('task_id' => $task_id, 'name' => $name)) + ); return $this->db->table(self::TABLE)->save(array( 'task_id' => $task_id, diff --git a/app/Model/GithubWebhook.php b/app/Model/GithubWebhook.php index 9c8bd366..f66358eb 100644 --- a/app/Model/GithubWebhook.php +++ b/app/Model/GithubWebhook.php @@ -2,6 +2,8 @@ namespace Model; +use Event\GenericEvent; + /** * Github Webhook model * @@ -88,7 +90,10 @@ class GithubWebhook extends Base } if ($task['is_active'] == Task::STATUS_OPEN) { - $this->event->trigger(self::EVENT_COMMIT, array('task_id' => $task_id) + $task); + $this->container['dispatcher']->dispatch( + self::EVENT_COMMIT, + new GenericEvent(array('task_id' => $task_id) + $task) + ); } } @@ -146,7 +151,11 @@ class GithubWebhook extends Base 'task_id' => $task['id'], ); - $this->event->trigger(self::EVENT_ISSUE_COMMENT, $event); + $this->container['dispatcher']->dispatch( + self::EVENT_ISSUE_COMMENT, + new GenericEvent($event) + ); + return true; } @@ -169,7 +178,11 @@ class GithubWebhook extends Base 'description' => $issue['body']."\n\n[".t('Github Issue').']('.$issue['html_url'].')', ); - $this->event->trigger(self::EVENT_ISSUE_OPENED, $event); + $this->container['dispatcher']->dispatch( + self::EVENT_ISSUE_OPENED, + new GenericEvent($event) + ); + return true; } @@ -191,7 +204,11 @@ class GithubWebhook extends Base 'reference' => $issue['number'], ); - $this->event->trigger(self::EVENT_ISSUE_CLOSED, $event); + $this->container['dispatcher']->dispatch( + self::EVENT_ISSUE_CLOSED, + new GenericEvent($event) + ); + return true; } @@ -216,7 +233,11 @@ class GithubWebhook extends Base 'reference' => $issue['number'], ); - $this->event->trigger(self::EVENT_ISSUE_REOPENED, $event); + $this->container['dispatcher']->dispatch( + self::EVENT_ISSUE_REOPENED, + new GenericEvent($event) + ); + return true; } @@ -244,7 +265,11 @@ class GithubWebhook extends Base 'reference' => $issue['number'], ); - $this->event->trigger(self::EVENT_ISSUE_ASSIGNEE_CHANGE, $event); + $this->container['dispatcher']->dispatch( + self::EVENT_ISSUE_ASSIGNEE_CHANGE, + new GenericEvent($event) + ); + return true; } @@ -271,7 +296,11 @@ class GithubWebhook extends Base 'reference' => $issue['number'], ); - $this->event->trigger(self::EVENT_ISSUE_ASSIGNEE_CHANGE, $event); + $this->container['dispatcher']->dispatch( + self::EVENT_ISSUE_ASSIGNEE_CHANGE, + new GenericEvent($event) + ); + return true; } @@ -299,7 +328,11 @@ class GithubWebhook extends Base 'label' => $label['name'], ); - $this->event->trigger(self::EVENT_ISSUE_LABEL_CHANGE, $event); + $this->container['dispatcher']->dispatch( + self::EVENT_ISSUE_LABEL_CHANGE, + new GenericEvent($event) + ); + return true; } @@ -328,7 +361,11 @@ class GithubWebhook extends Base 'category_id' => 0, ); - $this->event->trigger(self::EVENT_ISSUE_LABEL_CHANGE, $event); + $this->container['dispatcher']->dispatch( + self::EVENT_ISSUE_LABEL_CHANGE, + new GenericEvent($event) + ); + return true; } diff --git a/app/Model/Notification.php b/app/Model/Notification.php index 8d1fca09..ccda1488 100644 --- a/app/Model/Notification.php +++ b/app/Model/Notification.php @@ -94,37 +94,6 @@ class Notification extends Base } /** - * Attach events - * - * @access public - */ - public function attachEvents() - { - $events = array( - Task::EVENT_CREATE => 'task_creation', - Task::EVENT_UPDATE => 'task_update', - Task::EVENT_CLOSE => 'task_close', - Task::EVENT_OPEN => 'task_open', - Task::EVENT_MOVE_COLUMN => 'task_move_column', - Task::EVENT_MOVE_POSITION => 'task_move_position', - Task::EVENT_ASSIGNEE_CHANGE => 'task_assignee_change', - SubTask::EVENT_CREATE => 'subtask_creation', - SubTask::EVENT_UPDATE => 'subtask_update', - Comment::EVENT_CREATE => 'comment_creation', - Comment::EVENT_UPDATE => 'comment_update', - File::EVENT_CREATE => 'file_creation', - ); - - foreach ($events as $event_name => $template_name) { - - $listener = new NotificationListener($this->container); - $listener->setTemplate($template_name); - - $this->event->attach($event_name, $listener); - } - } - - /** * Send the email notifications * * @access public diff --git a/app/Model/Project.php b/app/Model/Project.php index c4ec232a..9c0adee9 100644 --- a/app/Model/Project.php +++ b/app/Model/Project.php @@ -4,7 +4,6 @@ namespace Model; use SimpleValidator\Validator; use SimpleValidator\Validators; -use Event\ProjectModificationDateListener; use Core\Security; /** @@ -489,34 +488,4 @@ class Project extends Base $v->getErrors() ); } - - /** - * Attach events - * - * @access public - */ - public function attachEvents() - { - $events = array( - Task::EVENT_CREATE_UPDATE, - Task::EVENT_CLOSE, - Task::EVENT_OPEN, - Task::EVENT_MOVE_COLUMN, - Task::EVENT_MOVE_POSITION, - Task::EVENT_ASSIGNEE_CHANGE, - GithubWebhook::EVENT_ISSUE_OPENED, - GithubWebhook::EVENT_ISSUE_CLOSED, - GithubWebhook::EVENT_ISSUE_REOPENED, - GithubWebhook::EVENT_ISSUE_ASSIGNEE_CHANGE, - GithubWebhook::EVENT_ISSUE_LABEL_CHANGE, - GithubWebhook::EVENT_ISSUE_COMMENT, - GithubWebhook::EVENT_COMMIT, - ); - - $listener = new ProjectModificationDateListener($this->container); - - foreach ($events as $event_name) { - $this->event->attach($event_name, $listener); - } - } } diff --git a/app/Model/ProjectActivity.php b/app/Model/ProjectActivity.php index 000dfa09..b0a079dc 100644 --- a/app/Model/ProjectActivity.php +++ b/app/Model/ProjectActivity.php @@ -3,7 +3,6 @@ namespace Model; use Core\Template; -use Event\ProjectActivityListener; /** * Project activity model @@ -127,34 +126,6 @@ class ProjectActivity extends Base } /** - * Attach events to be able to record the history - * - * @access public - */ - public function attachEvents() - { - $events = array( - Task::EVENT_ASSIGNEE_CHANGE, - Task::EVENT_UPDATE, - Task::EVENT_CREATE, - Task::EVENT_CLOSE, - Task::EVENT_OPEN, - Task::EVENT_MOVE_COLUMN, - Task::EVENT_MOVE_POSITION, - Comment::EVENT_UPDATE, - Comment::EVENT_CREATE, - SubTask::EVENT_UPDATE, - SubTask::EVENT_CREATE, - ); - - $listener = new ProjectActivityListener($this->container); - - foreach ($events as $event_name) { - $this->event->attach($event_name, $listener); - } - } - - /** * Get the event html content * * @access public diff --git a/app/Model/ProjectDailySummary.php b/app/Model/ProjectDailySummary.php index 0ed3c02b..6c29758a 100644 --- a/app/Model/ProjectDailySummary.php +++ b/app/Model/ProjectDailySummary.php @@ -3,7 +3,6 @@ namespace Model; use Core\Template; -use Event\ProjectDailySummaryListener; /** * Project daily summary @@ -157,25 +156,4 @@ class ProjectDailySummary extends Base return $metrics; } - - /** - * Attach events to be able to record the metrics - * - * @access public - */ - public function attachEvents() - { - $events = array( - Task::EVENT_CREATE, - Task::EVENT_CLOSE, - Task::EVENT_OPEN, - Task::EVENT_MOVE_COLUMN, - ); - - $listener = new ProjectDailySummaryListener($this->container); - - foreach ($events as $event_name) { - $this->event->attach($event_name, $listener); - } - } } diff --git a/app/Model/SubTask.php b/app/Model/SubTask.php index f301ad62..12558429 100644 --- a/app/Model/SubTask.php +++ b/app/Model/SubTask.php @@ -2,6 +2,7 @@ namespace Model; +use Event\SubtaskEvent; use SimpleValidator\Validator; use SimpleValidator\Validators; @@ -146,7 +147,10 @@ class SubTask extends Base $subtask_id = $this->persist(self::TABLE, $values); if ($subtask_id) { - $this->event->trigger(self::EVENT_CREATE, array('id' => $subtask_id) + $values); + $this->container['dispatcher']->dispatch( + self::EVENT_CREATE, + new SubtaskEvent(array('id' => $subtask_id) + $values) + ); } return $subtask_id; @@ -165,7 +169,10 @@ class SubTask extends Base $result = $this->db->table(self::TABLE)->eq('id', $values['id'])->save($values); if ($result) { - $this->event->trigger(self::EVENT_UPDATE, $values); + $this->container['dispatcher']->dispatch( + self::EVENT_UPDATE, + new SubtaskEvent($values) + ); } return $result; diff --git a/app/Model/Task.php b/app/Model/Task.php index 3cd03741..bc2913ec 100644 --- a/app/Model/Task.php +++ b/app/Model/Task.php @@ -30,6 +30,7 @@ class Task extends Base * * @var string */ + const EVENT_MOVE_PROJECT = 'task.move.project'; const EVENT_MOVE_COLUMN = 'task.move.column'; const EVENT_MOVE_POSITION = 'task.move.position'; const EVENT_MOVE_SWIMLANE = 'task.move.swimlane'; diff --git a/app/Model/TaskCreation.php b/app/Model/TaskCreation.php index de9f7ce1..6a2c0f9c 100644 --- a/app/Model/TaskCreation.php +++ b/app/Model/TaskCreation.php @@ -2,6 +2,8 @@ namespace Model; +use Event\TaskEvent; + /** * Task Creation * @@ -64,7 +66,7 @@ class TaskCreation extends Base private function fireEvents($task_id, array $values) { $values['task_id'] = $task_id; - $this->event->trigger(Task::EVENT_CREATE_UPDATE, $values); - $this->event->trigger(Task::EVENT_CREATE, $values); + $this->container['dispatcher']->dispatch(Task::EVENT_CREATE_UPDATE, new TaskEvent($values)); + $this->container['dispatcher']->dispatch(Task::EVENT_CREATE, new TaskEvent($values)); } } diff --git a/app/Model/TaskDuplication.php b/app/Model/TaskDuplication.php index 2410213b..172edb9f 100644 --- a/app/Model/TaskDuplication.php +++ b/app/Model/TaskDuplication.php @@ -2,6 +2,8 @@ namespace Model; +use Event\TaskEvent; + /** * Task Duplication * @@ -84,7 +86,14 @@ class TaskDuplication extends Base $this->checkDestinationProjectValues($values); - return $this->db->table(Task::TABLE)->eq('id', $task['id'])->update($values); + if ($this->db->table(Task::TABLE)->eq('id', $task['id'])->update($values)) { + $this->container['dispatcher']->dispatch( + Task::EVENT_MOVE_PROJECT, + new TaskEvent(array_merge($task, $values, array('task_id' => $task['id']))) + ); + } + + return true; } /** diff --git a/app/Model/TaskModification.php b/app/Model/TaskModification.php index b165ea24..dac52334 100644 --- a/app/Model/TaskModification.php +++ b/app/Model/TaskModification.php @@ -2,6 +2,8 @@ namespace Model; +use Event\TaskEvent; + /** * Task Modification * @@ -15,17 +17,16 @@ class TaskModification extends Base * * @access public * @param array $values - * @param boolean $fire_events * @return boolean */ - public function update(array $values, $fire_events = true) + public function update(array $values) { $original_task = $this->taskFinder->getById($values['id']); $this->prepare($values); $result = $this->db->table(Task::TABLE)->eq('id', $original_task['id'])->update($values); - if ($result && $fire_events) { + if ($result) { $this->fireEvents($original_task, $values); } @@ -51,7 +52,7 @@ class TaskModification extends Base } foreach ($events as $event) { - $this->event->trigger($event, $event_data); + $this->container['dispatcher']->dispatch($event, new TaskEvent($event_data)); } } diff --git a/app/Model/TaskPosition.php b/app/Model/TaskPosition.php index 9a9642e5..e5152b0b 100644 --- a/app/Model/TaskPosition.php +++ b/app/Model/TaskPosition.php @@ -2,6 +2,8 @@ namespace Model; +use Event\TaskEvent; + /** * Task Position * @@ -139,13 +141,13 @@ class TaskPosition extends Base ); if ($task['swimlane_id'] != $new_swimlane_id) { - $this->event->trigger(Task::EVENT_MOVE_SWIMLANE, $event_data); + $this->container['dispatcher']->dispatch(Task::EVENT_MOVE_SWIMLANE, new TaskEvent($event_data)); } else if ($task['column_id'] != $new_column_id) { - $this->event->trigger(Task::EVENT_MOVE_COLUMN, $event_data); + $this->container['dispatcher']->dispatch(Task::EVENT_MOVE_COLUMN, new TaskEvent($event_data)); } else if ($task['position'] != $new_position) { - $this->event->trigger(Task::EVENT_MOVE_POSITION, $event_data); + $this->container['dispatcher']->dispatch(Task::EVENT_MOVE_POSITION, new TaskEvent($event_data)); } } diff --git a/app/Model/TaskStatus.php b/app/Model/TaskStatus.php index 99faffde..225b3933 100644 --- a/app/Model/TaskStatus.php +++ b/app/Model/TaskStatus.php @@ -2,6 +2,8 @@ namespace Model; +use Event\TaskEvent; + /** * Task Status * @@ -84,9 +86,9 @@ class TaskStatus extends Base )); if ($result) { - $this->event->trigger( + $this->container['dispatcher']->dispatch( $event, - array('task_id' => $task_id) + $this->taskFinder->getById($task_id) + new TaskEvent(array('task_id' => $task_id) + $this->taskFinder->getById($task_id)) ); } diff --git a/app/Model/Webhook.php b/app/Model/Webhook.php index 14d50684..7edffa6e 100644 --- a/app/Model/Webhook.php +++ b/app/Model/Webhook.php @@ -2,8 +2,6 @@ namespace Model; -use Event\WebhookListener; - /** * Webhook model * @@ -34,87 +32,6 @@ class Webhook extends Base const HTTP_USER_AGENT = 'Kanboard Webhook'; /** - * URL to call for task creation - * - * @access private - * @var string - */ - private $url_task_creation = ''; - - /** - * URL to call for task modification - * - * @access private - * @var string - */ - private $url_task_modification = ''; - - /** - * Webook token - * - * @access private - * @var string - */ - private $token = ''; - - /** - * Attach events - * - * @access public - */ - public function attachEvents() - { - $this->url_task_creation = $this->config->get('webhook_url_task_creation'); - $this->url_task_modification = $this->config->get('webhook_url_task_modification'); - $this->token = $this->config->get('webhook_token'); - - if ($this->url_task_creation) { - $this->attachCreateEvents(); - } - - if ($this->url_task_modification) { - $this->attachUpdateEvents(); - } - } - - /** - * Attach events for task modification - * - * @access public - */ - public function attachUpdateEvents() - { - $events = array( - Task::EVENT_UPDATE, - Task::EVENT_CLOSE, - Task::EVENT_OPEN, - Task::EVENT_MOVE_COLUMN, - Task::EVENT_MOVE_POSITION, - Task::EVENT_ASSIGNEE_CHANGE, - ); - - $listener = new WebhookListener($this->container); - $listener->setUrl($this->url_task_modification); - - foreach ($events as $event_name) { - $this->event->attach($event_name, $listener); - } - } - - /** - * Attach events for task creation - * - * @access public - */ - public function attachCreateEvents() - { - $listener = new WebhookListener($this->container); - $listener->setUrl($this->url_task_creation); - - $this->event->attach(Task::EVENT_CREATE, $listener); - } - - /** * Call the external URL * * @access public @@ -123,6 +40,8 @@ class Webhook extends Base */ public function notify($url, array $task) { + $token = $this->config->get('webhook_token'); + $headers = array( 'Connection: close', 'User-Agent: '.self::HTTP_USER_AGENT, @@ -140,10 +59,10 @@ class Webhook extends Base )); if (strpos($url, '?') !== false) { - $url .= '&token='.$this->token; + $url .= '&token='.$token; } else { - $url .= '?token='.$this->token; + $url .= '?token='.$token; } @file_get_contents($url, false, $context); diff --git a/app/ServiceProvider/Database.php b/app/ServiceProvider/DatabaseProvider.php index 75e1f73e..fa5319a0 100644 --- a/app/ServiceProvider/Database.php +++ b/app/ServiceProvider/DatabaseProvider.php @@ -4,9 +4,9 @@ namespace ServiceProvider; use Pimple\Container; use Pimple\ServiceProviderInterface; -use PicoDb\Database as Dbal; +use PicoDb\Database; -class Database implements ServiceProviderInterface +class DatabaseProvider implements ServiceProviderInterface { public function register(Container $container) { @@ -55,7 +55,7 @@ class Database implements ServiceProviderInterface { require_once __DIR__.'/../Schema/Sqlite.php'; - return new Dbal(array( + return new Database(array( 'driver' => 'sqlite', 'filename' => DB_FILENAME )); @@ -70,7 +70,7 @@ class Database implements ServiceProviderInterface { require_once __DIR__.'/../Schema/Mysql.php'; - return new Dbal(array( + return new Database(array( 'driver' => 'mysql', 'hostname' => DB_HOSTNAME, 'username' => DB_USERNAME, @@ -89,7 +89,7 @@ class Database implements ServiceProviderInterface { require_once __DIR__.'/../Schema/Postgres.php'; - return new Dbal(array( + return new Database(array( 'driver' => 'postgres', 'hostname' => DB_HOSTNAME, 'username' => DB_USERNAME, diff --git a/app/ServiceProvider/Event.php b/app/ServiceProvider/Event.php deleted file mode 100644 index 0436aa7b..00000000 --- a/app/ServiceProvider/Event.php +++ /dev/null @@ -1,15 +0,0 @@ -<?php - -namespace ServiceProvider; - -use Pimple\Container; -use Pimple\ServiceProviderInterface; -use Core\Event as EventDispatcher; - -class Event implements ServiceProviderInterface -{ - public function register(Container $container) - { - $container['event'] = new EventDispatcher; - } -} diff --git a/app/ServiceProvider/EventDispatcherProvider.php b/app/ServiceProvider/EventDispatcherProvider.php new file mode 100644 index 00000000..90210ba6 --- /dev/null +++ b/app/ServiceProvider/EventDispatcherProvider.php @@ -0,0 +1,28 @@ +<?php + +namespace ServiceProvider; + +use Pimple\Container; +use Pimple\ServiceProviderInterface; +use Subscriber\NotificationSubscriber; +use Subscriber\ProjectActivitySubscriber; +use Subscriber\ProjectDailySummarySubscriber; +use Subscriber\ProjectModificationDateSubscriber; +use Subscriber\WebhookSubscriber; +use Symfony\Component\EventDispatcher\EventDispatcher; + +class EventDispatcherProvider implements ServiceProviderInterface +{ + public function register(Container $container) + { + $container['dispatcher'] = new EventDispatcher; + $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)); + + // Automatic actions + $container['action']->attachEvents(); + } +} diff --git a/app/ServiceProvider/Logging.php b/app/ServiceProvider/LoggingProvider.php index 9737cadc..93f55a9c 100644 --- a/app/ServiceProvider/Logging.php +++ b/app/ServiceProvider/LoggingProvider.php @@ -8,7 +8,7 @@ use Monolog\Logger; use Monolog\Handler\StreamHandler; use Monolog\Handler\SyslogHandler; -class Logging implements ServiceProviderInterface +class LoggingProvider implements ServiceProviderInterface { public function register(Container $container) { diff --git a/app/ServiceProvider/Mailer.php b/app/ServiceProvider/MailerProvider.php index c82c16f6..f6b71363 100644 --- a/app/ServiceProvider/Mailer.php +++ b/app/ServiceProvider/MailerProvider.php @@ -8,7 +8,7 @@ use Swift_SmtpTransport; use Swift_SendmailTransport; use Swift_MailTransport; -class Mailer implements ServiceProviderInterface +class MailerProvider implements ServiceProviderInterface { public function register(Container $container) { diff --git a/app/ServiceProvider/ModelProvider.php b/app/ServiceProvider/ModelProvider.php new file mode 100644 index 00000000..1a940058 --- /dev/null +++ b/app/ServiceProvider/ModelProvider.php @@ -0,0 +1,63 @@ +<?php + +namespace ServiceProvider; + +use Model\Config; +use Model\Project; +use Model\Webhook; +use Pimple\Container; +use Pimple\ServiceProviderInterface; + +class ModelProvider implements ServiceProviderInterface +{ + private $models = array( + 'Acl', + 'Action', + 'Authentication', + 'Board', + 'Category', + 'Color', + 'Comment', + 'Config', + 'DateParser', + 'File', + 'GithubWebhook', + 'LastLogin', + 'Notification', + 'Project', + 'ProjectActivity', + 'ProjectAnalytics', + 'ProjectDailySummary', + 'ProjectPaginator', + 'ProjectPermission', + 'SubTask', + 'SubtaskPaginator', + 'Swimlane', + 'Task', + 'TaskCreation', + 'TaskDuplication', + 'TaskExport', + 'TaskFinder', + 'TaskModification', + 'TaskPaginator', + 'TaskPermission', + 'TaskPosition', + 'TaskStatus', + 'TaskValidator', + 'TimeTracking', + 'User', + 'Webhook', + ); + + public function register(Container $container) + { + foreach ($this->models as $model) { + + $class = '\Model\\'.$model; + + $container[lcfirst($model)] = function ($c) use ($class) { + return new $class($c); + }; + } + } +} diff --git a/app/Subscriber/Base.php b/app/Subscriber/Base.php new file mode 100644 index 00000000..1ed15327 --- /dev/null +++ b/app/Subscriber/Base.php @@ -0,0 +1,47 @@ +<?php + +namespace Subscriber; + +use Event\TaskEvent; +use Model\Task; +use Pimple\Container; + +/** + * Base subscriber class + * + * @package subscriber + * @author Frederic Guillot + */ +abstract class Base +{ + /** + * Container instance + * + * @access protected + * @var \Pimple\Container + */ + protected $container; + + /** + * Constructor + * + * @access public + * @param \Pimple\Container $container + */ + public function __construct(Container $container) + { + $this->container = $container; + } + + /** + * Load automatically models + * + * @access public + * @param string $name Model name + * @return mixed + */ + public function __get($name) + { + return $this->container[$name]; + } +} diff --git a/app/Subscriber/NotificationSubscriber.php b/app/Subscriber/NotificationSubscriber.php new file mode 100644 index 00000000..4412636f --- /dev/null +++ b/app/Subscriber/NotificationSubscriber.php @@ -0,0 +1,81 @@ +<?php + +namespace Subscriber; + +use Event\GenericEvent; +use Model\Task; +use Model\Comment; +use Model\SubTask; +use Model\File; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +class NotificationSubscriber extends Base implements EventSubscriberInterface +{ + private $templates = array( + Task::EVENT_CREATE => 'task_creation', + Task::EVENT_UPDATE => 'task_update', + Task::EVENT_CLOSE => 'task_close', + Task::EVENT_OPEN => 'task_open', + Task::EVENT_MOVE_COLUMN => 'task_move_column', + Task::EVENT_MOVE_POSITION => 'task_move_position', + Task::EVENT_ASSIGNEE_CHANGE => 'task_assignee_change', + SubTask::EVENT_CREATE => 'subtask_creation', + SubTask::EVENT_UPDATE => 'subtask_update', + Comment::EVENT_CREATE => 'comment_creation', + Comment::EVENT_UPDATE => 'comment_update', + File::EVENT_CREATE => 'file_creation', + ); + + public static function getSubscribedEvents() + { + return array( + Task::EVENT_CREATE => 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), + SubTask::EVENT_CREATE => array('execute', 0), + SubTask::EVENT_UPDATE => array('execute', 0), + Comment::EVENT_CREATE => array('execute', 0), + Comment::EVENT_UPDATE => array('execute', 0), + File::EVENT_CREATE => array('execute', 0), + ); + } + + public function execute(GenericEvent $event) + { + $values = $this->getTemplateData($event); + $users = $this->notification->getUsersList($values['task']['project_id']); + + if ($users) { + $this->notification->sendEmails($this->templates[$event->getName()], $users, $values); + } + } + + public function getTemplateData(GenericEvent $event) + { + $values = array(); + + switch (get_class($event)) { + case 'Event\TaskEvent': + $values['task'] = $this->taskFinder->getDetails($event['task_id']); + break; + case 'Event\SubtaskEvent': + $values['subtask'] = $this->subTask->getById($event['id'], true); + $values['task'] = $this->taskFinder->getDetails($event['task_id']); + break; + case 'Event\FileEvent': + $values['file'] = $event->getAll(); + $values['task'] = $this->taskFinder->getDetails($event['task_id']); + break; + case 'Event\CommentEvent': + $values['comment'] = $this->comment->getById($event['id']); + $values['task'] = $this->taskFinder->getDetails($values['comment']['task_id']); + break; + } + + return $values; + } +} diff --git a/app/Subscriber/ProjectActivitySubscriber.php b/app/Subscriber/ProjectActivitySubscriber.php new file mode 100644 index 00000000..1aca8539 --- /dev/null +++ b/app/Subscriber/ProjectActivitySubscriber.php @@ -0,0 +1,63 @@ +<?php + +namespace Subscriber; + +use Event\GenericEvent; +use Model\Task; +use Model\Comment; +use Model\SubTask; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +class ProjectActivitySubscriber extends Base implements EventSubscriberInterface +{ + public static function getSubscribedEvents() + { + return array( + Task::EVENT_ASSIGNEE_CHANGE => array('execute', 0), + Task::EVENT_UPDATE => array('execute', 0), + Task::EVENT_CREATE => 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), + Comment::EVENT_UPDATE => array('execute', 0), + Comment::EVENT_CREATE => array('execute', 0), + SubTask::EVENT_UPDATE => array('execute', 0), + SubTask::EVENT_CREATE => array('execute', 0), + ); + } + + public function execute(GenericEvent $event) + { + // Executed only when someone is logged + if ($this->container['acl']->isLogged() && isset($event['task_id'])) { + + $values = $this->getValues($event); + + $this->projectActivity->createEvent( + $values['task']['project_id'], + $values['task']['id'], + $this->acl->getUserId(), + $event->getName(), + $values + ); + } + } + + private function getValues(GenericEvent $event) + { + $values = array(); + $values['task'] = $this->taskFinder->getDetails($event['task_id']); + + switch (get_class($event)) { + case 'Event\SubtaskEvent': + $values['subtask'] = $this->subTask->getById($event['id'], true); + break; + case 'Event\CommentEvent': + $values['comment'] = $this->comment->getById($event['id']); + break; + } + + return $values; + } +} diff --git a/app/Subscriber/ProjectDailySummarySubscriber.php b/app/Subscriber/ProjectDailySummarySubscriber.php new file mode 100644 index 00000000..6d737734 --- /dev/null +++ b/app/Subscriber/ProjectDailySummarySubscriber.php @@ -0,0 +1,27 @@ +<?php + +namespace Subscriber; + +use Event\TaskEvent; +use Model\Task; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +class ProjectDailySummarySubscriber extends Base implements EventSubscriberInterface +{ + public static function getSubscribedEvents() + { + return array( + Task::EVENT_CREATE => array('execute', 0), + Task::EVENT_CLOSE => array('execute', 0), + Task::EVENT_OPEN => array('execute', 0), + Task::EVENT_MOVE_COLUMN => array('execute', 0), + ); + } + + public function execute(TaskEvent $event) + { + if (isset($event['project_id'])) { + $this->projectDailySummary->updateTotals($event['project_id'], date('Y-m-d')); + } + } +} diff --git a/app/Subscriber/ProjectModificationDateSubscriber.php b/app/Subscriber/ProjectModificationDateSubscriber.php new file mode 100644 index 00000000..3d5484f7 --- /dev/null +++ b/app/Subscriber/ProjectModificationDateSubscriber.php @@ -0,0 +1,38 @@ +<?php + +namespace Subscriber; + +use Event\GenericEvent; +use Model\Task; +use Model\GithubWebhook; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +class ProjectModificationDateSubscriber extends Base implements EventSubscriberInterface +{ + public static function getSubscribedEvents() + { + return array( + Task::EVENT_CREATE_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_MOVE_PROJECT => array('execute', 0), + Task::EVENT_ASSIGNEE_CHANGE => array('execute', 0), + GithubWebhook::EVENT_ISSUE_OPENED => array('execute', 0), + GithubWebhook::EVENT_ISSUE_CLOSED => array('execute', 0), + GithubWebhook::EVENT_ISSUE_REOPENED => array('execute', 0), + GithubWebhook::EVENT_ISSUE_ASSIGNEE_CHANGE => array('execute', 0), + GithubWebhook::EVENT_ISSUE_LABEL_CHANGE => array('execute', 0), + GithubWebhook::EVENT_ISSUE_COMMENT => array('execute', 0), + GithubWebhook::EVENT_COMMIT => array('execute', 0), + ); + } + + public function execute(GenericEvent $event) + { + if (isset($event['project_id'])) { + $this->project->updateModificationDate($event['project_id']); + } + } +} diff --git a/app/Subscriber/WebhookSubscriber.php b/app/Subscriber/WebhookSubscriber.php new file mode 100644 index 00000000..20d765e2 --- /dev/null +++ b/app/Subscriber/WebhookSubscriber.php @@ -0,0 +1,42 @@ +<?php + +namespace Subscriber; + +use Event\TaskEvent; +use Model\Task; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +class WebhookSubscriber extends Base implements EventSubscriberInterface +{ + public static function getSubscribedEvents() + { + return array( + Task::EVENT_CREATE => array('onTaskCreation', 0), + Task::EVENT_UPDATE => array('onTaskModification', 0), + Task::EVENT_CLOSE => array('onTaskModification', 0), + Task::EVENT_OPEN => array('onTaskModification', 0), + Task::EVENT_MOVE_COLUMN => array('onTaskModification', 0), + Task::EVENT_MOVE_POSITION => array('onTaskModification', 0), + Task::EVENT_ASSIGNEE_CHANGE => array('onTaskModification', 0), + ); + } + + public function onTaskCreation(TaskEvent $event) + { + $this->executeRequest('webhook_url_task_creation'); + } + + public function onTaskModification(TaskEvent $event) + { + $this->executeRequest('webhook_url_task_modification'); + } + + public function executeRequest($parameter) + { + $url = $this->config->get($parameter); + + if (! empty($url)) { + $this->webhook->notify($url, $event->getAll()); + } + } +} diff --git a/app/common.php b/app/common.php index addfe874..14d8f8ba 100644 --- a/app/common.php +++ b/app/common.php @@ -10,7 +10,11 @@ if (file_exists('config.php')) { require __DIR__.'/constants.php'; $container = new Pimple\Container; -$container->register(new ServiceProvider\Logging); -$container->register(new ServiceProvider\Database); -$container->register(new ServiceProvider\Event); -$container->register(new ServiceProvider\Mailer); +$container->register(new ServiceProvider\LoggingProvider); +$container->register(new ServiceProvider\DatabaseProvider); +$container->register(new ServiceProvider\ModelProvider); +$container->register(new ServiceProvider\EventDispatcherProvider); +$container->register(new ServiceProvider\MailerProvider); + +$container['config']->setupTranslations(); +$container['config']->setupTimezone(); |