First commit

This commit is contained in:
Frédéric Guillot
2014-01-25 14:56:02 -05:00
commit 9383a15af6
80 changed files with 7519 additions and 0 deletions

1
controllers/.htaccess Normal file
View File

@@ -0,0 +1 @@
Deny from all

16
controllers/app.php Normal file
View File

@@ -0,0 +1,16 @@
<?php
namespace Controller;
class App extends Base
{
public function index()
{
if ($this->project->countByStatus(\Model\Project::ACTIVE)) {
$this->response->redirect('?controller=board');
}
else {
$this->redirectNoProject();
}
}
}

79
controllers/base.php Normal file
View File

@@ -0,0 +1,79 @@
<?php
namespace Controller;
require __DIR__.'/../lib/request.php';
require __DIR__.'/../lib/response.php';
require __DIR__.'/../lib/session.php';
require __DIR__.'/../lib/template.php';
require __DIR__.'/../lib/helper.php';
require __DIR__.'/../lib/translator.php';
require __DIR__.'/../models/base.php';
require __DIR__.'/../models/config.php';
require __DIR__.'/../models/user.php';
require __DIR__.'/../models/project.php';
require __DIR__.'/../models/task.php';
require __DIR__.'/../models/board.php';
abstract class Base
{
protected $request;
protected $response;
protected $session;
protected $template;
protected $user;
protected $project;
protected $task;
protected $board;
protected $config;
public function __construct()
{
$this->request = new \Request;
$this->response = new \Response;
$this->session = new \Session;
$this->template = new \Template;
$this->config = new \Model\Config;
$this->user = new \Model\User;
$this->project = new \Model\Project;
$this->task = new \Model\Task;
$this->board = new \Model\Board;
}
public function beforeAction($controller, $action)
{
$this->session->open();
$public = array(
'user' => array('login', 'check'),
'task' => array('add'),
);
if (! isset($_SESSION['user']) && ! isset($public[$controller]) && ! in_array($action, $public[$controller])) {
$this->response->redirect('?controller=user&action=login');
}
// Load translations
$language = $this->config->get('language', 'en_US');
if ($language !== 'en_US') \Translator\load($language);
$this->response->csp();
$this->response->nosniff();
$this->response->xss();
$this->response->hsts();
$this->response->xframe();
}
public function checkPermissions()
{
if ($_SESSION['user']['is_admin'] == 0) {
$this->response->redirect('?controller=user&action=forbidden');
}
}
public function redirectNoProject()
{
$this->session->flash(t('There is no active project, the first step is to create a new project.'));
$this->response->redirect('?controller=project&action=create');
}
}

185
controllers/board.php Normal file
View File

