Fix bugs, improve perfs and use SimpleLogger instead of Monolog

This commit is contained in:
Frédéric Guillot
2015-01-02 17:19:13 -05:00
parent c32567857d
commit 3076ba22dd
39 changed files with 288 additions and 139 deletions

View File

@@ -101,9 +101,13 @@ abstract class Base
public function __destruct()
{
if (DEBUG) {
foreach ($this->container['db']->getLogMessages() as $message) {
$this->container['logger']->addDebug($message);
$this->container['logger']->debug($message);
}
$this->container['logger']->debug('SQL_QUERIES={nb}', array('nb' => $this->container['db']->nb_queries));
$this->container['logger']->debug('RENDERING={time}', array('time' => microtime(true) - $_SERVER['REQUEST_TIME_FLOAT']));
}
}

58
app/Core/Cache.php Normal file
View File

@@ -0,0 +1,58 @@
<?php
namespace Core;
use Pimple\Container;
abstract class Cache
{
/**
* Container instance
*
* @access protected
* @var \Pimple\Container
*/
protected $container;
abstract public function init();
abstract public function set($key, $value);
abstract public function get($key);
abstract public function flush();
abstract public function remove($key);
/**
* Constructor
*
* @access public
* @param \Pimple\Container $container
*/
public function __construct(Container $container)
{
$this->container = $container;
$this->init();
}
/**
* Proxy cache
*
* Note: Arguments must be scalar types
*
* @access public
* @param string $container Container name
* @param string $method Container method
* @return mixed
*/
public function proxy($container, $method)
{
$args = func_get_args();
$key = 'proxy_'.implode('_', $args);
$result = $this->get($key);
if ($result === null) {
$result = call_user_func_array(array($this->container[$container], $method), array_splice($args, 2));
$this->set($key, $result);
}
return $result;
}
}

41
app/Core/FileCache.php Normal file
View File

@@ -0,0 +1,41 @@
<?php
namespace Core;
class FileCache extends Cache
{
const CACHE_FOLDER = 'data/cache/';
public function init()
{
if (! is_dir(self::CACHE_FOLDER)) {
mkdir(self::CACHE_FOLDER);
}
}
public function set($key, $value)
{
file_put_contents(self::CACHE_FOLDER.$key, json_encode($value));
}
public function get($key)
{
if (file_exists(self::CACHE_FOLDER.$key)) {
return json_decode(file_get_contents(self::CACHE_FOLDER.$key), true);
}
return null;
}
public function flush()
{
foreach (glob(self::CACHE_FOLDER.'*') as $filename) {
@unlink($filename);
}
}
public function remove($key)
{
@unlink(self::CACHE_FOLDER.$key);
}
}

View File

