Move Task::duplicate() to class ProjectTaskDuplicationModel

This commit is contained in:
Frederic Guillot
2016-07-02 15:29:48 -04:00
parent 6d5577fa0b
commit b7ac354e83
8 changed files with 75 additions and 59 deletions

View File

@@ -86,6 +86,7 @@ use Pimple\Container;
* @property \Kanboard\Model\ProjectGroupRoleModel $projectGroupRoleModel * @property \Kanboard\Model\ProjectGroupRoleModel $projectGroupRoleModel
* @property \Kanboard\Model\ProjectNotificationModel $projectNotificationModel * @property \Kanboard\Model\ProjectNotificationModel $projectNotificationModel
* @property \Kanboard\Model\ProjectNotificationTypeModel $projectNotificationTypeModel * @property \Kanboard\Model\ProjectNotificationTypeModel $projectNotificationTypeModel
* @property \Kanboard\Model\ProjectTaskDuplicationModel $projectTaskDuplicationModel
* @property \Kanboard\Model\RememberMeSessionModel $rememberMeSessionModel * @property \Kanboard\Model\RememberMeSessionModel $rememberMeSessionModel
* @property \Kanboard\Model\SubtaskModel $subtaskModel * @property \Kanboard\Model\SubtaskModel $subtaskModel
* @property \Kanboard\Model\SubtaskTimeTrackingModel $subtaskTimeTrackingModel * @property \Kanboard\Model\SubtaskTimeTrackingModel $subtaskTimeTrackingModel

View File

@@ -29,7 +29,7 @@ class ProjectDuplicationModel extends Base
'swimlaneModel', 'swimlaneModel',
'tagDuplicationModel', 'tagDuplicationModel',
'projectMetadataModel', 'projectMetadataModel',
'taskModel', 'projectTaskDuplicationModel',
); );
} }
@@ -49,7 +49,7 @@ class ProjectDuplicationModel extends Base
'swimlaneModel', 'swimlaneModel',
'tagDuplicationModel', 'tagDuplicationModel',
'projectMetadataModel', 'projectMetadataModel',
'taskModel', 'projectTaskDuplicationModel',
); );
} }

View File

@@ -0,0 +1,35 @@
<?php
namespace Kanboard\Model;
use Kanboard\Core\Base;
/**
* Project Task Duplication Model
*
* @package Kanboard\Model
* @author Frederic Guillot
*/
class ProjectTaskDuplicationModel extends Base
{
/**
* Duplicate all tasks to another project
*
* @access public
* @param integer $src_project_id
* @param integer $dst_project_id
* @return boolean
*/
public function duplicate($src_project_id, $dst_project_id)
{
$task_ids = $this->taskFinderModel->getAllIds($src_project_id, array(TaskModel::STATUS_OPEN, TaskModel::STATUS_CLOSED));
foreach ($task_ids as $task_id) {
if (! $this->taskProjectDuplicationModel->duplicateToProject($task_id, $dst_project_id)) {
return false;
}
}
return true;
}
}

View File

