summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/Controller/Task.php106
-rw-r--r--app/Controller/Taskduplication.php143
-rw-r--r--app/Locale/da_DK/translations.php4
-rw-r--r--app/Locale/de_DE/translations.php4
-rw-r--r--app/Locale/es_ES/translations.php4
-rw-r--r--app/Locale/fi_FI/translations.php4
-rw-r--r--app/Locale/fr_FR/translations.php4
-rw-r--r--app/Locale/hu_HU/translations.php4
-rw-r--r--app/Locale/it_IT/translations.php4
-rw-r--r--app/Locale/ja_JP/translations.php4
-rw-r--r--app/Locale/nl_NL/translations.php4
-rw-r--r--app/Locale/pl_PL/translations.php4
-rw-r--r--app/Locale/pt_BR/translations.php4
-rw-r--r--app/Locale/ru_RU/translations.php4
-rw-r--r--app/Locale/sr_Latn_RS/translations.php4
-rw-r--r--app/Locale/sv_SE/translations.php4
-rw-r--r--app/Locale/th_TH/translations.php4
-rw-r--r--app/Locale/tr_TR/translations.php4
-rw-r--r--app/Locale/zh_CN/translations.php4
-rw-r--r--app/Model/Acl.php1
-rwxr-xr-xapp/Model/TaskDuplication.php41
-rw-r--r--app/Template/task/duplicate_project.php24
-rw-r--r--app/Template/task/move_project.php24
-rw-r--r--app/Template/task/sidebar.php6
-rw-r--r--app/Template/task_duplication/copy.php43
-rw-r--r--app/Template/task_duplication/duplicate.php (renamed from app/Template/task/duplicate.php)2
-rw-r--r--app/Template/task_duplication/move.php43
-rw-r--r--app/common.php6
28 files changed, 335 insertions, 172 deletions
diff --git a/app/Controller/Task.php b/app/Controller/Task.php
index 6e525b13..1b9f9417 100644
--- a/app/Controller/Task.php
+++ b/app/Controller/Task.php
@@ -367,34 +367,6 @@ class Task extends Base
}
/**
- * Duplicate a task
- *
- * @access public
- */
- public function duplicate()
- {
- $task = $this->getTask();
-
- if ($this->request->getStringParam('confirmation') === 'yes') {
-
- $this->checkCSRFParam();
- $task_id = $this->taskDuplication->duplicate($task['id']);
-
- if ($task_id) {
- $this->session->flash(t('Task created successfully.'));
- $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])));
- } else {
- $this->session->flashError(t('Unable to create this task.'));
- $this->response->redirect($this->helper->url->to('task', 'duplicate', array('project_id' => $task['project_id'], 'task_id' => $task['id'])));
- }
- }
-
- $this->response->html($this->taskLayout('task/duplicate', array(
- 'task' => $task,
- )));
- }
-
- /**
* Edit description form
*
* @access public
@@ -493,84 +465,6 @@ class Task extends Base
}
/**
- * Move a task to another project
- *
- * @access public
- */
- public function move()
- {
- $task = $this->getTask();
- $values = $task;
- $errors = array();
- $projects_list = $this->projectPermission->getActiveMemberProjects($this->userSession->getId());
-
- unset($projects_list[$task['project_id']]);
-
- if ($this->request->isPost()) {
-
- $values = $this->request->getValues();
- list($valid, $errors) = $this->taskValidator->validateProjectModification($values);
-
- if ($valid) {
-
- if ($this->taskDuplication->moveToProject($task['id'], $values['project_id'])) {
- $this->session->flash(t('Task updated successfully.'));
- $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['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' => $projects_list,
- )));
- }
-
- /**
- * Duplicate a task to another project
- *
- * @access public
- */
- public function copy()
- {
- $task = $this->getTask();
- $values = $task;
- $errors = array();
- $projects_list = $this->projectPermission->getActiveMemberProjects($this->userSession->getId());
-
- unset($projects_list[$task['project_id']]);
-
- if ($this->request->isPost()) {
-
- $values = $this->request->getValues();
- list($valid, $errors) = $this->taskValidator->validateProjectModification($values);
-
- if ($valid) {
- $task_id = $this->taskDuplication->duplicateToProject($task['id'], $values['project_id']);
- if ($task_id) {
- $this->session->flash(t('Task created successfully.'));
- $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])));
- }
- else {
- $this->session->flashError(t('Unable to create your task.'));
- }
- }
- }
-
- $this->response->html($this->taskLayout('task/duplicate_project', array(
- 'values' => $values,
- 'errors' => $errors,
- 'task' => $task,
- 'projects_list' => $projects_list,
- )));
- }
-
- /**
* Display the time tracking details
*
* @access public
diff --git a/app/Controller/Taskduplication.php b/app/Controller/Taskduplication.php
new file mode 100644
index 00000000..91291b0d
--- /dev/null
+++ b/app/Controller/Taskduplication.php
@@ -0,0 +1,143 @@
+<?php
+
+namespace Controller;
+
+/**
+ * Task Duplication controller
+ *
+ * @package controller
+ * @author Frederic Guillot
+ */
+class Taskduplication extends Base
+{
+ /**
+ * Duplicate a task
+ *
+ * @access public
+ */
+ public function duplicate()
+ {
+ $task = $this->getTask();
+
+ if ($this->request->getStringParam('confirmation') === 'yes') {
+
+ $this->checkCSRFParam();
+ $task_id = $this->taskDuplication->duplicate($task['id']);
+
+ if ($task_id > 0) {
+ $this->session->flash(t('Task created successfully.'));
+ $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])));
+ } else {
+ $this->session->flashError(t('Unable to create this task.'));
+ $this->response->redirect($this->helper->url->to('taskduplication', 'duplicate', array('project_id' => $task['project_id'], 'task_id' => $task['id'])));
+ }
+ }
+
+ $this->response->html($this->taskLayout('task_duplication/duplicate', array(
+ 'task' => $task,
+ )));
+ }
+
+ /**
+ * Move a task to another project
+ *
+ * @access public
+ */
+ public function move()
+ {
+ $task = $this->getTask();
+
+ if ($this->request->isPost()) {
+
+ $values = $this->request->getValues();
+ list($valid, $errors) = $this->taskValidator->validateProjectModification($values);
+
+ if ($valid && $this->taskDuplication->moveToProject($task['id'],
+ $values['project_id'],
+ $values['swimlane_id'],
+ $values['column_id'],
+ $values['category_id'],
+ $values['owner_id'])) {
+
+ $this->session->flash(t('Task updated successfully.'));
+ $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $values['project_id'], 'task_id' => $task['id'])));
+ }
+
+ $this->session->flashError(t('Unable to update your task.'));
+ }
+
+ $this->chooseDestination($task, 'task_duplication/move');
+ }
+
+ /**
+ * Duplicate a task to another project
+ *
+ * @access public
+ */
+ public function copy()
+ {
+ $task = $this->getTask();
+
+ if ($this->request->isPost()) {
+
+ $values = $this->request->getValues();
+ list($valid, $errors) = $this->taskValidator->validateProjectModification($values);
+
+ if ($valid && $this->taskDuplication->duplicateToProject($task['id'],
+ $values['project_id'],
+ $values['swimlane_id'],
+ $values['column_id'],
+ $values['category_id'],
+ $values['owner_id'])) {
+
+ $this->session->flash(t('Task created successfully.'));
+ $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])));
+ }
+
+ $this->session->flashError(t('Unable to create your task.'));
+ }
+
+ $this->chooseDestination($task, 'task_duplication/copy');
+ }
+
+ /**
+ * Choose destination when move/copy task to another project
+ *
+ * @access private
+ */
+ private function chooseDestination(array $task, $template)
+ {
+ $values = array();
+ $projects_list = $this->projectPermission->getActiveMemberProjects($this->userSession->getId());
+
+ unset($projects_list[$task['project_id']]);
+
+ if (! empty($projects_list)) {
+ $dst_project_id = $this->request->getIntegerParam('dst_project_id', key($projects_list));
+
+ $swimlanes_list = $this->swimlane->getList($dst_project_id, false, true);
+ $columns_list = $this->board->getColumnsList($dst_project_id);
+ $categories_list = $this->category->getList($dst_project_id);
+ $users_list = $this->projectPermission->getMemberList($dst_project_id);
+
+ $values = $this->taskDuplication->checkDestinationProjectValues($task);
+ $values['project_id'] = $dst_project_id;
+ }
+ else {
+ $swimlanes_list = array();
+ $columns_list = array();
+ $categories_list = array();
+ $users_list = array();
+ }
+
+ $this->response->html($this->taskLayout($template, array(
+ 'values' => $values,
+ 'task' => $task,
+ 'projects_list' => $projects_list,
+ 'swimlanes_list' => $swimlanes_list,
+ 'columns_list' => $columns_list,
+ 'categories_list' => $categories_list,
+ 'users_list' => $users_list,
+ )));
+ }
+}
diff --git a/app/Locale/da_DK/translations.php b/app/Locale/da_DK/translations.php
index a85ef96c..6916b84e 100644
--- a/app/Locale/da_DK/translations.php
+++ b/app/Locale/da_DK/translations.php
@@ -999,4 +999,8 @@ return array(
// 'New remote user' => '',
// 'New local user' => '',
// 'Default task color' => '',
+ // 'Hide sidebar' => '',
+ // 'Expand sidebar' => '',
+ // 'This feature does not work with all browsers.' => '',
+ // 'There is no destination project available.' => '',
);
diff --git a/app/Locale/de_DE/translations.php b/app/Locale/de_DE/translations.php
index cb6cc8e3..1b381157 100644
--- a/app/Locale/de_DE/translations.php
+++ b/app/Locale/de_DE/translations.php
@@ -999,4 +999,8 @@ return array(
// 'New remote user' => '',
// 'New local user' => '',
// 'Default task color' => '',
+ // 'Hide sidebar' => '',
+ // 'Expand sidebar' => '',
+ // 'This feature does not work with all browsers.' => '',
+ // 'There is no destination project available.' => '',
);
diff --git a/app/Locale/es_ES/translations.php b/app/Locale/es_ES/translations.php
index 2f5e9b9a..867cc3db 100644
--- a/app/Locale/es_ES/translations.php
+++ b/app/Locale/es_ES/translations.php
@@ -999,4 +999,8 @@ return array(
// 'New remote user' => '',
// 'New local user' => '',
// 'Default task color' => '',
+ // 'Hide sidebar' => '',
+ // 'Expand sidebar' => '',
+ // 'This feature does not work with all browsers.' => '',
+ // 'There is no destination project available.' => '',
);
diff --git a/app/Locale/fi_FI/translations.php b/app/Locale/fi_FI/translations.php
index ab857645..79124b15 100644
--- a/app/Locale/fi_FI/translations.php
+++ b/app/Locale/fi_FI/translations.php
@@ -999,4 +999,8 @@ return array(
// 'New remote user' => '',
// 'New local user' => '',
// 'Default task color' => '',
+ // 'Hide sidebar' => '',
+ // 'Expand sidebar' => '',
+ // 'This feature does not work with all browsers.' => '',
+ // 'There is no destination project available.' => '',
);
diff --git a/app/Locale/fr_FR/translations.php b/app/Locale/fr_FR/translations.php
index db950a20..81159fcf 100644
--- a/app/Locale/fr_FR/translations.php
+++ b/app/Locale/fr_FR/translations.php
@@ -1001,4 +1001,8 @@ return array(
'New remote user' => 'Créer un utilisateur distant',
'New local user' => 'Créer un utilisateur local',
'Default task color' => 'Couleur par défaut des tâches',
+ 'Hide sidebar' => 'Cacher la barre latérale',
+ 'Expand sidebar' => 'Déplier la barre latérale',
+ 'This feature does not work with all browsers.' => 'Cette fonctionnalité n\'est pas compatible avec tous les navigateurs',
+ 'There is no destination project available.' => 'Il n\'y a pas de projet de destination disponible.',
);
diff --git a/app/Locale/hu_HU/translations.php b/app/Locale/hu_HU/translations.php
index ffc66324..cd2bca0a 100644
--- a/app/Locale/hu_HU/translations.php
+++ b/app/Locale/hu_HU/translations.php
@@ -999,4 +999,8 @@ return array(
// 'New remote user' => '',
// 'New local user' => '',
// 'Default task color' => '',
+ // 'Hide sidebar' => '',
+ // 'Expand sidebar' => '',
+ // 'This feature does not work with all browsers.' => '',
+ // 'There is no destination project available.' => '',
);
diff --git a/app/Locale/it_IT/translations.php b/app/Locale/it_IT/translations.php
index b232bdcb..353630c3 100644
--- a/app/Locale/it_IT/translations.php
+++ b/app/Locale/it_IT/translations.php
@@ -999,4 +999,8 @@ return array(
// 'New remote user' => '',
// 'New local user' => '',
// 'Default task color' => '',
+ // 'Hide sidebar' => '',
+ // 'Expand sidebar' => '',
+ // 'This feature does not work with all browsers.' => '',
+ // 'There is no destination project available.' => '',
);
diff --git a/app/Locale/ja_JP/translations.php b/app/Locale/ja_JP/translations.php
index 89d317ed..636df9a5 100644
--- a/app/Locale/ja_JP/translations.php
+++ b/app/Locale/ja_JP/translations.php
@@ -999,4 +999,8 @@ return array(
// 'New remote user' => '',
// 'New local user' => '',
// 'Default task color' => '',
+ // 'Hide sidebar' => '',
+ // 'Expand sidebar' => '',
+ // 'This feature does not work with all browsers.' => '',
+ // 'There is no destination project available.' => '',
);
diff --git a/app/Locale/nl_NL/translations.php b/app/Locale/nl_NL/translations.php
index bf43a9a7..c0a6a032 100644
--- a/app/Locale/nl_NL/translations.php
+++ b/app/Locale/nl_NL/translations.php
@@ -999,4 +999,8 @@ return array(
// 'New remote user' => '',
// 'New local user' => '',
// 'Default task color' => '',
+ // 'Hide sidebar' => '',
+ // 'Expand sidebar' => '',
+ // 'This feature does not work with all browsers.' => '',
+ // 'There is no destination project available.' => '',
);
diff --git a/app/Locale/pl_PL/translations.php b/app/Locale/pl_PL/translations.php
index 6b4b411b..9c4558d3 100644
--- a/app/Locale/pl_PL/translations.php
+++ b/app/Locale/pl_PL/translations.php
@@ -999,4 +999,8 @@ return array(
// 'New remote user' => '',
// 'New local user' => '',
// 'Default task color' => '',
+ // 'Hide sidebar' => '',
+ // 'Expand sidebar' => '',
+ // 'This feature does not work with all browsers.' => '',
+ // 'There is no destination project available.' => '',
);
diff --git a/app/Locale/pt_BR/translations.php b/app/Locale/pt_BR/translations.php
index ebe5466f..b31f815c 100644
--- a/app/Locale/pt_BR/translations.php
+++ b/app/Locale/pt_BR/translations.php
@@ -999,4 +999,8 @@ return array(
// 'New remote user' => '',
// 'New local user' => '',
// 'Default task color' => '',
+ // 'Hide sidebar' => '',
+ // 'Expand sidebar' => '',
+ // 'This feature does not work with all browsers.' => '',
+ // 'There is no destination project available.' => '',
);
diff --git a/app/Locale/ru_RU/translations.php b/app/Locale/ru_RU/translations.php
index 75dd15c0..9ce2ea6e 100644
--- a/app/Locale/ru_RU/translations.php
+++ b/app/Locale/ru_RU/translations.php
@@ -999,4 +999,8 @@ return array(
// 'New remote user' => '',
// 'New local user' => '',
// 'Default task color' => '',
+ // 'Hide sidebar' => '',
+ // 'Expand sidebar' => '',
+ // 'This feature does not work with all browsers.' => '',
+ // 'There is no destination project available.' => '',
);
diff --git a/app/Locale/sr_Latn_RS/translations.php b/app/Locale/sr_Latn_RS/translations.php
index 706efbb0..7f90af2d 100644
--- a/app/Locale/sr_Latn_RS/translations.php
+++ b/app/Locale/sr_Latn_RS/translations.php
@@ -999,4 +999,8 @@ return array(
// 'New remote user' => '',
// 'New local user' => '',
// 'Default task color' => '',
+ // 'Hide sidebar' => '',
+ // 'Expand sidebar' => '',
+ // 'This feature does not work with all browsers.' => '',
+ // 'There is no destination project available.' => '',
);
diff --git a/app/Locale/sv_SE/translations.php b/app/Locale/sv_SE/translations.php
index a03aadfd..67e07192 100644
--- a/app/Locale/sv_SE/translations.php
+++ b/app/Locale/sv_SE/translations.php
@@ -999,4 +999,8 @@ return array(
// 'New remote user' => '',
// 'New local user' => '',
// 'Default task color' => '',
+ // 'Hide sidebar' => '',
+ // 'Expand sidebar' => '',
+ // 'This feature does not work with all browsers.' => '',
+ // 'There is no destination project available.' => '',
);
diff --git a/app/Locale/th_TH/translations.php b/app/Locale/th_TH/translations.php
index 8c24aa65..a44d0116 100644
--- a/app/Locale/th_TH/translations.php
+++ b/app/Locale/th_TH/translations.php
@@ -999,4 +999,8 @@ return array(
// 'New remote user' => '',
// 'New local user' => '',
// 'Default task color' => '',
+ // 'Hide sidebar' => '',
+ // 'Expand sidebar' => '',
+ // 'This feature does not work with all browsers.' => '',
+ // 'There is no destination project available.' => '',
);
diff --git a/app/Locale/tr_TR/translations.php b/app/Locale/tr_TR/translations.php
index e9fb19cd..d394a67a 100644
--- a/app/Locale/tr_TR/translations.php
+++ b/app/Locale/tr_TR/translations.php
@@ -999,4 +999,8 @@ return array(
// 'New remote user' => '',
// 'New local user' => '',
// 'Default task color' => '',
+ // 'Hide sidebar' => '',
+ // 'Expand sidebar' => '',
+ // 'This feature does not work with all browsers.' => '',
+ // 'There is no destination project available.' => '',
);
diff --git a/app/Locale/zh_CN/translations.php b/app/Locale/zh_CN/translations.php
index d1eec36f..4de3aeaf 100644
--- a/app/Locale/zh_CN/translations.php
+++ b/app/Locale/zh_CN/translations.php
@@ -999,4 +999,8 @@ return array(
// 'New remote user' => '',
// 'New local user' => '',
// 'Default task color' => '',
+ // 'Hide sidebar' => '',
+ // 'Expand sidebar' => '',
+ // 'This feature does not work with all browsers.' => '',
+ // 'There is no destination project available.' => '',
);
diff --git a/app/Model/Acl.php b/app/Model/Acl.php
index b9c06e98..6ee78faa 100644
--- a/app/Model/Acl.php
+++ b/app/Model/Acl.php
@@ -41,6 +41,7 @@ class Acl extends Base
'activity' => '*',
'subtask' => '*',
'task' => '*',
+ 'taskduplication' => '*',
'tasklink' => '*',
'timer' => '*',
'calendar' => array('show', 'project'),
diff --git a/app/Model/TaskDuplication.php b/app/Model/TaskDuplication.php
index afcac4c7..8048f036 100755
--- a/app/Model/TaskDuplication.php
+++ b/app/Model/TaskDuplication.php
@@ -93,15 +93,22 @@ class TaskDuplication extends Base
* Duplicate a task to another project
*
* @access public
- * @param integer $task_id Task id
- * @param integer $project_id Project id
- * @return boolean|integer Duplicated task id
+ * @param integer $task_id
+ * @param integer $project_id
+ * @param integer $swimlane_id
+ * @param integer $column_id
+ * @param integer $category_id
+ * @param integer $owner_id
+ * @return boolean|integer
*/
- public function duplicateToProject($task_id, $project_id)
+ public function duplicateToProject($task_id, $project_id, $swimlane_id = null, $column_id = null, $category_id = null, $owner_id = null)
{
$values = $this->copyFields($task_id);
$values['project_id'] = $project_id;
- $values['column_id'] = $this->board->getFirstColumn($project_id);
+ $values['column_id'] = $column_id !== null ? $column_id : $this->board->getFirstColumn($project_id);
+ $values['swimlane_id'] = $swimlane_id !== null ? $swimlane_id : $values['swimlane_id'];
+ $values['category_id'] = $category_id !== null ? $category_id : $values['category_id'];
+ $values['owner_id'] = $owner_id !== null ? $owner_id : $values['owner_id'];
$this->checkDestinationProjectValues($values);
@@ -112,22 +119,26 @@ class TaskDuplication extends Base
* Move a task to another project
*
* @access public
- * @param integer $task_id Task id
- * @param integer $project_id Project id
+ * @param integer $task_id
+ * @param integer $project_id
+ * @param integer $swimlane_id
+ * @param integer $column_id
+ * @param integer $category_id
+ * @param integer $owner_id
* @return boolean
*/
- public function moveToProject($task_id, $project_id)
+ public function moveToProject($task_id, $project_id, $swimlane_id = null, $column_id = null, $category_id = null, $owner_id = null)
{
$task = $this->taskFinder->getById($task_id);
$values = array();
$values['is_active'] = 1;
$values['project_id'] = $project_id;
- $values['column_id'] = $this->board->getFirstColumn($project_id);
+ $values['column_id'] = $column_id !== null ? $column_id : $this->board->getFirstColumn($project_id);
$values['position'] = $this->taskFinder->countByColumnId($project_id, $values['column_id']) + 1;
- $values['owner_id'] = $task['owner_id'];
- $values['category_id'] = $task['category_id'];
- $values['swimlane_id'] = $task['swimlane_id'];
+ $values['swimlane_id'] = $swimlane_id !== null ? $swimlane_id : $task['swimlane_id'];
+ $values['category_id'] = $category_id !== null ? $category_id : $task['category_id'];
+ $values['owner_id'] = $owner_id !== null ? $owner_id : $task['owner_id'];
$this->checkDestinationProjectValues($values);
@@ -144,10 +155,10 @@ class TaskDuplication extends Base
/**
* Check if the assignee and the category are available in the destination project
*
- * @access private
+ * @access public
* @param array $values
*/
- private function checkDestinationProjectValues(&$values)
+ public function checkDestinationProjectValues(array &$values)
{
// Check if the assigned user is allowed for the destination project
if ($values['owner_id'] > 0 && ! $this->projectPermission->isUserAllowed($values['project_id'], $values['owner_id'])) {
@@ -169,6 +180,8 @@ class TaskDuplication extends Base
$this->swimlane->getNameById($values['swimlane_id'])
);
}
+
+ return $values;
}
/**
diff --git a/app/Template/task/duplicate_project.php b/app/Template/task/duplicate_project.php
deleted file mode 100644
index 9a8e3c4a..00000000
--- a/app/Template/task/duplicate_project.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<div class="page-header">
- <h2><?= t('Duplicate the task to another project') ?></h2>
-</div>
-
-<?php if (empty($projects_list)): ?>
- <p class="alert"><?= t('No project') ?></p>
-<?php else: ?>
-
- <form method="post" action="<?= $this->url->href('task', 'copy', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" autocomplete="off">
-
- <?= $this->form->csrf() ?>
-
- <?= $this->form->hidden('id', $values) ?>
- <?= $this->form->label(t('Project'), 'project_id') ?>
- <?= $this->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') ?>
- <?= $this->url->link(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
- </div>
- </form>
-
-<?php endif ?> \ No newline at end of file
diff --git a/app/Template/task/move_project.php b/app/Template/task/move_project.php
deleted file mode 100644
index b0b33f81..00000000
--- a/app/Template/task/move_project.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<div class="page-header">
- <h2><?= t('Move the task to another project') ?></h2>
-</div>
-
-<?php if (empty($projects_list)): ?>
- <p class="alert"><?= t('No project') ?></p>
-<?php else: ?>
-
- <form method="post" action="<?= $this->url->href('task', 'move', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" autocomplete="off">
-
- <?= $this->form->csrf() ?>
-
- <?= $this->form->hidden('id', $values) ?>
- <?= $this->form->label(t('Project'), 'project_id') ?>
- <?= $this->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') ?>
- <?= $this->url->link(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
- </div>
- </form>
-
-<?php endif ?> \ No newline at end of file
diff --git a/app/Template/task/sidebar.php b/app/Template/task/sidebar.php
index e6a5517a..942e7d01 100644
--- a/app/Template/task/sidebar.php
+++ b/app/Template/task/sidebar.php
@@ -46,13 +46,13 @@
<?= $this->url->link(t('Add a screenshot'), 'file', 'screenshot', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <?= $this->url->link(t('Duplicate'), 'task', 'duplicate', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
+ <?= $this->url->link(t('Duplicate'), 'taskduplication', 'duplicate', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <?= $this->url->link(t('Duplicate to another project'), 'task', 'copy', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
+ <?= $this->url->link(t('Duplicate to another project'), 'taskduplication', 'copy', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
- <?= $this->url->link(t('Move to another project'), 'task', 'move', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
+ <?= $this->url->link(t('Move to another project'), 'taskduplication', 'move', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
<?php if ($task['is_active'] == 1): ?>
diff --git a/app/Template/task_duplication/copy.php b/app/Template/task_duplication/copy.php
new file mode 100644
index 00000000..f9106c1d
--- /dev/null
+++ b/app/Template/task_duplication/copy.php
@@ -0,0 +1,43 @@
+<div class="page-header">
+ <h2><?= t('Duplicate the task to another project') ?></h2>
+</div>
+
+<?php if (empty($projects_list)): ?>
+ <p class="alert"><?= t('There is no destination project available.') ?></p>
+<?php else: ?>
+
+ <form method="post" action="<?= $this->url->href('taskduplication', 'copy', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" autocomplete="off">
+
+ <?= $this->form->csrf() ?>
+ <?= $this->form->hidden('id', $values) ?>
+
+ <?= $this->form->label(t('Project'), 'project_id') ?>
+ <?= $this->form->select(
+ 'project_id',
+ $projects_list,
+ $values,
+ array(),
+ array('data-redirect="'.$this->url->href('taskduplication', 'copy', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'dst_project_id' => 'PROJECT_ID')).'"'),
+ 'task-reload-project-destination'
+ ) ?>
+
+ <?= $this->form->label(t('Swimlane'), 'swimlane_id') ?>
+ <?= $this->form->select('swimlane_id', $swimlanes_list, $values) ?>
+
+ <?= $this->form->label(t('Column'), 'column_id') ?>
+ <?= $this->form->select('column_id', $columns_list, $values) ?>
+
+ <?= $this->form->label(t('Category'), 'category_id') ?>
+ <?= $this->form->select('category_id', $categories_list, $values) ?>
+
+ <?= $this->form->label(t('Assignee'), 'owner_id') ?>
+ <?= $this->form->select('owner_id', $users_list, $values) ?>
+
+ <div class="form-actions">
+ <input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
+ <?= t('or') ?>
+ <?= $this->url->link(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
+ </div>
+ </form>
+
+<?php endif ?> \ No newline at end of file
diff --git a/app/Template/task/duplicate.php b/app/Template/task_duplication/duplicate.php
index e74d2906..4b50d9ca 100644
--- a/app/Template/task/duplicate.php
+++ b/app/Template/task_duplication/duplicate.php
@@ -8,7 +8,7 @@
</p>
<div class="form-actions">
- <?= $this->url->link(t('Yes'), 'task', 'duplicate', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'confirmation' => 'yes'), true, 'btn btn-red') ?>
+ <?= $this->url->link(t('Yes'), 'taskduplication', 'duplicate', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'confirmation' => 'yes'), true, 'btn btn-red') ?>
<?= t('or') ?>
<?= $this->url->link(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</div>
diff --git a/app/Template/task_duplication/move.php b/app/Template/task_duplication/move.php
new file mode 100644
index 00000000..e90424a2
--- /dev/null
+++ b/app/Template/task_duplication/move.php
@@ -0,0 +1,43 @@
+<div class="page-header">
+ <h2><?= t('Move the task to another project') ?></h2>
+</div>
+
+<?php if (empty($projects_list)): ?>
+ <p class="alert"><?= t('There is no destination project available.') ?></p>
+<?php else: ?>
+
+ <form method="post" action="<?= $this->url->href('taskduplication', 'move', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" autocomplete="off">
+
+ <?= $this->form->csrf() ?>
+ <?= $this->form->hidden('id', $values) ?>
+
+ <?= $this->form->label(t('Project'), 'project_id') ?>
+ <?= $this->form->select(
+ 'project_id',
+ $projects_list,
+ $values,
+ array(),
+ array('data-redirect="'.$this->url->href('taskduplication', 'move', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'dst_project_id' => 'PROJECT_ID')).'"'),
+ 'task-reload-project-destination'
+ ) ?>
+
+ <?= $this->form->label(t('Swimlane'), 'swimlane_id') ?>
+ <?= $this->form->select('swimlane_id', $swimlanes_list, $values) ?>
+
+ <?= $this->form->label(t('Column'), 'column_id') ?>
+ <?= $this->form->select('column_id', $columns_list, $values) ?>
+
+ <?= $this->form->label(t('Category'), 'category_id') ?>
+ <?= $this->form->select('category_id', $categories_list, $values) ?>
+
+ <?= $this->form->label(t('Assignee'), 'owner_id') ?>
+ <?= $this->form->select('owner_id', $users_list, $values) ?>
+
+ <div class="form-actions">
+ <input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
+ <?= t('or') ?>
+ <?= $this->url->link(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
+ </div>
+ </form>
+
+<?php endif ?> \ No newline at end of file
diff --git a/app/common.php b/app/common.php
index 734f094b..815d2643 100644
--- a/app/common.php
+++ b/app/common.php
@@ -89,6 +89,12 @@ if (ENABLE_URL_REWRITE) {
$container['router']->addRoute('project/:project_id/swimlane/:swimlane_id/column/:column_id', 'task', 'create', array('project_id', 'swimlane_id', 'column_id'));
$container['router']->addRoute('public/task/:task_id/:token', 'task', 'readonly', array('task_id', 'token'));
+ $container['router']->addRoute('project/:project_id/task/:task_id/duplicate', 'taskduplication', 'duplicate', array('task_id', 'project_id'));
+ $container['router']->addRoute('project/:project_id/task/:task_id/copy', 'taskduplication', 'copy', array('task_id', 'project_id'));
+ $container['router']->addRoute('project/:project_id/task/:task_id/copy/:dst_project_id', 'taskduplication', 'copy', array('task_id', 'project_id', 'dst_project_id'));
+ $container['router']->addRoute('project/:project_id/task/:task_id/move', 'taskduplication', 'move', array('task_id', 'project_id'));
+ $container['router']->addRoute('project/:project_id/task/:task_id/move/:dst_project_id', 'taskduplication', 'move', array('task_id', 'project_id', 'dst_project_id'));
+
// Board routes
$container['router']->addRoute('board/:project_id', 'board', 'show', array('project_id'));
$container['router']->addRoute('b/:project_id', 'board', 'show', array('project_id'));