diff options
-rw-r--r-- | app/Controller/Task.php | 33 | ||||
-rw-r--r-- | app/Locales/de_DE/translations.php | 2 | ||||
-rw-r--r-- | app/Locales/es_ES/translations.php | 2 | ||||
-rw-r--r-- | app/Locales/fi_FI/translations.php | 2 | ||||
-rw-r--r-- | app/Locales/fr_FR/translations.php | 2 | ||||
-rw-r--r-- | app/Locales/it_IT/translations.php | 2 | ||||
-rw-r--r-- | app/Locales/pl_PL/translations.php | 2 | ||||
-rw-r--r-- | app/Locales/pt_BR/translations.php | 2 | ||||
-rw-r--r-- | app/Locales/sv_SE/translations.php | 2 | ||||
-rw-r--r-- | app/Locales/zh_CN/translations.php | 2 | ||||
-rw-r--r-- | app/Model/Category.php | 13 | ||||
-rw-r--r-- | app/Model/Task.php | 96 | ||||
-rw-r--r-- | app/Templates/task_duplicate.php | 14 | ||||
-rw-r--r-- | app/Templates/task_show.php | 1 | ||||
-rw-r--r-- | app/Templates/task_sidebar.php | 2 | ||||
-rw-r--r-- | tests/units/ActionTest.php | 12 | ||||
-rw-r--r-- | tests/units/TaskTest.php | 27 |
17 files changed, 137 insertions, 79 deletions
diff --git a/app/Controller/Task.php b/app/Controller/Task.php index 35ef6965..e905ef30 100644 --- a/app/Controller/Task.php +++ b/app/Controller/Task.php @@ -332,7 +332,7 @@ class Task extends Base } /** - * Duplicate a task (fill the form for a new task) + * Duplicate a task * * @access public */ @@ -340,25 +340,24 @@ class Task extends Base { $task = $this->getTask(); - if (! empty($task['date_due'])) { - $task['date_due'] = date(t('m/d/Y'), $task['date_due']); - } - else { - $task['date_due'] = ''; - } + if ($this->request->getStringParam('confirmation') === 'yes') { - $task['score'] = $task['score'] ?: ''; + $this->checkCSRFParam(); + $task_id = $this->task->duplicateSameProject($task); - $this->response->html($this->template->layout('task_new', array( - 'errors' => array(), - 'values' => $task, - 'columns_list' => $this->board->getColumnsList($task['project_id']), - 'users_list' => $this->project->getUsersList($task['project_id']), - 'colors_list' => $this->task->getColors(), - 'categories_list' => $this->category->getList($task['project_id']), - 'duplicate' => true, + if ($task_id) { + $this->session->flash(t('Task created successfully.')); + $this->response->redirect('?controller=task&action=show&task_id='.$task_id); + } else { + $this->session->flashError(t('Unable to create this task.')); + $this->response->redirect('?controller=task&action=duplicate&task_id='.$task['id']); + } + } + + $this->response->html($this->taskLayout('task_duplicate', array( + 'task' => $task, 'menu' => 'tasks', - 'title' => t('New task') + 'title' => t('Duplicate a task') ))); } diff --git a/app/Locales/de_DE/translations.php b/app/Locales/de_DE/translations.php index 868e33ba..eaa32aa6 100644 --- a/app/Locales/de_DE/translations.php +++ b/app/Locales/de_DE/translations.php @@ -436,4 +436,6 @@ return array( // 'Project activation' => '', // 'Move the task to another project' => '', // 'Move to another project' => '', + // 'Do you really want to duplicate this task?' => '', + // 'Duplicate a task' => '', ); diff --git a/app/Locales/es_ES/translations.php b/app/Locales/es_ES/translations.php index 3df0393e..93e0dd46 100644 --- a/app/Locales/es_ES/translations.php +++ b/app/Locales/es_ES/translations.php @@ -436,4 +436,6 @@ return array( // 'Project activation' => '', // 'Move the task to another project' => '', // 'Move to another project' => '', + // 'Do you really want to duplicate this task?' => '', + // 'Duplicate a task' => '', ); diff --git a/app/Locales/fi_FI/translations.php b/app/Locales/fi_FI/translations.php index aa9d9805..1d9d8150 100644 --- a/app/Locales/fi_FI/translations.php +++ b/app/Locales/fi_FI/translations.php @@ -436,4 +436,6 @@ return array( // 'Project activation' => '', // 'Move the task to another project' => '', // 'Move to another project' => '', + // 'Do you really want to duplicate this task?' => '', + // 'Duplicate a task' => '', ); diff --git a/app/Locales/fr_FR/translations.php b/app/Locales/fr_FR/translations.php index c80fdb9a..147e12f6 100644 --- a/app/Locales/fr_FR/translations.php +++ b/app/Locales/fr_FR/translations.php @@ -436,4 +436,6 @@ return array( 'Project activation' => 'Activation du projet', 'Move the task to another project' => 'Déplacer la tâche vers un autre projet', 'Move to another project' => 'Déplacer vers un autre projet', + 'Do you really want to duplicate this task?' => 'Voulez-vous vraiment dupliquer cette tâche ?', + 'Duplicate a task' => 'Dupliquer une tâche' ); diff --git a/app/Locales/it_IT/translations.php b/app/Locales/it_IT/translations.php index ff35aaf9..f313187e 100644 --- a/app/Locales/it_IT/translations.php +++ b/app/Locales/it_IT/translations.php @@ -436,4 +436,6 @@ return array( // 'Project activation' => '', // 'Move the task to another project' => '', // 'Move to another project' => '', + // 'Do you really want to duplicate this task?' => '', + // 'Duplicate a task' => '', ); diff --git a/app/Locales/pl_PL/translations.php b/app/Locales/pl_PL/translations.php index f74b84c1..7967a674 100644 --- a/app/Locales/pl_PL/translations.php +++ b/app/Locales/pl_PL/translations.php @@ -436,4 +436,6 @@ return array( // 'Project activation' => '', // 'Move the task to another project' => '', // 'Move to another project' => '', + // 'Do you really want to duplicate this task?' => '', + // 'Duplicate a task' => '', ); diff --git a/app/Locales/pt_BR/translations.php b/app/Locales/pt_BR/translations.php index 1836c385..f8e68d74 100644 --- a/app/Locales/pt_BR/translations.php +++ b/app/Locales/pt_BR/translations.php @@ -436,4 +436,6 @@ return array( // 'Project activation' => '', // 'Move the task to another project' => '', // 'Move to another project' => '', + // 'Do you really want to duplicate this task?' => '', + // 'Duplicate a task' => '', ); diff --git a/app/Locales/sv_SE/translations.php b/app/Locales/sv_SE/translations.php index 31f743c8..57a0e29d 100644 --- a/app/Locales/sv_SE/translations.php +++ b/app/Locales/sv_SE/translations.php @@ -436,4 +436,6 @@ return array( // 'Project activation' => '', // 'Move the task to another project' => '', // 'Move to another project' => '', + // 'Do you really want to duplicate this task?' => '', + // 'Duplicate a task' => '', ); diff --git a/app/Locales/zh_CN/translations.php b/app/Locales/zh_CN/translations.php index 97005794..dcbd3b74 100644 --- a/app/Locales/zh_CN/translations.php +++ b/app/Locales/zh_CN/translations.php @@ -436,4 +436,6 @@ return array( // 'Project activation' => '', // 'Move the task to another project' => '', // 'Move to another project' => '', + // 'Do you really want to duplicate this task?' => '', + // 'Duplicate a task' => '', ); diff --git a/app/Model/Category.php b/app/Model/Category.php index 58841f9a..4f296944 100644 --- a/app/Model/Category.php +++ b/app/Model/Category.php @@ -21,6 +21,19 @@ class Category extends Base const TABLE = 'project_has_categories'; /** + * Return true if a category exists for a given project + * + * @access public + * @param integer $category_id Category id + * @param integer $project_id Project id + * @return boolean + */ + public function exists($category_id, $project_id) + { + return $this->db->table(self::TABLE)->eq('id', $category_id)->eq('project_id', $project_id)->count() > 0; + } + + /** * Get a category by the id * * @access public diff --git a/app/Model/Task.php b/app/Model/Task.php index 30c1781b..6a20f4d0 100644 --- a/app/Model/Task.php +++ b/app/Model/Task.php @@ -263,55 +263,20 @@ class Task extends Base } /** - * Duplicate a task + * Generic method to duplicate a task * * @access public - * @param integer $task_id Task id - * @return boolean + * @param array $task Task data + * @param array $override Task properties to override + * @return integer|boolean */ - public function duplicate($task_id) + public function copy(array $task, array $override = array()) { - $this->db->startTransaction(); - - // Get the original task - $task = $this->getById($task_id); - - // Cleanup data - unset($task['id']); - unset($task['date_completed']); - - // Assign new values - $task['date_creation'] = time(); - $task['is_active'] = 1; - $task['position'] = $this->countByColumnId($task['project_id'], $task['column_id']); - - // Save task - if (! $this->db->table(self::TABLE)->save($task)) { - $this->db->cancelTransaction(); - return false; + // Values to override + if (! empty($override)) { + $task = $override + $task; } - $task_id = $this->db->getConnection()->getLastId(); - - $this->db->closeTransaction(); - - // Trigger events - $this->event->trigger(self::EVENT_CREATE_UPDATE, array('task_id' => $task_id) + $task); - $this->event->trigger(self::EVENT_CREATE, array('task_id' => $task_id) + $task); - - return $task_id; - } - - /** - * Duplicate a task to another project (always copy to the first column) - * - * @access public - * @param integer $project_id Destination project id - * @param array $task Task data - * @return boolean - */ - public function duplicateToAnotherProject($project_id, array $task) - { $this->db->startTransaction(); // Assign new values @@ -322,19 +287,24 @@ class Task extends Base $values['date_modification'] = $values['date_creation']; $values['date_due'] = $task['date_due']; $values['color_id'] = $task['color_id']; - $values['project_id'] = $project_id; - $values['column_id'] = $this->board->getFirstColumn($project_id); + $values['project_id'] = $task['project_id']; + $values['column_id'] = $task['column_id']; $values['owner_id'] = 0; $values['creator_id'] = $task['creator_id']; - $values['position'] = $this->countByColumnId($project_id, $values['column_id']); + $values['position'] = $this->countByColumnId($values['project_id'], $values['column_id']) + 1; $values['score'] = $task['score']; $values['category_id'] = 0; // Check if the assigned user is allowed for the new project - if ($task['owner_id'] && $this->project->isUserAllowed($project_id, $task['owner_id'])) { + if ($task['owner_id'] && $this->project->isUserAllowed($values['project_id'], $task['owner_id'])) { $values['owner_id'] = $task['owner_id']; } + // Check if the category exists + if ($task['category_id'] && $this->category->exists($task['category_id'], $task['project_id'])) { + $values['category_id'] = $task['category_id']; + } + // Save task if (! $this->db->table(self::TABLE)->save($values)) { $this->db->cancelTransaction(); @@ -359,6 +329,34 @@ class Task extends Base } /** + * Duplicate a task to the same project + * + * @access public + * @param array $task Task data + * @return integer|boolean + */ + public function duplicateSameProject($task) + { + return $this->copy($task); + } + + /** + * Duplicate a task to another project (always copy to the first column) + * + * @access public + * @param integer $project_id Destination project id + * @param array $task Task data + * @return integer|boolean + */ + public function duplicateToAnotherProject($project_id, array $task) + { + return $this->copy($task, array( + 'project_id' => $project_id, + 'column_id' => $this->board->getFirstColumn($project_id), + )); + } + + /** * Prepare data before task creation or modification * * @access public @@ -399,7 +397,7 @@ class Task extends Base $this->prepare($values); $values['date_creation'] = time(); $values['date_modification'] = $values['date_creation']; - $values['position'] = $this->countByColumnId($values['project_id'], $values['column_id']); + $values['position'] = $this->countByColumnId($values['project_id'], $values['column_id']) + 1; // Save task if (! $this->db->table(self::TABLE)->save($values)) { @@ -592,7 +590,7 @@ class Task extends Base // We use the first column of the new project $values['column_id'] = $this->board->getFirstColumn($project_id); - $values['position'] = $this->countByColumnId($project_id, $values['column_id']); + $values['position'] = $this->countByColumnId($project_id, $values['column_id']) + 1; $values['project_id'] = $project_id; if ($this->db->table(self::TABLE)->eq('id', $task['id'])->update($values)) { diff --git a/app/Templates/task_duplicate.php b/app/Templates/task_duplicate.php new file mode 100644 index 00000000..ef903f1d --- /dev/null +++ b/app/Templates/task_duplicate.php @@ -0,0 +1,14 @@ +<div class="page-header"> + <h2><?= t('Duplicate a task') ?></h2> +</div> + +<div class="confirm"> + <p class="alert alert-info"> + <?= t('Do you really want to duplicate this task?') ?> + </p> + + <div class="form-actions"> + <a href="?controller=task&action=duplicate&confirmation=yes&task_id=<?= $task['id'].Helper\param_csrf() ?>" class="btn btn-red"><?= t('Yes') ?></a> + <?= t('or') ?> <a href="?controller=task&action=show&task_id=<?= $task['id'] ?>"><?= t('cancel') ?></a> + </div> +</div>
\ No newline at end of file diff --git a/app/Templates/task_show.php b/app/Templates/task_show.php index 329fde80..a152bf07 100644 --- a/app/Templates/task_show.php +++ b/app/Templates/task_show.php @@ -41,6 +41,7 @@ <strong><?= Helper\escape($task['column_title']) ?></strong> (<?= Helper\escape($task['project_name']) ?>) </li> + <li><?= t('Task position:').' '.Helper\escape($task['position']) ?></li> <?php if ($task['category_name']): ?> <li> <?= t('Category:') ?> <strong><?= Helper\escape($task['category_name']) ?></strong> diff --git a/app/Templates/task_sidebar.php b/app/Templates/task_sidebar.php index 43170aa6..5d93d7b1 100644 --- a/app/Templates/task_sidebar.php +++ b/app/Templates/task_sidebar.php @@ -9,8 +9,8 @@ <li><a href="?controller=comment&action=create&task_id=<?= $task['id'] ?>"><?= t('Add a comment') ?></a></li> <li><a href="?controller=file&action=create&task_id=<?= $task['id'] ?>"><?= t('Attach a document') ?></a></li> <li><a href="?controller=task&action=duplicate&project_id=<?= $task['project_id'] ?>&task_id=<?= $task['id'] ?>"><?= t('Duplicate') ?></a></li> - <li><a href="?controller=task&action=move&project_id=<?= $task['project_id'] ?>&task_id=<?= $task['id'] ?>"><?= t('Move to another project') ?></a></li> <li><a href="?controller=task&action=copy&project_id=<?= $task['project_id'] ?>&task_id=<?= $task['id'] ?>"><?= t('Duplicate to another project') ?></a></li> + <li><a href="?controller=task&action=move&project_id=<?= $task['project_id'] ?>&task_id=<?= $task['id'] ?>"><?= t('Move to another project') ?></a></li> <li> <?php if ($task['is_active'] == 1): ?> <a href="?controller=task&action=confirmClose&task_id=<?= $task['id'] ?>"><?= t('Close this task') ?></a> diff --git a/tests/units/ActionTest.php b/tests/units/ActionTest.php index b6528333..19226449 100644 --- a/tests/units/ActionTest.php +++ b/tests/units/ActionTest.php @@ -142,29 +142,29 @@ class ActionTest extends Base // Our task should have the color red and position=0 $t1 = $task->getById(1); - $this->assertEquals(0, $t1['position']); + $this->assertEquals(1, $t1['position']); $this->assertEquals(1, $t1['is_active']); $this->assertEquals('red', $t1['color_id']); $t1 = $task->getById(2); - $this->assertEquals(1, $t1['position']); + $this->assertEquals(2, $t1['position']); $this->assertEquals(1, $t1['is_active']); $this->assertEquals('yellow', $t1['color_id']); // We move our tasks - $task->movePosition(1, 1, 1); // task #1 to position 1 - $task->movePosition(2, 1, 0); // task #2 to position 0 + $task->movePosition(1, 1, 2); // task #1 to position 2 + $task->movePosition(2, 1, 1); // task #2 to position 1 $this->assertTrue($this->registry->event->isEventTriggered(Task::EVENT_MOVE_POSITION)); // Both tasks should be green $t1 = $task->getById(1); - $this->assertEquals(1, $t1['position']); + $this->assertEquals(2, $t1['position']); $this->assertEquals(1, $t1['is_active']); $this->assertEquals('green', $t1['color_id']); $t1 = $task->getById(2); - $this->assertEquals(0, $t1['position']); + $this->assertEquals(1, $t1['position']); $this->assertEquals(1, $t1['is_active']); $this->assertEquals('green', $t1['color_id']); } diff --git a/tests/units/TaskTest.php b/tests/units/TaskTest.php index 064f30b0..e1a976c1 100644 --- a/tests/units/TaskTest.php +++ b/tests/units/TaskTest.php @@ -132,21 +132,29 @@ class TaskTest extends Base $this->assertEquals('2014-03-05', date('Y-m-d', $t->parseDate('03/05/2014'))); } - public function testDuplicateTask() + public function testDuplicateToTheSameProject() { $t = new Task($this->registry); $p = new Project($this->registry); + $c = new Category($this->registry); // We create a task and a project $this->assertEquals(1, $p->create(array('name' => 'test1'))); + + // Some categories + $this->assertNotFalse($c->create(array('name' => 'Category #1', 'project_id' => 1))); + $this->assertNotFalse($c->create(array('name' => 'Category #2', 'project_id' => 1))); + $this->assertTrue($c->exists(1, 1)); + $this->assertTrue($c->exists(2, 1)); + $this->assertEquals(1, $t->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 3, 'owner_id' => 1, 'category_id' => 2))); $task = $t->getById(1); $this->assertNotEmpty($task); - $this->assertEquals(0, $task['position']); + $this->assertEquals(1, $task['position']); // We duplicate our task - $this->assertEquals(2, $t->duplicate(1)); + $this->assertEquals(2, $t->duplicateSameProject($task)); $this->assertTrue($this->registry->event->isEventTriggered(Task::EVENT_CREATE)); // Check the values of the duplicated task @@ -155,21 +163,26 @@ class TaskTest extends Base $this->assertEquals(Task::STATUS_OPEN, $task['is_active']); $this->assertEquals(1, $task['project_id']); $this->assertEquals(1, $task['owner_id']); - $this->assertEquals(1, $task['position']); $this->assertEquals(2, $task['category_id']); + $this->assertEquals(3, $task['column_id']); + $this->assertEquals(2, $task['position']); } public function testDuplicateToAnotherProject() { $t = new Task($this->registry); $p = new Project($this->registry); + $c = new Category($this->registry); // We create 2 projects $this->assertEquals(1, $p->create(array('name' => 'test1'))); $this->assertEquals(2, $p->create(array('name' => 'test2'))); + $this->assertNotFalse($c->create(array('name' => 'Category #1', 'project_id' => 1))); + $this->assertTrue($c->exists(1, 1)); + // We create a task - $this->assertEquals(1, $t->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1, 'owner_id' => 1, 'category_id' => 1))); + $this->assertEquals(1, $t->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 2, 'owner_id' => 1, 'category_id' => 1))); $task = $t->getById(1); // We duplicate our task to the 2nd project @@ -181,6 +194,8 @@ class TaskTest extends Base $this->assertNotEmpty($task); $this->assertEquals(1, $task['owner_id']); $this->assertEquals(0, $task['category_id']); + $this->assertEquals(5, $task['column_id']); + $this->assertEquals(1, $task['position']); $this->assertEquals(2, $task['project_id']); $this->assertEquals('test', $task['title']); } @@ -215,7 +230,7 @@ class TaskTest extends Base $this->assertEquals(0, $task['category_id']); $this->assertEquals(2, $task['project_id']); $this->assertEquals(5, $task['column_id']); - $this->assertEquals(0, $task['position']); + $this->assertEquals(1, $task['position']); $this->assertEquals('test', $task['title']); // We allow only one user on the second project |