@@ -17,80 +17,80 @@ class TaskModel extends Base
* *
* @var string * @var string
*/ */
const TABLE = 'tasks'; const TABLE = 'tasks';
/** /**
* Task status * Task status
* *
* @var integer * @var integer
*/ */
const STATUS_OPEN = 1; const STATUS_OPEN = 1;
const STATUS_CLOSED = 0; const STATUS_CLOSED = 0;
/** /**
* Events * Events
* *
* @var string * @var string
*/ */
const EVENT_MOVE_PROJECT = 'task.move.project'; const EVENT_MOVE_PROJECT = 'task.move.project';
const EVENT_MOVE_COLUMN = 'task.move.column'; const EVENT_MOVE_COLUMN = 'task.move.column';
const EVENT_MOVE_POSITION = 'task.move.position'; const EVENT_MOVE_POSITION = 'task.move.position';
const EVENT_MOVE_SWIMLANE = 'task.move.swimlane'; const EVENT_MOVE_SWIMLANE = 'task.move.swimlane';
const EVENT_UPDATE = 'task.update'; const EVENT_UPDATE = 'task.update';
const EVENT_CREATE = 'task.create'; const EVENT_CREATE = 'task.create';
const EVENT_CLOSE = 'task.close'; const EVENT_CLOSE = 'task.close';
const EVENT_OPEN = 'task.open'; const EVENT_OPEN = 'task.open';
const EVENT_CREATE_UPDATE = 'task.create_update'; const EVENT_CREATE_UPDATE = 'task.create_update';
const EVENT_ASSIGNEE_CHANGE = 'task.assignee_change'; const EVENT_ASSIGNEE_CHANGE = 'task.assignee_change';
const EVENT_OVERDUE = 'task.overdue'; const EVENT_OVERDUE = 'task.overdue';
const EVENT_USER_MENTION = 'task.user.mention'; const EVENT_USER_MENTION = 'task.user.mention';
const EVENT_DAILY_CRONJOB = 'task.cronjob.daily'; const EVENT_DAILY_CRONJOB = 'task.cronjob.daily';
/** /**
* Recurrence: status * Recurrence: status
* *
* @var integer * @var integer
*/ */
const RECURRING_STATUS_NONE = 0; const RECURRING_STATUS_NONE = 0;
const RECURRING_STATUS_PENDING = 1; const RECURRING_STATUS_PENDING = 1;
const RECURRING_STATUS_PROCESSED = 2; const RECURRING_STATUS_PROCESSED = 2;
/** /**
* Recurrence: trigger * Recurrence: trigger
* *
* @var integer * @var integer
*/ */
const RECURRING_TRIGGER_FIRST_COLUMN = 0; const RECURRING_TRIGGER_FIRST_COLUMN = 0;
const RECURRING_TRIGGER_LAST_COLUMN = 1; const RECURRING_TRIGGER_LAST_COLUMN = 1;
const RECURRING_TRIGGER_CLOSE = 2; const RECURRING_TRIGGER_CLOSE = 2;
/** /**
* Recurrence: timeframe * Recurrence: timeframe
* *
* @var integer * @var integer
*/ */
const RECURRING_TIMEFRAME_DAYS = 0; const RECURRING_TIMEFRAME_DAYS = 0;
const RECURRING_TIMEFRAME_MONTHS = 1; const RECURRING_TIMEFRAME_MONTHS = 1;
const RECURRING_TIMEFRAME_YEARS = 2; const RECURRING_TIMEFRAME_YEARS = 2;
/** /**
* Recurrence: base date used to calculate new due date * Recurrence: base date used to calculate new due date
* *
* @var integer * @var integer
*/ */
const RECURRING_BASEDATE_DUEDATE = 0; const RECURRING_BASEDATE_DUEDATE = 0;
const RECURRING_BASEDATE_TRIGGERDATE = 1; const RECURRING_BASEDATE_TRIGGERDATE = 1;
/** /**
* Remove a task * Remove a task
* *
* @access public * @access public
* @param integer $task_id Task id * @param integer $task_id Task id
* @return boolean * @return boolean
*/ */
public function remove($task_id) public function remove($task_id)
{ {
if (! $this->taskFinderModel->exists($task_id)) { if (!$this->taskFinderModel->exists($task_id)) {
return false; return false;
} }
@@ -105,7 +105,7 @@ class TaskModel extends Base
* Example: "Fix bug #1234" will return 1234 * Example: "Fix bug #1234" will return 1234
* *
* @access public * @access public
* @param string $message Text * @param string $message Text
* @return integer * @return integer
*/ */
public function getTaskIdFromText($message) public function getTaskIdFromText($message)
@@ -179,8 +179,8 @@ class TaskModel extends Base
* Get task progress based on the column position * Get task progress based on the column position
* *
* @access public * @access public
* @param array $task * @param array $task
* @param array $columns * @param array $columns
* @return integer * @return integer
*/ */
public function getProgress(array $task, array $columns) public function getProgress(array $task, array $columns)
@@ -201,25 +201,4 @@ class TaskModel extends Base
return round(($position * 100) / count($columns), 1); return round(($position * 100) / count($columns), 1);
} }
/**
* Helper method to duplicate all tasks to another project
*
* @access public
* @param integer $src_project_id
* @param integer $dst_project_id
* @return boolean
*/
public function duplicate($src_project_id, $dst_project_id)
{
$task_ids = $this->taskFinderModel->getAllIds($src_project_id, array(TaskModel::STATUS_OPEN, TaskModel::STATUS_CLOSED));
foreach ($task_ids as $task_id) {
if (! $this->taskProjectDuplicationModel->duplicateToProject($task_id, $dst_project_id)) {
return false;
}
}
return true;
}
} }

View File

@@ -55,6 +55,7 @@ class ClassProvider implements ServiceProviderInterface
'ProjectNotificationModel', 'ProjectNotificationModel',
'ProjectMetadataModel', 'ProjectMetadataModel',
'ProjectGroupRoleModel', 'ProjectGroupRoleModel',
'ProjectTaskDuplicationModel',
'ProjectUserRoleModel', 'ProjectUserRoleModel',
'RememberMeSessionModel', 'RememberMeSessionModel',
'SubtaskModel', 'SubtaskModel',

View File

@@ -26,7 +26,7 @@
<?= $this->form->checkbox('tagDuplicationModel', t('Tags'), 1, true) ?> <?= $this->form->checkbox('tagDuplicationModel', t('Tags'), 1, true) ?>
<?= $this->form->checkbox('actionModel', t('Actions'), 1, true) ?> <?= $this->form->checkbox('actionModel', t('Actions'), 1, true) ?>
<?= $this->form->checkbox('swimlaneModel', t('Swimlanes'), 1, true) ?> <?= $this->form->checkbox('swimlaneModel', t('Swimlanes'), 1, true) ?>
<?= $this->form->checkbox('taskModel', t('Tasks'), 1, false) ?> <?= $this->form->checkbox('projectTaskDuplicationModel', t('Tasks'), 1, false) ?>
</div> </div>
<div class="form-actions"> <div class="form-actions">

