diff options
Diffstat (limited to 'app/Action')
27 files changed, 850 insertions, 157 deletions
diff --git a/app/Action/Base.php b/app/Action/Base.php index 4d2d6da6..e8449d0c 100644 --- a/app/Action/Base.php +++ b/app/Action/Base.php @@ -3,7 +3,6 @@ namespace Kanboard\Action; use Kanboard\Event\GenericEvent; -use Pimple\Container; /** * Base class for automatic actions @@ -14,6 +13,14 @@ use Pimple\Container; abstract class Base extends \Kanboard\Core\Base { /** + * Extended events + * + * @access private + * @var array + */ + private $compatibleEvents = array(); + + /** * Flag for called listener * * @access private @@ -27,7 +34,7 @@ abstract class Base extends \Kanboard\Core\Base * @access private * @var integer */ - private $project_id = 0; + private $projectId = 0; /** * User parameters @@ -38,20 +45,25 @@ abstract class Base extends \Kanboard\Core\Base private $params = array(); /** - * Attached event name + * Get automatic action name * - * @access protected - * @var string + * @final + * @access public + * @return string */ - protected $event_name = ''; + final public function getName() + { + return '\\'.get_called_class(); + } /** - * Container instance + * Get automatic action description * - * @access protected - * @var \Pimple\Container + * @abstract + * @access public + * @return string */ - protected $container; + abstract public function getDescription(); /** * Execute the action @@ -100,30 +112,32 @@ abstract class Base extends \Kanboard\Core\Base abstract public function hasRequiredCondition(array $data); /** - * Constructor + * Return class information * * @access public - * @param \Pimple\Container $container Container - * @param integer $project_id Project id - * @param string $event_name Attached event name + * @return string */ - public function __construct(Container $container, $project_id, $event_name) + public function __toString() { - $this->container = $container; - $this->project_id = $project_id; - $this->event_name = $event_name; - $this->called = false; + $params = array(); + + foreach ($this->params as $key => $value) { + $params[] = $key.'='.var_export($value, true); + } + + return $this->getName().'('.implode('|', $params).')'; } /** - * Return class information + * Set project id * * @access public - * @return string + * @return Base */ - public function __toString() + public function setProjectId($project_id) { - return get_called_class(); + $this->projectId = $project_id; + return $this; } /** @@ -134,7 +148,7 @@ abstract class Base extends \Kanboard\Core\Base */ public function getProjectId() { - return $this->project_id; + return $this->projectId; } /** @@ -143,10 +157,12 @@ abstract class Base extends \Kanboard\Core\Base * @access public * @param string $name Parameter name * @param mixed $value Value + * @param Base */ public function setParam($name, $value) { $this->params[$name] = $value; + return $this; } /** @@ -154,24 +170,25 @@ abstract class Base extends \Kanboard\Core\Base * * @access public * @param string $name Parameter name - * @param mixed $default_value Default value + * @param mixed $default Default value * @return mixed */ - public function getParam($name, $default_value = null) + public function getParam($name, $default = null) { - return isset($this->params[$name]) ? $this->params[$name] : $default_value; + return isset($this->params[$name]) ? $this->params[$name] : $default; } /** * Check if an action is executable (right project and required parameters) * * @access public - * @param array $data Event data dictionary - * @return bool True if the action is executable + * @param array $data + * @param string $eventName + * @return bool */ - public function isExecutable(array $data) + public function isExecutable(array $data, $eventName) { - return $this->hasCompatibleEvent() && + return $this->hasCompatibleEvent($eventName) && $this->hasRequiredProject($data) && $this->hasRequiredParameters($data) && $this->hasRequiredCondition($data); @@ -181,11 +198,12 @@ abstract class Base extends \Kanboard\Core\Base * Check if the event is compatible with the action * * @access public + * @param string $eventName * @return bool */ - public function hasCompatibleEvent() + public function hasCompatibleEvent($eventName) { - return in_array($this->event_name, $this->getCompatibleEvents()); + return in_array($eventName, $this->getEvents()); } /** @@ -197,7 +215,7 @@ abstract class Base extends \Kanboard\Core\Base */ public function hasRequiredProject(array $data) { - return isset($data['project_id']) && $data['project_id'] == $this->project_id; + return isset($data['project_id']) && $data['project_id'] == $this->getProjectId(); } /** @@ -222,10 +240,11 @@ abstract class Base extends \Kanboard\Core\Base * Execute the action * * @access public - * @param \Event\GenericEvent $event Event data dictionary - * @return bool True if the action was executed or false when not executed + * @param \Kanboard\Event\GenericEvent $event + * @param string $eventName + * @return bool */ - public function execute(GenericEvent $event) + public function execute(GenericEvent $event, $eventName) { // Avoid infinite loop, a listener instance can be called only one time if ($this->called) { @@ -233,17 +252,44 @@ abstract class Base extends \Kanboard\Core\Base } $data = $event->getAll(); - $result = false; + $executable = $this->isExecutable($data, $eventName); + $executed = false; - if ($this->isExecutable($data)) { + if ($executable) { $this->called = true; - $result = $this->doAction($data); + $executed = $this->doAction($data); } - if (DEBUG) { - $this->container['logger']->debug(get_called_class().' => '.($result ? 'true' : 'false')); + $this->logger->debug($this.' ['.$eventName.'] => executable='.var_export($executable, true).' exec_success='.var_export($executed, true)); + + return $executed; + } + + /** + * Register a new event for the automatic action + * + * @access public + * @param string $event + * @param string $description + */ + public function addEvent($event, $description = '') + { + if ($description !== '') { + $this->eventManager->register($event, $description); } - return $result; + $this->compatibleEvents[] = $event; + return $this; + } + + /** + * Get all compatible events of an automatic action + * + * @access public + * @return array + */ + public function getEvents() + { + return array_unique(array_merge($this->getCompatibleEvents(), $this->compatibleEvents)); } } diff --git a/app/Action/CommentCreation.php b/app/Action/CommentCreation.php index 73fedc3b..b91e39e2 100644 --- a/app/Action/CommentCreation.php +++ b/app/Action/CommentCreation.php @@ -2,10 +2,6 @@ namespace Kanboard\Action; -use Kanboard\Integration\BitbucketWebhook; -use Kanboard\Integration\GithubWebhook; -use Kanboard\Integration\GitlabWebhook; - /** * Create automatically a comment from a webhook * @@ -15,6 +11,17 @@ use Kanboard\Integration\GitlabWebhook; class CommentCreation extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Create a comment from an external provider'); + } + + /** * Get the list of compatible events * * @access public @@ -22,14 +29,7 @@ class CommentCreation extends Base */ public function getCompatibleEvents() { - return array( - GithubWebhook::EVENT_ISSUE_COMMENT, - GithubWebhook::EVENT_COMMIT, - BitbucketWebhook::EVENT_ISSUE_COMMENT, - BitbucketWebhook::EVENT_COMMIT, - GitlabWebhook::EVENT_COMMIT, - GitlabWebhook::EVENT_ISSUE_COMMENT, - ); + return array(); } /** @@ -67,9 +67,9 @@ class CommentCreation extends Base { return (bool) $this->comment->create(array( 'reference' => isset($data['reference']) ? $data['reference'] : '', - 'comment' => empty($data['comment']) ? $data['commit_comment'] : $data['comment'], + 'comment' => $data['comment'], 'task_id' => $data['task_id'], - 'user_id' => empty($data['user_id']) ? 0 : $data['user_id'], + 'user_id' => isset($data['user_id']) && $this->projectPermission->isAssignable($this->getProjectId(), $data['user_id']) ? $data['user_id'] : 0, )); } @@ -82,6 +82,6 @@ class CommentCreation extends Base */ public function hasRequiredCondition(array $data) { - return ! empty($data['comment']) || ! empty($data['commit_comment']); + return ! empty($data['comment']); } } diff --git a/app/Action/TaskLogMoveAnotherColumn.php b/app/Action/CommentCreationMoveTaskColumn.php index a699c4ab..11224d67 100644 --- a/app/Action/TaskLogMoveAnotherColumn.php +++ b/app/Action/CommentCreationMoveTaskColumn.php @@ -5,14 +5,25 @@ namespace Kanboard\Action; use Kanboard\Model\Task; /** - * Add a log of the triggering event to the task description. + * Add a comment of the triggering event to the task description. * * @package action * @author Oren Ben-Kiki */ -class TaskLogMoveAnotherColumn extends Base +class CommentCreationMoveTaskColumn extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Add a comment log when moving the task between columns'); + } + + /** * Get the list of compatible events * * @access public @@ -60,7 +71,7 @@ class TaskLogMoveAnotherColumn extends Base return false; } - $column = $this->board->getColumn($data['column_id']); + $column = $this->column->getById($data['column_id']); return (bool) $this->comment->create(array( 'comment' => t('Moved to column %s', $column['title']), diff --git a/app/Action/TaskAssignCategoryColor.php b/app/Action/TaskAssignCategoryColor.php index ffa1ac2a..f5085cb0 100644 --- a/app/Action/TaskAssignCategoryColor.php +++ b/app/Action/TaskAssignCategoryColor.php @@ -13,6 +13,17 @@ use Kanboard\Model\Task; class TaskAssignCategoryColor extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Assign automatically a category based on a color'); + } + + /** * Get the list of compatible events * * @access public diff --git a/app/Action/TaskAssignCategoryLabel.php b/app/Action/TaskAssignCategoryLabel.php index 0ef474b6..95fa116e 100644 --- a/app/Action/TaskAssignCategoryLabel.php +++ b/app/Action/TaskAssignCategoryLabel.php @@ -2,8 +2,6 @@ namespace Kanboard\Action; -use Kanboard\Integration\GithubWebhook; - /** * Set a category automatically according to a label * @@ -13,6 +11,17 @@ use Kanboard\Integration\GithubWebhook; class TaskAssignCategoryLabel extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Change the category based on an external label'); + } + + /** * Get the list of compatible events * * @access public @@ -20,9 +29,7 @@ class TaskAssignCategoryLabel extends Base */ public function getCompatibleEvents() { - return array( - GithubWebhook::EVENT_ISSUE_LABEL_CHANGE, - ); + return array(); } /** @@ -64,7 +71,7 @@ class TaskAssignCategoryLabel extends Base { $values = array( 'id' => $data['task_id'], - 'category_id' => isset($data['category_id']) ? $data['category_id'] : $this->getParam('category_id'), + 'category_id' => $this->getParam('category_id'), ); return $this->taskModification->update($values); @@ -79,6 +86,6 @@ class TaskAssignCategoryLabel extends Base */ public function hasRequiredCondition(array $data) { - return $data['label'] == $this->getParam('label'); + return $data['label'] == $this->getParam('label') && empty($data['category_id']); } } diff --git a/app/Action/TaskAssignCategoryLink.php b/app/Action/TaskAssignCategoryLink.php new file mode 100644 index 00000000..b39e41b4 --- /dev/null +++ b/app/Action/TaskAssignCategoryLink.php @@ -0,0 +1,101 @@ +<?php + +namespace Kanboard\Action; + +use Kanboard\Model\TaskLink; + +/** + * Set a category automatically according to a task link + * + * @package action + * @author Olivier Maridat + * @author Frederic Guillot + */ +class TaskAssignCategoryLink extends Base +{ + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Assign automatically a category based on a link'); + } + + /** + * Get the list of compatible events + * + * @access public + * @return array + */ + public function getCompatibleEvents() + { + return array( + TaskLink::EVENT_CREATE_UPDATE, + ); + } + + /** + * Get the required parameter for the action (defined by the user) + * + * @access public + * @return array + */ + public function getActionRequiredParameters() + { + return array( + 'category_id' => t('Category'), + 'link_id' => t('Link type'), + ); + } + + /** + * Get the required parameter for the event + * + * @access public + * @return string[] + */ + public function getEventRequiredParameters() + { + return array( + 'task_id', + 'link_id', + ); + } + + /** + * Execute the action (change the category) + * + * @access public + * @param array $data Event data dictionary + * @return bool True if the action was executed or false when not executed + */ + public function doAction(array $data) + { + $values = array( + 'id' => $data['task_id'], + 'category_id' => $this->getParam('category_id'), + ); + + return $this->taskModification->update($values); + } + + /** + * Check if the event data meet the action condition + * + * @access public + * @param array $data Event data dictionary + * @return bool + */ + public function hasRequiredCondition(array $data) + { + if ($data['link_id'] == $this->getParam('link_id')) { + $task = $this->taskFinder->getById($data['task_id']); + return empty($task['category_id']); + } + + return false; + } +} diff --git a/app/Action/TaskAssignColorCategory.php b/app/Action/TaskAssignColorCategory.php index a2332f78..139c24cb 100644 --- a/app/Action/TaskAssignColorCategory.php +++ b/app/Action/TaskAssignColorCategory.php @@ -13,6 +13,17 @@ use Kanboard\Model\Task; class TaskAssignColorCategory extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Assign automatically a color based on a category'); + } + + /** * Get the list of compatible events * * @access public @@ -67,7 +78,7 @@ class TaskAssignColorCategory extends Base 'color_id' => $this->getParam('color_id'), ); - return $this->taskModification->update($values); + return $this->taskModification->update($values, false); } /** diff --git a/app/Action/TaskAssignColorColumn.php b/app/Action/TaskAssignColorColumn.php index 53140733..92412739 100644 --- a/app/Action/TaskAssignColorColumn.php +++ b/app/Action/TaskAssignColorColumn.php @@ -13,6 +13,17 @@ use Kanboard\Model\Task; class TaskAssignColorColumn extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Assign a color when the task is moved to a specific column'); + } + + /** * Get the list of compatible events * * @access public @@ -68,7 +79,7 @@ class TaskAssignColorColumn extends Base 'color_id' => $this->getParam('color_id'), ); - return $this->taskModification->update($values); + return $this->taskModification->update($values, false); } /** diff --git a/app/Action/TaskAssignColorLink.php b/app/Action/TaskAssignColorLink.php index 67b2ef62..12ceabb3 100644 --- a/app/Action/TaskAssignColorLink.php +++ b/app/Action/TaskAssignColorLink.php @@ -13,6 +13,17 @@ use Kanboard\Model\TaskLink; class TaskAssignColorLink extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Change task color when using a specific task link'); + } + + /** * Get the list of compatible events * * @access public @@ -67,7 +78,7 @@ class TaskAssignColorLink extends Base 'color_id' => $this->getParam('color_id'), ); - return $this->taskModification->update($values); + return $this->taskModification->update($values, false); } /** diff --git a/app/Action/TaskAssignColorUser.php b/app/Action/TaskAssignColorUser.php index 6bf02c36..6ec8ce95 100644 --- a/app/Action/TaskAssignColorUser.php +++ b/app/Action/TaskAssignColorUser.php @@ -13,6 +13,17 @@ use Kanboard\Model\Task; class TaskAssignColorUser extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Assign a color to a specific user'); + } + + /** * Get the list of compatible events * * @access public @@ -68,7 +79,7 @@ class TaskAssignColorUser extends Base 'color_id' => $this->getParam('color_id'), ); - return $this->taskModification->update($values); + return $this->taskModification->update($values, false); } /** diff --git a/app/Action/TaskAssignCurrentUser.php b/app/Action/TaskAssignCurrentUser.php index f34c4f36..192a120c 100644 --- a/app/Action/TaskAssignCurrentUser.php +++ b/app/Action/TaskAssignCurrentUser.php @@ -13,6 +13,17 @@ use Kanboard\Model\Task; class TaskAssignCurrentUser extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Assign the task to the person who does the action'); + } + + /** * Get the list of compatible events * * @access public @@ -22,7 +33,6 @@ class TaskAssignCurrentUser extends Base { return array( Task::EVENT_CREATE, - Task::EVENT_MOVE_COLUMN, ); } @@ -34,9 +44,7 @@ class TaskAssignCurrentUser extends Base */ public function getActionRequiredParameters() { - return array( - 'column_id' => t('Column'), - ); + return array(); } /** @@ -49,7 +57,6 @@ class TaskAssignCurrentUser extends Base { return array( 'task_id', - 'column_id', ); } @@ -83,6 +90,6 @@ class TaskAssignCurrentUser extends Base */ public function hasRequiredCondition(array $data) { - return $data['column_id'] == $this->getParam('column_id'); + return true; } } diff --git a/app/Action/TaskAssignCurrentUserColumn.php b/app/Action/TaskAssignCurrentUserColumn.php new file mode 100644 index 00000000..05d08dd3 --- /dev/null +++ b/app/Action/TaskAssignCurrentUserColumn.php @@ -0,0 +1,98 @@ +<?php + +namespace Kanboard\Action; + +use Kanboard\Model\Task; + +/** + * Assign a task to the logged user on column change + * + * @package action + * @author Frederic Guillot + */ +class TaskAssignCurrentUserColumn extends Base +{ + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Assign the task to the person who does the action when the column is changed'); + } + + /** + * Get the list of compatible events + * + * @access public + * @return array + */ + public function getCompatibleEvents() + { + return array( + Task::EVENT_MOVE_COLUMN, + ); + } + + /** + * Get the required parameter for the action (defined by the user) + * + * @access public + * @return array + */ + public function getActionRequiredParameters() + { + return array( + 'column_id' => t('Column'), + ); + } + + /** + * Get the required parameter for the event + * + * @access public + * @return string[] + */ + public function getEventRequiredParameters() + { + return array( + 'task_id', + 'column_id', + ); + } + + /** + * 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 doAction(array $data) + { + if (! $this->userSession->isLogged()) { + return false; + } + + $values = array( + 'id' => $data['task_id'], + 'owner_id' => $this->userSession->getId(), + ); + + return $this->taskModification->update($values); + } + + /** + * Check if the event data meet the action condition + * + * @access public + * @param array $data Event data dictionary + * @return bool + */ + public function hasRequiredCondition(array $data) + { + return $data['column_id'] == $this->getParam('column_id'); + } +} diff --git a/app/Action/TaskAssignSpecificUser.php b/app/Action/TaskAssignSpecificUser.php index dfcb281b..2dc3e966 100644 --- a/app/Action/TaskAssignSpecificUser.php +++ b/app/Action/TaskAssignSpecificUser.php @@ -13,6 +13,17 @@ use Kanboard\Model\Task; class TaskAssignSpecificUser extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Assign the task to a specific user'); + } + + /** * Get the list of compatible events * * @access public diff --git a/app/Action/TaskAssignUser.php b/app/Action/TaskAssignUser.php index a5821729..da54d186 100644 --- a/app/Action/TaskAssignUser.php +++ b/app/Action/TaskAssignUser.php @@ -2,9 +2,6 @@ namespace Kanboard\Action; -use Kanboard\Integration\GithubWebhook; -use Kanboard\Integration\BitbucketWebhook; - /** * Assign a task to someone * @@ -14,6 +11,17 @@ use Kanboard\Integration\BitbucketWebhook; class TaskAssignUser extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Change the assignee based on an external username'); + } + + /** * Get the list of compatible events * * @access public @@ -21,10 +29,7 @@ class TaskAssignUser extends Base */ public function getCompatibleEvents() { - return array( - GithubWebhook::EVENT_ISSUE_ASSIGNEE_CHANGE, - BitbucketWebhook::EVENT_ISSUE_ASSIGNEE_CHANGE, - ); + return array(); } /** @@ -78,6 +83,6 @@ class TaskAssignUser extends Base */ public function hasRequiredCondition(array $data) { - return true; + return $this->projectPermission->isAssignable($this->getProjectId(), $data['owner_id']); } } diff --git a/app/Action/TaskClose.php b/app/Action/TaskClose.php index d80bd023..cf91e83e 100644 --- a/app/Action/TaskClose.php +++ b/app/Action/TaskClose.php @@ -2,11 +2,6 @@ namespace Kanboard\Action; -use Kanboard\Integration\GitlabWebhook; -use Kanboard\Integration\GithubWebhook; -use Kanboard\Integration\BitbucketWebhook; -use Kanboard\Model\Task; - /** * Close automatically a task * @@ -16,6 +11,17 @@ use Kanboard\Model\Task; class TaskClose extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Close a task'); + } + + /** * Get the list of compatible events * * @access public @@ -23,15 +29,7 @@ class TaskClose extends Base */ public function getCompatibleEvents() { - return array( - Task::EVENT_MOVE_COLUMN, - GithubWebhook::EVENT_COMMIT, - GithubWebhook::EVENT_ISSUE_CLOSED, - GitlabWebhook::EVENT_COMMIT, - GitlabWebhook::EVENT_ISSUE_CLOSED, - BitbucketWebhook::EVENT_COMMIT, - BitbucketWebhook::EVENT_ISSUE_CLOSED, - ); + return array(); } /** @@ -42,17 +40,7 @@ class TaskClose extends Base */ public function getActionRequiredParameters() { - switch ($this->event_name) { - case GithubWebhook::EVENT_COMMIT: - case GithubWebhook::EVENT_ISSUE_CLOSED: - case GitlabWebhook::EVENT_COMMIT: - case GitlabWebhook::EVENT_ISSUE_CLOSED: - case BitbucketWebhook::EVENT_COMMIT: - case BitbucketWebhook::EVENT_ISSUE_CLOSED: - return array(); - default: - return array('column_id' => t('Column')); - } + return array(); } /** @@ -63,17 +51,7 @@ class TaskClose extends Base */ public function getEventRequiredParameters() { - switch ($this->event_name) { - case GithubWebhook::EVENT_COMMIT: - case GithubWebhook::EVENT_ISSUE_CLOSED: - case GitlabWebhook::EVENT_COMMIT: - case GitlabWebhook::EVENT_ISSUE_CLOSED: - case BitbucketWebhook::EVENT_COMMIT: - case BitbucketWebhook::EVENT_ISSUE_CLOSED: - return array('task_id'); - default: - return array('task_id', 'column_id'); - } + return array('task_id'); } /** @@ -97,16 +75,6 @@ class TaskClose extends Base */ public function hasRequiredCondition(array $data) { - switch ($this->event_name) { - case GithubWebhook::EVENT_COMMIT: - case GithubWebhook::EVENT_ISSUE_CLOSED: - case GitlabWebhook::EVENT_COMMIT: - case GitlabWebhook::EVENT_ISSUE_CLOSED: - case BitbucketWebhook::EVENT_COMMIT: - case BitbucketWebhook::EVENT_ISSUE_CLOSED: - return true; - default: - return $data['column_id'] == $this->getParam('column_id'); - } + return true; } } diff --git a/app/Action/TaskCloseColumn.php b/app/Action/TaskCloseColumn.php new file mode 100644 index 00000000..09af3b96 --- /dev/null +++ b/app/Action/TaskCloseColumn.php @@ -0,0 +1,84 @@ +<?php + +namespace Kanboard\Action; + +use Kanboard\Model\Task; + +/** + * Close automatically a task in a specific column + * + * @package action + * @author Frederic Guillot + */ +class TaskCloseColumn extends Base +{ + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Close a task in a specific column'); + } + + /** + * Get the list of compatible events + * + * @access public + * @return array + */ + public function getCompatibleEvents() + { + return array( + Task::EVENT_MOVE_COLUMN, + ); + } + + /** + * Get the required parameter for the action (defined by the user) + * + * @access public + * @return array + */ + public function getActionRequiredParameters() + { + return array('column_id' => t('Column')); + } + + /** + * Get the required parameter for the event + * + * @access public + * @return string[] + */ + public function getEventRequiredParameters() + { + return array('task_id', 'column_id'); + } + + /** + * Execute the action (close the task) + * + * @access public + * @param array $data Event data dictionary + * @return bool True if the action was executed or false when not executed + */ + public function doAction(array $data) + { + return $this->taskStatus->close($data['task_id']); + } + + /** + * Check if the event data meet the action condition + * + * @access public + * @param array $data Event data dictionary + * @return bool + */ + public function hasRequiredCondition(array $data) + { + return $data['column_id'] == $this->getParam('column_id'); + } +} diff --git a/app/Action/TaskCloseNoActivity.php b/app/Action/TaskCloseNoActivity.php new file mode 100644 index 00000000..59f7f56a --- /dev/null +++ b/app/Action/TaskCloseNoActivity.php @@ -0,0 +1,95 @@ +<?php + +namespace Kanboard\Action; + +use Kanboard\Model\Task; + +/** + * Close automatically a task after when inactive + * + * @package action + * @author Frederic Guillot + */ +class TaskCloseNoActivity extends Base +{ + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Close a task when there is no activity'); + } + + /** + * Get the list of compatible events + * + * @access public + * @return array + */ + public function getCompatibleEvents() + { + return array(Task::EVENT_DAILY_CRONJOB); + } + + /** + * Get the required parameter for the action (defined by the user) + * + * @access public + * @return array + */ + public function getActionRequiredParameters() + { + return array( + 'duration' => t('Duration in days') + ); + } + + /** + * Get the required parameter for the event + * + * @access public + * @return string[] + */ + public function getEventRequiredParameters() + { + return array('tasks'); + } + + /** + * Execute the action (close the task) + * + * @access public + * @param array $data Event data dictionary + * @return bool True if the action was executed or false when not executed + */ + public function doAction(array $data) + { + $results = array(); + $max = $this->getParam('duration') * 86400; + + foreach ($data['tasks'] as $task) { + $duration = time() - $task['date_modification']; + + if ($duration > $max) { + $results[] = $this->taskStatus->close($task['id']); + } + } + + return in_array(true, $results, true); + } + + /** + * Check if the event data meet the action condition + * + * @access public + * @param array $data Event data dictionary + * @return bool + */ + public function hasRequiredCondition(array $data) + { + return count($data['tasks']) > 0; + } +} diff --git a/app/Action/TaskCreation.php b/app/Action/TaskCreation.php index af1403f0..290c31e1 100644 --- a/app/Action/TaskCreation.php +++ b/app/Action/TaskCreation.php @@ -2,10 +2,6 @@ namespace Kanboard\Action; -use Kanboard\Integration\GithubWebhook; -use Kanboard\Integration\GitlabWebhook; -use Kanboard\Integration\BitbucketWebhook; - /** * Create automatically a task from a webhook * @@ -15,6 +11,17 @@ use Kanboard\Integration\BitbucketWebhook; class TaskCreation extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Create a task from an external provider'); + } + + /** * Get the list of compatible events * * @access public @@ -22,11 +29,7 @@ class TaskCreation extends Base */ public function getCompatibleEvents() { - return array( - GithubWebhook::EVENT_ISSUE_OPENED, - GitlabWebhook::EVENT_ISSUE_OPENED, - BitbucketWebhook::EVENT_ISSUE_OPENED, - ); + return array(); } /** diff --git a/app/Action/TaskDuplicateAnotherProject.php b/app/Action/TaskDuplicateAnotherProject.php index 1f6684dd..5f05136e 100644 --- a/app/Action/TaskDuplicateAnotherProject.php +++ b/app/Action/TaskDuplicateAnotherProject.php @@ -13,6 +13,17 @@ use Kanboard\Model\Task; class TaskDuplicateAnotherProject extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Duplicate the task to another project'); + } + + /** * Get the list of compatible events * * @access public @@ -51,7 +62,6 @@ class TaskDuplicateAnotherProject extends Base return array( 'task_id', 'column_id', - 'project_id', ); } @@ -64,8 +74,7 @@ class TaskDuplicateAnotherProject extends Base */ public function doAction(array $data) { - $destination_column_id = $this->board->getFirstColumn($this->getParam('project_id')); - + $destination_column_id = $this->column->getFirstColumnId($this->getParam('project_id')); return (bool) $this->taskDuplication->duplicateToProject($data['task_id'], $this->getParam('project_id'), null, $destination_column_id); } diff --git a/app/Action/TaskEmail.php b/app/Action/TaskEmail.php index 7fb76c4c..4e0e06a6 100644 --- a/app/Action/TaskEmail.php +++ b/app/Action/TaskEmail.php @@ -13,6 +13,17 @@ use Kanboard\Model\Task; class TaskEmail extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Send a task by email to someone'); + } + + /** * Get the list of compatible events * * @access public diff --git a/app/Action/TaskEmailNoActivity.php b/app/Action/TaskEmailNoActivity.php new file mode 100644 index 00000000..c5d7a797 --- /dev/null +++ b/app/Action/TaskEmailNoActivity.php @@ -0,0 +1,124 @@ +<?php + +namespace Kanboard\Action; + +use Kanboard\Model\Task; + +/** + * Email a task with no activity + * + * @package action + * @author Frederic Guillot + */ +class TaskEmailNoActivity extends Base +{ + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Send email when there is no activity on a task'); + } + + /** + * Get the list of compatible events + * + * @access public + * @return array + */ + public function getCompatibleEvents() + { + return array( + Task::EVENT_DAILY_CRONJOB, + ); + } + + /** + * Get the required parameter for the action (defined by the user) + * + * @access public + * @return array + */ + public function getActionRequiredParameters() + { + return array( + 'user_id' => t('User that will receive the email'), + 'subject' => t('Email subject'), + 'duration' => t('Duration in days'), + ); + } + + /** + * Get the required parameter for the event + * + * @access public + * @return string[] + */ + public function getEventRequiredParameters() + { + return array('tasks'); + } + + /** + * Check if the event data meet the action condition + * + * @access public + * @param array $data Event data dictionary + * @return bool + */ + public function hasRequiredCondition(array $data) + { + return count($data['tasks']) > 0; + } + + /** + * Execute the action (move the task to another column) + * + * @access public + * @param array $data Event data dictionary + * @return bool True if the action was executed or false when not executed + */ + public function doAction(array $data) + { + $results = array(); + $max = $this->getParam('duration') * 86400; + $user = $this->user->getById($this->getParam('user_id')); + + if (! empty($user['email'])) { + foreach ($data['tasks'] as $task) { + $duration = time() - $task['date_modification']; + + if ($duration > $max) { + $results[] = $this->sendEmail($task['id'], $user); + } + } + } + + return in_array(true, $results, true); + } + + /** + * Send email + * + * @access private + * @param integer $task_id + * @param array $user + * @return boolean + */ + private function sendEmail($task_id, array $user) + { + $task = $this->taskFinder->getDetails($task_id); + + $this->emailClient->send( + $user['email'], + $user['name'] ?: $user['username'], + $this->getParam('subject'), + $this->template->render('notification/task_create', array('task' => $task, 'application_url' => $this->config->get('application_url'))) + ); + + return true; + } +} diff --git a/app/Action/TaskMoveAnotherProject.php b/app/Action/TaskMoveAnotherProject.php index 476e2036..fdff0d8c 100644 --- a/app/Action/TaskMoveAnotherProject.php +++ b/app/Action/TaskMoveAnotherProject.php @@ -13,6 +13,17 @@ use Kanboard\Model\Task; class TaskMoveAnotherProject extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Move the task to another project'); + } + + /** * Get the list of compatible events * * @access public diff --git a/app/Action/TaskMoveColumnAssigned.php b/app/Action/TaskMoveColumnAssigned.php index 16622ee4..1b23a591 100644 --- a/app/Action/TaskMoveColumnAssigned.php +++ b/app/Action/TaskMoveColumnAssigned.php @@ -13,6 +13,17 @@ use Kanboard\Model\Task; class TaskMoveColumnAssigned extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Move the task to another column when assigned to a user'); + } + + /** * Get the list of compatible events * * @access public @@ -51,7 +62,6 @@ class TaskMoveColumnAssigned extends Base return array( 'task_id', 'column_id', - 'project_id', 'owner_id' ); } diff --git a/app/Action/TaskMoveColumnCategoryChange.php b/app/Action/TaskMoveColumnCategoryChange.php index 1e12be4a..0f591eda 100644 --- a/app/Action/TaskMoveColumnCategoryChange.php +++ b/app/Action/TaskMoveColumnCategoryChange.php @@ -13,6 +13,17 @@ use Kanboard\Model\Task; class TaskMoveColumnCategoryChange extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Move the task to another column when the category is changed'); + } + + /** * Get the list of compatible events * * @access public @@ -50,7 +61,6 @@ class TaskMoveColumnCategoryChange extends Base return array( 'task_id', 'column_id', - 'project_id', 'category_id', ); } @@ -71,7 +81,8 @@ class TaskMoveColumnCategoryChange extends Base $data['task_id'], $this->getParam('dest_column_id'), $original_task['position'], - $original_task['swimlane_id'] + $original_task['swimlane_id'], + false ); } diff --git a/app/Action/TaskMoveColumnUnAssigned.php b/app/Action/TaskMoveColumnUnAssigned.php index 617c75a8..99ef9351 100644 --- a/app/Action/TaskMoveColumnUnAssigned.php +++ b/app/Action/TaskMoveColumnUnAssigned.php @@ -13,6 +13,17 @@ use Kanboard\Model\Task; class TaskMoveColumnUnAssigned extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Move the task to another column when assignee is cleared'); + } + + /** * Get the list of compatible events * * @access public @@ -51,7 +62,6 @@ class TaskMoveColumnUnAssigned extends Base return array( 'task_id', 'column_id', - 'project_id', 'owner_id' ); } diff --git a/app/Action/TaskOpen.php b/app/Action/TaskOpen.php index 2e53efae..ec0f96f7 100644 --- a/app/Action/TaskOpen.php +++ b/app/Action/TaskOpen.php @@ -2,9 +2,6 @@ namespace Kanboard\Action; -use Kanboard\Integration\GithubWebhook; -use Kanboard\Integration\BitbucketWebhook; - /** * Open automatically a task * @@ -14,6 +11,17 @@ use Kanboard\Integration\BitbucketWebhook; class TaskOpen extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Open a task'); + } + + /** * Get the list of compatible events * * @access public @@ -21,10 +29,7 @@ class TaskOpen extends Base */ public function getCompatibleEvents() { - return array( - GithubWebhook::EVENT_ISSUE_REOPENED, - BitbucketWebhook::EVENT_ISSUE_REOPENED, - ); + return array(); } /** diff --git a/app/Action/TaskUpdateStartDate.php b/app/Action/TaskUpdateStartDate.php index 4cd548af..e5cea01b 100644 --- a/app/Action/TaskUpdateStartDate.php +++ b/app/Action/TaskUpdateStartDate.php @@ -13,6 +13,17 @@ use Kanboard\Model\Task; class TaskUpdateStartDate extends Base { /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Automatically update the start date'); + } + + /** * Get the list of compatible events * * @access public @@ -66,7 +77,7 @@ class TaskUpdateStartDate extends Base 'date_started' => time(), ); - return $this->taskModification->update($values); + return $this->taskModification->update($values, false); } /** |