@@ -48,6 +48,22 @@ class Helper
return $this->container[$name];
}
/**
* Proxy cache helper for acl::isManagerActionAllowed()
*
* @access public
* @param integer $project_id
* @return boolean
*/
public function isManager($project_id)
{
if ($this->userSession->isAdmin()) {
return true;
}
return $this->container['memoryCache']->proxy('acl', 'isManagerActionAllowed', $project_id);
}
/**
* Return the user full name
*

32
app/Core/MemoryCache.php Normal file
View File

@@ -0,0 +1,32 @@
<?php
namespace Core;
class MemoryCache extends Cache
{
private $storage = array();
public function init()
{
}
public function set($key, $value)
{
$this->storage[$key] = $value;
}
public function get($key)
{
return isset($this->storage[$key]) ? $this->storage[$key] : null;
}
public function flush()
{
$this->storage = array();
}
public function remove($key)
{
unset($this->storage[$key]);
}
}

View File

@@ -182,7 +182,7 @@ return array(
'Change assignee' => 'Ændre ansvarlig',
'Change assignee for the task "%s"' => 'Ændre ansvarlig for opgaven: "%s"',
'Timezone' => 'Tidszone',
'Sorry, I didn\'t found this information in my database!' => 'Denne information kunne ikke findes i databasen!',
'Sorry, I didn\'t find this information in my database!' => 'Denne information kunne ikke findes i databasen!',
'Page not found' => 'Siden er ikke fundet',
'Complexity' => 'Kompleksitet',
'limit' => 'Begrænsning',

View File

@@ -182,7 +182,7 @@ return array(
'Change assignee' => 'Zuständigkeit ändern',
'Change assignee for the task "%s"' => 'Zuständigkeit für diese Aufgabe ändern: "%s"',
'Timezone' => 'Zeitzone',
'Sorry, I didn\'t found this information in my database!' => 'Diese Information wurde in der Datenbank nicht gefunden!',
'Sorry, I didn\'t find this information in my database!' => 'Diese Information wurde in der Datenbank nicht gefunden!',
'Page not found' => 'Seite nicht gefunden',
'Complexity' => 'Komplexität',
'limit' => 'Limit',

View File

@@ -182,7 +182,7 @@ return array(
'Change assignee' => 'Cambiar la persona asignada',
'Change assignee for the task "%s"' => 'Cambiar la persona asignada por la tarea « %s »',
'Timezone' => 'Zona horaria',
'Sorry, I didn\'t found this information in my database!' => 'Lo siento no he encontrado información en la base de datos!',
'Sorry, I didn\'t find this information in my database!' => 'Lo siento no he encontrado información en la base de datos!',
'Page not found' => 'Página no encontrada',
'Complexity' => 'Complejidad',
'limit' => 'límite',

View File

@@ -182,7 +182,7 @@ return array(
'Change assignee' => 'Vaihda suorittajaa',
'Change assignee for the task "%s"' => 'Vaihda suorittajaa tehtävälle %s',
'Timezone' => 'Aikavyöhyke',
'Sorry, I didn\'t found this information in my database!' => 'Anteeksi, en löytänyt tätä tietoa tietokannastani',
'Sorry, I didn\'t find this information in my database!' => 'Anteeksi, en löytänyt tätä tietoa tietokannastani',
'Page not found' => 'Sivua ei löydy',
'Complexity' => 'Monimutkaisuus',
'limit' => 'raja',

View File

@@ -182,7 +182,7 @@ return array(
'Change assignee' => 'Changer la personne assignée',
'Change assignee for the task "%s"' => 'Changer la personne assignée pour la tâche « %s »',
'Timezone' => 'Fuseau horaire',
'Sorry, I didn\'t found this information in my database!' => 'Désolé, je n\'ai pas trouvé cette information dans ma base de données !',
'Sorry, I didn\'t find this information in my database!' => 'Désolé, je n\'ai pas trouvé cette information dans ma base de données !',
'Page not found' => 'Page introuvable',
'Complexity' => 'Complexité',
'limit' => 'limite',

View File

@@ -182,7 +182,7 @@ return array(
'Change assignee' => 'Felelős módosítása',
'Change assignee for the task "%s"' => 'Feladat felelősének módosítása: "%s"',
'Timezone' => 'Időzóna',
'Sorry, I didn\'t found this information in my database!' => 'Ez az információ nem található az adatbázisban!',
'Sorry, I didn\'t find this information in my database!' => 'Ez az információ nem található az adatbázisban!',
'Page not found' => 'Az oldal nem található',
'Complexity' => 'Bonyolultság',
'limit' => 'határ',

View File

@@ -182,7 +182,7 @@ return array(
'Change assignee' => 'Cambiare la persona assegnata',
'Change assignee for the task "%s"' => 'Cambiare la persona assegnata per il compito « %s »',
'Timezone' => 'Fuso orario',
'Sorry, I didn\'t found this information in my database!' => 'Mi dispiace, non ho trovato questa informazione sulla base dati!',
'Sorry, I didn\'t find this information in my database!' => 'Mi dispiace, non ho trovato questa informazione sulla base dati!',
'Page not found' => 'Pagina non trovata',
// 'Complexity' => '',
'limit' => 'limite',

View File

@@ -182,7 +182,7 @@ return array(
'Change assignee' => '担当を変更する',
'Change assignee for the task "%s"' => 'タスク「%s」の担当を変更する',
'Timezone' => 'タイムゾーン',
'Sorry, I didn\'t found this information in my database!' => 'データベース上で情報が見つかりませんでした!',
'Sorry, I didn\'t find this information in my database!' => 'データベース上で情報が見つかりませんでした!',
'Page not found' => 'ページが見つかりません',
'Complexity' => '複雑さ',
'limit' => '制限',

View File

@@ -182,7 +182,7 @@ return array(
'Change assignee' => 'Zmień odpowiedzialną osobę',
'Change assignee for the task "%s"' => 'Zmień odpowiedzialną osobę dla zadania "%s"',
'Timezone' => 'Strefa czasowa',
'Sorry, I didn\'t found this information in my database!' => 'Niestety nie znaleziono tej informacji w bazie danych',
'Sorry, I didn\'t find this information in my database!' => 'Niestety nie znaleziono tej informacji w bazie danych',
'Page not found' => 'Strona nie istnieje',
'Complexity' => 'Poziom trudności',
'limit' => 'limit',

View File

@@ -182,7 +182,7 @@ return array(
'Change assignee' => 'Mudar a designação',
'Change assignee for the task "%s"' => 'Modificar designação para a tarefa "%s"',
'Timezone' => 'Fuso horário',
'Sorry, I didn\'t found this information in my database!' => 'Desculpe, não encontrei esta informação no meu banco de dados!',
'Sorry, I didn\'t find this information in my database!' => 'Desculpe, não encontrei esta informação no meu banco de dados!',
'Page not found' => 'Página não encontrada',
'Complexity' => 'Complexidade',
'limit' => 'limite',

View File

@@ -182,7 +182,7 @@ return array(
'Change assignee' => 'Сменить назначенного',
'Change assignee for the task "%s"' => 'Сменить назначенного для задачи « %s »',
'Timezone' => 'Часовой пояс',
'Sorry, I didn\'t found this information in my database!' => 'К сожалению, информация в базе данных не найдена !',
'Sorry, I didn\'t find this information in my database!' => 'К сожалению, информация в базе данных не найдена !',
'Page not found' => 'Страница не найдена',
'Complexity' => 'Сложность',
'limit' => 'лимит',

View File

@@ -182,7 +182,7 @@ return array(
'Change assignee' => 'Ändra uppdragsinnehavare',
'Change assignee for the task "%s"' => 'Ändra uppdragsinnehavare för uppgiften "%s"',
'Timezone' => 'Tidszon',
'Sorry, I didn\'t found this information in my database!' => 'Informationen kunde inte hittas i databasen.',
'Sorry, I didn\'t find this information in my database!' => 'Informationen kunde inte hittas i databasen.',
'Page not found' => 'Sidan hittas inte',
'Complexity' => 'Ungefärligt antal timmar',
'limit' => 'max',

View File

@@ -182,7 +182,7 @@ return array(
'Change assignee' => 'เปลี่ยนการกำหนด',
'Change assignee for the task "%s"' => 'เปลี่ยนการกำหนดสำหรับงาน « %s »',
'Timezone' => 'เขตเวลา',
'Sorry, I didn\'t found this information in my database!' => 'เสียใจด้วย ไม่สามารถหาข้อมูลในฐานข้อมูลได้',
'Sorry, I didn\'t find this information in my database!' => 'เสียใจด้วย ไม่สามารถหาข้อมูลในฐานข้อมูลได้',
'Page not found' => 'ไม่พบหน้า',
'Complexity' => 'ความซับซ้อน',
'limit' => 'จำกัด',

View File

@@ -182,7 +182,7 @@ return array(
'Change assignee' => '变更负责人',
'Change assignee for the task "%s"' => '更改任务"%s"的负责人',
'Timezone' => '时区',
'Sorry, I didn\'t found this information in my database!' => '抱歉,无法在数据库中找到该信息!',
'Sorry, I didn\'t find this information in my database!' => '抱歉,无法在数据库中找到该信息!',
'Page not found' => '页面未找到',
'Complexity' => '复杂度',
'limit' => '限制',

View File

@@ -189,10 +189,6 @@ class Acl extends Base
public function isManagerActionAllowed($project_id)
{
if ($this->userSession->isAdmin()) {
return true;
}
return $project_id > 0 && $this->projectPermission->isManager($project_id, $this->userSession->getId());
}

View File

@@ -199,6 +199,7 @@ class Action extends Base
*/
public function remove($action_id)
{
// $this->container['fileCache']->remove('proxy_action_getAll');
return $this->db->table(self::TABLE)->eq('id', $action_id)->remove();
}
@@ -242,6 +243,8 @@ class Action extends Base
$this->db->closeTransaction();
// $this->container['fileCache']->remove('proxy_action_getAll');
return true;
}
@@ -252,7 +255,10 @@ class Action extends Base
*/
public function attachEvents()
{
foreach ($this->getAll() as $action) {
//$actions = $this->container['fileCache']->proxy('action', 'getAll');
$actions = $this->getAll();
foreach ($actions as $action) {
$listener = $this->load($action['action_name'], $action['project_id'], $action['event_name']);
@@ -315,6 +321,8 @@ class Action extends Base
}
}
// $this->container['fileCache']->remove('proxy_action_getAll');
return true;
}

