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

1
.gitignore vendored
View File

@ -54,4 +54,5 @@ Thumbs.db
################
config.php
data/files
data/cache
vendor

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>

View File

@ -8,9 +8,9 @@
"erusev/parsedown": "1.1.1",
"lusitanian/oauth": "0.3.5",
"pimple/pimple": "~3.0",
"monolog/monolog": "1.11.0",
"symfony/console": "@stable",
"symfony/event-dispatcher": "~2.6"
"symfony/event-dispatcher": "~2.6",
"fguillot/simpleLogger": "dev-master"
},
"autoload": {
"psr-0": {"": "app/"},

122
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "b36eeeb06a0ff9d55f2342792bd6e880",
"hash": "32ca2365366d59b6b6f4fc2b5af435a7",
"packages": [
{
"name": "erusev/parsedown",
@ -88,12 +88,12 @@
"source": {
"type": "git",
"url": "https://github.com/fguillot/picoDb.git",
"reference": "682616b9accbfd719677ed0b3f478107cea2dacc"
"reference": "3ee555da2e2bda42b5d6aa9b231b534fd69db96c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fguillot/picoDb/zipball/682616b9accbfd719677ed0b3f478107cea2dacc",
"reference": "682616b9accbfd719677ed0b3f478107cea2dacc",
"url": "https://api.github.com/repos/fguillot/picoDb/zipball/3ee555da2e2bda42b5d6aa9b231b534fd69db96c",
"reference": "3ee555da2e2bda42b5d6aa9b231b534fd69db96c",
"shasum": ""
},
"require": {
@ -117,7 +117,7 @@
],
"description": "Minimalist database query builder",
"homepage": "https://github.com/fguillot/picoDb",
"time": "2014-12-31 17:44:58"
"time": "2015-01-02 22:00:06"
},
{
"name": "fguillot/simple-validator",
@ -156,6 +156,43 @@
"homepage": "https://github.com/fguillot/simpleValidator",
"time": "2014-11-25 22:58:14"
},
{
"name": "fguillot/simpleLogger",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/fguillot/simpleLogger.git",
"reference": "81df5643931d97e0101b4757d9454dbcb13a3fa9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fguillot/simpleLogger/zipball/81df5643931d97e0101b4757d9454dbcb13a3fa9",
"reference": "81df5643931d97e0101b4757d9454dbcb13a3fa9",
"shasum": ""
},
"require": {
"php": ">=5.3.0",
"psr/log": "~1.0"
},
"type": "library",
"autoload": {
"psr-0": {
"SimpleLogger": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Frédéric Guillot"
}
],
"description": "PHP library to write logs (compatible with PSR-3)",
"homepage": "https://github.com/fguillot/simpleLogger",
"time": "2015-01-02 03:40:21"
},
{
"name": "ircmaxell/password-compat",
"version": "1.0.3",
@ -257,78 +294,6 @@
],
"time": "2014-09-05 15:19:58"
},
{
"name": "monolog/monolog",
"version": "1.11.0",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "ec3961874c43840e96da3a8a1ed20d8c73d7e5aa"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/ec3961874c43840e96da3a8a1ed20d8c73d7e5aa",
"reference": "ec3961874c43840e96da3a8a1ed20d8c73d7e5aa",
"shasum": ""
},
"require": {
"php": ">=5.3.0",
"psr/log": "~1.0"
},
"provide": {
"psr/log-implementation": "1.0.0"
},
"require-dev": {
"aws/aws-sdk-php": "~2.4, >2.4.8",
"doctrine/couchdb": "~1.0@dev",
"graylog2/gelf-php": "~1.0",
"phpunit/phpunit": "~3.7.0",
"raven/raven": "~0.5",
"ruflin/elastica": "0.90.*",
"videlalvaro/php-amqplib": "~2.4"
},
"suggest": {
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
"doctrine/couchdb": "Allow sending log messages to a CouchDB server",
"ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
"ext-mongo": "Allow sending log messages to a MongoDB server",
"graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
"raven/raven": "Allow sending log messages to a Sentry server",
"rollbar/rollbar": "Allow sending log messages to Rollbar",
"ruflin/elastica": "Allow sending log messages to an Elastic Search server",
"videlalvaro/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.11.x-dev"
}
},
"autoload": {
"psr-4": {
"Monolog\\": "src/Monolog"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jordi Boggiano",
"email": "j.boggiano@seld.be",
"homepage": "http://seld.be"
}
],
"description": "Sends your logs to files, sockets, inboxes, databases and various web services",
"homepage": "http://github.com/Seldaek/monolog",
"keywords": [
"log",
"logging",
"psr-3"
],
"time": "2014-09-30 13:30:58"
},
{
"name": "pimple/pimple",
"version": "v3.0.0",
@ -637,7 +602,8 @@
"swiftmailer/swiftmailer": 0,
"fguillot/json-rpc": 20,
"fguillot/picodb": 20,
"symfony/console": 0
"symfony/console": 0,
"fguillot/simplelogger": 20
},
"prefer-stable": false,
"platform": [],