import from la bonne adresse and first refactoring for ouidade.com

This commit is contained in:
Bachir Soussi Chiadmi
2017-06-19 11:25:19 +02:00
commit 344dae1543
2240 changed files with 288691 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
<?php
// autoload.php @generated by Composer
require_once __DIR__ . '/composer' . '/autoload_real.php';
return ComposerAutoloaderInit9c7eca5a86e870ee40cf566b71462ccd::getLoader();
+413
View File
@@ -0,0 +1,413 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* 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 Composer\Autoload;
/**
* ClassLoader implements a PSR-0 class loader
*
* See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
*/
class ClassLoader
{
// PSR-4
private $prefixLengthsPsr4 = array();
private $prefixDirsPsr4 = array();
private $fallbackDirsPsr4 = array();
// PSR-0
private $prefixesPsr0 = array();
private $fallbackDirsPsr0 = array();
private $useIncludePath = false;
private $classMap = array();
private $classMapAuthoritative = false;
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', $this->prefixesPsr0);
}
return array();
}
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array $classMap Class to filename map
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*/
public function add($prefix, $paths, $prepend = false)
{
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-0 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 base directories
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}
/**
* Unregisters this instance as an autoloader.
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return bool|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
return true;
}
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
if ('\\' == $class[0]) {
$class = substr($class, 1);
}
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative) {
return false;
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if ($file === null && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if ($file === null) {
// Remember that this class does not exist.
return $this->classMap[$class] = false;
}
return $file;
}
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
if (0 === strpos($class, $prefix)) {
foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
}
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*/
function includeFile($file)
{
include $file;
}
+21
View File
@@ -0,0 +1,21 @@
Copyright (c) 2015 Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+786
View File
@@ -0,0 +1,786 @@
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'CSSmin' => $vendorDir . '/mrclay/minify/min/lib/CSSmin.php',
'DebugBar\\Bridge\\CacheCacheCollector' => $vendorDir . '/maximebf/debugbar/src/DebugBar/Bridge/CacheCacheCollector.php',
'DebugBar\\Bridge\\DoctrineCollector' => $vendorDir . '/maximebf/debugbar/src/DebugBar/Bridge/DoctrineCollector.php',
'DebugBar\\Bridge\\MonologCollector' => $vendorDir . '/maximebf/debugbar/src/DebugBar/Bridge/MonologCollector.php',
'DebugBar\\Bridge\\Propel2Collector' => $vendorDir . '/maximebf/debugbar/src/DebugBar/Bridge/Propel2Collector.php',
'DebugBar\\Bridge\\PropelCollector' => $vendorDir . '/maximebf/debugbar/src/DebugBar/Bridge/PropelCollector.php',
'DebugBar\\Bridge\\SlimCollector' => $vendorDir . '/maximebf/debugbar/src/DebugBar/Bridge/SlimCollector.php',
'DebugBar\\Bridge\\SwiftMailer\\SwiftLogCollector' => $vendorDir . '/maximebf/debugbar/src/DebugBar/Bridge/SwiftMailer/SwiftLogCollector.php',
'DebugBar\\Bridge\\SwiftMailer\\SwiftMailCollector' => $vendorDir . '/maximebf/debugbar/src/DebugBar/Bridge/SwiftMailer/SwiftMailCollector.php',
'DebugBar\\Bridge\\Twig\\TraceableTwigEnvironment' => $vendorDir . '/maximebf/debugbar/src/DebugBar/Bridge/Twig/TraceableTwigEnvironment.php',
'DebugBar\\Bridge\\Twig\\TraceableTwigTemplate' => $vendorDir . '/maximebf/debugbar/src/DebugBar/Bridge/Twig/TraceableTwigTemplate.php',
'DebugBar\\Bridge\\Twig\\TwigCollector' => $vendorDir . '/maximebf/debugbar/src/DebugBar/Bridge/Twig/TwigCollector.php',
'DebugBar\\DataCollector\\AggregatedCollector' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DataCollector/AggregatedCollector.php',
'DebugBar\\DataCollector\\AssetProvider' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DataCollector/AssetProvider.php',
'DebugBar\\DataCollector\\ConfigCollector' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DataCollector/ConfigCollector.php',
'DebugBar\\DataCollector\\DataCollector' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DataCollector/DataCollector.php',
'DebugBar\\DataCollector\\DataCollectorInterface' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DataCollector/DataCollectorInterface.php',
'DebugBar\\DataCollector\\ExceptionsCollector' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DataCollector/ExceptionsCollector.php',
'DebugBar\\DataCollector\\LocalizationCollector' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DataCollector/LocalizationCollector.php',
'DebugBar\\DataCollector\\MemoryCollector' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DataCollector/MemoryCollector.php',
'DebugBar\\DataCollector\\MessagesAggregateInterface' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DataCollector/MessagesAggregateInterface.php',
'DebugBar\\DataCollector\\MessagesCollector' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DataCollector/MessagesCollector.php',
'DebugBar\\DataCollector\\PDO\\PDOCollector' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DataCollector/PDO/PDOCollector.php',
'DebugBar\\DataCollector\\PDO\\TraceablePDO' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DataCollector/PDO/TraceablePDO.php',
'DebugBar\\DataCollector\\PDO\\TraceablePDOStatement' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DataCollector/PDO/TraceablePDOStatement.php',
'DebugBar\\DataCollector\\PDO\\TracedStatement' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DataCollector/PDO/TracedStatement.php',
'DebugBar\\DataCollector\\PhpInfoCollector' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DataCollector/PhpInfoCollector.php',
'DebugBar\\DataCollector\\Renderable' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DataCollector/Renderable.php',
'DebugBar\\DataCollector\\RequestDataCollector' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DataCollector/RequestDataCollector.php',
'DebugBar\\DataCollector\\TimeDataCollector' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DataCollector/TimeDataCollector.php',
'DebugBar\\DataFormatter\\DataFormatter' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DataFormatter/DataFormatter.php',
'DebugBar\\DataFormatter\\DataFormatterInterface' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DataFormatter/DataFormatterInterface.php',
'DebugBar\\DebugBar' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DebugBar.php',
'DebugBar\\DebugBarException' => $vendorDir . '/maximebf/debugbar/src/DebugBar/DebugBarException.php',
'DebugBar\\HttpDriverInterface' => $vendorDir . '/maximebf/debugbar/src/DebugBar/HttpDriverInterface.php',
'DebugBar\\JavascriptRenderer' => $vendorDir . '/maximebf/debugbar/src/DebugBar/JavascriptRenderer.php',
'DebugBar\\OpenHandler' => $vendorDir . '/maximebf/debugbar/src/DebugBar/OpenHandler.php',
'DebugBar\\PhpHttpDriver' => $vendorDir . '/maximebf/debugbar/src/DebugBar/PhpHttpDriver.php',
'DebugBar\\RequestIdGenerator' => $vendorDir . '/maximebf/debugbar/src/DebugBar/RequestIdGenerator.php',
'DebugBar\\RequestIdGeneratorInterface' => $vendorDir . '/maximebf/debugbar/src/DebugBar/RequestIdGeneratorInterface.php',
'DebugBar\\StandardDebugBar' => $vendorDir . '/maximebf/debugbar/src/DebugBar/StandardDebugBar.php',
'DebugBar\\Storage\\FileStorage' => $vendorDir . '/maximebf/debugbar/src/DebugBar/Storage/FileStorage.php',
'DebugBar\\Storage\\MemcachedStorage' => $vendorDir . '/maximebf/debugbar/src/DebugBar/Storage/MemcachedStorage.php',
'DebugBar\\Storage\\PdoStorage' => $vendorDir . '/maximebf/debugbar/src/DebugBar/Storage/PdoStorage.php',
'DebugBar\\Storage\\RedisStorage' => $vendorDir . '/maximebf/debugbar/src/DebugBar/Storage/RedisStorage.php',
'DebugBar\\Storage\\StorageInterface' => $vendorDir . '/maximebf/debugbar/src/DebugBar/Storage/StorageInterface.php',
'Doctrine\\Common\\Cache\\ApcCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php',
'Doctrine\\Common\\Cache\\ArrayCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php',
'Doctrine\\Common\\Cache\\Cache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php',
'Doctrine\\Common\\Cache\\CacheProvider' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php',
'Doctrine\\Common\\Cache\\ChainCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php',
'Doctrine\\Common\\Cache\\ClearableCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php',
'Doctrine\\Common\\Cache\\CouchbaseCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php',
'Doctrine\\Common\\Cache\\FileCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php',
'Doctrine\\Common\\Cache\\FilesystemCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php',
'Doctrine\\Common\\Cache\\FlushableCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php',
'Doctrine\\Common\\Cache\\MemcacheCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php',
'Doctrine\\Common\\Cache\\MemcachedCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php',
'Doctrine\\Common\\Cache\\MongoDBCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php',
'Doctrine\\Common\\Cache\\MultiGetCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/MultiGetCache.php',
'Doctrine\\Common\\Cache\\PhpFileCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php',
'Doctrine\\Common\\Cache\\PredisCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php',
'Doctrine\\Common\\Cache\\RedisCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php',
'Doctrine\\Common\\Cache\\RiakCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/RiakCache.php',
'Doctrine\\Common\\Cache\\SQLite3Cache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php',
'Doctrine\\Common\\Cache\\Version' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/Version.php',
'Doctrine\\Common\\Cache\\VoidCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/VoidCache.php',
'Doctrine\\Common\\Cache\\WinCacheCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php',
'Doctrine\\Common\\Cache\\XcacheCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php',
'Doctrine\\Common\\Cache\\ZendDataCache' => $vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php',
'DooDigestAuth' => $vendorDir . '/mrclay/minify/min/lib/DooDigestAuth.php',
'FirePHP' => $vendorDir . '/mrclay/minify/min/lib/FirePHP.php',
'Grav\\Common\\Assets' => $baseDir . '/system/src/Grav/Common/Assets.php',
'Grav\\Common\\Backup\\ZipBackup' => $baseDir . '/system/src/Grav/Common/Backup/ZipBackup.php',
'Grav\\Common\\Browser' => $baseDir . '/system/src/Grav/Common/Browser.php',
'Grav\\Common\\Cache' => $baseDir . '/system/src/Grav/Common/Cache.php',
'Grav\\Common\\Composer' => $baseDir . '/system/src/Grav/Common/Composer.php',
'Grav\\Common\\Config\\Blueprints' => $baseDir . '/system/src/Grav/Common/Config/Blueprints.php',
'Grav\\Common\\Config\\Config' => $baseDir . '/system/src/Grav/Common/Config/Config.php',
'Grav\\Common\\Config\\ConfigFinder' => $baseDir . '/system/src/Grav/Common/Config/ConfigFinder.php',
'Grav\\Common\\Config\\Languages' => $baseDir . '/system/src/Grav/Common/Config/Languages.php',
'Grav\\Common\\Data\\Blueprint' => $baseDir . '/system/src/Grav/Common/Data/Blueprint.php',
'Grav\\Common\\Data\\Blueprints' => $baseDir . '/system/src/Grav/Common/Data/Blueprints.php',
'Grav\\Common\\Data\\Data' => $baseDir . '/system/src/Grav/Common/Data/Data.php',
'Grav\\Common\\Data\\DataInterface' => $baseDir . '/system/src/Grav/Common/Data/DataInterface.php',
'Grav\\Common\\Data\\DataMutatorTrait' => $baseDir . '/system/src/Grav/Common/Data/DataMutatorTrait.php',
'Grav\\Common\\Data\\Validation' => $baseDir . '/system/src/Grav/Common/Data/Validation.php',
'Grav\\Common\\Debugger' => $baseDir . '/system/src/Grav/Common/Debugger.php',
'Grav\\Common\\Errors\\Errors' => $baseDir . '/system/src/Grav/Common/Errors/Errors.php',
'Grav\\Common\\Errors\\SimplePageHandler' => $baseDir . '/system/src/Grav/Common/Errors/SimplePageHandler.php',
'Grav\\Common\\File\\CompiledFile' => $baseDir . '/system/src/Grav/Common/File/CompiledFile.php',
'Grav\\Common\\File\\CompiledMarkdownFile' => $baseDir . '/system/src/Grav/Common/File/CompiledMarkdownFile.php',
'Grav\\Common\\File\\CompiledYamlFile' => $baseDir . '/system/src/Grav/Common/File/CompiledYamlFile.php',
'Grav\\Common\\Filesystem\\Folder' => $baseDir . '/system/src/Grav/Common/Filesystem/Folder.php',
'Grav\\Common\\Filesystem\\RecursiveFolderFilterIterator' => $baseDir . '/system/src/Grav/Common/Filesystem/RecursiveFolderFilterIterator.php',
'Grav\\Common\\GPM\\AbstractCollection' => $baseDir . '/system/src/Grav/Common/GPM/AbstractCollection.php',
'Grav\\Common\\GPM\\Common\\AbstractPackageCollection' => $baseDir . '/system/src/Grav/Common/GPM/Common/AbstractPackageCollection.php',
'Grav\\Common\\GPM\\Common\\CachedCollection' => $baseDir . '/system/src/Grav/Common/GPM/Common/CachedCollection.php',
'Grav\\Common\\GPM\\Common\\Package' => $baseDir . '/system/src/Grav/Common/GPM/Common/Package.php',
'Grav\\Common\\GPM\\GPM' => $baseDir . '/system/src/Grav/Common/GPM/GPM.php',
'Grav\\Common\\GPM\\Installer' => $baseDir . '/system/src/Grav/Common/GPM/Installer.php',
'Grav\\Common\\GPM\\Local\\AbstractPackageCollection' => $baseDir . '/system/src/Grav/Common/GPM/Local/AbstractPackageCollection.php',
'Grav\\Common\\GPM\\Local\\Package' => $baseDir . '/system/src/Grav/Common/GPM/Local/Package.php',
'Grav\\Common\\GPM\\Local\\Packages' => $baseDir . '/system/src/Grav/Common/GPM/Local/Packages.php',
'Grav\\Common\\GPM\\Local\\Plugins' => $baseDir . '/system/src/Grav/Common/GPM/Local/Plugins.php',
'Grav\\Common\\GPM\\Local\\Themes' => $baseDir . '/system/src/Grav/Common/GPM/Local/Themes.php',
'Grav\\Common\\GPM\\Package' => $baseDir . '/system/src/Grav/Common/GPM/PackageInterface.php',
'Grav\\Common\\GPM\\Remote\\AbstractPackageCollection' => $baseDir . '/system/src/Grav/Common/GPM/Remote/AbstractPackageCollection.php',
'Grav\\Common\\GPM\\Remote\\Grav' => $baseDir . '/system/src/Grav/Common/GPM/Remote/Grav.php',
'Grav\\Common\\GPM\\Remote\\Package' => $baseDir . '/system/src/Grav/Common/GPM/Remote/Package.php',
'Grav\\Common\\GPM\\Remote\\Packages' => $baseDir . '/system/src/Grav/Common/GPM/Remote/Packages.php',
'Grav\\Common\\GPM\\Remote\\Plugins' => $baseDir . '/system/src/Grav/Common/GPM/Remote/Plugins.php',
'Grav\\Common\\GPM\\Remote\\Themes' => $baseDir . '/system/src/Grav/Common/GPM/Remote/Themes.php',
'Grav\\Common\\GPM\\Response' => $baseDir . '/system/src/Grav/Common/GPM/Response.php',
'Grav\\Common\\GPM\\Upgrader' => $baseDir . '/system/src/Grav/Common/GPM/Upgrader.php',
'Grav\\Common\\Getters' => $baseDir . '/system/src/Grav/Common/Getters.php',
'Grav\\Common\\Grav' => $baseDir . '/system/src/Grav/Common/Grav.php',
'Grav\\Common\\GravTrait' => $baseDir . '/system/src/Grav/Common/GravTrait.php',
'Grav\\Common\\Helpers\\Truncator' => $baseDir . '/system/src/Grav/Common/Helpers/Truncator.php',
'Grav\\Common\\Inflector' => $baseDir . '/system/src/Grav/Common/Inflector.php',
'Grav\\Common\\Iterator' => $baseDir . '/system/src/Grav/Common/Iterator.php',
'Grav\\Common\\Language\\Language' => $baseDir . '/system/src/Grav/Common/Language/Language.php',
'Grav\\Common\\Language\\LanguageCodes' => $baseDir . '/system/src/Grav/Common/Language/LanguageCodes.php',
'Grav\\Common\\Markdown\\Parsedown' => $baseDir . '/system/src/Grav/Common/Markdown/Parsedown.php',
'Grav\\Common\\Markdown\\ParsedownExtra' => $baseDir . '/system/src/Grav/Common/Markdown/ParsedownExtra.php',
'Grav\\Common\\Markdown\\ParsedownGravTrait' => $baseDir . '/system/src/Grav/Common/Markdown/ParsedownGravTrait.php',
'Grav\\Common\\Page\\Collection' => $baseDir . '/system/src/Grav/Common/Page/Collection.php',
'Grav\\Common\\Page\\Header' => $baseDir . '/system/src/Grav/Common/Page/Header.php',
'Grav\\Common\\Page\\Media' => $baseDir . '/system/src/Grav/Common/Page/Media.php',
'Grav\\Common\\Page\\Medium\\AudioMedium' => $baseDir . '/system/src/Grav/Common/Page/Medium/AudioMedium.php',
'Grav\\Common\\Page\\Medium\\ImageFile' => $baseDir . '/system/src/Grav/Common/Page/Medium/ImageFile.php',
'Grav\\Common\\Page\\Medium\\ImageMedium' => $baseDir . '/system/src/Grav/Common/Page/Medium/ImageMedium.php',
'Grav\\Common\\Page\\Medium\\Link' => $baseDir . '/system/src/Grav/Common/Page/Medium/Link.php',
'Grav\\Common\\Page\\Medium\\Medium' => $baseDir . '/system/src/Grav/Common/Page/Medium/Medium.php',
'Grav\\Common\\Page\\Medium\\MediumFactory' => $baseDir . '/system/src/Grav/Common/Page/Medium/MediumFactory.php',
'Grav\\Common\\Page\\Medium\\ParsedownHtmlTrait' => $baseDir . '/system/src/Grav/Common/Page/Medium/ParsedownHtmlTrait.php',
'Grav\\Common\\Page\\Medium\\RenderableInterface' => $baseDir . '/system/src/Grav/Common/Page/Medium/RenderableInterface.php',
'Grav\\Common\\Page\\Medium\\StaticImageMedium' => $baseDir . '/system/src/Grav/Common/Page/Medium/StaticImageMedium.php',
'Grav\\Common\\Page\\Medium\\StaticResizeTrait' => $baseDir . '/system/src/Grav/Common/Page/Medium/StaticResizeTrait.php',
'Grav\\Common\\Page\\Medium\\ThumbnailImageMedium' => $baseDir . '/system/src/Grav/Common/Page/Medium/ThumbnailImageMedium.php',
'Grav\\Common\\Page\\Medium\\VideoMedium' => $baseDir . '/system/src/Grav/Common/Page/Medium/VideoMedium.php',
'Grav\\Common\\Page\\Page' => $baseDir . '/system/src/Grav/Common/Page/Page.php',
'Grav\\Common\\Page\\Pages' => $baseDir . '/system/src/Grav/Common/Page/Pages.php',
'Grav\\Common\\Page\\Types' => $baseDir . '/system/src/Grav/Common/Page/Types.php',
'Grav\\Common\\Plugin' => $baseDir . '/system/src/Grav/Common/Plugin.php',
'Grav\\Common\\Plugins' => $baseDir . '/system/src/Grav/Common/Plugins.php',
'Grav\\Common\\Service\\ConfigServiceProvider' => $baseDir . '/system/src/Grav/Common/Service/ConfigServiceProvider.php',
'Grav\\Common\\Service\\ErrorServiceProvider' => $baseDir . '/system/src/Grav/Common/Service/ErrorServiceProvider.php',
'Grav\\Common\\Service\\LoggerServiceProvider' => $baseDir . '/system/src/Grav/Common/Service/LoggerServiceProvider.php',
'Grav\\Common\\Service\\StreamsServiceProvider' => $baseDir . '/system/src/Grav/Common/Service/StreamsServiceProvider.php',
'Grav\\Common\\Session' => $baseDir . '/system/src/Grav/Common/Session.php',
'Grav\\Common\\Taxonomy' => $baseDir . '/system/src/Grav/Common/Taxonomy.php',
'Grav\\Common\\Theme' => $baseDir . '/system/src/Grav/Common/Theme.php',
'Grav\\Common\\Themes' => $baseDir . '/system/src/Grav/Common/Themes.php',
'Grav\\Common\\Twig\\Twig' => $baseDir . '/system/src/Grav/Common/Twig/Twig.php',
'Grav\\Common\\Twig\\TwigEnvironment' => $baseDir . '/system/src/Grav/Common/Twig/TwigEnvironment.php',
'Grav\\Common\\Twig\\TwigExtension' => $baseDir . '/system/src/Grav/Common/Twig/TwigExtension.php',
'Grav\\Common\\Twig\\WriteCacheFileTrait' => $baseDir . '/system/src/Grav/Common/Twig/WriteCacheFileTrait.php',
'Grav\\Common\\Uri' => $baseDir . '/system/src/Grav/Common/Uri.php',
'Grav\\Common\\User\\Authentication' => $baseDir . '/system/src/Grav/Common/User/Authentication.php',
'Grav\\Common\\User\\User' => $baseDir . '/system/src/Grav/Common/User/User.php',
'Grav\\Common\\Utils' => $baseDir . '/system/src/Grav/Common/Utils.php',
'Grav\\Console\\Cli\\BackupCommand' => $baseDir . '/system/src/Grav/Console/Cli/BackupCommand.php',
'Grav\\Console\\Cli\\CleanCommand' => $baseDir . '/system/src/Grav/Console/Cli/CleanCommand.php',
'Grav\\Console\\Cli\\ClearCacheCommand' => $baseDir . '/system/src/Grav/Console/Cli/ClearCacheCommand.php',
'Grav\\Console\\Cli\\ComposerCommand' => $baseDir . '/system/src/Grav/Console/Cli/ComposerCommand.php',
'Grav\\Console\\Cli\\InstallCommand' => $baseDir . '/system/src/Grav/Console/Cli/InstallCommand.php',
'Grav\\Console\\Cli\\NewProjectCommand' => $baseDir . '/system/src/Grav/Console/Cli/NewProjectCommand.php',
'Grav\\Console\\Cli\\NewUserCommand' => $baseDir . '/system/src/Grav/Console/Cli/NewUserCommand.php',
'Grav\\Console\\Cli\\SandboxCommand' => $baseDir . '/system/src/Grav/Console/Cli/SandboxCommand.php',
'Grav\\Console\\ConsoleTrait' => $baseDir . '/system/src/Grav/Console/ConsoleTrait.php',
'Grav\\Console\\Gpm\\IndexCommand' => $baseDir . '/system/src/Grav/Console/Gpm/IndexCommand.php',
'Grav\\Console\\Gpm\\InfoCommand' => $baseDir . '/system/src/Grav/Console/Gpm/InfoCommand.php',
'Grav\\Console\\Gpm\\InstallCommand' => $baseDir . '/system/src/Grav/Console/Gpm/InstallCommand.php',
'Grav\\Console\\Gpm\\SelfupgradeCommand' => $baseDir . '/system/src/Grav/Console/Gpm/SelfupgradeCommand.php',
'Grav\\Console\\Gpm\\UninstallCommand' => $baseDir . '/system/src/Grav/Console/Gpm/UninstallCommand.php',
'Grav\\Console\\Gpm\\UpdateCommand' => $baseDir . '/system/src/Grav/Console/Gpm/UpdateCommand.php',
'Grav\\Console\\Gpm\\VersionCommand' => $baseDir . '/system/src/Grav/Console/Gpm/VersionCommand.php',
'Gregwar\\Cache\\Cache' => $vendorDir . '/gregwar/cache/Gregwar/Cache/Cache.php',
'Gregwar\\Cache\\GarbageCollect' => $vendorDir . '/gregwar/cache/Gregwar/Cache/GarbageCollect.php',
'Gregwar\\Image\\Adapter\\Adapter' => $vendorDir . '/gregwar/image/Gregwar/Image/Adapter/Adapter.php',
'Gregwar\\Image\\Adapter\\AdapterInterface' => $vendorDir . '/gregwar/image/Gregwar/Image/Adapter/AdapterInterface.php',
'Gregwar\\Image\\Adapter\\Common' => $vendorDir . '/gregwar/image/Gregwar/Image/Adapter/Common.php',
'Gregwar\\Image\\Adapter\\GD' => $vendorDir . '/gregwar/image/Gregwar/Image/Adapter/GD.php',
'Gregwar\\Image\\Adapter\\Imagick' => $vendorDir . '/gregwar/image/Gregwar/Image/Adapter/Imagick.php',
'Gregwar\\Image\\Exceptions\\GenerationError' => $vendorDir . '/gregwar/image/Gregwar/Image/Exceptions/GenerationError.php',
'Gregwar\\Image\\GarbageCollect' => $vendorDir . '/gregwar/image/Gregwar/Image/GarbageCollect.php',
'Gregwar\\Image\\Image' => $vendorDir . '/gregwar/image/Gregwar/Image/Image.php',
'Gregwar\\Image\\ImageColor' => $vendorDir . '/gregwar/image/Gregwar/Image/ImageColor.php',
'Gregwar\\Image\\Source\\Create' => $vendorDir . '/gregwar/image/Gregwar/Image/Source/Create.php',
'Gregwar\\Image\\Source\\Data' => $vendorDir . '/gregwar/image/Gregwar/Image/Source/Data.php',
'Gregwar\\Image\\Source\\File' => $vendorDir . '/gregwar/image/Gregwar/Image/Source/File.php',
'Gregwar\\Image\\Source\\Resource' => $vendorDir . '/gregwar/image/Gregwar/Image/Source/Resource.php',
'Gregwar\\Image\\Source\\Source' => $vendorDir . '/gregwar/image/Gregwar/Image/Source/Source.php',
'HTTP_ConditionalGet' => $vendorDir . '/mrclay/minify/min/lib/HTTP/ConditionalGet.php',
'HTTP_Encoder' => $vendorDir . '/mrclay/minify/min/lib/HTTP/Encoder.php',
'JSCompilerContext' => $vendorDir . '/mrclay/minify/min/lib/JSMinPlus.php',
'JSMin' => $vendorDir . '/mrclay/minify/min/lib/JSMin.php',
'JSMinPlus' => $vendorDir . '/mrclay/minify/min/lib/JSMinPlus.php',
'JSMin_UnterminatedCommentException' => $vendorDir . '/mrclay/minify/min/lib/JSMin.php',
'JSMin_UnterminatedRegExpException' => $vendorDir . '/mrclay/minify/min/lib/JSMin.php',
'JSMin_UnterminatedStringException' => $vendorDir . '/mrclay/minify/min/lib/JSMin.php',
'JSNode' => $vendorDir . '/mrclay/minify/min/lib/JSMinPlus.php',
'JSParser' => $vendorDir . '/mrclay/minify/min/lib/JSMinPlus.php',
'JSToken' => $vendorDir . '/mrclay/minify/min/lib/JSMinPlus.php',
'JSTokenizer' => $vendorDir . '/mrclay/minify/min/lib/JSMinPlus.php',
'Minify' => $vendorDir . '/mrclay/minify/min/lib/Minify.php',
'Minify_Build' => $vendorDir . '/mrclay/minify/min/lib/Minify/Build.php',
'Minify_CSS' => $vendorDir . '/mrclay/minify/min/lib/Minify/CSS.php',
'Minify_CSS_Compressor' => $vendorDir . '/mrclay/minify/min/lib/Minify/CSS/Compressor.php',
'Minify_CSS_UriRewriter' => $vendorDir . '/mrclay/minify/min/lib/Minify/CSS/UriRewriter.php',
'Minify_CSSmin' => $vendorDir . '/mrclay/minify/min/lib/Minify/CSSmin.php',
'Minify_Cache_APC' => $vendorDir . '/mrclay/minify/min/lib/Minify/Cache/APC.php',
'Minify_Cache_File' => $vendorDir . '/mrclay/minify/min/lib/Minify/Cache/File.php',
'Minify_Cache_Memcache' => $vendorDir . '/mrclay/minify/min/lib/Minify/Cache/Memcache.php',
'Minify_Cache_WinCache' => $vendorDir . '/mrclay/minify/min/lib/Minify/Cache/WinCache.php',
'Minify_Cache_XCache' => $vendorDir . '/mrclay/minify/min/lib/Minify/Cache/XCache.php',
'Minify_Cache_ZendPlatform' => $vendorDir . '/mrclay/minify/min/lib/Minify/Cache/ZendPlatform.php',
'Minify_ClosureCompiler' => $vendorDir . '/mrclay/minify/min/lib/Minify/ClosureCompiler.php',
'Minify_ClosureCompiler_Exception' => $vendorDir . '/mrclay/minify/min/lib/Minify/ClosureCompiler.php',
'Minify_CommentPreserver' => $vendorDir . '/mrclay/minify/min/lib/Minify/CommentPreserver.php',
'Minify_Controller_Base' => $vendorDir . '/mrclay/minify/min/lib/Minify/Controller/Base.php',
'Minify_Controller_Files' => $vendorDir . '/mrclay/minify/min/lib/Minify/Controller/Files.php',
'Minify_Controller_Groups' => $vendorDir . '/mrclay/minify/min/lib/Minify/Controller/Groups.php',
'Minify_Controller_MinApp' => $vendorDir . '/mrclay/minify/min/lib/Minify/Controller/MinApp.php',
'Minify_Controller_Page' => $vendorDir . '/mrclay/minify/min/lib/Minify/Controller/Page.php',
'Minify_Controller_Version1' => $vendorDir . '/mrclay/minify/min/lib/Minify/Controller/Version1.php',
'Minify_DebugDetector' => $vendorDir . '/mrclay/minify/min/lib/Minify/DebugDetector.php',
'Minify_HTML' => $vendorDir . '/mrclay/minify/min/lib/Minify/HTML.php',
'Minify_HTML_Helper' => $vendorDir . '/mrclay/minify/min/lib/Minify/HTML/Helper.php',
'Minify_ImportProcessor' => $vendorDir . '/mrclay/minify/min/lib/Minify/ImportProcessor.php',
'Minify_JS_ClosureCompiler' => $vendorDir . '/mrclay/minify/min/lib/Minify/JS/ClosureCompiler.php',
'Minify_JS_ClosureCompiler_Exception' => $vendorDir . '/mrclay/minify/min/lib/Minify/JS/ClosureCompiler.php',
'Minify_Lines' => $vendorDir . '/mrclay/minify/min/lib/Minify/Lines.php',
'Minify_Loader' => $vendorDir . '/mrclay/minify/min/lib/Minify/Loader.php',
'Minify_Logger' => $vendorDir . '/mrclay/minify/min/lib/Minify/Logger.php',
'Minify_Packer' => $vendorDir . '/mrclay/minify/min/lib/Minify/Packer.php',
'Minify_Source' => $vendorDir . '/mrclay/minify/min/lib/Minify/Source.php',
'Minify_YUICompressor' => $vendorDir . '/mrclay/minify/min/lib/Minify/YUICompressor.php',
'Minify_YUI_CssCompressor' => $vendorDir . '/mrclay/minify/min/lib/Minify/YUI/CssCompressor.php',
'Monolog\\ErrorHandler' => $vendorDir . '/monolog/monolog/src/Monolog/ErrorHandler.php',
'Monolog\\Formatter\\ChromePHPFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php',
'Monolog\\Formatter\\ElasticaFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/ElasticaFormatter.php',
'Monolog\\Formatter\\FlowdockFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/FlowdockFormatter.php',
'Monolog\\Formatter\\FormatterInterface' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php',
'Monolog\\Formatter\\GelfMessageFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php',
'Monolog\\Formatter\\HtmlFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/HtmlFormatter.php',
'Monolog\\Formatter\\JsonFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php',
'Monolog\\Formatter\\LineFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/LineFormatter.php',
'Monolog\\Formatter\\LogglyFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/LogglyFormatter.php',
'Monolog\\Formatter\\LogstashFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/LogstashFormatter.php',
'Monolog\\Formatter\\MongoDBFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/MongoDBFormatter.php',
'Monolog\\Formatter\\NormalizerFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php',
'Monolog\\Formatter\\ScalarFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/ScalarFormatter.php',
'Monolog\\Formatter\\WildfireFormatter' => $vendorDir . '/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php',
'Monolog\\Handler\\AbstractHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/AbstractHandler.php',
'Monolog\\Handler\\AbstractProcessingHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php',
'Monolog\\Handler\\AbstractSyslogHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php',
'Monolog\\Handler\\AmqpHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/AmqpHandler.php',
'Monolog\\Handler\\BrowserConsoleHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/BrowserConsoleHandler.php',
'Monolog\\Handler\\BufferHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/BufferHandler.php',
'Monolog\\Handler\\ChromePHPHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php',
'Monolog\\Handler\\CouchDBHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php',
'Monolog\\Handler\\CubeHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/CubeHandler.php',
'Monolog\\Handler\\Curl\\Util' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/Curl/Util.php',
'Monolog\\Handler\\DoctrineCouchDBHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/DoctrineCouchDBHandler.php',
'Monolog\\Handler\\DynamoDbHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php',
'Monolog\\Handler\\ElasticSearchHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/ElasticSearchHandler.php',
'Monolog\\Handler\\ErrorLogHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php',
'Monolog\\Handler\\FilterHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/FilterHandler.php',
'Monolog\\Handler\\FingersCrossedHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php',
'Monolog\\Handler\\FingersCrossed\\ActivationStrategyInterface' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php',
'Monolog\\Handler\\FingersCrossed\\ChannelLevelActivationStrategy' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php',
'Monolog\\Handler\\FingersCrossed\\ErrorLevelActivationStrategy' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php',
'Monolog\\Handler\\FirePHPHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php',
'Monolog\\Handler\\FleepHookHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/FleepHookHandler.php',
'Monolog\\Handler\\FlowdockHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php',
'Monolog\\Handler\\GelfHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/GelfHandler.php',
'Monolog\\Handler\\GroupHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/GroupHandler.php',
'Monolog\\Handler\\HandlerInterface' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/HandlerInterface.php',
'Monolog\\Handler\\HipChatHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/HipChatHandler.php',
'Monolog\\Handler\\IFTTTHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/IFTTTHandler.php',
'Monolog\\Handler\\LogEntriesHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php',
'Monolog\\Handler\\LogglyHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/LogglyHandler.php',
'Monolog\\Handler\\MailHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/MailHandler.php',
'Monolog\\Handler\\MandrillHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/MandrillHandler.php',
'Monolog\\Handler\\MissingExtensionException' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/MissingExtensionException.php',
'Monolog\\Handler\\MongoDBHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php',
'Monolog\\Handler\\NativeMailerHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php',
'Monolog\\Handler\\NewRelicHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/NewRelicHandler.php',
'Monolog\\Handler\\NullHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/NullHandler.php',
'Monolog\\Handler\\PHPConsoleHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/PHPConsoleHandler.php',
'Monolog\\Handler\\PsrHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/PsrHandler.php',
'Monolog\\Handler\\PushoverHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/PushoverHandler.php',
'Monolog\\Handler\\RavenHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/RavenHandler.php',
'Monolog\\Handler\\RedisHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/RedisHandler.php',
'Monolog\\Handler\\RollbarHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/RollbarHandler.php',
'Monolog\\Handler\\RotatingFileHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php',
'Monolog\\Handler\\SamplingHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/SamplingHandler.php',
'Monolog\\Handler\\SlackHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/SlackHandler.php',
'Monolog\\Handler\\SocketHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/SocketHandler.php',
'Monolog\\Handler\\StreamHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/StreamHandler.php',
'Monolog\\Handler\\SwiftMailerHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.php',
'Monolog\\Handler\\SyslogHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/SyslogHandler.php',
'Monolog\\Handler\\SyslogUdpHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php',
'Monolog\\Handler\\SyslogUdp\\UdpSocket' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.php',
'Monolog\\Handler\\TestHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/TestHandler.php',
'Monolog\\Handler\\WhatFailureGroupHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/WhatFailureGroupHandler.php',
'Monolog\\Handler\\ZendMonitorHandler' => $vendorDir . '/monolog/monolog/src/Monolog/Handler/ZendMonitorHandler.php',
'Monolog\\Logger' => $vendorDir . '/monolog/monolog/src/Monolog/Logger.php',
'Monolog\\Processor\\GitProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/GitProcessor.php',
'Monolog\\Processor\\IntrospectionProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php',
'Monolog\\Processor\\MemoryPeakUsageProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php',
'Monolog\\Processor\\MemoryProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php',
'Monolog\\Processor\\MemoryUsageProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php',
'Monolog\\Processor\\ProcessIdProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php',
'Monolog\\Processor\\PsrLogMessageProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php',
'Monolog\\Processor\\TagProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/TagProcessor.php',
'Monolog\\Processor\\UidProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/UidProcessor.php',
'Monolog\\Processor\\WebProcessor' => $vendorDir . '/monolog/monolog/src/Monolog/Processor/WebProcessor.php',
'Monolog\\Registry' => $vendorDir . '/monolog/monolog/src/Monolog/Registry.php',
'MrClay\\Cli' => $vendorDir . '/mrclay/minify/min/lib/MrClay/Cli.php',
'MrClay\\Cli\\Arg' => $vendorDir . '/mrclay/minify/min/lib/MrClay/Cli/Arg.php',
'Parsedown' => $vendorDir . '/erusev/parsedown/Parsedown.php',
'ParsedownExtra' => $vendorDir . '/erusev/parsedown-extra/ParsedownExtra.php',
'Pimple\\Container' => $vendorDir . '/pimple/pimple/src/Pimple/Container.php',
'Pimple\\ServiceProviderInterface' => $vendorDir . '/pimple/pimple/src/Pimple/ServiceProviderInterface.php',
'Pimple\\Tests\\Fixtures\\Invokable' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Fixtures/Invokable.php',
'Pimple\\Tests\\Fixtures\\NonInvokable' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Fixtures/NonInvokable.php',
'Pimple\\Tests\\Fixtures\\PimpleServiceProvider' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Fixtures/PimpleServiceProvider.php',
'Pimple\\Tests\\Fixtures\\Service' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Fixtures/Service.php',
'Pimple\\Tests\\PimpleServiceProviderInterfaceTest' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/PimpleServiceProviderInterfaceTest.php',
'Pimple\\Tests\\PimpleTest' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/PimpleTest.php',
'Psr\\Log\\AbstractLogger' => $vendorDir . '/psr/log/Psr/Log/AbstractLogger.php',
'Psr\\Log\\InvalidArgumentException' => $vendorDir . '/psr/log/Psr/Log/InvalidArgumentException.php',
'Psr\\Log\\LogLevel' => $vendorDir . '/psr/log/Psr/Log/LogLevel.php',
'Psr\\Log\\LoggerAwareInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareInterface.php',
'Psr\\Log\\LoggerAwareTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareTrait.php',
'Psr\\Log\\LoggerInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerInterface.php',
'Psr\\Log\\LoggerTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerTrait.php',
'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php',
'Psr\\Log\\Test\\DummyTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
'Psr\\Log\\Test\\LoggerInterfaceTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
'RocketTheme\\Toolbox\\ArrayTraits\\ArrayAccess' => $vendorDir . '/rockettheme/toolbox/ArrayTraits/src/ArrayAccess.php',
'RocketTheme\\Toolbox\\ArrayTraits\\ArrayAccessWithGetters' => $vendorDir . '/rockettheme/toolbox/ArrayTraits/src/ArrayAccessWithGetters.php',
'RocketTheme\\Toolbox\\ArrayTraits\\Constructor' => $vendorDir . '/rockettheme/toolbox/ArrayTraits/src/Constructor.php',
'RocketTheme\\Toolbox\\ArrayTraits\\Countable' => $vendorDir . '/rockettheme/toolbox/ArrayTraits/src/Countable.php',
'RocketTheme\\Toolbox\\ArrayTraits\\Export' => $vendorDir . '/rockettheme/toolbox/ArrayTraits/src/Export.php',
'RocketTheme\\Toolbox\\ArrayTraits\\ExportInterface' => $vendorDir . '/rockettheme/toolbox/ArrayTraits/src/ExportInterface.php',
'RocketTheme\\Toolbox\\ArrayTraits\\Iterator' => $vendorDir . '/rockettheme/toolbox/ArrayTraits/src/Iterator.php',
'RocketTheme\\Toolbox\\ArrayTraits\\NestedArrayAccess' => $vendorDir . '/rockettheme/toolbox/ArrayTraits/src/NestedArrayAccess.php',
'RocketTheme\\Toolbox\\ArrayTraits\\NestedArrayAccessWithGetters' => $vendorDir . '/rockettheme/toolbox/ArrayTraits/src/NestedArrayAccessWithGetters.php',
'RocketTheme\\Toolbox\\ArrayTraits\\Serializable' => $vendorDir . '/rockettheme/toolbox/ArrayTraits/src/Serializable.php',
'RocketTheme\\Toolbox\\Blueprints\\Blueprints' => $vendorDir . '/rockettheme/toolbox/Blueprints/src/Blueprints.php',
'RocketTheme\\Toolbox\\DI\\Container' => $vendorDir . '/rockettheme/toolbox/DI/src/Container.php',
'RocketTheme\\Toolbox\\DI\\ServiceProviderInterface' => $vendorDir . '/rockettheme/toolbox/DI/src/ServiceProviderInterface.php',
'RocketTheme\\Toolbox\\Event\\Event' => $vendorDir . '/rockettheme/toolbox/Event/src/Event.php',
'RocketTheme\\Toolbox\\Event\\EventDispatcher' => $vendorDir . '/rockettheme/toolbox/Event/src/EventDispatcher.php',
'RocketTheme\\Toolbox\\Event\\EventSubscriberInterface' => $vendorDir . '/rockettheme/toolbox/Event/src/EventSubscriberInterface.php',
'RocketTheme\\Toolbox\\File\\File' => $vendorDir . '/rockettheme/toolbox/File/src/File.php',
'RocketTheme\\Toolbox\\File\\FileInterface' => $vendorDir . '/rockettheme/toolbox/File/src/FileInterface.php',
'RocketTheme\\Toolbox\\File\\IniFile' => $vendorDir . '/rockettheme/toolbox/File/src/IniFile.php',
'RocketTheme\\Toolbox\\File\\JsonFile' => $vendorDir . '/rockettheme/toolbox/File/src/JsonFile.php',
'RocketTheme\\Toolbox\\File\\LogFile' => $vendorDir . '/rockettheme/toolbox/File/src/LogFile.php',
'RocketTheme\\Toolbox\\File\\MarkdownFile' => $vendorDir . '/rockettheme/toolbox/File/src/MarkdownFile.php',
'RocketTheme\\Toolbox\\File\\MoFile' => $vendorDir . '/rockettheme/toolbox/File/src/MoFile.php',
'RocketTheme\\Toolbox\\File\\PhpFile' => $vendorDir . '/rockettheme/toolbox/File/src/PhpFile.php',
'RocketTheme\\Toolbox\\File\\YamlFile' => $vendorDir . '/rockettheme/toolbox/File/src/YamlFile.php',
'RocketTheme\\Toolbox\\ResourceLocator\\RecursiveUniformResourceIterator' => $vendorDir . '/rockettheme/toolbox/ResourceLocator/src/RecursiveUniformResourceIterator.php',
'RocketTheme\\Toolbox\\ResourceLocator\\ResourceLocatorInterface' => $vendorDir . '/rockettheme/toolbox/ResourceLocator/src/ResourceLocatorInterface.php',
'RocketTheme\\Toolbox\\ResourceLocator\\UniformResourceIterator' => $vendorDir . '/rockettheme/toolbox/ResourceLocator/src/UniformResourceIterator.php',
'RocketTheme\\Toolbox\\ResourceLocator\\UniformResourceLocator' => $vendorDir . '/rockettheme/toolbox/ResourceLocator/src/UniformResourceLocator.php',
'RocketTheme\\Toolbox\\Session\\Message' => $vendorDir . '/rockettheme/toolbox/Session/src/Message.php',
'RocketTheme\\Toolbox\\Session\\Session' => $vendorDir . '/rockettheme/toolbox/Session/src/Session.php',
'RocketTheme\\Toolbox\\StreamWrapper\\ReadOnlyStream' => $vendorDir . '/rockettheme/toolbox/StreamWrapper/src/ReadOnlyStream.php',
'RocketTheme\\Toolbox\\StreamWrapper\\Stream' => $vendorDir . '/rockettheme/toolbox/StreamWrapper/src/Stream.php',
'RocketTheme\\Toolbox\\StreamWrapper\\StreamBuilder' => $vendorDir . '/rockettheme/toolbox/StreamWrapper/src/StreamBuilder.php',
'RocketTheme\\Toolbox\\StreamWrapper\\StreamInterface' => $vendorDir . '/rockettheme/toolbox/StreamWrapper/src/StreamInterface.php',
'Symfony\\Component\\Console\\Application' => $vendorDir . '/symfony/console/Application.php',
'Symfony\\Component\\Console\\Command\\Command' => $vendorDir . '/symfony/console/Command/Command.php',
'Symfony\\Component\\Console\\Command\\HelpCommand' => $vendorDir . '/symfony/console/Command/HelpCommand.php',
'Symfony\\Component\\Console\\Command\\ListCommand' => $vendorDir . '/symfony/console/Command/ListCommand.php',
'Symfony\\Component\\Console\\ConsoleEvents' => $vendorDir . '/symfony/console/ConsoleEvents.php',
'Symfony\\Component\\Console\\Descriptor\\ApplicationDescription' => $vendorDir . '/symfony/console/Descriptor/ApplicationDescription.php',
'Symfony\\Component\\Console\\Descriptor\\Descriptor' => $vendorDir . '/symfony/console/Descriptor/Descriptor.php',
'Symfony\\Component\\Console\\Descriptor\\DescriptorInterface' => $vendorDir . '/symfony/console/Descriptor/DescriptorInterface.php',
'Symfony\\Component\\Console\\Descriptor\\JsonDescriptor' => $vendorDir . '/symfony/console/Descriptor/JsonDescriptor.php',
'Symfony\\Component\\Console\\Descriptor\\MarkdownDescriptor' => $vendorDir . '/symfony/console/Descriptor/MarkdownDescriptor.php',
'Symfony\\Component\\Console\\Descriptor\\TextDescriptor' => $vendorDir . '/symfony/console/Descriptor/TextDescriptor.php',
'Symfony\\Component\\Console\\Descriptor\\XmlDescriptor' => $vendorDir . '/symfony/console/Descriptor/XmlDescriptor.php',
'Symfony\\Component\\Console\\Event\\ConsoleCommandEvent' => $vendorDir . '/symfony/console/Event/ConsoleCommandEvent.php',
'Symfony\\Component\\Console\\Event\\ConsoleEvent' => $vendorDir . '/symfony/console/Event/ConsoleEvent.php',
'Symfony\\Component\\Console\\Event\\ConsoleExceptionEvent' => $vendorDir . '/symfony/console/Event/ConsoleExceptionEvent.php',
'Symfony\\Component\\Console\\Event\\ConsoleTerminateEvent' => $vendorDir . '/symfony/console/Event/ConsoleTerminateEvent.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatter' => $vendorDir . '/symfony/console/Formatter/OutputFormatter.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatterInterface' => $vendorDir . '/symfony/console/Formatter/OutputFormatterInterface.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyle' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyle.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleInterface' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyleInterface.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleStack' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyleStack.php',
'Symfony\\Component\\Console\\Helper\\DebugFormatterHelper' => $vendorDir . '/symfony/console/Helper/DebugFormatterHelper.php',
'Symfony\\Component\\Console\\Helper\\DescriptorHelper' => $vendorDir . '/symfony/console/Helper/DescriptorHelper.php',
'Symfony\\Component\\Console\\Helper\\DialogHelper' => $vendorDir . '/symfony/console/Helper/DialogHelper.php',
'Symfony\\Component\\Console\\Helper\\FormatterHelper' => $vendorDir . '/symfony/console/Helper/FormatterHelper.php',
'Symfony\\Component\\Console\\Helper\\Helper' => $vendorDir . '/symfony/console/Helper/Helper.php',
'Symfony\\Component\\Console\\Helper\\HelperInterface' => $vendorDir . '/symfony/console/Helper/HelperInterface.php',
'Symfony\\Component\\Console\\Helper\\HelperSet' => $vendorDir . '/symfony/console/Helper/HelperSet.php',
'Symfony\\Component\\Console\\Helper\\InputAwareHelper' => $vendorDir . '/symfony/console/Helper/InputAwareHelper.php',
'Symfony\\Component\\Console\\Helper\\ProcessHelper' => $vendorDir . '/symfony/console/Helper/ProcessHelper.php',
'Symfony\\Component\\Console\\Helper\\ProgressBar' => $vendorDir . '/symfony/console/Helper/ProgressBar.php',
'Symfony\\Component\\Console\\Helper\\ProgressHelper' => $vendorDir . '/symfony/console/Helper/ProgressHelper.php',
'Symfony\\Component\\Console\\Helper\\QuestionHelper' => $vendorDir . '/symfony/console/Helper/QuestionHelper.php',
'Symfony\\Component\\Console\\Helper\\SymfonyQuestionHelper' => $vendorDir . '/symfony/console/Helper/SymfonyQuestionHelper.php',
'Symfony\\Component\\Console\\Helper\\Table' => $vendorDir . '/symfony/console/Helper/Table.php',
'Symfony\\Component\\Console\\Helper\\TableCell' => $vendorDir . '/symfony/console/Helper/TableCell.php',
'Symfony\\Component\\Console\\Helper\\TableHelper' => $vendorDir . '/symfony/console/Helper/TableHelper.php',
'Symfony\\Component\\Console\\Helper\\TableSeparator' => $vendorDir . '/symfony/console/Helper/TableSeparator.php',
'Symfony\\Component\\Console\\Helper\\TableStyle' => $vendorDir . '/symfony/console/Helper/TableStyle.php',
'Symfony\\Component\\Console\\Input\\ArgvInput' => $vendorDir . '/symfony/console/Input/ArgvInput.php',
'Symfony\\Component\\Console\\Input\\ArrayInput' => $vendorDir . '/symfony/console/Input/ArrayInput.php',
'Symfony\\Component\\Console\\Input\\Input' => $vendorDir . '/symfony/console/Input/Input.php',
'Symfony\\Component\\Console\\Input\\InputArgument' => $vendorDir . '/symfony/console/Input/InputArgument.php',
'Symfony\\Component\\Console\\Input\\InputAwareInterface' => $vendorDir . '/symfony/console/Input/InputAwareInterface.php',
'Symfony\\Component\\Console\\Input\\InputDefinition' => $vendorDir . '/symfony/console/Input/InputDefinition.php',
'Symfony\\Component\\Console\\Input\\InputInterface' => $vendorDir . '/symfony/console/Input/InputInterface.php',
'Symfony\\Component\\Console\\Input\\InputOption' => $vendorDir . '/symfony/console/Input/InputOption.php',
'Symfony\\Component\\Console\\Input\\StringInput' => $vendorDir . '/symfony/console/Input/StringInput.php',
'Symfony\\Component\\Console\\Logger\\ConsoleLogger' => $vendorDir . '/symfony/console/Logger/ConsoleLogger.php',
'Symfony\\Component\\Console\\Output\\BufferedOutput' => $vendorDir . '/symfony/console/Output/BufferedOutput.php',
'Symfony\\Component\\Console\\Output\\ConsoleOutput' => $vendorDir . '/symfony/console/Output/ConsoleOutput.php',
'Symfony\\Component\\Console\\Output\\ConsoleOutputInterface' => $vendorDir . '/symfony/console/Output/ConsoleOutputInterface.php',
'Symfony\\Component\\Console\\Output\\NullOutput' => $vendorDir . '/symfony/console/Output/NullOutput.php',
'Symfony\\Component\\Console\\Output\\Output' => $vendorDir . '/symfony/console/Output/Output.php',
'Symfony\\Component\\Console\\Output\\OutputInterface' => $vendorDir . '/symfony/console/Output/OutputInterface.php',
'Symfony\\Component\\Console\\Output\\StreamOutput' => $vendorDir . '/symfony/console/Output/StreamOutput.php',
'Symfony\\Component\\Console\\Question\\ChoiceQuestion' => $vendorDir . '/symfony/console/Question/ChoiceQuestion.php',
'Symfony\\Component\\Console\\Question\\ConfirmationQuestion' => $vendorDir . '/symfony/console/Question/ConfirmationQuestion.php',
'Symfony\\Component\\Console\\Question\\Question' => $vendorDir . '/symfony/console/Question/Question.php',
'Symfony\\Component\\Console\\Shell' => $vendorDir . '/symfony/console/Shell.php',
'Symfony\\Component\\Console\\Style\\OutputStyle' => $vendorDir . '/symfony/console/Style/OutputStyle.php',
'Symfony\\Component\\Console\\Style\\StyleInterface' => $vendorDir . '/symfony/console/Style/StyleInterface.php',
'Symfony\\Component\\Console\\Style\\SymfonyStyle' => $vendorDir . '/symfony/console/Style/SymfonyStyle.php',
'Symfony\\Component\\Console\\Tester\\ApplicationTester' => $vendorDir . '/symfony/console/Tester/ApplicationTester.php',
'Symfony\\Component\\Console\\Tester\\CommandTester' => $vendorDir . '/symfony/console/Tester/CommandTester.php',
'Symfony\\Component\\Console\\Tests\\ApplicationTest' => $vendorDir . '/symfony/console/Tests/ApplicationTest.php',
'Symfony\\Component\\Console\\Tests\\Command\\CommandTest' => $vendorDir . '/symfony/console/Tests/Command/CommandTest.php',
'Symfony\\Component\\Console\\Tests\\Command\\HelpCommandTest' => $vendorDir . '/symfony/console/Tests/Command/HelpCommandTest.php',
'Symfony\\Component\\Console\\Tests\\Command\\ListCommandTest' => $vendorDir . '/symfony/console/Tests/Command/ListCommandTest.php',
'Symfony\\Component\\Console\\Tests\\CustomApplication' => $vendorDir . '/symfony/console/Tests/ApplicationTest.php',
'Symfony\\Component\\Console\\Tests\\CustomDefaultCommandApplication' => $vendorDir . '/symfony/console/Tests/ApplicationTest.php',
'Symfony\\Component\\Console\\Tests\\Descriptor\\AbstractDescriptorTest' => $vendorDir . '/symfony/console/Tests/Descriptor/AbstractDescriptorTest.php',
'Symfony\\Component\\Console\\Tests\\Descriptor\\JsonDescriptorTest' => $vendorDir . '/symfony/console/Tests/Descriptor/JsonDescriptorTest.php',
'Symfony\\Component\\Console\\Tests\\Descriptor\\MarkdownDescriptorTest' => $vendorDir . '/symfony/console/Tests/Descriptor/MarkdownDescriptorTest.php',
'Symfony\\Component\\Console\\Tests\\Descriptor\\ObjectsProvider' => $vendorDir . '/symfony/console/Tests/Descriptor/ObjectsProvider.php',
'Symfony\\Component\\Console\\Tests\\Descriptor\\TextDescriptorTest' => $vendorDir . '/symfony/console/Tests/Descriptor/TextDescriptorTest.php',
'Symfony\\Component\\Console\\Tests\\Descriptor\\XmlDescriptorTest' => $vendorDir . '/symfony/console/Tests/Descriptor/XmlDescriptorTest.php',
'Symfony\\Component\\Console\\Tests\\Fixtures\\DescriptorApplication1' => $vendorDir . '/symfony/console/Tests/Fixtures/DescriptorApplication1.php',
'Symfony\\Component\\Console\\Tests\\Fixtures\\DescriptorApplication2' => $vendorDir . '/symfony/console/Tests/Fixtures/DescriptorApplication2.php',
'Symfony\\Component\\Console\\Tests\\Fixtures\\DescriptorCommand1' => $vendorDir . '/symfony/console/Tests/Fixtures/DescriptorCommand1.php',
'Symfony\\Component\\Console\\Tests\\Fixtures\\DescriptorCommand2' => $vendorDir . '/symfony/console/Tests/Fixtures/DescriptorCommand2.php',
'Symfony\\Component\\Console\\Tests\\Fixtures\\DummyOutput' => $vendorDir . '/symfony/console/Tests/Fixtures/DummyOutput.php',
'Symfony\\Component\\Console\\Tests\\Formatter\\OutputFormatterStyleStackTest' => $vendorDir . '/symfony/console/Tests/Formatter/OutputFormatterStyleStackTest.php',
'Symfony\\Component\\Console\\Tests\\Formatter\\OutputFormatterStyleTest' => $vendorDir . '/symfony/console/Tests/Formatter/OutputFormatterStyleTest.php',
'Symfony\\Component\\Console\\Tests\\Formatter\\OutputFormatterTest' => $vendorDir . '/symfony/console/Tests/Formatter/OutputFormatterTest.php',
'Symfony\\Component\\Console\\Tests\\Formatter\\TableCell' => $vendorDir . '/symfony/console/Tests/Formatter/OutputFormatterTest.php',
'Symfony\\Component\\Console\\Tests\\Helper\\FormatterHelperTest' => $vendorDir . '/symfony/console/Tests/Helper/FormatterHelperTest.php',
'Symfony\\Component\\Console\\Tests\\Helper\\HelperSetTest' => $vendorDir . '/symfony/console/Tests/Helper/HelperSetTest.php',
'Symfony\\Component\\Console\\Tests\\Helper\\LegacyDialogHelperTest' => $vendorDir . '/symfony/console/Tests/Helper/LegacyDialogHelperTest.php',
'Symfony\\Component\\Console\\Tests\\Helper\\LegacyProgressHelperTest' => $vendorDir . '/symfony/console/Tests/Helper/LegacyProgressHelperTest.php',
'Symfony\\Component\\Console\\Tests\\Helper\\LegacyTableHelperTest' => $vendorDir . '/symfony/console/Tests/Helper/LegacyTableHelperTest.php',
'Symfony\\Component\\Console\\Tests\\Helper\\ProcessHelperTest' => $vendorDir . '/symfony/console/Tests/Helper/ProcessHelperTest.php',
'Symfony\\Component\\Console\\Tests\\Helper\\ProgressBarTest' => $vendorDir . '/symfony/console/Tests/Helper/ProgressBarTest.php',
'Symfony\\Component\\Console\\Tests\\Helper\\QuestionHelperTest' => $vendorDir . '/symfony/console/Tests/Helper/QuestionHelperTest.php',
'Symfony\\Component\\Console\\Tests\\Helper\\TableStyleTest' => $vendorDir . '/symfony/console/Tests/Helper/TableStyleTest.php',
'Symfony\\Component\\Console\\Tests\\Helper\\TableTest' => $vendorDir . '/symfony/console/Tests/Helper/TableTest.php',
'Symfony\\Component\\Console\\Tests\\Input\\ArgvInputTest' => $vendorDir . '/symfony/console/Tests/Input/ArgvInputTest.php',
'Symfony\\Component\\Console\\Tests\\Input\\ArrayInputTest' => $vendorDir . '/symfony/console/Tests/Input/ArrayInputTest.php',
'Symfony\\Component\\Console\\Tests\\Input\\InputArgumentTest' => $vendorDir . '/symfony/console/Tests/Input/InputArgumentTest.php',
'Symfony\\Component\\Console\\Tests\\Input\\InputDefinitionTest' => $vendorDir . '/symfony/console/Tests/Input/InputDefinitionTest.php',
'Symfony\\Component\\Console\\Tests\\Input\\InputOptionTest' => $vendorDir . '/symfony/console/Tests/Input/InputOptionTest.php',
'Symfony\\Component\\Console\\Tests\\Input\\InputTest' => $vendorDir . '/symfony/console/Tests/Input/InputTest.php',
'Symfony\\Component\\Console\\Tests\\Input\\StringInputTest' => $vendorDir . '/symfony/console/Tests/Input/StringInputTest.php',
'Symfony\\Component\\Console\\Tests\\Logger\\ConsoleLoggerTest' => $vendorDir . '/symfony/console/Tests/Logger/ConsoleLoggerTest.php',
'Symfony\\Component\\Console\\Tests\\Output\\ConsoleOutputTest' => $vendorDir . '/symfony/console/Tests/Output/ConsoleOutputTest.php',
'Symfony\\Component\\Console\\Tests\\Output\\NullOutputTest' => $vendorDir . '/symfony/console/Tests/Output/NullOutputTest.php',
'Symfony\\Component\\Console\\Tests\\Output\\OutputTest' => $vendorDir . '/symfony/console/Tests/Output/OutputTest.php',
'Symfony\\Component\\Console\\Tests\\Output\\StreamOutputTest' => $vendorDir . '/symfony/console/Tests/Output/StreamOutputTest.php',
'Symfony\\Component\\Console\\Tests\\Output\\TestOutput' => $vendorDir . '/symfony/console/Tests/Output/OutputTest.php',
'Symfony\\Component\\Console\\Tests\\Style\\SymfonyStyleTest' => $vendorDir . '/symfony/console/Tests/Style/SymfonyStyleTest.php',
'Symfony\\Component\\Console\\Tests\\Tester\\ApplicationTesterTest' => $vendorDir . '/symfony/console/Tests/Tester/ApplicationTesterTest.php',
'Symfony\\Component\\Console\\Tests\\Tester\\CommandTesterTest' => $vendorDir . '/symfony/console/Tests/Tester/CommandTesterTest.php',
'Symfony\\Component\\EventDispatcher\\ContainerAwareEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/ContainerAwareEventDispatcher.php',
'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php',
'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcherInterface' => $vendorDir . '/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php',
'Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener' => $vendorDir . '/symfony/event-dispatcher/Debug/WrappedListener.php',
'Symfony\\Component\\EventDispatcher\\DependencyInjection\\RegisterListenersPass' => $vendorDir . '/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php',
'Symfony\\Component\\EventDispatcher\\Event' => $vendorDir . '/symfony/event-dispatcher/Event.php',
'Symfony\\Component\\EventDispatcher\\EventDispatcher' => $vendorDir . '/symfony/event-dispatcher/EventDispatcher.php',
'Symfony\\Component\\EventDispatcher\\EventDispatcherInterface' => $vendorDir . '/symfony/event-dispatcher/EventDispatcherInterface.php',
'Symfony\\Component\\EventDispatcher\\EventSubscriberInterface' => $vendorDir . '/symfony/event-dispatcher/EventSubscriberInterface.php',
'Symfony\\Component\\EventDispatcher\\GenericEvent' => $vendorDir . '/symfony/event-dispatcher/GenericEvent.php',
'Symfony\\Component\\EventDispatcher\\ImmutableEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/ImmutableEventDispatcher.php',
'Symfony\\Component\\EventDispatcher\\Tests\\AbstractEventDispatcherTest' => $vendorDir . '/symfony/event-dispatcher/Tests/AbstractEventDispatcherTest.php',
'Symfony\\Component\\EventDispatcher\\Tests\\CallableClass' => $vendorDir . '/symfony/event-dispatcher/Tests/AbstractEventDispatcherTest.php',
'Symfony\\Component\\EventDispatcher\\Tests\\ContainerAwareEventDispatcherTest' => $vendorDir . '/symfony/event-dispatcher/Tests/ContainerAwareEventDispatcherTest.php',
'Symfony\\Component\\EventDispatcher\\Tests\\Debug\\EventSubscriber' => $vendorDir . '/symfony/event-dispatcher/Tests/Debug/TraceableEventDispatcherTest.php',
'Symfony\\Component\\EventDispatcher\\Tests\\Debug\\TraceableEventDispatcherTest' => $vendorDir . '/symfony/event-dispatcher/Tests/Debug/TraceableEventDispatcherTest.php',
'Symfony\\Component\\EventDispatcher\\Tests\\DependencyInjection\\RegisterListenersPassTest' => $vendorDir . '/symfony/event-dispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php',
'Symfony\\Component\\EventDispatcher\\Tests\\DependencyInjection\\SubscriberService' => $vendorDir . '/symfony/event-dispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php',
'Symfony\\Component\\EventDispatcher\\Tests\\EventDispatcherTest' => $vendorDir . '/symfony/event-dispatcher/Tests/EventDispatcherTest.php',
'Symfony\\Component\\EventDispatcher\\Tests\\EventTest' => $vendorDir . '/symfony/event-dispatcher/Tests/EventTest.php',
'Symfony\\Component\\EventDispatcher\\Tests\\GenericEventTest' => $vendorDir . '/symfony/event-dispatcher/Tests/GenericEventTest.php',
'Symfony\\Component\\EventDispatcher\\Tests\\ImmutableEventDispatcherTest' => $vendorDir . '/symfony/event-dispatcher/Tests/ImmutableEventDispatcherTest.php',
'Symfony\\Component\\EventDispatcher\\Tests\\Service' => $vendorDir . '/symfony/event-dispatcher/Tests/ContainerAwareEventDispatcherTest.php',
'Symfony\\Component\\EventDispatcher\\Tests\\SubscriberService' => $vendorDir . '/symfony/event-dispatcher/Tests/ContainerAwareEventDispatcherTest.php',
'Symfony\\Component\\EventDispatcher\\Tests\\TestEventListener' => $vendorDir . '/symfony/event-dispatcher/Tests/AbstractEventDispatcherTest.php',
'Symfony\\Component\\EventDispatcher\\Tests\\TestEventSubscriber' => $vendorDir . '/symfony/event-dispatcher/Tests/AbstractEventDispatcherTest.php',
'Symfony\\Component\\EventDispatcher\\Tests\\TestEventSubscriberWithMultipleListeners' => $vendorDir . '/symfony/event-dispatcher/Tests/AbstractEventDispatcherTest.php',
'Symfony\\Component\\EventDispatcher\\Tests\\TestEventSubscriberWithPriorities' => $vendorDir . '/symfony/event-dispatcher/Tests/AbstractEventDispatcherTest.php',
'Symfony\\Component\\EventDispatcher\\Tests\\TestWithDispatcher' => $vendorDir . '/symfony/event-dispatcher/Tests/AbstractEventDispatcherTest.php',
'Symfony\\Component\\VarDumper\\Caster\\AmqpCaster' => $vendorDir . '/symfony/var-dumper/Caster/AmqpCaster.php',
'Symfony\\Component\\VarDumper\\Caster\\Caster' => $vendorDir . '/symfony/var-dumper/Caster/Caster.php',
'Symfony\\Component\\VarDumper\\Caster\\ConstStub' => $vendorDir . '/symfony/var-dumper/Caster/ConstStub.php',
'Symfony\\Component\\VarDumper\\Caster\\CutStub' => $vendorDir . '/symfony/var-dumper/Caster/CutStub.php',
'Symfony\\Component\\VarDumper\\Caster\\DOMCaster' => $vendorDir . '/symfony/var-dumper/Caster/DOMCaster.php',
'Symfony\\Component\\VarDumper\\Caster\\DoctrineCaster' => $vendorDir . '/symfony/var-dumper/Caster/DoctrineCaster.php',
'Symfony\\Component\\VarDumper\\Caster\\ExceptionCaster' => $vendorDir . '/symfony/var-dumper/Caster/ExceptionCaster.php',
'Symfony\\Component\\VarDumper\\Caster\\MongoCaster' => $vendorDir . '/symfony/var-dumper/Caster/MongoCaster.php',
'Symfony\\Component\\VarDumper\\Caster\\PdoCaster' => $vendorDir . '/symfony/var-dumper/Caster/PdoCaster.php',
'Symfony\\Component\\VarDumper\\Caster\\ReflectionCaster' => $vendorDir . '/symfony/var-dumper/Caster/ReflectionCaster.php',
'Symfony\\Component\\VarDumper\\Caster\\ResourceCaster' => $vendorDir . '/symfony/var-dumper/Caster/ResourceCaster.php',
'Symfony\\Component\\VarDumper\\Caster\\SplCaster' => $vendorDir . '/symfony/var-dumper/Caster/SplCaster.php',
'Symfony\\Component\\VarDumper\\Caster\\StubCaster' => $vendorDir . '/symfony/var-dumper/Caster/StubCaster.php',
'Symfony\\Component\\VarDumper\\Caster\\XmlResourceCaster' => $vendorDir . '/symfony/var-dumper/Caster/XmlResourceCaster.php',
'Symfony\\Component\\VarDumper\\Cloner\\AbstractCloner' => $vendorDir . '/symfony/var-dumper/Cloner/AbstractCloner.php',
'Symfony\\Component\\VarDumper\\Cloner\\ClonerInterface' => $vendorDir . '/symfony/var-dumper/Cloner/ClonerInterface.php',
'Symfony\\Component\\VarDumper\\Cloner\\Cursor' => $vendorDir . '/symfony/var-dumper/Cloner/Cursor.php',
'Symfony\\Component\\VarDumper\\Cloner\\Data' => $vendorDir . '/symfony/var-dumper/Cloner/Data.php',
'Symfony\\Component\\VarDumper\\Cloner\\DumperInterface' => $vendorDir . '/symfony/var-dumper/Cloner/DumperInterface.php',
'Symfony\\Component\\VarDumper\\Cloner\\Stub' => $vendorDir . '/symfony/var-dumper/Cloner/Stub.php',
'Symfony\\Component\\VarDumper\\Cloner\\VarCloner' => $vendorDir . '/symfony/var-dumper/Cloner/VarCloner.php',
'Symfony\\Component\\VarDumper\\Dumper\\AbstractDumper' => $vendorDir . '/symfony/var-dumper/Dumper/AbstractDumper.php',
'Symfony\\Component\\VarDumper\\Dumper\\CliDumper' => $vendorDir . '/symfony/var-dumper/Dumper/CliDumper.php',
'Symfony\\Component\\VarDumper\\Dumper\\DataDumperInterface' => $vendorDir . '/symfony/var-dumper/Dumper/DataDumperInterface.php',
'Symfony\\Component\\VarDumper\\Dumper\\HtmlDumper' => $vendorDir . '/symfony/var-dumper/Dumper/HtmlDumper.php',
'Symfony\\Component\\VarDumper\\Exception\\ThrowingCasterException' => $vendorDir . '/symfony/var-dumper/Exception/ThrowingCasterException.php',
'Symfony\\Component\\VarDumper\\Test\\VarDumperTestCase' => $vendorDir . '/symfony/var-dumper/Test/VarDumperTestCase.php',
'Symfony\\Component\\VarDumper\\Test\\VarDumperTestTrait' => $vendorDir . '/symfony/var-dumper/Test/VarDumperTestTrait.php',
'Symfony\\Component\\VarDumper\\Tests\\Caster\\CasterTest' => $vendorDir . '/symfony/var-dumper/Tests/Caster/CasterTest.php',
'Symfony\\Component\\VarDumper\\Tests\\Caster\\PdoCasterTest' => $vendorDir . '/symfony/var-dumper/Tests/Caster/PdoCasterTest.php',
'Symfony\\Component\\VarDumper\\Tests\\Caster\\ReflectionCasterTest' => $vendorDir . '/symfony/var-dumper/Tests/Caster/ReflectionCasterTest.php',
'Symfony\\Component\\VarDumper\\Tests\\CliDumperTest' => $vendorDir . '/symfony/var-dumper/Tests/CliDumperTest.php',
'Symfony\\Component\\VarDumper\\Tests\\Fixture\\DumbFoo' => $vendorDir . '/symfony/var-dumper/Tests/Fixtures/dumb-var.php',
'Symfony\\Component\\VarDumper\\Tests\\HtmlDumperTest' => $vendorDir . '/symfony/var-dumper/Tests/HtmlDumperTest.php',
'Symfony\\Component\\VarDumper\\Tests\\Test\\VarDumperTestTraitTest' => $vendorDir . '/symfony/var-dumper/Tests/Test/VarDumpTestTraitRequire54.php',
'Symfony\\Component\\VarDumper\\Tests\\VarClonerTest' => $vendorDir . '/symfony/var-dumper/Tests/VarClonerTest.php',
'Symfony\\Component\\VarDumper\\VarDumper' => $vendorDir . '/symfony/var-dumper/VarDumper.php',
'Symfony\\Component\\Yaml\\Dumper' => $vendorDir . '/symfony/yaml/Dumper.php',
'Symfony\\Component\\Yaml\\Escaper' => $vendorDir . '/symfony/yaml/Escaper.php',
'Symfony\\Component\\Yaml\\Exception\\DumpException' => $vendorDir . '/symfony/yaml/Exception/DumpException.php',
'Symfony\\Component\\Yaml\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/yaml/Exception/ExceptionInterface.php',
'Symfony\\Component\\Yaml\\Exception\\ParseException' => $vendorDir . '/symfony/yaml/Exception/ParseException.php',
'Symfony\\Component\\Yaml\\Exception\\RuntimeException' => $vendorDir . '/symfony/yaml/Exception/RuntimeException.php',
'Symfony\\Component\\Yaml\\Inline' => $vendorDir . '/symfony/yaml/Inline.php',
'Symfony\\Component\\Yaml\\Parser' => $vendorDir . '/symfony/yaml/Parser.php',
'Symfony\\Component\\Yaml\\Tests\\A' => $vendorDir . '/symfony/yaml/Tests/DumperTest.php',
'Symfony\\Component\\Yaml\\Tests\\B' => $vendorDir . '/symfony/yaml/Tests/ParserTest.php',
'Symfony\\Component\\Yaml\\Tests\\DumperTest' => $vendorDir . '/symfony/yaml/Tests/DumperTest.php',
'Symfony\\Component\\Yaml\\Tests\\InlineTest' => $vendorDir . '/symfony/yaml/Tests/InlineTest.php',
'Symfony\\Component\\Yaml\\Tests\\ParseExceptionTest' => $vendorDir . '/symfony/yaml/Tests/ParseExceptionTest.php',
'Symfony\\Component\\Yaml\\Tests\\ParserTest' => $vendorDir . '/symfony/yaml/Tests/ParserTest.php',
'Symfony\\Component\\Yaml\\Tests\\YamlTest' => $vendorDir . '/symfony/yaml/Tests/YamlTest.php',
'Symfony\\Component\\Yaml\\Unescaper' => $vendorDir . '/symfony/yaml/Unescaper.php',
'Symfony\\Component\\Yaml\\Yaml' => $vendorDir . '/symfony/yaml/Yaml.php',
'Twig_Autoloader' => $vendorDir . '/twig/twig/lib/Twig/Autoloader.php',
'Twig_BaseNodeVisitor' => $vendorDir . '/twig/twig/lib/Twig/BaseNodeVisitor.php',
'Twig_CacheInterface' => $vendorDir . '/twig/twig/lib/Twig/CacheInterface.php',
'Twig_Cache_Filesystem' => $vendorDir . '/twig/twig/lib/Twig/Cache/Filesystem.php',
'Twig_Cache_Null' => $vendorDir . '/twig/twig/lib/Twig/Cache/Null.php',
'Twig_Compiler' => $vendorDir . '/twig/twig/lib/Twig/Compiler.php',
'Twig_CompilerInterface' => $vendorDir . '/twig/twig/lib/Twig/CompilerInterface.php',
'Twig_Environment' => $vendorDir . '/twig/twig/lib/Twig/Environment.php',
'Twig_Error' => $vendorDir . '/twig/twig/lib/Twig/Error.php',
'Twig_Error_Loader' => $vendorDir . '/twig/twig/lib/Twig/Error/Loader.php',
'Twig_Error_Runtime' => $vendorDir . '/twig/twig/lib/Twig/Error/Runtime.php',
'Twig_Error_Syntax' => $vendorDir . '/twig/twig/lib/Twig/Error/Syntax.php',
'Twig_ExistsLoaderInterface' => $vendorDir . '/twig/twig/lib/Twig/ExistsLoaderInterface.php',
'Twig_ExpressionParser' => $vendorDir . '/twig/twig/lib/Twig/ExpressionParser.php',
'Twig_Extension' => $vendorDir . '/twig/twig/lib/Twig/Extension.php',
'Twig_ExtensionInterface' => $vendorDir . '/twig/twig/lib/Twig/ExtensionInterface.php',
'Twig_Extension_Core' => $vendorDir . '/twig/twig/lib/Twig/Extension/Core.php',
'Twig_Extension_Debug' => $vendorDir . '/twig/twig/lib/Twig/Extension/Debug.php',
'Twig_Extension_Escaper' => $vendorDir . '/twig/twig/lib/Twig/Extension/Escaper.php',
'Twig_Extension_Optimizer' => $vendorDir . '/twig/twig/lib/Twig/Extension/Optimizer.php',
'Twig_Extension_Profiler' => $vendorDir . '/twig/twig/lib/Twig/Extension/Profiler.php',
'Twig_Extension_Sandbox' => $vendorDir . '/twig/twig/lib/Twig/Extension/Sandbox.php',
'Twig_Extension_Staging' => $vendorDir . '/twig/twig/lib/Twig/Extension/Staging.php',
'Twig_Extension_StringLoader' => $vendorDir . '/twig/twig/lib/Twig/Extension/StringLoader.php',
'Twig_FileExtensionEscapingStrategy' => $vendorDir . '/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php',
'Twig_Filter' => $vendorDir . '/twig/twig/lib/Twig/Filter.php',
'Twig_FilterCallableInterface' => $vendorDir . '/twig/twig/lib/Twig/FilterCallableInterface.php',
'Twig_FilterInterface' => $vendorDir . '/twig/twig/lib/Twig/FilterInterface.php',
'Twig_Filter_Function' => $vendorDir . '/twig/twig/lib/Twig/Filter/Function.php',
'Twig_Filter_Method' => $vendorDir . '/twig/twig/lib/Twig/Filter/Method.php',
'Twig_Filter_Node' => $vendorDir . '/twig/twig/lib/Twig/Filter/Node.php',
'Twig_Function' => $vendorDir . '/twig/twig/lib/Twig/Function.php',
'Twig_FunctionCallableInterface' => $vendorDir . '/twig/twig/lib/Twig/FunctionCallableInterface.php',
'Twig_FunctionInterface' => $vendorDir . '/twig/twig/lib/Twig/FunctionInterface.php',
'Twig_Function_Function' => $vendorDir . '/twig/twig/lib/Twig/Function/Function.php',
'Twig_Function_Method' => $vendorDir . '/twig/twig/lib/Twig/Function/Method.php',
'Twig_Function_Node' => $vendorDir . '/twig/twig/lib/Twig/Function/Node.php',
'Twig_Lexer' => $vendorDir . '/twig/twig/lib/Twig/Lexer.php',
'Twig_LexerInterface' => $vendorDir . '/twig/twig/lib/Twig/LexerInterface.php',
'Twig_LoaderInterface' => $vendorDir . '/twig/twig/lib/Twig/LoaderInterface.php',
'Twig_Loader_Array' => $vendorDir . '/twig/twig/lib/Twig/Loader/Array.php',
'Twig_Loader_Chain' => $vendorDir . '/twig/twig/lib/Twig/Loader/Chain.php',
'Twig_Loader_Filesystem' => $vendorDir . '/twig/twig/lib/Twig/Loader/Filesystem.php',
'Twig_Loader_String' => $vendorDir . '/twig/twig/lib/Twig/Loader/String.php',
'Twig_Markup' => $vendorDir . '/twig/twig/lib/Twig/Markup.php',
'Twig_Node' => $vendorDir . '/twig/twig/lib/Twig/Node.php',
'Twig_NodeInterface' => $vendorDir . '/twig/twig/lib/Twig/NodeInterface.php',
'Twig_NodeOutputInterface' => $vendorDir . '/twig/twig/lib/Twig/NodeOutputInterface.php',
'Twig_NodeTraverser' => $vendorDir . '/twig/twig/lib/Twig/NodeTraverser.php',
'Twig_NodeVisitorInterface' => $vendorDir . '/twig/twig/lib/Twig/NodeVisitorInterface.php',
'Twig_NodeVisitor_Escaper' => $vendorDir . '/twig/twig/lib/Twig/NodeVisitor/Escaper.php',
'Twig_NodeVisitor_Optimizer' => $vendorDir . '/twig/twig/lib/Twig/NodeVisitor/Optimizer.php',
'Twig_NodeVisitor_SafeAnalysis' => $vendorDir . '/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php',
'Twig_NodeVisitor_Sandbox' => $vendorDir . '/twig/twig/lib/Twig/NodeVisitor/Sandbox.php',
'Twig_Node_AutoEscape' => $vendorDir . '/twig/twig/lib/Twig/Node/AutoEscape.php',
'Twig_Node_Block' => $vendorDir . '/twig/twig/lib/Twig/Node/Block.php',
'Twig_Node_BlockReference' => $vendorDir . '/twig/twig/lib/Twig/Node/BlockReference.php',
'Twig_Node_Body' => $vendorDir . '/twig/twig/lib/Twig/Node/Body.php',
'Twig_Node_CheckSecurity' => $vendorDir . '/twig/twig/lib/Twig/Node/CheckSecurity.php',
'Twig_Node_Do' => $vendorDir . '/twig/twig/lib/Twig/Node/Do.php',
'Twig_Node_Embed' => $vendorDir . '/twig/twig/lib/Twig/Node/Embed.php',
'Twig_Node_Expression' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression.php',
'Twig_Node_Expression_Array' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Array.php',
'Twig_Node_Expression_AssignName' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/AssignName.php',
'Twig_Node_Expression_Binary' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary.php',
'Twig_Node_Expression_Binary_Add' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Add.php',
'Twig_Node_Expression_Binary_And' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/And.php',
'Twig_Node_Expression_Binary_BitwiseAnd' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php',
'Twig_Node_Expression_Binary_BitwiseOr' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php',
'Twig_Node_Expression_Binary_BitwiseXor' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php',
'Twig_Node_Expression_Binary_Concat' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php',
'Twig_Node_Expression_Binary_Div' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Div.php',
'Twig_Node_Expression_Binary_EndsWith' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php',
'Twig_Node_Expression_Binary_Equal' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php',
'Twig_Node_Expression_Binary_FloorDiv' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php',
'Twig_Node_Expression_Binary_Greater' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php',
'Twig_Node_Expression_Binary_GreaterEqual' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php',
'Twig_Node_Expression_Binary_In' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/In.php',
'Twig_Node_Expression_Binary_Less' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Less.php',
'Twig_Node_Expression_Binary_LessEqual' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php',
'Twig_Node_Expression_Binary_Matches' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php',
'Twig_Node_Expression_Binary_Mod' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php',
'Twig_Node_Expression_Binary_Mul' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php',
'Twig_Node_Expression_Binary_NotEqual' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php',
'Twig_Node_Expression_Binary_NotIn' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php',
'Twig_Node_Expression_Binary_Or' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Or.php',
'Twig_Node_Expression_Binary_Power' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Power.php',
'Twig_Node_Expression_Binary_Range' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Range.php',
'Twig_Node_Expression_Binary_StartsWith' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php',
'Twig_Node_Expression_Binary_Sub' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php',
'Twig_Node_Expression_BlockReference' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/BlockReference.php',
'Twig_Node_Expression_Call' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Call.php',
'Twig_Node_Expression_Conditional' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Conditional.php',
'Twig_Node_Expression_Constant' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Constant.php',
'Twig_Node_Expression_ExtensionReference' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php',
'Twig_Node_Expression_Filter' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Filter.php',
'Twig_Node_Expression_Filter_Default' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Filter/Default.php',
'Twig_Node_Expression_Function' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Function.php',
'Twig_Node_Expression_GetAttr' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/GetAttr.php',
'Twig_Node_Expression_MethodCall' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/MethodCall.php',
'Twig_Node_Expression_Name' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Name.php',
'Twig_Node_Expression_Parent' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Parent.php',
'Twig_Node_Expression_TempName' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/TempName.php',
'Twig_Node_Expression_Test' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Test.php',
'Twig_Node_Expression_Test_Constant' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Test/Constant.php',
'Twig_Node_Expression_Test_Defined' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Test/Defined.php',
'Twig_Node_Expression_Test_Divisibleby' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php',
'Twig_Node_Expression_Test_Even' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Test/Even.php',
'Twig_Node_Expression_Test_Null' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Test/Null.php',
'Twig_Node_Expression_Test_Odd' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Test/Odd.php',
'Twig_Node_Expression_Test_Sameas' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php',
'Twig_Node_Expression_Unary' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Unary.php',
'Twig_Node_Expression_Unary_Neg' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php',
'Twig_Node_Expression_Unary_Not' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Unary/Not.php',
'Twig_Node_Expression_Unary_Pos' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php',
'Twig_Node_Flush' => $vendorDir . '/twig/twig/lib/Twig/Node/Flush.php',
'Twig_Node_For' => $vendorDir . '/twig/twig/lib/Twig/Node/For.php',
'Twig_Node_ForLoop' => $vendorDir . '/twig/twig/lib/Twig/Node/ForLoop.php',
'Twig_Node_If' => $vendorDir . '/twig/twig/lib/Twig/Node/If.php',
'Twig_Node_Import' => $vendorDir . '/twig/twig/lib/Twig/Node/Import.php',
'Twig_Node_Include' => $vendorDir . '/twig/twig/lib/Twig/Node/Include.php',
'Twig_Node_Macro' => $vendorDir . '/twig/twig/lib/Twig/Node/Macro.php',
'Twig_Node_Module' => $vendorDir . '/twig/twig/lib/Twig/Node/Module.php',
'Twig_Node_Print' => $vendorDir . '/twig/twig/lib/Twig/Node/Print.php',
'Twig_Node_Sandbox' => $vendorDir . '/twig/twig/lib/Twig/Node/Sandbox.php',
'Twig_Node_SandboxedPrint' => $vendorDir . '/twig/twig/lib/Twig/Node/SandboxedPrint.php',
'Twig_Node_Set' => $vendorDir . '/twig/twig/lib/Twig/Node/Set.php',
'Twig_Node_SetTemp' => $vendorDir . '/twig/twig/lib/Twig/Node/SetTemp.php',
'Twig_Node_Spaceless' => $vendorDir . '/twig/twig/lib/Twig/Node/Spaceless.php',
'Twig_Node_Text' => $vendorDir . '/twig/twig/lib/Twig/Node/Text.php',
'Twig_Parser' => $vendorDir . '/twig/twig/lib/Twig/Parser.php',
'Twig_ParserInterface' => $vendorDir . '/twig/twig/lib/Twig/ParserInterface.php',
'Twig_Profiler_Dumper_Blackfire' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php',
'Twig_Profiler_Dumper_Html' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Html.php',
'Twig_Profiler_Dumper_Text' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Text.php',
'Twig_Profiler_NodeVisitor_Profiler' => $vendorDir . '/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php',
'Twig_Profiler_Node_EnterProfile' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php',
'Twig_Profiler_Node_LeaveProfile' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php',
'Twig_Profiler_Profile' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Profile.php',
'Twig_Sandbox_SecurityError' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityError.php',
'Twig_Sandbox_SecurityNotAllowedFilterError' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php',
'Twig_Sandbox_SecurityNotAllowedFunctionError' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php',
'Twig_Sandbox_SecurityNotAllowedTagError' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php',
'Twig_Sandbox_SecurityPolicy' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php',
'Twig_Sandbox_SecurityPolicyInterface' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php',
'Twig_SimpleFilter' => $vendorDir . '/twig/twig/lib/Twig/SimpleFilter.php',
'Twig_SimpleFunction' => $vendorDir . '/twig/twig/lib/Twig/SimpleFunction.php',
'Twig_SimpleTest' => $vendorDir . '/twig/twig/lib/Twig/SimpleTest.php',
'Twig_Template' => $vendorDir . '/twig/twig/lib/Twig/Template.php',
'Twig_TemplateInterface' => $vendorDir . '/twig/twig/lib/Twig/TemplateInterface.php',
'Twig_Test' => $vendorDir . '/twig/twig/lib/Twig/Test.php',
'Twig_TestCallableInterface' => $vendorDir . '/twig/twig/lib/Twig/TestCallableInterface.php',
'Twig_TestInterface' => $vendorDir . '/twig/twig/lib/Twig/TestInterface.php',
'Twig_Test_Function' => $vendorDir . '/twig/twig/lib/Twig/Test/Function.php',
'Twig_Test_IntegrationTestCase' => $vendorDir . '/twig/twig/lib/Twig/Test/IntegrationTestCase.php',
'Twig_Test_Method' => $vendorDir . '/twig/twig/lib/Twig/Test/Method.php',
'Twig_Test_Node' => $vendorDir . '/twig/twig/lib/Twig/Test/Node.php',
'Twig_Test_NodeTestCase' => $vendorDir . '/twig/twig/lib/Twig/Test/NodeTestCase.php',
'Twig_Token' => $vendorDir . '/twig/twig/lib/Twig/Token.php',
'Twig_TokenParser' => $vendorDir . '/twig/twig/lib/Twig/TokenParser.php',
'Twig_TokenParserBroker' => $vendorDir . '/twig/twig/lib/Twig/TokenParserBroker.php',
'Twig_TokenParserBrokerInterface' => $vendorDir . '/twig/twig/lib/Twig/TokenParserBrokerInterface.php',
'Twig_TokenParserInterface' => $vendorDir . '/twig/twig/lib/Twig/TokenParserInterface.php',
'Twig_TokenParser_AutoEscape' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/AutoEscape.php',
'Twig_TokenParser_Block' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Block.php',
'Twig_TokenParser_Do' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Do.php',
'Twig_TokenParser_Embed' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Embed.php',
'Twig_TokenParser_Extends' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Extends.php',
'Twig_TokenParser_Filter' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Filter.php',
'Twig_TokenParser_Flush' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Flush.php',
'Twig_TokenParser_For' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/For.php',
'Twig_TokenParser_From' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/From.php',
'Twig_TokenParser_If' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/If.php',
'Twig_TokenParser_Import' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Import.php',
'Twig_TokenParser_Include' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Include.php',
'Twig_TokenParser_Macro' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Macro.php',
'Twig_TokenParser_Sandbox' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Sandbox.php',
'Twig_TokenParser_Set' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Set.php',
'Twig_TokenParser_Spaceless' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Spaceless.php',
'Twig_TokenParser_Use' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Use.php',
'Twig_TokenStream' => $vendorDir . '/twig/twig/lib/Twig/TokenStream.php',
'Twig_Util_DeprecationCollector' => $vendorDir . '/twig/twig/lib/Twig/Util/DeprecationCollector.php',
'Twig_Util_TemplateDirIterator' => $vendorDir . '/twig/twig/lib/Twig/Util/TemplateDirIterator.php',
'Whoops\\Exception\\ErrorException' => $vendorDir . '/filp/whoops/src/Whoops/Exception/ErrorException.php',
'Whoops\\Exception\\Formatter' => $vendorDir . '/filp/whoops/src/Whoops/Exception/Formatter.php',
'Whoops\\Exception\\Frame' => $vendorDir . '/filp/whoops/src/Whoops/Exception/Frame.php',
'Whoops\\Exception\\FrameCollection' => $vendorDir . '/filp/whoops/src/Whoops/Exception/FrameCollection.php',
'Whoops\\Exception\\Inspector' => $vendorDir . '/filp/whoops/src/Whoops/Exception/Inspector.php',
'Whoops\\Handler\\CallbackHandler' => $vendorDir . '/filp/whoops/src/Whoops/Handler/CallbackHandler.php',
'Whoops\\Handler\\Handler' => $vendorDir . '/filp/whoops/src/Whoops/Handler/Handler.php',
'Whoops\\Handler\\HandlerInterface' => $vendorDir . '/filp/whoops/src/Whoops/Handler/HandlerInterface.php',
'Whoops\\Handler\\JsonResponseHandler' => $vendorDir . '/filp/whoops/src/Whoops/Handler/JsonResponseHandler.php',
'Whoops\\Handler\\PlainTextHandler' => $vendorDir . '/filp/whoops/src/Whoops/Handler/PlainTextHandler.php',
'Whoops\\Handler\\PrettyPageHandler' => $vendorDir . '/filp/whoops/src/Whoops/Handler/PrettyPageHandler.php',
'Whoops\\Handler\\SoapResponseHandler' => $vendorDir . '/filp/whoops/src/Whoops/Handler/SoapResponseHandler.php',
'Whoops\\Handler\\XmlResponseHandler' => $vendorDir . '/filp/whoops/src/Whoops/Handler/XmlResponseHandler.php',
'Whoops\\Module' => $vendorDir . '/filp/whoops/src/deprecated/Zend/Module.php',
'Whoops\\Provider\\Phalcon\\WhoopsServiceProvider' => $vendorDir . '/filp/whoops/src/Whoops/Provider/Phalcon/WhoopsServiceProvider.php',
'Whoops\\Provider\\Silex\\WhoopsServiceProvider' => $vendorDir . '/filp/whoops/src/Whoops/Provider/Silex/WhoopsServiceProvider.php',
'Whoops\\Provider\\Zend\\ExceptionStrategy' => $vendorDir . '/filp/whoops/src/deprecated/Zend/ExceptionStrategy.php',
'Whoops\\Provider\\Zend\\RouteNotFoundStrategy' => $vendorDir . '/filp/whoops/src/deprecated/Zend/RouteNotFoundStrategy.php',
'Whoops\\Run' => $vendorDir . '/filp/whoops/src/Whoops/Run.php',
'Whoops\\Util\\Misc' => $vendorDir . '/filp/whoops/src/Whoops/Util/Misc.php',
'Whoops\\Util\\TemplateHelper' => $vendorDir . '/filp/whoops/src/Whoops/Util/TemplateHelper.php',
);
+13
View File
@@ -0,0 +1,13 @@
<?php
// autoload_files.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
$vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
$vendorDir . '/ircmaxell/password-compat/lib/password.php',
$vendorDir . '/donatj/phpuseragentparser/Source/UserAgentParser.php',
$baseDir . '/system/defines.php',
);
+19
View File
@@ -0,0 +1,19 @@
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Whoops' => array($vendorDir . '/filp/whoops/src'),
'Twig_' => array($vendorDir . '/twig/twig/lib'),
'Psr\\Log\\' => array($vendorDir . '/psr/log'),
'Pimple' => array($vendorDir . '/pimple/pimple/src'),
'ParsedownExtra' => array($vendorDir . '/erusev/parsedown-extra'),
'Parsedown' => array($vendorDir . '/erusev/parsedown'),
'Gregwar\\Image' => array($vendorDir . '/gregwar/image'),
'Gregwar\\Cache' => array($vendorDir . '/gregwar/cache'),
'Doctrine\\Common\\Cache\\' => array($vendorDir . '/doctrine/cache/lib'),
'DebugBar' => array($vendorDir . '/maximebf/debugbar/src'),
);
+23
View File
@@ -0,0 +1,23 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
'Symfony\\Component\\VarDumper\\' => array($vendorDir . '/symfony/var-dumper'),
'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
'RocketTheme\\Toolbox\\StreamWrapper\\' => array($vendorDir . '/rockettheme/toolbox/StreamWrapper/src'),
'RocketTheme\\Toolbox\\Session\\' => array($vendorDir . '/rockettheme/toolbox/Session/src'),
'RocketTheme\\Toolbox\\ResourceLocator\\' => array($vendorDir . '/rockettheme/toolbox/ResourceLocator/src'),
'RocketTheme\\Toolbox\\File\\' => array($vendorDir . '/rockettheme/toolbox/File/src'),
'RocketTheme\\Toolbox\\Event\\' => array($vendorDir . '/rockettheme/toolbox/Event/src'),
'RocketTheme\\Toolbox\\DI\\' => array($vendorDir . '/rockettheme/toolbox/DI/src'),
'RocketTheme\\Toolbox\\Blueprints\\' => array($vendorDir . '/rockettheme/toolbox/Blueprints/src'),
'RocketTheme\\Toolbox\\ArrayTraits\\' => array($vendorDir . '/rockettheme/toolbox/ArrayTraits/src'),
'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
'Grav\\' => array($baseDir . '/system/src/Grav'),
);
+55
View File
@@ -0,0 +1,55 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit9c7eca5a86e870ee40cf566b71462ccd
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit9c7eca5a86e870ee40cf566b71462ccd', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit9c7eca5a86e870ee40cf566b71462ccd', 'loadClassLoader'));
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
$loader->register(true);
$includeFiles = require __DIR__ . '/autoload_files.php';
foreach ($includeFiles as $file) {
composerRequire9c7eca5a86e870ee40cf566b71462ccd($file);
}
return $loader;
}
}
function composerRequire9c7eca5a86e870ee40cf566b71462ccd($file)
{
require $file;
}
+1030
View File
File diff suppressed because it is too large Load Diff
+18
View File
@@ -0,0 +1,18 @@
# How to Contribute
## Reporting Issues
Issues can be reported via the [Github Issues](https://github.com/donatj/PhpUserAgent/issues) page.
- **Detail is key**: If a browser is being misidentified, one or more sample user agent strings are key to getting it resolved.
- **Missing Browser**: Is it modern? What is it being misidentified as? There are a lot of dead browsers out there that there is no reason to support.
Please do not file any requests for OS version identification. It is not a desired feature.
## Pull Requests
Pull requests are truly appreciated. While I try my best to stay on top of browsers hitting the market it is still a difficult task.
- **Formatting**: Indentation **must** use tabs. Please try to match internal formatting and spacing to existing code.
- **Tests**: If you're adding support for a new browser be sure to add test user agents for if at all possible ***every platform*** the browser is available on. Untested code will take much longer to be merged.
- **Terseness**: Try to be terse. Be clever. Take up as little space as possible. The point of this project initially was to be smaller than the other guys.
+22
View File
@@ -0,0 +1,22 @@
The MIT License
===============
Copyright (c) 2013 Jesse G. Donat
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+114
View File
@@ -0,0 +1,114 @@
# PHP User Agent Parser
[![Latest Stable Version](https://poser.pugx.org/donatj/phpuseragentparser/v/stable.png)](https://packagist.org/packages/donatj/phpuseragentparser) [![Total Downloads](https://poser.pugx.org/donatj/phpuseragentparser/downloads.png)](https://packagist.org/packages/donatj/phpuseragentparser) [![Latest Unstable Version](https://poser.pugx.org/donatj/phpuseragentparser/v/unstable.png)](https://packagist.org/packages/donatj/phpuseragentparser) [![License](https://poser.pugx.org/donatj/phpuseragentparser/license.png)](https://packagist.org/packages/donatj/phpuseragentparser)
[![Build Status](https://travis-ci.org/donatj/PhpUserAgent.png?branch=master)](https://travis-ci.org/donatj/PhpUserAgent)
[![HHVM Status](http://hhvm.h4cc.de/badge/donatj/phpuseragentparser.png)](http://hhvm.h4cc.de/package/donatj/phpuseragentparser) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/donatj/PhpUserAgent/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/donatj/PhpUserAgent/?branch=master)
## What It Is
A simple, streamlined PHP user-agent parser!
Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
## Why Use This
You have your choice in user-agent parsers. This one detects **all modern browsers** in a very light, quick, understandable fashion.
It is less than 200 lines of code, and consists of just three regular expressions!
It can also correctly identify exotic versions of IE others fail on.
It offers 100% unit test coverage, is installable via Composer, and is very easy to use.
## What It Does Not Do
### OS Versions
User-agent strings **are not** a reliable source of OS Version!
- Many agents simply don't send the information.
- Others provide varying levels of accuracy.
- Parsing Windows versions alone almost nearly doubles the size of the code.
I'm much more interested in keeping this thing *tiny* and accurate than adding niché features and would rather focus on things that can be **done well**.
All that said, there is the start of a [branch to do it](https://github.com/donatj/PhpUserAgent/tree/os_version_detection) I created for a client if you want to poke it, I update it from time to time, but frankly if you need to *reliably detect OS Version*, using user-agent isn't the way to do it. I'd go with JavaScript.
## Requirements
- PHP 5.3.0+
## Installing
PHP User Agent is available through Packagist via Composer.
```json
{
"require": {
"donatj/phpuseragentparser": "*"
}
}
```
## Sample Usage
```php
$ua_info = parse_user_agent();
/*
array(
'platform' => '[Detected Platform]',
'browser' => '[Detected Browser]',
'version' => '[Detected Browser Version]',
);
*/
```
## Currently Detected Platforms
- Desktop
- Windows
- Linux
- Macintosh
- Chrome OS
- Mobile
- Android
- iPhone
- iPad / iPod Touch
- Windows Phone OS
- Kindle
- Kindle Fire
- BlackBerry
- Playbook
- Tizen
- Console
- Nintendo 3DS
- New Nintendo 3DS
- Nintendo Wii
- Nintendo WiiU
- PlayStation 3
- PlayStation 4
- PlayStation Vita
- Xbox 360
- Xbox One
## Currently Detected Browsers
- Android Browser
- BlackBerry Browser
- Camino
- Kindle / Silk
- Firefox / Iceweasel
- Safari
- Internet Explorer
- IEMobile
- Chrome
- Opera
- Midori
- Vivaldi
- TizenBrowser
- Lynx
- Wget
- Curl
More information is available at [Donat Studios](http://donatstudios.com/PHP-Parser-HTTP_USER_AGENT).
@@ -0,0 +1,167 @@
<?php
/**
* Parses a user agent string into its important parts
*
* @author Jesse G. Donat <donatj@gmail.com>
* @link https://github.com/donatj/PhpUserAgent
* @link http://donatstudios.com/PHP-Parser-HTTP_USER_AGENT
* @param string|null $u_agent User agent string to parse or null. Uses $_SERVER['HTTP_USER_AGENT'] on NULL
* @throws InvalidArgumentException on not having a proper user agent to parse.
* @return string[] an array with browser, version and platform keys
*/
function parse_user_agent( $u_agent = null ) {
if( is_null($u_agent) ) {
if( isset($_SERVER['HTTP_USER_AGENT']) ) {
$u_agent = $_SERVER['HTTP_USER_AGENT'];
} else {
throw new \InvalidArgumentException('parse_user_agent requires a user agent');
}
}
$platform = null;
$browser = null;
$version = null;
$empty = array( 'platform' => $platform, 'browser' => $browser, 'version' => $version );
if( !$u_agent ) return $empty;
if( preg_match('/\((.*?)\)/im', $u_agent, $parent_matches) ) {
preg_match_all('/(?P<platform>BB\d+;|Android|CrOS|Tizen|iPhone|iPad|iPod|Linux|Macintosh|Windows(\ Phone)?|Silk|linux-gnu|BlackBerry|PlayBook|(New\ )?Nintendo\ (WiiU?|3?DS)|Xbox(\ One)?)
(?:\ [^;]*)?
(?:;|$)/imx', $parent_matches[1], $result, PREG_PATTERN_ORDER);
$priority = array( 'Xbox One', 'Xbox', 'Windows Phone', 'Tizen', 'Android' );
$result['platform'] = array_unique($result['platform']);
if( count($result['platform']) > 1 ) {
if( $keys = array_intersect($priority, $result['platform']) ) {
$platform = reset($keys);
} else {
$platform = $result['platform'][0];
}
} elseif( isset($result['platform'][0]) ) {
$platform = $result['platform'][0];
}
}
if( $platform == 'linux-gnu' ) {
$platform = 'Linux';
} elseif( $platform == 'CrOS' ) {
$platform = 'Chrome OS';
}
preg_match_all('%(?P<browser>Camino|Kindle(\ Fire)?|Firefox|Iceweasel|Safari|MSIE|Trident|AppleWebKit|TizenBrowser|Chrome|
Vivaldi|IEMobile|Opera|OPR|Silk|Midori|Edge|CriOS|
Baiduspider|Googlebot|YandexBot|bingbot|Lynx|Version|Wget|curl|
NintendoBrowser|PLAYSTATION\ (\d|Vita)+)
(?:\)?;?)
(?:(?:[:/ ])(?P<version>[0-9A-Z.]+)|/(?:[A-Z]*))%ix',
$u_agent, $result, PREG_PATTERN_ORDER);
// If nothing matched, return null (to avoid undefined index errors)
if( !isset($result['browser'][0]) || !isset($result['version'][0]) ) {
if( preg_match('%^(?!Mozilla)(?P<browser>[A-Z0-9\-]+)(/(?P<version>[0-9A-Z.]+))?%ix', $u_agent, $result) ) {
return array( 'platform' => $platform ?: null, 'browser' => $result['browser'], 'version' => isset($result['version']) ? $result['version'] ?: null : null );
}
return $empty;
}
if( preg_match('/rv:(?P<version>[0-9A-Z.]+)/si', $u_agent, $rv_result) ) {
$rv_result = $rv_result['version'];
}
$browser = $result['browser'][0];
$version = $result['version'][0];
$lowerBrowser = array_map('strtolower', $result['browser']);
$find = function ( $search, &$key ) use ( $lowerBrowser ) {
$xkey = array_search(strtolower($search), $lowerBrowser);
if( $xkey !== false ) {
$key = $xkey;
return true;
}
return false;
};
$key = 0;
$ekey = 0;
if( $browser == 'Iceweasel' ) {
$browser = 'Firefox';
} elseif( $find('Playstation Vita', $key) ) {
$platform = 'PlayStation Vita';
$browser = 'Browser';
} elseif( $find('Kindle Fire', $key) || $find('Silk', $key) ) {
$browser = $result['browser'][$key] == 'Silk' ? 'Silk' : 'Kindle';
$platform = 'Kindle Fire';
if( !($version = $result['version'][$key]) || !is_numeric($version[0]) ) {
$version = $result['version'][array_search('Version', $result['browser'])];
}
} elseif( $find('NintendoBrowser', $key) || $platform == 'Nintendo 3DS' ) {
$browser = 'NintendoBrowser';
$version = $result['version'][$key];
} elseif( $find('Kindle', $key) ) {
$browser = $result['browser'][$key];
$platform = 'Kindle';
$version = $result['version'][$key];
} elseif( $find('OPR', $key) ) {
$browser = 'Opera Next';
$version = $result['version'][$key];
} elseif( $find('Opera', $key) ) {
$browser = 'Opera';
$find('Version', $key);
$version = $result['version'][$key];
} elseif( $find('Midori', $key) ) {
$browser = 'Midori';
$version = $result['version'][$key];
} elseif( $browser == 'MSIE' || ($rv_result && $find('Trident', $key)) || $find('Edge', $ekey) ) {
$browser = 'MSIE';
if( $find('IEMobile', $key) ) {
$browser = 'IEMobile';
$version = $result['version'][$key];
} elseif( $ekey ) {
$version = $result['version'][$ekey];
} else {
$version = $rv_result ?: $result['version'][$key];
}
if( version_compare($version, '12', '>=') ) {
$browser = 'Edge';
}
} elseif( $find('Vivaldi', $key) ) {
$browser = 'Vivaldi';
$version = $result['version'][$key];
} elseif( $find('Chrome', $key) || $find('CriOS', $key) ) {
$browser = 'Chrome';
$version = $result['version'][$key];
} elseif( $browser == 'AppleWebKit' ) {
if( ($platform == 'Android' && !($key = 0)) ) {
$browser = 'Android Browser';
} elseif( strpos($platform, 'BB') === 0 ) {
$browser = 'BlackBerry Browser';
$platform = 'BlackBerry';
} elseif( $platform == 'BlackBerry' || $platform == 'PlayBook' ) {
$browser = 'BlackBerry Browser';
} elseif( $find('Safari', $key) ) {
$browser = 'Safari';
} elseif( $find('TizenBrowser', $key) ) {
$browser = 'TizenBrowser';
}
$find('Version', $key);
$version = $result['version'][$key];
} elseif( $key = preg_grep('/playstation \d/i', array_map('strtolower', $result['browser'])) ) {
$key = reset($key);
$platform = 'PlayStation ' . preg_replace('/[^\d]/i', '', $key);
$browser = 'NetFront';
}
return array( 'platform' => $platform ?: null, 'browser' => $browser ?: null, 'version' => $version ?: null );
}
+20
View File
@@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2013 Emanuil Rusev, erusev.com
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+526
View File
@@ -0,0 +1,526 @@
<?php
#
#
# Parsedown Extra
# https://github.com/erusev/parsedown-extra
#
# (c) Emanuil Rusev
# http://erusev.com
#
# For the full license information, view the LICENSE file that was distributed
# with this source code.
#
#
class ParsedownExtra extends Parsedown
{
# ~
const version = '0.7.0';
# ~
function __construct()
{
if (parent::version < '1.5.0')
{
throw new Exception('ParsedownExtra requires a later version of Parsedown');
}
$this->BlockTypes[':'] []= 'DefinitionList';
$this->BlockTypes['*'] []= 'Abbreviation';
# identify footnote definitions before reference definitions
array_unshift($this->BlockTypes['['], 'Footnote');
# identify footnote markers before before links
array_unshift($this->InlineTypes['['], 'FootnoteMarker');
}
#
# ~
function text($text)
{
$markup = parent::text($text);
# merge consecutive dl elements
$markup = preg_replace('/<\/dl>\s+<dl>\s+/', '', $markup);
# add footnotes
if (isset($this->DefinitionData['Footnote']))
{
$Element = $this->buildFootnoteElement();
$markup .= "\n" . $this->element($Element);
}
return $markup;
}
#
# Blocks
#
#
# Abbreviation
protected function blockAbbreviation($Line)
{
if (preg_match('/^\*\[(.+?)\]:[ ]*(.+?)[ ]*$/', $Line['text'], $matches))
{
$this->DefinitionData['Abbreviation'][$matches[1]] = $matches[2];
$Block = array(
'hidden' => true,
);
return $Block;
}
}
#
# Footnote
protected function blockFootnote($Line)
{
if (preg_match('/^\[\^(.+?)\]:[ ]?(.*)$/', $Line['text'], $matches))
{
$Block = array(
'label' => $matches[1],
'text' => $matches[2],
'hidden' => true,
);
return $Block;
}
}
protected function blockFootnoteContinue($Line, $Block)
{
if ($Line['text'][0] === '[' and preg_match('/^\[\^(.+?)\]:/', $Line['text']))
{
return;
}
if (isset($Block['interrupted']))
{
if ($Line['indent'] >= 4)
{
$Block['text'] .= "\n\n" . $Line['text'];
return $Block;
}
}
else
{
$Block['text'] .= "\n" . $Line['text'];
return $Block;
}
}
protected function blockFootnoteComplete($Block)
{
$this->DefinitionData['Footnote'][$Block['label']] = array(
'text' => $Block['text'],
'count' => null,
'number' => null,
);
return $Block;
}
#
# Definition List
protected function blockDefinitionList($Line, $Block)
{
if ( ! isset($Block) or isset($Block['type']))
{
return;
}
$Element = array(
'name' => 'dl',
'handler' => 'elements',
'text' => array(),
);
$terms = explode("\n", $Block['element']['text']);
foreach ($terms as $term)
{
$Element['text'] []= array(
'name' => 'dt',
'handler' => 'line',
'text' => $term,
);
}
$Block['element'] = $Element;
$Block = $this->addDdElement($Line, $Block);
return $Block;
}
protected function blockDefinitionListContinue($Line, array $Block)
{
if ($Line['text'][0] === ':')
{
$Block = $this->addDdElement($Line, $Block);
return $Block;
}
else
{
if (isset($Block['interrupted']) and $Line['indent'] === 0)
{
return;
}
if (isset($Block['interrupted']))
{
$Block['dd']['handler'] = 'text';
$Block['dd']['text'] .= "\n\n";
unset($Block['interrupted']);
}
$text = substr($Line['body'], min($Line['indent'], 4));
$Block['dd']['text'] .= "\n" . $text;
return $Block;
}
}
#
# Header
protected function blockHeader($Line)
{
$Block = parent::blockHeader($Line);
if (preg_match('/[ #]*{('.$this->regexAttribute.'+)}[ ]*$/', $Block['element']['text'], $matches, PREG_OFFSET_CAPTURE))
{
$attributeString = $matches[1][0];
$Block['element']['attributes'] = $this->parseAttributeData($attributeString);
$Block['element']['text'] = substr($Block['element']['text'], 0, $matches[0][1]);
}
return $Block;
}
#
# Markup
protected function blockMarkupComplete($Block)
{
if ( ! isset($Block['void']))
{
$Block['markup'] = $this->processTag($Block['markup']);
}
return $Block;
}
#
# Setext
protected function blockSetextHeader($Line, array $Block = null)
{
$Block = parent::blockSetextHeader($Line, $Block);
if (preg_match('/[ ]*{('.$this->regexAttribute.'+)}[ ]*$/', $Block['element']['text'], $matches, PREG_OFFSET_CAPTURE))
{
$attributeString = $matches[1][0];
$Block['element']['attributes'] = $this->parseAttributeData($attributeString);
$Block['element']['text'] = substr($Block['element']['text'], 0, $matches[0][1]);
}
return $Block;
}
#
# Inline Elements
#
#
# Footnote Marker
protected function inlineFootnoteMarker($Excerpt)
{
if (preg_match('/^\[\^(.+?)\]/', $Excerpt['text'], $matches))
{
$name = $matches[1];
if ( ! isset($this->DefinitionData['Footnote'][$name]))
{
return;
}
$this->DefinitionData['Footnote'][$name]['count'] ++;
if ( ! isset($this->DefinitionData['Footnote'][$name]['number']))
{
$this->DefinitionData['Footnote'][$name]['number'] = ++ $this->footnoteCount; # » &
}
$Element = array(
'name' => 'sup',
'attributes' => array('id' => 'fnref'.$this->DefinitionData['Footnote'][$name]['count'].':'.$name),
'handler' => 'element',
'text' => array(
'name' => 'a',
'attributes' => array('href' => '#fn:'.$name, 'class' => 'footnote-ref'),
'text' => $this->DefinitionData['Footnote'][$name]['number'],
),
);
return array(
'extent' => strlen($matches[0]),
'element' => $Element,
);
}
}
private $footnoteCount = 0;
#
# Link
protected function inlineLink($Excerpt)
{
$Link = parent::inlineLink($Excerpt);
$remainder = substr($Excerpt['text'], $Link['extent']);
if (preg_match('/^[ ]*{('.$this->regexAttribute.'+)}/', $remainder, $matches))
{
$Link['element']['attributes'] += $this->parseAttributeData($matches[1]);
$Link['extent'] += strlen($matches[0]);
}
return $Link;
}
#
# ~
#
protected function unmarkedText($text)
{
$text = parent::unmarkedText($text);
if (isset($this->DefinitionData['Abbreviation']))
{
foreach ($this->DefinitionData['Abbreviation'] as $abbreviation => $meaning)
{
$pattern = '/\b'.preg_quote($abbreviation).'\b/';
$text = preg_replace($pattern, '<abbr title="'.$meaning.'">'.$abbreviation.'</abbr>', $text);
}
}
return $text;
}
#
# Util Methods
#
protected function addDdElement(array $Line, array $Block)
{
$text = substr($Line['text'], 1);
$text = trim($text);
unset($Block['dd']);
$Block['dd'] = array(
'name' => 'dd',
'handler' => 'line',
'text' => $text,
);
if (isset($Block['interrupted']))
{
$Block['dd']['handler'] = 'text';
unset($Block['interrupted']);
}
$Block['element']['text'] []= & $Block['dd'];
return $Block;
}
protected function buildFootnoteElement()
{
$Element = array(
'name' => 'div',
'attributes' => array('class' => 'footnotes'),
'handler' => 'elements',
'text' => array(
array(
'name' => 'hr',
),
array(
'name' => 'ol',
'handler' => 'elements',
'text' => array(),
),
),
);
uasort($this->DefinitionData['Footnote'], 'self::sortFootnotes');
foreach ($this->DefinitionData['Footnote'] as $definitionId => $DefinitionData)
{
if ( ! isset($DefinitionData['number']))
{
continue;
}
$text = $DefinitionData['text'];
$text = parent::text($text);
$numbers = range(1, $DefinitionData['count']);
$backLinksMarkup = '';
foreach ($numbers as $number)
{
$backLinksMarkup .= ' <a href="#fnref'.$number.':'.$definitionId.'" rev="footnote" class="footnote-backref">&#8617;</a>';
}
$backLinksMarkup = substr($backLinksMarkup, 1);
if (substr($text, - 4) === '</p>')
{
$backLinksMarkup = '&#160;'.$backLinksMarkup;
$text = substr_replace($text, $backLinksMarkup.'</p>', - 4);
}
else
{
$text .= "\n".'<p>'.$backLinksMarkup.'</p>';
}
$Element['text'][1]['text'] []= array(
'name' => 'li',
'attributes' => array('id' => 'fn:'.$definitionId),
'text' => "\n".$text."\n",
);
}
return $Element;
}
# ~
protected function parseAttributeData($attributeString)
{
$Data = array();
$attributes = preg_split('/[ ]+/', $attributeString, - 1, PREG_SPLIT_NO_EMPTY);
foreach ($attributes as $attribute)
{
if ($attribute[0] === '#')
{
$Data['id'] = substr($attribute, 1);
}
else # "."
{
$classes []= substr($attribute, 1);
}
}
if (isset($classes))
{
$Data['class'] = implode(' ', $classes);
}
return $Data;
}
# ~
protected function processTag($elementMarkup) # recursive
{
# http://stackoverflow.com/q/1148928/200145
libxml_use_internal_errors(true);
$DOMDocument = new DOMDocument;
# http://stackoverflow.com/q/11309194/200145
$elementMarkup = mb_convert_encoding($elementMarkup, 'HTML-ENTITIES', 'UTF-8');
# http://stackoverflow.com/q/4879946/200145
$DOMDocument->loadHTML($elementMarkup);
$DOMDocument->removeChild($DOMDocument->doctype);
$DOMDocument->replaceChild($DOMDocument->firstChild->firstChild->firstChild, $DOMDocument->firstChild);
$elementText = '';
if ($DOMDocument->documentElement->getAttribute('markdown') === '1')
{
foreach ($DOMDocument->documentElement->childNodes as $Node)
{
$elementText .= $DOMDocument->saveHTML($Node);
}
$DOMDocument->documentElement->removeAttribute('markdown');
$elementText = "\n".$this->text($elementText)."\n";
}
else
{
foreach ($DOMDocument->documentElement->childNodes as $Node)
{
$nodeMarkup = $DOMDocument->saveHTML($Node);
if ($Node instanceof DOMElement and ! in_array($Node->nodeName, $this->textLevelElements))
{
$elementText .= $this->processTag($nodeMarkup);
}
else
{
$elementText .= $nodeMarkup;
}
}
}
# because we don't want for markup to get encoded
$DOMDocument->documentElement->nodeValue = 'placeholder';
$markup = $DOMDocument->saveHTML($DOMDocument->documentElement);
$markup = str_replace('placeholder', $elementText, $markup);
return $markup;
}
# ~
protected function sortFootnotes($A, $B) # callback
{
return $A['number'] - $B['number'];
}
#
# Fields
#
protected $regexAttribute = '(?:[#.][-\w]+[ ]*)';
}
+27
View File
@@ -0,0 +1,27 @@
## Parsedown Extra
An extension of [Parsedown](http://parsedown.org) that adds support for [Markdown Extra](https://michelf.ca/projects/php-markdown/extra/).
[[ demo ]](http://parsedown.org/extra/)
### Installation
Include both `Parsedown.php` and `ParsedownExtra.php` or install [the composer package](https://packagist.org/packages/erusev/parsedown-extra).
### Example
``` php
$Extra = new ParsedownExtra();
echo $Extra->text('Hello _Extra_!'); # prints: <p>Hello <em>Extra</em>!</p>
```
### Questions
**Who uses Parsedown Extra?**
[October CMS](http://octobercms.com/), [Bolt CMS](http://bolt.cm/), [Kirby CMS](http://getkirby.com/), [Grav CMS](http://getgrav.org/), [Statamic CMS](http://www.statamic.com/) and [more](https://www.versioneye.com/php/erusev:parsedown-extra/references).
**How can I help?**
Use it, star it, share it and if you feel generous, [donate some money](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=528P3NZQMP8N2).
+20
View File
@@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2013 Emanuil Rusev, erusev.com
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
File diff suppressed because it is too large Load Diff
+57
View File
@@ -0,0 +1,57 @@
## Parsedown
[![Build Status](https://img.shields.io/travis/erusev/parsedown/master.svg?style=flat-square)](https://travis-ci.org/erusev/parsedown)
<!--[![Total Downloads](http://img.shields.io/packagist/dt/erusev/parsedown.svg?style=flat-square)](https://packagist.org/packages/erusev/parsedown)-->
Better Markdown Parser in PHP
[Demo](http://parsedown.org/demo) |
[Benchmarks](http://parsedown.org/speed) |
[Tests](http://parsedown.org/tests/) |
[Documentation](https://github.com/erusev/parsedown/wiki/)
### Features
* Super Fast
* [GitHub flavored](https://help.github.com/articles/github-flavored-markdown)
* Extensible
* Tested in 5.3 to 5.6
* [Markdown Extra extension](https://github.com/erusev/parsedown-extra)
### Installation
Include `Parsedown.php` or install [the composer package](https://packagist.org/packages/erusev/parsedown).
### Example
``` php
$Parsedown = new Parsedown();
echo $Parsedown->text('Hello _Parsedown_!'); # prints: <p>Hello <em>Parsedown</em>!</p>
```
More examples in [the wiki](https://github.com/erusev/parsedown/wiki/) and in [this video tutorial](http://youtu.be/wYZBY8DEikI).
### Questions
**How does Parsedown work?**
It tries to read Markdown like a human. First, it looks at the lines. Its interested in how the lines start. This helps it recognise blocks. It knows, for example, that if a line start with a `-` then it perhaps belong to a list. Once it recognises the blocks, it continues to the content. As it reads, it watches out for special characters. This helps it recognise inline elements (or inlines).
We call this approach "line based". We believe that Parsedown is the first Markdown parser to use it. Since the release of Parsedown, other developers have used the same approach to develop other Markdown parsers in PHP and in other languages.
**Is it compliant with CommonMark?**
It passes most of the CommonMark tests. Most of the tests that don't pass deal with cases that are quite uncommon. Still, as CommonMark matures, compliance should improve.
**Who uses it?**
[phpDocumentor](http://www.phpdoc.org/), [October CMS](http://octobercms.com/), [Bolt CMS](http://bolt.cm/), [Kirby CMS](http://getkirby.com/), [Grav CMS](http://getgrav.org/), [Statamic CMS](http://www.statamic.com/), [RaspberryPi.org](http://www.raspberrypi.org/) and [more](https://www.versioneye.com/php/erusev:parsedown/references).
**How can I help?**
Use it, star it, share it and if you feel generous, [donate](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=528P3NZQMP8N2).
---
You might also like [Caret](http://caret.io) - our Markdown editor for the desktop.
+10
View File
@@ -0,0 +1,10 @@
docs/ export-ignore
examples/ export-ignore
tests/ export-ignore
.gitattributes export-ignore
.gitignore export-ignore
.scrutinizer.yml export-ignore
.travis.yml export-ignore
phpunit.xml.dist export-ignore
CONTRIBUTING.md export-ignore
README.md export-ignore
+11
View File
@@ -0,0 +1,11 @@
If you want to give me some feedback or make a suggestion, create an [issue on GitHub](https://github.com/filp/whoops/issues/new).
If you want to get your hands dirty, great! Here's a couple of steps/guidelines:
- See [a list of possible features to add](https://github.com/filp/whoops/wiki/Possible-features-to-add) for ideas on what can be improved.
- Add tests for your changes (in `tests/`).
- Remember to stick to the existing code style as best as possible. When in doubt, follow `PSR-2`.
- Before investing a lot of time coding, create an issue to get our opinion on your big changes.
- Update the documentation, if applicable.
- If you want to add an integration to a web framework, please [review our guidelines for that](docs/Framework%20Integration.md#contributing-an-integration-with-a-framework).
In `PrettyPageHandler` we are using a Zepto library, but if you are only familiar with jQuery, note that it is pretty much identical.
+19
View File
@@ -0,0 +1,19 @@
#The MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+84
View File
@@ -0,0 +1,84 @@
# whoops
php errors for cool kids
[![Total Downloads](https://img.shields.io/packagist/dm/filp/whoops.svg)](https://packagist.org/packages/filp/whoops)
[![Latest Version](http://img.shields.io/packagist/v/filp/whoops.svg)](https://packagist.org/packages/filp/whoops)
[![Reference Status](https://www.versioneye.com/php/filp:whoops/reference_badge.svg?style=flat)](https://www.versioneye.com/php/filp:whoops/references)
[![Dependency Status](https://www.versioneye.com/php/filp:whoops/1.1.5/badge.svg)](https://www.versioneye.com/php/filp:whoops/1.1.5)
[![Build Status](https://travis-ci.org/filp/whoops.svg?branch=master)](https://travis-ci.org/filp/whoops)
[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/filp/whoops/badges/quality-score.png?s=6225c36f2a2dd1fdca11ecc7b10b29105c8c62bd)](https://scrutinizer-ci.com/g/filp/whoops)
[![Code Coverage](https://scrutinizer-ci.com/g/filp/whoops/badges/coverage.png?s=711feb2069144d252d111b211965ffb19a7d09a8)](https://scrutinizer-ci.com/g/filp/whoops)
-----
![Whoops!](http://i.imgur.com/xvwyvOY.png)
**whoops** is an error handler base/framework for PHP. Out-of-the-box, it provides a pretty
error interface that helps you debug your web projects, but at heart it's a simple yet
powerful stacked error handling system.
## (current) Features
- Flexible, stack-based error handling
- Stand-alone library with (currently) no required dependencies
- Simple API for dealing with exceptions, trace frames & their data
- Includes a pretty rad error page for your webapp projects
- Includes the ability to [open referenced files directly in your editor and IDE](docs/Open%20Files%20In%20An%20Editor.md)
- Includes handlers for different response formats (JSON, XML, SOAP)
- Includes a Silex Service Provider for painless integration with [Silex](http://silex.sensiolabs.org/)
- Includes a Phalcon Service Provider for painless integration with [Phalcon](http://phalconphp.com/)
- Includes a Module for equally painless integration with [Zend Framework 2](http://framework.zend.com/)
- Easy to extend and integrate with existing libraries
- Clean, well-structured & tested code-base
## Installing
If you use Laravel 4, you already have Whoops. There are also community-provided instructions on how to integrate Whoops into
[Silex](docs/Framework%20Integration.md#integrating-with-silex),
[Silex 2](https://github.com/texthtml/whoops-silex),
[Phalcon](docs/Framework%20Integration.md#integrating-with-phalcon),
[Laravel 3](https://gist.github.com/hugomrdias/5169713#file-start-php),
[Laravel 5](https://mattstauffer.co/blog/bringing-whoops-back-to-laravel-5),
[CakePHP 2](https://github.com/oldskool/WhoopsCakephp/tree/cake2),
[CakePHP 3](https://github.com/oldskool/WhoopsCakephp),
[Zend Framework 2](https://github.com/ghislainf/zf2-whoops),
[Yii 1](https://github.com/igorsantos07/yii-whoops),
[FuelPHP](https://github.com/indigophp/fuel-whoops),
[Slim](https://github.com/zeuxisoo/php-slim-whoops/),
[Pimple](https://github.com/texthtml/whoops-pimple),
or any framework consuming [StackPHP middlewares](https://github.com/thecodingmachine/whoops-stackphp).
If you are not using any of these frameworks, here's a very simple way to install:
1. Use [Composer](http://getcomposer.org) to install Whoops into your project:
```bash
composer require filp/whoops
```
1. Register the pretty handler in your code:
```php
$whoops = new \Whoops\Run;
$whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler);
$whoops->register();
```
For more options, have a look at the **example files** in `examples/` to get a feel for how things work. Also take a look at the [API Documentation](docs/API%20Documentation.md) and the list of available handers below.
### Available Handlers
**whoops** currently ships with the following built-in handlers, available in the `Whoops\Handler` namespace:
- [`PrettyPageHandler`](https://github.com/filp/whoops/blob/master/src/Whoops/Handler/PrettyPageHandler.php) - Shows a pretty error page when something goes pants-up
- [`PlainTextHandler`](https://github.com/filp/whoops/blob/master/src/Whoops/Handler/PlainTextHandler.php) - Outputs plain text message for use in CLI applications
- [`CallbackHandler`](https://github.com/filp/whoops/blob/master/src/Whoops/Handler/CallbackHandler.php) - Wraps a closure or other callable as a handler. You do not need to use this handler explicitly, **whoops** will automatically wrap any closure or callable you pass to `Whoops\Run::pushHandler`
- [`JsonResponseHandler`](https://github.com/filp/whoops/blob/master/src/Whoops/Handler/JsonResponseHandler.php) - Captures exceptions and returns information on them as a JSON string. Can be used to, for example, play nice with AJAX requests.
- [`XmlResponseHandler`](https://github.com/filp/whoops/blob/master/src/Whoops/Handler/XmlResponseHandler.php) - Captures exceptions and returns information on them as a XML string. Can be used to, for example, play nice with AJAX requests.
- [`SoapResponseHandler`](https://github.com/filp/whoops/blob/master/src/Whoops/Handler/SoapResponseHandler.php) - Captures exceptions and returns information on them as a SOAP string. Might be used for SOAP Webservices.
## Authors
This library was primarily developed by [Filipe Dobreira](https://github.com/filp), and is currently maintained by [Denis Sokolov](https://github.com/denis-sokolov). A lot of awesome fixes and enhancements were also sent in by [various contributors](https://github.com/filp/whoops/contributors).
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/filp/whoops/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
@@ -0,0 +1,17 @@
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Exception;
use ErrorException as BaseErrorException;
/**
* Wraps ErrorException; mostly used for typing (at least now)
* to easily cleanup the stack trace of redundant info.
*/
class ErrorException extends BaseErrorException
{
}
+74
View File
@@ -0,0 +1,74 @@
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Exception;
class Formatter
{
/**
* Returns all basic information about the exception in a simple array
* for further convertion to other languages
* @param Inspector $inspector
* @param bool $shouldAddTrace
* @return array
*/
public static function formatExceptionAsDataArray(Inspector $inspector, $shouldAddTrace)
{
$exception = $inspector->getException();
$response = array(
'type' => get_class($exception),
'message' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
);
if ($shouldAddTrace) {
$frames = $inspector->getFrames();
$frameData = array();
foreach ($frames as $frame) {
/** @var Frame $frame */
$frameData[] = array(
'file' => $frame->getFile(),
'line' => $frame->getLine(),
'function' => $frame->getFunction(),
'class' => $frame->getClass(),
'args' => $frame->getArgs(),
);
}
$response['trace'] = $frameData;
}
return $response;
}
public static function formatExceptionPlain(Inspector $inspector)
{
$message = $inspector->getException()->getMessage();
$frames = $inspector->getFrames();
$plain = $inspector->getExceptionName();
$plain .= ' thrown with message "';
$plain .= $message;
$plain .= '"'."\n\n";
$plain .= "Stacktrace:\n";
foreach ($frames as $i => $frame) {
$plain .= "#". (count($frames) - $i - 1). " ";
$plain .= $frame->getClass() ?: '';
$plain .= $frame->getClass() && $frame->getFunction() ? ":" : "";
$plain .= $frame->getFunction() ?: '';
$plain .= ' in ';
$plain .= ($frame->getFile() ?: '<#unknown>');
$plain .= ':';
$plain .= (int) $frame->getLine(). "\n";
}
return $plain;
}
}
+269
View File
@@ -0,0 +1,269 @@
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Exception;
use InvalidArgumentException;
use Serializable;
class Frame implements Serializable
{
/**
* @var array
*/
protected $frame;
/**
* @var string
*/
protected $fileContentsCache;
/**
* @var array[]
*/
protected $comments = array();
/**
* @param array[]
*/
public function __construct(array $frame)
{
$this->frame = $frame;
}
/**
* @param bool $shortened
* @return string|null
*/
public function getFile($shortened = false)
{
if (empty($this->frame['file'])) {
return null;
}
$file = $this->frame['file'];
// Check if this frame occurred within an eval().
// @todo: This can be made more reliable by checking if we've entered
// eval() in a previous trace, but will need some more work on the upper
// trace collector(s).
if (preg_match('/^(.*)\((\d+)\) : (?:eval\(\)\'d|assert) code$/', $file, $matches)) {
$file = $this->frame['file'] = $matches[1];
$this->frame['line'] = (int) $matches[2];
}
if ($shortened && is_string($file)) {
// Replace the part of the path that all frames have in common, and add 'soft hyphens' for smoother line-breaks.
$dirname = dirname(dirname(dirname(dirname(dirname(dirname(__DIR__))))));
$file = str_replace($dirname, "&hellip;", $file);
$file = str_replace("/", "/&shy;", $file);
}
return $file;
}
/**
* @return int|null
*/
public function getLine()
{
return isset($this->frame['line']) ? $this->frame['line'] : null;
}
/**
* @return string|null
*/
public function getClass()
{
return isset($this->frame['class']) ? $this->frame['class'] : null;
}
/**
* @return string|null
*/
public function getFunction()
{
return isset($this->frame['function']) ? $this->frame['function'] : null;
}
/**
* @return array
*/
public function getArgs()
{
return isset($this->frame['args']) ? (array) $this->frame['args'] : array();
}
/**
* Returns the full contents of the file for this frame,
* if it's known.
* @return string|null
*/
public function getFileContents()
{
if ($this->fileContentsCache === null && $filePath = $this->getFile()) {
// Leave the stage early when 'Unknown' is passed
// this would otherwise raise an exception when
// open_basedir is enabled.
if ($filePath === "Unknown") {
return null;
}
// Return null if the file doesn't actually exist.
if (!is_file($filePath)) {
return null;
}
$this->fileContentsCache = file_get_contents($filePath);
}
return $this->fileContentsCache;
}
/**
* Adds a comment to this frame, that can be received and
* used by other handlers. For example, the PrettyPage handler
* can attach these comments under the code for each frame.
*
* An interesting use for this would be, for example, code analysis
* & annotations.
*
* @param string $comment
* @param string $context Optional string identifying the origin of the comment
*/
public function addComment($comment, $context = 'global')
{
$this->comments[] = array(
'comment' => $comment,
'context' => $context,
);
}
/**
* Returns all comments for this frame. Optionally allows
* a filter to only retrieve comments from a specific
* context.
*
* @param string $filter
* @return array[]
*/
public function getComments($filter = null)
{
$comments = $this->comments;
if ($filter !== null) {
$comments = array_filter($comments, function ($c) use ($filter) {
return $c['context'] == $filter;
});
}
return $comments;
}
/**
* Returns the array containing the raw frame data from which
* this Frame object was built
*
* @return array
*/
public function getRawFrame()
{
return $this->frame;
}
/**
* Returns the contents of the file for this frame as an
* array of lines, and optionally as a clamped range of lines.
*
* NOTE: lines are 0-indexed
*
* @example
* Get all lines for this file
* $frame->getFileLines(); // => array( 0 => '<?php', 1 => '...', ...)
* @example
* Get one line for this file, starting at line 10 (zero-indexed, remember!)
* $frame->getFileLines(9, 1); // array( 10 => '...', 11 => '...')
*
* @throws InvalidArgumentException if $length is less than or equal to 0
* @param int $start
* @param int $length
* @return string[]|null
*/
public function getFileLines($start = 0, $length = null)
{
if (null !== ($contents = $this->getFileContents())) {
$lines = explode("\n", $contents);
// Get a subset of lines from $start to $end
if ($length !== null) {
$start = (int) $start;
$length = (int) $length;
if ($start < 0) {
$start = 0;
}
if ($length <= 0) {
throw new InvalidArgumentException(
"\$length($length) cannot be lower or equal to 0"
);
}
$lines = array_slice($lines, $start, $length, true);
}
return $lines;
}
}
/**
* Implements the Serializable interface, with special
* steps to also save the existing comments.
*
* @see Serializable::serialize
* @return string
*/
public function serialize()
{
$frame = $this->frame;
if (!empty($this->comments)) {
$frame['_comments'] = $this->comments;
}
return serialize($frame);
}
/**
* Unserializes the frame data, while also preserving
* any existing comment data.
*
* @see Serializable::unserialize
* @param string $serializedFrame
*/
public function unserialize($serializedFrame)
{
$frame = unserialize($serializedFrame);
if (!empty($frame['_comments'])) {
$this->comments = $frame['_comments'];
unset($frame['_comments']);
}
$this->frame = $frame;
}
/**
* Compares Frame against one another
* @param Frame $frame
* @return bool
*/
public function equals(Frame $frame)
{
if (!$this->getFile() || $this->getFile() === 'Unknown' || !$this->getLine()) {
return false;
}
return $frame->getFile() === $this->getFile() && $frame->getLine() === $this->getLine();
}
}
@@ -0,0 +1,191 @@
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Exception;
use ArrayAccess;
use ArrayIterator;
use Countable;
use IteratorAggregate;
use Serializable;
use UnexpectedValueException;
/**
* Exposes a fluent interface for dealing with an ordered list
* of stack-trace frames.
*/
class FrameCollection implements ArrayAccess, IteratorAggregate, Serializable, Countable
{
/**
* @var array[]
*/
private $frames;
/**
* @param array $frames
*/
public function __construct(array $frames)
{
$this->frames = array_map(function ($frame) {
return new Frame($frame);
}, $frames);
}
/**
* Filters frames using a callable, returns the same FrameCollection
*
* @param callable $callable
* @return FrameCollection
*/
public function filter($callable)
{
$this->frames = array_filter($this->frames, $callable);
return $this;
}
/**
* Map the collection of frames
*
* @param callable $callable
* @return FrameCollection
*/
public function map($callable)
{
// Contain the map within a higher-order callable
// that enforces type-correctness for the $callable
$this->frames = array_map(function ($frame) use ($callable) {
$frame = call_user_func($callable, $frame);
if (!$frame instanceof Frame) {
throw new UnexpectedValueException(
"Callable to " . __METHOD__ . " must return a Frame object"
);
}
return $frame;
}, $this->frames);
return $this;
}
/**
* Returns an array with all frames, does not affect
* the internal array.
*
* @todo If this gets any more complex than this,
* have getIterator use this method.
* @see FrameCollection::getIterator
* @return array
*/
public function getArray()
{
return $this->frames;
}
/**
* @see IteratorAggregate::getIterator
* @return ArrayIterator
*/
public function getIterator()
{
return new ArrayIterator($this->frames);
}
/**
* @see ArrayAccess::offsetExists
* @param int $offset
*/
public function offsetExists($offset)
{
return isset($this->frames[$offset]);
}
/**
* @see ArrayAccess::offsetGet
* @param int $offset
*/
public function offsetGet($offset)
{
return $this->frames[$offset];
}
/**
* @see ArrayAccess::offsetSet
* @param int $offset
*/
public function offsetSet($offset, $value)
{
throw new \Exception(__CLASS__ . ' is read only');
}
/**
* @see ArrayAccess::offsetUnset
* @param int $offset
*/
public function offsetUnset($offset)
{
throw new \Exception(__CLASS__ . ' is read only');
}
/**
* @see Countable::count
* @return int
*/
public function count()
{
return count($this->frames);
}
/**
* @see Serializable::serialize
* @return string
*/
public function serialize()
{
return serialize($this->frames);
}
/**
* @see Serializable::unserialize
* @param string $serializedFrames
*/
public function unserialize($serializedFrames)
{
$this->frames = unserialize($serializedFrames);
}
/**
* @param Frame[] $frames Array of Frame instances, usually from $e->getPrevious()
*/
public function prependFrames(array $frames)
{
$this->frames = array_merge($frames, $this->frames);
}
/**
* Gets the innermost part of stack trace that is not the same as that of outer exception
*
* @param FrameCollection $parentFrames Outer exception frames to compare tail against
* @return Frame[]
*/
public function topDiff(FrameCollection $parentFrames)
{
$diff = $this->frames;
$parentFrames = $parentFrames->getArray();
$p = count($parentFrames)-1;
for ($i = count($diff)-1; $i >= 0 && $p >= 0; $i--) {
/** @var Frame $tailFrame */
$tailFrame = $diff[$i];
if ($tailFrame->equals($parentFrames[$p])) {
unset($diff[$i]);
}
$p--;
}
return $diff;
}
}
+209
View File
@@ -0,0 +1,209 @@
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Exception;
use Exception;
class Inspector
{
/**
* @var Exception
*/
private $exception;
/**
* @var \Whoops\Exception\FrameCollection
*/
private $frames;
/**
* @var \Whoops\Exception\Inspector
*/
private $previousExceptionInspector;
/**
* @param Exception $exception The exception to inspect
*/
public function __construct(Exception $exception)
{
$this->exception = $exception;
}
/**
* @return Exception
*/
public function getException()
{
return $this->exception;
}
/**
* @return string
*/
public function getExceptionName()
{
return get_class($this->exception);
}
/**
* @return string
*/
public function getExceptionMessage()
{
return $this->exception->getMessage();
}
/**
* Does the wrapped Exception has a previous Exception?
* @return bool
*/
public function hasPreviousException()
{
return $this->previousExceptionInspector || $this->exception->getPrevious();
}
/**
* Returns an Inspector for a previous Exception, if any.
* @todo Clean this up a bit, cache stuff a bit better.
* @return Inspector
*/
public function getPreviousExceptionInspector()
{
if ($this->previousExceptionInspector === null) {
$previousException = $this->exception->getPrevious();
if ($previousException) {
$this->previousExceptionInspector = new Inspector($previousException);
}
}
return $this->previousExceptionInspector;
}
/**
* Returns an iterator for the inspected exception's
* frames.
* @return \Whoops\Exception\FrameCollection
*/
public function getFrames()
{
if ($this->frames === null) {
$frames = $this->getTrace($this->exception);
// If we're handling an ErrorException thrown by Whoops,
// get rid of the last frame, which matches the handleError method,
// and do not add the current exception to trace. We ensure that
// the next frame does have a filename / linenumber, though.
if ($this->exception instanceof ErrorException && empty($frames[1]['line'])) {
$frames = array($this->getFrameFromError($this->exception));
} else {
$firstFrame = $this->getFrameFromException($this->exception);
array_unshift($frames, $firstFrame);
}
$this->frames = new FrameCollection($frames);
if ($previousInspector = $this->getPreviousExceptionInspector()) {
// Keep outer frame on top of the inner one
$outerFrames = $this->frames;
$newFrames = clone $previousInspector->getFrames();
// I assume it will always be set, but let's be safe
if (isset($newFrames[0])) {
$newFrames[0]->addComment(
$previousInspector->getExceptionMessage(),
'Exception message:'
);
}
$newFrames->prependFrames($outerFrames->topDiff($newFrames));
$this->frames = $newFrames;
}
}
return $this->frames;
}
/**
* Gets the backgrace from an exception.
*
* If xdebug is installed
*
* @param Exception $e
* @return array
*/
protected function getTrace(\Exception $e)
{
$traces = $e->getTrace();
// Get trace from xdebug if enabled, failure exceptions only trace to the shutdown handler by default
if (!$e instanceof \ErrorException) {
return $traces;
}
switch ($e->getSeverity()) {
case E_ERROR:
case E_RECOVERABLE_ERROR:
case E_PARSE:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_USER_ERROR:
$fatal = true;
break;
default:
$fatal = false;
break;
}
if (!$fatal) {
return $traces;
}
if (!extension_loaded('xdebug') || !xdebug_is_enabled()) {
return array();
}
// Use xdebug to get the full stack trace and remove the shutdown handler stack trace
$stack = array_reverse(xdebug_get_function_stack());
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
$traces = array_diff_key($stack, $trace);
return $traces;
}
/**
* Given an exception, generates an array in the format
* generated by Exception::getTrace()
* @param Exception $exception
* @return array
*/
protected function getFrameFromException(Exception $exception)
{
return array(
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'class' => get_class($exception),
'args' => array(
$exception->getMessage(),
),
);
}
/**
* Given an error, generates an array in the format
* generated by ErrorException
* @param ErrorException $exception
* @return array
*/
protected function getFrameFromError(ErrorException $exception)
{
return array(
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'class' => null,
'args' => array(),
);
}
}
@@ -0,0 +1,52 @@
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Handler;
use InvalidArgumentException;
/**
* Wrapper for Closures passed as handlers. Can be used
* directly, or will be instantiated automagically by Whoops\Run
* if passed to Run::pushHandler
*/
class CallbackHandler extends Handler
{
/**
* @var callable
*/
protected $callable;
/**
* @throws InvalidArgumentException If argument is not callable
* @param callable $callable
*/
public function __construct($callable)
{
if (!is_callable($callable)) {
throw new InvalidArgumentException(
'Argument to ' . __METHOD__ . ' must be valid callable'
);
}
$this->callable = $callable;
}
/**
* @return int|null
*/
public function handle()
{
$exception = $this->getException();
$inspector = $this->getInspector();
$run = $this->getRun();
$callable = $this->callable;
// invoke the callable directly, to get simpler stacktraces (in comparison to call_user_func).
// this assumes that $callable is a properly typed php-callable, which we check in __construct().
return $callable($exception, $inspector, $run);
}
}
+89
View File
@@ -0,0 +1,89 @@
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Handler;
use Exception;
use Whoops\Exception\Inspector;
use Whoops\Run;
/**
* Abstract implementation of a Handler.
*/
abstract class Handler implements HandlerInterface
{
/**
* Return constants that can be returned from Handler::handle
* to message the handler walker.
*/
const DONE = 0x10; // returning this is optional, only exists for
// semantic purposes
const LAST_HANDLER = 0x20;
const QUIT = 0x30;
/**
* @var Run
*/
private $run;
/**
* @var Inspector $inspector
*/
private $inspector;
/**
* @var Exception $exception
*/
private $exception;
/**
* @param Run $run
*/
public function setRun(Run $run)
{
$this->run = $run;
}
/**
* @return Run
*/
protected function getRun()
{
return $this->run;
}
/**
* @param Inspector $inspector
*/
public function setInspector(Inspector $inspector)
{
$this->inspector = $inspector;
}
/**
* @return Inspector
*/
protected function getInspector()
{
return $this->inspector;
}
/**
* @param Exception $exception
*/
public function setException(Exception $exception)
{
$this->exception = $exception;
}
/**
* @return Exception
*/
protected function getException()
{
return $this->exception;
}
}
@@ -0,0 +1,37 @@
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Handler;
use Exception;
use Whoops\Exception\Inspector;
use Whoops\Run;
interface HandlerInterface
{
/**
* @return int|null A handler may return nothing, or a Handler::HANDLE_* constant
*/
public function handle();
/**
* @param Run $run
* @return void
*/
public function setRun(Run $run);
/**
* @param Exception $exception
* @return void
*/
public function setException(Exception $exception);
/**
* @param Inspector $inspector
* @return void
*/
public function setInspector(Inspector $inspector);
}
@@ -0,0 +1,91 @@
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Handler;
use Whoops\Exception\Formatter;
/**
* Catches an exception and converts it to a JSON
* response. Additionally can also return exception
* frames for consumption by an API.
*/
class JsonResponseHandler extends Handler
{
/**
* @var bool
*/
private $returnFrames = false;
/**
* @var bool
*/
private $onlyForAjaxRequests = false;
/**
* @param bool|null $returnFrames
* @return bool|$this
*/
public function addTraceToOutput($returnFrames = null)
{
if (func_num_args() == 0) {
return $this->returnFrames;
}
$this->returnFrames = (bool) $returnFrames;
return $this;
}
/**
* @param bool|null $onlyForAjaxRequests
* @return null|bool
*/
public function onlyForAjaxRequests($onlyForAjaxRequests = null)
{
if (func_num_args() == 0) {
return $this->onlyForAjaxRequests;
}
$this->onlyForAjaxRequests = (bool) $onlyForAjaxRequests;
}
/**
* Check, if possible, that this execution was triggered by an AJAX request.
*
* @return bool
*/
private function isAjaxRequest()
{
return (
!empty($_SERVER['HTTP_X_REQUESTED_WITH'])
&& strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
}
/**
* @return int
*/
public function handle()
{
if ($this->onlyForAjaxRequests() && !$this->isAjaxRequest()) {
return Handler::DONE;
}
$response = array(
'error' => Formatter::formatExceptionAsDataArray(
$this->getInspector(),
$this->addTraceToOutput()
),
);
if (\Whoops\Util\Misc::canSendHeaders()) {
header('Content-Type: application/json');
}
echo json_encode($response, defined('JSON_PARTIAL_OUTPUT_ON_ERROR') ? JSON_PARTIAL_OUTPUT_ON_ERROR : 0);
return Handler::QUIT;
}
}
@@ -0,0 +1,331 @@
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
* Plaintext handler for command line and logs.
* @author Pierre-Yves Landuré <https://howto.biapy.com/>
*/
namespace Whoops\Handler;
use InvalidArgumentException;
use Psr\Log\LoggerInterface;
use Whoops\Exception\Frame;
/**
* Handler outputing plaintext error messages. Can be used
* directly, or will be instantiated automagically by Whoops\Run
* if passed to Run::pushHandler
*/
class PlainTextHandler extends Handler
{
const VAR_DUMP_PREFIX = ' | ';
/**
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* @var bool
*/
private $addTraceToOutput = true;
/**
* @var bool|integer
*/
private $addTraceFunctionArgsToOutput = false;
/**
* @var integer
*/
private $traceFunctionArgsOutputLimit = 1024;
/**
* @var bool
*/
private $onlyForCommandLine = false;
/**
* @var bool
*/
private $outputOnlyIfCommandLine = true;
/**
* @var bool
*/
private $loggerOnly = false;
/**
* Constructor.
* @throws InvalidArgumentException If argument is not null or a LoggerInterface
* @param \Psr\Log\LoggerInterface|null $logger
*/
public function __construct($logger = null)
{
$this->setLogger($logger);
}
/**
* Set the output logger interface.
* @throws InvalidArgumentException If argument is not null or a LoggerInterface
* @param \Psr\Log\LoggerInterface|null $logger
*/
public function setLogger($logger = null)
{
if (! (is_null($logger)
|| $logger instanceof LoggerInterface)) {
throw new InvalidArgumentException(
'Argument to ' . __METHOD__ .
" must be a valid Logger Interface (aka. Monolog), " .
get_class($logger) . ' given.'
);
}
$this->logger = $logger;
}
/**
* @return \Psr\Log\LoggerInterface|null
*/
public function getLogger()
{
return $this->logger;
}
/**
* Add error trace to output.
* @param bool|null $addTraceToOutput
* @return bool|$this
*/
public function addTraceToOutput($addTraceToOutput = null)
{
if (func_num_args() == 0) {
return $this->addTraceToOutput;
}
$this->addTraceToOutput = (bool) $addTraceToOutput;
return $this;
}
/**
* Add error trace function arguments to output.
* Set to True for all frame args, or integer for the n first frame args.
* @param bool|integer|null $addTraceFunctionArgsToOutput
* @return null|bool|integer
*/
public function addTraceFunctionArgsToOutput($addTraceFunctionArgsToOutput = null)
{
if (func_num_args() == 0) {
return $this->addTraceFunctionArgsToOutput;
}
if (! is_integer($addTraceFunctionArgsToOutput)) {
$this->addTraceFunctionArgsToOutput = (bool) $addTraceFunctionArgsToOutput;
} else {
$this->addTraceFunctionArgsToOutput = $addTraceFunctionArgsToOutput;
}
}
/**
* Set the size limit in bytes of frame arguments var_dump output.
* If the limit is reached, the var_dump output is discarded.
* Prevent memory limit errors.
* @var integer
*/
public function setTraceFunctionArgsOutputLimit($traceFunctionArgsOutputLimit)
{
$this->traceFunctionArgsOutputLimit = (integer) $traceFunctionArgsOutputLimit;
}
/**
* Get the size limit in bytes of frame arguments var_dump output.
* If the limit is reached, the var_dump output is discarded.
* Prevent memory limit errors.
* @return integer
*/
public function getTraceFunctionArgsOutputLimit()
{
return $this->traceFunctionArgsOutputLimit;
}
/**
* Restrict error handling to command line calls.
* @param bool|null $onlyForCommandLine
* @return null|bool
*/
public function onlyForCommandLine($onlyForCommandLine = null)
{
if (func_num_args() == 0) {
return $this->onlyForCommandLine;
}
$this->onlyForCommandLine = (bool) $onlyForCommandLine;
}
/**
* Output the error message only if using command line.
* else, output to logger if available.
* Allow to safely add this handler to web pages.
* @param bool|null $outputOnlyIfCommandLine
* @return null|bool
*/
public function outputOnlyIfCommandLine($outputOnlyIfCommandLine = null)
{
if (func_num_args() == 0) {
return $this->outputOnlyIfCommandLine;
}
$this->outputOnlyIfCommandLine = (bool) $outputOnlyIfCommandLine;
}
/**
* Only output to logger.
* @param bool|null $loggerOnly
* @return null|bool
*/
public function loggerOnly($loggerOnly = null)
{
if (func_num_args() == 0) {
return $this->loggerOnly;
}
$this->loggerOnly = (bool) $loggerOnly;
}
/**
* Check, if possible, that this execution was triggered by a command line.
* @return bool
*/
private function isCommandLine()
{
return PHP_SAPI == 'cli';
}
/**
* Test if handler can process the exception..
* @return bool
*/
private function canProcess()
{
return $this->isCommandLine() || !$this->onlyForCommandLine();
}
/**
* Test if handler can output to stdout.
* @return bool
*/
private function canOutput()
{
return ($this->isCommandLine() || ! $this->outputOnlyIfCommandLine())
&& ! $this->loggerOnly();
}
/**
* Get the frame args var_dump.
* @param \Whoops\Exception\Frame $frame [description]
* @param integer $line [description]
* @return string
*/
private function getFrameArgsOutput(Frame $frame, $line)
{
if ($this->addTraceFunctionArgsToOutput() === false
|| $this->addTraceFunctionArgsToOutput() < $line) {
return '';
}
// Dump the arguments:
ob_start();
var_dump($frame->getArgs());
if (ob_get_length() > $this->getTraceFunctionArgsOutputLimit()) {
// The argument var_dump is to big.
// Discarded to limit memory usage.
ob_clean();
return sprintf(
"\n%sArguments dump length greater than %d Bytes. Discarded.",
self::VAR_DUMP_PREFIX,
$this->getTraceFunctionArgsOutputLimit()
);
}
return sprintf("\n%s",
preg_replace('/^/m', self::VAR_DUMP_PREFIX, ob_get_clean())
);
}
/**
* Get the exception trace as plain text.
* @return string
*/
private function getTraceOutput()
{
if (! $this->addTraceToOutput()) {
return '';
}
$inspector = $this->getInspector();
$frames = $inspector->getFrames();
$response = "\nStack trace:";
$line = 1;
foreach ($frames as $frame) {
/** @var Frame $frame */
$class = $frame->getClass();
$template = "\n%3d. %s->%s() %s:%d%s";
if (! $class) {
// Remove method arrow (->) from output.
$template = "\n%3d. %s%s() %s:%d%s";
}
$response .= sprintf(
$template,
$line,
$class,
$frame->getFunction(),
$frame->getFile(),
$frame->getLine(),
$this->getFrameArgsOutput($frame, $line)
);
$line++;
}
return $response;
}
/**
* @return int
*/
public function handle()
{
if (! $this->canProcess()) {
return Handler::DONE;
}
$exception = $this->getException();
$response = sprintf("%s: %s in file %s on line %d%s\n",
get_class($exception),
$exception->getMessage(),
$exception->getFile(),
$exception->getLine(),
$this->getTraceOutput()
);
if ($this->getLogger()) {
$this->getLogger()->error($response);
}
if (! $this->canOutput()) {
return Handler::DONE;
}
if (class_exists('\Whoops\Util\Misc')
&& \Whoops\Util\Misc::canSendHeaders()) {
header('Content-Type: text/plain');
}
echo $response;
return Handler::QUIT;
}
}
@@ -0,0 +1,529 @@
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Handler;
use InvalidArgumentException;
use RuntimeException;
use UnexpectedValueException;
use Whoops\Exception\Formatter;
use Whoops\Util\Misc;
use Whoops\Util\TemplateHelper;
class PrettyPageHandler extends Handler
{
/**
* Search paths to be scanned for resources, in the reverse
* order they're declared.
*
* @var array
*/
private $searchPaths = array();
/**
* Fast lookup cache for known resource locations.
*
* @var array
*/
private $resourceCache = array();
/**
* The name of the custom css file.
*
* @var string
*/
private $customCss = null;
/**
* @var array[]
*/
private $extraTables = array();
/**
* @var bool
*/
private $handleUnconditionally = false;
/**
* @var string
*/
private $pageTitle = "Whoops! There was an error.";
/**
* A string identifier for a known IDE/text editor, or a closure
* that resolves a string that can be used to open a given file
* in an editor. If the string contains the special substrings
* %file or %line, they will be replaced with the correct data.
*
* @example
* "txmt://open?url=%file&line=%line"
* @var mixed $editor
*/
protected $editor;
/**
* A list of known editor strings
* @var array
*/
protected $editors = array(
"sublime" => "subl://open?url=file://%file&line=%line",
"textmate" => "txmt://open?url=file://%file&line=%line",
"emacs" => "emacs://open?url=file://%file&line=%line",
"macvim" => "mvim://open/?url=file://%file&line=%line",
"phpstorm" => "phpstorm://open?file=%file&line=%line",
);
/**
* Constructor.
*/
public function __construct()
{
if (ini_get('xdebug.file_link_format') || extension_loaded('xdebug')) {
// Register editor using xdebug's file_link_format option.
$this->editors['xdebug'] = function ($file, $line) {
return str_replace(array('%f', '%l'), array($file, $line), ini_get('xdebug.file_link_format'));
};
}
// Add the default, local resource search path:
$this->searchPaths[] = __DIR__ . "/../Resources";
}
/**
* @return int|null
*/
public function handle()
{
if (!$this->handleUnconditionally()) {
// Check conditions for outputting HTML:
// @todo: Make this more robust
if (php_sapi_name() === 'cli') {
// Help users who have been relying on an internal test value
// fix their code to the proper method
if (isset($_ENV['whoops-test'])) {
throw new \Exception(
'Use handleUnconditionally instead of whoops-test'
.' environment variable'
);
}
return Handler::DONE;
}
}
// @todo: Make this more dynamic
$helper = new TemplateHelper();
$templateFile = $this->getResource("views/layout.html.php");
$cssFile = $this->getResource("css/whoops.base.css");
$zeptoFile = $this->getResource("js/zepto.min.js");
$jsFile = $this->getResource("js/whoops.base.js");
if ($this->customCss) {
$customCssFile = $this->getResource($this->customCss);
}
$inspector = $this->getInspector();
$frames = $inspector->getFrames();
$code = $inspector->getException()->getCode();
if ($inspector->getException() instanceof \ErrorException) {
// ErrorExceptions wrap the php-error types within the "severity" property
$code = Misc::translateErrorCode($inspector->getException()->getSeverity());
}
// List of variables that will be passed to the layout template.
$vars = array(
"page_title" => $this->getPageTitle(),
// @todo: Asset compiler
"stylesheet" => file_get_contents($cssFile),
"zepto" => file_get_contents($zeptoFile),
"javascript" => file_get_contents($jsFile),
// Template paths:
"header" => $this->getResource("views/header.html.php"),
"frame_list" => $this->getResource("views/frame_list.html.php"),
"frame_code" => $this->getResource("views/frame_code.html.php"),
"env_details" => $this->getResource("views/env_details.html.php"),
"title" => $this->getPageTitle(),
"name" => explode("\\", $inspector->getExceptionName()),
"message" => $inspector->getException()->getMessage(),
"code" => $code,
"plain_exception" => Formatter::formatExceptionPlain($inspector),
"frames" => $frames,
"has_frames" => !!count($frames),
"handler" => $this,
"handlers" => $this->getRun()->getHandlers(),
"tables" => array(
"GET Data" => $_GET,
"POST Data" => $_POST,
"Files" => $_FILES,
"Cookies" => $_COOKIE,
"Session" => isset($_SESSION) ? $_SESSION : array(),
"Server/Request Data" => $_SERVER,
"Environment Variables" => $_ENV,
),
);
if (isset($customCssFile)) {
$vars["stylesheet"] .= file_get_contents($customCssFile);
}
// Add extra entries list of data tables:
// @todo: Consolidate addDataTable and addDataTableCallback
$extraTables = array_map(function ($table) {
return $table instanceof \Closure ? $table() : $table;
}, $this->getDataTables());
$vars["tables"] = array_merge($extraTables, $vars["tables"]);
$helper->setVariables($vars);
$helper->render($templateFile);
return Handler::QUIT;
}
/**
* Adds an entry to the list of tables displayed in the template.
* The expected data is a simple associative array. Any nested arrays
* will be flattened with print_r
* @param string $label
* @param array $data
*/
public function addDataTable($label, array $data)
{
$this->extraTables[$label] = $data;
}
/**
* Lazily adds an entry to the list of tables displayed in the table.
* The supplied callback argument will be called when the error is rendered,
* it should produce a simple associative array. Any nested arrays will
* be flattened with print_r.
*
* @throws InvalidArgumentException If $callback is not callable
* @param string $label
* @param callable $callback Callable returning an associative array
*/
public function addDataTableCallback($label, /* callable */ $callback)
{
if (!is_callable($callback)) {
throw new InvalidArgumentException('Expecting callback argument to be callable');
}
$this->extraTables[$label] = function () use ($callback) {
try {
$result = call_user_func($callback);
// Only return the result if it can be iterated over by foreach().
return is_array($result) || $result instanceof \Traversable ? $result : array();
} catch (\Exception $e) {
// Don't allow failure to break the rendering of the original exception.
return array();
}
};
}
/**
* Returns all the extra data tables registered with this handler.
* Optionally accepts a 'label' parameter, to only return the data
* table under that label.
* @param string|null $label
* @return array[]|callable
*/
public function getDataTables($label = null)
{
if ($label !== null) {
return isset($this->extraTables[$label]) ?
$this->extraTables[$label] : array();
}
return $this->extraTables;
}
/**
* Allows to disable all attempts to dynamically decide whether to
* handle or return prematurely.
* Set this to ensure that the handler will perform no matter what.
* @param bool|null $value
* @return bool|null
*/
public function handleUnconditionally($value = null)
{
if (func_num_args() == 0) {
return $this->handleUnconditionally;
}
$this->handleUnconditionally = (bool) $value;
}
/**
* Adds an editor resolver, identified by a string
* name, and that may be a string path, or a callable
* resolver. If the callable returns a string, it will
* be set as the file reference's href attribute.
*
* @example
* $run->addEditor('macvim', "mvim://open?url=file://%file&line=%line")
* @example
* $run->addEditor('remove-it', function($file, $line) {
* unlink($file);
* return "http://stackoverflow.com";
* });
* @param string $identifier
* @param string $resolver
*/
public function addEditor($identifier, $resolver)
{
$this->editors[$identifier] = $resolver;
}
/**
* Set the editor to use to open referenced files, by a string
* identifier, or a callable that will be executed for every
* file reference, with a $file and $line argument, and should
* return a string.
*
* @example
* $run->setEditor(function($file, $line) { return "file:///{$file}"; });
* @example
* $run->setEditor('sublime');
*
* @throws InvalidArgumentException If invalid argument identifier provided
* @param string|callable $editor
*/
public function setEditor($editor)
{
if (!is_callable($editor) && !isset($this->editors[$editor])) {
throw new InvalidArgumentException(
"Unknown editor identifier: $editor. Known editors:" .
implode(",", array_keys($this->editors))
);
}
$this->editor = $editor;
}
/**
* Given a string file path, and an integer file line,
* executes the editor resolver and returns, if available,
* a string that may be used as the href property for that
* file reference.
*
* @throws InvalidArgumentException If editor resolver does not return a string
* @param string $filePath
* @param int $line
* @return string|bool
*/
public function getEditorHref($filePath, $line)
{
$editor = $this->getEditor($filePath, $line);
if (!$editor) {
return false;
}
// Check that the editor is a string, and replace the
// %line and %file placeholders:
if (!isset($editor['url']) || !is_string($editor['url'])) {
throw new UnexpectedValueException(
__METHOD__ . " should always resolve to a string or a valid editor array; got something else instead."
);
}
$editor['url'] = str_replace("%line", rawurlencode($line), $editor['url']);
$editor['url'] = str_replace("%file", rawurlencode($filePath), $editor['url']);
return $editor['url'];
}
/**
* Given a boolean if the editor link should
* act as an Ajax request. The editor must be a
* valid callable function/closure
*
* @throws UnexpectedValueException If editor resolver does not return a boolean
* @param string $filePath
* @param int $line
* @return bool
*/
public function getEditorAjax($filePath, $line)
{
$editor = $this->getEditor($filePath, $line);
// Check that the ajax is a bool
if (!isset($editor['ajax']) || !is_bool($editor['ajax'])) {
throw new UnexpectedValueException(
__METHOD__ . " should always resolve to a bool; got something else instead."
);
}
return $editor['ajax'];
}
/**
* Given a boolean if the editor link should
* act as an Ajax request. The editor must be a
* valid callable function/closure
*
* @throws UnexpectedValueException If editor resolver does not return a boolean
* @param string $filePath
* @param int $line
* @return mixed
*/
protected function getEditor($filePath, $line)
{
if ($this->editor === null && !is_string($this->editor) && !is_callable($this->editor))
{
return false;
}
else if(is_string($this->editor) && isset($this->editors[$this->editor]) && !is_callable($this->editors[$this->editor]))
{
return array(
'ajax' => false,
'url' => $this->editors[$this->editor],
);
}
else if(is_callable($this->editor) || (isset($this->editors[$this->editor]) && is_callable($this->editors[$this->editor])))
{
if(is_callable($this->editor))
{
$callback = call_user_func($this->editor, $filePath, $line);
}
else
{
$callback = call_user_func($this->editors[$this->editor], $filePath, $line);
}
return array(
'ajax' => isset($callback['ajax']) ? $callback['ajax'] : false,
'url' => (is_array($callback) ? $callback['url'] : $callback),
);
}
return false;
}
/**
* @param string $title
* @return void
*/
public function setPageTitle($title)
{
$this->pageTitle = (string) $title;
}
/**
* @return string
*/
public function getPageTitle()
{
return $this->pageTitle;
}
/**
* Adds a path to the list of paths to be searched for
* resources.
*
* @throws InvalidArgumnetException If $path is not a valid directory
*
* @param string $path
* @return void
*/
public function addResourcePath($path)
{
if (!is_dir($path)) {
throw new InvalidArgumentException(
"'$path' is not a valid directory"
);
}
array_unshift($this->searchPaths, $path);
}
/**
* Adds a custom css file to be loaded.
*
* @param string $name
* @return void
*/
public function addCustomCss($name)
{
$this->customCss = $name;
}
/**
* @return array
*/
public function getResourcePaths()
{
return $this->searchPaths;
}
/**
* Finds a resource, by its relative path, in all available search paths.
* The search is performed starting at the last search path, and all the
* way back to the first, enabling a cascading-type system of overrides
* for all resources.
*
* @throws RuntimeException If resource cannot be found in any of the available paths
*
* @param string $resource
* @return string
*/
protected function getResource($resource)
{
// If the resource was found before, we can speed things up
// by caching its absolute, resolved path:
if (isset($this->resourceCache[$resource])) {
return $this->resourceCache[$resource];
}
// Search through available search paths, until we find the
// resource we're after:
foreach ($this->searchPaths as $path) {
$fullPath = $path . "/$resource";
if (is_file($fullPath)) {
// Cache the result:
$this->resourceCache[$resource] = $fullPath;
return $fullPath;
}
}
// If we got this far, nothing was found.
throw new RuntimeException(
"Could not find resource '$resource' in any resource paths."
. "(searched: " . join(", ", $this->searchPaths). ")"
);
}
/**
* @deprecated
*
* @return string
*/
public function getResourcesPath()
{
$allPaths = $this->getResourcePaths();
// Compat: return only the first path added
return end($allPaths) ?: null;
}
/**
* @deprecated
*
* @param string $resourcesPath
* @return void
*/
public function setResourcesPath($resourcesPath)
{
$this->addResourcePath($resourcesPath);
}
}
@@ -0,0 +1,49 @@
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Handler;
/**
* Catches an exception and converts it to an Soap XML
* response.
*
* @author Markus Staab <http://github.com/staabm>
*/
class SoapResponseHandler extends Handler
{
/**
* @return int
*/
public function handle()
{
$exception = $this->getException();
echo $this->toXml($exception);
return Handler::QUIT;
}
/**
* Converts a Exception into a SoapFault XML
*/
private function toXml(\Exception $exception)
{
$xml = '';
$xml .= '<?xml version="1.0" encoding="UTF-8"?>';
$xml .= '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">';
$xml .= ' <SOAP-ENV:Body>';
$xml .= ' <SOAP-ENV:Fault>';
$xml .= ' <faultcode>'. htmlspecialchars($exception->getCode()) .'</faultcode>';
$xml .= ' <faultstring>'. htmlspecialchars($exception->getMessage()) .'</faultstring>';
$xml .= ' <detail><trace>'. htmlspecialchars($exception->getTraceAsString()) .'</trace></detail>';
$xml .= ' </SOAP-ENV:Fault>';
$xml .= ' </SOAP-ENV:Body>';
$xml .= '</SOAP-ENV:Envelope>';
return $xml;
}
}
@@ -0,0 +1,99 @@
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Handler;
use SimpleXMLElement;
use Whoops\Exception\Formatter;
/**
* Catches an exception and converts it to an XML
* response. Additionally can also return exception
* frames for consumption by an API.
*/
class XmlResponseHandler extends Handler
{
/**
* @var bool
*/
private $returnFrames = false;
/**
* @param bool|null $returnFrames
* @return bool|$this
*/
public function addTraceToOutput($returnFrames = null)
{
if (func_num_args() == 0) {
return $this->returnFrames;
}
$this->returnFrames = (bool) $returnFrames;
return $this;
}
/**
* @return int
*/
public function handle()
{
$response = array(
'error' => Formatter::formatExceptionAsDataArray(
$this->getInspector(),
$this->addTraceToOutput()
),
);
echo $this->toXml($response);
return Handler::QUIT;
}
/**
* @param SimpleXMLElement $node Node to append data to, will be modified in place
* @param array|Traversable $data
* @return SimpleXMLElement The modified node, for chaining
*/
private static function addDataToNode(\SimpleXMLElement $node, $data)
{
assert('is_array($data) || $node instanceof Traversable');
foreach ($data as $key => $value) {
if (is_numeric($key)) {
// Convert the key to a valid string
$key = "unknownNode_". (string) $key;
}
// Delete any char not allowed in XML element names
$key = preg_replace('/[^a-z0-9\-\_\.\:]/i', '', $key);
if (is_array($value)) {
$child = $node->addChild($key);
self::addDataToNode($child, $value);
} else {
$value = str_replace('&', '&amp;', print_r($value, true));
$node->addChild($key, $value);
}
}
return $node;
}
/**
* The main function for converting to an XML document.
*
* @param array|Traversable $data
* @return string XML
*/
private static function toXml($data)
{
assert('is_array($data) || $node instanceof Traversable');
$node = simplexml_load_string("<?xml version='1.0' encoding='utf-8'?><root />");
return self::addDataToNode($node, $data)->asXML();
}
}
@@ -0,0 +1,78 @@
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Provider\Phalcon;
use Phalcon\DI;
use Phalcon\DI\Exception;
use Whoops\Handler\JsonResponseHandler;
use Whoops\Handler\PrettyPageHandler;
use Whoops\Run;
class WhoopsServiceProvider
{
/**
* @param DI $di
*/
public function __construct(DI $di = null)
{
if (!$di) {
$di = DI::getDefault();
}
// There's only ever going to be one error page...right?
$di->setShared('whoops.pretty_page_handler', function () {
return new PrettyPageHandler();
});
// There's only ever going to be one error page...right?
$di->setShared('whoops.json_response_handler', function () {
$jsonHandler = new JsonResponseHandler();
$jsonHandler->onlyForAjaxRequests(true);
return $jsonHandler;
});
// Retrieves info on the Phalcon environment and ships it off
// to the PrettyPageHandler's data tables:
// This works by adding a new handler to the stack that runs
// before the error page, retrieving the shared page handler
// instance, and working with it to add new data tables
$phalcon_info_handler = function () use ($di) {
try {
$request = $di['request'];
} catch (Exception $e) {
// This error occurred too early in the application's life
// and the request instance is not yet available.
return;
}
// Request info:
$di['whoops.pretty_page_handler']->addDataTable('Phalcon Application (Request)', array(
'URI' => $request->getScheme().'://'.$request->getServer('HTTP_HOST').$request->getServer('REQUEST_URI'),
'Request URI' => $request->getServer('REQUEST_URI'),
'Path Info' => $request->getServer('PATH_INFO'),
'Query String' => $request->getServer('QUERY_STRING') ?: '<none>',
'HTTP Method' => $request->getMethod(),
'Script Name' => $request->getServer('SCRIPT_NAME'),
//'Base Path' => $request->getBasePath(),
//'Base URL' => $request->getBaseUrl(),
'Scheme' => $request->getScheme(),
'Port' => $request->getServer('SERVER_PORT'),
'Host' => $request->getServerName(),
));
};
$di->setShared('whoops', function () use ($di,$phalcon_info_handler) {
$run = new Run();
$run->pushHandler($di['whoops.pretty_page_handler']);
$run->pushHandler($phalcon_info_handler);
$run->pushHandler($di['whoops.json_response_handler']);
return $run;
});
$di['whoops']->register();
}
}
@@ -0,0 +1,111 @@
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Provider\Silex;
use RuntimeException;
use Silex\Application;
use Silex\ServiceProviderInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Whoops\Handler\Handler;
use Whoops\Handler\PlainTextHandler;
use Whoops\Handler\PrettyPageHandler;
use Whoops\Run;
class WhoopsServiceProvider implements ServiceProviderInterface
{
/**
* @param Application $app
*/
public function register(Application $app)
{
// There's only ever going to be one error page...right?
$app['whoops.error_page_handler'] = $app->share(function () {
if (PHP_SAPI === 'cli') {
return new PlainTextHandler();
} else {
return new PrettyPageHandler();
}
});
// Retrieves info on the Silex environment and ships it off
// to the PrettyPageHandler's data tables:
// This works by adding a new handler to the stack that runs
// before the error page, retrieving the shared page handler
// instance, and working with it to add new data tables
$app['whoops.silex_info_handler'] = $app->protect(function () use ($app) {
try {
/** @var Request $request */
$request = $app['request'];
} catch (RuntimeException $e) {
// This error occurred too early in the application's life
// and the request instance is not yet available.
return;
}
/** @var Handler $errorPageHandler */
$errorPageHandler = $app["whoops.error_page_handler"];
if ($errorPageHandler instanceof PrettyPageHandler) {
/** @var PrettyPageHandler $errorPageHandler */
// General application info:
$errorPageHandler->addDataTable('Silex Application', array(
'Charset' => $app['charset'],
'Locale' => $app['locale'],
'Route Class' => $app['route_class'],
'Dispatcher Class' => $app['dispatcher_class'],
'Application Class' => get_class($app),
));
// Request info:
$errorPageHandler->addDataTable('Silex Application (Request)', array(
'URI' => $request->getUri(),
'Request URI' => $request->getRequestUri(),
'Path Info' => $request->getPathInfo(),
'Query String' => $request->getQueryString() ?: '<none>',
'HTTP Method' => $request->getMethod(),
'Script Name' => $request->getScriptName(),
'Base Path' => $request->getBasePath(),
'Base URL' => $request->getBaseUrl(),
'Scheme' => $request->getScheme(),
'Port' => $request->getPort(),
'Host' => $request->getHost(),
));
}
});
$app['whoops'] = $app->share(function () use ($app) {
$run = new Run();
$run->allowQuit(false);
$run->pushHandler($app['whoops.error_page_handler']);
$run->pushHandler($app['whoops.silex_info_handler']);
return $run;
});
$app->error(function ($e) use ($app) {
$method = Run::EXCEPTION_HANDLER;
ob_start();
$app['whoops']->$method($e);
$response = ob_get_clean();
$code = $e instanceof HttpException ? $e->getStatusCode() : 500;
return new Response($response, $code);
});
$app['whoops']->register();
}
/**
* @see Silex\ServiceProviderInterface::boot
*/
public function boot(Application $app)
{
}
}
@@ -0,0 +1,428 @@
.cf:before, .cf:after {content: " ";display: table;} .cf:after {clear: both;} .cf {*zoom: 1;}
body {
font: 14px helvetica, arial, sans-serif;
color: #2B2B2B;
background-color: #D4D4D4;
padding:0;
margin: 0;
max-height: 100%;
}
a {
text-decoration: none;
}
.container{
height: 100%;
width: 100%;
position: fixed;
margin: 0;
padding: 0;
left: 0;
top: 0;
}
.branding {
position: absolute;
top: 10px;
right: 20px;
color: #777777;
font-size: 10px;
z-index: 100;
}
.branding a {
color: #CD3F3F;
}
header {
padding: 30px 20px;
color: white;
background: #272727;
box-sizing: border-box;
border-left: 5px solid #CD3F3F;
}
.exc-title {
margin: 0;
color: #616161;
text-shadow: 0 1px 2px rgba(0, 0, 0, .1);
}
.exc-title-primary { color: #CD3F3F; }
.exc-message {
font-size: 32px;
margin: 5px 0;
word-wrap: break-word;
}
.stack-container {
height: 100%;
position: relative;
}
.details-container {
height: 100%;
overflow: auto;
float: right;
width: 70%;
background: #DADADA;
}
.details {
padding: 10px;
padding-left: 5px;
border-left: 5px solid rgba(0, 0, 0, .1);
}
.frames-container {
height: 100%;
overflow: auto;
float: left;
width: 30%;
background: #FFF;
}
.frame {
padding: 14px;
background: #F3F3F3;
border-right: 1px solid rgba(0, 0, 0, .2);
cursor: pointer;
}
.frame.active {
background-color: #4288CE;
color: #F3F3F3;
box-shadow: inset -2px 0 0 rgba(255, 255, 255, .1);
text-shadow: 0 1px 0 rgba(0, 0, 0, .2);
}
.frame:not(.active):hover {
background: #BEE9EA;
}
.frame-class, .frame-function, .frame-index {
font-weight: bold;
}
.frame-index {
font-size: 11px;
color: #BDBDBD;
}
.frame-class {
color: #4288CE;
}
.active .frame-class {
color: #BEE9EA;
}
.frame-file {
font-family: "Inconsolata", "Fira Mono", "Source Code Pro", Monaco, Consolas, "Lucida Console", monospace;
word-wrap:break-word;
}
.frame-file .editor-link {
color: #272727;
}
.frame-line {
font-weight: bold;
color: #4288CE;
}
.active .frame-line { color: #BEE9EA; }
.frame-line:before {
content: ":";
}
.frame-code {
padding: 10px;
padding-left: 5px;
background: #BDBDBD;
display: none;
border-left: 5px solid #4288CE;
}
.frame-code.active {
display: block;
}
.frame-code .frame-file {
background: #C6C6C6;
color: #525252;
text-shadow: 0 1px 0 #E7E7E7;
padding: 10px 10px 5px 10px;
border-top-right-radius: 6px;
border-top-left-radius: 6px;
border: 1px solid rgba(0, 0, 0, .1);
border-bottom: none;
box-shadow: inset 0 1px 0 #DADADA;
}
.code-block {
padding: 10px;
margin: 0;
box-shadow: inset 0 0 6px rgba(0, 0, 0, .3);
}
.linenums {
margin: 0;
margin-left: 10px;
}
.frame-comments {
box-shadow: inset 0 0 6px rgba(0, 0, 0, .3);
border: 1px solid rgba(0, 0, 0, .2);
border-top: none;
border-bottom-right-radius: 6px;
border-bottom-left-radius: 6px;
padding: 5px;
font-size: 12px;
background: #404040;
}
.frame-comments.empty {
padding: 8px 15px;
}
.frame-comments.empty:before {
content: "No comments for this stack frame.";
font-style: italic;
color: #828282;
}
.frame-comment {
padding: 10px;
color: #D2D2D2;
}
.frame-comment a {
color: #BEE9EA;
font-weight: bold;
text-decoration: none;
}
.frame-comment a:hover {
color: #4bb1b1;
}
.frame-comment:not(:last-child) {
border-bottom: 1px dotted rgba(0, 0, 0, .3);
}
.frame-comment-context {
font-size: 10px;
font-weight: bold;
color: #86D2B6;
}
.data-table-container label {
font-size: 16px;
font-weight: bold;
color: #4288CE;
margin: 10px 0;
padding: 10px 0;
display: block;
margin-bottom: 5px;
padding-bottom: 5px;
border-bottom: 1px dotted rgba(0, 0, 0, .2);
}
.data-table {
width: 100%;
margin: 10px 0;
}
.data-table tbody {
font: 13px "Inconsolata", "Fira Mono", "Source Code Pro", Monaco, Consolas, "Lucida Console", monospace;
}
.data-table thead {
display: none;
}
.data-table tr {
padding: 5px 0;
}
.data-table td:first-child {
width: 20%;
min-width: 130px;
overflow: hidden;
font-weight: bold;
color: #463C54;
padding-right: 5px;
}
.data-table td:last-child {
width: 80%;
-ms-word-break: break-all;
word-break: break-all;
word-break: break-word;
-webkit-hyphens: auto;
-moz-hyphens: auto;
hyphens: auto;
}
.data-table span.empty {
color: rgba(0, 0, 0, .3);
font-style: italic;
}
.data-table label.empty {
display: inline;
}
.handler {
padding: 10px;
font: 14px "Inconsolata", "Fira Mono", "Source Code Pro", Monaco, Consolas, "Lucida Console", monospace;
}
.handler.active {
color: #BBBBBB;
background: #989898;
font-weight: bold;
}
/* prettify code style
Uses the Doxy theme as a base */
pre .str, code .str { color: #BCD42A; } /* string */
pre .kwd, code .kwd { color: #4bb1b1; font-weight: bold; } /* keyword*/
pre .com, code .com { color: #888; font-weight: bold; } /* comment */
pre .typ, code .typ { color: #ef7c61; } /* type */
pre .lit, code .lit { color: #BCD42A; } /* literal */
pre .pun, code .pun { color: #fff; font-weight: bold; } /* punctuation */
pre .pln, code .pln { color: #e9e4e5; } /* plaintext */
pre .tag, code .tag { color: #4bb1b1; } /* html/xml tag */
pre .htm, code .htm { color: #dda0dd; } /* html tag */
pre .xsl, code .xsl { color: #d0a0d0; } /* xslt tag */
pre .atn, code .atn { color: #ef7c61; font-weight: normal;} /* html/xml attribute name */
pre .atv, code .atv { color: #bcd42a; } /* html/xml attribute value */
pre .dec, code .dec { color: #606; } /* decimal */
pre.prettyprint, code.prettyprint {
font-family: "Inconsolata", "Fira Mono", "Source Code Pro", Monaco, Consolas, "Lucida Console", monospace;
background: #333;
color: #e9e4e5;
}
pre.prettyprint {
white-space: pre-wrap;
}
pre.prettyprint a, code.prettyprint a {
text-decoration:none;
}
.linenums li {
color: #A5A5A5;
}
.linenums li.current{
background: rgba(255, 100, 100, .07);
padding-top: 4px;
padding-left: 1px;
}
.linenums li.current.active {
background: rgba(255, 100, 100, .17);
}
#plain-exception {
display: none;
}
#copy-button {
display: none;
float: right;
cursor: pointer;
border: 0;
}
.clipboard {
width: 29px;
height: 28px;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAcCAYAAACdz7SqAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gUUByMD0ZSoGQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAACAklEQVRIx72Wv0sbYRjHP29y1VoXxR9UskjpXTaHoBUcpGgKkS5OZ1Ec/QeKOIhalEghoOCqQsGhFAWbISKYyaFDS1BKKW0TCYrQSdElXSReh9bkksu9iZdLbnrvvee9z/N83+d9nldo2gvjzd5Hxp4246W6J5tJszsxwvxPIbXzwBQDLgABvM1P6JsAwzCkdopl5vqIuWev2K4QpH/4QjjQci/nPCVny3iaNzMcrVUsC1sChFMpwtTu8dTqx7J9dR3a2BngUb0j7Xr+jtjasBR8f+jpNqqqoqoqmqblxjOJq/8GTfhCK8TWhmmykdhRpEIIhBCWMcD51wQXN3KwY3nvYGYgQPbXOMHJKOlMA77QCvsbugXsOFLZ+5+jGULBtyQuFB4PzlrAVSWSGWaptpdbjAcniaZv6RhcIL6VByvVZqsQouBMdutJkrrVrr1/gdjqN4Ze/3DvyBwcnnF9I7N4gC8YYdqNSHP7uD5G/7pdJRrl/ecIva1t9IRcgpolLk6qQic8eB+6GOkdrDjSf/OiTD91CS4r+jXrMqWkrgvUtuDbeVNTKGzw6SRDto5QBc5Yehlg0WbTc8mwHCeld1u+yZSySySlspTHFmZUeIkrgBYvtvPcyBdXkqWKq5OLmbk/luqVYjPOd3lxLXf/J/P7mJ0oCL/fX1Yfs4RO5CxW8C97dLBw2Q3fUwAAAABJRU5ErkJggg==');
background-repeat: no-repeat;
}
.help button {
cursor: help;
height: 28px;
float: right;
margin-left: 10px;
}
.help button:hover + #help-overlay {
display: block;
}
#help-overlay {
pointer-events: none;
display: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(54, 54, 54, 0.5);
}
#help-overlay div {
width: 200px;
padding: 10px;
color: #463c54;
background-color: #d9ad00;
border-radius: 3px;
text-align: center;
}
#help-clipboard {
position: absolute;
right: 30px;
top: 90px;
}
#help-framestack {
position: absolute;
left: 200px;
top: 50px;
}
#help-exc-message {
position: absolute;
left: 65%;
top: 10px;
}
#help-code {
position: absolute;
right: 30px;
top: 250px;
}
#help-request {
position: absolute;
right: 30px;
top: 480px;
}
#help-appinfo {
position: absolute;
right: 30px;
top: 550px;
}
/* inspired by githubs kbd styles */
kbd {
-moz-border-bottom-colors: none;
-moz-border-left-colors: none;
-moz-border-right-colors: none;
-moz-border-top-colors: none;
background-color: #fcfcfc;
border-color: #ccc #ccc #bbb;
border-image: none;
border-radius: 3px;
border-style: solid;
border-width: 1px;
box-shadow: 0 -1px 0 #bbb inset;
color: #555;
display: inline-block;
font-size: 11px;
line-height: 10px;
padding: 3px 5px;
vertical-align: middle;
}
@@ -0,0 +1,86 @@
Zepto(function($) {
prettyPrint();
var $frameContainer = $('.frames-container');
var $container = $('.details-container');
var $activeLine = $frameContainer.find('.frame.active');
var $activeFrame = $container.find('.frame-code.active');
var $ajaxEditors = $('.editor-link[data-ajax]');
var headerHeight = $('header').height();
var highlightCurrentLine = function() {
// Highlight the active and neighboring lines for this frame:
var activeLineNumber = +($activeLine.find('.frame-line').text());
var $lines = $activeFrame.find('.linenums li');
var firstLine = +($lines.first().val());
$($lines[activeLineNumber - firstLine - 1]).addClass('current');
$($lines[activeLineNumber - firstLine]).addClass('current active');
$($lines[activeLineNumber - firstLine + 1]).addClass('current');
}
// Highlight the active for the first frame:
highlightCurrentLine();
$frameContainer.on('click', '.frame', function() {
var $this = $(this);
var id = /frame\-line\-([\d]*)/.exec($this.attr('id'))[1];
var $codeFrame = $('#frame-code-' + id);
if ($codeFrame) {
$activeLine.removeClass('active');
$activeFrame.removeClass('active');
$this.addClass('active');
$codeFrame.addClass('active');
$activeLine = $this;
$activeFrame = $codeFrame;
highlightCurrentLine();
$container.scrollTop(headerHeight);
}
});
if (typeof ZeroClipboard !== "undefined") {
ZeroClipboard.config({
moviePath: '//ajax.cdnjs.com/ajax/libs/zeroclipboard/1.3.5/ZeroClipboard.swf',
});
var clipEl = document.getElementById("copy-button");
var clip = new ZeroClipboard( clipEl );
var $clipEl = $(clipEl);
// show the button, when swf could be loaded successfully from CDN
clip.on("load", function() {
$clipEl.show();
});
}
$(document).on('keydown', function(e) {
if(e.ctrlKey) {
// CTRL+Arrow-UP/Arrow-Down support:
// 1) select the next/prev element
// 2) make sure the newly selected element is within the view-scope
// 3) focus the (right) container, so arrow-up/down (without ctrl) scroll the details
if (e.which === 38 /* arrow up */) {
$activeLine.prev('.frame').click();
$activeLine[0].scrollIntoView();
$container.focus();
e.preventDefault();
} else if (e.which === 40 /* arrow down */) {
$activeLine.next('.frame').click();
$activeLine[0].scrollIntoView();
$container.focus();
e.preventDefault();
}
}
});
// Avoid to quit the page with some protocol (e.g. IntelliJ Platform REST API)
$ajaxEditors.on('click', function(e){
e.preventDefault();
$.get(this.href);
});
});
File diff suppressed because one or more lines are too long
@@ -0,0 +1,40 @@
<?php /* List data-table values, i.e: $_SERVER, $_GET, .... */ ?>
<div class="details">
<div class="data-table-container" id="data-tables">
<?php foreach ($tables as $label => $data): ?>
<div class="data-table" id="sg-<?php echo $tpl->escape($tpl->slug($label)) ?>">
<?php if (!empty($data)): ?>
<label><?php echo $tpl->escape($label) ?></label>
<table class="data-table">
<thead>
<tr>
<td class="data-table-k">Key</td>
<td class="data-table-v">Value</td>
</tr>
</thead>
<?php foreach ($data as $k => $value): ?>
<tr>
<td><?php echo $tpl->escape($k) ?></td>
<td><?php echo $tpl->escape(print_r($value, true)) ?></td>
</tr>
<?php endforeach ?>
</table>
<?php else: ?>
<label class="empty"><?php echo $tpl->escape($label) ?></label>
<span class="empty">empty</span>
<?php endif ?>
</div>
<?php endforeach ?>
</div>
<?php /* List registered handlers, in order of first to last registered */ ?>
<div class="data-table-container" id="handlers">
<label>Registered Handlers</label>
<?php foreach ($handlers as $i => $handler): ?>
<div class="handler <?php echo ($handler === $handler) ? 'active' : ''?>">
<?php echo $i ?>. <?php echo $tpl->escape(get_class($handler)) ?>
</div>
<?php endforeach ?>
</div>
</div>
@@ -0,0 +1,52 @@
<?php /* Display a code block for all frames in the stack.
* @todo: This should PROBABLY be done on-demand, lest
* we get 200 frames to process. */ ?>
<div class="frame-code-container <?php echo (!$has_frames ? 'empty' : '') ?>">
<?php foreach ($frames as $i => $frame): ?>
<?php $line = $frame->getLine(); ?>
<div class="frame-code <?php echo ($i == 0 ) ? 'active' : '' ?>" id="frame-code-<?php echo $i ?>">
<div class="frame-file">
<?php $filePath = $frame->getFile(); ?>
<?php if ($filePath && $editorHref = $handler->getEditorHref($filePath, (int) $line)): ?>
Open:
<a href="<?php echo $editorHref ?>" class="editor-link"<?php echo ($handler->getEditorAjax($filePath, (int) $line) ? ' data-ajax' : '') ?>>
<strong><?php echo $tpl->escape($filePath ?: '<#unknown>') ?></strong>
</a>
<?php else: ?>
<strong><?php echo $tpl->escape($filePath ?: '<#unknown>') ?></strong>
<?php endif ?>
</div>
<?php
// Do nothing if there's no line to work off
if ($line !== null):
// the $line is 1-indexed, we nab -1 where needed to account for this
$range = $frame->getFileLines($line - 8, 10);
// getFileLines can return null if there is no source code
if ($range):
$range = array_map(function ($line) { return empty($line) ? ' ' : $line;}, $range);
$start = key($range) + 1;
$code = join("\n", $range);
?>
<pre class="code-block prettyprint linenums:<?php echo $start ?>"><?php echo $tpl->escape($code) ?></pre>
<?php endif ?>
<?php endif ?>
<?php
// Append comments for this frame
$comments = $frame->getComments();
?>
<div class="frame-comments <?php echo empty($comments) ? 'empty' : '' ?>">
<?php foreach ($comments as $commentNo => $comment): ?>
<?php extract($comment) ?>
<div class="frame-comment" id="comment-<?php echo $i . '-' . $commentNo ?>">
<span class="frame-comment-context"><?php echo $tpl->escape($context) ?></span>
<?php echo $tpl->escapeButPreserveUris($comment) ?>
</div>
<?php endforeach ?>
</div>
</div>
<?php endforeach ?>
</div>
@@ -0,0 +1,17 @@
<?php /* List file names & line numbers for all stack frames;
clicking these links/buttons will display the code view
for that particular frame */ ?>
<?php foreach ($frames as $i => $frame): ?>
<div class="frame <?php echo ($i == 0 ? 'active' : '') ?>" id="frame-line-<?php echo $i ?>">
<div class="frame-method-info">
<span class="frame-index"><?php echo (count($frames) - $i - 1) ?>.</span>
<span class="frame-class"><?php echo $tpl->escape($frame->getClass() ?: '') ?></span>
<span class="frame-function"><?php echo $tpl->escape($frame->getFunction() ?: '') ?></span>
</div>
<span class="frame-file">
<?php echo ($frame->getFile(true) ?: '<#unknown>') ?><!--
--><span class="frame-line"><?php echo (int) $frame->getLine() ?></span>
</span>
</div>
<?php endforeach ?>
@@ -0,0 +1,34 @@
<div class="exception">
<h3 class="exc-title">
<?php foreach ($name as $i => $nameSection): ?>
<?php if ($i == count($name) - 1): ?>
<span class="exc-title-primary"><?php echo $tpl->escape($nameSection) ?></span>
<?php else: ?>
<?php echo $tpl->escape($nameSection) . ' \\' ?>
<?php endif ?>
<?php endforeach ?>
<?php if ($code): ?>
<span title="Exception Code">(<?php echo $tpl->escape($code) ?>)</span>
<?php endif ?>
</h3>
<div class="help">
<button title="show help">HELP</button>
<div id="help-overlay">
<div id="help-framestack">Callstack information; navigate with mouse or keyboard using <kbd>Ctrl+&uparrow;</kbd> or <kbd>Ctrl+&downarrow;</kbd></div>
<div id="help-clipboard">Copy-to-clipboard button</div>
<div id="help-exc-message">Exception message and its type</div>
<div id="help-code">Code snippet where the error was thrown</div>
<div id="help-request">Server state information</div>
<div id="help-appinfo">Application provided context information</div>
</div>
</div>
<button id="copy-button" class="clipboard" data-clipboard-target="plain-exception" title="copy exception into clipboard"></button>
<span id="plain-exception"><?php echo $tpl->escape($plain_exception) ?></span>
<p class="exc-message">
<?php echo $tpl->escape($message) ?>
</p>
</div>
@@ -0,0 +1,37 @@
<?php
/**
* Layout template file for Whoops's pretty error output.
*/
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><?php echo $tpl->escape($page_title) ?></title>
<style><?php echo $stylesheet ?></style>
</head>
<body>
<div class="Whoops container">
<div class="stack-container">
<div class="frames-container cf <?php echo (!$has_frames ? 'empty' : '') ?>">
<?php $tpl->render($frame_list) ?>
</div>
<div class="details-container cf">
<header>
<?php $tpl->render($header) ?>
</header>
<?php $tpl->render($frame_code) ?>
<?php $tpl->render($env_details) ?>
</div>
</div>
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/zeroclipboard/1.3.5/ZeroClipboard.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/prettify/r224/prettify.js"></script>
<script><?php echo $zepto ?></script>
<script><?php echo $javascript ?></script>
</body>
</html>
+408
View File
@@ -0,0 +1,408 @@
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops;
use Exception;
use InvalidArgumentException;
use Whoops\Exception\ErrorException;
use Whoops\Exception\Inspector;
use Whoops\Handler\CallbackHandler;
use Whoops\Handler\Handler;
use Whoops\Handler\HandlerInterface;
class Run
{
const EXCEPTION_HANDLER = "handleException";
const ERROR_HANDLER = "handleError";
const SHUTDOWN_HANDLER = "handleShutdown";
protected $isRegistered;
protected $allowQuit = true;
protected $sendOutput = true;
/**
* @var integer|false
*/
protected $sendHttpCode = 500;
/**
* @var HandlerInterface[]
*/
protected $handlerStack = array();
protected $silencedPatterns = array();
/**
* Pushes a handler to the end of the stack
*
* @throws InvalidArgumentException If argument is not callable or instance of HandlerInterface
* @param Callable|HandlerInterface $handler
* @return Run
*/
public function pushHandler($handler)
{
if (is_callable($handler)) {
$handler = new CallbackHandler($handler);
}
if (!$handler instanceof HandlerInterface) {
throw new InvalidArgumentException(
"Argument to " . __METHOD__ . " must be a callable, or instance of"
. "Whoops\\Handler\\HandlerInterface"
);
}
$this->handlerStack[] = $handler;
return $this;
}
/**
* Removes the last handler in the stack and returns it.
* Returns null if there"s nothing else to pop.
* @return null|HandlerInterface
*/
public function popHandler()
{
return array_pop($this->handlerStack);
}
/**
* Returns an array with all handlers, in the
* order they were added to the stack.
* @return array
*/
public function getHandlers()
{
return $this->handlerStack;
}
/**
* Clears all handlers in the handlerStack, including
* the default PrettyPage handler.
* @return Run
*/
public function clearHandlers()
{
$this->handlerStack = array();
return $this;
}
/**
* @param Exception $exception
* @return Inspector
*/
protected function getInspector(Exception $exception)
{
return new Inspector($exception);
}
/**
* Registers this instance as an error handler.
* @return Run
*/
public function register()
{
if (!$this->isRegistered) {
// Workaround PHP bug 42098
// https://bugs.php.net/bug.php?id=42098
class_exists("\\Whoops\\Exception\\ErrorException");
class_exists("\\Whoops\\Exception\\FrameCollection");
class_exists("\\Whoops\\Exception\\Frame");
class_exists("\\Whoops\\Exception\\Inspector");
set_error_handler(array($this, self::ERROR_HANDLER));
set_exception_handler(array($this, self::EXCEPTION_HANDLER));
register_shutdown_function(array($this, self::SHUTDOWN_HANDLER));
$this->isRegistered = true;
}
return $this;
}
/**
* Unregisters all handlers registered by this Whoops\Run instance
* @return Run
*/
public function unregister()
{
if ($this->isRegistered) {
restore_exception_handler();
restore_error_handler();
$this->isRegistered = false;
}
return $this;
}
/**
* Should Whoops allow Handlers to force the script to quit?
* @param bool|int $exit
* @return bool
*/
public function allowQuit($exit = null)
{
if (func_num_args() == 0) {
return $this->allowQuit;
}
return $this->allowQuit = (bool) $exit;
}
/**
* Silence particular errors in particular files
* @param array|string $patterns List or a single regex pattern to match
* @param int $levels Defaults to E_STRICT | E_DEPRECATED
* @return \Whoops\Run
*/
public function silenceErrorsInPaths($patterns, $levels = 10240)
{
$this->silencedPatterns = array_merge(
$this->silencedPatterns,
array_map(
function ($pattern) use ($levels) {
return array(
"pattern" => $pattern,
"levels" => $levels,
);
},
(array) $patterns
)
);
return $this;
}
/*
* Should Whoops send HTTP error code to the browser if possible?
* Whoops will by default send HTTP code 500, but you may wish to
* use 502, 503, or another 5xx family code.
*
* @param bool|int $code
* @return int|false
*/
public function sendHttpCode($code = null)
{
if (func_num_args() == 0) {
return $this->sendHttpCode;
}
if (!$code) {
return $this->sendHttpCode = false;
}
if ($code === true) {
$code = 500;
}
if ($code < 400 || 600 <= $code) {
throw new InvalidArgumentException(
"Invalid status code '$code', must be 4xx or 5xx"
);
}
return $this->sendHttpCode = $code;
}
/**
* Should Whoops push output directly to the client?
* If this is false, output will be returned by handleException
* @param bool|int $send
* @return bool
*/
public function writeToOutput($send = null)
{
if (func_num_args() == 0) {
return $this->sendOutput;
}
return $this->sendOutput = (bool) $send;
}
/**
* Handles an exception, ultimately generating a Whoops error
* page.
*
* @param Exception $exception
* @return string Output generated by handlers
*/
public function handleException(Exception $exception)
{
// Walk the registered handlers in the reverse order
// they were registered, and pass off the exception
$inspector = $this->getInspector($exception);
// Capture output produced while handling the exception,
// we might want to send it straight away to the client,
// or return it silently.
ob_start();
// Just in case there are no handlers:
$handlerResponse = null;
foreach (array_reverse($this->handlerStack) as $handler) {
$handler->setRun($this);
$handler->setInspector($inspector);
$handler->setException($exception);
// The HandlerInterface does not require an Exception passed to handle()
// and neither of our bundled handlers use it.
// However, 3rd party handlers may have already relied on this parameter,
// and removing it would be possibly breaking for users.
$handlerResponse = $handler->handle($exception);
if (in_array($handlerResponse, array(Handler::LAST_HANDLER, Handler::QUIT))) {
// The Handler has handled the exception in some way, and
// wishes to quit execution (Handler::QUIT), or skip any
// other handlers (Handler::LAST_HANDLER). If $this->allowQuit
// is false, Handler::QUIT behaves like Handler::LAST_HANDLER
break;
}
}
$willQuit = $handlerResponse == Handler::QUIT && $this->allowQuit();
$output = ob_get_clean();
// If we're allowed to, send output generated by handlers directly
// to the output, otherwise, and if the script doesn't quit, return
// it so that it may be used by the caller
if ($this->writeToOutput()) {
// @todo Might be able to clean this up a bit better
// If we're going to quit execution, cleanup all other output
// buffers before sending our own output:
if ($willQuit) {
while (ob_get_level() > 0) {
ob_end_clean();
}
}
$this->writeToOutputNow($output);
}
if ($willQuit) {
flush(); // HHVM fix for https://github.com/facebook/hhvm/issues/4055
exit(1);
}
return $output;
}
/**
* Converts generic PHP errors to \ErrorException
* instances, before passing them off to be handled.
*
* This method MUST be compatible with set_error_handler.
*
* @param int $level
* @param string $message
* @param string $file
* @param int $line
*
* @return bool
* @throws ErrorException
*/
public function handleError($level, $message, $file = null, $line = null)
{
if ($level & error_reporting()) {
foreach ($this->silencedPatterns as $entry) {
$pathMatches = (bool) preg_match($entry["pattern"], $file);
$levelMatches = $level & $entry["levels"];
if ($pathMatches && $levelMatches) {
// Ignore the error, abort handling
return true;
}
}
// XXX we pass $level for the "code" param only for BC reasons.
// see https://github.com/filp/whoops/issues/267
$exception = new ErrorException($message, /*code*/ $level, /*severity*/ $level, $file, $line);
if ($this->canThrowExceptions) {
throw $exception;
} else {
$this->handleException($exception);
}
// Do not propagate errors which were already handled by Whoops.
return true;
}
// Propagate error to the next handler, allows error_get_last() to
// work on silenced errors.
return false;
}
/**
* Special case to deal with Fatal errors and the like.
*/
public function handleShutdown()
{
// If we reached this step, we are in shutdown handler.
// An exception thrown in a shutdown handler will not be propagated
// to the exception handler. Pass that information along.
$this->canThrowExceptions = false;
$error = error_get_last();
if ($error && $this->isLevelFatal($error['type'])) {
// If there was a fatal error,
// it was not handled in handleError yet.
$this->handleError(
$error['type'],
$error['message'],
$error['file'],
$error['line']
);
}
}
/**
* In certain scenarios, like in shutdown handler, we can not throw exceptions
* @var bool
*/
private $canThrowExceptions = true;
/**
* Echo something to the browser
* @param string $output
* @return $this
*/
private function writeToOutputNow($output)
{
if ($this->sendHttpCode() && \Whoops\Util\Misc::canSendHeaders()) {
$httpCode = $this->sendHttpCode();
if (function_exists('http_response_code')) {
http_response_code($httpCode);
} else {
// http_response_code is added in 5.4.
// For compatibility with 5.3 we use the third argument in header call
// First argument must be a real header.
// If it is empty, PHP will ignore the third argument.
// If it is invalid, such as a single space, Apache will handle it well,
// but the PHP development server will hang.
// Setting a full status line would require us to hardcode
// string values for all different status code, and detect the protocol.
// which is an extra error-prone complexity.
header('X-Ignore-This: 1', true, $httpCode);
}
}
echo $output;
return $this;
}
private static function isLevelFatal($level)
{
$errors = E_ERROR;
$errors |= E_PARSE;
$errors |= E_CORE_ERROR;
$errors |= E_CORE_WARNING;
$errors |= E_COMPILE_ERROR;
$errors |= E_COMPILE_WARNING;
return ($level & $errors) > 0;
}
}
+44
View File
@@ -0,0 +1,44 @@
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Util;
class Misc
{
/**
* Can we at this point in time send HTTP headers?
*
* Currently this checks if we are even serving an HTTP request,
* as opposed to running from a command line.
*
* If we are serving an HTTP request, we check if it's not too late.
*
* @return bool
*/
public static function canSendHeaders()
{
return isset($_SERVER["REQUEST_URI"]) && !headers_sent();
}
/**
* Translate ErrorException code into the represented constant.
*
* @param int $error_code
* @return string
*/
public static function translateErrorCode($error_code)
{
$constants = get_defined_constants(true);
if (array_key_exists('Core' , $constants)) {
foreach ($constants['Core'] as $constant => $value) {
if (substr($constant, 0, 2) == 'E_' && $value == $error_code) {
return $constant;
}
}
}
return "E_UNKNOWN";
}
}
+154
View File
@@ -0,0 +1,154 @@
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
*/
namespace Whoops\Util;
/**
* Exposes useful tools for working with/in templates
*/
class TemplateHelper
{
/**
* An array of variables to be passed to all templates
* @var array
*/
private $variables = array();
/**
* Escapes a string for output in an HTML document
*
* @param string $raw
* @return string
*/
public function escape($raw)
{
$flags = ENT_QUOTES;
// HHVM has all constants defined, but only ENT_IGNORE
// works at the moment
if (defined("ENT_SUBSTITUTE") && !defined("HHVM_VERSION")) {
$flags |= ENT_SUBSTITUTE;
} else {
// This is for 5.3.
// The documentation warns of a potential security issue,
// but it seems it does not apply in our case, because
// we do not blacklist anything anywhere.
$flags |= ENT_IGNORE;
}
return htmlspecialchars($raw, $flags, "UTF-8");
}
/**
* Escapes a string for output in an HTML document, but preserves
* URIs within it, and converts them to clickable anchor elements.
*
* @param string $raw
* @return string
*/
public function escapeButPreserveUris($raw)
{
$escaped = $this->escape($raw);
return preg_replace(
"@([A-z]+?://([-\w\.]+[-\w])+(:\d+)?(/([\w/_\.#-]*(\?\S+)?[^\.\s])?)?)@",
"<a href=\"$1\" target=\"_blank\">$1</a>", $escaped
);
}
/**
* Convert a string to a slug version of itself
*
* @param string $original
* @return string
*/
public function slug($original)
{
$slug = str_replace(" ", "-", $original);
$slug = preg_replace('/[^\w\d\-\_]/i', '', $slug);
return strtolower($slug);
}
/**
* Given a template path, render it within its own scope. This
* method also accepts an array of additional variables to be
* passed to the template.
*
* @param string $template
* @param array $additionalVariables
*/
public function render($template, array $additionalVariables = null)
{
$variables = $this->getVariables();
// Pass the helper to the template:
$variables["tpl"] = $this;
if ($additionalVariables !== null) {
$variables = array_replace($variables, $additionalVariables);
}
call_user_func(function () {
extract(func_get_arg(1));
require func_get_arg(0);
}, $template, $variables);
}
/**
* Sets the variables to be passed to all templates rendered
* by this template helper.
*
* @param array $variables
*/
public function setVariables(array $variables)
{
$this->variables = $variables;
}
/**
* Sets a single template variable, by its name:
*
* @param string $variableName
* @param mixd $variableValue
*/
public function setVariable($variableName, $variableValue)
{
$this->variables[$variableName] = $variableValue;
}
/**
* Gets a single template variable, by its name, or
* $defaultValue if the variable does not exist
*
* @param string $variableName
* @param mixed $defaultValue
* @return mixed
*/
public function getVariable($variableName, $defaultValue = null)
{
return isset($this->variables[$variableName]) ?
$this->variables[$variableName] : $defaultValue;
}
/**
* Unsets a single template variable, by its name
*
* @param string $variableName
*/
public function delVariable($variableName)
{
unset($this->variables[$variableName]);
}
/**
* Returns all variables for this helper
*
* @return array
*/
public function getVariables()
{
return $this->variables;
}
}
@@ -0,0 +1,63 @@
<?php
/**
* ZF2 Integration for Whoops
* @author Balázs Németh <zsilbi@zsilbi.hu>
*/
namespace Whoops\Provider\Zend;
use Whoops\Run;
use Zend\Http\Response;
use Zend\Mvc\Application;
use Zend\Mvc\MvcEvent;
use Zend\Mvc\View\Http\ExceptionStrategy as BaseExceptionStrategy;
/**
* @deprecated Use https://github.com/ghislainf/zf2-whoops
*/
class ExceptionStrategy extends BaseExceptionStrategy
{
protected $run;
public function __construct(Run $run)
{
$this->run = $run;
return $this;
}
public function prepareExceptionViewModel(MvcEvent $event)
{
// Do nothing if no error in the event
$error = $event->getError();
if (empty($error)) {
return;
}
// Do nothing if the result is a response object
$result = $event->getResult();
if ($result instanceof Response) {
return;
}
switch ($error) {
case Application::ERROR_CONTROLLER_NOT_FOUND:
case Application::ERROR_CONTROLLER_INVALID:
case Application::ERROR_ROUTER_NO_MATCH:
// Specifically not handling these
return;
case Application::ERROR_EXCEPTION:
default:
$exception = $event->getParam('exception');
if ($exception) {
$response = $event->getResponse();
if (!$response || $response->getStatusCode() === 200) {
header('HTTP/1.0 500 Internal Server Error', true, 500);
}
ob_clean();
$this->run->handleException($event->getParam('exception'));
}
break;
}
}
}
+107
View File
@@ -0,0 +1,107 @@
<?php
/**
* ZF2 Integration for Whoops
* @author Balázs Németh <zsilbi@zsilbi.hu>
*
* The Whoops directory should be added as a module to ZF2 (/vendor/Whoops)
*
* Whoops must be added as the first module
* For example:
* 'modules' => array(
* 'Whoops',
* 'Application',
* ),
*
* This file should be moved next to Whoops/Run.php (/vendor/Whoops/Module.php)
*
*/
namespace Whoops;
use Whoops\Handler\JsonResponseHandler;
use Whoops\Handler\PrettyPageHandler;
use Whoops\Provider\Zend\ExceptionStrategy;
use Whoops\Provider\Zend\RouteNotFoundStrategy;
use Zend\Console\Request as ConsoleRequest;
use Zend\EventManager\EventInterface;
/**
* @deprecated Use https://github.com/ghislainf/zf2-whoops
*/
class Module
{
protected $run;
public function onBootstrap(EventInterface $event)
{
$prettyPageHandler = new PrettyPageHandler();
// Set editor
$config = $event->getApplication()->getServiceManager()->get('Config');
if (isset($config['view_manager']['editor'])) {
$prettyPageHandler->setEditor($config['view_manager']['editor']);
}
$this->run = new Run();
$this->run->register();
$this->run->pushHandler($prettyPageHandler);
$this->attachListeners($event);
}
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
private function attachListeners(EventInterface $event)
{
$request = $event->getRequest();
$application = $event->getApplication();
$services = $application->getServiceManager();
$events = $application->getEventManager();
$config = $services->get('Config');
//Display exceptions based on configuration and console mode
if ($request instanceof ConsoleRequest || empty($config['view_manager']['display_exceptions'])) {
return;
}
$jsonHandler = new JsonResponseHandler();
if (!empty($config['view_manager']['json_exceptions']['show_trace'])) {
//Add trace to the JSON output
$jsonHandler->addTraceToOutput(true);
}
if (!empty($config['view_manager']['json_exceptions']['ajax_only'])) {
//Only return JSON response for AJAX requests
$jsonHandler->onlyForAjaxRequests(true);
}
if (!empty($config['view_manager']['json_exceptions']['display'])) {
//Turn on JSON handler
$this->run->pushHandler($jsonHandler);
}
//Attach the Whoops ExceptionStrategy
$exceptionStrategy = new ExceptionStrategy($this->run);
$exceptionStrategy->attach($events);
//Attach the Whoops RouteNotFoundStrategy
$routeNotFoundStrategy = new RouteNotFoundStrategy($this->run);
$routeNotFoundStrategy->attach($events);
//Detach default ExceptionStrategy
$services->get('Zend\Mvc\View\Http\ExceptionStrategy')->detach($events);
//Detach default RouteNotFoundStrategy
$services->get('Zend\Mvc\View\Http\RouteNotFoundStrategy')->detach($events);
}
}
@@ -0,0 +1,67 @@
<?php
/**
* ZF2 Integration for Whoops
* @author Balázs Németh <zsilbi@zsilbi.hu>
*/
namespace Whoops\Provider\Zend;
use Whoops\Run;
use Zend\Mvc\MvcEvent;
use Zend\Mvc\View\Http\RouteNotFoundStrategy as BaseRouteNotFoundStrategy;
use Zend\Stdlib\ResponseInterface as Response;
use Zend\View\Model\ViewModel;
/**
* @deprecated Use https://github.com/ghislainf/zf2-whoops
*/
class RouteNotFoundStrategy extends BaseRouteNotFoundStrategy
{
protected $run;
public function __construct(Run $run)
{
$this->run = $run;
}
public function prepareNotFoundViewModel(MvcEvent $e)
{
$vars = $e->getResult();
if ($vars instanceof Response) {
// Already have a response as the result
return;
}
$response = $e->getResponse();
if ($response->getStatusCode() != 404) {
// Only handle 404 responses
return;
}
if (!$vars instanceof ViewModel) {
$model = new ViewModel();
if (is_string($vars)) {
$model->setVariable('message', $vars);
} else {
$model->setVariable('message', 'Page not found.');
}
} else {
$model = $vars;
if ($model->getVariable('message') === null) {
$model->setVariable('message', 'Page not found.');
}
}
// If displaying reasons, inject the reason
$this->injectNotFoundReason($model, $e);
// If displaying exceptions, inject
$this->injectException($model, $e);
// Inject controller if we're displaying either the reason or the exception
$this->injectController($model, $e);
ob_clean();
throw new \Exception($model->getVariable('message') . ' ' . $model->getVariable('reason'));
}
}
@@ -0,0 +1,20 @@
<?php
/**
* ZF2 Integration for Whoops
* @author Balázs Németh <zsilbi@zsilbi.hu>
*
* Example controller configuration
*/
return array(
'view_manager' => array(
'editor' => 'sublime',
'display_not_found_reason' => true,
'display_exceptions' => true,
'json_exceptions' => array(
'display' => true,
'ajax_only' => true,
'show_trace' => true,
),
),
);
+58
View File
@@ -0,0 +1,58 @@
<?php
namespace Gregwar\Image\Adapter;
use Gregwar\Image\Source\Source;
/**
* Base Adapter Implementation to handle Image information
*/
abstract class Adapter implements AdapterInterface
{
/**
* @var Source
*/
protected $source;
/**
* The image resource handler
*/
protected $resource;
public function __construct(){
}
/**
* @inheritdoc
*/
public function setSource(Source $source)
{
$this->source = $source;
return $this;
}
/**
* @inheritdoc
*/
public function getResource()
{
return $this->resource;
}
/**
* Does this adapter supports the given type ?
*/
protected function supports($type)
{
return false;
}
/**
* Converts the image to true color
*/
protected function convertToTrueColor()
{
}
}
@@ -0,0 +1,388 @@
<?php
namespace Gregwar\Image\Adapter;
use Gregwar\Image\Image;
use Gregwar\Image\Source\Source;
/**
* all the functions / methods to work on images
*
* if changing anything please also add it to \Gregwar\Image\Image
*
* @author wodka <michael.schramm@gmail.com>
*/
interface AdapterInterface{
/**
* set the image source for the adapter
*
* @param Source $source
* @return $this
*/
public function setSource(Source $source);
/**
* get the raw resource
*
* @return resource
*/
public function getResource();
/**
* Gets the name of the adapter
*
* @return string
*/
public function getName();
/**
* Image width
*
* @return int
*/
public function width();
/**
* Image height
*
* @return int
*/
public function height();
/**
* Init the resource
*
* @return $this
*/
public function init();
/**
* Save the image as a gif
*
* @return $this
*/
public function saveGif($file);
/**
* Save the image as a png
*
* @return $this
*/
public function savePng($file);
/**
* Save the image as a jpeg
*
* @return $this
*/
public function saveJpeg($file, $quality);
/**
* Works as resize() excepts that the layout will be cropped
*
* @param int $width the width
* @param int $height the height
* @param int $background the background
*
* @return $this
*/
public function cropResize($width = null, $height = null, $background=0xffffff);
/**
* Resize the image preserving scale. Can enlarge it.
*
* @param int $width the width
* @param int $height the height
* @param int $background the background
* @param boolean $crop
*
* @return $this
*/
public function scaleResize($width = null, $height = null, $background=0xffffff, $crop = false);
/**
* Resizes the image. It will never be enlarged.
*
* @param int $width the width
* @param int $height the height
* @param int $background the background
* @param boolean $force
* @param boolean $rescale
* @param boolean $crop
*
* @return $this
*/
public function resize($width = null, $height = null, $background = 0xffffff, $force = false, $rescale = false, $crop = false);
/**
* Crops the image
*
* @param int $x the top-left x position of the crop box
* @param int $y the top-left y position of the crop box
* @param int $width the width of the crop box
* @param int $height the height of the crop box
*
* @return $this
*/
public function crop($x, $y, $width, $height);
/**
* enable progressive image loading
*
* @return $this
*/
public function enableProgressive();
/**
* Resizes the image forcing the destination to have exactly the
* given width and the height
*
* @param int $width the width
* @param int $height the height
* @param int $background the background
*
* @return $this
*/
public function forceResize($width = null, $height = null, $background = 0xffffff);
/**
* Perform a zoom crop of the image to desired width and height
*
* @param integer $width Desired width
* @param integer $height Desired height
* @param int $background
*
* @return $this
*/
public function zoomCrop($width, $height, $background = 0xffffff);
/**
* Fills the image background to $bg if the image is transparent
*
* @param int $background background color
*
* @return $this
*/
public function fillBackground($background = 0xffffff);
/**
* Negates the image
*
* @return $this
*/
public function negate();
/**
* Changes the brightness of the image
*
* @param int $brightness the brightness
*
* @return $this
*/
public function brightness($brightness);
/**
* Contrasts the image
*
* @param int $contrast the contrast [-100, 100]
*
* @return $this
*/
public function contrast($contrast);
/**
* Apply a grayscale level effect on the image
*
* @return $this
*/
public function grayscale();
/**
* Emboss the image
*
* @return $this
*/
public function emboss();
/**
* Smooth the image
*
* @param int $p value between [-10,10]
*
* @return $this
*/
public function smooth($p);
/**
* Sharps the image
*
* @return $this
*/
public function sharp();
/**
* Edges the image
*
* @return $this
*/
public function edge();
/**
* Colorize the image
*
* @param int $red value in range [-255, 255]
* @param int $green value in range [-255, 255]
* @param int $blue value in range [-255, 255]
*
* @return $this
*/
public function colorize($red, $green, $blue);
/**
* apply sepia to the image
*
* @return $this
*/
public function sepia();
/**
* Merge with another image
*
* @param Image $other
* @param int $x
* @param int $y
* @param int $width
* @param int $height
*
* @return $this
*/
public function merge(Image $other, $x = 0, $y = 0, $width = null, $height = null);
/**
* Rotate the image
*
* @param float $angle
* @param int $background
*
* @return $this
*/
public function rotate($angle, $background = 0xffffff);
/**
* Fills the image
*
* @param int $color
* @param int $x
* @param int $y
*
* @return $this
*/
public function fill($color = 0xffffff, $x = 0, $y = 0);
/**
* write text to the image
*
* @param string $font
* @param string $text
* @param int $x
* @param int $y
* @param int $size
* @param int $angle
* @param int $color
* @param string $align
*/
public function write($font, $text, $x = 0, $y = 0, $size = 12, $angle = 0, $color = 0x000000, $align = 'left');
/**
* Draws a rectangle
*
* @param int $x1
* @param int $y1
* @param int $x2
* @param int $y2
* @param int $color
* @param bool $filled
*
* @return $this
*/
public function rectangle($x1, $y1, $x2, $y2, $color, $filled = false);
/**
* Draws a rounded rectangle
*
* @param int $x1
* @param int $y1
* @param int $x2
* @param int $y2
* @param int $radius
* @param int $color
* @param bool $filled
*
* @return $this
*/
public function roundedRectangle($x1, $y1, $x2, $y2, $radius, $color, $filled = false);
/**
* Draws a line
*
* @param int $x1
* @param int $y1
* @param int $x2
* @param int $y2
* @param int $color
*
* @return $this
*/
public function line($x1, $y1, $x2, $y2, $color = 0x000000);
/**
* Draws an ellipse
*
* @param int $cx
* @param int $cy
* @param int $width
* @param int $height
* @param int $color
* @param bool $filled
*
* @return $this
*/
public function ellipse($cx, $cy, $width, $height, $color = 0x000000, $filled = false);
/**
* Draws a circle
*
* @param int $cx
* @param int $cy
* @param int $r
* @param int $color
* @param bool $filled
*
* @return $this
*/
public function circle($cx, $cy, $r, $color = 0x000000, $filled = false);
/**
* Draws a polygon
*
* @param array $points
* @param int $color
* @param bool $filled
*
* @return $this
*/
public function polygon(array $points, $color, $filled = false);
/**
* Flips the image
*
* @param int $flipVertical
* @param int $flipHorizontal
*
* @return $this
*/
public function flip($flipVertical, $flipHorizontal);
}
+351
View File
@@ -0,0 +1,351 @@
<?php
namespace Gregwar\Image\Adapter;
abstract class Common extends Adapter
{
/**
* @inheritdoc
*/
public function zoomCrop($width, $height, $background = 'transparent', $xPosLetter = 'center', $yPosLetter = 'center')
{
// Calculate the different ratios
$originalRatio = $this->width() / $this->height();
$newRatio = $width / $height;
// Compare ratios
if ($originalRatio > $newRatio) {
// Original image is wider
$newHeight = $height;
$newWidth = (int) $height * $originalRatio;
} else {
// Equal width or smaller
$newHeight = (int) $width / $originalRatio;
$newWidth = $width;
}
// Perform resize
$this->resize($newWidth, $newHeight, $background, true);
// Define x position
switch($xPosLetter) {
case 'L':
case 'left':
$xPos = 0;
break;
case 'R':
case 'right':
$xPos = (int) $newWidth - $width;
break;
default:
$xPos = (int) ($newWidth - $width) / 2;
}
// Define y position
switch($yPosLetter) {
case 'T':
case 'top':
$yPos = 0;
break;
case 'B':
case 'bottom':
$yPos = (int) $newHeight - $height;
break;
default:
$yPos = (int) ($newHeight - $height) / 2;
}
// Crop image to reach desired size
$this->crop($xPos, $yPos, $width, $height);
return $this;
}
/**
* Resizes the image forcing the destination to have exactly the
* given width and the height
*
* @param int $w the width
* @param int $h the height
* @param int $bg the background
*/
public function forceResize($width = null, $height = null, $background = 'transparent')
{
return $this->resize($width, $height, $background, true);
}
/**
* @inheritdoc
*/
public function scaleResize($width = null, $height = null, $background='transparent', $crop = false)
{
return $this->resize($width, $height, $background, false, true, $crop);
}
/**
* @inheritdoc
*/
public function cropResize($width = null, $height = null, $background='transparent')
{
return $this->resize($width, $height, $background, false, false, true);
}
/**
* Fix orientation using Exif informations
*/
public function fixOrientation()
{
if (!extension_loaded('exif')) {
throw new \RuntimeException('You need to EXIF PHP Extension to use this function');
}
$exif = exif_read_data($this->source->getInfos());
if(!array_key_exists('Orientation', $exif)) {
return $this;
}
switch($exif['Orientation']) {
case 1:
break;
case 2:
$this->flip(false, true);
break;
case 3: // 180 rotate left
$this->rotate(180);
break;
case 4: // vertical flip
$this->flip(true, false);
break;
case 5: // vertical flip + 90 rotate right
$this->flip(true, false);
$this->rotate(-90);
break;
case 6: // 90 rotate right
$this->rotate(-90);
break;
case 7: // horizontal flip + 90 rotate right
$this->flip(false, true);
$this->rotate(-90);
break;
case 8: // 90 rotate left
$this->rotate(90);
break;
}
return $this;
}
/**
* Opens the image
*/
abstract protected function openGif($file);
abstract protected function openJpeg($file);
abstract protected function openPng($file);
/**
* Creates an image
*/
abstract protected function createImage($width, $height);
/**
* Creating an image using $data
*/
abstract protected function createImageFromData($data);
/**
* Loading image from $resource
*/
protected function loadResource($resource)
{
$this->resource = $resource;
}
protected function loadFile($file, $type)
{
if (!$this->supports($type)) {
throw new \RuntimeException('Type '.$type.' is not supported by GD');
}
if ($type == 'jpeg') {
$this->openJpeg($file);
}
if ($type == 'gif') {
$this->openGif($file);
}
if ($type == 'png') {
$this->openPng($file);
}
if (false === $this->resource) {
throw new \UnexpectedValueException('Unable to open file ('.$file.')');
} else {
$this->convertToTrueColor();
}
}
/**
* @inheritdoc
*/
public function init()
{
$source = $this->source;
if ($source instanceof \Gregwar\Image\Source\File) {
$this->loadFile($source->getFile(), $source->guessType());
} else if ($source instanceof \Gregwar\Image\Source\Create) {
$this->createImage($source->getWidth(), $source->getHeight());
} else if ($source instanceof \Gregwar\Image\Source\Data) {
$this->createImageFromData($source->getData());
} else if ($source instanceof \Gregwar\Image\Source\Resource) {
$this->loadResource($source->getResource());
} else {
throw new \Exception('Unsupported image source type '.get_class($source));
}
return $this;
}
/**
* @inheritdoc
*/
public function resize($width = null, $height = null, $background = 'transparent', $force = false, $rescale = false, $crop = false)
{
$current_width = $this->width();
$current_height = $this->height();
$new_width = 0;
$new_height = 0;
$scale = 1.0;
if ($height === null && preg_match('#^(.+)%$#mUsi', $width, $matches)) {
$width = round($current_width * ((float)$matches[1]/100.0));
$height = round($current_height * ((float)$matches[1]/100.0));
}
if (!$rescale && (!$force || $crop)) {
if ($width!=null && $current_width>$width) {
$scale = $current_width/$width;
}
if ($height!=null && $current_height>$height) {
if ($current_height/$height > $scale)
$scale = $current_height/$height;
}
} else {
if ($width!=null) {
$scale = $current_width/$width;
$new_width = $width;
}
if ($height!=null) {
if ($width!=null && $rescale) {
$scale = max($scale,$current_height/$height);
} else {
$scale = $current_height/$height;
}
$new_height = $height;
}
}
if (!$force || $width==null || $rescale) {
$new_width = round($current_width/$scale);
}
if (!$force || $height==null || $rescale) {
$new_height = round($current_height/$scale);
}
if ($width == null || $crop) {
$width = $new_width;
}
if ($height == null || $crop) {
$height = $new_height;
}
$this->doResize($background, $width, $height, $new_width, $new_height);
}
/**
* Trim background color arround the image
*
* @param int $bg the background
*/
protected function _trimColor($background='transparent')
{
$width = $this->width();
$height = $this->height();
$b_top = 0;
$b_lft = 0;
$b_btm = $height - 1;
$b_rt = $width - 1;
//top
for(; $b_top < $height; ++$b_top) {
for($x = 0; $x < $width; ++$x) {
if ($this->getColor($x, $b_top) != $background) {
break 2;
}
}
}
// bottom
for(; $b_btm >= 0; --$b_btm) {
for($x = 0; $x < $width; ++$x) {
if ($this->getColor($x, $b_btm) != $background) {
break 2;
}
}
}
// left
for(; $b_lft < $width; ++$b_lft) {
for($y = $b_top; $y <= $b_btm; ++$y) {
if ($this->getColor($b_lft, $y) != $background) {
break 2;
}
}
}
// right
for(; $b_rt >= 0; --$b_rt) {
for($y = $b_top; $y <= $b_btm; ++$y) {
if ($this->getColor($b_rt, $y) != $background) {
break 2;
}
}
}
$b_btm++;
$b_rt++;
$this->crop($b_lft, $b_top, $b_rt - $b_lft, $b_btm - $b_top);
}
/**
* Resizes the image to an image having size of $target_width, $target_height, using
* $new_width and $new_height and padding with $bg color
*/
abstract protected function doResize($bg, $target_width, $target_height, $new_width, $new_height);
/**
* Gets the color of the $x, $y pixel
*/
abstract protected function getColor($x, $y);
/**
* @inheritdoc
*/
public function enableProgressive(){
throw new \Exception('The Adapter '.$this->getName().' does not support Progressive Image loading');
}
}
+567
View File
@@ -0,0 +1,567 @@
<?php
namespace Gregwar\Image\Adapter;
use Gregwar\Image\ImageColor;
use Gregwar\Image\Image;
class GD extends Common
{
public static $gdTypes = array(
'jpeg' => \IMG_JPG,
'gif' => \IMG_GIF,
'png' => \IMG_PNG,
);
protected function loadResource($resource)
{
parent::loadResource($resource);
imagesavealpha($this->resource, true);
}
/**
* Gets the width and the height for writing some text
*/
public static function TTFBox($font, $text, $size, $angle = 0)
{
$box = imagettfbbox($size, $angle, $font, $text);
return array(
'width' => abs($box[2] - $box[0]),
'height' => abs($box[3] - $box[5])
);
}
public function __construct()
{
parent::__construct();
if (!(extension_loaded('gd') && function_exists('gd_info'))) {
throw new \RuntimeException('You need to install GD PHP Extension to use this library');
}
}
/**
* @inheritdoc
*/
public function getName()
{
return 'GD';
}
/**
* @inheritdoc
*/
public function fillBackground($background = 0xffffff)
{
$w = $this->width();
$h = $this->height();
$n = imagecreatetruecolor($w, $h);
imagefill($n, 0, 0, ImageColor::gdAllocate($this->resource, $background));
imagecopyresampled($n, $this->resource, 0, 0, 0, 0, $w, $h, $w, $h);
imagedestroy($this->resource);
$this->resource = $n;
return $this;
}
/**
* Do the image resize
*
* @return $this
*/
protected function doResize($bg, $target_width, $target_height, $new_width, $new_height)
{
$width = $this->width();
$height = $this->height();
$n = imagecreatetruecolor($target_width, $target_height);
if ($bg != 'transparent') {
imagefill($n, 0, 0, ImageColor::gdAllocate($this->resource, $bg));
} else {
imagealphablending($n, false);
$color = ImageColor::gdAllocate($this->resource, 'transparent');
imagefill($n, 0, 0, $color);
imagesavealpha($n, true);
}
imagecopyresampled($n, $this->resource, ($target_width-$new_width)/2, ($target_height-$new_height)/2, 0, 0, $new_width, $new_height, $width, $height);
imagedestroy($this->resource);
$this->resource = $n;
return $this;
}
/**
* @inheritdoc
*/
public function crop($x, $y, $width, $height)
{
$destination = imagecreatetruecolor($width, $height);
imagealphablending($destination, false);
imagesavealpha($destination, true);
imagecopy($destination, $this->resource, 0, 0, $x, $y, $this->width(), $this->height());
imagedestroy($this->resource);
$this->resource = $destination;
return $this;
}
/**
* @inheritdoc
*/
public function negate()
{
imagefilter($this->resource, IMG_FILTER_NEGATE);
return $this;
}
/**
* @inheritdoc
*/
public function brightness($brightness)
{
imagefilter($this->resource, IMG_FILTER_BRIGHTNESS, $brightness);
return $this;
}
/**
* @inheritdoc
*/
public function contrast($contrast)
{
imagefilter($this->resource, IMG_FILTER_CONTRAST, $contrast);
return $this;
}
/**
* @inheritdoc
*/
public function grayscale()
{
imagefilter($this->resource, IMG_FILTER_GRAYSCALE);
return $this;
}
/**
* @inheritdoc
*/
public function emboss()
{
imagefilter($this->resource, IMG_FILTER_EMBOSS);
return $this;
}
/**
* @inheritdoc
*/
public function smooth($p)
{
imagefilter($this->resource, IMG_FILTER_SMOOTH, $p);
return $this;
}
/**
* @inheritdoc
*/
public function sharp()
{
imagefilter($this->resource, IMG_FILTER_MEAN_REMOVAL);
return $this;
}
/**
* @inheritdoc
*/
public function edge()
{
imagefilter($this->resource, IMG_FILTER_EDGEDETECT);
return $this;
}
/**
* @inheritdoc
*/
public function colorize($red, $green, $blue)
{
imagefilter($this->resource, IMG_FILTER_COLORIZE, $red, $green, $blue);
return $this;
}
/**
* @inheritdoc
*/
public function sepia()
{
imagefilter($this->resource, IMG_FILTER_GRAYSCALE);
imagefilter($this->resource, IMG_FILTER_COLORIZE, 100, 50, 0);
return $this;
}
/**
* @inheritdoc
*/
public function merge(Image $other, $x = 0, $y = 0, $width = null, $height = null)
{
$other = clone $other;
$other->init();
$other->applyOperations();
imagealphablending($this->resource, true);
if (null == $width) {
$width = $other->width();
}
if (null == $height) {
$height = $other->height();
}
imagecopyresampled($this->resource, $other->getAdapter()->getResource(), $x, $y, 0, 0, $width, $height, $width, $height);
return $this;
}
/**
* @inheritdoc
*/
public function rotate($angle, $background = 0xffffff)
{
$this->resource = imagerotate($this->resource, $angle, ImageColor::gdAllocate($this->resource, $background));
imagealphablending($this->resource, true);
imagesavealpha($this->resource, true);
return $this;
}
/**
* @inheritdoc
*/
public function fill($color = 0xffffff, $x = 0, $y = 0)
{
imagealphablending($this->resource, false);
imagefill($this->resource, $x, $y, ImageColor::gdAllocate($this->resource, $color));
return $this;
}
/**
* @inheritdoc
*/
public function write($font, $text, $x = 0, $y = 0, $size = 12, $angle = 0, $color = 0x000000, $align = 'left')
{
imagealphablending($this->resource, true);
if ($align != 'left') {
$sim_size = self::TTFBox($font, $text, $size, $angle);
if ($align == 'center') {
$x -= $sim_size['width'] / 2;
}
if ($align == 'right') {
$x -= $sim_size['width'];
}
}
imagettftext($this->resource, $size, $angle, $x, $y, ImageColor::gdAllocate($this->resource, $color), $font, $text);
return $this;
}
/**
* @inheritdoc
*/
public function rectangle($x1, $y1, $x2, $y2, $color, $filled = false)
{
if ($filled) {
imagefilledrectangle($this->resource, $x1, $y1, $x2, $y2, ImageColor::gdAllocate($this->resource, $color));
} else {
imagerectangle($this->resource, $x1, $y1, $x2, $y2, ImageColor::gdAllocate($this->resource, $color));
}
return $this;
}
/**
* @inheritdoc
*/
public function roundedRectangle($x1, $y1, $x2, $y2, $radius, $color, $filled = false) {
if ($color) {
$color = ImageColor::gdAllocate($this->resource, $color);
}
if ($filled == true) {
imagefilledrectangle($this->resource, $x1+$radius, $y1, $x2-$radius, $y2, $color);
imagefilledrectangle($this->resource, $x1, $y1+$radius, $x1+$radius-1, $y2-$radius, $color);
imagefilledrectangle($this->resource, $x2-$radius+1, $y1+$radius, $x2, $y2-$radius, $color);
imagefilledarc($this->resource,$x1+$radius, $y1+$radius, $radius*2, $radius*2, 180 , 270, $color, IMG_ARC_PIE);
imagefilledarc($this->resource,$x2-$radius, $y1+$radius, $radius*2, $radius*2, 270 , 360, $color, IMG_ARC_PIE);
imagefilledarc($this->resource,$x1+$radius, $y2-$radius, $radius*2, $radius*2, 90 , 180, $color, IMG_ARC_PIE);
imagefilledarc($this->resource,$x2-$radius, $y2-$radius, $radius*2, $radius*2, 360 , 90, $color, IMG_ARC_PIE);
} else {
imageline($this->resource, $x1+$radius, $y1, $x2-$radius, $y1, $color);
imageline($this->resource, $x1+$radius, $y2, $x2-$radius, $y2, $color);
imageline($this->resource, $x1, $y1+$radius, $x1, $y2-$radius, $color);
imageline($this->resource, $x2, $y1+$radius, $x2, $y2-$radius, $color);
imagearc($this->resource,$x1+$radius, $y1+$radius, $radius*2, $radius*2, 180 , 270, $color);
imagearc($this->resource,$x2-$radius, $y1+$radius, $radius*2, $radius*2, 270 , 360, $color);
imagearc($this->resource,$x1+$radius, $y2-$radius, $radius*2, $radius*2, 90 , 180, $color);
imagearc($this->resource,$x2-$radius, $y2-$radius, $radius*2, $radius*2, 360 , 90, $color);
}
return $this;
}
/**
* @inheritdoc
*/
public function line($x1, $y1, $x2, $y2, $color = 0x000000)
{
imageline($this->resource, $x1, $y1, $x2, $y2, ImageColor::gdAllocate($this->resource, $color));
return $this;
}
/**
* @inheritdoc
*/
public function ellipse($cx, $cy, $width, $height, $color = 0x000000, $filled = false)
{
if ($filled) {
imagefilledellipse($this->resource, $cx, $cy, $width, $height, ImageColor::gdAllocate($this->resource, $color));
} else {
imageellipse($this->resource, $cx, $cy, $width, $height, ImageColor::gdAllocate($this->resource, $color));
}
return $this;
}
/**
* @inheritdoc
*/
public function circle($cx, $cy, $r, $color = 0x000000, $filled = false)
{
return $this->ellipse($cx, $cy, $r, $r, ImageColor::gdAllocate($this->resource, $color), $filled);
}
/**
* @inheritdoc
*/
public function polygon(array $points, $color, $filled = false)
{
if ($filled) {
imagefilledpolygon($this->resource, $points, count($points)/2, ImageColor::gdAllocate($this->resource, $color));
} else {
imagepolygon($this->resource, $points, count($points)/2, ImageColor::gdAllocate($this->resource, $color));
}
return $this;
}
/**
* @inheritdoc
*/
public function flip($flipVertical, $flipHorizontal) {
if (!$flipVertical && !$flipHorizontal) {
return $this;
}
if (function_exists('imageflip')) {
if ($flipVertical && $flipHorizontal) {
$flipMode = \IMG_FLIP_BOTH;
} else if ($flipVertical && !$flipHorizontal) {
$flipMode = \IMG_FLIP_VERTICAL;
} else if (!$flipVertical && $flipHorizontal) {
$flipMode = \IMG_FLIP_HORIZONTAL;
}
imageflip($this->resource, $flipMode);
} else {
$width = $this->width();
$height = $this->height();
$src_x = 0;
$src_y = 0;
$src_width = $width;
$src_height = $height;
if ($flipVertical) {
$src_y = $height -1;
$src_height = -$height;
}
if ($flipHorizontal) {
$src_x = $width -1;
$src_width = -$width;
}
$imgdest = imagecreatetruecolor ($width, $height);
imagealphablending($imgdest, false);
imagesavealpha($imgdest, true);
if (imagecopyresampled($imgdest, $this->resource, 0, 0, $src_x, $src_y , $width, $height, $src_width, $src_height)) {
imagedestroy($this->resource);
$this->resource = $imgdest;
}
}
return $this;
}
/**
* @inheritdoc
*/
public function width()
{
if (null === $this->resource) {
$this->init();
}
return imagesx($this->resource);
}
/**
* @inheritdoc
*/
public function height()
{
if (null === $this->resource) {
$this->init();
}
return imagesy($this->resource);
}
protected function createImage($width, $height)
{
$this->resource = imagecreatetruecolor($width, $height);
}
protected function createImageFromData($data)
{
$this->resource = @imagecreatefromstring($data);
}
/**
* Converts the image to true color
*/
protected function convertToTrueColor()
{
if (!imageistruecolor($this->resource)) {
if (function_exists('imagepalettetotruecolor')) {
// Available in PHP 5.5
imagepalettetotruecolor($this->resource);
} else {
$transparentIndex = imagecolortransparent($this->resource);
$w = $this->width();
$h = $this->height();
$img = imagecreatetruecolor($w, $h);
imagecopy($img, $this->resource, 0, 0, 0, 0, $w, $h);
if ($transparentIndex != -1) {
$width = $this->width();
$height = $this->height();
imagealphablending($img, false);
imagesavealpha($img, true);
for ($x=0; $x<$width; $x++) {
for ($y=0; $y<$height; $y++) {
if (imagecolorat($this->resource, $x, $y) == $transparentIndex) {
imagesetpixel($img, $x, $y, 127 << 24);
}
}
}
}
$this->resource = $img;
}
}
imagesavealpha($this->resource, true);
}
/**
* @inheritdoc
*/
public function saveGif($file)
{
$transColor = imagecolorallocatealpha($this->resource, 255, 255, 255, 127);
imagecolortransparent($this->resource, $transColor);
imagegif($this->resource, $file);
return $this;
}
/**
* @inheritdoc
*/
public function savePng($file)
{
imagepng($this->resource, $file);
return $this;
}
/**
* @inheritdoc
*/
public function saveJpeg($file, $quality)
{
imagejpeg($this->resource, $file, $quality);
return $this;
}
/**
* Try to open the file using jpeg
*
*/
protected function openJpeg($file)
{
$this->resource = @imagecreatefromjpeg($file);
}
/**
* Try to open the file using gif
*/
protected function openGif($file)
{
$this->resource = @imagecreatefromgif($file);
}
/**
* Try to open the file using PNG
*/
protected function openPng($file)
{
$this->resource = @imagecreatefrompng($file);
}
/**
* Does this adapter supports type ?
*/
protected function supports($type)
{
return (imagetypes() & self::$gdTypes[$type]);
}
protected function getColor($x, $y)
{
return imagecolorat($this->resource, $x, $y);
}
/**
* @inheritdoc
*/
public function enableProgressive(){
imageinterlace($this->resource, 1);
return $this;
}
}
+389
View File
@@ -0,0 +1,389 @@
<?php
namespace Gregwar\Image\Adapter;
use Gregwar\Image\Image;
class Imagick extends Common{
public function __construct(){
throw new \Exception('Imagick is not supported right now');
}
/**
* Gets the name of the adapter
*
* @return string
*/
public function getName(){
return 'ImageMagick';
}
/**
* Image width
*
* @return int
*/
public function width(){
// TODO: Implement width() method.
}
/**
* Image height
*
* @return int
*/
public function height(){
// TODO: Implement height() method.
}
/**
* Save the image as a gif
*
* @return $this
*/
public function saveGif($file){
// TODO: Implement saveGif() method.
}
/**
* Save the image as a png
*
* @return $this
*/
public function savePng($file){
// TODO: Implement savePng() method.
}
/**
* Save the image as a jpeg
*
* @return $this
*/
public function saveJpeg($file, $quality){
// TODO: Implement saveJpeg() method.
}
/**
* Crops the image
*
* @param int $x the top-left x position of the crop box
* @param int $y the top-left y position of the crop box
* @param int $width the width of the crop box
* @param int $height the height of the crop box
*
* @return $this
*/
public function crop($x, $y, $width, $height){
// TODO: Implement crop() method.
}
/**
* Fills the image background to $bg if the image is transparent
*
* @param int $background background color
*
* @return $this
*/
public function fillBackground($background = 0xffffff){
// TODO: Implement fillBackground() method.
}
/**
* Negates the image
*
* @return $this
*/
public function negate(){
// TODO: Implement negate() method.
}
/**
* Changes the brightness of the image
*
* @param int $brightness the brightness
*
* @return $this
*/
public function brightness($brightness){
// TODO: Implement brightness() method.
}
/**
* Contrasts the image
*
* @param int $contrast the contrast [-100, 100]
*
* @return $this
*/
public function contrast($contrast){
// TODO: Implement contrast() method.
}
/**
* Apply a grayscale level effect on the image
*
* @return $this
*/
public function grayscale(){
// TODO: Implement grayscale() method.
}
/**
* Emboss the image
*
* @return $this
*/
public function emboss(){
// TODO: Implement emboss() method.
}
/**
* Smooth the image
*
* @param int $p value between [-10,10]
*
* @return $this
*/
public function smooth($p){
// TODO: Implement smooth() method.
}
/**
* Sharps the image
*
* @return $this
*/
public function sharp(){
// TODO: Implement sharp() method.
}
/**
* Edges the image
*
* @return $this
*/
public function edge(){
// TODO: Implement edge() method.
}
/**
* Colorize the image
*
* @param int $red value in range [-255, 255]
* @param int $green value in range [-255, 255]
* @param int $blue value in range [-255, 255]
*
* @return $this
*/
public function colorize($red, $green, $blue){
// TODO: Implement colorize() method.
}
/**
* apply sepia to the image
*
* @return $this
*/
public function sepia(){
// TODO: Implement sepia() method.
}
/**
* Merge with another image
*
* @param Image $other
* @param int $x
* @param int $y
* @param int $width
* @param int $height
*
* @return $this
*/
public function merge(Image $other, $x = 0, $y = 0, $width = null, $height = null){
// TODO: Implement merge() method.
}
/**
* Rotate the image
*
* @param float $angle
* @param int $background
*
* @return $this
*/
public function rotate($angle, $background = 0xffffff){
// TODO: Implement rotate() method.
}
/**
* Fills the image
*
* @param int $color
* @param int $x
* @param int $y
*
* @return $this
*/
public function fill($color = 0xffffff, $x = 0, $y = 0){
// TODO: Implement fill() method.
}
/**
* write text to the image
*
* @param string $font
* @param string $text
* @param int $x
* @param int $y
* @param int $size
* @param int $angle
* @param int $color
* @param string $align
*/
public function write($font, $text, $x = 0, $y = 0, $size = 12, $angle = 0, $color = 0x000000, $align = 'left'){
// TODO: Implement write() method.
}
/**
* Draws a rectangle
*
* @param int $x1
* @param int $y1
* @param int $x2
* @param int $y2
* @param int $color
* @param bool $filled
*
* @return $this
*/
public function rectangle($x1, $y1, $x2, $y2, $color, $filled = false){
// TODO: Implement rectangle() method.
}
/**
* Draws a rounded rectangle
*
* @param int $x1
* @param int $y1
* @param int $x2
* @param int $y2
* @param int $radius
* @param int $color
* @param bool $filled
*
* @return $this
*/
public function roundedRectangle($x1, $y1, $x2, $y2, $radius, $color, $filled = false){
// TODO: Implement roundedRectangle() method.
}
/**
* Draws a line
*
* @param int $x1
* @param int $y1
* @param int $x2
* @param int $y2
* @param int $color
*
* @return $this
*/
public function line($x1, $y1, $x2, $y2, $color = 0x000000){
// TODO: Implement line() method.
}
/**
* Draws an ellipse
*
* @param int $cx
* @param int $cy
* @param int $width
* @param int $height
* @param int $color
* @param bool $filled
*
* @return $this
*/
public function ellipse($cx, $cy, $width, $height, $color = 0x000000, $filled = false){
// TODO: Implement ellipse() method.
}
/**
* Draws a circle
*
* @param int $cx
* @param int $cy
* @param int $r
* @param int $color
* @param bool $filled
*
* @return $this
*/
public function circle($cx, $cy, $r, $color = 0x000000, $filled = false){
// TODO: Implement circle() method.
}
/**
* Draws a polygon
*
* @param array $points
* @param int $color
* @param bool $filled
*
* @return $this
*/
public function polygon(array $points, $color, $filled = false){
// TODO: Implement polygon() method.
}
/**
* @inheritdoc
*/
public function flip($flipVertical, $flipHorizontal) {
// TODO: Implement flip method
}
/**
* Opens the image
*/
protected function openGif($file){
// TODO: Implement openGif() method.
}
protected function openJpeg($file){
// TODO: Implement openJpeg() method.
}
protected function openPng($file){
// TODO: Implement openPng() method.
}
/**
* Creates an image
*/
protected function createImage($width, $height){
// TODO: Implement createImage() method.
}
/**
* Creating an image using $data
*/
protected function createImageFromData($data){
// TODO: Implement createImageFromData() method.
}
/**
* Resizes the image to an image having size of $target_width, $target_height, using
* $new_width and $new_height and padding with $bg color
*/
protected function doResize($bg, $target_width, $target_height, $new_width, $new_height){
// TODO: Implement doResize() method.
}
/**
* Gets the color of the $x, $y pixel
*/
protected function getColor($x, $y){
// TODO: Implement getColor() method.
}
}
@@ -0,0 +1,16 @@
<?php
namespace Gregwar\Image\Exceptions;
class GenerationError extends \Exception
{
public function __construct($newNewFile)
{
$this->newNewFile = $newNewFile;
}
public function getNewFile()
{
return $this->newNewFile;
}
}
+83
View File
@@ -0,0 +1,83 @@
<?php
namespace Gregwar\Image;
/**
* Garbage collect a directory, this will crawl a directory, lookng
* for files older than X days and destroy them
*
* @author Gregwar <g.passault@gmail.com>
*/
class GarbageCollect
{
/**
* Drops old files of a directory
*
* @param string $directory the name of the target directory
* @param int $days the number of days to consider a file old
* @param bool $verbose enable verbose output
*
* @return true if all the files/directories of a directory was wiped
*/
public static function dropOldFiles($directory, $days = 30, $verbose = false)
{
$allDropped = true;
$now = time();
$dir = opendir($directory);
if (!$dir) {
if ($verbose) {
echo "! Unable to open $directory\n";
}
return false;
}
while ($file = readdir($dir)) {
if ($file == '.' || $file == '..') {
continue;
}
$fullName = $directory.'/'.$file;
$old = $now-filemtime($fullName);
if (is_dir($fullName)) {
// Directories are recursively crawled
if (static::dropOldFiles($fullName, $days, $verbose)) {
self::drop($fullName, $verbose);
} else {
$allDropped = false;
}
} else {
if ($old > (24*60*60*$days)) {
self::drop($fullName, $verbose);
} else {
$allDropped = false;
}
}
}
closedir($dir);
return $allDropped;
}
/**
* Drops a file or an empty directory
*/
public static function drop($file, $verbose = false)
{
if (is_dir($file)) {
@rmdir($file);
} else {
@unlink($file);
}
if ($verbose) {
echo "> Dropping $file...\n";
}
}
}
+752
View File
@@ -0,0 +1,752 @@
<?php
namespace Gregwar\Image;
use Gregwar\Image\Adapter\AdapterInterface;
use Gregwar\Image\Exceptions\GenerationError;
/**
* Images handling class
*
* @author Gregwar <g.passault@gmail.com>
*
* @method Image saveGif($file)
* @method Image savePng($file)
* @method Image saveJpeg($file, $quality)
* @method Image cropResize($width = null, $height = null, $background=0xffffff)
* @method Image scale($width = null, $height = null, $background=0xffffff, $crop = false)
* @method Image ($width = null, $height = null, $background = 0xffffff, $force = false, $rescale = false, $crop = false)
* @method Image crop($x, $y, $width, $height)
* @method Image enableProgressive()
* @method Image force($width = null, $height = null, $background = 0xffffff)
* @method Image zoomCrop($width, $height, $background = 0xffffff)
* @method Image fillBackground($background = 0xffffff)
* @method Image negate()
* @method Image brightness($brightness)
* @method Image contrast($contrast)
* @method Image grayscale()
* @method Image emboss()
* @method Image smooth($p)
* @method Image sharp()
* @method Image edge()
* @method Image colorize($red, $green, $blue)
* @method Image sepia()
* @method Image merge(Image $other, $x = 0, $y = 0, $width = null, $height = null)
* @method Image rotate($angle, $background = 0xffffff)
* @method Image fill($color = 0xffffff, $x = 0, $y = 0)
* @method Image write($font, $text, $x = 0, $y = 0, $size = 12, $angle = 0, $color = 0x000000, $align = 'left')
* @method Image rectangle($x1, $y1, $x2, $y2, $color, $filled = false)
* @method Image roundedRectangle($x1, $y1, $x2, $y2, $radius, $color, $filled = false)
* @method Image line($x1, $y1, $x2, $y2, $color = 0x000000)
* @method Image ellipse($cx, $cy, $width, $height, $color = 0x000000, $filled = false)
* @method Image circle($cx, $cy, $r, $color = 0x000000, $filled = false)
* @method Image polygon(array $points, $color, $filled = false)
* @method Image flip($flipVertical, $flipHorizontal)
*/
class Image
{
/**
* Directory to use for file caching
*/
protected $cacheDir = 'cache/images';
/**
* Directory cache mode
*/
protected $cacheMode = null;
/**
* Internal adapter
*
* @var AdapterInterface
*/
protected $adapter = null;
/**
* Pretty name for the image
*/
protected $prettyName = '';
protected $prettyPrefix;
/**
* Transformations hash
*/
protected $hash = null;
/**
* The image source
*/
protected $source = null;
/**
* Force image caching, even if there is no operation applied
*/
protected $forceCache = true;
/**
* Supported types
*/
public static $types = array(
'jpg' => 'jpeg',
'jpeg' => 'jpeg',
'png' => 'png',
'gif' => 'gif',
);
/**
* Fallback image
*/
protected $fallback;
/**
* Use fallback image
*/
protected $useFallbackImage = true;
/**
* Cache system
*/
protected $cache;
/**
* Change the caching directory
*/
public function setCacheDir($cacheDir)
{
$this->cache->setCacheDirectory($cacheDir);
return $this;
}
/**
* @param int $dirMode
*/
public function setCacheDirMode($dirMode)
{
$this->cache->setDirectoryMode($dirMode);
}
/**
* Enable or disable to force cache even if the file is unchanged
*/
public function setForceCache($forceCache = true)
{
$this->forceCache = $forceCache;
return $this;
}
/**
* The actual cache dir
*/
public function setActualCacheDir($actualCacheDir)
{
$this->cache->setActualCacheDirectory($actualCacheDir);
return $this;
}
/**
* Sets the pretty name of the image
*/
public function setPrettyName($name, $prefix = true)
{
if (empty($name)) {
return $this;
}
$this->prettyName = $this->urlize($name);
$this->prettyPrefix = $prefix;
return $this;
}
/**
* Urlizes the prettyName
*/
protected function urlize($name)
{
$transliterator = '\Behat\Transliterator\Transliterator';
if (class_exists($transliterator)) {
$name = $transliterator::transliterate($name);
$name = $transliterator::urlize($name);
} else {
$name = strtolower($name);
$name = str_replace(' ', '-', $name);
$name = preg_replace('/([^a-z0-9\-]+)/m', '', $name);
}
return $name;
}
/**
* Operations array
*/
protected $operations = array();
public function __construct($originalFile = null, $width = null, $height = null)
{
$this->cache = new \Gregwar\Cache\Cache;
$this->cache->setCacheDirectory($this->cacheDir);
$this->setFallback(null);
if ($originalFile) {
$this->source = new Source\File($originalFile);
} else {
$this->source = new Source\Create($width, $height);
}
}
/**
* Sets the image data
*/
public function setData($data)
{
$this->source = new Source\Data($data);
}
/**
* Sets the resource
*/
public function setResource($resource)
{
$this->source = new Source\Resource($resource);
}
/**
* Use the fallback image or not
*/
public function useFallback($useFallbackImage = true)
{
$this->useFallbackImage = $useFallbackImage;
return $this;
}
/**
* Sets the fallback image to use
*/
public function setFallback($fallback = null)
{
if ($fallback === null) {
$this->fallback = __DIR__ . '/images/error.jpg';
} else {
$this->fallback = $fallback;
}
return $this;
}
/**
* Gets the fallack image path
*/
public function getFallback()
{
return $this->fallback;
}
/**
* Gets the fallback into the cache dir
*/
public function getCacheFallback()
{
$fallback = $this->fallback;
return $this->cache->getOrCreateFile('fallback.jpg', array(), function($target) use ($fallback) {
copy($fallback, $target);
});
}
/**
* @return AdapterInterface
*/
public function getAdapter()
{
if (null === $this->adapter) {
// Defaults to GD
$this->setAdapter('gd');
}
return $this->adapter;
}
public function setAdapter($adapter)
{
if ($adapter instanceof Adapter\Adapter) {
$this->adapter = $adapter;
} else {
if (is_string($adapter)) {
$adapter = strtolower($adapter);
switch ($adapter) {
case 'gd':
$this->adapter = new Adapter\GD();
break;
case 'imagemagick':
case 'imagick':
$this->adapter = new Adapter\Imagick();
break;
default:
throw new \Exception('Unknown adapter: '.$adapter);
break;
}
} else {
throw new \Exception('Unable to load the given adapter (not string or Adapter)');
}
}
$this->adapter->setSource($this->source);
}
/**
* Get the file path
*
* @return mixed a string with the filen name, null if the image
* does not depends on a file
*/
public function getFilePath()
{
if ($this->source instanceof Source\File) {
return $this->source->getFile();
} else {
return null;
}
}
/**
* Defines the file only after instantiation
*
* @param string $originalFile the file path
*/
public function fromFile($originalFile)
{
$this->source = new Source\File($originalFile);
return $this;
}
/**
* Tells if the image is correct
*/
public function correct()
{
return $this->source->correct();
}
/**
* Guess the file type
*/
public function guessType()
{
return $this->source->guessType();
}
/**
* Adds an operation
*/
protected function addOperation($method, $args)
{
$this->operations[] = array($method, $args);
}
/**
* Generic function
*/
public function __call($methodName, $args)
{
$adapter = $this->getAdapter();
$reflection = new \ReflectionClass(get_class($adapter));
if ($reflection->hasMethod($methodName)) {
$method = $reflection->getMethod($methodName);
if ($method->getNumberOfRequiredParameters() > count($args)) {
throw new \InvalidArgumentException('Not enough arguments given for '.$methodName);
}
$this->addOperation($methodName, $args);
return $this;
}
throw new \BadFunctionCallException('Invalid method: '.$methodName);
}
/**
* Serialization of operations
*/
public function serializeOperations()
{
$datas = array();
foreach ($this->operations as $operation) {
$method = $operation[0];
$args = $operation[1];
foreach ($args as &$arg) {
if ($arg instanceof self) {
$arg = $arg->getHash();
}
}
$datas[] = array($method, $args);
}
return serialize($datas);
}
/**
* Generates the hash
*/
public function generateHash($type = 'guess', $quality = 80)
{
$inputInfos = $this->source->getInfos();
$datas = array(
$inputInfos,
$this->serializeOperations(),
$type,
$quality
);
$this->hash = sha1(serialize($datas));
}
/**
* Gets the hash
*/
public function getHash($type = 'guess', $quality = 80)
{
if (null === $this->hash) {
$this->generateHash($type, $quality);
}
return $this->hash;
}
/**
* Gets the cache file name and generate it if it does not exists.
* Note that if it exists, all the image computation process will
* not be done.
*
* @param string $type the image type
* @param int $quality the quality (for JPEG)
*/
public function cacheFile($type = 'jpg', $quality = 80, $actual = false)
{
if ($type == 'guess') {
$type = $this->guessType();
}
if (!count($this->operations) && $type == $this->guessType() && !$this->forceCache) {
return $this->getFilename($this->getFilePath());
}
// Computes the hash
$this->hash = $this->getHash($type, $quality);
// Generates the cache file
$cacheFile = '';
if (!$this->prettyName || $this->prettyPrefix) {
$cacheFile .= $this->hash;
}
if ($this->prettyPrefix) {
$cacheFile .= '-';
}
if ($this->prettyName) {
$cacheFile .= $this->prettyName;
}
$cacheFile .= '.'.$type;
// If the files does not exists, save it
$image = $this;
// Target file should be younger than all the current image
// dependencies
$conditions = array(
'younger-than' => $this->getDependencies()
);
// The generating function
$generate = function($target) use ($image, $type, $quality) {
$result = $image->save($target, $type, $quality);
if ($result != $target) {
throw new GenerationError($result);
}
};
// Asking the cache for the cacheFile
try {
$file = $this->cache->getOrCreateFile($cacheFile, $conditions, $generate, $actual);
} catch (GenerationError $e) {
$file = $e->getNewFile();
}
if ($actual) {
return $file;
} else {
return $this->getFilename($file);
}
}
/**
* Get cache data (to render the image)
*
* @param string $type the image type
* @param int $quality the quality (for JPEG)
*/
public function cacheData($type = 'jpg', $quality = 80)
{
return file_get_contents($this->cacheFile($type, $quality));
}
/**
* Hook to helps to extends and enhance this class
*/
protected function getFilename($filename)
{
return $filename;
}
/**
* Generates and output a jpeg cached file
*/
public function jpeg($quality = 80)
{
return $this->cacheFile('jpg', $quality);
}
/**
* Generates and output a gif cached file
*/
public function gif()
{
return $this->cacheFile('gif');
}
/**
* Generates and output a png cached file
*/
public function png()
{
return $this->cacheFile('png');
}
/**
* Generates and output an image using the same type as input
*/
public function guess($quality = 80)
{
return $this->cacheFile('guess', $quality);
}
/**
* Get all the files that this image depends on
*
* @return string[] this is an array of strings containing all the files that the
* current Image depends on
*/
public function getDependencies()
{
$dependencies = array();
$file = $this->getFilePath();
if ($file) {
$dependencies[] = $file;
}
foreach ($this->operations as $operation) {
foreach ($operation[1] as $argument) {
if ($argument instanceof self) {
$dependencies = array_merge($dependencies, $argument->getDependencies());
}
}
}
return $dependencies;
}
/**
* Applies the operations
*/
public function applyOperations()
{
// Renders the effects
foreach ($this->operations as $operation) {
call_user_func_array(array($this->adapter, $operation[0]), $operation[1]);
}
}
/**
* Initialize the adapter
*/
public function init()
{
$this->getAdapter()->init();
}
/**
* Save the file to a given output
*/
public function save($file, $type = 'guess', $quality = 80)
{
if ($file) {
$directory = dirname($file);
if (!is_dir($directory)) {
@mkdir($directory, 0777, true);
}
}
if (is_int($type)) {
$quality = $type;
$type = 'jpeg';
}
if ($type == 'guess') {
$type = $this->guessType();
}
if (!isset(self::$types[$type])) {
throw new \InvalidArgumentException('Given type ('.$type.') is not valid');
}
$type = self::$types[$type];
try {
$this->init();
$this->applyOperations();
$success = false;
if (null == $file) {
ob_start();
}
if ($type == 'jpeg') {
$success = $this->getAdapter()->saveJpeg($file, $quality);
}
if ($type == 'gif') {
$success = $this->getAdapter()->saveGif($file);
}
if ($type == 'png') {
$success = $this->getAdapter()->savePng($file);
}
if (!$success) {
return false;
}
return (null === $file ? ob_get_clean() : $file);
} catch (\Exception $e) {
if ($this->useFallbackImage) {
return (null === $file ? file_get_contents($this->fallback) : $this->getCacheFallback());
} else {
throw $e;
}
}
}
/**
* Get the contents of the image
*/
public function get($type = 'guess', $quality = 80)
{
return $this->save(null, $type, $quality);
}
/* Image API */
/**
* Image width
*/
public function width()
{
return $this->getAdapter()->width();
}
/**
* Image height
*/
public function height()
{
return $this->getAdapter()->height();
}
/**
* Tostring defaults to jpeg
*/
public function __toString()
{
return $this->guess();
}
/**
* Returning basic html code for this image
*/
public function html($title = '', $type = 'jpg', $quality = 80)
{
return '<img title="' . $title . '" src="' . $this->cacheFile($type, $quality) . '" />';
}
/**
* Returns the Base64 inlinable representation
*/
public function inline($type = 'jpg', $quality = 80)
{
$mime = $type;
if ($mime == 'jpg') {
$mime = 'jpeg';
}
return 'data:image/'.$mime.';base64,'.base64_encode(file_get_contents($this->cacheFile($type, $quality, true)));
}
/**
* Creates an instance, usefull for one-line chaining
*/
public static function open($file = '')
{
return new static($file);
}
/**
* Creates an instance of a new resource
*/
public static function create($width, $height)
{
return new static(null, $width, $height);
}
/**
* Creates an instance of image from its data
*/
public static function fromData($data)
{
$image = new static();
$image->setData($data);
return $image;
}
/**
* Creates an instance of image from resource
*/
public static function fromResource($resource)
{
$image = new static();
$image->setResource($resource);
return $image;
}
}
+93
View File
@@ -0,0 +1,93 @@
<?php
namespace Gregwar\Image;
/**
* Color manipulation class
*/
class ImageColor
{
private static $colors = array(
'black' => 0x000000,
'silver' => 0xc0c0c0,
'gray' => 0x808080,
'teal' => 0x008080,
'aqua' => 0x00ffff,
'blue' => 0x0000ff,
'navy' => 0x000080,
'green' => 0x008000,
'lime' => 0x00ff00,
'white' => 0xffffff,
'fuschia' => 0xff00ff,
'purple' => 0x800080,
'olive' => 0x808000,
'yellow' => 0xffff00,
'orange' => 0xffA500,
'red' => 0xff0000,
'maroon' => 0x800000,
'transparent' => 0x7fffffff
);
public static function gdAllocate($image, $color)
{
$colorRGBA = self::parse($color);
$b = ($colorRGBA)&0xff;
$colorRGBA >>= 8;
$g = ($colorRGBA)&0xff;
$colorRGBA >>= 8;
$r = ($colorRGBA)&0xff;
$colorRGBA >>= 8;
$a = ($colorRGBA)&0xff;
$c = imagecolorallocatealpha($image, $r, $g, $b, $a);
if ($color == 'transparent') {
imagecolortransparent($image, $c);
}
return $c;
}
public static function parse($color)
{
// Direct color representation (ex: 0xff0000)
if (!is_string($color) && is_numeric($color))
return $color;
// Color name (ex: "red")
if (isset(self::$colors[$color]))
return self::$colors[$color];
if (is_string($color)) {
$color_string = str_replace(' ', '', $color);
// Color string (ex: "ff0000", "#ff0000" or "0xfff")
if (preg_match('/^(#|0x|)([0-9a-f]{3,6})/i', $color_string, $matches)) {
$col = $matches[2];
if (strlen($col) == 6)
return hexdec($col);
if (strlen($col) == 3) {
$r = '';
for ($i=0; $i<3; $i++)
$r.= $col[$i].$col[$i];
return hexdec($r);
}
}
// Colors like "rgb(255, 0, 0)"
if (preg_match('/^rgb\(([0-9]+),([0-9]+),([0-9]+)\)/i', $color_string, $matches)) {
$r = $matches[1];
$g = $matches[2];
$b = $matches[3];
if ($r>=0 && $r<=0xff && $g>=0 && $g<=0xff && $b>=0 && $b<=0xff) {
return ($r << 16) | ($g << 8) | ($b);
}
}
}
throw new \InvalidArgumentException('Invalid color: '.$color);
}
}
+19
View File
@@ -0,0 +1,19 @@
Copyright (c) <2012-2013> Grégoire Passault
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+275
View File
@@ -0,0 +1,275 @@
# Gregwar's Image class
[![Build status](https://travis-ci.org/Gregwar/Image.svg?branch=master)](https://travis-ci.org/Gregwar/Image)
The `Gregwar\Image` class purpose is to provide a simple object-oriented images handling and caching API.
# Installation
With composer :
``` json
{
...
"require": {
"gregwar/image": "2.*"
}
}
```
# Usage
## Basic handling
Using methods chaining, you can open, transform and save a file in a single line:
```php
<?php use Gregwar\Image\Image;
Image::open('in.png')
->resize(100, 100)
->negate()
->save('out.jpg');
```
Here are the resize methods:
* `resize($width, $height, $background)`: resizes the image, will preserve scale and never
enlarge it (background is `red` in order to understand what happens):
![resize()](doc/resize.jpg)
* `scaleResize($width, $height, $background)`: resizes the image, will preserve scale, can enlarge
it (background is `red` in order to understand what happens):
![scaleResize()](doc/scaleResize.jpg)
* `forceResize($width, $height, $background)`: resizes the image forcing it to
be exactly `$width` by `$height`
![forceResize()](doc/forceResize.jpg)
* `cropResize($width, $height, $background)`: resizes the image preserving scale (just like `resize()`)
and croping the whitespaces:
![cropResize()](doc/cropResize.jpg)
* `zoomCrop($width, $height, $background, $xPos, $yPos)`: resize and crop the image to fit to given dimensions:
![zoomCrop()](doc/zoomCrop.jpg)
* In `zoomCrop()`, You can change the position of the resized image using the `$xPos` (center, left or right) and `$yPos` (center,
top or bottom):
![zoomCrop() with yPos=top](doc/zoomCropTop.jpg)
The other methods available are:
* `crop($x, $y, $w, $h)`: crops the image to a box located on coordinates $x,y and
which size is $w by $h
* `negate()`: negates the image colors
* `brighness($b)`: applies a brightness effect to the image (from -255 to +255)
* `contrast($c)`: applies a contrast effect to the image (from -100 to +100)
* `grayscale()`: converts the image to grayscale
* `emboss()`: emboss the image
* `smooth($p)`: smooth the image
* `sharp()`: applies a mean removal filter on the image
* `edge()`: applies an edge effect on the image
* `colorize($red, $green, $blue)`: colorize the image (from -255 to +255 for each color)
* `sepia()`: applies a sepia effect
* `merge($image, $x, $y, $width, $height)`: merges two images
* `fill($color, $x, $y)`: fills the image with the given color
* `write($font, $text, $x, $y, $size, $angle, $color, $position)`: writes text over image, $position can be any of 'left', 'right', or 'center'
* `rectangle($x1, $y1, $x2, $y2, $color, $filled=false)`: draws a rectangle
* `rotate($angle, $background = 0xffffff)` : rotate the image to given angle
* `roundedRectangle($x1, $y1, $x2, $y2, $radius, $color, $filled=false)`: draws a rounded rectangle ($radius can be anything from 0)
* `line($x1, $y1, $x2, $y2, $color)`: draws a line
* `ellipse($cx, $cy, $width, $height, $color, $filled=false)`: draws an ellipse
* `circle($cx, $cy, $r, $color, $filled=false)`: draws a circle
* `fillBackground($bg=0xffffff)`: fills the background of a transparent image to the 'bg' color
* `fixOrientation()`: return the image rotated and flipped using image exif information
* `html($title = '', $type = 'jpg')`: return the `<img ... />` tag with the cache image
* `flip($flipVertical, $flipHorizontal)`: flips the image in the given directions. Both params are boolean and at least one must be true.
* `inline($type = 'jpg')`: returns the HTML inlinable base64 string (see `demo/inline.php`)
You can also create image from scratch using:
```php
<?php
Image::create(200, 100);
```
Where 200 is the width and 100 the height
## Saving the image
You can save the image to an explicit file using `save($file, $type = 'jpg', $quality = 80)`:
```php
<?php
// ...
$image->save('output.jpg', 'jpg', 85);
```
You can also get the contents of the image using `get($type = 'jpg', $quality = 80)`, which will return the binary contents of the image
## Using cache
Each operation above is not actually applied on the opened image, but added in an operations
array. This operation array, the name, type and modification time of file are hashed using
`sha1()` and the hash is used to look up for a cache file.
Once the cache directory configured, you can call the following methods:
* `jpeg($quality = 80)`: lookup or create a jpeg cache file on-the-fly
* `gif()`: lookup or create a gif cache file on-the-fly
* `png()`: lookup or create a png cache file on-the-fly
* `guess($quality = 80)`: guesses the type (use the same as input) and lookup or create a
cache file on-the-fly
* `setPrettyName($prettyName, $prefix = true)`: sets a "pretty" name suffix for the file, if you want it to be more SEO-friendly.
for instance, if you call it "Fancy Image", the cache will look like something/something-fancy-image.jpg.
If `$prefix` is passed to `false` (default `true`), the pretty name won't have any hash prefix.
If you want to use non-latin1 pretty names, **behat/transliterator** package must be installed.
For instance:
```php
<?php use Gregwar\Image\Image;
echo Image::open('test.png')
->sepia()
->jpeg();
//Outputs: cache/images/1/8/6/9/c/86e4532dbd9c073075ef08e9751fc9bc0f4.jpg
```
If the original file and operations do not change, the hashed value will be the same and the
cache will not be generated again.
You can use this directly in an HTML document:
```php
<?php use Gregwar\Image\Image;
// ...
<img src="<?php echo Image::open('image.jpg')->resize(150, 150)->jpeg(); ?>" />
// ...
```
This is powerful since if you change the original image or any of your code the cached hash
will change and the file will be regenerated.
Writing image
-------------
You can also create your own image on-the-fly using drawing functions:
```php
<?php
$img_src = Image::create(300, 300)
->fill(0xffaaaa) // Filling with a light red
->rectangle(0xff3333, 0, 100, 300, 200, true) // Drawing a red rectangle
// Writing "Hello $username !" on the picture using a custom TTF font file
->write('./fonts/CaviarDreams.ttf', 'Hello '.$username.'!', 150, 150, 20, 0, 'white', 'center')
->jpeg();
?>
<img src="<?= $img_src ?>" />
```
## Using fallback image
If the image file doesn't exists, you can configurate a fallback image that will be used
by the class (note that this require the cache directory to be available).
A default "error" image which is used is in `images/error.jpg`, you can change it with:
```php
<?php
$img->setFallback('/path/to/my/fallback.jpg');
```
## Garbage Collect
To prevent the cache from growing forever, you can use the provided GarbageCollect class as below:
```php
<?php use Gregwar\Image\GarbageCollect;
// This could be a cron called each day @3:00AM for instance
// Removes all the files from ../cache that are more than 30 days
// old. A verbose output will explain which files are deleted
GarbageCollect::dropOldFiles(__DIR__.'/../cache', 30, true);
```
# Development
`Gregwar\Image` is using PHP metaprogramming paradigms that makes it easy to enhance.
Each function that handles the image is implemented in an *Adapter*, this is where
all the specific actions take place.
The `Common` adapter is design to contain common abstract actions, while the
specific adatpers (like `GD`) are designed to contain actions specific to the low
level layer.
You can add your own methods by adding it in the corresponding adapter.
```php
<?php
// In the adapter
private function myFilter()
{
$this->negate();
$this->sepia();
}
```
Which could be used on the Image
```php
<?php
$image->myFilter();
```
You can also write your own adapter which could extend one of this repository and use it by calling `setAdapter()`:
```php
<?php
$image->setAdapter(new MyCustomAdapter);
```
# License
`Gregwar\Image` is under MIT License, please read the LICENSE file for further details.
Do not hesitate to fork this repository and customize it !
+38
View File
@@ -0,0 +1,38 @@
<?php
namespace Gregwar\Image\Source;
/**
* Creates a new image from scratch
*/
class Create extends Source
{
protected $width;
protected $height;
public function __construct($width, $height)
{
$this->width = $width;
$this->height = $height;
}
public function getWidth()
{
return $this->width;
}
public function getHeight()
{
return $this->height;
}
public function getInfos()
{
return array($this->width, $this->height);
}
public function correct()
{
return $this->width > 0 && $this->height > 0;
}
}
+26
View File
@@ -0,0 +1,26 @@
<?php
namespace Gregwar\Image\Source;
/**
* Having image in some string
*/
class Data extends Source
{
protected $data;
public function __construct($data)
{
$this->data = $data;
}
public function getData()
{
return $this->data;
}
public function getInfos()
{
return sha1($this->data);
}
}
+63
View File
@@ -0,0 +1,63 @@
<?php
namespace Gregwar\Image\Source;
use Gregwar\Image\Image;
/**
* Open an image from a file
*/
class File extends Source
{
protected $file;
public function __construct($file)
{
$this->file = $file;
}
public function getFile()
{
return $this->file;
}
public function correct()
{
return false !== @exif_imagetype($this->file);
}
public function guessType()
{
if (function_exists('exif_imagetype')) {
$type = @exif_imagetype($this->file);
if (false !== $type) {
if ($type == IMAGETYPE_JPEG) {
return 'jpeg';
}
if ($type == IMAGETYPE_GIF) {
return 'gif';
}
if ($type == IMAGETYPE_PNG) {
return 'png';
}
}
}
$parts = explode('.', $this->file);
$ext = strtolower($parts[count($parts)-1]);
if (isset(Image::$types[$ext])) {
return Image::$types[$ext];
}
return 'jpeg';
}
public function getInfos()
{
return $this->file;
}
}
+21
View File
@@ -0,0 +1,21 @@
<?php
namespace Gregwar\Image\Source;
/**
* Have the image directly in a specific resource
*/
class Resource extends Source
{
protected $resource;
public function __construct($resource)
{
$this->resource = $resource;
}
public function getResource()
{
return $this->resource;
}
}
+34
View File
@@ -0,0 +1,34 @@
<?php
namespace Gregwar\Image\Source;
/**
* An Image source
*/
class Source
{
/**
* Guess the type of the image
*/
public function guessType()
{
return 'jpeg';
}
/**
* Is this image correct ?
*/
public function correct()
{
return true;
}
/**
* Returns information about images, these informations should
* change only if the original image changed
*/
public function getInfos()
{
return null;
}
}
+21
View File
@@ -0,0 +1,21 @@
<?php
$vendors = __DIR__.'/vendor/autoload.php';
if (file_exists($vendors)) {
require($vendors);
}
/**
* Registers an autoload for all the classes in Gregwar\Image
*/
spl_autoload_register(function ($className) {
$namespace = 'Gregwar\\Image';
if (strpos($className, $namespace) === 0) {
$className = str_replace($namespace, '', $className);
$fileName = __DIR__ . '/' . str_replace('\\', '/', $className) . '.php';
if (file_exists($fileName)) {
require($fileName);
}
}
});
@@ -0,0 +1,8 @@
* text=auto
/test export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
/.travis.yml export-ignore
/phpunit.xml.dist export-ignore
/README.md export-ignore
+7
View File
@@ -0,0 +1,7 @@
Copyright (c) 2012 Anthony Ferrara
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+76
View File
@@ -0,0 +1,76 @@
password_compat
===============
[![Build Status](https://travis-ci.org/ircmaxell/password_compat.png?branch=master)](https://travis-ci.org/ircmaxell/password_compat)
This library is intended to provide forward compatibility with the [password_*](http://php.net/password) functions being worked on for PHP 5.5.
See [the RFC](https://wiki.php.net/rfc/password_hash) for more detailed information.
Requirements
============
This library requires `PHP >= 5.3.7` OR a version that has the `$2y` fix backported into it (such as RedHat provides). Note that Debian's 5.3.3 version is **NOT** supported.
The runtime checks have been removed due to this version issue. To see if password_compat is available for your system, run the included `version-test.php`. If it outputs "Pass", you can safely use the library. If not, you cannot.
If you attempt to use password-compat on an unsupported version, attempts to create or verify hashes will return `false`. You have been warned!
The reason for this is that PHP prior to 5.3.7 contains a [security issue with its BCRYPT implementation](http://php.net/security/crypt_blowfish.php). Therefore, it's highly recommended that you upgrade to a newer version of PHP prior to using this layer.
Installation
============
To install, simply `require` the `password.php` file under `lib`.
You can also install it via `Composer` by using the [Packagist archive](http://packagist.org/packages/ircmaxell/password-compat).
Usage
=====
**Creating Password Hashes**
To create a password hash from a password, simply use the `password_hash` function.
````PHP
$hash = password_hash($password, PASSWORD_BCRYPT);
````
Note that the algorithm that we chose is `PASSWORD_BCRYPT`. That's the current strongest algorithm supported. This is the `BCRYPT` crypt algorithm. It produces a 60 character hash as the result.
`BCRYPT` also allows for you to define a `cost` parameter in the options array. This allows for you to change the CPU cost of the algorithm:
````PHP
$hash = password_hash($password, PASSWORD_BCRYPT, array("cost" => 10));
````
That's the same as the default. The cost can range from `4` to `31`. I would suggest that you use the highest cost that you can, while keeping response time reasonable (I target between 0.1 and 0.5 seconds for a hash, depending on use-case).
Another algorithm name is supported:
````PHP
PASSWORD_DEFAULT
````
This will use the strongest algorithm available to PHP at the current time. Presently, this is the same as specifying `PASSWORD_BCRYPT`. But in future versions of PHP, it may be updated to use a stronger algorithm if one is introduced. It can also be changed if a problem is identified with the BCRYPT algorithm. Note that if you use this option, you are **strongly** encouraged to store it in a `VARCHAR(255)` column to avoid truncation issues if a future algorithm increases the length of the generated hash.
It is very important that you should check the return value of `password_hash` prior to storing it, because a `false` may be returned if it encountered an error.
**Verifying Password Hashes**
To verify a hash created by `password_hash`, simply call:
````PHP
if (password_verify($password, $hash)) {
/* Valid */
} else {
/* Invalid */
}
````
That's all there is to it.
**Rehashing Passwords**
From time to time you may update your hashing parameters (algorithm, cost, etc). So a function to determine if rehashing is necessary is available:
````PHP
if (password_verify($password, $hash)) {
if (password_needs_rehash($hash, $algorithm, $options)) {
$hash = password_hash($password, $algorithm, $options);
/* Store new hash in db */
}
}
````
+314
View File
@@ -0,0 +1,314 @@
<?php
/**
* A Compatibility library with PHP 5.5's simplified password hashing API.
*
* @author Anthony Ferrara <ircmaxell@php.net>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @copyright 2012 The Authors
*/
namespace {
if (!defined('PASSWORD_BCRYPT')) {
/**
* PHPUnit Process isolation caches constants, but not function declarations.
* So we need to check if the constants are defined separately from
* the functions to enable supporting process isolation in userland
* code.
*/
define('PASSWORD_BCRYPT', 1);
define('PASSWORD_DEFAULT', PASSWORD_BCRYPT);
define('PASSWORD_BCRYPT_DEFAULT_COST', 10);
}
if (!function_exists('password_hash')) {
/**
* Hash the password using the specified algorithm
*
* @param string $password The password to hash
* @param int $algo The algorithm to use (Defined by PASSWORD_* constants)
* @param array $options The options for the algorithm to use
*
* @return string|false The hashed password, or false on error.
*/
function password_hash($password, $algo, array $options = array()) {
if (!function_exists('crypt')) {
trigger_error("Crypt must be loaded for password_hash to function", E_USER_WARNING);
return null;
}
if (is_null($password) || is_int($password)) {
$password = (string) $password;
}
if (!is_string($password)) {
trigger_error("password_hash(): Password must be a string", E_USER_WARNING);
return null;
}
if (!is_int($algo)) {
trigger_error("password_hash() expects parameter 2 to be long, " . gettype($algo) . " given", E_USER_WARNING);
return null;
}
$resultLength = 0;
switch ($algo) {
case PASSWORD_BCRYPT:
$cost = PASSWORD_BCRYPT_DEFAULT_COST;
if (isset($options['cost'])) {
$cost = $options['cost'];
if ($cost < 4 || $cost > 31) {
trigger_error(sprintf("password_hash(): Invalid bcrypt cost parameter specified: %d", $cost), E_USER_WARNING);
return null;
}
}
// The length of salt to generate
$raw_salt_len = 16;
// The length required in the final serialization
$required_salt_len = 22;
$hash_format = sprintf("$2y$%02d$", $cost);
// The expected length of the final crypt() output
$resultLength = 60;
break;
default:
trigger_error(sprintf("password_hash(): Unknown password hashing algorithm: %s", $algo), E_USER_WARNING);
return null;
}
$salt_requires_encoding = false;
if (isset($options['salt'])) {
switch (gettype($options['salt'])) {
case 'NULL':
case 'boolean':
case 'integer':
case 'double':
case 'string':
$salt = (string) $options['salt'];
break;
case 'object':
if (method_exists($options['salt'], '__tostring')) {
$salt = (string) $options['salt'];
break;
}
case 'array':
case 'resource':
default:
trigger_error('password_hash(): Non-string salt parameter supplied', E_USER_WARNING);
return null;
}
if (PasswordCompat\binary\_strlen($salt) < $required_salt_len) {
trigger_error(sprintf("password_hash(): Provided salt is too short: %d expecting %d", PasswordCompat\binary\_strlen($salt), $required_salt_len), E_USER_WARNING);
return null;
} elseif (0 == preg_match('#^[a-zA-Z0-9./]+$#D', $salt)) {
$salt_requires_encoding = true;
}
} else {
$buffer = '';
$buffer_valid = false;
if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) {
$buffer = mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM);
if ($buffer) {
$buffer_valid = true;
}
}
if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) {
$buffer = openssl_random_pseudo_bytes($raw_salt_len);
if ($buffer) {
$buffer_valid = true;
}
}
if (!$buffer_valid && @is_readable('/dev/urandom')) {
$f = fopen('/dev/urandom', 'r');
$read = PasswordCompat\binary\_strlen($buffer);
while ($read < $raw_salt_len) {
$buffer .= fread($f, $raw_salt_len - $read);
$read = PasswordCompat\binary\_strlen($buffer);
}
fclose($f);
if ($read >= $raw_salt_len) {
$buffer_valid = true;
}
}
if (!$buffer_valid || PasswordCompat\binary\_strlen($buffer) < $raw_salt_len) {
$bl = PasswordCompat\binary\_strlen($buffer);
for ($i = 0; $i < $raw_salt_len; $i++) {
if ($i < $bl) {
$buffer[$i] = $buffer[$i] ^ chr(mt_rand(0, 255));
} else {
$buffer .= chr(mt_rand(0, 255));
}
}
}
$salt = $buffer;
$salt_requires_encoding = true;
}
if ($salt_requires_encoding) {
// encode string with the Base64 variant used by crypt
$base64_digits =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
$bcrypt64_digits =
'./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$base64_string = base64_encode($salt);
$salt = strtr(rtrim($base64_string, '='), $base64_digits, $bcrypt64_digits);
}
$salt = PasswordCompat\binary\_substr($salt, 0, $required_salt_len);
$hash = $hash_format . $salt;
$ret = crypt($password, $hash);
if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != $resultLength) {
return false;
}
return $ret;
}
/**
* Get information about the password hash. Returns an array of the information
* that was used to generate the password hash.
*
* array(
* 'algo' => 1,
* 'algoName' => 'bcrypt',
* 'options' => array(
* 'cost' => PASSWORD_BCRYPT_DEFAULT_COST,
* ),
* )
*
* @param string $hash The password hash to extract info from
*
* @return array The array of information about the hash.
*/
function password_get_info($hash) {
$return = array(
'algo' => 0,
'algoName' => 'unknown',
'options' => array(),
);
if (PasswordCompat\binary\_substr($hash, 0, 4) == '$2y$' && PasswordCompat\binary\_strlen($hash) == 60) {
$return['algo'] = PASSWORD_BCRYPT;
$return['algoName'] = 'bcrypt';
list($cost) = sscanf($hash, "$2y$%d$");
$return['options']['cost'] = $cost;
}
return $return;
}
/**
* Determine if the password hash needs to be rehashed according to the options provided
*
* If the answer is true, after validating the password using password_verify, rehash it.
*
* @param string $hash The hash to test
* @param int $algo The algorithm used for new password hashes
* @param array $options The options array passed to password_hash
*
* @return boolean True if the password needs to be rehashed.
*/
function password_needs_rehash($hash, $algo, array $options = array()) {
$info = password_get_info($hash);
if ($info['algo'] != $algo) {
return true;
}
switch ($algo) {
case PASSWORD_BCRYPT:
$cost = isset($options['cost']) ? $options['cost'] : PASSWORD_BCRYPT_DEFAULT_COST;
if ($cost != $info['options']['cost']) {
return true;
}
break;
}
return false;
}
/**
* Verify a password against a hash using a timing attack resistant approach
*
* @param string $password The password to verify
* @param string $hash The hash to verify against
*
* @return boolean If the password matches the hash
*/
function password_verify($password, $hash) {
if (!function_exists('crypt')) {
trigger_error("Crypt must be loaded for password_verify to function", E_USER_WARNING);
return false;
}
$ret = crypt($password, $hash);
if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != PasswordCompat\binary\_strlen($hash) || PasswordCompat\binary\_strlen($ret) <= 13) {
return false;
}
$status = 0;
for ($i = 0; $i < PasswordCompat\binary\_strlen($ret); $i++) {
$status |= (ord($ret[$i]) ^ ord($hash[$i]));
}
return $status === 0;
}
}
}
namespace PasswordCompat\binary {
if (!function_exists('PasswordCompat\\binary\\_strlen')) {
/**
* Count the number of bytes in a string
*
* We cannot simply use strlen() for this, because it might be overwritten by the mbstring extension.
* In this case, strlen() will count the number of *characters* based on the internal encoding. A
* sequence of bytes might be regarded as a single multibyte character.
*
* @param string $binary_string The input string
*
* @internal
* @return int The number of bytes
*/
function _strlen($binary_string) {
if (function_exists('mb_strlen')) {
return mb_strlen($binary_string, '8bit');
}
return strlen($binary_string);
}
/**
* Get a substring based on byte limits
*
* @see _strlen()
*
* @param string $binary_string The input string
* @param int $start
* @param int $length
*
* @internal
* @return string The substring
*/
function _substr($binary_string, $start, $length) {
if (function_exists('mb_substr')) {
return mb_substr($binary_string, $start, $length, '8bit');
}
return substr($binary_string, $start, $length);
}
/**
* Check if current PHP version is compatible with the library
*
* @return boolean the check result
*/
function check() {
static $pass = NULL;
if (is_null($pass)) {
if (function_exists('crypt')) {
$hash = '$2y$04$usesomesillystringfore7hnbRJHxXVLeakoG8K30oukPsA.ztMG';
$test = crypt("password", $hash);
$pass = $test == $hash;
} else {
$pass = false;
}
}
return $pass;
}
}
}
+12
View File
@@ -0,0 +1,12 @@
* text=auto
/docs export-ignore
/demo export-ignore
/tests export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
/.travis.yml export-ignore
/phpunit.xml.dist export-ignore
/CHANGELOG.md export-ignore
/CONTRIBUTING.md export-ignore
/README.md export-ignore
+95
View File
@@ -0,0 +1,95 @@
# Changelog
2014-12 (1.10.2):
- Use Symfony VarDumper instead of kintLite as DataFormatter (#179)
- Better resize handling (#185)
2014-11 (1.10.1):
- Add disableVendor() option to JavascriptRenderer to remove a specific vendor (#182)
- Fix macros in Twig Collector (#167, #177)
- Update Font Awesome to 4.2.0
2014-10 (1.10.0):
- Add bindToXHR() as alternative to jQuery ajax handling.
- Extend TemplateWidget to show more information + parameters
- Extend TimeDataCollector to show parameters + collector source
2014-08:
- Replace image files with inline data in css
- Tweak OpenHandler display
2014-06-10:
- Add LocalizationCollector
2014-03-29:
- Add hasMeasure() method to TimeDataCollector
2014-03-25:
- Duplicate SQL detection
2014-03-23:
- Add syntax highlighting
2014-03-22:
- added AssetProvider interface
- added JavascriptRenderer::addAssets()
- added Memcached storage
2014-01-04:
- added DataFormatter
2013-12-29:
- display an error where the header is too large when sending data with an ajax request
- close button instead of minimize
2013-12-27:
- responsiveness of the debugbar in the browser
2013-12-19:
- use Bower to manage assets
2013-10-24:
- added option to render sql with params in PDO collector
2013-10-06:
- prefixed all css classes
- new PhpDebugBar.utils.csscls() function
- changed datetime to time in datasets selector
- close and open buttons now uses images instead of font-awesome
2013-09-23:
- send the request id in headers and use the open handler to retreive the dataset
- !! modified sendDataAsHeaders() to add $useOpenHandler as the first argument
- OpenHandler::handle() can now take any objects implementing ArrayAccess as request data
2013-09-19:
- added HttpDriver
- added jQuery.noConflict() managment
2013-09-15 (1.6):
- added sending data through HTTP headers
- added stacked data
- bug fixes
1.5:
- added storage
- added open handler
+23
View File
@@ -0,0 +1,23 @@
# Contributing to PHP DebugBar
First of all, thank you for contributing!
All contributions are welcome as long as they come through pull requests.
Each PR will be reviewed and eventually accepted. Some changes may be required before integration.
A contribution must follow the following guidelines:
- PHP code convention must follow PSR-1
- Javascript code convention described below
- Unit tests must be added/updated and pass
- Docs must be updated for new features
- Changelog must be updated (bug fix are not required to be added to the changelog)
- ensure that examples in demo/ folder are still working
Javascript code convention:
- based on: http://javascript.crockford.com/code.html
- blank lines between attributes of a class declaration
- jsdoc comments
- all code in a file must be wrapped into an anonymous function
- variables representing jquery objects must be prefixed with a dollar sign
+19
View File
@@ -0,0 +1,19 @@
Copyright (C) 2013 Maxime Bouroumeau-Fuseau
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+100
View File
@@ -0,0 +1,100 @@
# PHP Debug Bar
[![Latest Stable Version](https://poser.pugx.org/maximebf/debugbar/v/stable.png)](https://packagist.org/packages/maximebf/debugbar) [![Total Downloads](https://poser.pugx.org/maximebf/debugbar/downloads.svg)](https://packagist.org/packages/maximebf/debugbar) [![License](https://poser.pugx.org/maximebf/debugbar/license.svg)](https://packagist.org/packages/maximebf/debugbar) [![Build Status](https://travis-ci.org/maximebf/php-debugbar.png?branch=master)](https://travis-ci.org/maximebf/php-debugbar)
Displays a debug bar in the browser with information from php.
No more `var_dump()` in your code!
![Screenshot](https://raw.github.com/maximebf/php-debugbar/master/docs/screenshot.png)
**Features:**
- Generic debug bar
- Easy to integrate with any project
- Clean, fast and easy to use interface
- Handles AJAX request
- Includes generic data collectors and collectors for well known libraries
- The client side bar is 100% coded in javascript
- Easily create your own collectors and their associated view in the bar
- Save and re-open previous requests
- [Very well documented](http://phpdebugbar.com/docs)
Includes collectors for:
- [PDO](http://php.net/manual/en/book.pdo.php)
- [CacheCache](http://maximebf.github.io/CacheCache/)
- [Doctrine](http://doctrine-project.org)
- [Monolog](https://github.com/Seldaek/monolog)
- [Propel](http://propelorm.org/)
- [Slim](http://slimframework.com)
- [Swift Mailer](http://swiftmailer.org/)
- [Twig](http://twig.sensiolabs.org/)
Checkout the [demo](https://github.com/maximebf/php-debugbar/tree/master/demo) for
examples and [phpdebugbar.com](http://phpdebugbar.com) for a live example.
Integrations with other frameworks:
- [Laravel](https://github.com/barryvdh/laravel-debugbar)
- [Atomik](http://atomikframework.com/docs/error-log-debug.html#debug-bar)
- [XOOPS](http://xoops.org/modules/news/article.php?storyid=6538)
- [Zend Framework 2](https://github.com/snapshotpl/ZfSnapPhpDebugBar)
- [Phalcon](https://github.com/snowair/phalcon-debugbar)
- Framework-agnostic middleware and PSR-7 with [php-middleware/phpdebugbar](https://github.com/php-middleware/phpdebugbar).
*(drop me a message or submit a PR to add your DebugBar related project here)*
## Installation
The best way to install DebugBar is using [Composer](http://getcomposer.org)
with the following command:
```composer require maximebf/debugbar```
## Quick start
DebugBar is very easy to use and you can add it to any of your projects in no time.
The easiest way is using the `render()` functions
```PHP
<?php
// Require the Composer autoloader, if not already loaded
require 'vendor/autoload.php';
use DebugBar\StandardDebugBar;
$debugbar = new StandardDebugBar();
$debugbarRenderer = $debugbar->getJavascriptRenderer();
$debugbar["messages"]->addMessage("hello world!");
?>
<html>
<head>
<?php echo $debugbarRenderer->renderHead() ?>
</head>
<body>
...
<?php echo $debugbarRenderer->render() ?>
</body>
</html>
```
The DebugBar uses DataCollectors to collect data from your PHP code. Some of them are
automated but others are manual. Use the `DebugBar` like an array where keys are the
collector names. In our previous example, we add a message to the `MessagesCollector`:
```PHP
$debugbar["messages"]->addMessage("hello world!");
```
`StandardDebugBar` activates the following collectors:
- `MemoryCollector` (*memory*)
- `MessagesCollector` (*messages*)
- `PhpInfoCollector` (*php*)
- `RequestDataCollector` (*request*)
- `TimeDataCollector` (*time*)
- `ExceptionsCollector` (*exceptions*)
Learn more about DebugBar in the [docs](http://phpdebugbar.com/docs).
@@ -0,0 +1,62 @@
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\Bridge;
use CacheCache\Cache;
use CacheCache\LoggingBackend;
use Monolog\Logger;
/**
* Collects CacheCache operations
*
* http://maximebf.github.io/CacheCache/
*
* Example:
* <code>
* $debugbar->addCollector(new CacheCacheCollector(CacheManager::get('default')));
* // or
* $debugbar->addCollector(new CacheCacheCollector());
* $debugbar['cache']->addCache(CacheManager::get('default'));
* </code>
*/
class CacheCacheCollector extends MonologCollector
{
protected $logger;
public function __construct(Cache $cache = null, Logger $logger = null, $level = Logger::DEBUG, $bubble = true)
{
parent::__construct(null, $level, $bubble);
if ($logger === null) {
$logger = new Logger('Cache');
}
$this->logger = $logger;
if ($cache !== null) {
$this->addCache($cache);
}
}
public function addCache(Cache $cache)
{
$backend = $cache->getBackend();
if (!($backend instanceof LoggingBackend)) {
$backend = new LoggingBackend($backend, $this->logger);
}
$cache->setBackend($backend);
$this->addLogger($backend->getLogger());
}
public function getName()
{
return 'cache';
}
}
@@ -0,0 +1,98 @@
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\Bridge;
use DebugBar\DataCollector\AssetProvider;
use DebugBar\DataCollector\DataCollector;
use DebugBar\DataCollector\Renderable;
use DebugBar\DebugBarException;
use Doctrine\DBAL\Logging\DebugStack;
use Doctrine\ORM\EntityManager;
/**
* Collects Doctrine queries
*
* http://doctrine-project.org
*
* Uses the DebugStack logger to collects data about queries
*
* <code>
* $debugStack = new Doctrine\DBAL\Logging\DebugStack();
* $entityManager->getConnection()->getConfiguration()->setSQLLogger($debugStack);
* $debugbar->addCollector(new DoctrineCollector($debugStack));
* </code>
*/
class DoctrineCollector extends DataCollector implements Renderable, AssetProvider
{
protected $debugStack;
public function __construct($debugStackOrEntityManager)
{
if ($debugStackOrEntityManager instanceof EntityManager) {
$debugStackOrEntityManager = $debugStackOrEntityManager->getConnection()->getConfiguration()->getSQLLogger();
}
if (!($debugStackOrEntityManager instanceof DebugStack)) {
throw new DebugBarException("'DoctrineCollector' requires an 'EntityManager' or 'DebugStack' object");
}
$this->debugStack = $debugStackOrEntityManager;
}
public function collect()
{
$queries = array();
$totalExecTime = 0;
foreach ($this->debugStack->queries as $q) {
$queries[] = array(
'sql' => $q['sql'],
'params' => (object) $q['params'],
'duration' => $q['executionMS'],
'duration_str' => $this->formatDuration($q['executionMS'])
);
$totalExecTime += $q['executionMS'];
}
return array(
'nb_statements' => count($queries),
'accumulated_duration' => $totalExecTime,
'accumulated_duration_str' => $this->formatDuration($totalExecTime),
'statements' => $queries
);
}
public function getName()
{
return 'doctrine';
}
public function getWidgets()
{
return array(
"database" => array(
"icon" => "arrow-right",
"widget" => "PhpDebugBar.Widgets.SQLQueriesWidget",
"map" => "doctrine",
"default" => "[]"
),
"database:badge" => array(
"map" => "doctrine.nb_statements",
"default" => 0
)
);
}
public function getAssets()
{
return array(
'css' => 'widgets/sqlqueries/widget.css',
'js' => 'widgets/sqlqueries/widget.js'
);
}
}
@@ -0,0 +1,103 @@
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\Bridge;
use DebugBar\DataCollector\DataCollectorInterface;
use DebugBar\DataCollector\MessagesAggregateInterface;
use DebugBar\DataCollector\Renderable;
use Monolog\Handler\AbstractProcessingHandler;
use Monolog\Logger;
/**
* A monolog handler as well as a data collector
*
* https://github.com/Seldaek/monolog
*
* <code>
* $debugbar->addCollector(new MonologCollector($logger));
* </code>
*/
class MonologCollector extends AbstractProcessingHandler implements DataCollectorInterface, Renderable, MessagesAggregateInterface
{
protected $name;
protected $records = array();
/**
* @param Logger $logger
* @param int $level
* @param boolean $bubble
* @param string $name
*/
public function __construct(Logger $logger = null, $level = Logger::DEBUG, $bubble = true, $name = 'monolog')
{
parent::__construct($level, $bubble);
$this->name = $name;
if ($logger !== null) {
$this->addLogger($logger);
}
}
/**
* Adds logger which messages you want to log
*
* @param Logger $logger
*/
public function addLogger(Logger $logger)
{
$logger->pushHandler($this);
}
protected function write(array $record)
{
$this->records[] = array(
'message' => $record['formatted'],
'is_string' => true,
'label' => strtolower($record['level_name']),
'time' => $record['datetime']->format('U')
);
}
public function getMessages()
{
return $this->records;
}
public function collect()
{
return array(
'count' => count($this->records),
'records' => $this->records
);
}
public function getName()
{
return $this->name;
}
public function getWidgets()
{
$name = $this->getName();
return array(
$name => array(
"icon" => "suitcase",
"widget" => "PhpDebugBar.Widgets.MessagesWidget",
"map" => "$name.records",
"default" => "[]"
),
"$name:badge" => array(
"map" => "$name.count",
"default" => "null"
)
);
}
}
@@ -0,0 +1,307 @@
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\Bridge;
use DebugBar\DataCollector\AssetProvider;
use DebugBar\DataCollector\DataCollector;
use DebugBar\DataCollector\Renderable;
use Monolog\Handler\TestHandler;
use Monolog\Logger;
use Propel\Runtime\Connection\ConnectionInterface;
use Propel\Runtime\Connection\ProfilerConnectionWrapper;
use Propel\Runtime\Propel;
use Psr\Log\LogLevel;
use Psr\Log\LoggerInterface;
/**
* A Propel logger which acts as a data collector
*
* http://propelorm.org/
*
* Will log queries and display them using the SQLQueries widget.
*
* Example:
* <code>
* $debugbar->addCollector(new \DebugBar\Bridge\Propel2Collector(\Propel\Runtime\Propel::getServiceContainer()->getReadConnection()));
* </code>
*/
class Propel2Collector extends DataCollector implements Renderable, AssetProvider
{
/**
* @var null|TestHandler
*/
protected $handler = null;
/**
* @var null|Logger
*/
protected $logger = null;
/**
* @var array
*/
protected $config = array();
/**
* @var array
*/
protected $errors = array();
/**
* @var int
*/
protected $queryCount = 0;
/**
* @param ConnectionInterface $connection Propel connection
*/
public function __construct(
ConnectionInterface $connection,
array $logMethods = array(
'beginTransaction',
'commit',
'rollBack',
'forceRollBack',
'exec',
'query',
'execute'
)
) {
if ($connection instanceof ProfilerConnectionWrapper) {
$connection->setLogMethods($logMethods);
$this->config = $connection->getProfiler()->getConfiguration();
$this->handler = new TestHandler();
if ($connection->getLogger() instanceof Logger) {
$this->logger = $connection->getLogger();
$this->logger->pushHandler($this->handler);
} else {
$this->errors[] = 'Supported only monolog logger';
}
} else {
$this->errors[] = 'You need set ProfilerConnectionWrapper';
}
}
/**
* @return TestHandler|null
*/
public function getHandler()
{
return $this->handler;
}
/**
* @return array
*/
public function getConfig()
{
return $this->config;
}
/**
* @return Logger|null
*/
public function getLogger()
{
return $this->logger;
}
/**
* @return LoggerInterface
*/
protected function getDefaultLogger()
{
return Propel::getServiceContainer()->getLogger();
}
/**
* @return int
*/
protected function getQueryCount()
{
return $this->queryCount;
}
/**
* @param array $records
* @param array $config
* @return array
*/
protected function getStatements($records, $config)
{
$statements = array();
foreach ($records as $record) {
$duration = null;
$memory = null;
$isSuccess = ( LogLevel::INFO === strtolower($record['level_name']) );
$detailsCount = count($config['details']);
$parameters = explode($config['outerGlue'], $record['message'], $detailsCount + 1);
if (count($parameters) === ($detailsCount + 1)) {
$parameters = array_map('trim', $parameters);
$_details = array();
foreach (array_splice($parameters, 0, $detailsCount) as $string) {
list($key, $value) = array_map('trim', explode($config['innerGlue'], $string, 2));
$_details[$key] = $value;
}
$details = array();
foreach ($config['details'] as $key => $detail) {
if (isset($_details[$detail['name']])) {
$value = $_details[$detail['name']];
if ('time' === $key) {
if (substr_count($value, 'ms')) {
$value = (float)$value / 1000;
} else {
$value = (float)$value;
}
} else {
$suffixes = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
$suffix = substr($value, -2);
$i = array_search($suffix, $suffixes, true);
$i = (false === $i) ? 0 : $i;
$value = ((float)$value) * pow(1024, $i);
}
$details[$key] = $value;
}
}
if (isset($details['time'])) {
$duration = $details['time'];
}
if (isset($details['memDelta'])) {
$memory = $details['memDelta'];
}
$message = end($parameters);
if ($isSuccess) {
$this->queryCount++;
}
} else {
$message = $record['message'];
}
$statement = array(
'sql' => $message,
'is_success' => $isSuccess,
'duration' => $duration,
'duration_str' => $this->getDataFormatter()->formatDuration($duration),
'memory' => $memory,
'memory_str' => $this->getDataFormatter()->formatBytes($memory),
);
if (false === $isSuccess) {
$statement['sql'] = '';
$statement['error_code'] = $record['level'];
$statement['error_message'] = $message;
}
$statements[] = $statement;
}
return $statements;
}
/**
* @return array
*/
public function collect()
{
if (count($this->errors)) {
return array(
'statements' => array_map(function ($message) {
return array('sql' => '', 'is_success' => false, 'error_code' => 500, 'error_message' => $message);
}, $this->errors),
'nb_statements' => 0,
'nb_failed_statements' => count($this->errors),
);
}
if ($this->getHandler() === null) {
return array();
}
$statements = $this->getStatements($this->getHandler()->getRecords(), $this->getConfig());
$failedStatement = count(array_filter($statements, function ($statement) {
return false === $statement['is_success'];
}));
$accumulatedDuration = array_reduce($statements, function ($accumulatedDuration, $statement) {
$time = isset($statement['duration']) ? $statement['duration'] : 0;
return $accumulatedDuration += $time;
});
$memoryUsage = array_reduce($statements, function ($memoryUsage, $statement) {
$time = isset($statement['memory']) ? $statement['memory'] : 0;
return $memoryUsage += $time;
});
return array(
'nb_statements' => $this->getQueryCount(),
'nb_failed_statements' => $failedStatement,
'accumulated_duration' => $accumulatedDuration,
'accumulated_duration_str' => $this->getDataFormatter()->formatDuration($accumulatedDuration),
'memory_usage' => $memoryUsage,
'memory_usage_str' => $this->getDataFormatter()->formatBytes($memoryUsage),
'statements' => $statements
);
}
/**
* @return string
*/
public function getName()
{
$additionalName = '';
if ($this->getLogger() !== $this->getDefaultLogger()) {
$additionalName = ' ('.$this->getLogger()->getName().')';
}
return 'propel2'.$additionalName;
}
/**
* @return array
*/
public function getWidgets()
{
return array(
$this->getName() => array(
'icon' => 'bolt',
'widget' => 'PhpDebugBar.Widgets.SQLQueriesWidget',
'map' => $this->getName(),
'default' => '[]'
),
$this->getName().':badge' => array(
'map' => $this->getName().'.nb_statements',
'default' => 0
),
);
}
/**
* @return array
*/
public function getAssets()
{
return array(
'css' => 'widgets/sqlqueries/widget.css',
'js' => 'widgets/sqlqueries/widget.js'
);
}
}
@@ -0,0 +1,253 @@
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\Bridge;
use BasicLogger;
use DebugBar\DataCollector\AssetProvider;
use DebugBar\DataCollector\DataCollector;
use DebugBar\DataCollector\Renderable;
use Propel;
use PropelConfiguration;
use PropelPDO;
use Psr\Log\LogLevel;
use Psr\Log\LoggerInterface;
/**
* A Propel logger which acts as a data collector
*
* http://propelorm.org/
*
* Will log queries and display them using the SQLQueries widget.
* You can provide a LoggerInterface object to forward non-query related message to.
*
* Example:
* <code>
* $debugbar->addCollector(new PropelCollector($debugbar['messages']));
* PropelCollector::enablePropelProfiling();
* </code>
*/
class PropelCollector extends DataCollector implements BasicLogger, Renderable, AssetProvider
{
protected $logger;
protected $statements = array();
protected $accumulatedTime = 0;
protected $peakMemory = 0;
/**
* Sets the needed configuration option in propel to enable query logging
*
* @param PropelConfiguration $config Apply profiling on a specific config
*/
public static function enablePropelProfiling(PropelConfiguration $config = null)
{
if ($config === null) {
$config = Propel::getConfiguration(PropelConfiguration::TYPE_OBJECT);
}
$config->setParameter('debugpdo.logging.details.method.enabled', true);
$config->setParameter('debugpdo.logging.details.time.enabled', true);
$config->setParameter('debugpdo.logging.details.mem.enabled', true);
$allMethods = array(
'PropelPDO::__construct', // logs connection opening
'PropelPDO::__destruct', // logs connection close
'PropelPDO::exec', // logs a query
'PropelPDO::query', // logs a query
'PropelPDO::beginTransaction', // logs a transaction begin
'PropelPDO::commit', // logs a transaction commit
'PropelPDO::rollBack', // logs a transaction rollBack (watch out for the capital 'B')
'DebugPDOStatement::execute', // logs a query from a prepared statement
);
$config->setParameter('debugpdo.logging.methods', $allMethods, false);
}
/**
* @param LoggerInterface $logger A logger to forward non-query log lines to
* @param PropelPDO $conn Bound this collector to a connection only
*/
public function __construct(LoggerInterface $logger = null, PropelPDO $conn = null)
{
if ($conn) {
$conn->setLogger($this);
} else {
Propel::setLogger($this);
}
$this->logger = $logger;
$this->logQueriesToLogger = false;
}
public function setLogQueriesToLogger($enable = true)
{
$this->logQueriesToLogger = $enable;
return $this;
}
public function isLogQueriesToLogger()
{
return $this->logQueriesToLogger;
}
public function emergency($m)
{
$this->log($m, Propel::LOG_EMERG);
}
public function alert($m)
{
$this->log($m, Propel::LOG_ALERT);
}
public function crit($m)
{
$this->log($m, Propel::LOG_CRIT);
}
public function err($m)
{
$this->log($m, Propel::LOG_ERR);
}
public function warning($m)
{
$this->log($m, Propel::LOG_WARNING);
}
public function notice($m)
{
$this->log($m, Propel::LOG_NOTICE);
}
public function info($m)
{
$this->log($m, Propel::LOG_INFO);
}
public function debug($m)
{
$this->log($m, Propel::LOG_DEBUG);
}
public function log($message, $severity = null)
{
if (strpos($message, 'DebugPDOStatement::execute') !== false) {
list($sql, $duration_str) = $this->parseAndLogSqlQuery($message);
if (!$this->logQueriesToLogger) {
return;
}
$message = "$sql ($duration_str)";
}
if ($this->logger !== null) {
$this->logger->log($this->convertLogLevel($severity), $message);
}
}
/**
* Converts Propel log levels to PSR log levels
*
* @param int $level
* @return string
*/
protected function convertLogLevel($level)
{
$map = array(
Propel::LOG_EMERG => LogLevel::EMERGENCY,
Propel::LOG_ALERT => LogLevel::ALERT,
Propel::LOG_CRIT => LogLevel::CRITICAL,
Propel::LOG_ERR => LogLevel::ERROR,
Propel::LOG_WARNING => LogLevel::WARNING,
Propel::LOG_NOTICE => LogLevel::NOTICE,
Propel::LOG_DEBUG => LogLevel::DEBUG
);
return $map[$level];
}
/**
* Parse a log line to extract query information
*
* @param string $message
*/
protected function parseAndLogSqlQuery($message)
{
$parts = explode('|', $message, 4);
$sql = trim($parts[3]);
$duration = 0;
if (preg_match('/([0-9]+\.[0-9]+)/', $parts[1], $matches)) {
$duration = (float) $matches[1];
}
$memory = 0;
if (preg_match('/([0-9]+\.[0-9]+) ([A-Z]{1,2})/', $parts[2], $matches)) {
$memory = (float) $matches[1];
if ($matches[2] == 'KB') {
$memory *= 1024;
} elseif ($matches[2] == 'MB') {
$memory *= 1024 * 1024;
}
}
$this->statements[] = array(
'sql' => $sql,
'is_success' => true,
'duration' => $duration,
'duration_str' => $this->formatDuration($duration),
'memory' => $memory,
'memory_str' => $this->formatBytes($memory)
);
$this->accumulatedTime += $duration;
$this->peakMemory = max($this->peakMemory, $memory);
return array($sql, $this->formatDuration($duration));
}
public function collect()
{
return array(
'nb_statements' => count($this->statements),
'nb_failed_statements' => 0,
'accumulated_duration' => $this->accumulatedTime,
'accumulated_duration_str' => $this->formatDuration($this->accumulatedTime),
'peak_memory_usage' => $this->peakMemory,
'peak_memory_usage_str' => $this->formatBytes($this->peakMemory),
'statements' => $this->statements
);
}
public function getName()
{
return 'propel';
}
public function getWidgets()
{
return array(
"propel" => array(
"icon" => "bolt",
"widget" => "PhpDebugBar.Widgets.SQLQueriesWidget",
"map" => "propel",
"default" => "[]"
),
"propel:badge" => array(
"map" => "propel.nb_statements",
"default" => 0
)
);
}
public function getAssets()
{
return array(
'css' => 'widgets/sqlqueries/widget.css',
'js' => 'widgets/sqlqueries/widget.js'
);
}
}
@@ -0,0 +1,66 @@
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\Bridge;
use DebugBar\DataCollector\MessagesCollector;
use Psr\Log\LogLevel;
use Slim\Log;
use Slim\Slim;
/**
* Collects messages from a Slim logger
*
* http://slimframework.com
*/
class SlimCollector extends MessagesCollector
{
protected $slim;
protected $originalLogWriter;
public function __construct(Slim $slim)
{
$this->slim = $slim;
if ($log = $slim->getLog()) {
$this->originalLogWriter = $log->getWriter();
$log->setWriter($this);
$log->setEnabled(true);
}
}
public function write($message, $level)
{
if ($this->originalLogWriter) {
$this->originalLogWriter->write($message, $level);
}
$this->addMessage($message, $this->getLevelName($level));
}
protected function getLevelName($level)
{
$map = array(
Log::EMERGENCY => LogLevel::EMERGENCY,
Log::ALERT => LogLevel::ALERT,
Log::CRITICAL => LogLevel::CRITICAL,
Log::ERROR => LogLevel::ERROR,
Log::WARN => LogLevel::WARNING,
Log::NOTICE => LogLevel::NOTICE,
Log::INFO => LogLevel::INFO,
Log::DEBUG => LogLevel::DEBUG
);
return $map[$level];
}
public function getName()
{
return 'slim';
}
}
@@ -0,0 +1,44 @@
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\Bridge\SwiftMailer;
use DebugBar\DataCollector\MessagesCollector;
use Swift_Mailer;
use Swift_Plugins_Logger;
use Swift_Plugins_LoggerPlugin;
/**
* Collects log messages
*
* http://swiftmailer.org/
*/
class SwiftLogCollector extends MessagesCollector implements Swift_Plugins_Logger
{
public function __construct(Swift_Mailer $mailer)
{
$mailer->registerPlugin(new Swift_Plugins_LoggerPlugin($this));
}
public function add($entry)
{
$this->addMessage($entry);
}
public function dump()
{
return implode(PHP_EOL, $this->_log);
}
public function getName()
{
return 'swiftmailer_logs';
}
}
@@ -0,0 +1,92 @@
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\Bridge\SwiftMailer;
use DebugBar\DataCollector\AssetProvider;
use DebugBar\DataCollector\DataCollector;
use DebugBar\DataCollector\Renderable;
use Swift_Mailer;
use Swift_Plugins_MessageLogger;
/**
* Collects data about sent mails
*
* http://swiftmailer.org/
*/
class SwiftMailCollector extends DataCollector implements Renderable, AssetProvider
{
protected $messagesLogger;
public function __construct(Swift_Mailer $mailer)
{
$this->messagesLogger = new Swift_Plugins_MessageLogger();
$mailer->registerPlugin($this->messagesLogger);
}
public function collect()
{
$mails = array();
foreach ($this->messagesLogger->getMessages() as $msg) {
$mails[] = array(
'to' => $this->formatTo($msg->getTo()),
'subject' => $msg->getSubject(),
'headers' => $msg->getHeaders()->toString()
);
}
return array(
'count' => count($mails),
'mails' => $mails
);
}
protected function formatTo($to)
{
if (!$to) {
return '';
}
$f = array();
foreach ($to as $k => $v) {
$f[] = (empty($v) ? '' : "$v ") . "<$k>";
}
return implode(', ', $f);
}
public function getName()
{
return 'swiftmailer_mails';
}
public function getWidgets()
{
return array(
'emails' => array(
'icon' => 'inbox',
'widget' => 'PhpDebugBar.Widgets.MailsWidget',
'map' => 'swiftmailer_mails.mails',
'default' => '[]',
'title' => 'Mails'
),
'emails:badge' => array(
'map' => 'swiftmailer_mails.count',
'default' => 'null'
)
);
}
public function getAssets()
{
return array(
'css' => 'widgets/mails/widget.css',
'js' => 'widgets/mails/widget.js'
);
}
}
@@ -0,0 +1,417 @@
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\Bridge\Twig;
use DebugBar\DataCollector\TimeDataCollector;
use Twig_CompilerInterface;
use Twig_Environment;
use Twig_ExtensionInterface;
use Twig_LexerInterface;
use Twig_LoaderInterface;
use Twig_NodeInterface;
use Twig_NodeVisitorInterface;
use Twig_ParserInterface;
use Twig_TokenParserInterface;
use Twig_TokenStream;
/**
* Wrapped a Twig Environment to provide profiling features
*/
class TraceableTwigEnvironment extends Twig_Environment
{
protected $twig;
protected $renderedTemplates = array();
protected $timeDataCollector;
/**
* @param Twig_Environment $twig
* @param TimeDataCollector $timeDataCollector
*/
public function __construct(Twig_Environment $twig, TimeDataCollector $timeDataCollector = null)
{
$this->twig = $twig;
$this->timeDataCollector = $timeDataCollector;
}
public function __call($name, $arguments)
{
return call_user_func_array(array($this->twig, $name), $arguments);
}
public function getRenderedTemplates()
{
return $this->renderedTemplates;
}
public function addRenderedTemplate(array $info)
{
$this->renderedTemplates[] = $info;
}
public function getTimeDataCollector()
{
return $this->timeDataCollector;
}
public function getBaseTemplateClass()
{
return $this->twig->getBaseTemplateClass();
}
public function setBaseTemplateClass($class)
{
$this->twig->setBaseTemplateClass($class);
}
public function enableDebug()
{
$this->twig->enableDebug();
}
public function disableDebug()
{
$this->twig->disableDebug();
}
public function isDebug()
{
return $this->twig->isDebug();
}
public function enableAutoReload()
{
$this->twig->enableAutoReload();
}
public function disableAutoReload()
{
$this->twig->disableAutoReload();
}
public function isAutoReload()
{
return $this->twig->isAutoReload();
}
public function enableStrictVariables()
{
$this->twig->enableStrictVariables();
}
public function disableStrictVariables()
{
$this->twig->disableStrictVariables();
}
public function isStrictVariables()
{
return $this->twig->isStrictVariables();
}
public function getCache()
{
return $this->twig->getCache();
}
public function setCache($cache)
{
$this->twig->setCache($cache);
}
public function getCacheFilename($name)
{
return $this->twig->getCacheFilename($name);
}
public function getTemplateClass($name, $index = null)
{
return $this->twig->getTemplateClass($name, $index);
}
public function getTemplateClassPrefix()
{
return $this->twig->getTemplateClassPrefix();
}
public function render($name, array $context = array())
{
return $this->loadTemplate($name)->render($context);
}
public function display($name, array $context = array())
{
$this->loadTemplate($name)->display($context);
}
public function loadTemplate($name, $index = null)
{
$cls = $this->twig->getTemplateClass($name, $index);
if (isset($this->twig->loadedTemplates[$cls])) {
return $this->twig->loadedTemplates[$cls];
}
if (!class_exists($cls, false)) {
if (false === $cache = $this->getCacheFilename($name)) {
eval('?>'.$this->compileSource($this->getLoader()->getSource($name), $name));
} else {
if (!is_file($cache) || ($this->isAutoReload() && !$this->isTemplateFresh($name, filemtime($cache)))) {
$this->writeCacheFile($cache, $this->compileSource($this->getLoader()->getSource($name), $name));
}
require_once $cache;
}
}
if (!$this->twig->runtimeInitialized) {
$this->initRuntime();
}
return $this->twig->loadedTemplates[$cls] = new TraceableTwigTemplate($this, new $cls($this));
}
public function isTemplateFresh($name, $time)
{
return $this->twig->isTemplateFresh($name, $time);
}
public function resolveTemplate($names)
{
return $this->twig->resolveTemplate($names);
}
public function clearTemplateCache()
{
$this->twig->clearTemplateCache();
}
public function clearCacheFiles()
{
$this->twig->clearCacheFiles();
}
public function getLexer()
{
return $this->twig->getLexer();
}
public function setLexer(Twig_LexerInterface $lexer)
{
$this->twig->setLexer($lexer);
}
public function tokenize($source, $name = null)
{
return $this->twig->tokenize($source, $name);
}
public function getParser()
{
return $this->twig->getParser();
}
public function setParser(Twig_ParserInterface $parser)
{
$this->twig->setParser($parser);
}
public function parse(Twig_TokenStream $tokens)
{
return $this->twig->parse($tokens);
}
public function getCompiler()
{
return $this->twig->getCompiler();
}
public function setCompiler(Twig_CompilerInterface $compiler)
{
$this->twig->setCompiler($compiler);
}
public function compile(Twig_NodeInterface $node)
{
return $this->twig->compile($node);
}
public function compileSource($source, $name = null)
{
return $this->twig->compileSource($source, $name);
}
public function setLoader(Twig_LoaderInterface $loader)
{
$this->twig->setLoader($loader);
}
public function getLoader()
{
return $this->twig->getLoader();
}
public function setCharset($charset)
{
$this->twig->setCharset($charset);
}
public function getCharset()
{
return $this->twig->getCharset();
}
public function initRuntime()
{
$this->twig->initRuntime();
}
public function hasExtension($name)
{
return $this->twig->hasExtension($name);
}
public function getExtension($name)
{
return $this->twig->getExtension($name);
}
public function addExtension(Twig_ExtensionInterface $extension)
{
$this->twig->addExtension($extension);
}
public function removeExtension($name)
{
$this->twig->removeExtension($name);
}
public function setExtensions(array $extensions)
{
$this->twig->setExtensions($extensions);
}
public function getExtensions()
{
return $this->twig->getExtensions();
}
public function addTokenParser(Twig_TokenParserInterface $parser)
{
$this->twig->addTokenParser($parser);
}
public function getTokenParsers()
{
return $this->twig->getTokenParsers();
}
public function getTags()
{
return $this->twig->getTags();
}
public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
{
$this->twig->addNodeVisitor($visitor);
}
public function getNodeVisitors()
{
return $this->twig->getNodeVisitors();
}
public function addFilter($name, $filter = null)
{
$this->twig->addFilter($name, $filter);
}
public function getFilter($name)
{
return $this->twig->getFilter($name);
}
public function registerUndefinedFilterCallback($callable)
{
$this->twig->registerUndefinedFilterCallback($callable);
}
public function getFilters()
{
return $this->twig->getFilters();
}
public function addTest($name, $test = null)
{
$this->twig->addTest($name, $test);
}
public function getTests()
{
return $this->twig->getTests();
}
public function getTest($name)
{
return $this->twig->getTest($name);
}
public function addFunction($name, $function = null)
{
$this->twig->addFunction($name, $function);
}
public function getFunction($name)
{
return $this->twig->getFunction($name);
}
public function registerUndefinedFunctionCallback($callable)
{
$this->twig->registerUndefinedFunctionCallback($callable);
}
public function getFunctions()
{
return $this->twig->getFunctions();
}
public function addGlobal($name, $value)
{
$this->twig->addGlobal($name, $value);
}
public function getGlobals()
{
return $this->twig->getGlobals();
}
public function mergeGlobals(array $context)
{
return $this->twig->mergeGlobals($context);
}
public function getUnaryOperators()
{
return $this->twig->getUnaryOperators();
}
public function getBinaryOperators()
{
return $this->twig->getBinaryOperators();
}
public function computeAlternatives($name, $items)
{
return $this->twig->computeAlternatives($name, $items);
}
}
@@ -0,0 +1,131 @@
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\Bridge\Twig;
use Twig_Template;
use Twig_TemplateInterface;
/**
* Wraps a Twig_Template to add profiling features
*/
class TraceableTwigTemplate implements Twig_TemplateInterface
{
protected $template;
/**
* @param TraceableTwigEnvironment $env
* @param Twig_Template $template
*/
public function __construct(TraceableTwigEnvironment $env, Twig_Template $template)
{
$this->env = $env;
$this->template = $template;
}
public function __call($name, $arguments)
{
return call_user_func_array(array($this->template, $name), $arguments);
}
public function getTemplateName()
{
return $this->template->getTemplateName();
}
public function getEnvironment()
{
return $this->template->getEnvironment();
}
public function getParent(array $context)
{
return $this->template->getParent($context);
}
public function isTraitable()
{
return $this->template->isTraitable();
}
public function displayParentBlock($name, array $context, array $blocks = array())
{
$this->template->displayParentBlock($name, $context, $blocks);
}
public function displayBlock($name, array $context, array $blocks = array(), $useBlocks = true)
{
$this->template->displayBlock($name, $context, $blocks, $useBlocks);
}
public function renderParentBlock($name, array $context, array $blocks = array())
{
return $this->template->renderParentBlock($name, $context, $blocks);
}
public function renderBlock($name, array $context, array $blocks = array(), $useBlocks = true)
{
return $this->template->renderBlock($name, $context, $blocks, $useBlocks);
}
public function hasBlock($name)
{
return $this->template->hasBlock($name);
}
public function getBlockNames()
{
return $this->template->getBlockNames();
}
public function getBlocks()
{
return $this->template->getBlocks();
}
public function display(array $context, array $blocks = array())
{
$start = microtime(true);
$this->template->display($context, $blocks);
$end = microtime(true);
if ($timeDataCollector = $this->env->getTimeDataCollector()) {
$name = sprintf("twig.render(%s)", $this->template->getTemplateName());
$timeDataCollector->addMeasure($name, $start, $end);
}
$this->env->addRenderedTemplate(array(
'name' => $this->template->getTemplateName(),
'render_time' => $end - $start
));
}
public function render(array $context)
{
$level = ob_get_level();
ob_start();
try {
$this->display($context);
} catch (Exception $e) {
while (ob_get_level() > $level) {
ob_end_clean();
}
throw $e;
}
return ob_get_clean();
}
public static function clearCache()
{
Twig_Template::clearCache();
}
}
@@ -0,0 +1,87 @@
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\Bridge\Twig;
use DebugBar\DataCollector\AssetProvider;
use DebugBar\DataCollector\DataCollector;
use DebugBar\DataCollector\Renderable;
/**
* Collects data about rendered templates
*
* http://twig.sensiolabs.org/
*
* Your Twig_Environment object needs to be wrapped in a
* TraceableTwigEnvironment object
*
* <code>
* $env = new TraceableTwigEnvironment(new Twig_Environment($loader));
* $debugbar->addCollector(new TwigCollector($env));
* </code>
*/
class TwigCollector extends DataCollector implements Renderable, AssetProvider
{
public function __construct(TraceableTwigEnvironment $twig)
{
$this->twig = $twig;
}
public function collect()
{
$templates = array();
$accuRenderTime = 0;
foreach ($this->twig->getRenderedTemplates() as $tpl) {
$accuRenderTime += $tpl['render_time'];
$templates[] = array(
'name' => $tpl['name'],
'render_time' => $tpl['render_time'],
'render_time_str' => $this->formatDuration($tpl['render_time'])
);
}
return array(
'nb_templates' => count($templates),
'templates' => $templates,
'accumulated_render_time' => $accuRenderTime,
'accumulated_render_time_str' => $this->formatDuration($accuRenderTime)
);
}
public function getName()
{
return 'twig';
}
public function getWidgets()
{
return array(
'twig' => array(
'icon' => 'leaf',
'widget' => 'PhpDebugBar.Widgets.TemplatesWidget',
'map' => 'twig',
'default' => '[]'
),
'twig:badge' => array(
'map' => 'twig.nb_templates',
'default' => 0
)
);
}
public function getAssets()
{
return array(
'css' => 'widgets/templates/widget.css',
'js' => 'widgets/templates/widget.js'
);
}
}
@@ -0,0 +1,166 @@
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\DataCollector;
use ArrayAccess;
use DebugBar\DebugBarException;
/**
* Aggregates data from multiple collectors
*
* <code>
* $aggcollector = new AggregateCollector('foobar');
* $aggcollector->addCollector(new MessagesCollector('msg1'));
* $aggcollector->addCollector(new MessagesCollector('msg2'));
* $aggcollector['msg1']->addMessage('hello world');
* </code>
*/
class AggregatedCollector implements DataCollectorInterface, ArrayAccess
{
protected $name;
protected $mergeProperty;
protected $sort;
protected $collectors = array();
/**
* @param string $name
* @param string $mergeProperty
* @param boolean $sort
*/
public function __construct($name, $mergeProperty = null, $sort = false)
{
$this->name = $name;
$this->mergeProperty = $mergeProperty;
$this->sort = $sort;
}
/**
* @param DataCollectorInterface $collector
*/
public function addCollector(DataCollectorInterface $collector)
{
$this->collectors[$collector->getName()] = $collector;
}
/**
* @return array
*/
public function getCollectors()
{
return $this->collectors;
}
/**
* Merge data from one of the key/value pair of the collected data
*
* @param string $property
*/
public function setMergeProperty($property)
{
$this->mergeProperty = $property;
}
/**
* @return string
*/
public function getMergeProperty()
{
return $this->mergeProperty;
}
/**
* Sorts the collected data
*
* If true, sorts using sort()
* If it is a string, sorts the data using the value from a key/value pair of the array
*
* @param bool|string $sort
*/
public function setSort($sort)
{
$this->sort = $sort;
}
/**
* @return bool|string
*/
public function getSort()
{
return $this->sort;
}
public function collect()
{
$aggregate = array();
foreach ($this->collectors as $collector) {
$data = $collector->collect();
if ($this->mergeProperty !== null) {
$data = $data[$this->mergeProperty];
}
$aggregate = array_merge($aggregate, $data);
}
return $this->sort($aggregate);
}
/**
* Sorts the collected data
*
* @param array $data
* @return array
*/
protected function sort($data)
{
if (is_string($this->sort)) {
$p = $this->sort;
usort($data, function ($a, $b) use ($p) {
if ($a[$p] == $b[$p]) {
return 0;
}
return $a[$p] < $b[$p] ? -1 : 1;
});
} elseif ($this->sort === true) {
sort($data);
}
return $data;
}
public function getName()
{
return $this->name;
}
// --------------------------------------------
// ArrayAccess implementation
public function offsetSet($key, $value)
{
throw new DebugBarException("AggregatedCollector[] is read-only");
}
public function offsetGet($key)
{
return $this->collectors[$key];
}
public function offsetExists($key)
{
return isset($this->collectors[$key]);
}
public function offsetUnset($key)
{
throw new DebugBarException("AggregatedCollector[] is read-only");
}
}
@@ -0,0 +1,28 @@
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\DataCollector;
/**
* Indicates that a DataCollector provides some assets
*/
interface AssetProvider
{
/**
* Returns an array with the following keys:
* - base_path
* - base_url
* - css: an array of filenames
* - js: an array of filenames
*
* @return array
*/
function getAssets();
}
@@ -0,0 +1,71 @@
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\DataCollector;
/**
* Collects array data
*/
class ConfigCollector extends DataCollector implements Renderable
{
protected $name;
protected $data;
/**
* @param array $data
* @param string $name
*/
public function __construct(array $data = array(), $name = 'config')
{
$this->name = $name;
$this->data = $data;
}
/**
* Sets the data
*
* @param array $data
*/
public function setData(array $data)
{
$this->data = $data;
}
public function collect()
{
$data = array();
foreach ($this->data as $k => $v) {
if (!is_string($v)) {
$v = $this->getDataFormatter()->formatVar($v);
}
$data[$k] = $v;
}
return $data;
}
public function getName()
{
return $this->name;
}
public function getWidgets()
{
$name = $this->getName();
return array(
"$name" => array(
"icon" => "gear",
"widget" => "PhpDebugBar.Widgets.VariableListWidget",
"map" => "$name",
"default" => "{}"
)
);
}
}
@@ -0,0 +1,90 @@
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\DataCollector;
use DebugBar\DataFormatter\DataFormatter;
use DebugBar\DataFormatter\DataFormatterInterface;
/**
* Abstract class for data collectors
*/
abstract class DataCollector implements DataCollectorInterface
{
private static $defaultDataFormatter;
protected $dataFormater;
/**
* Sets the default data formater instance used by all collectors subclassing this class
*
* @param DataFormatterInterface $formater
*/
public static function setDefaultDataFormatter(DataFormatterInterface $formater)
{
self::$defaultDataFormatter = $formater;
}
/**
* Returns the default data formater
*
* @return DataFormatterInterface
*/
public static function getDefaultDataFormatter()
{
if (self::$defaultDataFormatter === null) {
self::$defaultDataFormatter = new DataFormatter();
}
return self::$defaultDataFormatter;
}
/**
* Sets the data formater instance used by this collector
*
* @param DataFormatterInterface $formater
*/
public function setDataFormatter(DataFormatterInterface $formater)
{
$this->dataFormater = $formater;
return $this;
}
public function getDataFormatter()
{
if ($this->dataFormater === null) {
$this->dataFormater = self::getDefaultDataFormatter();
}
return $this->dataFormater;
}
/**
* @deprecated
*/
public function formatVar($var)
{
return $this->getDataFormatter()->formatVar($var);
}
/**
* @deprecated
*/
public function formatDuration($seconds)
{
return $this->getDataFormatter()->formatDuration($seconds);
}
/**
* @deprecated
*/
public function formatBytes($size, $precision = 2)
{
return $this->getDataFormatter()->formatBytes($size, $precision);
}
}
@@ -0,0 +1,31 @@
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\DataCollector;
/**
* DataCollector Interface
*/
interface DataCollectorInterface
{
/**
* Called by the DebugBar when data needs to be collected
*
* @return array Collected data
*/
function collect();
/**
* Returns the unique name of the collector
*
* @return string
*/
function getName();
}
@@ -0,0 +1,111 @@
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\DataCollector;
use Exception;
/**
* Collects info about exceptions
*/
class ExceptionsCollector extends DataCollector implements Renderable
{
protected $exceptions = array();
protected $chainExceptions = false;
/**
* Adds an exception to be profiled in the debug bar
*
* @param Exception $e
*/
public function addException(Exception $e)
{
$this->exceptions[] = $e;
if ($this->chainExceptions && $previous = $e->getPrevious()) {
$this->addException($previous);
}
}
/**
* Configure whether or not all chained exceptions should be shown.
*
* @param bool $chainExceptions
*/
public function setChainExceptions($chainExceptions = true)
{
$this->chainExceptions = $chainExceptions;
}
/**
* Returns the list of exceptions being profiled
*
* @return array[Exception]
*/
public function getExceptions()
{
return $this->exceptions;
}
public function collect()
{
return array(
'count' => count($this->exceptions),
'exceptions' => array_map(array($this, 'formatExceptionData'), $this->exceptions)
);
}
/**
* Returns exception data as an array
*
* @param Exception $e
* @return array
*/
public function formatExceptionData(Exception $e)
{
$filePath = $e->getFile();
if ($filePath && file_exists($filePath)) {
$lines = file($filePath);
$start = $e->getLine() - 4;
$lines = array_slice($lines, $start < 0 ? 0 : $start, 7);
} else {
$lines = array("Cannot open the file ($filePath) in which the exception occurred ");
}
return array(
'type' => get_class($e),
'message' => $e->getMessage(),
'code' => $e->getCode(),
'file' => $filePath,
'line' => $e->getLine(),
'surrounding_lines' => $lines
);
}
public function getName()
{
return 'exceptions';
}
public function getWidgets()
{
return array(
'exceptions' => array(
'icon' => 'bug',
'widget' => 'PhpDebugBar.Widgets.ExceptionsWidget',
'map' => 'exceptions.exceptions',
'default' => '[]'
),
'exceptions:badge' => array(
'map' => 'exceptions.count',
'default' => 'null'
)
);
}
}
@@ -0,0 +1,64 @@
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\DataCollector;
/**
* Collects info about the current localization state
*/
class LocalizationCollector extends DataCollector implements Renderable
{
/**
* Get the current locale
*
* @return string
*/
public function getLocale()
{
return setlocale(LC_ALL, 0);
}
/**
* Get the current translations domain
*
* @return string
*/
public function getDomain()
{
return textdomain();
}
public function collect()
{
return array(
'locale' => $this->getLocale(),
'domain' => $this->getDomain(),
);
}
public function getName()
{
return 'localization';
}
public function getWidgets()
{
return array(
'domain' => array(
'icon' => 'bookmark',
'map' => 'localization.domain',
),
'locale' => array(
'icon' => 'flag',
'map' => 'localization.locale',
)
);
}
}
@@ -0,0 +1,63 @@
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\DataCollector;
/**
* Collects info about memory usage
*/
class MemoryCollector extends DataCollector implements Renderable
{
protected $peakUsage = 0;
/**
* Returns the peak memory usage
*
* @return integer
*/
public function getPeakUsage()
{
return $this->peakUsage;
}
/**
* Updates the peak memory usage value
*/
public function updatePeakUsage()
{
$this->peakUsage = memory_get_peak_usage(true);
}
public function collect()
{
$this->updatePeakUsage();
return array(
'peak_usage' => $this->peakUsage,
'peak_usage_str' => $this->getDataFormatter()->formatBytes($this->peakUsage)
);
}
public function getName()
{
return 'memory';
}
public function getWidgets()
{
return array(
"memory" => array(
"icon" => "cogs",
"tooltip" => "Memory Usage",
"map" => "memory.peak_usage_str",
"default" => "'0B'"
)
);
}
}
@@ -0,0 +1,21 @@
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\DataCollector;
interface MessagesAggregateInterface
{
/**
* Returns collected messages
*
* @return array
*/
public function getMessages();
}
@@ -0,0 +1,152 @@
<?php
/*
* This file is part of the DebugBar package.
*
* (c) 2013 Maxime Bouroumeau-Fuseau
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace DebugBar\DataCollector;
use Psr\Log\AbstractLogger;
/**
* Provides a way to log messages
*/
class MessagesCollector extends AbstractLogger implements DataCollectorInterface, MessagesAggregateInterface, Renderable
{
protected $name;
protected $messages = array();
protected $aggregates = array();
protected $dataFormater;
/**
* @param string $name
*/
public function __construct($name = 'messages')
{
$this->name = $name;
}
/**
* Sets the data formater instance used by this collector
*
* @param DataFormatterInterface $formater
*/
public function setDataFormatter(DataFormatterInterface $formater)
{
$this->dataFormater = $formater;
return $this;
}
public function getDataFormatter()
{
if ($this->dataFormater === null) {
$this->dataFormater = DataCollector::getDefaultDataFormatter();
}
return $this->dataFormater;
}
/**
* Adds a message
*
* A message can be anything from an object to a string
*
* @param mixed $message
* @param string $label
*/
public function addMessage($message, $label = 'info', $isString = true)
{
if (!is_string($message)) {
$message = $this->getDataFormatter()->formatVar($message);
$isString = false;
}
$this->messages[] = array(
'message' => $message,
'is_string' => $isString,
'label' => $label,
'time' => microtime(true)
);
}
/**
* Aggregates messages from other collectors
*
* @param MessagesAggregateInterface $messages
*/
public function aggregate(MessagesAggregateInterface $messages)
{
$this->aggregates[] = $messages;
}
public function getMessages()
{
$messages = $this->messages;
foreach ($this->aggregates as $collector) {
$msgs = array_map(function ($m) use ($collector) {
$m['collector'] = $collector->getName();
return $m;
}, $collector->getMessages());
$messages = array_merge($messages, $msgs);
}
// sort messages by their timestamp
usort($messages, function ($a, $b) {
if ($a['time'] === $b['time']) {
return 0;
}
return $a['time'] < $b['time'] ? -1 : 1;
});
return $messages;
}
public function log($level, $message, array $context = array())
{
$this->addMessage($message, $level);
}
/**
* Deletes all messages
*/
public function clear()
{
$this->messages = array();
}
public function collect()
{
$messages = $this->getMessages();
return array(
'count' => count($messages),
'messages' => $messages
);
}
public function getName()
{
return $this->name;
}
public function getWidgets()
{
$name = $this->getName();
return array(
"$name" => array(
'icon' => 'list-alt',
"widget" => "PhpDebugBar.Widgets.MessagesWidget",
"map" => "$name.messages",
"default" => "[]"
),
"$name:badge" => array(
"map" => "$name.count",
"default" => "null"
)
);
}
}

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