View File

@@ -253,6 +253,23 @@ class Board extends Base
return $swimlanes;
}
/**
* Get the total of tasks per column
*
* @access public
* @param integer $project_id
* @return array
*/
public function getColumnStats($project_id)
{
return $this->db
->table(Task::TABLE)
->eq('project_id', $project_id)
->eq('is_active', 1)
->groupBy('column_id')
->listing('column_id', 'COUNT(*) AS total');
}
/**
* Get the first column id for a given project
*

View File

@@ -114,7 +114,7 @@ class Notification extends Base
}
}
catch (Swift_TransportException $e) {
$this->container['logger']->addError($e->getMessage());
$this->container['logger']->error($e->getMessage());
}
}

View File

@@ -191,11 +191,12 @@ class Project extends Base
public function getStats($project_id)
{
$stats = array();
$columns = $this->board->getColumns($project_id);
$stats['nb_active_tasks'] = 0;
$columns = $this->board->getColumns($project_id);
$column_stats = $this->board->getColumnStats($project_id);
foreach ($columns as &$column) {
$column['nb_active_tasks'] = $this->taskFinder->countByColumnId($project_id, $column['id']);
$column['nb_active_tasks'] = isset($column_stats[$column['id']]) ? $column_stats[$column['id']] : 0;
$stats['nb_active_tasks'] += $column['nb_active_tasks'];
}

View File

@@ -38,9 +38,10 @@ class ProjectPaginator extends Base
foreach ($projects as &$project) {
$project['columns'] = $this->board->getColumns($project['id']);
$stats = $this->board->getColumnStats($project['id']);
foreach ($project['columns'] as &$column) {
$column['nb_tasks'] = $this->taskFinder->countByColumnId($project['id'], $column['id']);
$column['nb_tasks'] = isset($stats[$column['id']]) ? $stats[$column['id']] : 0;
}
}

View File

@@ -298,7 +298,11 @@ class ProjectPermission extends Base
*/
public function getAllowedProjects($user_id)
{
return $this->filterProjects($this->project->getListByStatus(Project::ACTIVE), $user_id, 'isUserAllowed');
if ($this->user->isAdmin($user_id)) {
return $this->project->getListByStatus(Project::ACTIVE);
}
return $this->getMemberProjects($user_id);
}
/**
@@ -310,7 +314,11 @@ class ProjectPermission extends Base
*/
public function getMemberProjects($user_id)
{
return $this->filterProjects($this->project->getListByStatus(Project::ACTIVE), $user_id, 'isMember');
return $this->db
->table(Project::TABLE)
->eq('user_id', $user_id)
->join(self::TABLE, 'project_id', 'id')
->listing('projects.id', 'name');
}
/**

View File

@@ -216,16 +216,15 @@ class TaskFinder extends Base
* @access public
* @param integer $project_id Project id
* @param integer $column_id Column id
* @param array $status List of status id
* @return integer
*/
public function countByColumnId($project_id, $column_id, array $status = array(Task::STATUS_OPEN))
public function countByColumnId($project_id, $column_id)
{
return $this->db
->table(Task::TABLE)
->eq('project_id', $project_id)
->eq('column_id', $column_id)
->in('is_active', $status)
->in('is_active', 1)
->count();
}

