diff options
-rw-r--r-- | app/Controller/Task.php | 53 | ||||
-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/Acl.php | 1 | ||||
-rw-r--r-- | app/Model/Board.php | 2 | ||||
-rw-r--r-- | app/Model/Task.php | 53 | ||||
-rw-r--r-- | app/Templates/task_edit_description.php | 11 | ||||
-rw-r--r-- | app/Templates/task_move_project.php | 18 | ||||
-rw-r--r-- | app/Templates/task_sidebar.php | 1 | ||||
-rw-r--r-- | tests/units/ActionTest.php | 8 | ||||
-rw-r--r-- | tests/units/TaskTest.php | 52 |
18 files changed, 194 insertions, 23 deletions
diff --git a/app/Controller/Task.php b/app/Controller/Task.php index 7414f7f9..0fc42ce4 100644 --- a/app/Controller/Task.php +++ b/app/Controller/Task.php @@ -352,7 +352,6 @@ class Task extends Base $this->response->html($this->template->layout('task_new', array( 'errors' => array(), 'values' => $task, - 'projects_list' => $this->project->getListByStatus(ProjectModel::ACTIVE), 'columns_list' => $this->board->getColumnsList($task['project_id']), 'users_list' => $this->project->getUsersList($task['project_id']), 'colors_list' => $this->task->getColors(), @@ -373,13 +372,14 @@ class Task extends Base $task = $this->getTask(); $params = array( - 'values' => $task, - 'errors' => array(), - 'task' => $task, - 'ajax' => $this->request->isAjax(), - 'menu' => 'tasks', - 'title' => t('Edit the description') - ); + 'values' => $task, + 'errors' => array(), + 'task' => $task, + 'ajax' => $this->request->isAjax(), + 'menu' => 'tasks', + 'title' => t('Edit the description'), + ); + if ($this->request->isAjax()) { $this->response->html($this->template->load('task_edit_description', $params)); } @@ -425,4 +425,41 @@ class Task extends Base 'title' => t('Edit the description') ))); } + + /** + * Move a task to another project + * + * @access public + */ + public function move() + { + $task = $this->getTask(); + $values = $task; + $errors = array(); + + if ($this->request->isPost()) { + + $values = $this->request->getValues(); + list($valid, $errors) = $this->task->validateProjectModification($values); + + if ($valid) { + if ($this->task->moveToAnotherProject($values['project_id'], $task)) { + $this->session->flash(t('Task updated successfully.')); + $this->response->redirect('?controller=task&action=show&task_id='.$values['id']); + } + else { + $this->session->flashError(t('Unable to update your task.')); + } + } + } + + $this->response->html($this->taskLayout('task_move_project', array( + 'values' => $values, + 'errors' => $errors, + 'task' => $task, + 'projects_list' => $this->project->getAvailableList($this->acl->getUserId()), + 'menu' => 'tasks', + 'title' => t('Move the task to another project') + ))); + } } diff --git a/app/Locales/de_DE/translations.php b/app/Locales/de_DE/translations.php index 2a5a4c0c..868e33ba 100644 --- a/app/Locales/de_DE/translations.php +++ b/app/Locales/de_DE/translations.php @@ -434,4 +434,6 @@ return array( // 'Do you really want to duplicate this project: "%s"?' => '', // 'Do you really want to enable this project: "%s"?' => '', // 'Project activation' => '', + // 'Move the task to another project' => '', + // 'Move to another project' => '', ); diff --git a/app/Locales/es_ES/translations.php b/app/Locales/es_ES/translations.php index 0edf3837..3df0393e 100644 --- a/app/Locales/es_ES/translations.php +++ b/app/Locales/es_ES/translations.php @@ -434,4 +434,6 @@ return array( // 'Do you really want to duplicate this project: "%s"?' => '', // 'Do you really want to enable this project: "%s"?' => '', // 'Project activation' => '', + // 'Move the task to another project' => '', + // 'Move to another project' => '', ); diff --git a/app/Locales/fi_FI/translations.php b/app/Locales/fi_FI/translations.php index df0d4176..aa9d9805 100644 --- a/app/Locales/fi_FI/translations.php +++ b/app/Locales/fi_FI/translations.php @@ -434,4 +434,6 @@ return array( // 'Do you really want to duplicate this project: "%s"?' => '', // 'Do you really want to enable this project: "%s"?' => '', // 'Project activation' => '', + // 'Move the task to another project' => '', + // 'Move to another project' => '', ); diff --git a/app/Locales/fr_FR/translations.php b/app/Locales/fr_FR/translations.php index cfb0733f..477361bd 100644 --- a/app/Locales/fr_FR/translations.php +++ b/app/Locales/fr_FR/translations.php @@ -434,4 +434,6 @@ return array( 'Do you really want to duplicate this project: "%s"?' => 'Voulez-vous vraiment dupliquer ce projet : « %s » ?', 'Do you really want to enable this project: "%s"?' => 'Voulez-vous vraiment activer ce projet : « %s » ?', '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', ); diff --git a/app/Locales/it_IT/translations.php b/app/Locales/it_IT/translations.php index 9dad1d6d..ff35aaf9 100644 --- a/app/Locales/it_IT/translations.php +++ b/app/Locales/it_IT/translations.php @@ -434,4 +434,6 @@ return array( // 'Do you really want to duplicate this project: "%s"?' => '', // 'Do you really want to enable this project: "%s"?' => '', // 'Project activation' => '', + // 'Move the task to another project' => '', + // 'Move to another project' => '', ); diff --git a/app/Locales/pl_PL/translations.php b/app/Locales/pl_PL/translations.php index e042ef21..f74b84c1 100644 --- a/app/Locales/pl_PL/translations.php +++ b/app/Locales/pl_PL/translations.php @@ -434,4 +434,6 @@ return array( // 'Do you really want to duplicate this project: "%s"?' => '', // 'Do you really want to enable this project: "%s"?' => '', // 'Project activation' => '', + // 'Move the task to another project' => '', + // 'Move to another project' => '', ); diff --git a/app/Locales/pt_BR/translations.php b/app/Locales/pt_BR/translations.php index a0bad1c1..1836c385 100644 --- a/app/Locales/pt_BR/translations.php +++ b/app/Locales/pt_BR/translations.php @@ -434,4 +434,6 @@ return array( // 'Do you really want to duplicate this project: "%s"?' => '', // 'Do you really want to enable this project: "%s"?' => '', // 'Project activation' => '', + // 'Move the task to another project' => '', + // 'Move to another project' => '', ); diff --git a/app/Locales/sv_SE/translations.php b/app/Locales/sv_SE/translations.php index 5de96279..31f743c8 100644 --- a/app/Locales/sv_SE/translations.php +++ b/app/Locales/sv_SE/translations.php @@ -434,4 +434,6 @@ return array( // 'Do you really want to duplicate this project: "%s"?' => '', // 'Do you really want to enable this project: "%s"?' => '', // 'Project activation' => '', + // 'Move the task to another project' => '', + // 'Move to another project' => '', ); diff --git a/app/Locales/zh_CN/translations.php b/app/Locales/zh_CN/translations.php index 31addc37..97005794 100644 --- a/app/Locales/zh_CN/translations.php +++ b/app/Locales/zh_CN/translations.php @@ -434,4 +434,6 @@ return array( // 'Do you really want to duplicate this project: "%s"?' => '', // 'Do you really want to enable this project: "%s"?' => '', // 'Project activation' => '', + // 'Move the task to another project' => '', + // 'Move to another project' => '', ); diff --git a/app/Model/Acl.php b/app/Model/Acl.php index b2644686..23f6ff44 100644 --- a/app/Model/Acl.php +++ b/app/Model/Acl.php @@ -52,6 +52,7 @@ class Acl extends Base 'confirmremove', 'editdescription', 'savedescription', + 'move', ), ); diff --git a/app/Model/Board.php b/app/Model/Board.php index 74e29040..8fb30e70 100644 --- a/app/Model/Board.php +++ b/app/Model/Board.php @@ -35,7 +35,7 @@ class Board extends Base foreach ($positions as $value) { // We trigger events only for the selected task - if (! $this->task->move($value['task_id'], $value['column_id'], $value['position'], $value['task_id'] == $selected_task_id)) { + if (! $this->task->movePosition($value['task_id'], $value['column_id'], $value['position'], $value['task_id'] == $selected_task_id)) { $this->db->cancelTransaction(); return false; } diff --git a/app/Model/Task.php b/app/Model/Task.php index 09c77573..64f3b74c 100644 --- a/app/Model/Task.php +++ b/app/Model/Task.php @@ -545,7 +545,7 @@ class Task extends Base * @param boolean $trigger_events Flag to trigger events * @return boolean */ - public function move($task_id, $column_id, $position, $trigger_events = true) + public function movePosition($task_id, $column_id, $position, $trigger_events = true) { $this->event->clearTriggeredEvents(); @@ -559,6 +559,35 @@ class Task extends Base } /** + * Move a task to another project + * + * @access public + * @param integer $project_id Project id + * @param array $task Task data + * @return boolean + */ + public function moveToAnotherProject($project_id, array $task) + { + $values = array(); + + // Clear values (categories are different for each project) + $values['category_id'] = 0; + $values['owner_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'])) { + $values['owner_id'] = $task['owner_id']; + } + + // 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['project_id'] = $project_id; + + return $this->db->table(self::TABLE)->eq('id', $task['id'])->update($values); + } + + /** * Validate task creation * * @access public @@ -663,6 +692,28 @@ class Task extends Base } /** + * Validate project modification + * + * @access public + * @param array $values Form values + * @return array $valid, $errors [0] = Success or not, [1] = List of errors + */ + public function validateProjectModification(array $values) + { + $v = new Validator($values, array( + new Validators\Required('id', t('The id is required')), + new Validators\Integer('id', t('This value must be an integer')), + new Validators\Required('project_id', t('The project is required')), + new Validators\Integer('project_id', t('This value must be an integer')), + )); + + return array( + $v->execute(), + $v->getErrors() + ); + } + + /** * Return a timestamp if the given date format is correct otherwise return 0 * * @access public diff --git a/app/Templates/task_edit_description.php b/app/Templates/task_edit_description.php index e3a3e8b9..d403190f 100644 --- a/app/Templates/task_edit_description.php +++ b/app/Templates/task_edit_description.php @@ -13,11 +13,10 @@ <div class="form-actions"> <input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/> <?= t('or') ?> -<?php if ($ajax): ?> - <a href="?controller=board&action=show&project_id=<?= $task['project_id'] ?>"><?= t('cancel') ?></a> -<?php else: ?> - <a href="?controller=task&action=show&task_id=<?= $task['id'] ?>"><?= t('cancel') ?></a> -<?php endif ?> + <?php if ($ajax): ?> + <a href="?controller=board&action=show&project_id=<?= $task['project_id'] ?>"><?= t('cancel') ?></a> + <?php else: ?> + <a href="?controller=task&action=show&task_id=<?= $task['id'] ?>"><?= t('cancel') ?></a> + <?php endif ?> </div> </form> - diff --git a/app/Templates/task_move_project.php b/app/Templates/task_move_project.php new file mode 100644 index 00000000..190a93d9 --- /dev/null +++ b/app/Templates/task_move_project.php @@ -0,0 +1,18 @@ +<div class="page-header"> + <h2><?= t('Move the task to another project') ?></h2> +</div> + +<form method="post" action="?controller=task&action=move&task_id=<?= $task['id'] ?>&project_id=<?= $task['project_id'] ?>" autocomplete="off"> + + <?= Helper\form_csrf() ?> + + <?= Helper\form_hidden('id', $values) ?> + <?= Helper\form_label(t('Project'), 'project_id') ?> + <?= Helper\form_select('project_id', $projects_list, $values, $errors) ?><br/> + + <div class="form-actions"> + <input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/> + <?= t('or') ?> + <a href="?controller=board&action=show&project_id=<?= $task['project_id'] ?>"><?= t('cancel') ?></a> + </div> +</form>
\ No newline at end of file diff --git a/app/Templates/task_sidebar.php b/app/Templates/task_sidebar.php index d97c44e2..ba9d7a86 100644 --- a/app/Templates/task_sidebar.php +++ b/app/Templates/task_sidebar.php @@ -9,6 +9,7 @@ <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> <?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 8108767d..b6528333 100644 --- a/tests/units/ActionTest.php +++ b/tests/units/ActionTest.php @@ -84,7 +84,7 @@ class ActionTest extends Base $this->assertEquals(1, $t1['column_id']); // We move our task - $task->move(1, 4, 1); + $task->movePosition(1, 4, 1); $this->assertTrue($this->registry->event->isEventTriggered(Task::EVENT_MOVE_COLUMN)); $this->assertTrue($this->registry->event->isEventTriggered(Task::EVENT_UPDATE)); @@ -152,8 +152,8 @@ class ActionTest extends Base $this->assertEquals('yellow', $t1['color_id']); // We move our tasks - $task->move(1, 1, 1); // task #1 to position 1 - $task->move(2, 1, 0); // task #2 to position 0 + $task->movePosition(1, 1, 1); // task #1 to position 1 + $task->movePosition(2, 1, 0); // task #2 to position 0 $this->assertTrue($this->registry->event->isEventTriggered(Task::EVENT_MOVE_POSITION)); @@ -223,7 +223,7 @@ class ActionTest extends Base $this->assertEquals(1, $t1['project_id']); // We move our task - $task->move(1, 4, 1); + $task->movePosition(1, 4, 1); $this->assertTrue($this->registry->event->isEventTriggered(Task::EVENT_CLOSE)); $this->assertTrue($this->registry->event->isEventTriggered(Task::EVENT_MOVE_COLUMN)); diff --git a/tests/units/TaskTest.php b/tests/units/TaskTest.php index 1ea03fca..66f82016 100644 --- a/tests/units/TaskTest.php +++ b/tests/units/TaskTest.php @@ -5,6 +5,7 @@ require_once __DIR__.'/Base.php'; use Model\Task; use Model\Project; use Model\Category; +use Model\User; class TaskTest extends Base { @@ -183,6 +184,51 @@ class TaskTest extends Base $this->assertEquals('test', $task['title']); } + public function testMoveToAnotherProject() + { + $t = new Task($this->registry); + $p = new Project($this->registry); + $user = new User($this->registry); + + // We create a regular user + $user->create(array('username' => 'unittest1', 'password' => 'unittest')); + $user->create(array('username' => 'unittest2', 'password' => 'unittest')); + + // We create 2 projects + $this->assertEquals(1, $p->create(array('name' => 'test1'))); + $this->assertEquals(2, $p->create(array('name' => 'test2'))); + + // We create a task + $this->assertEquals(1, $t->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1, 'owner_id' => 1, 'category_id' => 10, 'position' => 333))); + $this->assertEquals(2, $t->create(array('title' => 'test2', 'project_id' => 1, 'column_id' => 1, 'owner_id' => 3, 'category_id' => 10, 'position' => 333))); + + // We duplicate our task to the 2nd project + $task = $t->getById(1); + $this->assertTrue($t->moveToAnotherProject(2, $task)); + //$this->assertTrue($this->registry->event->isEventTriggered(Task::EVENT_CREATE)); + + // Check the values of the duplicated task + $task = $t->getById(1); + $this->assertNotEmpty($task); + $this->assertEquals(1, $task['owner_id']); + $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('test', $task['title']); + + // We allow only one user on the second project + $this->assertTrue($p->allowUser(2, 2)); + + // The owner should be reseted + $task = $t->getById(2); + $this->assertTrue($t->moveToAnotherProject(2, $task)); + + $task = $t->getById(2); + $this->assertNotEmpty($task); + $this->assertEquals(0, $task['owner_id']); + } + public function testEvents() { $t = new Task($this->registry); @@ -209,15 +255,15 @@ class TaskTest extends Base $this->assertTrue($this->registry->event->isEventTriggered(Task::EVENT_OPEN)); // We change the column of our task - $this->assertTrue($t->move(1, 2, 1)); + $this->assertTrue($t->movePosition(1, 2, 1)); $this->assertTrue($this->registry->event->isEventTriggered(Task::EVENT_MOVE_COLUMN)); // We change the position of our task - $this->assertTrue($t->move(1, 2, 2)); + $this->assertTrue($t->movePosition(1, 2, 2)); $this->assertTrue($this->registry->event->isEventTriggered(Task::EVENT_MOVE_POSITION)); // We change the column and the position of our task - $this->assertTrue($t->move(1, 1, 3)); + $this->assertTrue($t->movePosition(1, 1, 3)); $this->assertTrue($this->registry->event->isEventTriggered(Task::EVENT_MOVE_COLUMN)); } } |