summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/Controller/Task.php33
-rw-r--r--app/Locales/de_DE/translations.php2
-rw-r--r--app/Locales/es_ES/translations.php2
-rw-r--r--app/Locales/fi_FI/translations.php2
-rw-r--r--app/Locales/fr_FR/translations.php2
-rw-r--r--app/Locales/it_IT/translations.php2
-rw-r--r--app/Locales/pl_PL/translations.php2
-rw-r--r--app/Locales/pt_BR/translations.php2
-rw-r--r--app/Locales/sv_SE/translations.php2
-rw-r--r--app/Locales/zh_CN/translations.php2
-rw-r--r--app/Model/Category.php13
-rw-r--r--app/Model/Task.php96
-rw-r--r--app/Templates/task_duplicate.php14
-rw-r--r--app/Templates/task_show.php1
-rw-r--r--app/Templates/task_sidebar.php2
-rw-r--r--tests/units/ActionTest.php12
-rw-r--r--tests/units/TaskTest.php27
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&amp;action=duplicate&amp;confirmation=yes&amp;task_id=<?= $task['id'].Helper\param_csrf() ?>" class="btn btn-red"><?= t('Yes') ?></a>
+ <?= t('or') ?> <a href="?controller=task&amp;action=show&amp;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&amp;action=create&amp;task_id=<?= $task['id'] ?>"><?= t('Add a comment') ?></a></li>
<li><a href="?controller=file&amp;action=create&amp;task_id=<?= $task['id'] ?>"><?= t('Attach a document') ?></a></li>
<li><a href="?controller=task&amp;action=duplicate&amp;project_id=<?= $task['project_id'] ?>&amp;task_id=<?= $task['id'] ?>"><?= t('Duplicate') ?></a></li>
- <li><a href="?controller=task&amp;action=move&amp;project_id=<?= $task['project_id'] ?>&amp;task_id=<?= $task['id'] ?>"><?= t('Move to another project') ?></a></li>
<li><a href="?controller=task&amp;action=copy&amp;project_id=<?= $task['project_id'] ?>&amp;task_id=<?= $task['id'] ?>"><?= t('Duplicate to another project') ?></a></li>
+ <li><a href="?controller=task&amp;action=move&amp;project_id=<?= $task['project_id'] ?>&amp;task_id=<?= $task['id'] ?>"><?= t('Move to another project') ?></a></li>
<li>
<?php if ($task['is_active'] == 1): ?>
<a href="?controller=task&amp;action=confirmClose&amp;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