View File

@@ -48,7 +48,8 @@ class User extends Base
*/
public function isAdmin($user_id)
{
return $this->db
return $this->userSession->isAdmin() || // Avoid SQL query if connected
$this->db
->table(User::TABLE)
->eq('id', $user_id)
->eq('is_admin', 1)

View File

@@ -52,6 +52,8 @@ class ClassProvider implements ServiceProviderInterface
'Core' => array(
'Template',
'Session',
'MemoryCache',
'FileCache',
),
'Integration' => array(
'GitlabWebhook',

View File

@@ -12,6 +12,7 @@ class DatabaseProvider implements ServiceProviderInterface
{
$container['db'] = $this->getInstance();
$container['db']->stopwatch = DEBUG;
$container['db']->log_queries = DEBUG;
}
/**

View File

@@ -4,19 +4,19 @@ namespace ServiceProvider;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\SyslogHandler;
use SimpleLogger\Logger;
use SimpleLogger\Syslog;
use SimpleLogger\File;
class LoggingProvider implements ServiceProviderInterface
{
public function register(Container $container)
{
$logger = new Logger('app');
$logger->pushHandler(new SyslogHandler('kanboard', LOG_USER, Logger::INFO));
$logger = new Logger;
$logger->setLogger(new Syslog('kanboard'));
if (DEBUG) {
$logger->pushHandler(new StreamHandler(__DIR__.'/../../data/debug.log', Logger::DEBUG));
$logger->setLogger(new File(__DIR__.'/../../data/debug.log'));
}
$container['logger'] = $logger;

View File

@@ -12,25 +12,22 @@ class MailerProvider implements ServiceProviderInterface
{
public function register(Container $container)
{
$container['mailer'] = $this->getInstance();
}
$container['mailer'] = function () {
switch (MAIL_TRANSPORT) {
case 'smtp':
$transport = Swift_SmtpTransport::newInstance(MAIL_SMTP_HOSTNAME, MAIL_SMTP_PORT);
$transport->setUsername(MAIL_SMTP_USERNAME);
$transport->setPassword(MAIL_SMTP_PASSWORD);
$transport->setEncryption(MAIL_SMTP_ENCRYPTION);
break;
case 'sendmail':
$transport = Swift_SendmailTransport::newInstance(MAIL_SENDMAIL_COMMAND);
break;
default:
$transport = Swift_MailTransport::newInstance();
}
public function getInstance()
{
switch (MAIL_TRANSPORT) {
case 'smtp':
$transport = Swift_SmtpTransport::newInstance(MAIL_SMTP_HOSTNAME, MAIL_SMTP_PORT);
$transport->setUsername(MAIL_SMTP_USERNAME);
$transport->setPassword(MAIL_SMTP_PASSWORD);
$transport->setEncryption(MAIL_SMTP_ENCRYPTION);
break;
case 'sendmail':
$transport = Swift_SendmailTransport::newInstance(MAIL_SENDMAIL_COMMAND);
break;
default:
$transport = Swift_MailTransport::newInstance();
}
return $transport;
return $transport;
};
}
}

View File

@@ -1,5 +1,5 @@
<section id="main">
<p class="alert alert-error">
<?= t('Sorry, I didn\'t found this information in my database!') ?>
<?= t('Sorry, I didn\'t find this information in my database!') ?>
</p>
</section>

View File

@@ -14,7 +14,7 @@
<?= $this->a('#'.$project['id'], 'board', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link') ?>
</td>
<td>
<?php if ($this->projectPermission->isManager($project['id'], $this->userSession->getId())): ?>
<?php if ($this->isManager($project['id'])): ?>
<?= $this->a('<i class="fa fa-cog"></i>', 'project', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link', t('Settings')) ?>&nbsp;
<?php endif ?>
<?= $this->a($this->e($project['name']), 'board', 'show', array('project_id' => $project['id'])) ?>

View File

@@ -63,7 +63,7 @@
<?php endif ?>
<div class="task-board-title">
<?= $this->a($this->e($task['title']), 'task', 'show', array('task_id' => $task['id']), false, '', t('View this task')) ?>
<?= $this->a($this->e($task['title']), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?>
</div>
<?php endif ?>

View File

@@ -5,7 +5,7 @@
<?= $this->a(t('Summary'), 'project', 'show', array('project_id' => $project['id'])) ?>
</li>
<?php if ($this->acl->isManagerActionAllowed($project['id'])): ?>
<?php if ($this->isManager($project['id'])): ?>
<li>
<?= $this->a(t('Public access'), 'project', 'share', array('project_id' => $project['id'])) ?>
</li>