@@ -0,0 +1,185 @@
<?php
namespace Controller;
class Board extends Base
{
// Display current board
public function index()
{
$projects = $this->project->getListByStatus(\Model\Project::ACTIVE);
if (! count($projects)) {
$this->redirectNoProject();
}
else if (! empty($_SESSION['user']['default_project_id']) && isset($projects[$_SESSION['user']['default_project_id']])) {
$project_id = $_SESSION['user']['default_project_id'];
$project_name = $projects[$_SESSION['user']['default_project_id']];
}
else {
list($project_id, $project_name) = each($projects);
}
$this->response->html($this->template->layout('board_index', array(
'projects' => $projects,
'current_project_id' => $project_id,
'current_project_name' => $project_name,
'columns' => $this->board->get($project_id),
'menu' => 'boards',
'title' => $project_name
)));
}
// Show a board
public function show()
{
$projects = $this->project->getListByStatus(\Model\Project::ACTIVE);
$project_id = $this->request->getIntegerParam('project_id');
$project_name = $projects[$project_id];
$this->response->html($this->template->layout('board_index', array(
'projects' => $projects,
'current_project_id' => $project_id,
'current_project_name' => $project_name,
'columns' => $this->board->get($project_id),
'menu' => 'boards',
'title' => $project_name
)));
}
// Display a form to edit a board
public function edit()
{
$this->checkPermissions();
$project_id = $this->request->getIntegerParam('project_id');
$project = $this->project->get($project_id);
$columns = $this->board->getColumnsList($project_id);
$values = array();
foreach ($columns as $column_id => $column_title) {
$values['title['.$column_id.']'] = $column_title;
}
$this->response->html($this->template->layout('board_edit', array(
'errors' => array(),
'values' => $values + array('project_id' => $project_id),
'columns' => $columns,
'project' => $project,
'menu' => 'projects',
'title' => t('Edit board')
)));
}
// Validate and update a board
public function update()
{
$this->checkPermissions();
$project_id = $this->request->getIntegerParam('project_id');
$project = $this->project->get($project_id);
$columns = $this->board->getColumnsList($project_id);
$data = $this->request->getValues();
$values = array();
foreach ($columns as $column_id => $column_title) {
$values['title['.$column_id.']'] = isset($data['title'][$column_id]) ? $data['title'][$column_id] : '';
}
list($valid, $errors) = $this->board->validateModification($columns, $values);
if ($valid) {
if ($this->board->update($data['title'])) {
$this->session->flash(t('Board updated successfully.'));
$this->response->redirect('?controller=board&action=edit&project_id='.$project['id']);
}
else {
$this->session->flashError(t('Unable to update this board.'));
}
}
$this->response->html($this->template->layout('board_edit', array(
'errors' => $errors,
'values' => $values + array('project_id' => $project_id),
'columns' => $columns,
'project' => $project,
'menu' => 'projects',
'title' => t('Edit board')
)));
}
// Validate and add a new column
public function add()
{
$this->checkPermissions();
$project_id = $this->request->getIntegerParam('project_id');
$project = $this->project->get($project_id);
$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;
}
list($valid, $errors) = $this->board->validateCreation($data);
if ($valid) {
if ($this->board->add($data)) {
$this->session->flash(t('Board updated successfully.'));
$this->response->redirect('?controller=board&action=edit&project_id='.$project['id']);
}
else {
$this->session->flashError(t('Unable to update this board.'));
}
}
$this->response->html($this->template->layout('board_edit', array(
'errors' => $errors,
'values' => $values + $data,
'columns' => $columns,
'project' => $project,
'menu' => 'projects',
'title' => t('Edit board')
)));
}
// Confirmation dialog before removing a column
public function confirm()
{
$this->checkPermissions();
$this->response->html($this->template->layout('board_remove', array(
'column' => $this->board->getColumn($this->request->getIntegerParam('column_id')),
'menu' => 'projects',
'title' => t('Remove a column from a board')
)));
}
// Remove a column
public function remove()
{
$this->checkPermissions();
$column = $this->board->getColumn($this->request->getIntegerParam('column_id'));
if ($column && $this->board->removeColumn($column['id'])) {
$this->session->flash(t('Column removed successfully.'));
} else {
$this->session->flashError(t('Unable to remove this column.'));
}
$this->response->redirect('?controller=board&action=edit&project_id='.$column['project_id']);
}
// Save the board (Ajax request made by drag and drop)
public function save()
{
$this->response->json(array(
'result' => $this->board->saveTasksPosition($this->request->getValues())
));
}
}

70
controllers/config.php Normal file
View File

@@ -0,0 +1,70 @@
<?php
namespace Controller;
class Config extends Base
{
// Settings page
public function index()
{
$this->response->html($this->template->layout('config_index', array(
'db_size' => $this->config->getDatabaseSize(),
'user' => $_SESSION['user'],
'projects' => $this->project->getList(),
'languages' => $this->config->getLanguages(),
'values' => $this->config->getAll(),
'errors' => array(),
'menu' => 'config',
'title' => t('Settings')
)));
}
// Validate and save settings
public function save()
{
$this->checkPermissions();
$values = $this->request->getValues();
list($valid, $errors) = $this->config->validateModification($values);
if ($valid) {
if ($this->config->save($values)) {
$this->config->reload();
$this->session->flash(t('Settings saved successfully.'));
$this->response->redirect('?controller=config');
}
else {
$this->session->flashError(t('Unable to save your settings.'));
}
}
$this->response->html($this->template->layout('config_index', array(
'db_size' => $this->config->getDatabaseSize(),
'user' => $_SESSION['user'],
'projects' => $this->project->getList(),
'languages' => $this->config->getLanguages(),
'values' => $values,
'errors' => $errors,
'menu' => 'config',
'title' => t('Settings')
)));
}
// Download the database
public function downloadDb()
{
$this->checkPermissions();
$this->response->forceDownload('db.sqlite.gz');
$this->response->binary($this->config->downloadDatabase());
}
// Optimize the database
public function optimizeDb()
{
$this->checkPermissions();
$this->config->optimizeDatabase();
$this->session->flash(t('Database optimization done.'));
$this->response->redirect('?controller=config');
}
}

162
controllers/project.php Normal file
View File

