Add class SubtaskListFormatter

This commit is contained in:
Frederic Guillot 2017-02-26 16:06:09 -05:00
parent 4a87fb34ba
commit 4f325193be
9 changed files with 118 additions and 98 deletions

View File

@ -69,6 +69,7 @@ use Pimple\Container;
* @property \Kanboard\Formatter\GroupAutoCompleteFormatter $groupAutoCompleteFormatter * @property \Kanboard\Formatter\GroupAutoCompleteFormatter $groupAutoCompleteFormatter
* @property \Kanboard\Formatter\ProjectActivityEventFormatter $projectActivityEventFormatter * @property \Kanboard\Formatter\ProjectActivityEventFormatter $projectActivityEventFormatter
* @property \Kanboard\Formatter\ProjectGanttFormatter $projectGanttFormatter * @property \Kanboard\Formatter\ProjectGanttFormatter $projectGanttFormatter
* @property \Kanboard\Formatter\SubtaskListFormatter $subtaskListFormatter
* @property \Kanboard\Formatter\SubtaskTimeTrackingCalendarFormatter $subtaskTimeTrackingCalendarFormatter * @property \Kanboard\Formatter\SubtaskTimeTrackingCalendarFormatter $subtaskTimeTrackingCalendarFormatter
* @property \Kanboard\Formatter\TaskAutoCompleteFormatter $taskAutoCompleteFormatter * @property \Kanboard\Formatter\TaskAutoCompleteFormatter $taskAutoCompleteFormatter
* @property \Kanboard\Formatter\TaskCalendarFormatter $taskCalendarFormatter * @property \Kanboard\Formatter\TaskCalendarFormatter $taskCalendarFormatter

View File

