diff options
35 files changed, 236 insertions, 39 deletions
@@ -6,6 +6,7 @@ New features: * New automated actions: - Close tasks without activity in a specific column - Set due date automatically + - Move a task to another column when closed * Added internal task links to activity stream * Added new event for removed comments * Added search filter for task priority diff --git a/app/Action/Base.php b/app/Action/Base.php index e0ed8bde..9a502a08 100644 --- a/app/Action/Base.php +++ b/app/Action/Base.php @@ -7,7 +7,7 @@ use Kanboard\Event\GenericEvent; /** * Base class for automatic actions * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ abstract class Base extends \Kanboard\Core\Base diff --git a/app/Action/CommentCreation.php b/app/Action/CommentCreation.php index 60ca24f7..301d2cf9 100644 --- a/app/Action/CommentCreation.php +++ b/app/Action/CommentCreation.php @@ -5,7 +5,7 @@ namespace Kanboard\Action; /** * Create automatically a comment from a webhook * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class CommentCreation extends Base diff --git a/app/Action/CommentCreationMoveTaskColumn.php b/app/Action/CommentCreationMoveTaskColumn.php index 8ab792ad..d5bdd807 100644 --- a/app/Action/CommentCreationMoveTaskColumn.php +++ b/app/Action/CommentCreationMoveTaskColumn.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskModel; /** * Add a comment of the triggering event to the task description. * - * @package action + * @package Kanboard\Action * @author Oren Ben-Kiki */ class CommentCreationMoveTaskColumn extends Base diff --git a/app/Action/TaskAssignCategoryColor.php b/app/Action/TaskAssignCategoryColor.php index 2df90b2c..9228e1ff 100644 --- a/app/Action/TaskAssignCategoryColor.php +++ b/app/Action/TaskAssignCategoryColor.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskModel; /** * Set a category automatically according to the color * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskAssignCategoryColor extends Base diff --git a/app/Action/TaskAssignCategoryLabel.php b/app/Action/TaskAssignCategoryLabel.php index 48299010..c390414e 100644 --- a/app/Action/TaskAssignCategoryLabel.php +++ b/app/Action/TaskAssignCategoryLabel.php @@ -5,7 +5,7 @@ namespace Kanboard\Action; /** * Set a category automatically according to a label * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskAssignCategoryLabel extends Base diff --git a/app/Action/TaskAssignCategoryLink.php b/app/Action/TaskAssignCategoryLink.php index d4a4c0ec..6c4b6c96 100644 --- a/app/Action/TaskAssignCategoryLink.php +++ b/app/Action/TaskAssignCategoryLink.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskLinkModel; /** * Set a category automatically according to a task link * - * @package action + * @package Kanboard\Action * @author Olivier Maridat * @author Frederic Guillot */ diff --git a/app/Action/TaskAssignColorCategory.php b/app/Action/TaskAssignColorCategory.php index 91860be4..a136ffd2 100644 --- a/app/Action/TaskAssignColorCategory.php +++ b/app/Action/TaskAssignColorCategory.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskModel; /** * Assign a color to a specific category * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskAssignColorCategory extends Base diff --git a/app/Action/TaskAssignColorColumn.php b/app/Action/TaskAssignColorColumn.php index 6c674b1f..da6e3aed 100644 --- a/app/Action/TaskAssignColorColumn.php +++ b/app/Action/TaskAssignColorColumn.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskModel; /** * Assign a color to a task * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskAssignColorColumn extends Base diff --git a/app/Action/TaskAssignColorLink.php b/app/Action/TaskAssignColorLink.php index 9759f622..19c37afe 100644 --- a/app/Action/TaskAssignColorLink.php +++ b/app/Action/TaskAssignColorLink.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskLinkModel; /** * Assign a color to a specific task link * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskAssignColorLink extends Base diff --git a/app/Action/TaskAssignColorPriority.php b/app/Action/TaskAssignColorPriority.php index 57000ba8..37f7ffed 100644 --- a/app/Action/TaskAssignColorPriority.php +++ b/app/Action/TaskAssignColorPriority.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskModel; /** * Assign a color to a priority * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskAssignColorPriority extends Base diff --git a/app/Action/TaskAssignColorUser.php b/app/Action/TaskAssignColorUser.php index 385db793..468d0198 100644 --- a/app/Action/TaskAssignColorUser.php +++ b/app/Action/TaskAssignColorUser.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskModel; /** * Assign a color to a specific user * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskAssignColorUser extends Base diff --git a/app/Action/TaskAssignCurrentUser.php b/app/Action/TaskAssignCurrentUser.php index 997aa98f..dee5e7db 100644 --- a/app/Action/TaskAssignCurrentUser.php +++ b/app/Action/TaskAssignCurrentUser.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskModel; /** * Assign a task to the logged user * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskAssignCurrentUser extends Base diff --git a/app/Action/TaskAssignCurrentUserColumn.php b/app/Action/TaskAssignCurrentUserColumn.php index e4eade33..60ada7ef 100644 --- a/app/Action/TaskAssignCurrentUserColumn.php +++ b/app/Action/TaskAssignCurrentUserColumn.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskModel; /** * Assign a task to the logged user on column change * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskAssignCurrentUserColumn extends Base diff --git a/app/Action/TaskAssignDueDateOnCreation.php b/app/Action/TaskAssignDueDateOnCreation.php index 79ff765c..5c6e2b61 100644 --- a/app/Action/TaskAssignDueDateOnCreation.php +++ b/app/Action/TaskAssignDueDateOnCreation.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskModel; /** * Set the due date of task * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskAssignDueDateOnCreation extends Base diff --git a/app/Action/TaskAssignSpecificUser.php b/app/Action/TaskAssignSpecificUser.php index 2c7dcacd..daf9e1df 100644 --- a/app/Action/TaskAssignSpecificUser.php +++ b/app/Action/TaskAssignSpecificUser.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskModel; /** * Assign a task to a specific user * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskAssignSpecificUser extends Base diff --git a/app/Action/TaskAssignUser.php b/app/Action/TaskAssignUser.php index 9ea22986..8727b672 100644 --- a/app/Action/TaskAssignUser.php +++ b/app/Action/TaskAssignUser.php @@ -5,7 +5,7 @@ namespace Kanboard\Action; /** * Assign a task to someone * - * @package action + * @package Kanboard\Actionv * @author Frederic Guillot */ class TaskAssignUser extends Base diff --git a/app/Action/TaskClose.php b/app/Action/TaskClose.php index 91e8cf43..e476e9ba 100644 --- a/app/Action/TaskClose.php +++ b/app/Action/TaskClose.php @@ -5,7 +5,7 @@ namespace Kanboard\Action; /** * Close automatically a task * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskClose extends Base diff --git a/app/Action/TaskCloseColumn.php b/app/Action/TaskCloseColumn.php index 4f1ffc92..523996f4 100644 --- a/app/Action/TaskCloseColumn.php +++ b/app/Action/TaskCloseColumn.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskModel; /** * Close automatically a task in a specific column * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskCloseColumn extends Base diff --git a/app/Action/TaskCloseNoActivity.php b/app/Action/TaskCloseNoActivity.php index 5a10510f..ea724d8c 100644 --- a/app/Action/TaskCloseNoActivity.php +++ b/app/Action/TaskCloseNoActivity.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskModel; /** * Close automatically a task after when inactive * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskCloseNoActivity extends Base diff --git a/app/Action/TaskCloseNoActivityColumn.php b/app/Action/TaskCloseNoActivityColumn.php index 7af0b7fc..b2ee5224 100644 --- a/app/Action/TaskCloseNoActivityColumn.php +++ b/app/Action/TaskCloseNoActivityColumn.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskModel; /** * Close automatically a task after inactive and in an defined column * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskCloseNoActivityColumn extends Base diff --git a/app/Action/TaskCreation.php b/app/Action/TaskCreation.php index 0620afd3..01d91228 100644 --- a/app/Action/TaskCreation.php +++ b/app/Action/TaskCreation.php @@ -5,7 +5,7 @@ namespace Kanboard\Action; /** * Create automatically a task from a webhook * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskCreation extends Base diff --git a/app/Action/TaskDuplicateAnotherProject.php b/app/Action/TaskDuplicateAnotherProject.php index d6d8d51f..0ad7713c 100644 --- a/app/Action/TaskDuplicateAnotherProject.php +++ b/app/Action/TaskDuplicateAnotherProject.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskModel; /** * Duplicate a task to another project * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskDuplicateAnotherProject extends Base diff --git a/app/Action/TaskEmail.php b/app/Action/TaskEmail.php index 526e9aa8..fdfe7987 100644 --- a/app/Action/TaskEmail.php +++ b/app/Action/TaskEmail.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskModel; /** * Email a task to someone * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskEmail extends Base diff --git a/app/Action/TaskEmailNoActivity.php b/app/Action/TaskEmailNoActivity.php index c60702fb..cac4281e 100644 --- a/app/Action/TaskEmailNoActivity.php +++ b/app/Action/TaskEmailNoActivity.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskModel; /** * Email a task with no activity * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskEmailNoActivity extends Base diff --git a/app/Action/TaskMoveAnotherProject.php b/app/Action/TaskMoveAnotherProject.php index 148b6b0c..0fa22b1b 100644 --- a/app/Action/TaskMoveAnotherProject.php +++ b/app/Action/TaskMoveAnotherProject.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskModel; /** * Move a task to another project * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskMoveAnotherProject extends Base diff --git a/app/Action/TaskMoveColumnAssigned.php b/app/Action/TaskMoveColumnAssigned.php index 1c1f657a..1cfe6743 100644 --- a/app/Action/TaskMoveColumnAssigned.php +++ b/app/Action/TaskMoveColumnAssigned.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskModel; /** * Move a task to another column when an assignee is set * - * @package action + * @package Kanboard\Action * @author Francois Ferrand */ class TaskMoveColumnAssigned extends Base diff --git a/app/Action/TaskMoveColumnCategoryChange.php b/app/Action/TaskMoveColumnCategoryChange.php index 4c2b289a..13d6ee4f 100644 --- a/app/Action/TaskMoveColumnCategoryChange.php +++ b/app/Action/TaskMoveColumnCategoryChange.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskModel; /** * Move a task to another column when the category is changed * - * @package action + * @package Kanboard\Action * @author Francois Ferrand */ class TaskMoveColumnCategoryChange extends Base diff --git a/app/Action/TaskMoveColumnClosed.php b/app/Action/TaskMoveColumnClosed.php new file mode 100644 index 00000000..3f3e2124 --- /dev/null +++ b/app/Action/TaskMoveColumnClosed.php @@ -0,0 +1,102 @@ +<?php + +namespace Kanboard\Action; + +use Kanboard\Model\TaskModel; + +/** + * Move a task to another column when the task is closed + * + * @package Kanboard\Action + * @author Frederic Guillot + */ +class TaskMoveColumnClosed extends Base +{ + /** + * Get automatic action description + * + * @access public + * @return string + */ + public function getDescription() + { + return t('Move the task to another column when closed'); + } + + /** + * Get the list of compatible events + * + * @access public + * @return array + */ + public function getCompatibleEvents() + { + return array( + TaskModel::EVENT_CLOSE, + ); + } + + /** + * Get the required parameter for the action (defined by the user) + * + * @access public + * @return array + */ + public function getActionRequiredParameters() + { + return array( + 'dest_column_id' => t('Destination column'), + ); + } + + /** + * Get the required parameter for the event + * + * @access public + * @return string[] + */ + public function getEventRequiredParameters() + { + return array( + 'task_id', + 'task' => array( + 'project_id', + 'column_id', + 'swimlane_id', + 'is_active', + ) + ); + } + + /** + * 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) + { + return $this->taskPositionModel->movePosition( + $data['task']['project_id'], + $data['task']['id'], + $this->getParam('dest_column_id'), + 1, + $data['task']['swimlane_id'], + false, + false + ); + } + + /** + * 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['task']['column_id'] != $this->getParam('dest_column_id') && $data['task']['is_active'] == 0; + } +} diff --git a/app/Action/TaskMoveColumnUnAssigned.php b/app/Action/TaskMoveColumnUnAssigned.php index 0e9a8a16..ab63d624 100644 --- a/app/Action/TaskMoveColumnUnAssigned.php +++ b/app/Action/TaskMoveColumnUnAssigned.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskModel; /** * Move a task to another column when an assignee is cleared * - * @package action + * @package Kanboard\Action * @author Francois Ferrand */ class TaskMoveColumnUnAssigned extends Base diff --git a/app/Action/TaskOpen.php b/app/Action/TaskOpen.php index 8e847b8e..49017831 100644 --- a/app/Action/TaskOpen.php +++ b/app/Action/TaskOpen.php @@ -5,7 +5,7 @@ namespace Kanboard\Action; /** * Open automatically a task * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskOpen extends Base diff --git a/app/Action/TaskUpdateStartDate.php b/app/Action/TaskUpdateStartDate.php index cc016da1..160f6ee5 100644 --- a/app/Action/TaskUpdateStartDate.php +++ b/app/Action/TaskUpdateStartDate.php @@ -7,7 +7,7 @@ use Kanboard\Model\TaskModel; /** * Set the start date of task * - * @package action + * @package Kanboard\Action * @author Frederic Guillot */ class TaskUpdateStartDate extends Base diff --git a/app/Model/TaskPositionModel.php b/app/Model/TaskPositionModel.php index d6d2a0af..3d95a763 100644 --- a/app/Model/TaskPositionModel.php +++ b/app/Model/TaskPositionModel.php @@ -16,15 +16,16 @@ class TaskPositionModel extends Base * Move a task to another column or to another position * * @access public - * @param integer $project_id Project id - * @param integer $task_id Task id - * @param integer $column_id Column id - * @param integer $position Position (must be >= 1) - * @param integer $swimlane_id Swimlane id - * @param boolean $fire_events Fire events - * @return boolean + * @param integer $project_id Project id + * @param integer $task_id Task id + * @param integer $column_id Column id + * @param integer $position Position (must be >= 1) + * @param integer $swimlane_id Swimlane id + * @param boolean $fire_events Fire events + * @param bool $onlyOpen Do not move closed tasks + * @return bool */ - public function movePosition($project_id, $task_id, $column_id, $position, $swimlane_id = 0, $fire_events = true) + public function movePosition($project_id, $task_id, $column_id, $position, $swimlane_id = 0, $fire_events = true, $onlyOpen = true) { if ($position < 1) { return false; @@ -32,7 +33,7 @@ class TaskPositionModel extends Base $task = $this->taskFinderModel->getById($task_id); - if ($task['is_active'] == TaskModel::STATUS_CLOSED) { + if ($onlyOpen && $task['is_active'] == TaskModel::STATUS_CLOSED) { return true; } diff --git a/app/ServiceProvider/ActionProvider.php b/app/ServiceProvider/ActionProvider.php index c76555fa..cbc60679 100644 --- a/app/ServiceProvider/ActionProvider.php +++ b/app/ServiceProvider/ActionProvider.php @@ -4,6 +4,7 @@ namespace Kanboard\ServiceProvider; use Kanboard\Action\TaskAssignColorPriority; use Kanboard\Action\TaskAssignDueDateOnCreation; +use Kanboard\Action\TaskMoveColumnClosed; use Pimple\Container; use Pimple\ServiceProviderInterface; use Kanboard\Core\Action\ActionManager; @@ -78,6 +79,7 @@ class ActionProvider implements ServiceProviderInterface $container['actionManager']->register(new TaskMoveAnotherProject($container)); $container['actionManager']->register(new TaskMoveColumnAssigned($container)); $container['actionManager']->register(new TaskMoveColumnCategoryChange($container)); + $container['actionManager']->register(new TaskMoveColumnClosed($container)); $container['actionManager']->register(new TaskMoveColumnUnAssigned($container)); $container['actionManager']->register(new TaskOpen($container)); $container['actionManager']->register(new TaskUpdateStartDate($container)); diff --git a/tests/units/Action/TaskMoveColumnClosedTest.php b/tests/units/Action/TaskMoveColumnClosedTest.php new file mode 100644 index 00000000..318b995d --- /dev/null +++ b/tests/units/Action/TaskMoveColumnClosedTest.php @@ -0,0 +1,91 @@ +<?php + +use Kanboard\Action\TaskMoveColumnClosed; +use Kanboard\EventBuilder\TaskEventBuilder; +use Kanboard\Model\ProjectModel; +use Kanboard\Model\TaskCreationModel; +use Kanboard\Model\TaskFinderModel; +use Kanboard\Model\TaskModel; + +require_once __DIR__.'/../Base.php'; + +class TaskMoveColumnClosedTest extends Base +{ + public function testSuccess() + { + $projectModel = new ProjectModel($this->container); + $taskCreationModel = new TaskCreationModel($this->container); + $taskFinderModel = new TaskFinderModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test', 'is_active' => 0))); + + $event = TaskEventBuilder::getInstance($this->container) + ->withTaskId(1) + ->buildEvent(); + + $action = new TaskMoveColumnClosed($this->container); + $action->setProjectId(1); + $action->setParam('dest_column_id', 2); + + $this->assertTrue($action->execute($event, TaskModel::EVENT_CLOSE)); + + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals('test', $task['title']); + $this->assertEquals(2, $task['column_id']); + } + + public function testWhenTaskIsOpen() + { + $projectModel = new ProjectModel($this->container); + $taskCreationModel = new TaskCreationModel($this->container); + $taskFinderModel = new TaskFinderModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test'))); + + $event = TaskEventBuilder::getInstance($this->container) + ->withTaskId(1) + ->buildEvent(); + + $action = new TaskMoveColumnClosed($this->container); + $action->setProjectId(1); + $action->setParam('dest_column_id', 2); + + $this->assertFalse($action->execute($event, TaskModel::EVENT_CLOSE)); + + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals('test', $task['title']); + $this->assertEquals(1, $task['column_id']); + } + + public function testWhenTaskIsAlreadyInDestinationColumn() + { + $projectModel = new ProjectModel($this->container); + $taskCreationModel = new TaskCreationModel($this->container); + $taskFinderModel = new TaskFinderModel($this->container); + + $this->assertEquals(1, $projectModel->create(array('name' => 'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' => 'test2'))); + $this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test', 'is_active' => 0, 'column_id' => 2))); + + $event = TaskEventBuilder::getInstance($this->container) + ->withTaskId(1) + ->buildEvent(); + + $action = new TaskMoveColumnClosed($this->container); + $action->setProjectId(1); + $action->setParam('dest_column_id', 2); + + $this->assertFalse($action->execute($event, TaskModel::EVENT_CLOSE)); + + $task = $taskFinderModel->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals('test', $task['title']); + $this->assertEquals(2, $task['column_id']); + } +} |