Browse Source

Merge branch '1.9.x' of github.com:chamilo/chamilo-lms into 1.9.x

Yannick Warnier 10 years ago
parent
commit
48c55c6f3e
100 changed files with 7935 additions and 298 deletions
  1. 1 1
      vendor/autoload.php
  2. 1 0
      vendor/bin/generate_vcards
  3. 1 0
      vendor/bin/vobject
  4. 10 0
      vendor/composer/autoload_psr4.php
  5. 4 4
      vendor/composer/autoload_real.php
  6. 217 217
      vendor/composer/installed.json
  7. 19 0
      vendor/monolog/monolog/CHANGELOG.mdown
  8. 6 2
      vendor/monolog/monolog/README.mdown
  9. 1 1
      vendor/monolog/monolog/composer.json
  10. 1 1
      vendor/monolog/monolog/src/Monolog/ErrorHandler.php
  11. 87 0
      vendor/monolog/monolog/src/Monolog/Formatter/ElasticaFormatter.php
  12. 104 0
      vendor/monolog/monolog/src/Monolog/Formatter/FlowdockFormatter.php
  13. 127 0
      vendor/monolog/monolog/src/Monolog/Formatter/HtmlFormatter.php
  14. 22 11
      vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php
  15. 47 0
      vendor/monolog/monolog/src/Monolog/Formatter/LogglyFormatter.php
  16. 43 24
      vendor/monolog/monolog/src/Monolog/Formatter/LogstashFormatter.php
  17. 48 0
      vendor/monolog/monolog/src/Monolog/Formatter/ScalarFormatter.php
  18. 13 2
      vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php
  19. 92 0
      vendor/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php
  20. 1 1
      vendor/monolog/monolog/src/Monolog/Handler/AmqpHandler.php
  21. 184 0
      vendor/monolog/monolog/src/Monolog/Handler/BrowserConsoleHandler.php
  22. 7 3
      vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.php
  23. 15 6
      vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php
  24. 1 1
      vendor/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php
  25. 89 0
      vendor/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php
  26. 128 0
      vendor/monolog/monolog/src/Monolog/Handler/ElasticSearchHandler.php
  27. 9 0
      vendor/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php
  28. 131 0
      vendor/monolog/monolog/src/Monolog/Handler/FilterHandler.php
  29. 17 6
      vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php
  30. 103 0
      vendor/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php
  31. 57 0
      vendor/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php
  32. 93 0
      vendor/monolog/monolog/src/Monolog/Handler/LogglyHandler.php
  33. 17 0
      vendor/monolog/monolog/src/Monolog/Handler/PushoverHandler.php
  34. 9 0
      vendor/monolog/monolog/src/Monolog/Handler/RavenHandler.php
  35. 64 0
      vendor/monolog/monolog/src/Monolog/Handler/RollbarHandler.php
  36. 8 5
      vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php
  37. 11 4
      vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php
  38. 62 0
      vendor/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.php
  39. 80 0
      vendor/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php
  40. 1 1
      vendor/monolog/monolog/src/Monolog/Logger.php
  41. 64 0
      vendor/monolog/monolog/src/Monolog/Processor/GitProcessor.php
  42. 1 1
      vendor/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php
  43. 20 6
      vendor/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php
  44. 1 1
      vendor/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php
  45. 34 0
      vendor/monolog/monolog/src/Monolog/Processor/TagProcessor.php
  46. 118 0
      vendor/monolog/monolog/src/Monolog/Registry.php
  47. 31 0
      vendor/monolog/monolog/tests/Monolog/ErrorHandlerTest.php
  48. 158 0
      vendor/monolog/monolog/tests/Monolog/Formatter/ChromePHPFormatterTest.php
  49. 79 0
      vendor/monolog/monolog/tests/Monolog/Formatter/ElasticaFormatterTest.php
  50. 55 0
      vendor/monolog/monolog/tests/Monolog/Formatter/FlowdockFormatterTest.php
  51. 191 0
      vendor/monolog/monolog/tests/Monolog/Formatter/GelfMessageFormatterTest.php
  52. 79 0
      vendor/monolog/monolog/tests/Monolog/Formatter/JsonFormatterTest.php
  53. 194 0
      vendor/monolog/monolog/tests/Monolog/Formatter/LineFormatterTest.php
  54. 40 0
      vendor/monolog/monolog/tests/Monolog/Formatter/LogglyFormatterTest.php
  55. 292 0
      vendor/monolog/monolog/tests/Monolog/Formatter/LogstashFormatterTest.php
  56. 182 0
      vendor/monolog/monolog/tests/Monolog/Formatter/NormalizerFormatterTest.php
  57. 96 0
      vendor/monolog/monolog/tests/Monolog/Formatter/ScalarFormatterTest.php
  58. 142 0
      vendor/monolog/monolog/tests/Monolog/Formatter/WildfireFormatterTest.php
  59. 32 0
      vendor/monolog/monolog/tests/Monolog/Functional/Handler/FirePHPHandlerTest.php
  60. 104 0
      vendor/monolog/monolog/tests/Monolog/Handler/AbstractHandlerTest.php
  61. 80 0
      vendor/monolog/monolog/tests/Monolog/Handler/AbstractProcessingHandlerTest.php
  62. 80 0
      vendor/monolog/monolog/tests/Monolog/Handler/AmqpHandlerTest.php
  63. 131 0
      vendor/monolog/monolog/tests/Monolog/Handler/BrowserConsoleHandlerTest.php
  64. 149 0
      vendor/monolog/monolog/tests/Monolog/Handler/BufferHandlerTest.php
  65. 141 0
      vendor/monolog/monolog/tests/Monolog/Handler/ChromePHPHandlerTest.php
  66. 41 0
      vendor/monolog/monolog/tests/Monolog/Handler/CouchDBHandlerTest.php
  67. 52 0
      vendor/monolog/monolog/tests/Monolog/Handler/DoctrineCouchDBHandlerTest.php
  68. 73 0
      vendor/monolog/monolog/tests/Monolog/Handler/DynamoDbHandlerTest.php
  69. 239 0
      vendor/monolog/monolog/tests/Monolog/Handler/ElasticSearchHandlerTest.php
  70. 43 0
      vendor/monolog/monolog/tests/Monolog/Handler/ErrorLogHandlerTest.php
  71. 151 0
      vendor/monolog/monolog/tests/Monolog/Handler/FilterHandlerTest.php
  72. 189 0
      vendor/monolog/monolog/tests/Monolog/Handler/FingersCrossedHandlerTest.php
  73. 96 0
      vendor/monolog/monolog/tests/Monolog/Handler/FirePHPHandlerTest.php
  74. 0 0
      vendor/monolog/monolog/tests/Monolog/Handler/Fixtures/.gitkeep
  75. 88 0
      vendor/monolog/monolog/tests/Monolog/Handler/FlowdockHandlerTest.php
  76. 93 0
      vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerLegacyTest.php
  77. 119 0
      vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerTest.php
  78. 89 0
      vendor/monolog/monolog/tests/Monolog/Handler/GroupHandlerTest.php
  79. 167 0
      vendor/monolog/monolog/tests/Monolog/Handler/HipChatHandlerTest.php
  80. 84 0
      vendor/monolog/monolog/tests/Monolog/Handler/LogEntriesHandlerTest.php
  81. 75 0
      vendor/monolog/monolog/tests/Monolog/Handler/MailHandlerTest.php
  82. 26 0
      vendor/monolog/monolog/tests/Monolog/Handler/MockRavenClient.php
  83. 63 0
      vendor/monolog/monolog/tests/Monolog/Handler/MongoDBHandlerTest.php
  84. 43 0
      vendor/monolog/monolog/tests/Monolog/Handler/NativeMailerHandlerTest.php
  85. 102 0
      vendor/monolog/monolog/tests/Monolog/Handler/NewRelicHandlerTest.php
  86. 33 0
      vendor/monolog/monolog/tests/Monolog/Handler/NullHandlerTest.php
  87. 142 0
      vendor/monolog/monolog/tests/Monolog/Handler/PushoverHandlerTest.php
  88. 150 0
      vendor/monolog/monolog/tests/Monolog/Handler/RavenHandlerTest.php
  89. 71 0
      vendor/monolog/monolog/tests/Monolog/Handler/RedisHandlerTest.php
  90. 99 0
      vendor/monolog/monolog/tests/Monolog/Handler/RotatingFileHandlerTest.php
  91. 283 0
      vendor/monolog/monolog/tests/Monolog/Handler/SocketHandlerTest.php
  92. 88 0
      vendor/monolog/monolog/tests/Monolog/Handler/StreamHandlerTest.php
  93. 43 0
      vendor/monolog/monolog/tests/Monolog/Handler/SyslogHandlerTest.php
  94. 37 0
      vendor/monolog/monolog/tests/Monolog/Handler/SyslogUdpHandlerTest.php
  95. 56 0
      vendor/monolog/monolog/tests/Monolog/Handler/TestHandlerTest.php
  96. 45 0
      vendor/monolog/monolog/tests/Monolog/Handler/UdpSocketTest.php
  97. 69 0
      vendor/monolog/monolog/tests/Monolog/Handler/ZendMonitorHandlerTest.php
  98. 409 0
      vendor/monolog/monolog/tests/Monolog/LoggerTest.php
  99. 29 0
      vendor/monolog/monolog/tests/Monolog/Processor/GitProcessorTest.php
  100. 123 0
      vendor/monolog/monolog/tests/Monolog/Processor/IntrospectionProcessorTest.php

+ 1 - 1
vendor/autoload.php

@@ -4,4 +4,4 @@
 
 require_once __DIR__ . '/composer' . '/autoload_real.php';
 
-return ComposerAutoloaderInitc8544b9da483382b715efa095e59273d::getLoader();
+return ComposerAutoloaderInit08a6911999fe3a5a9a895c13400e7221::getLoader();

+ 1 - 0
vendor/bin/generate_vcards

@@ -0,0 +1 @@
+../sabre/vobject/bin/generate_vcards

+ 1 - 0
vendor/bin/vobject

@@ -0,0 +1 @@
+../sabre/vobject/bin/vobject

+ 10 - 0
vendor/composer/autoload_psr4.php

@@ -0,0 +1,10 @@
+<?php
+
+// autoload_psr4.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+    'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
+);

+ 4 - 4
vendor/composer/autoload_real.php

@@ -2,7 +2,7 @@
 
 // autoload_real.php @generated by Composer
 
-class ComposerAutoloaderInitc8544b9da483382b715efa095e59273d
+class ComposerAutoloaderInit08a6911999fe3a5a9a895c13400e7221
 {
     private static $loader;
 
@@ -19,9 +19,9 @@ class ComposerAutoloaderInitc8544b9da483382b715efa095e59273d
             return self::$loader;
         }
 
-        spl_autoload_register(array('ComposerAutoloaderInitc8544b9da483382b715efa095e59273d', 'loadClassLoader'), true, true);
+        spl_autoload_register(array('ComposerAutoloaderInit08a6911999fe3a5a9a895c13400e7221', 'loadClassLoader'), true, true);
         self::$loader = $loader = new \Composer\Autoload\ClassLoader();
-        spl_autoload_unregister(array('ComposerAutoloaderInitc8544b9da483382b715efa095e59273d', 'loadClassLoader'));
+        spl_autoload_unregister(array('ComposerAutoloaderInit08a6911999fe3a5a9a895c13400e7221', 'loadClassLoader'));
 
         $vendorDir = dirname(__DIR__);
         $baseDir = dirname($vendorDir);
@@ -47,7 +47,7 @@ class ComposerAutoloaderInitc8544b9da483382b715efa095e59273d
     }
 }
 
-function composerRequirec8544b9da483382b715efa095e59273d($file)
+function composerRequire08a6911999fe3a5a9a895c13400e7221($file)
 {
     require $file;
 }

+ 217 - 217
vendor/composer/installed.json

@@ -1,97 +1,4 @@
 [
-    {
-        "name": "symfony/filesystem",
-        "version": "v2.4.3",
-        "version_normalized": "2.4.3.0",
-        "target-dir": "Symfony/Component/Filesystem",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/symfony/Filesystem.git",
-            "reference": "b717952487176a993e9b12a08b87beae25ae419c"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/symfony/Filesystem/zipball/b717952487176a993e9b12a08b87beae25ae419c",
-            "reference": "b717952487176a993e9b12a08b87beae25ae419c",
-            "shasum": ""
-        },
-        "require": {
-            "php": ">=5.3.3"
-        },
-        "time": "2014-03-26 11:55:03",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "2.4-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-0": {
-                "Symfony\\Component\\Filesystem\\": ""
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Fabien Potencier",
-                "email": "fabien@symfony.com",
-                "homepage": "http://fabien.potencier.org",
-                "role": "Lead Developer"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "http://symfony.com/contributors"
-            }
-        ],
-        "description": "Symfony Filesystem Component",
-        "homepage": "http://symfony.com"
-    },
-    {
-        "name": "neutron/temporary-filesystem",
-        "version": "2.1.1",
-        "version_normalized": "2.1.1.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/romainneutron/Temporary-Filesystem.git",
-            "reference": "6b21fa99fd452efea16b9a7adb7304ccfff854d0"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/romainneutron/Temporary-Filesystem/zipball/6b21fa99fd452efea16b9a7adb7304ccfff854d0",
-            "reference": "6b21fa99fd452efea16b9a7adb7304ccfff854d0",
-            "shasum": ""
-        },
-        "require": {
-            "symfony/filesystem": "~2.0"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "~3.7"
-        },
-        "time": "2013-10-10 10:58:09",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-0": {
-                "Neutron": "src"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Romain Neutron",
-                "email": "imprec@gmail.com",
-                "homepage": "http://www.lickmychip.com/"
-            }
-        ],
-        "description": "Symfony filesystem extension to handle temporary files"
-    },
     {
         "name": "evenement/evenement",
         "version": "v1.0.0",
@@ -211,35 +118,76 @@
         ]
     },
     {
-        "name": "symfony/process",
-        "version": "v2.4.3",
-        "version_normalized": "2.4.3.0",
-        "target-dir": "Symfony/Component/Process",
+        "name": "psr/log",
+        "version": "1.0.0",
+        "version_normalized": "1.0.0.0",
         "source": {
             "type": "git",
-            "url": "https://github.com/symfony/Process.git",
-            "reference": "c09c3b08455c35688eee3e481fdfc85518ef01d7"
+            "url": "https://github.com/php-fig/log.git",
+            "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
+            "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
+            "shasum": ""
+        },
+        "time": "2012-12-21 11:40:51",
+        "type": "library",
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Psr\\Log\\": ""
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "PHP-FIG",
+                "homepage": "http://www.php-fig.org/"
+            }
+        ],
+        "description": "Common interface for logging libraries",
+        "keywords": [
+            "log",
+            "psr",
+            "psr-3"
+        ]
+    },
+    {
+        "name": "alchemy/binary-driver",
+        "version": "1.5.0",
+        "version_normalized": "1.5.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/alchemy-fr/BinaryDriver.git",
+            "reference": "b32c03d4b56ce29f783051eac55887adae654b41"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/symfony/Process/zipball/c09c3b08455c35688eee3e481fdfc85518ef01d7",
-            "reference": "c09c3b08455c35688eee3e481fdfc85518ef01d7",
+            "url": "https://api.github.com/repos/alchemy-fr/BinaryDriver/zipball/b32c03d4b56ce29f783051eac55887adae654b41",
+            "reference": "b32c03d4b56ce29f783051eac55887adae654b41",
             "shasum": ""
         },
         "require": {
-            "php": ">=5.3.3"
+            "evenement/evenement": "~1.0",
+            "monolog/monolog": "~1.3",
+            "php": ">=5.3.3",
+            "psr/log": "~1.0",
+            "symfony/process": "~2.0"
         },
-        "time": "2014-03-26 11:35:33",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "2.4-dev"
-            }
+        "require-dev": {
+            "phpunit/phpunit": "~3.7"
         },
+        "time": "2013-06-21 15:51:20",
+        "type": "library",
         "installation-source": "dist",
         "autoload": {
             "psr-0": {
-                "Symfony\\Component\\Process\\": ""
+                "Alchemy": "src"
             }
         },
         "notification-url": "https://packagist.org/downloads/",
@@ -248,40 +196,67 @@
         ],
         "authors": [
             {
-                "name": "Fabien Potencier",
-                "email": "fabien@symfony.com",
-                "homepage": "http://fabien.potencier.org",
-                "role": "Lead Developer"
+                "name": "Romain Neutron",
+                "email": "imprec@gmail.com",
+                "homepage": "http://www.lickmychip.com/"
             },
             {
-                "name": "Symfony Community",
-                "homepage": "http://symfony.com/contributors"
+                "name": "Nicolas Le Goff",
+                "email": "legoff.n@gmail.com"
+            },
+            {
+                "name": "Phraseanet Team",
+                "email": "info@alchemy.fr",
+                "homepage": "http://www.phraseanet.com/"
             }
         ],
-        "description": "Symfony Process Component",
-        "homepage": "http://symfony.com"
+        "description": "A set of tools to build binary drivers",
+        "keywords": [
+            "binary",
+            "driver"
+        ]
     },
     {
-        "name": "psr/log",
-        "version": "1.0.0",
-        "version_normalized": "1.0.0.0",
+        "name": "php-ffmpeg/php-ffmpeg",
+        "version": "0.3.x-dev",
+        "version_normalized": "0.3.9999999.9999999-dev",
         "source": {
             "type": "git",
-            "url": "https://github.com/php-fig/log.git",
-            "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
+            "url": "https://github.com/PHP-FFMpeg/PHP-FFMpeg.git",
+            "reference": "185fb5c33da594db7ffbf3f89d48e9841bc666a0"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
-            "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
+            "url": "https://api.github.com/repos/PHP-FFMpeg/PHP-FFMpeg/zipball/185fb5c33da594db7ffbf3f89d48e9841bc666a0",
+            "reference": "185fb5c33da594db7ffbf3f89d48e9841bc666a0",
             "shasum": ""
         },
-        "time": "2012-12-21 11:40:51",
+        "require": {
+            "alchemy/binary-driver": "~1.5",
+            "doctrine/cache": "~1.0",
+            "evenement/evenement": "~1.0",
+            "neutron/temporary-filesystem": "~2.1, >=2.1.1",
+            "php": ">=5.3.3"
+        },
+        "require-dev": {
+            "phpunit/phpunit": "~3.7",
+            "sami/sami": "~1.0",
+            "silex/silex": "~1.0"
+        },
+        "suggest": {
+            "php-ffmpeg/extras": "A compilation of common audio & video drivers for PHP-FFMpeg"
+        },
+        "time": "2013-10-21 12:13:46",
         "type": "library",
-        "installation-source": "dist",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "0.4-dev"
+            }
+        },
+        "installation-source": "source",
         "autoload": {
             "psr-0": {
-                "Psr\\Log\\": ""
+                "FFMpeg": "src"
             }
         },
         "notification-url": "https://packagist.org/downloads/",
@@ -290,30 +265,41 @@
         ],
         "authors": [
             {
-                "name": "PHP-FIG",
-                "homepage": "http://www.php-fig.org/"
+                "name": "Romain Neutron",
+                "email": "imprec@gmail.com",
+                "homepage": "http://www.lickmychip.com/"
+            },
+            {
+                "name": "Phraseanet Team",
+                "email": "info@alchemy.fr",
+                "homepage": "http://www.phraseanet.com/"
             }
         ],
-        "description": "Common interface for logging libraries",
+        "description": "FFMpeg PHP, an Object Oriented library to communicate with AVconv / ffmpeg",
         "keywords": [
-            "log",
-            "psr",
-            "psr-3"
+            "audio",
+            "audio processing",
+            "avconv",
+            "avprobe",
+            "ffmpeg",
+            "ffprobe",
+            "video",
+            "video processing"
         ]
     },
     {
         "name": "monolog/monolog",
-        "version": "1.8.0",
-        "version_normalized": "1.8.0.0",
+        "version": "1.9.1",
+        "version_normalized": "1.9.1.0",
         "source": {
             "type": "git",
             "url": "https://github.com/Seldaek/monolog.git",
-            "reference": "392ef35fd470638e08d0160d6b1cbab63cb23174"
+            "reference": "65026b610f8c19e61d7242f600530677b0466aac"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/Seldaek/monolog/zipball/392ef35fd470638e08d0160d6b1cbab63cb23174",
-            "reference": "392ef35fd470638e08d0160d6b1cbab63cb23174",
+            "url": "https://api.github.com/repos/Seldaek/monolog/zipball/65026b610f8c19e61d7242f600530677b0466aac",
+            "reference": "65026b610f8c19e61d7242f600530677b0466aac",
             "shasum": ""
         },
         "require": {
@@ -338,11 +324,11 @@
             "rollbar/rollbar": "Allow sending log messages to Rollbar",
             "ruflin/elastica": "Allow sending log messages to an Elastic Search server"
         },
-        "time": "2014-03-23 19:50:26",
+        "time": "2014-04-24 13:29:03",
         "type": "library",
         "extra": {
             "branch-alias": {
-                "dev-master": "1.8.x-dev"
+                "dev-master": "1.9.x-dev"
             }
         },
         "installation-source": "dist",
@@ -372,36 +358,35 @@
         ]
     },
     {
-        "name": "alchemy/binary-driver",
-        "version": "1.5.0",
-        "version_normalized": "1.5.0.0",
+        "name": "symfony/process",
+        "version": "v2.4.5",
+        "version_normalized": "2.4.5.0",
+        "target-dir": "Symfony/Component/Process",
         "source": {
             "type": "git",
-            "url": "https://github.com/alchemy-fr/BinaryDriver.git",
-            "reference": "b32c03d4b56ce29f783051eac55887adae654b41"
+            "url": "https://github.com/symfony/Process.git",
+            "reference": "a7118cb290c62068b3c8ecfbf8b2eda8421fb841"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/alchemy-fr/BinaryDriver/zipball/b32c03d4b56ce29f783051eac55887adae654b41",
-            "reference": "b32c03d4b56ce29f783051eac55887adae654b41",
+            "url": "https://api.github.com/repos/symfony/Process/zipball/a7118cb290c62068b3c8ecfbf8b2eda8421fb841",
+            "reference": "a7118cb290c62068b3c8ecfbf8b2eda8421fb841",
             "shasum": ""
         },
         "require": {
-            "evenement/evenement": "~1.0",
-            "monolog/monolog": "~1.3",
-            "php": ">=5.3.3",
-            "psr/log": "~1.0",
-            "symfony/process": "~2.0"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "~3.7"
+            "php": ">=5.3.3"
         },
-        "time": "2013-06-21 15:51:20",
+        "time": "2014-05-22 13:46:01",
         "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "2.4-dev"
+            }
+        },
         "installation-source": "dist",
         "autoload": {
             "psr-0": {
-                "Alchemy": "src"
+                "Symfony\\Component\\Process\\": ""
             }
         },
         "notification-url": "https://packagist.org/downloads/",
@@ -410,67 +395,97 @@
         ],
         "authors": [
             {
-                "name": "Romain Neutron",
-                "email": "imprec@gmail.com",
-                "homepage": "http://www.lickmychip.com/"
-            },
-            {
-                "name": "Nicolas Le Goff",
-                "email": "legoff.n@gmail.com"
+                "name": "Fabien Potencier",
+                "email": "fabien@symfony.com",
+                "homepage": "http://fabien.potencier.org",
+                "role": "Lead Developer"
             },
             {
-                "name": "Phraseanet Team",
-                "email": "info@alchemy.fr",
-                "homepage": "http://www.phraseanet.com/"
+                "name": "Symfony Community",
+                "homepage": "http://symfony.com/contributors"
             }
         ],
-        "description": "A set of tools to build binary drivers",
-        "keywords": [
-            "binary",
-            "driver"
-        ]
+        "description": "Symfony Process Component",
+        "homepage": "http://symfony.com"
     },
     {
-        "name": "php-ffmpeg/php-ffmpeg",
-        "version": "0.3.x-dev",
-        "version_normalized": "0.3.9999999.9999999-dev",
+        "name": "symfony/filesystem",
+        "version": "v2.4.5",
+        "version_normalized": "2.4.5.0",
+        "target-dir": "Symfony/Component/Filesystem",
         "source": {
             "type": "git",
-            "url": "https://github.com/PHP-FFMpeg/PHP-FFMpeg.git",
-            "reference": "185fb5c33da594db7ffbf3f89d48e9841bc666a0"
+            "url": "https://github.com/symfony/Filesystem.git",
+            "reference": "a3af8294bcce4a7c1b2892363b0c9d8109affad4"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/PHP-FFMpeg/PHP-FFMpeg/zipball/185fb5c33da594db7ffbf3f89d48e9841bc666a0",
-            "reference": "185fb5c33da594db7ffbf3f89d48e9841bc666a0",
+            "url": "https://api.github.com/repos/symfony/Filesystem/zipball/a3af8294bcce4a7c1b2892363b0c9d8109affad4",
+            "reference": "a3af8294bcce4a7c1b2892363b0c9d8109affad4",
             "shasum": ""
         },
         "require": {
-            "alchemy/binary-driver": "~1.5",
-            "doctrine/cache": "~1.0",
-            "evenement/evenement": "~1.0",
-            "neutron/temporary-filesystem": "~2.1, >=2.1.1",
             "php": ">=5.3.3"
         },
-        "require-dev": {
-            "phpunit/phpunit": "~3.7",
-            "sami/sami": "~1.0",
-            "silex/silex": "~1.0"
-        },
-        "suggest": {
-            "php-ffmpeg/extras": "A compilation of common audio & video drivers for PHP-FFMpeg"
-        },
-        "time": "2013-10-21 12:13:46",
+        "time": "2014-04-16 10:34:31",
         "type": "library",
         "extra": {
             "branch-alias": {
-                "dev-master": "0.4-dev"
+                "dev-master": "2.4-dev"
             }
         },
-        "installation-source": "source",
+        "installation-source": "dist",
         "autoload": {
             "psr-0": {
-                "FFMpeg": "src"
+                "Symfony\\Component\\Filesystem\\": ""
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Fabien Potencier",
+                "email": "fabien@symfony.com",
+                "homepage": "http://fabien.potencier.org",
+                "role": "Lead Developer"
+            },
+            {
+                "name": "Symfony Community",
+                "homepage": "http://symfony.com/contributors"
+            }
+        ],
+        "description": "Symfony Filesystem Component",
+        "homepage": "http://symfony.com"
+    },
+    {
+        "name": "neutron/temporary-filesystem",
+        "version": "2.1.1",
+        "version_normalized": "2.1.1.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/romainneutron/Temporary-Filesystem.git",
+            "reference": "6b21fa99fd452efea16b9a7adb7304ccfff854d0"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/romainneutron/Temporary-Filesystem/zipball/6b21fa99fd452efea16b9a7adb7304ccfff854d0",
+            "reference": "6b21fa99fd452efea16b9a7adb7304ccfff854d0",
+            "shasum": ""
+        },
+        "require": {
+            "symfony/filesystem": "~2.0"
+        },
+        "require-dev": {
+            "phpunit/phpunit": "~3.7"
+        },
+        "time": "2013-10-10 10:58:09",
+        "type": "library",
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Neutron": "src"
             }
         },
         "notification-url": "https://packagist.org/downloads/",
@@ -482,38 +497,23 @@
                 "name": "Romain Neutron",
                 "email": "imprec@gmail.com",
                 "homepage": "http://www.lickmychip.com/"
-            },
-            {
-                "name": "Phraseanet Team",
-                "email": "info@alchemy.fr",
-                "homepage": "http://www.phraseanet.com/"
             }
         ],
