summaryrefslogtreecommitdiff
path: root/app/Controller
diff options
context:
space:
mode:
Diffstat (limited to 'app/Controller')
-rw-r--r--app/Controller/Action.php100
-rw-r--r--app/Controller/ActionCreation.php121
-rw-r--r--app/Controller/ActionProject.php38
-rw-r--r--app/Controller/Activity.php5
-rw-r--r--app/Controller/Analytic.php33
-rw-r--r--app/Controller/App.php36
-rw-r--r--app/Controller/Auth.php12
-rw-r--r--app/Controller/Base.php96
-rw-r--r--app/Controller/Board.php4
-rw-r--r--app/Controller/BoardPopover.php7
-rw-r--r--app/Controller/BoardTooltip.php20
-rw-r--r--app/Controller/Calendar.php2
-rw-r--r--app/Controller/Category.php6
-rw-r--r--app/Controller/Column.php84
-rw-r--r--app/Controller/Comment.php33
-rw-r--r--app/Controller/Config.php47
-rw-r--r--app/Controller/Currency.php18
-rw-r--r--app/Controller/Customfilter.php21
-rw-r--r--app/Controller/Doc.php4
-rw-r--r--app/Controller/Export.php6
-rw-r--r--app/Controller/File.php192
-rw-r--r--app/Controller/FileViewer.php116
-rw-r--r--app/Controller/Gantt.php23
-rw-r--r--app/Controller/Group.php19
-rw-r--r--app/Controller/Ical.php3
-rw-r--r--app/Controller/Link.php22
-rw-r--r--app/Controller/Listing.php5
-rw-r--r--app/Controller/Oauth.php46
-rw-r--r--app/Controller/PasswordReset.php4
-rw-r--r--app/Controller/Project.php79
-rw-r--r--app/Controller/ProjectCreation.php125
-rw-r--r--app/Controller/ProjectEdit.php6
-rw-r--r--app/Controller/ProjectFile.php79
-rw-r--r--app/Controller/ProjectOverview.php29
-rw-r--r--app/Controller/ProjectPermission.php58
-rw-r--r--app/Controller/Projectuser.php27
-rw-r--r--app/Controller/Search.php3
-rw-r--r--app/Controller/Subtask.php140
-rw-r--r--app/Controller/SubtaskRestriction.php61
-rw-r--r--app/Controller/SubtaskStatus.php72
-rw-r--r--app/Controller/Swimlane.php103
-rw-r--r--app/Controller/Task.php36
-rw-r--r--app/Controller/TaskExternalLink.php185
-rw-r--r--app/Controller/TaskFile.php98
-rw-r--r--app/Controller/TaskImport.php2
-rw-r--r--app/Controller/TaskRecurrence.php61
-rw-r--r--app/Controller/Taskcreation.php39
-rw-r--r--app/Controller/Taskduplication.php12
-rw-r--r--app/Controller/Tasklink.php49
-rw-r--r--app/Controller/Taskmodification.php136
-rw-r--r--app/Controller/Taskstatus.php42
-rw-r--r--app/Controller/Timer.php34
-rw-r--r--app/Controller/Twofactor.php8
-rw-r--r--app/Controller/User.php83
-rw-r--r--app/Controller/UserImport.php2
-rw-r--r--app/Controller/UserStatus.php111
56 files changed, 1646 insertions, 1157 deletions
diff --git a/app/Controller/Action.php b/app/Controller/Action.php
index 645b53b7..8881e8ec 100644
--- a/app/Controller/Action.php
+++ b/app/Controller/Action.php
@@ -3,7 +3,7 @@
namespace Kanboard\Controller;
/**
- * Automatic actions management
+ * Automatic Actions
*
* @package controller
* @author Frederic Guillot
@@ -20,14 +20,14 @@ class Action extends Base
$project = $this->getProject();
$actions = $this->action->getAllByProject($project['id']);
- $this->response->html($this->projectLayout('action/index', array(
+ $this->response->html($this->helper->layout->project('action/index', array(
'values' => array('project_id' => $project['id']),
'project' => $project,
'actions' => $actions,
'available_actions' => $this->actionManager->getAvailableActions(),
'available_events' => $this->eventManager->getAll(),
'available_params' => $this->actionManager->getAvailableParameters($actions),
- 'columns_list' => $this->board->getColumnsList($project['id']),
+ 'columns_list' => $this->column->getList($project['id']),
'users_list' => $this->projectUserRole->getAssignableUsersList($project['id']),
'projects_list' => $this->projectUserRole->getProjectsByUser($this->userSession->getId()),
'colors_list' => $this->color->getList(),
@@ -38,98 +38,6 @@ class Action extends Base
}
/**
- * Choose the event according to the action (step 2)
- *
- * @access public
- */
- public function event()
- {
- $project = $this->getProject();
- $values = $this->request->getValues();
-
- if (empty($values['action_name']) || empty($values['project_id'])) {
- $this->response->redirect($this->helper->url->to('action', 'index', array('project_id' => $project['id'])));
- }
-
- $this->response->html($this->projectLayout('action/event', array(
- 'values' => $values,
- 'project' => $project,
- 'events' => $this->actionManager->getCompatibleEvents($values['action_name']),
- 'title' => t('Automatic actions')
- )));
- }
-
- /**
- * Define action parameters (step 3)
- *
- * @access public
- */
- public function params()
- {
- $project = $this->getProject();
- $values = $this->request->getValues();
-
- if (empty($values['action_name']) || empty($values['project_id']) || empty($values['event_name'])) {
- $this->response->redirect($this->helper->url->to('action', 'index', array('project_id' => $project['id'])));
- }
-
- $action = $this->actionManager->getAction($values['action_name']);
- $action_params = $action->getActionRequiredParameters();
-
- if (empty($action_params)) {
- $this->doCreation($project, $values + array('params' => array()));
- }
-
- $projects_list = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
- unset($projects_list[$project['id']]);
-
- $this->response->html($this->projectLayout('action/params', array(
- 'values' => $values,
- 'action_params' => $action_params,
- 'columns_list' => $this->board->getColumnsList($project['id']),
- 'users_list' => $this->projectUserRole->getAssignableUsersList($project['id']),
- 'projects_list' => $projects_list,
- 'colors_list' => $this->color->getList(),
- 'categories_list' => $this->category->getList($project['id']),
- 'links_list' => $this->link->getList(0, false),
- 'project' => $project,
- 'title' => t('Automatic actions')
- )));
- }
-
- /**
- * Create a new action (last step)
- *
- * @access public
- */
- public function create()
- {
- $this->doCreation($this->getProject(), $this->request->getValues());
- }
-
- /**
- * Save the action
- *
- * @access private
- * @param array $project Project properties
- * @param array $values Form values
- */
- private function doCreation(array $project, array $values)
- {
- list($valid, ) = $this->actionValidator->validateCreation($values);
-
- if ($valid) {
- if ($this->action->create($values) !== false) {
- $this->flash->success(t('Your automatic action have been created successfully.'));
- } else {
- $this->flash->failure(t('Unable to create your automatic action.'));
- }
- }
-
- $this->response->redirect($this->helper->url->to('action', 'index', array('project_id' => $project['id'])));
- }
-
- /**
* Confirmation dialog before removing an action
*
* @access public
@@ -138,7 +46,7 @@ class Action extends Base
{
$project = $this->getProject();
- $this->response->html($this->projectLayout('action/remove', array(
+ $this->response->html($this->helper->layout->project('action/remove', array(
'action' => $this->action->getById($this->request->getIntegerParam('action_id')),
'available_events' => $this->eventManager->getAll(),
'available_actions' => $this->actionManager->getAvailableActions(),
diff --git a/app/Controller/ActionCreation.php b/app/Controller/ActionCreation.php
new file mode 100644
index 00000000..24a12d92
--- /dev/null
+++ b/app/Controller/ActionCreation.php
@@ -0,0 +1,121 @@
+<?php
+
+namespace Kanboard\Controller;
+
+/**
+ * Action Creation
+ *
+ * @package controller
+ * @author Frederic Guillot
+ */
+class ActionCreation extends Base
+{
+ /**
+ * Show the form (step 1)
+ *
+ * @access public
+ */
+ public function create()
+ {
+ $project = $this->getProject();
+
+ $this->response->html($this->template->render('action_creation/create', array(
+ 'project' => $project,
+ 'values' => array('project_id' => $project['id']),
+ 'available_actions' => $this->actionManager->getAvailableActions(),
+ )));
+ }
+
+ /**
+ * Choose the event according to the action (step 2)
+ *
+ * @access public
+ */
+ public function event()
+ {
+ $project = $this->getProject();
+ $values = $this->request->getValues();
+
+ if (empty($values['action_name']) || empty($values['project_id'])) {
+ return $this->create();
+ }
+
+ $this->response->html($this->template->render('action_creation/event', array(
+ 'values' => $values,
+ 'project' => $project,
+ 'available_actions' => $this->actionManager->getAvailableActions(),
+ 'events' => $this->actionManager->getCompatibleEvents($values['action_name']),
+ )));
+ }
+
+ /**
+ * Define action parameters (step 3)
+ *
+ * @access public
+ */
+ public function params()
+ {
+ $project = $this->getProject();
+ $values = $this->request->getValues();
+
+ if (empty($values['action_name']) || empty($values['project_id']) || empty($values['event_name'])) {
+ return $this->create();
+ }
+
+ $action = $this->actionManager->getAction($values['action_name']);
+ $action_params = $action->getActionRequiredParameters();
+
+ if (empty($action_params)) {
+ $this->doCreation($project, $values + array('params' => array()));
+ }
+
+ $projects_list = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
+ unset($projects_list[$project['id']]);
+
+ $this->response->html($this->template->render('action_creation/params', array(
+ 'values' => $values,
+ 'action_params' => $action_params,
+ 'columns_list' => $this->column->getList($project['id']),
+ 'users_list' => $this->projectUserRole->getAssignableUsersList($project['id']),
+ 'projects_list' => $projects_list,
+ 'colors_list' => $this->color->getList(),
+ 'categories_list' => $this->category->getList($project['id']),
+ 'links_list' => $this->link->getList(0, false),
+ 'project' => $project,
+ 'available_actions' => $this->actionManager->getAvailableActions(),
+ 'events' => $this->actionManager->getCompatibleEvents($values['action_name']),
+ )));
+ }
+
+ /**
+ * Save the action (last step)
+ *
+ * @access public
+ */
+ public function save()
+ {
+ $this->doCreation($this->getProject(), $this->request->getValues());
+ }
+
+ /**
+ * Common method to save the action
+ *
+ * @access private
+ * @param array $project Project properties
+ * @param array $values Form values
+ */
+ private function doCreation(array $project, array $values)
+ {
+ list($valid, ) = $this->actionValidator->validateCreation($values);
+
+ if ($valid) {
+ if ($this->action->create($values) !== false) {
+ $this->flash->success(t('Your automatic action have been created successfully.'));
+ } else {
+ $this->flash->failure(t('Unable to create your automatic action.'));
+ }
+ }
+
+ $this->response->redirect($this->helper->url->to('action', 'index', array('project_id' => $project['id'])));
+ }
+}
diff --git a/app/Controller/ActionProject.php b/app/Controller/ActionProject.php
new file mode 100644
index 00000000..e5063f73
--- /dev/null
+++ b/app/Controller/ActionProject.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace Kanboard\Controller;
+
+/**
+ * Duplicate automatic action from another project
+ *
+ * @package controller
+ * @author Frederic Guillot
+ */
+class ActionProject extends Base
+{
+ public function project()
+ {
+ $project = $this->getProject();
+ $projects = $this->projectUserRole->getProjectsByUser($this->userSession->getId());
+ unset($projects[$project['id']]);
+
+ $this->response->html($this->template->render('action_project/project', array(
+ 'project' => $project,
+ 'projects_list' => $projects,
+ )));
+ }
+
+ public function save()
+ {
+ $project = $this->getProject();
+ $src_project_id = $this->request->getValue('src_project_id');
+
+ if ($this->action->duplicate($src_project_id, $project['id'])) {
+ $this->flash->success(t('Actions duplicated successfully.'));
+ } else {
+ $this->flash->failure(t('Unable to duplicate actions.'));
+ }
+
+ $this->response->redirect($this->helper->url->to('action', 'index', array('project_id' => $project['id'])));
+ }
+}
diff --git a/app/Controller/Activity.php b/app/Controller/Activity.php
index 38658345..db520ebe 100644
--- a/app/Controller/Activity.php
+++ b/app/Controller/Activity.php
@@ -19,8 +19,7 @@ class Activity extends Base
{
$project = $this->getProject();
- $this->response->html($this->template->layout('activity/project', array(
- 'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
+ $this->response->html($this->helper->layout->app('activity/project', array(
'events' => $this->projectActivity->getProject($project['id']),
'project' => $project,
'title' => t('%s\'s activity', $project['name'])
@@ -36,7 +35,7 @@ class Activity extends Base
{
$task = $this->getTask();
- $this->response->html($this->taskLayout('activity/task', array(
+ $this->response->html($this->helper->layout->task('activity/task', array(
'title' => $task['title'],
'task' => $task,
'events' => $this->projectActivity->getTask($task['id']),
diff --git a/app/Controller/Analytic.php b/app/Controller/Analytic.php
index d203fb8e..6ce062c4 100644
--- a/app/Controller/Analytic.php
+++ b/app/Controller/Analytic.php
@@ -1,6 +1,7 @@
<?php
namespace Kanboard\Controller;
+
use Kanboard\Model\Task as TaskModel;
/**
@@ -12,22 +13,6 @@ use Kanboard\Model\Task as TaskModel;
class Analytic extends Base
{
/**
- * Common layout for analytic views
- *
- * @access private
- * @param string $template Template name
- * @param array $params Template parameters
- * @return string
- */
- private function layout($template, array $params)
- {
- $params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
- $params['content_for_sublayout'] = $this->template->render($template, $params);
-
- return $this->template->layout('analytic/layout', $params);
- }
-
- /**
* Show average Lead and Cycle time
*
* @access public
@@ -37,7 +22,7 @@ class Analytic extends Base
$project = $this->getProject();
list($from, $to) = $this->getDates();
- $this->response->html($this->layout('analytic/lead_cycle_time', array(
+ $this->response->html($this->helper->layout->analytic('analytic/lead_cycle_time', array(
'values' => array(
'from' => $from,
'to' => $to,
@@ -46,7 +31,7 @@ class Analytic extends Base
'average' => $this->averageLeadCycleTimeAnalytic->build($project['id']),
'metrics' => $this->projectDailyStats->getRawMetrics($project['id'], $from, $to),
'date_format' => $this->config->get('application_date_format'),
- 'date_formats' => $this->dateParser->getAvailableFormats(),
+ 'date_formats' => $this->dateParser->getAvailableFormats($this->dateParser->getDateFormats()),
'title' => t('Lead and Cycle time for "%s"', $project['name']),
)));
}
@@ -69,7 +54,7 @@ class Analytic extends Base
->setQuery($query)
->calculate();
- $this->response->html($this->layout('analytic/compare_hours', array(
+ $this->response->html($this->helper->layout->analytic('analytic/compare_hours', array(
'project' => $project,
'paginator' => $paginator,
'metrics' => $this->estimatedTimeComparisonAnalytic->build($project['id']),
@@ -86,7 +71,7 @@ class Analytic extends Base
{
$project = $this->getProject();
- $this->response->html($this->layout('analytic/avg_time_columns', array(
+ $this->response->html($this->helper->layout->analytic('analytic/avg_time_columns', array(
'project' => $project,
'metrics' => $this->averageTimeSpentColumnAnalytic->build($project['id']),
'title' => t('Average time spent into each column for "%s"', $project['name']),
@@ -102,7 +87,7 @@ class Analytic extends Base
{
$project = $this->getProject();
- $this->response->html($this->layout('analytic/tasks', array(
+ $this->response->html($this->helper->layout->analytic('analytic/tasks', array(
'project' => $project,
'metrics' => $this->taskDistributionAnalytic->build($project['id']),
'title' => t('Task repartition for "%s"', $project['name']),
@@ -118,7 +103,7 @@ class Analytic extends Base
{
$project = $this->getProject();
- $this->response->html($this->layout('analytic/users', array(
+ $this->response->html($this->helper->layout->analytic('analytic/users', array(
'project' => $project,
'metrics' => $this->userDistributionAnalytic->build($project['id']),
'title' => t('User repartition for "%s"', $project['name']),
@@ -160,7 +145,7 @@ class Analytic extends Base
$display_graph = $this->projectDailyColumnStats->countDays($project['id'], $from, $to) >= 2;
- $this->response->html($this->layout($template, array(
+ $this->response->html($this->helper->layout->analytic($template, array(
'values' => array(
'from' => $from,
'to' => $to,
@@ -169,7 +154,7 @@ class Analytic extends Base
'metrics' => $display_graph ? $this->projectDailyColumnStats->getAggregatedMetrics($project['id'], $from, $to, $column) : array(),
'project' => $project,
'date_format' => $this->config->get('application_date_format'),
- 'date_formats' => $this->dateParser->getAvailableFormats(),
+ 'date_formats' => $this->dateParser->getAvailableFormats($this->dateParser->getDateFormats()),
'title' => t($title, $project['name']),
)));
}
diff --git a/app/Controller/App.php b/app/Controller/App.php
index bdd7fbcf..df1d3c90 100644
--- a/app/Controller/App.php
+++ b/app/Controller/App.php
@@ -2,6 +2,7 @@
namespace Kanboard\Controller;
+use Kanboard\Model\Project as ProjectModel;
use Kanboard\Model\Subtask as SubtaskModel;
/**
@@ -13,35 +14,20 @@ use Kanboard\Model\Subtask as SubtaskModel;
class App extends Base
{
/**
- * Common layout for dashboard views
- *
- * @access private
- * @param string $template Template name
- * @param array $params Template parameters
- * @return string
- */
- private function layout($template, array $params)
- {
- $params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
- $params['content_for_sublayout'] = $this->template->render($template, $params);
-
- return $this->template->layout('app/layout', $params);
- }
-
- /**
* Get project pagination
*
* @access private
* @param integer $user_id
* @param string $action
* @param integer $max
+ * @return \Kanboard\Core\Paginator
*/
private function getProjectPaginator($user_id, $action, $max)
{
return $this->paginator
->setUrl('app', $action, array('pagination' => 'projects', 'user_id' => $user_id))
->setMax($max)
- ->setOrder('name')
+ ->setOrder(ProjectModel::TABLE.'.name')
->setQuery($this->project->getQueryColumnStats($this->projectPermission->getActiveProjectIds($user_id)))
->calculateOnlyIf($this->request->getStringParam('pagination') === 'projects');
}
@@ -53,6 +39,7 @@ class App extends Base
* @param integer $user_id
* @param string $action
* @param integer $max
+ * @return \Kanboard\Core\Paginator
*/
private function getTaskPaginator($user_id, $action, $max)
{
@@ -71,6 +58,7 @@ class App extends Base
* @param integer $user_id
* @param string $action
* @param integer $max
+ * @return \Kanboard\Core\Paginator
*/
private function getSubtaskPaginator($user_id, $action, $max)
{
@@ -101,7 +89,7 @@ class App extends Base
{
$user = $this->getUser();
- $this->response->html($this->layout('app/overview', array(
+ $this->response->html($this->helper->layout->dashboard('app/overview', array(
'title' => t('Dashboard'),
'project_paginator' => $this->getProjectPaginator($user['id'], 'index', 10),
'task_paginator' => $this->getTaskPaginator($user['id'], 'index', 10),
@@ -119,7 +107,7 @@ class App extends Base
{
$user = $this->getUser();
- $this->response->html($this->layout('app/tasks', array(
+ $this->response->html($this->helper->layout->dashboard('app/tasks', array(
'title' => t('My tasks'),
'paginator' => $this->getTaskPaginator($user['id'], 'tasks', 50),
'user' => $user,
@@ -135,7 +123,7 @@ class App extends Base
{
$user = $this->getUser();
- $this->response->html($this->layout('app/subtasks', array(
+ $this->response->html($this->helper->layout->dashboard('app/subtasks', array(
'title' => t('My subtasks'),
'paginator' => $this->getSubtaskPaginator($user['id'], 'subtasks', 50),
'user' => $user,
@@ -151,7 +139,7 @@ class App extends Base
{
$user = $this->getUser();
- $this->response->html($this->layout('app/projects', array(
+ $this->response->html($this->helper->layout->dashboard('app/projects', array(
'title' => t('My projects'),
'paginator' => $this->getProjectPaginator($user['id'], 'projects', 25),
'user' => $user,
@@ -167,7 +155,7 @@ class App extends Base
{
$user = $this->getUser();
- $this->response->html($this->layout('app/activity', array(
+ $this->response->html($this->helper->layout->dashboard('app/activity', array(
'title' => t('My activity stream'),
'events' => $this->projectActivity->getProjects($this->projectPermission->getActiveProjectIds($user['id']), 100),
'user' => $user,
@@ -181,7 +169,7 @@ class App extends Base
*/
public function calendar()
{
- $this->response->html($this->layout('app/calendar', array(
+ $this->response->html($this->helper->layout->dashboard('app/calendar', array(
'title' => t('My calendar'),
'user' => $this->getUser(),
)));
@@ -196,7 +184,7 @@ class App extends Base
{
$user = $this->getUser();
- $this->response->html($this->layout('app/notifications', array(
+ $this->response->html($this->helper->layout->dashboard('app/notifications', array(
'title' => t('My notifications'),
'notifications' => $this->userUnreadNotification->getAll($user['id']),
'user' => $user,
diff --git a/app/Controller/Auth.php b/app/Controller/Auth.php
index 5284e126..b882a720 100644
--- a/app/Controller/Auth.php
+++ b/app/Controller/Auth.php
@@ -14,6 +14,8 @@ class Auth extends Base
* Display the form login
*
* @access public
+ * @param array $values
+ * @param array $errors
*/
public function login(array $values = array(), array $errors = array())
{
@@ -21,7 +23,7 @@ class Auth extends Base
$this->response->redirect($this->helper->url->to('app', 'index'));
}
- $this->response->html($this->template->layout('auth/index', array(
+ $this->response->html($this->helper->layout->app('auth/index', array(
'captcha' => ! empty($values['username']) && $this->userLocking->hasCaptcha($values['username']),
'errors' => $errors,
'values' => $values,
@@ -55,8 +57,12 @@ class Auth extends Base
*/
public function logout()
{
- $this->sessionManager->close();
- $this->response->redirect($this->helper->url->to('auth', 'login'));
+ if (! DISABLE_LOGOUT) {
+ $this->sessionManager->close();
+ $this->response->redirect($this->helper->url->to('auth', 'login'));
+ } else {
+ $this->response->redirect($this->helper->url->to('auth', 'index'));
+ }
}
/**
diff --git a/app/Controller/Base.php b/app/Controller/Base.php
index efeab31e..2453be18 100644
--- a/app/Controller/Base.php
+++ b/app/Controller/Base.php
@@ -131,7 +131,7 @@ abstract class Base extends \Kanboard\Core\Base
*/
protected function notfound($no_layout = false)
{
- $this->response->html($this->template->layout('app/notfound', array(
+ $this->response->html($this->helper->layout->app('app/notfound', array(
'title' => t('Page not found'),
'no_layout' => $no_layout,
)));
@@ -149,7 +149,7 @@ abstract class Base extends \Kanboard\Core\Base
$this->response->text('Access Forbidden', 403);
}
- $this->response->html($this->template->layout('app/forbidden', array(
+ $this->response->html($this->helper->layout->app('app/forbidden', array(
'title' => t('Access Forbidden'),
'no_layout' => $no_layout,
)));
@@ -180,43 +180,6 @@ abstract class Base extends \Kanboard\Core\Base
}
/**
- * Common layout for task views
- *
- * @access protected
- * @param string $template Template name
- * @param array $params Template parameters
- * @return string
- */
- protected function taskLayout($template, array $params)
- {
- $content = $this->template->render($template, $params);
- $params['task_content_for_layout'] = $content;
- $params['title'] = $params['task']['project_name'].' &gt; '.$params['task']['title'];
- $params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
-
- return $this->template->layout('task/layout', $params);
- }
-
- /**
- * Common layout for project views
- *
- * @access protected
- * @param string $template Template name
- * @param array $params Template parameters
- * @return string
- */
- protected function projectLayout($template, array $params, $sidebar_template = 'project/sidebar')
- {
- $content = $this->template->render($template, $params);
- $params['project_content_for_layout'] = $content;
- $params['title'] = $params['project']['name'] === $params['title'] ? $params['title'] : $params['project']['name'].' &gt; '.$params['title'];
- $params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
- $params['sidebar_template'] = $sidebar_template;
-
- return $this->template->layout('project/layout', $params);
- }
-
- /**
* Common method to get a task for task views
*
* @access protected
@@ -239,6 +202,36 @@ abstract class Base extends \Kanboard\Core\Base
}
/**
+ * Get Task or Project file
+ *
+ * @access protected
+ */
+ protected function getFile()
+ {
+ $task_id = $this->request->getIntegerParam('task_id');
+ $file_id = $this->request->getIntegerParam('file_id');
+ $model = 'projectFile';
+
+ if ($task_id > 0) {
+ $model = 'taskFile';
+ $project_id = $this->taskFinder->getProjectId($task_id);
+
+ if ($project_id !== $this->request->getIntegerParam('project_id')) {
+ $this->forbidden();
+ }
+ }
+
+ $file = $this->$model->getById($file_id);
+
+ if (empty($file)) {
+ $this->notfound();
+ }
+
+ $file['model'] = $model;
+ return $file;
+ }
+
+ /**
* Common method to get a project
*
* @access protected
@@ -251,8 +244,7 @@ abstract class Base extends \Kanboard\Core\Base
$project = $this->project->getByIdWithOwner($project_id);
if (empty($project)) {
- $this->flash->failure(t('Project not found.'));
- $this->response->redirect($this->helper->url->to('project', 'index'));
+ $this->notfound();
}
return $project;
@@ -280,6 +272,23 @@ abstract class Base extends \Kanboard\Core\Base
}
/**
+ * Get the current subtask
+ *
+ * @access protected
+ * @return array
+ */
+ protected function getSubtask()
+ {
+ $subtask = $this->subtask->getById($this->request->getIntegerParam('subtask_id'));
+
+ if (empty($subtask)) {
+ $this->notfound();
+ }
+
+ return $subtask;
+ }
+
+ /**
* Common method to get project filters
*
* @access protected
@@ -319,9 +328,10 @@ abstract class Base extends \Kanboard\Core\Base
* @param array &$project
* @return string
*/
- protected function getProjectDescription(array &$project) {
+ protected function getProjectDescription(array &$project)
+ {
if ($project['owner_id'] > 0) {
- $description = t('Project owner: ').'**'.$this->template->e($project['owner_name'] ?: $project['owner_username']).'**'.PHP_EOL.PHP_EOL;
+ $description = t('Project owner: ').'**'.$this->helper->text->e($project['owner_name'] ?: $project['owner_username']).'**'.PHP_EOL.PHP_EOL;
if (! empty($project['description'])) {
$description .= '***'.PHP_EOL.PHP_EOL;
diff --git a/app/Controller/Board.php b/app/Controller/Board.php
index f64de69a..199f1703 100644
--- a/app/Controller/Board.php
+++ b/app/Controller/Board.php
@@ -27,7 +27,7 @@ class Board extends Base
}
// Display the board with a specific layout
- $this->response->html($this->template->layout('board/view_public', array(
+ $this->response->html($this->helper->layout->app('board/view_public', array(
'project' => $project,
'swimlanes' => $this->board->getBoard($project['id']),
'title' => $project['name'],
@@ -49,7 +49,7 @@ class Board extends Base
{
$params = $this->getProjectFilters('board', 'show');
- $this->response->html($this->template->layout('board/view_private', array(
+ $this->response->html($this->helper->layout->app('board/view_private', array(
'categories_list' => $this->category->getList($params['project']['id'], false),
'users_list' => $this->projectUserRole->getAssignableUsersList($params['project']['id'], false),
'custom_filters_list' => $this->customFilter->getAll($params['project']['id'], $this->userSession->getId()),
diff --git a/app/Controller/BoardPopover.php b/app/Controller/BoardPopover.php
index a214439a..63dab302 100644
--- a/app/Controller/BoardPopover.php
+++ b/app/Controller/BoardPopover.php
@@ -93,9 +93,8 @@ class BoardPopover extends Base
{
$task = $this->getTask();
- $this->response->html($this->template->render('file/screenshot', array(
+ $this->response->html($this->template->render('task_file/screenshot', array(
'task' => $task,
- 'redirect' => 'board',
)));
}
@@ -113,7 +112,7 @@ class BoardPopover extends Base
$this->response->html($this->template->render('board/popover_close_all_tasks_column', array(
'project' => $project,
'nb_tasks' => $this->taskFinder->countByColumnAndSwimlaneId($project['id'], $column_id, $swimlane_id),
- 'column' => $this->board->getColumnTitleById($column_id),
+ 'column' => $this->column->getColumnTitleById($column_id),
'swimlane' => $this->swimlane->getNameById($swimlane_id) ?: t($project['default_swimlane']),
'values' => array('column_id' => $column_id, 'swimlane_id' => $swimlane_id),
)));
@@ -130,7 +129,7 @@ class BoardPopover extends Base
$values = $this->request->getValues();
$this->taskStatus->closeTasksBySwimlaneAndColumn($values['swimlane_id'], $values['column_id']);
- $this->flash->success(t('All tasks of the column "%s" and the swimlane "%s" have been closed successfully.', $this->board->getColumnTitleById($values['column_id']), $this->swimlane->getNameById($values['swimlane_id']) ?: t($project['default_swimlane'])));
+ $this->flash->success(t('All tasks of the column "%s" and the swimlane "%s" have been closed successfully.', $this->column->getColumnTitleById($values['column_id']), $this->swimlane->getNameById($values['swimlane_id']) ?: t($project['default_swimlane'])));
$this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $project['id'])));
}
}
diff --git a/app/Controller/BoardTooltip.php b/app/Controller/BoardTooltip.php
index ed58a2f2..bc07ce09 100644
--- a/app/Controller/BoardTooltip.php
+++ b/app/Controller/BoardTooltip.php
@@ -19,7 +19,21 @@ class BoardTooltip extends Base
{
$task = $this->getTask();
$this->response->html($this->template->render('board/tooltip_tasklinks', array(
- 'links' => $this->taskLink->getAll($task['id']),
+ 'links' => $this->taskLink->getAllGroupedByLabel($task['id']),
+ 'task' => $task,
+ )));
+ }
+
+ /**
+ * Get links on mouseover
+ *
+ * @access public
+ */
+ public function externallinks()
+ {
+ $task = $this->getTask();
+ $this->response->html($this->template->render('board/tooltip_external_links', array(
+ 'links' => $this->taskExternalLink->getAll($task['id']),
'task' => $task,
)));
}
@@ -48,7 +62,7 @@ class BoardTooltip extends Base
$task = $this->getTask();
$this->response->html($this->template->render('board/tooltip_files', array(
- 'files' => $this->file->getAll($task['id']),
+ 'files' => $this->taskFile->getAll($task['id']),
'task' => $task,
)));
}
@@ -90,7 +104,7 @@ class BoardTooltip extends Base
{
$task = $this->getTask();
- $this->response->html($this->template->render('task/recurring_info', array(
+ $this->response->html($this->template->render('task_recurrence/info', array(
'task' => $task,
'recurrence_trigger_list' => $this->task->getRecurrenceTriggerList(),
'recurrence_timeframe_list' => $this->task->getRecurrenceTimeframeList(),
diff --git a/app/Controller/Calendar.php b/app/Controller/Calendar.php
index 67a402d3..a0a25e41 100644
--- a/app/Controller/Calendar.php
+++ b/app/Controller/Calendar.php
@@ -20,7 +20,7 @@ class Calendar extends Base
*/
public function show()
{
- $this->response->html($this->template->layout('calendar/show', array(
+ $this->response->html($this->helper->layout->app('calendar/show', array(
'check_interval' => $this->config->get('board_private_refresh_interval'),
) + $this->getProjectFilters('calendar', 'show')));
}
diff --git a/app/Controller/Category.php b/app/Controller/Category.php
index a0af4139..258a3b78 100644
--- a/app/Controller/Category.php
+++ b/app/Controller/Category.php
@@ -38,7 +38,7 @@ class Category extends Base
{
$project = $this->getProject();
- $this->response->html($this->projectLayout('category/index', array(
+ $this->response->html($this->helper->layout->project('category/index', array(
'categories' => $this->category->getList($project['id'], false),
'values' => $values + array('project_id' => $project['id']),
'errors' => $errors,
@@ -81,7 +81,7 @@ class Category extends Base
$project = $this->getProject();
$category = $this->getCategory($project['id']);
- $this->response->html($this->projectLayout('category/edit', array(
+ $this->response->html($this->helper->layout->project('category/edit', array(
'values' => empty($values) ? $category : $values,
'errors' => $errors,
'project' => $project,
@@ -123,7 +123,7 @@ class Category extends Base
$project = $this->getProject();
$category = $this->getCategory($project['id']);
- $this->response->html($this->projectLayout('category/remove', array(
+ $this->response->html($this->helper->layout->project('category/remove', array(
'project' => $project,
'category' => $category,
'title' => t('Remove a category')
diff --git a/app/Controller/Column.php b/app/Controller/Column.php
index 1ce575d7..bbe12fe1 100644
--- a/app/Controller/Column.php
+++ b/app/Controller/Column.php
@@ -15,20 +15,12 @@ class Column extends Base
*
* @access public
*/
- public function index(array $values = array(), array $errors = array())
+ public function index()
{
$project = $this->getProject();
- $columns = $this->board->getColumns($project['id']);
+ $columns = $this->column->getAll($project['id']);
- foreach ($columns as $column) {
- $values['title['.$column['id'].']'] = $column['title'];
- $values['description['.$column['id'].']'] = $column['description'];
- $values['task_limit['.$column['id'].']'] = $column['task_limit'] ?: null;
- }
-
- $this->response->html($this->projectLayout('column/index', array(
- 'errors' => $errors,
- 'values' => $values + array('project_id' => $project['id']),
+ $this->response->html($this->helper->layout->project('column/index', array(
'columns' => $columns,
'project' => $project,
'title' => t('Edit board')
@@ -36,46 +28,63 @@ class Column extends Base
}
/**
- * Validate and add a new column
+ * Show form to create a new column
*
* @access public
*/
- public function create()
+ public function create(array $values = array(), array $errors = array())
{
$project = $this->getProject();
- $columns = $this->board->getColumnsList($project['id']);
- $data = $this->request->getValues();
- $values = array();
- foreach ($columns as $column_id => $column_title) {
- $values['title['.$column_id.']'] = $column_title;
+ if (empty($values)) {
+ $values = array('project_id' => $project['id']);
}
- list($valid, $errors) = $this->columnValidator->validateCreation($data);
+ $this->response->html($this->template->render('column/create', array(
+ 'values' => $values,
+ 'errors' => $errors,
+ 'project' => $project,
+ 'title' => t('Add a new column')
+ )));
+ }
+
+ /**
+ * Validate and add a new column
+ *
+ * @access public
+ */
+ public function save()
+ {
+ $project = $this->getProject();
+ $values = $this->request->getValues();
+
+ list($valid, $errors) = $this->columnValidator->validateCreation($values);
if ($valid) {
- if ($this->board->addColumn($project['id'], $data['title'], $data['task_limit'], $data['description'])) {
- $this->flash->success(t('Board updated successfully.'));
- $this->response->redirect($this->helper->url->to('column', 'index', array('project_id' => $project['id'])));
+ if ($this->column->create($project['id'], $values['title'], $values['task_limit'], $values['description'])) {
+ $this->flash->success(t('Column created successfully.'));
+ return $this->response->redirect($this->helper->url->to('column', 'index', array('project_id' => $project['id'])), true);
} else {
- $this->flash->failure(t('Unable to update this board.'));
+ $errors['title'] = array(t('Another column with the same name exists in the project'));
}
}
- $this->index($values, $errors);
+ $this->create($values, $errors);
}
/**
* Display a form to edit a column
*
* @access public
+ * @param array $values
+ * @param array $errors
*/
public function edit(array $values = array(), array $errors = array())
{
$project = $this->getProject();
- $column = $this->board->getColumn($this->request->getIntegerParam('column_id'));
+ $column = $this->column->getById($this->request->getIntegerParam('column_id'));
- $this->response->html($this->projectLayout('column/edit', array(
+ $this->response->html($this->helper->layout->project('column/edit', array(
'errors' => $errors,
'values' => $values ?: $column,
'project' => $project,
@@ -97,7 +106,7 @@ class Column extends Base
list($valid, $errors) = $this->columnValidator->validateModification($values);
if ($valid) {
- if ($this->board->updateColumn($values['id'], $values['title'], $values['task_limit'], $values['description'])) {
+ if ($this->column->update($values['id'], $values['title'], $values['task_limit'], $values['description'])) {
$this->flash->success(t('Board updated successfully.'));
$this->response->redirect($this->helper->url->to('column', 'index', array('project_id' => $project['id'])));
} else {
@@ -109,22 +118,21 @@ class Column extends Base
}
/**
- * Move a column up or down
+ * Move column position
*
* @access public
*/
public function move()
{
- $this->checkCSRFParam();
$project = $this->getProject();
- $column_id = $this->request->getIntegerParam('column_id');
- $direction = $this->request->getStringParam('direction');
+ $values = $this->request->getJson();
- if ($direction === 'up' || $direction === 'down') {
- $this->board->{'move'.$direction}($project['id'], $column_id);
+ if (! empty($values) && isset($values['column_id']) && isset($values['position'])) {
+ $result = $this->column->changePosition($project['id'], $values['column_id'], $values['position']);
+ return $this->response->json(array('result' => $result));
}
- $this->response->redirect($this->helper->url->to('column', 'index', array('project_id' => $project['id'])));
+ $this->forbidden();
}
/**
@@ -136,8 +144,8 @@ class Column extends Base
{
$project = $this->getProject();
- $this->response->html($this->projectLayout('column/remove', array(
- 'column' => $this->board->getColumn($this->request->getIntegerParam('column_id')),
+ $this->response->html($this->helper->layout->project('column/remove', array(
+ 'column' => $this->column->getById($this->request->getIntegerParam('column_id')),
'project' => $project,
'title' => t('Remove a column from a board')
)));
@@ -152,9 +160,9 @@ class Column extends Base
{
$project = $this->getProject();
$this->checkCSRFParam();
- $column = $this->board->getColumn($this->request->getIntegerParam('column_id'));
+ $column_id = $this->request->getIntegerParam('column_id');
- if (! empty($column) && $this->board->removeColumn($column['id'])) {
+ if ($this->column->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/Comment.php b/app/Controller/Comment.php
index a608dd1c..da3213e0 100644
--- a/app/Controller/Comment.php
+++ b/app/Controller/Comment.php
@@ -21,13 +21,11 @@ class Comment extends Base
$comment = $this->comment->getById($this->request->getIntegerParam('comment_id'));
if (empty($comment)) {
- $this->notfound();
+ return $this->notfound();
}
if (! $this->userSession->isAdmin() && $comment['user_id'] != $this->userSession->getId()) {
- $this->response->html($this->template->layout('comment/forbidden', array(
- 'title' => t('Access Forbidden')
- )));
+ return $this->forbidden();
}
return $comment;
@@ -41,7 +39,6 @@ class Comment extends Base
public function create(array $values = array(), array $errors = array())
{
$task = $this->getTask();
- $ajax = $this->request->isAjax() || $this->request->getIntegerParam('ajax');
if (empty($values)) {
$values = array(
@@ -50,16 +47,7 @@ class Comment extends Base
);
}
- if ($ajax) {
- $this->response->html($this->template->render('comment/create', array(
- 'values' => $values,
- 'errors' => $errors,
- 'task' => $task,
- 'ajax' => $ajax,
- )));
- }
-
- $this->response->html($this->taskLayout('comment/create', array(
+ $this->response->html($this->helper->layout->task('comment/create', array(
'values' => $values,
'errors' => $errors,
'task' => $task,
@@ -76,7 +64,6 @@ class Comment extends Base
{
$task = $this->getTask();
$values = $this->request->getValues();
- $ajax = $this->request->isAjax() || $this->request->getIntegerParam('ajax');
list($valid, $errors) = $this->commentValidator->validateCreation($values);
@@ -87,11 +74,7 @@ class Comment extends Base
$this->flash->failure(t('Unable to create your comment.'));
}
- if ($ajax) {
- $this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $task['project_id'])));
- }
-
- $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), 'comments'));
+ return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), 'comments'), true);
}
$this->create($values, $errors);
@@ -107,7 +90,7 @@ class Comment extends Base
$task = $this->getTask();
$comment = $this->getComment();
- $this->response->html($this->taskLayout('comment/edit', array(
+ $this->response->html($this->helper->layout->task('comment/edit', array(
'values' => empty($values) ? $comment : $values,
'errors' => $errors,
'comment' => $comment,
@@ -124,7 +107,7 @@ class Comment extends Base
public function update()
{
$task = $this->getTask();
- $comment = $this->getComment();
+ $this->getComment();
$values = $this->request->getValues();
list($valid, $errors) = $this->commentValidator->validateModification($values);
@@ -136,7 +119,7 @@ class Comment extends Base
$this->flash->failure(t('Unable to update your comment.'));
}
- $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), 'comment-'.$comment['id']));
+ return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), false);
}
$this->edit($values, $errors);
@@ -152,7 +135,7 @@ class Comment extends Base
$task = $this->getTask();
$comment = $this->getComment();
- $this->response->html($this->taskLayout('comment/remove', array(
+ $this->response->html($this->helper->layout->task('comment/remove', array(
'comment' => $comment,
'task' => $task,
'title' => t('Remove a comment')
diff --git a/app/Controller/Config.php b/app/Controller/Config.php
index 4aee8553..e811f870 100644
--- a/app/Controller/Config.php
+++ b/app/Controller/Config.php
@@ -11,24 +11,6 @@ namespace Kanboard\Controller;
class Config extends Base
{
/**
- * Common layout for config views
- *
- * @access private
- * @param string $template Template name
- * @param array $params Template parameters
- * @return string
- */
- private function layout($template, array $params)
- {
- $params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
- $params['values'] = $this->config->getAll();
- $params['errors'] = array();
- $params['config_content_for_layout'] = $this->template->render($template, $params);
-
- return $this->template->layout('config/layout', $params);
- }
-
- /**
* Common method between pages
*
* @access private
@@ -44,7 +26,12 @@ class Config extends Base
$values += array('password_reset' => 0);
break;
case 'project':
- $values += array('subtask_restriction' => 0, 'subtask_time_tracking' => 0, 'cfd_include_closed_tasks' => 0);
+ $values += array(
+ 'subtask_restriction' => 0,
+ 'subtask_time_tracking' => 0,
+ 'cfd_include_closed_tasks' => 0,
+ 'disable_private_project' => 0,
+ );
break;
case 'integrations':
$values += array('integration_gravatar' => 0);
@@ -72,7 +59,7 @@ class Config extends Base
*/
public function index()
{
- $this->response->html($this->layout('config/about', array(
+ $this->response->html($this->helper->layout->config('config/about', array(
'db_size' => $this->config->getDatabaseSize(),
'title' => t('Settings').' &gt; '.t('About'),
)));
@@ -85,7 +72,7 @@ class Config extends Base
*/
public function plugins()
{
- $this->response->html($this->layout('config/plugins', array(
+ $this->response->html($this->helper->layout->config('config/plugins', array(
'plugins' => $this->pluginLoader->plugins,
'title' => t('Settings').' &gt; '.t('Plugins'),
)));
@@ -100,10 +87,12 @@ class Config extends Base
{
$this->common('application');
- $this->response->html($this->layout('config/application', array(
+ $this->response->html($this->helper->layout->config('config/application', array(
'languages' => $this->config->getLanguages(),
'timezones' => $this->config->getTimezones(),
- 'date_formats' => $this->dateParser->getAvailableFormats(),
+ 'date_formats' => $this->dateParser->getAvailableFormats($this->dateParser->getDateFormats()),
+ 'datetime_formats' => $this->dateParser->getAvailableFormats($this->dateParser->getDateTimeFormats()),
+ 'time_formats' => $this->dateParser->getAvailableFormats($this->dateParser->getTimeFormats()),
'title' => t('Settings').' &gt; '.t('Application settings'),
)));
}
@@ -117,7 +106,7 @@ class Config extends Base
{
$this->common('project');
- $this->response->html($this->layout('config/project', array(
+ $this->response->html($this->helper->layout->config('config/project', array(
'colors' => $this->color->getList(),
'default_columns' => implode(', ', $this->board->getDefaultColumns()),
'title' => t('Settings').' &gt; '.t('Project settings'),
@@ -133,7 +122,7 @@ class Config extends Base
{
$this->common('board');
- $this->response->html($this->layout('config/board', array(
+ $this->response->html($this->helper->layout->config('config/board', array(
'title' => t('Settings').' &gt; '.t('Board settings'),
)));
}
@@ -147,7 +136,7 @@ class Config extends Base
{
$this->common('calendar');
- $this->response->html($this->layout('config/calendar', array(
+ $this->response->html($this->helper->layout->config('config/calendar', array(
'title' => t('Settings').' &gt; '.t('Calendar settings'),
)));
}
@@ -161,7 +150,7 @@ class Config extends Base
{
$this->common('integrations');
- $this->response->html($this->layout('config/integrations', array(
+ $this->response->html($this->helper->layout->config('config/integrations', array(
'title' => t('Settings').' &gt; '.t('Integrations'),
)));
}
@@ -175,7 +164,7 @@ class Config extends Base
{
$this->common('webhook');
- $this->response->html($this->layout('config/webhook', array(
+ $this->response->html($this->helper->layout->config('config/webhook', array(
'title' => t('Settings').' &gt; '.t('Webhook settings'),
)));
}
@@ -187,7 +176,7 @@ class Config extends Base
*/
public function api()
{
- $this->response->html($this->layout('config/api', array(
+ $this->response->html($this->helper->layout->config('config/api', array(
'title' => t('Settings').' &gt; '.t('API'),
)));
}
diff --git a/app/Controller/Currency.php b/app/Controller/Currency.php
index 42e404f8..ecaa9834 100644
--- a/app/Controller/Currency.php
+++ b/app/Controller/Currency.php
@@ -11,29 +11,13 @@ namespace Kanboard\Controller;
class Currency extends Base
{
/**
- * Common layout for config views
- *
- * @access private
- * @param string $template Template name
- * @param array $params Template parameters
- * @return string
- */
- private function layout($template, array $params)
- {
- $params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
- $params['config_content_for_layout'] = $this->template->render($template, $params);
-
- return $this->template->layout('config/layout', $params);
- }
-
- /**
* Display all currency rates and form
*
* @access public
*/
public function index(array $values = array(), array $errors = array())
{
- $this->response->html($this->layout('currency/index', array(
+ $this->response->html($this->helper->layout->config('currency/index', array(
'config_values' => array('application_currency' => $this->config->get('application_currency')),
'values' => $values,
'errors' => $errors,
diff --git a/app/Controller/Customfilter.php b/app/Controller/Customfilter.php
index 1b43f1d0..41da0b11 100644
--- a/app/Controller/Customfilter.php
+++ b/app/Controller/Customfilter.php
@@ -21,7 +21,7 @@ class Customfilter extends Base
{
$project = $this->getProject();
- $this->response->html($this->projectLayout('custom_filter/index', array(
+ $this->response->html($this->helper->layout->project('custom_filter/index', array(
'values' => $values + array('project_id' => $project['id']),
'errors' => $errors,
'project' => $project,
@@ -57,6 +57,23 @@ class Customfilter extends Base
}
/**
+ * Confirmation dialog before removing a custom filter
+ *
+ * @access public
+ */
+ public function confirm()
+ {
+ $project = $this->getProject();
+ $filter = $this->customFilter->getById($this->request->getIntegerParam('filter_id'));
+
+ $this->response->html($this->helper->layout->project('custom_filter/remove', array(
+ 'project' => $project,
+ 'filter' => $filter,
+ 'title' => t('Remove a custom filter')
+ )));
+ }
+
+ /**
* Remove a custom filter
*
* @access public
@@ -90,7 +107,7 @@ class Customfilter extends Base
$this->checkPermission($project, $filter);
- $this->response->html($this->projectLayout('custom_filter/edit', array(
+ $this->response->html($this->helper->layout->project('custom_filter/edit', array(
'values' => empty($values) ? $filter : $values,
'errors' => $errors,
'project' => $project,
diff --git a/app/Controller/Doc.php b/app/Controller/Doc.php
index a233b120..6f309d48 100644
--- a/app/Controller/Doc.php
+++ b/app/Controller/Doc.php
@@ -52,8 +52,6 @@ class Doc extends Base
}
}
- $this->response->html($this->template->layout('doc/show', $this->readFile($filename) + array(
- 'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
- )));
+ $this->response->html($this->helper->layout->app('doc/show', $this->readFile($filename)));
}
}
diff --git a/app/Controller/Export.php b/app/Controller/Export.php
index c39f58a1..c2ff652e 100644
--- a/app/Controller/Export.php
+++ b/app/Controller/Export.php
@@ -27,7 +27,7 @@ class Export extends Base
$this->response->csv($data);
}
- $this->response->html($this->projectLayout('export/'.$action, array(
+ $this->response->html($this->helper->layout->project('export/'.$action, array(
'values' => array(
'controller' => 'export',
'action' => $action,
@@ -37,7 +37,7 @@ class Export extends Base
),
'errors' => array(),
'date_format' => $this->config->get('application_date_format'),
- 'date_formats' => $this->dateParser->getAvailableFormats(),
+ 'date_formats' => $this->dateParser->getAvailableFormats($this->dateParser->getDateFormats()),
'project' => $project,
'title' => $page_title,
), 'export/sidebar'));
@@ -80,6 +80,6 @@ class Export extends Base
*/
public function transitions()
{
- $this->common('transition', 'export', t('Transitions'), 'transitions', t('Task transitions export'));
+ $this->common('transitionExport', 'export', t('Transitions'), 'transitions', t('Task transitions export'));
}
}
diff --git a/app/Controller/File.php b/app/Controller/File.php
deleted file mode 100644
index b46f7d19..00000000
--- a/app/Controller/File.php
+++ /dev/null
@@ -1,192 +0,0 @@
-<?php
-
-namespace Kanboard\Controller;
-
-use Kanboard\Core\ObjectStorage\ObjectStorageException;
-
-/**
- * File controller
- *
- * @package controller
- * @author Frederic Guillot
- */
-class File extends Base
-{
- /**
- * Screenshot
- *
- * @access public
- */
- public function screenshot()
- {
- $task = $this->getTask();
-
- if ($this->request->isPost() && $this->file->uploadScreenshot($task['project_id'], $task['id'], $this->request->getValue('screenshot')) !== false) {
- $this->flash->success(t('Screenshot uploaded successfully.'));
-
- if ($this->request->getStringParam('redirect') === 'board') {
- $this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $task['project_id'])));
- }
-
- $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])));
- }
-
- $this->response->html($this->taskLayout('file/screenshot', array(
- 'task' => $task,
- 'redirect' => 'task',
- )));
- }
-
- /**
- * File upload form
- *
- * @access public
- */
- public function create()
- {
- $task = $this->getTask();
-
- $this->response->html($this->taskLayout('file/new', array(
- 'task' => $task,
- 'max_size' => ini_get('upload_max_filesize'),
- )));
- }
-
- /**
- * File upload (save files)
- *
- * @access public
- */
- public function save()
- {
- $task = $this->getTask();
-
- if (! $this->file->uploadFiles($task['project_id'], $task['id'], 'files')) {
- $this->flash->failure(t('Unable to upload the file.'));
- }
-
- $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])));
- }
-
- /**
- * File download
- *
- * @access public
- */
- public function download()
- {
- try {
- $task = $this->getTask();
- $file = $this->file->getById($this->request->getIntegerParam('file_id'));
-
- if ($file['task_id'] != $task['id']) {
- $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])));
- }
-
- $this->response->forceDownload($file['name']);
- $this->objectStorage->output($file['path']);
- } catch (ObjectStorageException $e) {
- $this->logger->error($e->getMessage());
- }
- }
-
- /**
- * Open a file (show the content in a popover)
- *
- * @access public
- */
- public function open()
- {
- $task = $this->getTask();
- $file = $this->file->getById($this->request->getIntegerParam('file_id'));
-
- if ($file['task_id'] == $task['id']) {
- $this->response->html($this->template->render('file/open', array(
- 'file' => $file,
- 'task' => $task,
- )));
- }
- }
-
- /**
- * Display image
- *
- * @access public
- */
- public function image()
- {
- try {
- $task = $this->getTask();
- $file = $this->file->getById($this->request->getIntegerParam('file_id'));
-
- if ($file['task_id'] == $task['id']) {
- $this->response->contentType($this->file->getImageMimeType($file['name']));
- $this->objectStorage->output($file['path']);
- }
- } catch (ObjectStorageException $e) {
- $this->logger->error($e->getMessage());
- }
- }
-
- /**
- * Display image thumbnails
- *
- * @access public
- */
- public function thumbnail()
- {
- $this->response->contentType('image/jpeg');
-
- try {
- $task = $this->getTask();
- $file = $this->file->getById($this->request->getIntegerParam('file_id'));
-
- if ($file['task_id'] == $task['id']) {
- $this->objectStorage->output($this->file->getThumbnailPath($file['path']));
- }
- } catch (ObjectStorageException $e) {
- $this->logger->error($e->getMessage());
-
- // Try to generate thumbnail on the fly for images uploaded before Kanboard < 1.0.19
- $data = $this->objectStorage->get($file['path']);
- $this->file->generateThumbnailFromData($file['path'], $data);
- $this->objectStorage->output($this->file->getThumbnailPath($file['path']));
- }
- }
-
- /**
- * Remove a file
- *
- * @access public
- */
- public function remove()
- {
- $this->checkCSRFParam();
- $task = $this->getTask();
- $file = $this->file->getById($this->request->getIntegerParam('file_id'));
-
- if ($file['task_id'] == $task['id'] && $this->file->remove($file['id'])) {
- $this->flash->success(t('File removed successfully.'));
- } else {
- $this->flash->failure(t('Unable to remove this file.'));
- }
-
- $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])));
- }
-
- /**
- * Confirmation dialog before removing a file
- *
- * @access public
- */
- public function confirm()
- {
- $task = $this->getTask();
- $file = $this->file->getById($this->request->getIntegerParam('file_id'));
-
- $this->response->html($this->taskLayout('file/remove', array(
- 'task' => $task,
- 'file' => $file,
- )));
- }
-}
diff --git a/app/Controller/FileViewer.php b/app/Controller/FileViewer.php
new file mode 100644
index 00000000..bc91c3d8
--- /dev/null
+++ b/app/Controller/FileViewer.php
@@ -0,0 +1,116 @@
+<?php
+
+namespace Kanboard\Controller;
+
+use Kanboard\Core\ObjectStorage\ObjectStorageException;
+
+/**
+ * File Viewer Controller
+ *
+ * @package controller
+ * @author Frederic Guillot
+ */
+class FileViewer extends Base
+{
+ /**
+ * Get file content from object storage
+ *
+ * @access private
+ * @param array $file
+ * @return string
+ */
+ private function getFileContent(array $file)
+ {
+ $content = '';
+
+ try {
+
+ if ($file['is_image'] == 0) {
+ $content = $this->objectStorage->get($file['path']);
+ }
+
+ } catch (ObjectStorageException $e) {
+ $this->logger->error($e->getMessage());
+ }
+
+ return $content;
+ }
+
+ /**
+ * Show file content in a popover
+ *
+ * @access public
+ */
+ public function show()
+ {
+ $file = $this->getFile();
+ $type = $this->helper->file->getPreviewType($file['name']);
+ $params = array('file_id' => $file['id'], 'project_id' => $this->request->getIntegerParam('project_id'));
+
+ if ($file['model'] === 'taskFile') {
+ $params['task_id'] = $file['task_id'];
+ }
+
+ $this->response->html($this->template->render('file_viewer/show', array(
+ 'file' => $file,
+ 'params' => $params,
+ 'type' => $type,
+ 'content' => $this->getFileContent($file),
+ )));
+ }
+
+ /**
+ * Display image
+ *
+ * @access public
+ */
+ public function image()
+ {
+ try {
+ $file = $this->getFile();
+ $this->response->contentType($this->helper->file->getImageMimeType($file['name']));
+ $this->objectStorage->output($file['path']);
+ } catch (ObjectStorageException $e) {
+ $this->logger->error($e->getMessage());
+ }
+ }
+
+ /**
+ * Display image thumbnail
+ *
+ * @access public
+ */
+ public function thumbnail()
+ {
+ $this->response->contentType('image/jpeg');
+
+ try {
+ $file = $this->getFile();
+ $model = $file['model'];
+ $this->objectStorage->output($this->$model->getThumbnailPath($file['path']));
+ } catch (ObjectStorageException $e) {
+ $this->logger->error($e->getMessage());
+
+ // Try to generate thumbnail on the fly for images uploaded before Kanboard < 1.0.19
+ $data = $this->objectStorage->get($file['path']);
+ $this->$model->generateThumbnailFromData($file['path'], $data);
+ $this->objectStorage->output($this->$model->getThumbnailPath($file['path']));
+ }
+ }
+
+ /**
+ * File download
+ *
+ * @access public
+ */
+ public function download()
+ {
+ try {
+ $file = $this->getFile();
+ $this->response->forceDownload($file['name']);
+ $this->objectStorage->output($file['path']);
+ } catch (ObjectStorageException $e) {
+ $this->logger->error($e->getMessage());
+ }
+ }
+}
diff --git a/app/Controller/Gantt.php b/app/Controller/Gantt.php
index ac0e6fad..9ffa277f 100644
--- a/app/Controller/Gantt.php
+++ b/app/Controller/Gantt.php
@@ -23,10 +23,9 @@ class Gantt extends Base
$project_ids = $this->projectPermission->getActiveProjectIds($this->userSession->getId());
}
- $this->response->html($this->template->layout('gantt/projects', array(
+ $this->response->html($this->helper->layout->app('gantt/projects', array(
'projects' => $this->projectGanttFormatter->filter($project_ids)->format(),
'title' => t('Gantt chart for all projects'),
- 'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
)));
}
@@ -65,7 +64,7 @@ class Gantt extends Base
$filter->getQuery()->asc('column_position')->asc(TaskModel::TABLE.'.position');
}
- $this->response->html($this->template->layout('gantt/project', $params + array(
+ $this->response->html($this->helper->layout->app('gantt/project', $params + array(
'users_list' => $this->projectUserRole->getAssignableUsersList($params['project']['id'], false),
'sorting' => $sorting,
'tasks' => $filter->format(),
@@ -102,19 +101,23 @@ class Gantt extends Base
{
$project = $this->getProject();
+ $values = $values + array(
+ 'project_id' => $project['id'],
+ 'column_id' => $this->column->getFirstColumnId($project['id']),
+ 'position' => 1
+ );
+
+ $values = $this->hook->merge('controller:task:form:default', $values, array('default_values' => $values));
+ $values = $this->hook->merge('controller:gantt:task:form:default', $values, array('default_values' => $values));
+
$this->response->html($this->template->render('gantt/task_creation', array(
+ 'project' => $project,
'errors' => $errors,
- 'values' => $values + array(
- 'project_id' => $project['id'],
- 'column_id' => $this->board->getFirstColumn($project['id']),
- 'position' => 1
- ),
+ 'values' => $values,
'users_list' => $this->projectUserRole->getAssignableUsersList($project['id'], true, false, true),
'colors_list' => $this->color->getList(),
'categories_list' => $this->category->getList($project['id']),
'swimlanes_list' => $this->swimlane->getList($project['id'], false, true),
- 'date_format' => $this->config->get('application_date_format'),
- 'date_formats' => $this->dateParser->getAvailableFormats(),
'title' => $project['name'].' &gt; '.t('New task')
)));
}
diff --git a/app/Controller/Group.php b/app/Controller/Group.php
index e952c0e5..fa47f428 100644
--- a/app/Controller/Group.php
+++ b/app/Controller/Group.php
@@ -24,8 +24,7 @@ class Group extends Base
->setQuery($this->group->getQuery())
->calculate();
- $this->response->html($this->template->layout('group/index', array(
- 'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
+ $this->response->html($this->helper->layout->app('group/index', array(
'title' => t('Groups').' ('.$paginator->getTotal().')',
'paginator' => $paginator,
)));
@@ -48,8 +47,7 @@ class Group extends Base
->setQuery($this->groupMember->getQuery($group_id))
->calculate();
- $this->response->html($this->template->layout('group/users', array(
- 'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
+ $this->response->html($this->helper->layout->app('group/users', array(
'title' => t('Members of %s', $group['name']).' ('.$paginator->getTotal().')',
'paginator' => $paginator,
'group' => $group,
@@ -63,8 +61,7 @@ class Group extends Base
*/
public function create(array $values = array(), array $errors = array())
{
- $this->response->html($this->template->layout('group/create', array(
- 'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
+ $this->response->html($this->helper->layout->app('group/create', array(
'errors' => $errors,
'values' => $values,
'title' => t('New group')
@@ -104,8 +101,7 @@ class Group extends Base
$values = $this->group->getById($this->request->getIntegerParam('group_id'));
}
- $this->response->html($this->template->layout('group/edit', array(
- 'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
+ $this->response->html($this->helper->layout->app('group/edit', array(
'errors' => $errors,
'values' => $values,
'title' => t('Edit group')
@@ -148,8 +144,7 @@ class Group extends Base
$values['group_id'] = $group_id;
}
- $this->response->html($this->template->layout('group/associate', array(
- 'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
+ $this->response->html($this->helper->layout->app('group/associate', array(
'users' => $this->user->prepareList($this->groupMember->getNotMembers($group_id)),
'group' => $group,
'errors' => $errors,
@@ -191,7 +186,7 @@ class Group extends Base
$group = $this->group->getById($group_id);
$user = $this->user->getById($user_id);
- $this->response->html($this->template->layout('group/dissociate', array(
+ $this->response->html($this->helper->layout->app('group/dissociate', array(
'group' => $group,
'user' => $user,
'title' => t('Remove user from group "%s"', $group['name']),
@@ -228,7 +223,7 @@ class Group extends Base
$group_id = $this->request->getIntegerParam('group_id');
$group = $this->group->getById($group_id);
- $this->response->html($this->template->layout('group/remove', array(
+ $this->response->html($this->helper->layout->app('group/remove', array(
'group' => $group,
'title' => t('Remove group'),
)));
diff --git a/app/Controller/Ical.php b/app/Controller/Ical.php
index f8e9e25f..f1ea6d8f 100644
--- a/app/Controller/Ical.php
+++ b/app/Controller/Ical.php
@@ -3,6 +3,7 @@
namespace Kanboard\Controller;
use Kanboard\Model\TaskFilter;
+use Kanboard\Model\Task as TaskModel;
use Eluceo\iCal\Component\Calendar as iCalendar;
/**
@@ -31,6 +32,7 @@ class Ical extends Base
// Common filter
$filter = $this->taskFilterICalendarFormatter
->create()
+ ->filterByStatus(TaskModel::STATUS_OPEN)
->filterByOwner($user['id']);
// Calendar properties
@@ -60,6 +62,7 @@ class Ical extends Base
// Common filter
$filter = $this->taskFilterICalendarFormatter
->create()
+ ->filterByStatus(TaskModel::STATUS_OPEN)
->filterByProject($project['id']);
// Calendar properties
diff --git a/app/Controller/Link.php b/app/Controller/Link.php
index d52d1f91..ec7ab1af 100644
--- a/app/Controller/Link.php
+++ b/app/Controller/Link.php
@@ -12,22 +12,6 @@ namespace Kanboard\Controller;
class Link extends Base
{
/**
- * Common layout for config views
- *
- * @access private
- * @param string $template Template name
- * @param array $params Template parameters
- * @return string
- */
- private function layout($template, array $params)
- {
- $params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
- $params['config_content_for_layout'] = $this->template->render($template, $params);
-
- return $this->template->layout('config/layout', $params);
- }
-
- /**
* Get the current link
*
* @access private
@@ -51,7 +35,7 @@ class Link extends Base
*/
public function index(array $values = array(), array $errors = array())
{
- $this->response->html($this->layout('link/index', array(
+ $this->response->html($this->helper->layout->config('link/index', array(
'links' => $this->link->getMergedList(),
'values' => $values,
'errors' => $errors,
@@ -91,7 +75,7 @@ class Link extends Base
$link = $this->getLink();
$link['label'] = t($link['label']);
- $this->response->html($this->layout('link/edit', array(
+ $this->response->html($this->helper->layout->config('link/edit', array(
'values' => $values ?: $link,
'errors' => $errors,
'labels' => $this->link->getList($link['id']),
@@ -131,7 +115,7 @@ class Link extends Base
{
$link = $this->getLink();
- $this->response->html($this->layout('link/remove', array(
+ $this->response->html($this->helper->layout->config('link/remove', array(
'link' => $link,
'title' => t('Remove a link')
)));
diff --git a/app/Controller/Listing.php b/app/Controller/Listing.php
index b9c851f5..c784dd50 100644
--- a/app/Controller/Listing.php
+++ b/app/Controller/Listing.php
@@ -30,8 +30,11 @@ class Listing extends Base
->setQuery($query)
->calculate();
- $this->response->html($this->template->layout('listing/show', $params + array(
+ $this->response->html($this->helper->layout->app('listing/show', $params + array(
'paginator' => $paginator,
+ 'categories_list' => $this->category->getList($params['project']['id'], false),
+ 'users_list' => $this->projectUserRole->getAssignableUsersList($params['project']['id'], false),
+ 'custom_filters_list' => $this->customFilter->getAll($params['project']['id'], $this->userSession->getId()),
)));
}
}
diff --git a/app/Controller/Oauth.php b/app/Controller/Oauth.php
index ed901def..452faecd 100644
--- a/app/Controller/Oauth.php
+++ b/app/Controller/Oauth.php
@@ -11,36 +11,6 @@ namespace Kanboard\Controller;
class Oauth extends Base
{
/**
- * Link or authenticate a Google account
- *
- * @access public
- */
- public function google()
- {
- $this->step1('Google');
- }
-
- /**
- * Link or authenticate a Github account
- *
- * @access public
- */
- public function github()
- {
- $this->step1('Github');
- }
-
- /**
- * Link or authenticate a Gitlab account
- *
- * @access public
- */
- public function gitlab()
- {
- $this->step1('Gitlab');
- }
-
- /**
* Unlink external account
*
* @access public
@@ -65,7 +35,7 @@ class Oauth extends Base
* @access private
* @param string $provider
*/
- private function step1($provider)
+ protected function step1($provider)
{
$code = $this->request->getStringParam('code');
@@ -79,11 +49,11 @@ class Oauth extends Base
/**
* Link or authenticate the user
*
- * @access private
+ * @access protected
* @param string $provider
* @param string $code
*/
- private function step2($provider, $code)
+ protected function step2($provider, $code)
{
$this->authenticationManager->getProvider($provider)->setCode($code);
@@ -97,10 +67,10 @@ class Oauth extends Base
/**
* Link the account
*
- * @access private
+ * @access protected
* @param string $provider
*/
- private function link($provider)
+ protected function link($provider)
{
$authProvider = $this->authenticationManager->getProvider($provider);
@@ -117,15 +87,15 @@ class Oauth extends Base
/**
* Authenticate the account
*
- * @access private
+ * @access protected
* @param string $provider
*/
- private function authenticate($provider)
+ protected function authenticate($provider)
{
if ($this->authenticationManager->oauthAuthentication($provider)) {
$this->response->redirect($this->helper->url->to('app', 'index'));
} else {
- $this->response->html($this->template->layout('auth/index', array(
+ $this->response->html($this->helper->layout->app('auth/index', array(
'errors' => array('login' => t('External authentication failed')),
'values' => array(),
'no_layout' => true,
diff --git a/app/Controller/PasswordReset.php b/app/Controller/PasswordReset.php
index 23567c9c..f6a0eb8e 100644
--- a/app/Controller/PasswordReset.php
+++ b/app/Controller/PasswordReset.php
@@ -17,7 +17,7 @@ class PasswordReset extends Base
{
$this->checkActivation();
- $this->response->html($this->template->layout('password_reset/create', array(
+ $this->response->html($this->helper->layout->app('password_reset/create', array(
'errors' => $errors,
'values' => $values,
'no_layout' => true,
@@ -53,7 +53,7 @@ class PasswordReset extends Base
$user_id = $this->passwordReset->getUserIdByToken($token);
if ($user_id !== false) {
- $this->response->html($this->template->layout('password_reset/change', array(
+ $this->response->html($this->helper->layout->app('password_reset/change', array(
'token' => $token,
'errors' => $errors,
'values' => $values,
diff --git a/app/Controller/Project.php b/app/Controller/Project.php
index ffd62b09..cdfbd94a 100644
--- a/app/Controller/Project.php
+++ b/app/Controller/Project.php
@@ -32,8 +32,7 @@ class Project extends Base
->setQuery($this->project->getQueryColumnStats($project_ids))
->calculate();
- $this->response->html($this->template->layout('project/index', array(
- 'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
+ $this->response->html($this->helper->layout->app('project/index', array(
'paginator' => $paginator,
'nb_projects' => $nb_projects,
'title' => t('Projects').' ('.$nb_projects.')'
@@ -49,7 +48,7 @@ class Project extends Base
{
$project = $this->getProject();
- $this->response->html($this->projectLayout('project/show', array(
+ $this->response->html($this->helper->layout->project('project/show', array(
'project' => $project,
'stats' => $this->project->getTaskStats($project['id']),
'title' => $project['name'],
@@ -78,7 +77,7 @@ class Project extends Base
$this->response->redirect($this->helper->url->to('project', 'share', array('project_id' => $project['id'])));
}
- $this->response->html($this->projectLayout('project/share', array(
+ $this->response->html($this->helper->layout->project('project/share', array(
'project' => $project,
'title' => t('Public access'),
)));
@@ -99,7 +98,7 @@ class Project extends Base
$this->response->redirect($this->helper->url->to('project', 'integrations', array('project_id' => $project['id'])));
}
- $this->response->html($this->projectLayout('project/integrations', array(
+ $this->response->html($this->helper->layout->project('project/integrations', array(
'project' => $project,
'title' => t('Integrations'),
'webhook_token' => $this->config->get('webhook_token'),
@@ -124,7 +123,7 @@ class Project extends Base
$this->response->redirect($this->helper->url->to('project', 'notifications', array('project_id' => $project['id'])));
}
- $this->response->html($this->projectLayout('project/notifications', array(
+ $this->response->html($this->helper->layout->project('project/notifications', array(
'notifications' => $this->projectNotification->readSettings($project['id']),
'types' => $this->projectNotificationType->getTypes(),
'project' => $project,
@@ -153,7 +152,7 @@ class Project extends Base
$this->response->redirect($this->helper->url->to('project', 'index'));
}
- $this->response->html($this->projectLayout('project/remove', array(
+ $this->response->html($this->helper->layout->project('project/remove', array(
'project' => $project,
'title' => t('Remove project')
)));
@@ -171,17 +170,18 @@ class Project extends Base
$project = $this->getProject();
if ($this->request->getStringParam('duplicate') === 'yes') {
- $values = array_keys($this->request->getValues());
- if ($this->projectDuplication->duplicate($project['id'], $values) !== false) {
+ $project_id = $this->projectDuplication->duplicate($project['id'], array_keys($this->request->getValues()), $this->userSession->getId());
+
+ if ($project_id !== false) {
$this->flash->success(t('Project cloned successfully.'));
} else {
$this->flash->failure(t('Unable to clone this project.'));
}
- $this->response->redirect($this->helper->url->to('project', 'index'));
+ $this->response->redirect($this->helper->url->to('project', 'show', array('project_id' => $project_id)));
}
- $this->response->html($this->projectLayout('project/duplicate', array(
+ $this->response->html($this->helper->layout->project('project/duplicate', array(
'project' => $project,
'title' => t('Clone this project')
)));
@@ -208,7 +208,7 @@ class Project extends Base
$this->response->redirect($this->helper->url->to('project', 'show', array('project_id' => $project['id'])));
}
- $this->response->html($this->projectLayout('project/disable', array(
+ $this->response->html($this->helper->layout->project('project/disable', array(
'project' => $project,
'title' => t('Project activation')
)));
@@ -235,62 +235,9 @@ class Project extends Base
$this->response->redirect($this->helper->url->to('project', 'show', array('project_id' => $project['id'])));
}
- $this->response->html($this->projectLayout('project/enable', array(
+ $this->response->html($this->helper->layout->project('project/enable', array(
'project' => $project,
'title' => t('Project activation')
)));
}
-
- /**
- * Display a form to create a new project
- *
- * @access public
- */
- public function create(array $values = array(), array $errors = array())
- {
- $is_private = isset($values['is_private']) && $values['is_private'] == 1;
-
- $this->response->html($this->template->layout('project/new', array(
- 'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
- 'values' => $values,
- 'errors' => $errors,
- 'is_private' => $is_private,
- 'title' => $is_private ? t('New private project') : t('New project'),
- )));
- }
-
- /**
- * Display a form to create a private project
- *
- * @access public
- */
- public function createPrivate(array $values = array(), array $errors = array())
- {
- $values['is_private'] = 1;
- $this->create($values, $errors);
- }
-
- /**
- * Validate and save a new project
- *
- * @access public
- */
- public function save()
- {
- $values = $this->request->getValues();
- list($valid, $errors) = $this->projectValidator->validateCreation($values);
-
- if ($valid) {
- $project_id = $this->project->create($values, $this->userSession->getId(), true);
-
- if ($project_id > 0) {
- $this->flash->success(t('Your project have been created successfully.'));
- $this->response->redirect($this->helper->url->to('project', 'show', array('project_id' => $project_id)));
- }
-
- $this->flash->failure(t('Unable to create your project.'));
- }
-
- $this->create($values, $errors);
- }
}
diff --git a/app/Controller/ProjectCreation.php b/app/Controller/ProjectCreation.php
new file mode 100644
index 00000000..88f41fcd
--- /dev/null
+++ b/app/Controller/ProjectCreation.php
@@ -0,0 +1,125 @@
+<?php
+
+namespace Kanboard\Controller;
+
+/**
+ * Project Creation Controller
+ *
+ * @package controller
+ * @author Frederic Guillot
+ */
+class ProjectCreation extends Base
+{
+ /**
+ * Display a form to create a new project
+ *
+ * @access public
+ */
+ public function create(array $values = array(), array $errors = array())
+ {
+ $is_private = isset($values['is_private']) && $values['is_private'] == 1;
+ $projects_list = array(0 => t('Do not duplicate anything')) + $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
+
+ $this->response->html($this->helper->layout->app('project_creation/create', array(
+ 'values' => $values,
+ 'errors' => $errors,
+ 'is_private' => $is_private,
+ 'projects_list' => $projects_list,
+ 'title' => $is_private ? t('New private project') : t('New project'),
+ )));
+ }
+
+ /**
+ * Display a form to create a private project
+ *
+ * @access public
+ */
+ public function createPrivate(array $values = array(), array $errors = array())
+ {
+ $values['is_private'] = 1;
+ $this->create($values, $errors);
+ }
+
+ /**
+ * Validate and save a new project
+ *
+ * @access public
+ */
+ public function save()
+ {
+ $values = $this->request->getValues();
+ list($valid, $errors) = $this->projectValidator->validateCreation($values);
+
+ if ($valid) {
+ $project_id = $this->createOrDuplicate($values);
+
+ if ($project_id > 0) {
+ $this->flash->success(t('Your project have been created successfully.'));
+ return $this->response->redirect($this->helper->url->to('project', 'show', array('project_id' => $project_id)));
+ }
+
+ $this->flash->failure(t('Unable to create your project.'));
+ }
+
+ $this->create($values, $errors);
+ }
+
+ /**
+ * Create or duplicate a project
+ *
+ * @access private
+ * @param array $values
+ * @return boolean|integer
+ */
+ private function createOrDuplicate(array $values)
+ {
+ if (empty($values['src_project_id'])) {
+ return $this->createNewProject($values);
+ }
+
+ return $this->duplicateNewProject($values);
+ }
+
+ /**
+ * Save a new project
+ *
+ * @access private
+ * @param array $values
+ * @return boolean|integer
+ */
+ private function createNewProject(array $values)
+ {
+ $project = array(
+ 'name' => $values['name'],
+ 'is_private' => $values['is_private'],
+ );
+
+ return $this->project->create($project, $this->userSession->getId(), true);
+ }
+
+ /**
+ * Creatte from another project
+ *
+ * @access private
+ * @param array $values
+ * @return boolean|integer
+ */
+ private function duplicateNewProject(array $values)
+ {
+ $selection = array();
+
+ foreach ($this->projectDuplication->getOptionalSelection() as $item) {
+ if (isset($values[$item]) && $values[$item] == 1) {
+ $selection[] = $item;
+ }
+ }
+
+ return $this->projectDuplication->duplicate(
+ $values['src_project_id'],
+ $selection,
+ $this->userSession->getId(),
+ $values['name'],
+ $values['is_private'] == 1
+ );
+ }
+}
diff --git a/app/Controller/ProjectEdit.php b/app/Controller/ProjectEdit.php
index 0dfc7de3..f4a3a7cb 100644
--- a/app/Controller/ProjectEdit.php
+++ b/app/Controller/ProjectEdit.php
@@ -89,11 +89,11 @@ class ProjectEdit extends Base
{
if ($redirect === 'edit') {
if (isset($values['is_private'])) {
- if (! $this->helper->user->hasProjectAccess('project', 'create', $project['id'])) {
+ if (! $this->helper->user->hasProjectAccess('ProjectCreation', 'create', $project['id'])) {
unset($values['is_private']);
}
} elseif ($project['is_private'] == 1 && ! isset($values['is_private'])) {
- if ($this->helper->user->hasProjectAccess('project', 'create', $project['id'])) {
+ if ($this->helper->user->hasProjectAccess('ProjectCreation', 'create', $project['id'])) {
$values += array('is_private' => 0);
}
}
@@ -114,7 +114,7 @@ class ProjectEdit extends Base
{
$project = $this->getProject();
- $this->response->html($this->projectLayout($template, array(
+ $this->response->html($this->helper->layout->project($template, array(
'owners' => $this->projectUserRole->getAssignableUsersList($project['id'], true),
'values' => empty($values) ? $project : $values,
'errors' => $errors,
diff --git a/app/Controller/ProjectFile.php b/app/Controller/ProjectFile.php
new file mode 100644
index 00000000..96764a92
--- /dev/null
+++ b/app/Controller/ProjectFile.php
@@ -0,0 +1,79 @@
+<?php
+
+namespace Kanboard\Controller;
+
+/**
+ * Project File Controller
+ *
+ * @package controller
+ * @author Frederic Guillot
+ */
+class ProjectFile extends Base
+{
+ /**
+ * File upload form
+ *
+ * @access public
+ */
+ public function create()
+ {
+ $project = $this->getProject();
+
+ $this->response->html($this->template->render('project_file/create', array(
+ 'project' => $project,
+ 'max_size' => $this->helper->text->phpToBytes(ini_get('upload_max_filesize')),
+ )));
+ }
+
+ /**
+ * Save uploaded files
+ *
+ * @access public
+ */
+ public function save()
+ {
+ $project = $this->getProject();
+
+ if (! $this->projectFile->uploadFiles($project['id'], $this->request->getFileInfo('files'))) {
+ $this->flash->failure(t('Unable to upload the file.'));
+ }
+
+ $this->response->redirect($this->helper->url->to('ProjectOverview', 'show', array('project_id' => $project['id'])), true);
+ }
+
+ /**
+ * Remove a file
+ *
+ * @access public
+ */
+ public function remove()
+ {
+ $this->checkCSRFParam();
+ $project = $this->getProject();
+ $file = $this->projectFile->getById($this->request->getIntegerParam('file_id'));
+
+ if ($this->projectFile->remove($file['id'])) {
+ $this->flash->success(t('File removed successfully.'));
+ } else {
+ $this->flash->failure(t('Unable to remove this file.'));
+ }
+
+ $this->response->redirect($this->helper->url->to('ProjectOverview', 'show', array('project_id' => $project['id'])));
+ }
+
+ /**
+ * Confirmation dialog before removing a file
+ *
+ * @access public
+ */
+ public function confirm()
+ {
+ $project = $this->getProject();
+ $file = $this->projectFile->getById($this->request->getIntegerParam('file_id'));
+
+ $this->response->html($this->template->render('project_file/remove', array(
+ 'project' => $project,
+ 'file' => $file,
+ )));
+ }
+}
diff --git a/app/Controller/ProjectOverview.php b/app/Controller/ProjectOverview.php
new file mode 100644
index 00000000..b0687ed3
--- /dev/null
+++ b/app/Controller/ProjectOverview.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Kanboard\Controller;
+
+/**
+ * Project Overview Controller
+ *
+ * @package controller
+ * @author Frederic Guillot
+ */
+class ProjectOverview extends Base
+{
+ /**
+ * Show project overview
+ */
+ public function show()
+ {
+ $params = $this->getProjectFilters('ProjectOverview', 'show');
+ $params['users'] = $this->projectUserRole->getAllUsersGroupedByRole($params['project']['id']);
+ $params['roles'] = $this->role->getProjectRoles();
+ $params['events'] = $this->projectActivity->getProject($params['project']['id'], 10);
+ $params['images'] = $this->projectFile->getAllImages($params['project']['id']);
+ $params['files'] = $this->projectFile->getAllDocuments($params['project']['id']);
+
+ $this->project->getColumnStats($params['project']);
+
+ $this->response->html($this->helper->layout->app('project_overview/show', $params));
+ }
+}
diff --git a/app/Controller/ProjectPermission.php b/app/Controller/ProjectPermission.php
index 4434d017..800da02f 100644
--- a/app/Controller/ProjectPermission.php
+++ b/app/Controller/ProjectPermission.php
@@ -13,6 +13,24 @@ use Kanboard\Core\Security\Role;
class ProjectPermission extends Base
{
/**
+ * Permissions are only available for team projects
+ *
+ * @access protected
+ * @param integer $project_id Default project id
+ * @return array
+ */
+ protected function getProject($project_id = 0)
+ {
+ $project = parent::getProject($project_id);
+
+ if ($project['is_private'] == 1) {
+ $this->forbidden();
+ }
+
+ return $project;
+ }
+
+ /**
* Show all permissions
*
* @access public
@@ -25,7 +43,7 @@ class ProjectPermission extends Base
$values['role'] = Role::PROJECT_MEMBER;
}
- $this->response->html($this->projectLayout('project_permission/index', array(
+ $this->response->html($this->helper->layout->project('project_permission/index', array(
'project' => $project,
'users' => $this->projectUserRole->getUsers($project['id']),
'groups' => $this->projectGroupRole->getGroups($project['id']),
@@ -62,6 +80,7 @@ class ProjectPermission extends Base
*/
public function addUser()
{
+ $project = $this->getProject();
$values = $this->request->getValues();
if ($this->projectUserRole->addUser($values['project_id'], $values['user_id'], $values['role'])) {
@@ -70,7 +89,7 @@ class ProjectPermission extends Base
$this->flash->failure(t('Unable to update this project.'));
}
- $this->response->redirect($this->helper->url->to('ProjectPermission', 'index', array('project_id' => $values['project_id'])));
+ $this->response->redirect($this->helper->url->to('ProjectPermission', 'index', array('project_id' => $project['id'])));
}
/**
@@ -81,19 +100,16 @@ class ProjectPermission extends Base
public function removeUser()
{
$this->checkCSRFParam();
+ $project = $this->getProject();
+ $user_id = $this->request->getIntegerParam('user_id');
- $values = array(
- 'project_id' => $this->request->getIntegerParam('project_id'),
- 'user_id' => $this->request->getIntegerParam('user_id'),
- );
-
- if ($this->projectUserRole->removeUser($values['project_id'], $values['user_id'])) {
+ if ($this->projectUserRole->removeUser($project['id'], $user_id)) {
$this->flash->success(t('Project updated successfully.'));
} else {
$this->flash->failure(t('Unable to update this project.'));
}
- $this->response->redirect($this->helper->url->to('ProjectPermission', 'index', array('project_id' => $values['project_id'])));
+ $this->response->redirect($this->helper->url->to('ProjectPermission', 'index', array('project_id' => $project['id'])));
}
/**
@@ -103,10 +119,10 @@ class ProjectPermission extends Base
*/
public function changeUserRole()
{
- $project_id = $this->request->getIntegerParam('project_id');
+ $project = $this->getProject();
$values = $this->request->getJson();
- if (! empty($project_id) && ! empty($values) && $this->projectUserRole->changeUserRole($project_id, $values['id'], $values['role'])) {
+ if (! empty($project) && ! empty($values) && $this->projectUserRole->changeUserRole($project['id'], $values['id'], $values['role'])) {
$this->response->json(array('status' => 'ok'));
} else {
$this->response->json(array('status' => 'error'));
@@ -120,19 +136,20 @@ class ProjectPermission extends Base
*/
public function addGroup()
{
+ $project = $this->getProject();
$values = $this->request->getValues();
if (empty($values['group_id']) && ! empty($values['external_id'])) {
$values['group_id'] = $this->group->create($values['name'], $values['external_id']);
}
- if ($this->projectGroupRole->addGroup($values['project_id'], $values['group_id'], $values['role'])) {
+ if ($this->projectGroupRole->addGroup($project['id'], $values['group_id'], $values['role'])) {
$this->flash->success(t('Project updated successfully.'));
} else {
$this->flash->failure(t('Unable to update this project.'));
}
- $this->response->redirect($this->helper->url->to('ProjectPermission', 'index', array('project_id' => $values['project_id'])));
+ $this->response->redirect($this->helper->url->to('ProjectPermission', 'index', array('project_id' => $project['id'])));
}
/**
@@ -143,19 +160,16 @@ class ProjectPermission extends Base
public function removeGroup()
{
$this->checkCSRFParam();
+ $project = $this->getProject();
+ $group_id = $this->request->getIntegerParam('group_id');
- $values = array(
- 'project_id' => $this->request->getIntegerParam('project_id'),
- 'group_id' => $this->request->getIntegerParam('group_id'),
- );
-
- if ($this->projectGroupRole->removeGroup($values['project_id'], $values['group_id'])) {
+ if ($this->projectGroupRole->removeGroup($project['id'], $group_id)) {
$this->flash->success(t('Project updated successfully.'));
} else {
$this->flash->failure(t('Unable to update this project.'));
}
- $this->response->redirect($this->helper->url->to('ProjectPermission', 'index', array('project_id' => $values['project_id'])));
+ $this->response->redirect($this->helper->url->to('ProjectPermission', 'index', array('project_id' => $project['id'])));
}
/**
@@ -165,10 +179,10 @@ class ProjectPermission extends Base
*/
public function changeGroupRole()
{
- $project_id = $this->request->getIntegerParam('project_id');
+ $project = $this->getProject();
$values = $this->request->getJson();
- if (! empty($project_id) && ! empty($values) && $this->projectGroupRole->changeGroupRole($project_id, $values['id'], $values['role'])) {
+ if (! empty($project) && ! empty($values) && $this->projectGroupRole->changeGroupRole($project['id'], $values['id'], $values['role'])) {
$this->response->json(array('status' => 'ok'));
} else {
$this->response->json(array('status' => 'error'));
diff --git a/app/Controller/Projectuser.php b/app/Controller/Projectuser.php
index 78b93ab6..a6d4fe4e 100644
--- a/app/Controller/Projectuser.php
+++ b/app/Controller/Projectuser.php
@@ -14,23 +14,6 @@ use Kanboard\Core\Security\Role;
*/
class Projectuser extends Base
{
- /**
- * Common layout for users overview views
- *
- * @access private
- * @param string $template Template name
- * @param array $params Template parameters
- * @return string
- */
- private function layout($template, array $params)
- {
- $params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
- $params['content_for_sublayout'] = $this->template->render($template, $params);
- $params['filter'] = array('user_id' => $params['user_id']);
-
- return $this->template->layout('project_user/layout', $params);
- }
-
private function common()
{
$user_id = $this->request->getIntegerParam('user_id', UserModel::EVERYBODY_ID);
@@ -41,7 +24,7 @@ class Projectuser extends Base
$project_ids = $this->projectPermission->getActiveProjectIds($this->userSession->getId());
}
- return array($user_id, $project_ids, $this->user->getList(true));
+ return array($user_id, $project_ids, $this->user->getActiveUsersList(true));
}
private function role($role, $action, $title, $title_user)
@@ -50,7 +33,7 @@ class Projectuser extends Base
$query = $this->projectPermission->getQueryByRole($project_ids, $role)->callback(array($this->project, 'applyColumnStats'));
- if ($user_id !== UserModel::EVERYBODY_ID) {
+ if ($user_id !== UserModel::EVERYBODY_ID && isset($users[$user_id])) {
$query->eq(UserModel::TABLE.'.id', $user_id);
$title = t($title_user, $users[$user_id]);
}
@@ -62,7 +45,7 @@ class Projectuser extends Base
->setQuery($query)
->calculate();
- $this->response->html($this->layout('project_user/roles', array(
+ $this->response->html($this->helper->layout->projectUser('project_user/roles', array(
'paginator' => $paginator,
'title' => $title,
'user_id' => $user_id,
@@ -76,7 +59,7 @@ class Projectuser extends Base
$query = $this->taskFinder->getProjectUserOverviewQuery($project_ids, $is_active);
- if ($user_id !== UserModel::EVERYBODY_ID) {
+ if ($user_id !== UserModel::EVERYBODY_ID && isset($users[$user_id])) {
$query->eq(TaskModel::TABLE.'.owner_id', $user_id);
$title = t($title_user, $users[$user_id]);
}
@@ -88,7 +71,7 @@ class Projectuser extends Base
->setQuery($query)
->calculate();
- $this->response->html($this->layout('project_user/tasks', array(
+ $this->response->html($this->helper->layout->projectUser('project_user/tasks', array(
'paginator' => $paginator,
'title' => $title,
'user_id' => $user_id,
diff --git a/app/Controller/Search.php b/app/Controller/Search.php
index 390210c0..9b9b9e65 100644
--- a/app/Controller/Search.php
+++ b/app/Controller/Search.php
@@ -36,8 +36,7 @@ class Search extends Base
$nb_tasks = $paginator->getTotal();
}
- $this->response->html($this->template->layout('search/index', array(
- 'board_selector' => $projects,
+ $this->response->html($this->helper->layout->app('search/index', array(
'values' => array(
'search' => $search,
'controller' => 'search',
diff --git a/app/Controller/Subtask.php b/app/Controller/Subtask.php
index caaaa85e..8ca0ce92 100644
--- a/app/Controller/Subtask.php
+++ b/app/Controller/Subtask.php
@@ -2,8 +2,6 @@
namespace Kanboard\Controller;
-use Kanboard\Model\Subtask as SubtaskModel;
-
/**
* Subtask controller
*
@@ -13,20 +11,19 @@ use Kanboard\Model\Subtask as SubtaskModel;
class Subtask extends Base
{
/**
- * Get the current subtask
- *
- * @access private
- * @return array
+ * Show list of subtasks
*/
- private function getSubtask()
+ public function show()
{
- $subtask = $this->subtask->getById($this->request->getIntegerParam('subtask_id'));
-
- if (empty($subtask)) {
- $this->notfound();
- }
+ $task = $this->getTask();
- return $subtask;
+ $this->response->html($this->helper->layout->task('subtask/show', array(
+ 'users_list' => $this->projectUserRole->getAssignableUsersList($task['project_id']),
+ 'task' => $task,
+ 'project' => $this->getProject(),
+ 'subtasks' => $this->subtask->getAll($task['id']),
+ 'editable' => true,
+ )));
}
/**
@@ -45,7 +42,7 @@ class Subtask extends Base
);
}
- $this->response->html($this->taskLayout('subtask/create', array(
+ $this->response->html($this->helper->layout->task('subtask/create', array(
'values' => $values,
'errors' => $errors,
'users_list' => $this->projectUserRole->getAssignableUsersList($task['project_id']),
@@ -73,10 +70,10 @@ class Subtask extends Base
}
if (isset($values['another_subtask']) && $values['another_subtask'] == 1) {
- $this->response->redirect($this->helper->url->to('subtask', 'create', array('project_id' => $task['project_id'], 'task_id' => $task['id'], 'another_subtask' => 1)));
+ return $this->create(array('project_id' => $task['project_id'], 'task_id' => $task['id'], 'another_subtask' => 1));
}
- $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id']), 'subtasks'));
+ return $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id']), 'subtasks'), true);
}
$this->create($values, $errors);
@@ -92,7 +89,7 @@ class Subtask extends Base
$task = $this->getTask();
$subtask = $this->getSubTask();
- $this->response->html($this->taskLayout('subtask/edit', array(
+ $this->response->html($this->helper->layout->task('subtask/edit', array(
'values' => empty($values) ? $subtask : $values,
'errors' => $errors,
'users_list' => $this->projectUserRole->getAssignableUsersList($task['project_id']),
@@ -122,7 +119,7 @@ class Subtask extends Base
$this->flash->failure(t('Unable to update your sub-task.'));
}
- $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id']), 'subtasks'));
+ return $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true);
}
$this->edit($values, $errors);
@@ -138,7 +135,7 @@ class Subtask extends Base
$task = $this->getTask();
$subtask = $this->getSubtask();
- $this->response->html($this->taskLayout('subtask/remove', array(
+ $this->response->html($this->helper->layout->task('subtask/remove', array(
'subtask' => $subtask,
'task' => $task,
)));
@@ -161,97 +158,7 @@ class Subtask extends Base
$this->flash->failure(t('Unable to remove this sub-task.'));
}
- $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id']), 'subtasks'));
- }
-
- /**
- * Change status to the next status: Toto -> In Progress -> Done
- *
- * @access public
- */
- public function toggleStatus()
- {
- $task = $this->getTask();
- $subtask = $this->getSubtask();
- $redirect = $this->request->getStringParam('redirect', 'task');
-
- $this->subtask->toggleStatus($subtask['id']);
-
- if ($redirect === 'board') {
- $this->sessionStorage->hasSubtaskInProgress = $this->subtask->hasSubtaskInProgress($this->userSession->getId());
-
- $this->response->html($this->template->render('board/tooltip_subtasks', array(
- 'subtasks' => $this->subtask->getAll($task['id']),
- 'task' => $task,
- )));
- }
-
- $this->toggleRedirect($task, $redirect);
- }
-
- /**
- * Handle subtask restriction (popover)
- *
- * @access public
- */
- public function subtaskRestriction()
- {
- $task = $this->getTask();
- $subtask = $this->getSubtask();
-
- $this->response->html($this->template->render('subtask/restriction_change_status', array(
- 'status_list' => array(
- SubtaskModel::STATUS_TODO => t('Todo'),
- SubtaskModel::STATUS_DONE => t('Done'),
- ),
- 'subtask_inprogress' => $this->subtask->getSubtaskInProgress($this->userSession->getId()),
- 'subtask' => $subtask,
- 'task' => $task,
- 'redirect' => $this->request->getStringParam('redirect'),
- )));
- }
-
- /**
- * Change status of the in progress subtask and the other subtask
- *
- * @access public
- */
- public function changeRestrictionStatus()
- {
- $task = $this->getTask();
- $subtask = $this->getSubtask();
- $values = $this->request->getValues();
-
- // Change status of the previous in progress subtask
- $this->subtask->update(array(
- 'id' => $values['id'],
- 'status' => $values['status'],
- ));
-
- // Set the current subtask to in pogress
- $this->subtask->update(array(
- 'id' => $subtask['id'],
- 'status' => SubtaskModel::STATUS_INPROGRESS,
- ));
-
- $this->toggleRedirect($task, $values['redirect']);
- }
-
- /**
- * Redirect to the right page
- *
- * @access private
- */
- private function toggleRedirect(array $task, $redirect)
- {
- switch ($redirect) {
- case 'board':
- $this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $task['project_id'])));
- case 'dashboard':
- $this->response->redirect($this->helper->url->to('app', 'index'));
- default:
- $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), 'subtasks'));
- }
+ $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true);
}
/**
@@ -261,14 +168,15 @@ class Subtask extends Base
*/
public function movePosition()
{
- $this->checkCSRFParam();
$project_id = $this->request->getIntegerParam('project_id');
$task_id = $this->request->getIntegerParam('task_id');
- $subtask_id = $this->request->getIntegerParam('subtask_id');
- $direction = $this->request->getStringParam('direction');
- $method = $direction === 'up' ? 'moveUp' : 'moveDown';
+ $values = $this->request->getJson();
+
+ if (! empty($values) && $this->helper->user->hasProjectAccess('Subtask', 'movePosition', $project_id)) {
+ $result = $this->subtask->changePosition($task_id, $values['subtask_id'], $values['position']);
+ return $this->response->json(array('result' => $result));
+ }
- $this->subtask->$method($task_id, $subtask_id);
- $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $project_id, 'task_id' => $task_id), 'subtasks'));
+ $this->forbidden();
}
}
diff --git a/app/Controller/SubtaskRestriction.php b/app/Controller/SubtaskRestriction.php
new file mode 100644
index 00000000..56024867
--- /dev/null
+++ b/app/Controller/SubtaskRestriction.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace Kanboard\Controller;
+
+use Kanboard\Model\Subtask as SubtaskModel;
+
+/**
+ * Subtask Restriction
+ *
+ * @package controller
+ * @author Frederic Guillot
+ */
+class SubtaskRestriction extends Base
+{
+ /**
+ * Show popup
+ *
+ * @access public
+ */
+ public function popover()
+ {
+ $task = $this->getTask();
+ $subtask = $this->getSubtask();
+
+ $this->response->html($this->template->render('subtask_restriction/popover', array(
+ 'status_list' => array(
+ SubtaskModel::STATUS_TODO => t('Todo'),
+ SubtaskModel::STATUS_DONE => t('Done'),
+ ),
+ 'subtask_inprogress' => $this->subtask->getSubtaskInProgress($this->userSession->getId()),
+ 'subtask' => $subtask,
+ 'task' => $task,
+ )));
+ }
+
+ /**
+ * Change status of the in progress subtask and the other subtask
+ *
+ * @access public
+ */
+ public function update()
+ {
+ $task = $this->getTask();
+ $subtask = $this->getSubtask();
+ $values = $this->request->getValues();
+
+ // Change status of the previous "in progress" subtask
+ $this->subtask->update(array(
+ 'id' => $values['id'],
+ 'status' => $values['status'],
+ ));
+
+ // Set the current subtask to "in progress"
+ $this->subtask->update(array(
+ 'id' => $subtask['id'],
+ 'status' => SubtaskModel::STATUS_INPROGRESS,
+ ));
+
+ $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true);
+ }
+}
diff --git a/app/Controller/SubtaskStatus.php b/app/Controller/SubtaskStatus.php
new file mode 100644
index 00000000..4fb82fc0
--- /dev/null
+++ b/app/Controller/SubtaskStatus.php
@@ -0,0 +1,72 @@
+<?php
+
+namespace Kanboard\Controller;
+
+/**
+ * Subtask Status
+ *
+ * @package controller
+ * @author Frederic Guillot
+ */
+class SubtaskStatus extends Base
+{
+ /**
+ * Change status to the next status: Toto -> In Progress -> Done
+ *
+ * @access public
+ */
+ public function change()
+ {
+ $task = $this->getTask();
+ $subtask = $this->getSubtask();
+
+ $status = $this->subtask->toggleStatus($subtask['id']);
+
+ if ($this->request->getIntegerParam('refresh-table') === 0) {
+ $subtask['status'] = $status;
+ $html = $this->helper->subtask->toggleStatus($subtask, $task['project_id']);
+ } else {
+ $html = $this->renderTable($task);
+ }
+
+ $this->response->html($html);
+ }
+
+ /**
+ * Start/stop timer for subtasks
+ *
+ * @access public
+ */
+ public function timer()
+ {
+ $task = $this->getTask();
+ $subtask_id = $this->request->getIntegerParam('subtask_id');
+ $timer = $this->request->getStringParam('timer');
+
+ if ($timer === 'start') {
+ $this->subtaskTimeTracking->logStartTime($subtask_id, $this->userSession->getId());
+ } elseif ($timer === 'stop') {
+ $this->subtaskTimeTracking->logEndTime($subtask_id, $this->userSession->getId());
+ $this->subtaskTimeTracking->updateTaskTimeTracking($task['id']);
+ }
+
+ $this->response->html($this->renderTable($task));
+ }
+
+ /**
+ * Render table
+ *
+ * @access private
+ * @param array $task
+ * @return string
+ */
+ private function renderTable(array $task)
+ {
+ return $this->template->render('subtask/table', array(
+ 'task' => $task,
+ 'subtasks' => $this->subtask->getAll($task['id']),
+ 'editable' => true,
+ 'redirect' => 'task',
+ ));
+ }
+}
diff --git a/app/Controller/Swimlane.php b/app/Controller/Swimlane.php
index 66410888..8270a16f 100644
--- a/app/Controller/Swimlane.php
+++ b/app/Controller/Swimlane.php
@@ -36,18 +36,32 @@ class Swimlane extends Base
*
* @access public
*/
- public function index(array $values = array(), array $errors = array())
+ public function index()
{
$project = $this->getProject();
- $this->response->html($this->projectLayout('swimlane/index', array(
+ $this->response->html($this->helper->layout->project('swimlane/index', array(
'default_swimlane' => $this->swimlane->getDefault($project['id']),
'active_swimlanes' => $this->swimlane->getAllByStatus($project['id'], SwimlaneModel::ACTIVE),
'inactive_swimlanes' => $this->swimlane->getAllByStatus($project['id'], SwimlaneModel::INACTIVE),
+ 'project' => $project,
+ 'title' => t('Swimlanes')
+ )));
+ }
+
+ /**
+ * Create a new swimlane
+ *
+ * @access public
+ */
+ public function create(array $values = array(), array $errors = array())
+ {
+ $project = $this->getProject();
+
+ $this->response->html($this->template->render('swimlane/create', array(
'values' => $values + array('project_id' => $project['id']),
'errors' => $errors,
'project' => $project,
- 'title' => t('Swimlanes')
)));
}
@@ -67,11 +81,28 @@ class Swimlane extends Base
$this->flash->success(t('Your swimlane have been created successfully.'));
$this->response->redirect($this->helper->url->to('swimlane', 'index', array('project_id' => $project['id'])));
} else {
- $this->flash->failure(t('Unable to create your swimlane.'));
+ $errors = array('name' => array(t('Another swimlane with the same name exists in the project')));
}
}
- $this->index($values, $errors);
+ $this->create($values, $errors);
+ }
+
+ /**
+ * Edit default swimlane (display the form)
+ *
+ * @access public
+ */
+ public function editDefault(array $values = array(), array $errors = array())
+ {
+ $project = $this->getProject();
+ $swimlane = $this->swimlane->getDefault($project['id']);
+
+ $this->response->html($this->helper->layout->project('swimlane/edit_default', array(
+ 'values' => empty($values) ? $swimlane : $values,
+ 'errors' => $errors,
+ 'project' => $project,
+ )));
}
/**
@@ -79,23 +110,23 @@ class Swimlane extends Base
*
* @access public
*/
- public function change()
+ public function updateDefault()
{
$project = $this->getProject();
$values = $this->request->getValues() + array('show_default_swimlane' => 0);
- list($valid, ) = $this->swimlaneValidator->validateDefaultModification($values);
+ list($valid, $errors) = $this->swimlaneValidator->validateDefaultModification($values);
if ($valid) {
if ($this->swimlane->updateDefault($values)) {
$this->flash->success(t('The default swimlane have been updated successfully.'));
- $this->response->redirect($this->helper->url->to('swimlane', 'index', array('project_id' => $project['id'])));
+ $this->response->redirect($this->helper->url->to('swimlane', 'index', array('project_id' => $project['id'])), true);
} else {
$this->flash->failure(t('Unable to update this swimlane.'));
}
}
- $this->index();
+ $this->editDefault($values, $errors);
}
/**
@@ -108,11 +139,10 @@ class Swimlane extends Base
$project = $this->getProject();
$swimlane = $this->getSwimlane($project['id']);
- $this->response->html($this->projectLayout('swimlane/edit', array(
+ $this->response->html($this->helper->layout->project('swimlane/edit', array(
'values' => empty($values) ? $swimlane : $values,
'errors' => $errors,
'project' => $project,
- 'title' => t('Swimlanes')
)));
}
@@ -133,7 +163,7 @@ class Swimlane extends Base
$this->flash->success(t('Swimlane updated successfully.'));
$this->response->redirect($this->helper->url->to('swimlane', 'index', array('project_id' => $project['id'])));
} else {
- $this->flash->failure(t('Unable to update this swimlane.'));
+ $errors = array('name' => array(t('Another swimlane with the same name exists in the project')));
}
}
@@ -150,10 +180,9 @@ class Swimlane extends Base
$project = $this->getProject();
$swimlane = $this->getSwimlane($project['id']);
- $this->response->html($this->projectLayout('swimlane/remove', array(
+ $this->response->html($this->helper->layout->project('swimlane/remove', array(
'project' => $project,
'swimlane' => $swimlane,
- 'title' => t('Remove a swimlane')
)));
}
@@ -198,6 +227,25 @@ class Swimlane extends Base
}
/**
+ * Disable default swimlane
+ *
+ * @access public
+ */
+ public function disableDefault()
+ {
+ $this->checkCSRFParam();
+ $project = $this->getProject();
+
+ if ($this->swimlane->disableDefault($project['id'])) {
+ $this->flash->success(t('Swimlane updated successfully.'));
+ } else {
+ $this->flash->failure(t('Unable to update this swimlane.'));
+ }
+
+ $this->response->redirect($this->helper->url->to('swimlane', 'index', array('project_id' => $project['id'])));
+ }
+
+ /**
* Enable a swimlane
*
* @access public
@@ -218,32 +266,39 @@ class Swimlane extends Base
}
/**
- * Move up a swimlane
+ * Enable default swimlane
*
* @access public
*/
- public function moveup()
+ public function enableDefault()
{
$this->checkCSRFParam();
$project = $this->getProject();
- $swimlane_id = $this->request->getIntegerParam('swimlane_id');
- $this->swimlane->moveUp($project['id'], $swimlane_id);
+ if ($this->swimlane->enableDefault($project['id'])) {
+ $this->flash->success(t('Swimlane updated successfully.'));
+ } else {
+ $this->flash->failure(t('Unable to update this swimlane.'));
+ }
+
$this->response->redirect($this->helper->url->to('swimlane', 'index', array('project_id' => $project['id'])));
}
/**
- * Move down a swimlane
+ * Move swimlane position
*
* @access public
*/
- public function movedown()
+ public function move()
{
- $this->checkCSRFParam();
$project = $this->getProject();
- $swimlane_id = $this->request->getIntegerParam('swimlane_id');
+ $values = $this->request->getJson();
- $this->swimlane->moveDown($project['id'], $swimlane_id);
- $this->response->redirect($this->helper->url->to('swimlane', 'index', array('project_id' => $project['id'])));
+ if (! empty($values) && isset($values['swimlane_id']) && isset($values['position'])) {
+ $result = $this->swimlane->changePosition($project['id'], $values['swimlane_id'], $values['position']);
+ return $this->response->json(array('result' => $result));
+ }
+
+ $this->forbidden();
}
}
diff --git a/app/Controller/Task.php b/app/Controller/Task.php
index 1811dcb7..56d222d0 100644
--- a/app/Controller/Task.php
+++ b/app/Controller/Task.php
@@ -2,6 +2,8 @@
namespace Kanboard\Controller;
+use Kanboard\Core\DateParser;
+
/**
* Task controller
*
@@ -21,22 +23,26 @@ class Task extends Base
// Token verification
if (empty($project)) {
- $this->forbidden(true);
+ return $this->forbidden(true);
}
$task = $this->taskFinder->getDetails($this->request->getIntegerParam('task_id'));
if (empty($task)) {
- $this->notfound(true);
+ return $this->notfound(true);
+ }
+
+ if ($task['project_id'] != $project['id']) {
+ return $this->forbidden(true);
}
- $this->response->html($this->template->layout('task/public', array(
+ $this->response->html($this->helper->layout->app('task/public', array(
'project' => $project,
'comments' => $this->comment->getAll($task['id']),
'subtasks' => $this->subtask->getAll($task['id']),
'links' => $this->taskLink->getAllGroupedByLabel($task['id']),
'task' => $task,
- 'columns_list' => $this->board->getColumnsList($task['project_id']),
+ 'columns_list' => $this->column->getList($task['project_id']),
'colors_list' => $this->color->getList(),
'title' => $task['title'],
'no_layout' => true,
@@ -62,23 +68,21 @@ class Task extends Base
'time_spent' => $task['time_spent'] ?: '',
);
- $this->dateParser->format($values, array('date_started'), 'Y-m-d H:i');
+ $values = $this->dateParser->format($values, array('date_started'), $this->config->get('application_datetime_format', DateParser::DATE_TIME_FORMAT));
- $this->response->html($this->taskLayout('task/show', array(
+ $this->response->html($this->helper->layout->task('task/show', array(
'project' => $this->project->getById($task['project_id']),
- 'files' => $this->file->getAllDocuments($task['id']),
- 'images' => $this->file->getAllImages($task['id']),
+ 'files' => $this->taskFile->getAllDocuments($task['id']),
+ 'images' => $this->taskFile->getAllImages($task['id']),
'comments' => $this->comment->getAll($task['id'], $this->userSession->getCommentSorting()),
'subtasks' => $subtasks,
'links' => $this->taskLink->getAllGroupedByLabel($task['id']),
'task' => $task,
'values' => $values,
'link_label_list' => $this->link->getList(0, false),
- 'columns_list' => $this->board->getColumnsList($task['project_id']),
+ 'columns_list' => $this->column->getList($task['project_id']),
'colors_list' => $this->color->getList(),
'users_list' => $this->projectUserRole->getAssignableUsersList($task['project_id'], true, false, false),
- 'date_format' => $this->config->get('application_date_format'),
- 'date_formats' => $this->dateParser->getAvailableFormats(),
'title' => $task['project_name'].' &gt; '.$task['title'],
'recurrence_trigger_list' => $this->task->getRecurrenceTriggerList(),
'recurrence_timeframe_list' => $this->task->getRecurrenceTimeframeList(),
@@ -95,7 +99,7 @@ class Task extends Base
{
$task = $this->getTask();
- $this->response->html($this->taskLayout('task/analytics', array(
+ $this->response->html($this->helper->layout->task('task/analytics', array(
'title' => $task['title'],
'task' => $task,
'lead_time' => $this->taskAnalytic->getLeadTime($task),
@@ -114,14 +118,14 @@ class Task extends Base
$task = $this->getTask();
$subtask_paginator = $this->paginator
- ->setUrl('task', 'timesheet', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'pagination' => 'subtasks'))
+ ->setUrl('task', 'timetracking', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'pagination' => 'subtasks'))
->setMax(15)
->setOrder('start')
->setDirection('DESC')
->setQuery($this->subtaskTimeTracking->getTaskQuery($task['id']))
->calculateOnlyIf($this->request->getStringParam('pagination') === 'subtasks');
- $this->response->html($this->taskLayout('task/time_tracking_details', array(
+ $this->response->html($this->helper->layout->task('task/time_tracking_details', array(
'task' => $task,
'subtask_paginator' => $subtask_paginator,
)));
@@ -136,7 +140,7 @@ class Task extends Base
{
$task = $this->getTask();
- $this->response->html($this->taskLayout('task/transitions', array(
+ $this->response->html($this->helper->layout->task('task/transitions', array(
'task' => $task,
'transitions' => $this->transition->getAllByTask($task['id']),
)));
@@ -167,7 +171,7 @@ class Task extends Base
$this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $task['project_id'])));
}
- $this->response->html($this->taskLayout('task/remove', array(
+ $this->response->html($this->helper->layout->task('task/remove', array(
'task' => $task,
)));
}
diff --git a/app/Controller/TaskExternalLink.php b/app/Controller/TaskExternalLink.php
new file mode 100644
index 00000000..f26922dd
--- /dev/null
+++ b/app/Controller/TaskExternalLink.php
@@ -0,0 +1,185 @@
+<?php
+
+namespace Kanboard\Controller;
+
+use Kanboard\Core\ExternalLink\ExternalLinkProviderNotFound;
+
+/**
+ * Task External Link Controller
+ *
+ * @package controller
+ * @author Frederic Guillot
+ */
+class TaskExternalLink extends Base
+{
+ /**
+ * Creation form
+ *
+ * @access public
+ */
+ public function show()
+ {
+ $task = $this->getTask();
+
+ $this->response->html($this->helper->layout->task('task_external_link/show', array(
+ 'links' => $this->taskExternalLink->getAll($task['id']),
+ 'task' => $task,
+ 'title' => t('List of external links'),
+ )));
+ }
+
+ /**
+ * First creation form
+ *
+ * @access public
+ */
+ public function find(array $values = array(), array $errors = array())
+ {
+ $task = $this->getTask();
+
+ $this->response->html($this->helper->layout->task('task_external_link/find', array(
+ 'values' => $values,
+ 'errors' => $errors,
+ 'task' => $task,
+ 'types' => $this->externalLinkManager->getTypes(),
+ )));
+ }
+
+ /**
+ * Second creation form
+ *
+ * @access public
+ */
+ public function create()
+ {
+ try {
+
+ $task = $this->getTask();
+ $values = $this->request->getValues();
+
+ $provider = $this->externalLinkManager->setUserInput($values)->find();
+ $link = $provider->getLink();
+
+ $this->response->html($this->helper->layout->task('task_external_link/create', array(
+ 'values' => array(
+ 'title' => $link->getTitle(),
+ 'url' => $link->getUrl(),
+ 'link_type' => $provider->getType(),
+ ),
+ 'dependencies' => $provider->getDependencies(),
+ 'errors' => array(),
+ 'task' => $task,
+ )));
+
+ } catch (ExternalLinkProviderNotFound $e) {
+ $errors = array('text' => array(t('Unable to fetch link information.')));
+ $this->find($values, $errors);
+ }
+ }
+
+ /**
+ * Save link
+ *
+ * @access public
+ */
+ public function save()
+ {
+ $task = $this->getTask();
+ $values = $this->request->getValues();
+ list($valid, $errors) = $this->externalLinkValidator->validateCreation($values);
+
+ if ($valid && $this->taskExternalLink->create($values)) {
+ $this->flash->success(t('Link added successfully.'));
+ return $this->response->redirect($this->helper->url->to('TaskExternalLink', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true);
+ }
+
+ $this->edit($values, $errors);
+ }
+
+ /**
+ * Edit form
+ *
+ * @access public
+ */
+ 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->taskExternalLink->getById($link_id);
+ }
+
+ if (empty($values)) {
+ return $this->notfound();
+ }
+
+ $provider = $this->externalLinkManager->getProvider($values['link_type']);
+
+ $this->response->html($this->helper->layout->task('task_external_link/edit', array(
+ 'values' => $values,
+ 'errors' => $errors,
+ 'task' => $task,
+ 'dependencies' => $provider->getDependencies(),
+ )));
+ }
+
+ /**
+ * Update link
+ *
+ * @access public
+ */
+ public function update()
+ {
+ $task = $this->getTask();
+ $values = $this->request->getValues();
+ list($valid, $errors) = $this->externalLinkValidator->validateModification($values);
+
+ if ($valid && $this->taskExternalLink->update($values)) {
+ $this->flash->success(t('Link updated successfully.'));
+ return $this->response->redirect($this->helper->url->to('TaskExternalLink', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true);
+ }
+
+ $this->edit($values, $errors);
+ }
+
+ /**
+ * Confirmation dialog before removing a link
+ *
+ * @access public
+ */
+ public function confirm()
+ {
+ $task = $this->getTask();
+ $link_id = $this->request->getIntegerParam('link_id');
+ $link = $this->taskExternalLink->getById($link_id);
+
+ if (empty($link)) {
+ return $this->notfound();
+ }
+
+ $this->response->html($this->helper->layout->task('task_external_link/remove', array(
+ 'link' => $link,
+ 'task' => $task,
+ )));
+ }
+
+ /**
+ * Remove a link
+ *
+ * @access public
+ */
+ public function remove()
+ {
+ $this->checkCSRFParam();
+ $task = $this->getTask();
+
+ if ($this->taskExternalLink->remove($this->request->getIntegerParam('link_id'))) {
+ $this->flash->success(t('Link removed successfully.'));
+ } else {
+ $this->flash->failure(t('Unable to remove this link.'));
+ }
+
+ $this->response->redirect($this->helper->url->to('TaskExternalLink', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])));
+ }
+}
diff --git a/app/Controller/TaskFile.php b/app/Controller/TaskFile.php
new file mode 100644
index 00000000..2b0152a7
--- /dev/null
+++ b/app/Controller/TaskFile.php
@@ -0,0 +1,98 @@
+<?php
+
+namespace Kanboard\Controller;
+
+/**
+ * Task File Controller
+ *
+ * @package controller
+ * @author Frederic Guillot
+ */
+class TaskFile extends Base
+{
+ /**
+ * Screenshot
+ *
+ * @access public
+ */
+ public function screenshot()
+ {
+ $task = $this->getTask();
+
+ if ($this->request->isPost() && $this->taskFile->uploadScreenshot($task['id'], $this->request->getValue('screenshot')) !== false) {
+ $this->flash->success(t('Screenshot uploaded successfully.'));
+ return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true);
+ }
+
+ $this->response->html($this->template->render('task_file/screenshot', array(
+ 'task' => $task,
+ )));
+ }
+
+ /**
+ * File upload form
+ *
+ * @access public
+ */
+ public function create()
+ {
+ $task = $this->getTask();
+
+ $this->response->html($this->template->render('task_file/create', array(
+ 'task' => $task,
+ 'max_size' => $this->helper->text->phpToBytes(ini_get('upload_max_filesize')),
+ )));
+ }
+
+ /**
+ * File upload (save files)
+ *
+ * @access public
+ */
+ public function save()
+ {
+ $task = $this->getTask();
+
+ if (! $this->taskFile->uploadFiles($task['id'], $this->request->getFileInfo('files'))) {
+ $this->flash->failure(t('Unable to upload the file.'));
+ }
+
+ $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true);
+ }
+
+ /**
+ * Remove a file
+ *
+ * @access public
+ */
+ public function remove()
+ {
+ $this->checkCSRFParam();
+ $task = $this->getTask();
+ $file = $this->taskFile->getById($this->request->getIntegerParam('file_id'));
+
+ if ($file['task_id'] == $task['id'] && $this->taskFile->remove($file['id'])) {
+ $this->flash->success(t('File removed successfully.'));
+ } else {
+ $this->flash->failure(t('Unable to remove this file.'));
+ }
+
+ $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])));
+ }
+
+ /**
+ * Confirmation dialog before removing a file
+ *
+ * @access public
+ */
+ public function confirm()
+ {
+ $task = $this->getTask();
+ $file = $this->taskFile->getById($this->request->getIntegerParam('file_id'));
+
+ $this->response->html($this->template->render('task_file/remove', array(
+ 'task' => $task,
+ 'file' => $file,
+ )));
+ }
+}
diff --git a/app/Controller/TaskImport.php b/app/Controller/TaskImport.php
index f09c14ce..460c608c 100644
--- a/app/Controller/TaskImport.php
+++ b/app/Controller/TaskImport.php
@@ -20,7 +20,7 @@ class TaskImport extends Base
{
$project = $this->getProject();
- $this->response->html($this->projectLayout('task_import/step1', array(
+ $this->response->html($this->helper->layout->project('task_import/step1', array(
'project' => $project,
'values' => $values,
'errors' => $errors,
diff --git a/app/Controller/TaskRecurrence.php b/app/Controller/TaskRecurrence.php
new file mode 100644
index 00000000..f02f3cdc
--- /dev/null
+++ b/app/Controller/TaskRecurrence.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace Kanboard\Controller;
+
+/**
+ * Task Recurrence controller
+ *
+ * @package controller
+ * @author Frederic Guillot
+ */
+class TaskRecurrence extends Base
+{
+ /**
+ * Edit recurrence form
+ *
+ * @access public
+ */
+ public function edit(array $values = array(), array $errors = array())
+ {
+ $task = $this->getTask();
+
+ if (empty($values)) {
+ $values = $task;
+ }
+
+ $this->response->html($this->helper->layout->task('task_recurrence/edit', array(
+ 'values' => $values,
+ 'errors' => $errors,
+ 'task' => $task,
+ 'recurrence_status_list' => $this->task->getRecurrenceStatusList(),
+ 'recurrence_trigger_list' => $this->task->getRecurrenceTriggerList(),
+ 'recurrence_timeframe_list' => $this->task->getRecurrenceTimeframeList(),
+ 'recurrence_basedate_list' => $this->task->getRecurrenceBasedateList(),
+ )));
+ }
+
+ /**
+ * Update recurrence form
+ *
+ * @access public
+ */
+ public function update()
+ {
+ $task = $this->getTask();
+ $values = $this->request->getValues();
+
+ list($valid, $errors) = $this->taskValidator->validateEditRecurrence($values);
+
+ if ($valid) {
+ if ($this->taskModification->update($values)) {
+ $this->flash->success(t('Task updated successfully.'));
+ } else {
+ $this->flash->failure(t('Unable to update your task.'));
+ }
+
+ $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true);
+ }
+
+ $this->edit($values, $errors);
+ }
+}
diff --git a/app/Controller/Taskcreation.php b/app/Controller/Taskcreation.php
index 49ccea7f..1d8a0e29 100644
--- a/app/Controller/Taskcreation.php
+++ b/app/Controller/Taskcreation.php
@@ -18,31 +18,29 @@ class Taskcreation extends Base
public function create(array $values = array(), array $errors = array())
{
$project = $this->getProject();
- $method = $this->request->isAjax() ? 'render' : 'layout';
$swimlanes_list = $this->swimlane->getList($project['id'], false, true);
if (empty($values)) {
$values = array(
'swimlane_id' => $this->request->getIntegerParam('swimlane_id', key($swimlanes_list)),
'column_id' => $this->request->getIntegerParam('column_id'),
- 'color_id' => $this->request->getStringParam('color_id', $this->color->getDefaultColor()),
- 'owner_id' => $this->request->getIntegerParam('owner_id'),
- 'another_task' => $this->request->getIntegerParam('another_task'),
+ 'color_id' => $this->color->getDefaultColor(),
+ 'owner_id' => $this->userSession->getId(),
);
+
+ $values = $this->hook->merge('controller:task:form:default', $values, array('default_values' => $values));
+ $values = $this->hook->merge('controller:task-creation:form:default', $values, array('default_values' => $values));
}
- $this->response->html($this->template->$method('task_creation/form', array(
+ $this->response->html($this->template->render('task_creation/form', array(
'project' => $project,
- 'ajax' => $this->request->isAjax(),
'errors' => $errors,
'values' => $values + array('project_id' => $project['id']),
- 'columns_list' => $this->board->getColumnsList($project['id']),
+ 'columns_list' => $this->column->getList($project['id']),
'users_list' => $this->projectUserRole->getAssignableUsersList($project['id'], true, false, true),
'colors_list' => $this->color->getList(),
'categories_list' => $this->category->getList($project['id']),
'swimlanes_list' => $swimlanes_list,
- 'date_format' => $this->config->get('application_date_format'),
- 'date_formats' => $this->dateParser->getAvailableFormats(),
'title' => $project['name'].' &gt; '.t('New task')
)));
}
@@ -61,25 +59,26 @@ class Taskcreation extends Base
if ($valid && $this->taskCreation->create($values)) {
$this->flash->success(t('Task created successfully.'));
- $this->afterSave($project, $values);
- } else {
- $this->flash->failure(t('Unable to create your task.'));
+ return $this->afterSave($project, $values);
}
+ $this->flash->failure(t('Unable to create your task.'));
$this->create($values, $errors);
}
private function afterSave(array $project, array &$values)
{
if (isset($values['another_task']) && $values['another_task'] == 1) {
- unset($values['title']);
- unset($values['description']);
-
- if (! $this->request->isAjax()) {
- $this->response->redirect($this->helper->url->to('taskcreation', 'create', $values));
- }
- } else {
- $this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $project['id'])));
+ return $this->create(array(
+ 'owner_id' => $values['owner_id'],
+ 'color_id' => $values['color_id'],
+ 'category_id' => isset($values['category_id']) ? $values['category_id'] : 0,
+ 'column_id' => $values['column_id'],
+ 'swimlane_id' => isset($values['swimlane_id']) ? $values['swimlane_id'] : 0,
+ 'another_task' => 1,
+ ));
}
+
+ $this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $project['id'])));
}
}
diff --git a/app/Controller/Taskduplication.php b/app/Controller/Taskduplication.php
index ae8bfcbc..7641a48d 100644
--- a/app/Controller/Taskduplication.php
+++ b/app/Controller/Taskduplication.php
@@ -2,8 +2,6 @@
namespace Kanboard\Controller;
-use Kanboard\Model\Project as ProjectModel;
-
/**
* Task Duplication controller
*
@@ -30,11 +28,11 @@ class Taskduplication extends Base
$this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task_id)));
} else {
$this->flash->failure(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->redirect($this->helper->url->to('taskduplication', 'duplicate', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true);
}
}
- $this->response->html($this->taskLayout('task_duplication/duplicate', array(
+ $this->response->html($this->helper->layout->task('task_duplication/duplicate', array(
'task' => $task,
)));
}
@@ -109,7 +107,7 @@ class Taskduplication extends Base
private function chooseDestination(array $task, $template)
{
$values = array();
- $projects_list = $this->projectUserRole->getProjectsByUser($this->userSession->getId(), array(ProjectModel::ACTIVE));
+ $projects_list = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
unset($projects_list[$task['project_id']]);
@@ -117,7 +115,7 @@ class Taskduplication extends Base
$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);
+ $columns_list = $this->column->getList($dst_project_id);
$categories_list = $this->category->getList($dst_project_id);
$users_list = $this->projectUserRole->getAssignableUsersList($dst_project_id);
@@ -130,7 +128,7 @@ class Taskduplication extends Base
$users_list = array();
}
- $this->response->html($this->taskLayout($template, array(
+ $this->response->html($this->helper->layout->task($template, array(
'values' => $values,
'task' => $task,
'projects_list' => $projects_list,
diff --git a/app/Controller/Tasklink.php b/app/Controller/Tasklink.php
index a81d3ee5..fdb4fada 100644
--- a/app/Controller/Tasklink.php
+++ b/app/Controller/Tasklink.php
@@ -22,13 +22,32 @@ class Tasklink extends Base
$link = $this->taskLink->getById($this->request->getIntegerParam('link_id'));
if (empty($link)) {
- $this->notfound();
+ return $this->notfound();
}
return $link;
}
/**
+ * Show links
+ *
+ * @access public
+ */
+ public function show()
+ {
+ $task = $this->getTask();
+ $project = $this->project->getById($task['project_id']);
+
+ $this->response->html($this->helper->layout->task('tasklink/show', array(
+ 'links' => $this->taskLink->getAllGroupedByLabel($task['id']),
+ 'task' => $task,
+ 'project' => $project,
+ 'editable' => true,
+ 'is_public' => false,
+ )));
+ }
+
+ /**
* Creation form
*
* @access public
@@ -36,20 +55,8 @@ class Tasklink extends Base
public function create(array $values = array(), array $errors = array())
{
$task = $this->getTask();
- $ajax = $this->request->isAjax() || $this->request->getIntegerParam('ajax');
-
- if ($ajax && empty($errors)) {
- $this->response->html($this->template->render('tasklink/create', array(
- 'values' => $values,
- 'errors' => $errors,
- 'task' => $task,
- 'labels' => $this->link->getList(0, false),
- 'title' => t('Add a new link'),
- 'ajax' => $ajax,
- )));
- }
- $this->response->html($this->taskLayout('tasklink/create', array(
+ $this->response->html($this->helper->layout->task('tasklink/create', array(
'values' => $values,
'errors' => $errors,
'task' => $task,
@@ -67,19 +74,13 @@ class Tasklink extends Base
{
$task = $this->getTask();
$values = $this->request->getValues();
- $ajax = $this->request->isAjax() || $this->request->getIntegerParam('ajax');
list($valid, $errors) = $this->taskLinkValidator->validateCreation($values);
if ($valid) {
if ($this->taskLink->create($values['task_id'], $values['opposite_task_id'], $values['link_id'])) {
$this->flash->success(t('Link added successfully.'));
-
- if ($ajax) {
- $this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $task['project_id'])));
- }
-
- $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])).'#links');
+ return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])).'#links', true);
}
$errors = array('title' => array(t('The exact same link already exists')));
@@ -105,7 +106,7 @@ class Tasklink extends Base
$values['title'] = '#'.$opposite_task['id'].' - '.$opposite_task['title'];
}
- $this->response->html($this->taskLayout('tasklink/edit', array(
+ $this->response->html($this->helper->layout->task('tasklink/edit', array(
'values' => $values,
'errors' => $errors,
'task_link' => $task_link,
@@ -130,7 +131,7 @@ class Tasklink extends Base
if ($valid) {
if ($this->taskLink->update($values['id'], $values['task_id'], $values['opposite_task_id'], $values['link_id'])) {
$this->flash->success(t('Link updated successfully.'));
- $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])).'#links');
+ return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])).'#links');
}
$this->flash->failure(t('Unable to update your link.'));
@@ -149,7 +150,7 @@ class Tasklink extends Base
$task = $this->getTask();
$link = $this->getTaskLink();
- $this->response->html($this->taskLayout('tasklink/remove', array(
+ $this->response->html($this->helper->layout->task('tasklink/remove', array(
'link' => $link,
'task' => $task,
)));
diff --git a/app/Controller/Taskmodification.php b/app/Controller/Taskmodification.php
index 2c97970b..5fcb810c 100644
--- a/app/Controller/Taskmodification.php
+++ b/app/Controller/Taskmodification.php
@@ -2,6 +2,8 @@
namespace Kanboard\Controller;
+use Kanboard\Core\DateParser;
+
/**
* Task Modification controller
*
@@ -23,71 +25,48 @@ class Taskmodification extends Base
}
/**
- * Update time tracking information
+ * Edit description form
*
* @access public
*/
- public function time()
+ public function description(array $values = array(), array $errors = array())
{
$task = $this->getTask();
- $values = $this->request->getValues();
-
- list($valid, ) = $this->taskValidator->validateTimeModification($values);
- if ($valid && $this->taskModification->update($values)) {
- $this->flash->success(t('Task updated successfully.'));
- } else {
- $this->flash->failure(t('Unable to update your task.'));
+ if (empty($values)) {
+ $values = array('id' => $task['id'], 'description' => $task['description']);
}
- $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])));
+ $this->response->html($this->helper->layout->task('task_modification/edit_description', array(
+ 'values' => $values,
+ 'errors' => $errors,
+ 'task' => $task,
+ )));
}
/**
- * Edit description form
+ * Update description
*
* @access public
*/
- public function description()
+ public function updateDescription()
{
$task = $this->getTask();
- $ajax = $this->request->isAjax() || $this->request->getIntegerParam('ajax');
-
- if ($this->request->isPost()) {
- $values = $this->request->getValues();
-
- list($valid, $errors) = $this->taskValidator->validateDescriptionCreation($values);
+ $values = $this->request->getValues();
- if ($valid) {
- if ($this->taskModification->update($values)) {
- $this->flash->success(t('Task updated successfully.'));
- } else {
- $this->flash->failure(t('Unable to update your task.'));
- }
+ list($valid, $errors) = $this->taskValidator->validateDescriptionCreation($values);
- if ($ajax) {
- $this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $task['project_id'])));
- } else {
- $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])));
- }
+ if ($valid) {
+ if ($this->taskModification->update($values)) {
+ $this->flash->success(t('Task updated successfully.'));
+ } else {
+ $this->flash->failure(t('Unable to update your task.'));
}
- } else {
- $values = $task;
- $errors = array();
- }
- $params = array(
- 'values' => $values,
- 'errors' => $errors,
- 'task' => $task,
- 'ajax' => $ajax,
- );
-
- if ($ajax) {
- $this->response->html($this->template->render('task_modification/edit_description', $params));
- } else {
- $this->response->html($this->taskLayout('task_modification/edit_description', $params));
+ return $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true);
}
+
+ $this->description($values, $errors);
}
/**
@@ -99,15 +78,17 @@ class Taskmodification extends Base
{
$task = $this->getTask();
$project = $this->project->getById($task['project_id']);
- $ajax = $this->request->isAjax();
if (empty($values)) {
$values = $task;
+ $values = $this->hook->merge('controller:task:form:default', $values, array('default_values' => $values));
+ $values = $this->hook->merge('controller:task-modification:form:default', $values, array('default_values' => $values));
}
- $this->dateParser->format($values, array('date_due'));
+ $values = $this->dateParser->format($values, array('date_due'), $this->config->get('application_date_format', DateParser::DATE_FORMAT));
+ $values = $this->dateParser->format($values, array('date_started'), $this->config->get('application_datetime_format', DateParser::DATE_TIME_FORMAT));
- $params = array(
+ $this->response->html($this->helper->layout->task('task_modification/edit_task', array(
'project' => $project,
'values' => $values,
'errors' => $errors,
@@ -115,18 +96,7 @@ class Taskmodification extends Base
'users_list' => $this->projectUserRole->getAssignableUsersList($task['project_id']),
'colors_list' => $this->color->getList(),
'categories_list' => $this->category->getList($task['project_id']),
- 'date_format' => $this->config->get('application_date_format'),
- 'date_formats' => $this->dateParser->getAvailableFormats(),
- 'ajax' => $ajax,
- );
-
- if ($ajax) {
- $html = $this->template->render('task_modification/edit_task', $params);
- } else {
- $html = $this->taskLayout('task_modification/edit_task', $params);
- }
-
- $this->response->html($html);
+ )));
}
/**
@@ -143,56 +113,10 @@ class Taskmodification extends Base
if ($valid && $this->taskModification->update($values)) {
$this->flash->success(t('Task updated successfully.'));
-
- if ($this->request->isAjax()) {
- $this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $task['project_id'])));
- } else {
- $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])));
- }
+ return $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true);
} else {
$this->flash->failure(t('Unable to update your task.'));
$this->edit($values, $errors);
}
}
-
- /**
- * Edit recurrence form
- *
- * @access public
- */
- public function recurrence()
- {
- $task = $this->getTask();
-
- if ($this->request->isPost()) {
- $values = $this->request->getValues();
-
- list($valid, $errors) = $this->taskValidator->validateEditRecurrence($values);
-
- if ($valid) {
- if ($this->taskModification->update($values)) {
- $this->flash->success(t('Task updated successfully.'));
- } else {
- $this->flash->failure(t('Unable to update your task.'));
- }
-
- $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])));
- }
- } else {
- $values = $task;
- $errors = array();
- }
-
- $params = array(
- 'values' => $values,
- 'errors' => $errors,
- 'task' => $task,
- 'recurrence_status_list' => $this->task->getRecurrenceStatusList(),
- 'recurrence_trigger_list' => $this->task->getRecurrenceTriggerList(),
- 'recurrence_timeframe_list' => $this->task->getRecurrenceTimeframeList(),
- 'recurrence_basedate_list' => $this->task->getRecurrenceBasedateList(),
- );
-
- $this->response->html($this->taskLayout('task_modification/edit_recurrence', $params));
- }
}
diff --git a/app/Controller/Taskstatus.php b/app/Controller/Taskstatus.php
index b03baebf..c07f2cc5 100644
--- a/app/Controller/Taskstatus.php
+++ b/app/Controller/Taskstatus.php
@@ -17,9 +17,7 @@ class Taskstatus extends Base
*/
public function close()
{
- $task = $this->getTask();
- $this->changeStatus($task, 'close', t('Task closed successfully.'), t('Unable to close this task.'));
- $this->renderTemplate($task, 'task_status/close');
+ $this->changeStatus('close', 'task_status/close', t('Task closed successfully.'), t('Unable to close this task.'));
}
/**
@@ -29,13 +27,22 @@ class Taskstatus extends Base
*/
public function open()
{
- $task = $this->getTask();
- $this->changeStatus($task, 'open', t('Task opened successfully.'), t('Unable to open this task.'));
- $this->renderTemplate($task, 'task_status/open');
+ $this->changeStatus('open', 'task_status/open', t('Task opened successfully.'), t('Unable to open this task.'));
}
- private function changeStatus(array $task, $method, $success_message, $failure_message)
+ /**
+ * Common method to change status
+ *
+ * @access private
+ * @param string $method
+ * @param string $template
+ * @param string $success_message
+ * @param string $failure_message
+ */
+ private function changeStatus($method, $template, $success_message, $failure_message)
{
+ $task = $this->getTask();
+
if ($this->request->getStringParam('confirmation') === 'yes') {
$this->checkCSRFParam();
@@ -45,28 +52,11 @@ class Taskstatus extends Base
$this->flash->failure($failure_message);
}
- if ($this->request->getStringParam('redirect') === 'board') {
- $this->response->redirect($this->helper->url->to('board', 'show', array('project_id' => $task['project_id'])));
- }
-
- $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])));
- }
- }
-
- private function renderTemplate(array $task, $template)
- {
- $redirect = $this->request->getStringParam('redirect');
-
- if ($this->request->isAjax()) {
- $this->response->html($this->template->render($template, array(
- 'task' => $task,
- 'redirect' => $redirect,
- )));
+ return $this->response->redirect($this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true);
}
- $this->response->html($this->taskLayout($template, array(
+ $this->response->html($this->helper->layout->task($template, array(
'task' => $task,
- 'redirect' => $redirect,
)));
}
}
diff --git a/app/Controller/Timer.php b/app/Controller/Timer.php
deleted file mode 100644
index 0267fcdd..00000000
--- a/app/Controller/Timer.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-
-namespace Kanboard\Controller;
-
-/**
- * Time Tracking controller
- *
- * @package controller
- * @author Frederic Guillot
- */
-class Timer extends Base
-{
- /**
- * Start/stop timer for subtasks
- *
- * @access public
- */
- public function subtask()
- {
- $project_id = $this->request->getIntegerParam('project_id');
- $task_id = $this->request->getIntegerParam('task_id');
- $subtask_id = $this->request->getIntegerParam('subtask_id');
- $timer = $this->request->getStringParam('timer');
-
- if ($timer === 'start') {
- $this->subtaskTimeTracking->logStartTime($subtask_id, $this->userSession->getId());
- } elseif ($timer === 'stop') {
- $this->subtaskTimeTracking->logEndTime($subtask_id, $this->userSession->getId());
- $this->subtaskTimeTracking->updateTaskTimeTracking($task_id);
- }
-
- $this->response->redirect($this->helper->url->to('task', 'show', array('project_id' => $project_id, 'task_id' => $task_id)).'#subtasks');
- }
-}
diff --git a/app/Controller/Twofactor.php b/app/Controller/Twofactor.php
index 8dbfcf66..10292261 100644
--- a/app/Controller/Twofactor.php
+++ b/app/Controller/Twofactor.php
@@ -33,7 +33,7 @@ class Twofactor extends User
$this->checkCurrentUser($user);
unset($this->sessionStorage->twoFactorSecret);
- $this->response->html($this->layout('twofactor/index', array(
+ $this->response->html($this->helper->layout->user('twofactor/index', array(
'user' => $user,
'provider' => $this->authenticationManager->getPostAuthenticationProvider()->getName(),
)));
@@ -60,7 +60,7 @@ class Twofactor extends User
$provider->setSecret($this->sessionStorage->twoFactorSecret);
}
- $this->response->html($this->layout('twofactor/show', array(
+ $this->response->html($this->helper->layout->user('twofactor/show', array(
'user' => $user,
'secret' => $this->sessionStorage->twoFactorSecret,
'qrcode_url' => $provider->getQrCodeUrl($label),
@@ -165,7 +165,7 @@ class Twofactor extends User
$this->sessionStorage->twoFactorBeforeCodeCalled = true;
}
- $this->response->html($this->template->layout('twofactor/check', array(
+ $this->response->html($this->helper->layout->app('twofactor/check', array(
'title' => t('Check two factor authentication code'),
)));
}
@@ -191,7 +191,7 @@ class Twofactor extends User
$this->response->redirect($this->helper->url->to('user', 'show', array('user_id' => $user['id'])));
}
- $this->response->html($this->layout('twofactor/disable', array(
+ $this->response->html($this->helper->layout->user('twofactor/disable', array(
'user' => $user,
)));
}
diff --git a/app/Controller/User.php b/app/Controller/User.php
index 97e01553..f7d7d2e0 100644
--- a/app/Controller/User.php
+++ b/app/Controller/User.php
@@ -15,27 +15,6 @@ use Kanboard\Core\Security\Role;
class User extends Base
{
/**
- * Common layout for user views
- *
- * @access protected
- * @param string $template Template name
- * @param array $params Template parameters
- * @return string
- */
- protected function layout($template, array $params)
- {
- $content = $this->template->render($template, $params);
- $params['user_content_for_layout'] = $content;
- $params['board_selector'] = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId());
-
- if (isset($params['user'])) {
- $params['title'] = ($params['user']['name'] ?: $params['user']['username']).' (#'.$params['user']['id'].')';
- }
-
- return $this->template->layout('user/layout', $params);
- }
-
- /**
* List all users
*
* @access public
@@ -50,11 +29,11 @@ class User extends Base
->calculate();
$this->response->html(
- $this->template->layout('user/index', array(
- 'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
+ $this->helper->layout->app('user/index', array(
'title' => t('Users').' ('.$paginator->getTotal().')',
'paginator' => $paginator,
- )));
+ )
+ ));
}
/**
@@ -71,8 +50,7 @@ class User extends Base
}
$this->response->html(
- $this->template->layout('user/profile', array(
- 'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
+ $this->helper->layout->app('user/profile', array(
'title' => $user['name'] ?: $user['username'],
'user' => $user,
)
@@ -88,11 +66,10 @@ class User extends Base
{
$is_remote = $this->request->getIntegerParam('remote') == 1 || (isset($values['is_ldap_user']) && $values['is_ldap_user'] == 1);
- $this->response->html($this->template->layout($is_remote ? 'user/create_remote' : 'user/create_local', array(
+ $this->response->html($this->helper->layout->app($is_remote ? 'user/create_remote' : 'user/create_local', array(
'timezones' => $this->config->getTimezones(true),
'languages' => $this->config->getLanguages(true),
'roles' => $this->role->getApplicationRoles(),
- 'board_selector' => $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()),
'projects' => $this->project->getList(),
'errors' => $errors,
'values' => $values + array('role' => Role::APP_USER),
@@ -142,7 +119,7 @@ class User extends Base
public function show()
{
$user = $this->getUser();
- $this->response->html($this->layout('user/show', array(
+ $this->response->html($this->helper->layout->user('user/show', array(
'user' => $user,
'timezones' => $this->config->getTimezones(true),
'languages' => $this->config->getLanguages(true),
@@ -166,7 +143,7 @@ class User extends Base
->setQuery($this->subtaskTimeTracking->getUserQuery($user['id']))
->calculateOnlyIf($this->request->getStringParam('pagination') === 'subtasks');
- $this->response->html($this->layout('user/timesheet', array(
+ $this->response->html($this->helper->layout->user('user/timesheet', array(
'subtask_paginator' => $subtask_paginator,
'user' => $user,
)));
@@ -180,7 +157,7 @@ class User extends Base
public function passwordReset()
{
$user = $this->getUser();
- $this->response->html($this->layout('user/password_reset', array(
+ $this->response->html($this->helper->layout->user('user/password_reset', array(
'tokens' => $this->passwordReset->getAll($user['id']),
'user' => $user,
)));
@@ -194,7 +171,7 @@ class User extends Base
public function last()
{
$user = $this->getUser();
- $this->response->html($this->layout('user/last', array(
+ $this->response->html($this->helper->layout->user('user/last', array(
'last_logins' => $this->lastLogin->getAll($user['id']),
'user' => $user,
)));
@@ -208,7 +185,7 @@ class User extends Base
public function sessions()
{
$user = $this->getUser();
- $this->response->html($this->layout('user/sessions', array(
+ $this->response->html($this->helper->layout->user('user/sessions', array(
'sessions' => $this->rememberMeSession->getAll($user['id']),
'user' => $user,
)));
@@ -243,7 +220,7 @@ class User extends Base
$this->response->redirect($this->helper->url->to('user', 'notifications', array('user_id' => $user['id'])));
}
- $this->response->html($this->layout('user/notifications', array(
+ $this->response->html($this->helper->layout->user('user/notifications', array(
'projects' => $this->projectUserRole->getProjectsByUser($user['id'], array(ProjectModel::ACTIVE)),
'notifications' => $this->userNotification->readSettings($user['id']),
'types' => $this->userNotificationType->getTypes(),
@@ -268,7 +245,7 @@ class User extends Base
$this->response->redirect($this->helper->url->to('user', 'integrations', array('user_id' => $user['id'])));
}
- $this->response->html($this->layout('user/integrations', array(
+ $this->response->html($this->helper->layout->user('user/integrations', array(
'user' => $user,
'values' => $this->userMetadata->getall($user['id']),
)));
@@ -282,7 +259,7 @@ class User extends Base
public function external()
{
$user = $this->getUser();
- $this->response->html($this->layout('user/external', array(
+ $this->response->html($this->helper->layout->user('user/external', array(
'last_logins' => $this->lastLogin->getAll($user['id']),
'user' => $user,
)));
@@ -310,7 +287,7 @@ class User extends Base
$this->response->redirect($this->helper->url->to('user', 'share', array('user_id' => $user['id'])));
}
- $this->response->html($this->layout('user/share', array(
+ $this->response->html($this->helper->layout->user('user/share', array(
'user' => $user,
'title' => t('Public access'),
)));
@@ -342,7 +319,7 @@ class User extends Base
}
}
- $this->response->html($this->layout('user/password', array(
+ $this->response->html($this->helper->layout->user('user/password', array(
'values' => $values,
'errors' => $errors,
'user' => $user,
@@ -384,7 +361,7 @@ class User extends Base
}
}
- $this->response->html($this->layout('user/edit', array(
+ $this->response->html($this->helper->layout->user('user/edit', array(
'values' => $values,
'errors' => $errors,
'user' => $user,
@@ -422,36 +399,10 @@ class User extends Base
}
}
- $this->response->html($this->layout('user/authentication', array(
+ $this->response->html($this->helper->layout->user('user/authentication', array(
'values' => $values,
'errors' => $errors,
'user' => $user,
)));
}
-
- /**
- * Remove a user
- *
- * @access public
- */
- public function remove()
- {
- $user = $this->getUser();
-
- if ($this->request->getStringParam('confirmation') === 'yes') {
- $this->checkCSRFParam();
-
- if ($this->user->remove($user['id'])) {
- $this->flash->success(t('User removed successfully.'));
- } else {
- $this->flash->failure(t('Unable to remove this user.'));
- }
-
- $this->response->redirect($this->helper->url->to('user', 'index'));
- }
-
- $this->response->html($this->layout('user/remove', array(
- 'user' => $user,
- )));
- }
}
diff --git a/app/Controller/UserImport.php b/app/Controller/UserImport.php
index cbc5aa14..debd69e5 100644
--- a/app/Controller/UserImport.php
+++ b/app/Controller/UserImport.php
@@ -18,7 +18,7 @@ class UserImport extends Base
*/
public function step1(array $values = array(), array $errors = array())
{
- $this->response->html($this->template->layout('user_import/step1', array(
+ $this->response->html($this->helper->layout->app('user_import/step1', array(
'values' => $values,
'errors' => $errors,
'max_size' => ini_get('upload_max_filesize'),
diff --git a/app/Controller/UserStatus.php b/app/Controller/UserStatus.php
new file mode 100644
index 00000000..b8ee5c91
--- /dev/null
+++ b/app/Controller/UserStatus.php
@@ -0,0 +1,111 @@
+<?php
+
+namespace Kanboard\Controller;
+
+/**
+ * User Status Controller
+ *
+ * @package controller
+ * @author Frederic Guillot
+ */
+class UserStatus extends Base
+{
+ /**
+ * Confirm remove a user
+ *
+ * @access public
+ */
+ public function confirmRemove()
+ {
+ $user = $this->getUser();
+
+ $this->response->html($this->helper->layout->user('user_status/remove', array(
+ 'user' => $user,
+ )));
+ }
+
+ /**
+ * Remove a user
+ *
+ * @access public
+ */
+ public function remove()
+ {
+ $user = $this->getUser();
+ $this->checkCSRFParam();
+
+ if ($this->user->remove($user['id'])) {
+ $this->flash->success(t('User removed successfully.'));
+ } else {
+ $this->flash->failure(t('Unable to remove this user.'));
+ }
+
+ $this->response->redirect($this->helper->url->to('user', 'index'));
+ }
+
+ /**
+ * Confirm enable a user
+ *
+ * @access public
+ */
+ public function confirmEnable()
+ {
+ $user = $this->getUser();
+
+ $this->response->html($this->helper->layout->user('user_status/enable', array(
+ 'user' => $user,
+ )));
+ }
+
+ /**
+ * Enable a user
+ *
+ * @access public
+ */
+ public function enable()
+ {
+ $user = $this->getUser();
+ $this->checkCSRFParam();
+
+ if ($this->user->enable($user['id'])) {
+ $this->flash->success(t('User activated successfully.'));
+ } else {
+ $this->flash->failure(t('Unable to enable this user.'));
+ }
+
+ $this->response->redirect($this->helper->url->to('user', 'index'));
+ }
+
+ /**
+ * Confirm disable a user
+ *
+ * @access public
+ */
+ public function confirmDisable()
+ {
+ $user = $this->getUser();
+
+ $this->response->html($this->helper->layout->user('user_status/disable', array(
+ 'user' => $user,
+ )));
+ }
+
+ /**
+ * Disable a user
+ *
+ * @access public
+ */
+ public function disable()
+ {
+ $user = $this->getUser();
+ $this->checkCSRFParam();
+
+ if ($this->user->disable($user['id'])) {
+ $this->flash->success(t('User disabled successfully.'));
+ } else {
+ $this->flash->failure(t('Unable to disable this user.'));
+ }
+
+ $this->response->redirect($this->helper->url->to('user', 'index'));
+ }
+}