@@ -0,0 +1,162 @@
<?php
namespace Controller;
class Project extends Base
{
// List of projects
public function index()
{
$projects = $this->project->getAll(true);
$nb_projects = count($projects);
$this->response->html($this->template->layout('project_index', array(
'projects' => $projects,
'nb_projects' => $nb_projects,
'menu' => 'projects',
'title' => t('Projects').' ('.$nb_projects.')'
)));
}
// Display a form to create a new project
public function create()
{
$this->checkPermissions();
$this->response->html($this->template->layout('project_new', array(
'errors' => array(),
'values' => array(),
'menu' => 'projects',
'title' => t('New project')
)));
}
// Validate and save a new project
public function save()
{
$this->checkPermissions();
$values = $this->request->getValues();
list($valid, $errors) = $this->project->validateCreation($values);
if ($valid) {
if ($this->project->create($values)) {
$this->session->flash(t('Your project have been created successfully.'));
$this->response->redirect('?controller=project');
}
else {
$this->session->flashError(t('Unable to create your project.'));
}
}
$this->response->html($this->template->layout('project_new', array(
'errors' => $errors,
'values' => $values,
'menu' => 'projects',
'title' => t('New Project')
)));
}
// Display a form to edit a project
public function edit()
{
$this->checkPermissions();
$project = $this->project->get($this->request->getIntegerParam('project_id'));
$this->response->html($this->template->layout('project_edit', array(
'errors' => array(),
'values' => $project,
'menu' => 'projects',
'title' => t('Edit project')
)));
}
// Validate and update a project
public function update()
{
$this->checkPermissions();
$values = $this->request->getValues() + array('is_active' => 0);
list($valid, $errors) = $this->project->validateModification($values);
if ($valid) {
if ($this->project->update($values)) {
$this->session->flash(t('Project updated successfully.'));
$this->response->redirect('?controller=project');
}
else {
$this->session->flashError(t('Unable to update this project.'));
}
}
$this->response->html($this->template->layout('project_edit', array(
'errors' => $errors,
'values' => $values,
'menu' => 'projects',
'title' => t('Edit Project')
)));
}
// Confirmation dialog before to remove a project
public function confirm()
{
$this->checkPermissions();
$this->response->html($this->template->layout('project_remove', array(
'project' => $this->project->get($this->request->getIntegerParam('project_id')),
'menu' => 'projects',
'title' => t('Remove project')
)));
}
// Remove a project
public function remove()
{
$this->checkPermissions();
$project_id = $this->request->getIntegerParam('project_id');
if ($project_id && $this->project->remove($project_id)) {
$this->session->flash(t('Project removed successfully.'));
} else {
$this->session->flashError(t('Unable to remove this project.'));
}
$this->response->redirect('?controller=project');
}
// Enable a project
public function enable()
{
$this->checkPermissions();
$project_id = $this->request->getIntegerParam('project_id');
if ($project_id && $this->project->enable($project_id)) {
$this->session->flash(t('Project activated successfully.'));
} else {
$this->session->flashError(t('Unable to activate this project.'));
}
$this->response->redirect('?controller=project');
}
// Disable a project
public function disable()
{
$this->checkPermissions();
$project_id = $this->request->getIntegerParam('project_id');
if ($project_id && $this->project->disable($project_id)) {
$this->session->flash(t('Project disabled successfully.'));
} else {
$this->session->flashError(t('Unable to disable this project.'));
}
$this->response->redirect('?controller=project');
}
}

201
controllers/task.php Normal file
View File

