summaryrefslogtreecommitdiff
path: root/app/Controller
diff options
context:
space:
mode:
Diffstat (limited to 'app/Controller')
-rw-r--r--app/Controller/ActionController.php5
-rw-r--r--app/Controller/ActionCreationController.php7
-rw-r--r--app/Controller/ActivityController.php2
-rw-r--r--app/Controller/AppController.php2
-rw-r--r--app/Controller/BaseController.php163
-rw-r--r--app/Controller/CalendarController.php120
-rw-r--r--app/Controller/CategoryController.php31
-rw-r--r--app/Controller/ColumnController.php16
-rw-r--r--app/Controller/ColumnMoveRestrictionController.php3
-rw-r--r--app/Controller/CommentController.php43
-rw-r--r--app/Controller/CommentMailController.php1
-rw-r--r--app/Controller/ConfigController.php18
-rw-r--r--app/Controller/CustomFilterController.php7
-rw-r--r--app/Controller/DashboardController.php14
-rw-r--r--app/Controller/ICalendarController.php97
-rw-r--r--app/Controller/PredefinedTaskDescriptionController.php116
-rw-r--r--app/Controller/ProjectEditController.php2
-rw-r--r--app/Controller/ProjectGanttController.php56
-rw-r--r--app/Controller/ProjectPermissionController.php23
-rw-r--r--app/Controller/ProjectPredefinedContentController.php50
-rw-r--r--app/Controller/ProjectStatusController.php2
-rw-r--r--app/Controller/ProjectTagController.php33
-rw-r--r--app/Controller/SubtaskController.php65
-rw-r--r--app/Controller/SubtaskConverterController.php5
-rw-r--r--app/Controller/SubtaskRestrictionController.php6
-rw-r--r--app/Controller/SubtaskStatusController.php60
-rw-r--r--app/Controller/SwimlaneController.php43
-rw-r--r--app/Controller/TaskBulkController.php11
-rw-r--r--app/Controller/TaskCreationController.php1
-rw-r--r--app/Controller/TaskExternalLinkController.php37
-rw-r--r--app/Controller/TaskGanttController.php61
-rw-r--r--app/Controller/TaskImportController.php15
-rw-r--r--app/Controller/TaskInternalLinkController.php47
-rw-r--r--app/Controller/TaskMailController.php8
-rw-r--r--app/Controller/TaskModificationController.php21
-rw-r--r--app/Controller/TaskRecurrenceController.php1
-rw-r--r--app/Controller/UserAjaxController.php8
-rw-r--r--app/Controller/UserApiAccessController.php6
-rw-r--r--app/Controller/UserCredentialController.php8
-rw-r--r--app/Controller/UserModificationController.php11
40 files changed, 676 insertions, 549 deletions
diff --git a/app/Controller/ActionController.php b/app/Controller/ActionController.php
index c935125a..43acf590 100644
--- a/app/Controller/ActionController.php
+++ b/app/Controller/ActionController.php
@@ -46,9 +46,10 @@ class ActionController extends BaseController
public function confirm()
{
$project = $this->getProject();
+ $action = $this->getAction($project);
$this->response->html($this->helper->layout->project('action/remove', array(
- 'action' => $this->actionModel->getById($this->request->getIntegerParam('action_id')),
+ 'action' => $action,
'available_events' => $this->eventManager->getAll(),
'available_actions' => $this->actionManager->getAvailableActions(),
'project' => $project,
@@ -65,7 +66,7 @@ class ActionController extends BaseController
{
$this->checkCSRFParam();
$project = $this->getProject();
- $action = $this->actionModel->getById($this->request->getIntegerParam('action_id'));
+ $action = $this->getAction($project);
if (! empty($action) && $this->actionModel->remove($action['id'])) {
$this->flash->success(t('Action removed successfully.'));
diff --git a/app/Controller/ActionCreationController.php b/app/Controller/ActionCreationController.php
index 7fee58d1..abb214e6 100644
--- a/app/Controller/ActionCreationController.php
+++ b/app/Controller/ActionCreationController.php
@@ -35,8 +35,9 @@ class ActionCreationController extends BaseController
{
$project = $this->getProject();
$values = $this->request->getValues();
+ $values['project_id'] = $project['id'];
- if (empty($values['action_name']) || empty($values['project_id'])) {
+ if (empty($values['action_name'])) {
return $this->create();
}
@@ -57,8 +58,9 @@ class ActionCreationController extends BaseController
{
$project = $this->getProject();
$values = $this->request->getValues();
+ $values['project_id'] = $project['id'];
- if (empty($values['action_name']) || empty($values['project_id']) || empty($values['event_name'])) {
+ if (empty($values['action_name']) || empty($values['event_name'])) {
$this->create();
return;
}
@@ -109,6 +111,7 @@ class ActionCreationController extends BaseController
*/
private function doCreation(array $project, array $values)
{
+ $values['project_id'] = $project['id'];
list($valid, ) = $this->actionValidator->validateCreation($values);
if ($valid) {
diff --git a/app/Controller/ActivityController.php b/app/Controller/ActivityController.php
index a1734af1..7a58e670 100644
--- a/app/Controller/ActivityController.php
+++ b/app/Controller/ActivityController.php
@@ -19,7 +19,7 @@ class ActivityController extends BaseController
{
$user = $this->getUser();
- $this->response->html($this->helper->layout->dashboard('activity/user', array(
+ $this->response->html($this->template->render('activity/user', array(
'title' => t('Activity stream for %s', $this->helper->user->getFullname($user)),
'events' => $this->helper->projectActivity->getProjectsEvents($this->projectPermissionModel->getActiveProjectIds($user['id']), 100),
'user' => $user,
diff --git a/app/Controller/AppController.php b/app/Controller/AppController.php
index 34b9c8cc..645cae7f 100644
--- a/app/Controller/AppController.php
+++ b/app/Controller/AppController.php
@@ -27,7 +27,7 @@ class AppController extends Base
$this->response->html($this->helper->layout->app('app/forbidden', array(
'title' => t('Access Forbidden'),
'no_layout' => $withoutLayout,
- )));
+ )), 403);
}
}
diff --git a/app/Controller/BaseController.php b/app/Controller/BaseController.php
index 5233e27f..43ecfaab 100644
--- a/app/Controller/BaseController.php
+++ b/app/Controller/BaseController.php
@@ -74,13 +74,14 @@ abstract class BaseController extends Base
{
$task_id = $this->request->getIntegerParam('task_id');
$file_id = $this->request->getIntegerParam('file_id');
+ $project_id = $this->request->getIntegerParam('project_id');
$model = 'projectFileModel';
if ($task_id > 0) {
$model = 'taskFileModel';
- $project_id = $this->taskFinderModel->getProjectId($task_id);
+ $task_project_id = $this->taskFinderModel->getProjectId($task_id);
- if ($project_id !== $this->request->getIntegerParam('project_id')) {
+ if ($project_id != $task_project_id) {
throw new AccessForbiddenException();
}
}
@@ -91,6 +92,12 @@ abstract class BaseController extends Base
throw new PageNotFoundException();
}
+ if (isset($file['task_id']) && $file['task_id'] != $task_id) {
+ throw new AccessForbiddenException();
+ } else if (isset($file['project_id']) && $file['project_id'] != $project_id) {
+ throw new AccessForbiddenException();
+ }
+
$file['model'] = $model;
return $file;
}
@@ -138,14 +145,7 @@ abstract class BaseController extends Base
return $user;
}
- /**
- * Get the current subtask
- *
- * @access protected
- * @return array
- * @throws PageNotFoundException
- */
- protected function getSubtask()
+ protected function getSubtask(array $task)
{
$subtask = $this->subtaskModel->getById($this->request->getIntegerParam('subtask_id'));
@@ -153,6 +153,149 @@ abstract class BaseController extends Base
throw new PageNotFoundException();
}
+ if ($subtask['task_id'] != $task['id']) {
+ throw new AccessForbiddenException();
+ }
+
return $subtask;
}
+
+ protected function getComment(array $task)
+ {
+ $comment = $this->commentModel->getById($this->request->getIntegerParam('comment_id'));
+
+ if (empty($comment)) {
+ throw new PageNotFoundException();
+ }
+
+ if (! $this->userSession->isAdmin() && $comment['user_id'] != $this->userSession->getId()) {
+ throw new AccessForbiddenException();
+ }
+
+ if ($comment['task_id'] != $task['id']) {
+ throw new AccessForbiddenException();
+ }
+
+ return $comment;
+ }
+
+ protected function getExternalTaskLink(array $task)
+ {
+ $link = $this->taskExternalLinkModel->getById($this->request->getIntegerParam('link_id'));
+
+ if (empty($link)) {
+ throw new PageNotFoundException();
+ }
+
+ if ($link['task_id'] != $task['id']) {
+ throw new AccessForbiddenException();
+ }
+
+ return $link;
+ }
+
+ protected function getInternalTaskLink(array $task)
+ {
+ $link = $this->taskLinkModel->getById($this->request->getIntegerParam('link_id'));
+
+ if (empty($link)) {
+ throw new PageNotFoundException();
+ }
+
+ if ($link['task_id'] != $task['id']) {
+ throw new AccessForbiddenException();
+ }
+
+ return $link;
+ }
+
+ protected function getColumn(array $project)
+ {
+ $column = $this->columnModel->getById($this->request->getIntegerParam('column_id'));
+
+ if (empty($column)) {
+ throw new PageNotFoundException();
+ }
+
+ if ($column['project_id'] != $project['id']) {
+ throw new AccessForbiddenException();
+ }
+
+ return $column;
+ }
+
+ protected function getSwimlane(array $project)
+ {
+ $swimlane = $this->swimlaneModel->getById($this->request->getIntegerParam('swimlane_id'));
+
+ if (empty($swimlane)) {
+ throw new PageNotFoundException();
+ }
+
+ if ($swimlane['project_id'] != $project['id']) {
+ throw new AccessForbiddenException();
+ }
+
+ return $swimlane;
+ }
+
+ protected function getCategory(array $project)
+ {
+ $category = $this->categoryModel->getById($this->request->getIntegerParam('category_id'));
+
+ if (empty($category)) {
+ throw new PageNotFoundException();
+ }
+
+ if ($category['project_id'] != $project['id']) {
+ throw new AccessForbiddenException();
+ }
+
+ return $category;
+ }
+
+ protected function getProjectTag(array $project)
+ {
+ $tag = $this->tagModel->getById($this->request->getIntegerParam('tag_id'));
+
+ if (empty($tag)) {
+ throw new PageNotFoundException();
+ }
+
+ if ($tag['project_id'] != $project['id']) {
+ throw new AccessForbiddenException();
+ }
+
+ return $tag;
+ }
+
+ protected function getAction(array $project)
+ {
+ $action = $this->actionModel->getById($this->request->getIntegerParam('action_id'));
+
+ if (empty($action)) {
+ throw new PageNotFoundException();
+ }
+
+ if ($action['project_id'] != $project['id']) {
+ throw new AccessForbiddenException();
+ }
+
+ return $action;
+ }
+
+ protected function getCustomFilter(array $project)
+ {
+ $filter = $this->customFilterModel->getById($this->request->getIntegerParam('filter_id'));
+
+ if (empty($filter)) {
+ throw new PageNotFoundException();
+ }
+
+ if ($filter['project_id'] != $project['id']) {
+ throw new AccessForbiddenException();
+ }
+
+ return $filter;
+ }
}
diff --git a/app/Controller/CalendarController.php b/app/Controller/CalendarController.php
deleted file mode 100644
index e764549d..00000000
--- a/app/Controller/CalendarController.php
+++ /dev/null
@@ -1,120 +0,0 @@
-<?php
-
-namespace Kanboard\Controller;
-
-use Kanboard\Filter\TaskAssigneeFilter;
-use Kanboard\Filter\TaskProjectFilter;
-use Kanboard\Filter\TaskStatusFilter;
-use Kanboard\Model\TaskModel;
-
-/**
- * Calendar Controller
- *
- * @package Kanboard\Controller
- * @author Frederic Guillot
- * @author Timo Litzbarski
- */
-class CalendarController extends BaseController
-{
- /**
- * Show calendar view for a user
- *
- * @access public
- */
- public function user()
- {
- $user = $this->getUser();
-
- $this->response->html($this->helper->layout->app('calendar/user', array(
- 'user' => $user,
- )));
- }
-
- /**
- * Show calendar view for a project
- *
- * @access public
- */
- public function project()
- {
- $project = $this->getProject();
-
- $this->response->html($this->helper->layout->app('calendar/project', array(
- 'project' => $project,
- 'title' => $project['name'],
- 'description' => $this->helper->projectHeader->getDescription($project),
- )));
- }
-
- /**
- * Get tasks to display on the calendar (project view)
- *
- * @access public
- */
- public function projectEvents()
- {
- $project_id = $this->request->getIntegerParam('project_id');
- $start = $this->request->getStringParam('start');
- $end = $this->request->getStringParam('end');
- $search = $this->userSession->getFilters($project_id);
- $queryBuilder = $this->taskLexer->build($search)->withFilter(new TaskProjectFilter($project_id));
-
- $events = $this->helper->calendar->getTaskDateDueEvents(clone($queryBuilder), $start, $end);
- $events = array_merge($events, $this->helper->calendar->getTaskEvents(clone($queryBuilder), $start, $end));
-
- $events = $this->hook->merge('controller:calendar:project:events', $events, array(
- 'project_id' => $project_id,
- 'start' => $start,
- 'end' => $end,
- ));
-
- $this->response->json($events);
- }
-
- /**
- * Get tasks to display on the calendar (user view)
- *
- * @access public
- */
- public function userEvents()
- {
- $user_id = $this->request->getIntegerParam('user_id');
- $start = $this->request->getStringParam('start');
- $end = $this->request->getStringParam('end');
- $queryBuilder = $this->taskQuery
- ->withFilter(new TaskAssigneeFilter($user_id))
- ->withFilter(new TaskStatusFilter(TaskModel::STATUS_OPEN));
-
- $events = $this->helper->calendar->getTaskDateDueEvents(clone($queryBuilder), $start, $end);
- $events = array_merge($events, $this->helper->calendar->getTaskEvents(clone($queryBuilder), $start, $end));
-
- if ($this->configModel->get('calendar_user_subtasks_time_tracking') == 1) {
- $events = array_merge($events, $this->helper->calendar->getSubtaskTimeTrackingEvents($user_id, $start, $end));
- }
-
- $events = $this->hook->merge('controller:calendar:user:events', $events, array(
- 'user_id' => $user_id,
- 'start' => $start,
- 'end' => $end,
- ));
-
- $this->response->json($events);
- }
-
- /**
- * Update task due date
- *
- * @access public
- */
- public function save()
- {
- if ($this->request->isAjax() && $this->request->isPost()) {
- $values = $this->request->getJson();
-
- $this->taskModificationModel->update(array(
- 'id' => $values['task_id'],
- 'date_due' => substr($values['date_due'], 0, 10),
- ));
- }
- }
-}
diff --git a/app/Controller/CategoryController.php b/app/Controller/CategoryController.php
index 69bbad5a..e3f2406b 100644
--- a/app/Controller/CategoryController.php
+++ b/app/Controller/CategoryController.php
@@ -13,24 +13,6 @@ use Kanboard\Core\Controller\PageNotFoundException;
class CategoryController extends BaseController
{
/**
- * Get the category (common method between actions)
- *
- * @access private
- * @return array
- * @throws PageNotFoundException
- */
- private function getCategory()
- {
- $category = $this->categoryModel->getById($this->request->getIntegerParam('category_id'));
-
- if (empty($category)) {
- throw new PageNotFoundException();
- }
-
- return $category;
- }
-
- /**
* List of categories for a given project
*
* @access public
@@ -72,8 +54,9 @@ class CategoryController extends BaseController
public function save()
{
$project = $this->getProject();
-
$values = $this->request->getValues();
+ $values['project_id'] = $project['id'];
+
list($valid, $errors) = $this->categoryValidator->validateCreation($values);
if ($valid) {
@@ -100,7 +83,7 @@ class CategoryController extends BaseController
public function edit(array $values = array(), array $errors = array())
{
$project = $this->getProject();
- $category = $this->getCategory();
+ $category = $this->getCategory($project);
$this->response->html($this->template->render('category/edit', array(
'values' => empty($values) ? $category : $values,
@@ -117,8 +100,12 @@ class CategoryController extends BaseController
public function update()
{
$project = $this->getProject();
+ $category = $this->getCategory($project);
$values = $this->request->getValues();
+ $values['project_id'] = $project['id'];
+ $values['id'] = $category['id'];
+
list($valid, $errors) = $this->categoryValidator->validateModification($values);
if ($valid) {
@@ -141,7 +128,7 @@ class CategoryController extends BaseController
public function confirm()
{
$project = $this->getProject();
- $category = $this->getCategory();
+ $category = $this->getCategory($project);
$this->response->html($this->helper->layout->project('category/remove', array(
'project' => $project,
@@ -158,7 +145,7 @@ class CategoryController extends BaseController
{
$this->checkCSRFParam();
$project = $this->getProject();
- $category = $this->getCategory();
+ $category = $this->getCategory($project);
if ($this->categoryModel->remove($category['id'])) {
$this->flash->success(t('Category removed successfully.'));
diff --git a/app/Controller/ColumnController.php b/app/Controller/ColumnController.php
index 7047d30e..8e4712d9 100644
--- a/app/Controller/ColumnController.php
+++ b/app/Controller/ColumnController.php
@@ -61,6 +61,7 @@ class ColumnController extends BaseController
{
$project = $this->getProject();
$values = $this->request->getValues() + array('hide_in_dashboard' => 0);
+ $values['project_id'] = $project['id'];
list($valid, $errors) = $this->columnValidator->validateCreation($values);
@@ -95,7 +96,7 @@ class ColumnController extends BaseController
public function edit(array $values = array(), array $errors = array())
{
$project = $this->getProject();
- $column = $this->columnModel->getById($this->request->getIntegerParam('column_id'));
+ $column = $this->getColumn($project);
$this->response->html($this->helper->layout->project('column/edit', array(
'errors' => $errors,
@@ -113,7 +114,11 @@ class ColumnController extends BaseController
public function update()
{
$project = $this->getProject();
+ $column = $this->getColumn($project);
+
$values = $this->request->getValues() + array('hide_in_dashboard' => 0);
+ $values['project_id'] = $project['id'];
+ $values['id'] = $column['id'];
list($valid, $errors) = $this->columnValidator->validateModification($values);
@@ -164,9 +169,10 @@ class ColumnController extends BaseController
public function confirm()
{
$project = $this->getProject();
+ $column = $this->getColumn($project);
$this->response->html($this->helper->layout->project('column/remove', array(
- 'column' => $this->columnModel->getById($this->request->getIntegerParam('column_id')),
+ 'column' => $column,
'project' => $project,
)));
}
@@ -178,11 +184,11 @@ class ColumnController extends BaseController
*/
public function remove()
{
- $project = $this->getProject();
$this->checkCSRFParam();
- $column_id = $this->request->getIntegerParam('column_id');
+ $project = $this->getProject();
+ $column = $this->getColumn($project);
- if ($this->columnModel->remove($column_id)) {
+ if ($this->columnModel->remove($column['id'])) {
$this->flash->success(t('Column removed successfully.'));
} else {
$this->flash->failure(t('Unable to remove this column.'));
diff --git a/app/Controller/ColumnMoveRestrictionController.php b/app/Controller/ColumnMoveRestrictionController.php
index b12f6b77..9a75bf75 100644
--- a/app/Controller/ColumnMoveRestrictionController.php
+++ b/app/Controller/ColumnMoveRestrictionController.php
@@ -49,7 +49,8 @@ class ColumnMoveRestrictionController extends BaseController
$project['id'],
$values['role_id'],
$values['src_column_id'],
- $values['dst_column_id']
+ $values['dst_column_id'],
+ isset($values['only_assigned']) && $values['only_assigned'] == 1
);
if ($restriction_id !== false) {
diff --git a/app/Controller/CommentController.php b/app/Controller/CommentController.php
index 9a89103e..a29491a3 100644
--- a/app/Controller/CommentController.php
+++ b/app/Controller/CommentController.php
@@ -14,29 +14,6 @@ use Kanboard\Core\Controller\PageNotFoundException;
class CommentController extends BaseController
{
/**
- * Get the current comment
- *
- * @access protected
- * @return array
- * @throws PageNotFoundException
- * @throws AccessForbiddenException
- */
- protected function getComment()
- {
- $comment = $this->commentModel->getById($this->request->getIntegerParam('comment_id'));
-
- if (empty($comment)) {
- throw new PageNotFoundException();
- }
-
- if (! $this->userSession->isAdmin() && $comment['user_id'] != $this->userSession->getId()) {
- throw new AccessForbiddenException();
- }
-
- return $comment;
- }
-
- /**
* Add comment form
*
* @access public
@@ -49,14 +26,6 @@ class CommentController extends BaseController
{
$project = $this->getProject();
$task = $this->getTask();
-
- if (empty($values)) {
- $values = array(
- 'user_id' => $this->userSession->getId(),
- 'task_id' => $task['id'],
- );
- }
-
$values['project_id'] = $task['project_id'];
$this->response->html($this->helper->layout->task('comment/create', array(
@@ -106,7 +75,7 @@ class CommentController extends BaseController
public function edit(array $values = array(), array $errors = array())
{
$task = $this->getTask();
- $comment = $this->getComment();
+ $comment = $this->getComment($task);
if (empty($values)) {
$values = $comment;
@@ -130,9 +99,13 @@ class CommentController extends BaseController
public function update()
{
$task = $this->getTask();
- $this->getComment();
+ $comment = $this->getComment($task);
$values = $this->request->getValues();
+ $values['id'] = $comment['id'];
+ $values['task_id'] = $task['id'];
+ $values['user_id'] = $comment['user_id'];
+
list($valid, $errors) = $this->commentValidator->validateModification($values);
if ($valid) {
@@ -157,7 +130,7 @@ class CommentController extends BaseController
public function confirm()
{
$task = $this->getTask();
- $comment = $this->getComment();
+ $comment = $this->getComment($task);
$this->response->html($this->template->render('comment/remove', array(
'comment' => $comment,
@@ -175,7 +148,7 @@ class CommentController extends BaseController
{
$this->checkCSRFParam();
$task = $this->getTask();
- $comment = $this->getComment();
+ $comment = $this->getComment($task);
if ($this->commentModel->remove($comment['id'])) {
$this->flash->success(t('Comment removed successfully.'));
diff --git a/app/Controller/CommentMailController.php b/app/Controller/CommentMailController.php
index e30d6a55..144c9a13 100644
--- a/app/Controller/CommentMailController.php
+++ b/app/Controller/CommentMailController.php
@@ -20,6 +20,7 @@ class CommentMailController extends BaseController
'errors' => $errors,
'task' => $task,
'project' => $project,
+ 'members' => $this->projectPermissionModel->getMembersWithEmail($project['id']),
)));
}
diff --git a/app/Controller/ConfigController.php b/app/Controller/ConfigController.php
index 6b85d1f9..2ea04b35 100644
--- a/app/Controller/ConfigController.php
+++ b/app/Controller/ConfigController.php
@@ -46,12 +46,6 @@ class ConfigController extends BaseController
'disable_private_project' => 0,
);
break;
- case 'integrations':
- $values += array('integration_gravatar' => 0);
- break;
- case 'calendar':
- $values += array('calendar_user_subtasks_time_tracking' => 0);
- break;
}
if ($this->configModel->save($values)) {
@@ -128,18 +122,6 @@ class ConfigController extends BaseController
}
/**
- * Display the calendar settings page
- *
- * @access public
- */
- public function calendar()
- {
- $this->response->html($this->helper->layout->config('config/calendar', array(
- 'title' => t('Settings').' &gt; '.t('Calendar settings'),
- )));
- }
-
- /**
* Display the integration settings page
*
* @access public
diff --git a/app/Controller/CustomFilterController.php b/app/Controller/CustomFilterController.php
index dfe1ffc4..1bf1617e 100644
--- a/app/Controller/CustomFilterController.php
+++ b/app/Controller/CustomFilterController.php
@@ -59,6 +59,7 @@ class CustomFilterController extends BaseController
$project = $this->getProject();
$values = $this->request->getValues();
+ $values['project_id'] = $project['id'];
$values['user_id'] = $this->userSession->getId();
list($valid, $errors) = $this->customFilterValidator->validateCreation($values);
@@ -84,7 +85,7 @@ class CustomFilterController extends BaseController
public function confirm()
{
$project = $this->getProject();
- $filter = $this->customFilterModel->getById($this->request->getIntegerParam('filter_id'));
+ $filter = $this->getCustomFilter($project);
$this->response->html($this->helper->layout->project('custom_filter/remove', array(
'project' => $project,
@@ -102,7 +103,7 @@ class CustomFilterController extends BaseController
{
$this->checkCSRFParam();
$project = $this->getProject();
- $filter = $this->customFilterModel->getById($this->request->getIntegerParam('filter_id'));
+ $filter = $this->getCustomFilter($project);
$this->checkPermission($project, $filter);
@@ -153,6 +154,8 @@ class CustomFilterController extends BaseController
$this->checkPermission($project, $filter);
$values = $this->request->getValues();
+ $values['id'] = $filter['id'];
+ $values['project_id'] = $project['id'];
if (! isset($values['is_shared'])) {
$values += array('is_shared' => 0);
diff --git a/app/Controller/DashboardController.php b/app/Controller/DashboardController.php
index 7fdc53ff..6758381e 100644
--- a/app/Controller/DashboardController.php
+++ b/app/Controller/DashboardController.php
@@ -19,12 +19,11 @@ class DashboardController extends BaseController
{
$user = $this->getUser();
- $this->response->html($this->helper->layout->dashboard('dashboard/show', array(
- 'title' => t('Dashboard for %s', $this->helper->user->getFullname($user)),
- 'project_paginator' => $this->projectPagination->getDashboardPaginator($user['id'], 'show', 10),
- 'task_paginator' => $this->taskPagination->getDashboardPaginator($user['id'], 'show', 10),
- 'subtask_paginator' => $this->subtaskPagination->getDashboardPaginator($user['id'], 'show', 10),
- 'user' => $user,
+ $this->response->html($this->helper->layout->dashboard('dashboard/overview', array(
+ 'title' => t('Dashboard for %s', $this->helper->user->getFullname($user)),
+ 'user' => $user,
+ 'overview_paginator' => $this->dashboardPagination->getOverview($user['id']),
+ 'project_paginator' => $this->projectPagination->getDashboardPaginator($user['id'], 'show', 10),
)));
}
@@ -55,8 +54,9 @@ class DashboardController extends BaseController
$this->response->html($this->helper->layout->dashboard('dashboard/subtasks', array(
'title' => t('Subtasks overview for %s', $this->helper->user->getFullname($user)),
- 'paginator' => $this->subtaskPagination->getDashboardPaginator($user['id'], 'subtasks', 50),
+ 'paginator' => $this->subtaskPagination->getDashboardPaginator($user['id']),
'user' => $user,
+ 'nb_subtasks' => $this->subtaskModel->countByAssigneeAndTaskStatus($user['id']),
)));
}
diff --git a/app/Controller/ICalendarController.php b/app/Controller/ICalendarController.php
index 4fe8b78a..38475a32 100644
--- a/app/Controller/ICalendarController.php
+++ b/app/Controller/ICalendarController.php
@@ -5,6 +5,7 @@ namespace Kanboard\Controller;
use Kanboard\Core\Controller\AccessForbiddenException;
use Kanboard\Core\Filter\QueryBuilder;
use Kanboard\Filter\TaskAssigneeFilter;
+use Kanboard\Filter\TaskDueDateRangeFilter;
use Kanboard\Filter\TaskProjectFilter;
use Kanboard\Filter\TaskStatusFilter;
use Kanboard\Model\TaskModel;
@@ -18,81 +19,97 @@ use Eluceo\iCal\Component\Calendar as iCalendar;
*/
class ICalendarController extends BaseController
{
- /**
- * Get user iCalendar
- *
- * @access public
- */
public function user()
{
$token = $this->request->getStringParam('token');
$user = $this->userModel->getByToken($token);
- // Token verification
if (empty($user)) {
throw AccessForbiddenException::getInstance()->withoutLayout();
}
- // Common filter
- $queryBuilder = new QueryBuilder();
- $queryBuilder
- ->withQuery($this->taskFinderModel->getICalQuery())
- ->withFilter(new TaskStatusFilter(TaskModel::STATUS_OPEN))
- ->withFilter(new TaskAssigneeFilter($user['id']));
+ $startRange = strtotime('-2 months');
+ $endRange = strtotime('+6 months');
+
+ $startColumn = $this->configModel->get('calendar_project_tasks', 'date_started');
- // Calendar properties
$calendar = new iCalendar('Kanboard');
$calendar->setName($user['name'] ?: $user['username']);
$calendar->setDescription($user['name'] ?: $user['username']);
$calendar->setPublishedTTL('PT1H');
- $this->renderCalendar($queryBuilder, $calendar);
+ $queryDueDateOnly = QueryBuilder::create()
+ ->withQuery($this->taskFinderModel->getICalQuery())
+ ->withFilter(new TaskStatusFilter(TaskModel::STATUS_OPEN))
+ ->withFilter(new TaskDueDateRangeFilter(array($startRange, $endRange)))
+ ->withFilter(new TaskAssigneeFilter($user['id']))
+ ->getQuery();
+
+ $queryStartAndDueDate = QueryBuilder::create()
+ ->withQuery($this->taskFinderModel->getICalQuery())
+ ->withFilter(new TaskStatusFilter(TaskModel::STATUS_OPEN))
+ ->withFilter(new TaskAssigneeFilter($user['id']))
+ ->getQuery()
+ ->addCondition($this->getConditionForTasksWithStartAndDueDate($startRange, $endRange, $startColumn, 'date_due'));
+
+ $this->response->ical($this->taskICalFormatter
+ ->setCalendar($calendar)
+ ->addTasksWithDueDateOnly($queryDueDateOnly)
+ ->addTasksWithStartAndDueDate($queryStartAndDueDate, $startColumn, 'date_due')
+ ->format());
}
- /**
- * Get project iCalendar
- *
- * @access public
- */
public function project()
{
$token = $this->request->getStringParam('token');
$project = $this->projectModel->getByToken($token);
- // Token verification
if (empty($project)) {
throw AccessForbiddenException::getInstance()->withoutLayout();
}
- // Common filter
- $queryBuilder = new QueryBuilder();
- $queryBuilder
- ->withQuery($this->taskFinderModel->getICalQuery())
- ->withFilter(new TaskStatusFilter(TaskModel::STATUS_OPEN))
- ->withFilter(new TaskProjectFilter($project['id']));
+ $startRange = strtotime('-2 months');
+ $endRange = strtotime('+6 months');
+
+ $startColumn = $this->configModel->get('calendar_project_tasks', 'date_started');
- // Calendar properties
$calendar = new iCalendar('Kanboard');
$calendar->setName($project['name']);
$calendar->setDescription($project['name']);
$calendar->setPublishedTTL('PT1H');
- $this->renderCalendar($queryBuilder, $calendar);
+ $queryDueDateOnly = QueryBuilder::create()
+ ->withQuery($this->taskFinderModel->getICalQuery())
+ ->withFilter(new TaskStatusFilter(TaskModel::STATUS_OPEN))
+ ->withFilter(new TaskProjectFilter($project['id']))
+ ->withFilter(new TaskDueDateRangeFilter(array($startRange, $endRange)))
+ ->getQuery();
+
+ $queryStartAndDueDate = QueryBuilder::create()
+ ->withQuery($this->taskFinderModel->getICalQuery())
+ ->withFilter(new TaskStatusFilter(TaskModel::STATUS_OPEN))
+ ->withFilter(new TaskProjectFilter($project['id']))
+ ->getQuery()
+ ->addCondition($this->getConditionForTasksWithStartAndDueDate($startRange, $endRange, $startColumn, 'date_due'));
+
+ $this->response->ical($this->taskICalFormatter
+ ->setCalendar($calendar)
+ ->addTasksWithDueDateOnly($queryDueDateOnly)
+ ->addTasksWithStartAndDueDate($queryStartAndDueDate, $startColumn, 'date_due')
+ ->format());
}
- /**
- * Common method to render iCal events
- *
- * @access private
- * @param QueryBuilder $queryBuilder
- * @param iCalendar $calendar
- */
- private function renderCalendar(QueryBuilder $queryBuilder, iCalendar $calendar)
+ protected function getConditionForTasksWithStartAndDueDate($start_time, $end_time, $start_column, $end_column)
{
- $start = $this->request->getStringParam('start', strtotime('-2 month'));
- $end = $this->request->getStringParam('end', strtotime('+6 months'));
+ $start_column = $this->db->escapeIdentifier($start_column);
+ $end_column = $this->db->escapeIdentifier($end_column);
+
+ $conditions = array(
+ "($start_column >= '$start_time' AND $start_column <= '$end_time')",
+ "($start_column <= '$start_time' AND $end_column >= '$start_time')",
+ "($start_column <= '$start_time' AND ($end_column = '0' OR $end_column IS NULL))",
+ );
- $this->helper->ical->addTaskDateDueEvents($queryBuilder, $calendar, $start, $end);
- $this->response->ical($this->taskICalFormatter->setCalendar($calendar)->format());
+ return $start_column.' IS NOT NULL AND '.$start_column.' > 0 AND ('.implode(' OR ', $conditions).')';
}
}
diff --git a/app/Controller/PredefinedTaskDescriptionController.php b/app/Controller/PredefinedTaskDescriptionController.php
new file mode 100644
index 00000000..1b7eca12
--- /dev/null
+++ b/app/Controller/PredefinedTaskDescriptionController.php
@@ -0,0 +1,116 @@
+<?php
+
+namespace Kanboard\Controller;
+
+use Kanboard\Core\Controller\PageNotFoundException;
+
+/**
+ * Predefined Task Description Controller
+ *
+ * @package Kanboard\Controller
+ * @author Frederic Guillot
+ */
+class PredefinedTaskDescriptionController extends BaseController
+{
+ public function create(array $values = array(), array $errors = array())
+ {
+ $project = $this->getProject();
+
+ $this->response->html($this->template->render('predefined_task_description/create', array(
+ 'values' => $values,
+ 'errors' => $errors,
+ 'project' => $project,
+ )));
+ }
+
+ public function save()
+ {
+ $project = $this->getProject();
+ $values = $this->request->getValues();
+
+ list($valid, $errors) = $this->predefinedTaskDescriptionValidator->validate($values);
+
+ if ($valid) {
+ if ($this->predefinedTaskDescriptionModel->create($project['id'], $values['title'], $values['description']) !== false) {
+ $this->flash->success(t('Template created successfully.'));
+ } else {
+ $this->flash->failure(t('Unable to create this template.'));
+ }
+
+ $this->response->redirect($this->helper->url->to('ProjectPredefinedContentController', 'show', array('project_id' => $project['id'])), true);
+ } else {
+ $this->create($values, $errors);
+ }
+ }
+
+ public function edit(array $values = array(), array $errors = array())
+ {
+ $project = $this->getProject();
+ $template = $this->predefinedTaskDescriptionModel->getById($project['id'], $this->request->getIntegerParam('id'));
+
+ $this->response->html($this->template->render('predefined_task_description/edit', array(
+ 'values' => empty($values) ? $template : $values,
+ 'template' => $template,
+ 'errors' => $errors,
+ 'project' => $project,
+ )));
+ }
+
+ public function update()
+ {
+ $project = $this->getProject();
+ $template = $this->getTemplate($project);
+ $values = $this->request->getValues();
+
+ list($valid, $errors) = $this->predefinedTaskDescriptionValidator->validate($values);
+
+ if ($valid) {
+ if ($this->predefinedTaskDescriptionModel->update($project['id'], $template['id'], $values['title'], $values['description']) !== false) {
+ $this->flash->success(t('Template updated successfully.'));
+ } else {
+ $this->flash->failure(t('Unable to update this template.'));
+ }
+
+ $this->response->redirect($this->helper->url->to('ProjectPredefinedContentController', 'show', array('project_id' => $project['id'])), true);
+ } else {
+ $this->edit($values, $errors);
+ }
+ }
+
+ public function confirm()
+ {
+ $project = $this->getProject();
+ $template = $this->getTemplate($project);
+
+ $this->response->html($this->template->render('predefined_task_description/remove', array(
+ 'template' => $template,
+ 'project' => $project,
+ )));
+ }
+
+ public function remove()
+ {
+ $this->checkCSRFParam();
+ $project = $this->getProject();
+ $template = $this->getTemplate($project);
+
+ if ($this->predefinedTaskDescriptionModel->remove($project['id'], $template['id'])) {
+ $this->flash->success(t('Template removed successfully.'));
+ } else {
+ $this->flash->failure(t('Unable to remove this template.'));
+ }
+
+ $this->response->redirect($this->helper->url->to('ProjectPredefinedContentController', 'show', array('project_id' => $project['id'])), true);
+ }
+
+ protected function getTemplate(array $project)
+ {
+ $template = $this->predefinedTaskDescriptionModel->getById($project['id'], $this->request->getIntegerParam('id'));
+
+ if (empty($template)) {
+ throw new PageNotFoundException();
+ }
+
+ return $template;
+ }
+} \ No newline at end of file
diff --git a/app/Controller/ProjectEditController.php b/app/Controller/ProjectEditController.php
index ae39fdf3..dd534508 100644
--- a/app/Controller/ProjectEditController.php
+++ b/app/Controller/ProjectEditController.php
@@ -65,6 +65,8 @@ class ProjectEditController extends BaseController
*/
private function prepareValues(array $project, array $values)
{
+ $values['id'] = $project['id'];
+
if (isset($values['is_private'])) {
if (! $this->helper->user->hasProjectAccess('ProjectCreationController', 'create', $project['id'])) {
unset($values['is_private']);
diff --git a/app/Controller/ProjectGanttController.php b/app/Controller/ProjectGanttController.php
deleted file mode 100644
index 8239005e..00000000
--- a/app/Controller/ProjectGanttController.php
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-
-namespace Kanboard\Controller;
-
-use Kanboard\Filter\ProjectIdsFilter;
-use Kanboard\Filter\ProjectStatusFilter;
-use Kanboard\Filter\ProjectTypeFilter;
-use Kanboard\Model\ProjectModel;
-
-/**
- * Projects Gantt Controller
- *
- * @package Kanboard\Controller
- * @author Frederic Guillot
- */
-class ProjectGanttController extends BaseController
-{
- /**
- * Show Gantt chart for all projects
- */
- public function show()
- {
- $project_ids = $this->projectPermissionModel->getActiveProjectIds($this->userSession->getId());
- $filter = $this->projectQuery
- ->withFilter(new ProjectTypeFilter(ProjectModel::TYPE_TEAM))
- ->withFilter(new ProjectStatusFilter(ProjectModel::ACTIVE))
- ->withFilter(new ProjectIdsFilter($project_ids));
-
- $filter->getQuery()->asc(ProjectModel::TABLE.'.start_date');
-
- $this->response->html($this->helper->layout->app('project_gantt/show', array(
- 'projects' => $filter->format($this->projectGanttFormatter),
- 'title' => t('Gantt chart for all projects'),
- )));
- }
-
- /**
- * Save new project start date and end date
- */
- public function save()
- {
- $values = $this->request->getJson();
-
- $result = $this->projectModel->update(array(
- 'id' => $values['id'],
- 'start_date' => $this->dateParser->getIsoDate(strtotime($values['start'])),
- 'end_date' => $this->dateParser->getIsoDate(strtotime($values['end'])),
- ));
-
- if (! $result) {
- $this->response->json(array('message' => 'Unable to save project'), 400);
- } else {
- $this->response->json(array('message' => 'OK'), 201);
- }
- }
-}
diff --git a/app/Controller/ProjectPermissionController.php b/app/Controller/ProjectPermissionController.php
index 56777b25..3fb6c090 100644
--- a/app/Controller/ProjectPermissionController.php
+++ b/app/Controller/ProjectPermissionController.php
@@ -60,25 +60,6 @@ class ProjectPermissionController extends BaseController
}
/**
- * Allow everybody
- *
- * @access public
- */
- public function allowEverybody()
- {
- $project = $this->getProject();
- $values = $this->request->getValues() + array('is_everybody_allowed' => 0);
-
- if ($this->projectModel->update($values)) {
- $this->flash->success(t('Project updated successfully.'));
- } else {
- $this->flash->failure(t('Unable to update this project.'));
- }
-
- $this->response->redirect($this->helper->url->to('ProjectPermissionController', 'index', array('project_id' => $project['id'])));
- }
-
- /**
* Add user to the project
*
* @access public
@@ -88,6 +69,10 @@ class ProjectPermissionController extends BaseController
$project = $this->getProject();
$values = $this->request->getValues();
+ if (empty($values['user_id']) && ! empty($values['external_id']) && ! empty($values['external_id_column'])) {
+ $values['user_id'] = $this->userModel->getOrCreateExternalUserId($values['username'], $values['name'], $values['external_id_column'], $values['external_id']);
+ }
+
if (empty($values['user_id'])) {
$this->flash->failure(t('User not found.'));
} elseif ($this->projectUserRoleModel->addUser($values['project_id'], $values['user_id'], $values['role'])) {
diff --git a/app/Controller/ProjectPredefinedContentController.php b/app/Controller/ProjectPredefinedContentController.php
new file mode 100644
index 00000000..709d6b79
--- /dev/null
+++ b/app/Controller/ProjectPredefinedContentController.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace Kanboard\Controller;
+
+/**
+ * Project Predefined Content Controller
+ *
+ * @package Kanboard\Controller
+ * @author Frederic Guillot
+ */
+class ProjectPredefinedContentController extends BaseController
+{
+ public function show(array $values = array(), array $errors = array())
+ {
+ $project = $this->getProject();
+
+ $this->response->html($this->helper->layout->project('project_predefined_content/show', array(
+ 'values' => empty($values) ? $project : $values,
+ 'errors' => $errors,
+ 'project' => $project,
+ 'predefined_task_descriptions' => $this->predefinedTaskDescriptionModel->getAll($project['id']),
+ 'title' => t('Predefined Contents'),
+ )));
+ }
+
+ public function update()
+ {
+ $project = $this->getProject();
+ $values = $this->request->getValues();
+
+ $values = array(
+ 'id' => $project['id'],
+ 'name' => $project['name'],
+ 'predefined_email_subjects' => isset($values['predefined_email_subjects']) ? $values['predefined_email_subjects'] : '',
+ );
+
+ list($valid, $errors) = $this->projectValidator->validateModification($values);
+
+ if ($valid) {
+ if ($this->projectModel->update($values)) {
+ $this->flash->success(t('Project updated successfully.'));
+ return $this->response->redirect($this->helper->url->to('ProjectPredefinedContentController', 'show', array('project_id' => $project['id'])), true);
+ } else {
+ $this->flash->failure(t('Unable to update this project.'));
+ }
+ }
+
+ return $this->show($values, $errors);
+ }
+}
diff --git a/app/Controller/ProjectStatusController.php b/app/Controller/ProjectStatusController.php
index 5bc445be..4fdbb6ea 100644
--- a/app/Controller/ProjectStatusController.php
+++ b/app/Controller/ProjectStatusController.php
@@ -95,6 +95,6 @@ class ProjectStatusController extends BaseController
$this->flash->failure(t('Unable to remove this project.'));
}
- $this->response->redirect($this->helper->url->to('ProjectListController', 'show'), true);
+ $this->response->redirect($this->helper->url->to('ProjectListController', 'show'));
}
}
diff --git a/app/Controller/ProjectTagController.php b/app/Controller/ProjectTagController.php
index d225f0ca..c45e71e1 100644
--- a/app/Controller/ProjectTagController.php
+++ b/app/Controller/ProjectTagController.php
@@ -2,8 +2,6 @@
namespace Kanboard\Controller;
-use Kanboard\Core\Controller\AccessForbiddenException;
-
/**
* Class ProjectTagController
*
@@ -27,10 +25,6 @@ class ProjectTagController extends BaseController
{
$project = $this->getProject();
- if (empty($values)) {
- $values['project_id'] = $project['id'];
- }
-
$this->response->html($this->template->render('project_tag/create', array(
'project' => $project,
'values' => $values,
@@ -42,6 +36,8 @@ class ProjectTagController extends BaseController
{
$project = $this->getProject();
$values = $this->request->getValues();
+ $values['project_id'] = $project['id'];
+
list($valid, $errors) = $this->tagValidator->validateCreation($values);
if ($valid) {
@@ -60,8 +56,7 @@ class ProjectTagController extends BaseController
public function edit(array $values = array(), array $errors = array())
{
$project = $this->getProject();
- $tag_id = $this->request->getIntegerParam('tag_id');
- $tag = $this->tagModel->getById($tag_id);
+ $tag = $this->getProjectTag($project);
if (empty($values)) {
$values = $tag;
@@ -78,14 +73,12 @@ class ProjectTagController extends BaseController
public function update()
{
$project = $this->getProject();
- $tag_id = $this->request->getIntegerParam('tag_id');
- $tag = $this->tagModel->getById($tag_id);
+ $tag = $this->getProjectTag($project);
$values = $this->request->getValues();
- list($valid, $errors) = $this->tagValidator->validateModification($values);
+ $values['project_id'] = $project['id'];
+ $values['id'] = $tag['id'];
- if ($tag['project_id'] != $project['id']) {
- throw new AccessForbiddenException();
- }
+ list($valid, $errors) = $this->tagValidator->validateModification($values);
if ($valid) {
if ($this->tagModel->update($values['id'], $values['name'])) {
@@ -103,8 +96,7 @@ class ProjectTagController extends BaseController
public function confirm()
{
$project = $this->getProject();
- $tag_id = $this->request->getIntegerParam('tag_id');
- $tag = $this->tagModel->getById($tag_id);
+ $tag = $this->getProjectTag($project);
$this->response->html($this->template->render('project_tag/remove', array(
'tag' => $tag,
@@ -116,14 +108,9 @@ class ProjectTagController extends BaseController
{
$this->checkCSRFParam();
$project = $this->getProject();
- $tag_id = $this->request->getIntegerParam('tag_id');
- $tag = $this->tagModel->getById($tag_id);
-
- if ($tag['project_id'] != $project['id']) {
- throw new AccessForbiddenException();
- }
+ $tag = $this->getProjectTag($project);
- if ($this->tagModel->remove($tag_id)) {
+ if ($this->tagModel->remove($tag['id'])) {
$this->flash->success(t('Tag removed successfully.'));
} else {
$this->flash->failure(t('Unable to remove this tag.'));
diff --git a/app/Controller/SubtaskController.php b/app/Controller/SubtaskController.php
index 5fa55f6b..d5db9b2e 100644
--- a/app/Controller/SubtaskController.php
+++ b/app/Controller/SubtaskController.php
@@ -66,29 +66,51 @@ class SubtaskController extends BaseController
{
$task = $this->getTask();
$values = $this->request->getValues();
+ $values['task_id'] = $task['id'];
+ $subtasks = explode("\r\n", isset($values['title']) ? $values['title'] : '');
+ $subtasksAdded = 0;
- list($valid, $errors) = $this->subtaskValidator->validateCreation($values);
+ foreach ($subtasks as $subtask) {
+ $subtask = trim($subtask);
- if ($valid) {
- if ($this->subtaskModel->create($values) !== false) {
- $this->flash->success(t('Sub-task added successfully.'));
- } else {
- $this->flash->failure(t('Unable to create your sub-task.'));
- }
+ if (! empty($subtask)) {
+ $subtaskValues = $values;
+ $subtaskValues['title'] = $subtask;
+
+ list($valid, $errors) = $this->subtaskValidator->validateCreation($subtaskValues);
+
+ if (! $valid) {
+ $this->create($values, $errors);
+ return false;
+ }
- if (isset($values['another_subtask']) && $values['another_subtask'] == 1) {
- return $this->create(array(
- 'project_id' => $task['project_id'],
- 'task_id' => $task['id'],
- 'user_id' => $values['user_id'],
- 'another_subtask' => 1
- ));
+ if (! $this->subtaskModel->create($subtaskValues)) {
+ $this->flash->failure(t('Unable to create your sub-task.'));
+ $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id']), 'subtasks'), true);
+ return false;
+ }
+
+ $subtasksAdded++;
}
+ }
- return $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id']), 'subtasks'), true);
+ if (isset($values['another_subtask']) && $values['another_subtask'] == 1) {
+ return $this->create(array(
+ 'project_id' => $task['project_id'],
+ 'task_id' => $task['id'],
+ 'user_id' => $values['user_id'],
+ 'another_subtask' => 1,
+ 'subtasks_added' => $subtasksAdded,
+ ));
+ } else if ($subtasksAdded > 0) {
+ if ($subtasksAdded === 1) {
+ $this->flash->success(t('Subtask added successfully.'));
+ } else {
+ $this->flash->success(t('%d subtasks added successfully.', $subtasksAdded));
+ }
}
- return $this->create($values, $errors);
+ $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id']), 'subtasks'), true);
}
/**
@@ -103,7 +125,7 @@ class SubtaskController extends BaseController
public function edit(array $values = array(), array $errors = array())
{
$task = $this->getTask();
- $subtask = $this->getSubtask();
+ $subtask = $this->getSubtask($task);
$this->response->html($this->template->render('subtask/edit', array(
'values' => empty($values) ? $subtask : $values,
@@ -123,9 +145,12 @@ class SubtaskController extends BaseController
public function update()
{
$task = $this->getTask();
- $this->getSubtask();
+ $subtask = $this->getSubtask($task);
$values = $this->request->getValues();
+ $values['id'] = $subtask['id'];
+ $values['task_id'] = $task['id'];
+
list($valid, $errors) = $this->subtaskValidator->validateModification($values);
if ($valid) {
@@ -149,7 +174,7 @@ class SubtaskController extends BaseController
public function confirm()
{
$task = $this->getTask();
- $subtask = $this->getSubtask();
+ $subtask = $this->getSubtask($task);
$this->response->html($this->template->render('subtask/remove', array(
'subtask' => $subtask,
@@ -166,7 +191,7 @@ class SubtaskController extends BaseController
{
$this->checkCSRFParam();
$task = $this->getTask();
- $subtask = $this->getSubtask();
+ $subtask = $this->getSubtask($task);
if ($this->subtaskModel->remove($subtask['id'])) {
$this->flash->success(t('Sub-task removed successfully.'));
diff --git a/app/Controller/SubtaskConverterController.php b/app/Controller/SubtaskConverterController.php
index 404c50d0..dafbb7e0 100644
--- a/app/Controller/SubtaskConverterController.php
+++ b/app/Controller/SubtaskConverterController.php
@@ -13,7 +13,7 @@ class SubtaskConverterController extends BaseController
public function show()
{
$task = $this->getTask();
- $subtask = $this->getSubtask();
+ $subtask = $this->getSubtask($task);
$this->response->html($this->template->render('subtask_converter/show', array(
'subtask' => $subtask,
@@ -24,7 +24,8 @@ class SubtaskConverterController extends BaseController
public function save()
{
$project = $this->getProject();
- $subtask = $this->getSubtask();
+ $task = $this->getTask();
+ $subtask = $this->getSubtask($task);
$task_id = $this->subtaskTaskConversionModel->convertToTask($project['id'], $subtask['id']);
diff --git a/app/Controller/SubtaskRestrictionController.php b/app/Controller/SubtaskRestrictionController.php
index 0e207674..315b023d 100644
--- a/app/Controller/SubtaskRestrictionController.php
+++ b/app/Controller/SubtaskRestrictionController.php
@@ -20,7 +20,7 @@ class SubtaskRestrictionController extends BaseController
public function show()
{
$task = $this->getTask();
- $subtask = $this->getSubtask();
+ $subtask = $this->getSubtask($task);
$this->response->html($this->template->render('subtask_restriction/show', array(
'status_list' => array(
@@ -41,21 +41,19 @@ class SubtaskRestrictionController extends BaseController
public function save()
{
$task = $this->getTask();
- $subtask = $this->getSubtask();
+ $subtask = $this->getSubtask($task);
$values = $this->request->getValues();
// Change status of the previous "in progress" subtask
$this->subtaskModel->update(array(
'id' => $values['id'],
'status' => $values['status'],
- 'task_id' => $task['id'],
));
// Set the current subtask to "in progress"
$this->subtaskModel->update(array(
'id' => $subtask['id'],
'status' => SubtaskModel::STATUS_INPROGRESS,
- 'task_id' => $task['id'],
));
$this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true);
diff --git a/app/Controller/SubtaskStatusController.php b/app/Controller/SubtaskStatusController.php
index 72feb685..c912848e 100644
--- a/app/Controller/SubtaskStatusController.php
+++ b/app/Controller/SubtaskStatusController.php
@@ -18,12 +18,21 @@ class SubtaskStatusController extends BaseController
public function change()
{
$task = $this->getTask();
- $subtask = $this->getSubtask();
+ $subtask = $this->getSubtask($task);
+ $fragment = $this->request->getStringParam('fragment');
$status = $this->subtaskStatusModel->toggleStatus($subtask['id']);
$subtask['status'] = $status;
- $this->response->html($this->helper->subtask->renderToggleStatus($task, $subtask));
+ if ($fragment === 'table') {
+ $html = $this->renderTable($task);
+ } elseif ($fragment === 'rows') {
+ $html = $this->renderRows($task);
+ } else {
+ $html = $this->helper->subtask->renderToggleStatus($task, $subtask);
+ }
+
+ $this->response->html($html);
}
/**
@@ -34,19 +43,58 @@ class SubtaskStatusController extends BaseController
public function timer()
{
$task = $this->getTask();
- $subtaskId = $this->request->getIntegerParam('subtask_id');
+ $subtask = $this->getSubtask($task);
$timer = $this->request->getStringParam('timer');
if ($timer === 'start') {
- $this->subtaskTimeTrackingModel->logStartTime($subtaskId, $this->userSession->getId());
+ $this->subtaskTimeTrackingModel->logStartTime($subtask['id'], $this->userSession->getId());
} elseif ($timer === 'stop') {
- $this->subtaskTimeTrackingModel->logEndTime($subtaskId, $this->userSession->getId());
+ $this->subtaskTimeTrackingModel->logEndTime($subtask['id'], $this->userSession->getId());
$this->subtaskTimeTrackingModel->updateTaskTimeTracking($task['id']);
}
$this->response->html($this->template->render('subtask/timer', array(
'task' => $task,
- 'subtask' => $this->subtaskModel->getByIdWithDetails($subtaskId),
+ 'subtask' => $this->subtaskModel->getByIdWithDetails($subtask['id']),
)));
}
+
+ /**
+ * Render table
+ *
+ * @access protected
+ * @param array $task
+ * @return string
+ */
+ protected function renderTable(array $task)
+ {
+ return $this->template->render('subtask/table', array(
+ 'task' => $task,
+ 'subtasks' => $this->subtaskModel->getAll($task['id']),
+ 'editable' => true,
+ ));
+ }
+
+ /**
+ * Render task list rows
+ *
+ * @access protected
+ * @param array $task
+ * @return string
+ */
+ protected function renderRows(array $task)
+ {
+ $userId = $this->request->getIntegerParam('user_id');
+
+ if ($userId > 0) {
+ $task['subtasks'] = $this->subtaskModel->getAllByTaskIdsAndAssignee(array($task['id']), $userId);
+ } else {
+ $task['subtasks'] = $this->subtaskModel->getAll($task['id']);
+ }
+
+ return $this->template->render('task_list/task_subtasks', array(
+ 'task' => $task,
+ 'user_id' => $userId,
+ ));
+ }
}
diff --git a/app/Controller/SwimlaneController.php b/app/Controller/SwimlaneController.php
index 0d81d83c..e6368b24 100644
--- a/app/Controller/SwimlaneController.php
+++ b/app/Controller/SwimlaneController.php
@@ -3,8 +3,6 @@
namespace Kanboard\Controller;
use Kanboard\Core\Controller\AccessForbiddenException;
-use Kanboard\Core\Controller\PageNotFoundException;
-use Kanboard\Model\SwimlaneModel;
/**
* Swimlanes Controller
@@ -15,24 +13,6 @@ use Kanboard\Model\SwimlaneModel;
class SwimlaneController extends BaseController
{
/**
- * Get the swimlane (common method between actions)
- *
- * @access private
- * @return array
- * @throws PageNotFoundException
- */
- private function getSwimlane()
- {
- $swimlane = $this->swimlaneModel->getById($this->request->getIntegerParam('swimlane_id'));
-
- if (empty($swimlane)) {
- throw new PageNotFoundException();
- }
-
- return $swimlane;
- }
-
- /**
* List of swimlanes for a given project
*
* @access public
@@ -78,6 +58,8 @@ class SwimlaneController extends BaseController
{
$project = $this->getProject();
$values = $this->request->getValues();
+ $values['project_id'] = $project['id'];
+
list($valid, $errors) = $this->swimlaneValidator->validateCreation($values);
if ($valid) {
@@ -104,7 +86,7 @@ class SwimlaneController extends BaseController
public function edit(array $values = array(), array $errors = array())
{
$project = $this->getProject();
- $swimlane = $this->getSwimlane();
+ $swimlane = $this->getSwimlane($project);
$this->response->html($this->helper->layout->project('swimlane/edit', array(
'values' => empty($values) ? $swimlane : $values,
@@ -121,8 +103,11 @@ class SwimlaneController extends BaseController
public function update()
{
$project = $this->getProject();
-
+ $swimlane = $this->getSwimlane($project);
$values = $this->request->getValues();
+ $values['project_id'] = $project['id'];
+ $values['id'] = $swimlane['id'];
+
list($valid, $errors) = $this->swimlaneValidator->validateModification($values);
if ($valid) {
@@ -145,7 +130,7 @@ class SwimlaneController extends BaseController
public function confirm()
{
$project = $this->getProject();
- $swimlane = $this->getSwimlane();
+ $swimlane = $this->getSwimlane($project);
$this->response->html($this->helper->layout->project('swimlane/remove', array(
'project' => $project,
@@ -162,9 +147,9 @@ class SwimlaneController extends BaseController
{
$this->checkCSRFParam();
$project = $this->getProject();
- $swimlane_id = $this->request->getIntegerParam('swimlane_id');
+ $swimlane = $this->getSwimlane($project);
- if ($this->swimlaneModel->remove($project['id'], $swimlane_id)) {
+ if ($this->swimlaneModel->remove($project['id'], $swimlane['id'])) {
$this->flash->success(t('Swimlane removed successfully.'));
} else {
$this->flash->failure(t('Unable to remove this swimlane.'));
@@ -182,9 +167,9 @@ class SwimlaneController extends BaseController
{
$this->checkCSRFParam();
$project = $this->getProject();
- $swimlane_id = $this->request->getIntegerParam('swimlane_id');
+ $swimlane = $this->getSwimlane($project);
- if ($this->swimlaneModel->disable($project['id'], $swimlane_id)) {
+ if ($this->swimlaneModel->disable($project['id'], $swimlane['id'])) {
$this->flash->success(t('Swimlane updated successfully.'));
} else {
$this->flash->failure(t('Unable to update this swimlane.'));
@@ -202,9 +187,9 @@ class SwimlaneController extends BaseController
{
$this->checkCSRFParam();
$project = $this->getProject();
- $swimlane_id = $this->request->getIntegerParam('swimlane_id');
+ $swimlane = $this->getSwimlane($project);
- if ($this->swimlaneModel->enable($project['id'], $swimlane_id)) {
+ if ($this->swimlaneModel->enable($project['id'], $swimlane['id'])) {
$this->flash->success(t('Swimlane updated successfully.'));
} else {
$this->flash->failure(t('Unable to update this swimlane.'));
diff --git a/app/Controller/TaskBulkController.php b/app/Controller/TaskBulkController.php
index 4345a68f..0f49fb76 100644
--- a/app/Controller/TaskBulkController.php
+++ b/app/Controller/TaskBulkController.php
@@ -35,6 +35,7 @@ class TaskBulkController extends BaseController
'users_list' => $this->projectUserRoleModel->getAssignableUsersList($project['id'], true, false, $project['is_private'] == 1),
'colors_list' => $this->colorModel->getList(),
'categories_list' => $this->categoryModel->getList($project['id']),
+ 'task_description_templates' => $this->predefinedTaskDescriptionModel->getList($project['id']),
)));
}
@@ -85,8 +86,18 @@ class TaskBulkController extends BaseController
'owner_id' => empty($values['owner_id']) ? 0 : $values['owner_id'],
'color_id' => $values['color_id'],
'project_id' => $project['id'],
+ 'description' => $this->getTaskDescription($project, $values),
));
}
}
}
+
+ protected function getTaskDescription(array $project, array $values)
+ {
+ if (empty($values['task_description_template_id'])) {
+ return '';
+ }
+
+ return $this->predefinedTaskDescriptionModel->getDescriptionById($project['id'], $values['task_description_template_id']);
+ }
}
diff --git a/app/Controller/TaskCreationController.php b/app/Controller/TaskCreationController.php
index 0d808c54..d050a60d 100644
--- a/app/Controller/TaskCreationController.php
+++ b/app/Controller/TaskCreationController.php
@@ -49,6 +49,7 @@ class TaskCreationController extends BaseController
{
$project = $this->getProject();
$values = $this->request->getValues();
+ $values['project_id'] = $project['id'];
list($valid, $errors) = $this->taskValidator->validateCreation($values);
diff --git a/app/Controller/TaskExternalLinkController.php b/app/Controller/TaskExternalLinkController.php
index df23f87b..946451fc 100644
--- a/app/Controller/TaskExternalLinkController.php
+++ b/app/Controller/TaskExternalLinkController.php
@@ -74,6 +74,8 @@ class TaskExternalLinkController extends BaseController
{
$task = $this->getTask();
$values = $this->request->getValues();
+ $values['task_id'] = $task['id'];
+
list($valid, $errors) = $this->externalLinkValidator->validateCreation($values);
if ($valid) {
@@ -108,22 +110,14 @@ class TaskExternalLinkController extends BaseController
public function edit(array $values = array(), array $errors = array())
{
$task = $this->getTask();
- $link_id = $this->request->getIntegerParam('link_id');
-
- if ($link_id > 0) {
- $values = $this->taskExternalLinkModel->getById($link_id);
- }
-
- if (empty($values)) {
- throw new PageNotFoundException();
- }
-
- $provider = $this->externalLinkManager->getProvider($values['link_type']);
+ $link = $this->getExternalTaskLink($task);
+ $provider = $this->externalLinkManager->getProvider($link['link_type']);
$this->response->html($this->template->render('task_external_link/edit', array(
- 'values' => $values,
- 'errors' => $errors,
- 'task' => $task,
+ 'values' => empty($values) ? $link : $values,
+ 'errors' => $errors,
+ 'task' => $task,
+ 'link' => $link,
'dependencies' => $provider->getDependencies(),
)));
}
@@ -136,7 +130,12 @@ class TaskExternalLinkController extends BaseController
public function update()
{
$task = $this->getTask();
+ $link = $this->getExternalTaskLink($task);
+
$values = $this->request->getValues();
+ $values['id'] = $link['id'];
+ $values['task_id'] = $link['task_id'];
+
list($valid, $errors) = $this->externalLinkValidator->validateModification($values);
if ($valid && $this->taskExternalLinkModel->update($values)) {
@@ -155,12 +154,7 @@ class TaskExternalLinkController extends BaseController
public function confirm()
{
$task = $this->getTask();
- $link_id = $this->request->getIntegerParam('link_id');
- $link = $this->taskExternalLinkModel->getById($link_id);
-
- if (empty($link)) {
- throw new PageNotFoundException();
- }
+ $link = $this->getExternalTaskLink($task);
$this->response->html($this->template->render('task_external_link/remove', array(
'link' => $link,
@@ -177,8 +171,9 @@ class TaskExternalLinkController extends BaseController
{
$this->checkCSRFParam();
$task = $this->getTask();
+ $link = $this->getExternalTaskLink($task);
- if ($this->taskExternalLinkModel->remove($this->request->getIntegerParam('link_id'))) {
+ if ($this->taskExternalLinkModel->remove($link['id'])) {
$this->flash->success(t('Link removed successfully.'));
} else {
$this->flash->failure(t('Unable to remove this link.'));
diff --git a/app/Controller/TaskGanttController.php b/app/Controller/TaskGanttController.php
deleted file mode 100644
index b03b9d00..00000000
--- a/app/Controller/TaskGanttController.php
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-
-namespace Kanboard\Controller;
-
-use Kanboard\Filter\TaskProjectFilter;
-use Kanboard\Model\TaskModel;
-
-/**
- * Tasks Gantt Controller
- *
- * @package Kanboard\Controller
- * @author Frederic Guillot
- */
-class TaskGanttController extends BaseController
-{
- /**
- * Show Gantt chart for one project
- */
- public function show()
- {
- $project = $this->getProject();
- $search = $this->helper->projectHeader->getSearchQuery($project);
- $sorting = $this->request->getStringParam('sorting', 'board');
- $filter = $this->taskLexer->build($search)->withFilter(new TaskProjectFilter($project['id']));
-
- if ($sorting === 'date') {
- $filter->getQuery()->asc(TaskModel::TABLE.'.date_started')->asc(TaskModel::TABLE.'.date_creation');
- } else {
- $filter->getQuery()->asc('column_position')->asc(TaskModel::TABLE.'.position');
- }
-
- $this->response->html($this->helper->layout->app('task_gantt/show', array(
- 'project' => $project,
- 'title' => $project['name'],
- 'description' => $this->helper->projectHeader->getDescription($project),
- 'sorting' => $sorting,
- 'tasks' => $filter->format($this->taskGanttFormatter),
- )));
- }
-
- /**
- * Save new task start date and due date
- */
- public function save()
- {
- $this->getProject();
- $values = $this->request->getJson();
-
- $result = $this->taskModificationModel->update(array(
- 'id' => $values['id'],
- 'date_started' => strtotime($values['start']),
- 'date_due' => strtotime($values['end']),
- ));
-
- if (! $result) {
- $this->response->json(array('message' => 'Unable to save task'), 400);
- } else {
- $this->response->json(array('message' => 'OK'), 201);
- }
- }
-}
diff --git a/app/Controller/TaskImportController.php b/app/Controller/TaskImportController.php
index 2e323979..d6506880 100644
--- a/app/Controller/TaskImportController.php
+++ b/app/Controller/TaskImportController.php
@@ -3,6 +3,7 @@
namespace Kanboard\Controller;
use Kanboard\Core\Csv;
+use Kanboard\Import\TaskImport;
/**
* Task Import controller
@@ -45,14 +46,15 @@ class TaskImportController extends BaseController
if (! file_exists($filename)) {
$this->show($values, array('file' => array(t('Unable to read your file'))));
} else {
- $this->taskImport->projectId = $project['id'];
+ $taskImport = new TaskImport($this->container);
+ $taskImport->setProjectId($project['id']);
$csv = new Csv($values['delimiter'], $values['enclosure']);
- $csv->setColumnMapping($this->taskImport->getColumnMapping());
- $csv->read($filename, array($this->taskImport, 'import'));
+ $csv->setColumnMapping($taskImport->getColumnMapping());
+ $csv->read($filename, array($taskImport, 'importTask'));
- if ($this->taskImport->counter > 0) {
- $this->flash->success(t('%d task(s) have been imported successfully.', $this->taskImport->counter));
+ if ($taskImport->getNumberOfImportedTasks() > 0) {
+ $this->flash->success(t('%d task(s) have been imported successfully.', $taskImport->getNumberOfImportedTasks()));
} else {
$this->flash->failure(t('Nothing have been imported!'));
}
@@ -67,7 +69,8 @@ class TaskImportController extends BaseController
*/
public function template()
{
+ $taskImport = new TaskImport($this->container);
$this->response->withFileDownload('tasks.csv');
- $this->response->csv(array($this->taskImport->getColumnMapping()));
+ $this->response->csv(array($taskImport->getColumnMapping()));
}
}
diff --git a/app/Controller/TaskInternalLinkController.php b/app/Controller/TaskInternalLinkController.php
index a140f1ff..02cc15c4 100644
--- a/app/Controller/TaskInternalLinkController.php
+++ b/app/Controller/TaskInternalLinkController.php
@@ -14,24 +14,6 @@ use Kanboard\Core\Controller\PageNotFoundException;
class TaskInternalLinkController extends BaseController
{
/**
- * Get the current link
- *
- * @access private
- * @return array
- * @throws PageNotFoundException
- */
- private function getTaskLink()
- {
- $link = $this->taskLinkModel->getById($this->request->getIntegerParam('link_id'));
-
- if (empty($link)) {
- throw new PageNotFoundException();
- }
-
- return $link;
- }
-
- /**
* Creation form
*
* @access public
@@ -44,6 +26,11 @@ class TaskInternalLinkController extends BaseController
{
$task = $this->getTask();
+ if (empty($values)) {
+ $values['another_tasklink'] = $this->request->getIntegerParam('another_tasklink', 0);
+ $values = $this->hook->merge('controller:tasklink:form:default', $values, array('default_values' => $values));
+ }
+
$this->response->html($this->template->render('task_internal_link/create', array(
'values' => $values,
'errors' => $errors,
@@ -61,12 +48,23 @@ class TaskInternalLinkController extends BaseController
{
$task = $this->getTask();
$values = $this->request->getValues();
+ $values['task_id'] = $task['id'];
list($valid, $errors) = $this->taskLinkValidator->validateCreation($values);
if ($valid) {
- if ($this->taskLinkModel->create($values['task_id'], $values['opposite_task_id'], $values['link_id'])) {
+ if ($this->taskLinkModel->create($values['task_id'], $values['opposite_task_id'], $values['link_id']) !== false) {
$this->flash->success(t('Link added successfully.'));
+
+ if (isset($values['another_tasklink']) && $values['another_tasklink'] == 1) {
+ return $this->create(array(
+ 'project_id' => $task['project_id'],
+ 'task_id' => $task['id'],
+ 'link_id' => $values['link_id'],
+ 'another_tasklink' => 1
+ ));
+ }
+
return $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true);
}
@@ -89,7 +87,7 @@ class TaskInternalLinkController extends BaseController
public function edit(array $values = array(), array $errors = array())
{
$task = $this->getTask();
- $task_link = $this->getTaskLink();
+ $task_link = $this->getInternalTaskLink($task);
if (empty($values)) {
$opposite_task = $this->taskFinderModel->getById($task_link['opposite_task_id']);
@@ -114,7 +112,11 @@ class TaskInternalLinkController extends BaseController
public function update()
{
$task = $this->getTask();
+ $task_link = $this->getInternalTaskLink($task);
+
$values = $this->request->getValues();
+ $values['task_id'] = $task['id'];
+ $values['id'] = $task_link['id'];
list($valid, $errors) = $this->taskLinkValidator->validateModification($values);
@@ -138,7 +140,7 @@ class TaskInternalLinkController extends BaseController
public function confirm()
{
$task = $this->getTask();
- $link = $this->getTaskLink();
+ $link = $this->getInternalTaskLink($task);
$this->response->html($this->template->render('task_internal_link/remove', array(
'link' => $link,
@@ -155,8 +157,9 @@ class TaskInternalLinkController extends BaseController
{
$this->checkCSRFParam();
$task = $this->getTask();
+ $link = $this->getInternalTaskLink($task);
- if ($this->taskLinkModel->remove($this->request->getIntegerParam('link_id'))) {
+ if ($this->taskLinkModel->remove($link['id'])) {
$this->flash->success(t('Link removed successfully.'));
} else {
$this->flash->failure(t('Unable to remove this link.'));
diff --git a/app/Controller/TaskMailController.php b/app/Controller/TaskMailController.php
index e95ddf03..feb96a68 100644
--- a/app/Controller/TaskMailController.php
+++ b/app/Controller/TaskMailController.php
@@ -20,6 +20,7 @@ class TaskMailController extends BaseController
'errors' => $errors,
'task' => $task,
'project' => $project,
+ 'members' => $this->projectPermissionModel->getMembersWithEmail($project['id']),
)));
}
@@ -33,6 +34,13 @@ class TaskMailController extends BaseController
if ($valid) {
$this->sendByEmail($values, $task);
$this->flash->success(t('Task sent by email successfully.'));
+
+ $this->commentModel->create(array(
+ 'comment' => t('This task was sent by email to "%s" with subject "%s".', $values['email'], $values['subject']),
+ 'user_id' => $this->userSession->getId(),
+ 'task_id' => $task['id'],
+ ));
+
$this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), 'comments'), true);
} else {
$this->create($values, $errors);
diff --git a/app/Controller/TaskModificationController.php b/app/Controller/TaskModificationController.php
index 520bf70e..338ed540 100644
--- a/app/Controller/TaskModificationController.php
+++ b/app/Controller/TaskModificationController.php
@@ -22,7 +22,11 @@ class TaskModificationController extends BaseController
public function start()
{
$task = $this->getTask();
- $this->taskModificationModel->update(array('id' => $task['id'], 'date_started' => time()));
+ $values = array('id' => $task['id'], 'date_started' => time());
+ if (! $this->helper->projectRole->canUpdateTask($task)) {
+ throw new AccessForbiddenException(t('You are not allowed to update tasks assigned to someone else.'));
+ }
+ $this->taskModificationModel->update($values);
$this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])));
}
@@ -38,6 +42,11 @@ class TaskModificationController extends BaseController
public function edit(array $values = array(), array $errors = array())
{
$task = $this->getTask();
+
+ if (! $this->helper->projectRole->canUpdateTask($task)) {
+ throw new AccessForbiddenException(t('You are not allowed to update tasks assigned to someone else.'));
+ }
+
$project = $this->projectModel->getById($task['project_id']);
if (empty($values)) {
@@ -89,6 +98,8 @@ class TaskModificationController extends BaseController
{
$task = $this->getTask();
$values = $this->request->getValues();
+ $values['id'] = $task['id'];
+ $values['project_id'] = $task['project_id'];
list($valid, $errors) = $this->taskValidator->validateModification($values);
@@ -103,6 +114,14 @@ class TaskModificationController extends BaseController
protected function updateTask(array &$task, array &$values, array &$errors)
{
+ if (isset($values['owner_id']) && $values['owner_id'] != $task['owner_id'] && !$this->helper->projectRole->canChangeAssignee($task)) {
+ throw new AccessForbiddenException(t('You are not allowed to change the assignee.'));
+ }
+
+ if (! $this->helper->projectRole->canUpdateTask($task)) {
+ throw new AccessForbiddenException(t('You are not allowed to update tasks assigned to someone else.'));
+ }
+
$result = $this->taskModificationModel->update($values);
if ($result && ! empty($task['external_uri'])) {
diff --git a/app/Controller/TaskRecurrenceController.php b/app/Controller/TaskRecurrenceController.php
index c6fdfa37..7f14cb53 100644
--- a/app/Controller/TaskRecurrenceController.php
+++ b/app/Controller/TaskRecurrenceController.php
@@ -47,6 +47,7 @@ class TaskRecurrenceController extends BaseController
{
$task = $this->getTask();
$values = $this->request->getValues();
+ $values['id'] = $task['id'];
list($valid, $errors) = $this->taskValidator->validateEditRecurrence($values);
diff --git a/app/Controller/UserAjaxController.php b/app/Controller/UserAjaxController.php
index 17567a00..57596202 100644
--- a/app/Controller/UserAjaxController.php
+++ b/app/Controller/UserAjaxController.php
@@ -2,9 +2,6 @@
namespace Kanboard\Controller;
-use Kanboard\Filter\UserNameFilter;
-use Kanboard\Model\UserModel;
-
/**
* User Ajax Controller
*
@@ -21,9 +18,8 @@ class UserAjaxController extends BaseController
public function autocomplete()
{
$search = $this->request->getStringParam('term');
- $filter = $this->userQuery->withFilter(new UserNameFilter($search));
- $filter->getQuery()->asc(UserModel::TABLE.'.name')->asc(UserModel::TABLE.'.username');
- $this->response->json($filter->format($this->userAutoCompleteFormatter));
+ $users = $this->userManager->find($search);
+ $this->response->json($this->userAutoCompleteFormatter->withUsers($users)->format());
}
/**
diff --git a/app/Controller/UserApiAccessController.php b/app/Controller/UserApiAccessController.php
index 0f1c891e..f9628ae6 100644
--- a/app/Controller/UserApiAccessController.php
+++ b/app/Controller/UserApiAccessController.php
@@ -32,7 +32,7 @@ class UserApiAccessController extends BaseController
'api_access_token' => Token::getToken(),
));
- $this->renderResponse();
+ $this->renderResponse($user);
}
public function remove()
@@ -45,10 +45,10 @@ class UserApiAccessController extends BaseController
'api_access_token' => null,
));
- $this->renderResponse();
+ $this->renderResponse($user);
}
- protected function renderResponse()
+ protected function renderResponse(array $user)
{
if ($this->request->isAjax()) {
$this->show();
diff --git a/app/Controller/UserCredentialController.php b/app/Controller/UserCredentialController.php
index 23e7edba..a8b90b7b 100644
--- a/app/Controller/UserCredentialController.php
+++ b/app/Controller/UserCredentialController.php
@@ -43,6 +43,14 @@ class UserCredentialController extends BaseController
list($valid, $errors) = $this->userValidator->validatePasswordModification($values);
+ if (! $this->userSession->isAdmin()) {
+ $values = array(
+ 'id' => $this->userSession->getId(),
+ 'password' => isset($values['password']) ? $values['password'] : '',
+ 'confirmation' => isset($values['confirmation']) ? $values['confirmation'] : '',
+ );
+ }
+
if ($valid) {
if ($this->userModel->update($values)) {
$this->flash->success(t('Password modified successfully.'));
diff --git a/app/Controller/UserModificationController.php b/app/Controller/UserModificationController.php
index ed145921..f4916f6f 100644
--- a/app/Controller/UserModificationController.php
+++ b/app/Controller/UserModificationController.php
@@ -47,9 +47,14 @@ class UserModificationController extends BaseController
$values = $this->request->getValues();
if (! $this->userSession->isAdmin()) {
- if (isset($values['role'])) {
- unset($values['role']);
- }
+ $values = array(
+ 'id' => $this->userSession->getId(),
+ 'username' => isset($values['username']) ? $values['username'] : '',
+ 'name' => isset($values['name']) ? $values['name'] : '',
+ 'email' => isset($values['email']) ? $values['email'] : '',
+ 'timezone' => isset($values['timezone']) ? $values['timezone'] : '',
+ 'language' => isset($values['language']) ? $values['language'] : '',
+ );
}
list($valid, $errors) = $this->userValidator->validateModification($values);