the whole shebang
This commit is contained in:
5
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/.gitignore
vendored
Normal file
5
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
vendor/
|
||||
composer.lock
|
||||
phpunit.xml
|
||||
Tests/ProjectContainer.php
|
||||
Tests/classes.map
|
197
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Bundle/Bundle.php
vendored
Normal file
197
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Bundle/Bundle.php
vendored
Normal file
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Bundle;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerAware;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Container;
|
||||
use Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
|
||||
|
||||
/**
|
||||
* An implementation of BundleInterface that adds a few conventions
|
||||
* for DependencyInjection extensions and Console commands.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
abstract class Bundle extends ContainerAware implements BundleInterface
|
||||
{
|
||||
protected $name;
|
||||
protected $reflected;
|
||||
protected $extension;
|
||||
|
||||
/**
|
||||
* Boots the Bundle.
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdowns the Bundle.
|
||||
*/
|
||||
public function shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the bundle.
|
||||
*
|
||||
* It is only ever called once when the cache is empty.
|
||||
*
|
||||
* This method can be overridden to register compilation passes,
|
||||
* other extensions, ...
|
||||
*
|
||||
* @param ContainerBuilder $container A ContainerBuilder instance
|
||||
*/
|
||||
public function build(ContainerBuilder $container)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bundle's container extension.
|
||||
*
|
||||
* @return ExtensionInterface|null The container extension
|
||||
*
|
||||
* @throws \LogicException
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getContainerExtension()
|
||||
{
|
||||
if (null === $this->extension) {
|
||||
$basename = preg_replace('/Bundle$/', '', $this->getName());
|
||||
|
||||
$class = $this->getNamespace().'\\DependencyInjection\\'.$basename.'Extension';
|
||||
if (class_exists($class)) {
|
||||
$extension = new $class();
|
||||
|
||||
// check naming convention
|
||||
$expectedAlias = Container::underscore($basename);
|
||||
if ($expectedAlias != $extension->getAlias()) {
|
||||
throw new \LogicException(sprintf(
|
||||
'The extension alias for the default extension of a '.
|
||||
'bundle must be the underscored version of the '.
|
||||
'bundle name ("%s" instead of "%s")',
|
||||
$expectedAlias, $extension->getAlias()
|
||||
));
|
||||
}
|
||||
|
||||
$this->extension = $extension;
|
||||
} else {
|
||||
$this->extension = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->extension) {
|
||||
return $this->extension;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Bundle namespace.
|
||||
*
|
||||
* @return string The Bundle namespace
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getNamespace()
|
||||
{
|
||||
if (null === $this->reflected) {
|
||||
$this->reflected = new \ReflectionObject($this);
|
||||
}
|
||||
|
||||
return $this->reflected->getNamespaceName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Bundle directory path.
|
||||
*
|
||||
* @return string The Bundle absolute path
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
if (null === $this->reflected) {
|
||||
$this->reflected = new \ReflectionObject($this);
|
||||
}
|
||||
|
||||
return dirname($this->reflected->getFileName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bundle parent name.
|
||||
*
|
||||
* @return string The Bundle parent name it overrides or null if no parent
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bundle name (the class short name).
|
||||
*
|
||||
* @return string The Bundle name
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
final public function getName()
|
||||
{
|
||||
if (null !== $this->name) {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
$name = get_class($this);
|
||||
$pos = strrpos($name, '\\');
|
||||
|
||||
return $this->name = false === $pos ? $name : substr($name, $pos + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds and registers Commands.
|
||||
*
|
||||
* Override this method if your bundle commands do not follow the conventions:
|
||||
*
|
||||
* * Commands are in the 'Command' sub-directory
|
||||
* * Commands extend Symfony\Component\Console\Command\Command
|
||||
*
|
||||
* @param Application $application An Application instance
|
||||
*/
|
||||
public function registerCommands(Application $application)
|
||||
{
|
||||
if (!is_dir($dir = $this->getPath().'/Command')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$finder = new Finder();
|
||||
$finder->files()->name('*Command.php')->in($dir);
|
||||
|
||||
$prefix = $this->getNamespace().'\\Command';
|
||||
foreach ($finder as $file) {
|
||||
$ns = $prefix;
|
||||
if ($relativePath = $file->getRelativePath()) {
|
||||
$ns .= '\\'.strtr($relativePath, '/', '\\');
|
||||
}
|
||||
$r = new \ReflectionClass($ns.'\\'.$file->getBasename('.php'));
|
||||
if ($r->isSubclassOf('Symfony\\Component\\Console\\Command\\Command') && !$r->isAbstract() && !$r->getConstructor()->getNumberOfRequiredParameters()) {
|
||||
$application->add($r->newInstance());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
102
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Bundle/BundleInterface.php
vendored
Normal file
102
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Bundle/BundleInterface.php
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Bundle;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
|
||||
|
||||
/**
|
||||
* BundleInterface.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
interface BundleInterface extends ContainerAwareInterface
|
||||
{
|
||||
/**
|
||||
* Boots the Bundle.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function boot();
|
||||
|
||||
/**
|
||||
* Shutdowns the Bundle.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function shutdown();
|
||||
|
||||
/**
|
||||
* Builds the bundle.
|
||||
*
|
||||
* It is only ever called once when the cache is empty.
|
||||
*
|
||||
* @param ContainerBuilder $container A ContainerBuilder instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function build(ContainerBuilder $container);
|
||||
|
||||
/**
|
||||
* Returns the container extension that should be implicitly loaded.
|
||||
*
|
||||
* @return ExtensionInterface|null The default extension or null if there is none
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getContainerExtension();
|
||||
|
||||
/**
|
||||
* Returns the bundle name that this bundle overrides.
|
||||
*
|
||||
* Despite its name, this method does not imply any parent/child relationship
|
||||
* between the bundles, just a way to extend and override an existing
|
||||
* bundle.
|
||||
*
|
||||
* @return string The Bundle name it overrides or null if no parent
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getParent();
|
||||
|
||||
/**
|
||||
* Returns the bundle name (the class short name).
|
||||
*
|
||||
* @return string The Bundle name
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* Gets the Bundle namespace.
|
||||
*
|
||||
* @return string The Bundle namespace
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getNamespace();
|
||||
|
||||
/**
|
||||
* Gets the Bundle directory path.
|
||||
*
|
||||
* The path should always be returned as a Unix path (with /).
|
||||
*
|
||||
* @return string The Bundle absolute path
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getPath();
|
||||
}
|
51
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CHANGELOG.md
vendored
Normal file
51
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CHANGELOG.md
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
2.3.0
|
||||
-----
|
||||
|
||||
* [BC BREAK] renamed `Symfony\Component\HttpKernel\EventListener\DeprecationLoggerListener` to `Symfony\Component\HttpKernel\EventListener\ErrorsLoggerListener` and changed its constructor
|
||||
* deprecated `Symfony\Component\HttpKernel\Debug\ErrorHandler`, `Symfony\Component\HttpKernel\Debug\ExceptionHandler`,
|
||||
`Symfony\Component\HttpKernel\Exception\FatalErrorException`, and `Symfony\Component\HttpKernel\Exception\FlattenException`
|
||||
* deprecated `Symfony\Component\HttpKernel\Kernel::init()``
|
||||
* added the possibility to specify an id an extra attributes to hinclude tags
|
||||
* added the collect of data if a controller is a Closure in the Request collector
|
||||
* pass exceptions from the ExceptionListener to the logger using the logging context to allow for more
|
||||
detailed messages
|
||||
|
||||
2.2.0
|
||||
-----
|
||||
|
||||
* [BC BREAK] the path info for sub-request is now always _fragment (or whatever you configured instead of the default)
|
||||
* added Symfony\Component\HttpKernel\EventListener\FragmentListener
|
||||
* added Symfony\Component\HttpKernel\UriSigner
|
||||
* added Symfony\Component\HttpKernel\FragmentRenderer and rendering strategies (in Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface)
|
||||
* added Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel
|
||||
* added ControllerReference to create reference of Controllers (used in the FragmentRenderer class)
|
||||
* [BC BREAK] renamed TimeDataCollector::getTotalTime() to
|
||||
TimeDataCollector::getDuration()
|
||||
* updated the MemoryDataCollector to include the memory used in the
|
||||
kernel.terminate event listeners
|
||||
* moved the Stopwatch classes to a new component
|
||||
* added TraceableControllerResolver
|
||||
* added TraceableEventDispatcher (removed ContainerAwareTraceableEventDispatcher)
|
||||
* added support for WinCache opcode cache in ConfigDataCollector
|
||||
|
||||
2.1.0
|
||||
-----
|
||||
|
||||
* [BC BREAK] the charset is now configured via the Kernel::getCharset() method
|
||||
* [BC BREAK] the current locale for the user is not stored anymore in the session
|
||||
* added the HTTP method to the profiler storage
|
||||
* updated all listeners to implement EventSubscriberInterface
|
||||
* added TimeDataCollector
|
||||
* added ContainerAwareTraceableEventDispatcher
|
||||
* moved TraceableEventDispatcherInterface to the EventDispatcher component
|
||||
* added RouterListener, LocaleListener, and StreamedResponseListener
|
||||
* added CacheClearerInterface (and ChainCacheClearer)
|
||||
* added a kernel.terminate event (via TerminableInterface and PostResponseEvent)
|
||||
* added a Stopwatch class
|
||||
* added WarmableInterface
|
||||
* improved extensibility between bundles
|
||||
* added profiler storages for Memcache(d), File-based, MongoDB, Redis
|
||||
* moved Filesystem class to its own component
|
27
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CacheClearer/CacheClearerInterface.php
vendored
Normal file
27
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CacheClearer/CacheClearerInterface.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\CacheClearer;
|
||||
|
||||
/**
|
||||
* CacheClearerInterface.
|
||||
*
|
||||
* @author Dustin Dobervich <ddobervich@gmail.com>
|
||||
*/
|
||||
interface CacheClearerInterface
|
||||
{
|
||||
/**
|
||||
* Clears any caches necessary.
|
||||
*
|
||||
* @param string $cacheDir The cache directory.
|
||||
*/
|
||||
public function clear($cacheDir);
|
||||
}
|
55
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CacheClearer/ChainCacheClearer.php
vendored
Normal file
55
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CacheClearer/ChainCacheClearer.php
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\CacheClearer;
|
||||
|
||||
/**
|
||||
* ChainCacheClearer.
|
||||
*
|
||||
* @author Dustin Dobervich <ddobervich@gmail.com>
|
||||
*/
|
||||
class ChainCacheClearer implements CacheClearerInterface
|
||||
{
|
||||
/**
|
||||
* @var array $clearers
|
||||
*/
|
||||
protected $clearers;
|
||||
|
||||
/**
|
||||
* Constructs a new instance of ChainCacheClearer.
|
||||
*
|
||||
* @param array $clearers The initial clearers.
|
||||
*/
|
||||
public function __construct(array $clearers = array())
|
||||
{
|
||||
$this->clearers = $clearers;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function clear($cacheDir)
|
||||
{
|
||||
foreach ($this->clearers as $clearer) {
|
||||
$clearer->clear($cacheDir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a cache clearer to the aggregate.
|
||||
*
|
||||
* @param CacheClearerInterface $clearer
|
||||
*/
|
||||
public function add(CacheClearerInterface $clearer)
|
||||
{
|
||||
$this->clearers[] = $clearer;
|
||||
}
|
||||
}
|
32
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmer.php
vendored
Normal file
32
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmer.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\CacheWarmer;
|
||||
|
||||
/**
|
||||
* Abstract cache warmer that knows how to write a file to the cache.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
abstract class CacheWarmer implements CacheWarmerInterface
|
||||
{
|
||||
protected function writeCacheFile($file, $content)
|
||||
{
|
||||
$tmpFile = tempnam(dirname($file), basename($file));
|
||||
if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $file)) {
|
||||
@chmod($file, 0666 & ~umask());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $file));
|
||||
}
|
||||
}
|
73
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmerAggregate.php
vendored
Normal file
73
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmerAggregate.php
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\CacheWarmer;
|
||||
|
||||
/**
|
||||
* Aggregates several cache warmers into a single one.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class CacheWarmerAggregate implements CacheWarmerInterface
|
||||
{
|
||||
protected $warmers;
|
||||
protected $optionalsEnabled;
|
||||
|
||||
public function __construct(array $warmers = array())
|
||||
{
|
||||
$this->setWarmers($warmers);
|
||||
$this->optionalsEnabled = false;
|
||||
}
|
||||
|
||||
public function enableOptionalWarmers()
|
||||
{
|
||||
$this->optionalsEnabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Warms up the cache.
|
||||
*
|
||||
* @param string $cacheDir The cache directory
|
||||
*/
|
||||
public function warmUp($cacheDir)
|
||||
{
|
||||
foreach ($this->warmers as $warmer) {
|
||||
if (!$this->optionalsEnabled && $warmer->isOptional()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$warmer->warmUp($cacheDir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this warmer is optional or not.
|
||||
*
|
||||
* @return Boolean always true
|
||||
*/
|
||||
public function isOptional()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function setWarmers(array $warmers)
|
||||
{
|
||||
$this->warmers = array();
|
||||
foreach ($warmers as $warmer) {
|
||||
$this->add($warmer);
|
||||
}
|
||||
}
|
||||
|
||||
public function add(CacheWarmerInterface $warmer)
|
||||
{
|
||||
$this->warmers[] = $warmer;
|
||||
}
|
||||
}
|
32
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmerInterface.php
vendored
Normal file
32
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmerInterface.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\CacheWarmer;
|
||||
|
||||
/**
|
||||
* Interface for classes able to warm up the cache.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface CacheWarmerInterface extends WarmableInterface
|
||||
{
|
||||
/**
|
||||
* Checks whether this warmer is optional or not.
|
||||
*
|
||||
* Optional warmers can be ignored on certain conditions.
|
||||
*
|
||||
* A warmer should return true if the cache can be
|
||||
* generated incrementally and on-demand.
|
||||
*
|
||||
* @return Boolean true if the warmer is optional, false otherwise
|
||||
*/
|
||||
public function isOptional();
|
||||
}
|
27
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CacheWarmer/WarmableInterface.php
vendored
Normal file
27
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/CacheWarmer/WarmableInterface.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\CacheWarmer;
|
||||
|
||||
/**
|
||||
* Interface for classes that support warming their cache.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface WarmableInterface
|
||||
{
|
||||
/**
|
||||
* Warms up the cache.
|
||||
*
|
||||
* @param string $cacheDir The cache directory
|
||||
*/
|
||||
public function warmUp($cacheDir);
|
||||
}
|
211
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Client.php
vendored
Normal file
211
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Client.php
vendored
Normal file
@@ -0,0 +1,211 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel;
|
||||
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\BrowserKit\Client as BaseClient;
|
||||
use Symfony\Component\BrowserKit\Request as DomRequest;
|
||||
use Symfony\Component\BrowserKit\Response as DomResponse;
|
||||
use Symfony\Component\BrowserKit\Cookie as DomCookie;
|
||||
use Symfony\Component\BrowserKit\History;
|
||||
use Symfony\Component\BrowserKit\CookieJar;
|
||||
use Symfony\Component\HttpKernel\TerminableInterface;
|
||||
|
||||
/**
|
||||
* Client simulates a browser and makes requests to a Kernel object.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class Client extends BaseClient
|
||||
{
|
||||
protected $kernel;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param HttpKernelInterface $kernel An HttpKernel instance
|
||||
* @param array $server The server parameters (equivalent of $_SERVER)
|
||||
* @param History $history A History instance to store the browser history
|
||||
* @param CookieJar $cookieJar A CookieJar instance to store the cookies
|
||||
*/
|
||||
public function __construct(HttpKernelInterface $kernel, array $server = array(), History $history = null, CookieJar $cookieJar = null)
|
||||
{
|
||||
$this->kernel = $kernel;
|
||||
|
||||
parent::__construct($server, $history, $cookieJar);
|
||||
|
||||
$this->followRedirects = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return Request|null A Request instance
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
return parent::getRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return Response|null A Response instance
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return parent::getResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
*
|
||||
* @return Response A Response instance
|
||||
*/
|
||||
protected function doRequest($request)
|
||||
{
|
||||
$response = $this->kernel->handle($request);
|
||||
|
||||
if ($this->kernel instanceof TerminableInterface) {
|
||||
$this->kernel->terminate($request, $response);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the script to execute when the request must be insulated.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getScript($request)
|
||||
{
|
||||
$kernel = str_replace("'", "\\'", serialize($this->kernel));
|
||||
$request = str_replace("'", "\\'", serialize($request));
|
||||
|
||||
$r = new \ReflectionClass('\\Symfony\\Component\\ClassLoader\\ClassLoader');
|
||||
$requirePath = str_replace("'", "\\'", $r->getFileName());
|
||||
$symfonyPath = str_replace("'", "\\'", realpath(__DIR__.'/../../..'));
|
||||
|
||||
return <<<EOF
|
||||
<?php
|
||||
|
||||
require_once '$requirePath';
|
||||
|
||||
\$loader = new Symfony\Component\ClassLoader\ClassLoader();
|
||||
\$loader->addPrefix('Symfony', '$symfonyPath');
|
||||
\$loader->register();
|
||||
|
||||
\$kernel = unserialize('$kernel');
|
||||
echo serialize(\$kernel->handle(unserialize('$request')));
|
||||
EOF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the BrowserKit request to a HttpKernel request.
|
||||
*
|
||||
* @param DomRequest $request A DomRequest instance
|
||||
*
|
||||
* @return Request A Request instance
|
||||
*/
|
||||
protected function filterRequest(DomRequest $request)
|
||||
{
|
||||
$httpRequest = Request::create($request->getUri(), $request->getMethod(), $request->getParameters(), $request->getCookies(), $request->getFiles(), $request->getServer(), $request->getContent());
|
||||
|
||||
$httpRequest->files->replace($this->filterFiles($httpRequest->files->all()));
|
||||
|
||||
return $httpRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters an array of files.
|
||||
*
|
||||
* This method created test instances of UploadedFile so that the move()
|
||||
* method can be called on those instances.
|
||||
*
|
||||
* If the size of a file is greater than the allowed size (from php.ini) then
|
||||
* an invalid UploadedFile is returned with an error set to UPLOAD_ERR_INI_SIZE.
|
||||
*
|
||||
* @see Symfony\Component\HttpFoundation\File\UploadedFile
|
||||
*
|
||||
* @param array $files An array of files
|
||||
*
|
||||
* @return array An array with all uploaded files marked as already moved
|
||||
*/
|
||||
protected function filterFiles(array $files)
|
||||
{
|
||||
$filtered = array();
|
||||
foreach ($files as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$filtered[$key] = $this->filterFiles($value);
|
||||
} elseif ($value instanceof UploadedFile) {
|
||||
if ($value->isValid() && $value->getSize() > UploadedFile::getMaxFilesize()) {
|
||||
$filtered[$key] = new UploadedFile(
|
||||
'',
|
||||
$value->getClientOriginalName(),
|
||||
$value->getClientMimeType(),
|
||||
0,
|
||||
UPLOAD_ERR_INI_SIZE,
|
||||
true
|
||||
);
|
||||
} else {
|
||||
$filtered[$key] = new UploadedFile(
|
||||
$value->getPathname(),
|
||||
$value->getClientOriginalName(),
|
||||
$value->getClientMimeType(),
|
||||
$value->getClientSize(),
|
||||
$value->getError(),
|
||||
true
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$filtered[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $filtered;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the HttpKernel response to a BrowserKit response.
|
||||
*
|
||||
* @param Response $response A Response instance
|
||||
*
|
||||
* @return DomResponse A DomResponse instance
|
||||
*/
|
||||
protected function filterResponse($response)
|
||||
{
|
||||
$headers = $response->headers->all();
|
||||
if ($response->headers->getCookies()) {
|
||||
$cookies = array();
|
||||
foreach ($response->headers->getCookies() as $cookie) {
|
||||
$cookies[] = new DomCookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly());
|
||||
}
|
||||
$headers['Set-Cookie'] = $cookies;
|
||||
}
|
||||
|
||||
// this is needed to support StreamedResponse
|
||||
ob_start();
|
||||
$response->sendContent();
|
||||
$content = ob_get_clean();
|
||||
|
||||
return new DomResponse($content, $response->getStatusCode(), $headers);
|
||||
}
|
||||
}
|
56
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Config/FileLocator.php
vendored
Normal file
56
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Config/FileLocator.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Config;
|
||||
|
||||
use Symfony\Component\Config\FileLocator as BaseFileLocator;
|
||||
use Symfony\Component\HttpKernel\KernelInterface;
|
||||
|
||||
/**
|
||||
* FileLocator uses the KernelInterface to locate resources in bundles.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class FileLocator extends BaseFileLocator
|
||||
{
|
||||
private $kernel;
|
||||
private $path;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param KernelInterface $kernel A KernelInterface instance
|
||||
* @param null|string $path The path the global resource directory
|
||||
* @param array $paths An array of paths where to look for resources
|
||||
*/
|
||||
public function __construct(KernelInterface $kernel, $path = null, array $paths = array())
|
||||
{
|
||||
$this->kernel = $kernel;
|
||||
if (null !== $path) {
|
||||
$this->path = $path;
|
||||
$paths[] = $path;
|
||||
}
|
||||
|
||||
parent::__construct($paths);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function locate($file, $currentPath = null, $first = true)
|
||||
{
|
||||
if ('@' === $file[0]) {
|
||||
return $this->kernel->locateResource($file, $this->path, $first);
|
||||
}
|
||||
|
||||
return parent::locate($file, $currentPath, $first);
|
||||
}
|
||||
}
|
45
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Controller/ControllerReference.php
vendored
Normal file
45
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Controller/ControllerReference.php
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Controller;
|
||||
|
||||
/**
|
||||
* Acts as a marker and a data holder for a Controller.
|
||||
*
|
||||
* Some methods in Symfony accept both a URI (as a string) or a controller as
|
||||
* an argument. In the latter case, instead of passing an array representing
|
||||
* the controller, you can use an instance of this class.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @see Symfony\Component\HttpKernel\FragmentRenderer
|
||||
* @see Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface
|
||||
*/
|
||||
class ControllerReference
|
||||
{
|
||||
public $controller;
|
||||
public $attributes = array();
|
||||
public $query = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $controller The controller name
|
||||
* @param array $attributes An array of parameters to add to the Request attributes
|
||||
* @param array $query An array of parameters to add to the Request query string
|
||||
*/
|
||||
public function __construct($controller, array $attributes = array(), array $query = array())
|
||||
{
|
||||
$this->controller = $controller;
|
||||
$this->attributes = $attributes;
|
||||
$this->query = $query;
|
||||
}
|
||||
}
|
164
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Controller/ControllerResolver.php
vendored
Normal file
164
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Controller/ControllerResolver.php
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Controller;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* ControllerResolver.
|
||||
*
|
||||
* This implementation uses the '_controller' request attribute to determine
|
||||
* the controller to execute and uses the request attributes to determine
|
||||
* the controller method arguments.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class ControllerResolver implements ControllerResolverInterface
|
||||
{
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param LoggerInterface $logger A LoggerInterface instance
|
||||
*/
|
||||
public function __construct(LoggerInterface $logger = null)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Controller instance associated with a Request.
|
||||
*
|
||||
* This method looks for a '_controller' request attribute that represents
|
||||
* the controller name (a string like ClassName::MethodName).
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
*
|
||||
* @return mixed|Boolean A PHP callable representing the Controller,
|
||||
* or false if this resolver is not able to determine the controller
|
||||
*
|
||||
* @throws \InvalidArgumentException|\LogicException If the controller can't be found
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getController(Request $request)
|
||||
{
|
||||
if (!$controller = $request->attributes->get('_controller')) {
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->warning('Unable to look for the controller as the "_controller" parameter is missing');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_array($controller) || (is_object($controller) && method_exists($controller, '__invoke'))) {
|
||||
return $controller;
|
||||
}
|
||||
|
||||
if (false === strpos($controller, ':')) {
|
||||
if (method_exists($controller, '__invoke')) {
|
||||
return new $controller;
|
||||
} elseif (function_exists($controller)) {
|
||||
return $controller;
|
||||
}
|
||||
}
|
||||
|
||||
$callable = $this->createController($controller);
|
||||
|
||||
if (!is_callable($callable)) {
|
||||
throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable.', $request->getPathInfo()));
|
||||
}
|
||||
|
||||
return $callable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the arguments to pass to the controller.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param mixed $controller A PHP callable
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \RuntimeException When value for argument given is not provided
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getArguments(Request $request, $controller)
|
||||
{
|
||||
if (is_array($controller)) {
|
||||
$r = new \ReflectionMethod($controller[0], $controller[1]);
|
||||
} elseif (is_object($controller) && !$controller instanceof \Closure) {
|
||||
$r = new \ReflectionObject($controller);
|
||||
$r = $r->getMethod('__invoke');
|
||||
} else {
|
||||
$r = new \ReflectionFunction($controller);
|
||||
}
|
||||
|
||||
return $this->doGetArguments($request, $controller, $r->getParameters());
|
||||
}
|
||||
|
||||
protected function doGetArguments(Request $request, $controller, array $parameters)
|
||||
{
|
||||
$attributes = $request->attributes->all();
|
||||
$arguments = array();
|
||||
foreach ($parameters as $param) {
|
||||
if (array_key_exists($param->name, $attributes)) {
|
||||
$arguments[] = $attributes[$param->name];
|
||||
} elseif ($param->getClass() && $param->getClass()->isInstance($request)) {
|
||||
$arguments[] = $request;
|
||||
} elseif ($param->isDefaultValueAvailable()) {
|
||||
$arguments[] = $param->getDefaultValue();
|
||||
} else {
|
||||
if (is_array($controller)) {
|
||||
$repr = sprintf('%s::%s()', get_class($controller[0]), $controller[1]);
|
||||
} elseif (is_object($controller)) {
|
||||
$repr = get_class($controller);
|
||||
} else {
|
||||
$repr = $controller;
|
||||
}
|
||||
|
||||
throw new \RuntimeException(sprintf('Controller "%s" requires that you provide a value for the "$%s" argument (because there is no default value or because there is a non optional argument after this one).', $repr, $param->name));
|
||||
}
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a callable for the given controller.
|
||||
*
|
||||
* @param string $controller A Controller string
|
||||
*
|
||||
* @return mixed A PHP callable
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected function createController($controller)
|
||||
{
|
||||
if (false === strpos($controller, '::')) {
|
||||
throw new \InvalidArgumentException(sprintf('Unable to find controller "%s".', $controller));
|
||||
}
|
||||
|
||||
list($class, $method) = explode('::', $controller, 2);
|
||||
|
||||
if (!class_exists($class)) {
|
||||
throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class));
|
||||
}
|
||||
|
||||
return array(new $class(), $method);
|
||||
}
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Controller;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* A ControllerResolverInterface implementation knows how to determine the
|
||||
* controller to execute based on a Request object.
|
||||
*
|
||||
* It can also determine the arguments to pass to the Controller.
|
||||
*
|
||||
* A Controller can be any valid PHP callable.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
interface ControllerResolverInterface
|
||||
{
|
||||
/**
|
||||
* Returns the Controller instance associated with a Request.
|
||||
*
|
||||
* As several resolvers can exist for a single application, a resolver must
|
||||
* return false when it is not able to determine the controller.
|
||||
*
|
||||
* The resolver must only throw an exception when it should be able to load
|
||||
* controller but cannot because of some errors made by the developer.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
*
|
||||
* @return mixed|Boolean A PHP callable representing the Controller,
|
||||
* or false if this resolver is not able to determine the controller
|
||||
*
|
||||
* @throws \InvalidArgumentException|\LogicException If the controller can't be found
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getController(Request $request);
|
||||
|
||||
/**
|
||||
* Returns the arguments to pass to the controller.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param mixed $controller A PHP callable
|
||||
*
|
||||
* @return array An array of arguments to pass to the controller
|
||||
*
|
||||
* @throws \RuntimeException When value for argument given is not provided
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getArguments(Request $request, $controller);
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Controller;
|
||||
|
||||
use Symfony\Component\Stopwatch\Stopwatch;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* TraceableControllerResolver.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class TraceableControllerResolver implements ControllerResolverInterface
|
||||
{
|
||||
private $resolver;
|
||||
private $stopwatch;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param ControllerResolverInterface $resolver A ControllerResolverInterface instance
|
||||
* @param Stopwatch $stopwatch A Stopwatch instance
|
||||
*/
|
||||
public function __construct(ControllerResolverInterface $resolver, Stopwatch $stopwatch)
|
||||
{
|
||||
$this->resolver = $resolver;
|
||||
$this->stopwatch = $stopwatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getController(Request $request)
|
||||
{
|
||||
$e = $this->stopwatch->start('controller.get_callable');
|
||||
|
||||
$ret = $this->resolver->getController($request);
|
||||
|
||||
$e->stop();
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getArguments(Request $request, $controller)
|
||||
{
|
||||
$e = $this->stopwatch->start('controller.get_arguments');
|
||||
|
||||
$ret = $this->resolver->getArguments($request, $controller);
|
||||
|
||||
$e->stop();
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
246
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php
vendored
Normal file
246
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php
vendored
Normal file
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\DataCollector;
|
||||
|
||||
use Symfony\Component\HttpKernel\KernelInterface;
|
||||
use Symfony\Component\HttpKernel\Kernel;
|
||||
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* ConfigDataCollector.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class ConfigDataCollector extends DataCollector
|
||||
{
|
||||
private $kernel;
|
||||
private $name;
|
||||
private $version;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $name The name of the application using the web profiler
|
||||
* @param string $version The version of the application using the web profiler
|
||||
*/
|
||||
public function __construct($name = null, $version = null)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->version = $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Kernel associated with this Request.
|
||||
*
|
||||
* @param KernelInterface $kernel A KernelInterface instance
|
||||
*/
|
||||
public function setKernel(KernelInterface $kernel = null)
|
||||
{
|
||||
$this->kernel = $kernel;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Exception $exception = null)
|
||||
{
|
||||
$this->data = array(
|
||||
'app_name' => $this->name,
|
||||
'app_version' => $this->version,
|
||||
'token' => $response->headers->get('X-Debug-Token'),
|
||||
'symfony_version' => Kernel::VERSION,
|
||||
'name' => isset($this->kernel) ? $this->kernel->getName() : 'n/a',
|
||||
'env' => isset($this->kernel) ? $this->kernel->getEnvironment() : 'n/a',
|
||||
'debug' => isset($this->kernel) ? $this->kernel->isDebug() : 'n/a',
|
||||
'php_version' => PHP_VERSION,
|
||||
'xdebug_enabled' => extension_loaded('xdebug'),
|
||||
'eaccel_enabled' => extension_loaded('eaccelerator') && ini_get('eaccelerator.enable'),
|
||||
'apc_enabled' => extension_loaded('apc') && ini_get('apc.enabled'),
|
||||
'xcache_enabled' => extension_loaded('xcache') && ini_get('xcache.cacher'),
|
||||
'wincache_enabled' => extension_loaded('wincache') && ini_get('wincache.ocenabled'),
|
||||
'zend_opcache_enabled' => extension_loaded('Zend OPcache') && ini_get('opcache.enable'),
|
||||
'bundles' => array(),
|
||||
'sapi_name' => php_sapi_name()
|
||||
);
|
||||
|
||||
if (isset($this->kernel)) {
|
||||
foreach ($this->kernel->getBundles() as $name => $bundle) {
|
||||
$this->data['bundles'][$name] = $bundle->getPath();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getApplicationName()
|
||||
{
|
||||
return $this->data['app_name'];
|
||||
}
|
||||
|
||||
public function getApplicationVersion()
|
||||
{
|
||||
return $this->data['app_version'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the token.
|
||||
*
|
||||
* @return string The token
|
||||
*/
|
||||
public function getToken()
|
||||
{
|
||||
return $this->data['token'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Symfony version.
|
||||
*
|
||||
* @return string The Symfony version
|
||||
*/
|
||||
public function getSymfonyVersion()
|
||||
{
|
||||
return $this->data['symfony_version'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the PHP version.
|
||||
*
|
||||
* @return string The PHP version
|
||||
*/
|
||||
public function getPhpVersion()
|
||||
{
|
||||
return $this->data['php_version'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the application name.
|
||||
*
|
||||
* @return string The application name
|
||||
*/
|
||||
public function getAppName()
|
||||
{
|
||||
return $this->data['name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the environment.
|
||||
*
|
||||
* @return string The environment
|
||||
*/
|
||||
public function getEnv()
|
||||
{
|
||||
return $this->data['env'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the debug is enabled.
|
||||
*
|
||||
* @return Boolean true if debug is enabled, false otherwise
|
||||
*/
|
||||
public function isDebug()
|
||||
{
|
||||
return $this->data['debug'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the XDebug is enabled.
|
||||
*
|
||||
* @return Boolean true if XDebug is enabled, false otherwise
|
||||
*/
|
||||
public function hasXDebug()
|
||||
{
|
||||
return $this->data['xdebug_enabled'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if EAccelerator is enabled.
|
||||
*
|
||||
* @return Boolean true if EAccelerator is enabled, false otherwise
|
||||
*/
|
||||
public function hasEAccelerator()
|
||||
{
|
||||
return $this->data['eaccel_enabled'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if APC is enabled.
|
||||
*
|
||||
* @return Boolean true if APC is enabled, false otherwise
|
||||
*/
|
||||
public function hasApc()
|
||||
{
|
||||
return $this->data['apc_enabled'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if Zend OPcache is enabled
|
||||
*
|
||||
* @return Boolean true if Zend OPcache is enabled, false otherwise
|
||||
*/
|
||||
public function hasZendOpcache()
|
||||
{
|
||||
return $this->data['zend_opcache_enabled'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if XCache is enabled.
|
||||
*
|
||||
* @return Boolean true if XCache is enabled, false otherwise
|
||||
*/
|
||||
public function hasXCache()
|
||||
{
|
||||
return $this->data['xcache_enabled'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if WinCache is enabled.
|
||||
*
|
||||
* @return Boolean true if WinCache is enabled, false otherwise
|
||||
*/
|
||||
public function hasWinCache()
|
||||
{
|
||||
return $this->data['wincache_enabled'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if any accelerator is enabled.
|
||||
*
|
||||
* @return Boolean true if any accelerator is enabled, false otherwise
|
||||
*/
|
||||
public function hasAccelerator()
|
||||
{
|
||||
return $this->hasApc() || $this->hasZendOpcache() || $this->hasEAccelerator() || $this->hasXCache() || $this->hasWinCache();
|
||||
}
|
||||
|
||||
public function getBundles()
|
||||
{
|
||||
return $this->data['bundles'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the PHP SAPI name.
|
||||
*
|
||||
* @return string The environment
|
||||
*/
|
||||
public function getSapiName()
|
||||
{
|
||||
return $this->data['sapi_name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'config';
|
||||
}
|
||||
}
|
75
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/DataCollector.php
vendored
Normal file
75
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/DataCollector.php
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\DataCollector;
|
||||
|
||||
/**
|
||||
* DataCollector.
|
||||
*
|
||||
* Children of this class must store the collected data in the data property.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
abstract class DataCollector implements DataCollectorInterface, \Serializable
|
||||
{
|
||||
protected $data;
|
||||
|
||||
public function serialize()
|
||||
{
|
||||
return serialize($this->data);
|
||||
}
|
||||
|
||||
public function unserialize($data)
|
||||
{
|
||||
$this->data = unserialize($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a PHP variable to a string.
|
||||
*
|
||||
* @param mixed $var A PHP variable
|
||||
*
|
||||
* @return string The string representation of the variable
|
||||
*/
|
||||
protected function varToString($var)
|
||||
{
|
||||
if (is_object($var)) {
|
||||
return sprintf('Object(%s)', get_class($var));
|
||||
}
|
||||
|
||||
if (is_array($var)) {
|
||||
$a = array();
|
||||
foreach ($var as $k => $v) {
|
||||
$a[] = sprintf('%s => %s', $k, $this->varToString($v));
|
||||
}
|
||||
|
||||
return sprintf("Array(%s)", implode(', ', $a));
|
||||
}
|
||||
|
||||
if (is_resource($var)) {
|
||||
return sprintf('Resource(%s)', get_resource_type($var));
|
||||
}
|
||||
|
||||
if (null === $var) {
|
||||
return 'null';
|
||||
}
|
||||
|
||||
if (false === $var) {
|
||||
return 'false';
|
||||
}
|
||||
|
||||
if (true === $var) {
|
||||
return 'true';
|
||||
}
|
||||
|
||||
return (string) $var;
|
||||
}
|
||||
}
|
45
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/DataCollectorInterface.php
vendored
Normal file
45
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/DataCollectorInterface.php
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\DataCollector;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* DataCollectorInterface.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
interface DataCollectorInterface
|
||||
{
|
||||
/**
|
||||
* Collects data for the given Request and Response.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param Response $response A Response instance
|
||||
* @param \Exception $exception An Exception instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Exception $exception = null);
|
||||
|
||||
/**
|
||||
* Returns the name of the collector.
|
||||
*
|
||||
* @return string The collector name
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getName();
|
||||
}
|
91
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/EventDataCollector.php
vendored
Normal file
91
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/EventDataCollector.php
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\DataCollector;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcherInterface;
|
||||
|
||||
/**
|
||||
* EventDataCollector.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class EventDataCollector extends DataCollector
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Exception $exception = null)
|
||||
{
|
||||
$this->data = array(
|
||||
'called_listeners' => array(),
|
||||
'not_called_listeners' => array(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the called listeners.
|
||||
*
|
||||
* @param array $listeners An array of called listeners
|
||||
*
|
||||
* @see TraceableEventDispatcherInterface
|
||||
*/
|
||||
public function setCalledListeners(array $listeners)
|
||||
{
|
||||
$this->data['called_listeners'] = $listeners;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the called listeners.
|
||||
*
|
||||
* @return array An array of called listeners
|
||||
*
|
||||
* @see TraceableEventDispatcherInterface
|
||||
*/
|
||||
public function getCalledListeners()
|
||||
{
|
||||
return $this->data['called_listeners'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the not called listeners.
|
||||
*
|
||||
* @param array $listeners An array of not called listeners
|
||||
*
|
||||
* @see TraceableEventDispatcherInterface
|
||||
*/
|
||||
public function setNotCalledListeners(array $listeners)
|
||||
{
|
||||
$this->data['not_called_listeners'] = $listeners;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the not called listeners.
|
||||
*
|
||||
* @return array An array of not called listeners
|
||||
*
|
||||
* @see TraceableEventDispatcherInterface
|
||||
*/
|
||||
public function getNotCalledListeners()
|
||||
{
|
||||
return $this->data['not_called_listeners'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'events';
|
||||
}
|
||||
}
|
104
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/ExceptionDataCollector.php
vendored
Normal file
104
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/ExceptionDataCollector.php
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\DataCollector;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\FlattenException;
|
||||
|
||||
/**
|
||||
* ExceptionDataCollector.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class ExceptionDataCollector extends DataCollector
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Exception $exception = null)
|
||||
{
|
||||
if (null !== $exception) {
|
||||
$this->data = array(
|
||||
'exception' => FlattenException::create($exception),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the exception is not null.
|
||||
*
|
||||
* @return Boolean true if the exception is not null, false otherwise
|
||||
*/
|
||||
public function hasException()
|
||||
{
|
||||
return isset($this->data['exception']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the exception.
|
||||
*
|
||||
* @return \Exception The exception
|
||||
*/
|
||||
public function getException()
|
||||
{
|
||||
return $this->data['exception'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the exception message.
|
||||
*
|
||||
* @return string The exception message
|
||||
*/
|
||||
public function getMessage()
|
||||
{
|
||||
return $this->data['exception']->getMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the exception code.
|
||||
*
|
||||
* @return integer The exception code
|
||||
*/
|
||||
public function getCode()
|
||||
{
|
||||
return $this->data['exception']->getCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the status code.
|
||||
*
|
||||
* @return integer The status code
|
||||
*/
|
||||
public function getStatusCode()
|
||||
{
|
||||
return $this->data['exception']->getStatusCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the exception trace.
|
||||
*
|
||||
* @return array The exception trace
|
||||
*/
|
||||
public function getTrace()
|
||||
{
|
||||
return $this->data['exception']->getTrace();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'exception';
|
||||
}
|
||||
}
|
125
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php
vendored
Normal file
125
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\DataCollector;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Debug\ErrorHandler;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
|
||||
|
||||
/**
|
||||
* LogDataCollector.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class LoggerDataCollector extends DataCollector
|
||||
{
|
||||
private $logger;
|
||||
|
||||
public function __construct($logger = null)
|
||||
{
|
||||
if (null !== $logger && $logger instanceof DebugLoggerInterface) {
|
||||
$this->logger = $logger;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Exception $exception = null)
|
||||
{
|
||||
if (null !== $this->logger) {
|
||||
$this->data = array(
|
||||
'error_count' => $this->logger->countErrors(),
|
||||
'logs' => $this->sanitizeLogs($this->logger->getLogs()),
|
||||
'deprecation_count' => $this->computeDeprecationCount()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the called events.
|
||||
*
|
||||
* @return array An array of called events
|
||||
*
|
||||
* @see TraceableEventDispatcherInterface
|
||||
*/
|
||||
public function countErrors()
|
||||
{
|
||||
return isset($this->data['error_count']) ? $this->data['error_count'] : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the logs.
|
||||
*
|
||||
* @return array An array of logs
|
||||
*/
|
||||
public function getLogs()
|
||||
{
|
||||
return isset($this->data['logs']) ? $this->data['logs'] : array();
|
||||
}
|
||||
|
||||
public function countDeprecations()
|
||||
{
|
||||
return isset($this->data['deprecation_count']) ? $this->data['deprecation_count'] : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'logger';
|
||||
}
|
||||
|
||||
private function sanitizeLogs($logs)
|
||||
{
|
||||
foreach ($logs as $i => $log) {
|
||||
$logs[$i]['context'] = $this->sanitizeContext($log['context']);
|
||||
}
|
||||
|
||||
return $logs;
|
||||
}
|
||||
|
||||
private function sanitizeContext($context)
|
||||
{
|
||||
if (is_array($context)) {
|
||||
foreach ($context as $key => $value) {
|
||||
$context[$key] = $this->sanitizeContext($value);
|
||||
}
|
||||
|
||||
return $context;
|
||||
}
|
||||
|
||||
if (is_resource($context)) {
|
||||
return sprintf('Resource(%s)', get_resource_type($context));
|
||||
}
|
||||
|
||||
if (is_object($context)) {
|
||||
return sprintf('Object(%s)', get_class($context));
|
||||
}
|
||||
|
||||
return $context;
|
||||
}
|
||||
|
||||
private function computeDeprecationCount()
|
||||
{
|
||||
$count = 0;
|
||||
foreach ($this->logger->getLogs() as $log) {
|
||||
if (isset($log['context']['type']) && ErrorHandler::TYPE_DEPRECATION === $log['context']['type']) {
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
}
|
91
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/MemoryDataCollector.php
vendored
Normal file
91
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/MemoryDataCollector.php
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\DataCollector;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* MemoryDataCollector.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class MemoryDataCollector extends DataCollector
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->data = array(
|
||||
'memory' => 0,
|
||||
'memory_limit' => $this->convertToBytes(strtolower(ini_get('memory_limit'))),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Exception $exception = null)
|
||||
{
|
||||
$this->updateMemoryUsage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the memory.
|
||||
*
|
||||
* @return integer The memory
|
||||
*/
|
||||
public function getMemory()
|
||||
{
|
||||
return $this->data['memory'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the PHP memory limit.
|
||||
*
|
||||
* @return integer The memory limit
|
||||
*/
|
||||
public function getMemoryLimit()
|
||||
{
|
||||
return $this->data['memory_limit'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the memory usage data.
|
||||
*/
|
||||
public function updateMemoryUsage()
|
||||
{
|
||||
$this->data['memory'] = memory_get_peak_usage(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'memory';
|
||||
}
|
||||
|
||||
private function convertToBytes($memoryLimit)
|
||||
{
|
||||
if ('-1' === $memoryLimit) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (preg_match('#^\+?(0x?)?(.*?)([kmg]?)$#', $memoryLimit, $match)) {
|
||||
$shifts = array('' => 0, 'k' => 10, 'm' => 20, 'g' => 30);
|
||||
$bases = array('' => 10, '0' => 8, '0x' => 16);
|
||||
|
||||
return intval($match[2], $bases[$match[1]]) << $shifts[$match[3]];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
326
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php
vendored
Normal file
326
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php
vendored
Normal file
@@ -0,0 +1,326 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\DataCollector;
|
||||
|
||||
use Symfony\Component\HttpFoundation\ParameterBag;
|
||||
use Symfony\Component\HttpFoundation\HeaderBag;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* RequestDataCollector.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class RequestDataCollector extends DataCollector implements EventSubscriberInterface
|
||||
{
|
||||
protected $controllers;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->controllers = new \SplObjectStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Exception $exception = null)
|
||||
{
|
||||
$responseHeaders = $response->headers->all();
|
||||
$cookies = array();
|
||||
foreach ($response->headers->getCookies() as $cookie) {
|
||||
$cookies[] = $this->getCookieHeader($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly());
|
||||
}
|
||||
if (count($cookies) > 0) {
|
||||
$responseHeaders['Set-Cookie'] = $cookies;
|
||||
}
|
||||
|
||||
$attributes = array();
|
||||
foreach ($request->attributes->all() as $key => $value) {
|
||||
if ('_route' == $key && is_object($value)) {
|
||||
$attributes['_route'] = $this->varToString($value->getPath());
|
||||
} elseif ('_route_params' == $key) {
|
||||
foreach ($value as $key => $v) {
|
||||
$attributes['_route_params'][$key] = $this->varToString($v);
|
||||
}
|
||||
} else {
|
||||
$attributes[$key] = $this->varToString($value);
|
||||
}
|
||||
}
|
||||
|
||||
$content = null;
|
||||
try {
|
||||
$content = $request->getContent();
|
||||
} catch (\LogicException $e) {
|
||||
// the user already got the request content as a resource
|
||||
$content = false;
|
||||
}
|
||||
|
||||
$sessionMetadata = array();
|
||||
$sessionAttributes = array();
|
||||
$flashes = array();
|
||||
if ($request->hasSession()) {
|
||||
$session = $request->getSession();
|
||||
if ($session->isStarted()) {
|
||||
$sessionMetadata['Created'] = date(DATE_RFC822, $session->getMetadataBag()->getCreated());
|
||||
$sessionMetadata['Last used'] = date(DATE_RFC822, $session->getMetadataBag()->getLastUsed());
|
||||
$sessionMetadata['Lifetime'] = $session->getMetadataBag()->getLifetime();
|
||||
$sessionAttributes = $session->all();
|
||||
$flashes = $session->getFlashBag()->peekAll();
|
||||
}
|
||||
}
|
||||
|
||||
$statusCode = $response->getStatusCode();
|
||||
|
||||
$this->data = array(
|
||||
'format' => $request->getRequestFormat(),
|
||||
'content' => $content,
|
||||
'content_type' => $response->headers->get('Content-Type') ? $response->headers->get('Content-Type') : 'text/html',
|
||||
'status_text' => isset(Response::$statusTexts[$statusCode]) ? Response::$statusTexts[$statusCode] : '',
|
||||
'status_code' => $statusCode,
|
||||
'request_query' => $request->query->all(),
|
||||
'request_request' => $request->request->all(),
|
||||
'request_headers' => $request->headers->all(),
|
||||
'request_server' => $request->server->all(),
|
||||
'request_cookies' => $request->cookies->all(),
|
||||
'request_attributes' => $attributes,
|
||||
'response_headers' => $responseHeaders,
|
||||
'session_metadata' => $sessionMetadata,
|
||||
'session_attributes' => $sessionAttributes,
|
||||
'flashes' => $flashes,
|
||||
'path_info' => $request->getPathInfo(),
|
||||
'controller' => 'n/a',
|
||||
'locale' => $request->getLocale(),
|
||||
);
|
||||
|
||||
if (isset($this->data['request_headers']['php-auth-pw'])) {
|
||||
$this->data['request_headers']['php-auth-pw'] = '******';
|
||||
}
|
||||
|
||||
if (isset($this->data['request_server']['PHP_AUTH_PW'])) {
|
||||
$this->data['request_server']['PHP_AUTH_PW'] = '******';
|
||||
}
|
||||
|
||||
if (isset($this->controllers[$request])) {
|
||||
$controller = $this->controllers[$request];
|
||||
if (is_array($controller)) {
|
||||
try {
|
||||
$r = new \ReflectionMethod($controller[0], $controller[1]);
|
||||
$this->data['controller'] = array(
|
||||
'class' => is_object($controller[0]) ? get_class($controller[0]) : $controller[0],
|
||||
'method' => $controller[1],
|
||||
'file' => $r->getFilename(),
|
||||
'line' => $r->getStartLine(),
|
||||
);
|
||||
} catch (\ReflectionException $re) {
|
||||
if (is_callable($controller)) {
|
||||
// using __call or __callStatic
|
||||
$this->data['controller'] = array(
|
||||
'class' => is_object($controller[0]) ? get_class($controller[0]) : $controller[0],
|
||||
'method' => $controller[1],
|
||||
'file' => 'n/a',
|
||||
'line' => 'n/a',
|
||||
);
|
||||
}
|
||||
}
|
||||
} elseif ($controller instanceof \Closure) {
|
||||
$r = new \ReflectionFunction($controller);
|
||||
$this->data['controller'] = array(
|
||||
'class' => $r->getName(),
|
||||
'method' => null,
|
||||
'file' => $r->getFilename(),
|
||||
'line' => $r->getStartLine(),
|
||||
);
|
||||
} else {
|
||||
$this->data['controller'] = (string) $controller ?: 'n/a';
|
||||
}
|
||||
unset($this->controllers[$request]);
|
||||
}
|
||||
}
|
||||
|
||||
public function getPathInfo()
|
||||
{
|
||||
return $this->data['path_info'];
|
||||
}
|
||||
|
||||
public function getRequestRequest()
|
||||
{
|
||||
return new ParameterBag($this->data['request_request']);
|
||||
}
|
||||
|
||||
public function getRequestQuery()
|
||||
{
|
||||
return new ParameterBag($this->data['request_query']);
|
||||
}
|
||||
|
||||
public function getRequestHeaders()
|
||||
{
|
||||
return new HeaderBag($this->data['request_headers']);
|
||||
}
|
||||
|
||||
public function getRequestServer()
|
||||
{
|
||||
return new ParameterBag($this->data['request_server']);
|
||||
}
|
||||
|
||||
public function getRequestCookies()
|
||||
{
|
||||
return new ParameterBag($this->data['request_cookies']);
|
||||
}
|
||||
|
||||
public function getRequestAttributes()
|
||||
{
|
||||
return new ParameterBag($this->data['request_attributes']);
|
||||
}
|
||||
|
||||
public function getResponseHeaders()
|
||||
{
|
||||
return new ResponseHeaderBag($this->data['response_headers']);
|
||||
}
|
||||
|
||||
public function getSessionMetadata()
|
||||
{
|
||||
return $this->data['session_metadata'];
|
||||
}
|
||||
|
||||
public function getSessionAttributes()
|
||||
{
|
||||
return $this->data['session_attributes'];
|
||||
}
|
||||
|
||||
public function getFlashes()
|
||||
{
|
||||
return $this->data['flashes'];
|
||||
}
|
||||
|
||||
public function getContent()
|
||||
{
|
||||
return $this->data['content'];
|
||||
}
|
||||
|
||||
public function getContentType()
|
||||
{
|
||||
return $this->data['content_type'];
|
||||
}
|
||||
|
||||
public function getStatusText()
|
||||
{
|
||||
return $this->data['status_text'];
|
||||
}
|
||||
|
||||
public function getStatusCode()
|
||||
{
|
||||
return $this->data['status_code'];
|
||||
}
|
||||
|
||||
public function getFormat()
|
||||
{
|
||||
return $this->data['format'];
|
||||
}
|
||||
|
||||
public function getLocale()
|
||||
{
|
||||
return $this->data['locale'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the route name.
|
||||
*
|
||||
* The _route request attributes is automatically set by the Router Matcher.
|
||||
*
|
||||
* @return string The route
|
||||
*/
|
||||
public function getRoute()
|
||||
{
|
||||
return isset($this->data['request_attributes']['_route']) ? $this->data['request_attributes']['_route'] : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the route parameters.
|
||||
*
|
||||
* The _route_params request attributes is automatically set by the RouterListener.
|
||||
*
|
||||
* @return array The parameters
|
||||
*/
|
||||
public function getRouteParams()
|
||||
{
|
||||
return isset($this->data['request_attributes']['_route_params']) ? $this->data['request_attributes']['_route_params'] : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the controller.
|
||||
*
|
||||
* @return string The controller as a string
|
||||
*/
|
||||
public function getController()
|
||||
{
|
||||
return $this->data['controller'];
|
||||
}
|
||||
|
||||
public function onKernelController(FilterControllerEvent $event)
|
||||
{
|
||||
$this->controllers[$event->getRequest()] = $event->getController();
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(KernelEvents::CONTROLLER => 'onKernelController');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'request';
|
||||
}
|
||||
|
||||
private function getCookieHeader($name, $value, $expires, $path, $domain, $secure, $httponly)
|
||||
{
|
||||
$cookie = sprintf('%s=%s', $name, urlencode($value));
|
||||
|
||||
if (0 !== $expires) {
|
||||
if (is_numeric($expires)) {
|
||||
$expires = (int) $expires;
|
||||
} elseif ($expires instanceof \DateTime) {
|
||||
$expires = $expires->getTimestamp();
|
||||
} else {
|
||||
$expires = strtotime($expires);
|
||||
if (false === $expires || -1 == $expires) {
|
||||
throw new \InvalidArgumentException(sprintf('The "expires" cookie parameter is not valid.', $expires));
|
||||
}
|
||||
}
|
||||
|
||||
$cookie .= '; expires='.substr(\DateTime::createFromFormat('U', $expires, new \DateTimeZone('UTC'))->format('D, d-M-Y H:i:s T'), 0, -5);
|
||||
}
|
||||
|
||||
if ($domain) {
|
||||
$cookie .= '; domain='.$domain;
|
||||
}
|
||||
|
||||
$cookie .= '; path='.$path;
|
||||
|
||||
if ($secure) {
|
||||
$cookie .= '; secure';
|
||||
}
|
||||
|
||||
if ($httponly) {
|
||||
$cookie .= '; httponly';
|
||||
}
|
||||
|
||||
return $cookie;
|
||||
}
|
||||
}
|
103
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/RouterDataCollector.php
vendored
Normal file
103
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/RouterDataCollector.php
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\DataCollector;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
|
||||
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
|
||||
|
||||
/**
|
||||
* RouterDataCollector.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class RouterDataCollector extends DataCollector
|
||||
{
|
||||
protected $controllers;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->controllers = new \SplObjectStorage();
|
||||
|
||||
$this->data = array(
|
||||
'redirect' => false,
|
||||
'url' => null,
|
||||
'route' => null,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Exception $exception = null)
|
||||
{
|
||||
if ($response instanceof RedirectResponse) {
|
||||
$this->data['redirect'] = true;
|
||||
$this->data['url'] = $response->getTargetUrl();
|
||||
|
||||
if ($this->controllers->contains($request)) {
|
||||
$this->data['route'] = $this->guessRoute($request, $this->controllers[$request]);
|
||||
}
|
||||
}
|
||||
|
||||
unset($this->controllers[$request]);
|
||||
}
|
||||
|
||||
protected function guessRoute(Request $request, $controller)
|
||||
{
|
||||
return 'n/a';
|
||||
}
|
||||
|
||||
/**
|
||||
* Remembers the controller associated to each request.
|
||||
*
|
||||
* @param FilterControllerEvent $event The filter controller event
|
||||
*/
|
||||
public function onKernelController(FilterControllerEvent $event)
|
||||
{
|
||||
$this->controllers[$event->getRequest()] = $event->getController();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Boolean Whether this request will result in a redirect
|
||||
*/
|
||||
public function getRedirect()
|
||||
{
|
||||
return $this->data['redirect'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null The target URL
|
||||
*/
|
||||
public function getTargetUrl()
|
||||
{
|
||||
return $this->data['url'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null The target route
|
||||
*/
|
||||
public function getTargetRoute()
|
||||
{
|
||||
return $this->data['route'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'router';
|
||||
}
|
||||
}
|
123
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/TimeDataCollector.php
vendored
Normal file
123
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DataCollector/TimeDataCollector.php
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\DataCollector;
|
||||
|
||||
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
|
||||
use Symfony\Component\HttpKernel\KernelInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* TimeDataCollector.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class TimeDataCollector extends DataCollector
|
||||
{
|
||||
protected $kernel;
|
||||
|
||||
public function __construct(KernelInterface $kernel = null)
|
||||
{
|
||||
$this->kernel = $kernel;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Exception $exception = null)
|
||||
{
|
||||
if (null !== $this->kernel) {
|
||||
$startTime = $this->kernel->getStartTime();
|
||||
} else {
|
||||
$startTime = $request->server->get('REQUEST_TIME_FLOAT', $request->server->get('REQUEST_TIME'));
|
||||
}
|
||||
|
||||
$this->data = array(
|
||||
'start_time' => $startTime * 1000,
|
||||
'events' => array(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the request events.
|
||||
*
|
||||
* @param array $events The request events
|
||||
*/
|
||||
public function setEvents(array $events)
|
||||
{
|
||||
foreach ($events as $event) {
|
||||
$event->ensureStopped();
|
||||
}
|
||||
|
||||
$this->data['events'] = $events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the request events.
|
||||
*
|
||||
* @return array The request events
|
||||
*/
|
||||
public function getEvents()
|
||||
{
|
||||
return $this->data['events'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the request elapsed time.
|
||||
*
|
||||
* @return float The elapsed time
|
||||
*/
|
||||
public function getDuration()
|
||||
{
|
||||
if (!isset($this->data['events']['__section__'])) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$lastEvent = $this->data['events']['__section__'];
|
||||
|
||||
return $lastEvent->getOrigin() + $lastEvent->getDuration() - $this->getStartTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the initialization time.
|
||||
*
|
||||
* This is the time spent until the beginning of the request handling.
|
||||
*
|
||||
* @return float The elapsed time
|
||||
*/
|
||||
public function getInitTime()
|
||||
{
|
||||
if (!isset($this->data['events']['__section__'])) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $this->data['events']['__section__']->getOrigin() - $this->getStartTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the request time.
|
||||
*
|
||||
* @return integer The time
|
||||
*/
|
||||
public function getStartTime()
|
||||
{
|
||||
return $this->data['start_time'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'time';
|
||||
}
|
||||
}
|
25
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/ErrorHandler.php
vendored
Normal file
25
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/ErrorHandler.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Debug;
|
||||
|
||||
use Symfony\Component\Debug\ErrorHandler as DebugErrorHandler;
|
||||
|
||||
/**
|
||||
* ErrorHandler.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @deprecated Deprecated in 2.3, to be removed in 3.0. Use the same class from the Debug component instead.
|
||||
*/
|
||||
class ErrorHandler extends DebugErrorHandler
|
||||
{
|
||||
}
|
25
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/ExceptionHandler.php
vendored
Normal file
25
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/ExceptionHandler.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Debug;
|
||||
|
||||
use Symfony\Component\Debug\ExceptionHandler as DebugExceptionHandler;
|
||||
|
||||
/**
|
||||
* ExceptionHandler converts an exception to a Response object.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @deprecated Deprecated in 2.3, to be removed in 3.0. Use the same class from the Debug component instead.
|
||||
*/
|
||||
class ExceptionHandler extends DebugExceptionHandler
|
||||
{
|
||||
}
|
469
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/TraceableEventDispatcher.php
vendored
Normal file
469
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Debug/TraceableEventDispatcher.php
vendored
Normal file
@@ -0,0 +1,469 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Debug;
|
||||
|
||||
use Symfony\Component\Stopwatch\Stopwatch;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\HttpKernel\Profiler\Profile;
|
||||
use Symfony\Component\HttpKernel\Profiler\Profiler;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\EventDispatcher\Event;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcherInterface;
|
||||
|
||||
/**
|
||||
* Collects some data about event listeners.
|
||||
*
|
||||
* This event dispatcher delegates the dispatching to another one.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class TraceableEventDispatcher implements EventDispatcherInterface, TraceableEventDispatcherInterface
|
||||
{
|
||||
private $logger;
|
||||
private $called;
|
||||
private $stopwatch;
|
||||
private $profiler;
|
||||
private $dispatcher;
|
||||
private $wrappedListeners;
|
||||
private $firstCalledEvent;
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
|
||||
* @param Stopwatch $stopwatch A Stopwatch instance
|
||||
* @param LoggerInterface $logger A LoggerInterface instance
|
||||
*/
|
||||
public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $stopwatch, LoggerInterface $logger = null)
|
||||
{
|
||||
$this->dispatcher = $dispatcher;
|
||||
$this->stopwatch = $stopwatch;
|
||||
$this->logger = $logger;
|
||||
$this->called = array();
|
||||
$this->wrappedListeners = array();
|
||||
$this->firstCalledEvent = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the profiler.
|
||||
*
|
||||
* @param Profiler|null $profiler A Profiler instance
|
||||
*/
|
||||
public function setProfiler(Profiler $profiler = null)
|
||||
{
|
||||
$this->profiler = $profiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function addListener($eventName, $listener, $priority = 0)
|
||||
{
|
||||
$this->dispatcher->addListener($eventName, $listener, $priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addSubscriber(EventSubscriberInterface $subscriber)
|
||||
{
|
||||
$this->dispatcher->addSubscriber($subscriber);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function removeListener($eventName, $listener)
|
||||
{
|
||||
return $this->dispatcher->removeListener($eventName, $listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function removeSubscriber(EventSubscriberInterface $subscriber)
|
||||
{
|
||||
return $this->dispatcher->removeSubscriber($subscriber);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getListeners($eventName = null)
|
||||
{
|
||||
return $this->dispatcher->getListeners($eventName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasListeners($eventName = null)
|
||||
{
|
||||
return $this->dispatcher->hasListeners($eventName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function dispatch($eventName, Event $event = null)
|
||||
{
|
||||
if (null === $event) {
|
||||
$event = new Event();
|
||||
}
|
||||
|
||||
$this->id = spl_object_hash($event);
|
||||
|
||||
$this->preDispatch($eventName, $event);
|
||||
|
||||
$e = $this->stopwatch->start($eventName, 'section');
|
||||
|
||||
$this->firstCalledEvent[$eventName] = $this->stopwatch->start($eventName.'.loading', 'event_listener_loading');
|
||||
|
||||
if (!$this->dispatcher->hasListeners($eventName)) {
|
||||
$this->firstCalledEvent[$eventName]->stop();
|
||||
}
|
||||
|
||||
$this->dispatcher->dispatch($eventName, $event);
|
||||
|
||||
// reset the id as another event might have been dispatched during the dispatching of this event
|
||||
$this->id = spl_object_hash($event);
|
||||
|
||||
unset($this->firstCalledEvent[$eventName]);
|
||||
|
||||
$e->stop();
|
||||
|
||||
$this->postDispatch($eventName, $event);
|
||||
|
||||
return $event;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getCalledListeners()
|
||||
{
|
||||
return $this->called;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getNotCalledListeners()
|
||||
{
|
||||
$notCalled = array();
|
||||
|
||||
foreach ($this->getListeners() as $name => $listeners) {
|
||||
foreach ($listeners as $listener) {
|
||||
$info = $this->getListenerInfo($listener, $name);
|
||||
if (!isset($this->called[$name.'.'.$info['pretty']])) {
|
||||
$notCalled[$name.'.'.$info['pretty']] = $info;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $notCalled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxies all method calls to the original event dispatcher.
|
||||
*
|
||||
* @param string $method The method name
|
||||
* @param array $arguments The method arguments
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($method, $arguments)
|
||||
{
|
||||
return call_user_func_array(array($this->dispatcher, $method), $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a private method and must not be used.
|
||||
*
|
||||
* This method is public because it is used in a closure.
|
||||
* Whenever Symfony will require PHP 5.4, this could be changed
|
||||
* to a proper private method.
|
||||
*/
|
||||
public function logSkippedListeners($eventName, Event $event, $listener)
|
||||
{
|
||||
if (null === $this->logger) {
|
||||
return;
|
||||
}
|
||||
|
||||
$info = $this->getListenerInfo($listener, $eventName);
|
||||
|
||||
$this->logger->debug(sprintf('Listener "%s" stopped propagation of the event "%s".', $info['pretty'], $eventName));
|
||||
|
||||
$skippedListeners = $this->getListeners($eventName);
|
||||
$skipped = false;
|
||||
|
||||
foreach ($skippedListeners as $skippedListener) {
|
||||
$skippedListener = $this->unwrapListener($skippedListener);
|
||||
|
||||
if ($skipped) {
|
||||
$info = $this->getListenerInfo($skippedListener, $eventName);
|
||||
$this->logger->debug(sprintf('Listener "%s" was not called for event "%s".', $info['pretty'], $eventName));
|
||||
}
|
||||
|
||||
if ($skippedListener === $listener) {
|
||||
$skipped = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a private method.
|
||||
*
|
||||
* This method is public because it is used in a closure.
|
||||
* Whenever Symfony will require PHP 5.4, this could be changed
|
||||
* to a proper private method.
|
||||
*/
|
||||
public function preListenerCall($eventName, $listener)
|
||||
{
|
||||
// is it the first called listener?
|
||||
if (isset($this->firstCalledEvent[$eventName])) {
|
||||
$this->firstCalledEvent[$eventName]->stop();
|
||||
|
||||
unset($this->firstCalledEvent[$eventName]);
|
||||
}
|
||||
|
||||
$info = $this->getListenerInfo($listener, $eventName);
|
||||
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug(sprintf('Notified event "%s" to listener "%s".', $eventName, $info['pretty']));
|
||||
}
|
||||
|
||||
$this->called[$eventName.'.'.$info['pretty']] = $info;
|
||||
|
||||
return $this->stopwatch->start(isset($info['class']) ? $info['class'] : $info['type'], 'event_listener');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about the listener
|
||||
*
|
||||
* @param object $listener The listener
|
||||
* @param string $eventName The event name
|
||||
*
|
||||
* @return array Informations about the listener
|
||||
*/
|
||||
private function getListenerInfo($listener, $eventName)
|
||||
{
|
||||
$listener = $this->unwrapListener($listener);
|
||||
|
||||
$info = array(
|
||||
'event' => $eventName,
|
||||
);
|
||||
if ($listener instanceof \Closure) {
|
||||
$info += array(
|
||||
'type' => 'Closure',
|
||||
'pretty' => 'closure'
|
||||
);
|
||||
} elseif (is_string($listener)) {
|
||||
try {
|
||||
$r = new \ReflectionFunction($listener);
|
||||
$file = $r->getFileName();
|
||||
$line = $r->getStartLine();
|
||||
} catch (\ReflectionException $e) {
|
||||
$file = null;
|
||||
$line = null;
|
||||
}
|
||||
$info += array(
|
||||
'type' => 'Function',
|
||||
'function' => $listener,
|
||||
'file' => $file,
|
||||
'line' => $line,
|
||||
'pretty' => $listener,
|
||||
);
|
||||
} elseif (is_array($listener) || (is_object($listener) && is_callable($listener))) {
|
||||
if (!is_array($listener)) {
|
||||
$listener = array($listener, '__invoke');
|
||||
}
|
||||
$class = is_object($listener[0]) ? get_class($listener[0]) : $listener[0];
|
||||
try {
|
||||
$r = new \ReflectionMethod($class, $listener[1]);
|
||||
$file = $r->getFileName();
|
||||
$line = $r->getStartLine();
|
||||
} catch (\ReflectionException $e) {
|
||||
$file = null;
|
||||
$line = null;
|
||||
}
|
||||
$info += array(
|
||||
'type' => 'Method',
|
||||
'class' => $class,
|
||||
'method' => $listener[1],
|
||||
'file' => $file,
|
||||
'line' => $line,
|
||||
'pretty' => $class.'::'.$listener[1],
|
||||
);
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the stopwatch data in the profile hierarchy.
|
||||
*
|
||||
* @param string $token Profile token
|
||||
* @param Boolean $updateChildren Whether to update the children altogether
|
||||
*/
|
||||
private function updateProfiles($token, $updateChildren)
|
||||
{
|
||||
if (!$this->profiler || !$profile = $this->profiler->loadProfile($token)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->saveInfoInProfile($profile, $updateChildren);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the profiles with the timing and events information and saves them.
|
||||
*
|
||||
* @param Profile $profile The root profile
|
||||
* @param Boolean $updateChildren Whether to update the children altogether
|
||||
*/
|
||||
private function saveInfoInProfile(Profile $profile, $updateChildren)
|
||||
{
|
||||
try {
|
||||
$collector = $profile->getCollector('memory');
|
||||
$collector->updateMemoryUsage();
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
}
|
||||
|
||||
try {
|
||||
$collector = $profile->getCollector('time');
|
||||
$collector->setEvents($this->stopwatch->getSectionEvents($profile->getToken()));
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
}
|
||||
|
||||
try {
|
||||
$collector = $profile->getCollector('events');
|
||||
$collector->setCalledListeners($this->getCalledListeners());
|
||||
$collector->setNotCalledListeners($this->getNotCalledListeners());
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
}
|
||||
|
||||
$this->profiler->saveProfile($profile);
|
||||
|
||||
if ($updateChildren) {
|
||||
foreach ($profile->getChildren() as $child) {
|
||||
$this->saveInfoInProfile($child, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function preDispatch($eventName, Event $event)
|
||||
{
|
||||
// wrap all listeners before they are called
|
||||
$this->wrappedListeners[$this->id] = new \SplObjectStorage();
|
||||
|
||||
$listeners = $this->dispatcher->getListeners($eventName);
|
||||
|
||||
foreach ($listeners as $listener) {
|
||||
$this->dispatcher->removeListener($eventName, $listener);
|
||||
$wrapped = $this->wrapListener($eventName, $listener);
|
||||
$this->wrappedListeners[$this->id][$wrapped] = $listener;
|
||||
$this->dispatcher->addListener($eventName, $wrapped);
|
||||
}
|
||||
|
||||
switch ($eventName) {
|
||||
case KernelEvents::REQUEST:
|
||||
$this->stopwatch->openSection();
|
||||
break;
|
||||
case KernelEvents::VIEW:
|
||||
case KernelEvents::RESPONSE:
|
||||
// stop only if a controller has been executed
|
||||
if ($this->stopwatch->isStarted('controller')) {
|
||||
$this->stopwatch->stop('controller');
|
||||
}
|
||||
break;
|
||||
case KernelEvents::TERMINATE:
|
||||
$token = $event->getResponse()->headers->get('X-Debug-Token');
|
||||
// There is a very special case when using builtin AppCache class as kernel wrapper, in the case
|
||||
// of an ESI request leading to a `stale` response [B] inside a `fresh` cached response [A].
|
||||
// In this case, `$token` contains the [B] debug token, but the open `stopwatch` section ID
|
||||
// is equal to the [A] debug token. Trying to reopen section with the [B] token throws an exception
|
||||
// which must be caught.
|
||||
try {
|
||||
$this->stopwatch->openSection($token);
|
||||
} catch (\LogicException $e) {}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function postDispatch($eventName, Event $event)
|
||||
{
|
||||
switch ($eventName) {
|
||||
case KernelEvents::CONTROLLER:
|
||||
$this->stopwatch->start('controller', 'section');
|
||||
break;
|
||||
case KernelEvents::RESPONSE:
|
||||
$token = $event->getResponse()->headers->get('X-Debug-Token');
|
||||
$this->stopwatch->stopSection($token);
|
||||
if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) {
|
||||
// The profiles can only be updated once they have been created
|
||||
// that is after the 'kernel.response' event of the main request
|
||||
$this->updateProfiles($token, true);
|
||||
}
|
||||
break;
|
||||
case KernelEvents::TERMINATE:
|
||||
$token = $event->getResponse()->headers->get('X-Debug-Token');
|
||||
// In the special case described in the `preDispatch` method above, the `$token` section
|
||||
// does not exist, then closing it throws an exception which must be caught.
|
||||
try {
|
||||
$this->stopwatch->stopSection($token);
|
||||
} catch (\LogicException $e) {}
|
||||
// The children profiles have been updated by the previous 'kernel.response'
|
||||
// event. Only the root profile need to be updated with the 'kernel.terminate'
|
||||
// timing informations.
|
||||
$this->updateProfiles($token, false);
|
||||
break;
|
||||
}
|
||||
|
||||
foreach ($this->wrappedListeners[$this->id] as $wrapped) {
|
||||
$this->dispatcher->removeListener($eventName, $wrapped);
|
||||
$this->dispatcher->addListener($eventName, $this->wrappedListeners[$this->id][$wrapped]);
|
||||
}
|
||||
|
||||
unset($this->wrappedListeners[$this->id]);
|
||||
}
|
||||
|
||||
private function wrapListener($eventName, $listener)
|
||||
{
|
||||
$self = $this;
|
||||
|
||||
return function (Event $event) use ($self, $eventName, $listener) {
|
||||
$e = $self->preListenerCall($eventName, $listener);
|
||||
|
||||
call_user_func($listener, $event);
|
||||
|
||||
$e->stop();
|
||||
|
||||
if ($event->isPropagationStopped()) {
|
||||
$self->logSkippedListeners($eventName, $event, $listener);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private function unwrapListener($listener)
|
||||
{
|
||||
// get the original listener
|
||||
if (is_object($listener) && isset($this->wrappedListeners[$this->id][$listener])) {
|
||||
return $this->wrappedListeners[$this->id][$listener];
|
||||
}
|
||||
|
||||
return $listener;
|
||||
}
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
|
||||
use Symfony\Component\HttpKernel\Kernel;
|
||||
|
||||
/**
|
||||
* Sets the classes to compile in the cache for the container.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class AddClassesToCachePass implements CompilerPassInterface
|
||||
{
|
||||
private $kernel;
|
||||
|
||||
public function __construct(Kernel $kernel)
|
||||
{
|
||||
$this->kernel = $kernel;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$classes = array();
|
||||
foreach ($container->getExtensions() as $extension) {
|
||||
if ($extension instanceof Extension) {
|
||||
$classes = array_merge($classes, $extension->getClassesToCompile());
|
||||
}
|
||||
}
|
||||
|
||||
$this->kernel->setClassCache(array_unique($container->getParameterBag()->resolveValue($classes)));
|
||||
}
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* This extension sub-class provides first-class integration with the
|
||||
* Config/Definition Component.
|
||||
*
|
||||
* You can use this as base class if you
|
||||
*
|
||||
* a) use the Config/Definition component for configuration
|
||||
* b) your configuration class is named "Configuration" and
|
||||
* c) the configuration class resides in the DependencyInjection sub-folder
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
abstract class ConfigurableExtension extends Extension
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
final public function load(array $configs, ContainerBuilder $container)
|
||||
{
|
||||
$this->loadInternal($this->processConfiguration($this->getConfiguration($configs, $container), $configs), $container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the passed container according to the merged configuration.
|
||||
*
|
||||
* @param array $mergedConfig
|
||||
* @param ContainerBuilder $container
|
||||
*/
|
||||
abstract protected function loadInternal(array $mergedConfig, ContainerBuilder $container);
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\DependencyInjection;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpKernel\HttpKernel;
|
||||
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Scope;
|
||||
|
||||
/**
|
||||
* Adds a managed request scope.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ContainerAwareHttpKernel extends HttpKernel
|
||||
{
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
|
||||
* @param ContainerInterface $container A ContainerInterface instance
|
||||
* @param ControllerResolverInterface $controllerResolver A ControllerResolverInterface instance
|
||||
*/
|
||||
public function __construct(EventDispatcherInterface $dispatcher, ContainerInterface $container, ControllerResolverInterface $controllerResolver)
|
||||
{
|
||||
parent::__construct($dispatcher, $controllerResolver);
|
||||
|
||||
$this->container = $container;
|
||||
|
||||
// the request scope might have been created before (see FrameworkBundle)
|
||||
if (!$container->hasScope('request')) {
|
||||
$container->addScope(new Scope('request'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
|
||||
{
|
||||
$request->headers->set('X-Php-Ob-Level', ob_get_level());
|
||||
|
||||
$this->container->enterScope('request');
|
||||
$this->container->set('request', $request, 'request');
|
||||
|
||||
try {
|
||||
$response = parent::handle($request, $type, $catch);
|
||||
} catch (\Exception $e) {
|
||||
$this->container->set('request', null, 'request');
|
||||
$this->container->leaveScope('request');
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$this->container->set('request', null, 'request');
|
||||
$this->container->leaveScope('request');
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
44
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DependencyInjection/Extension.php
vendored
Normal file
44
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/DependencyInjection/Extension.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Extension\Extension as BaseExtension;
|
||||
|
||||
/**
|
||||
* Allow adding classes to the class cache.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
abstract class Extension extends BaseExtension
|
||||
{
|
||||
private $classes = array();
|
||||
|
||||
/**
|
||||
* Gets the classes to cache.
|
||||
*
|
||||
* @return array An array of classes
|
||||
*/
|
||||
public function getClassesToCompile()
|
||||
{
|
||||
return $this->classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds classes to the class cache.
|
||||
*
|
||||
* @param array $classes An array of classes
|
||||
*/
|
||||
public function addClassesToCompile(array $classes)
|
||||
{
|
||||
$this->classes = array_merge($this->classes, $classes);
|
||||
}
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationPass as BaseMergeExtensionConfigurationPass;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* Ensures certain extensions are always loaded.
|
||||
*
|
||||
* @author Kris Wallsmith <kris@symfony.com>
|
||||
*/
|
||||
class MergeExtensionConfigurationPass extends BaseMergeExtensionConfigurationPass
|
||||
{
|
||||
private $extensions;
|
||||
|
||||
public function __construct(array $extensions)
|
||||
{
|
||||
$this->extensions = $extensions;
|
||||
}
|
||||
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
foreach ($this->extensions as $extension) {
|
||||
if (!count($container->getExtensionConfig($extension))) {
|
||||
$container->loadFromExtension($extension, array());
|
||||
}
|
||||
}
|
||||
|
||||
parent::process($container);
|
||||
}
|
||||
}
|
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
|
||||
/**
|
||||
* Compiler pass to register tagged services for an event dispatcher.
|
||||
*/
|
||||
class RegisterListenersPass implements CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $dispatcherService;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $listenerTag;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $subscriberTag;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $dispatcherService Service name of the event dispatcher in processed container
|
||||
* @param string $listenerTag Tag name used for listener
|
||||
* @param string $subscriberTag Tag name used for subscribers
|
||||
*/
|
||||
public function __construct($dispatcherService = 'event_dispatcher', $listenerTag = 'kernel.event_listener', $subscriberTag = 'kernel.event_subscriber')
|
||||
{
|
||||
$this->dispatcherService = $dispatcherService;
|
||||
$this->listenerTag = $listenerTag;
|
||||
$this->subscriberTag = $subscriberTag;
|
||||
}
|
||||
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition($this->dispatcherService)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$definition = $container->getDefinition($this->dispatcherService);
|
||||
|
||||
foreach ($container->findTaggedServiceIds($this->listenerTag) as $id => $events) {
|
||||
foreach ($events as $event) {
|
||||
$priority = isset($event['priority']) ? $event['priority'] : 0;
|
||||
|
||||
if (!isset($event['event'])) {
|
||||
throw new \InvalidArgumentException(sprintf('Service "%s" must define the "event" attribute on "kernel.event_listener" tags.', $id));
|
||||
}
|
||||
|
||||
if (!isset($event['method'])) {
|
||||
$event['method'] = 'on'.preg_replace_callback(array(
|
||||
'/(?<=\b)[a-z]/i',
|
||||
'/[^a-z0-9]/i',
|
||||
), function ($matches) { return strtoupper($matches[0]); }, $event['event']);
|
||||
$event['method'] = preg_replace('/[^a-z0-9]/i', '', $event['method']);
|
||||
}
|
||||
|
||||
$definition->addMethodCall('addListenerService', array($event['event'], array($id, $event['method']), $priority));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($container->findTaggedServiceIds($this->subscriberTag) as $id => $attributes) {
|
||||
// We must assume that the class value has been correctly filled, even if the service is created by a factory
|
||||
$class = $container->getDefinition($id)->getClass();
|
||||
|
||||
$refClass = new \ReflectionClass($class);
|
||||
$interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface';
|
||||
if (!$refClass->implementsInterface($interface)) {
|
||||
throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface));
|
||||
}
|
||||
|
||||
$definition->addMethodCall('addSubscriberService', array($id, $class));
|
||||
}
|
||||
}
|
||||
}
|
109
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Event/FilterControllerEvent.php
vendored
Normal file
109
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Event/FilterControllerEvent.php
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Event;
|
||||
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Allows filtering of a controller callable
|
||||
*
|
||||
* You can call getController() to retrieve the current controller. With
|
||||
* setController() you can set a new controller that is used in the processing
|
||||
* of the request.
|
||||
*
|
||||
* Controllers should be callables.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class FilterControllerEvent extends KernelEvent
|
||||
{
|
||||
/**
|
||||
* The current controller
|
||||
* @var callable
|
||||
*/
|
||||
private $controller;
|
||||
|
||||
public function __construct(HttpKernelInterface $kernel, $controller, Request $request, $requestType)
|
||||
{
|
||||
parent::__construct($kernel, $request, $requestType);
|
||||
|
||||
$this->setController($controller);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current controller
|
||||
*
|
||||
* @return callable
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getController()
|
||||
{
|
||||
return $this->controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new controller
|
||||
*
|
||||
* @param callable $controller
|
||||
*
|
||||
* @throws \LogicException
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setController($controller)
|
||||
{
|
||||
// controller must be a callable
|
||||
if (!is_callable($controller)) {
|
||||
throw new \LogicException(sprintf('The controller must be a callable (%s given).', $this->varToString($controller)));
|
||||
}
|
||||
|
||||
$this->controller = $controller;
|
||||
}
|
||||
|
||||
private function varToString($var)
|
||||
{
|
||||
if (is_object($var)) {
|
||||
return sprintf('Object(%s)', get_class($var));
|
||||
}
|
||||
|
||||
if (is_array($var)) {
|
||||
$a = array();
|
||||
foreach ($var as $k => $v) {
|
||||
$a[] = sprintf('%s => %s', $k, $this->varToString($v));
|
||||
}
|
||||
|
||||
return sprintf("Array(%s)", implode(', ', $a));
|
||||
}
|
||||
|
||||
if (is_resource($var)) {
|
||||
return sprintf('Resource(%s)', get_resource_type($var));
|
||||
}
|
||||
|
||||
if (null === $var) {
|
||||
return 'null';
|
||||
}
|
||||
|
||||
if (false === $var) {
|
||||
return 'false';
|
||||
}
|
||||
|
||||
if (true === $var) {
|
||||
return 'true';
|
||||
}
|
||||
|
||||
return (string) $var;
|
||||
}
|
||||
}
|
67
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Event/FilterResponseEvent.php
vendored
Normal file
67
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Event/FilterResponseEvent.php
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Event;
|
||||
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* Allows to filter a Response object
|
||||
*
|
||||
* You can call getResponse() to retrieve the current response. With
|
||||
* setResponse() you can set a new response that will be returned to the
|
||||
* browser.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class FilterResponseEvent extends KernelEvent
|
||||
{
|
||||
/**
|
||||
* The current response object
|
||||
* @var Response
|
||||
*/
|
||||
private $response;
|
||||
|
||||
public function __construct(HttpKernelInterface $kernel, Request $request, $requestType, Response $response)
|
||||
{
|
||||
parent::__construct($kernel, $request, $requestType);
|
||||
|
||||
$this->setResponse($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current response object
|
||||
*
|
||||
* @return Response
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new response object
|
||||
*
|
||||
* @param Response $response
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setResponse(Response $response)
|
||||
{
|
||||
$this->response = $response;
|
||||
}
|
||||
}
|
72
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Event/GetResponseEvent.php
vendored
Normal file
72
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Event/GetResponseEvent.php
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Event;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* Allows to create a response for a request
|
||||
*
|
||||
* Call setResponse() to set the response that will be returned for the
|
||||
* current request. The propagation of this event is stopped as soon as a
|
||||
* response is set.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class GetResponseEvent extends KernelEvent
|
||||
{
|
||||
/**
|
||||
* The response object
|
||||
* @var Response
|
||||
*/
|
||||
private $response;
|
||||
|
||||
/**
|
||||
* Returns the response object
|
||||
*
|
||||
* @return Response
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a response and stops event propagation
|
||||
*
|
||||
* @param Response $response
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setResponse(Response $response)
|
||||
{
|
||||
$this->response = $response;
|
||||
|
||||
$this->stopPropagation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a response was set
|
||||
*
|
||||
* @return Boolean Whether a response was set
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function hasResponse()
|
||||
{
|
||||
return null !== $this->response;
|
||||
}
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Event;
|
||||
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Allows to create a response for the return value of a controller
|
||||
*
|
||||
* Call setResponse() to set the response that will be returned for the
|
||||
* current request. The propagation of this event is stopped as soon as a
|
||||
* response is set.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class GetResponseForControllerResultEvent extends GetResponseEvent
|
||||
{
|
||||
/**
|
||||
* The return value of the controller
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
private $controllerResult;
|
||||
|
||||
public function __construct(HttpKernelInterface $kernel, Request $request, $requestType, $controllerResult)
|
||||
{
|
||||
parent::__construct($kernel, $request, $requestType);
|
||||
|
||||
$this->controllerResult = $controllerResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the return value of the controller.
|
||||
*
|
||||
* @return mixed The controller return value
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getControllerResult()
|
||||
{
|
||||
return $this->controllerResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the return value of the controller.
|
||||
*
|
||||
* @param mixed The controller return value
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setControllerResult($controllerResult)
|
||||
{
|
||||
$this->controllerResult = $controllerResult;
|
||||
}
|
||||
}
|
72
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Event/GetResponseForExceptionEvent.php
vendored
Normal file
72
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Event/GetResponseForExceptionEvent.php
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Event;
|
||||
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Allows to create a response for a thrown exception
|
||||
*
|
||||
* Call setResponse() to set the response that will be returned for the
|
||||
* current request. The propagation of this event is stopped as soon as a
|
||||
* response is set.
|
||||
*
|
||||
* You can also call setException() to replace the thrown exception. This
|
||||
* exception will be thrown if no response is set during processing of this
|
||||
* event.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class GetResponseForExceptionEvent extends GetResponseEvent
|
||||
{
|
||||
/**
|
||||
* The exception object
|
||||
* @var \Exception
|
||||
*/
|
||||
private $exception;
|
||||
|
||||
public function __construct(HttpKernelInterface $kernel, Request $request, $requestType, \Exception $e)
|
||||
{
|
||||
parent::__construct($kernel, $request, $requestType);
|
||||
|
||||
$this->setException($e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the thrown exception
|
||||
*
|
||||
* @return \Exception The thrown exception
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getException()
|
||||
{
|
||||
return $this->exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the thrown exception
|
||||
*
|
||||
* This exception will be thrown if no response is set in the event.
|
||||
*
|
||||
* @param \Exception $exception The thrown exception
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setException(\Exception $exception)
|
||||
{
|
||||
$this->exception = $exception;
|
||||
}
|
||||
}
|
89
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Event/KernelEvent.php
vendored
Normal file
89
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Event/KernelEvent.php
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Event;
|
||||
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\EventDispatcher\Event;
|
||||
|
||||
/**
|
||||
* Base class for events thrown in the HttpKernel component
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class KernelEvent extends Event
|
||||
{
|
||||
/**
|
||||
* The kernel in which this event was thrown
|
||||
* @var HttpKernelInterface
|
||||
*/
|
||||
private $kernel;
|
||||
|
||||
/**
|
||||
* The request the kernel is currently processing
|
||||
* @var Request
|
||||
*/
|
||||
private $request;
|
||||
|
||||
/**
|
||||
* The request type the kernel is currently processing. One of
|
||||
* HttpKernelInterface::MASTER_REQUEST and HttpKernelInterface::SUB_REQUEST
|
||||
* @var integer
|
||||
*/
|
||||
private $requestType;
|
||||
|
||||
public function __construct(HttpKernelInterface $kernel, Request $request, $requestType)
|
||||
{
|
||||
$this->kernel = $kernel;
|
||||
$this->request = $request;
|
||||
$this->requestType = $requestType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the kernel in which this event was thrown
|
||||
*
|
||||
* @return HttpKernelInterface
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getKernel()
|
||||
{
|
||||
return $this->kernel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request the kernel is currently processing
|
||||
*
|
||||
* @return Request
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
return $this->request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request type the kernel is currently processing
|
||||
*
|
||||
* @return integer One of HttpKernelInterface::MASTER_REQUEST and
|
||||
* HttpKernelInterface::SUB_REQUEST
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getRequestType()
|
||||
{
|
||||
return $this->requestType;
|
||||
}
|
||||
}
|
72
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Event/PostResponseEvent.php
vendored
Normal file
72
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Event/PostResponseEvent.php
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Event;
|
||||
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\EventDispatcher\Event;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* Allows to execute logic after a response was sent
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
class PostResponseEvent extends Event
|
||||
{
|
||||
/**
|
||||
* The kernel in which this event was thrown
|
||||
* @var HttpKernelInterface
|
||||
*/
|
||||
private $kernel;
|
||||
|
||||
private $request;
|
||||
|
||||
private $response;
|
||||
|
||||
public function __construct(HttpKernelInterface $kernel, Request $request, Response $response)
|
||||
{
|
||||
$this->kernel = $kernel;
|
||||
$this->request = $request;
|
||||
$this->response = $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the kernel in which this event was thrown.
|
||||
*
|
||||
* @return HttpKernelInterface
|
||||
*/
|
||||
public function getKernel()
|
||||
{
|
||||
return $this->kernel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request for which this event was thrown.
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
return $this->request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the response for which this event was thrown.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
}
|
48
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/ErrorsLoggerListener.php
vendored
Normal file
48
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/ErrorsLoggerListener.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\EventListener;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\HttpKernel\Debug\ErrorHandler;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
|
||||
/**
|
||||
* Injects the logger into the ErrorHandler, so that it can log various errors.
|
||||
*
|
||||
* @author Colin Frei <colin@colinfrei.com>
|
||||
* @author Konstantin Myakshin <koc-dp@yandex.ru>
|
||||
*/
|
||||
class ErrorsLoggerListener implements EventSubscriberInterface
|
||||
{
|
||||
private $channel;
|
||||
|
||||
private $logger;
|
||||
|
||||
public function __construct($channel, LoggerInterface $logger = null)
|
||||
{
|
||||
$this->channel = $channel;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function injectLogger()
|
||||
{
|
||||
if (null !== $this->logger) {
|
||||
ErrorHandler::setLogger($this->logger, $this->channel);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(KernelEvents::REQUEST => 'injectLogger');
|
||||
}
|
||||
}
|
59
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/EsiListener.php
vendored
Normal file
59
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/EsiListener.php
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\EventListener;
|
||||
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\HttpKernel\HttpCache\Esi;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* EsiListener adds a Surrogate-Control HTTP header when the Response needs to be parsed for ESI.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class EsiListener implements EventSubscriberInterface
|
||||
{
|
||||
private $esi;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Esi $esi An ESI instance
|
||||
*/
|
||||
public function __construct(Esi $esi = null)
|
||||
{
|
||||
$this->esi = $esi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the Response.
|
||||
*
|
||||
* @param FilterResponseEvent $event A FilterResponseEvent instance
|
||||
*/
|
||||
public function onKernelResponse(FilterResponseEvent $event)
|
||||
{
|
||||
if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType() || null === $this->esi) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->esi->addSurrogateControl($event->getResponse());
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
KernelEvents::RESPONSE => 'onKernelResponse',
|
||||
);
|
||||
}
|
||||
}
|
112
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php
vendored
Normal file
112
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\EventListener;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\FlattenException;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* ExceptionListener.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class ExceptionListener implements EventSubscriberInterface
|
||||
{
|
||||
protected $controller;
|
||||
protected $logger;
|
||||
|
||||
public function __construct($controller, LoggerInterface $logger = null)
|
||||
{
|
||||
$this->controller = $controller;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function onKernelException(GetResponseForExceptionEvent $event)
|
||||
{
|
||||
static $handling;
|
||||
|
||||
if (true === $handling) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$handling = true;
|
||||
|
||||
$exception = $event->getException();
|
||||
$request = $event->getRequest();
|
||||
|
||||
$this->logException($exception, sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', get_class($exception), $exception->getMessage(), $exception->getFile(), $exception->getLine()));
|
||||
|
||||
$attributes = array(
|
||||
'_controller' => $this->controller,
|
||||
'exception' => FlattenException::create($exception),
|
||||
'logger' => $this->logger instanceof DebugLoggerInterface ? $this->logger : null,
|
||||
// keep for BC -- as $format can be an argument of the controller callable
|
||||
// see src/Symfony/Bundle/TwigBundle/Controller/ExceptionController.php
|
||||
// @deprecated in 2.4, to be removed in 3.0
|
||||
'format' => $request->getRequestFormat(),
|
||||
);
|
||||
|
||||
$request = $request->duplicate(null, null, $attributes);
|
||||
$request->setMethod('GET');
|
||||
|
||||
try {
|
||||
$response = $event->getKernel()->handle($request, HttpKernelInterface::SUB_REQUEST, true);
|
||||
} catch (\Exception $e) {
|
||||
$this->logException($exception, sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $e->getMessage()), false);
|
||||
|
||||
// set handling to false otherwise it wont be able to handle further more
|
||||
$handling = false;
|
||||
|
||||
// re-throw the exception from within HttpKernel as this is a catch-all
|
||||
return;
|
||||
}
|
||||
|
||||
$event->setResponse($response);
|
||||
|
||||
$handling = false;
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
KernelEvents::EXCEPTION => array('onKernelException', -128),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs an exception.
|
||||
*
|
||||
* @param \Exception $exception The original \Exception instance
|
||||
* @param string $message The error message to log
|
||||
* @param Boolean $original False when the handling of the exception thrown another exception
|
||||
*/
|
||||
protected function logException(\Exception $exception, $message, $original = true)
|
||||
{
|
||||
$isCritical = !$exception instanceof HttpExceptionInterface || $exception->getStatusCode() >= 500;
|
||||
$context = array('exception' => $exception);
|
||||
if (null !== $this->logger) {
|
||||
if ($isCritical) {
|
||||
$this->logger->critical($message, $context);
|
||||
} else {
|
||||
$this->logger->error($message, $context);
|
||||
}
|
||||
} elseif (!$original || $isCritical) {
|
||||
error_log($message);
|
||||
}
|
||||
}
|
||||
}
|
107
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/FragmentListener.php
vendored
Normal file
107
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/FragmentListener.php
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\EventListener;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\IpUtils;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Symfony\Component\HttpKernel\UriSigner;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* Handles content fragments represented by special URIs.
|
||||
*
|
||||
* All URL paths starting with /_fragment are handled as
|
||||
* content fragments by this listener.
|
||||
*
|
||||
* If the request does not come from a trusted IP, it throws an
|
||||
* AccessDeniedHttpException exception.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class FragmentListener implements EventSubscriberInterface
|
||||
{
|
||||
private $signer;
|
||||
private $fragmentPath;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param UriSigner $signer A UriSigner instance
|
||||
* @param string $fragmentPath The path that triggers this listener
|
||||
*/
|
||||
public function __construct(UriSigner $signer, $fragmentPath = '/_fragment')
|
||||
{
|
||||
$this->signer = $signer;
|
||||
$this->fragmentPath = $fragmentPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes request attributes when the path is '/_fragment'.
|
||||
*
|
||||
* @param GetResponseEvent $event A GetResponseEvent instance
|
||||
*
|
||||
* @throws AccessDeniedHttpException if the request does not come from a trusted IP.
|
||||
*/
|
||||
public function onKernelRequest(GetResponseEvent $event)
|
||||
{
|
||||
$request = $event->getRequest();
|
||||
|
||||
if ($this->fragmentPath !== rawurldecode($request->getPathInfo())) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->validateRequest($request);
|
||||
|
||||
parse_str($request->query->get('_path', ''), $attributes);
|
||||
$request->attributes->add($attributes);
|
||||
$request->attributes->set('_route_params', array_replace($request->attributes->get('_route_params', array()), $attributes));
|
||||
$request->query->remove('_path');
|
||||
}
|
||||
|
||||
protected function validateRequest(Request $request)
|
||||
{
|
||||
// is the Request safe?
|
||||
if (!$request->isMethodSafe()) {
|
||||
throw new AccessDeniedHttpException();
|
||||
}
|
||||
|
||||
// does the Request come from a trusted IP?
|
||||
$trustedIps = array_merge($this->getLocalIpAddresses(), $request->getTrustedProxies());
|
||||
$remoteAddress = $request->server->get('REMOTE_ADDR');
|
||||
if (IpUtils::checkIp($remoteAddress, $trustedIps)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// is the Request signed?
|
||||
// we cannot use $request->getUri() here as we want to work with the original URI (no query string reordering)
|
||||
if ($this->signer->check($request->getSchemeAndHttpHost().$request->getBaseUrl().$request->getPathInfo().(null !== ($qs = $request->server->get('QUERY_STRING')) ? '?'.$qs : ''))) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new AccessDeniedHttpException();
|
||||
}
|
||||
|
||||
protected function getLocalIpAddresses()
|
||||
{
|
||||
return array('127.0.0.1', 'fe80::1', '::1');
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
KernelEvents::REQUEST => array(array('onKernelRequest', 48)),
|
||||
);
|
||||
}
|
||||
}
|
66
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/LocaleListener.php
vendored
Normal file
66
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/LocaleListener.php
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\EventListener;
|
||||
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\RequestContextAwareInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* Initializes the locale based on the current request.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class LocaleListener implements EventSubscriberInterface
|
||||
{
|
||||
private $router;
|
||||
private $defaultLocale;
|
||||
|
||||
public function __construct($defaultLocale = 'en', RequestContextAwareInterface $router = null)
|
||||
{
|
||||
$this->defaultLocale = $defaultLocale;
|
||||
$this->router = $router;
|
||||
}
|
||||
|
||||
public function setRequest(Request $request = null)
|
||||
{
|
||||
if (null === $request) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($locale = $request->attributes->get('_locale')) {
|
||||
$request->setLocale($locale);
|
||||
}
|
||||
|
||||
if (null !== $this->router) {
|
||||
$this->router->getContext()->setParameter('_locale', $request->getLocale());
|
||||
}
|
||||
}
|
||||
|
||||
public function onKernelRequest(GetResponseEvent $event)
|
||||
{
|
||||
$request = $event->getRequest();
|
||||
$request->setDefaultLocale($this->defaultLocale);
|
||||
|
||||
$this->setRequest($request);
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
// must be registered after the Router to have access to the _locale
|
||||
KernelEvents::REQUEST => array(array('onKernelRequest', 16)),
|
||||
);
|
||||
}
|
||||
}
|
166
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/ProfilerListener.php
vendored
Normal file
166
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/ProfilerListener.php
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\EventListener;
|
||||
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
|
||||
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\HttpKernel\Profiler\Profile;
|
||||
use Symfony\Component\HttpKernel\Profiler\Profiler;
|
||||
use Symfony\Component\HttpFoundation\RequestMatcherInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* ProfilerListener collects data for the current request by listening to the onKernelResponse event.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class ProfilerListener implements EventSubscriberInterface
|
||||
{
|
||||
protected $profiler;
|
||||
protected $matcher;
|
||||
protected $onlyException;
|
||||
protected $onlyMasterRequests;
|
||||
protected $exception;
|
||||
protected $children;
|
||||
protected $requests;
|
||||
protected $profiles;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Profiler $profiler A Profiler instance
|
||||
* @param RequestMatcherInterface $matcher A RequestMatcher instance
|
||||
* @param Boolean $onlyException true if the profiler only collects data when an exception occurs, false otherwise
|
||||
* @param Boolean $onlyMasterRequests true if the profiler only collects data when the request is a master request, false otherwise
|
||||
*/
|
||||
public function __construct(Profiler $profiler, RequestMatcherInterface $matcher = null, $onlyException = false, $onlyMasterRequests = false)
|
||||
{
|
||||
$this->profiler = $profiler;
|
||||
$this->matcher = $matcher;
|
||||
$this->onlyException = (Boolean) $onlyException;
|
||||
$this->onlyMasterRequests = (Boolean) $onlyMasterRequests;
|
||||
$this->children = new \SplObjectStorage();
|
||||
$this->profiles = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the onKernelException event.
|
||||
*
|
||||
* @param GetResponseForExceptionEvent $event A GetResponseForExceptionEvent instance
|
||||
*/
|
||||
public function onKernelException(GetResponseForExceptionEvent $event)
|
||||
{
|
||||
if ($this->onlyMasterRequests && HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->exception = $event->getException();
|
||||
}
|
||||
|
||||
public function onKernelRequest(GetResponseEvent $event)
|
||||
{
|
||||
$this->requests[] = $event->getRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the onKernelResponse event.
|
||||
*
|
||||
* @param FilterResponseEvent $event A FilterResponseEvent instance
|
||||
*/
|
||||
public function onKernelResponse(FilterResponseEvent $event)
|
||||
{
|
||||
$master = HttpKernelInterface::MASTER_REQUEST === $event->getRequestType();
|
||||
if ($this->onlyMasterRequests && !$master) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->onlyException && null === $this->exception) {
|
||||
return;
|
||||
}
|
||||
|
||||
$request = $event->getRequest();
|
||||
$exception = $this->exception;
|
||||
$this->exception = null;
|
||||
|
||||
if (null !== $this->matcher && !$this->matcher->matches($request)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$profile = $this->profiler->collect($request, $event->getResponse(), $exception)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->profiles[] = $profile;
|
||||
|
||||
if (null !== $exception) {
|
||||
foreach ($this->profiles as $profile) {
|
||||
$this->profiler->saveProfile($profile);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// keep the profile as the child of its parent
|
||||
if (!$master) {
|
||||
array_pop($this->requests);
|
||||
|
||||
$parent = end($this->requests);
|
||||
|
||||
// when simulating requests, we might not have the parent
|
||||
if ($parent) {
|
||||
$profiles = isset($this->children[$parent]) ? $this->children[$parent] : array();
|
||||
$profiles[] = $profile;
|
||||
$this->children[$parent] = $profiles;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->children[$request])) {
|
||||
foreach ($this->children[$request] as $child) {
|
||||
$profile->addChild($child);
|
||||
}
|
||||
$this->children[$request] = array();
|
||||
}
|
||||
|
||||
if ($master) {
|
||||
$this->saveProfiles($profile);
|
||||
|
||||
unset($this->children);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
// kernel.request must be registered as early as possible to not break
|
||||
// when an exception is thrown in any other kernel.request listener
|
||||
KernelEvents::REQUEST => array('onKernelRequest', 1024),
|
||||
KernelEvents::RESPONSE => array('onKernelResponse', -100),
|
||||
KernelEvents::EXCEPTION => 'onKernelException',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the profile hierarchy.
|
||||
*
|
||||
* @param Profile $profile The root profile
|
||||
*/
|
||||
private function saveProfiles(Profile $profile)
|
||||
{
|
||||
$this->profiler->saveProfile($profile);
|
||||
foreach ($profile->getChildren() as $profile) {
|
||||
$this->saveProfiles($profile);
|
||||
}
|
||||
}
|
||||
}
|
59
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/ResponseListener.php
vendored
Normal file
59
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/ResponseListener.php
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\EventListener;
|
||||
|
||||
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* ResponseListener fixes the Response headers based on the Request.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class ResponseListener implements EventSubscriberInterface
|
||||
{
|
||||
private $charset;
|
||||
|
||||
public function __construct($charset)
|
||||
{
|
||||
$this->charset = $charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the Response.
|
||||
*
|
||||
* @param FilterResponseEvent $event A FilterResponseEvent instance
|
||||
*/
|
||||
public function onKernelResponse(FilterResponseEvent $event)
|
||||
{
|
||||
if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$response = $event->getResponse();
|
||||
|
||||
if (null === $response->getCharset()) {
|
||||
$response->setCharset($this->charset);
|
||||
}
|
||||
|
||||
$response->prepare($event->getRequest());
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
KernelEvents::RESPONSE => 'onKernelResponse',
|
||||
);
|
||||
}
|
||||
}
|
140
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/RouterListener.php
vendored
Normal file
140
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/EventListener/RouterListener.php
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\EventListener;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
|
||||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||||
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
|
||||
use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
use Symfony\Component\Routing\RequestContextAwareInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Initializes the context from the request and sets request attributes based on a matching route.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class RouterListener implements EventSubscriberInterface
|
||||
{
|
||||
private $matcher;
|
||||
private $context;
|
||||
private $logger;
|
||||
private $request;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param UrlMatcherInterface|RequestMatcherInterface $matcher The Url or Request matcher
|
||||
* @param RequestContext|null $context The RequestContext (can be null when $matcher implements RequestContextAwareInterface)
|
||||
* @param LoggerInterface|null $logger The logger
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct($matcher, RequestContext $context = null, LoggerInterface $logger = null)
|
||||
{
|
||||
if (!$matcher instanceof UrlMatcherInterface && !$matcher instanceof RequestMatcherInterface) {
|
||||
throw new \InvalidArgumentException('Matcher must either implement UrlMatcherInterface or RequestMatcherInterface.');
|
||||
}
|
||||
|
||||
if (null === $context && !$matcher instanceof RequestContextAwareInterface) {
|
||||
throw new \InvalidArgumentException('You must either pass a RequestContext or the matcher must implement RequestContextAwareInterface.');
|
||||
}
|
||||
|
||||
$this->matcher = $matcher;
|
||||
$this->context = $context ?: $matcher->getContext();
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current Request.
|
||||
*
|
||||
* The application should call this method whenever the Request
|
||||
* object changes (entering a Request scope for instance, but
|
||||
* also when leaving a Request scope -- especially when they are
|
||||
* nested).
|
||||
*
|
||||
* @param Request|null $request A Request instance
|
||||
*/
|
||||
public function setRequest(Request $request = null)
|
||||
{
|
||||
if (null !== $request && $this->request !== $request) {
|
||||
$this->context->fromRequest($request);
|
||||
}
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
public function onKernelRequest(GetResponseEvent $event)
|
||||
{
|
||||
$request = $event->getRequest();
|
||||
|
||||
// initialize the context that is also used by the generator (assuming matcher and generator share the same context instance)
|
||||
// we call setRequest even if most of the time, it has already been done to keep compatibility
|
||||
// with frameworks which do not use the Symfony service container
|
||||
$this->setRequest($request);
|
||||
|
||||
if ($request->attributes->has('_controller')) {
|
||||
// routing is already done
|
||||
return;
|
||||
}
|
||||
|
||||
// add attributes based on the request (routing)
|
||||
try {
|
||||
// matching a request is more powerful than matching a URL path + context, so try that first
|
||||
if ($this->matcher instanceof RequestMatcherInterface) {
|
||||
$parameters = $this->matcher->matchRequest($request);
|
||||
} else {
|
||||
$parameters = $this->matcher->match($request->getPathInfo());
|
||||
}
|
||||
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->info(sprintf('Matched route "%s" (parameters: %s)', $parameters['_route'], $this->parametersToString($parameters)));
|
||||
}
|
||||
|
||||
$request->attributes->add($parameters);
|
||||
unset($parameters['_route']);
|
||||
unset($parameters['_controller']);
|
||||
$request->attributes->set('_route_params', $parameters);
|
||||
} catch (ResourceNotFoundException $e) {
|
||||
$message = sprintf('No route found for "%s %s"', $request->getMethod(), $request->getPathInfo());
|
||||
|
||||
throw new NotFoundHttpException($message, $e);
|
||||
} catch (MethodNotAllowedException $e) {
|
||||
$message = sprintf('No route found for "%s %s": Method Not Allowed (Allow: %s)', $request->getMethod(), $request->getPathInfo(), strtoupper(implode(', ', $e->getAllowedMethods())));
|
||||
|
||||
throw new MethodNotAllowedHttpException($e->getAllowedMethods(), $message, $e);
|
||||
}
|
||||
}
|
||||
|
||||
private function parametersToString(array $parameters)
|
||||
{
|
||||
$pieces = array();
|
||||
foreach ($parameters as $key => $val) {
|
||||
$pieces[] = sprintf('"%s": "%s"', $key, (is_string($val) ? $val : json_encode($val)));
|
||||
}
|
||||
|
||||
return implode(', ', $pieces);
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
KernelEvents::REQUEST => array(array('onKernelRequest', 32)),
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\EventListener;
|
||||
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* StreamedResponseListener is responsible for sending the Response
|
||||
* to the client.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class StreamedResponseListener implements EventSubscriberInterface
|
||||
{
|
||||
/**
|
||||
* Filters the Response.
|
||||
*
|
||||
* @param FilterResponseEvent $event A FilterResponseEvent instance
|
||||
*/
|
||||
public function onKernelResponse(FilterResponseEvent $event)
|
||||
{
|
||||
if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$response = $event->getResponse();
|
||||
|
||||
if ($response instanceof StreamedResponse) {
|
||||
$response->send();
|
||||
}
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
KernelEvents::RESPONSE => array('onKernelResponse', -1024),
|
||||
);
|
||||
}
|
||||
}
|
33
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/AccessDeniedHttpException.php
vendored
Normal file
33
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/AccessDeniedHttpException.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Exception;
|
||||
|
||||
/**
|
||||
* AccessDeniedHttpException.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
*/
|
||||
class AccessDeniedHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $message The internal exception message
|
||||
* @param \Exception $previous The previous exception
|
||||
* @param integer $code The internal exception code
|
||||
*/
|
||||
public function __construct($message = null, \Exception $previous = null, $code = 0)
|
||||
{
|
||||
parent::__construct(403, $message, $previous, array(), $code);
|
||||
}
|
||||
}
|
32
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/BadRequestHttpException.php
vendored
Normal file
32
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/BadRequestHttpException.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Exception;
|
||||
|
||||
/**
|
||||
* BadRequestHttpException.
|
||||
*
|
||||
* @author Ben Ramsey <ben@benramsey.com>
|
||||
*/
|
||||
class BadRequestHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $message The internal exception message
|
||||
* @param \Exception $previous The previous exception
|
||||
* @param integer $code The internal exception code
|
||||
*/
|
||||
public function __construct($message = null, \Exception $previous = null, $code = 0)
|
||||
{
|
||||
parent::__construct(400, $message, $previous, array(), $code);
|
||||
}
|
||||
}
|
32
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/ConflictHttpException.php
vendored
Normal file
32
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/ConflictHttpException.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Exception;
|
||||
|
||||
/**
|
||||
* ConflictHttpException.
|
||||
*
|
||||
* @author Ben Ramsey <ben@benramsey.com>
|
||||
*/
|
||||
class ConflictHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $message The internal exception message
|
||||
* @param \Exception $previous The previous exception
|
||||
* @param integer $code The internal exception code
|
||||
*/
|
||||
public function __construct($message = null, \Exception $previous = null, $code = 0)
|
||||
{
|
||||
parent::__construct(409, $message, $previous, array(), $code);
|
||||
}
|
||||
}
|
25
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/FatalErrorException.php
vendored
Normal file
25
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/FatalErrorException.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Exception;
|
||||
|
||||
use Symfony\Component\Debug\Exception\FatalErrorException as DebugFatalErrorException;
|
||||
|
||||
/**
|
||||
* Fatal Error Exception.
|
||||
*
|
||||
* @author Konstanton Myakshin <koc-dp@yandex.ru>
|
||||
*
|
||||
* @deprecated Deprecated in 2.3, to be removed in 3.0. Use the same class from the Debug component instead.
|
||||
*/
|
||||
class FatalErrorException extends DebugFatalErrorException
|
||||
{
|
||||
}
|
27
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/FlattenException.php
vendored
Normal file
27
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/FlattenException.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Exception;
|
||||
|
||||
use Symfony\Component\Debug\Exception\FlattenException as DebugFlattenException;
|
||||
|
||||
/**
|
||||
* FlattenException wraps a PHP Exception to be able to serialize it.
|
||||
*
|
||||
* Basically, this class removes all objects from the trace.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @deprecated Deprecated in 2.3, to be removed in 3.0. Use the same class from the Debug component instead.
|
||||
*/
|
||||
class FlattenException extends DebugFlattenException
|
||||
{
|
||||
}
|
32
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/GoneHttpException.php
vendored
Normal file
32
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/GoneHttpException.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Exception;
|
||||
|
||||
/**
|
||||
* GoneHttpException.
|
||||
*
|
||||
* @author Ben Ramsey <ben@benramsey.com>
|
||||
*/
|
||||
class GoneHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $message The internal exception message
|
||||
* @param \Exception $previous The previous exception
|
||||
* @param integer $code The internal exception code
|
||||
*/
|
||||
public function __construct($message = null, \Exception $previous = null, $code = 0)
|
||||
{
|
||||
parent::__construct(410, $message, $previous, array(), $code);
|
||||
}
|
||||
}
|
41
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/HttpException.php
vendored
Normal file
41
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/HttpException.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Exception;
|
||||
|
||||
/**
|
||||
* HttpException.
|
||||
*
|
||||
* @author Kris Wallsmith <kris@symfony.com>
|
||||
*/
|
||||
class HttpException extends \RuntimeException implements HttpExceptionInterface
|
||||
{
|
||||
private $statusCode;
|
||||
private $headers;
|
||||
|
||||
public function __construct($statusCode, $message = null, \Exception $previous = null, array $headers = array(), $code = 0)
|
||||
{
|
||||
$this->statusCode = $statusCode;
|
||||
$this->headers = $headers;
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
|
||||
public function getStatusCode()
|
||||
{
|
||||
return $this->statusCode;
|
||||
}
|
||||
|
||||
public function getHeaders()
|
||||
{
|
||||
return $this->headers;
|
||||
}
|
||||
}
|
34
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/HttpExceptionInterface.php
vendored
Normal file
34
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/HttpExceptionInterface.php
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Exception;
|
||||
|
||||
/**
|
||||
* Interface for HTTP error exceptions.
|
||||
*
|
||||
* @author Kris Wallsmith <kris@symfony.com>
|
||||
*/
|
||||
interface HttpExceptionInterface
|
||||
{
|
||||
/**
|
||||
* Returns the status code.
|
||||
*
|
||||
* @return integer An HTTP response status code
|
||||
*/
|
||||
public function getStatusCode();
|
||||
|
||||
/**
|
||||
* Returns response headers.
|
||||
*
|
||||
* @return array Response headers
|
||||
*/
|
||||
public function getHeaders();
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Exception;
|
||||
|
||||
/**
|
||||
* LengthRequiredHttpException.
|
||||
*
|
||||
* @author Ben Ramsey <ben@benramsey.com>
|
||||
*/
|
||||
class LengthRequiredHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $message The internal exception message
|
||||
* @param \Exception $previous The previous exception
|
||||
* @param integer $code The internal exception code
|
||||
*/
|
||||
public function __construct($message = null, \Exception $previous = null, $code = 0)
|
||||
{
|
||||
parent::__construct(411, $message, $previous, array(), $code);
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Exception;
|
||||
|
||||
/**
|
||||
* MethodNotAllowedHttpException.
|
||||
*
|
||||
* @author Kris Wallsmith <kris@symfony.com>
|
||||
*/
|
||||
class MethodNotAllowedHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $allow An array of allowed methods
|
||||
* @param string $message The internal exception message
|
||||
* @param \Exception $previous The previous exception
|
||||
* @param integer $code The internal exception code
|
||||
*/
|
||||
public function __construct(array $allow, $message = null, \Exception $previous = null, $code = 0)
|
||||
{
|
||||
$headers = array('Allow' => strtoupper(implode(', ', $allow)));
|
||||
|
||||
parent::__construct(405, $message, $previous, $headers, $code);
|
||||
}
|
||||
}
|
32
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/NotAcceptableHttpException.php
vendored
Normal file
32
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/NotAcceptableHttpException.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Exception;
|
||||
|
||||
/**
|
||||
* NotAcceptableHttpException.
|
||||
*
|
||||
* @author Ben Ramsey <ben@benramsey.com>
|
||||
*/
|
||||
class NotAcceptableHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $message The internal exception message
|
||||
* @param \Exception $previous The previous exception
|
||||
* @param integer $code The internal exception code
|
||||
*/
|
||||
public function __construct($message = null, \Exception $previous = null, $code = 0)
|
||||
{
|
||||
parent::__construct(406, $message, $previous, array(), $code);
|
||||
}
|
||||
}
|
32
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/NotFoundHttpException.php
vendored
Normal file
32
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/NotFoundHttpException.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Exception;
|
||||
|
||||
/**
|
||||
* NotFoundHttpException.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class NotFoundHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $message The internal exception message
|
||||
* @param \Exception $previous The previous exception
|
||||
* @param integer $code The internal exception code
|
||||
*/
|
||||
public function __construct($message = null, \Exception $previous = null, $code = 0)
|
||||
{
|
||||
parent::__construct(404, $message, $previous, array(), $code);
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Exception;
|
||||
|
||||
/**
|
||||
* PreconditionFailedHttpException.
|
||||
*
|
||||
* @author Ben Ramsey <ben@benramsey.com>
|
||||
*/
|
||||
class PreconditionFailedHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $message The internal exception message
|
||||
* @param \Exception $previous The previous exception
|
||||
* @param integer $code The internal exception code
|
||||
*/
|
||||
public function __construct($message = null, \Exception $previous = null, $code = 0)
|
||||
{
|
||||
parent::__construct(412, $message, $previous, array(), $code);
|
||||
}
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Exception;
|
||||
|
||||
/**
|
||||
* PreconditionRequiredHttpException.
|
||||
*
|
||||
* @author Ben Ramsey <ben@benramsey.com>
|
||||
* @see http://tools.ietf.org/html/rfc6585
|
||||
*/
|
||||
class PreconditionRequiredHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $message The internal exception message
|
||||
* @param \Exception $previous The previous exception
|
||||
* @param integer $code The internal exception code
|
||||
*/
|
||||
public function __construct($message = null, \Exception $previous = null, $code = 0)
|
||||
{
|
||||
parent::__construct(428, $message, $previous, array(), $code);
|
||||
}
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Exception;
|
||||
|
||||
/**
|
||||
* ServiceUnavailableHttpException.
|
||||
*
|
||||
* @author Ben Ramsey <ben@benramsey.com>
|
||||
*/
|
||||
class ServiceUnavailableHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int|string $retryAfter The number of seconds or HTTP-date after which the request may be retried
|
||||
* @param string $message The internal exception message
|
||||
* @param \Exception $previous The previous exception
|
||||
* @param integer $code The internal exception code
|
||||
*/
|
||||
public function __construct($retryAfter = null, $message = null, \Exception $previous = null, $code = 0)
|
||||
{
|
||||
$headers = array();
|
||||
if ($retryAfter) {
|
||||
$headers = array('Retry-After' => $retryAfter);
|
||||
}
|
||||
|
||||
parent::__construct(503, $message, $previous, $headers, $code);
|
||||
}
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Exception;
|
||||
|
||||
/**
|
||||
* TooManyRequestsHttpException.
|
||||
*
|
||||
* @author Ben Ramsey <ben@benramsey.com>
|
||||
* @see http://tools.ietf.org/html/rfc6585
|
||||
*/
|
||||
class TooManyRequestsHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param integer|string $retryAfter The number of seconds or HTTP-date after which the request may be retried
|
||||
* @param string $message The internal exception message
|
||||
* @param \Exception $previous The previous exception
|
||||
* @param integer $code The internal exception code
|
||||
*/
|
||||
public function __construct($retryAfter = null, $message = null, \Exception $previous = null, $code = 0)
|
||||
{
|
||||
$headers = array();
|
||||
if ($retryAfter) {
|
||||
$headers = array('Retry-After' => $retryAfter);
|
||||
}
|
||||
|
||||
parent::__construct(429, $message, $previous, $headers, $code);
|
||||
}
|
||||
}
|
35
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/UnauthorizedHttpException.php
vendored
Normal file
35
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Exception/UnauthorizedHttpException.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Exception;
|
||||
|
||||
/**
|
||||
* UnauthorizedHttpException.
|
||||
*
|
||||
* @author Ben Ramsey <ben@benramsey.com>
|
||||
*/
|
||||
class UnauthorizedHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $challenge WWW-Authenticate challenge string
|
||||
* @param string $message The internal exception message
|
||||
* @param \Exception $previous The previous exception
|
||||
* @param integer $code The internal exception code
|
||||
*/
|
||||
public function __construct($challenge, $message = null, \Exception $previous = null, $code = 0)
|
||||
{
|
||||
$headers = array('WWW-Authenticate' => $challenge);
|
||||
|
||||
parent::__construct(401, $message, $previous, $headers, $code);
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Exception;
|
||||
|
||||
/**
|
||||
* UnsupportedMediaTypeHttpException.
|
||||
*
|
||||
* @author Ben Ramsey <ben@benramsey.com>
|
||||
*/
|
||||
class UnsupportedMediaTypeHttpException extends HttpException
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $message The internal exception message
|
||||
* @param \Exception $previous The previous exception
|
||||
* @param integer $code The internal exception code
|
||||
*/
|
||||
public function __construct($message = null, \Exception $previous = null, $code = 0)
|
||||
{
|
||||
parent::__construct(415, $message, $previous, array(), $code);
|
||||
}
|
||||
}
|
84
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Fragment/EsiFragmentRenderer.php
vendored
Normal file
84
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Fragment/EsiFragmentRenderer.php
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Fragment;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Controller\ControllerReference;
|
||||
use Symfony\Component\HttpKernel\HttpCache\Esi;
|
||||
|
||||
/**
|
||||
* Implements the ESI rendering strategy.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class EsiFragmentRenderer extends RoutableFragmentRenderer
|
||||
{
|
||||
private $esi;
|
||||
private $inlineStrategy;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* The "fallback" strategy when ESI is not available should always be an
|
||||
* instance of InlineFragmentRenderer.
|
||||
*
|
||||
* @param Esi $esi An Esi instance
|
||||
* @param InlineFragmentRenderer $inlineStrategy The inline strategy to use when ESI is not supported
|
||||
*/
|
||||
public function __construct(Esi $esi, InlineFragmentRenderer $inlineStrategy)
|
||||
{
|
||||
$this->esi = $esi;
|
||||
$this->inlineStrategy = $inlineStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Note that if the current Request has no ESI capability, this method
|
||||
* falls back to use the inline rendering strategy.
|
||||
*
|
||||
* Additional available options:
|
||||
*
|
||||
* * alt: an alternative URI to render in case of an error
|
||||
* * comment: a comment to add when returning an esi:include tag
|
||||
*
|
||||
* @see Symfony\Component\HttpKernel\HttpCache\ESI
|
||||
*/
|
||||
public function render($uri, Request $request, array $options = array())
|
||||
{
|
||||
if (!$this->esi->hasSurrogateEsiCapability($request)) {
|
||||
return $this->inlineStrategy->render($uri, $request, $options);
|
||||
}
|
||||
|
||||
if ($uri instanceof ControllerReference) {
|
||||
$uri = $this->generateFragmentUri($uri, $request);
|
||||
}
|
||||
|
||||
$alt = isset($options['alt']) ? $options['alt'] : null;
|
||||
if ($alt instanceof ControllerReference) {
|
||||
$alt = $this->generateFragmentUri($alt, $request);
|
||||
}
|
||||
|
||||
$tag = $this->esi->renderIncludeTag($uri, $alt, isset($options['ignore_errors']) ? $options['ignore_errors'] : false, isset($options['comment']) ? $options['comment'] : '');
|
||||
|
||||
return new Response($tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'esi';
|
||||
}
|
||||
}
|
127
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Fragment/FragmentHandler.php
vendored
Normal file
127
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Fragment/FragmentHandler.php
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Fragment;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use Symfony\Component\HttpKernel\Controller\ControllerReference;
|
||||
|
||||
/**
|
||||
* Renders a URI that represents a resource fragment.
|
||||
*
|
||||
* This class handles the rendering of resource fragments that are included into
|
||||
* a main resource. The handling of the rendering is managed by specialized renderers.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @see FragmentRendererInterface
|
||||
*/
|
||||
class FragmentHandler
|
||||
{
|
||||
private $debug;
|
||||
private $renderers;
|
||||
private $request;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param FragmentRendererInterface[] $renderers An array of FragmentRendererInterface instances
|
||||
* @param Boolean $debug Whether the debug mode is enabled or not
|
||||
*/
|
||||
public function __construct(array $renderers = array(), $debug = false)
|
||||
{
|
||||
$this->renderers = array();
|
||||
foreach ($renderers as $renderer) {
|
||||
$this->addRenderer($renderer);
|
||||
}
|
||||
$this->debug = $debug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a renderer.
|
||||
*
|
||||
* @param FragmentRendererInterface $renderer A FragmentRendererInterface instance
|
||||
*/
|
||||
public function addRenderer(FragmentRendererInterface $renderer)
|
||||
{
|
||||
$this->renderers[$renderer->getName()] = $renderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current Request.
|
||||
*
|
||||
* @param Request $request The current Request
|
||||
*/
|
||||
public function setRequest(Request $request = null)
|
||||
{
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a URI and returns the Response content.
|
||||
*
|
||||
* Available options:
|
||||
*
|
||||
* * ignore_errors: true to return an empty string in case of an error
|
||||
*
|
||||
* @param string|ControllerReference $uri A URI as a string or a ControllerReference instance
|
||||
* @param string $renderer The renderer name
|
||||
* @param array $options An array of options
|
||||
*
|
||||
* @return string|null The Response content or null when the Response is streamed
|
||||
*
|
||||
* @throws \InvalidArgumentException when the renderer does not exist
|
||||
* @throws \RuntimeException when the Response is not successful
|
||||
*/
|
||||
public function render($uri, $renderer = 'inline', array $options = array())
|
||||
{
|
||||
if (!isset($options['ignore_errors'])) {
|
||||
$options['ignore_errors'] = !$this->debug;
|
||||
}
|
||||
|
||||
if (!isset($this->renderers[$renderer])) {
|
||||
throw new \InvalidArgumentException(sprintf('The "%s" renderer does not exist.', $renderer));
|
||||
}
|
||||
|
||||
if (null === $this->request) {
|
||||
throw new \LogicException('Rendering a fragment can only be done when handling a master Request.');
|
||||
}
|
||||
|
||||
return $this->deliver($this->renderers[$renderer]->render($uri, $this->request, $options));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delivers the Response as a string.
|
||||
*
|
||||
* When the Response is a StreamedResponse, the content is streamed immediately
|
||||
* instead of being returned.
|
||||
*
|
||||
* @param Response $response A Response instance
|
||||
*
|
||||
* @return string|null The Response content or null when the Response is streamed
|
||||
*
|
||||
* @throws \RuntimeException when the Response is not successful
|
||||
*/
|
||||
protected function deliver(Response $response)
|
||||
{
|
||||
if (!$response->isSuccessful()) {
|
||||
throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $this->request->getUri(), $response->getStatusCode()));
|
||||
}
|
||||
|
||||
if (!$response instanceof StreamedResponse) {
|
||||
return $response->getContent();
|
||||
}
|
||||
|
||||
$response->sendContent();
|
||||
}
|
||||
}
|
43
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Fragment/FragmentRendererInterface.php
vendored
Normal file
43
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Fragment/FragmentRendererInterface.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Fragment;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Controller\ControllerReference;
|
||||
|
||||
/**
|
||||
* Interface implemented by all rendering strategies.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @see Symfony\Component\HttpKernel\FragmentRenderer
|
||||
*/
|
||||
interface FragmentRendererInterface
|
||||
{
|
||||
/**
|
||||
* Renders a URI and returns the Response content.
|
||||
*
|
||||
* @param string|ControllerReference $uri A URI as a string or a ControllerReference instance
|
||||
* @param Request $request A Request instance
|
||||
* @param array $options An array of options
|
||||
*
|
||||
* @return Response A Response instance
|
||||
*/
|
||||
public function render($uri, Request $request, array $options = array());
|
||||
|
||||
/**
|
||||
* Gets the name of the strategy.
|
||||
*
|
||||
* @return string The strategy name
|
||||
*/
|
||||
public function getName();
|
||||
}
|
162
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Fragment/HIncludeFragmentRenderer.php
vendored
Normal file
162
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Fragment/HIncludeFragmentRenderer.php
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Fragment;
|
||||
|
||||
if (!defined('ENT_SUBSTITUTE')) {
|
||||
define('ENT_SUBSTITUTE', 8);
|
||||
}
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Templating\EngineInterface;
|
||||
use Symfony\Component\HttpKernel\Controller\ControllerReference;
|
||||
use Symfony\Component\HttpKernel\UriSigner;
|
||||
|
||||
/**
|
||||
* Implements the Hinclude rendering strategy.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class HIncludeFragmentRenderer extends RoutableFragmentRenderer
|
||||
{
|
||||
private $globalDefaultTemplate;
|
||||
private $signer;
|
||||
private $templating;
|
||||
private $charset;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param EngineInterface|\Twig_Environment $templating An EngineInterface or a \Twig_Environment instance
|
||||
* @param UriSigner $signer A UriSigner instance
|
||||
* @param string $globalDefaultTemplate The global default content (it can be a template name or the content)
|
||||
* @param string $charset
|
||||
*/
|
||||
public function __construct($templating = null, UriSigner $signer = null, $globalDefaultTemplate = null, $charset = 'utf-8')
|
||||
{
|
||||
$this->setTemplating($templating);
|
||||
$this->globalDefaultTemplate = $globalDefaultTemplate;
|
||||
$this->signer = $signer;
|
||||
$this->charset = $charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the templating engine to use to render the default content.
|
||||
*
|
||||
* @param EngineInterface|\Twig_Environment|null $templating An EngineInterface or a \Twig_Environment instance
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setTemplating($templating)
|
||||
{
|
||||
if (null !== $templating && !$templating instanceof EngineInterface && !$templating instanceof \Twig_Environment) {
|
||||
throw new \InvalidArgumentException('The hinclude rendering strategy needs an instance of \Twig_Environment or Symfony\Component\Templating\EngineInterface');
|
||||
}
|
||||
|
||||
$this->templating = $templating;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a templating engine has been set.
|
||||
*
|
||||
* @return Boolean true if the templating engine has been set, false otherwise
|
||||
*/
|
||||
public function hasTemplating()
|
||||
{
|
||||
return null !== $this->templating;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Additional available options:
|
||||
*
|
||||
* * default: The default content (it can be a template name or the content)
|
||||
* * id: An optional hx:include tag id attribute
|
||||
* * attributes: An optional array of hx:include tag attributes
|
||||
*/
|
||||
public function render($uri, Request $request, array $options = array())
|
||||
{
|
||||
if ($uri instanceof ControllerReference) {
|
||||
if (null === $this->signer) {
|
||||
throw new \LogicException('You must use a proper URI when using the Hinclude rendering strategy or set a URL signer.');
|
||||
}
|
||||
|
||||
$uri = $this->signer->sign($this->generateFragmentUri($uri, $request));
|
||||
}
|
||||
|
||||
// We need to replace ampersands in the URI with the encoded form in order to return valid html/xml content.
|
||||
$uri = str_replace('&', '&', $uri);
|
||||
|
||||
$template = isset($options['default']) ? $options['default'] : $this->globalDefaultTemplate;
|
||||
if (null !== $this->templating && $template && $this->templateExists($template)) {
|
||||
$content = $this->templating->render($template);
|
||||
} else {
|
||||
$content = $template;
|
||||
}
|
||||
|
||||
$attributes = isset($options['attributes']) && is_array($options['attributes']) ? $options['attributes'] : array();
|
||||
if (isset($options['id']) && $options['id']) {
|
||||
$attributes['id'] = $options['id'];
|
||||
}
|
||||
$renderedAttributes = '';
|
||||
if (count($attributes) > 0) {
|
||||
foreach ($attributes as $attribute => $value) {
|
||||
$renderedAttributes .= sprintf(
|
||||
' %s="%s"',
|
||||
htmlspecialchars($attribute, ENT_QUOTES | ENT_SUBSTITUTE, $this->charset, false),
|
||||
htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, $this->charset, false)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return new Response(sprintf('<hx:include src="%s"%s>%s</hx:include>', $uri, $renderedAttributes, $content));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $template
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function templateExists($template)
|
||||
{
|
||||
if ($this->templating instanceof EngineInterface) {
|
||||
try {
|
||||
return $this->templating->exists($template);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$loader = $this->templating->getLoader();
|
||||
if ($loader instanceof \Twig_ExistsLoaderInterface) {
|
||||
return $loader->exists($template);
|
||||
}
|
||||
|
||||
try {
|
||||
$loader->getSource($template);
|
||||
|
||||
return true;
|
||||
} catch (\Twig_Error_Loader $e) {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'hinclude';
|
||||
}
|
||||
}
|
152
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php
vendored
Normal file
152
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Fragment;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpKernel\Controller\ControllerReference;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
|
||||
/**
|
||||
* Implements the inline rendering strategy where the Request is rendered by the current HTTP kernel.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class InlineFragmentRenderer extends RoutableFragmentRenderer
|
||||
{
|
||||
private $kernel;
|
||||
private $dispatcher;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param HttpKernelInterface $kernel A HttpKernelInterface instance
|
||||
*/
|
||||
public function __construct(HttpKernelInterface $kernel, EventDispatcherInterface $dispatcher = null)
|
||||
{
|
||||
$this->kernel = $kernel;
|
||||
$this->dispatcher = $dispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Additional available options:
|
||||
*
|
||||
* * alt: an alternative URI to render in case of an error
|
||||
*/
|
||||
public function render($uri, Request $request, array $options = array())
|
||||
{
|
||||
$reference = null;
|
||||
if ($uri instanceof ControllerReference) {
|
||||
$reference = $uri;
|
||||
|
||||
// Remove attributes from the generated URI because if not, the Symfony
|
||||
// routing system will use them to populate the Request attributes. We don't
|
||||
// want that as we want to preserve objects (so we manually set Request attributes
|
||||
// below instead)
|
||||
$attributes = $reference->attributes;
|
||||
$reference->attributes = array();
|
||||
|
||||
// The request format and locale might have been overriden by the user
|
||||
foreach (array('_format', '_locale') as $key) {
|
||||
if (isset($attributes[$key])) {
|
||||
$reference->attributes[$key] = $attributes[$key];
|
||||
}
|
||||
}
|
||||
|
||||
$uri = $this->generateFragmentUri($uri, $request);
|
||||
$reference->attributes = array_merge($attributes, $reference->attributes);
|
||||
}
|
||||
|
||||
$subRequest = $this->createSubRequest($uri, $request);
|
||||
|
||||
// override Request attributes as they can be objects (which are not supported by the generated URI)
|
||||
if (null !== $reference) {
|
||||
$subRequest->attributes->add($reference->attributes);
|
||||
}
|
||||
|
||||
$level = ob_get_level();
|
||||
try {
|
||||
return $this->kernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false);
|
||||
} catch (\Exception $e) {
|
||||
// we dispatch the exception event to trigger the logging
|
||||
// the response that comes back is simply ignored
|
||||
if (isset($options['ignore_errors']) && $options['ignore_errors'] && $this->dispatcher) {
|
||||
$event = new GetResponseForExceptionEvent($this->kernel, $request, HttpKernelInterface::SUB_REQUEST, $e);
|
||||
|
||||
$this->dispatcher->dispatch(KernelEvents::EXCEPTION, $event);
|
||||
}
|
||||
|
||||
// let's clean up the output buffers that were created by the sub-request
|
||||
while (ob_get_level() > $level) {
|
||||
ob_get_clean();
|
||||
}
|
||||
|
||||
if (isset($options['alt'])) {
|
||||
$alt = $options['alt'];
|
||||
unset($options['alt']);
|
||||
|
||||
return $this->render($alt, $request, $options);
|
||||
}
|
||||
|
||||
if (!isset($options['ignore_errors']) || !$options['ignore_errors']) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return new Response();
|
||||
}
|
||||
}
|
||||
|
||||
protected function createSubRequest($uri, Request $request)
|
||||
{
|
||||
$cookies = $request->cookies->all();
|
||||
$server = $request->server->all();
|
||||
|
||||
// Override the arguments to emulate a sub-request.
|
||||
// Sub-request object will point to localhost as client ip and real client ip
|
||||
// will be included into trusted header for client ip
|
||||
try {
|
||||
if ($trustedHeaderName = Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP)) {
|
||||
$currentXForwardedFor = $request->headers->get($trustedHeaderName, '');
|
||||
|
||||
$server['HTTP_'.$trustedHeaderName] = ($currentXForwardedFor ? $currentXForwardedFor.', ' : '').$request->getClientIp();
|
||||
}
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
$server['REMOTE_ADDR'] = '127.0.0.1';
|
||||
|
||||
$subRequest = $request::create($uri, 'get', array(), $cookies, array(), $server);
|
||||
if ($request->headers->has('Surrogate-Capability')) {
|
||||
$subRequest->headers->set('Surrogate-Capability', $request->headers->get('Surrogate-Capability'));
|
||||
}
|
||||
|
||||
if ($session = $request->getSession()) {
|
||||
$subRequest->setSession($session);
|
||||
}
|
||||
|
||||
return $subRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'inline';
|
||||
}
|
||||
}
|
74
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Fragment/RoutableFragmentRenderer.php
vendored
Normal file
74
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Fragment/RoutableFragmentRenderer.php
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Fragment;
|
||||
|
||||
use Symfony\Component\HttpKernel\Controller\ControllerReference;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\EventListener\FragmentListener;
|
||||
|
||||
/**
|
||||
* Adds the possibility to generate a fragment URI for a given Controller.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
abstract class RoutableFragmentRenderer implements FragmentRendererInterface
|
||||
{
|
||||
private $fragmentPath = '/_fragment';
|
||||
|
||||
/**
|
||||
* Sets the fragment path that triggers the fragment listener.
|
||||
*
|
||||
* @param string $path The path
|
||||
*
|
||||
* @see FragmentListener
|
||||
*/
|
||||
public function setFragmentPath($path)
|
||||
{
|
||||
$this->fragmentPath = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a fragment URI for a given controller.
|
||||
*
|
||||
* @param ControllerReference $reference A ControllerReference instance
|
||||
* @param Request $request A Request instance
|
||||
* @param Boolean $absolute Whether to generate an absolute URL or not
|
||||
*
|
||||
* @return string A fragment URI
|
||||
*/
|
||||
protected function generateFragmentUri(ControllerReference $reference, Request $request, $absolute = false)
|
||||
{
|
||||
// We need to forward the current _format and _locale values as we don't have
|
||||
// a proper routing pattern to do the job for us.
|
||||
// This makes things inconsistent if you switch from rendering a controller
|
||||
// to rendering a route if the route pattern does not contain the special
|
||||
// _format and _locale placeholders.
|
||||
if (!isset($reference->attributes['_format'])) {
|
||||
$reference->attributes['_format'] = $request->getRequestFormat();
|
||||
}
|
||||
if (!isset($reference->attributes['_locale'])) {
|
||||
$reference->attributes['_locale'] = $request->getLocale();
|
||||
}
|
||||
|
||||
$reference->attributes['_controller'] = $reference->controller;
|
||||
|
||||
$reference->query['_path'] = http_build_query($reference->attributes, '', '&');
|
||||
|
||||
$path = $this->fragmentPath.'?'.http_build_query($reference->query, '', '&');
|
||||
|
||||
if ($absolute) {
|
||||
return $request->getUriForPath($path);
|
||||
}
|
||||
|
||||
return $request->getBaseUrl().$path;
|
||||
}
|
||||
}
|
245
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/Esi.php
vendored
Normal file
245
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/Esi.php
vendored
Normal file
@@ -0,0 +1,245 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\HttpCache;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
|
||||
/**
|
||||
* Esi implements the ESI capabilities to Request and Response instances.
|
||||
*
|
||||
* For more information, read the following W3C notes:
|
||||
*
|
||||
* * ESI Language Specification 1.0 (http://www.w3.org/TR/esi-lang)
|
||||
*
|
||||
* * Edge Architecture Specification (http://www.w3.org/TR/edge-arch)
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Esi
|
||||
{
|
||||
private $contentTypes;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $contentTypes An array of content-type that should be parsed for ESI information.
|
||||
* (default: text/html, text/xml, application/xhtml+xml, and application/xml)
|
||||
*/
|
||||
public function __construct(array $contentTypes = array('text/html', 'text/xml', 'application/xhtml+xml', 'application/xml'))
|
||||
{
|
||||
$this->contentTypes = $contentTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new cache strategy instance.
|
||||
*
|
||||
* @return EsiResponseCacheStrategyInterface A EsiResponseCacheStrategyInterface instance
|
||||
*/
|
||||
public function createCacheStrategy()
|
||||
{
|
||||
return new EsiResponseCacheStrategy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that at least one surrogate has ESI/1.0 capability.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
*
|
||||
* @return Boolean true if one surrogate has ESI/1.0 capability, false otherwise
|
||||
*/
|
||||
public function hasSurrogateEsiCapability(Request $request)
|
||||
{
|
||||
if (null === $value = $request->headers->get('Surrogate-Capability')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false !== strpos($value, 'ESI/1.0');
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds ESI/1.0 capability to the given Request.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
*/
|
||||
public function addSurrogateEsiCapability(Request $request)
|
||||
{
|
||||
$current = $request->headers->get('Surrogate-Capability');
|
||||
$new = 'symfony2="ESI/1.0"';
|
||||
|
||||
$request->headers->set('Surrogate-Capability', $current ? $current.', '.$new : $new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds HTTP headers to specify that the Response needs to be parsed for ESI.
|
||||
*
|
||||
* This method only adds an ESI HTTP header if the Response has some ESI tags.
|
||||
*
|
||||
* @param Response $response A Response instance
|
||||
*/
|
||||
public function addSurrogateControl(Response $response)
|
||||
{
|
||||
if (false !== strpos($response->getContent(), '<esi:include')) {
|
||||
$response->headers->set('Surrogate-Control', 'content="ESI/1.0"');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the Response needs to be parsed for ESI tags.
|
||||
*
|
||||
* @param Response $response A Response instance
|
||||
*
|
||||
* @return Boolean true if the Response needs to be parsed, false otherwise
|
||||
*/
|
||||
public function needsEsiParsing(Response $response)
|
||||
{
|
||||
if (!$control = $response->headers->get('Surrogate-Control')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (Boolean) preg_match('#content="[^"]*ESI/1.0[^"]*"#', $control);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders an ESI tag.
|
||||
*
|
||||
* @param string $uri A URI
|
||||
* @param string $alt An alternate URI
|
||||
* @param Boolean $ignoreErrors Whether to ignore errors or not
|
||||
* @param string $comment A comment to add as an esi:include tag
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function renderIncludeTag($uri, $alt = null, $ignoreErrors = true, $comment = '')
|
||||
{
|
||||
$html = sprintf('<esi:include src="%s"%s%s />',
|
||||
$uri,
|
||||
$ignoreErrors ? ' onerror="continue"' : '',
|
||||
$alt ? sprintf(' alt="%s"', $alt) : ''
|
||||
);
|
||||
|
||||
if (!empty($comment)) {
|
||||
return sprintf("<esi:comment text=\"%s\" />\n%s", $comment, $html);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces a Response ESI tags with the included resource content.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param Response $response A Response instance
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function process(Request $request, Response $response)
|
||||
{
|
||||
$this->request = $request;
|
||||
$type = $response->headers->get('Content-Type');
|
||||
if (empty($type)) {
|
||||
$type = 'text/html';
|
||||
}
|
||||
|
||||
$parts = explode(';', $type);
|
||||
if (!in_array($parts[0], $this->contentTypes)) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
// we don't use a proper XML parser here as we can have ESI tags in a plain text response
|
||||
$content = $response->getContent();
|
||||
$content = str_replace(array('<?', '<%'), array('<?php echo "<?"; ?>', '<?php echo "<%"; ?>'), $content);
|
||||
$content = preg_replace_callback('#<esi\:include\s+(.*?)\s*(?:/|</esi\:include)>#', array($this, 'handleEsiIncludeTag'), $content);
|
||||
$content = preg_replace('#<esi\:comment[^>]*(?:/|</esi\:comment)>#', '', $content);
|
||||
$content = preg_replace('#<esi\:remove>.*?</esi\:remove>#', '', $content);
|
||||
|
||||
$response->setContent($content);
|
||||
$response->headers->set('X-Body-Eval', 'ESI');
|
||||
|
||||
// remove ESI/1.0 from the Surrogate-Control header
|
||||
if ($response->headers->has('Surrogate-Control')) {
|
||||
$value = $response->headers->get('Surrogate-Control');
|
||||
if ('content="ESI/1.0"' == $value) {
|
||||
$response->headers->remove('Surrogate-Control');
|
||||
} elseif (preg_match('#,\s*content="ESI/1.0"#', $value)) {
|
||||
$response->headers->set('Surrogate-Control', preg_replace('#,\s*content="ESI/1.0"#', '', $value));
|
||||
} elseif (preg_match('#content="ESI/1.0",\s*#', $value)) {
|
||||
$response->headers->set('Surrogate-Control', preg_replace('#content="ESI/1.0",\s*#', '', $value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles an ESI from the cache.
|
||||
*
|
||||
* @param HttpCache $cache An HttpCache instance
|
||||
* @param string $uri The main URI
|
||||
* @param string $alt An alternative URI
|
||||
* @param Boolean $ignoreErrors Whether to ignore errors or not
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function handle(HttpCache $cache, $uri, $alt, $ignoreErrors)
|
||||
{
|
||||
$subRequest = Request::create($uri, 'get', array(), $cache->getRequest()->cookies->all(), array(), $cache->getRequest()->server->all());
|
||||
|
||||
try {
|
||||
$response = $cache->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true);
|
||||
|
||||
if (!$response->isSuccessful()) {
|
||||
throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $subRequest->getUri(), $response->getStatusCode()));
|
||||
}
|
||||
|
||||
return $response->getContent();
|
||||
} catch (\Exception $e) {
|
||||
if ($alt) {
|
||||
return $this->handle($cache, $alt, '', $ignoreErrors);
|
||||
}
|
||||
|
||||
if (!$ignoreErrors) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles an ESI include tag (called internally).
|
||||
*
|
||||
* @param array $attributes An array containing the attributes.
|
||||
*
|
||||
* @return string The response content for the include.
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
private function handleEsiIncludeTag($attributes)
|
||||
{
|
||||
$options = array();
|
||||
preg_match_all('/(src|onerror|alt)="([^"]*?)"/', $attributes[1], $matches, PREG_SET_ORDER);
|
||||
foreach ($matches as $set) {
|
||||
$options[$set[1]] = $set[2];
|
||||
}
|
||||
|
||||
if (!isset($options['src'])) {
|
||||
throw new \RuntimeException('Unable to process an ESI tag without a "src" attribute.');
|
||||
}
|
||||
|
||||
return sprintf('<?php echo $this->esi->handle($this, \'%s\', \'%s\', %s) ?>'."\n",
|
||||
$options['src'],
|
||||
isset($options['alt']) ? $options['alt'] : null,
|
||||
isset($options['onerror']) && 'continue' == $options['onerror'] ? 'true' : 'false'
|
||||
);
|
||||
}
|
||||
}
|
85
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/EsiResponseCacheStrategy.php
vendored
Normal file
85
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/EsiResponseCacheStrategy.php
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This code is partially based on the Rack-Cache library by Ryan Tomayko,
|
||||
* which is released under the MIT license.
|
||||
* (based on commit 02d2b48d75bcb63cf1c0c7149c077ad256542801)
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\HttpCache;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* EsiResponseCacheStrategy knows how to compute the Response cache HTTP header
|
||||
* based on the different ESI response cache headers.
|
||||
*
|
||||
* This implementation changes the master response TTL to the smallest TTL received
|
||||
* or force validation if one of the ESI has validation cache strategy.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class EsiResponseCacheStrategy implements EsiResponseCacheStrategyInterface
|
||||
{
|
||||
private $cacheable = true;
|
||||
private $embeddedResponses = 0;
|
||||
private $ttls = array();
|
||||
private $maxAges = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function add(Response $response)
|
||||
{
|
||||
if ($response->isValidateable()) {
|
||||
$this->cacheable = false;
|
||||
} else {
|
||||
$this->ttls[] = $response->getTtl();
|
||||
$this->maxAges[] = $response->getMaxAge();
|
||||
}
|
||||
|
||||
$this->embeddedResponses++;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function update(Response $response)
|
||||
{
|
||||
// if we have no embedded Response, do nothing
|
||||
if (0 === $this->embeddedResponses) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove validation related headers in order to avoid browsers using
|
||||
// their own cache, because some of the response content comes from
|
||||
// at least one embedded response (which likely has a different caching strategy).
|
||||
if ($response->isValidateable()) {
|
||||
$response->setEtag(null);
|
||||
$response->setLastModified(null);
|
||||
$this->cacheable = false;
|
||||
}
|
||||
|
||||
if (!$this->cacheable) {
|
||||
$response->headers->set('Cache-Control', 'no-cache, must-revalidate');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->ttls[] = $response->getTtl();
|
||||
$this->maxAges[] = $response->getMaxAge();
|
||||
|
||||
if (null !== $maxAge = min($this->maxAges)) {
|
||||
$response->setSharedMaxAge($maxAge);
|
||||
$response->headers->set('Age', $maxAge - min($this->ttls));
|
||||
}
|
||||
$response->setMaxAge(0);
|
||||
}
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This code is partially based on the Rack-Cache library by Ryan Tomayko,
|
||||
* which is released under the MIT license.
|
||||
* (based on commit 02d2b48d75bcb63cf1c0c7149c077ad256542801)
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\HttpCache;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* EsiResponseCacheStrategyInterface implementations know how to compute the
|
||||
* Response cache HTTP header based on the different ESI response cache headers.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface EsiResponseCacheStrategyInterface
|
||||
{
|
||||
/**
|
||||
* Adds a Response.
|
||||
*
|
||||
* @param Response $response
|
||||
*/
|
||||
public function add(Response $response);
|
||||
|
||||
/**
|
||||
* Updates the Response HTTP headers based on the embedded Responses.
|
||||
*
|
||||
* @param Response $response
|
||||
*/
|
||||
public function update(Response $response);
|
||||
}
|
688
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/HttpCache.php
vendored
Normal file
688
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/HttpCache.php
vendored
Normal file
@@ -0,0 +1,688 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This code is partially based on the Rack-Cache library by Ryan Tomayko,
|
||||
* which is released under the MIT license.
|
||||
* (based on commit 02d2b48d75bcb63cf1c0c7149c077ad256542801)
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\HttpCache;
|
||||
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpKernel\TerminableInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\HttpCache\Esi;
|
||||
|
||||
/**
|
||||
* Cache provides HTTP caching.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class HttpCache implements HttpKernelInterface, TerminableInterface
|
||||
{
|
||||
private $kernel;
|
||||
private $store;
|
||||
private $request;
|
||||
private $esi;
|
||||
private $esiCacheStrategy;
|
||||
private $traces;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* The available options are:
|
||||
*
|
||||
* * debug: If true, the traces are added as a HTTP header to ease debugging
|
||||
*
|
||||
* * default_ttl The number of seconds that a cache entry should be considered
|
||||
* fresh when no explicit freshness information is provided in
|
||||
* a response. Explicit Cache-Control or Expires headers
|
||||
* override this value. (default: 0)
|
||||
*
|
||||
* * private_headers Set of request headers that trigger "private" cache-control behavior
|
||||
* on responses that don't explicitly state whether the response is
|
||||
* public or private via a Cache-Control directive. (default: Authorization and Cookie)
|
||||
*
|
||||
* * allow_reload Specifies whether the client can force a cache reload by including a
|
||||
* Cache-Control "no-cache" directive in the request. Set it to ``true``
|
||||
* for compliance with RFC 2616. (default: false)
|
||||
*
|
||||
* * allow_revalidate Specifies whether the client can force a cache revalidate by including
|
||||
* a Cache-Control "max-age=0" directive in the request. Set it to ``true``
|
||||
* for compliance with RFC 2616. (default: false)
|
||||
*
|
||||
* * stale_while_revalidate Specifies the default number of seconds (the granularity is the second as the
|
||||
* Response TTL precision is a second) during which the cache can immediately return
|
||||
* a stale response while it revalidates it in the background (default: 2).
|
||||
* This setting is overridden by the stale-while-revalidate HTTP Cache-Control
|
||||
* extension (see RFC 5861).
|
||||
*
|
||||
* * stale_if_error Specifies the default number of seconds (the granularity is the second) during which
|
||||
* the cache can serve a stale response when an error is encountered (default: 60).
|
||||
* This setting is overridden by the stale-if-error HTTP Cache-Control extension
|
||||
* (see RFC 5861).
|
||||
*
|
||||
* @param HttpKernelInterface $kernel An HttpKernelInterface instance
|
||||
* @param StoreInterface $store A Store instance
|
||||
* @param Esi $esi An Esi instance
|
||||
* @param array $options An array of options
|
||||
*/
|
||||
public function __construct(HttpKernelInterface $kernel, StoreInterface $store, Esi $esi = null, array $options = array())
|
||||
{
|
||||
$this->store = $store;
|
||||
$this->kernel = $kernel;
|
||||
|
||||
// needed in case there is a fatal error because the backend is too slow to respond
|
||||
register_shutdown_function(array($this->store, 'cleanup'));
|
||||
|
||||
$this->options = array_merge(array(
|
||||
'debug' => false,
|
||||
'default_ttl' => 0,
|
||||
'private_headers' => array('Authorization', 'Cookie'),
|
||||
'allow_reload' => false,
|
||||
'allow_revalidate' => false,
|
||||
'stale_while_revalidate' => 2,
|
||||
'stale_if_error' => 60,
|
||||
), $options);
|
||||
$this->esi = $esi;
|
||||
$this->traces = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current store.
|
||||
*
|
||||
* @return StoreInterface $store A StoreInterface instance
|
||||
*/
|
||||
public function getStore()
|
||||
{
|
||||
return $this->store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of events that took place during processing of the last request.
|
||||
*
|
||||
* @return array An array of events
|
||||
*/
|
||||
public function getTraces()
|
||||
{
|
||||
return $this->traces;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a log message for the events of the last request processing.
|
||||
*
|
||||
* @return string A log message
|
||||
*/
|
||||
public function getLog()
|
||||
{
|
||||
$log = array();
|
||||
foreach ($this->traces as $request => $traces) {
|
||||
$log[] = sprintf('%s: %s', $request, implode(', ', $traces));
|
||||
}
|
||||
|
||||
return implode('; ', $log);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Request instance associated with the master request.
|
||||
*
|
||||
* @return Request A Request instance
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
return $this->request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Kernel instance
|
||||
*
|
||||
* @return HttpKernelInterface An HttpKernelInterface instance
|
||||
*/
|
||||
public function getKernel()
|
||||
{
|
||||
return $this->kernel;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the Esi instance
|
||||
*
|
||||
* @return Esi An Esi instance
|
||||
*/
|
||||
public function getEsi()
|
||||
{
|
||||
return $this->esi;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
|
||||
{
|
||||
// FIXME: catch exceptions and implement a 500 error page here? -> in Varnish, there is a built-in error page mechanism
|
||||
if (HttpKernelInterface::MASTER_REQUEST === $type) {
|
||||
$this->traces = array();
|
||||
$this->request = $request;
|
||||
if (null !== $this->esi) {
|
||||
$this->esiCacheStrategy = $this->esi->createCacheStrategy();
|
||||
}
|
||||
}
|
||||
|
||||
$path = $request->getPathInfo();
|
||||
if ($qs = $request->getQueryString()) {
|
||||
$path .= '?'.$qs;
|
||||
}
|
||||
$this->traces[$request->getMethod().' '.$path] = array();
|
||||
|
||||
if (!$request->isMethodSafe()) {
|
||||
$response = $this->invalidate($request, $catch);
|
||||
} elseif ($request->headers->has('expect')) {
|
||||
$response = $this->pass($request, $catch);
|
||||
} else {
|
||||
$response = $this->lookup($request, $catch);
|
||||
}
|
||||
|
||||
$this->restoreResponseBody($request, $response);
|
||||
|
||||
$response->setDate(new \DateTime(null, new \DateTimeZone('UTC')));
|
||||
|
||||
if (HttpKernelInterface::MASTER_REQUEST === $type && $this->options['debug']) {
|
||||
$response->headers->set('X-Symfony-Cache', $this->getLog());
|
||||
}
|
||||
|
||||
if (null !== $this->esi) {
|
||||
if (HttpKernelInterface::MASTER_REQUEST === $type) {
|
||||
$this->esiCacheStrategy->update($response);
|
||||
} else {
|
||||
$this->esiCacheStrategy->add($response);
|
||||
}
|
||||
}
|
||||
|
||||
$response->prepare($request);
|
||||
|
||||
$response->isNotModified($request);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function terminate(Request $request, Response $response)
|
||||
{
|
||||
if ($this->getKernel() instanceof TerminableInterface) {
|
||||
$this->getKernel()->terminate($request, $response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forwards the Request to the backend without storing the Response in the cache.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param Boolean $catch Whether to process exceptions
|
||||
*
|
||||
* @return Response A Response instance
|
||||
*/
|
||||
protected function pass(Request $request, $catch = false)
|
||||
{
|
||||
$this->record($request, 'pass');
|
||||
|
||||
return $this->forward($request, $catch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates non-safe methods (like POST, PUT, and DELETE).
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param Boolean $catch Whether to process exceptions
|
||||
*
|
||||
* @return Response A Response instance
|
||||
*
|
||||
* @throws \Exception
|
||||
*
|
||||
* @see RFC2616 13.10
|
||||
*/
|
||||
protected function invalidate(Request $request, $catch = false)
|
||||
{
|
||||
$response = $this->pass($request, $catch);
|
||||
|
||||
// invalidate only when the response is successful
|
||||
if ($response->isSuccessful() || $response->isRedirect()) {
|
||||
try {
|
||||
$this->store->invalidate($request, $catch);
|
||||
|
||||
// As per the RFC, invalidate Location and Content-Location URLs if present
|
||||
foreach (array('Location', 'Content-Location') as $header) {
|
||||
if ($uri = $response->headers->get($header)) {
|
||||
$subRequest = $request::create($uri, 'get', array(), array(), array(), $request->server->all());
|
||||
|
||||
$this->store->invalidate($subRequest);
|
||||
}
|
||||
}
|
||||
|
||||
$this->record($request, 'invalidate');
|
||||
} catch (\Exception $e) {
|
||||
$this->record($request, 'invalidate-failed');
|
||||
|
||||
if ($this->options['debug']) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookups a Response from the cache for the given Request.
|
||||
*
|
||||
* When a matching cache entry is found and is fresh, it uses it as the
|
||||
* response without forwarding any request to the backend. When a matching
|
||||
* cache entry is found but is stale, it attempts to "validate" the entry with
|
||||
* the backend using conditional GET. When no matching cache entry is found,
|
||||
* it triggers "miss" processing.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param Boolean $catch whether to process exceptions
|
||||
*
|
||||
* @return Response A Response instance
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function lookup(Request $request, $catch = false)
|
||||
{
|
||||
// if allow_reload and no-cache Cache-Control, allow a cache reload
|
||||
if ($this->options['allow_reload'] && $request->isNoCache()) {
|
||||
$this->record($request, 'reload');
|
||||
|
||||
return $this->fetch($request);
|
||||
}
|
||||
|
||||
try {
|
||||
$entry = $this->store->lookup($request);
|
||||
} catch (\Exception $e) {
|
||||
$this->record($request, 'lookup-failed');
|
||||
|
||||
if ($this->options['debug']) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return $this->pass($request, $catch);
|
||||
}
|
||||
|
||||
if (null === $entry) {
|
||||
$this->record($request, 'miss');
|
||||
|
||||
return $this->fetch($request, $catch);
|
||||
}
|
||||
|
||||
if (!$this->isFreshEnough($request, $entry)) {
|
||||
$this->record($request, 'stale');
|
||||
|
||||
return $this->validate($request, $entry, $catch);
|
||||
}
|
||||
|
||||
$this->record($request, 'fresh');
|
||||
|
||||
$entry->headers->set('Age', $entry->getAge());
|
||||
|
||||
return $entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that a cache entry is fresh.
|
||||
*
|
||||
* The original request is used as a template for a conditional
|
||||
* GET request with the backend.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param Response $entry A Response instance to validate
|
||||
* @param Boolean $catch Whether to process exceptions
|
||||
*
|
||||
* @return Response A Response instance
|
||||
*/
|
||||
protected function validate(Request $request, Response $entry, $catch = false)
|
||||
{
|
||||
$subRequest = clone $request;
|
||||
|
||||
// send no head requests because we want content
|
||||
$subRequest->setMethod('GET');
|
||||
|
||||
// add our cached last-modified validator
|
||||
$subRequest->headers->set('if_modified_since', $entry->headers->get('Last-Modified'));
|
||||
|
||||
// Add our cached etag validator to the environment.
|
||||
// We keep the etags from the client to handle the case when the client
|
||||
// has a different private valid entry which is not cached here.
|
||||
$cachedEtags = $entry->getEtag() ? array($entry->getEtag()) : array();
|
||||
$requestEtags = $request->getEtags();
|
||||
if ($etags = array_unique(array_merge($cachedEtags, $requestEtags))) {
|
||||
$subRequest->headers->set('if_none_match', implode(', ', $etags));
|
||||
}
|
||||
|
||||
$response = $this->forward($subRequest, $catch, $entry);
|
||||
|
||||
if (304 == $response->getStatusCode()) {
|
||||
$this->record($request, 'valid');
|
||||
|
||||
// return the response and not the cache entry if the response is valid but not cached
|
||||
$etag = $response->getEtag();
|
||||
if ($etag && in_array($etag, $requestEtags) && !in_array($etag, $cachedEtags)) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$entry = clone $entry;
|
||||
$entry->headers->remove('Date');
|
||||
|
||||
foreach (array('Date', 'Expires', 'Cache-Control', 'ETag', 'Last-Modified') as $name) {
|
||||
if ($response->headers->has($name)) {
|
||||
$entry->headers->set($name, $response->headers->get($name));
|
||||
}
|
||||
}
|
||||
|
||||
$response = $entry;
|
||||
} else {
|
||||
$this->record($request, 'invalid');
|
||||
}
|
||||
|
||||
if ($response->isCacheable()) {
|
||||
$this->store($request, $response);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forwards the Request to the backend and determines whether the response should be stored.
|
||||
*
|
||||
* This methods is triggered when the cache missed or a reload is required.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param Boolean $catch whether to process exceptions
|
||||
*
|
||||
* @return Response A Response instance
|
||||
*/
|
||||
protected function fetch(Request $request, $catch = false)
|
||||
{
|
||||
$subRequest = clone $request;
|
||||
|
||||
// send no head requests because we want content
|
||||
$subRequest->setMethod('GET');
|
||||
|
||||
// avoid that the backend sends no content
|
||||
$subRequest->headers->remove('if_modified_since');
|
||||
$subRequest->headers->remove('if_none_match');
|
||||
|
||||
$response = $this->forward($subRequest, $catch);
|
||||
|
||||
if ($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) {
|
||||
$response->setPrivate(true);
|
||||
} elseif ($this->options['default_ttl'] > 0 && null === $response->getTtl() && !$response->headers->getCacheControlDirective('must-revalidate')) {
|
||||
$response->setTtl($this->options['default_ttl']);
|
||||
}
|
||||
|
||||
if ($response->isCacheable()) {
|
||||
$this->store($request, $response);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forwards the Request to the backend and returns the Response.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param Boolean $catch Whether to catch exceptions or not
|
||||
* @param Response $entry A Response instance (the stale entry if present, null otherwise)
|
||||
*
|
||||
* @return Response A Response instance
|
||||
*/
|
||||
protected function forward(Request $request, $catch = false, Response $entry = null)
|
||||
{
|
||||
if ($this->esi) {
|
||||
$this->esi->addSurrogateEsiCapability($request);
|
||||
}
|
||||
|
||||
// modify the X-Forwarded-For header if needed
|
||||
$forwardedFor = $request->headers->get('X-Forwarded-For');
|
||||
if ($forwardedFor) {
|
||||
$request->headers->set('X-Forwarded-For', $forwardedFor.', '.$request->server->get('REMOTE_ADDR'));
|
||||
} else {
|
||||
$request->headers->set('X-Forwarded-For', $request->server->get('REMOTE_ADDR'));
|
||||
}
|
||||
|
||||
// fix the client IP address by setting it to 127.0.0.1 as HttpCache
|
||||
// is always called from the same process as the backend.
|
||||
$request->server->set('REMOTE_ADDR', '127.0.0.1');
|
||||
|
||||
// always a "master" request (as the real master request can be in cache)
|
||||
$response = $this->kernel->handle($request, HttpKernelInterface::MASTER_REQUEST, $catch);
|
||||
// FIXME: we probably need to also catch exceptions if raw === true
|
||||
|
||||
// we don't implement the stale-if-error on Requests, which is nonetheless part of the RFC
|
||||
if (null !== $entry && in_array($response->getStatusCode(), array(500, 502, 503, 504))) {
|
||||
if (null === $age = $entry->headers->getCacheControlDirective('stale-if-error')) {
|
||||
$age = $this->options['stale_if_error'];
|
||||
}
|
||||
|
||||
if (abs($entry->getTtl()) < $age) {
|
||||
$this->record($request, 'stale-if-error');
|
||||
|
||||
return $entry;
|
||||
}
|
||||
}
|
||||
|
||||
$this->processResponseBody($request, $response);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the cache entry is "fresh enough" to satisfy the Request.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param Response $entry A Response instance
|
||||
*
|
||||
* @return Boolean true if the cache entry if fresh enough, false otherwise
|
||||
*/
|
||||
protected function isFreshEnough(Request $request, Response $entry)
|
||||
{
|
||||
if (!$entry->isFresh()) {
|
||||
return $this->lock($request, $entry);
|
||||
}
|
||||
|
||||
if ($this->options['allow_revalidate'] && null !== $maxAge = $request->headers->getCacheControlDirective('max-age')) {
|
||||
return $maxAge > 0 && $maxAge >= $entry->getAge();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks a Request during the call to the backend.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param Response $entry A Response instance
|
||||
*
|
||||
* @return Boolean true if the cache entry can be returned even if it is staled, false otherwise
|
||||
*/
|
||||
protected function lock(Request $request, Response $entry)
|
||||
{
|
||||
// try to acquire a lock to call the backend
|
||||
$lock = $this->store->lock($request, $entry);
|
||||
|
||||
// there is already another process calling the backend
|
||||
if (true !== $lock) {
|
||||
// check if we can serve the stale entry
|
||||
if (null === $age = $entry->headers->getCacheControlDirective('stale-while-revalidate')) {
|
||||
$age = $this->options['stale_while_revalidate'];
|
||||
}
|
||||
|
||||
if (abs($entry->getTtl()) < $age) {
|
||||
$this->record($request, 'stale-while-revalidate');
|
||||
|
||||
// server the stale response while there is a revalidation
|
||||
return true;
|
||||
}
|
||||
|
||||
// wait for the lock to be released
|
||||
$wait = 0;
|
||||
while ($this->store->isLocked($request) && $wait < 5000000) {
|
||||
usleep(50000);
|
||||
$wait += 50000;
|
||||
}
|
||||
|
||||
if ($wait < 2000000) {
|
||||
// replace the current entry with the fresh one
|
||||
$new = $this->lookup($request);
|
||||
$entry->headers = $new->headers;
|
||||
$entry->setContent($new->getContent());
|
||||
$entry->setStatusCode($new->getStatusCode());
|
||||
$entry->setProtocolVersion($new->getProtocolVersion());
|
||||
foreach ($new->headers->getCookies() as $cookie) {
|
||||
$entry->headers->setCookie($cookie);
|
||||
}
|
||||
} else {
|
||||
// backend is slow as hell, send a 503 response (to avoid the dog pile effect)
|
||||
$entry->setStatusCode(503);
|
||||
$entry->setContent('503 Service Unavailable');
|
||||
$entry->headers->set('Retry-After', 10);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// we have the lock, call the backend
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the Response to the cache.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param Response $response A Response instance
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function store(Request $request, Response $response)
|
||||
{
|
||||
try {
|
||||
$this->store->write($request, $response);
|
||||
|
||||
$this->record($request, 'store');
|
||||
|
||||
$response->headers->set('Age', $response->getAge());
|
||||
} catch (\Exception $e) {
|
||||
$this->record($request, 'store-failed');
|
||||
|
||||
if ($this->options['debug']) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
// now that the response is cached, release the lock
|
||||
$this->store->unlock($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the Response body.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param Response $response A Response instance
|
||||
*
|
||||
* @return Response A Response instance
|
||||
*/
|
||||
private function restoreResponseBody(Request $request, Response $response)
|
||||
{
|
||||
if ($request->isMethod('HEAD') || 304 === $response->getStatusCode()) {
|
||||
$response->setContent(null);
|
||||
$response->headers->remove('X-Body-Eval');
|
||||
$response->headers->remove('X-Body-File');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($response->headers->has('X-Body-Eval')) {
|
||||
ob_start();
|
||||
|
||||
if ($response->headers->has('X-Body-File')) {
|
||||
include $response->headers->get('X-Body-File');
|
||||
} else {
|
||||
eval('; ?>'.$response->getContent().'<?php ;');
|
||||
}
|
||||
|
||||
$response->setContent(ob_get_clean());
|
||||
$response->headers->remove('X-Body-Eval');
|
||||
if (!$response->headers->has('Transfer-Encoding')) {
|
||||
$response->headers->set('Content-Length', strlen($response->getContent()));
|
||||
}
|
||||
} elseif ($response->headers->has('X-Body-File')) {
|
||||
$response->setContent(file_get_contents($response->headers->get('X-Body-File')));
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
$response->headers->remove('X-Body-File');
|
||||
}
|
||||
|
||||
protected function processResponseBody(Request $request, Response $response)
|
||||
{
|
||||
if (null !== $this->esi && $this->esi->needsEsiParsing($response)) {
|
||||
$this->esi->process($request, $response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the Request includes authorization or other sensitive information
|
||||
* that should cause the Response to be considered private by default.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
*
|
||||
* @return Boolean true if the Request is private, false otherwise
|
||||
*/
|
||||
private function isPrivateRequest(Request $request)
|
||||
{
|
||||
foreach ($this->options['private_headers'] as $key) {
|
||||
$key = strtolower(str_replace('HTTP_', '', $key));
|
||||
|
||||
if ('cookie' === $key) {
|
||||
if (count($request->cookies->all())) {
|
||||
return true;
|
||||
}
|
||||
} elseif ($request->headers->has($key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Records that an event took place.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param string $event The event name
|
||||
*/
|
||||
private function record(Request $request, $event)
|
||||
{
|
||||
$path = $request->getPathInfo();
|
||||
if ($qs = $request->getQueryString()) {
|
||||
$path .= '?'.$qs;
|
||||
}
|
||||
$this->traces[$request->getMethod().' '.$path][] = $event;
|
||||
}
|
||||
}
|
429
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/Store.php
vendored
Normal file
429
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/Store.php
vendored
Normal file
@@ -0,0 +1,429 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This code is partially based on the Rack-Cache library by Ryan Tomayko,
|
||||
* which is released under the MIT license.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\HttpCache;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* Store implements all the logic for storing cache metadata (Request and Response headers).
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Store implements StoreInterface
|
||||
{
|
||||
protected $root;
|
||||
private $keyCache;
|
||||
private $locks;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $root The path to the cache directory
|
||||
*/
|
||||
public function __construct($root)
|
||||
{
|
||||
$this->root = $root;
|
||||
if (!is_dir($this->root)) {
|
||||
mkdir($this->root, 0777, true);
|
||||
}
|
||||
$this->keyCache = new \SplObjectStorage();
|
||||
$this->locks = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanups storage.
|
||||
*/
|
||||
public function cleanup()
|
||||
{
|
||||
// unlock everything
|
||||
foreach ($this->locks as $lock) {
|
||||
@unlink($lock);
|
||||
}
|
||||
|
||||
$error = error_get_last();
|
||||
if (1 === $error['type'] && false === headers_sent()) {
|
||||
// send a 503
|
||||
header('HTTP/1.0 503 Service Unavailable');
|
||||
header('Retry-After: 10');
|
||||
echo '503 Service Unavailable';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks the cache for a given Request.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
*
|
||||
* @return Boolean|string true if the lock is acquired, the path to the current lock otherwise
|
||||
*/
|
||||
public function lock(Request $request)
|
||||
{
|
||||
$path = $this->getPath($this->getCacheKey($request).'.lck');
|
||||
if (!is_dir(dirname($path)) && false === @mkdir(dirname($path), 0777, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$lock = @fopen($path, 'x');
|
||||
if (false !== $lock) {
|
||||
fclose($lock);
|
||||
|
||||
$this->locks[] = $path;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return !file_exists($path) ?: $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the lock for the given Request.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
*
|
||||
* @return Boolean False if the lock file does not exist or cannot be unlocked, true otherwise
|
||||
*/
|
||||
public function unlock(Request $request)
|
||||
{
|
||||
$file = $this->getPath($this->getCacheKey($request).'.lck');
|
||||
|
||||
return is_file($file) ? @unlink($file) : false;
|
||||
}
|
||||
|
||||
public function isLocked(Request $request)
|
||||
{
|
||||
return is_file($this->getPath($this->getCacheKey($request).'.lck'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates a cached Response for the Request provided.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
*
|
||||
* @return Response|null A Response instance, or null if no cache entry was found
|
||||
*/
|
||||
public function lookup(Request $request)
|
||||
{
|
||||
$key = $this->getCacheKey($request);
|
||||
|
||||
if (!$entries = $this->getMetadata($key)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// find a cached entry that matches the request.
|
||||
$match = null;
|
||||
foreach ($entries as $entry) {
|
||||
if ($this->requestsMatch(isset($entry[1]['vary'][0]) ? $entry[1]['vary'][0] : '', $request->headers->all(), $entry[0])) {
|
||||
$match = $entry;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (null === $match) {
|
||||
return null;
|
||||
}
|
||||
|
||||
list($req, $headers) = $match;
|
||||
if (is_file($body = $this->getPath($headers['x-content-digest'][0]))) {
|
||||
return $this->restoreResponse($headers, $body);
|
||||
}
|
||||
|
||||
// TODO the metaStore referenced an entity that doesn't exist in
|
||||
// the entityStore. We definitely want to return nil but we should
|
||||
// also purge the entry from the meta-store when this is detected.
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a cache entry to the store for the given Request and Response.
|
||||
*
|
||||
* Existing entries are read and any that match the response are removed. This
|
||||
* method calls write with the new list of cache entries.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param Response $response A Response instance
|
||||
*
|
||||
* @return string The key under which the response is stored
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function write(Request $request, Response $response)
|
||||
{
|
||||
$key = $this->getCacheKey($request);
|
||||
$storedEnv = $this->persistRequest($request);
|
||||
|
||||
// write the response body to the entity store if this is the original response
|
||||
if (!$response->headers->has('X-Content-Digest')) {
|
||||
$digest = $this->generateContentDigest($response);
|
||||
|
||||
if (false === $this->save($digest, $response->getContent())) {
|
||||
throw new \RuntimeException('Unable to store the entity.');
|
||||
}
|
||||
|
||||
$response->headers->set('X-Content-Digest', $digest);
|
||||
|
||||
if (!$response->headers->has('Transfer-Encoding')) {
|
||||
$response->headers->set('Content-Length', strlen($response->getContent()));
|
||||
}
|
||||
}
|
||||
|
||||
// read existing cache entries, remove non-varying, and add this one to the list
|
||||
$entries = array();
|
||||
$vary = $response->headers->get('vary');
|
||||
foreach ($this->getMetadata($key) as $entry) {
|
||||
if (!isset($entry[1]['vary'][0])) {
|
||||
$entry[1]['vary'] = array('');
|
||||
}
|
||||
|
||||
if ($vary != $entry[1]['vary'][0] || !$this->requestsMatch($vary, $entry[0], $storedEnv)) {
|
||||
$entries[] = $entry;
|
||||
}
|
||||
}
|
||||
|
||||
$headers = $this->persistResponse($response);
|
||||
unset($headers['age']);
|
||||
|
||||
array_unshift($entries, array($storedEnv, $headers));
|
||||
|
||||
if (false === $this->save($key, serialize($entries))) {
|
||||
throw new \RuntimeException('Unable to store the metadata.');
|
||||
}
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns content digest for $response.
|
||||
*
|
||||
* @param Response $response
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function generateContentDigest(Response $response)
|
||||
{
|
||||
return 'en'.sha1($response->getContent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates all cache entries that match the request.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function invalidate(Request $request)
|
||||
{
|
||||
$modified = false;
|
||||
$key = $this->getCacheKey($request);
|
||||
|
||||
$entries = array();
|
||||
foreach ($this->getMetadata($key) as $entry) {
|
||||
$response = $this->restoreResponse($entry[1]);
|
||||
if ($response->isFresh()) {
|
||||
$response->expire();
|
||||
$modified = true;
|
||||
$entries[] = array($entry[0], $this->persistResponse($response));
|
||||
} else {
|
||||
$entries[] = $entry;
|
||||
}
|
||||
}
|
||||
|
||||
if ($modified) {
|
||||
if (false === $this->save($key, serialize($entries))) {
|
||||
throw new \RuntimeException('Unable to store the metadata.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether two Request HTTP header sets are non-varying based on
|
||||
* the vary response header value provided.
|
||||
*
|
||||
* @param string $vary A Response vary header
|
||||
* @param array $env1 A Request HTTP header array
|
||||
* @param array $env2 A Request HTTP header array
|
||||
*
|
||||
* @return Boolean true if the two environments match, false otherwise
|
||||
*/
|
||||
private function requestsMatch($vary, $env1, $env2)
|
||||
{
|
||||
if (empty($vary)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach (preg_split('/[\s,]+/', $vary) as $header) {
|
||||
$key = strtr(strtolower($header), '_', '-');
|
||||
$v1 = isset($env1[$key]) ? $env1[$key] : null;
|
||||
$v2 = isset($env2[$key]) ? $env2[$key] : null;
|
||||
if ($v1 !== $v2) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all data associated with the given key.
|
||||
*
|
||||
* Use this method only if you know what you are doing.
|
||||
*
|
||||
* @param string $key The store key
|
||||
*
|
||||
* @return array An array of data associated with the key
|
||||
*/
|
||||
private function getMetadata($key)
|
||||
{
|
||||
if (false === $entries = $this->load($key)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
return unserialize($entries);
|
||||
}
|
||||
|
||||
/**
|
||||
* Purges data for the given URL.
|
||||
*
|
||||
* @param string $url A URL
|
||||
*
|
||||
* @return Boolean true if the URL exists and has been purged, false otherwise
|
||||
*/
|
||||
public function purge($url)
|
||||
{
|
||||
if (is_file($path = $this->getPath($this->getCacheKey(Request::create($url))))) {
|
||||
unlink($path);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads data for the given key.
|
||||
*
|
||||
* @param string $key The store key
|
||||
*
|
||||
* @return string The data associated with the key
|
||||
*/
|
||||
private function load($key)
|
||||
{
|
||||
$path = $this->getPath($key);
|
||||
|
||||
return is_file($path) ? file_get_contents($path) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save data for the given key.
|
||||
*
|
||||
* @param string $key The store key
|
||||
* @param string $data The data to store
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
private function save($key, $data)
|
||||
{
|
||||
$path = $this->getPath($key);
|
||||
if (!is_dir(dirname($path)) && false === @mkdir(dirname($path), 0777, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$tmpFile = tempnam(dirname($path), basename($path));
|
||||
if (false === $fp = @fopen($tmpFile, 'wb')) {
|
||||
return false;
|
||||
}
|
||||
@fwrite($fp, $data);
|
||||
@fclose($fp);
|
||||
|
||||
if ($data != file_get_contents($tmpFile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (false === @rename($tmpFile, $path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@chmod($path, 0666 & ~umask());
|
||||
}
|
||||
|
||||
public function getPath($key)
|
||||
{
|
||||
return $this->root.DIRECTORY_SEPARATOR.substr($key, 0, 2).DIRECTORY_SEPARATOR.substr($key, 2, 2).DIRECTORY_SEPARATOR.substr($key, 4, 2).DIRECTORY_SEPARATOR.substr($key, 6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cache key for the given Request.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
*
|
||||
* @return string A key for the given Request
|
||||
*/
|
||||
private function getCacheKey(Request $request)
|
||||
{
|
||||
if (isset($this->keyCache[$request])) {
|
||||
return $this->keyCache[$request];
|
||||
}
|
||||
|
||||
return $this->keyCache[$request] = 'md'.sha1($request->getUri());
|
||||
}
|
||||
|
||||
/**
|
||||
* Persists the Request HTTP headers.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
*
|
||||
* @return array An array of HTTP headers
|
||||
*/
|
||||
private function persistRequest(Request $request)
|
||||
{
|
||||
return $request->headers->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Persists the Response HTTP headers.
|
||||
*
|
||||
* @param Response $response A Response instance
|
||||
*
|
||||
* @return array An array of HTTP headers
|
||||
*/
|
||||
private function persistResponse(Response $response)
|
||||
{
|
||||
$headers = $response->headers->all();
|
||||
$headers['X-Status'] = array($response->getStatusCode());
|
||||
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores a Response from the HTTP headers and body.
|
||||
*
|
||||
* @param array $headers An array of HTTP headers for the Response
|
||||
* @param string $body The Response body
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
private function restoreResponse($headers, $body = null)
|
||||
{
|
||||
$status = $headers['X-Status'][0];
|
||||
unset($headers['X-Status']);
|
||||
|
||||
if (null !== $body) {
|
||||
$headers['X-Body-File'] = array($body);
|
||||
}
|
||||
|
||||
return new Response($body, $status, $headers);
|
||||
}
|
||||
}
|
96
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/StoreInterface.php
vendored
Normal file
96
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpCache/StoreInterface.php
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This code is partially based on the Rack-Cache library by Ryan Tomayko,
|
||||
* which is released under the MIT license.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\HttpCache;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* Interface implemented by HTTP cache stores.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface StoreInterface
|
||||
{
|
||||
/**
|
||||
* Locates a cached Response for the Request provided.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
*
|
||||
* @return Response|null A Response instance, or null if no cache entry was found
|
||||
*/
|
||||
public function lookup(Request $request);
|
||||
|
||||
/**
|
||||
* Writes a cache entry to the store for the given Request and Response.
|
||||
*
|
||||
* Existing entries are read and any that match the response are removed. This
|
||||
* method calls write with the new list of cache entries.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param Response $response A Response instance
|
||||
*
|
||||
* @return string The key under which the response is stored
|
||||
*/
|
||||
public function write(Request $request, Response $response);
|
||||
|
||||
/**
|
||||
* Invalidates all cache entries that match the request.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
*/
|
||||
public function invalidate(Request $request);
|
||||
|
||||
/**
|
||||
* Locks the cache for a given Request.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
*
|
||||
* @return Boolean|string true if the lock is acquired, the path to the current lock otherwise
|
||||
*/
|
||||
public function lock(Request $request);
|
||||
|
||||
/**
|
||||
* Releases the lock for the given Request.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
*
|
||||
* @return Boolean False if the lock file does not exist or cannot be unlocked, true otherwise
|
||||
*/
|
||||
public function unlock(Request $request);
|
||||
|
||||
/**
|
||||
* Returns whether or not a lock exists.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
*
|
||||
* @return Boolean true if lock exists, false otherwise
|
||||
*/
|
||||
public function isLocked(Request $request);
|
||||
|
||||
/**
|
||||
* Purges data for the given URL.
|
||||
*
|
||||
* @param string $url A URL
|
||||
*
|
||||
* @return Boolean true if the URL exists and has been purged, false otherwise
|
||||
*/
|
||||
public function purge($url);
|
||||
|
||||
/**
|
||||
* Cleanups storage.
|
||||
*/
|
||||
public function cleanup();
|
||||
}
|
243
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernel.php
vendored
Normal file
243
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernel.php
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel;
|
||||
|
||||
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
|
||||
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
|
||||
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
|
||||
use Symfony\Component\HttpKernel\Event\PostResponseEvent;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
|
||||
/**
|
||||
* HttpKernel notifies events to convert a Request object to a Response one.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class HttpKernel implements HttpKernelInterface, TerminableInterface
|
||||
{
|
||||
protected $dispatcher;
|
||||
protected $resolver;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
|
||||
* @param ControllerResolverInterface $resolver A ControllerResolverInterface instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver)
|
||||
{
|
||||
$this->dispatcher = $dispatcher;
|
||||
$this->resolver = $resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
|
||||
{
|
||||
try {
|
||||
return $this->handleRaw($request, $type);
|
||||
} catch (\Exception $e) {
|
||||
if (false === $catch) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return $this->handleException($e, $request, $type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function terminate(Request $request, Response $response)
|
||||
{
|
||||
$this->dispatcher->dispatch(KernelEvents::TERMINATE, new PostResponseEvent($this, $request, $response));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a request to convert it to a response.
|
||||
*
|
||||
* Exceptions are not caught.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST)
|
||||
*
|
||||
* @return Response A Response instance
|
||||
*
|
||||
* @throws \LogicException If one of the listener does not behave as expected
|
||||
* @throws NotFoundHttpException When controller cannot be found
|
||||
*/
|
||||
private function handleRaw(Request $request, $type = self::MASTER_REQUEST)
|
||||
{
|
||||
// request
|
||||
$event = new GetResponseEvent($this, $request, $type);
|
||||
$this->dispatcher->dispatch(KernelEvents::REQUEST, $event);
|
||||
|
||||
if ($event->hasResponse()) {
|
||||
return $this->filterResponse($event->getResponse(), $request, $type);
|
||||
}
|
||||
|
||||
// load controller
|
||||
if (false === $controller = $this->resolver->getController($request)) {
|
||||
throw new NotFoundHttpException(sprintf('Unable to find the controller for path "%s". Maybe you forgot to add the matching route in your routing configuration?', $request->getPathInfo()));
|
||||
}
|
||||
|
||||
$event = new FilterControllerEvent($this, $controller, $request, $type);
|
||||
$this->dispatcher->dispatch(KernelEvents::CONTROLLER, $event);
|
||||
$controller = $event->getController();
|
||||
|
||||
// controller arguments
|
||||
$arguments = $this->resolver->getArguments($request, $controller);
|
||||
|
||||
// call controller
|
||||
$response = call_user_func_array($controller, $arguments);
|
||||
|
||||
// view
|
||||
if (!$response instanceof Response) {
|
||||
$event = new GetResponseForControllerResultEvent($this, $request, $type, $response);
|
||||
$this->dispatcher->dispatch(KernelEvents::VIEW, $event);
|
||||
|
||||
if ($event->hasResponse()) {
|
||||
$response = $event->getResponse();
|
||||
}
|
||||
|
||||
if (!$response instanceof Response) {
|
||||
$msg = sprintf('The controller must return a response (%s given).', $this->varToString($response));
|
||||
|
||||
// the user may have forgotten to return something
|
||||
if (null === $response) {
|
||||
$msg .= ' Did you forget to add a return statement somewhere in your controller?';
|
||||
}
|
||||
throw new \LogicException($msg);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->filterResponse($response, $request, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters a response object.
|
||||
*
|
||||
* @param Response $response A Response instance
|
||||
* @param Request $request An error message in case the response is not a Response object
|
||||
* @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST)
|
||||
*
|
||||
* @return Response The filtered Response instance
|
||||
*
|
||||
* @throws \RuntimeException if the passed object is not a Response instance
|
||||
*/
|
||||
private function filterResponse(Response $response, Request $request, $type)
|
||||
{
|
||||
$event = new FilterResponseEvent($this, $request, $type, $response);
|
||||
|
||||
$this->dispatcher->dispatch(KernelEvents::RESPONSE, $event);
|
||||
|
||||
return $event->getResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles an exception by trying to convert it to a Response.
|
||||
*
|
||||
* @param \Exception $e An \Exception instance
|
||||
* @param Request $request A Request instance
|
||||
* @param integer $type The type of the request
|
||||
*
|
||||
* @return Response A Response instance
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function handleException(\Exception $e, $request, $type)
|
||||
{
|
||||
$event = new GetResponseForExceptionEvent($this, $request, $type, $e);
|
||||
$this->dispatcher->dispatch(KernelEvents::EXCEPTION, $event);
|
||||
|
||||
// a listener might have replaced the exception
|
||||
$e = $event->getException();
|
||||
|
||||
if (!$event->hasResponse()) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$response = $event->getResponse();
|
||||
|
||||
// the developer asked for a specific status code
|
||||
if ($response->headers->has('X-Status-Code')) {
|
||||
$response->setStatusCode($response->headers->get('X-Status-Code'));
|
||||
|
||||
$response->headers->remove('X-Status-Code');
|
||||
} elseif (!$response->isClientError() && !$response->isServerError() && !$response->isRedirect()) {
|
||||
// ensure that we actually have an error response
|
||||
if ($e instanceof HttpExceptionInterface) {
|
||||
// keep the HTTP status code and headers
|
||||
$response->setStatusCode($e->getStatusCode());
|
||||
$response->headers->add($e->getHeaders());
|
||||
} else {
|
||||
$response->setStatusCode(500);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return $this->filterResponse($response, $request, $type);
|
||||
} catch (\Exception $e) {
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
private function varToString($var)
|
||||
{
|
||||
if (is_object($var)) {
|
||||
return sprintf('Object(%s)', get_class($var));
|
||||
}
|
||||
|
||||
if (is_array($var)) {
|
||||
$a = array();
|
||||
foreach ($var as $k => $v) {
|
||||
$a[] = sprintf('%s => %s', $k, $this->varToString($v));
|
||||
}
|
||||
|
||||
return sprintf("Array(%s)", implode(', ', $a));
|
||||
}
|
||||
|
||||
if (is_resource($var)) {
|
||||
return sprintf('Resource(%s)', get_resource_type($var));
|
||||
}
|
||||
|
||||
if (null === $var) {
|
||||
return 'null';
|
||||
}
|
||||
|
||||
if (false === $var) {
|
||||
return 'false';
|
||||
}
|
||||
|
||||
if (true === $var) {
|
||||
return 'true';
|
||||
}
|
||||
|
||||
return (string) $var;
|
||||
}
|
||||
}
|
47
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernelInterface.php
vendored
Normal file
47
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernelInterface.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* HttpKernelInterface handles a Request to convert it to a Response.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
interface HttpKernelInterface
|
||||
{
|
||||
const MASTER_REQUEST = 1;
|
||||
const SUB_REQUEST = 2;
|
||||
|
||||
/**
|
||||
* Handles a Request to convert it to a Response.
|
||||
*
|
||||
* When $catch is true, the implementation must catch all exceptions
|
||||
* and do its best to convert them to a Response instance.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param integer $type The type of the request
|
||||
* (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST)
|
||||
* @param Boolean $catch Whether to catch exceptions or not
|
||||
*
|
||||
* @return Response A Response instance
|
||||
*
|
||||
* @throws \Exception When an Exception occurs during processing
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true);
|
||||
}
|
793
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Kernel.php
vendored
Normal file
793
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Kernel.php
vendored
Normal file
@@ -0,0 +1,793 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel;
|
||||
|
||||
use Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator;
|
||||
use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
|
||||
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
|
||||
use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
|
||||
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
|
||||
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
|
||||
use Symfony\Component\HttpKernel\Config\FileLocator;
|
||||
use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass;
|
||||
use Symfony\Component\HttpKernel\DependencyInjection\AddClassesToCachePass;
|
||||
use Symfony\Component\Config\Loader\LoaderResolver;
|
||||
use Symfony\Component\Config\Loader\DelegatingLoader;
|
||||
use Symfony\Component\Config\ConfigCache;
|
||||
use Symfony\Component\ClassLoader\ClassCollectionLoader;
|
||||
|
||||
/**
|
||||
* The Kernel is the heart of the Symfony system.
|
||||
*
|
||||
* It manages an environment made of bundles.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
abstract class Kernel implements KernelInterface, TerminableInterface
|
||||
{
|
||||
/**
|
||||
* @var BundleInterface[]
|
||||
*/
|
||||
protected $bundles;
|
||||
|
||||
protected $bundleMap;
|
||||
protected $container;
|
||||
protected $rootDir;
|
||||
protected $environment;
|
||||
protected $debug;
|
||||
protected $booted;
|
||||
protected $name;
|
||||
protected $startTime;
|
||||
protected $loadClassCache;
|
||||
|
||||
const VERSION = '2.3.5-DEV';
|
||||
const VERSION_ID = '20305';
|
||||
const MAJOR_VERSION = '2';
|
||||
const MINOR_VERSION = '3';
|
||||
const RELEASE_VERSION = '5';
|
||||
const EXTRA_VERSION = 'DEV';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $environment The environment
|
||||
* @param Boolean $debug Whether to enable debugging or not
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __construct($environment, $debug)
|
||||
{
|
||||
$this->environment = $environment;
|
||||
$this->debug = (Boolean) $debug;
|
||||
$this->booted = false;
|
||||
$this->rootDir = $this->getRootDir();
|
||||
$this->name = $this->getName();
|
||||
$this->bundles = array();
|
||||
|
||||
if ($this->debug) {
|
||||
$this->startTime = microtime(true);
|
||||
}
|
||||
|
||||
$this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated since version 2.3, to be removed in 3.0. Move your logic in the constructor instead.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
}
|
||||
|
||||
public function __clone()
|
||||
{
|
||||
if ($this->debug) {
|
||||
$this->startTime = microtime(true);
|
||||
}
|
||||
|
||||
$this->booted = false;
|
||||
$this->container = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Boots the current kernel.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
if (true === $this->booted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->loadClassCache) {
|
||||
$this->doLoadClassCache($this->loadClassCache[0], $this->loadClassCache[1]);
|
||||
}
|
||||
|
||||
// init bundles
|
||||
$this->initializeBundles();
|
||||
|
||||
// init container
|
||||
$this->initializeContainer();
|
||||
|
||||
foreach ($this->getBundles() as $bundle) {
|
||||
$bundle->setContainer($this->container);
|
||||
$bundle->boot();
|
||||
}
|
||||
|
||||
$this->booted = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function terminate(Request $request, Response $response)
|
||||
{
|
||||
if (false === $this->booted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->getHttpKernel() instanceof TerminableInterface) {
|
||||
$this->getHttpKernel()->terminate($request, $response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function shutdown()
|
||||
{
|
||||
if (false === $this->booted) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->booted = false;
|
||||
|
||||
foreach ($this->getBundles() as $bundle) {
|
||||
$bundle->shutdown();
|
||||
$bundle->setContainer(null);
|
||||
}
|
||||
|
||||
$this->container = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
|
||||
{
|
||||
if (false === $this->booted) {
|
||||
$this->boot();
|
||||
}
|
||||
|
||||
return $this->getHttpKernel()->handle($request, $type, $catch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a http kernel from the container
|
||||
*
|
||||
* @return HttpKernel
|
||||
*/
|
||||
protected function getHttpKernel()
|
||||
{
|
||||
return $this->container->get('http_kernel');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getBundles()
|
||||
{
|
||||
return $this->bundles;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function isClassInActiveBundle($class)
|
||||
{
|
||||
foreach ($this->getBundles() as $bundle) {
|
||||
if (0 === strpos($class, $bundle->getNamespace())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getBundle($name, $first = true)
|
||||
{
|
||||
if (!isset($this->bundleMap[$name])) {
|
||||
throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled. Maybe you forgot to add it in the registerBundles() method of your %s.php file?', $name, get_class($this)));
|
||||
}
|
||||
|
||||
if (true === $first) {
|
||||
return $this->bundleMap[$name][0];
|
||||
}
|
||||
|
||||
return $this->bundleMap[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file path for a given resource.
|
||||
*
|
||||
* A Resource can be a file or a directory.
|
||||
*
|
||||
* The resource name must follow the following pattern:
|
||||
*
|
||||
* @<BundleName>/path/to/a/file.something
|
||||
*
|
||||
* where BundleName is the name of the bundle
|
||||
* and the remaining part is the relative path in the bundle.
|
||||
*
|
||||
* If $dir is passed, and the first segment of the path is "Resources",
|
||||
* this method will look for a file named:
|
||||
*
|
||||
* $dir/<BundleName>/path/without/Resources
|
||||
*
|
||||
* before looking in the bundle resource folder.
|
||||
*
|
||||
* @param string $name A resource name to locate
|
||||
* @param string $dir A directory where to look for the resource first
|
||||
* @param Boolean $first Whether to return the first path or paths for all matching bundles
|
||||
*
|
||||
* @return string|array The absolute path of the resource or an array if $first is false
|
||||
*
|
||||
* @throws \InvalidArgumentException if the file cannot be found or the name is not valid
|
||||
* @throws \RuntimeException if the name contains invalid/unsafe
|
||||
* @throws \RuntimeException if a custom resource is hidden by a resource in a derived bundle
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function locateResource($name, $dir = null, $first = true)
|
||||
{
|
||||
if ('@' !== $name[0]) {
|
||||
throw new \InvalidArgumentException(sprintf('A resource name must start with @ ("%s" given).', $name));
|
||||
}
|
||||
|
||||
if (false !== strpos($name, '..')) {
|
||||
throw new \RuntimeException(sprintf('File name "%s" contains invalid characters (..).', $name));
|
||||
}
|
||||
|
||||
$bundleName = substr($name, 1);
|
||||
$path = '';
|
||||
if (false !== strpos($bundleName, '/')) {
|
||||
list($bundleName, $path) = explode('/', $bundleName, 2);
|
||||
}
|
||||
|
||||
$isResource = 0 === strpos($path, 'Resources') && null !== $dir;
|
||||
$overridePath = substr($path, 9);
|
||||
$resourceBundle = null;
|
||||
$bundles = $this->getBundle($bundleName, false);
|
||||
$files = array();
|
||||
|
||||
foreach ($bundles as $bundle) {
|
||||
if ($isResource && file_exists($file = $dir.'/'.$bundle->getName().$overridePath)) {
|
||||
if (null !== $resourceBundle) {
|
||||
throw new \RuntimeException(sprintf('"%s" resource is hidden by a resource from the "%s" derived bundle. Create a "%s" file to override the bundle resource.',
|
||||
$file,
|
||||
$resourceBundle,
|
||||
$dir.'/'.$bundles[0]->getName().$overridePath
|
||||
));
|
||||
}
|
||||
|
||||
if ($first) {
|
||||
return $file;
|
||||
}
|
||||
$files[] = $file;
|
||||
}
|
||||
|
||||
if (file_exists($file = $bundle->getPath().'/'.$path)) {
|
||||
if ($first && !$isResource) {
|
||||
return $file;
|
||||
}
|
||||
$files[] = $file;
|
||||
$resourceBundle = $bundle->getName();
|
||||
}
|
||||
}
|
||||
|
||||
if (count($files) > 0) {
|
||||
return $first && $isResource ? $files[0] : $files;
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException(sprintf('Unable to find file "%s".', $name));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
if (null === $this->name) {
|
||||
$this->name = preg_replace('/[^a-zA-Z0-9_]+/', '', basename($this->rootDir));
|
||||
}
|
||||
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getEnvironment()
|
||||
{
|
||||
return $this->environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function isDebug()
|
||||
{
|
||||
return $this->debug;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getRootDir()
|
||||
{
|
||||
if (null === $this->rootDir) {
|
||||
$r = new \ReflectionObject($this);
|
||||
$this->rootDir = str_replace('\\', '/', dirname($r->getFileName()));
|
||||
}
|
||||
|
||||
return $this->rootDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getContainer()
|
||||
{
|
||||
return $this->container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the PHP class cache.
|
||||
*
|
||||
* This methods only registers the fact that you want to load the cache classes.
|
||||
* The cache will actually only be loaded when the Kernel is booted.
|
||||
*
|
||||
* That optimization is mainly useful when using the HttpCache class in which
|
||||
* case the class cache is not loaded if the Response is in the cache.
|
||||
*
|
||||
* @param string $name The cache name prefix
|
||||
* @param string $extension File extension of the resulting file
|
||||
*/
|
||||
public function loadClassCache($name = 'classes', $extension = '.php')
|
||||
{
|
||||
$this->loadClassCache = array($name, $extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used internally.
|
||||
*/
|
||||
public function setClassCache(array $classes)
|
||||
{
|
||||
file_put_contents($this->getCacheDir().'/classes.map', sprintf('<?php return %s;', var_export($classes, true)));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getStartTime()
|
||||
{
|
||||
return $this->debug ? $this->startTime : -INF;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getCacheDir()
|
||||
{
|
||||
return $this->rootDir.'/cache/'.$this->environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getLogDir()
|
||||
{
|
||||
return $this->rootDir.'/logs';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getCharset()
|
||||
{
|
||||
return 'UTF-8';
|
||||
}
|
||||
|
||||
protected function doLoadClassCache($name, $extension)
|
||||
{
|
||||
if (!$this->booted && is_file($this->getCacheDir().'/classes.map')) {
|
||||
ClassCollectionLoader::load(include($this->getCacheDir().'/classes.map'), $this->getCacheDir(), $name, $this->debug, false, $extension);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the data structures related to the bundle management.
|
||||
*
|
||||
* - the bundles property maps a bundle name to the bundle instance,
|
||||
* - the bundleMap property maps a bundle name to the bundle inheritance hierarchy (most derived bundle first).
|
||||
*
|
||||
* @throws \LogicException if two bundles share a common name
|
||||
* @throws \LogicException if a bundle tries to extend a non-registered bundle
|
||||
* @throws \LogicException if a bundle tries to extend itself
|
||||
* @throws \LogicException if two bundles extend the same ancestor
|
||||
*/
|
||||
protected function initializeBundles()
|
||||
{
|
||||
// init bundles
|
||||
$this->bundles = array();
|
||||
$topMostBundles = array();
|
||||
$directChildren = array();
|
||||
|
||||
foreach ($this->registerBundles() as $bundle) {
|
||||
$name = $bundle->getName();
|
||||
if (isset($this->bundles[$name])) {
|
||||
throw new \LogicException(sprintf('Trying to register two bundles with the same name "%s"', $name));
|
||||
}
|
||||
$this->bundles[$name] = $bundle;
|
||||
|
||||
if ($parentName = $bundle->getParent()) {
|
||||
if (isset($directChildren[$parentName])) {
|
||||
throw new \LogicException(sprintf('Bundle "%s" is directly extended by two bundles "%s" and "%s".', $parentName, $name, $directChildren[$parentName]));
|
||||
}
|
||||
if ($parentName == $name) {
|
||||
throw new \LogicException(sprintf('Bundle "%s" can not extend itself.', $name));
|
||||
}
|
||||
$directChildren[$parentName] = $name;
|
||||
} else {
|
||||
$topMostBundles[$name] = $bundle;
|
||||
}
|
||||
}
|
||||
|
||||
// look for orphans
|
||||
if (count($diff = array_values(array_diff(array_keys($directChildren), array_keys($this->bundles))))) {
|
||||
throw new \LogicException(sprintf('Bundle "%s" extends bundle "%s", which is not registered.', $directChildren[$diff[0]], $diff[0]));
|
||||
}
|
||||
|
||||
// inheritance
|
||||
$this->bundleMap = array();
|
||||
foreach ($topMostBundles as $name => $bundle) {
|
||||
$bundleMap = array($bundle);
|
||||
$hierarchy = array($name);
|
||||
|
||||
while (isset($directChildren[$name])) {
|
||||
$name = $directChildren[$name];
|
||||
array_unshift($bundleMap, $this->bundles[$name]);
|
||||
$hierarchy[] = $name;
|
||||
}
|
||||
|
||||
foreach ($hierarchy as $bundle) {
|
||||
$this->bundleMap[$bundle] = $bundleMap;
|
||||
array_pop($bundleMap);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the container class.
|
||||
*
|
||||
* @return string The container class
|
||||
*/
|
||||
protected function getContainerClass()
|
||||
{
|
||||
return $this->name.ucfirst($this->environment).($this->debug ? 'Debug' : '').'ProjectContainer';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the container's base class.
|
||||
*
|
||||
* All names except Container must be fully qualified.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getContainerBaseClass()
|
||||
{
|
||||
return 'Container';
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the service container.
|
||||
*
|
||||
* The cached version of the service container is used when fresh, otherwise the
|
||||
* container is built.
|
||||
*/
|
||||
protected function initializeContainer()
|
||||
{
|
||||
$class = $this->getContainerClass();
|
||||
$cache = new ConfigCache($this->getCacheDir().'/'.$class.'.php', $this->debug);
|
||||
$fresh = true;
|
||||
if (!$cache->isFresh()) {
|
||||
$container = $this->buildContainer();
|
||||
$container->compile();
|
||||
$this->dumpContainer($cache, $container, $class, $this->getContainerBaseClass());
|
||||
|
||||
$fresh = false;
|
||||
}
|
||||
|
||||
require_once $cache;
|
||||
|
||||
$this->container = new $class();
|
||||
$this->container->set('kernel', $this);
|
||||
|
||||
if (!$fresh && $this->container->has('cache_warmer')) {
|
||||
$this->container->get('cache_warmer')->warmUp($this->container->getParameter('kernel.cache_dir'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the kernel parameters.
|
||||
*
|
||||
* @return array An array of kernel parameters
|
||||
*/
|
||||
protected function getKernelParameters()
|
||||
{
|
||||
$bundles = array();
|
||||
foreach ($this->bundles as $name => $bundle) {
|
||||
$bundles[$name] = get_class($bundle);
|
||||
}
|
||||
|
||||
return array_merge(
|
||||
array(
|
||||
'kernel.root_dir' => $this->rootDir,
|
||||
'kernel.environment' => $this->environment,
|
||||
'kernel.debug' => $this->debug,
|
||||
'kernel.name' => $this->name,
|
||||
'kernel.cache_dir' => $this->getCacheDir(),
|
||||
'kernel.logs_dir' => $this->getLogDir(),
|
||||
'kernel.bundles' => $bundles,
|
||||
'kernel.charset' => $this->getCharset(),
|
||||
'kernel.container_class' => $this->getContainerClass(),
|
||||
),
|
||||
$this->getEnvParameters()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the environment parameters.
|
||||
*
|
||||
* Only the parameters starting with "SYMFONY__" are considered.
|
||||
*
|
||||
* @return array An array of parameters
|
||||
*/
|
||||
protected function getEnvParameters()
|
||||
{
|
||||
$parameters = array();
|
||||
foreach ($_SERVER as $key => $value) {
|
||||
if (0 === strpos($key, 'SYMFONY__')) {
|
||||
$parameters[strtolower(str_replace('__', '.', substr($key, 9)))] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the service container.
|
||||
*
|
||||
* @return ContainerBuilder The compiled service container
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function buildContainer()
|
||||
{
|
||||
foreach (array('cache' => $this->getCacheDir(), 'logs' => $this->getLogDir()) as $name => $dir) {
|
||||
if (!is_dir($dir)) {
|
||||
if (false === @mkdir($dir, 0777, true)) {
|
||||
throw new \RuntimeException(sprintf("Unable to create the %s directory (%s)\n", $name, $dir));
|
||||
}
|
||||
} elseif (!is_writable($dir)) {
|
||||
throw new \RuntimeException(sprintf("Unable to write in the %s directory (%s)\n", $name, $dir));
|
||||
}
|
||||
}
|
||||
|
||||
$container = $this->getContainerBuilder();
|
||||
$container->addObjectResource($this);
|
||||
$this->prepareContainer($container);
|
||||
|
||||
if (null !== $cont = $this->registerContainerConfiguration($this->getContainerLoader($container))) {
|
||||
$container->merge($cont);
|
||||
}
|
||||
|
||||
$container->addCompilerPass(new AddClassesToCachePass($this));
|
||||
|
||||
return $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the ContainerBuilder before it is compiled.
|
||||
*
|
||||
* @param ContainerBuilder $container A ContainerBuilder instance
|
||||
*/
|
||||
protected function prepareContainer(ContainerBuilder $container)
|
||||
{
|
||||
$extensions = array();
|
||||
foreach ($this->bundles as $bundle) {
|
||||
if ($extension = $bundle->getContainerExtension()) {
|
||||
$container->registerExtension($extension);
|
||||
$extensions[] = $extension->getAlias();
|
||||
}
|
||||
|
||||
if ($this->debug) {
|
||||
$container->addObjectResource($bundle);
|
||||
}
|
||||
}
|
||||
foreach ($this->bundles as $bundle) {
|
||||
$bundle->build($container);
|
||||
}
|
||||
|
||||
// ensure these extensions are implicitly loaded
|
||||
$container->getCompilerPassConfig()->setMergePass(new MergeExtensionConfigurationPass($extensions));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a new ContainerBuilder instance used to build the service container.
|
||||
*
|
||||
* @return ContainerBuilder
|
||||
*/
|
||||
protected function getContainerBuilder()
|
||||
{
|
||||
$container = new ContainerBuilder(new ParameterBag($this->getKernelParameters()));
|
||||
|
||||
if (class_exists('ProxyManager\Configuration')) {
|
||||
$container->setProxyInstantiator(new RuntimeInstantiator());
|
||||
}
|
||||
|
||||
return $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the service container to PHP code in the cache.
|
||||
*
|
||||
* @param ConfigCache $cache The config cache
|
||||
* @param ContainerBuilder $container The service container
|
||||
* @param string $class The name of the class to generate
|
||||
* @param string $baseClass The name of the container's base class
|
||||
*/
|
||||
protected function dumpContainer(ConfigCache $cache, ContainerBuilder $container, $class, $baseClass)
|
||||
{
|
||||
// cache the container
|
||||
$dumper = new PhpDumper($container);
|
||||
|
||||
if (class_exists('ProxyManager\Configuration')) {
|
||||
$dumper->setProxyDumper(new ProxyDumper());
|
||||
}
|
||||
|
||||
$content = $dumper->dump(array('class' => $class, 'base_class' => $baseClass));
|
||||
if (!$this->debug) {
|
||||
$content = self::stripComments($content);
|
||||
}
|
||||
|
||||
$cache->write($content, $container->getResources());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a loader for the container.
|
||||
*
|
||||
* @param ContainerInterface $container The service container
|
||||
*
|
||||
* @return DelegatingLoader The loader
|
||||
*/
|
||||
protected function getContainerLoader(ContainerInterface $container)
|
||||
{
|
||||
$locator = new FileLocator($this);
|
||||
$resolver = new LoaderResolver(array(
|
||||
new XmlFileLoader($container, $locator),
|
||||
new YamlFileLoader($container, $locator),
|
||||
new IniFileLoader($container, $locator),
|
||||
new PhpFileLoader($container, $locator),
|
||||
new ClosureLoader($container),
|
||||
));
|
||||
|
||||
return new DelegatingLoader($resolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes comments from a PHP source string.
|
||||
*
|
||||
* We don't use the PHP php_strip_whitespace() function
|
||||
* as we want the content to be readable and well-formatted.
|
||||
*
|
||||
* @param string $source A PHP string
|
||||
*
|
||||
* @return string The PHP string with the comments removed
|
||||
*/
|
||||
public static function stripComments($source)
|
||||
{
|
||||
if (!function_exists('token_get_all')) {
|
||||
return $source;
|
||||
}
|
||||
|
||||
$rawChunk = '';
|
||||
$output = '';
|
||||
$tokens = token_get_all($source);
|
||||
for (reset($tokens); false !== $token = current($tokens); next($tokens)) {
|
||||
if (is_string($token)) {
|
||||
$rawChunk .= $token;
|
||||
} elseif (T_START_HEREDOC === $token[0]) {
|
||||
$output .= preg_replace(array('/\s+$/Sm', '/\n+/S'), "\n", $rawChunk).$token[1];
|
||||
do {
|
||||
$token = next($tokens);
|
||||
$output .= $token[1];
|
||||
} while ($token[0] !== T_END_HEREDOC);
|
||||
$rawChunk = '';
|
||||
} elseif (!in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) {
|
||||
$rawChunk .= $token[1];
|
||||
}
|
||||
}
|
||||
|
||||
// replace multiple new lines with a single newline
|
||||
$output .= preg_replace(array('/\s+$/Sm', '/\n+/S'), "\n", $rawChunk);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function serialize()
|
||||
{
|
||||
return serialize(array($this->environment, $this->debug));
|
||||
}
|
||||
|
||||
public function unserialize($data)
|
||||
{
|
||||
list($environment, $debug) = unserialize($data);
|
||||
|
||||
$this->__construct($environment, $debug);
|
||||
}
|
||||
}
|
105
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/KernelEvents.php
vendored
Normal file
105
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/KernelEvents.php
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel;
|
||||
|
||||
/**
|
||||
* Contains all events thrown in the HttpKernel component
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
final class KernelEvents
|
||||
{
|
||||
/**
|
||||
* The REQUEST event occurs at the very beginning of request
|
||||
* dispatching
|
||||
*
|
||||
* This event allows you to create a response for a request before any
|
||||
* other code in the framework is executed. The event listener method
|
||||
* receives a Symfony\Component\HttpKernel\Event\GetResponseEvent
|
||||
* instance.
|
||||
*
|
||||
* @var string
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
const REQUEST = 'kernel.request';
|
||||
|
||||
/**
|
||||
* The EXCEPTION event occurs when an uncaught exception appears
|
||||
*
|
||||
* This event allows you to create a response for a thrown exception or
|
||||
* to modify the thrown exception. The event listener method receives
|
||||
* a Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent
|
||||
* instance.
|
||||
*
|
||||
* @var string
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
const EXCEPTION = 'kernel.exception';
|
||||
|
||||
/**
|
||||
* The VIEW event occurs when the return value of a controller
|
||||
* is not a Response instance
|
||||
*
|
||||
* This event allows you to create a response for the return value of the
|
||||
* controller. The event listener method receives a
|
||||
* Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent
|
||||
* instance.
|
||||
*
|
||||
* @var string
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
const VIEW = 'kernel.view';
|
||||
|
||||
/**
|
||||
* The CONTROLLER event occurs once a controller was found for
|
||||
* handling a request
|
||||
*
|
||||
* This event allows you to change the controller that will handle the
|
||||
* request. The event listener method receives a
|
||||
* Symfony\Component\HttpKernel\Event\FilterControllerEvent instance.
|
||||
*
|
||||
* @var string
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
const CONTROLLER = 'kernel.controller';
|
||||
|
||||
/**
|
||||
* The RESPONSE event occurs once a response was created for
|
||||
* replying to a request
|
||||
*
|
||||
* This event allows you to modify or replace the response that will be
|
||||
* replied. The event listener method receives a
|
||||
* Symfony\Component\HttpKernel\Event\FilterResponseEvent instance.
|
||||
*
|
||||
* @var string
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
const RESPONSE = 'kernel.response';
|
||||
|
||||
/**
|
||||
* The TERMINATE event occurs once a response was sent
|
||||
*
|
||||
* This event allows you to run expensive post-response jobs.
|
||||
* The event listener method receives a
|
||||
* Symfony\Component\HttpKernel\Event\PostResponseEvent instance.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const TERMINATE = 'kernel.terminate';
|
||||
}
|
208
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/KernelInterface.php
vendored
Normal file
208
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/KernelInterface.php
vendored
Normal file
@@ -0,0 +1,208 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
|
||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||
|
||||
/**
|
||||
* The Kernel is the heart of the Symfony system.
|
||||
*
|
||||
* It manages an environment made of bundles.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
interface KernelInterface extends HttpKernelInterface, \Serializable
|
||||
{
|
||||
/**
|
||||
* Returns an array of bundles to registers.
|
||||
*
|
||||
* @return BundleInterface[] An array of bundle instances.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function registerBundles();
|
||||
|
||||
/**
|
||||
* Loads the container configuration
|
||||
*
|
||||
* @param LoaderInterface $loader A LoaderInterface instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function registerContainerConfiguration(LoaderInterface $loader);
|
||||
|
||||
/**
|
||||
* Boots the current kernel.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function boot();
|
||||
|
||||
/**
|
||||
* Shutdowns the kernel.
|
||||
*
|
||||
* This method is mainly useful when doing functional testing.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function shutdown();
|
||||
|
||||
/**
|
||||
* Gets the registered bundle instances.
|
||||
*
|
||||
* @return BundleInterface[] An array of registered bundle instances
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getBundles();
|
||||
|
||||
/**
|
||||
* Checks if a given class name belongs to an active bundle.
|
||||
*
|
||||
* @param string $class A class name
|
||||
*
|
||||
* @return Boolean true if the class belongs to an active bundle, false otherwise
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function isClassInActiveBundle($class);
|
||||
|
||||
/**
|
||||
* Returns a bundle and optionally its descendants by its name.
|
||||
*
|
||||
* @param string $name Bundle name
|
||||
* @param Boolean $first Whether to return the first bundle only or together with its descendants
|
||||
*
|
||||
* @return BundleInterface|BundleInterface[] A BundleInterface instance or an array of BundleInterface instances if $first is false
|
||||
*
|
||||
* @throws \InvalidArgumentException when the bundle is not enabled
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getBundle($name, $first = true);
|
||||
|
||||
/**
|
||||
* Returns the file path for a given resource.
|
||||
*
|
||||
* A Resource can be a file or a directory.
|
||||
*
|
||||
* The resource name must follow the following pattern:
|
||||
*
|
||||
* @BundleName/path/to/a/file.something
|
||||
*
|
||||
* where BundleName is the name of the bundle
|
||||
* and the remaining part is the relative path in the bundle.
|
||||
*
|
||||
* If $dir is passed, and the first segment of the path is Resources,
|
||||
* this method will look for a file named:
|
||||
*
|
||||
* $dir/BundleName/path/without/Resources
|
||||
*
|
||||
* @param string $name A resource name to locate
|
||||
* @param string $dir A directory where to look for the resource first
|
||||
* @param Boolean $first Whether to return the first path or paths for all matching bundles
|
||||
*
|
||||
* @return string|array The absolute path of the resource or an array if $first is false
|
||||
*
|
||||
* @throws \InvalidArgumentException if the file cannot be found or the name is not valid
|
||||
* @throws \RuntimeException if the name contains invalid/unsafe characters
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function locateResource($name, $dir = null, $first = true);
|
||||
|
||||
/**
|
||||
* Gets the name of the kernel
|
||||
*
|
||||
* @return string The kernel name
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* Gets the environment.
|
||||
*
|
||||
* @return string The current environment
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getEnvironment();
|
||||
|
||||
/**
|
||||
* Checks if debug mode is enabled.
|
||||
*
|
||||
* @return Boolean true if debug mode is enabled, false otherwise
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function isDebug();
|
||||
|
||||
/**
|
||||
* Gets the application root dir.
|
||||
*
|
||||
* @return string The application root dir
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getRootDir();
|
||||
|
||||
/**
|
||||
* Gets the current container.
|
||||
*
|
||||
* @return ContainerInterface A ContainerInterface instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getContainer();
|
||||
|
||||
/**
|
||||
* Gets the request start time (not available if debug is disabled).
|
||||
*
|
||||
* @return integer The request start timestamp
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getStartTime();
|
||||
|
||||
/**
|
||||
* Gets the cache directory.
|
||||
*
|
||||
* @return string The cache directory
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getCacheDir();
|
||||
|
||||
/**
|
||||
* Gets the log directory.
|
||||
*
|
||||
* @return string The log directory
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getLogDir();
|
||||
|
||||
/**
|
||||
* Gets the charset of the application.
|
||||
*
|
||||
* @return string The charset
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getCharset();
|
||||
}
|
19
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/LICENSE
vendored
Normal file
19
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/LICENSE
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2004-2013 Fabien Potencier
|
||||
|
||||
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.
|
38
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Log/DebugLoggerInterface.php
vendored
Normal file
38
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Log/DebugLoggerInterface.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Log;
|
||||
|
||||
/**
|
||||
* DebugLoggerInterface.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface DebugLoggerInterface
|
||||
{
|
||||
/**
|
||||
* Returns an array of logs.
|
||||
*
|
||||
* A log is an array with the following mandatory keys:
|
||||
* timestamp, message, priority, and priorityName.
|
||||
* It can also have an optional context key containing an array.
|
||||
*
|
||||
* @return array An array of logs
|
||||
*/
|
||||
public function getLogs();
|
||||
|
||||
/**
|
||||
* Returns the number of errors.
|
||||
*
|
||||
* @return integer The number of errors
|
||||
*/
|
||||
public function countErrors();
|
||||
}
|
49
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Log/LoggerInterface.php
vendored
Normal file
49
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Log/LoggerInterface.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Log;
|
||||
|
||||
use Psr\Log\LoggerInterface as PsrLogger;
|
||||
|
||||
/**
|
||||
* LoggerInterface.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @deprecated since 2.2, to be removed in 3.0. Type-hint \Psr\Log\LoggerInterface instead.
|
||||
* @api
|
||||
*/
|
||||
interface LoggerInterface extends PsrLogger
|
||||
{
|
||||
/**
|
||||
* @api
|
||||
* @deprecated since 2.2, to be removed in 3.0. Use emergency() which is PSR-3 compatible.
|
||||
*/
|
||||
public function emerg($message, array $context = array());
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @deprecated since 2.2, to be removed in 3.0. Use critical() which is PSR-3 compatible.
|
||||
*/
|
||||
public function crit($message, array $context = array());
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @deprecated since 2.2, to be removed in 3.0. Use error() which is PSR-3 compatible.
|
||||
*/
|
||||
public function err($message, array $context = array());
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @deprecated since 2.2, to be removed in 3.0. Use warning() which is PSR-3 compatible.
|
||||
*/
|
||||
public function warn($message, array $context = array());
|
||||
}
|
56
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Log/NullLogger.php
vendored
Normal file
56
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Log/NullLogger.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Log;
|
||||
|
||||
use Psr\Log\NullLogger as PsrNullLogger;
|
||||
|
||||
/**
|
||||
* NullLogger.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class NullLogger extends PsrNullLogger implements LoggerInterface
|
||||
{
|
||||
/**
|
||||
* @api
|
||||
* @deprecated since 2.2, to be removed in 3.0. Use emergency() which is PSR-3 compatible.
|
||||
*/
|
||||
public function emerg($message, array $context = array())
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @deprecated since 2.2, to be removed in 3.0. Use critical() which is PSR-3 compatible.
|
||||
*/
|
||||
public function crit($message, array $context = array())
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @deprecated since 2.2, to be removed in 3.0. Use error() which is PSR-3 compatible.
|
||||
*/
|
||||
public function err($message, array $context = array())
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @deprecated since 2.2, to be removed in 3.0. Use warning() which is PSR-3 compatible.
|
||||
*/
|
||||
public function warn($message, array $context = array())
|
||||
{
|
||||
}
|
||||
}
|
308
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/BaseMemcacheProfilerStorage.php
vendored
Normal file
308
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/BaseMemcacheProfilerStorage.php
vendored
Normal file
@@ -0,0 +1,308 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
/**
|
||||
* Base Memcache storage for profiling information in a Memcache.
|
||||
*
|
||||
* @author Andrej Hudec <pulzarraider@gmail.com>
|
||||
*/
|
||||
abstract class BaseMemcacheProfilerStorage implements ProfilerStorageInterface
|
||||
{
|
||||
const TOKEN_PREFIX = 'sf_profiler_';
|
||||
|
||||
protected $dsn;
|
||||
protected $lifetime;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $dsn A data source name
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param int $lifetime The lifetime to use for the purge
|
||||
*/
|
||||
public function __construct($dsn, $username = '', $password = '', $lifetime = 86400)
|
||||
{
|
||||
$this->dsn = $dsn;
|
||||
$this->lifetime = (int) $lifetime;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function find($ip, $url, $limit, $method, $start = null, $end = null)
|
||||
{
|
||||
$indexName = $this->getIndexName();
|
||||
|
||||
$indexContent = $this->getValue($indexName);
|
||||
if (!$indexContent) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$profileList = explode("\n", $indexContent);
|
||||
$result = array();
|
||||
|
||||
foreach ($profileList as $item) {
|
||||
|
||||
if ($limit === 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ($item=='') {
|
||||
continue;
|
||||
}
|
||||
|
||||
list($itemToken, $itemIp, $itemMethod, $itemUrl, $itemTime, $itemParent) = explode("\t", $item, 6);
|
||||
|
||||
$itemTime = (int) $itemTime;
|
||||
|
||||
if ($ip && false === strpos($itemIp, $ip) || $url && false === strpos($itemUrl, $url) || $method && false === strpos($itemMethod, $method)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!empty($start) && $itemTime < $start) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!empty($end) && $itemTime > $end) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result[$itemToken] = array(
|
||||
'token' => $itemToken,
|
||||
'ip' => $itemIp,
|
||||
'method' => $itemMethod,
|
||||
'url' => $itemUrl,
|
||||
'time' => $itemTime,
|
||||
'parent' => $itemParent,
|
||||
);
|
||||
--$limit;
|
||||
}
|
||||
|
||||
usort($result, function($a, $b) {
|
||||
if ($a['time'] === $b['time']) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $a['time'] > $b['time'] ? -1 : 1;
|
||||
});
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function purge()
|
||||
{
|
||||
// delete only items from index
|
||||
$indexName = $this->getIndexName();
|
||||
|
||||
$indexContent = $this->getValue($indexName);
|
||||
|
||||
if (!$indexContent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$profileList = explode("\n", $indexContent);
|
||||
|
||||
foreach ($profileList as $item) {
|
||||
if ($item == '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (false !== $pos = strpos($item, "\t")) {
|
||||
$this->delete($this->getItemName(substr($item, 0, $pos)));
|
||||
}
|
||||
}
|
||||
|
||||
return $this->delete($indexName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function read($token)
|
||||
{
|
||||
if (empty($token)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$profile = $this->getValue($this->getItemName($token));
|
||||
|
||||
if (false !== $profile) {
|
||||
$profile = $this->createProfileFromData($token, $profile);
|
||||
}
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function write(Profile $profile)
|
||||
{
|
||||
$data = array(
|
||||
'token' => $profile->getToken(),
|
||||
'parent' => $profile->getParentToken(),
|
||||
'children' => array_map(function ($p) { return $p->getToken(); }, $profile->getChildren()),
|
||||
'data' => $profile->getCollectors(),
|
||||
'ip' => $profile->getIp(),
|
||||
'method' => $profile->getMethod(),
|
||||
'url' => $profile->getUrl(),
|
||||
'time' => $profile->getTime(),
|
||||
);
|
||||
|
||||
$profileIndexed = false !== $this->getValue($this->getItemName($profile->getToken()));
|
||||
|
||||
if ($this->setValue($this->getItemName($profile->getToken()), $data, $this->lifetime)) {
|
||||
|
||||
if (!$profileIndexed) {
|
||||
// Add to index
|
||||
$indexName = $this->getIndexName();
|
||||
|
||||
$indexRow = implode("\t", array(
|
||||
$profile->getToken(),
|
||||
$profile->getIp(),
|
||||
$profile->getMethod(),
|
||||
$profile->getUrl(),
|
||||
$profile->getTime(),
|
||||
$profile->getParentToken(),
|
||||
))."\n";
|
||||
|
||||
return $this->appendValue($indexName, $indexRow, $this->lifetime);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve item from the memcache server
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function getValue($key);
|
||||
|
||||
/**
|
||||
* Store an item on the memcache server under the specified key
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param int $expiration
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
abstract protected function setValue($key, $value, $expiration = 0);
|
||||
|
||||
/**
|
||||
* Delete item from the memcache server
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
abstract protected function delete($key);
|
||||
|
||||
/**
|
||||
* Append data to an existing item on the memcache server
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @param int $expiration
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
abstract protected function appendValue($key, $value, $expiration = 0);
|
||||
|
||||
private function createProfileFromData($token, $data, $parent = null)
|
||||
{
|
||||
$profile = new Profile($token);
|
||||
$profile->setIp($data['ip']);
|
||||
$profile->setMethod($data['method']);
|
||||
$profile->setUrl($data['url']);
|
||||
$profile->setTime($data['time']);
|
||||
$profile->setCollectors($data['data']);
|
||||
|
||||
if (!$parent && $data['parent']) {
|
||||
$parent = $this->read($data['parent']);
|
||||
}
|
||||
|
||||
if ($parent) {
|
||||
$profile->setParent($parent);
|
||||
}
|
||||
|
||||
foreach ($data['children'] as $token) {
|
||||
if (!$token) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$childProfileData = $this->getValue($this->getItemName($token))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$profile->addChild($this->createProfileFromData($token, $childProfileData, $profile));
|
||||
}
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get item name
|
||||
*
|
||||
* @param string $token
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getItemName($token)
|
||||
{
|
||||
$name = self::TOKEN_PREFIX.$token;
|
||||
|
||||
if ($this->isItemNameValid($name)) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name of index
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getIndexName()
|
||||
{
|
||||
$name = self::TOKEN_PREFIX.'index';
|
||||
|
||||
if ($this->isItemNameValid($name)) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function isItemNameValid($name)
|
||||
{
|
||||
$length = strlen($name);
|
||||
|
||||
if ($length > 250) {
|
||||
throw new \RuntimeException(sprintf('The memcache item key "%s" is too long (%s bytes). Allowed maximum size is 250 bytes.', $name, $length));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
277
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php
vendored
Normal file
277
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php
vendored
Normal file
@@ -0,0 +1,277 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
/**
|
||||
* Storage for profiler using files.
|
||||
*
|
||||
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
||||
*/
|
||||
class FileProfilerStorage implements ProfilerStorageInterface
|
||||
{
|
||||
/**
|
||||
* Folder where profiler data are stored.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $folder;
|
||||
|
||||
/**
|
||||
* Constructs the file storage using a "dsn-like" path.
|
||||
*
|
||||
* Example : "file:/path/to/the/storage/folder"
|
||||
*
|
||||
* @param string $dsn The DSN
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function __construct($dsn)
|
||||
{
|
||||
if (0 !== strpos($dsn, 'file:')) {
|
||||
throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use FileStorage with an invalid dsn "%s". The expected format is "file:/path/to/the/storage/folder".', $dsn));
|
||||
}
|
||||
$this->folder = substr($dsn, 5);
|
||||
|
||||
if (!is_dir($this->folder)) {
|
||||
mkdir($this->folder, 0777, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function find($ip, $url, $limit, $method, $start = null, $end = null)
|
||||
{
|
||||
$file = $this->getIndexFilename();
|
||||
|
||||
if (!file_exists($file)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$file = fopen($file, 'r');
|
||||
fseek($file, 0, SEEK_END);
|
||||
|
||||
$result = array();
|
||||
while (count($result) < $limit && $line = $this->readLineFromFile($file)) {
|
||||
list($csvToken, $csvIp, $csvMethod, $csvUrl, $csvTime, $csvParent) = str_getcsv($line);
|
||||
|
||||
$csvTime = (int) $csvTime;
|
||||
|
||||
if ($ip && false === strpos($csvIp, $ip) || $url && false === strpos($csvUrl, $url) || $method && false === strpos($csvMethod, $method)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!empty($start) && $csvTime < $start) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!empty($end) && $csvTime > $end) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result[$csvToken] = array(
|
||||
'token' => $csvToken,
|
||||
'ip' => $csvIp,
|
||||
'method' => $csvMethod,
|
||||
'url' => $csvUrl,
|
||||
'time' => $csvTime,
|
||||
'parent' => $csvParent,
|
||||
);
|
||||
}
|
||||
|
||||
fclose($file);
|
||||
|
||||
return array_values($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function purge()
|
||||
{
|
||||
$flags = \FilesystemIterator::SKIP_DOTS;
|
||||
$iterator = new \RecursiveDirectoryIterator($this->folder, $flags);
|
||||
$iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::CHILD_FIRST);
|
||||
|
||||
foreach ($iterator as $file) {
|
||||
if (is_file($file)) {
|
||||
unlink($file);
|
||||
} else {
|
||||
rmdir($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function read($token)
|
||||
{
|
||||
if (!$token || !file_exists($file = $this->getFilename($token))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->createProfileFromData($token, unserialize(file_get_contents($file)));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function write(Profile $profile)
|
||||
{
|
||||
$file = $this->getFilename($profile->getToken());
|
||||
|
||||
$profileIndexed = is_file($file);
|
||||
if (!$profileIndexed) {
|
||||
// Create directory
|
||||
$dir = dirname($file);
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0777, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Store profile
|
||||
$data = array(
|
||||
'token' => $profile->getToken(),
|
||||
'parent' => $profile->getParentToken(),
|
||||
'children' => array_map(function ($p) { return $p->getToken(); }, $profile->getChildren()),
|
||||
'data' => $profile->getCollectors(),
|
||||
'ip' => $profile->getIp(),
|
||||
'method' => $profile->getMethod(),
|
||||
'url' => $profile->getUrl(),
|
||||
'time' => $profile->getTime(),
|
||||
);
|
||||
|
||||
if (false === file_put_contents($file, serialize($data))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$profileIndexed) {
|
||||
// Add to index
|
||||
if (false === $file = fopen($this->getIndexFilename(), 'a')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fputcsv($file, array(
|
||||
$profile->getToken(),
|
||||
$profile->getIp(),
|
||||
$profile->getMethod(),
|
||||
$profile->getUrl(),
|
||||
$profile->getTime(),
|
||||
$profile->getParentToken(),
|
||||
));
|
||||
fclose($file);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets filename to store data, associated to the token.
|
||||
*
|
||||
* @param string $token
|
||||
*
|
||||
* @return string The profile filename
|
||||
*/
|
||||
protected function getFilename($token)
|
||||
{
|
||||
// Uses 4 last characters, because first are mostly the same.
|
||||
$folderA = substr($token, -2, 2);
|
||||
$folderB = substr($token, -4, 2);
|
||||
|
||||
return $this->folder.'/'.$folderA.'/'.$folderB.'/'.$token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index filename.
|
||||
*
|
||||
* @return string The index filename
|
||||
*/
|
||||
protected function getIndexFilename()
|
||||
{
|
||||
return $this->folder.'/index.csv';
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a line in the file, backward.
|
||||
*
|
||||
* This function automatically skips the empty lines and do not include the line return in result value.
|
||||
*
|
||||
* @param resource $file The file resource, with the pointer placed at the end of the line to read
|
||||
*
|
||||
* @return mixed A string representing the line or null if beginning of file is reached
|
||||
*/
|
||||
protected function readLineFromFile($file)
|
||||
{
|
||||
$line = '';
|
||||
$position = ftell($file);
|
||||
|
||||
if (0 === $position) {
|
||||
return null;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
$chunkSize = min($position, 1024);
|
||||
$position -= $chunkSize;
|
||||
fseek($file, $position);
|
||||
|
||||
if (0 === $chunkSize) {
|
||||
// bof reached
|
||||
break;
|
||||
}
|
||||
|
||||
$buffer = fread($file, $chunkSize);
|
||||
|
||||
if (false === ($upTo = strrpos($buffer, "\n"))) {
|
||||
$line = $buffer.$line;
|
||||
continue;
|
||||
}
|
||||
|
||||
$position += $upTo;
|
||||
$line = substr($buffer, $upTo + 1).$line;
|
||||
fseek($file, max(0, $position), SEEK_SET);
|
||||
|
||||
if ('' !== $line) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return '' === $line ? null : $line;
|
||||
}
|
||||
|
||||
protected function createProfileFromData($token, $data, $parent = null)
|
||||
{
|
||||
$profile = new Profile($token);
|
||||
$profile->setIp($data['ip']);
|
||||
$profile->setMethod($data['method']);
|
||||
$profile->setUrl($data['url']);
|
||||
$profile->setTime($data['time']);
|
||||
$profile->setCollectors($data['data']);
|
||||
|
||||
if (!$parent && $data['parent']) {
|
||||
$parent = $this->read($data['parent']);
|
||||
}
|
||||
|
||||
if ($parent) {
|
||||
$profile->setParent($parent);
|
||||
}
|
||||
|
||||
foreach ($data['children'] as $token) {
|
||||
if (!$token || !file_exists($file = $this->getFilename($token))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$profile->addChild($this->createProfileFromData($token, unserialize(file_get_contents($file)), $profile));
|
||||
}
|
||||
|
||||
return $profile;
|
||||
}
|
||||
}
|
110
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/MemcacheProfilerStorage.php
vendored
Normal file
110
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/MemcacheProfilerStorage.php
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
use Memcache;
|
||||
|
||||
/**
|
||||
* Memcache Profiler Storage
|
||||
*
|
||||
* @author Andrej Hudec <pulzarraider@gmail.com>
|
||||
*/
|
||||
class MemcacheProfilerStorage extends BaseMemcacheProfilerStorage
|
||||
{
|
||||
/**
|
||||
* @var Memcache
|
||||
*/
|
||||
private $memcache;
|
||||
|
||||
/**
|
||||
* Internal convenience method that returns the instance of the Memcache
|
||||
*
|
||||
* @return Memcache
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function getMemcache()
|
||||
{
|
||||
if (null === $this->memcache) {
|
||||
if (!preg_match('#^memcache://(?(?=\[.*\])\[(.*)\]|(.*)):(.*)$#', $this->dsn, $matches)) {
|
||||
throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Memcache with an invalid dsn "%s". The expected format is "memcache://[host]:port".', $this->dsn));
|
||||
}
|
||||
|
||||
$host = $matches[1] ?: $matches[2];
|
||||
$port = $matches[3];
|
||||
|
||||
$memcache = new Memcache;
|
||||
$memcache->addServer($host, $port);
|
||||
|
||||
$this->memcache = $memcache;
|
||||
}
|
||||
|
||||
return $this->memcache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set instance of the Memcache
|
||||
*
|
||||
* @param Memcache $memcache
|
||||
*/
|
||||
public function setMemcache($memcache)
|
||||
{
|
||||
$this->memcache = $memcache;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getValue($key)
|
||||
{
|
||||
return $this->getMemcache()->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setValue($key, $value, $expiration = 0)
|
||||
{
|
||||
return $this->getMemcache()->set($key, $value, false, time() + $expiration);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function delete($key)
|
||||
{
|
||||
return $this->getMemcache()->delete($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function appendValue($key, $value, $expiration = 0)
|
||||
{
|
||||
$memcache = $this->getMemcache();
|
||||
|
||||
if (method_exists($memcache, 'append')) {
|
||||
|
||||
//Memcache v3.0
|
||||
if (!$result = $memcache->append($key, $value, false, $expiration)) {
|
||||
return $memcache->set($key, $value, false, $expiration);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
//simulate append in Memcache <3.0
|
||||
$content = $memcache->get($key);
|
||||
|
||||
return $memcache->set($key, $content.$value, false, $expiration);
|
||||
}
|
||||
}
|
105
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/MemcachedProfilerStorage.php
vendored
Normal file
105
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/MemcachedProfilerStorage.php
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
use Memcached;
|
||||
|
||||
/**
|
||||
* Memcached Profiler Storage
|
||||
*
|
||||
* @author Andrej Hudec <pulzarraider@gmail.com>
|
||||
*/
|
||||
class MemcachedProfilerStorage extends BaseMemcacheProfilerStorage
|
||||
{
|
||||
/**
|
||||
* @var Memcached
|
||||
*/
|
||||
private $memcached;
|
||||
|
||||
/**
|
||||
* Internal convenience method that returns the instance of the Memcached
|
||||
*
|
||||
* @return Memcached
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function getMemcached()
|
||||
{
|
||||
if (null === $this->memcached) {
|
||||
if (!preg_match('#^memcached://(?(?=\[.*\])\[(.*)\]|(.*)):(.*)$#', $this->dsn, $matches)) {
|
||||
throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Memcached with an invalid dsn "%s". The expected format is "memcached://[host]:port".', $this->dsn));
|
||||
}
|
||||
|
||||
$host = $matches[1] ?: $matches[2];
|
||||
$port = $matches[3];
|
||||
|
||||
$memcached = new Memcached;
|
||||
|
||||
//disable compression to allow appending
|
||||
$memcached->setOption(Memcached::OPT_COMPRESSION, false);
|
||||
|
||||
$memcached->addServer($host, $port);
|
||||
|
||||
$this->memcached = $memcached;
|
||||
}
|
||||
|
||||
return $this->memcached;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set instance of the Memcached
|
||||
*
|
||||
* @param Memcached $memcached
|
||||
*/
|
||||
public function setMemcached($memcached)
|
||||
{
|
||||
$this->memcached = $memcached;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getValue($key)
|
||||
{
|
||||
return $this->getMemcached()->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setValue($key, $value, $expiration = 0)
|
||||
{
|
||||
return $this->getMemcached()->set($key, $value, time() + $expiration);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function delete($key)
|
||||
{
|
||||
return $this->getMemcached()->delete($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function appendValue($key, $value, $expiration = 0)
|
||||
{
|
||||
$memcached = $this->getMemcached();
|
||||
|
||||
if (!$result = $memcached->append($key, $value)) {
|
||||
return $memcached->set($key, $value, $expiration);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
236
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/MongoDbProfilerStorage.php
vendored
Normal file
236
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/MongoDbProfilerStorage.php
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
class MongoDbProfilerStorage implements ProfilerStorageInterface
|
||||
{
|
||||
protected $dsn;
|
||||
protected $lifetime;
|
||||
private $mongo;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $dsn A data source name
|
||||
* @param string $username Not used
|
||||
* @param string $password Not used
|
||||
* @param integer $lifetime The lifetime to use for the purge
|
||||
*/
|
||||
public function __construct($dsn, $username = '', $password = '', $lifetime = 86400)
|
||||
{
|
||||
$this->dsn = $dsn;
|
||||
$this->lifetime = (int) $lifetime;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function find($ip, $url, $limit, $method, $start = null, $end = null)
|
||||
{
|
||||
$cursor = $this->getMongo()->find($this->buildQuery($ip, $url, $method, $start, $end), array('_id', 'parent', 'ip', 'method', 'url', 'time'))->sort(array('time' => -1))->limit($limit);
|
||||
|
||||
$tokens = array();
|
||||
foreach ($cursor as $profile) {
|
||||
$tokens[] = $this->getData($profile);
|
||||
}
|
||||
|
||||
return $tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function purge()
|
||||
{
|
||||
$this->getMongo()->remove(array());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function read($token)
|
||||
{
|
||||
$profile = $this->getMongo()->findOne(array('_id' => $token, 'data' => array('$exists' => true)));
|
||||
|
||||
if (null !== $profile) {
|
||||
$profile = $this->createProfileFromData($this->getData($profile));
|
||||
}
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function write(Profile $profile)
|
||||
{
|
||||
$this->cleanup();
|
||||
|
||||
$record = array(
|
||||
'_id' => $profile->getToken(),
|
||||
'parent' => $profile->getParentToken(),
|
||||
'data' => base64_encode(serialize($profile->getCollectors())),
|
||||
'ip' => $profile->getIp(),
|
||||
'method' => $profile->getMethod(),
|
||||
'url' => $profile->getUrl(),
|
||||
'time' => $profile->getTime()
|
||||
);
|
||||
|
||||
$result = $this->getMongo()->update(array('_id' => $profile->getToken()), array_filter($record, function ($v) { return !empty($v); }), array('upsert' => true));
|
||||
|
||||
return (boolean) (isset($result['ok']) ? $result['ok'] : $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal convenience method that returns the instance of the MongoDB Collection
|
||||
*
|
||||
* @return \MongoCollection
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function getMongo()
|
||||
{
|
||||
if ($this->mongo === null) {
|
||||
if (preg_match('#^(mongodb://.*)/(.*)/(.*)$#', $this->dsn, $matches)) {
|
||||
$server = $matches[1].(!empty($matches[2]) ? '/'.$matches[2] : '');
|
||||
$database = $matches[2];
|
||||
$collection = $matches[3];
|
||||
|
||||
$mongoClass = (version_compare(phpversion('mongo'), '1.3.0', '<')) ? '\Mongo' : '\MongoClient';
|
||||
$mongo = new $mongoClass($server);
|
||||
$this->mongo = $mongo->selectCollection($database, $collection);
|
||||
} else {
|
||||
throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use MongoDB with an invalid dsn "%s". The expected format is "mongodb://[user:pass@]host/database/collection"', $this->dsn));
|
||||
}
|
||||
}
|
||||
|
||||
return $this->mongo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Profile
|
||||
*/
|
||||
protected function createProfileFromData(array $data)
|
||||
{
|
||||
$profile = $this->getProfile($data);
|
||||
|
||||
if ($data['parent']) {
|
||||
$parent = $this->getMongo()->findOne(array('_id' => $data['parent'], 'data' => array('$exists' => true)));
|
||||
if ($parent) {
|
||||
$profile->setParent($this->getProfile($this->getData($parent)));
|
||||
}
|
||||
}
|
||||
|
||||
$profile->setChildren($this->readChildren($data['token']));
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $token
|
||||
*
|
||||
* @return Profile[] An array of Profile instances
|
||||
*/
|
||||
protected function readChildren($token)
|
||||
{
|
||||
$profiles = array();
|
||||
|
||||
$cursor = $this->getMongo()->find(array('parent' => $token, 'data' => array('$exists' => true)));
|
||||
foreach ($cursor as $d) {
|
||||
$profiles[] = $this->getProfile($this->getData($d));
|
||||
}
|
||||
|
||||
return $profiles;
|
||||
}
|
||||
|
||||
protected function cleanup()
|
||||
{
|
||||
$this->getMongo()->remove(array('time' => array('$lt' => time() - $this->lifetime)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $ip
|
||||
* @param string $url
|
||||
* @param string $method
|
||||
* @param int $start
|
||||
* @param int $end
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function buildQuery($ip, $url, $method, $start, $end)
|
||||
{
|
||||
$query = array();
|
||||
|
||||
if (!empty($ip)) {
|
||||
$query['ip'] = $ip;
|
||||
}
|
||||
|
||||
if (!empty($url)) {
|
||||
$query['url'] = $url;
|
||||
}
|
||||
|
||||
if (!empty($method)) {
|
||||
$query['method'] = $method;
|
||||
}
|
||||
|
||||
if (!empty($start) || !empty($end)) {
|
||||
$query['time'] = array();
|
||||
}
|
||||
|
||||
if (!empty($start)) {
|
||||
$query['time']['$gte'] = $start;
|
||||
}
|
||||
|
||||
if (!empty($end)) {
|
||||
$query['time']['$lte'] = $end;
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getData(array $data)
|
||||
{
|
||||
return array(
|
||||
'token' => $data['_id'],
|
||||
'parent' => isset($data['parent']) ? $data['parent'] : null,
|
||||
'ip' => isset($data['ip']) ? $data['ip'] : null,
|
||||
'method' => isset($data['method']) ? $data['method'] : null,
|
||||
'url' => isset($data['url']) ? $data['url'] : null,
|
||||
'time' => isset($data['time']) ? $data['time'] : null,
|
||||
'data' => isset($data['data']) ? $data['data'] : null,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Profile
|
||||
*/
|
||||
private function getProfile(array $data)
|
||||
{
|
||||
$profile = new Profile($data['token']);
|
||||
$profile->setIp($data['ip']);
|
||||
$profile->setMethod($data['method']);
|
||||
$profile->setUrl($data['url']);
|
||||
$profile->setTime($data['time']);
|
||||
$profile->setCollectors(unserialize(base64_decode($data['data'])));
|
||||
|
||||
return $profile;
|
||||
}
|
||||
}
|
79
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/MysqlProfilerStorage.php
vendored
Normal file
79
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/MysqlProfilerStorage.php
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
/**
|
||||
* A ProfilerStorage for Mysql
|
||||
*
|
||||
* @author Jan Schumann <js@schumann-it.com>
|
||||
*/
|
||||
class MysqlProfilerStorage extends PdoProfilerStorage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function initDb()
|
||||
{
|
||||
if (null === $this->db) {
|
||||
if (0 !== strpos($this->dsn, 'mysql')) {
|
||||
throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use Mysql with an invalid dsn "%s". The expected format is "mysql:dbname=database_name;host=host_name".', $this->dsn));
|
||||
}
|
||||
|
||||
if (!class_exists('PDO') || !in_array('mysql', \PDO::getAvailableDrivers(), true)) {
|
||||
throw new \RuntimeException('You need to enable PDO_Mysql extension for the profiler to run properly.');
|
||||
}
|
||||
|
||||
$db = new \PDO($this->dsn, $this->username, $this->password);
|
||||
$db->exec('CREATE TABLE IF NOT EXISTS sf_profiler_data (token VARCHAR(255) PRIMARY KEY, data LONGTEXT, ip VARCHAR(64), method VARCHAR(6), url VARCHAR(255), time INTEGER UNSIGNED, parent VARCHAR(255), created_at INTEGER UNSIGNED, KEY (created_at), KEY (ip), KEY (method), KEY (url), KEY (parent))');
|
||||
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
return $this->db;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function buildCriteria($ip, $url, $start, $end, $limit, $method)
|
||||
{
|
||||
$criteria = array();
|
||||
$args = array();
|
||||
|
||||
if ($ip = preg_replace('/[^\d\.]/', '', $ip)) {
|
||||
$criteria[] = 'ip LIKE :ip';
|
||||
$args[':ip'] = '%'.$ip.'%';
|
||||
}
|
||||
|
||||
if ($url) {
|
||||
$criteria[] = 'url LIKE :url';
|
||||
$args[':url'] = '%'.addcslashes($url, '%_\\').'%';
|
||||
}
|
||||
|
||||
if ($method) {
|
||||
$criteria[] = 'method = :method';
|
||||
$args[':method'] = $method;
|
||||
}
|
||||
|
||||
if (!empty($start)) {
|
||||
$criteria[] = 'time >= :start';
|
||||
$args[':start'] = $start;
|
||||
}
|
||||
|
||||
if (!empty($end)) {
|
||||
$criteria[] = 'time <= :end';
|
||||
$args[':end'] = $end;
|
||||
}
|
||||
|
||||
return array($criteria, $args);
|
||||
}
|
||||
}
|
264
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/PdoProfilerStorage.php
vendored
Normal file
264
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/PdoProfilerStorage.php
vendored
Normal file
@@ -0,0 +1,264 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
/**
|
||||
* Base PDO storage for profiling information in a PDO database.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jan Schumann <js@schumann-it.com>
|
||||
*/
|
||||
abstract class PdoProfilerStorage implements ProfilerStorageInterface
|
||||
{
|
||||
protected $dsn;
|
||||
protected $username;
|
||||
protected $password;
|
||||
protected $lifetime;
|
||||
protected $db;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $dsn A data source name
|
||||
* @param string $username The username for the database
|
||||
* @param string $password The password for the database
|
||||
* @param integer $lifetime The lifetime to use for the purge
|
||||
*/
|
||||
public function __construct($dsn, $username = '', $password = '', $lifetime = 86400)
|
||||
{
|
||||
$this->dsn = $dsn;
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
$this->lifetime = (int) $lifetime;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function find($ip, $url, $limit, $method, $start = null, $end = null)
|
||||
{
|
||||
if (null === $start) {
|
||||
$start = 0;
|
||||
}
|
||||
|
||||
if (null === $end) {
|
||||
$end = time();
|
||||
}
|
||||
|
||||
list($criteria, $args) = $this->buildCriteria($ip, $url, $start, $end, $limit, $method);
|
||||
|
||||
$criteria = $criteria ? 'WHERE '.implode(' AND ', $criteria) : '';
|
||||
|
||||
$db = $this->initDb();
|
||||
$tokens = $this->fetch($db, 'SELECT token, ip, method, url, time, parent FROM sf_profiler_data '.$criteria.' ORDER BY time DESC LIMIT '.((integer) $limit), $args);
|
||||
$this->close($db);
|
||||
|
||||
return $tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function read($token)
|
||||
{
|
||||
$db = $this->initDb();
|
||||
$args = array(':token' => $token);
|
||||
$data = $this->fetch($db, 'SELECT data, parent, ip, method, url, time FROM sf_profiler_data WHERE token = :token LIMIT 1', $args);
|
||||
$this->close($db);
|
||||
if (isset($data[0]['data'])) {
|
||||
return $this->createProfileFromData($token, $data[0]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function write(Profile $profile)
|
||||
{
|
||||
$db = $this->initDb();
|
||||
$args = array(
|
||||
':token' => $profile->getToken(),
|
||||
':parent' => $profile->getParentToken(),
|
||||
':data' => base64_encode(serialize($profile->getCollectors())),
|
||||
':ip' => $profile->getIp(),
|
||||
':method' => $profile->getMethod(),
|
||||
':url' => $profile->getUrl(),
|
||||
':time' => $profile->getTime(),
|
||||
':created_at' => time(),
|
||||
);
|
||||
|
||||
try {
|
||||
if ($this->has($profile->getToken())) {
|
||||
$this->exec($db, 'UPDATE sf_profiler_data SET parent = :parent, data = :data, ip = :ip, method = :method, url = :url, time = :time, created_at = :created_at WHERE token = :token', $args);
|
||||
} else {
|
||||
$this->exec($db, 'INSERT INTO sf_profiler_data (token, parent, data, ip, method, url, time, created_at) VALUES (:token, :parent, :data, :ip, :method, :url, :time, :created_at)', $args);
|
||||
}
|
||||
$this->cleanup();
|
||||
$status = true;
|
||||
} catch (\Exception $e) {
|
||||
$status = false;
|
||||
}
|
||||
|
||||
$this->close($db);
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function purge()
|
||||
{
|
||||
$db = $this->initDb();
|
||||
$this->exec($db, 'DELETE FROM sf_profiler_data');
|
||||
$this->close($db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build SQL criteria to fetch records by ip and url
|
||||
*
|
||||
* @param string $ip The IP
|
||||
* @param string $url The URL
|
||||
* @param string $start The start period to search from
|
||||
* @param string $end The end period to search to
|
||||
* @param string $limit The maximum number of tokens to return
|
||||
* @param string $method The request method
|
||||
*
|
||||
* @return array An array with (criteria, args)
|
||||
*/
|
||||
abstract protected function buildCriteria($ip, $url, $start, $end, $limit, $method);
|
||||
|
||||
/**
|
||||
* Initializes the database
|
||||
*
|
||||
* @throws \RuntimeException When the requested database driver is not installed
|
||||
*/
|
||||
abstract protected function initDb();
|
||||
|
||||
protected function cleanup()
|
||||
{
|
||||
$db = $this->initDb();
|
||||
$this->exec($db, 'DELETE FROM sf_profiler_data WHERE created_at < :time', array(':time' => time() - $this->lifetime));
|
||||
$this->close($db);
|
||||
}
|
||||
|
||||
protected function exec($db, $query, array $args = array())
|
||||
{
|
||||
$stmt = $this->prepareStatement($db, $query);
|
||||
|
||||
foreach ($args as $arg => $val) {
|
||||
$stmt->bindValue($arg, $val, is_int($val) ? \PDO::PARAM_INT : \PDO::PARAM_STR);
|
||||
}
|
||||
$success = $stmt->execute();
|
||||
if (!$success) {
|
||||
throw new \RuntimeException(sprintf('Error executing query "%s"', $query));
|
||||
}
|
||||
}
|
||||
|
||||
protected function prepareStatement($db, $query)
|
||||
{
|
||||
try {
|
||||
$stmt = $db->prepare($query);
|
||||
} catch (\Exception $e) {
|
||||
$stmt = false;
|
||||
}
|
||||
|
||||
if (false === $stmt) {
|
||||
throw new \RuntimeException('The database cannot successfully prepare the statement');
|
||||
}
|
||||
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
protected function fetch($db, $query, array $args = array())
|
||||
{
|
||||
$stmt = $this->prepareStatement($db, $query);
|
||||
|
||||
foreach ($args as $arg => $val) {
|
||||
$stmt->bindValue($arg, $val, is_int($val) ? \PDO::PARAM_INT : \PDO::PARAM_STR);
|
||||
}
|
||||
$stmt->execute();
|
||||
$return = $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
protected function close($db)
|
||||
{
|
||||
}
|
||||
|
||||
protected function createProfileFromData($token, $data, $parent = null)
|
||||
{
|
||||
$profile = new Profile($token);
|
||||
$profile->setIp($data['ip']);
|
||||
$profile->setMethod($data['method']);
|
||||
$profile->setUrl($data['url']);
|
||||
$profile->setTime($data['time']);
|
||||
$profile->setCollectors(unserialize(base64_decode($data['data'])));
|
||||
|
||||
if (!$parent && !empty($data['parent'])) {
|
||||
$parent = $this->read($data['parent']);
|
||||
}
|
||||
|
||||
if ($parent) {
|
||||
$profile->setParent($parent);
|
||||
}
|
||||
|
||||
$profile->setChildren($this->readChildren($token, $profile));
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the child profiles for the given token.
|
||||
*
|
||||
* @param string $token The parent token
|
||||
* @param string $parent The parent instance
|
||||
*
|
||||
* @return Profile[] An array of Profile instance
|
||||
*/
|
||||
protected function readChildren($token, $parent)
|
||||
{
|
||||
$db = $this->initDb();
|
||||
$data = $this->fetch($db, 'SELECT token, data, ip, method, url, time FROM sf_profiler_data WHERE parent = :token', array(':token' => $token));
|
||||
$this->close($db);
|
||||
|
||||
if (!$data) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$profiles = array();
|
||||
foreach ($data as $d) {
|
||||
$profiles[] = $this->createProfileFromData($d['token'], $d, $parent);
|
||||
}
|
||||
|
||||
return $profiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether data for the given token already exists in storage.
|
||||
*
|
||||
* @param string $token The profile token
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function has($token)
|
||||
{
|
||||
$db = $this->initDb();
|
||||
$tokenExists = $this->fetch($db, 'SELECT 1 FROM sf_profiler_data WHERE token = :token LIMIT 1', array(':token' => $token));
|
||||
$this->close($db);
|
||||
|
||||
return !empty($tokenExists);
|
||||
}
|
||||
}
|
275
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/Profile.php
vendored
Normal file
275
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/Profile.php
vendored
Normal file
@@ -0,0 +1,275 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
|
||||
|
||||
/**
|
||||
* Profile.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Profile
|
||||
{
|
||||
private $token;
|
||||
|
||||
/**
|
||||
* @var DataCollectorInterface[]
|
||||
*/
|
||||
private $collectors = array();
|
||||
|
||||
private $ip;
|
||||
private $method;
|
||||
private $url;
|
||||
private $time;
|
||||
|
||||
/**
|
||||
* @var Profile
|
||||
*/
|
||||
private $parent;
|
||||
|
||||
/**
|
||||
* @var Profile[]
|
||||
*/
|
||||
private $children = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $token The token
|
||||
*/
|
||||
public function __construct($token)
|
||||
{
|
||||
$this->token = $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the token.
|
||||
*
|
||||
* @param string $token The token
|
||||
*/
|
||||
public function setToken($token)
|
||||
{
|
||||
$this->token = $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the token.
|
||||
*
|
||||
* @return string The token
|
||||
*/
|
||||
public function getToken()
|
||||
{
|
||||
return $this->token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the parent token
|
||||
*
|
||||
* @param Profile $parent The parent Profile
|
||||
*/
|
||||
public function setParent(Profile $parent)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent profile.
|
||||
*
|
||||
* @return Profile The parent profile
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent token.
|
||||
*
|
||||
* @return null|string The parent token
|
||||
*/
|
||||
public function getParentToken()
|
||||
{
|
||||
return $this->parent ? $this->parent->getToken() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the IP.
|
||||
*
|
||||
* @return string The IP
|
||||
*/
|
||||
public function getIp()
|
||||
{
|
||||
return $this->ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the IP.
|
||||
*
|
||||
* @param string $ip
|
||||
*/
|
||||
public function setIp($ip)
|
||||
{
|
||||
$this->ip = $ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request method.
|
||||
*
|
||||
* @return string The request method
|
||||
*/
|
||||
public function getMethod()
|
||||
{
|
||||
return $this->method;
|
||||
}
|
||||
|
||||
public function setMethod($method)
|
||||
{
|
||||
$this->method = $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL.
|
||||
*
|
||||
* @return string The URL
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
public function setUrl($url)
|
||||
{
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time.
|
||||
*
|
||||
* @return string The time
|
||||
*/
|
||||
public function getTime()
|
||||
{
|
||||
if (null === $this->time) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $this->time;
|
||||
}
|
||||
|
||||
public function setTime($time)
|
||||
{
|
||||
$this->time = $time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds children profilers.
|
||||
*
|
||||
* @return Profile[] An array of Profile
|
||||
*/
|
||||
public function getChildren()
|
||||
{
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets children profiler.
|
||||
*
|
||||
* @param Profile[] $children An array of Profile
|
||||
*/
|
||||
public function setChildren(array $children)
|
||||
{
|
||||
$this->children = array();
|
||||
foreach ($children as $child) {
|
||||
$this->addChild($child);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the child token
|
||||
*
|
||||
* @param Profile $child The child Profile
|
||||
*/
|
||||
public function addChild(Profile $child)
|
||||
{
|
||||
$this->children[] = $child;
|
||||
$child->setParent($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Collector by name.
|
||||
*
|
||||
* @param string $name A collector name
|
||||
*
|
||||
* @return DataCollectorInterface A DataCollectorInterface instance
|
||||
*
|
||||
* @throws \InvalidArgumentException if the collector does not exist
|
||||
*/
|
||||
public function getCollector($name)
|
||||
{
|
||||
if (!isset($this->collectors[$name])) {
|
||||
throw new \InvalidArgumentException(sprintf('Collector "%s" does not exist.', $name));
|
||||
}
|
||||
|
||||
return $this->collectors[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Collectors associated with this profile.
|
||||
*
|
||||
* @return DataCollectorInterface[]
|
||||
*/
|
||||
public function getCollectors()
|
||||
{
|
||||
return $this->collectors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Collectors associated with this profile.
|
||||
*
|
||||
* @param DataCollectorInterface[] $collectors
|
||||
*/
|
||||
public function setCollectors(array $collectors)
|
||||
{
|
||||
$this->collectors = array();
|
||||
foreach ($collectors as $collector) {
|
||||
$this->addCollector($collector);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Collector.
|
||||
*
|
||||
* @param DataCollectorInterface $collector A DataCollectorInterface instance
|
||||
*/
|
||||
public function addCollector(DataCollectorInterface $collector)
|
||||
{
|
||||
$this->collectors[$collector->getName()] = $collector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a Collector for the given name exists.
|
||||
*
|
||||
* @param string $name A collector name
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function hasCollector($name)
|
||||
{
|
||||
return isset($this->collectors[$name]);
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
return array('token', 'parent', 'children', 'collectors', 'ip', 'method', 'url', 'time');
|
||||
}
|
||||
}
|
287
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/Profiler.php
vendored
Normal file
287
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/Profiler.php
vendored
Normal file
@@ -0,0 +1,287 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Profiler\ProfilerStorageInterface;
|
||||
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Profiler.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Profiler
|
||||
{
|
||||
/**
|
||||
* @var ProfilerStorageInterface
|
||||
*/
|
||||
private $storage;
|
||||
|
||||
/**
|
||||
* @var DataCollectorInterface[]
|
||||
*/
|
||||
private $collectors = array();
|
||||
|
||||
/**
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* @var Boolean
|
||||
*/
|
||||
private $enabled = true;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param ProfilerStorageInterface $storage A ProfilerStorageInterface instance
|
||||
* @param LoggerInterface $logger A LoggerInterface instance
|
||||
*/
|
||||
public function __construct(ProfilerStorageInterface $storage, LoggerInterface $logger = null)
|
||||
{
|
||||
$this->storage = $storage;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the profiler.
|
||||
*/
|
||||
public function disable()
|
||||
{
|
||||
$this->enabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the profiler.
|
||||
*/
|
||||
public function enable()
|
||||
{
|
||||
$this->enabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the Profile for the given Response.
|
||||
*
|
||||
* @param Response $response A Response instance
|
||||
*
|
||||
* @return Profile A Profile instance
|
||||
*/
|
||||
public function loadProfileFromResponse(Response $response)
|
||||
{
|
||||
if (!$token = $response->headers->get('X-Debug-Token')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->loadProfile($token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the Profile for the given token.
|
||||
*
|
||||
* @param string $token A token
|
||||
*
|
||||
* @return Profile A Profile instance
|
||||
*/
|
||||
public function loadProfile($token)
|
||||
{
|
||||
return $this->storage->read($token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a Profile.
|
||||
*
|
||||
* @param Profile $profile A Profile instance
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function saveProfile(Profile $profile)
|
||||
{
|
||||
if (!($ret = $this->storage->write($profile)) && null !== $this->logger) {
|
||||
$this->logger->warning('Unable to store the profiler information.');
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Purges all data from the storage.
|
||||
*/
|
||||
public function purge()
|
||||
{
|
||||
$this->storage->purge();
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports the current profiler data.
|
||||
*
|
||||
* @param Profile $profile A Profile instance
|
||||
*
|
||||
* @return string The exported data
|
||||
*/
|
||||
public function export(Profile $profile)
|
||||
{
|
||||
return base64_encode(serialize($profile));
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports data into the profiler storage.
|
||||
*
|
||||
* @param string $data A data string as exported by the export() method
|
||||
*
|
||||
* @return Profile A Profile instance
|
||||
*/
|
||||
public function import($data)
|
||||
{
|
||||
$profile = unserialize(base64_decode($data));
|
||||
|
||||
if ($this->storage->read($profile->getToken())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->saveProfile($profile);
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds profiler tokens for the given criteria.
|
||||
*
|
||||
* @param string $ip The IP
|
||||
* @param string $url The URL
|
||||
* @param string $limit The maximum number of tokens to return
|
||||
* @param string $method The request method
|
||||
* @param string $start The start date to search from
|
||||
* @param string $end The end date to search to
|
||||
*
|
||||
* @return array An array of tokens
|
||||
*
|
||||
* @see http://fr2.php.net/manual/en/datetime.formats.php for the supported date/time formats
|
||||
*/
|
||||
public function find($ip, $url, $limit, $method, $start, $end)
|
||||
{
|
||||
if ('' != $start && null !== $start) {
|
||||
$start = new \DateTime($start);
|
||||
$start = $start->getTimestamp();
|
||||
} else {
|
||||
$start = null;
|
||||
}
|
||||
|
||||
if ('' != $end && null !== $end) {
|
||||
$end = new \DateTime($end);
|
||||
$end = $end->getTimestamp();
|
||||
} else {
|
||||
$end = null;
|
||||
}
|
||||
|
||||
return $this->storage->find($ip, $url, $limit, $method, $start, $end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects data for the given Response.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param Response $response A Response instance
|
||||
* @param \Exception $exception An exception instance if the request threw one
|
||||
*
|
||||
* @return Profile|null A Profile instance or null if the profiler is disabled
|
||||
*/
|
||||
public function collect(Request $request, Response $response, \Exception $exception = null)
|
||||
{
|
||||
if (false === $this->enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
$profile = new Profile(substr(sha1(uniqid(mt_rand(), true)), 0, 6));
|
||||
$profile->setTime(time());
|
||||
$profile->setUrl($request->getUri());
|
||||
$profile->setIp($request->getClientIp());
|
||||
$profile->setMethod($request->getMethod());
|
||||
|
||||
$response->headers->set('X-Debug-Token', $profile->getToken());
|
||||
|
||||
foreach ($this->collectors as $collector) {
|
||||
$collector->collect($request, $response, $exception);
|
||||
|
||||
// forces collectors to become "read/only" (they loose their object dependencies)
|
||||
$profile->addCollector(unserialize(serialize($collector)));
|
||||
}
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Collectors associated with this profiler.
|
||||
*
|
||||
* @return array An array of collectors
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
return $this->collectors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Collectors associated with this profiler.
|
||||
*
|
||||
* @param DataCollectorInterface[] $collectors An array of collectors
|
||||
*/
|
||||
public function set(array $collectors = array())
|
||||
{
|
||||
$this->collectors = array();
|
||||
foreach ($collectors as $collector) {
|
||||
$this->add($collector);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Collector.
|
||||
*
|
||||
* @param DataCollectorInterface $collector A DataCollectorInterface instance
|
||||
*/
|
||||
public function add(DataCollectorInterface $collector)
|
||||
{
|
||||
$this->collectors[$collector->getName()] = $collector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a Collector for the given name exists.
|
||||
*
|
||||
* @param string $name A collector name
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function has($name)
|
||||
{
|
||||
return isset($this->collectors[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Collector by name.
|
||||
*
|
||||
* @param string $name A collector name
|
||||
*
|
||||
* @return DataCollectorInterface A DataCollectorInterface instance
|
||||
*
|
||||
* @throws \InvalidArgumentException if the collector does not exist
|
||||
*/
|
||||
public function get($name)
|
||||
{
|
||||
if (!isset($this->collectors[$name])) {
|
||||
throw new \InvalidArgumentException(sprintf('Collector "%s" does not exist.', $name));
|
||||
}
|
||||
|
||||
return $this->collectors[$name];
|
||||
}
|
||||
}
|
59
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/ProfilerStorageInterface.php
vendored
Normal file
59
vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Profiler/ProfilerStorageInterface.php
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Profiler;
|
||||
|
||||
/**
|
||||
* ProfilerStorageInterface.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface ProfilerStorageInterface
|
||||
{
|
||||
/**
|
||||
* Finds profiler tokens for the given criteria.
|
||||
*
|
||||
* @param string $ip The IP
|
||||
* @param string $url The URL
|
||||
* @param string $limit The maximum number of tokens to return
|
||||
* @param string $method The request method
|
||||
* @param int|null $start The start date to search from
|
||||
* @param int|null $end The end date to search to
|
||||
*
|
||||
* @return array An array of tokens
|
||||
*/
|
||||
public function find($ip, $url, $limit, $method, $start = null, $end = null);
|
||||
|
||||
/**
|
||||
* Reads data associated with the given token.
|
||||
*
|
||||
* The method returns false if the token does not exist in the storage.
|
||||
*
|
||||
* @param string $token A token
|
||||
*
|
||||
* @return Profile The profile associated with token
|
||||
*/
|
||||
public function read($token);
|
||||
|
||||
/**
|
||||
* Saves a Profile.
|
||||
*
|
||||
* @param Profile $profile A Profile instance
|
||||
*
|
||||
* @return Boolean Write operation successful
|
||||
*/
|
||||
public function write(Profile $profile);
|
||||
|
||||
/**
|
||||
* Purges all data from the database.
|
||||
*/
|
||||
public function purge();
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user