-        "description": "FFMpeg PHP, an Object Oriented library to communicate with AVconv / ffmpeg",
-        "keywords": [
-            "audio",
-            "audio processing",
-            "avconv",
-            "avprobe",
-            "ffmpeg",
-            "ffprobe",
-            "video",
-            "video processing"
-        ]
+        "description": "Symfony filesystem extension to handle temporary files"
     },
     {
         "name": "sabre/vobject",
-        "version": "3.2.0",
-        "version_normalized": "3.2.0.0",
+        "version": "3.2.2",
+        "version_normalized": "3.2.2.0",
         "source": {
             "type": "git",
             "url": "https://github.com/fruux/sabre-vobject.git",
-            "reference": "dd1dd19b6601cdc99408b70ec260052825f70b8f"
+            "reference": "a829266cebcaccf602bde3af2c7e85a952034a16"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/fruux/sabre-vobject/zipball/dd1dd19b6601cdc99408b70ec260052825f70b8f",
-            "reference": "dd1dd19b6601cdc99408b70ec260052825f70b8f",
+            "url": "https://api.github.com/repos/fruux/sabre-vobject/zipball/a829266cebcaccf602bde3af2c7e85a952034a16",
+            "reference": "a829266cebcaccf602bde3af2c7e85a952034a16",
             "shasum": ""
         },
         "require": {
@@ -523,7 +523,7 @@
         "require-dev": {
             "phpunit/phpunit": "*"
         },
-        "time": "2014-04-02 23:53:27",
+        "time": "2014-05-07 20:02:21",
         "bin": [
             "bin/vobject",
             "bin/generate_vcards"

+ 19 - 0
vendor/monolog/monolog/CHANGELOG.mdown

@@ -1,3 +1,22 @@
+### 1.9.1 (2014-04-24)
+
+  * Fixed regression in RotatingFileHandler file permissions
+  * Fixed initialization of the BufferHandler to make sure it gets flushed after receiving records
+  * Fixed ChromePHPHandler and FirePHPHandler's activation strategies to be more conservative
+
+### 1.9.0 (2014-04-20)
+
+  * Added LogEntriesHandler to send logs to a LogEntries account
+  * Added $filePermissions to tweak file mode on StreamHandler and RotatingFileHandler
+  * Added $useFormatting flag to MemoryProcessor to make it send raw data in bytes
+  * Added support for table formatting in FirePHPHandler via the table context key
+  * Added a TagProcessor to add tags to records, and support for tags in RavenHandler
+  * Added $appendNewline flag to the JsonFormatter to enable using it when logging to files
+  * Added sound support to the PushoverHandler
+  * Fixed multi-threading support in StreamHandler
+  * Fixed empty headers issue when ChromePHPHandler received no records
+  * Fixed default format of the ErrorLogHandler
+
 ### 1.8.0 (2014-03-23)
 
   * Break: the LineFormatter now strips newlines by default because this was a bug, set $allowInlineLineBreaks to true if you need them

+ 6 - 2
vendor/monolog/monolog/README.mdown

@@ -136,6 +136,7 @@ Handlers
 - _LogglyHandler_: Logs records to a [Loggly](http://www.loggly.com/) account.
 - _RollbarHandler_: Logs records to a [Rollbar](https://rollbar.com/) account.
 - _SyslogUdpHandler_: Logs records to a remote [Syslogd](http://www.rsyslog.com/) server.
+- _LogEntriesHandler_: Logs records to a [LogEntries](http://logentries.com/) account.
 
 ### Logging in development
 
@@ -206,10 +207,14 @@ Processors
 - _ProcessIdProcessor_: Adds the process id to a log record.
 - _UidProcessor_: Adds a unique identifier to a log record.
 - _GitProcessor_: Adds the current git branch and commit to a log record.
+- _TagProcessor_: Adds an array of predefined tags to a log record.
 
 Utilities
 ---------
 
+- _Registry_: The `Monolog\Registry` class lets you configure global loggers that you
+  can then statically access from anywhere. It is not really a best practice but can
+  help in some older codebases or for ease of use.
 - _ErrorHandler_: The `Monolog\ErrorHandler` class allows you to easily register
   a Logger instance as an exception handler, error handler or fatal error handler.
 - _ErrorLevelActivationStrategy_: Activates a FingersCrossedHandler when a certain log
@@ -223,8 +228,7 @@ About
 Requirements
 ------------
 
-- Any flavor of PHP 5.3 or above should do
-- [optional] PHPUnit 3.5+ to execute the test suite (phpunit --version)
+- Monolog works with PHP 5.3 or above, and is also tested to work with HHVM.
 
 Submitting bugs and feature requests
 ------------------------------------

+ 1 - 1
vendor/monolog/monolog/composer.json

@@ -39,7 +39,7 @@
     },
     "extra": {
         "branch-alias": {
-            "dev-master": "1.8.x-dev"
+            "dev-master": "1.9.x-dev"
         }
     }
 }

+ 1 - 1
vendor/monolog/monolog/src/Monolog/ErrorHandler.php

@@ -123,7 +123,7 @@ class ErrorHandler
     {
         $this->logger->log(
             $this->uncaughtExceptionLevel === null ? LogLevel::ERROR : $this->uncaughtExceptionLevel,
-            'Uncaught exception',
+            sprintf('Uncaught Exception %s: "%s" at %s line %s', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine()),
             array('exception' => $e)
         );
 

+ 87 - 0
vendor/monolog/monolog/src/Monolog/Formatter/ElasticaFormatter.php

@@ -0,0 +1,87 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use Elastica\Document;
+
+/**
+ * Format a log message into an Elastica Document
+ *
+ * @author Jelle Vink <jelle.vink@gmail.com>
+ */
+class ElasticaFormatter extends NormalizerFormatter
+{
+    /**
+     * @var string Elastic search index name
+     */
+    protected $index;
+
+    /**
+     * @var string Elastic search document type
+     */
+    protected $type;
+
+    /**
+     * @param string $index Elastic Search index name
+     * @param string $type  Elastic Search document type
+     */
+    public function __construct($index, $type)
+    {
+        parent::__construct(\DateTime::ISO8601);
+        $this->index = $index;
+        $this->type = $type;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function format(array $record)
+    {
+        $record = parent::format($record);
+
+        return $this->getDocument($record);
+    }
+
+    /**
+     * Getter index
+     * @return string
+     */
+    public function getIndex()
+    {
+        return $this->index;
+    }
+
+    /**
+     * Getter type
+     * @return string
+     */
+    public function getType()
+    {
+        return $this->type;
+    }
+
+    /**
+     * Convert a log message into an Elastica Document
+     *
+     * @param  array    $record Log message
+     * @return Document
+     */
+    protected function getDocument($record)
+    {
+        $document = new Document();
+        $document->setData($record);
+        $document->setType($this->type);
+        $document->setIndex($this->index);
+
+        return $document;
+    }
+}

+ 104 - 0
vendor/monolog/monolog/src/Monolog/Formatter/FlowdockFormatter.php

@@ -0,0 +1,104 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+/**
+ * formats the record to be used in the FlowdockHandler
+ *
+ * @author Dominik Liebler <liebler.dominik@gmail.com>
+ */
+class FlowdockFormatter implements FormatterInterface
+{
+    /**
+     * @var string
+     */
+    private $source;
+
+    /**
+     * @var string
+     */
+    private $sourceEmail;
+
+    /**
+     * @param string $source
+     * @param string $sourceEmail
+     */
+    public function __construct($source, $sourceEmail)
+    {
+        $this->source = $source;
+        $this->sourceEmail = $sourceEmail;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function format(array $record)
+    {
+        $tags = array(
+            '#logs',
+            '#' . strtolower($record['level_name']),
+            '#' . $record['channel'],
+        );
+
+        foreach ($record['extra'] as $value) {
+            $tags[] = '#' . $value;
+        }
+
+        $subject = sprintf(
+            'in %s: %s - %s',
+            $this->source,
+            $record['level_name'],
+            $this->getShortMessage($record['message'])
+        );
+
+        $record['flowdock'] = array(
+            'source' => $this->source,
+            'from_address' => $this->sourceEmail,
+            'subject' => $subject,
+            'content' => $record['message'],
+            'tags' => $tags,
+            'project' => $this->source,
+        );
+
+        return $record;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function formatBatch(array $records)
+    {
+        $formatted = array();
+
+        foreach ($records as $record) {
+            $formatted[] = $this->format($record);
+        }
+
+        return $formatted;
+    }
+
+    /**
+     * @param string $message
+     *
+     * @return string
+     */
+    public function getShortMessage($message)
+    {
+        $maxLength = 45;
+
+        if (strlen($message) > $maxLength) {
+            $message = substr($message, 0, $maxLength - 4) . ' ...';
+        }
+
+        return $message;
+    }
+}

+ 127 - 0
vendor/monolog/monolog/src/Monolog/Formatter/HtmlFormatter.php

@@ -0,0 +1,127 @@
+<?php
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use Monolog\Logger;
+
+/**
+ * Formats incoming records into an HTML table
+ *
+ * This is especially useful for html email logging
+ *
+ * @author Tiago Brito <tlfbrito@gmail.com>
+ */
+class HtmlFormatter extends NormalizerFormatter
+{
+    /**
+     * Translates Monolog log levels to html color priorities.
+     */
+    private $logLevels = array(
+        Logger::DEBUG     => '#cccccc',
+        Logger::INFO      => '#468847',
+        Logger::NOTICE    => '#3a87ad',
+        Logger::WARNING   => '#c09853',
+        Logger::ERROR     => '#f0ad4e',
+        Logger::CRITICAL  => '#FF7708',
+        Logger::ALERT     => '#C12A19',
+        Logger::EMERGENCY => '#000000',
+    );
+
+    /**
+     * @param string $dateFormat The format of the timestamp: one supported by DateTime::format
+     */
+    public function __construct($dateFormat = null)
+    {
+        parent::__construct($dateFormat);
+    }
+
+    /**
+     * Creates an HTML table row
+     *
+     * @param  string $th Row header content
+     * @param  string $td Row standard cell content
+     * @return string
+     */
+    private function addRow($th, $td = ' ')
+    {
+        $th = htmlspecialchars($th, ENT_NOQUOTES, 'UTF-8');
+        $td = '<pre>'.htmlspecialchars($td, ENT_NOQUOTES, 'UTF-8').'</pre>';
+
+        return "<tr style=\"padding: 4px;spacing: 0;text-align: left;\">\n<th style=\"background: #cccccc\" width=\"100px\">$th:</th>\n<td style=\"padding: 4px;spacing: 0;text-align: left;background: #eeeeee\">".$td."</td>\n</tr>";
+    }
+
+    /**
+     * Create a HTML h1 tag
+     *
+     * @param  string  $title Text to be in the h1
+     * @param  integer $level Error level
+     * @return string
+     */
+    private function addTitle($title, $level)
+    {
+        $title = htmlspecialchars($title, ENT_NOQUOTES, 'UTF-8');
+
+        return '<h1 style="background: '.$this->logLevels[$level].';color: #ffffff;padding: 5px;">'.$title.'</h1>';
+    }
+    /**
+     * Formats a log record.
+     *
+     * @param  array $record A record to format
+     * @return mixed The formatted record
+     */
+    public function format(array $record)
+    {
+        $output = $this->addTitle($record['level_name'], $record['level']);
+        $output .= '<table cellspacing="1" width="100%">';
+
+        $output .= $this->addRow('Message', (string) $record['message']);
+        $output .= $this->addRow('Time', $record['datetime']->format('Y-m-d\TH:i:s.uO'));
+        $output .= $this->addRow('Channel', $record['channel']);
+        if ($record['context']) {
+            $output .= $this->addRow('Context', $this->convertToString($record['context']));
+        }
+        if ($record['extra']) {
+            $output .= $this->addRow('Extra', $this->convertToString($record['extra']));
+        }
+
+        return $output.'</table>';
+    }
+
+    /**
+     * Formats a set of log records.
+     *
+     * @param  array $records A set of records to format
+     * @return mixed The formatted set of records
+     */
+    public function formatBatch(array $records)
+    {
+        $message = '';
+        foreach ($records as $record) {
+            $message .= $this->format($record);
+        }
+
+        return $message;
+    }
+
+    protected function convertToString($data)
+    {
+        if (null === $data || is_scalar($data)) {
+            return (string) $data;
+        }
+
+        $data = $this->normalize($data);
+        if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
+            return json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
+        }
+
+        return str_replace('\\/', '/', json_encode($data));
+    }
+}

+ 22 - 11
vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php

@@ -20,18 +20,19 @@ namespace Monolog\Formatter;
  */
 class JsonFormatter implements FormatterInterface
 {
-
-    protected $batch_mode;
+    protected $batchMode;
+    protected $appendNewline;
 
     const BATCH_MODE_JSON = 1;
     const BATCH_MODE_NEWLINES = 2;
 
     /**
-     * @param int $batch_mode
+     * @param int $batchMode
      */
-    public function __construct($batch_mode = self::BATCH_MODE_JSON)
+    public function __construct($batchMode = self::BATCH_MODE_JSON, $appendNewline = true)
     {
-        $this->batch_mode = $batch_mode;
+        $this->batchMode = $batchMode;
+        $this->appendNewline = $appendNewline;
     }
 
     /**
@@ -45,7 +46,17 @@ class JsonFormatter implements FormatterInterface
      */
     public function getBatchMode()
     {
-        return $this->batch_mode;
+        return $this->batchMode;
+    }
+
+    /**
+     * True if newlines are appended to every formatted record
+     *
+     * @return bool
+     */
+    public function isAppendingNewlines()
+    {
+        return $this->appendNewline;
     }
 
     /**
@@ -53,7 +64,7 @@ class JsonFormatter implements FormatterInterface
      */
     public function format(array $record)
     {
-        return json_encode($record);
+        return json_encode($record) . ($this->appendNewline ? "\n" : '');
     }
 
     /**
@@ -61,15 +72,13 @@ class JsonFormatter implements FormatterInterface
      */
     public function formatBatch(array $records)
     {
-        switch ($this->batch_mode) {
-
+        switch ($this->batchMode) {
             case static::BATCH_MODE_NEWLINES:
                 return $this->formatBatchNewlines($records);
 
             case static::BATCH_MODE_JSON:
             default:
                 return $this->formatBatchJson($records);
-
         }
     }
 
@@ -95,11 +104,13 @@ class JsonFormatter implements FormatterInterface
     {
         $instance = $this;
 
+        $oldNewline = $this->appendNewline;
+        $this->appendNewline = false;
         array_walk($records, function (&$value, $key) use ($instance) {
             $value = $instance->format($value);
         });
+        $this->appendNewline = $oldNewline;
 
         return implode("\n", $records);
     }
-
 }

+ 47 - 0
vendor/monolog/monolog/src/Monolog/Formatter/LogglyFormatter.php

@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+/**
+ * Encodes message information into JSON in a format compatible with Loggly.
+ *
+ * @author Adam Pancutt <adam@pancutt.com>
+ */
+class LogglyFormatter extends JsonFormatter
+{
+    /**
+     * Overrides the default batch mode to new lines for compatibility with the
+     * Loggly bulk API.
+     *
+     * @param integer $batchMode
+     */
+    public function __construct($batchMode = self::BATCH_MODE_NEWLINES, $appendNewline = false)
+    {
+        parent::__construct($batchMode, $appendNewline);
+    }
+
+    /**
+     * Appends the 'timestamp' parameter for indexing by Loggly.
+     *
+     * @see https://www.loggly.com/docs/automated-parsing/#json
+     * @see \Monolog\Formatter\JsonFormatter::format()
+     */
+    public function format(array $record)
+    {
+        if (isset($record["datetime"]) && ($record["datetime"] instanceof \DateTime)) {
+            $record["timestamp"] = $record["datetime"]->format("c");
+            // TODO 2.0 unset the 'datetime' parameter, retained for BC
+        }
+
+        return parent::format($record);
+    }
+}

+ 43 - 24
vendor/monolog/monolog/src/Monolog/Formatter/LogstashFormatter.php

@@ -85,33 +85,42 @@ class LogstashFormatter extends NormalizerFormatter
 
     protected function formatV0(array $record)
     {
+        if (empty($record['datetime'])) {
+            $record['datetime'] = gmdate('c');
+        }
         $message = array(
             '@timestamp' => $record['datetime'],
-            '@message' => $record['message'],
-            '@tags' => array($record['channel']),
             '@source' => $this->systemName,
-            '@fields' => array(
-                'channel' => $record['channel'],
-                'level' => $record['level']
-            )
+            '@fields' => array()
         );
-
+        if (isset($record['message'])) {
+            $message['@message'] = $record['message'];
+        }
+        if (isset($record['channel'])) {
+            $message['@tags'] = array($record['channel']);
+            $message['@fields']['channel'] = $record['channel'];
+        }
+        if (isset($record['level'])) {
+            $message['@fields']['level'] = $record['level'];
+        }
         if ($this->applicationName) {
             $message['@type'] = $this->applicationName;
         }
-
         if (isset($record['extra']['server'])) {
             $message['@source_host'] = $record['extra']['server'];
         }
         if (isset($record['extra']['url'])) {
             $message['@source_path'] = $record['extra']['url'];
         }
-        foreach ($record['extra'] as $key => $val) {
-            $message['@fields'][$this->extraPrefix . $key] = $val;
+        if (!empty($record['extra'])) {
+            foreach ($record['extra'] as $key => $val) {
+                $message['@fields'][$this->extraPrefix . $key] = $val;
+            }
         }
-
-        foreach ($record['context'] as $key => $val) {
-            $message['@fields'][$this->contextPrefix . $key] = $val;
+        if (!empty($record['context'])) {
+            foreach ($record['context'] as $key => $val) {
+                $message['@fields'][$this->contextPrefix . $key] = $val;
+            }
         }
 
         return $message;
@@ -119,26 +128,36 @@ class LogstashFormatter extends NormalizerFormatter
 
     protected function formatV1(array $record)
     {
+        if (empty($record['datetime'])) {
+            $record['datetime'] = gmdate('c');
+        }
         $message = array(
             '@timestamp' => $record['datetime'],
             '@version' => 1,
-            'message' => $record['message'],
             'host' => $this->systemName,
-            'type' => $record['channel'],
-            'channel' => $record['channel'],
-            'level' => $record['level_name']
         );
-
+        if (isset($record['message'])) {
+            $message['message'] = $record['message'];
+        }
+        if (isset($record['channel'])) {
+            $message['type'] = $record['channel'];
+            $message['channel'] = $record['channel'];
+        }
+        if (isset($record['level_name'])) {
+            $message['level'] = $record['level_name'];
+        }
         if ($this->applicationName) {
             $message['type'] = $this->applicationName;
         }
-
-        foreach ($record['extra'] as $key => $val) {
-            $message[$this->extraPrefix . $key] = $val;
+        if (!empty($record['extra'])) {
+            foreach ($record['extra'] as $key => $val) {
+                $message[$this->extraPrefix . $key] = $val;
+            }
         }
-
-        foreach ($record['context'] as $key => $val) {
-            $message[$this->contextPrefix . $key] = $val;
+        if (!empty($record['context'])) {
+            foreach ($record['context'] as $key => $val) {
+                $message[$this->contextPrefix . $key] = $val;
+            }
         }
 
         return $message;

+ 48 - 0
vendor/monolog/monolog/src/Monolog/Formatter/ScalarFormatter.php

@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+/**
+ * Formats data into an associative array of scalar values.
+ * Objects and arrays will be JSON encoded.
+ *
+ * @author Andrew Lawson <adlawson@gmail.com>
+ */
+class ScalarFormatter extends NormalizerFormatter
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function format(array $record)
+    {
+        foreach ($record as $key => $value) {
+            $record[$key] = $this->normalizeValue($value);
+        }
+
+        return $record;
+    }
+
+    /**
+     * @param  mixed $value
+     * @return mixed
+     */
+    protected function normalizeValue($value)
+    {
+        $normalized = $this->normalize($value);
+
+        if (is_array($normalized) || is_object($normalized)) {
+            return $this->toJson($normalized, true);
+        }
+
+        return $normalized;
+    }
+}

+ 13 - 2
vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php

@@ -22,6 +22,8 @@ use Monolog\Logger;
  */
 class WildfireFormatter extends NormalizerFormatter
 {
+    const TABLE = 'table';
+
     /**
      * Translates Monolog log levels to Wildfire levels.
      */
@@ -67,13 +69,22 @@ class WildfireFormatter extends NormalizerFormatter
             $message = reset($message);
         }
 
+        if (isset($record['context'][self::TABLE])) {
+            $type  = 'TABLE';
+            $label = $record['channel'] .': '. $record['message'];
+            $message = $record['context'][self::TABLE];
+        } else {
+            $type  = $this->logLevels[$record['level']];
+            $label = $record['channel'];
+        }
+
         // Create JSON object describing the appearance of the message in the console
         $json = $this->toJson(array(
             array(
-                'Type'  => $this->logLevels[$record['level']],
+                'Type'  => $type,
                 'File'  => $file,
                 'Line'  => $line,
-                'Label' => $record['channel'],
+                'Label' => $label,
             ),
             $message,
         ), $handleError);

+ 92 - 0
vendor/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php

@@ -0,0 +1,92 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\Formatter\LineFormatter;
+
+/**
+ * Common syslog functionality
+ */
+abstract class AbstractSyslogHandler extends AbstractProcessingHandler
+{
+    protected $facility;
+
+    /**
+     * Translates Monolog log levels to syslog log priorities.
+     */
+    protected $logLevels = array(
+        Logger::DEBUG     => LOG_DEBUG,
+        Logger::INFO      => LOG_INFO,
+        Logger::NOTICE    => LOG_NOTICE,
+        Logger::WARNING   => LOG_WARNING,
+        Logger::ERROR     => LOG_ERR,
+        Logger::CRITICAL  => LOG_CRIT,
+        Logger::ALERT     => LOG_ALERT,
+        Logger::EMERGENCY => LOG_EMERG,
+    );
+
+    /**
+     * List of valid log facility names.
+     */
+    protected $facilities = array(
+        'auth'     => LOG_AUTH,
+        'authpriv' => LOG_AUTHPRIV,
+        'cron'     => LOG_CRON,
+        'daemon'   => LOG_DAEMON,
+        'kern'     => LOG_KERN,
+        'lpr'      => LOG_LPR,
+        'mail'     => LOG_MAIL,
+        'news'     => LOG_NEWS,
+        'syslog'   => LOG_SYSLOG,
+        'user'     => LOG_USER,
+        'uucp'     => LOG_UUCP,
+    );
+
+    /**
+     * @param mixed   $facility
+     * @param integer $level    The minimum logging level at which this handler will be triggered
+     * @param Boolean $bubble   Whether the messages that are handled can bubble up the stack or not
+     */
+    public function __construct($facility = LOG_USER, $level = Logger::DEBUG, $bubble = true)
+    {
+        parent::__construct($level, $bubble);
+
+        if (!defined('PHP_WINDOWS_VERSION_BUILD')) {
+            $this->facilities['local0'] = LOG_LOCAL0;
+            $this->facilities['local1'] = LOG_LOCAL1;
+            $this->facilities['local2'] = LOG_LOCAL2;
+            $this->facilities['local3'] = LOG_LOCAL3;
+            $this->facilities['local4'] = LOG_LOCAL4;
+            $this->facilities['local5'] = LOG_LOCAL5;
+            $this->facilities['local6'] = LOG_LOCAL6;
+            $this->facilities['local7'] = LOG_LOCAL7;
+        }
+
+        // convert textual description of facility to syslog constant
+        if (array_key_exists(strtolower($facility), $this->facilities)) {
+            $facility = $this->facilities[strtolower($facility)];
+        } elseif (!in_array($facility, array_values($this->facilities), true)) {
+            throw new \UnexpectedValueException('Unknown facility value "'.$facility.'" given');
+        }
+
+        $this->facility = $facility;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getDefaultFormatter()
+    {
+        return new LineFormatter('%channel%.%level_name%: %message% %context% %extra%');
+    }
+}

+ 1 - 1
vendor/monolog/monolog/src/Monolog/Handler/AmqpHandler.php

@@ -64,6 +64,6 @@ class AmqpHandler extends AbstractProcessingHandler
      */
     protected function getDefaultFormatter()
     {
-        return new JsonFormatter();
+        return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false);
     }
 }

+ 184 - 0
vendor/monolog/monolog/src/Monolog/Handler/BrowserConsoleHandler.php

@@ -0,0 +1,184 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Formatter\LineFormatter;
+
+/**
+ * Handler sending logs to browser's javascript console with no browser extension required
+ *
+ * @author Olivier Poitrey <rs@dailymotion.com>
+ */
+class BrowserConsoleHandler extends AbstractProcessingHandler
+{
+    protected static $initialized = false;
+    protected static $records = array();
+
+    /**
+     * {@inheritDoc}
+     *
+     * Formatted output may contain some formatting markers to be transfered to `console.log` using the %c format.
+     *
+     * Example of formatted string:
+     *
+     *     You can do [[blue text]]{color: blue} or [[green background]]{background-color: green; color: white}
+     *
+     */
+    protected function getDefaultFormatter()
+    {
+        return new LineFormatter('[[%channel%]]{macro: autolabel} [[%level_name%]]{font-weight: bold} %message%');
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record)
+    {
+        // Accumulate records
+        self::$records[] = $record;
+
+        // Register shutdown handler if not already done
+        if (PHP_SAPI !== 'cli' && !self::$initialized) {
+            self::$initialized = true;
+            register_shutdown_function(array('Monolog\Handler\BrowserConsoleHandler', 'send'));
+        }
+    }
+
+    /**
+     * Convert records to javascript console commands and send it to the browser.
+     * This method is automatically called on PHP shutdown if output is HTML.
+     */
+    public static function send()
+    {
+        // Check content type
+        foreach (headers_list() as $header) {
+            if (stripos($header, 'content-type:') === 0) {
+                if (stripos($header, 'text/html') === false) {
+                    // This handler only works with HTML outputs
+                    return;
+                }
+                break;
+            }
+        }
+
+        if (count(self::$records)) {
+            echo '<script>' . self::generateScript() . '</script>';
+            self::reset();
+        }
+    }
+
+    /**
+     * Forget all logged records
+     */
+    public static function reset()
+    {
+        self::$records = array();
+    }
+
+    private static function generateScript()
+    {
+        $script = array();
+        foreach (self::$records as $record) {
+            $context = self::dump('Context', $record['context']);
+            $extra = self::dump('Extra', $record['extra']);
+
+            if (empty($context) && empty($extra)) {
+                $script[] = self::call_array('log', self::handleStyles($record['formatted']));
+            } else {
+                $script = array_merge($script,
+                    array(self::call_array('groupCollapsed', self::handleStyles($record['formatted']))),
+                    $context,
+                    $extra,
+                    array(self::call('groupEnd'))
+                );
+            }
+        }
+
+        return "(function (c) {if (c && c.groupCollapsed) {\n" . implode("\n", $script) . "\n}})(console);";
+    }
+
+    private static function handleStyles($formatted)
+    {
+        $args = array(self::quote('font-weight: normal'));
+        $format = '%c' . $formatted;
+        preg_match_all('/\[\[(.*?)\]\]\{([^}]*)\}/s', $format, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
+
+        foreach (array_reverse($matches) as $match) {
+            $args[] = self::quote(self::handleCustomStyles($match[2][0], $match[1][0]));
+            $args[] = '"font-weight: normal"';
+
+            $pos = $match[0][1];
+            $format = substr($format, 0, $pos) . '%c' . $match[1][0] . '%c' . substr($format, $pos + strlen($match[0][0]));
+        }
+
+        array_unshift($args, self::quote($format));
+
+        return $args;
+    }
+
+    private static function handleCustomStyles($style, $string)
+    {
+        static $colors = array('blue', 'green', 'red', 'magenta', 'orange', 'black', 'grey');
+        static $labels = array();
+
+        return preg_replace_callback('/macro\s*:(.*?)(?:;|$)/', function ($m) use ($string, &$colors, &$labels) {
+            if (trim($m[1]) === 'autolabel') {
+                // Format the string as a label with consistent auto assigned background color
+                if (!isset($labels[$string])) {
+                    $labels[$string] = $colors[count($labels) % count($colors)];
+                }
+                $color = $labels[$string];
+
+                return "background-color: $color; color: white; border-radius: 3px; padding: 0 2px 0 2px";
+            }
+
+            return $m[1];
+        }, $style);
+    }
+
+    private static function dump($title, array $dict)
+    {
+        $script = array();
+        $dict = array_filter($dict);
+        if (empty($dict)) {
+            return $script;
+        }
+        $script[] = self::call('log', self::quote('%c%s'), self::quote('font-weight: bold'), self::quote($title));
+        foreach ($dict as $key => $value) {
+            $value = json_encode($value);
+            if (empty($value)) {
+                $value = self::quote('');
+            }
+            $script[] = self::call('log', self::quote('%s: %o'), self::quote($key), $value);
+        }
+
+        return $script;
+    }
+
+    private static function quote($arg)
+    {
+        return '"' . addcslashes($arg, "\"\n") . '"';
+    }
+
+    private static function call()
+    {
+        $args = func_get_args();
+        $method = array_shift($args);
+
+        return self::call_array($method, $args);
+    }
+
+    private static function call_array($method, array $args)
+    {
+        return 'c.' . $method . '(' . implode(', ', $args) . ');';
+    }
+}

+ 7 - 3
vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.php

@@ -28,6 +28,7 @@ class BufferHandler extends AbstractHandler
     protected $bufferLimit;
     protected $flushOnOverflow;
     protected $buffer = array();
+    protected $initialized = false;
 
     /**
      * @param HandlerInterface $handler         Handler.
@@ -42,9 +43,6 @@ class BufferHandler extends AbstractHandler
         $this->handler = $handler;
         $this->bufferLimit = (int) $bufferLimit;
         $this->flushOnOverflow = $flushOnOverflow;
-
-        // __destructor() doesn't get called on Fatal errors
-        register_shutdown_function(array($this, 'close'));
     }
 
     /**
@@ -56,6 +54,12 @@ class BufferHandler extends AbstractHandler
             return false;
         }
 
+        if (!$this->initialized) {
+            // __destructor() doesn't get called on Fatal errors
+            register_shutdown_function(array($this, 'close'));
+            $this->initialized = true;
+        }
+
         if ($this->bufferLimit > 0 && $this->bufferSize === $this->bufferLimit) {
             if ($this->flushOnOverflow) {
                 $this->flush();

+ 15 - 6
vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php

@@ -100,15 +100,19 @@ class ChromePHPHandler extends AbstractProcessingHandler
      */
     protected function send()
     {
-        if (self::$overflowed) {
+        if (self::$overflowed || !self::$sendHeaders) {
             return;
         }
 
         if (!self::$initialized) {
+            self::$initialized = true;
+
             self::$sendHeaders = $this->headersAccepted();
-            self::$json['request_uri'] = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
+            if (!self::$sendHeaders) {
+                return;
+            }
 
-            self::$initialized = true;
+            self::$json['request_uri'] = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
         }
 
         $json = @json_encode(self::$json);
@@ -130,7 +134,9 @@ class ChromePHPHandler extends AbstractProcessingHandler
             $data = base64_encode(utf8_encode($json));
         }
 
-        $this->sendHeader(self::HEADER_NAME, $data);
+        if (trim($data) !== '') {
+            $this->sendHeader(self::HEADER_NAME, $data);
+        }
     }
 
     /**
@@ -153,8 +159,11 @@ class ChromePHPHandler extends AbstractProcessingHandler
      */
     protected function headersAccepted()
     {
-        return !isset($_SERVER['HTTP_USER_AGENT'])
-               || preg_match('{\bChrome/\d+[\.\d+]*\b}', $_SERVER['HTTP_USER_AGENT']);
+        if (empty($_SERVER['HTTP_USER_AGENT'])) {
+            return false;
+        }
+
+        return preg_match('{\bChrome/\d+[\.\d+]*\b}', $_SERVER['HTTP_USER_AGENT']);
     }
 
     /**

+ 1 - 1
vendor/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php

@@ -67,6 +67,6 @@ class CouchDBHandler extends AbstractProcessingHandler
      */
     protected function getDefaultFormatter()
     {
-        return new JsonFormatter();
+        return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false);
     }
 }

+ 89 - 0
vendor/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php

@@ -0,0 +1,89 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Aws\Common\Aws;
+use Aws\DynamoDb\DynamoDbClient;
+use Monolog\Formatter\ScalarFormatter;
+use Monolog\Logger;
+
+/**
+ * Amazon DynamoDB handler (http://aws.amazon.com/dynamodb/)
+ *
+ * @link https://github.com/aws/aws-sdk-php/
+ * @author Andrew Lawson <adlawson@gmail.com>
+ */
+class DynamoDbHandler extends AbstractProcessingHandler
+{
+    const DATE_FORMAT = 'Y-m-d\TH:i:s.uO';
+
+    /**
+     * @var DynamoDbClient
+     */
+    protected $client;
+
+    /**
+     * @var string
+     */
+    protected $table;
+
+    /**
+     * @param DynamoDbClient $client
+     * @param string         $table
+     * @param integer        $level
+     * @param boolean        $bubble
+     */
+    public function __construct(DynamoDbClient $client, $table, $level = Logger::DEBUG, $bubble = true)
+    {
+        if (!defined('Aws\Common\Aws::VERSION') || version_compare('3.0', Aws::VERSION, '<=')) {
+            throw new \RuntimeException('The DynamoDbHandler is only known to work with the AWS SDK 2.x releases');
+        }
+
+        $this->client = $client;
+        $this->table = $table;
+
+        parent::__construct($level, $bubble);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function write(array $record)
+    {
+        $filtered = $this->filterEmptyFields($record['formatted']);
+        $formatted = $this->client->formatAttributes($filtered);
+
+        $this->client->putItem(array(
+            'TableName' => $this->table,
+            'Item' => $formatted
+        ));
+    }
+
+    /**
+     * @param  array $record
+     * @return array
+     */
+    protected function filterEmptyFields(array $record)
+    {
+        return array_filter($record, function ($value) {
+            return !empty($value) || false === $value || 0 === $value;
+        });
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getDefaultFormatter()
+    {
+        return new ScalarFormatter(self::DATE_FORMAT);
+    }
+}

+ 128 - 0
vendor/monolog/monolog/src/Monolog/Handler/ElasticSearchHandler.php

@@ -0,0 +1,128 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Formatter\ElasticaFormatter;
+use Monolog\Logger;
+use Elastica\Client;
+use Elastica\Exception\ExceptionInterface;
+
+/**
+ * Elastic Search handler
+ *
+ * Usage example:
+ *
+ *    $client = new \Elastica\Client();
+ *    $options = array(
+ *        'index' => 'elastic_index_name',
+ *        'type' => 'elastic_doc_type',
+ *    );
+ *    $handler = new ElasticSearchHandler($client, $options);
+ *    $log = new Logger('application');
+ *    $log->pushHandler($handler);
+ *
+ * @author Jelle Vink <jelle.vink@gmail.com>
+ */
+class ElasticSearchHandler extends AbstractProcessingHandler
+{
+    /**
+     * @var Client
+     */
+    protected $client;
+
+    /**
+     * @var array Handler config options
+     */
+    protected $options = array();
+
+    /**
+     * @param Client  $client  Elastica Client object
+     * @param array   $options Handler configuration
+     * @param integer $level   The minimum logging level at which this handler will be triggered
+     * @param Boolean $bubble  Whether the messages that are handled can bubble up the stack or not
+     */
+    public function __construct(Client $client, array $options = array(), $level = Logger::DEBUG, $bubble = true)
+    {
+        parent::__construct($level, $bubble);
+        $this->client = $client;
+        $this->options = array_merge(
+            array(
+                'index'          => 'monolog',      // Elastic index name
+                'type'           => 'record',       // Elastic document type
+                'ignore_error'   => false,          // Suppress Elastica exceptions
+            ),
+            $options
+        );
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record)
+    {
+        $this->bulkSend(array($record['formatted']));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setFormatter(FormatterInterface $formatter)
+    {
+        if ($formatter instanceof ElasticaFormatter) {
+            return parent::setFormatter($formatter);
+        }
+        throw new \InvalidArgumentException('ElasticSearchHandler is only compatible with ElasticaFormatter');
+    }
+
+    /**
+     * Getter options
+     * @return array
+     */
+    public function getOptions()
+    {
+        return $this->options;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getDefaultFormatter()
+    {
+        return new ElasticaFormatter($this->options['index'], $this->options['type']);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handleBatch(array $records)
+    {
+        $documents = $this->getFormatter()->formatBatch($records);
+        $this->bulkSend($documents);
+    }
+
+    /**
+     * Use Elasticsearch bulk API to send list of documents
+     * @param  array             $documents
+     * @throws \RuntimeException
+     */
+    protected function bulkSend(array $documents)
+    {
+        try {
+            $this->client->addDocuments($documents);
+        } catch (ExceptionInterface $e) {
+            if (!$this->options['ignore_error']) {
+                throw new \RuntimeException("Error sending messages to Elasticsearch", 0, $e);
+            }
+        }
+    }
+}

+ 9 - 0
vendor/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php

@@ -11,6 +11,7 @@
 
 namespace Monolog\Handler;
 
+use Monolog\Formatter\LineFormatter;
 use Monolog\Logger;
 
 /**
@@ -53,6 +54,14 @@ class ErrorLogHandler extends AbstractProcessingHandler
         );
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    protected function getDefaultFormatter()
+    {
+        return new LineFormatter('[%datetime%] %channel%.%level_name%: %message% %context% %extra%');
+    }
+
     /**
      * {@inheritdoc}
      */

+ 131 - 0
vendor/monolog/monolog/src/Monolog/Handler/FilterHandler.php

@@ -0,0 +1,131 @@
+<?php
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+
+/**
+ * Simple handler wrapper that filters records based on a list of levels
+ *
+ * It can be configured with an exact list of levels to allow, or a min/max level.
+ *
+ * @author Hennadiy Verkh
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class FilterHandler extends AbstractHandler
+{
+    /**
+     * Handler or factory callable($record, $this)
+     *
+     * @var callable|\Monolog\Handler\HandlerInterface
+     */
+    protected $handler;
+
+    /**
+     * Minimum level for logs that are passes to handler
+     *
+     * @var int
+     */
+    protected $acceptedLevels;
+
+    /**
+     * Whether the messages that are handled can bubble up the stack or not
+     *
+     * @var Boolean
+     */
+    protected $bubble;
+
+    /**
+     * @param callable|HandlerInterface $handler        Handler or factory callable($record, $this).
+     * @param int|array                 $minLevelOrList A list of levels to accept or a minimum level if maxLevel is provided
+     * @param int                       $maxLevel       Maximum level to accept, only used if $minLevelOrList is not an array
+     * @param Boolean                   $bubble         Whether the messages that are handled can bubble up the stack or not
+     */
+    public function __construct($handler, $minLevelOrList = Logger::DEBUG, $maxLevel = Logger::EMERGENCY, $bubble = true)
+    {
+        $this->handler  = $handler;
+        $this->bubble   = $bubble;
+        $this->setAcceptedLevels($minLevelOrList, $maxLevel);
+    }
+
+    /**
+     * @return array
+     */
+    public function getAcceptedLevels()
+    {
+        return array_flip($this->acceptedLevels);
+    }
+
+    /**
+     * @param int|array $minLevelOrList A list of levels to accept or a minimum level if maxLevel is provided
+     * @param int       $maxLevel       Maximum level to accept, only used if $minLevelOrList is not an array
+     */
+    public function setAcceptedLevels($minLevelOrList = Logger::DEBUG, $maxLevel = Logger::EMERGENCY)
+    {
+        if (is_array($minLevelOrList)) {
+            $acceptedLevels = $minLevelOrList;
+        } else {
+            $acceptedLevels = array_filter(Logger::getLevels(), function ($level) use ($minLevelOrList, $maxLevel) {
+                return $level >= $minLevelOrList && $level <= $maxLevel;
+            });
+        }
+        $this->acceptedLevels = array_flip($acceptedLevels);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isHandling(array $record)
+    {
+        return isset($this->acceptedLevels[$record['level']]);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handle(array $record)
+    {
+        if (!$this->isHandling($record)) {
+            return false;
+        }
+
+        // The same logic as in FingersCrossedHandler
+        if (!$this->handler instanceof HandlerInterface) {
+            if (!is_callable($this->handler)) {
+                throw new \RuntimeException(
+                    "The given handler (" . json_encode($this->handler)
+                    . ") is not a callable nor a Monolog\\Handler\\HandlerInterface object"
+                );
+            }
+            $this->handler = call_user_func($this->handler, $record, $this);
+            if (!$this->handler instanceof HandlerInterface) {
+                throw new \RuntimeException("The factory callable should return a HandlerInterface");
+            }
+        }
+
+        if ($this->processors) {
+            foreach ($this->processors as $processor) {
+                $record = call_user_func($processor, $record);
+            }
+        }
+
+        $this->handler->handle($record);
+
+        return false === $this->bubble;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handleBatch(array $records)
+    {
+        $filtered = array();
+        foreach ($records as $record) {
+            if ($this->isHandling($record)) {
+                $filtered[] = $record;
+            }
+        }
+
+        $this->handler->handleBatch($filtered);
+    }
+}

+ 17 - 6
vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php

@@ -131,19 +131,28 @@ class FirePHPHandler extends AbstractProcessingHandler
      */
     protected function write(array $record)
     {
+        if (!self::$sendHeaders) {
+            return;
+        }
+
         // WildFire-specific headers must be sent prior to any messages
         if (!self::$initialized) {
+            self::$initialized = true;
+
             self::$sendHeaders = $this->headersAccepted();
+            if (!self::$sendHeaders) {
+                return;
+            }
 
             foreach ($this->getInitHeaders() as $header => $content) {
                 $this->sendHeader($header, $content);
             }
-
-            self::$initialized = true;
         }
 
         $header = $this->createRecordHeader($record);
-        $this->sendHeader(key($header), current($header));
+        if (trim(current($header)) !== '') {
+            $this->sendHeader(key($header), current($header));
+        }
     }
 
     /**
@@ -153,9 +162,11 @@ class FirePHPHandler extends AbstractProcessingHandler
      */
     protected function headersAccepted()
     {
-        return !isset($_SERVER['HTTP_USER_AGENT'])
-               || preg_match('{\bFirePHP/\d+\.\d+\b}', $_SERVER['HTTP_USER_AGENT'])
-               || isset($_SERVER['HTTP_X_FIREPHP_VERSION']);
+        if (!empty($_SERVER['HTTP_USER_AGENT']) && preg_match('{\bFirePHP/\d+\.\d+\b}', $_SERVER['HTTP_USER_AGENT'])) {
+            return true;
+        }
+
+        return isset($_SERVER['HTTP_X_FIREPHP_VERSION']);
     }
 
     /**

+ 103 - 0
vendor/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php

@@ -0,0 +1,103 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+
+/**
+ * Sends notifications through the Flowdock push API
+ *
+ * This must be configured with a FlowdockFormatter instance via setFormatter()
+ *
+ * Notes:
+ * API token - Flowdock API token
+ *
+ * @author Dominik Liebler <liebler.dominik@gmail.com>
+ * @see https://www.flowdock.com/api/push
+ */
+class FlowdockHandler extends SocketHandler
+{
+    /**
+     * @var string
+     */
+    protected $apiToken;
+
+    /**
+     * @param string   $apiToken
+     * @param bool|int $level    The minimum logging level at which this handler will be triggered
+     * @param bool     $bubble   Whether the messages that are handled can bubble up the stack or not
+     *
+     * @throws MissingExtensionException if OpenSSL is missing
+     */
+    public function __construct($apiToken, $level = Logger::DEBUG, $bubble = true)
+    {
+        if (!extension_loaded('openssl')) {
+            throw new MissingExtensionException('The OpenSSL PHP extension is required to use the FlowdockHandler');
+        }
+
+        parent::__construct('ssl://api.flowdock.com:443', $level, $bubble);
+        $this->apiToken = $apiToken;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param array $record
+     */
+    public function write(array $record)
+    {
+        parent::write($record);
+
+        $this->closeSocket();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param  array  $record
+     * @return string
+     */
+    protected function generateDataStream($record)
+    {
+        $content = $this->buildContent($record);
+
+        return $this->buildHeader($content) . $content;
+    }
+
+    /**
+     * Builds the body of API call
+     *
+     * @param  array  $record
+     * @return string
+     */
+    private function buildContent($record)
+    {
+        return json_encode($record['formatted']['flowdock']);
+    }
+
+    /**
+     * Builds the header of the API Call
+     *
+     * @param  string $content
+     * @return string
+     */
+    private function buildHeader($content)
+    {
+        $header = "POST /v1/messages/team_inbox/" . $this->apiToken . " HTTP/1.1\r\n";
+        $header .= "Host: api.flowdock.com\r\n";
+        $header .= "Content-Type: application/json\r\n";
+        $header .= "Content-Length: " . strlen($content) . "\r\n";
+        $header .= "\r\n";
+
+        return $header;
+    }
+}

+ 57 - 0
vendor/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php

@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+
+/**
+ * @author Robert Kaufmann III <rok3@rok3.me>
+ */
+class LogEntriesHandler extends SocketHandler
+{
+
+    /**
+     * @var string
+     */
+    protected $logToken;
+
+    /**
+     * @param string  $token  Log token supplied by LogEntries
+     * @param boolean $useSSL Whether or not SSL encryption should be used.
+     * @param int     $level  The minimum logging level to trigger this handler
+     * @param boolean $bubble Whether or not messages that are handled should bubble up the stack.
+     *
+     * @throws MissingExtensionExcpetion If SSL encryption is set to true and OpenSSL is missing
+     */
+    public function __construct($token, $useSSL = true, $level = Logger::DEBUG, $bubble = true)
+    {
+        if ($useSSL && !extension_loaded('openssl')) {
+            throw new MissingExtensionException('The OpenSSL PHP plugin is required to use SSL encrypted connection for LogEntriesHandler');
+        }
+
+        $endpoint = $useSSL ? 'ssl://api.logentries.com:20000' : 'data.logentries.com:80';
+        parent::__construct($endpoint, $level, $bubble);
+        $this->logToken = $token;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param  array  $record
+     * @return string
+     */
+    protected function generateDataStream($record)
+    {
+        return $this->logToken . ' ' . $record['formatted'];
+    }
+
+}

+ 93 - 0
vendor/monolog/monolog/src/Monolog/Handler/LogglyHandler.php

@@ -0,0 +1,93 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\Formatter\LogglyFormatter;
+
+/**
+ * Sends errors to Loggly.
+ *
+ * @author Przemek Sobstel <przemek@sobstel.org>
+ * @author Adam Pancutt <adam@pancutt.com>
+ */
+class LogglyHandler extends AbstractProcessingHandler
+{
+    const HOST = 'logs-01.loggly.com';
+    const ENDPOINT_SINGLE = 'inputs';
+    const ENDPOINT_BATCH = 'bulk';
+
+    protected $token;
+
+    protected $tag;
+
+    public function __construct($token, $level = Logger::DEBUG, $bubble = true)
+    {
+        if (!extension_loaded('curl')) {
+            throw new \LogicException('The curl extension is needed to use the LogglyHandler');
+        }
+
+        $this->token = $token;
+
+        parent::__construct($level, $bubble);
+    }
+
+    public function setTag($tag)
+    {
+        $this->tag = $tag;
+    }
+
+    protected function write(array $record)
+    {
+        $this->send($record["formatted"], self::ENDPOINT_SINGLE);
+    }
+
+    public function handleBatch(array $records)
+    {
+        $level = $this->level;
+
+        $records = array_filter($records, function ($record) use ($level) {
+            return ($record['level'] >= $level);
+        });
+
+        if ($records) {
+            $this->send($this->getFormatter()->formatBatch($records), self::ENDPOINT_BATCH);
+        }
+    }
+
+    protected function send($data, $endpoint)
+    {
+        $url = sprintf("https://%s/%s/%s/", self::HOST, $endpoint, $this->token);
+
+        $headers = array('Content-Type: application/json');
+
+        if ($this->tag) {
+            $headers[] = "X-LOGGLY-TAG: {$this->tag}";
+        }
+
+        $ch = curl_init();
+
+        curl_setopt($ch, CURLOPT_URL, $url);
+        curl_setopt($ch, CURLOPT_POST, true);
+        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
+        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+
+        curl_exec($ch);
+        curl_close($ch);
+    }
+
+    protected function getDefaultFormatter()
+    {
+        return new LogglyFormatter();
+    }
+}

+ 17 - 0
vendor/monolog/monolog/src/Monolog/Handler/PushoverHandler.php

@@ -31,6 +31,17 @@ class PushoverHandler extends SocketHandler
     private $highPriorityLevel;
     private $emergencyLevel;
 
+    /**
+     * Sounds the api supports by default
+     * @see https://pushover.net/api#sounds
+     * @var array
+     */
+    private $sounds = array(
+        'pushover', 'bike', 'bugle', 'cashregister', 'classical', 'cosmic', 'falling', 'gamelan', 'incoming',
+        'intermission', 'magic', 'mechanical', 'pianobar', 'siren', 'spacealarm', 'tugboat', 'alien', 'climb',
+        'persistent', 'echo', 'updown', 'none',
+    );
+
     /**
      * @param string       $token             Pushover api token
      * @param string|array $users             Pushover user id or array of ids the message will be sent to
@@ -90,6 +101,12 @@ class PushoverHandler extends SocketHandler
             $dataArray['priority'] = 1;
         }
 
+        if (isset($record['context']['sound']) && in_array($record['context']['sound'], $this->sounds)) {
+            $dataArray['sound'] = $record['context']['sound'];
+        } elseif (isset($record['extra']['sound']) && in_array($record['extra']['sound'], $this->sounds)) {
+            $dataArray['sound'] = $record['extra']['sound'];
+        }
+
         return http_build_query($dataArray);
     }
 

+ 9 - 0
vendor/monolog/monolog/src/Monolog/Handler/RavenHandler.php

@@ -129,6 +129,15 @@ class RavenHandler extends AbstractProcessingHandler
     {
         $options = array();
         $options['level'] = $this->logLevels[$record['level']];
+        $options['tags'] = array();
+        if (!empty($record['extra']['tags'])) {
+            $options['tags'] = array_merge($options['tags'], $record['extra']['tags']);
+            unset($record['extra']['tags']);
+        }
+        if (!empty($record['context']['tags'])) {
+            $options['tags'] = array_merge($options['tags'], $record['context']['tags']);
+            unset($record['context']['tags']);
+        }
         if (!empty($record['context'])) {
             $options['extra']['context'] = $record['context'];
         }

+ 64 - 0
vendor/monolog/monolog/src/Monolog/Handler/RollbarHandler.php

@@ -0,0 +1,64 @@
+<?php
+
+namespace Monolog\Handler;
+
+use RollbarNotifier;
+use Exception;
+use Monolog\Logger;
+
+/**
+ * Sends errors to Rollbar
+ *
+ * @author Paul Statezny <paulstatezny@gmail.com>
+ */
+class RollbarHandler extends AbstractProcessingHandler
+{
+    /**
+     * Rollbar notifier
+     *
+     * @var RollbarNotifier
+     */
+    protected $rollbarNotifier;
+
+    /**
+     * @param RollbarNotifier $rollbarNotifier RollbarNotifier object constructed with valid token
+     * @param integer         $level           The minimum logging level at which this handler will be triggered
+     * @param boolean         $bubble          Whether the messages that are handled can bubble up the stack or not
+     */
+    public function __construct(RollbarNotifier $rollbarNotifier, $level = Logger::ERROR, $bubble = true)
+    {
+        $this->rollbarNotifier = $rollbarNotifier;
+
+        parent::__construct($level, $bubble);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function write(array $record)
+    {
+        if (isset($record['context']['exception']) && $record['context']['exception'] instanceof Exception) {
+            $this->rollbarNotifier->report_exception($record['context']['exception']);
+        } else {
+            $extraData = array(
+                'level' => $record['level'],
+                'channel' => $record['channel'],
+                'datetime' => $record['datetime']->format('U'),
+            );
+
+            $this->rollbarNotifier->report_message(
+                $record['message'],
+                $record['level_name'],
+                array_merge($record['context'], $record['extra'], $extraData)
+            );
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function close()
+    {
+        $this->rollbarNotifier->flush();
+    }
+}

+ 8 - 5
vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php

@@ -33,11 +33,12 @@ class RotatingFileHandler extends StreamHandler
 
     /**
      * @param string  $filename
-     * @param integer $maxFiles The maximal amount of files to keep (0 means unlimited)
-     * @param integer $level    The minimum logging level at which this handler will be triggered
-     * @param Boolean $bubble   Whether the messages that are handled can bubble up the stack or not
+     * @param integer $maxFiles        The maximal amount of files to keep (0 means unlimited)
+     * @param integer $level           The minimum logging level at which this handler will be triggered
+     * @param Boolean $bubble          Whether the messages that are handled can bubble up the stack or not
+     * @param int     $filePermissions Optional file permissions (default (0644) are only for owner read/write)
      */
-    public function __construct($filename, $maxFiles = 0, $level = Logger::DEBUG, $bubble = true)
+    public function __construct($filename, $maxFiles = 0, $level = Logger::DEBUG, $bubble = true, $filePermission = null)
     {
         $this->filename = $filename;
         $this->maxFiles = (int) $maxFiles;
@@ -45,7 +46,7 @@ class RotatingFileHandler extends StreamHandler
         $this->filenameFormat = '{filename}-{date}';
         $this->dateFormat = 'Y-m-d';
 
-        parent::__construct($this->getTimedFilename(), $level, $bubble);
+        parent::__construct($this->getTimedFilename(), $level, $bubble, $filePermission);
     }
 
     /**
@@ -64,6 +65,8 @@ class RotatingFileHandler extends StreamHandler
     {
         $this->filenameFormat = $filenameFormat;
         $this->dateFormat = $dateFormat;
+        $this->url = $this->getTimedFilename();
+        $this->close();
     }
 
     /**

+ 11 - 4
vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php

@@ -25,13 +25,15 @@ class StreamHandler extends AbstractProcessingHandler
     protected $stream;
     protected $url;
     private $errorMessage;
+    protected $filePermission;
 
     /**
      * @param string  $stream
-     * @param integer $level  The minimum logging level at which this handler will be triggered
-     * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
+     * @param integer $level           The minimum logging level at which this handler will be triggered
+     * @param Boolean $bubble          Whether the messages that are handled can bubble up the stack or not
+     * @param int     $filePermissions Optional file permissions (default (0644) are only for owner read/write)
      */
-    public function __construct($stream, $level = Logger::DEBUG, $bubble = true)
+    public function __construct($stream, $level = Logger::DEBUG, $bubble = true, $filePermission = null)
     {
         parent::__construct($level, $bubble);
         if (is_resource($stream)) {
@@ -39,6 +41,8 @@ class StreamHandler extends AbstractProcessingHandler
         } else {
             $this->url = $stream;
         }
+
+        $this->filePermission = $filePermission;
     }
 
     /**
@@ -57,13 +61,16 @@ class StreamHandler extends AbstractProcessingHandler
      */
     protected function write(array $record)
     {
-        if (null === $this->stream) {
+        if (!is_resource($this->stream)) {
             if (!$this->url) {
                 throw new \LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().');
             }
             $this->errorMessage = null;
             set_error_handler(array($this, 'customErrorHandler'));
             $this->stream = fopen($this->url, 'a');
+            if ($this->filePermission !== null) {
+                @chmod($this->url, $this->filePermission);
+            }
             restore_error_handler();
             if (!is_resource($this->stream)) {
                 $this->stream = null;

+ 62 - 0
vendor/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.php

@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler\SyslogUdp;
+
+class UdpSocket
+{
+    const DATAGRAM_MAX_LENGTH = 2048;
+
+    public function __construct($ip, $port = 514)
+    {
+        $this->ip = $ip;
+        $this->port = $port;
+        $this->socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
+    }
+
+    public function write($line, $header = "")
+    {
+        $remaining = $line;
+        while (!is_null($remaining)) {
+            list($chunk, $remaining) = $this->splitLineIfNessesary($remaining, $header);
+            $this->send($chunk);
+        }
+    }
+
+    public function close()
+    {
+        socket_close($this->socket);
+    }
+
+    protected function send($chunk)
+    {
+        socket_sendto($this->socket, $chunk, strlen($chunk), $flags = 0, $this->ip, $this->port);
+    }
+
+    protected function splitLineIfNessesary($line, $header)
+    {
+        if ($this->shouldSplitLine($line, $header)) {
+            $chunkSize = self::DATAGRAM_MAX_LENGTH - strlen($header);
+            $chunk = $header . substr($line, 0, $chunkSize);
+            $remaining = substr($line, $chunkSize);
+        } else {
+            $chunk = $header . $line;
+            $remaining = null;
+        }
+
+        return array($chunk, $remaining);
+    }
+
+    protected function shouldSplitLine($remaining, $header)
+    {
+        return strlen($header.$remaining) > self::DATAGRAM_MAX_LENGTH;
+    }
+}

+ 80 - 0
vendor/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php

@@ -0,0 +1,80 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\Handler\SyslogUdp\UdpSocket;
+
+/**
+ * A Handler for logging to a remote syslogd server.
+ *
+ * @author Jesper Skovgaard Nielsen <nulpunkt@gmail.com>
+ */
+class SyslogUdpHandler extends AbstractSyslogHandler
+{
+    /**
+     * @param string  $host
+     * @param int     $port
+     * @param mixed   $facility
+     * @param integer $level    The minimum logging level at which this handler will be triggered
+     * @param Boolean $bubble   Whether the messages that are handled can bubble up the stack or not
+     */
+    public function __construct($host, $port = 514, $facility = LOG_USER, $level = Logger::DEBUG, $bubble = true)
+    {
+        parent::__construct($facility, $level, $bubble);
+
+        $this->socket = new UdpSocket($host, $port ?: 514);
+    }
+
+    protected function write(array $record)
+    {
+        $lines = $this->splitMessageIntoLines($record['formatted']);
+
+        $header = $this->makeCommonSyslogHeader($this->logLevels[$record['level']]);
+
+        foreach ($lines as $line) {
+            $this->socket->write($line, $header);
+        }
+    }
+
+    public function close()
+    {
+        $this->socket->close();
+    }
+
+    private function splitMessageIntoLines($message)
+    {
+        if (is_array($message)) {
+            $message = implode("\n", $message);
+        }
+
+        return preg_split('/$\R?^/m', $message);
+    }
+
+    /**
+     * Make common syslog header (see rfc5424)
+     */
+    private function makeCommonSyslogHeader($severity)
+    {
+        $priority = $severity + $this->facility;
+
+        return "<$priority>: ";
+    }
+
+    /**
+     * Inject your own socket, mainly used for testing
+     */
+    public function setSocket($socket)
+    {
+        $this->socket = $socket;
+    }
+}

+ 1 - 1
vendor/monolog/monolog/src/Monolog/Logger.php

@@ -103,7 +103,7 @@ class Logger implements LoggerInterface
     );
 
     /**
-     * @var DateTimeZone
+     * @var \DateTimeZone
      */
     protected static $timezone;
 

+ 64 - 0
vendor/monolog/monolog/src/Monolog/Processor/GitProcessor.php

@@ -0,0 +1,64 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Processor;
+
+use Monolog\Logger;
+
+/**
+ * Injects Git branch and Git commit SHA in all records
+ *
+ * @author Nick Otter
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class GitProcessor
+{
+    private $level;
+    private static $cache;
+
+    public function __construct($level = Logger::DEBUG)
+    {
+        $this->level = $level;
+    }
+
+    /**
+     * @param  array $record
+     * @return array
+     */
+    public function __invoke(array $record)
+    {
+        // return if the level is not high enough
+        if ($record['level'] < $this->level) {
+            return $record;
+        }
+
+        $record['extra']['git'] = self::getGitInfo();
+
+        return $record;
+    }
+
+    private static function getGitInfo()
+    {
+        if (self::$cache) {
+            return self::$cache;
+        }
+
+        $branches = `git branch -v --no-abbrev`;
+        if (preg_match('{^\* (.+?)\s+([a-f0-9]{40})(?:\s|$)}m', $branches, $matches)) {
+            return self::$cache = array(
+                'branch' => $matches[1],
+                'commit' => $matches[2],
+            );
+        }
+
+        return self::$cache = array();
+    }
+}

+ 1 - 1
vendor/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php

@@ -26,7 +26,7 @@ class MemoryPeakUsageProcessor extends MemoryProcessor
     public function __invoke(array $record)
     {
         $bytes = memory_get_peak_usage($this->realUsage);
-        $formatted = self::formatBytes($bytes);
+        $formatted = $this->formatBytes($bytes);
 
         $record['extra'] = array_merge(
             $record['extra'],

+ 20 - 6
vendor/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php

@@ -18,26 +18,40 @@ namespace Monolog\Processor;
  */
 abstract class MemoryProcessor
 {
+    /**
+     * @var boolean If true, get the real size of memory allocated from system. Else, only the memory used by emalloc() is reported.
+     */
     protected $realUsage;
 
     /**
-     * @param boolean $realUsage
+     * @var boolean If true, then format memory size to human readable string (MB, KB, B depending on size)
      */
-    public function __construct($realUsage = true)
+    protected $useFormatting;
+
+    /**
+     * @param boolean $realUsage     Set this to true to get the real size of memory allocated from system.
+     * @param boolean $useFormatting If true, then format memory size to human readable string (MB, KB, B depending on size)
+     */
+    public function __construct($realUsage = true, $useFormatting = true)
     {
         $this->realUsage = (boolean) $realUsage;
+        $this->useFormatting = (boolean) $useFormatting;
     }
 
     /**
-     * Formats bytes into a human readable string
+     * Formats bytes into a human readable string if $this->useFormatting is true, otherwise return $bytes as is
      *
-     * @param  int    $bytes
-     * @return string
+     * @param  int        $bytes
+     * @return string|int Formatted string if $this->useFormatting is true, otherwise return $bytes as is
      */
-    protected static function formatBytes($bytes)
+    protected function formatBytes($bytes)
     {
         $bytes = (int) $bytes;
 
+        if (!$this->useFormatting) {
+            return $bytes;
+        }
+
         if ($bytes > 1024*1024) {
             return round($bytes/1024/1024, 2).' MB';
         } elseif ($bytes > 1024) {

+ 1 - 1
vendor/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php

@@ -26,7 +26,7 @@ class MemoryUsageProcessor extends MemoryProcessor
     public function __invoke(array $record)
     {
         $bytes = memory_get_usage($this->realUsage);
-        $formatted = self::formatBytes($bytes);
+        $formatted = $this->formatBytes($bytes);
 
         $record['extra'] = array_merge(
             $record['extra'],

+ 34 - 0
vendor/monolog/monolog/src/Monolog/Processor/TagProcessor.php

@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Processor;
+
+/**
+ * Adds a tags array into record
+ *
+ * @author Martijn Riemers
+ */
+class TagProcessor
+{
+    private $tags;
+
+    public function __construct(array $tags = array())
+    {
+        $this->tags = $tags;
+    }
+
+    public function __invoke(array $record)
+    {
+        $record['extra']['tags'] = $this->tags;
+
+        return $record;
+    }
+}

+ 118 - 0
vendor/monolog/monolog/src/Monolog/Registry.php

@@ -0,0 +1,118 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog;
+
+use InvalidArgumentException;
+
+/**
+ * Monolog log registry
+ *
+ * Allows to get `Logger` instances in the global scope
+ * via static method calls on this class.
+ *
+ * <code>
+ * $application = new Monolog\Logger('application');
+ * $api = new Monolog\Logger('api');
+ *
+ * Monolog\Registry::addLogger($application);
+ * Monolog\Registry::addLogger($api);
+ *
+ * function testLogger()
+ * {
+ *     Monolog\Registry::api()->addError('Sent to $api Logger instance');
+ *     Monolog\Registry::application()->addError('Sent to $application Logger instance');
+ * }
+ * </code>
+ *
+ * @author Tomas Tatarko <tomas@tatarko.sk>
+ */
+class Registry
+{
+    /**
+     * List of all loggers in the registry (ba named indexes)
+     *
+     * @var Logger[]
+     */
+    private static $loggers = array();
+
+    /**
+     * Adds new logging channel to the registry
+     *
+     * @param  Logger                    $logger    Instance of the logging channel
+     * @param  string|null               $name      Name of the logging channel ($logger->getName() by default)
+     * @param  boolean                   $overwrite Overwrite instance in the registry if the given name already exists?
+     * @throws \InvalidArgumentException If $overwrite set to false and named Logger instance already exists
+     */
+    public static function addLogger(Logger $logger, $name = null, $overwrite = false)
+    {
+        $name = $name ?: $logger->getName();
+
+        if (isset(self::$loggers[$name]) && !$overwrite) {
+            throw new InvalidArgumentException('Logger with the given name already exists');
+        }
+
+        self::$loggers[$name] = $logger;
+    }
+
+    /**
+     * Removes instance from registry by name or instance
+     *
+     * @param string|Logger $logger Name or logger instance
+     */
+    public static function removeLogger($logger)
+    {
+        if ($logger instanceof Logger) {
+            if (false !== ($idx = array_search($logger, self::$loggers, true))) {
+                unset(self::$loggers[$idx]);
+            }
+        } else {
+            unset(self::$loggers[$logger]);
+        }
+    }
+
+    /**
+     * Clears the registry
+     */
+    public static function clear()
+    {
+        self::$loggers = array();
+    }
+
+    /**
+     * Gets Logger instance from the registry
+     *
+     * @param  string                    $name Name of the requested Logger instance
+     * @return Logger                    Requested instance of Logger
+     * @throws \InvalidArgumentException If named Logger instance is not in the registry
+     */
+    public static function getInstance($name)
+    {
+        if (!isset(self::$loggers[$name])) {
+            throw new InvalidArgumentException(sprintf('Requested "%s" logger instance is not in the registry', $name));
+        }
+
+        return self::$loggers[$name];
+    }
+
+    /**
+     * Gets Logger instance from the registry via static method call
+     *
+     * @param  string                    $name      Name of the requested Logger instance
+     * @param  array                     $arguments Arguments passed to static method call
+     * @return Logger                    Requested instance of Logger
+     * @throws \InvalidArgumentException If named Logger instance is not in the registry
+     */
+    public static function __callStatic($name, $arguments)
+    {
+        return self::getInstance($name);
+    }
+}

+ 31 - 0
vendor/monolog/monolog/tests/Monolog/ErrorHandlerTest.php

@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog;
+
+use Monolog\Handler\TestHandler;
+
+class ErrorHandlerTest extends \PHPUnit_Framework_TestCase
+{
+    public function testHandleError()
+    {
+        $logger = new Logger('test', array($handler = new TestHandler));
+        $errHandler = new ErrorHandler($logger);
+
+        $errHandler->registerErrorHandler(array(E_USER_NOTICE => Logger::EMERGENCY), false);
+        trigger_error('Foo', E_USER_ERROR);
+        $this->assertCount(1, $handler->getRecords());
+        $this->assertTrue($handler->hasErrorRecords());
+        trigger_error('Foo', E_USER_NOTICE);
+        $this->assertCount(2, $handler->getRecords());
+        $this->assertTrue($handler->hasEmergencyRecords());
+    }
+}

+ 158 - 0
vendor/monolog/monolog/tests/Monolog/Formatter/ChromePHPFormatterTest.php

@@ -0,0 +1,158 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use Monolog\Logger;
+
+class ChromePHPFormatterTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @covers Monolog\Formatter\ChromePHPFormatter::format
+     */
+    public function testDefaultFormat()
+    {
+        $formatter = new ChromePHPFormatter();
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array('from' => 'logger'),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array('ip' => '127.0.0.1'),
+            'message' => 'log',
+        );
+
+        $message = $formatter->format($record);
+
+        $this->assertEquals(
+            array(
+                'meh',
+                array(
+                    'message' => 'log',
+                    'context' => array('from' => 'logger'),
+                    'extra' => array('ip' => '127.0.0.1'),
+                ),
+                'unknown',
+                'error'
+            ),
+            $message
+        );
+    }
+
+    /**
+     * @covers Monolog\Formatter\ChromePHPFormatter::format
+     */
+    public function testFormatWithFileAndLine()
+    {
+        $formatter = new ChromePHPFormatter();
+        $record = array(
+            'level' => Logger::CRITICAL,
+            'level_name' => 'CRITICAL',
+            'channel' => 'meh',
+            'context' => array('from' => 'logger'),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array('ip' => '127.0.0.1', 'file' => 'test', 'line' => 14),
+            'message' => 'log',
+        );
+
+        $message = $formatter->format($record);
+
+        $this->assertEquals(
+            array(
+                'meh',
+                array(
+                    'message' => 'log',
+                    'context' => array('from' => 'logger'),
+                    'extra' => array('ip' => '127.0.0.1'),
+                ),
+                'test : 14',
+                'error'
+            ),
+            $message
+        );
+    }
+
+    /**
+     * @covers Monolog\Formatter\ChromePHPFormatter::format
+     */
+    public function testFormatWithoutContext()
+    {
+        $formatter = new ChromePHPFormatter();
+        $record = array(
+            'level' => Logger::DEBUG,
+            'level_name' => 'DEBUG',
+            'channel' => 'meh',
+            'context' => array(),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array(),
+            'message' => 'log',
+        );
+
+        $message = $formatter->format($record);
+
+        $this->assertEquals(
+            array(
+                'meh',
+                'log',
+                'unknown',
+                'log'
+            ),
+            $message
+        );
+    }
+
+    /**
+     * @covers Monolog\Formatter\ChromePHPFormatter::formatBatch
+     */
+    public function testBatchFormatThrowException()
+    {
+        $formatter = new ChromePHPFormatter();
+        $records = array(
+            array(
+                'level' => Logger::INFO,
+                'level_name' => 'INFO',
+                'channel' => 'meh',
+                'context' => array(),
+                'datetime' => new \DateTime("@0"),
+                'extra' => array(),
+                'message' => 'log',
+            ),
+            array(
+                'level' => Logger::WARNING,
+                'level_name' => 'WARNING',
+                'channel' => 'foo',
+                'context' => array(),
+                'datetime' => new \DateTime("@0"),
+                'extra' => array(),
+                'message' => 'log2',
+            ),
+        );
+
+        $this->assertEquals(
+            array(
+                array(
+                    'meh',
+                    'log',
+                    'unknown',
+                    'info'
+                ),
+                array(
+                    'foo',
+                    'log2',
+                    'unknown',
+                    'warn'
+                ),
+            ),
+            $formatter->formatBatch($records)
+        );
+    }
+}

+ 79 - 0
vendor/monolog/monolog/tests/Monolog/Formatter/ElasticaFormatterTest.php

@@ -0,0 +1,79 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use Monolog\Logger;
+
+class ElasticaFormatterTest extends \PHPUnit_Framework_TestCase
+{
+    public function setUp()
+    {
+        if (!class_exists("Elastica\Document")) {
+            $this->markTestSkipped("ruflin/elastica not installed");
+        }
+    }
+
+    /**
+     * @covers Monolog\Formatter\ElasticaFormatter::__construct
+     * @covers Monolog\Formatter\ElasticaFormatter::format
+     * @covers Monolog\Formatter\ElasticaFormatter::getDocument
+     */
+    public function testFormat()
+    {
+        // test log message
+        $msg = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array('foo' => 7, 'bar', 'class' => new \stdClass),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array(),
+            'message' => 'log',
+        );
+
+        // expected values
+        $expected = $msg;
+        $expected['datetime'] = '1970-01-01T00:00:00+0000';
+        $expected['context'] = array(
+            'class' => '[object] (stdClass: {})',
+            'foo' => 7,
+            0 => 'bar',
+        );
+
+        // format log message
+        $formatter = new ElasticaFormatter('my_index', 'doc_type');
+        $doc = $formatter->format($msg);
+        $this->assertInstanceOf('Elastica\Document', $doc);
+
+        // Document parameters
+        $params = $doc->getParams();
+        $this->assertEquals('my_index', $params['_index']);
+        $this->assertEquals('doc_type', $params['_type']);
+
+        // Document data values
+        $data = $doc->getData();
+        foreach (array_keys($expected) as $key) {
+            $this->assertEquals($expected[$key], $data[$key]);
+        }
+    }
+
+    /**
+     * @covers Monolog\Formatter\ElasticaFormatter::getIndex
+     * @covers Monolog\Formatter\ElasticaFormatter::getType
+     */
+    public function testGetters()
+    {
+        $formatter = new ElasticaFormatter('my_index', 'doc_type');
+        $this->assertEquals('my_index', $formatter->getIndex());
+        $this->assertEquals('doc_type', $formatter->getType());
+    }
+}

+ 55 - 0
vendor/monolog/monolog/tests/Monolog/Formatter/FlowdockFormatterTest.php

@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use Monolog\Logger;
+use Monolog\TestCase;
+
+class FlowdockFormatterTest extends TestCase
+{
+    /**
+     * @covers Monolog\Formatter\FlowdockFormatter::format
+     */
+    public function testFormat()
+    {
+        $formatter = new FlowdockFormatter('test_source', 'source@test.com');
+        $record = $this->getRecord();
+
+        $expected = array(
+            'source' => 'test_source',
+            'from_address' => 'source@test.com',
+            'subject' => 'in test_source: WARNING - test',
+            'content' => 'test',
+            'tags' => array('#logs', '#warning', '#test'),
+            'project' => 'test_source',
+        );
+        $formatted = $formatter->format($record);
+
+        $this->assertEquals($expected, $formatted['flowdock']);
+    }
+
+    /**
+     * @ covers Monolog\Formatter\FlowdockFormatter::formatBatch
+     */
+    public function testFormatBatch()
+    {
+        $formatter = new FlowdockFormatter('test_source', 'source@test.com');
+        $records = array(
+            $this->getRecord(Logger::WARNING),
+            $this->getRecord(Logger::DEBUG),
+        );
+        $formatted = $formatter->formatBatch($records);
+
+        $this->assertArrayHasKey('flowdock', $formatted[0]);
+        $this->assertArrayHasKey('flowdock', $formatted[1]);
+    }
+}

+ 191 - 0
vendor/monolog/monolog/tests/Monolog/Formatter/GelfMessageFormatterTest.php

@@ -0,0 +1,191 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use Monolog\Logger;
+
+class GelfMessageFormatterTest extends \PHPUnit_Framework_TestCase
+{
+    public function setUp()
+    {
+        if (!class_exists('\Gelf\Message')) {
+            $this->markTestSkipped("graylog2/gelf-php or mlehner/gelf-php is not installed");
+        }
+    }
+
+    /**
+     * @covers Monolog\Formatter\GelfMessageFormatter::format
+     */
+    public function testDefaultFormatter()
+    {
+        $formatter = new GelfMessageFormatter();
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array(),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array(),
+            'message' => 'log',
+        );
+
+        $message = $formatter->format($record);
+
+        $this->assertInstanceOf('Gelf\Message', $message);
+        $this->assertEquals(0, $message->getTimestamp());
+        $this->assertEquals('log', $message->getShortMessage());
+        $this->assertEquals('meh', $message->getFacility());
+        $this->assertEquals(null, $message->getLine());
+        $this->assertEquals(null, $message->getFile());
+        $this->assertEquals($this->isLegacy() ? 3 : 'error', $message->getLevel());
+        $this->assertNotEmpty($message->getHost());
+
+        $formatter = new GelfMessageFormatter('mysystem');
+
+        $message = $formatter->format($record);
+
+        $this->assertInstanceOf('Gelf\Message', $message);
+        $this->assertEquals('mysystem', $message->getHost());
+    }
+
+    /**
+     * @covers Monolog\Formatter\GelfMessageFormatter::format
+     */
+    public function testFormatWithFileAndLine()
+    {
+        $formatter = new GelfMessageFormatter();
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array('from' => 'logger'),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array('file' => 'test', 'line' => 14),
+            'message' => 'log',
+        );
+
+        $message = $formatter->format($record);
+
+        $this->assertInstanceOf('Gelf\Message', $message);
+        $this->assertEquals('test', $message->getFile());
+        $this->assertEquals(14, $message->getLine());
+    }
+
+    /**
+     * @covers Monolog\Formatter\GelfMessageFormatter::format
+     */
+    public function testFormatWithContext()
+    {
+        $formatter = new GelfMessageFormatter();
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array('from' => 'logger'),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array('key' => 'pair'),
+            'message' => 'log'
+        );
+
+        $message = $formatter->format($record);
+
+        $this->assertInstanceOf('Gelf\Message', $message);
+
+        $message_array = $message->toArray();
+
+        $this->assertArrayHasKey('_ctxt_from', $message_array);
+        $this->assertEquals('logger', $message_array['_ctxt_from']);
+
+        // Test with extraPrefix
+        $formatter = new GelfMessageFormatter(null, null, 'CTX');
+        $message = $formatter->format($record);
+
+        $this->assertInstanceOf('Gelf\Message', $message);
+
+        $message_array = $message->toArray();
+
+        $this->assertArrayHasKey('_CTXfrom', $message_array);
+        $this->assertEquals('logger', $message_array['_CTXfrom']);
+
+    }
+
+    /**
+     * @covers Monolog\Formatter\GelfMessageFormatter::format
+     */
+    public function testFormatWithContextContainingException()
+    {
+        $formatter = new GelfMessageFormatter();
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array('from' => 'logger', 'exception' => array(
+                'class' => '\Exception',
+                'file'  => '/some/file/in/dir.php:56',
+                'trace' => array('/some/file/1.php:23', '/some/file/2.php:3')
+            )),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array(),
+            'message' => 'log'
+        );
+
+        $message = $formatter->format($record);
+
+        $this->assertInstanceOf('Gelf\Message', $message);
+
+        $this->assertEquals("/some/file/in/dir.php", $message->getFile());
+        $this->assertEquals("56", $message->getLine());
+
+    }
+
+    /**
+     * @covers Monolog\Formatter\GelfMessageFormatter::format
+     */
+    public function testFormatWithExtra()
+    {
+        $formatter = new GelfMessageFormatter();
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array('from' => 'logger'),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array('key' => 'pair'),
+            'message' => 'log'
+        );
+
+        $message = $formatter->format($record);
+
+        $this->assertInstanceOf('Gelf\Message', $message);
+
+        $message_array = $message->toArray();
+
+        $this->assertArrayHasKey('_key', $message_array);
+        $this->assertEquals('pair', $message_array['_key']);
+
+        // Test with extraPrefix
+        $formatter = new GelfMessageFormatter(null, 'EXT');
+        $message = $formatter->format($record);
+
+        $this->assertInstanceOf('Gelf\Message', $message);
+
+        $message_array = $message->toArray();
+
+        $this->assertArrayHasKey('_EXTkey', $message_array);
+        $this->assertEquals('pair', $message_array['_EXTkey']);
+    }
+
+    private function isLegacy()
+    {
+        return interface_exists('\Gelf\IMessagePublisher');
+    }
+}

+ 79 - 0
vendor/monolog/monolog/tests/Monolog/Formatter/JsonFormatterTest.php

@@ -0,0 +1,79 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use Monolog\Logger;
+use Monolog\TestCase;
+
+class JsonFormatterTest extends TestCase
+{
+    /**
+     * @covers Monolog\Formatter\JsonFormatter::__construct
+     * @covers Monolog\Formatter\JsonFormatter::getBatchMode
+     * @covers Monolog\Formatter\JsonFormatter::isAppendingNewlines
+     */
+    public function testConstruct()
+    {
+        $formatter = new JsonFormatter();
+        $this->assertEquals(JsonFormatter::BATCH_MODE_JSON, $formatter->getBatchMode());
+        $this->assertEquals(true, $formatter->isAppendingNewlines());
+        $formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_NEWLINES, false);
+        $this->assertEquals(JsonFormatter::BATCH_MODE_NEWLINES, $formatter->getBatchMode());
+        $this->assertEquals(false, $formatter->isAppendingNewlines());
+    }
+
+    /**
+     * @covers Monolog\Formatter\JsonFormatter::format
+     */
+    public function testFormat()
+    {
+        $formatter = new JsonFormatter();
+        $record = $this->getRecord();
+        $this->assertEquals(json_encode($record)."\n", $formatter->format($record));
+
+        $formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false);
+        $record = $this->getRecord();
+        $this->assertEquals(json_encode($record), $formatter->format($record));
+    }
+
+    /**
+     * @covers Monolog\Formatter\JsonFormatter::formatBatch
+     * @covers Monolog\Formatter\JsonFormatter::formatBatchJson
+     */
+    public function testFormatBatch()
+    {
+        $formatter = new JsonFormatter();
+        $records = array(
+            $this->getRecord(Logger::WARNING),
+            $this->getRecord(Logger::DEBUG),
+        );
+        $this->assertEquals(json_encode($records), $formatter->formatBatch($records));
+    }
+
+    /**
+     * @covers Monolog\Formatter\JsonFormatter::formatBatch
+     * @covers Monolog\Formatter\JsonFormatter::formatBatchNewlines
+     */
+    public function testFormatBatchNewlines()
+    {
+
+        $formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_NEWLINES);
+        $records = $expected = array(
+            $this->getRecord(Logger::WARNING),
+            $this->getRecord(Logger::DEBUG),
+        );
+        array_walk($expected, function (&$value, $key) {
+            $value = json_encode($value);
+        });
+        $this->assertEquals(implode("\n", $expected), $formatter->formatBatch($records));
+    }
+}

+ 194 - 0
vendor/monolog/monolog/tests/Monolog/Formatter/LineFormatterTest.php

@@ -0,0 +1,194 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+/**
+ * @covers Monolog\Formatter\LineFormatter
+ */
+class LineFormatterTest extends \PHPUnit_Framework_TestCase
+{
+    public function testDefFormatWithString()
+    {
+        $formatter = new LineFormatter(null, 'Y-m-d');
+        $message = $formatter->format(array(
+            'level_name' => 'WARNING',
+            'channel' => 'log',
+            'context' => array(),
+            'message' => 'foo',
+            'datetime' => new \DateTime,
+            'extra' => array(),
+        ));
+        $this->assertEquals('['.date('Y-m-d').'] log.WARNING: foo [] []'."\n", $message);
+    }
+
+    public function testDefFormatWithArrayContext()
+    {
+        $formatter = new LineFormatter(null, 'Y-m-d');
+        $message = $formatter->format(array(
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'message' => 'foo',
+            'datetime' => new \DateTime,
+            'extra' => array(),
+            'context' => array(
+                'foo' => 'bar',
+                'baz' => 'qux',
+                'bool' => false,
+                'null' => null,
+            )
+        ));
+        $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: foo {"foo":"bar","baz":"qux","bool":false,"null":null} []'."\n", $message);
+    }
+
+    public function testDefFormatExtras()
+    {
+        $formatter = new LineFormatter(null, 'Y-m-d');
+        $message = $formatter->format(array(
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array(),
+            'datetime' => new \DateTime,
+            'extra' => array('ip' => '127.0.0.1'),
+            'message' => 'log',
+        ));
+        $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: log [] {"ip":"127.0.0.1"}'."\n", $message);
+    }
+
+    public function testFormatExtras()
+    {
+        $formatter = new LineFormatter("[%datetime%] %channel%.%level_name%: %message% %context% %extra.file% %extra%\n", 'Y-m-d');
+        $message = $formatter->format(array(
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array(),
+            'datetime' => new \DateTime,
+            'extra' => array('ip' => '127.0.0.1', 'file' => 'test'),
+            'message' => 'log',
+        ));
+        $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: log [] test {"ip":"127.0.0.1"}'."\n", $message);
+    }
+
+    public function testDefFormatWithObject()
+    {
+        $formatter = new LineFormatter(null, 'Y-m-d');
+        $message = $formatter->format(array(
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array(),
+            'datetime' => new \DateTime,
+            'extra' => array('foo' => new TestFoo, 'bar' => new TestBar, 'baz' => array(), 'res' => fopen('php://memory', 'rb')),
+            'message' => 'foobar',
+        ));
+
+        $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: foobar [] {"foo":"[object] (Monolog\\\\Formatter\\\\TestFoo: {\\"foo\\":\\"foo\\"})","bar":"[object] (Monolog\\\\Formatter\\\\TestBar: {})","baz":[],"res":"[resource]"}'."\n", $message);
+    }
+
+    public function testDefFormatWithException()
+    {
+        $formatter = new LineFormatter(null, 'Y-m-d');
+        $message = $formatter->format(array(
+            'level_name' => 'CRITICAL',
+            'channel' => 'core',
+            'context' => array('exception' => new \RuntimeException('Foo')),
+            'datetime' => new \DateTime,
+            'extra' => array(),
+            'message' => 'foobar',
+        ));
+
+        $path = str_replace('\\/', '/', json_encode(__FILE__));
+
+        $this->assertEquals('['.date('Y-m-d').'] core.CRITICAL: foobar {"exception":"[object] (RuntimeException: Foo at '.substr($path, 1, -1).':'.(__LINE__-8).')"} []'."\n", $message);
+    }
+
+    public function testDefFormatWithPreviousException()
+    {
+        $formatter = new LineFormatter(null, 'Y-m-d');
+        $previous = new \LogicException('Wut?');
+        $message = $formatter->format(array(
+            'level_name' => 'CRITICAL',
+            'channel' => 'core',
+            'context' => array('exception' => new \RuntimeException('Foo', 0, $previous)),
+            'datetime' => new \DateTime,
+            'extra' => array(),
+            'message' => 'foobar',
+        ));
+
+        $path = str_replace('\\/', '/', json_encode(__FILE__));
+
+        $this->assertEquals('['.date('Y-m-d').'] core.CRITICAL: foobar {"exception":"[object] (RuntimeException: Foo at '.substr($path, 1, -1).':'.(__LINE__-8).', LogicException: Wut? at '.substr($path, 1, -1).':'.(__LINE__-12).')"} []'."\n", $message);
+    }
+
+    public function testBatchFormat()
+    {
+        $formatter = new LineFormatter(null, 'Y-m-d');
+        $message = $formatter->formatBatch(array(
+            array(
+                'level_name' => 'CRITICAL',
+                'channel' => 'test',
+                'message' => 'bar',
+                'context' => array(),
+                'datetime' => new \DateTime,
+                'extra' => array(),
+            ),
+            array(
+                'level_name' => 'WARNING',
+                'channel' => 'log',
+                'message' => 'foo',
+                'context' => array(),
+                'datetime' => new \DateTime,
+                'extra' => array(),
+            ),
+        ));
+        $this->assertEquals('['.date('Y-m-d').'] test.CRITICAL: bar [] []'."\n".'['.date('Y-m-d').'] log.WARNING: foo [] []'."\n", $message);
+    }
+
+    public function testFormatShouldStripInlineLineBreaks()
+    {
+        $formatter = new LineFormatter(null, 'Y-m-d');
+        $message = $formatter->format(
+            array(
+                'message' => "foo\nbar",
+                'context' => array(),
+                'extra' => array(),
+            )
+        );
+
+        $this->assertRegExp('/foo bar/', $message);
+    }
+
+    public function testFormatShouldNotStripInlineLineBreaksWhenFlagIsSet()
+    {
+        $formatter = new LineFormatter(null, 'Y-m-d', true);
+        $message = $formatter->format(
+            array(
+                'message' => "foo\nbar",
+                'context' => array(),
+                'extra' => array(),
+            )
+        );
+
+        $this->assertRegExp('/foo\nbar/', $message);
+    }
+}
+
+class TestFoo
+{
+    public $foo = 'foo';
+}
+
+class TestBar
+{
+    public function __toString()
+    {
+        return 'bar';
+    }
+}

+ 40 - 0
vendor/monolog/monolog/tests/Monolog/Formatter/LogglyFormatterTest.php

@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use Monolog\TestCase;
+
+class LogglyFormatterTest extends TestCase
+{
+    /**
+     * @covers Monolog\Formatter\LogglyFormatter::__construct
+     */
+    public function testConstruct()
+    {
+        $formatter = new LogglyFormatter();
+        $this->assertEquals(LogglyFormatter::BATCH_MODE_NEWLINES, $formatter->getBatchMode());
+        $formatter = new LogglyFormatter(LogglyFormatter::BATCH_MODE_JSON);
+        $this->assertEquals(LogglyFormatter::BATCH_MODE_JSON, $formatter->getBatchMode());
+    }
+
+    /**
+     * @covers Monolog\Formatter\LogglyFormatter::format
+     */
+    public function testFormat()
+    {
+        $formatter = new LogglyFormatter();
+        $record = $this->getRecord();
+        $formatted_decoded = json_decode($formatter->format($record), true);
+        $this->assertArrayHasKey("timestamp", $formatted_decoded);
+        $this->assertEquals(new \DateTime($formatted_decoded["timestamp"]), $record["datetime"]);
+    }
+}

+ 292 - 0
vendor/monolog/monolog/tests/Monolog/Formatter/LogstashFormatterTest.php

@@ -0,0 +1,292 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use Monolog\Logger;
+
+class LogstashFormatterTest extends \PHPUnit_Framework_TestCase
+{
+
+    /**
+     * @covers Monolog\Formatter\LogstashFormatter::format
+     */
+    public function testDefaultFormatter()
+    {
+        $formatter = new LogstashFormatter('test', 'hostname');
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array(),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array(),
+            'message' => 'log',
+        );
+
+        $message = json_decode($formatter->format($record), true);
+
+        $this->assertEquals("1970-01-01T00:00:00.000000+00:00", $message['@timestamp']);
+        $this->assertEquals('log', $message['@message']);
+        $this->assertEquals('meh', $message['@fields']['channel']);
+        $this->assertContains('meh', $message['@tags']);
+        $this->assertEquals(Logger::ERROR, $message['@fields']['level']);
+        $this->assertEquals('test', $message['@type']);
+        $this->assertEquals('hostname', $message['@source']);
+
+        $formatter = new LogstashFormatter('mysystem');
+
+        $message = json_decode($formatter->format($record), true);
+
+        $this->assertEquals('mysystem', $message['@type']);
+    }
+
+    /**
+     * @covers Monolog\Formatter\LogstashFormatter::format
+     */
+    public function testFormatWithFileAndLine()
+    {
+        $formatter = new LogstashFormatter('test');
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array('from' => 'logger'),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array('file' => 'test', 'line' => 14),
+            'message' => 'log',
+        );
+
+        $message = json_decode($formatter->format($record), true);
+
+        $this->assertEquals('test', $message['@fields']['file']);
+        $this->assertEquals(14, $message['@fields']['line']);
+    }
+
+    /**
+     * @covers Monolog\Formatter\LogstashFormatter::format
+     */
+    public function testFormatWithContext()
+    {
+        $formatter = new LogstashFormatter('test');
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array('from' => 'logger'),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array('key' => 'pair'),
+            'message' => 'log'
+        );
+
+        $message = json_decode($formatter->format($record), true);
+
+        $message_array = $message['@fields'];
+
+        $this->assertArrayHasKey('ctxt_from', $message_array);
+        $this->assertEquals('logger', $message_array['ctxt_from']);
+
+        // Test with extraPrefix
+        $formatter = new LogstashFormatter('test', null, null, 'CTX');
+        $message = json_decode($formatter->format($record), true);
+
+        $message_array = $message['@fields'];
+
+        $this->assertArrayHasKey('CTXfrom', $message_array);
+        $this->assertEquals('logger', $message_array['CTXfrom']);
+
+    }
+
+    /**
+     * @covers Monolog\Formatter\LogstashFormatter::format
+     */
+    public function testFormatWithExtra()
+    {
+        $formatter = new LogstashFormatter('test');
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array('from' => 'logger'),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array('key' => 'pair'),
+            'message' => 'log'
+        );
+
+        $message = json_decode($formatter->format($record), true);
+
+        $message_array = $message['@fields'];
+
+        $this->assertArrayHasKey('key', $message_array);
+        $this->assertEquals('pair', $message_array['key']);
+
+        // Test with extraPrefix
+        $formatter = new LogstashFormatter('test', null, 'EXT');
+        $message = json_decode($formatter->format($record), true);
+
+        $message_array = $message['@fields'];
+
+        $this->assertArrayHasKey('EXTkey', $message_array);
+        $this->assertEquals('pair', $message_array['EXTkey']);
+    }
+
+    public function testFormatWithApplicationName()
+    {
+        $formatter = new LogstashFormatter('app', 'test');
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array('from' => 'logger'),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array('key' => 'pair'),
+            'message' => 'log'
+        );
+
+        $message = json_decode($formatter->format($record), true);
+
+        $this->assertArrayHasKey('@type', $message);
+        $this->assertEquals('app', $message['@type']);
+    }
+
+    /**
+     * @covers Monolog\Formatter\LogstashFormatter::format
+     */
+    public function testDefaultFormatterV1()
+    {
+        $formatter = new LogstashFormatter('test', 'hostname', null, 'ctxt_', LogstashFormatter::V1);
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array(),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array(),
+            'message' => 'log',
+        );
+
+        $message = json_decode($formatter->format($record), true);
+
+        $this->assertEquals("1970-01-01T00:00:00.000000+00:00", $message['@timestamp']);
+        $this->assertEquals("1", $message['@version']);
+        $this->assertEquals('log', $message['message']);
+        $this->assertEquals('meh', $message['channel']);
+        $this->assertEquals('ERROR', $message['level']);
+        $this->assertEquals('test', $message['type']);
+        $this->assertEquals('hostname', $message['host']);
+
+        $formatter = new LogstashFormatter('mysystem', null, null, 'ctxt_', LogstashFormatter::V1);
+
+        $message = json_decode($formatter->format($record), true);
+
+        $this->assertEquals('mysystem', $message['type']);
+    }
+
+    /**
+     * @covers Monolog\Formatter\LogstashFormatter::format
+     */
+    public function testFormatWithFileAndLineV1()
+    {
+        $formatter = new LogstashFormatter('test', null, null, 'ctxt_', LogstashFormatter::V1);
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array('from' => 'logger'),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array('file' => 'test', 'line' => 14),
+            'message' => 'log',
+        );
+
+        $message = json_decode($formatter->format($record), true);
+
+        $this->assertEquals('test', $message['file']);
+        $this->assertEquals(14, $message['line']);
+    }
+
+    /**
+     * @covers Monolog\Formatter\LogstashFormatter::format
+     */
+    public function testFormatWithContextV1()
+    {
+        $formatter = new LogstashFormatter('test', null, null, 'ctxt_', LogstashFormatter::V1);
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array('from' => 'logger'),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array('key' => 'pair'),
+            'message' => 'log'
+        );
+
+        $message = json_decode($formatter->format($record), true);
+
+        $this->assertArrayHasKey('ctxt_from', $message);
+        $this->assertEquals('logger', $message['ctxt_from']);
+
+        // Test with extraPrefix
+        $formatter = new LogstashFormatter('test', null, null, 'CTX', LogstashFormatter::V1);
+        $message = json_decode($formatter->format($record), true);
+
+        $this->assertArrayHasKey('CTXfrom', $message);
+        $this->assertEquals('logger', $message['CTXfrom']);
+
+    }
+
+    /**
+     * @covers Monolog\Formatter\LogstashFormatter::format
+     */
+    public function testFormatWithExtraV1()
+    {
+        $formatter = new LogstashFormatter('test', null, null, 'ctxt_', LogstashFormatter::V1);
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array('from' => 'logger'),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array('key' => 'pair'),
+            'message' => 'log'
+        );
+
+        $message = json_decode($formatter->format($record), true);
+
+        $this->assertArrayHasKey('key', $message);
+        $this->assertEquals('pair', $message['key']);
+
+        // Test with extraPrefix
+        $formatter = new LogstashFormatter('test', null, 'EXT', 'ctxt_', LogstashFormatter::V1);
+        $message = json_decode($formatter->format($record), true);
+
+        $this->assertArrayHasKey('EXTkey', $message);
+        $this->assertEquals('pair', $message['EXTkey']);
+    }
+
+    public function testFormatWithApplicationNameV1()
+    {
+        $formatter = new LogstashFormatter('app', 'test', null, 'ctxt_', LogstashFormatter::V1);
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array('from' => 'logger'),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array('key' => 'pair'),
+            'message' => 'log'
+        );
+
+        $message = json_decode($formatter->format($record), true);
+
+        $this->assertArrayHasKey('type', $message);
+        $this->assertEquals('app', $message['type']);
+    }
+}

+ 182 - 0
vendor/monolog/monolog/tests/Monolog/Formatter/NormalizerFormatterTest.php

@@ -0,0 +1,182 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+/**
+ * @covers Monolog\Formatter\NormalizerFormatter
+ */
+class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase
+{
+    public function testFormat()
+    {
+        $formatter = new NormalizerFormatter('Y-m-d');
+        $formatted = $formatter->format(array(
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'message' => 'foo',
+            'datetime' => new \DateTime,
+            'extra' => array('foo' => new TestFooNorm, 'bar' => new TestBarNorm, 'baz' => array(), 'res' => fopen('php://memory', 'rb')),
+            'context' => array(
+                'foo' => 'bar',
+                'baz' => 'qux',
+            ),
+        ));
+
+        $this->assertEquals(array(
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'message' => 'foo',
+            'datetime' => date('Y-m-d'),
+            'extra' => array(
+                'foo' => '[object] (Monolog\\Formatter\\TestFooNorm: {"foo":"foo"})',
+                'bar' => '[object] (Monolog\\Formatter\\TestBarNorm: {})',
+                'baz' => array(),
+                'res' => '[resource]',
+            ),
+            'context' => array(
+                'foo' => 'bar',
+                'baz' => 'qux',
+            )
+        ), $formatted);
+    }
+
+    public function testFormatExceptions()
+    {
+        $formatter = new NormalizerFormatter('Y-m-d');
+        $e = new \LogicException('bar');
+        $e2 = new \RuntimeException('foo', 0, $e);
+        $formatted = $formatter->format(array(
+            'exception' => $e2,
+        ));
+
+        $this->assertGreaterThan(5, count($formatted['exception']['trace']));
+        $this->assertTrue(isset($formatted['exception']['previous']));
+        unset($formatted['exception']['trace'], $formatted['exception']['previous']);
+
+        $this->assertEquals(array(
+            'exception' => array(
+                'class'   => get_class($e2),
+                'message' => $e2->getMessage(),
+                'file'   => $e2->getFile().':'.$e2->getLine(),
+            )
+        ), $formatted);
+    }
+
+    public function testBatchFormat()
+    {
+        $formatter = new NormalizerFormatter('Y-m-d');
+        $formatted = $formatter->formatBatch(array(
+            array(
+                'level_name' => 'CRITICAL',
+                'channel' => 'test',
+                'message' => 'bar',
+                'context' => array(),
+                'datetime' => new \DateTime,
+                'extra' => array(),
+            ),
+            array(
+                'level_name' => 'WARNING',
+                'channel' => 'log',
+                'message' => 'foo',
+                'context' => array(),
+                'datetime' => new \DateTime,
+                'extra' => array(),
+            ),
+        ));
+        $this->assertEquals(array(
+            array(
+                'level_name' => 'CRITICAL',
+                'channel' => 'test',
+                'message' => 'bar',
+                'context' => array(),
+                'datetime' => date('Y-m-d'),
+                'extra' => array(),
+            ),
+            array(
+                'level_name' => 'WARNING',
+                'channel' => 'log',
+                'message' => 'foo',
+                'context' => array(),
+                'datetime' => date('Y-m-d'),
+                'extra' => array(),
+            ),
+        ), $formatted);
+    }
+
+    /**
+     * Test issue #137
+     */
+    public function testIgnoresRecursiveObjectReferences()
+    {
+        // set up the recursion
+        $foo = new \stdClass();
+        $bar = new \stdClass();
+
+        $foo->bar = $bar;
+        $bar->foo = $foo;
+
+        // set an error handler to assert that the error is not raised anymore
+        $that = $this;
+        set_error_handler(function ($level, $message, $file, $line, $context) use ($that) {
+            if (error_reporting() & $level) {
+                restore_error_handler();
+                $that->fail("$message should not be raised");
+            }
+        });
+
+        $formatter = new NormalizerFormatter();
+        $reflMethod = new \ReflectionMethod($formatter, 'toJson');
+        $reflMethod->setAccessible(true);
+        $res = $reflMethod->invoke($formatter, array($foo, $bar), true);
+
+        restore_error_handler();
+
+        $this->assertEquals(@json_encode(array($foo, $bar)), $res);
+    }
+
+    public function testIgnoresInvalidTypes()
+    {
+        // set up the recursion
+        $resource = fopen(__FILE__, 'r');
+
+        // set an error handler to assert that the error is not raised anymore
+        $that = $this;
+        set_error_handler(function ($level, $message, $file, $line, $context) use ($that) {
+            if (error_reporting() & $level) {
+                restore_error_handler();
+                $that->fail("$message should not be raised");
+            }
+        });
+
+        $formatter = new NormalizerFormatter();
+        $reflMethod = new \ReflectionMethod($formatter, 'toJson');
+        $reflMethod->setAccessible(true);
+        $res = $reflMethod->invoke($formatter, array($resource), true);
+
+        restore_error_handler();
+
+        $this->assertEquals(@json_encode(array($resource)), $res);
+    }
+}
+
+class TestFooNorm
+{
+    public $foo = 'foo';
+}
+
+class TestBarNorm
+{
+    public function __toString()
+    {
+        return 'bar';
+    }
+}

+ 96 - 0
vendor/monolog/monolog/tests/Monolog/Formatter/ScalarFormatterTest.php

@@ -0,0 +1,96 @@
+<?php
+namespace Monolog\Formatter;
+
+class ScalarFormatterTest extends \PHPUnit_Framework_TestCase
+{
+    public function setUp()
+    {
+        $this->formatter = new ScalarFormatter();
+    }
+
+    public function buildTrace(\Exception $e)
+    {
+        $data = array();
+        $trace = $e->getTrace();
+        foreach ($trace as $frame) {
+            if (isset($frame['file'])) {
+                $data[] = $frame['file'].':'.$frame['line'];
+            } else {
+                $data[] = json_encode($frame);
+            }
+        }
+
+        return $data;
+    }
+
+    public function encodeJson($data)
+    {
+        if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
+            return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
+        }
+
+        return json_encode($data);
+    }
+
+    public function testFormat()
+    {
+        $exception = new \Exception('foo');
+        $formatted = $this->formatter->format(array(
+            'foo' => 'string',
+            'bar' => 1,
+            'baz' => false,
+            'bam' => array(1,2,3),
+            'bat' => array('foo' => 'bar'),
+            'bap' => \DateTime::createFromFormat(\DateTime::ISO8601, '1970-01-01T00:00:00+0000'),
+            'ban' => $exception
+        ));
+
+        $this->assertSame(array(
+            'foo' => 'string',
+            'bar' => 1,
+            'baz' => false,
+            'bam' => $this->encodeJson(array(1,2,3)),
+            'bat' => $this->encodeJson(array('foo' => 'bar')),
+            'bap' => '1970-01-01 00:00:00',
+            'ban' => $this->encodeJson(array(
+                'class'   => get_class($exception),
+                'message' => $exception->getMessage(),
+                'file'    => $exception->getFile() . ':' . $exception->getLine(),
+                'trace'   => $this->buildTrace($exception)
+            ))
+        ), $formatted);
+    }
+
+    public function testFormatWithErrorContext()
+    {
+        $context = array('file' => 'foo', 'line' => 1);
+        $formatted = $this->formatter->format(array(
+            'context' => $context
+        ));
+
+        $this->assertSame(array(
+            'context' => $this->encodeJson($context)
+        ), $formatted);
+    }
+
+    public function testFormatWithExceptionContext()
+    {
+        $exception = new \Exception('foo');
+        $formatted = $this->formatter->format(array(
+            'context' => array(
+                'exception' => $exception
+            )
+        ));
+
+        $this->assertSame(array(
+            'context' => $this->encodeJson(array(
+                'exception' => array(
+                    'class'   => get_class($exception),
+                    'message' => $exception->getMessage(),
+                    'file'    => $exception->getFile() . ':' . $exception->getLine(),
+                    'trace'   => $this->buildTrace($exception)
+                )
+            ))
+        ), $formatted);
+    }
+}

+ 142 - 0
vendor/monolog/monolog/tests/Monolog/Formatter/WildfireFormatterTest.php

@@ -0,0 +1,142 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use Monolog\Logger;
+
+class WildfireFormatterTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @covers Monolog\Formatter\WildfireFormatter::format
+     */
+    public function testDefaultFormat()
+    {
+        $wildfire = new WildfireFormatter();
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array('from' => 'logger'),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array('ip' => '127.0.0.1'),
+            'message' => 'log',
+        );
+
+        $message = $wildfire->format($record);
+
+        $this->assertEquals(
+            '125|[{"Type":"ERROR","File":"","Line":"","Label":"meh"},'
+                .'{"message":"log","context":{"from":"logger"},"extra":{"ip":"127.0.0.1"}}]|',
+            $message
+        );
+    }
+
+    /**
+     * @covers Monolog\Formatter\WildfireFormatter::format
+     */
+    public function testFormatWithFileAndLine()
+    {
+        $wildfire = new WildfireFormatter();
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array('from' => 'logger'),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array('ip' => '127.0.0.1', 'file' => 'test', 'line' => 14),
+            'message' => 'log',
+        );
+
+        $message = $wildfire->format($record);
+
+        $this->assertEquals(
+            '129|[{"Type":"ERROR","File":"test","Line":14,"Label":"meh"},'
+                .'{"message":"log","context":{"from":"logger"},"extra":{"ip":"127.0.0.1"}}]|',
+            $message
+        );
+    }
+
+    /**
+     * @covers Monolog\Formatter\WildfireFormatter::format
+     */
+    public function testFormatWithoutContext()
+    {
+        $wildfire = new WildfireFormatter();
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array(),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array(),
+            'message' => 'log',
+        );
+
+        $message = $wildfire->format($record);
+
+        $this->assertEquals(
+            '58|[{"Type":"ERROR","File":"","Line":"","Label":"meh"},"log"]|',
+            $message
+        );
+    }
+
+    /**
+     * @covers Monolog\Formatter\WildfireFormatter::formatBatch
+     * @expectedException BadMethodCallException
+     */
+    public function testBatchFormatThrowException()
+    {
+        $wildfire = new WildfireFormatter();
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array(),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array(),
+            'message' => 'log',
+        );
+
+        $wildfire->formatBatch(array($record));
+    }
+
+    /**
+     * @covers Monolog\Formatter\WildfireFormatter::format
+     */
+    public function testTableFormat()
+    {
+        $wildfire = new WildfireFormatter();
+        $record = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'table-channel',
+            'context' => array(
+            WildfireFormatter::TABLE => array(
+                    array('col1', 'col2', 'col3'),
+                    array('val1', 'val2', 'val3'),
+                    array('foo1', 'foo2', 'foo3'),
+                    array('bar1', 'bar2', 'bar3'),
+                ),
+            ),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array(),
+            'message' => 'table-message',
+        );
+
+        $message = $wildfire->format($record);
+
+        $this->assertEquals(
+            '171|[{"Type":"TABLE","File":"","Line":"","Label":"table-channel: table-message"},[["col1","col2","col3"],["val1","val2","val3"],["foo1","foo2","foo3"],["bar1","bar2","bar3"]]]|',
+            $message
+        );
+    }
+}

+ 32 - 0
vendor/monolog/monolog/tests/Monolog/Functional/Handler/FirePHPHandlerTest.php

@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+spl_autoload_register(function ($class) {
+    $file = __DIR__.'/../../../../src/'.strtr($class, '\\', '/').'.php';
+    if (file_exists($file)) {
+        require $file;
+
+        return true;
+    }
+});
+
+use Monolog\Logger;
+use Monolog\Handler\FirePHPHandler;
+use Monolog\Handler\ChromePHPHandler;
+
+$logger = new Logger('firephp');
+$logger->pushHandler(new FirePHPHandler);
+$logger->pushHandler(new ChromePHPHandler());
+
+$logger->addDebug('Debug');
+$logger->addInfo('Info');
+$logger->addWarning('Warning');
+$logger->addError('Error');

+ 104 - 0
vendor/monolog/monolog/tests/Monolog/Handler/AbstractHandlerTest.php

@@ -0,0 +1,104 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+use Monolog\Formatter\LineFormatter;
+use Monolog\Processor\WebProcessor;
+
+class AbstractHandlerTest extends TestCase
+{
+    /**
+     * @covers Monolog\Handler\AbstractHandler::__construct
+     * @covers Monolog\Handler\AbstractHandler::getLevel
+     * @covers Monolog\Handler\AbstractHandler::setLevel
+     * @covers Monolog\Handler\AbstractHandler::getBubble
+     * @covers Monolog\Handler\AbstractHandler::setBubble
+     * @covers Monolog\Handler\AbstractHandler::getFormatter
+     * @covers Monolog\Handler\AbstractHandler::setFormatter
+     */
+    public function testConstructAndGetSet()
+    {
+        $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler', array(Logger::WARNING, false));
+        $this->assertEquals(Logger::WARNING, $handler->getLevel());
+        $this->assertEquals(false, $handler->getBubble());
+
+        $handler->setLevel(Logger::ERROR);
+        $handler->setBubble(true);
+        $handler->setFormatter($formatter = new LineFormatter);
+        $this->assertEquals(Logger::ERROR, $handler->getLevel());
+        $this->assertEquals(true, $handler->getBubble());
+        $this->assertSame($formatter, $handler->getFormatter());
+    }
+
+    /**
+     * @covers Monolog\Handler\AbstractHandler::handleBatch
+     */
+    public function testHandleBatch()
+    {
+        $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler');
+        $handler->expects($this->exactly(2))
+            ->method('handle');
+        $handler->handleBatch(array($this->getRecord(), $this->getRecord()));
+    }
+
+    /**
+     * @covers Monolog\Handler\AbstractHandler::isHandling
+     */
+    public function testIsHandling()
+    {
+        $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler', array(Logger::WARNING, false));
+        $this->assertTrue($handler->isHandling($this->getRecord()));
+        $this->assertFalse($handler->isHandling($this->getRecord(Logger::DEBUG)));
+    }
+
+    /**
+     * @covers Monolog\Handler\AbstractHandler::getFormatter
+     * @covers Monolog\Handler\AbstractHandler::getDefaultFormatter
+     */
+    public function testGetFormatterInitializesDefault()
+    {
+        $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler');
+        $this->assertInstanceOf('Monolog\Formatter\LineFormatter', $handler->getFormatter());
+    }
+
+    /**
+     * @covers Monolog\Handler\AbstractHandler::pushProcessor
+     * @covers Monolog\Handler\AbstractHandler::popProcessor
+     * @expectedException LogicException
+     */
+    public function testPushPopProcessor()
+    {
+        $logger = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler');
+        $processor1 = new WebProcessor;
+        $processor2 = new WebProcessor;
+
+        $logger->pushProcessor($processor1);
+        $logger->pushProcessor($processor2);
+
+        $this->assertEquals($processor2, $logger->popProcessor());
+        $this->assertEquals($processor1, $logger->popProcessor());
+        $logger->popProcessor();
+    }
+
+    /**
+     * @covers Monolog\Handler\AbstractHandler::pushProcessor
+     * @expectedException InvalidArgumentException
+     */
+    public function testPushProcessorWithNonCallable()
+    {
+        $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler');
+
+        $handler->pushProcessor(new \stdClass());
+    }
+}

+ 80 - 0
vendor/monolog/monolog/tests/Monolog/Handler/AbstractProcessingHandlerTest.php

@@ -0,0 +1,80 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+use Monolog\Processor\WebProcessor;
+
+class AbstractProcessingHandlerTest extends TestCase
+{
+    /**
+     * @covers Monolog\Handler\AbstractProcessingHandler::handle
+     */
+    public function testHandleLowerLevelMessage()
+    {
+        $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', array(Logger::WARNING, true));
+        $this->assertFalse($handler->handle($this->getRecord(Logger::DEBUG)));
+    }
+
+    /**
+     * @covers Monolog\Handler\AbstractProcessingHandler::handle
+     */
+    public function testHandleBubbling()
+    {
+        $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', array(Logger::DEBUG, true));
+        $this->assertFalse($handler->handle($this->getRecord()));
+    }
+
+    /**
+     * @covers Monolog\Handler\AbstractProcessingHandler::handle
+     */
+    public function testHandleNotBubbling()
+    {
+        $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', array(Logger::DEBUG, false));
+        $this->assertTrue($handler->handle($this->getRecord()));
+    }
+
+    /**
+     * @covers Monolog\Handler\AbstractProcessingHandler::handle
+     */
+    public function testHandleIsFalseWhenNotHandled()
+    {
+        $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', array(Logger::WARNING, false));
+        $this->assertTrue($handler->handle($this->getRecord()));
+        $this->assertFalse($handler->handle($this->getRecord(Logger::DEBUG)));
+    }
+
+    /**
+     * @covers Monolog\Handler\AbstractProcessingHandler::processRecord
+     */
+    public function testProcessRecord()
+    {
+        $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler');
+        $handler->pushProcessor(new WebProcessor(array(
+            'REQUEST_URI' => '',
+            'REQUEST_METHOD' => '',
+            'REMOTE_ADDR' => '',
+            'SERVER_NAME' => '',
+            'UNIQUE_ID' => '',
+        )));
+        $handledRecord = null;
+        $handler->expects($this->once())
+            ->method('write')
+            ->will($this->returnCallback(function ($record) use (&$handledRecord) {
+                $handledRecord = $record;
+            }))
+        ;
+        $handler->handle($this->getRecord());
+        $this->assertEquals(6, count($handledRecord['extra']));
+    }
+}

+ 80 - 0
vendor/monolog/monolog/tests/Monolog/Handler/AmqpHandlerTest.php

@@ -0,0 +1,80 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+
+/**
+ * @covers Monolog\Handler\RotatingFileHandler
+ */
+class AmqpHandlerTest extends TestCase
+{
+    public function setUp()
+    {
+        if (!class_exists('AMQPConnection') || !class_exists('AMQPExchange')) {
+            $this->markTestSkipped("amqp-php not installed");
+        }
+
+        if (!class_exists('AMQPChannel')) {
+            $this->markTestSkipped("Please update AMQP to version >= 1.0");
+        }
+    }
+
+    public function testHandle()
+    {
+        $messages = array();
+
+        $exchange = $this->getMock('AMQPExchange', array('publish', 'setName'), array(), '', false);
+        $exchange->expects($this->once())
+            ->method('setName')
+            ->with('log')
+        ;
+        $exchange->expects($this->any())
+            ->method('publish')
+            ->will($this->returnCallback(function ($message, $routing_key, $flags = 0, $attributes = array()) use (&$messages) {
+                $messages[] = array($message, $routing_key, $flags, $attributes);
+            }))
+        ;
+
+        $handler = new AmqpHandler($exchange, 'log');
+
+        $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
+
+        $expected = array(
+            array(
+                'message' => 'test',
+                'context' => array(
+                    'data' => array(),
+                    'foo' => 34,
+                ),
+                'level' => 300,
+                'level_name' => 'WARNING',
+                'channel' => 'test',
+                'extra' => array(),
+            ),
+            'warn.test',
+            0,
+            array(
+                'delivery_mode' => 2,
+                'Content-type' => 'application/json'
+            )
+        );
+
+        $handler->handle($record);
+
+        $this->assertCount(1, $messages);
+        $messages[0][0] = json_decode($messages[0][0], true);
+        unset($messages[0][0]['datetime']);
+        $this->assertEquals($expected, $messages[0]);
+    }
+}

+ 131 - 0
vendor/monolog/monolog/tests/Monolog/Handler/BrowserConsoleHandlerTest.php

@@ -0,0 +1,131 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+
+/**
+ * @covers Monolog\Handler\BrowserConsoleHandlerTest
+ */
+class BrowserConsoleHandlerTest extends TestCase
+{
+    protected function setUp()
+    {
+        BrowserConsoleHandler::reset();
+    }
+
+    protected function generateScript()
+    {
+        $reflMethod = new \ReflectionMethod('Monolog\Handler\BrowserConsoleHandler', 'generateScript');
+        $reflMethod->setAccessible(true);
+
+        return $reflMethod->invoke(null);
+    }
+
+    public function testStyling()
+    {
+        $handler = new BrowserConsoleHandler();
+        $handler->setFormatter($this->getIdentityFormatter());
+
+        $handler->handle($this->getRecord(Logger::DEBUG, 'foo[[bar]]{color: red}'));
+
+        $expected = <<<EOF
+(function (c) {if (c && c.groupCollapsed) {
+c.log("%cfoo%cbar%c", "font-weight: normal", "color: red", "font-weight: normal");
+}})(console);
+EOF;
+
+        $this->assertEquals($expected, $this->generateScript());
+    }
+
+    public function testEscaping()
+    {
+        $handler = new BrowserConsoleHandler();
+        $handler->setFormatter($this->getIdentityFormatter());
+
+        $handler->handle($this->getRecord(Logger::DEBUG, "[foo] [[\"bar\n[baz]\"]]{color: red}"));
+
+        $expected = <<<EOF
+(function (c) {if (c && c.groupCollapsed) {
+c.log("%c[foo] %c\"bar\\n[baz]\"%c", "font-weight: normal", "color: red", "font-weight: normal");
+}})(console);
+EOF;
+
+        $this->assertEquals($expected, $this->generateScript());
+    }
+
+
+    public function testAutolabel()
+    {
+        $handler = new BrowserConsoleHandler();
+        $handler->setFormatter($this->getIdentityFormatter());
+
+        $handler->handle($this->getRecord(Logger::DEBUG, '[[foo]]{macro: autolabel}'));
+        $handler->handle($this->getRecord(Logger::DEBUG, '[[bar]]{macro: autolabel}'));
+        $handler->handle($this->getRecord(Logger::DEBUG, '[[foo]]{macro: autolabel}'));
+
+        $expected = <<<EOF
+(function (c) {if (c && c.groupCollapsed) {
+c.log("%c%cfoo%c", "font-weight: normal", "background-color: blue; color: white; border-radius: 3px; padding: 0 2px 0 2px", "font-weight: normal");
+c.log("%c%cbar%c", "font-weight: normal", "background-color: green; color: white; border-radius: 3px; padding: 0 2px 0 2px", "font-weight: normal");
+c.log("%c%cfoo%c", "font-weight: normal", "background-color: blue; color: white; border-radius: 3px; padding: 0 2px 0 2px", "font-weight: normal");
+}})(console);
+EOF;
+
+        $this->assertEquals($expected, $this->generateScript());
+    }
+
+    public function testContext()
+    {
+        $handler = new BrowserConsoleHandler();
+        $handler->setFormatter($this->getIdentityFormatter());
+
+        $handler->handle($this->getRecord(Logger::DEBUG, 'test', array('foo' => 'bar')));
+
+        $expected = <<<EOF
+(function (c) {if (c && c.groupCollapsed) {
+c.groupCollapsed("%ctest", "font-weight: normal");
+c.log("%c%s", "font-weight: bold", "Context");
+c.log("%s: %o", "foo", "bar");
+c.groupEnd();
+}})(console);
+EOF;
+
+        $this->assertEquals($expected, $this->generateScript());
+    }
+
+    public function testConcurrentHandlers()
+    {
+        $handler1 = new BrowserConsoleHandler();
+        $handler1->setFormatter($this->getIdentityFormatter());
+
+        $handler2 = new BrowserConsoleHandler();
+        $handler2->setFormatter($this->getIdentityFormatter());
+
+        $handler1->handle($this->getRecord(Logger::DEBUG, 'test1'));
+        $handler2->handle($this->getRecord(Logger::DEBUG, 'test2'));
+        $handler1->handle($this->getRecord(Logger::DEBUG, 'test3'));
+        $handler2->handle($this->getRecord(Logger::DEBUG, 'test4'));
+
+        $expected = <<<EOF
+(function (c) {if (c && c.groupCollapsed) {
+c.log("%ctest1", "font-weight: normal");
+c.log("%ctest2", "font-weight: normal");
+c.log("%ctest3", "font-weight: normal");
+c.log("%ctest4", "font-weight: normal");
+}})(console);
+EOF;
+
+        $this->assertEquals($expected, $this->generateScript());
+    }
+}

+ 149 - 0
vendor/monolog/monolog/tests/Monolog/Handler/BufferHandlerTest.php

@@ -0,0 +1,149 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+
+class BufferHandlerTest extends TestCase
+{
+    /**
+     * @covers Monolog\Handler\BufferHandler::__construct
+     * @covers Monolog\Handler\BufferHandler::handle
+     * @covers Monolog\Handler\BufferHandler::close
+     */
+    public function testHandleBuffers()
+    {
+        $test = new TestHandler();
+        $handler = new BufferHandler($test);
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->handle($this->getRecord(Logger::INFO));
+        $this->assertFalse($test->hasDebugRecords());
+        $this->assertFalse($test->hasInfoRecords());
+        $handler->close();
+        $this->assertTrue($test->hasInfoRecords());
+        $this->assertTrue(count($test->getRecords()) === 2);
+    }
+
+    /**
+     * @covers Monolog\Handler\BufferHandler::close
+     * @covers Monolog\Handler\BufferHandler::flush
+     */
+    public function testDestructPropagatesRecords()
+    {
+        $test = new TestHandler();
+        $handler = new BufferHandler($test);
+        $handler->handle($this->getRecord(Logger::WARNING));
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->__destruct();
+        $this->assertTrue($test->hasWarningRecords());
+        $this->assertTrue($test->hasDebugRecords());
+    }
+
+    /**
+     * @covers Monolog\Handler\BufferHandler::handle
+     */
+    public function testHandleBufferLimit()
+    {
+        $test = new TestHandler();
+        $handler = new BufferHandler($test, 2);
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->handle($this->getRecord(Logger::INFO));
+        $handler->handle($this->getRecord(Logger::WARNING));
+        $handler->close();
+        $this->assertTrue($test->hasWarningRecords());
+        $this->assertTrue($test->hasInfoRecords());
+        $this->assertFalse($test->hasDebugRecords());
+    }
+
+    /**
+     * @covers Monolog\Handler\BufferHandler::handle
+     */
+    public function testHandleBufferLimitWithFlushOnOverflow()
+    {
+        $test = new TestHandler();
+        $handler = new BufferHandler($test, 3, Logger::DEBUG, true, true);
+
+        // send two records
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $this->assertFalse($test->hasDebugRecords());
+        $this->assertCount(0, $test->getRecords());
+
+        // overflow
+        $handler->handle($this->getRecord(Logger::INFO));
+        $this->assertTrue($test->hasDebugRecords());
+        $this->assertCount(3, $test->getRecords());
+
+        // should buffer again
+        $handler->handle($this->getRecord(Logger::WARNING));
+        $this->assertCount(3, $test->getRecords());
+
+        $handler->close();
+        $this->assertCount(5, $test->getRecords());
+        $this->assertTrue($test->hasWarningRecords());
+        $this->assertTrue($test->hasInfoRecords());
+    }
+
+    /**
+     * @covers Monolog\Handler\BufferHandler::handle
+     */
+    public function testHandleLevel()
+    {
+        $test = new TestHandler();
+        $handler = new BufferHandler($test, 0, Logger::INFO);
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->handle($this->getRecord(Logger::INFO));
+        $handler->handle($this->getRecord(Logger::WARNING));
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->close();
+        $this->assertTrue($test->hasWarningRecords());
+        $this->assertTrue($test->hasInfoRecords());
+        $this->assertFalse($test->hasDebugRecords());
+    }
+
+    /**
+     * @covers Monolog\Handler\BufferHandler::flush
+     */
+    public function testFlush()
+    {
+        $test = new TestHandler();
+        $handler = new BufferHandler($test, 0);
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->handle($this->getRecord(Logger::INFO));
+        $handler->flush();
+        $this->assertTrue($test->hasInfoRecords());
+        $this->assertTrue($test->hasDebugRecords());
+        $this->assertFalse($test->hasWarningRecords());
+    }
+
+    /**
+     * @covers Monolog\Handler\BufferHandler::handle
+     */
+    public function testHandleUsesProcessors()
+    {
+        $test = new TestHandler();
+        $handler = new BufferHandler($test);
+        $handler->pushProcessor(function ($record) {
+            $record['extra']['foo'] = true;
+
+            return $record;
+        });
+        $handler->handle($this->getRecord(Logger::WARNING));
+        $handler->flush();
+        $this->assertTrue($test->hasWarningRecords());
+        $records = $test->getRecords();
+        $this->assertTrue($records[0]['extra']['foo']);
+    }
+}

+ 141 - 0
vendor/monolog/monolog/tests/Monolog/Handler/ChromePHPHandlerTest.php

@@ -0,0 +1,141 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+
+/**
+ * @covers Monolog\Handler\ChromePHPHandler
+ */
+class ChromePHPHandlerTest extends TestCase
+{
+    protected function setUp()
+    {
+        TestChromePHPHandler::reset();
+        $_SERVER['HTTP_USER_AGENT'] = 'Monolog Test; Chrome/1.0';
+    }
+
+    public function testHeaders()
+    {
+        $handler = new TestChromePHPHandler();
+        $handler->setFormatter($this->getIdentityFormatter());
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->handle($this->getRecord(Logger::WARNING));
+
+        $expected = array(
+            'X-ChromeLogger-Data'   => base64_encode(utf8_encode(json_encode(array(
+                'version' => ChromePHPHandler::VERSION,
+                'columns' => array('label', 'log', 'backtrace', 'type'),
+                'rows' => array(
+                    'test',
+                    'test',
+                ),
+                'request_uri' => '',
+            ))))
+        );
+
+        $this->assertEquals($expected, $handler->getHeaders());
+    }
+
+    public function testHeadersOverflow()
+    {
+        $handler = new TestChromePHPHandler();
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->handle($this->getRecord(Logger::WARNING, str_repeat('a', 150*1024)));
+
+        // overflow chrome headers limit
+        $handler->handle($this->getRecord(Logger::WARNING, str_repeat('a', 100*1024)));
+
+        $expected = array(
+            'X-ChromeLogger-Data'   => base64_encode(utf8_encode(json_encode(array(
+                'version' => ChromePHPHandler::VERSION,
+                'columns' => array('label', 'log', 'backtrace', 'type'),
+                'rows' => array(
+                    array(
+                        'test',
+                        'test',
+                        'unknown',
+                        'log',
+                    ),
+                    array(
+                        'test',
+                        str_repeat('a', 150*1024),
+                        'unknown',
+                        'warn',
+                    ),
+                    array(
+                        'monolog',
+                        'Incomplete logs, chrome header size limit reached',
+                        'unknown',
+                        'warn',
+                    ),
+                ),
+                'request_uri' => '',
+            ))))
+        );
+
+        $this->assertEquals($expected, $handler->getHeaders());
+    }
+
+    public function testConcurrentHandlers()
+    {
+        $handler = new TestChromePHPHandler();
+        $handler->setFormatter($this->getIdentityFormatter());
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->handle($this->getRecord(Logger::WARNING));
+
+        $handler2 = new TestChromePHPHandler();
+        $handler2->setFormatter($this->getIdentityFormatter());
+        $handler2->handle($this->getRecord(Logger::DEBUG));
+        $handler2->handle($this->getRecord(Logger::WARNING));
+
+        $expected = array(
+            'X-ChromeLogger-Data'   => base64_encode(utf8_encode(json_encode(array(
+                'version' => ChromePHPHandler::VERSION,
+                'columns' => array('label', 'log', 'backtrace', 'type'),
+                'rows' => array(
+                    'test',
+                    'test',
+                    'test',
+                    'test',
+                ),
+                'request_uri' => '',
+            ))))
+        );
+
+        $this->assertEquals($expected, $handler2->getHeaders());
+    }
+}
+
+class TestChromePHPHandler extends ChromePHPHandler
+{
+    protected $headers = array();
+
+    public static function reset()
+    {
+        self::$initialized = false;
+        self::$overflowed = false;
+        self::$sendHeaders = true;
+        self::$json['rows'] = array();
+    }
+
+    protected function sendHeader($header, $content)
+    {
+        $this->headers[$header] = $content;
+    }
+
+    public function getHeaders()
+    {
+        return $this->headers;
+    }
+}

+ 41 - 0
vendor/monolog/monolog/tests/Monolog/Handler/CouchDBHandlerTest.php

@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+
+class CouchDBHandlerTest extends TestCase
+{
+    public function testHandle()
+    {
+        $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
+
+        $expected = array(
+            'message' => 'test',
+            'context' => array('data' => '[object] (stdClass: {})', 'foo' => 34),
+            'level' => Logger::WARNING,
+            'level_name' => 'WARNING',
+            'channel' => 'test',
+            'datetime' => $record['datetime']->format('Y-m-d H:i:s'),
+            'extra' => array(),
+        );
+
+        $handler = new CouchDBHandler();
+
+        try {
+            $handler->handle($record);
+        } catch (\RuntimeException $e) {
+            $this->markTestSkipped('Could not connect to couchdb server on http://localhost:5984');
+        }
+    }
+}

+ 52 - 0
vendor/monolog/monolog/tests/Monolog/Handler/DoctrineCouchDBHandlerTest.php

@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+
+class DoctrineCouchDBHandlerTest extends TestCase
+{
+    protected function setup()
+    {
+        if (!class_exists('Doctrine\CouchDB\CouchDBClient')) {
+            $this->markTestSkipped('The "doctrine/couchdb" package is not installed');
+        }
+    }
+
+    public function testHandle()
+    {
+        $client = $this->getMockBuilder('Doctrine\\CouchDB\\CouchDBClient')
+            ->setMethods(array('postDocument'))
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
+
+        $expected = array(
+            'message' => 'test',
+            'context' => array('data' => '[object] (stdClass: {})', 'foo' => 34),
+            'level' => Logger::WARNING,
+            'level_name' => 'WARNING',
+            'channel' => 'test',
+            'datetime' => $record['datetime']->format('Y-m-d H:i:s'),
+            'extra' => array(),
+        );
+
+        $client->expects($this->once())
+            ->method('postDocument')
+            ->with($expected);
+
+        $handler = new DoctrineCouchDBHandler($client);
+        $handler->handle($record);
+    }
+}

+ 73 - 0
vendor/monolog/monolog/tests/Monolog/Handler/DynamoDbHandlerTest.php

@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+
+class DynamoDbHandlerTest extends TestCase
+{
+    public function setUp()
+    {
+        if (!class_exists('Aws\DynamoDb\DynamoDbClient')) {
+            $this->markTestSkipped('aws/aws-sdk-php not installed');
+        }
+
+        $this->client = $this->getMockBuilder('Aws\DynamoDb\DynamoDbClient')
+            ->setMethods(array('formatAttributes', '__call'))
+            ->disableOriginalConstructor()->getMock();
+    }
+
+    public function testConstruct()
+    {
+        $this->assertInstanceOf('Monolog\Handler\DynamoDbHandler', new DynamoDbHandler($this->client, 'foo'));
+    }
+
+    public function testInterface()
+    {
+        $this->assertInstanceOf('Monolog\Handler\HandlerInterface', new DynamoDbHandler($this->client, 'foo'));
+    }
+
+    public function testGetFormatter()
+    {
+        $handler = new DynamoDbHandler($this->client, 'foo');
+        $this->assertInstanceOf('Monolog\Formatter\ScalarFormatter', $handler->getFormatter());
+    }
+
+    public function testHandle()
+    {
+        $record = $this->getRecord();
+        $formatter = $this->getMock('Monolog\Formatter\FormatterInterface');
+        $formatted = array('foo' => 1, 'bar' => 2);
+        $handler = new DynamoDbHandler($this->client, 'foo');
+        $handler->setFormatter($formatter);
+
+        $formatter
+             ->expects($this->once())
+             ->method('format')
+             ->with($record)
+             ->will($this->returnValue($formatted));
+        $this->client
+             ->expects($this->once())
+             ->method('formatAttributes')
+             ->with($this->isType('array'))
+             ->will($this->returnValue($formatted));
+        $this->client
+             ->expects($this->once())
+             ->method('__call')
+             ->with('putItem', array(array(
+                 'TableName' => 'foo',
+                 'Item' => $formatted
+             )));
+
+        $handler->handle($record);
+    }
+}

+ 239 - 0
vendor/monolog/monolog/tests/Monolog/Handler/ElasticSearchHandlerTest.php

@@ -0,0 +1,239 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Formatter\ElasticaFormatter;
+use Monolog\Formatter\NormalizerFormatter;
+use Monolog\TestCase;
+use Monolog\Logger;
+use Elastica\Client;
+use Elastica\Request;
+use Elastica\Response;
+
+class ElasticSearchHandlerTest extends TestCase
+{
+    /**
+     * @var Client mock
+     */
+    protected $client;
+
+    /**
+     * @var array Default handler options
+     */
+    protected $options = array(
+        'index' => 'my_index',
+        'type'  => 'doc_type',
+    );
+
+    public function setUp()
+    {
+        // Elastica lib required
+        if (!class_exists("Elastica\Client")) {
+            $this->markTestSkipped("ruflin/elastica not installed");
+        }
+
+        // base mock Elastica Client object
+        $this->client = $this->getMockBuilder('Elastica\Client')
+            ->setMethods(array('addDocuments'))
+            ->disableOriginalConstructor()
+            ->getMock();
+    }
+
+    /**
+     * @covers Monolog\Handler\ElasticSearchHandler::write
+     * @covers Monolog\Handler\ElasticSearchHandler::handleBatch
+     * @covers Monolog\Handler\ElasticSearchHandler::bulkSend
+     * @covers Monolog\Handler\ElasticSearchHandler::getDefaultFormatter
+     */
+    public function testHandle()
+    {
+        // log message
+        $msg = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array('foo' => 7, 'bar', 'class' => new \stdClass),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array(),
+            'message' => 'log',
+        );
+
+        // format expected result
+        $formatter = new ElasticaFormatter($this->options['index'], $this->options['type']);
+        $expected = array($formatter->format($msg));
+
+        // setup ES client mock
+        $this->client->expects($this->any())
+            ->method('addDocuments')
+            ->with($expected);
+
+        // perform tests
+        $handler = new ElasticSearchHandler($this->client, $this->options);
+        $handler->handle($msg);
+        $handler->handleBatch(array($msg));
+    }
+
+    /**
+     * @covers Monolog\Handler\ElasticSearchHandler::setFormatter
+     */
+    public function testSetFormatter()
+    {
+        $handler = new ElasticSearchHandler($this->client);
+        $formatter = new ElasticaFormatter('index_new', 'type_new');
+        $handler->setFormatter($formatter);
+        $this->assertInstanceOf('Monolog\Formatter\ElasticaFormatter', $handler->getFormatter());
+        $this->assertEquals('index_new', $handler->getFormatter()->getIndex());
+        $this->assertEquals('type_new', $handler->getFormatter()->getType());
+    }
+
+    /**
+     * @covers                   Monolog\Handler\ElasticSearchHandler::setFormatter
+     * @expectedException        InvalidArgumentException
+     * @expectedExceptionMessage ElasticSearchHandler is only compatible with ElasticaFormatter
+     */
+    public function testSetFormatterInvalid()
+    {
+        $handler = new ElasticSearchHandler($this->client);
+        $formatter = new NormalizerFormatter();
+        $handler->setFormatter($formatter);
+    }
+
+    /**
+     * @covers Monolog\Handler\ElasticSearchHandler::__construct
+     * @covers Monolog\Handler\ElasticSearchHandler::getOptions
+     */
+    public function testOptions()
+    {
+        $expected = array(
+            'index' => $this->options['index'],
+            'type' => $this->options['type'],
+            'ignore_error' => false,
+        );
+        $handler = new ElasticSearchHandler($this->client, $this->options);
+        $this->assertEquals($expected, $handler->getOptions());
+    }
+
+    /**
+     * @covers       Monolog\Handler\ElasticSearchHandler::bulkSend
+     * @dataProvider providerTestConnectionErrors
+     */
+    public function testConnectionErrors($ignore, $expectedError)
+    {
+        $clientOpts = array('host' => '127.0.0.1', 'port' => 1);
+        $client = new Client($clientOpts);
+        $handlerOpts = array('ignore_error' => $ignore);
+        $handler = new ElasticSearchHandler($client, $handlerOpts);
+
+        if ($expectedError) {
+            $this->setExpectedException($expectedError[0], $expectedError[1]);
+            $handler->handle($this->getRecord());
+        } else {
+            $this->assertFalse($handler->handle($this->getRecord()));
+        }
+    }
+
+    /**
+     * @return array
+     */
+    public function providerTestConnectionErrors()
+    {
+        return array(
+            array(false, array('RuntimeException', 'Error sending messages to Elasticsearch')),
+            array(true, false),
+        );
+    }
+
+    /**
+     * Integration test using localhost Elastic Search server
+     *
+     * @covers Monolog\Handler\ElasticSearchHandler::__construct
+     * @covers Monolog\Handler\ElasticSearchHandler::handleBatch
+     * @covers Monolog\Handler\ElasticSearchHandler::bulkSend
+     * @covers Monolog\Handler\ElasticSearchHandler::getDefaultFormatter
+     */
+    public function testHandleIntegration()
+    {
+        $msg = array(
+            'level' => Logger::ERROR,
+            'level_name' => 'ERROR',
+            'channel' => 'meh',
+            'context' => array('foo' => 7, 'bar', 'class' => new \stdClass),
+            'datetime' => new \DateTime("@0"),
+            'extra' => array(),
+            'message' => 'log',
+        );
+
+        $expected = $msg;
+        $expected['datetime'] = $msg['datetime']->format(\DateTime::ISO8601);
+        $expected['context'] = array(
+            'class' => '[object] (stdClass: {})',
+            'foo' => 7,
+            0 => 'bar',
+        );
+
+        $client = new Client();
+        $handler = new ElasticSearchHandler($client, $this->options);
+        try {
+            $handler->handleBatch(array($msg));
+        } catch (\RuntimeException $e) {
+            $this->markTestSkipped("Cannot connect to Elastic Search server on localhost");
+        }
+
+        // check document id from ES server response
+        $documentId = $this->getCreatedDocId($client->getLastResponse());
+        $this->assertNotEmpty($documentId, 'No elastic document id received');
+
+        // retrieve document source from ES and validate
+        $document = $this->getDocSourceFromElastic(
+            $client,
+            $this->options['index'],
+            $this->options['type'],
+            $documentId
+        );
+        $this->assertEquals($expected, $document);
+
+        // remove test index from ES
+        $client->request("/{$this->options['index']}", Request::DELETE);
+    }
+
+    /**
+     * Return last created document id from ES response
+     * @param  Response    $response Elastica Response object
+     * @return string|null
+     */
+    protected function getCreatedDocId(Response $response)
+    {
+        $data = $response->getData();
+        if (!empty($data['items'][0]['create']['_id'])) {
+            return $data['items'][0]['create']['_id'];
+        }
+    }
+
+    /**
+     * Retrieve document by id from Elasticsearch
+     * @param  Client $client     Elastica client
+     * @param  string $index
+     * @param  string $type
+     * @param  string $documentId
+     * @return array
+     */
+    protected function getDocSourceFromElastic(Client $client, $index, $type, $documentId)
+    {
+        $resp = $client->request("/{$index}/{$type}/{$documentId}", Request::GET);
+        $data = $resp->getData();
+        if (!empty($data['_source'])) {
+            return $data['_source'];
+        }
+
+        return array();
+    }
+}

+ 43 - 0
vendor/monolog/monolog/tests/Monolog/Handler/ErrorLogHandlerTest.php

@@ -0,0 +1,43 @@
+<?php
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+
+function error_log()
+{
+    $GLOBALS['error_log'] = func_get_args();
+}
+
+class ErrorLogHandlerTest extends TestCase
+{
+
+    protected function setUp()
+    {
+        $GLOBALS['error_log'] = array();
+    }
+
+    /**
+     * @covers Monolog\Handler\ErrorLogHandler::__construct
+     * @expectedException InvalidArgumentException
+     * @expectedExceptionMessage The given message type "42" is not supported
+     */
+    public function testShouldNotAcceptAnInvalidTypeOnContructor()
+    {
+        new ErrorLogHandler(42);
+    }
+
+    /**
+     * @covers Monolog\Handler\ErrorLogHandler::write
+     */
+    public function testShouldLogMessagesUsingErrorLogFuncion()
+    {
+        $type = ErrorLogHandler::OPERATING_SYSTEM;
+        $handler = new ErrorLogHandler($type);
+        $handler->handle($this->getRecord(Logger::ERROR));
+
+        $this->assertStringMatchesFormat('[%s] test.ERROR: test [] []', $GLOBALS['error_log'][0]);
+        $this->assertSame($GLOBALS['error_log'][1], $type);
+    }
+}

+ 151 - 0
vendor/monolog/monolog/tests/Monolog/Handler/FilterHandlerTest.php

@@ -0,0 +1,151 @@
+<?php
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\TestCase;
+
+class FilterHandlerTest extends TestCase
+{
+    /**
+     * @covers Monolog\Handler\FilterHandler::isHandling
+     */
+    public function testIsHandling()
+    {
+        $test    = new TestHandler();
+        $handler = new FilterHandler($test, Logger::INFO, Logger::NOTICE);
+        $this->assertFalse($handler->isHandling($this->getRecord(Logger::DEBUG)));
+        $this->assertTrue($handler->isHandling($this->getRecord(Logger::INFO)));
+        $this->assertTrue($handler->isHandling($this->getRecord(Logger::NOTICE)));
+        $this->assertFalse($handler->isHandling($this->getRecord(Logger::WARNING)));
+        $this->assertFalse($handler->isHandling($this->getRecord(Logger::ERROR)));
+        $this->assertFalse($handler->isHandling($this->getRecord(Logger::CRITICAL)));
+        $this->assertFalse($handler->isHandling($this->getRecord(Logger::ALERT)));
+        $this->assertFalse($handler->isHandling($this->getRecord(Logger::EMERGENCY)));
+    }
+
+    /**
+     * @covers Monolog\Handler\FilterHandler::handle
+     * @covers Monolog\Handler\FilterHandler::setAcceptedLevels
+     * @covers Monolog\Handler\FilterHandler::isHandling
+     */
+    public function testHandleProcessOnlyNeededLevels()
+    {
+        $test    = new TestHandler();
+        $handler = new FilterHandler($test, Logger::INFO, Logger::NOTICE);
+
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $this->assertFalse($test->hasDebugRecords());
+
+        $handler->handle($this->getRecord(Logger::INFO));
+        $this->assertTrue($test->hasInfoRecords());
+        $handler->handle($this->getRecord(Logger::NOTICE));
+        $this->assertTrue($test->hasNoticeRecords());
+
+        $handler->handle($this->getRecord(Logger::WARNING));
+        $this->assertFalse($test->hasWarningRecords());
+        $handler->handle($this->getRecord(Logger::ERROR));
+        $this->assertFalse($test->hasErrorRecords());
+        $handler->handle($this->getRecord(Logger::CRITICAL));
+        $this->assertFalse($test->hasCriticalRecords());
+        $handler->handle($this->getRecord(Logger::ALERT));
+        $this->assertFalse($test->hasAlertRecords());
+        $handler->handle($this->getRecord(Logger::EMERGENCY));
+        $this->assertFalse($test->hasEmergencyRecords());
+
+        $test    = new TestHandler();
+        $handler = new FilterHandler($test, array(Logger::INFO, Logger::ERROR));
+
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $this->assertFalse($test->hasDebugRecords());
+        $handler->handle($this->getRecord(Logger::INFO));
+        $this->assertTrue($test->hasInfoRecords());
+        $handler->handle($this->getRecord(Logger::NOTICE));
+        $this->assertFalse($test->hasNoticeRecords());
+        $handler->handle($this->getRecord(Logger::ERROR));
+        $this->assertTrue($test->hasErrorRecords());
+        $handler->handle($this->getRecord(Logger::CRITICAL));
+        $this->assertFalse($test->hasCriticalRecords());
+    }
+
+    /**
+     * @covers Monolog\Handler\FilterHandler::setAcceptedLevels
+     * @covers Monolog\Handler\FilterHandler::getAcceptedLevels
+     */
+    public function testAcceptedLevelApi()
+    {
+        $test    = new TestHandler();
+        $handler = new FilterHandler($test);
+
+        $levels = array(Logger::INFO, Logger::ERROR);
+        $handler->setAcceptedLevels($levels);
+        $this->assertSame($levels, $handler->getAcceptedLevels());
+    }
+
+    /**
+     * @covers Monolog\Handler\FilterHandler::handle
+     */
+    public function testHandleUsesProcessors()
+    {
+        $test    = new TestHandler();
+        $handler = new FilterHandler($test, Logger::DEBUG, Logger::EMERGENCY);
+        $handler->pushProcessor(
+            function ($record) {
+                $record['extra']['foo'] = true;
+
+                return $record;
+            }
+        );
+        $handler->handle($this->getRecord(Logger::WARNING));
+        $this->assertTrue($test->hasWarningRecords());
+        $records = $test->getRecords();
+        $this->assertTrue($records[0]['extra']['foo']);
+    }
+
+    /**
+     * @covers Monolog\Handler\FilterHandler::handle
+     */
+    public function testHandleRespectsBubble()
+    {
+        $test = new TestHandler();
+
+        $handler = new FilterHandler($test, Logger::INFO, Logger::NOTICE, false);
+        $this->assertTrue($handler->handle($this->getRecord(Logger::INFO)));
+        $this->assertFalse($handler->handle($this->getRecord(Logger::WARNING)));
+
+        $handler = new FilterHandler($test, Logger::INFO, Logger::NOTICE, true);
+        $this->assertFalse($handler->handle($this->getRecord(Logger::INFO)));
+        $this->assertFalse($handler->handle($this->getRecord(Logger::WARNING)));
+    }
+
+    /**
+     * @covers Monolog\Handler\FilterHandler::handle
+     */
+    public function testHandleWithCallback()
+    {
+        $test    = new TestHandler();
+        $handler = new FilterHandler(
+            function ($record, $handler) use ($test) {
+                return $test;
+            }, Logger::INFO, Logger::NOTICE, false
+        );
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->handle($this->getRecord(Logger::INFO));
+        $this->assertFalse($test->hasDebugRecords());
+        $this->assertTrue($test->hasInfoRecords());
+    }
+
+    /**
+     * @covers Monolog\Handler\FilterHandler::handle
+     * @expectedException \RuntimeException
+     */
+    public function testHandleWithBadCallbackThrowsException()
+    {
+        $handler = new FilterHandler(
+            function ($record, $handler) {
+                return 'foo';
+            }
+        );
+        $handler->handle($this->getRecord(Logger::WARNING));
+    }
+}

+ 189 - 0
vendor/monolog/monolog/tests/Monolog/Handler/FingersCrossedHandlerTest.php

@@ -0,0 +1,189 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy;
+use Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy;
+
+class FingersCrossedHandlerTest extends TestCase
+{
+    /**
+     * @covers Monolog\Handler\FingersCrossedHandler::__construct
+     * @covers Monolog\Handler\FingersCrossedHandler::handle
+     */
+    public function testHandleBuffers()
+    {
+        $test = new TestHandler();
+        $handler = new FingersCrossedHandler($test);
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->handle($this->getRecord(Logger::INFO));
+        $this->assertFalse($test->hasDebugRecords());
+        $this->assertFalse($test->hasInfoRecords());
+        $handler->handle($this->getRecord(Logger::WARNING));
+        $this->assertTrue($test->hasInfoRecords());
+        $this->assertTrue(count($test->getRecords()) === 3);
+    }
+
+    /**
+     * @covers Monolog\Handler\FingersCrossedHandler::handle
+     */
+    public function testHandleStopsBufferingAfterTrigger()
+    {
+        $test = new TestHandler();
+        $handler = new FingersCrossedHandler($test);
+        $handler->handle($this->getRecord(Logger::WARNING));
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $this->assertTrue($test->hasWarningRecords());
+        $this->assertTrue($test->hasDebugRecords());
+    }
+
+    /**
+     * @covers Monolog\Handler\FingersCrossedHandler::handle
+     * @covers Monolog\Handler\FingersCrossedHandler::reset
+     */
+    public function testHandleRestartBufferingAfterReset()
+    {
+        $test = new TestHandler();
+        $handler = new FingersCrossedHandler($test);
+        $handler->handle($this->getRecord(Logger::WARNING));
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->reset();
+        $handler->handle($this->getRecord(Logger::INFO));
+        $this->assertTrue($test->hasWarningRecords());
+        $this->assertTrue($test->hasDebugRecords());
+        $this->assertFalse($test->hasInfoRecords());
+    }
+
+    /**
+     * @covers Monolog\Handler\FingersCrossedHandler::handle
+     */
+    public function testHandleRestartBufferingAfterBeingTriggeredWhenStopBufferingIsDisabled()
+    {
+        $test = new TestHandler();
+        $handler = new FingersCrossedHandler($test, Logger::WARNING, 0, false, false);
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->handle($this->getRecord(Logger::WARNING));
+        $handler->handle($this->getRecord(Logger::INFO));
+        $this->assertTrue($test->hasWarningRecords());
+        $this->assertTrue($test->hasDebugRecords());
+        $this->assertFalse($test->hasInfoRecords());
+    }
+
+    /**
+     * @covers Monolog\Handler\FingersCrossedHandler::handle
+     */
+    public function testHandleBufferLimit()
+    {
+        $test = new TestHandler();
+        $handler = new FingersCrossedHandler($test, Logger::WARNING, 2);
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->handle($this->getRecord(Logger::INFO));
+        $handler->handle($this->getRecord(Logger::WARNING));
+        $this->assertTrue($test->hasWarningRecords());
+        $this->assertTrue($test->hasInfoRecords());
+        $this->assertFalse($test->hasDebugRecords());
+    }
+
+    /**
+     * @covers Monolog\Handler\FingersCrossedHandler::handle
+     */
+    public function testHandleWithCallback()
+    {
+        $test = new TestHandler();
+        $handler = new FingersCrossedHandler(function ($record, $handler) use ($test) {
+                    return $test;
+                });
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->handle($this->getRecord(Logger::INFO));
+        $this->assertFalse($test->hasDebugRecords());
+        $this->assertFalse($test->hasInfoRecords());
+        $handler->handle($this->getRecord(Logger::WARNING));
+        $this->assertTrue($test->hasInfoRecords());
+        $this->assertTrue(count($test->getRecords()) === 3);
+    }
+
+    /**
+     * @covers Monolog\Handler\FingersCrossedHandler::handle
+     * @expectedException RuntimeException
+     */
+    public function testHandleWithBadCallbackThrowsException()
+    {
+        $handler = new FingersCrossedHandler(function ($record, $handler) {
+                    return 'foo';
+                });
+        $handler->handle($this->getRecord(Logger::WARNING));
+    }
+
+    /**
+     * @covers Monolog\Handler\FingersCrossedHandler::isHandling
+     */
+    public function testIsHandlingAlways()
+    {
+        $test = new TestHandler();
+        $handler = new FingersCrossedHandler($test, Logger::ERROR);
+        $this->assertTrue($handler->isHandling($this->getRecord(Logger::DEBUG)));
+    }
+
+    /**
+     * @covers Monolog\Handler\FingersCrossedHandler::__construct
+     * @covers Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy::__construct
+     * @covers Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy::isHandlerActivated
+     */
+    public function testErrorLevelActivationStrategy()
+    {
+        $test = new TestHandler();
+        $handler = new FingersCrossedHandler($test, new ErrorLevelActivationStrategy(Logger::WARNING));
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $this->assertFalse($test->hasDebugRecords());
+        $handler->handle($this->getRecord(Logger::WARNING));
+        $this->assertTrue($test->hasDebugRecords());
+        $this->assertTrue($test->hasWarningRecords());
+    }
+
+    /**
+     * @covers Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy::__construct
+     * @covers Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy::isHandlerActivated
+     */
+    public function testChannelLevelActivationStrategy()
+    {
+        $test = new TestHandler();
+        $handler = new FingersCrossedHandler($test, new ChannelLevelActivationStrategy(Logger::ERROR, array('othertest' => Logger::DEBUG)));
+        $handler->handle($this->getRecord(Logger::WARNING));
+        $this->assertFalse($test->hasWarningRecords());
+        $record = $this->getRecord(Logger::DEBUG);
+        $record['channel'] = 'othertest';
+        $handler->handle($record);
+        $this->assertTrue($test->hasDebugRecords());
+        $this->assertTrue($test->hasWarningRecords());
+    }
+
+    /**
+     * @covers Monolog\Handler\FingersCrossedHandler::handle
+     */
+    public function testHandleUsesProcessors()
+    {
+        $test = new TestHandler();
+        $handler = new FingersCrossedHandler($test, Logger::INFO);
+        $handler->pushProcessor(function ($record) {
+            $record['extra']['foo'] = true;
+
+            return $record;
+        });
+        $handler->handle($this->getRecord(Logger::WARNING));
+        $this->assertTrue($test->hasWarningRecords());
+        $records = $test->getRecords();
+        $this->assertTrue($records[0]['extra']['foo']);
+    }
+}

+ 96 - 0
vendor/monolog/monolog/tests/Monolog/Handler/FirePHPHandlerTest.php

@@ -0,0 +1,96 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+
+/**
+ * @covers Monolog\Handler\FirePHPHandler
+ */
+class FirePHPHandlerTest extends TestCase
+{
+    public function setUp()
+    {
+        TestFirePHPHandler::reset();
+        $_SERVER['HTTP_USER_AGENT'] = 'Monolog Test; FirePHP/1.0';
+    }
+
+    public function testHeaders()
+    {
+        $handler = new TestFirePHPHandler;
+        $handler->setFormatter($this->getIdentityFormatter());
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->handle($this->getRecord(Logger::WARNING));
+
+        $expected = array(
+            'X-Wf-Protocol-1'    => 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2',
+            'X-Wf-1-Structure-1' => 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1',
+            'X-Wf-1-Plugin-1'    => 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3',
+            'X-Wf-1-1-1-1'       => 'test',
+            'X-Wf-1-1-1-2'       => 'test',
+        );
+
+        $this->assertEquals($expected, $handler->getHeaders());
+    }
+
+    public function testConcurrentHandlers()
+    {
+        $handler = new TestFirePHPHandler;
+        $handler->setFormatter($this->getIdentityFormatter());
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->handle($this->getRecord(Logger::WARNING));
+
+        $handler2 = new TestFirePHPHandler;
+        $handler2->setFormatter($this->getIdentityFormatter());
+        $handler2->handle($this->getRecord(Logger::DEBUG));
+        $handler2->handle($this->getRecord(Logger::WARNING));
+
+        $expected = array(
+            'X-Wf-Protocol-1'    => 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2',
+            'X-Wf-1-Structure-1' => 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1',
+            'X-Wf-1-Plugin-1'    => 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3',
+            'X-Wf-1-1-1-1'       => 'test',
+            'X-Wf-1-1-1-2'       => 'test',
+        );
+
+        $expected2 = array(
+            'X-Wf-1-1-1-3'       => 'test',
+            'X-Wf-1-1-1-4'       => 'test',
+        );
+
+        $this->assertEquals($expected, $handler->getHeaders());
+        $this->assertEquals($expected2, $handler2->getHeaders());
+    }
+}
+
+class TestFirePHPHandler extends FirePHPHandler
+{
+    protected $headers = array();
+
+    public static function reset()
+    {
+        self::$initialized = false;
+        self::$sendHeaders = true;
+        self::$messageIndex = 1;
+    }
+
+    protected function sendHeader($header, $content)
+    {
+        $this->headers[$header] = $content;
+    }
+
+    public function getHeaders()
+    {
+        return $this->headers;
+    }
+}

+ 0 - 0
vendor/monolog/monolog/tests/Monolog/Handler/Fixtures/.gitkeep


+ 88 - 0
vendor/monolog/monolog/tests/Monolog/Handler/FlowdockHandlerTest.php

@@ -0,0 +1,88 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Formatter\FlowdockFormatter;
+use Monolog\TestCase;
+use Monolog\Logger;
+
+/**
+ * @author Dominik Liebler <liebler.dominik@gmail.com>
+ * @see    https://www.hipchat.com/docs/api
+ */
+class FlowdockHandlerTest extends TestCase
+{
+    /**
+     * @var resource
+     */
+    private $res;
+
+    /**
+     * @var FlowdockHandler
+     */
+    private $handler;
+
+    public function setUp()
+    {
+        if (!extension_loaded('openssl')) {
+            $this->markTestSkipped('This test requires openssl to run');
+        }
+    }
+
+    public function testWriteHeader()
+    {
+        $this->createHandler();
+        $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
+        fseek($this->res, 0);
+        $content = fread($this->res, 1024);
+
+        $this->assertRegexp('/POST \/v1\/messages\/team_inbox\/.* HTTP\/1.1\\r\\nHost: api.flowdock.com\\r\\nContent-Type: application\/json\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content);
+
+        return $content;
+    }
+
+    /**
+     * @depends testWriteHeader
+     */
+    public function testWriteContent($content)
+    {
+        $this->assertRegexp('/"source":"test_source"/', $content);
+        $this->assertRegexp('/"from_address":"source@test\.com"/', $content);
+    }
+
+    private function createHandler($token = 'myToken')
+    {
+        $constructorArgs = array($token, Logger::DEBUG);
+        $this->res = fopen('php://memory', 'a');
+        $this->handler = $this->getMock(
+            '\Monolog\Handler\FlowdockHandler',
+            array('fsockopen', 'streamSetTimeout', 'closeSocket'),
+            $constructorArgs
+        );
+
+        $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString');
+        $reflectionProperty->setAccessible(true);
+        $reflectionProperty->setValue($this->handler, 'localhost:1234');
+
+        $this->handler->expects($this->any())
+            ->method('fsockopen')
+            ->will($this->returnValue($this->res));
+        $this->handler->expects($this->any())
+            ->method('streamSetTimeout')
+            ->will($this->returnValue(true));
+        $this->handler->expects($this->any())
+            ->method('closeSocket')
+            ->will($this->returnValue(true));
+
+        $this->handler->setFormatter(new FlowdockFormatter('test_source', 'source@test.com'));
+    }
+}

+ 93 - 0
vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerLegacyTest.php

@@ -0,0 +1,93 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Gelf\Message;
+use Monolog\TestCase;
+use Monolog\Logger;
+use Monolog\Formatter\GelfMessageFormatter;
+
+class GelfHandlerLegacyTest extends TestCase
+{
+    public function setUp()
+    {
+        if (!class_exists('Gelf\MessagePublisher') || !class_exists('Gelf\Message')) {
+            $this->markTestSkipped("mlehner/gelf-php not installed");
+        }
+    }
+
+    /**
+     * @covers Monolog\Handler\GelfHandler::__construct
+     */
+    public function testConstruct()
+    {
+        $handler = new GelfHandler($this->getMessagePublisher());
+        $this->assertInstanceOf('Monolog\Handler\GelfHandler', $handler);
+    }
+
+    protected function getHandler($messagePublisher)
+    {
+        $handler = new GelfHandler($messagePublisher);
+
+        return $handler;
+    }
+
+    protected function getMessagePublisher()
+    {
+        return new MockMessagePublisher('localhost');
+    }
+
+    public function testDebug()
+    {
+        $messagePublisher = $this->getMessagePublisher();
+        $handler = $this->getHandler($messagePublisher);
+
+        $record = $this->getRecord(Logger::DEBUG, "A test debug message");
+        $handler->handle($record);
+
+        $this->assertEquals(7, $messagePublisher->lastMessage->getLevel());
+        $this->assertEquals('test', $messagePublisher->lastMessage->getFacility());
+        $this->assertEquals($record['message'], $messagePublisher->lastMessage->getShortMessage());
+        $this->assertEquals(null, $messagePublisher->lastMessage->getFullMessage());
+    }
+
+    public function testWarning()
+    {
+        $messagePublisher = $this->getMessagePublisher();
+        $handler = $this->getHandler($messagePublisher);
+
+        $record = $this->getRecord(Logger::WARNING, "A test warning message");
+        $handler->handle($record);
+
+        $this->assertEquals(4, $messagePublisher->lastMessage->getLevel());
+        $this->assertEquals('test', $messagePublisher->lastMessage->getFacility());
+        $this->assertEquals($record['message'], $messagePublisher->lastMessage->getShortMessage());
+        $this->assertEquals(null, $messagePublisher->lastMessage->getFullMessage());
+    }
+
+    public function testInjectedGelfMessageFormatter()
+    {
+        $messagePublisher = $this->getMessagePublisher();
+        $handler = $this->getHandler($messagePublisher);
+
+        $handler->setFormatter(new GelfMessageFormatter('mysystem', 'EXT', 'CTX'));
+
+        $record = $this->getRecord(Logger::WARNING, "A test warning message");
+        $record['extra']['blarg'] = 'yep';
+        $record['context']['from'] = 'logger';
+        $handler->handle($record);
+
+        $this->assertEquals('mysystem', $messagePublisher->lastMessage->getHost());
+        $this->assertArrayHasKey('_EXTblarg', $messagePublisher->lastMessage->toArray());
+        $this->assertArrayHasKey('_CTXfrom', $messagePublisher->lastMessage->toArray());
+    }
+}

+ 119 - 0
vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerTest.php

@@ -0,0 +1,119 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Gelf\Message;
+use Monolog\TestCase;
+use Monolog\Logger;
+use Monolog\Formatter\GelfMessageFormatter;
+
+class GelfHandlerTest extends TestCase
+{
+    public function setUp()
+    {
+        if (!class_exists('Gelf\Publisher') || !class_exists('Gelf\Message')) {
+            $this->markTestSkipped("graylog2/gelf-php not installed");
+        }
+    }
+
+    /**
+     * @covers Monolog\Handler\GelfHandler::__construct
+     */
+    public function testConstruct()
+    {
+        $handler = new GelfHandler($this->getMessagePublisher());
+        $this->assertInstanceOf('Monolog\Handler\GelfHandler', $handler);
+    }
+
+    protected function getHandler($messagePublisher)
+    {
+        $handler = new GelfHandler($messagePublisher);
+
+        return $handler;
+    }
+
+    protected function getMessagePublisher()
+    {
+        return $this->getMock('Gelf\Publisher', array('publish'), array(), '', false);
+    }
+
+    public function testDebug()
+    {
+        $record = $this->getRecord(Logger::DEBUG, "A test debug message");
+        $expectedMessage = new Message();
+        $expectedMessage
+            ->setLevel(7)
+            ->setFacility("test")
+            ->setShortMessage($record['message'])
+            ->setTimestamp($record['datetime'])
+        ;
+
+        $messagePublisher = $this->getMessagePublisher();
+        $messagePublisher->expects($this->once())
+            ->method('publish')
+            ->with($expectedMessage);
+
+        $handler = $this->getHandler($messagePublisher);
+
+        $handler->handle($record);
+
+    }
+
+    public function testWarning()
+    {
+        $record = $this->getRecord(Logger::WARNING, "A test warning message");
+        $expectedMessage = new Message();
+        $expectedMessage
+            ->setLevel(4)
+            ->setFacility("test")
+            ->setShortMessage($record['message'])
+            ->setTimestamp($record['datetime'])
+        ;
+
+        $messagePublisher = $this->getMessagePublisher();
+        $messagePublisher->expects($this->once())
+            ->method('publish')
+            ->with($expectedMessage);
+
+        $handler = $this->getHandler($messagePublisher);
+
+        $handler->handle($record);
+    }
+
+    public function testInjectedGelfMessageFormatter()
+    {
+        $record = $this->getRecord(Logger::WARNING, "A test warning message");
+        $record['extra']['blarg'] = 'yep';
+        $record['context']['from'] = 'logger';
+
+        $expectedMessage = new Message();
+        $expectedMessage
+            ->setLevel(4)
+            ->setFacility("test")
+            ->setHost("mysystem")
+            ->setShortMessage($record['message'])
+            ->setTimestamp($record['datetime'])
+            ->setAdditional("EXTblarg", 'yep')
+            ->setAdditional("CTXfrom", 'logger')
+        ;
+
+        $messagePublisher = $this->getMessagePublisher();
+        $messagePublisher->expects($this->once())
+            ->method('publish')
+            ->with($expectedMessage);
+
+        $handler = $this->getHandler($messagePublisher);
+        $handler->setFormatter(new GelfMessageFormatter('mysystem', 'EXT', 'CTX'));
+        $handler->handle($record);
+
+    }
+}

+ 89 - 0
vendor/monolog/monolog/tests/Monolog/Handler/GroupHandlerTest.php

@@ -0,0 +1,89 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+
+class GroupHandlerTest extends TestCase
+{
+    /**
+     * @covers Monolog\Handler\GroupHandler::__construct
+     * @expectedException InvalidArgumentException
+     */
+    public function testConstructorOnlyTakesHandler()
+    {
+        new GroupHandler(array(new TestHandler(), "foo"));
+    }
+
+    /**
+     * @covers Monolog\Handler\GroupHandler::__construct
+     * @covers Monolog\Handler\GroupHandler::handle
+     */
+    public function testHandle()
+    {
+        $testHandlers = array(new TestHandler(), new TestHandler());
+        $handler = new GroupHandler($testHandlers);
+        $handler->handle($this->getRecord(Logger::DEBUG));
+        $handler->handle($this->getRecord(Logger::INFO));
+        foreach ($testHandlers as $test) {
+            $this->assertTrue($test->hasDebugRecords());
+            $this->assertTrue($test->hasInfoRecords());
+            $this->assertTrue(count($test->getRecords()) === 2);
+        }
+    }
+
+    /**
+     * @covers Monolog\Handler\GroupHandler::handleBatch
+     */
+    public function testHandleBatch()
+    {
+        $testHandlers = array(new TestHandler(), new TestHandler());
+        $handler = new GroupHandler($testHandlers);
+        $handler->handleBatch(array($this->getRecord(Logger::DEBUG), $this->getRecord(Logger::INFO)));
+        foreach ($testHandlers as $test) {
+            $this->assertTrue($test->hasDebugRecords());
+            $this->assertTrue($test->hasInfoRecords());
+            $this->assertTrue(count($test->getRecords()) === 2);
+        }
+    }
+
+    /**
+     * @covers Monolog\Handler\GroupHandler::isHandling
+     */
+    public function testIsHandling()
+    {
+        $testHandlers = array(new TestHandler(Logger::ERROR), new TestHandler(Logger::WARNING));
+        $handler = new GroupHandler($testHandlers);
+        $this->assertTrue($handler->isHandling($this->getRecord(Logger::ERROR)));
+        $this->assertTrue($handler->isHandling($this->getRecord(Logger::WARNING)));
+        $this->assertFalse($handler->isHandling($this->getRecord(Logger::DEBUG)));
+    }
+
+    /**
+     * @covers Monolog\Handler\GroupHandler::handle
+     */
+    public function testHandleUsesProcessors()
+    {
+        $test = new TestHandler();
+        $handler = new GroupHandler(array($test));
+        $handler->pushProcessor(function ($record) {
+            $record['extra']['foo'] = true;
+
+            return $record;
+        });
+        $handler->handle($this->getRecord(Logger::WARNING));
+        $this->assertTrue($test->hasWarningRecords());
+        $records = $test->getRecords();
+        $this->assertTrue($records[0]['extra']['foo']);
+    }
+}

+ 167 - 0
vendor/monolog/monolog/tests/Monolog/Handler/HipChatHandlerTest.php

@@ -0,0 +1,167 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+
+/**
+ * @author Rafael Dohms <rafael@doh.ms>
+ * @see    https://www.hipchat.com/docs/api
+ */
+class HipChatHandlerTest extends TestCase
+{
+
+    private $res;
+    private $handler;
+
+    public function testWriteHeader()
+    {
+        $this->createHandler();
+        $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
+        fseek($this->res, 0);
+        $content = fread($this->res, 1024);
+
+        $this->assertRegexp('/POST \/v1\/rooms\/message\?format=json&auth_token=.* HTTP\/1.1\\r\\nHost: api.hipchat.com\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content);
+
+        return $content;
+    }
+
+    /**
+     * @depends testWriteHeader
+     */
+    public function testWriteContent($content)
+    {
+        $this->assertRegexp('/from=Monolog&room_id=room1&notify=0&message=test1&message_format=text&color=red$/', $content);
+    }
+
+    public function testWriteWithComplexMessage()
+    {
+        $this->createHandler();
+        $this->handler->handle($this->getRecord(Logger::CRITICAL, 'Backup of database "example" finished in 16 minutes.'));
+        fseek($this->res, 0);
+        $content = fread($this->res, 1024);
+
+        $this->assertRegexp('/message=Backup\+of\+database\+%22example%22\+finished\+in\+16\+minutes\./', $content);
+    }
+
+    /**
+     * @dataProvider provideLevelColors
+     */
+    public function testWriteWithErrorLevelsAndColors($level, $expectedColor)
+    {
+        $this->createHandler();
+        $this->handler->handle($this->getRecord($level, 'Backup of database "example" finished in 16 minutes.'));
+        fseek($this->res, 0);
+        $content = fread($this->res, 1024);
+
+        $this->assertRegexp('/color='.$expectedColor.'/', $content);
+    }
+
+    public function provideLevelColors()
+    {
+        return array(
+            array(Logger::DEBUG,    'gray'),
+            array(Logger::INFO,     'green'),
+            array(Logger::WARNING,  'yellow'),
+            array(Logger::ERROR,    'red'),
+            array(Logger::CRITICAL, 'red'),
+            array(Logger::ALERT,    'red'),
+            array(Logger::EMERGENCY,'red'),
+            array(Logger::NOTICE,   'green'),
+        );
+    }
+
+    /**
+     * @dataProvider provideBatchRecords
+     */
+    public function testHandleBatch($records, $expectedColor)
+    {
+        $this->createHandler();
+
+        $this->handler->handleBatch($records);
+
+        fseek($this->res, 0);
+        $content = fread($this->res, 1024);
+
+        $this->assertRegexp('/color='.$expectedColor.'/', $content);
+    }
+
+    public function provideBatchRecords()
+    {
+        return array(
+            array(
+                array(
+                    array('level' => Logger::WARNING, 'message' => 'Oh bugger!', 'level_name' => 'warning', 'datetime' => new \DateTime()),
+                    array('level' => Logger::NOTICE, 'message' => 'Something noticeable happened.', 'level_name' => 'notice', 'datetime' => new \DateTime()),
+                    array('level' => Logger::CRITICAL, 'message' => 'Everything is broken!', 'level_name' => 'critical', 'datetime' => new \DateTime())
+                ),
+                'red',
+            ),
+            array(
+                array(
+                    array('level' => Logger::WARNING, 'message' => 'Oh bugger!', 'level_name' => 'warning', 'datetime' => new \DateTime()),
+                    array('level' => Logger::NOTICE, 'message' => 'Something noticeable happened.', 'level_name' => 'notice', 'datetime' => new \DateTime()),
+                ),
+                'yellow',
+            ),
+            array(
+                array(
+                    array('level' => Logger::DEBUG, 'message' => 'Just debugging.', 'level_name' => 'debug', 'datetime' => new \DateTime()),
+                    array('level' => Logger::NOTICE, 'message' => 'Something noticeable happened.', 'level_name' => 'notice', 'datetime' => new \DateTime()),
+                ),
+                'green',
+            ),
+            array(
+                array(
+                    array('level' => Logger::DEBUG, 'message' => 'Just debugging.', 'level_name' => 'debug', 'datetime' => new \DateTime()),
+                ),
+                'gray',
+            ),
+        );
+    }
+
+    private function createHandler($token = 'myToken', $room = 'room1', $name = 'Monolog', $notify = false)
+    {
+        $constructorArgs = array($token, $room, $name, $notify, Logger::DEBUG);
+        $this->res = fopen('php://memory', 'a');
+        $this->handler = $this->getMock(
+            '\Monolog\Handler\HipChatHandler',
+            array('fsockopen', 'streamSetTimeout', 'closeSocket'),
+            $constructorArgs
+        );
+
+        $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString');
+        $reflectionProperty->setAccessible(true);
+        $reflectionProperty->setValue($this->handler, 'localhost:1234');
+
+        $this->handler->expects($this->any())
+            ->method('fsockopen')
+            ->will($this->returnValue($this->res));
+        $this->handler->expects($this->any())
+            ->method('streamSetTimeout')
+            ->will($this->returnValue(true));
+        $this->handler->expects($this->any())
+            ->method('closeSocket')
+            ->will($this->returnValue(true));
+
+        $this->handler->setFormatter($this->getIdentityFormatter());
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testCreateWithTooLongName()
+    {
+        $hipChatHandler = new \Monolog\Handler\HipChatHandler('token', 'room', 'SixteenCharsHere');
+    }
+}

+ 84 - 0
vendor/monolog/monolog/tests/Monolog/Handler/LogEntriesHandlerTest.php

@@ -0,0 +1,84 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+
+/**
+ * @author Robert Kaufmann III <rok3@rok3.me>
+ */
+class LogEntriesHandlerTest extends TestCase
+{
+    /**
+     * @var resource
+     */
+    private $res;
+
+    /**
+     * @var LogEntriesHandler
+     */
+    private $handler;
+
+    public function testWriteContent()
+    {
+        $this->createHandler();
+        $this->handler->handle($this->getRecord(Logger::CRITICAL, 'Critical write test'));
+
+        fseek($this->res, 0);
+        $content = fread($this->res, 1024);
+
+        $this->assertRegexp('/testToken \[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\] test.CRITICAL: Critical write test/', $content);
+    }
+
+    public function testWriteBatchContent()
+    {
+        $records = array(
+            $this->getRecord(),
+            $this->getRecord(),
+            $this->getRecord()
+        );
+        $this->createHandler();
+        $this->handler->handleBatch($records);
+
+        fseek($this->res, 0);
+        $content = fread($this->res, 1024);
+
+        $this->assertRegexp('/(testToken \[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\] .* \[\] \[\]\n){3}/', $content);
+    }
+
+    private function createHandler()
+    {
+        $useSSL = extension_loaded('openssl');
+        $args = array('testToken', $useSSL, Logger::DEBUG, true);
+        $this->res = fopen('php://memory', 'a');
+        $this->handler = $this->getMock(
+            '\Monolog\Handler\LogEntriesHandler',
+            array('fsockopen', 'streamSetTimeout', 'closeSocket'),
+            $args
+        );
+
+        $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString');
+        $reflectionProperty->setAccessible(true);
+        $reflectionProperty->setValue($this->handler, 'localhost:1234');
+
+        $this->handler->expects($this->any())
+            ->method('fsockopen')
+            ->will($this->returnValue($this->res));
+        $this->handler->expects($this->any())
+            ->method('streamSetTimeout')
+            ->will($this->returnValue(true));
+        $this->handler->expects($this->any())
+            ->method('closeSocket')
+            ->will($this->returnValue(true));
+    }
+}

+ 75 - 0
vendor/monolog/monolog/tests/Monolog/Handler/MailHandlerTest.php

@@ -0,0 +1,75 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\TestCase;
+
+class MailHandlerTest extends TestCase
+{
+    /**
+     * @covers Monolog\Handler\MailHandler::handleBatch
+     */
+    public function testHandleBatch()
+    {
+        $formatter = $this->getMock('Monolog\\Formatter\\FormatterInterface');
+        $formatter->expects($this->once())
+            ->method('formatBatch'); // Each record is formatted
+
+        $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler');
+        $handler->expects($this->once())
+            ->method('send');
+        $handler->expects($this->never())
+            ->method('write'); // write is for individual records
+
+        $handler->setFormatter($formatter);
+
+        $handler->handleBatch($this->getMultipleRecords());
+    }
+
+    /**
+     * @covers Monolog\Handler\MailHandler::handleBatch
+     */
+    public function testHandleBatchNotSendsMailIfMessagesAreBelowLevel()
+    {
+        $records = array(
+            $this->getRecord(Logger::DEBUG, 'debug message 1'),
+            $this->getRecord(Logger::DEBUG, 'debug message 2'),
+            $this->getRecord(Logger::INFO, 'information'),
+        );
+
+        $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler');
+        $handler->expects($this->never())
+            ->method('send');
+        $handler->setLevel(Logger::ERROR);
+
+        $handler->handleBatch($records);
+    }
+
+    /**
+     * @covers Monolog\Handler\MailHandler::write
+     */
+    public function testHandle()
+    {
+        $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler');
+
+        $record = $this->getRecord();
+        $records = array($record);
+        $records[0]['formatted'] = '['.$record['datetime']->format('Y-m-d H:i:s').'] test.WARNING: test [] []'."\n";
+
+        $handler->expects($this->once())
+            ->method('send')
+            ->with($records[0]['formatted'], $records);
+
+        $handler->handle($record);
+    }
+}

+ 26 - 0
vendor/monolog/monolog/tests/Monolog/Handler/MockRavenClient.php

@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Raven_Client;
+
+class MockRavenClient extends Raven_Client
+{
+    public function capture($data, $stack, $vars = null)
+    {
+        $this->lastData = $data;
+        $this->lastStack = $stack;
+    }
+
+    public $lastData;
+    public $lastStack;
+}

+ 63 - 0
vendor/monolog/monolog/tests/Monolog/Handler/MongoDBHandlerTest.php

@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+
+class MongoDBHandlerTest extends TestCase
+{
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testConstructorShouldThrowExceptionForInvalidMongo()
+    {
+        new MongoDBHandler(new \stdClass(), 'DB', 'Collection');
+    }
+
+    public function testHandle()
+    {
+        $mongo = $this->getMock('Mongo', array('selectCollection'), array(), '', false);
+        $collection = $this->getMock('stdClass', array('save'));
+
+        $mongo->expects($this->once())
+            ->method('selectCollection')
+            ->with('DB', 'Collection')
+            ->will($this->returnValue($collection));
+
+        $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
+
+        $expected = array(
+            'message' => 'test',
+            'context' => array('data' => '[object] (stdClass: {})', 'foo' => 34),
+            'level' => Logger::WARNING,
+            'level_name' => 'WARNING',
+            'channel' => 'test',
+            'datetime' => $record['datetime']->format('Y-m-d H:i:s'),
+            'extra' => array(),
+        );
+
+        $collection->expects($this->once())
+            ->method('save')
+            ->with($expected);
+
+        $handler = new MongoDBHandler($mongo, 'DB', 'Collection');
+        $handler->handle($record);
+    }
+}
+
+if (!class_exists('Mongo')) {
+    class Mongo
+    {
+        public function selectCollection() {}
+    }
+}

+ 43 - 0
vendor/monolog/monolog/tests/Monolog/Handler/NativeMailerHandlerTest.php

@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+
+class NativeMailerHandlerTest extends TestCase
+{
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testConstructorHeaderInjection()
+    {
+        $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', "receiver@example.org\r\nFrom: faked@attacker.org");
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testSetterHeaderInjection()
+    {
+        $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', 'receiver@example.org');
+        $mailer->addHeader("Content-Type: text/html\r\nFrom: faked@attacker.org");
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testSetterArrayHeaderInjection()
+    {
+        $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', 'receiver@example.org');
+        $mailer->addHeader(array("Content-Type: text/html\r\nFrom: faked@attacker.org"));
+    }
+}

+ 102 - 0
vendor/monolog/monolog/tests/Monolog/Handler/NewRelicHandlerTest.php

@@ -0,0 +1,102 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+use Psr\Log\LogLevel;
+
+class NewRelicHandlerTest extends TestCase
+{
+    public static $appname;
+
+    public function setUp()
+    {
+        $this::$appname = null;
+    }
+
+    /**
+     * @expectedException Monolog\Handler\MissingExtensionException
+     */
+    public function testThehandlerThrowsAnExceptionIfTheNRExtensionIsNotLoaded()
+    {
+        $handler = new StubNewRelicHandlerWithoutExtension();
+        $handler->handle($this->getRecord(Logger::ERROR));
+    }
+
+    public function testThehandlerCanHandleTheRecord()
+    {
+        $handler = new StubNewRelicHandler();
+        $handler->handle($this->getRecord(Logger::ERROR));
+    }
+
+    public function testThehandlerCanAddParamsToTheNewRelicTrace()
+    {
+        $handler = new StubNewRelicHandler();
+        $handler->handle($this->getRecord(Logger::ERROR, 'log message', array('a' => 'b')));
+    }
+
+    public function testTheAppNameIsNullByDefault()
+    {
+        $handler = new StubNewRelicHandler();
+        $handler->handle($this->getRecord(Logger::ERROR, 'log message'));
+
+        $this->assertEquals(null, $this::$appname);
+    }
+
+    public function testTheAppNameCanBeInjectedFromtheConstructor()
+    {
+        $handler = new StubNewRelicHandler(LogLevel::ALERT, false, 'myAppName');
+        $handler->handle($this->getRecord(Logger::ERROR, 'log message'));
+
+        $this->assertEquals('myAppName', $this::$appname);
+    }
+
+    public function testTheAppNameCanBeOverriddenFromEachLog()
+    {
+        $handler = new StubNewRelicHandler(LogLevel::ALERT, false, 'myAppName');
+        $handler->handle($this->getRecord(Logger::ERROR, 'log message', array('appname' => 'logAppName')));
+
+        $this->assertEquals('logAppName', $this::$appname);
+    }
+}
+
+class StubNewRelicHandlerWithoutExtension extends NewRelicHandler
+{
+    protected function isNewRelicEnabled()
+    {
+        return false;
+    }
+}
+
+class StubNewRelicHandler extends NewRelicHandler
+{
+    protected function isNewRelicEnabled()
+    {
+        return true;
+    }
+}
+
+function newrelic_notice_error()
+{
+    return true;
+}
+
+function newrelic_set_appname($appname)
+{
+    return NewRelicHandlerTest::$appname = $appname;
+}
+
+function newrelic_add_custom_parameter()
+{
+    return true;
+}

+ 33 - 0
vendor/monolog/monolog/tests/Monolog/Handler/NullHandlerTest.php

@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+
+/**
+ * @covers Monolog\Handler\NullHandler::handle
+ */
+class NullHandlerTest extends TestCase
+{
+    public function testHandle()
+    {
+        $handler = new NullHandler();
+        $this->assertTrue($handler->handle($this->getRecord()));
+    }
+
+    public function testHandleLowerLevelRecord()
+    {
+        $handler = new NullHandler(Logger::WARNING);
+        $this->assertFalse($handler->handle($this->getRecord(Logger::DEBUG)));
+    }
+}

+ 142 - 0
vendor/monolog/monolog/tests/Monolog/Handler/PushoverHandlerTest.php

@@ -0,0 +1,142 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+
+/**
+ * Almost all examples (expected header, titles, messages) taken from
+ * https://www.pushover.net/api
+ * @author Sebastian Göttschkes <sebastian.goettschkes@googlemail.com>
+ * @see https://www.pushover.net/api
+ */
+class PushoverHandlerTest extends TestCase
+{
+
+    private $res;
+    private $handler;
+
+    public function testWriteHeader()
+    {
+        $this->createHandler();
+        $this->handler->setHighPriorityLevel(Logger::EMERGENCY); // skip priority notifications
+        $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
+        fseek($this->res, 0);
+        $content = fread($this->res, 1024);
+
+        $this->assertRegexp('/POST \/1\/messages.json HTTP\/1.1\\r\\nHost: api.pushover.net\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content);
+
+        return $content;
+    }
+
+    /**
+     * @depends testWriteHeader
+     */
+    public function testWriteContent($content)
+    {
+        $this->assertRegexp('/token=myToken&user=myUser&message=test1&title=Monolog&timestamp=\d{10}$/', $content);
+    }
+
+    public function testWriteWithComplexTitle()
+    {
+        $this->createHandler('myToken', 'myUser', 'Backup finished - SQL1', Logger::EMERGENCY);
+        $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
+        fseek($this->res, 0);
+        $content = fread($this->res, 1024);
+
+        $this->assertRegexp('/title=Backup\+finished\+-\+SQL1/', $content);
+    }
+
+    public function testWriteWithComplexMessage()
+    {
+        $this->createHandler();
+        $this->handler->setHighPriorityLevel(Logger::EMERGENCY); // skip priority notifications
+        $this->handler->handle($this->getRecord(Logger::CRITICAL, 'Backup of database "example" finished in 16 minutes.'));
+        fseek($this->res, 0);
+        $content = fread($this->res, 1024);
+
+        $this->assertRegexp('/message=Backup\+of\+database\+%22example%22\+finished\+in\+16\+minutes\./', $content);
+    }
+
+    public function testWriteWithTooLongMessage()
+    {
+        $message = str_pad('test', 520, 'a');
+        $this->createHandler();
+        $this->handler->setHighPriorityLevel(Logger::EMERGENCY); // skip priority notifications
+        $this->handler->handle($this->getRecord(Logger::CRITICAL, $message));
+        fseek($this->res, 0);
+        $content = fread($this->res, 1024);
+
+        $expectedMessage = substr($message, 0, 505);
+
+        $this->assertRegexp('/message=' . $expectedMessage . '&title/', $content);
+    }
+
+    public function testWriteWithHighPriority()
+    {
+        $this->createHandler();
+        $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
+        fseek($this->res, 0);
+        $content = fread($this->res, 1024);
+
+        $this->assertRegexp('/token=myToken&user=myUser&message=test1&title=Monolog&timestamp=\d{10}&priority=1$/', $content);
+    }
+
+    public function testWriteWithEmergencyPriority()
+    {
+        $this->createHandler();
+        $this->handler->handle($this->getRecord(Logger::EMERGENCY, 'test1'));
+        fseek($this->res, 0);
+        $content = fread($this->res, 1024);
+
+        $this->assertRegexp('/token=myToken&user=myUser&message=test1&title=Monolog&timestamp=\d{10}&priority=2&retry=30&expire=25200$/', $content);
+    }
+
+    public function testWriteToMultipleUsers()
+    {
+        $this->createHandler('myToken', array('userA', 'userB'));
+        $this->handler->handle($this->getRecord(Logger::EMERGENCY, 'test1'));
+        fseek($this->res, 0);
+        $content = fread($this->res, 1024);
+
+        $this->assertRegexp('/token=myToken&user=userA&message=test1&title=Monolog&timestamp=\d{10}&priority=2&retry=30&expire=25200POST/', $content);
+        $this->assertRegexp('/token=myToken&user=userB&message=test1&title=Monolog&timestamp=\d{10}&priority=2&retry=30&expire=25200$/', $content);
+    }
+
+    private function createHandler($token = 'myToken', $user = 'myUser', $title = 'Monolog')
+    {
+        $constructorArgs = array($token, $user, $title);
+        $this->res = fopen('php://memory', 'a');
+        $this->handler = $this->getMock(
+            '\Monolog\Handler\PushoverHandler',
+            array('fsockopen', 'streamSetTimeout', 'closeSocket'),
+            $constructorArgs
+        );
+
+        $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString');
+        $reflectionProperty->setAccessible(true);
+        $reflectionProperty->setValue($this->handler, 'localhost:1234');
+
+        $this->handler->expects($this->any())
+            ->method('fsockopen')
+            ->will($this->returnValue($this->res));
+        $this->handler->expects($this->any())
+            ->method('streamSetTimeout')
+            ->will($this->returnValue(true));
+        $this->handler->expects($this->any())
+            ->method('closeSocket')
+            ->will($this->returnValue(true));
+
+        $this->handler->setFormatter($this->getIdentityFormatter());
+    }
+}

+ 150 - 0
vendor/monolog/monolog/tests/Monolog/Handler/RavenHandlerTest.php

@@ -0,0 +1,150 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+use Monolog\Formatter\LineFormatter;
+
+class RavenHandlerTest extends TestCase
+{
+    public function setUp()
+    {
+        if (!class_exists("Raven_Client")) {
+            $this->markTestSkipped("raven/raven not installed");
+        }
+
+        require_once __DIR__ . '/MockRavenClient.php';
+    }
+
+    /**
+     * @covers Monolog\Handler\RavenHandler::__construct
+     */
+    public function testConstruct()
+    {
+        $handler = new RavenHandler($this->getRavenClient());
+        $this->assertInstanceOf('Monolog\Handler\RavenHandler', $handler);
+    }
+
+    protected function getHandler($ravenClient)
+    {
+        $handler = new RavenHandler($ravenClient);
+
+        return $handler;
+    }
+
+    protected function getRavenClient()
+    {
+        $dsn = 'http://43f6017361224d098402974103bfc53d:a6a0538fc2934ba2bed32e08741b2cd3@marca.python.live.cheggnet.com:9000/1';
+
+        return new MockRavenClient($dsn);
+    }
+
+    public function testDebug()
+    {
+        $ravenClient = $this->getRavenClient();
+        $handler = $this->getHandler($ravenClient);
+
+        $record = $this->getRecord(Logger::DEBUG, "A test debug message");
+        $handler->handle($record);
+
+        $this->assertEquals($ravenClient::DEBUG, $ravenClient->lastData['level']);
+        $this->assertContains($record['message'], $ravenClient->lastData['message']);
+    }
+
+    public function testWarning()
+    {
+        $ravenClient = $this->getRavenClient();
+        $handler = $this->getHandler($ravenClient);
+
+        $record = $this->getRecord(Logger::WARNING, "A test warning message");
+        $handler->handle($record);
+
+        $this->assertEquals($ravenClient::WARNING, $ravenClient->lastData['level']);
+        $this->assertContains($record['message'], $ravenClient->lastData['message']);
+    }
+
+    public function testTag()
+    {
+        $ravenClient = $this->getRavenClient();
+        $handler = $this->getHandler($ravenClient);
+
+        $tags = array(1, 2, 'foo');
+        $record = $this->getRecord(Logger::INFO, "test", array('tags' => $tags));
+        $handler->handle($record);
+
+        $this->assertEquals($tags, $ravenClient->lastData['tags']);
+    }
+
+    public function testException()
+    {
+        $ravenClient = $this->getRavenClient();
+        $handler = $this->getHandler($ravenClient);
+
+        try {
+            $this->methodThatThrowsAnException();
+        } catch (\Exception $e) {
+            $record = $this->getRecord(Logger::ERROR, $e->getMessage(), array('exception' => $e));
+            $handler->handle($record);
+        }
+
+        $this->assertEquals($record['message'], $ravenClient->lastData['message']);
+    }
+
+    public function testHandleBatch()
+    {
+        $records = $this->getMultipleRecords();
+        $records[] = $this->getRecord(Logger::WARNING, 'warning');
+        $records[] = $this->getRecord(Logger::WARNING, 'warning');
+
+        $logFormatter = $this->getMock('Monolog\\Formatter\\FormatterInterface');
+        $logFormatter->expects($this->once())->method('formatBatch');
+
+        $formatter = $this->getMock('Monolog\\Formatter\\FormatterInterface');
+        $formatter->expects($this->once())->method('format')->with($this->callback(function ($record) {
+            return $record['level'] == 400;
+        }));
+
+        $handler = $this->getHandler($this->getRavenClient());
+        $handler->setBatchFormatter($logFormatter);
+        $handler->setFormatter($formatter);
+        $handler->handleBatch($records);
+    }
+
+    public function testHandleBatchDoNothingIfRecordsAreBelowLevel()
+    {
+        $records = array(
+            $this->getRecord(Logger::DEBUG, 'debug message 1'),
+            $this->getRecord(Logger::DEBUG, 'debug message 2'),
+            $this->getRecord(Logger::INFO, 'information'),
+        );
+
+        $handler = $this->getMock('Monolog\Handler\RavenHandler', null, array($this->getRavenClient()));
+        $handler->expects($this->never())->method('handle');
+        $handler->setLevel(Logger::ERROR);
+        $handler->handleBatch($records);
+    }
+
+    public function testGetSetBatchFormatter()
+    {
+        $ravenClient = $this->getRavenClient();
+        $handler = $this->getHandler($ravenClient);
+
+        $handler->setBatchFormatter($formatter = new LineFormatter());
+        $this->assertSame($formatter, $handler->getBatchFormatter());
+    }
+
+    private function methodThatThrowsAnException()
+    {
+        throw new \Exception('This is an exception');
+    }
+}

+ 71 - 0
vendor/monolog/monolog/tests/Monolog/Handler/RedisHandlerTest.php

@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+use Monolog\Formatter\LineFormatter;
+
+class RedisHandlerTest extends TestCase
+{
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testConstructorShouldThrowExceptionForInvalidRedis()
+    {
+        new RedisHandler(new \stdClass(), 'key');
+    }
+
+    public function testConstructorShouldWorkWithPredis()
+    {
+        $redis = $this->getMock('Predis\Client');
+        $this->assertInstanceof('Monolog\Handler\RedisHandler', new RedisHandler($redis, 'key'));
+    }
+
+    public function testConstructorShouldWorkWithRedis()
+    {
+        $redis = $this->getMock('Redis');
+        $this->assertInstanceof('Monolog\Handler\RedisHandler', new RedisHandler($redis, 'key'));
+    }
+
+    public function testPredisHandle()
+    {
+        $redis = $this->getMock('Predis\Client', array('rpush'));
+
+        // Predis\Client uses rpush
+        $redis->expects($this->once())
+            ->method('rpush')
+            ->with('key', 'test');
+
+        $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
+
+        $handler = new RedisHandler($redis, 'key');
+        $handler->setFormatter(new LineFormatter("%message%"));
+        $handler->handle($record);
+    }
+
+    public function testRedisHandle()
+    {
+        $redis = $this->getMock('Redis', array('rpush'));
+
+        // Redis uses rPush
+        $redis->expects($this->once())
+            ->method('rPush')
+            ->with('key', 'test');
+
+        $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
+
+        $handler = new RedisHandler($redis, 'key');
+        $handler->setFormatter(new LineFormatter("%message%"));
+        $handler->handle($record);
+    }
+}

+ 99 - 0
vendor/monolog/monolog/tests/Monolog/Handler/RotatingFileHandlerTest.php

@@ -0,0 +1,99 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+
+/**
+ * @covers Monolog\Handler\RotatingFileHandler
+ */
+class RotatingFileHandlerTest extends TestCase
+{
+    public function setUp()
+    {
+        $dir = __DIR__.'/Fixtures';
+        chmod($dir, 0777);
+        if (!is_writable($dir)) {
+            $this->markTestSkipped($dir.' must be writeable to test the RotatingFileHandler.');
+        }
+    }
+
+    public function testRotationCreatesNewFile()
+    {
+        touch(__DIR__.'/Fixtures/foo-'.date('Y-m-d', time() - 86400).'.rot');
+
+        $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot');
+        $handler->setFormatter($this->getIdentityFormatter());
+        $handler->handle($this->getRecord());
+
+        $log = __DIR__.'/Fixtures/foo-'.date('Y-m-d').'.rot';
+        $this->assertTrue(file_exists($log));
+        $this->assertEquals('test', file_get_contents($log));
+    }
+
+    /**
+     * @dataProvider rotationTests
+     */
+    public function testRotation($createFile)
+    {
+        touch($old1 = __DIR__.'/Fixtures/foo-'.date('Y-m-d', time() - 86400).'.rot');
+        touch($old2 = __DIR__.'/Fixtures/foo-'.date('Y-m-d', time() - 86400 * 2).'.rot');
+        touch($old3 = __DIR__.'/Fixtures/foo-'.date('Y-m-d', time() - 86400 * 3).'.rot');
+        touch($old4 = __DIR__.'/Fixtures/foo-'.date('Y-m-d', time() - 86400 * 4).'.rot');
+
+        $log = __DIR__.'/Fixtures/foo-'.date('Y-m-d').'.rot';
+
+        if ($createFile) {
+            touch($log);
+        }
+
+        $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot', 2);
+        $handler->setFormatter($this->getIdentityFormatter());
+        $handler->handle($this->getRecord());
+
+        $handler->close();
+
+        $this->assertTrue(file_exists($log));
+        $this->assertTrue(file_exists($old1));
+        $this->assertEquals($createFile, file_exists($old2));
+        $this->assertEquals($createFile, file_exists($old3));
+        $this->assertEquals($createFile, file_exists($old4));
+        $this->assertEquals('test', file_get_contents($log));
+    }
+
+    public function rotationTests()
+    {
+        return array(
+            'Rotation is triggered when the file of the current day is not present'
+                => array(true),
+            'Rotation is not triggered when the file is already present'
+                => array(false),
+        );
+    }
+
+    public function testReuseCurrentFile()
+    {
+        $log = __DIR__.'/Fixtures/foo-'.date('Y-m-d').'.rot';
+        file_put_contents($log, "foo");
+        $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot');
+        $handler->setFormatter($this->getIdentityFormatter());
+        $handler->handle($this->getRecord());
+        $this->assertEquals('footest', file_get_contents($log));
+    }
+
+    public function tearDown()
+    {
+        foreach (glob(__DIR__.'/Fixtures/*.rot') as $file) {
+            unlink($file);
+        }
+    }
+}

+ 283 - 0
vendor/monolog/monolog/tests/Monolog/Handler/SocketHandlerTest.php

@@ -0,0 +1,283 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+
+/**
+ * @author Pablo de Leon Belloc <pablolb@gmail.com>
+ */
+class SocketHandlerTest extends TestCase
+{
+    /**
+     * @var Monolog\Handler\SocketHandler
+     */
+    private $handler;
+
+    /**
+     * @var resource
+     */
+    private $res;
+
+    /**
+     * @expectedException UnexpectedValueException
+     */
+    public function testInvalidHostname()
+    {
+        $this->createHandler('garbage://here');
+        $this->writeRecord('data');
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     */
+    public function testBadConnectionTimeout()
+    {
+        $this->createHandler('localhost:1234');
+        $this->handler->setConnectionTimeout(-1);
+    }
+
+    public function testSetConnectionTimeout()
+    {
+        $this->createHandler('localhost:1234');
+        $this->handler->setConnectionTimeout(10.1);
+        $this->assertEquals(10.1, $this->handler->getConnectionTimeout());
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     */
+    public function testBadTimeout()
+    {
+        $this->createHandler('localhost:1234');
+        $this->handler->setTimeout(-1);
+    }
+
+    public function testSetTimeout()
+    {
+        $this->createHandler('localhost:1234');
+        $this->handler->setTimeout(10.25);
+        $this->assertEquals(10.25, $this->handler->getTimeout());
+    }
+
+    public function testSetConnectionString()
+    {
+        $this->createHandler('tcp://localhost:9090');
+        $this->assertEquals('tcp://localhost:9090', $this->handler->getConnectionString());
+    }
+
+    /**
+     * @expectedException UnexpectedValueException
+     */
+    public function testExceptionIsThrownOnFsockopenError()
+    {
+        $this->setMockHandler(array('fsockopen'));
+        $this->handler->expects($this->once())
+            ->method('fsockopen')
+            ->will($this->returnValue(false));
+        $this->writeRecord('Hello world');
+    }
+
+    /**
+     * @expectedException UnexpectedValueException
+     */
+    public function testExceptionIsThrownOnPfsockopenError()
+    {
+        $this->setMockHandler(array('pfsockopen'));
+        $this->handler->expects($this->once())
+            ->method('pfsockopen')
+            ->will($this->returnValue(false));
+        $this->handler->setPersistent(true);
+        $this->writeRecord('Hello world');
+    }
+
+    /**
+     * @expectedException UnexpectedValueException
+     */
+    public function testExceptionIsThrownIfCannotSetTimeout()
+    {
+        $this->setMockHandler(array('streamSetTimeout'));
+        $this->handler->expects($this->once())
+            ->method('streamSetTimeout')
+            ->will($this->returnValue(false));
+        $this->writeRecord('Hello world');
+    }
+
+    /**
+     * @expectedException RuntimeException
+     */
+    public function testWriteFailsOnIfFwriteReturnsFalse()
+    {
+        $this->setMockHandler(array('fwrite'));
+
+        $callback = function ($arg) {
+            $map = array(
+                'Hello world' => 6,
+                'world' => false,
+            );
+
+            return $map[$arg];
+        };
+
+        $this->handler->expects($this->exactly(2))
+            ->method('fwrite')
+            ->will($this->returnCallback($callback));
+
+        $this->writeRecord('Hello world');
+    }
+
+    /**
+     * @expectedException RuntimeException
+     */
+    public function testWriteFailsIfStreamTimesOut()
+    {
+        $this->setMockHandler(array('fwrite', 'streamGetMetadata'));
+
+        $callback = function ($arg) {
+            $map = array(
+                'Hello world' => 6,
+                'world' => 5,
+            );
+
+            return $map[$arg];
+        };
+
+        $this->handler->expects($this->exactly(1))
+            ->method('fwrite')
+            ->will($this->returnCallback($callback));
+        $this->handler->expects($this->exactly(1))
+            ->method('streamGetMetadata')
+            ->will($this->returnValue(array('timed_out' => true)));
+
+        $this->writeRecord('Hello world');
+    }
+
+    /**
+     * @expectedException RuntimeException
+     */
+    public function testWriteFailsOnIncompleteWrite()
+    {
+        $this->setMockHandler(array('fwrite', 'streamGetMetadata'));
+
+        $res = $this->res;
+        $callback = function ($string) use ($res) {
+            fclose($res);
+
+            return strlen('Hello');
+        };
+
+        $this->handler->expects($this->exactly(1))
+            ->method('fwrite')
+            ->will($this->returnCallback($callback));
+        $this->handler->expects($this->exactly(1))
+            ->method('streamGetMetadata')
+            ->will($this->returnValue(array('timed_out' => false)));
+
+        $this->writeRecord('Hello world');
+    }
+
+    public function testWriteWithMemoryFile()
+    {
+        $this->setMockHandler();
+        $this->writeRecord('test1');
+        $this->writeRecord('test2');
+        $this->writeRecord('test3');
+        fseek($this->res, 0);
+        $this->assertEquals('test1test2test3', fread($this->res, 1024));
+    }
+
+    public function testWriteWithMock()
+    {
+        $this->setMockHandler(array('fwrite'));
+
+        $callback = function ($arg) {
+            $map = array(
+                'Hello world' => 6,
+                'world' => 5,
+            );
+
+            return $map[$arg];
+        };
+
+        $this->handler->expects($this->exactly(2))
+            ->method('fwrite')
+            ->will($this->returnCallback($callback));
+
+        $this->writeRecord('Hello world');
+    }
+
+    public function testClose()
+    {
+        $this->setMockHandler();
+        $this->writeRecord('Hello world');
+        $this->assertInternalType('resource', $this->res);
+        $this->handler->close();
+        $this->assertFalse(is_resource($this->res), "Expected resource to be closed after closing handler");
+    }
+
+    public function testCloseDoesNotClosePersistentSocket()
+    {
+        $this->setMockHandler();
+        $this->handler->setPersistent(true);
+        $this->writeRecord('Hello world');
+        $this->assertTrue(is_resource($this->res));
+        $this->handler->close();
+        $this->assertTrue(is_resource($this->res));
+    }
+
+    private function createHandler($connectionString)
+    {
+        $this->handler = new SocketHandler($connectionString);
+        $this->handler->setFormatter($this->getIdentityFormatter());
+    }
+
+    private function writeRecord($string)
+    {
+        $this->handler->handle($this->getRecord(Logger::WARNING, $string));
+    }
+
+    private function setMockHandler(array $methods = array())
+    {
+        $this->res = fopen('php://memory', 'a');
+
+        $defaultMethods = array('fsockopen', 'pfsockopen', 'streamSetTimeout');
+        $newMethods = array_diff($methods, $defaultMethods);
+
+        $finalMethods = array_merge($defaultMethods, $newMethods);
+
+        $this->handler = $this->getMock(
+            '\Monolog\Handler\SocketHandler', $finalMethods, array('localhost:1234')
+        );
+
+        if (!in_array('fsockopen', $methods)) {
+            $this->handler->expects($this->any())
+                ->method('fsockopen')
+                ->will($this->returnValue($this->res));
+        }
+
+        if (!in_array('pfsockopen', $methods)) {
+            $this->handler->expects($this->any())
+                ->method('pfsockopen')
+                ->will($this->returnValue($this->res));
+        }
+
+        if (!in_array('streamSetTimeout', $methods)) {
+            $this->handler->expects($this->any())
+                ->method('streamSetTimeout')
+                ->will($this->returnValue(true));
+        }
+
+        $this->handler->setFormatter($this->getIdentityFormatter());
+    }
+
+}

+ 88 - 0
vendor/monolog/monolog/tests/Monolog/Handler/StreamHandlerTest.php

@@ -0,0 +1,88 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+
+class StreamHandlerTest extends TestCase
+{
+    /**
+     * @covers Monolog\Handler\StreamHandler::__construct
+     * @covers Monolog\Handler\StreamHandler::write
+     */
+    public function testWrite()
+    {
+        $handle = fopen('php://memory', 'a+');
+        $handler = new StreamHandler($handle);
+        $handler->setFormatter($this->getIdentityFormatter());
+        $handler->handle($this->getRecord(Logger::WARNING, 'test'));
+        $handler->handle($this->getRecord(Logger::WARNING, 'test2'));
+        $handler->handle($this->getRecord(Logger::WARNING, 'test3'));
+        fseek($handle, 0);
+        $this->assertEquals('testtest2test3', fread($handle, 100));
+    }
+
+    /**
+     * @covers Monolog\Handler\StreamHandler::close
+     */
+    public function testClose()
+    {
+        $handle = fopen('php://memory', 'a+');
+        $handler = new StreamHandler($handle);
+        $this->assertTrue(is_resource($handle));
+        $handler->close();
+        $this->assertFalse(is_resource($handle));
+    }
+
+    /**
+     * @covers Monolog\Handler\StreamHandler::write
+     */
+    public function testWriteCreatesTheStreamResource()
+    {
+        $handler = new StreamHandler('php://memory');
+        $handler->handle($this->getRecord());
+    }
+
+    /**
+     * @expectedException LogicException
+     * @covers Monolog\Handler\StreamHandler::__construct
+     * @covers Monolog\Handler\StreamHandler::write
+     */
+    public function testWriteMissingResource()
+    {
+        $handler = new StreamHandler(null);
+        $handler->handle($this->getRecord());
+    }
+
+    /**
+     * @expectedException UnexpectedValueException
+     * @covers Monolog\Handler\StreamHandler::__construct
+     * @covers Monolog\Handler\StreamHandler::write
+     */
+    public function testWriteInvalidResource()
+    {
+        $handler = new StreamHandler('bogus://url');
+        $handler->handle($this->getRecord());
+    }
+
+    /**
+     * @expectedException UnexpectedValueException
+     * @covers Monolog\Handler\StreamHandler::__construct
+     * @covers Monolog\Handler\StreamHandler::write
+     */
+    public function testWriteNonExistingResource()
+    {
+        $handler = new StreamHandler('/foo/bar/baz/'.rand(0, 10000));
+        $handler->handle($this->getRecord());
+    }
+}

+ 43 - 0
vendor/monolog/monolog/tests/Monolog/Handler/SyslogHandlerTest.php

@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+use Monolog\Logger;
+
+class SyslogHandlerTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @covers Monolog\Handler\SyslogHandler::__construct
+     */
+    public function testConstruct()
+    {
+        $handler = new SyslogHandler('test');
+        $this->assertInstanceOf('Monolog\Handler\SyslogHandler', $handler);
+
+        $handler = new SyslogHandler('test', LOG_USER);
+        $this->assertInstanceOf('Monolog\Handler\SyslogHandler', $handler);
+
+        $handler = new SyslogHandler('test', 'user');
+        $this->assertInstanceOf('Monolog\Handler\SyslogHandler', $handler);
+
+        $handler = new SyslogHandler('test', LOG_USER, Logger::DEBUG, true, LOG_PERROR);
+        $this->assertInstanceOf('Monolog\Handler\SyslogHandler', $handler);
+    }
+
+    /**
+     * @covers Monolog\Handler\SyslogHandler::__construct
+     */
+    public function testConstructInvalidFacility()
+    {
+        $this->setExpectedException('UnexpectedValueException');
+        $handler = new SyslogHandler('test', 'unknown');
+    }
+}

+ 37 - 0
vendor/monolog/monolog/tests/Monolog/Handler/SyslogUdpHandlerTest.php

@@ -0,0 +1,37 @@
+<?php
+
+namespace Monolog\Handler;
+
+class SyslogUdpHandlerTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @expectedException UnexpectedValueException
+     */
+    public function testWeValidateFacilities()
+    {
+        $handler = new SyslogUdpHandler("ip", null, "invalidFacility");
+    }
+
+    public function testWeSplitIntoLines()
+    {
+        $handler = new SyslogUdpHandler("127.0.0.1", 514, "authpriv");
+        $handler->setFormatter(new \Monolog\Formatter\ChromePHPFormatter());
+
+        $socket = $this->getMock('\Monolog\Handler\SyslogUdp\UdpSocket', array('write'), array('lol', 'lol'));
+        $socket->expects($this->at(0))
+            ->method('write')
+            ->with("lol", "<".(LOG_AUTHPRIV + LOG_WARNING).">: ");
+        $socket->expects($this->at(1))
+            ->method('write')
+            ->with("hej", "<".(LOG_AUTHPRIV + LOG_WARNING).">: ");
+
+        $handler->setSocket($socket);
+
+        $handler->handle($this->getRecordWithMessage("hej\nlol"));
+    }
+
+    protected function getRecordWithMessage($msg)
+    {
+        return array('message' => $msg, 'level' => \Monolog\Logger::WARNING, 'context' => null, 'extra' => array(), 'channel' => 'lol');
+    }
+}

+ 56 - 0
vendor/monolog/monolog/tests/Monolog/Handler/TestHandlerTest.php

@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+use Monolog\Logger;
+
+/**
+ * @covers Monolog\Handler\TestHandler
+ */
+class TestHandlerTest extends TestCase
+{
+    /**
+     * @dataProvider methodProvider
+     */
+    public function testHandler($method, $level)
+    {
+        $handler = new TestHandler;
+        $record = $this->getRecord($level, 'test'.$method);
+        $this->assertFalse($handler->{'has'.$method}($record));
+        $this->assertFalse($handler->{'has'.$method.'Records'}());
+        $handler->handle($record);
+
+        $this->assertFalse($handler->{'has'.$method}('bar'));
+        $this->assertTrue($handler->{'has'.$method}($record));
+        $this->assertTrue($handler->{'has'.$method}('test'.$method));
+        $this->assertTrue($handler->{'has'.$method.'Records'}());
+
+        $records = $handler->getRecords();
+        unset($records[0]['formatted']);
+        $this->assertEquals(array($record), $records);
+    }
+
+    public function methodProvider()
+    {
+        return array(
+            array('Emergency', Logger::EMERGENCY),
+            array('Alert'    , Logger::ALERT),
+            array('Critical' , Logger::CRITICAL),
+            array('Error'    , Logger::ERROR),
+            array('Warning'  , Logger::WARNING),
+            array('Info'     , Logger::INFO),
+            array('Notice'   , Logger::NOTICE),
+            array('Debug'    , Logger::DEBUG),
+        );
+    }
+}

+ 45 - 0
vendor/monolog/monolog/tests/Monolog/Handler/UdpSocketTest.php

@@ -0,0 +1,45 @@
+<?php
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+
+class UdpSocketTest extends TestCase
+{
+    public function testWeDoNotSplitShortMessages()
+    {
+        $socket = $this->getMock('\Monolog\Handler\SyslogUdp\UdpSocket', array('send'), array('lol', 'lol'));
+
+        $socket->expects($this->at(0))
+            ->method('send')
+            ->with("HEADER: The quick brown fox jumps over the lazy dog");
+
+        $socket->write("The quick brown fox jumps over the lazy dog", "HEADER: ");
+    }
+
+    public function testWeSplitLongMessages()
+    {
+        $socket = $this->getMock('\Monolog\Handler\SyslogUdp\UdpSocket', array('send'), array('lol', 'lol'));
+
+        $socket->expects($this->at(1))
+            ->method('send')
+            ->with("The quick brown fox jumps over the lazy dog");
+
+        $aStringOfLength2048 = str_repeat("derp", 2048/4);
+
+        $socket->write($aStringOfLength2048."The quick brown fox jumps over the lazy dog");
+    }
+
+    public function testAllSplitMessagesHasAHeader()
+    {
+        $socket = $this->getMock('\Monolog\Handler\SyslogUdp\UdpSocket', array('send'), array('lol', 'lol'));
+
+        $socket->expects($this->exactly(5))
+            ->method('send')
+            ->with($this->stringStartsWith("HEADER"));
+
+        $aStringOfLength8192 = str_repeat("derp", 2048);
+
+        $socket->write($aStringOfLength8192, "HEADER");
+    }
+}

+ 69 - 0
vendor/monolog/monolog/tests/Monolog/Handler/ZendMonitorHandlerTest.php

@@ -0,0 +1,69 @@
+<?php
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\TestCase;
+
+class ZendMonitorHandlerTest extends TestCase
+{
+    protected $zendMonitorHandler;
+
+    public function setUp()
+    {
+        if (!function_exists('zend_monitor_custom_event')) {
+            $this->markTestSkipped('ZendServer is not installed');
+        }
+    }
+
+    /**
+     * @covers  Monolog\Handler\ZendMonitorHandler::write
+     */
+    public function testWrite()
+    {
+        $record = $this->getRecord();
+        $formatterResult = array(
+            'message' => $record['message']
+        );
+
+        $zendMonitor = $this->getMockBuilder('Monolog\Handler\ZendMonitorHandler')
+            ->setMethods(array('writeZendMonitorCustomEvent', 'getDefaultFormatter'))
+            ->getMock();
+
+        $formatterMock = $this->getMockBuilder('Monolog\Formatter\NormalizerFormatter')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $formatterMock->expects($this->once())
+            ->method('format')
+            ->will($this->returnValue($formatterResult));
+
+        $zendMonitor->expects($this->once())
+            ->method('getDefaultFormatter')
+            ->will($this->returnValue($formatterMock));
+
+        $levelMap = $zendMonitor->getLevelMap();
+
+        $zendMonitor->expects($this->once())
+            ->method('writeZendMonitorCustomEvent')
+            ->with($levelMap[$record['level']], $record['message'], $formatterResult);
+
+        $zendMonitor->handle($record);
+    }
+
+    /**
+     * @covers Monolog\Handler\ZendMonitorHandler::getDefaultFormatter
+     */
+    public function testGetDefaultFormatterReturnsNormalizerFormatter()
+    {
+        $zendMonitor = new ZendMonitorHandler();
+        $this->assertInstanceOf('Monolog\Formatter\NormalizerFormatter', $zendMonitor->getDefaultFormatter());
+    }
+}

+ 409 - 0
vendor/monolog/monolog/tests/Monolog/LoggerTest.php

@@ -0,0 +1,409 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog;
+
+use Monolog\Processor\WebProcessor;
+use Monolog\Handler\TestHandler;
+
+class LoggerTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @covers Monolog\Logger::getName
+     */
+    public function testGetName()
+    {
+        $logger = new Logger('foo');
+        $this->assertEquals('foo', $logger->getName());
+    }
+
+    /**
+     * @covers Monolog\Logger::getLevelName
+     */
+    public function testGetLevelName()
+    {
+        $this->assertEquals('ERROR', Logger::getLevelName(Logger::ERROR));
+    }
+
+    /**
+     * @covers Monolog\Logger::getLevelName
+     * @expectedException InvalidArgumentException
+     */
+    public function testGetLevelNameThrows()
+    {
+        Logger::getLevelName(5);
+    }
+
+    /**
+     * @covers Monolog\Logger::__construct
+     */
+    public function testChannel()
+    {
+        $logger = new Logger('foo');
+        $handler = new TestHandler;
+        $logger->pushHandler($handler);
+        $logger->addWarning('test');
+        list($record) = $handler->getRecords();
+        $this->assertEquals('foo', $record['channel']);
+    }
+
+    /**
+     * @covers Monolog\Logger::addRecord
+     */
+    public function testLog()
+    {
+        $logger = new Logger(__METHOD__);
+
+        $handler = $this->getMock('Monolog\Handler\NullHandler', array('handle'));
+        $handler->expects($this->once())
+            ->method('handle');
+        $logger->pushHandler($handler);
+
+        $this->assertTrue($logger->addWarning('test'));
+    }
+
+    /**
+     * @covers Monolog\Logger::addRecord
+     */
+    public function testLogNotHandled()
+    {
+        $logger = new Logger(__METHOD__);
+
+        $handler = $this->getMock('Monolog\Handler\NullHandler', array('handle'), array(Logger::ERROR));
+        $handler->expects($this->never())
+            ->method('handle');
+        $logger->pushHandler($handler);
+
+        $this->assertFalse($logger->addWarning('test'));
+    }
+
+    public function testHandlersInCtor()
+    {
+        $handler1 = new TestHandler;
+        $handler2 = new TestHandler;
+        $logger = new Logger(__METHOD__, array($handler1, $handler2));
+
+        $this->assertEquals($handler1, $logger->popHandler());
+        $this->assertEquals($handler2, $logger->popHandler());
+    }
+
+    public function testProcessorsInCtor()
+    {
+        $processor1 = new WebProcessor;
+        $processor2 = new WebProcessor;
+        $logger = new Logger(__METHOD__, array(), array($processor1, $processor2));
+
+        $this->assertEquals($processor1, $logger->popProcessor());
+        $this->assertEquals($processor2, $logger->popProcessor());
+    }
+
+    /**
+     * @covers Monolog\Logger::pushHandler
+     * @covers Monolog\Logger::popHandler
+     * @expectedException LogicException
+     */
+    public function testPushPopHandler()
+    {
+        $logger = new Logger(__METHOD__);
+        $handler1 = new TestHandler;
+        $handler2 = new TestHandler;
+
+        $logger->pushHandler($handler1);
+        $logger->pushHandler($handler2);
+
+        $this->assertEquals($handler2, $logger->popHandler());
+        $this->assertEquals($handler1, $logger->popHandler());
+        $logger->popHandler();
+    }
+
+    /**
+     * @covers Monolog\Logger::pushProcessor
+     * @covers Monolog\Logger::popProcessor
+     * @expectedException LogicException
+     */
+    public function testPushPopProcessor()
+    {
+        $logger = new Logger(__METHOD__);
+        $processor1 = new WebProcessor;
+        $processor2 = new WebProcessor;
+
+        $logger->pushProcessor($processor1);
+        $logger->pushProcessor($processor2);
+
+        $this->assertEquals($processor2, $logger->popProcessor());
+        $this->assertEquals($processor1, $logger->popProcessor());
+        $logger->popProcessor();
+    }
+
+    /**
+     * @covers Monolog\Logger::pushProcessor
+     * @expectedException InvalidArgumentException
+     */
+    public function testPushProcessorWithNonCallable()
+    {
+        $logger = new Logger(__METHOD__);
+
+        $logger->pushProcessor(new \stdClass());
+    }
+
+    /**
+     * @covers Monolog\Logger::addRecord
+     */
+    public function testProcessorsAreExecuted()
+    {
+        $logger = new Logger(__METHOD__);
+        $handler = new TestHandler;
+        $logger->pushHandler($handler);
+        $logger->pushProcessor(function ($record) {
+            $record['extra']['win'] = true;
+
+            return $record;
+        });
+        $logger->addError('test');
+        list($record) = $handler->getRecords();
+        $this->assertTrue($record['extra']['win']);
+    }
+
+    /**
+     * @covers Monolog\Logger::addRecord
+     */
+    public function testProcessorsAreCalledOnlyOnce()
+    {
+        $logger = new Logger(__METHOD__);
+        $handler = $this->getMock('Monolog\Handler\HandlerInterface');
+        $handler->expects($this->any())
+            ->method('isHandling')
+            ->will($this->returnValue(true))
+        ;
+        $handler->expects($this->any())
+            ->method('handle')
+            ->will($this->returnValue(true))
+        ;
+        $logger->pushHandler($handler);
+
+        $processor = $this->getMockBuilder('Monolog\Processor\WebProcessor')
+            ->disableOriginalConstructor()
+            ->setMethods(array('__invoke'))
+            ->getMock()
+        ;
+        $processor->expects($this->once())
+            ->method('__invoke')
+            ->will($this->returnArgument(0))
+        ;
+        $logger->pushProcessor($processor);
+
+        $logger->addError('test');
+    }
+
+    /**
+     * @covers Monolog\Logger::addRecord
+     */
+    public function testProcessorsNotCalledWhenNotHandled()
+    {
+        $logger = new Logger(__METHOD__);
+        $handler = $this->getMock('Monolog\Handler\HandlerInterface');
+        $handler->expects($this->once())
+            ->method('isHandling')
+            ->will($this->returnValue(false))
+        ;
+        $logger->pushHandler($handler);
+        $that = $this;
+        $logger->pushProcessor(function ($record) use ($that) {
+            $that->fail('The processor should not be called');
+        });
+        $logger->addAlert('test');
+    }
+
+    /**
+     * @covers Monolog\Logger::addRecord
+     */
+    public function testHandlersNotCalledBeforeFirstHandling()
+    {
+        $logger = new Logger(__METHOD__);
+
+        $handler1 = $this->getMock('Monolog\Handler\HandlerInterface');
+        $handler1->expects($this->never())
+            ->method('isHandling')
+            ->will($this->returnValue(false))
+        ;
+        $handler1->expects($this->once())
+            ->method('handle')
+            ->will($this->returnValue(false))
+        ;
+        $logger->pushHandler($handler1);
+
+        $handler2 = $this->getMock('Monolog\Handler\HandlerInterface');
+        $handler2->expects($this->once())
+            ->method('isHandling')
+            ->will($this->returnValue(true))
+        ;
+        $handler2->expects($this->once())
+            ->method('handle')
+            ->will($this->returnValue(false))
+        ;
+        $logger->pushHandler($handler2);
+
+        $handler3 = $this->getMock('Monolog\Handler\HandlerInterface');
+        $handler3->expects($this->once())
+            ->method('isHandling')
+            ->will($this->returnValue(false))
+        ;
+        $handler3->expects($this->never())
+            ->method('handle')
+        ;
+        $logger->pushHandler($handler3);
+
+        $logger->debug('test');
+    }
+
+    /**
+     * @covers Monolog\Logger::addRecord
+     */
+    public function testBubblingWhenTheHandlerReturnsFalse()
+    {
+        $logger = new Logger(__METHOD__);
+
+        $handler1 = $this->getMock('Monolog\Handler\HandlerInterface');
+        $handler1->expects($this->any())
+            ->method('isHandling')
+            ->will($this->returnValue(true))
+        ;
+        $handler1->expects($this->once())
+            ->method('handle')
+            ->will($this->returnValue(false))
+        ;
+        $logger->pushHandler($handler1);
+
+        $handler2 = $this->getMock('Monolog\Handler\HandlerInterface');
+        $handler2->expects($this->any())
+            ->method('isHandling')
+            ->will($this->returnValue(true))
+        ;
+        $handler2->expects($this->once())
+            ->method('handle')
+            ->will($this->returnValue(false))
+        ;
+        $logger->pushHandler($handler2);
+
+        $logger->debug('test');
+    }
+
+    /**
+     * @covers Monolog\Logger::addRecord
+     */
+    public function testNotBubblingWhenTheHandlerReturnsTrue()
+    {
+        $logger = new Logger(__METHOD__);
+
+        $handler1 = $this->getMock('Monolog\Handler\HandlerInterface');
+        $handler1->expects($this->any())
+            ->method('isHandling')
+            ->will($this->returnValue(true))
+        ;
+        $handler1->expects($this->never())
+            ->method('handle')
+        ;
+        $logger->pushHandler($handler1);
+
+        $handler2 = $this->getMock('Monolog\Handler\HandlerInterface');
+        $handler2->expects($this->any())
+            ->method('isHandling')
+            ->will($this->returnValue(true))
+        ;
+        $handler2->expects($this->once())
+            ->method('handle')
+            ->will($this->returnValue(true))
+        ;
+        $logger->pushHandler($handler2);
+
+        $logger->debug('test');
+    }
+
+    /**
+     * @covers Monolog\Logger::isHandling
+     */
+    public function testIsHandling()
+    {
+        $logger = new Logger(__METHOD__);
+
+        $handler1 = $this->getMock('Monolog\Handler\HandlerInterface');
+        $handler1->expects($this->any())
+            ->method('isHandling')
+            ->will($this->returnValue(false))
+        ;
+
+        $logger->pushHandler($handler1);
+        $this->assertFalse($logger->isHandling(Logger::DEBUG));
+
+        $handler2 = $this->getMock('Monolog\Handler\HandlerInterface');
+        $handler2->expects($this->any())
+            ->method('isHandling')
+            ->will($this->returnValue(true))
+        ;
+
+        $logger->pushHandler($handler2);
+        $this->assertTrue($logger->isHandling(Logger::DEBUG));
+    }
+
+    /**
+     * @dataProvider logMethodProvider
+     * @covers Monolog\Logger::addDebug
+     * @covers Monolog\Logger::addInfo
+     * @covers Monolog\Logger::addNotice
+     * @covers Monolog\Logger::addWarning
+     * @covers Monolog\Logger::addError
+     * @covers Monolog\Logger::addCritical
+     * @covers Monolog\Logger::addAlert
+     * @covers Monolog\Logger::addEmergency
+     * @covers Monolog\Logger::debug
+     * @covers Monolog\Logger::info
+     * @covers Monolog\Logger::notice
+     * @covers Monolog\Logger::warn
+     * @covers Monolog\Logger::err
+     * @covers Monolog\Logger::crit
+     * @covers Monolog\Logger::alert
+     * @covers Monolog\Logger::emerg
+     */
+    public function testLogMethods($method, $expectedLevel)
+    {
+        $logger = new Logger('foo');
+        $handler = new TestHandler;
+        $logger->pushHandler($handler);
+        $logger->{$method}('test');
+        list($record) = $handler->getRecords();
+        $this->assertEquals($expectedLevel, $record['level']);
+    }
+
+    public function logMethodProvider()
+    {
+        return array(
+            // monolog methods
+            array('addDebug',     Logger::DEBUG),
+            array('addInfo',      Logger::INFO),
+            array('addNotice',    Logger::NOTICE),
+            array('addWarning',   Logger::WARNING),
+            array('addError',     Logger::ERROR),
+            array('addCritical',  Logger::CRITICAL),
+            array('addAlert',     Logger::ALERT),
+            array('addEmergency', Logger::EMERGENCY),
+
+            // ZF/Sf2 compat methods
+            array('debug',  Logger::DEBUG),
+            array('info',   Logger::INFO),
+            array('notice', Logger::NOTICE),
+            array('warn',   Logger::WARNING),
+            array('err',    Logger::ERROR),
+            array('crit',   Logger::CRITICAL),
+            array('alert',  Logger::ALERT),
+            array('emerg',  Logger::EMERGENCY),
+        );
+    }
+}

+ 29 - 0
vendor/monolog/monolog/tests/Monolog/Processor/GitProcessorTest.php

@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Processor;
+
+use Monolog\TestCase;
+
+class GitProcessorTest extends TestCase
+{
+    /**
+     * @covers Monolog\Processor\GitProcessor::__invoke
+     */
+    public function testProcessor()
+    {
+        $processor = new GitProcessor();
+        $record = $processor($this->getRecord());
+
+        $this->assertArrayHasKey('git', $record['extra']);
+        $this->assertTrue(!is_array($record['extra']['git']['branch']));
+    }
+}

+ 123 - 0
vendor/monolog/monolog/tests/Monolog/Processor/IntrospectionProcessorTest.php

@@ -0,0 +1,123 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Acme;
+
+class Tester
+{
+    public function test($handler, $record)
+    {
+        $handler->handle($record);
+    }
+}
+
+function tester($handler, $record)
+{
+    $handler->handle($record);
+}
+
+namespace Monolog\Processor;
+
+use Monolog\Logger;
+use Monolog\TestCase;
+use Monolog\Handler\TestHandler;
+
+class IntrospectionProcessorTest extends TestCase
+{
+    public function getHandler()
+    {
+        $processor = new IntrospectionProcessor();
+        $handler = new TestHandler();
+        $handler->pushProcessor($processor);
+
+        return $handler;
+    }
+
+    public function testProcessorFromClass()
+    {
+        $handler = $this->getHandler();
+        $tester = new \Acme\Tester;
+        $tester->test($handler, $this->getRecord());
+        list($record) = $handler->getRecords();
+        $this->assertEquals(__FILE__, $record['extra']['file']);
+        $this->assertEquals(18, $record['extra']['line']);
+        $this->assertEquals('Acme\Tester', $record['extra']['class']);
+        $this->assertEquals('test', $record['extra']['function']);
+    }
+
+    public function testProcessorFromFunc()
+    {
+        $handler = $this->getHandler();
+        \Acme\tester($handler, $this->getRecord());
+        list($record) = $handler->getRecords();
+        $this->assertEquals(__FILE__, $record['extra']['file']);
+        $this->assertEquals(24, $record['extra']['line']);
+        $this->assertEquals(null, $record['extra']['class']);
+        $this->assertEquals('Acme\tester', $record['extra']['function']);
+    }
+
+    public function testLevelTooLow()
+    {
+        $input = array(
+            'level' => Logger::DEBUG,
+            'extra' => array(),
+        );
+
+        $expected = $input;
+
+        $processor = new IntrospectionProcessor(Logger::CRITICAL);
+        $actual = $processor($input);
+
+        $this->assertEquals($expected, $actual);
+    }
+
+    public function testLevelEqual()
+    {
+        $input = array(
+            'level' => Logger::CRITICAL,
+            'extra' => array(),
+        );
+
+        $expected = $input;
+        $expected['extra'] = array(
+            'file' => null,
+            'line' => null,
+            'class' => 'ReflectionMethod',
+            'function' => 'invokeArgs',
+        );
+
+        $processor = new IntrospectionProcessor(Logger::CRITICAL);
+        $actual = $processor($input);
+
+        $this->assertEquals($expected, $actual);
+    }
+
+    public function testLevelHigher()
+    {
+        $input = array(
+            'level' => Logger::EMERGENCY,
+            'extra' => array(),
+        );
+
+        $expected = $input;
+        $expected['extra'] = array(
+            'file' => null,
+            'line' => null,
+            'class' => 'ReflectionMethod',
+            'function' => 'invokeArgs',
+        );
+
+        $processor = new IntrospectionProcessor(Logger::CRITICAL);
+        $actual = $processor($input);
+
+        $this->assertEquals($expected, $actual);
+    }
+}

Some files were not shown because too many files changed in this diff