diff options
Diffstat (limited to 'app/Controller')
37 files changed, 624 insertions, 294 deletions
diff --git a/app/Controller/BoardAjaxController.php b/app/Controller/BoardAjaxController.php index 484ef67d..ecb76e9c 100644 --- a/app/Controller/BoardAjaxController.php +++ b/app/Controller/BoardAjaxController.php @@ -3,7 +3,6 @@ namespace Kanboard\Controller; use Kanboard\Core\Controller\AccessForbiddenException; -use Kanboard\Formatter\BoardFormatter; use Kanboard\Model\UserMetadataModel; /** @@ -139,7 +138,7 @@ class BoardAjaxController extends BaseController 'board_highlight_period' => $this->configModel->get('board_highlight_period'), 'swimlanes' => $this->taskLexer ->build($this->userSession->getFilters($project_id)) - ->format(BoardFormatter::getInstance($this->container)->withProjectId($project_id)) + ->format($this->boardFormatter->withProjectId($project_id)) )); } } diff --git a/app/Controller/BoardViewController.php b/app/Controller/BoardViewController.php index 10165908..9ef77e54 100644 --- a/app/Controller/BoardViewController.php +++ b/app/Controller/BoardViewController.php @@ -3,7 +3,6 @@ namespace Kanboard\Controller; use Kanboard\Core\Controller\AccessForbiddenException; -use Kanboard\Formatter\BoardFormatter; use Kanboard\Model\TaskModel; /** @@ -35,7 +34,7 @@ class BoardViewController extends BaseController $this->response->html($this->helper->layout->app('board/view_public', array( 'project' => $project, - 'swimlanes' => BoardFormatter::getInstance($this->container) + 'swimlanes' => $this->boardFormatter ->withProjectId($project['id']) ->withQuery($query) ->format() @@ -68,7 +67,7 @@ class BoardViewController extends BaseController 'board_highlight_period' => $this->configModel->get('board_highlight_period'), 'swimlanes' => $this->taskLexer ->build($search) - ->format(BoardFormatter::getInstance($this->container)->withProjectId($project['id'])) + ->format($this->boardFormatter->withProjectId($project['id'])) ))); } } diff --git a/app/Controller/CalendarController.php b/app/Controller/CalendarController.php index e5114f02..5ad253e1 100644 --- a/app/Controller/CalendarController.php +++ b/app/Controller/CalendarController.php @@ -29,7 +29,6 @@ class CalendarController extends BaseController 'project' => $project, 'title' => $project['name'], 'description' => $this->helper->projectHeader->getDescription($project), - 'check_interval' => $this->configModel->get('board_private_refresh_interval'), ))); } diff --git a/app/Controller/ColumnController.php b/app/Controller/ColumnController.php index 8c366c6e..69167976 100644 --- a/app/Controller/ColumnController.php +++ b/app/Controller/ColumnController.php @@ -60,7 +60,7 @@ class ColumnController extends BaseController public function save() { $project = $this->getProject(); - $values = $this->request->getValues(); + $values = $this->request->getValues() + array('hide_in_dashboard' => 0); list($valid, $errors) = $this->columnValidator->validateCreation($values); @@ -70,18 +70,19 @@ class ColumnController extends BaseController $values['title'], $values['task_limit'], $values['description'], - isset($values['hide_in_dashboard']) ? $values['hide_in_dashboard'] : 0 + $values['hide_in_dashboard'] ); if ($result !== false) { $this->flash->success(t('Column created successfully.')); - return $this->response->redirect($this->helper->url->to('ColumnController', 'index', array('project_id' => $project['id'])), true); + $this->response->redirect($this->helper->url->to('ColumnController', 'index', array('project_id' => $project['id'])), true); + return; } else { $errors['title'] = array(t('Another column with the same name exists in the project')); } } - return $this->create($values, $errors); + $this->create($values, $errors); } /** @@ -112,7 +113,7 @@ class ColumnController extends BaseController public function update() { $project = $this->getProject(); - $values = $this->request->getValues(); + $values = $this->request->getValues() + array('hide_in_dashboard' => 0); list($valid, $errors) = $this->columnValidator->validateModification($values); @@ -122,18 +123,19 @@ class ColumnController extends BaseController $values['title'], $values['task_limit'], $values['description'], - isset($values['hide_in_dashboard']) ? $values['hide_in_dashboard'] : 0 + $values['hide_in_dashboard'] ); if ($result) { $this->flash->success(t('Board updated successfully.')); - return $this->response->redirect($this->helper->url->to('ColumnController', 'index', array('project_id' => $project['id']))); + $this->response->redirect($this->helper->url->to('ColumnController', 'index', array('project_id' => $project['id'])), true); + return; } else { $this->flash->failure(t('Unable to update this board.')); } } - return $this->edit($values, $errors); + $this->edit($values, $errors); } /** diff --git a/app/Controller/CommentController.php b/app/Controller/CommentController.php index c61a0602..526bd2bf 100644 --- a/app/Controller/CommentController.php +++ b/app/Controller/CommentController.php @@ -48,6 +48,7 @@ class CommentController extends BaseController */ public function create(array $values = array(), array $errors = array()) { + $project = $this->getProject(); $task = $this->getTask(); if (empty($values)) { @@ -57,10 +58,13 @@ class CommentController extends BaseController ); } - $this->response->html($this->template->render('comment/create', array( + $values['project_id'] = $task['project_id']; + + $this->response->html($this->helper->layout->task('comment/create', array( 'values' => $values, 'errors' => $errors, 'task' => $task, + 'project' => $project, ))); } @@ -103,8 +107,14 @@ class CommentController extends BaseController $task = $this->getTask(); $comment = $this->getComment(); + if (empty($values)) { + $values = $comment; + } + + $values['project_id'] = $task['project_id']; + $this->response->html($this->template->render('comment/edit', array( - 'values' => empty($values) ? $comment : $values, + 'values' => $values, 'errors' => $errors, 'comment' => $comment, 'task' => $task, diff --git a/app/Controller/ConfigController.php b/app/Controller/ConfigController.php index 8285ee13..8572316e 100644 --- a/app/Controller/ConfigController.php +++ b/app/Controller/ConfigController.php @@ -76,7 +76,6 @@ class ConfigController extends BaseController 'languages' => $this->languageModel->getLanguages(), 'timezones' => $this->timezoneModel->getTimezones(), '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').' > '.t('Application settings'), ))); diff --git a/app/Controller/CurrencyController.php b/app/Controller/CurrencyController.php index ad590035..155e229e 100644 --- a/app/Controller/CurrencyController.php +++ b/app/Controller/CurrencyController.php @@ -11,21 +11,33 @@ namespace Kanboard\Controller; class CurrencyController extends BaseController { /** - * Display all currency rates and form + * Display all currency rates + * + * @access public + */ + public function show() + { + $this->response->html($this->helper->layout->config('currency/show', array( + 'application_currency' => $this->configModel->get('application_currency'), + 'rates' => $this->currencyModel->getAll(), + 'currencies' => $this->currencyModel->getCurrencies(), + 'title' => t('Settings') . ' > ' . t('Currency rates'), + ))); + } + + /** + * Add or change currency rate * * @access public * @param array $values * @param array $errors */ - public function index(array $values = array(), array $errors = array()) + public function create(array $values = array(), array $errors = array()) { - $this->response->html($this->helper->layout->config('currency/index', array( - 'config_values' => array('application_currency' => $this->configModel->get('application_currency')), - 'values' => $values, - 'errors' => $errors, - 'rates' => $this->currencyModel->getAll(), + $this->response->html($this->template->render('currency/create', array( + 'values' => $values, + 'errors' => $errors, 'currencies' => $this->currencyModel->getCurrencies(), - 'title' => t('Settings').' > '.t('Currency rates'), ))); } @@ -34,7 +46,7 @@ class CurrencyController extends BaseController * * @access public */ - public function create() + public function save() { $values = $this->request->getValues(); list($valid, $errors) = $this->currencyValidator->validateCreation($values); @@ -42,13 +54,34 @@ class CurrencyController extends BaseController if ($valid) { if ($this->currencyModel->create($values['currency'], $values['rate'])) { $this->flash->success(t('The currency rate have been added successfully.')); - return $this->response->redirect($this->helper->url->to('CurrencyController', 'index')); + $this->response->redirect($this->helper->url->to('CurrencyController', 'show'), true); + return; } else { $this->flash->failure(t('Unable to add this currency rate.')); } } - return $this->index($values, $errors); + $this->create($values, $errors); + } + + /** + * Change reference currency + * + * @access public + * @param array $values + * @param array $errors + */ + public function change(array $values = array(), array $errors = array()) + { + if (empty($values)) { + $values['application_currency'] = $this->configModel->get('application_currency'); + } + + $this->response->html($this->template->render('currency/change', array( + 'values' => $values, + 'errors' => $errors, + 'currencies' => $this->currencyModel->getCurrencies(), + ))); } /** @@ -56,7 +89,7 @@ class CurrencyController extends BaseController * * @access public */ - public function reference() + public function update() { $values = $this->request->getValues(); @@ -66,6 +99,6 @@ class CurrencyController extends BaseController $this->flash->failure(t('Unable to save your settings.')); } - $this->response->redirect($this->helper->url->to('CurrencyController', 'index')); + $this->response->redirect($this->helper->url->to('CurrencyController', 'show'), true); } } diff --git a/app/Controller/CustomFilterController.php b/app/Controller/CustomFilterController.php index e5f674cd..dfe1ffc4 100644 --- a/app/Controller/CustomFilterController.php +++ b/app/Controller/CustomFilterController.php @@ -18,17 +18,13 @@ class CustomFilterController extends BaseController * Display list of filters * * @access public - * @param array $values - * @param array $errors * @throws \Kanboard\Core\Controller\PageNotFoundException */ - public function index(array $values = array(), array $errors = array()) + public function index() { $project = $this->getProject(); $this->response->html($this->helper->layout->project('custom_filter/index', array( - 'values' => $values + array('project_id' => $project['id']), - 'errors' => $errors, 'project' => $project, 'custom_filters' => $this->customFilterModel->getAll($project['id'], $this->userSession->getId()), 'title' => t('Custom filters'), @@ -36,6 +32,24 @@ class CustomFilterController extends BaseController } /** + * Show creation form for custom filters + * + * @access public + * @param array $values + * @param array $errors + */ + public function create(array $values = array(), array $errors = array()) + { + $project = $this->getProject(); + + $this->response->html($this->template->render('custom_filter/create', array( + 'values' => $values + array('project_id' => $project['id']), + 'errors' => $errors, + 'project' => $project, + ))); + } + + /** * Save a new custom filter * * @access public @@ -52,13 +66,14 @@ class CustomFilterController extends BaseController if ($valid) { if ($this->customFilterModel->create($values) !== false) { $this->flash->success(t('Your custom filter have been created successfully.')); - return $this->response->redirect($this->helper->url->to('CustomFilterController', 'index', array('project_id' => $project['id']))); + $this->response->redirect($this->helper->url->to('CustomFilterController', 'index', array('project_id' => $project['id'])), true); + return; } else { $this->flash->failure(t('Unable to create your custom filter.')); } } - return $this->index($values, $errors); + $this->create($values, $errors); } /** @@ -152,13 +167,14 @@ class CustomFilterController extends BaseController if ($valid) { if ($this->customFilterModel->update($values)) { $this->flash->success(t('Your custom filter have been updated successfully.')); - return $this->response->redirect($this->helper->url->to('CustomFilterController', 'index', array('project_id' => $project['id']))); + $this->response->redirect($this->helper->url->to('CustomFilterController', 'index', array('project_id' => $project['id'])), true); + return; } else { $this->flash->failure(t('Unable to update custom filter.')); } } - return $this->edit($values, $errors); + $this->edit($values, $errors); } private function checkPermission(array $project, array $filter) diff --git a/app/Controller/ExportController.php b/app/Controller/ExportController.php index b7ac92aa..19f73a7c 100644 --- a/app/Controller/ExportController.php +++ b/app/Controller/ExportController.php @@ -24,27 +24,29 @@ class ExportController extends BaseController private function common($model, $method, $filename, $action, $page_title) { $project = $this->getProject(); - $from = $this->request->getStringParam('from'); - $to = $this->request->getStringParam('to'); - if ($from && $to) { - $data = $this->$model->$method($project['id'], $from, $to); - $this->response->withFileDownload($filename.'.csv'); - $this->response->csv($data); - } else { + if ($this->request->isPost()) { + $values = $this->request->getValues(); + $from = empty($values['from']) ? '' : $values['from']; + $to = empty($values['to']) ? '' : $values['to']; - $this->response->html($this->helper->layout->project('export/'.$action, array( - 'values' => array( - 'controller' => 'ExportController', - 'action' => $action, + if ($from && $to) { + $data = $this->$model->$method($project['id'], $from, $to); + $this->response->withFileDownload($filename.'.csv'); + $this->response->csv($data); + return; + } + } else { + $this->response->html($this->template->render('export/'.$action, array( + 'values' => array( 'project_id' => $project['id'], - 'from' => $from, - 'to' => $to, + 'from' => '', + 'to' => '', ), - 'errors' => array(), + 'errors' => array(), 'project' => $project, - 'title' => $page_title, - ), 'export/sidebar')); + 'title' => $page_title, + ))); } } diff --git a/app/Controller/ExternalTaskCreationController.php b/app/Controller/ExternalTaskCreationController.php new file mode 100644 index 00000000..a1985adb --- /dev/null +++ b/app/Controller/ExternalTaskCreationController.php @@ -0,0 +1,97 @@ +<?php + +namespace Kanboard\Controller; + +use Kanboard\Core\ExternalTask\ExternalTaskException; + +/** + * External Task Creation Controller + * + * @package Kanboard\Controller + * @author Frederic Guillot + */ +class ExternalTaskCreationController extends BaseController +{ + public function step1(array $values = array(), $errorMessage = '') + { + $project = $this->getProject(); + $providerName = $this->request->getStringParam('provider_name'); + $taskProvider = $this->externalTaskManager->getProvider($providerName); + + if (empty($values)) { + $values = array( + 'swimlane_id' => $this->request->getIntegerParam('swimlane_id'), + 'column_id' => $this->request->getIntegerParam('column_id'), + ); + } + + $this->response->html($this->template->render('external_task_creation/step1', array( + 'project' => $project, + 'values' => $values, + 'error_message' => $errorMessage, + 'provider_name' => $providerName, + 'template' => $taskProvider->getImportFormTemplate(), + ))); + } + + public function step2(array $values = array(), array $errors = array()) + { + $project = $this->getProject(); + $providerName = $this->request->getStringParam('provider_name'); + + try { + $taskProvider = $this->externalTaskManager->getProvider($providerName); + + if (empty($values)) { + $values = $this->request->getValues(); + $externalTask = $taskProvider->fetch($taskProvider->buildTaskUri($values)); + + $values = $externalTask->getFormValues() + array( + 'external_uri' => $externalTask->getUri(), + 'external_provider' => $providerName, + 'project_id' => $project['id'], + 'swimlane_id' => $values['swimlane_id'], + 'column_id' => $values['column_id'], + 'color_id' => $this->colorModel->getDefaultColor(), + 'owner_id' => $this->userSession->getId(), + ); + } else { + $externalTask = $taskProvider->fetch($values['external_uri']); + } + + $this->response->html($this->template->render('external_task_creation/step2', array( + 'project' => $project, + 'external_task' => $externalTask, + 'provider_name' => $providerName, + 'values' => $values, + 'errors' => $errors, + 'template' => $taskProvider->getCreationFormTemplate(), + 'columns_list' => $this->columnModel->getList($project['id']), + 'users_list' => $this->projectUserRoleModel->getAssignableUsersList($project['id'], true, false, true), + 'categories_list' => $this->categoryModel->getList($project['id']), + 'swimlanes_list' => $this->swimlaneModel->getList($project['id'], false, true), + ))); + } catch (ExternalTaskException $e) { + $this->step1($values, $e->getMessage()); + } + } + + public function step3() + { + $project = $this->getProject(); + $values = $this->request->getValues(); + + list($valid, $errors) = $this->taskValidator->validateCreation($values); + + if (! $valid) { + $this->step2($values, $errors); + } else if (! $this->helper->projectRole->canCreateTaskInColumn($project['id'], $values['column_id'])) { + $this->flash->failure(t('You cannot create tasks in this column.')); + $this->response->redirect($this->helper->url->to('BoardViewController', 'show', array('project_id' => $project['id'])), true); + } else { + $taskId = $this->taskCreationModel->create($values); + $this->flash->success(t('Task created successfully.')); + $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('project_id' => $project['id'], 'task_id' => $taskId)), true); + } + } +} diff --git a/app/Controller/ExternalTaskViewController.php b/app/Controller/ExternalTaskViewController.php new file mode 100644 index 00000000..18bc15c1 --- /dev/null +++ b/app/Controller/ExternalTaskViewController.php @@ -0,0 +1,30 @@ +<?php + +namespace Kanboard\Controller; + +use Kanboard\Core\ExternalTask\ExternalTaskException; + +/** + * Class ExternalTaskViewController + * + * @package Kanboard\Controller + * @author Frederic Guillot + */ +class ExternalTaskViewController extends BaseController +{ + public function show() + { + try { + $task = $this->getTask(); + $taskProvider = $this->externalTaskManager->getProvider($task['external_provider']); + $externalTask = $taskProvider->fetch($task['external_uri']); + + $this->response->html($this->template->render($taskProvider->getViewTemplate(), array( + 'task' => $task, + 'external_task' => $externalTask, + ))); + } catch (ExternalTaskException $e) { + $this->response->html('<div class="alert alert-error">'.$e->getMessage().'</div>'); + } + } +} diff --git a/app/Controller/FileViewerController.php b/app/Controller/FileViewerController.php index 518f5b0b..49568912 100644 --- a/app/Controller/FileViewerController.php +++ b/app/Controller/FileViewerController.php @@ -15,11 +15,11 @@ class FileViewerController extends BaseController /** * Get file content from object storage * - * @access private + * @access protected * @param array $file * @return string */ - private function getFileContent(array $file) + protected function getFileContent(array $file) { $content = ''; @@ -35,6 +35,30 @@ class FileViewerController extends BaseController } /** + * Output file with cache + * + * @param array $file + * @param $mimetype + */ + protected function renderFileWithCache(array $file, $mimetype) + { + $etag = md5($file['path']); + + if ($this->request->getHeader('If-None-Match') === '"'.$etag.'"') { + $this->response->status(304); + } else { + try { + $this->response->withContentType($mimetype); + $this->response->withCache(5 * 86400, $etag); + $this->response->send(); + $this->objectStorage->output($file['path']); + } catch (ObjectStorageException $e) { + $this->logger->error($e->getMessage()); + } + } + } + + /** * Show file content in a popover * * @access public @@ -65,21 +89,18 @@ class FileViewerController extends BaseController public function image() { $file = $this->getFile(); - $etag = md5($file['path']); - $this->response->withContentType($this->helper->file->getImageMimeType($file['name'])); - $this->response->withCache(5 * 86400, $etag); - - if ($this->request->getHeader('If-None-Match') === '"'.$etag.'"') { - $this->response->status(304); - } else { + $this->renderFileWithCache($file, $this->helper->file->getImageMimeType($file['name'])); + } - try { - $this->response->send(); - $this->objectStorage->output($file['path']); - } catch (ObjectStorageException $e) { - $this->logger->error($e->getMessage()); - } - } + /** + * Display file in browser + * + * @access public + */ + public function browser() + { + $file = $this->getFile(); + $this->renderFileWithCache($file, $this->helper->file->getBrowserViewType($file['name'])); } /** diff --git a/app/Controller/GroupAjaxController.php b/app/Controller/GroupAjaxController.php index 496e9ef2..308bba9e 100644 --- a/app/Controller/GroupAjaxController.php +++ b/app/Controller/GroupAjaxController.php @@ -2,8 +2,6 @@ namespace Kanboard\Controller; -use Kanboard\Formatter\GroupAutoCompleteFormatter; - /** * Group Ajax Controller * @@ -20,7 +18,7 @@ class GroupAjaxController extends BaseController public function autocomplete() { $search = $this->request->getStringParam('term'); - $formatter = new GroupAutoCompleteFormatter($this->groupManager->find($search)); - $this->response->json($formatter->format()); + $groups = $this->groupManager->find($search); + $this->response->json($this->groupAutoCompleteFormatter->withGroups($groups)->format()); } } diff --git a/app/Controller/ICalendarController.php b/app/Controller/ICalendarController.php index e354c6f1..4fe8b78a 100644 --- a/app/Controller/ICalendarController.php +++ b/app/Controller/ICalendarController.php @@ -7,7 +7,6 @@ use Kanboard\Core\Filter\QueryBuilder; use Kanboard\Filter\TaskAssigneeFilter; use Kanboard\Filter\TaskProjectFilter; use Kanboard\Filter\TaskStatusFilter; -use Kanboard\Formatter\TaskICalFormatter; use Kanboard\Model\TaskModel; use Eluceo\iCal\Component\Calendar as iCalendar; @@ -94,8 +93,6 @@ class ICalendarController extends BaseController $end = $this->request->getStringParam('end', strtotime('+6 months')); $this->helper->ical->addTaskDateDueEvents($queryBuilder, $calendar, $start, $end); - - $formatter = new TaskICalFormatter($this->container); - $this->response->ical($formatter->setCalendar($calendar)->format()); + $this->response->ical($this->taskICalFormatter->setCalendar($calendar)->format()); } } diff --git a/app/Controller/LinkController.php b/app/Controller/LinkController.php index 477b25a4..2ad8a2b5 100644 --- a/app/Controller/LinkController.php +++ b/app/Controller/LinkController.php @@ -16,11 +16,11 @@ class LinkController extends BaseController /** * Get the current link * - * @access private + * @access protected * @return array * @throws PageNotFoundException */ - private function getLink() + protected function getLink() { $link = $this->linkModel->getById($this->request->getIntegerParam('link_id')); @@ -32,19 +32,31 @@ class LinkController extends BaseController } /** - * List of links + * List of labels + * + * @access public + */ + public function show() + { + $this->response->html($this->helper->layout->config('link/show', array( + 'links' => $this->linkModel->getMergedList(), + 'title' => t('Settings').' > '.t('Link labels'), + ))); + } + + /** + * Add new link label * * @access public * @param array $values * @param array $errors */ - public function index(array $values = array(), array $errors = array()) + public function create(array $values = array(), array $errors = array()) { - $this->response->html($this->helper->layout->config('link/index', array( - 'links' => $this->linkModel->getMergedList(), + $this->response->html($this->template->render('link/create', array( + 'links' => $this->linkModel->getMergedList(), 'values' => $values, 'errors' => $errors, - 'title' => t('Settings').' > '.t('Task\'s links'), ))); } @@ -61,21 +73,22 @@ class LinkController extends BaseController if ($valid) { if ($this->linkModel->create($values['label'], $values['opposite_label']) !== false) { $this->flash->success(t('Link added successfully.')); - return $this->response->redirect($this->helper->url->to('LinkController', 'index')); + $this->response->redirect($this->helper->url->to('LinkController', 'show'), true); + return; } else { $this->flash->failure(t('Unable to create your link.')); } } - return $this->index($values, $errors); + $this->create($values, $errors); } /** * Edit form * * @access public - * @param array $values - * @param array $errors + * @param array $values + * @param array $errors * @throws PageNotFoundException */ public function edit(array $values = array(), array $errors = array()) @@ -83,12 +96,11 @@ class LinkController extends BaseController $link = $this->getLink(); $link['label'] = t($link['label']); - $this->response->html($this->helper->layout->config('link/edit', array( + $this->response->html($this->template->render('link/edit', array( 'values' => $values ?: $link, 'errors' => $errors, 'labels' => $this->linkModel->getList($link['id']), - 'link' => $link, - 'title' => t('Link modification') + 'link' => $link, ))); } @@ -105,13 +117,14 @@ class LinkController extends BaseController if ($valid) { if ($this->linkModel->update($values)) { $this->flash->success(t('Link updated successfully.')); - return $this->response->redirect($this->helper->url->to('LinkController', 'index')); + $this->response->redirect($this->helper->url->to('LinkController', 'show'), true); + return; } else { $this->flash->failure(t('Unable to update your link.')); } } - return $this->edit($values, $errors); + $this->edit($values, $errors); } /** @@ -123,9 +136,8 @@ class LinkController extends BaseController { $link = $this->getLink(); - $this->response->html($this->helper->layout->config('link/remove', array( + $this->response->html($this->template->render('link/remove', array( 'link' => $link, - 'title' => t('Remove a link') ))); } @@ -145,6 +157,6 @@ class LinkController extends BaseController $this->flash->failure(t('Unable to remove this link.')); } - $this->response->redirect($this->helper->url->to('LinkController', 'index')); + $this->response->redirect($this->helper->url->to('LinkController', 'show'), true); } } diff --git a/app/Controller/PasswordResetController.php b/app/Controller/PasswordResetController.php index a1780ed9..cc0755ca 100644 --- a/app/Controller/PasswordResetController.php +++ b/app/Controller/PasswordResetController.php @@ -104,12 +104,12 @@ class PasswordResetController extends BaseController * * @param string $username */ - private function sendEmail($username) + protected function sendEmail($username) { $token = $this->passwordResetModel->create($username); if ($token !== false) { - $user = $this->userModel->getByUsername($username); + $user = $this->userCacheDecorator->getByUsername($username); $this->emailClient->send( $user['email'], @@ -117,13 +117,17 @@ class PasswordResetController extends BaseController t('Password Reset for Kanboard'), $this->template->render('password_reset/email', array('token' => $token)) ); + + $this->flash->success(t('A link to reset your password has been sent by email.')); + } else { + $this->flash->failure(t('Unfortunately, we are unable to reset your password. Did you entered a valid username? Do you have an email address in your profile?')); } } /** * Check feature availability */ - private function checkActivation() + protected function checkActivation() { if ($this->configModel->get('password_reset', 0) == 0) { throw AccessForbiddenException::getInstance()->withoutLayout(); diff --git a/app/Controller/PluginController.php b/app/Controller/PluginController.php index 7b9d64d9..dbb739d6 100644 --- a/app/Controller/PluginController.php +++ b/app/Controller/PluginController.php @@ -23,6 +23,7 @@ class PluginController extends BaseController { $this->response->html($this->helper->layout->plugin('plugin/show', array( 'plugins' => $this->pluginLoader->getPlugins(), + 'incompatible_plugins' => $this->pluginLoader->getIncompatiblePlugins(), 'title' => t('Installed Plugins'), 'is_configured' => Installer::isConfigured(), ))); diff --git a/app/Controller/ProjectEditController.php b/app/Controller/ProjectEditController.php index 228d681c..ae39fdf3 100644 --- a/app/Controller/ProjectEditController.php +++ b/app/Controller/ProjectEditController.php @@ -11,51 +11,23 @@ namespace Kanboard\Controller; class ProjectEditController extends BaseController { /** - * General edition (most common operations) + * Edit project * * @access public * @param array $values * @param array $errors */ - public function edit(array $values = array(), array $errors = array()) + public function show(array $values = array(), array $errors = array()) { - $this->renderView('project_edit/general', $values, $errors); - } - - /** - * Change start and end dates - * - * @access public - * @param array $values - * @param array $errors - */ - public function dates(array $values = array(), array $errors = array()) - { - $this->renderView('project_edit/dates', $values, $errors); - } - - /** - * Change project description - * - * @access public - * @param array $values - * @param array $errors - */ - public function description(array $values = array(), array $errors = array()) - { - $this->renderView('project_edit/description', $values, $errors); - } + $project = $this->getProject(); - /** - * Change task priority - * - * @access public - * @param array $values - * @param array $errors - */ - public function priority(array $values = array(), array $errors = array()) - { - $this->renderView('project_edit/task_priority', $values, $errors); + $this->response->html($this->helper->layout->project('project_edit/show', array( + 'owners' => $this->projectUserRoleModel->getAssignableUsersList($project['id'], true), + 'values' => empty($values) ? $project : $values, + 'errors' => $errors, + 'project' => $project, + 'title' => t('Edit project') + ))); } /** @@ -67,67 +39,42 @@ class ProjectEditController extends BaseController { $project = $this->getProject(); $values = $this->request->getValues(); - $redirect = $this->request->getStringParam('redirect', 'edit'); - $values = $this->prepareValues($redirect, $project, $values); + $values = $this->prepareValues($project, $values); list($valid, $errors) = $this->projectValidator->validateModification($values); if ($valid) { if ($this->projectModel->update($values)) { $this->flash->success(t('Project updated successfully.')); - return $this->response->redirect($this->helper->url->to('ProjectEditController', $redirect, array('project_id' => $project['id'])), true); + return $this->response->redirect($this->helper->url->to('ProjectEditController', 'show', array('project_id' => $project['id'])), true); } else { $this->flash->failure(t('Unable to update this project.')); } } - return $this->$redirect($values, $errors); + return $this->show($values, $errors); } /** * Prepare form values * * @access private - * @param string $redirect * @param array $project * @param array $values * @return array */ - private function prepareValues($redirect, array $project, array $values) + private function prepareValues(array $project, array $values) { - if ($redirect === 'edit') { - if (isset($values['is_private'])) { - if (! $this->helper->user->hasProjectAccess('ProjectCreationController', 'create', $project['id'])) { - unset($values['is_private']); - } - } elseif ($project['is_private'] == 1 && ! isset($values['is_private'])) { - if ($this->helper->user->hasProjectAccess('ProjectCreationController', 'create', $project['id'])) { - $values += array('is_private' => 0); - } + if (isset($values['is_private'])) { + if (! $this->helper->user->hasProjectAccess('ProjectCreationController', 'create', $project['id'])) { + unset($values['is_private']); + } + } elseif ($project['is_private'] == 1 && ! isset($values['is_private'])) { + if ($this->helper->user->hasProjectAccess('ProjectCreationController', 'create', $project['id'])) { + $values += array('is_private' => 0); } } return $values; } - - /** - * Common method to render different views - * - * @access private - * @param string $template - * @param array $values - * @param array $errors - */ - private function renderView($template, array $values, array $errors) - { - $project = $this->getProject(); - - $this->response->html($this->helper->layout->project($template, array( - 'owners' => $this->projectUserRoleModel->getAssignableUsersList($project['id'], true), - 'values' => empty($values) ? $project : $values, - 'errors' => $errors, - 'project' => $project, - 'title' => t('Edit project') - ))); - } } diff --git a/app/Controller/ProjectFileController.php b/app/Controller/ProjectFileController.php index cbe48679..9c38f684 100644 --- a/app/Controller/ProjectFileController.php +++ b/app/Controller/ProjectFileController.php @@ -21,7 +21,7 @@ class ProjectFileController extends BaseController $this->response->html($this->template->render('project_file/create', array( 'project' => $project, - 'max_size' => $this->helper->text->phpToBytes(ini_get('upload_max_filesize')), + 'max_size' => $this->helper->text->phpToBytes(get_upload_max_size()), ))); } diff --git a/app/Controller/ProjectGanttController.php b/app/Controller/ProjectGanttController.php index a70d9eee..8239005e 100644 --- a/app/Controller/ProjectGanttController.php +++ b/app/Controller/ProjectGanttController.php @@ -5,7 +5,6 @@ namespace Kanboard\Controller; use Kanboard\Filter\ProjectIdsFilter; use Kanboard\Filter\ProjectStatusFilter; use Kanboard\Filter\ProjectTypeFilter; -use Kanboard\Formatter\ProjectGanttFormatter; use Kanboard\Model\ProjectModel; /** @@ -30,7 +29,7 @@ class ProjectGanttController extends BaseController $filter->getQuery()->asc(ProjectModel::TABLE.'.start_date'); $this->response->html($this->helper->layout->app('project_gantt/show', array( - 'projects' => $filter->format(new ProjectGanttFormatter($this->container)), + 'projects' => $filter->format($this->projectGanttFormatter), 'title' => t('Gantt chart for all projects'), ))); } diff --git a/app/Controller/ProjectPermissionController.php b/app/Controller/ProjectPermissionController.php index 1aa59c6d..56777b25 100644 --- a/app/Controller/ProjectPermissionController.php +++ b/app/Controller/ProjectPermissionController.php @@ -132,7 +132,7 @@ class ProjectPermissionController extends BaseController if (! empty($project) && ! empty($values) && $this->projectUserRoleModel->changeUserRole($project['id'], $values['id'], $values['role'])) { $this->response->json(array('status' => 'ok')); } else { - $this->response->json(array('status' => 'error')); + $this->response->json(array('status' => 'error'), 500); } } diff --git a/app/Controller/TaskAjaxController.php b/app/Controller/TaskAjaxController.php index f9feff15..6d0b3fc2 100644 --- a/app/Controller/TaskAjaxController.php +++ b/app/Controller/TaskAjaxController.php @@ -5,8 +5,10 @@ namespace Kanboard\Controller; use Kanboard\Filter\TaskIdExclusionFilter; use Kanboard\Filter\TaskIdFilter; use Kanboard\Filter\TaskProjectsFilter; +use Kanboard\Filter\TaskStartsWithIdFilter; +use Kanboard\Filter\TaskStatusFilter; use Kanboard\Filter\TaskTitleFilter; -use Kanboard\Formatter\TaskAutoCompleteFormatter; +use Kanboard\Model\TaskModel; /** * Task Ajax Controller @@ -19,7 +21,6 @@ class TaskAjaxController extends BaseController /** * Task auto-completion (Ajax) * - * @access public */ public function autocomplete() { @@ -43,7 +44,27 @@ class TaskAjaxController extends BaseController $filter->withFilter(new TaskTitleFilter($search)); } - $this->response->json($filter->format(new TaskAutoCompleteFormatter($this->container))); + $this->response->json($filter->format($this->taskAutoCompleteFormatter)); + } + } + + /** + * Task ID suggest menu + */ + public function suggest() + { + $taskId = $this->request->getIntegerParam('search'); + $projectIds = $this->projectPermissionModel->getActiveProjectIds($this->userSession->getId()); + + if (empty($projectIds)) { + $this->response->json(array()); + } else { + $filter = $this->taskQuery + ->withFilter(new TaskProjectsFilter($projectIds)) + ->withFilter(new TaskStatusFilter(TaskModel::STATUS_OPEN)) + ->withFilter(new TaskStartsWithIdFilter($taskId)); + + $this->response->json($filter->format($this->taskSuggestMenuFormatter)); } } } diff --git a/app/Controller/TaskBulkController.php b/app/Controller/TaskBulkController.php index 4e06f636..4345a68f 100644 --- a/app/Controller/TaskBulkController.php +++ b/app/Controller/TaskBulkController.php @@ -32,7 +32,7 @@ class TaskBulkController extends BaseController 'project' => $project, 'values' => $values, 'errors' => $errors, - 'users_list' => $this->projectUserRoleModel->getAssignableUsersList($project['id'], true, false, true), + 'users_list' => $this->projectUserRoleModel->getAssignableUsersList($project['id'], true, false, $project['is_private'] == 1), 'colors_list' => $this->colorModel->getList(), 'categories_list' => $this->categoryModel->getList($project['id']), ))); diff --git a/app/Controller/TaskCreationController.php b/app/Controller/TaskCreationController.php index ec53e211..faf2d250 100644 --- a/app/Controller/TaskCreationController.php +++ b/app/Controller/TaskCreationController.php @@ -23,11 +23,8 @@ class TaskCreationController extends BaseController public function show(array $values = array(), array $errors = array()) { $project = $this->getProject(); - $swimlanes_list = $this->swimlaneModel->getList($project['id'], false, true); - - if (empty($values)) { - $values = $this->prepareValues($swimlanes_list); - } + $swimlanesList = $this->swimlaneModel->getList($project['id'], false, true); + $values += $this->prepareValues($project['is_private'], $swimlanesList); $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)); @@ -37,9 +34,9 @@ class TaskCreationController extends BaseController 'errors' => $errors, 'values' => $values + array('project_id' => $project['id']), 'columns_list' => $this->columnModel->getList($project['id']), - 'users_list' => $this->projectUserRoleModel->getAssignableUsersList($project['id'], true, false, true), + 'users_list' => $this->projectUserRoleModel->getAssignableUsersList($project['id'], true, false, $project['is_private'] == 1), 'categories_list' => $this->categoryModel->getList($project['id']), - 'swimlanes_list' => $swimlanes_list, + 'swimlanes_list' => $swimlanesList, ))); } @@ -116,18 +113,22 @@ class TaskCreationController extends BaseController * Prepare form values * * @access protected - * @param array $swimlanes_list + * @param bool $isPrivateProject + * @param array $swimlanesList * @return array */ - protected function prepareValues(array $swimlanes_list) + protected function prepareValues($isPrivateProject, array $swimlanesList) { $values = array( - 'swimlane_id' => $this->request->getIntegerParam('swimlane_id', key($swimlanes_list)), + 'swimlane_id' => $this->request->getIntegerParam('swimlane_id', key($swimlanesList)), 'column_id' => $this->request->getIntegerParam('column_id'), 'color_id' => $this->colorModel->getDefaultColor(), - 'owner_id' => $this->userSession->getId(), ); + if ($isPrivateProject) { + $values['owner_id'] = $this->userSession->getId(); + } + return $values; } diff --git a/app/Controller/TaskExternalLinkController.php b/app/Controller/TaskExternalLinkController.php index 9c04eb00..df23f87b 100644 --- a/app/Controller/TaskExternalLinkController.php +++ b/app/Controller/TaskExternalLinkController.php @@ -76,12 +76,23 @@ class TaskExternalLinkController extends BaseController $values = $this->request->getValues(); list($valid, $errors) = $this->externalLinkValidator->validateCreation($values); - if ($valid && $this->taskExternalLinkModel->create($values) !== false) { - $this->flash->success(t('Link added successfully.')); - return $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true); + if ($valid) { + if ($this->taskExternalLinkModel->create($values) !== false) { + $this->flash->success(t('Link added successfully.')); + } else { + $this->flash->success(t('Unable to create your link.')); + } + + $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true); + } else { + $provider = $this->externalLinkManager->getProvider($values['link_type']); + $this->response->html($this->template->render('task_external_link/create', array( + 'values' => $values, + 'errors' => $errors, + 'dependencies' => $provider->getDependencies(), + 'task' => $task, + ))); } - - return $this->edit($values, $errors); } /** diff --git a/app/Controller/TaskFileController.php b/app/Controller/TaskFileController.php index 77c0c026..8a0971e4 100644 --- a/app/Controller/TaskFileController.php +++ b/app/Controller/TaskFileController.php @@ -40,7 +40,7 @@ class TaskFileController extends BaseController $this->response->html($this->template->render('task_file/create', array( 'task' => $task, - 'max_size' => $this->helper->text->phpToBytes(ini_get('upload_max_filesize')), + 'max_size' => $this->helper->text->phpToBytes(get_upload_max_size()), ))); } diff --git a/app/Controller/TaskGanttController.php b/app/Controller/TaskGanttController.php index 868368e1..b03b9d00 100644 --- a/app/Controller/TaskGanttController.php +++ b/app/Controller/TaskGanttController.php @@ -3,7 +3,6 @@ namespace Kanboard\Controller; use Kanboard\Filter\TaskProjectFilter; -use Kanboard\Formatter\TaskGanttFormatter; use Kanboard\Model\TaskModel; /** @@ -35,7 +34,7 @@ class TaskGanttController extends BaseController 'title' => $project['name'], 'description' => $this->helper->projectHeader->getDescription($project), 'sorting' => $sorting, - 'tasks' => $filter->format(new TaskGanttFormatter($this->container)), + 'tasks' => $filter->format($this->taskGanttFormatter), ))); } diff --git a/app/Controller/TaskGanttCreationController.php b/app/Controller/TaskGanttCreationController.php deleted file mode 100644 index c5046f60..00000000 --- a/app/Controller/TaskGanttCreationController.php +++ /dev/null @@ -1,64 +0,0 @@ -<?php - -namespace Kanboard\Controller; - -/** - * Class TaskGanttCreationController - * - * @package Kanboard\Controller - * @author Frederic Guillot - */ -class TaskGanttCreationController extends BaseController -{ - /** - * Simplified form to create a new task - * - * @access public - * @param array $values - * @param array $errors - * @throws \Kanboard\Core\Controller\PageNotFoundException - */ - public function show(array $values = array(), array $errors = array()) - { - $project = $this->getProject(); - - $values = $values + array( - 'project_id' => $project['id'], - 'column_id' => $this->columnModel->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('task_gantt_creation/show', array( - 'project' => $project, - 'errors' => $errors, - 'values' => $values, - 'users_list' => $this->projectUserRoleModel->getAssignableUsersList($project['id'], true, false, true), - 'categories_list' => $this->categoryModel->getList($project['id']), - 'swimlanes_list' => $this->swimlaneModel->getList($project['id'], false, true), - ))); - } - - /** - * Validate and save a new task - * - * @access public - */ - public function save() - { - $project = $this->getProject(); - $values = $this->request->getValues(); - - list($valid, $errors) = $this->taskValidator->validateCreation($values); - - if ($valid && $this->taskCreationModel->create($values)) { - $this->flash->success(t('Task created successfully.')); - $this->response->redirect($this->helper->url->to('TaskGanttController', 'show', array('project_id' => $project['id']))); - } else { - $this->flash->failure(t('Unable to create your task.')); - $this->show($values, $errors); - } - } -} diff --git a/app/Controller/TaskImportController.php b/app/Controller/TaskImportController.php index aff2d390..2e323979 100644 --- a/app/Controller/TaskImportController.php +++ b/app/Controller/TaskImportController.php @@ -23,15 +23,14 @@ class TaskImportController extends BaseController { $project = $this->getProject(); - $this->response->html($this->helper->layout->project('task_import/show', array( + $this->response->html($this->template->render('task_import/show', array( 'project' => $project, 'values' => $values, 'errors' => $errors, - 'max_size' => ini_get('upload_max_filesize'), + 'max_size' => get_upload_max_size(), 'delimiters' => Csv::getDelimiters(), 'enclosures' => Csv::getEnclosures(), - 'title' => t('Import tasks from CSV file'), - ), 'task_import/sidebar')); + ))); } /** @@ -58,7 +57,7 @@ class TaskImportController extends BaseController $this->flash->failure(t('Nothing have been imported!')); } - $this->response->redirect($this->helper->url->to('TaskImportController', 'show', array('project_id' => $project['id']))); + $this->response->redirect($this->helper->url->to('TaskImportController', 'show', array('project_id' => $project['id'])), true); } } diff --git a/app/Controller/TaskModificationController.php b/app/Controller/TaskModificationController.php index f628e923..520bf70e 100644 --- a/app/Controller/TaskModificationController.php +++ b/app/Controller/TaskModificationController.php @@ -2,6 +2,10 @@ namespace Kanboard\Controller; +use Kanboard\Core\Controller\AccessForbiddenException; +use Kanboard\Core\ExternalTask\AccessForbiddenException as ExternalTaskAccessForbiddenException; +use Kanboard\Core\ExternalTask\ExternalTaskException; + /** * Task Modification controller * @@ -43,7 +47,7 @@ class TaskModificationController extends BaseController $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->response->html($this->template->render('task_modification/show', array( + $params = array( 'project' => $project, 'values' => $values, 'errors' => $errors, @@ -51,7 +55,29 @@ class TaskModificationController extends BaseController 'tags' => $this->taskTagModel->getList($task['id']), 'users_list' => $this->projectUserRoleModel->getAssignableUsersList($task['project_id']), 'categories_list' => $this->categoryModel->getList($task['project_id']), - ))); + ); + + $this->renderTemplate($task, $params); + } + + protected function renderTemplate(array &$task, array &$params) + { + if (empty($task['external_uri'])) { + $this->response->html($this->template->render('task_modification/show', $params)); + } else { + + try { + $taskProvider = $this->externalTaskManager->getProvider($task['external_provider']); + $params['template'] = $taskProvider->getModificationFormTemplate(); + $params['external_task'] = $taskProvider->fetch($task['external_uri']); + } catch (ExternalTaskAccessForbiddenException $e) { + throw new AccessForbiddenException($e->getMessage()); + } catch (ExternalTaskException $e) { + $params['error_message'] = $e->getMessage(); + } + + $this->response->html($this->template->render('external_task_modification/show', $params)); + } } /** @@ -66,7 +92,7 @@ class TaskModificationController extends BaseController list($valid, $errors) = $this->taskValidator->validateModification($values); - if ($valid && $this->taskModificationModel->update($values)) { + if ($valid && $this->updateTask($task, $values, $errors)) { $this->flash->success(t('Task updated successfully.')); $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('project_id' => $task['project_id'], 'task_id' => $task['id'])), true); } else { @@ -74,4 +100,23 @@ class TaskModificationController extends BaseController $this->edit($values, $errors); } } + + protected function updateTask(array &$task, array &$values, array &$errors) + { + $result = $this->taskModificationModel->update($values); + + if ($result && ! empty($task['external_uri'])) { + try { + $taskProvider = $this->externalTaskManager->getProvider($task['external_provider']); + $result = $taskProvider->save($task['external_uri'], $values, $errors); + } catch (ExternalTaskAccessForbiddenException $e) { + throw new AccessForbiddenException($e->getMessage()); + } catch (ExternalTaskException $e) { + $this->logger->error($e->getMessage()); + $result = false; + } + } + + return $result; + } } diff --git a/app/Controller/TaskMovePositionController.php b/app/Controller/TaskMovePositionController.php index a655ca0a..39687b79 100644 --- a/app/Controller/TaskMovePositionController.php +++ b/app/Controller/TaskMovePositionController.php @@ -3,7 +3,6 @@ namespace Kanboard\Controller; use Kanboard\Core\Controller\AccessForbiddenException; -use Kanboard\Formatter\BoardFormatter; use Kanboard\Model\TaskModel; /** @@ -20,7 +19,7 @@ class TaskMovePositionController extends BaseController $this->response->html($this->template->render('task_move_position/show', array( 'task' => $task, - 'board' => BoardFormatter::getInstance($this->container) + 'board' => $this->boardFormatter ->withProjectId($task['project_id']) ->withQuery($this->taskFinderModel->getExtendedQuery() ->eq(TaskModel::TABLE.'.is_active', TaskModel::STATUS_OPEN) @@ -36,10 +35,10 @@ class TaskMovePositionController extends BaseController $values = $this->request->getJson(); if (! $this->helper->projectRole->canMoveTask($task['project_id'], $task['column_id'], $values['column_id'])) { - throw new AccessForbiddenException(e("You don't have the permission to move this task")); + throw new AccessForbiddenException(e('You are not allowed to move this task.')); } - $result = $this->taskPositionModel->movePosition( + $this->taskPositionModel->movePosition( $task['project_id'], $task['id'], $values['column_id'], @@ -47,6 +46,6 @@ class TaskMovePositionController extends BaseController $values['swimlane_id'] ); - $this->response->json(array('result' => $result)); + $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']))); } } diff --git a/app/Controller/TaskStatusController.php b/app/Controller/TaskStatusController.php index 82b4f9c4..56d38400 100644 --- a/app/Controller/TaskStatusController.php +++ b/app/Controller/TaskStatusController.php @@ -52,11 +52,11 @@ class TaskStatusController extends BaseController $this->flash->failure($failure_message); } - return $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true); + $this->response->redirect($this->helper->url->to('TaskViewController', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])), true); + } else { + $this->response->html($this->template->render($template, array( + 'task' => $task, + ))); } - - return $this->response->html($this->template->render($template, array( - 'task' => $task, - ))); } } diff --git a/app/Controller/UserAjaxController.php b/app/Controller/UserAjaxController.php index ed180471..17567a00 100644 --- a/app/Controller/UserAjaxController.php +++ b/app/Controller/UserAjaxController.php @@ -3,7 +3,6 @@ namespace Kanboard\Controller; use Kanboard\Filter\UserNameFilter; -use Kanboard\Formatter\UserAutoCompleteFormatter; use Kanboard\Model\UserModel; /** @@ -24,7 +23,7 @@ class UserAjaxController extends BaseController $search = $this->request->getStringParam('term'); $filter = $this->userQuery->withFilter(new UserNameFilter($search)); $filter->getQuery()->asc(UserModel::TABLE.'.name')->asc(UserModel::TABLE.'.username'); - $this->response->json($filter->format(new UserAutoCompleteFormatter($this->container))); + $this->response->json($filter->format($this->userAutoCompleteFormatter)); } /** @@ -35,9 +34,10 @@ class UserAjaxController extends BaseController public function mention() { $project_id = $this->request->getStringParam('project_id'); - $query = $this->request->getStringParam('q'); + $query = $this->request->getStringParam('search'); $users = $this->projectPermissionModel->findUsernames($project_id, $query); - $this->response->json($users); + + $this->response->json($this->userMentionFormatter->withUsers($users)->format()); } /** diff --git a/app/Controller/UserApiAccessController.php b/app/Controller/UserApiAccessController.php new file mode 100644 index 00000000..e03514d5 --- /dev/null +++ b/app/Controller/UserApiAccessController.php @@ -0,0 +1,50 @@ +<?php + +namespace Kanboard\Controller; + +use Kanboard\Core\Security\Token; + +/** + * Class UserApiAccessController + * + * @package Kanboard\Controller + * @author Frederic Guillot + */ +class UserApiAccessController extends BaseController +{ + public function show() + { + $user = $this->getUser(); + + return $this->response->html($this->helper->layout->user('user_api_access/show', array( + 'user' => $user, + 'title' => t('API User Access'), + ))); + } + + public function generate() + { + $user = $this->getUser(); + $this->checkCSRFParam(); + + $this->userModel->update(array( + 'id' => $user['id'], + 'api_access_token' => Token::getToken(), + )); + + $this->response->redirect($this->helper->url->to('UserApiAccessController', 'show', array('user_id' => $user['id']))); + } + + public function remove() + { + $user = $this->getUser(); + $this->checkCSRFParam(); + + $this->userModel->update(array( + 'id' => $user['id'], + 'api_access_token' => null, + )); + + $this->response->redirect($this->helper->url->to('UserApiAccessController', 'show', array('user_id' => $user['id']))); + } +}
\ No newline at end of file diff --git a/app/Controller/UserCreationController.php b/app/Controller/UserCreationController.php index 9c873f85..27f1687b 100644 --- a/app/Controller/UserCreationController.php +++ b/app/Controller/UserCreationController.php @@ -22,10 +22,7 @@ class UserCreationController extends BaseController */ public function show(array $values = array(), array $errors = array()) { - $isRemote = $this->request->getIntegerParam('remote') == 1 || (isset($values['is_ldap_user']) && $values['is_ldap_user'] == 1); - $template = $isRemote ? 'user_creation/remote' : 'user_creation/local'; - - $this->response->html($this->template->render($template, array( + $this->response->html($this->template->render('user_creation/show', array( 'timezones' => $this->timezoneModel->getTimezones(true), 'languages' => $this->languageModel->getLanguages(true), 'roles' => $this->role->getApplicationRoles(), @@ -57,7 +54,7 @@ class UserCreationController extends BaseController * * @param array $values */ - private function createUser(array $values) + protected function createUser(array $values) { $project_id = empty($values['project_id']) ? 0 : $values['project_id']; unset($values['project_id']); diff --git a/app/Controller/UserImportController.php b/app/Controller/UserImportController.php index fec9a31d..6a9d5992 100644 --- a/app/Controller/UserImportController.php +++ b/app/Controller/UserImportController.php @@ -23,7 +23,7 @@ class UserImportController extends BaseController $this->response->html($this->template->render('user_import/show', array( 'values' => $values, 'errors' => $errors, - 'max_size' => ini_get('upload_max_filesize'), + 'max_size' => get_upload_max_size(), 'delimiters' => Csv::getDelimiters(), 'enclosures' => Csv::getEnclosures(), ))); diff --git a/app/Controller/UserInviteController.php b/app/Controller/UserInviteController.php new file mode 100644 index 00000000..8c77940c --- /dev/null +++ b/app/Controller/UserInviteController.php @@ -0,0 +1,107 @@ +<?php + +namespace Kanboard\Controller; + +use Kanboard\Core\Controller\PageNotFoundException; +use Kanboard\Core\Security\Role; +use Kanboard\Notification\MailNotification; + +/** + * Class UserInviteController + * + * @package Kanboard\Controller + * @author Frederic Guillot + */ +class UserInviteController extends BaseController +{ + public function show(array $values = array(), array $errors = array()) + { + $this->response->html($this->template->render('user_invite/show', array( + 'projects' => $this->projectModel->getList(), + 'errors' => $errors, + 'values' => $values, + ))); + } + + public function save() + { + $values = $this->request->getValues(); + + if (! empty($values['emails']) && isset($values['project_id'])) { + $emails = explode("\r\n", trim($values['emails'])); + $nb = $this->inviteModel->createInvites($emails, $values['project_id']); + $this->flash->success($nb > 1 ? t('%d invitations were sent.', $nb) : t('%d invitation was sent.', $nb)); + } + + $this->response->redirect($this->helper->url->to('UserListController', 'show')); + } + + public function signup(array $values = array(), array $errors = array()) + { + $invite = $this->getInvite(); + + $this->response->html($this->helper->layout->app('user_invite/signup', array( + 'no_layout' => true, + 'not_editable' => true, + 'token' => $invite['token'], + 'errors' => $errors, + 'values' => $values + array('email' => $invite['email']), + 'timezones' => $this->timezoneModel->getTimezones(true), + 'languages' => $this->languageModel->getLanguages(true), + ))); + } + + public function register() + { + $invite = $this->getInvite(); + + $values = $this->request->getValues(); + list($valid, $errors) = $this->userValidator->validateCreation($values); + + if ($valid) { + $this->createUser($invite, $values); + } else { + $this->signup($values, $errors); + } + } + + protected function getInvite() + { + $token = $this->request->getStringParam('token'); + + if (empty($token)) { + throw PageNotFoundException::getInstance()->withoutLayout(); + } + + $invite = $this->inviteModel->getByToken($token); + + if (empty($invite)) { + throw PageNotFoundException::getInstance()->withoutLayout(); + } + + return $invite; + } + + protected function createUser(array $invite, array $values) + { + $user_id = $this->userModel->create($values); + + if ($user_id !== false) { + if ($invite['project_id'] != 0) { + $this->projectUserRoleModel->addUser($invite['project_id'], $user_id, Role::PROJECT_MEMBER); + } + + if (! empty($values['notifications_enabled'])) { + $this->userNotificationTypeModel->saveSelectedTypes($user_id, array(MailNotification::TYPE)); + } + + $this->inviteModel->remove($invite['email']); + + $this->flash->success(t('User created successfully.')); + $this->response->redirect($this->helper->url->to('AuthController', 'login')); + } else { + $this->flash->failure(t('Unable to create this user.')); + $this->response->redirect($this->helper->url->to('UserInviteController', 'signup')); + } + } +} |