From 4f325193be4f16a9658258fecd525e71917156a0 Mon Sep 17 00:00:00 2001 From: Frederic Guillot Date: Sun, 26 Feb 2017 16:06:09 -0500 Subject: Add class SubtaskListFormatter --- app/Core/Base.php | 1 + app/EventBuilder/SubtaskEventBuilder.php | 2 +- app/Formatter/SubtaskListFormatter.php | 34 ++++++ app/Model/SubtaskModel.php | 134 ++++++++++++--------- app/Model/SubtaskTimeTrackingModel.php | 32 ----- app/ServiceProvider/FormatterProvider.php | 1 + tests/units/Model/NotificationModelTest.php | 4 +- tests/units/Model/SubtaskTimeTrackingModelTest.php | 6 +- tests/units/Notification/MailNotificationTest.php | 2 +- 9 files changed, 118 insertions(+), 98 deletions(-) create mode 100644 app/Formatter/SubtaskListFormatter.php diff --git a/app/Core/Base.php b/app/Core/Base.php index 3cc5199a..8ef34bfb 100644 --- a/app/Core/Base.php +++ b/app/Core/Base.php @@ -69,6 +69,7 @@ use Pimple\Container; * @property \Kanboard\Formatter\GroupAutoCompleteFormatter $groupAutoCompleteFormatter * @property \Kanboard\Formatter\ProjectActivityEventFormatter $projectActivityEventFormatter * @property \Kanboard\Formatter\ProjectGanttFormatter $projectGanttFormatter + * @property \Kanboard\Formatter\SubtaskListFormatter $subtaskListFormatter * @property \Kanboard\Formatter\SubtaskTimeTrackingCalendarFormatter $subtaskTimeTrackingCalendarFormatter * @property \Kanboard\Formatter\TaskAutoCompleteFormatter $taskAutoCompleteFormatter * @property \Kanboard\Formatter\TaskCalendarFormatter $taskCalendarFormatter diff --git a/app/EventBuilder/SubtaskEventBuilder.php b/app/EventBuilder/SubtaskEventBuilder.php index 5f7e831d..c1a41ae8 100644 --- a/app/EventBuilder/SubtaskEventBuilder.php +++ b/app/EventBuilder/SubtaskEventBuilder.php @@ -63,7 +63,7 @@ class SubtaskEventBuilder extends BaseEventBuilder public function buildEvent() { $eventData = array(); - $eventData['subtask'] = $this->subtaskModel->getById($this->subtaskId, true); + $eventData['subtask'] = $this->subtaskModel->getByIdWithDetails($this->subtaskId); if (empty($eventData['subtask'])) { $this->logger->debug(__METHOD__.': Subtask not found'); diff --git a/app/Formatter/SubtaskListFormatter.php b/app/Formatter/SubtaskListFormatter.php new file mode 100644 index 00000000..5b20111d --- /dev/null +++ b/app/Formatter/SubtaskListFormatter.php @@ -0,0 +1,34 @@ +subtaskModel->getStatusList(); + $subtasks = $this->query->findAll(); + + foreach ($subtasks as &$subtask) { + $subtask['status_name'] = $status[$subtask['status']]; + $subtask['timer_start_date'] = isset($subtask['timer_start_date']) ? $subtask['timer_start_date'] : 0; + $subtask['is_timer_started'] = ! empty($subtask['timer_start_date']); + } + + return $subtasks; + } +} diff --git a/app/Model/SubtaskModel.php b/app/Model/SubtaskModel.php index ca2c8488..af9af93b 100644 --- a/app/Model/SubtaskModel.php +++ b/app/Model/SubtaskModel.php @@ -42,14 +42,14 @@ class SubtaskModel extends Base * Get projectId from subtaskId * * @access public - * @param integer $subtask_id + * @param integer $subtaskId * @return integer */ - public function getProjectId($subtask_id) + public function getProjectId($subtaskId) { return $this->db ->table(self::TABLE) - ->eq(self::TABLE.'.id', $subtask_id) + ->eq(self::TABLE.'.id', $subtaskId) ->join(TaskModel::TABLE, 'id', 'task_id') ->findOneColumn(TaskModel::TABLE . '.project_id') ?: 0; } @@ -63,9 +63,9 @@ class SubtaskModel extends Base public function getStatusList() { return array( - self::STATUS_TODO => t('Todo'), + self::STATUS_TODO => t('Todo'), self::STATUS_INPROGRESS => t('In progress'), - self::STATUS_DONE => t('Done'), + self::STATUS_DONE => t('Done'), ); } @@ -73,11 +73,11 @@ class SubtaskModel extends Base * Get the query to fetch subtasks assigned to a user * * @access public - * @param integer $user_id User id - * @param array $status List of status + * @param integer $userId + * @param array $status * @return \PicoDb\Table */ - public function getUserQuery($user_id, array $status) + public function getUserQuery($userId, array $status) { return $this->db->table(SubtaskModel::TABLE) ->columns( @@ -87,8 +87,8 @@ class SubtaskModel extends Base TaskModel::TABLE.'.title AS task_name', ProjectModel::TABLE.'.name AS project_name' ) - ->subquery($this->subtaskTimeTrackingModel->getTimerQuery($user_id), 'timer_start_date') - ->eq('user_id', $user_id) + ->subquery($this->subtaskTimeTrackingModel->getTimerQuery($userId), 'timer_start_date') + ->eq('user_id', $userId) ->eq(ProjectModel::TABLE.'.is_active', ProjectModel::ACTIVE) ->eq(ColumnModel::TABLE.'.hide_in_dashboard', 0) ->in(SubtaskModel::TABLE.'.status', $status) @@ -98,66 +98,82 @@ class SubtaskModel extends Base ->callback(array($this, 'addStatusName')); } + /** + * Get common query + * + * @return \PicoDb\Table + */ + public function getQuery() + { + return $this->db + ->table(self::TABLE) + ->columns( + self::TABLE.'.*', + UserModel::TABLE.'.username', + UserModel::TABLE.'.name' + ) + ->subquery($this->subtaskTimeTrackingModel->getTimerQuery($this->userSession->getId()), 'timer_start_date') + ->join(UserModel::TABLE, 'id', 'user_id') + ->asc(self::TABLE.'.position'); + } + /** * Get all subtasks for a given task * * @access public - * @param integer $task_id Task id + * @param integer $taskId * @return array */ - public function getAll($task_id) + public function getAll($taskId) { - return $this->db - ->table(self::TABLE) - ->eq('task_id', $task_id) - ->columns( - self::TABLE.'.*', - UserModel::TABLE.'.username', - UserModel::TABLE.'.name' - ) - ->subquery($this->subtaskTimeTrackingModel->getTimerQuery($this->userSession->getId()), 'timer_start_date') - ->join(UserModel::TABLE, 'id', 'user_id') - ->asc(self::TABLE.'.position') - ->callback(array($this, 'addStatusName')) - ->findAll(); + return $this->subtaskListFormatter + ->withQuery($this->getQuery()->eq('task_id', $taskId)) + ->format(); } /** * Get a subtask by the id * * @access public - * @param integer $subtask_id Subtask id - * @param bool $more Fetch more data + * @param integer $subtaskId * @return array */ - public function getById($subtask_id, $more = false) + public function getById($subtaskId) { - if ($more) { - return $this->db - ->table(self::TABLE) - ->eq(self::TABLE.'.id', $subtask_id) - ->columns(self::TABLE.'.*', UserModel::TABLE.'.username', UserModel::TABLE.'.name') - ->subquery($this->subtaskTimeTrackingModel->getTimerQuery($this->userSession->getId()), 'timer_start_date') - ->join(UserModel::TABLE, 'id', 'user_id') - ->callback(array($this, 'addStatusName')) - ->findOne(); + return $this->db->table(self::TABLE)->eq('id', $subtaskId)->findOne(); + } + + /** + * Get subtask with additional information + * + * @param integer $subtaskId + * @return array|null + */ + public function getByIdWithDetails($subtaskId) + { + $subtasks = $this->subtaskListFormatter + ->withQuery($this->getQuery()->eq(self::TABLE.'.id', $subtaskId)) + ->format(); + + if (! empty($subtasks)) { + return $subtasks[0]; } - return $this->db->table(self::TABLE)->eq('id', $subtask_id)->findOne(); + return null; } /** * Get the position of the last column for a given project * * @access public - * @param integer $task_id Task id + * @param integer $taskId * @return integer */ - public function getLastPosition($task_id) + public function getLastPosition($taskId) { return (int) $this->db ->table(self::TABLE) - ->eq('task_id', $task_id) + ->eq('task_id', $taskId) ->desc('position') ->findOneColumn('position'); } @@ -172,25 +188,25 @@ class SubtaskModel extends Base public function create(array $values) { $this->prepareCreation($values); - $subtask_id = $this->db->table(self::TABLE)->persist($values); + $subtaskId = $this->db->table(self::TABLE)->persist($values); - if ($subtask_id !== false) { + if ($subtaskId !== false) { $this->subtaskTimeTrackingModel->updateTaskTimeTracking($values['task_id']); - $this->queueManager->push($this->subtaskEventJob->withParams($subtask_id, self::EVENT_CREATE)); + $this->queueManager->push($this->subtaskEventJob->withParams($subtaskId, self::EVENT_CREATE)); } - return $subtask_id; + return $subtaskId; } /** - * Update + * Update a subtask * * @access public * @param array $values - * @param bool $fire_event + * @param bool $fireEvent * @return bool */ - public function update(array $values, $fire_event = true) + public function update(array $values, $fireEvent = true) { $this->prepare($values); $result = $this->db->table(self::TABLE)->eq('id', $values['id'])->save($values); @@ -198,7 +214,7 @@ class SubtaskModel extends Base if ($result) { $this->subtaskTimeTrackingModel->updateTaskTimeTracking($values['task_id']); - if ($fire_event) { + if ($fireEvent) { $this->queueManager->push($this->subtaskEventJob->withParams($values['id'], self::EVENT_UPDATE, $values)); } } @@ -210,35 +226,35 @@ class SubtaskModel extends Base * Remove * * @access public - * @param integer $subtask_id Subtask id + * @param integer $subtaskId * @return bool */ - public function remove($subtask_id) + public function remove($subtaskId) { - $this->subtaskEventJob->execute($subtask_id, self::EVENT_DELETE); - return $this->db->table(self::TABLE)->eq('id', $subtask_id)->remove(); + $this->subtaskEventJob->execute($subtaskId, self::EVENT_DELETE); + return $this->db->table(self::TABLE)->eq('id', $subtaskId)->remove(); } /** * Duplicate all subtasks to another task * * @access public - * @param integer $src_task_id Source task id - * @param integer $dst_task_id Destination task id + * @param integer $srcTaskId + * @param integer $dstTaskId * @return bool */ - public function duplicate($src_task_id, $dst_task_id) + public function duplicate($srcTaskId, $dstTaskId) { - return $this->db->transaction(function (Database $db) use ($src_task_id, $dst_task_id) { + return $this->db->transaction(function (Database $db) use ($srcTaskId, $dstTaskId) { $subtasks = $db->table(SubtaskModel::TABLE) ->columns('title', 'time_estimated', 'position') - ->eq('task_id', $src_task_id) + ->eq('task_id', $srcTaskId) ->asc('position') ->findAll(); foreach ($subtasks as &$subtask) { - $subtask['task_id'] = $dst_task_id; + $subtask['task_id'] = $dstTaskId; if (! $db->table(SubtaskModel::TABLE)->save($subtask)) { return false; diff --git a/app/Model/SubtaskTimeTrackingModel.php b/app/Model/SubtaskTimeTrackingModel.php index 3b1b97e4..25fd95c7 100644 --- a/app/Model/SubtaskTimeTrackingModel.php +++ b/app/Model/SubtaskTimeTrackingModel.php @@ -99,38 +99,6 @@ class SubtaskTimeTrackingModel extends Base ->eq(TaskModel::TABLE.'.id', $task_id); } - /** - * Get query for project timesheet (pagination) - * - * @access public - * @param integer $project_id Project id - * @return \PicoDb\Table - */ - public function getProjectQuery($project_id) - { - return $this->db - ->table(self::TABLE) - ->columns( - self::TABLE.'.id', - self::TABLE.'.subtask_id', - self::TABLE.'.end', - self::TABLE.'.start', - self::TABLE.'.time_spent', - self::TABLE.'.user_id', - SubtaskModel::TABLE.'.task_id', - SubtaskModel::TABLE.'.title AS subtask_title', - TaskModel::TABLE.'.project_id', - TaskModel::TABLE.'.color_id', - UserModel::TABLE.'.username', - UserModel::TABLE.'.name AS user_fullname' - ) - ->join(SubtaskModel::TABLE, 'id', 'subtask_id') - ->join(TaskModel::TABLE, 'id', 'task_id', SubtaskModel::TABLE) - ->join(UserModel::TABLE, 'id', 'user_id', self::TABLE) - ->eq(TaskModel::TABLE.'.project_id', $project_id) - ->asc(self::TABLE.'.id'); - } - /** * Get all recorded time slots for a given user * diff --git a/app/ServiceProvider/FormatterProvider.php b/app/ServiceProvider/FormatterProvider.php index a9d25208..54f9f916 100644 --- a/app/ServiceProvider/FormatterProvider.php +++ b/app/ServiceProvider/FormatterProvider.php @@ -23,6 +23,7 @@ class FormatterProvider implements ServiceProviderInterface 'GroupAutoCompleteFormatter', 'ProjectActivityEventFormatter', 'ProjectGanttFormatter', + 'SubtaskListFormatter', 'SubtaskTimeTrackingCalendarFormatter', 'TaskAutoCompleteFormatter', 'TaskCalendarFormatter', diff --git a/tests/units/Model/NotificationModelTest.php b/tests/units/Model/NotificationModelTest.php index 0bd9db6e..e96e22bf 100644 --- a/tests/units/Model/NotificationModelTest.php +++ b/tests/units/Model/NotificationModelTest.php @@ -35,7 +35,7 @@ class NotificationModelTest extends Base $this->assertEquals(1, $taskLinkModel->create(1, 2, 1)); $task = $taskFinderModel->getDetails(1); - $subtask = $subtaskModel->getById(1, true); + $subtask = $subtaskModel->getByIdWithDetails(1); $comment = $commentModel->getById(1); $file = $commentModel->getById(1); $tasklink = $taskLinkModel->getById(1); @@ -76,7 +76,7 @@ class NotificationModelTest extends Base $this->assertEquals(1, $taskFileModel->create(1, 'test', 'blah', 123)); $task = $taskFinderModel->getDetails(1); - $subtask = $subtaskModel->getById(1, true); + $subtask = $subtaskModel->getByIdWithDetails(1); $comment = $commentModel->getById(1); $file = $commentModel->getById(1); $tasklink = $taskLinkModel->getById(1); diff --git a/tests/units/Model/SubtaskTimeTrackingModelTest.php b/tests/units/Model/SubtaskTimeTrackingModelTest.php index 8b0fe698..120cfc2c 100644 --- a/tests/units/Model/SubtaskTimeTrackingModelTest.php +++ b/tests/units/Model/SubtaskTimeTrackingModelTest.php @@ -85,7 +85,7 @@ class SubtaskTimeTrackingModelTest extends Base $this->assertEquals(0, $subtasks[0]['timer_start_date']); $this->assertFalse($subtasks[0]['is_timer_started']); - $subtask = $subtaskModel->getById(1, true); + $subtask = $subtaskModel->getByIdWithDetails(1); $this->assertNotEmpty($subtask); $this->assertEquals(0, $subtask['timer_start_date']); $this->assertFalse($subtask['is_timer_started']); @@ -98,7 +98,7 @@ class SubtaskTimeTrackingModelTest extends Base $this->assertEquals(time(), $subtasks[0]['timer_start_date'], '', 3); $this->assertTrue($subtasks[0]['is_timer_started']); - $subtask = $subtaskModel->getById(1, true); + $subtask = $subtaskModel->getByIdWithDetails(1); $this->assertNotEmpty($subtask); $this->assertEquals(time(), $subtask['timer_start_date'], '', 3); $this->assertTrue($subtask['is_timer_started']); @@ -110,7 +110,7 @@ class SubtaskTimeTrackingModelTest extends Base $this->assertEquals(0, $subtasks[0]['timer_start_date']); $this->assertFalse($subtasks[0]['is_timer_started']); - $subtask = $subtaskModel->getById(1, true); + $subtask = $subtaskModel->getByIdWithDetails(1); $this->assertNotEmpty($subtask); $this->assertEquals(0, $subtask['timer_start_date']); $this->assertFalse($subtask['is_timer_started']); diff --git a/tests/units/Notification/MailNotificationTest.php b/tests/units/Notification/MailNotificationTest.php index 93eeef0c..04e99c8a 100644 --- a/tests/units/Notification/MailNotificationTest.php +++ b/tests/units/Notification/MailNotificationTest.php @@ -36,7 +36,7 @@ class MailNotificationTest extends Base $this->assertEquals(1, $taskLinkModel->create(1, 2, 1)); $task = $taskFinderModel->getDetails(1); - $subtask = $subtaskModel->getById(1, true); + $subtask = $subtaskModel->getByIdWithDetails(1); $comment = $commentModel->getById(1); $file = $commentModel->getById(1); $tasklink = $taskLinkModel->getById(1); -- cgit v1.2.3