@@ -0,0 +1,201 @@
<?php
namespace Controller;
class Task extends Base
{
// Webhook to create a task (useful for external software)
public function add()
{
$token = $this->request->getStringParam('token');
if ($this->config->get('webhooks_token') !== $token) {
$this->response->text('Not Authorized', 401);
}
$values = array(
'title' => $this->request->getStringParam('title'),
'description' => $this->request->getStringParam('description'),
'color_id' => $this->request->getStringParam('color_id'),
'project_id' => $this->request->getIntegerParam('project_id'),
'owner_id' => $this->request->getIntegerParam('owner_id'),
'column_id' => $this->request->getIntegerParam('column_id'),
);
list($valid,) = $this->task->validateCreation($values);
if ($valid && $this->task->create($values)) {
$this->response->text('OK');
}
$this->response->text('FAILED');
}
// Show a task
public function show()
{
$task = $this->task->getById($this->request->getIntegerParam('task_id'), true);
$this->response->html($this->template->layout('task_show', array(
'task' => $task,
'columns_list' => $this->board->getColumnsList($task['project_id']),
'colors_list' => $this->task->getColors(),
'menu' => 'tasks',
'title' => $task['title']
)));
}
// Display a form to create a new task
public function create()
{
$project_id = $this->request->getIntegerParam('project_id');
$this->response->html($this->template->layout('task_new', array(
'errors' => array(),
'values' => array(
'project_id' => $project_id,
'column_id' => $this->request->getIntegerParam('column_id'),
'color_id' => $this->request->getStringParam('color_id'),
'owner_id' => $this->request->getIntegerParam('owner_id'),
'another_task' => $this->request->getIntegerParam('another_task'),
),
'projects_list' => $this->project->getListByStatus(\Model\Project::ACTIVE),
'columns_list' => $this->board->getColumnsList($project_id),
'users_list' => $this->user->getList(),
'colors_list' => $this->task->getColors(),
'menu' => 'tasks',
'title' => t('New task')
)));
}
// Validate and save a new task
public function save()
{
$values = $this->request->getValues();
list($valid, $errors) = $this->task->validateCreation($values);
if ($valid) {
if ($this->task->create($values)) {
$this->session->flash(t('Task created successfully.'));
if (isset($values['another_task']) && $values['another_task'] == 1) {
unset($values['title']);
unset($values['description']);
$this->response->redirect('?controller=task&action=create&'.http_build_query($values));
}
else {
$this->response->redirect('?controller=board&action=show&project_id='.$values['project_id']);
}
}
else {
$this->session->flashError(t('Unable to create your task.'));
}
}
$this->response->html($this->template->layout('task_new', array(
'errors' => $errors,
'values' => $values,
'projects_list' => $this->project->getListByStatus(\Model\Project::ACTIVE),
'columns_list' => $this->board->getColumnsList($values['project_id']),
'users_list' => $this->user->getList(),
'colors_list' => $this->task->getColors(),
'menu' => 'tasks',
'title' => t('New task')
)));
}
// Display a form to edit a task
public function edit()
{
$task = $this->task->getById($this->request->getIntegerParam('task_id'));
$this->response->html($this->template->layout('task_edit', array(
'errors' => array(),
'values' => $task,
'projects_list' => $this->project->getListByStatus(\Model\Project::ACTIVE),
'columns_list' => $this->board->getColumnsList($task['project_id']),
'users_list' => $this->user->getList(),
'colors_list' => $this->task->getColors(),
'menu' => 'tasks',
'title' => t('Edit a task')
)));
}
// Validate and update a task
public function update()
{
$values = $this->request->getValues();
list($valid, $errors) = $this->task->validateModification($values);
if ($valid) {
if ($this->task->update($values)) {
$this->session->flash(t('Task updated successfully.'));
$this->response->redirect('?controller=task&action=show&task_id='.$values['id']);
}
else {
$this->session->flashError(t('Unable to update your task.'));
}
}
$this->response->html($this->template->layout('task_edit', array(
'errors' => $errors,
'values' => $values,
'projects_list' => $this->project->getListByStatus(\Model\Project::ACTIVE),
'columns_list' => $this->board->getColumnsList($task['project_id']),
'users_list' => $this->user->getList(),
'colors_list' => $this->task->getColors(),
'menu' => 'tasks',
'title' => t('Edit a task')
)));
}
// Hide a task
public function close()
{
$task = $this->task->getById($this->request->getIntegerParam('task_id'));
if ($task && $this->task->close($task['id'])) {
$this->session->flash(t('Task closed successfully.'));
} else {
$this->session->flashError(t('Unable to close this task.'));
}
$this->response->redirect('?controller=board&action=show&project_id='.$task['project_id']);
}
// Confirmation dialog before to close a task
public function confirmClose()
{
$this->response->html($this->template->layout('task_close', array(
'task' => $this->task->getById($this->request->getIntegerParam('task_id')),
'menu' => 'tasks',
'title' => t('Close a task')
)));
}
// Open a task
public function open()
{
$task = $this->task->getById($this->request->getIntegerParam('task_id'));
if ($task && $this->task->close($task['id'])) {
$this->session->flash(t('Task opened successfully.'));
} else {
$this->session->flashError(t('Unable to open this task.'));
}
$this->response->redirect('?controller=board&action=show&project_id='.$task['project_id']);
}
// Confirmation dialog before to open a task
public function confirmOpen()
{
$this->response->html($this->template->layout('task_open', array(
'task' => $this->task->getById($this->request->getIntegerParam('task_id')),
'menu' => 'tasks',
'title' => t('Open a task')
)));
}
}

