Improve user interface

This commit is contained in:
Frédéric Guillot
2014-05-23 09:49:26 -04:00
parent a7167f63c5
commit 7b53d47d46
25 changed files with 586 additions and 541 deletions

View File

@@ -2,7 +2,7 @@
namespace Controller;
use Model\Project;
use Model\Project as ProjectModel;
/**
* Application controller
@@ -19,7 +19,7 @@ class App extends Base
*/
public function index()
{
if ($this->project->countByStatus(Project::ACTIVE)) {
if ($this->project->countByStatus(ProjectModel::ACTIVE)) {
$this->response->redirect('?controller=board');
}
else {

View File

@@ -11,6 +11,20 @@ use Model\LastLogin;
*
* @package controller
* @author Frederic Guillot
* @property \Model\Acl $acl
* @property \Model\Action $action
* @property \Model\Board $board
* @property \Model\Category $category
* @property \Model\Comment $comment
* @property \Model\Config $config
* @property \Model\File $file
* @property \Model\Google $google
* @property \Model\LastLogin $lastlogin
* @property \Model\Ldap $ldap
* @property \Model\Project $project
* @property \Model\RememberMe $rememberme
* @property \Model\Task $task
* @property \Model\User $user
*/
abstract class Base
{
@@ -172,56 +186,6 @@ abstract class Base
$this->response->redirect('?controller=project&action=create');
}
/**
* Display the template show task (common between different actions)
*
* @access protected
* @param array $task Task data
* @param array $comment_form Comment form data
* @param array $description_form Description form data
* @param array $comment_edit_form Comment edit form data
*/
protected function showTask(array $task, array $comment_form = array(), array $description_form = array(), array $comment_edit_form = array())
{
if (empty($comment_form)) {
$comment_form = array(
'values' => array('task_id' => $task['id'], 'user_id' => $this->acl->getUserId()),
'errors' => array()
);
}
if (empty($description_form)) {
$description_form = array(
'values' => array('id' => $task['id']),
'errors' => array()
);
}
if (empty($comment_edit_form)) {
$comment_edit_form = array(
'values' => array('id' => 0),
'errors' => array()
);
}
else {
$hide_comment_form = true;
}
$this->response->html($this->taskLayout('task_show', array(
'hide_comment_form' => isset($hide_comment_form),
'comment_edit_form' => $comment_edit_form,
'comment_form' => $comment_form,
'description_form' => $description_form,
'comments' => $this->comment->getAll($task['id']),
'task' => $task,
'columns_list' => $this->board->getColumnsList($task['project_id']),
'colors_list' => $this->task->getColors(),
'files' => $this->file->getAll($task['id']),
'menu' => 'tasks',
'title' => $task['title'],
)));
}
/**
* Common layout for task views
*
@@ -236,4 +200,23 @@ abstract class Base
return $this->template->layout('task_layout', $params);
}
/**
* Common method to get a task for task views
*
* @access protected
* @return array
*/
protected function getTask()
{
$task = $this->task->getById($this->request->getIntegerParam('task_id'), true);
if (! $task) {
$this->notfound();
}
$this->checkProjectPermissions($task['project_id']);
return $task;
}
}

View File

@@ -2,8 +2,8 @@
namespace Controller;
use Model\Project;
use Model\User;
use Model\Project as ProjectModel;
use Model\User as UserModel;
/**
* Board controller
@@ -52,7 +52,7 @@ class Board extends Base
{
$task = $this->task->getById($this->request->getIntegerParam('task_id'));
$project = $this->project->getById($task['project_id']);
$projects = $this->project->getListByStatus(Project::ACTIVE);
$projects = $this->project->getListByStatus(ProjectModel::ACTIVE);
if ($this->acl->isRegularUser()) {
$projects = $this->project->filterListByAccess($projects, $this->acl->getUserId());
@@ -143,7 +143,7 @@ class Board extends Base
*/
public function index()
{
$projects = $this->project->getListByStatus(Project::ACTIVE);
$projects = $this->project->getListByStatus(ProjectModel::ACTIVE);
if ($this->acl->isRegularUser()) {
$projects = $this->project->filterListByAccess($projects, $this->acl->getUserId());
@@ -177,10 +177,10 @@ class Board extends Base
public function show()
{
$project_id = $this->request->getIntegerParam('project_id');
$user_id = $this->request->getIntegerParam('user_id', User::EVERYBODY_ID);
$user_id = $this->request->getIntegerParam('user_id', UserModel::EVERYBODY_ID);
$this->checkProjectPermissions($project_id);
$projects = $this->project->getListByStatus(Project::ACTIVE);
$projects = $this->project->getListByStatus(ProjectModel::ACTIVE);
if ($this->acl->isRegularUser()) {
$projects = $this->project->filterListByAccess($projects, $this->acl->getUserId());

View File

@@ -10,6 +10,27 @@ namespace Controller;
*/
class Comment extends Base
{
/**
* Get the current comment
*
* @access private
* @return array
*/
private function getComment()
{
$comment = $this->comment->getById($this->request->getIntegerParam('comment_id'));
if (! $comment) {
$this->notfound();
}
if (! $this->acl->isAdminUser() && $comment['user_id'] != $this->acl->getUserId()) {
$this->forbidden();
}
return $comment;
}
/**
* Forbidden page for comments
*
@@ -23,6 +44,27 @@ class Comment extends Base
)));
}
/**
* Add comment form
*
* @access public
*/
public function create()
{
$task = $this->getTask();
$this->response->html($this->taskLayout('comment_create', array(
'values' => array(
'user_id' => $this->acl->getUserId(),
'task_id' => $task['id'],
),
'errors' => array(),
'task' => $task,
'menu' => 'tasks',
'title' => t('Add a comment')
)));
}
/**
* Add a comment
*
@@ -30,12 +72,9 @@ class Comment extends Base
*/
public function save()
{
$task = $this->task->getById($this->request->getIntegerParam('task_id'), true);
$task = $this->getTask();
$values = $this->request->getValues();
if (! $task) $this->notfound();
$this->checkProjectPermissions($task['project_id']);
list($valid, $errors) = $this->comment->validateCreation($values);
if ($valid) {
@@ -47,13 +86,16 @@ class Comment extends Base
$this->session->flashError(t('Unable to create your comment.'));
}
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']);
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#comments');
}
$this->showTask(
$task,
array('values' => $values, 'errors' => $errors)
);
$this->response->html($this->taskLayout('comment_create', array(
'values' => $values,
'errors' => $errors,
'task' => $task,
'menu' => 'tasks',
'title' => t('Add a comment')
)));
}
/**
@@ -63,26 +105,17 @@ class Comment extends Base
*/
public function edit()
{
$task_id = $this->request->getIntegerParam('task_id');
$comment_id = $this->request->getIntegerParam('comment_id');
$task = $this->getTask();
$comment = $this->getComment();
$task = $this->task->getById($task_id, true);
$comment = $this->comment->getById($comment_id);
if (! $task || ! $comment) $this->notfound();
$this->checkProjectPermissions($task['project_id']);
if ($this->acl->isAdminUser() || $comment['user_id'] == $this->acl->getUserId()) {
$this->showTask(
$task,
array(),
array(),
array('values' => array('id' => $comment['id']), 'errors' => array())
);
}
$this->forbidden();
$this->response->html($this->taskLayout('comment_edit', array(
'values' => $comment,
'errors' => array(),
'comment' => $comment,
'task' => $task,
'menu' => 'tasks',
'title' => t('Edit a comment')
)));
}
/**
@@ -92,42 +125,32 @@ class Comment extends Base
*/
public function update()
{
$task_id = $this->request->getIntegerParam('task_id');
$comment_id = $this->request->getIntegerParam('comment_id');
$task = $this->task->getById($task_id, true);
$comment = $this->comment->getById($comment_id);
$task = $this->getTask();
$comment = $this->getComment();
$values = $this->request->getValues();
list($valid, $errors) = $this->comment->validateModification($values);
if (! $task || ! $comment) $this->notfound();
$this->checkProjectPermissions($task['project_id']);
if ($valid) {
if ($this->acl->isAdminUser() || $comment['user_id'] == $this->acl->getUserId()) {
list($valid, $errors) = $this->comment->validateModification($values);
if ($valid) {
if ($this->comment->update($values)) {
$this->session->flash(t('Comment updated successfully.'));
}
else {
$this->session->flashError(t('Unable to update your comment.'));
}
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#comment-'.$comment_id);
if ($this->comment->update($values)) {
$this->session->flash(t('Comment updated successfully.'));
}
else {
$this->session->flashError(t('Unable to update your comment.'));
}
$this->showTask(
$task,
array(),
array(),
array('values' => $values, 'errors' => $errors)
);
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#comment-'.$comment['id']);
}
$this->forbidden();
$this->response->html($this->taskLayout('comment_edit', array(
'values' => $values,
'errors' => $errors,
'comment' => $comment,
'task' => $task,
'menu' => 'tasks',
'title' => t('Edit a comment')
)));
}
/**
@@ -137,25 +160,15 @@ class Comment extends Base
*/
public function confirm()
{
$project_id = $this->request->getIntegerParam('project_id');
$comment_id = $this->request->getIntegerParam('comment_id');
$task = $this->getTask();
$comment = $this->getComment();
$this->checkProjectPermissions($project_id);
$comment = $this->comment->getById($comment_id);
if (! $comment) $this->notfound();
if ($this->acl->isAdminUser() || $comment['user_id'] == $this->acl->getUserId()) {
$this->response->html($this->template->layout('comment_remove', array(
'comment' => $comment,
'project_id' => $project_id,
'menu' => 'tasks',
'title' => t('Remove a comment')
)));
}
$this->forbidden();
$this->response->html($this->taskLayout('comment_remove', array(
'comment' => $comment,
'task' => $task,
'menu' => 'tasks',
'title' => t('Remove a comment')
)));
}
/**
@@ -165,25 +178,16 @@ class Comment extends Base
*/
public function remove()
{
$project_id = $this->request->getIntegerParam('project_id');
$comment_id = $this->request->getIntegerParam('comment_id');
$task = $this->getTask();
$comment = $this->getComment();
$this->checkProjectPermissions($project_id);
$comment = $this->comment->getById($comment_id);
if (! $comment) $this->notfound();
if ($this->acl->isAdminUser() || $comment['user_id'] == $this->acl->getUserId()) {
if ($this->comment->remove($comment['id'])) {
$this->session->flash(t('Comment removed successfully.'));
} else {
$this->session->flashError(t('Unable to remove this comment.'));
}
$this->response->redirect('?controller=task&action=show&task_id='.$comment['task_id']);
if ($this->comment->remove($comment['id'])) {
$this->session->flash(t('Comment removed successfully.'));
}
else {
$this->session->flashError(t('Unable to remove this comment.'));
}
$this->forbidden();
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#comments');
}
}

136
app/Controller/File.php Normal file
View File

@@ -0,0 +1,136 @@
<?php
namespace Controller;
use Model\File as FileModel;
/**
* File controller
*
* @package controller
* @author Frederic Guillot
*/
class File extends Base
{
/**
* File upload form
*
* @access public
*/
public function create()
{
$task = $this->getTask();
$this->response->html($this->taskLayout('file_new', array(
'task' => $task,
'menu' => 'tasks',
'title' => t('Attach a document')
)));
}
/**
* File upload (save files)
*
* @access public
*/
public function save()
{
$task = $this->getTask();
$this->file->upload($task['project_id'], $task['id'], 'files');
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#attachments');
}
/**
* File download
*
* @access public
*/
public function download()
{
$task = $this->getTask();
$file = $this->file->getById($this->request->getIntegerParam('file_id'));
$filename = FileModel::BASE_PATH.$file['path'];
if ($file['task_id'] == $task['id'] && file_exists($filename)) {
$this->response->forceDownload($file['name']);
$this->response->binary(file_get_contents($filename));
}
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']);
}
/**
* 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->load('file_open', array(
'file' => $file
)));
}
}
/**
* Return the file content (work only for images)
*
* @access public
*/
public function image()
{
$task = $this->getTask();
$file = $this->file->getById($this->request->getIntegerParam('file_id'));
$filename = FileModel::BASE_PATH.$file['path'];
if ($file['task_id'] == $task['id'] && file_exists($filename)) {
$metadata = getimagesize($filename);
if (isset($metadata['mime'])) {
$this->response->contentType($metadata['mime']);
readfile($filename);
}
}
}
/**
* Remove a file
*
* @access public
*/
public function remove()
{
$task = $this->getTask();
$file = $this->file->getById($this->request->getIntegerParam('file_id'));
if ($file['task_id'] == $task['id'] && $this->file->remove($file['id'])) {
$this->session->flash(t('File removed successfully.'));
} else {
$this->session->flashError(t('Unable to remove this file.'));
}
$this->response->redirect('?controller=task&action=show&task_id='.$task['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,
'menu' => 'tasks',
'title' => t('Remove a file')
)));
}
}

View File

@@ -2,7 +2,7 @@
namespace Controller;
use Model\Task;
use Model\Task as TaskModel;
/**
* Project controller
@@ -96,7 +96,7 @@ class Project extends Base
$filters = array(
array('column' => 'project_id', 'operator' => 'eq', 'value' => $project_id),
array('column' => 'is_active', 'operator' => 'eq', 'value' => Task::STATUS_CLOSED),
array('column' => 'is_active', 'operator' => 'eq', 'value' => TaskModel::STATUS_CLOSED),
);
$tasks = $this->task->find($filters);

View File

@@ -2,8 +2,7 @@
namespace Controller;
use Model\Project;
use Model\File;
use Model\Project as ProjectModel;
/**
* Task controller
@@ -13,19 +12,6 @@ use Model\File;
*/
class Task extends Base
{
private function getTask()
{
$task = $this->task->getById($this->request->getIntegerParam('task_id'), true);
if (! $task) {
$this->notfound();
}
$this->checkProjectPermissions($task['project_id']);
return $task;
}
/**
* Webhook to create a task (useful for external software)
*
@@ -71,41 +57,17 @@ class Task extends Base
*/
public function show()
{
$this->showTask($this->getTask());
}
$task = $this->getTask();
/**
* Add a description from the show task page
*
* @access public
*/
public function description()
{
$task = $this->task->getById($this->request->getIntegerParam('task_id'), true);
$values = $this->request->getValues();
if (! $task) $this->notfound();
$this->checkProjectPermissions($task['project_id']);
list($valid, $errors) = $this->task->validateDescriptionCreation($values);
if ($valid) {
if ($this->task->update($values)) {
$this->session->flash(t('Task updated successfully.'));
}
else {
$this->session->flashError(t('Unable to update your task.'));
}
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']);
}
$this->showTask(
$task,
array(),
array('values' => $values, 'errors' => $errors)
);
$this->response->html($this->taskLayout('task_show', array(
'files' => $this->file->getAll($task['id']),
'comments' => $this->comment->getAll($task['id']),
'task' => $task,
'columns_list' => $this->board->getColumnsList($task['project_id']),
'colors_list' => $this->task->getColors(),
'menu' => 'tasks',
'title' => $task['title'],
)));
}
/**
@@ -127,7 +89,7 @@ class Task extends Base
'owner_id' => $this->request->getIntegerParam('owner_id'),
'another_task' => $this->request->getIntegerParam('another_task'),
),
'projects_list' => $this->project->getListByStatus(\Model\Project::ACTIVE),
'projects_list' => $this->project->getListByStatus(ProjectModel::ACTIVE),
'columns_list' => $this->board->getColumnsList($project_id),
'users_list' => $this->project->getUsersList($project_id),
'colors_list' => $this->task->getColors(),
@@ -171,7 +133,7 @@ class Task extends Base
$this->response->html($this->template->layout('task_new', array(
'errors' => $errors,
'values' => $values,
'projects_list' => $this->project->getListByStatus(Project::ACTIVE),
'projects_list' => $this->project->getListByStatus(ProjectModel::ACTIVE),
'columns_list' => $this->board->getColumnsList($values['project_id']),
'users_list' => $this->project->getUsersList($values['project_id']),
'colors_list' => $this->task->getColors(),
@@ -188,10 +150,7 @@ class Task extends Base
*/
public function edit()
{
$task = $this->task->getById($this->request->getIntegerParam('task_id'));
if (! $task) $this->notfound();
$this->checkProjectPermissions($task['project_id']);
$task = $this->getTask();
if (! empty($task['date_due'])) {
$task['date_due'] = date(t('m/d/Y'), $task['date_due']);
@@ -203,8 +162,9 @@ class Task extends Base
$task['score'] = $task['score'] ?: '';
$this->response->html($this->template->layout('task_edit', array(
'errors' => array(),
'values' => $task,
'errors' => array(),
'task' => $task,
'columns_list' => $this->board->getColumnsList($task['project_id']),
'users_list' => $this->project->getUsersList($task['project_id']),
'colors_list' => $this->task->getColors(),
@@ -221,8 +181,8 @@ class Task extends Base
*/
public function update()
{
$task = $this->getTask();
$values = $this->request->getValues();
$this->checkProjectPermissions($values['project_id']);
list($valid, $errors) = $this->task->validateModification($values);
@@ -238,8 +198,9 @@ class Task extends Base
}
$this->response->html($this->template->layout('task_edit', array(
'errors' => $errors,
'values' => $values,
'errors' => $errors,
'task' => $task,
'columns_list' => $this->board->getColumnsList($values['project_id']),
'users_list' => $this->project->getUsersList($values['project_id']),
'colors_list' => $this->task->getColors(),
@@ -372,7 +333,7 @@ class Task extends Base
$this->response->html($this->template->layout('task_new', array(
'errors' => array(),
'values' => $task,
'projects_list' => $this->project->getListByStatus(Project::ACTIVE),
'projects_list' => $this->project->getListByStatus(ProjectModel::ACTIVE),
'columns_list' => $this->board->getColumnsList($task['project_id']),
'users_list' => $this->project->getUsersList($task['project_id']),
'colors_list' => $this->task->getColors(),
@@ -384,124 +345,53 @@ class Task extends Base
}
/**
* File upload form
* Edit description form
*
* @access public
*/
public function file()
public function editDescription()
{
$task = $this->getTask();
$this->response->html($this->taskLayout('task_upload', array(
$this->response->html($this->taskLayout('task_edit_description', array(
'values' => $task,
'errors' => array(),
'task' => $task,
'menu' => 'tasks',
'title' => t('Attach a document')
'title' => t('Edit the description')
)));
}
/**
* File upload (save files)
* Save and validation the description
*
* @access public
*/
public function upload()
public function saveDescription()
{
$task = $this->getTask();
$this->file->upload($task['project_id'], $task['id'], 'files');
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#attachments');
}
$values = $this->request->getValues();
/**
* File download
*
* @access public
*/
public function download()
{
$task = $this->getTask();
$file = $this->file->getById($this->request->getIntegerParam('file_id'));
$filename = File::BASE_PATH.$file['path'];
list($valid, $errors) = $this->task->validateDescriptionCreation($values);
if ($file['task_id'] == $task['id'] && file_exists($filename)) {
$this->response->forceDownload($file['name']);
$this->response->binary(file_get_contents($filename));
}
if ($valid) {
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']);
}
/**
* Open a file (show the content in a popover)
*
* @access public
*/
public function openFile()
{
$task = $this->getTask();
$file = $this->file->getById($this->request->getIntegerParam('file_id'));
if ($file['task_id'] == $task['id']) {
$this->response->html($this->template->load('task_open_file', array(
'file' => $file
)));
}
}
/**
* Return the file content (work only for images)
*
* @access public
*/
public function image()
{
$task = $this->getTask();
$file = $this->file->getById($this->request->getIntegerParam('file_id'));
$filename = File::BASE_PATH.$file['path'];
if ($file['task_id'] == $task['id'] && file_exists($filename)) {
$metadata = getimagesize($filename);
if (isset($metadata['mime'])) {
$this->response->contentType($metadata['mime']);
readfile($filename);
if ($this->task->update($values)) {
$this->session->flash(t('Task updated successfully.'));
}
else {
$this->session->flashError(t('Unable to update your task.'));
}
}
}
/**
* Remove a file
*
* @access public
*/
public function removeFile()
{
$task = $this->getTask();
$file = $this->file->getById($this->request->getIntegerParam('file_id'));
if ($file['task_id'] == $task['id'] && $this->file->remove($file['id'])) {
$this->session->flash(t('File removed successfully.'));
} else {
$this->session->flashError(t('Unable to remove this file.'));
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']);
}
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']);
}
/**
* Confirmation dialog before removing a file
*
* @access public
*/
public function confirmRemoveFile()
{
$task = $this->getTask();
$file = $this->file->getById($this->request->getIntegerParam('file_id'));
$this->response->html($this->taskLayout('task_remove_file', array(
$this->response->html($this->taskLayout('task_edit_description', array(
'values' => $values,
'errors' => $errors,
'task' => $task,
'file' => $file,
'menu' => 'tasks',
'title' => t('Remove a file')
'title' => t('Edit the description')
)));
}
}