View File

@@ -19,7 +19,7 @@
<?= $this->form->checkbox('actionModel', t('Actions'), 1, true) ?> <?= $this->form->checkbox('actionModel', t('Actions'), 1, true) ?>
<?= $this->form->checkbox('swimlaneModel', t('Swimlanes'), 1, false) ?> <?= $this->form->checkbox('swimlaneModel', t('Swimlanes'), 1, false) ?>
<?= $this->form->checkbox('projectMetadataModel', t('Metadata'), 1, false) ?> <?= $this->form->checkbox('projectMetadataModel', t('Metadata'), 1, false) ?>
<?= $this->form->checkbox('taskModel', t('Tasks'), 1, false) ?> <?= $this->form->checkbox('projectTaskDuplicationModel', t('Tasks'), 1, false) ?>
<div class="form-actions"> <div class="form-actions">
<button type="submit" class="btn btn-red"><?= t('Duplicate') ?></button> <button type="submit" class="btn btn-red"><?= t('Duplicate') ?></button>

View File

@@ -428,7 +428,7 @@ class ProjectDuplicationModelTest extends Base
$this->assertEquals(2, $taskCreationModel->create(array('title' => 'T2', 'project_id' => 1, 'column_id' => 2))); $this->assertEquals(2, $taskCreationModel->create(array('title' => 'T2', 'project_id' => 1, 'column_id' => 2)));
$this->assertEquals(3, $taskCreationModel->create(array('title' => 'T3', 'project_id' => 1, 'column_id' => 3))); $this->assertEquals(3, $taskCreationModel->create(array('title' => 'T3', 'project_id' => 1, 'column_id' => 3)));
$this->assertEquals(2, $projectDuplicationModel->duplicate(1, array('categoryModel', 'actionModel', 'taskModel'))); $this->assertEquals(2, $projectDuplicationModel->duplicate(1, array('categoryModel', 'actionModel', 'projectTaskDuplicationModel')));
// Check if Tasks have been duplicated // Check if Tasks have been duplicated
$tasks = $taskFinderModel->getAll(2); $tasks = $taskFinderModel->getAll(2);
@@ -458,7 +458,7 @@ class ProjectDuplicationModelTest extends Base
$this->assertEquals(2, $taskCreationModel->create(array('title' => 'T2', 'project_id' => 1, 'column_id' => 2, 'owner_id' => 1))); $this->assertEquals(2, $taskCreationModel->create(array('title' => 'T2', 'project_id' => 1, 'column_id' => 2, 'owner_id' => 1)));
$this->assertEquals(3, $taskCreationModel->create(array('title' => 'T3', 'project_id' => 1, 'column_id' => 3, 'owner_id' => 1))); $this->assertEquals(3, $taskCreationModel->create(array('title' => 'T3', 'project_id' => 1, 'column_id' => 3, 'owner_id' => 1)));
$this->assertEquals(2, $projectDuplicationModel->duplicate(1, array('projectPermissionModel', 'swimlaneModel', 'taskModel'))); $this->assertEquals(2, $projectDuplicationModel->duplicate(1, array('projectPermissionModel', 'swimlaneModel', 'projectTaskDuplicationModel')));
// Check if Swimlanes have been duplicated // Check if Swimlanes have been duplicated
$swimlanes = $swimlaneModel->getAll(2); $swimlanes = $swimlaneModel->getAll(2);
@@ -496,7 +496,7 @@ class ProjectDuplicationModelTest extends Base
$this->assertEquals(2, $taskCreationModel->create(array('title' => 'T2', 'project_id' => 1, 'column_id' => 2, 'tags' => array('A', 'B')))); $this->assertEquals(2, $taskCreationModel->create(array('title' => 'T2', 'project_id' => 1, 'column_id' => 2, 'tags' => array('A', 'B'))));
$this->assertEquals(3, $taskCreationModel->create(array('title' => 'T3', 'project_id' => 1, 'column_id' => 3, 'tags' => array('C')))); $this->assertEquals(3, $taskCreationModel->create(array('title' => 'T3', 'project_id' => 1, 'column_id' => 3, 'tags' => array('C'))));
$this->assertEquals(2, $projectDuplicationModel->duplicate(1, array('categoryModel', 'actionModel', 'tagDuplicationModel', 'taskModel'))); $this->assertEquals(2, $projectDuplicationModel->duplicate(1, array('categoryModel', 'actionModel', 'tagDuplicationModel', 'projectTaskDuplicationModel')));
$tasks = $taskFinderModel->getAll(2); $tasks = $taskFinderModel->getAll(2);
$this->assertCount(3, $tasks); $this->assertCount(3, $tasks);