198
controllers/user.php Normal file
View File

@@ -0,0 +1,198 @@
<?php
namespace Controller;
class User extends Base
{
// Display access forbidden page
public function forbidden()
{
$this->response->html($this->template->layout('user_forbidden', array(
'menu' => 'users',
'title' => t('Access Forbidden')
)));
}
// Logout and destroy session
public function logout()
{
$this->session->close();
$this->response->redirect('?controller=user&action=login');
}
// Display the form login
public function login()
{
if (isset($_SESSION['user'])) $this->response->redirect('?controller=app');
$this->response->html($this->template->layout('user_login', array(
'errors' => array(),
'values' => array(),
'no_layout' => true,
'title' => t('Login')
)));
}
// Check credentials
public function check()
{
$values = $this->request->getValues();
list($valid, $errors) = $this->user->validateLogin($values);
if ($valid) $this->response->redirect('?controller=app');
$this->response->html($this->template->layout('user_login', array(
'errors' => $errors,
'values' => $values,
'no_layout' => true,
'title' => t('Login')
)));
}
// List all users
public function index()
{
$users = $this->user->getAll();
$nb_users = count($users);
$this->response->html(
$this->template->layout('user_index', array(
'projects' => $this->project->getList(),
'users' => $users,
'nb_users' => $nb_users,
'menu' => 'users',
'title' => t('Users').' ('.$nb_users.')'
)));
}
// Display a form to create a new user
public function create()
{
$this->checkPermissions();
$this->response->html($this->template->layout('user_new', array(
'projects' => $this->project->getList(),
'errors' => array(),
'values' => array(),
'menu' => 'users',
'title' => t('New user')
)));
}
// Validate and save a new user
public function save()
{
$this->checkPermissions();
$values = $this->request->getValues();
list($valid, $errors) = $this->user->validateCreation($values);
if ($valid) {
if ($this->user->create($values)) {
$this->session->flash(t('User created successfully.'));
$this->response->redirect('?controller=user');
}
else {
$this->session->flashError(t('Unable to create your user.'));
}
}
$this->response->html($this->template->layout('user_new', array(
'projects' => $this->project->getList(),
'errors' => $errors,
'values' => $values,
'menu' => 'users',
'title' => t('New user')
)));
}
// Display a form to edit a user
public function edit()
{
$user = $this->user->getById($this->request->getIntegerParam('user_id'));
if (! $_SESSION['user']['is_admin'] && $_SESSION['user']['id'] != $user['id']) {
$this->response->redirect('?controller=user&action=forbidden');
}
if (! empty($user)) unset($user['password']);
$this->response->html($this->template->layout('user_edit', array(
'projects' => $this->project->getList(),
'errors' => array(),
'values' => $user,
'menu' => 'users',
'title' => t('Edit user')
)));
}
// Validate and update a user
public function update()
{
$values = $this->request->getValues();
if ($_SESSION['user']['is_admin'] == 1) {
$values += array('is_admin' => 0);
}
else {
if ($_SESSION['user']['id'] != $values['id']) {
$this->response->redirect('?controller=user&action=forbidden');
}
if (isset($values['is_admin'])) {
unset($values['is_admin']); // Regular users can't be admin
}
}
list($valid, $errors) = $this->user->validateModification($values);
if ($valid) {
if ($this->user->update($values)) {
$this->session->flash(t('User updated successfully.'));
$this->response->redirect('?controller=user');
}
else {
$this->session->flashError(t('Unable to update your user.'));
}
}
$this->response->html($this->template->layout('user_edit', array(
'projects' => $this->project->getList(),
'errors' => $errors,
'values' => $values,
'menu' => 'users',
'title' => t('Edit user')
)));
}
// Confirmation dialog before to remove a user
public function confirm()
{
$this->checkPermissions();
$this->response->html($this->template->layout('user_remove', array(
'user' => $this->user->getById($this->request->getIntegerParam('user_id')),
'menu' => 'users',
'title' => t('Remove user')
)));
}
// Remove a user
public function remove()
{
$this->checkPermissions();
$user_id = $this->request->getIntegerParam('user_id');
if ($user_id && $this->user->remove($user_id)) {
$this->session->flash(t('User removed successfully.'));
} else {
$this->session->flashError(t('Unable to remove this user.'));
}
$this->response->redirect('?controller=user');
}
}