Add kiosk mode, public board access with read-only and auto-refresh
This commit is contained in:
parent
a1923d3d7f
commit
2f4651411b
|
|
@ -45,6 +45,7 @@ abstract class Base
|
|||
$public = array(
|
||||
'user' => array('login', 'check'),
|
||||
'task' => array('add'),
|
||||
'board' => array('readonly'),
|
||||
);
|
||||
|
||||
if (isset($public[$controller])) {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,29 @@ namespace Controller;
|
|||
|
||||
class Board extends Base
|
||||
{
|
||||
// Display current board
|
||||
// Display the public version of a board
|
||||
// Access checked by a simple token, no user login, read only, auto-refresh
|
||||
public function readonly()
|
||||
{
|
||||
$token = $this->request->getStringParam('token');
|
||||
$project = $this->project->getByToken($token);
|
||||
|
||||
// Token verification
|
||||
if (! $project) {
|
||||
$this->response->text('Not Authorized', 401);
|
||||
}
|
||||
|
||||
// Display the board with a specific layout
|
||||
$this->response->html($this->template->layout('board_public', array(
|
||||
'project' => $project,
|
||||
'columns' => $this->board->get($project['id']),
|
||||
'title' => $project['name'],
|
||||
'no_layout' => true,
|
||||
'auto_refresh' => true,
|
||||
)));
|
||||
}
|
||||
|
||||
// Display the default user project or the first project
|
||||
public function index()
|
||||
{
|
||||
$projects = $this->project->getListByStatus(\Model\Project::ACTIVE);
|
||||
|
|
@ -30,7 +52,7 @@ class Board extends Base
|
|||
)));
|
||||
}
|
||||
|
||||
// Show a board
|
||||
// Show a board for a given project
|
||||
public function show()
|
||||
{
|
||||
$projects = $this->project->getListByStatus(\Model\Project::ACTIVE);
|
||||
|
|
@ -175,7 +197,7 @@ class Board extends Base
|
|||
$this->response->redirect('?controller=board&action=edit&project_id='.$column['project_id']);
|
||||
}
|
||||
|
||||
// Save the board (Ajax request made by drag and drop)
|
||||
// Save the board (Ajax request made by the drag and drop)
|
||||
public function save()
|
||||
{
|
||||
$this->response->json(array(
|
||||
|
|
|
|||
|
|
@ -4,5 +4,10 @@ require __DIR__.'/check_setup.php';
|
|||
require __DIR__.'/controllers/base.php';
|
||||
require __DIR__.'/lib/router.php';
|
||||
|
||||
if (file_exists('config.php')) require 'config.php';
|
||||
|
||||
// Auto-refresh frequency in seconds for the public board view
|
||||
defined('AUTO_REFRESH_DURATION') or define('AUTO_REFRESH_DURATION', 60);
|
||||
|
||||
$router = new Router;
|
||||
$router->execute();
|
||||
|
|
|
|||
|
|
@ -179,4 +179,5 @@ return array(
|
|||
'Completed tasks for "%s"' => 'Tâches terminées pour "%s"',
|
||||
'%d closed tasks' => '%d tâches terminées',
|
||||
'no task for this project' => 'aucune tâche pour ce projet',
|
||||
'Public link' => 'Accès public',
|
||||
);
|
||||
|
|
|
|||
|
|
@ -181,5 +181,7 @@ return array(
|
|||
'List of projects' => '',
|
||||
'Completed tasks for "%s"' => '',
|
||||
'%d closed tasks' => '',
|
||||
'no task for this project' => '',*/
|
||||
'no task for this project' => '',
|
||||
'Public link' => '',
|
||||
*/
|
||||
);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ require __DIR__.'/schema.php';
|
|||
abstract class Base
|
||||
{
|
||||
const APP_VERSION = 'master';
|
||||
const DB_VERSION = 2;
|
||||
const DB_VERSION = 3;
|
||||
const DB_FILENAME = 'data/db.sqlite';
|
||||
|
||||
private static $dbInstance = null;
|
||||
|
|
@ -46,4 +46,17 @@ abstract class Base
|
|||
die('Unable to migrate database schema!');
|
||||
}
|
||||
}
|
||||
|
||||
// Generate a random token from /dev/urandom or with uniqid()
|
||||
public static function generateToken()
|
||||
{
|
||||
if (ini_get('open_basedir') === '') {
|
||||
$token = file_get_contents('/dev/urandom', false, null, 0, 30);
|
||||
}
|
||||
else {
|
||||
$token = uniqid(mt_rand(), true);
|
||||
}
|
||||
|
||||
return hash('crc32b', $token);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,16 +66,6 @@ class Config extends Base
|
|||
);
|
||||
}
|
||||
|
||||
public static function generateToken()
|
||||
{
|
||||
if (ini_get('open_basedir') === '') {
|
||||
return substr(base64_encode(file_get_contents('/dev/urandom', false, null, 0, 20)), 0, 15);
|
||||
}
|
||||
else {
|
||||
return substr(base64_encode(uniqid(mt_rand(), true)), 0, 20);
|
||||
}
|
||||
}
|
||||
|
||||
public function optimizeDatabase()
|
||||
{
|
||||
$this->db->getconnection()->exec("VACUUM");
|
||||
|
|
|
|||
|
|
@ -16,6 +16,11 @@ class Project extends Base
|
|||
return $this->db->table(self::TABLE)->eq('id', $project_id)->findOne();
|
||||
}
|
||||
|
||||
public function getByToken($token)
|
||||
{
|
||||
return $this->db->table(self::TABLE)->eq('token', $token)->findOne();
|
||||
}
|
||||
|
||||
public function getFirst()
|
||||
{
|
||||
return $this->db->table(self::TABLE)->findOne();
|
||||
|
|
@ -92,12 +97,12 @@ class Project extends Base
|
|||
{
|
||||
$this->db->startTransaction();
|
||||
|
||||
$values['token'] = self::generateToken();
|
||||
$this->db->table(self::TABLE)->save($values);
|
||||
|
||||
$project_id = $this->db->getConnection()->getLastId();
|
||||
|
||||
$boardModel = new \Model\Board;
|
||||
|
||||
$boardModel->create($project_id, array(
|
||||
t('Backlog'),
|
||||
t('Ready'),
|
||||
|
|
|
|||
|
|
@ -2,11 +2,27 @@
|
|||
|
||||
namespace Schema;
|
||||
|
||||
function version_3($pdo)
|
||||
{
|
||||
$pdo->exec('ALTER TABLE projects ADD column token TEXT');
|
||||
|
||||
// For each existing project, assign a different token
|
||||
$rq = $pdo->prepare("SELECT id FROM projects WHERE token IS NULL");
|
||||
$rq->execute();
|
||||
$results = $rq->fetchAll(\PDO::FETCH_ASSOC);
|
||||
|
||||
if ($results !== false) {
|
||||
|
||||
foreach ($results as &$result) {
|
||||
$rq = $pdo->prepare('UPDATE projects SET token=? WHERE id=?');
|
||||
$rq->execute(array(\Model\Base::generateToken(), $result['id']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function version_2($pdo)
|
||||
{
|
||||
$pdo->exec('ALTER TABLE tasks ADD column date_completed INTEGER');
|
||||
|
||||
// For all existing completed tasks, set the date of creation as a date of completion
|
||||
$pdo->exec('UPDATE tasks SET date_completed=date_creation WHERE is_active=0');
|
||||
}
|
||||
|
||||
|
|
@ -74,6 +90,6 @@ function version_1($pdo)
|
|||
$pdo->exec("
|
||||
INSERT INTO config
|
||||
(language, webhooks_token)
|
||||
VALUES ('en_US', '".\Model\Config::generateToken()."')
|
||||
VALUES ('en_US', '".\Model\Base::generateToken()."')
|
||||
");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
<section id="main">
|
||||
|
||||
<table id="board">
|
||||
<tr>
|
||||
<?php $column_with = round(100 / count($columns), 2); ?>
|
||||
<?php foreach ($columns as $column): ?>
|
||||
<th width="<?= $column_with ?>%">
|
||||
<?= Helper\escape($column['title']) ?>
|
||||
</th>
|
||||
<?php endforeach ?>
|
||||
</tr>
|
||||
<tr>
|
||||
<?php foreach ($columns as $column): ?>
|
||||
<td class="column">
|
||||
<?php foreach ($column['tasks'] as $task): ?>
|
||||
<div class="draggable-item">
|
||||
<div class="task task-<?= $task['color_id'] ?>">
|
||||
|
||||
#<?= $task['id'] ?> -
|
||||
|
||||
<span class="task-user">
|
||||
<?php if (! empty($task['owner_id'])): ?>
|
||||
<?= t('Assigned to %s', $task['username']) ?>
|
||||
<?php else: ?>
|
||||
<span class="task-nobody"><?= t('No body assigned') ?></span>
|
||||
<?php endif ?>
|
||||
</span>
|
||||
|
||||
<div class="task-title">
|
||||
<?= Helper\escape($task['title']) ?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach ?>
|
||||
</td>
|
||||
<?php endforeach ?>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</section>
|
||||
|
|
@ -10,6 +10,9 @@
|
|||
<link rel="apple-touch-icon" sizes="114x114" href="assets/img/touch-icon-iphone-retina.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="assets/img/touch-icon-ipad-retina.png">
|
||||
<title><?= isset($title) ? Helper\escape($title) : 'Kanboard' ?></title>
|
||||
<?php if (isset($auto_refresh)): ?>
|
||||
<meta http-equiv="refresh" content="<?= AUTO_REFRESH_DURATION ?>" >
|
||||
<?php endif ?>
|
||||
</head>
|
||||
<body>
|
||||
<?php if (isset($no_layout)): ?>
|
||||
|
|
|
|||
|
|
@ -75,6 +75,9 @@
|
|||
<li>
|
||||
<a href="?controller=project&action=confirm&project_id=<?= $project['id'] ?>"><?= t('Remove') ?></a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="?controller=board&action=readonly&token=<?= $project['token'] ?>" target="_blank"><?= t('Public link') ?></a>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
<?php endif ?>
|
||||
|
|
|
|||
Loading…
Reference in New Issue