@ -63,7 +63,7 @@ class SubtaskEventBuilder extends BaseEventBuilder
public function buildEvent() public function buildEvent()
{ {
$eventData = array(); $eventData = array();
$eventData['subtask'] = $this->subtaskModel->getById($this->subtaskId, true); $eventData['subtask'] = $this->subtaskModel->getByIdWithDetails($this->subtaskId);
if (empty($eventData['subtask'])) { if (empty($eventData['subtask'])) {
$this->logger->debug(__METHOD__.': Subtask not found'); $this->logger->debug(__METHOD__.': Subtask not found');

View File

@ -0,0 +1,34 @@
<?php
namespace Kanboard\Formatter;
use Kanboard\Core\Filter\FormatterInterface;
/**
* Class SubtaskListFormatter
*
* @package Kanboard\Formatter
* @author Frederic Guillot
*/
class SubtaskListFormatter extends BaseFormatter implements FormatterInterface
{
/**
* Apply formatter
*
* @access public
* @return mixed
*/
public function format()
{
$status = $this->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;
}
}

View File

@ -42,14 +42,14 @@ class SubtaskModel extends Base
* Get projectId from subtaskId * Get projectId from subtaskId
* *
* @access public * @access public
* @param integer $subtask_id * @param integer $subtaskId
* @return integer * @return integer
*/ */
public function getProjectId($subtask_id) public function getProjectId($subtaskId)
{ {
return $this->db return $this->db
->table(self::TABLE) ->table(self::TABLE)
->eq(self::TABLE.'.id', $subtask_id) ->eq(self::TABLE.'.id', $subtaskId)
->join(TaskModel::TABLE, 'id', 'task_id') ->join(TaskModel::TABLE, 'id', 'task_id')
->findOneColumn(TaskModel::TABLE . '.project_id') ?: 0; ->findOneColumn(TaskModel::TABLE . '.project_id') ?: 0;
} }
@ -63,9 +63,9 @@ class SubtaskModel extends Base
public function getStatusList() public function getStatusList()
{ {
return array( return array(
self::STATUS_TODO => t('Todo'), self::STATUS_TODO => t('Todo'),
self::STATUS_INPROGRESS => t('In progress'), 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 * Get the query to fetch subtasks assigned to a user
* *
* @access public * @access public
* @param integer $user_id User id * @param integer $userId
* @param array $status List of status * @param array $status
* @return \PicoDb\Table * @return \PicoDb\Table
*/ */
public function getUserQuery($user_id, array $status) public function getUserQuery($userId, array $status)
{ {
return $this->db->table(SubtaskModel::TABLE) return $this->db->table(SubtaskModel::TABLE)
->columns( ->columns(
@ -87,8 +87,8 @@ class SubtaskModel extends Base
TaskModel::TABLE.'.title AS task_name', TaskModel::TABLE.'.title AS task_name',
ProjectModel::TABLE.'.name AS project_name' ProjectModel::TABLE.'.name AS project_name'
) )
->subquery($this->subtaskTimeTrackingModel->getTimerQuery($user_id), 'timer_start_date') ->subquery($this->subtaskTimeTrackingModel->getTimerQuery($userId), 'timer_start_date')
->eq('user_id', $user_id) ->eq('user_id', $userId)
->eq(ProjectModel::TABLE.'.is_active', ProjectModel::ACTIVE) ->eq(ProjectModel::TABLE.'.is_active', ProjectModel::ACTIVE)
->eq(ColumnModel::TABLE.'.hide_in_dashboard', 0) ->eq(ColumnModel::TABLE.'.hide_in_dashboard', 0)
->in(SubtaskModel::TABLE.'.status', $status) ->in(SubtaskModel::TABLE.'.status', $status)
@ -98,66 +98,82 @@ class SubtaskModel extends Base
->callback(array($this, 'addStatusName')); ->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 * Get all subtasks for a given task
* *
* @access public * @access public
* @param integer $task_id Task id * @param integer $taskId
* @return array * @return array
*/ */
public function getAll($task_id) public function getAll($taskId)
{ {
return $this->db return $this->subtaskListFormatter
->table(self::TABLE) ->withQuery($this->getQuery()->eq('task_id', $taskId))
->eq('task_id', $task_id) ->format();
->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();
} }
/** /**
* Get a subtask by the id * Get a subtask by the id
* *
* @access public * @access public
* @param integer $subtask_id Subtask id * @param integer $subtaskId
* @param bool $more Fetch more data
* @return array * @return array
*/ */
public function getById($subtask_id, $more = false) public function getById($subtaskId)
{ {
if ($more) { return $this->db->table(self::TABLE)->eq('id', $subtaskId)->findOne();
return $this->db }
->table(self::TABLE)
->eq(self::TABLE.'.id', $subtask_id) /**
->columns(self::TABLE.'.*', UserModel::TABLE.'.username', UserModel::TABLE.'.name') * Get subtask with additional information
->subquery($this->subtaskTimeTrackingModel->getTimerQuery($this->userSession->getId()), 'timer_start_date') *
->join(UserModel::TABLE, 'id', 'user_id') * @param integer $subtaskId
->callback(array($this, 'addStatusName')) * @return array|null
->findOne(); */
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 * Get the position of the last column for a given project
* *
* @access public * @access public
* @param integer $task_id Task id * @param integer $taskId
* @return integer * @return integer
*/ */
public function getLastPosition($task_id) public function getLastPosition($taskId)
{ {
return (int) $this->db return (int) $this->db
->table(self::TABLE) ->table(self::TABLE)
->eq('task_id', $task_id) ->eq('task_id', $taskId)
->desc('position') ->desc('position')
->findOneColumn('position'); ->findOneColumn('position');
} }
@ -172,25 +188,25 @@ class SubtaskModel extends Base
public function create(array $values) public function create(array $values)
{ {
$this->prepareCreation($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->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 * @access public
* @param array $values * @param array $values
* @param bool $fire_event * @param bool $fireEvent
* @return bool * @return bool
*/ */
public function update(array $values, $fire_event = true) public function update(array $values, $fireEvent = true)
{ {
$this->prepare($values); $this->prepare($values);
$result = $this->db->table(self::TABLE)->eq('id', $values['id'])->save($values); $result = $this->db->table(self::TABLE)->eq('id', $values['id'])->save($values);
@ -198,7 +214,7 @@ class SubtaskModel extends Base
if ($result) { if ($result) {
$this->subtaskTimeTrackingModel->updateTaskTimeTracking($values['task_id']); $this->subtaskTimeTrackingModel->updateTaskTimeTracking($values['task_id']);
if ($fire_event) { if ($fireEvent) {
$this->queueManager->push($this->subtaskEventJob->withParams($values['id'], self::EVENT_UPDATE, $values)); $this->queueManager->push($this->subtaskEventJob->withParams($values['id'], self::EVENT_UPDATE, $values));
} }
} }
@ -210,35 +226,35 @@ class SubtaskModel extends Base
* Remove * Remove
* *
* @access public * @access public
* @param integer $subtask_id Subtask id * @param integer $subtaskId
* @return bool * @return bool
*/ */
public function remove($subtask_id) public function remove($subtaskId)
{ {
$this->subtaskEventJob->execute($subtask_id, self::EVENT_DELETE); $this->subtaskEventJob->execute($subtaskId, self::EVENT_DELETE);
return $this->db->table(self::TABLE)->eq('id', $subtask_id)->remove(); return $this->db->table(self::TABLE)->eq('id', $subtaskId)->remove();
} }
/** /**
* Duplicate all subtasks to another task * Duplicate all subtasks to another task
* *
* @access public * @access public
* @param integer $src_task_id Source task id * @param integer $srcTaskId
* @param integer $dst_task_id Destination task id * @param integer $dstTaskId
* @return bool * @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) $subtasks = $db->table(SubtaskModel::TABLE)
->columns('title', 'time_estimated', 'position') ->columns('title', 'time_estimated', 'position')
->eq('task_id', $src_task_id) ->eq('task_id', $srcTaskId)
->asc('position') ->asc('position')
->findAll(); ->findAll();
foreach ($subtasks as &$subtask) { foreach ($subtasks as &$subtask) {
$subtask['task_id'] = $dst_task_id; $subtask['task_id'] = $dstTaskId;
if (! $db->table(SubtaskModel::TABLE)->save($subtask)) { if (! $db->table(SubtaskModel::TABLE)->save($subtask)) {
return false; return false;

View File

@ -99,38 +99,6 @@ class SubtaskTimeTrackingModel extends Base
->eq(TaskModel::TABLE.'.id', $task_id); ->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 * Get all recorded time slots for a given user
* *

View File

@ -23,6 +23,7 @@ class FormatterProvider implements ServiceProviderInterface
'GroupAutoCompleteFormatter', 'GroupAutoCompleteFormatter',
'ProjectActivityEventFormatter', 'ProjectActivityEventFormatter',
'ProjectGanttFormatter', 'ProjectGanttFormatter',
'SubtaskListFormatter',
'SubtaskTimeTrackingCalendarFormatter', 'SubtaskTimeTrackingCalendarFormatter',
'TaskAutoCompleteFormatter', 'TaskAutoCompleteFormatter',
'TaskCalendarFormatter', 'TaskCalendarFormatter',

View File

@ -35,7 +35,7 @@ class NotificationModelTest extends Base
$this->assertEquals(1, $taskLinkModel->create(1, 2, 1)); $this->assertEquals(1, $taskLinkModel->create(1, 2, 1));
$task = $taskFinderModel->getDetails(1); $task = $taskFinderModel->getDetails(1);
$subtask = $subtaskModel->getById(1, true); $subtask = $subtaskModel->getByIdWithDetails(1);
$comment = $commentModel->getById(1); $comment = $commentModel->getById(1);
$file = $commentModel->getById(1); $file = $commentModel->getById(1);
$tasklink = $taskLinkModel->getById(1); $tasklink = $taskLinkModel->getById(1);
@ -76,7 +76,7 @@ class NotificationModelTest extends Base
$this->assertEquals(1, $taskFileModel->create(1, 'test', 'blah', 123)); $this->assertEquals(1, $taskFileModel->create(1, 'test', 'blah', 123));
$task = $taskFinderModel->getDetails(1); $task = $taskFinderModel->getDetails(1);
$subtask = $subtaskModel->getById(1, true); $subtask = $subtaskModel->getByIdWithDetails(1);
$comment = $commentModel->getById(1); $comment = $commentModel->getById(1);
$file = $commentModel->getById(1); $file = $commentModel->getById(1);
$tasklink = $taskLinkModel->getById(1); $tasklink = $taskLinkModel->getById(1);

View File

@ -85,7 +85,7 @@ class SubtaskTimeTrackingModelTest extends Base
$this->assertEquals(0, $subtasks[0]['timer_start_date']); $this->assertEquals(0, $subtasks[0]['timer_start_date']);
$this->assertFalse($subtasks[0]['is_timer_started']); $this->assertFalse($subtasks[0]['is_timer_started']);
$subtask = $subtaskModel->getById(1, true); $subtask = $subtaskModel->getByIdWithDetails(1);
$this->assertNotEmpty($subtask); $this->assertNotEmpty($subtask);
$this->assertEquals(0, $subtask['timer_start_date']); $this->assertEquals(0, $subtask['timer_start_date']);
$this->assertFalse($subtask['is_timer_started']); $this->assertFalse($subtask['is_timer_started']);
@ -98,7 +98,7 @@ class SubtaskTimeTrackingModelTest extends Base
$this->assertEquals(time(), $subtasks[0]['timer_start_date'], '', 3); $this->assertEquals(time(), $subtasks[0]['timer_start_date'], '', 3);
$this->assertTrue($subtasks[0]['is_timer_started']); $this->assertTrue($subtasks[0]['is_timer_started']);
$subtask = $subtaskModel->getById(1, true); $subtask = $subtaskModel->getByIdWithDetails(1);
$this->assertNotEmpty($subtask); $this->assertNotEmpty($subtask);
$this->assertEquals(time(), $subtask['timer_start_date'], '', 3); $this->assertEquals(time(), $subtask['timer_start_date'], '', 3);
$this->assertTrue($subtask['is_timer_started']); $this->assertTrue($subtask['is_timer_started']);
@ -110,7 +110,7 @@ class SubtaskTimeTrackingModelTest extends Base
$this->assertEquals(0, $subtasks[0]['timer_start_date']); $this->assertEquals(0, $subtasks[0]['timer_start_date']);
$this->assertFalse($subtasks[0]['is_timer_started']); $this->assertFalse($subtasks[0]['is_timer_started']);
$subtask = $subtaskModel->getById(1, true); $subtask = $subtaskModel->getByIdWithDetails(1);
$this->assertNotEmpty($subtask); $this->assertNotEmpty($subtask);
$this->assertEquals(0, $subtask['timer_start_date']); $this->assertEquals(0, $subtask['timer_start_date']);
$this->assertFalse($subtask['is_timer_started']); $this->assertFalse($subtask['is_timer_started']);

View File

@ -36,7 +36,7 @@ class MailNotificationTest extends Base
$this->assertEquals(1, $taskLinkModel->create(1, 2, 1)); $this->assertEquals(1, $taskLinkModel->create(1, 2, 1));
$task = $taskFinderModel->getDetails(1); $task = $taskFinderModel->getDetails(1);
$subtask = $subtaskModel->getById(1, true); $subtask = $subtaskModel->getByIdWithDetails(1);
$comment = $commentModel->getById(1); $comment = $commentModel->getById(1);
$file = $commentModel->getById(1); $file = $commentModel->getById(1);
$tasklink = $taskLinkModel->getById(1); $tasklink = $taskLinkModel->getById(1);