2015-08-18 00:00:26 +00:00
< ? 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 ;
2018-11-23 12:29:20 +00:00
use Symfony\Component\ClassLoader\ClassCollectionLoader ;
use Symfony\Component\Config\ConfigCache ;
use Symfony\Component\Config\Loader\DelegatingLoader ;
use Symfony\Component\Config\Loader\LoaderResolver ;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface ;
use Symfony\Component\DependencyInjection\Compiler\PassConfig ;
2015-08-18 00:00:26 +00:00
use Symfony\Component\DependencyInjection\ContainerBuilder ;
2018-11-23 12:29:20 +00:00
use Symfony\Component\DependencyInjection\ContainerInterface ;
2015-08-18 00:00:26 +00:00
use Symfony\Component\DependencyInjection\Dumper\PhpDumper ;
2018-11-23 12:29:20 +00:00
use Symfony\Component\DependencyInjection\Loader\ClosureLoader ;
use Symfony\Component\DependencyInjection\Loader\DirectoryLoader ;
use Symfony\Component\DependencyInjection\Loader\GlobFileLoader ;
2015-08-18 00:00:26 +00:00
use Symfony\Component\DependencyInjection\Loader\IniFileLoader ;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader ;
2018-11-23 12:29:20 +00:00
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader ;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader ;
use Symfony\Component\Filesystem\Filesystem ;
2015-08-18 00:00:26 +00:00
use Symfony\Component\HttpFoundation\Request ;
use Symfony\Component\HttpFoundation\Response ;
use Symfony\Component\HttpKernel\Bundle\BundleInterface ;
use Symfony\Component\HttpKernel\Config\EnvParametersResource ;
use Symfony\Component\HttpKernel\Config\FileLocator ;
2018-11-23 12:29:20 +00:00
use Symfony\Component\HttpKernel\DependencyInjection\AddAnnotatedClassesToCachePass ;
2015-08-18 00:00:26 +00:00
use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass ;
/**
* The Kernel is the heart of the Symfony system .
*
* It manages an environment made of bundles .
*
* @ author Fabien Potencier < fabien @ symfony . com >
*/
2018-11-23 12:29:20 +00:00
abstract class Kernel implements KernelInterface , RebootableInterface , TerminableInterface
2015-08-18 00:00:26 +00:00
{
/**
* @ var BundleInterface []
*/
protected $bundles = array ();
protected $bundleMap ;
protected $container ;
protected $rootDir ;
protected $environment ;
protected $debug ;
protected $booted = false ;
protected $name ;
protected $startTime ;
protected $loadClassCache ;
2018-11-23 12:29:20 +00:00
private $projectDir ;
private $warmupDir ;
private $requestStackSize = 0 ;
private $resetServices = false ;
const VERSION = '3.4.18' ;
const VERSION_ID = 30418 ;
const MAJOR_VERSION = 3 ;
const MINOR_VERSION = 4 ;
const RELEASE_VERSION = 18 ;
2017-02-03 00:28:38 +00:00
const EXTRA_VERSION = '' ;
2015-08-18 00:00:26 +00:00
2018-11-23 12:29:20 +00:00
const END_OF_MAINTENANCE = '11/2020' ;
const END_OF_LIFE = '11/2021' ;
2015-08-18 00:00:26 +00:00
/**
* @ param string $environment The environment
* @ param bool $debug Whether to enable debugging or not
*/
public function __construct ( $environment , $debug )
{
$this -> environment = $environment ;
$this -> debug = ( bool ) $debug ;
$this -> rootDir = $this -> getRootDir ();
$this -> name = $this -> getName ();
}
public function __clone ()
{
$this -> booted = false ;
$this -> container = null ;
2018-11-23 12:29:20 +00:00
$this -> requestStackSize = 0 ;
$this -> resetServices = false ;
2015-08-18 00:00:26 +00:00
}
/**
2018-11-23 12:29:20 +00:00
* { @ inheritdoc }
2015-08-18 00:00:26 +00:00
*/
public function boot ()
{
if ( true === $this -> booted ) {
2018-11-23 12:29:20 +00:00
if ( ! $this -> requestStackSize && $this -> resetServices ) {
if ( $this -> container -> has ( 'services_resetter' )) {
$this -> container -> get ( 'services_resetter' ) -> reset ();
}
$this -> resetServices = false ;
if ( $this -> debug ) {
$this -> startTime = microtime ( true );
}
}
2015-08-18 00:00:26 +00:00
return ;
}
2018-11-23 12:29:20 +00:00
if ( $this -> debug ) {
$this -> startTime = microtime ( true );
}
if ( $this -> debug && ! isset ( $_ENV [ 'SHELL_VERBOSITY' ]) && ! isset ( $_SERVER [ 'SHELL_VERBOSITY' ])) {
putenv ( 'SHELL_VERBOSITY=3' );
$_ENV [ 'SHELL_VERBOSITY' ] = 3 ;
$_SERVER [ 'SHELL_VERBOSITY' ] = 3 ;
}
2015-08-18 00:00:26 +00:00
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 ;
}
2018-11-23 12:29:20 +00:00
/**
* { @ inheritdoc }
*/
public function reboot ( $warmupDir )
{
$this -> shutdown ();
$this -> warmupDir = $warmupDir ;
$this -> boot ();
}
2015-08-18 00:00:26 +00:00
/**
* { @ inheritdoc }
*/
public function terminate ( Request $request , Response $response )
{
if ( false === $this -> booted ) {
return ;
}
if ( $this -> getHttpKernel () instanceof TerminableInterface ) {
$this -> getHttpKernel () -> terminate ( $request , $response );
}
}
/**
* { @ inheritdoc }
*/
public function shutdown ()
{
if ( false === $this -> booted ) {
return ;
}
$this -> booted = false ;
foreach ( $this -> getBundles () as $bundle ) {
$bundle -> shutdown ();
$bundle -> setContainer ( null );
}
$this -> container = null ;
2018-11-23 12:29:20 +00:00
$this -> requestStackSize = 0 ;
$this -> resetServices = false ;
2015-08-18 00:00:26 +00:00
}
/**
* { @ inheritdoc }
*/
public function handle ( Request $request , $type = HttpKernelInterface :: MASTER_REQUEST , $catch = true )
{
2018-11-23 12:29:20 +00:00
$this -> boot ();
++ $this -> requestStackSize ;
$this -> resetServices = true ;
2015-08-18 00:00:26 +00:00
2018-11-23 12:29:20 +00:00
try {
return $this -> getHttpKernel () -> handle ( $request , $type , $catch );
} finally {
-- $this -> requestStackSize ;
}
2015-08-18 00:00:26 +00:00
}
/**
* Gets a HTTP kernel from the container .
*
* @ return HttpKernel
*/
protected function getHttpKernel ()
{
return $this -> container -> get ( 'http_kernel' );
}
/**
* { @ inheritdoc }
*/
public function getBundles ()
{
return $this -> bundles ;
}
/**
* { @ inheritdoc }
*/
2018-11-23 12:29:20 +00:00
public function getBundle ( $name , $first = true /*, $noDeprecation = false */ )
2015-08-18 00:00:26 +00:00
{
2018-11-23 12:29:20 +00:00
$noDeprecation = false ;
if ( \func_num_args () >= 3 ) {
$noDeprecation = func_get_arg ( 2 );
2015-08-18 00:00:26 +00:00
}
2018-11-23 12:29:20 +00:00
if ( ! $first && ! $noDeprecation ) {
@ trigger_error ( sprintf ( 'Passing "false" as the second argument to "%s()" is deprecated as of 3.4 and will be removed in 4.0.' , __METHOD__ ), E_USER_DEPRECATED );
}
2015-08-18 00:00:26 +00:00
if ( ! isset ( $this -> bundleMap [ $name ])) {
2018-11-23 12:29:20 +00:00
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 )));
2015-08-18 00:00:26 +00:00
}
if ( true === $first ) {
return $this -> bundleMap [ $name ][ 0 ];
}
return $this -> bundleMap [ $name ];
}
/**
* { @ inheritdoc }
*
* @ throws \RuntimeException if a custom resource is hidden by a resource in a derived bundle
*/
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 ;
2018-11-23 12:29:20 +00:00
$bundles = $this -> getBundle ( $bundleName , false , true );
2015-08-18 00:00:26 +00:00
$files = array ();
foreach ( $bundles as $bundle ) {
if ( $isResource && file_exists ( $file = $dir . '/' . $bundle -> getName () . $overridePath )) {
if ( null !== $resourceBundle ) {
2018-11-23 12:29:20 +00:00
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 ));
2015-08-18 00:00:26 +00:00
}
if ( $first ) {
return $file ;
}
$files [] = $file ;
}
if ( file_exists ( $file = $bundle -> getPath () . '/' . $path )) {
if ( $first && ! $isResource ) {
return $file ;
}
$files [] = $file ;
$resourceBundle = $bundle -> getName ();
}
}
2018-11-23 12:29:20 +00:00
if ( \count ( $files ) > 0 ) {
2015-08-18 00:00:26 +00:00
return $first && $isResource ? $files [ 0 ] : $files ;
}
throw new \InvalidArgumentException ( sprintf ( 'Unable to find file "%s".' , $name ));
}
/**
* { @ inheritdoc }
*/
public function getName ()
{
if ( null === $this -> name ) {
$this -> name = preg_replace ( '/[^a-zA-Z0-9_]+/' , '' , basename ( $this -> rootDir ));
2017-04-13 14:53:35 +00:00
if ( ctype_digit ( $this -> name [ 0 ])) {
$this -> name = '_' . $this -> name ;
}
2015-08-18 00:00:26 +00:00
}
return $this -> name ;
}
/**
* { @ inheritdoc }
*/
public function getEnvironment ()
{
return $this -> environment ;
}
/**
* { @ inheritdoc }
*/
public function isDebug ()
{
return $this -> debug ;
}
/**
* { @ inheritdoc }
*/
public function getRootDir ()
{
if ( null === $this -> rootDir ) {
$r = new \ReflectionObject ( $this );
2018-11-23 12:29:20 +00:00
$this -> rootDir = \dirname ( $r -> getFileName ());
2015-08-18 00:00:26 +00:00
}
return $this -> rootDir ;
}
2018-11-23 12:29:20 +00:00
/**
* Gets the application root dir ( path of the project ' s composer file ) .
*
* @ return string The project root dir
*/
public function getProjectDir ()
{
if ( null === $this -> projectDir ) {
$r = new \ReflectionObject ( $this );
$dir = $rootDir = \dirname ( $r -> getFileName ());
while ( ! file_exists ( $dir . '/composer.json' )) {
if ( $dir === \dirname ( $dir )) {
return $this -> projectDir = $rootDir ;
}
$dir = \dirname ( $dir );
}
$this -> projectDir = $dir ;
}
return $this -> projectDir ;
}
2015-08-18 00:00:26 +00:00
/**
* { @ inheritdoc }
*/
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
2018-11-23 12:29:20 +00:00
*
* @ deprecated since version 3.3 , to be removed in 4.0 . The class cache is not needed anymore when using PHP 7.0 .
2015-08-18 00:00:26 +00:00
*/
public function loadClassCache ( $name = 'classes' , $extension = '.php' )
{
2018-11-23 12:29:20 +00:00
if ( \PHP_VERSION_ID >= 70000 ) {
@ trigger_error ( __METHOD__ . '() is deprecated since Symfony 3.3, to be removed in 4.0.' , E_USER_DEPRECATED );
}
2015-08-18 00:00:26 +00:00
$this -> loadClassCache = array ( $name , $extension );
}
/**
2018-11-23 12:29:20 +00:00
* @ internal
*
* @ deprecated since version 3.3 , to be removed in 4.0 .
2015-08-18 00:00:26 +00:00
*/
public function setClassCache ( array $classes )
{
2018-11-23 12:29:20 +00:00
if ( \PHP_VERSION_ID >= 70000 ) {
@ trigger_error ( __METHOD__ . '() is deprecated since Symfony 3.3, to be removed in 4.0.' , E_USER_DEPRECATED );
}
file_put_contents (( $this -> warmupDir ? : $this -> getCacheDir ()) . '/classes.map' , sprintf ( '<?php return %s;' , var_export ( $classes , true )));
}
/**
* @ internal
*/
public function setAnnotatedClassCache ( array $annotatedClasses )
{
file_put_contents (( $this -> warmupDir ? : $this -> getCacheDir ()) . '/annotations.map' , sprintf ( '<?php return %s;' , var_export ( $annotatedClasses , true )));
2015-08-18 00:00:26 +00:00
}
/**
* { @ inheritdoc }
*/
public function getStartTime ()
{
return $this -> debug ? $this -> startTime : - INF ;
}
/**
* { @ inheritdoc }
*/
public function getCacheDir ()
{
return $this -> rootDir . '/cache/' . $this -> environment ;
}
/**
* { @ inheritdoc }
*/
public function getLogDir ()
{
return $this -> rootDir . '/logs' ;
}
/**
* { @ inheritdoc }
*/
public function getCharset ()
{
return 'UTF-8' ;
}
2018-11-23 12:29:20 +00:00
/**
* @ deprecated since version 3.3 , to be removed in 4.0 .
*/
2015-08-18 00:00:26 +00:00
protected function doLoadClassCache ( $name , $extension )
{
2018-11-23 12:29:20 +00:00
if ( \PHP_VERSION_ID >= 70000 ) {
@ trigger_error ( __METHOD__ . '() is deprecated since Symfony 3.3, to be removed in 4.0.' , E_USER_DEPRECATED );
}
$cacheDir = $this -> warmupDir ? : $this -> getCacheDir ();
if ( ! $this -> booted && is_file ( $cacheDir . '/classes.map' )) {
ClassCollectionLoader :: load ( include ( $cacheDir . '/classes.map' ), $cacheDir , $name , $this -> debug , false , $extension );
2015-08-18 00:00:26 +00:00
}
}
/**
* 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 ()) {
2018-11-23 12:29:20 +00:00
@ trigger_error ( 'Bundle inheritance is deprecated as of 3.4 and will be removed in 4.0.' , E_USER_DEPRECATED );
2015-08-18 00:00:26 +00:00
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
2018-11-23 12:29:20 +00:00
if ( ! empty ( $directChildren ) && \count ( $diff = array_diff_key ( $directChildren , $this -> bundles ))) {
2015-08-18 00:00:26 +00:00
$diff = array_keys ( $diff );
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 ;
}
2017-02-03 00:28:38 +00:00
foreach ( $hierarchy as $hierarchyBundle ) {
$this -> bundleMap [ $hierarchyBundle ] = $bundleMap ;
2015-08-18 00:00:26 +00:00
array_pop ( $bundleMap );
}
}
}
2018-11-23 12:29:20 +00:00
/**
* The extension point similar to the Bundle :: build () method .
*
* Use this method to register compiler passes and manipulate the container during the building process .
*/
protected function build ( ContainerBuilder $container )
{
}
2015-08-18 00:00:26 +00:00
/**
* 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 ();
2018-11-23 12:29:20 +00:00
$cacheDir = $this -> warmupDir ? : $this -> getCacheDir ();
$cache = new ConfigCache ( $cacheDir . '/' . $class . '.php' , $this -> debug );
$oldContainer = null ;
if ( $fresh = $cache -> isFresh ()) {
// Silence E_WARNING to ignore "include" failures - don't use "@" to prevent silencing fatal errors
$errorLevel = error_reporting ( \E_ALL ^ \E_WARNING );
$fresh = $oldContainer = false ;
try {
if ( file_exists ( $cache -> getPath ()) && \is_object ( $this -> container = include $cache -> getPath ())) {
$this -> container -> set ( 'kernel' , $this );
$oldContainer = $this -> container ;
$fresh = true ;
}
} catch ( \Throwable $e ) {
} catch ( \Exception $e ) {
} finally {
error_reporting ( $errorLevel );
}
}
if ( $fresh ) {
return ;
}
if ( $this -> debug ) {
$collectedLogs = array ();
$previousHandler = \defined ( 'PHPUNIT_COMPOSER_INSTALL' );
$previousHandler = $previousHandler ? : set_error_handler ( function ( $type , $message , $file , $line ) use ( & $collectedLogs , & $previousHandler ) {
if ( E_USER_DEPRECATED !== $type && E_DEPRECATED !== $type ) {
return $previousHandler ? $previousHandler ( $type , $message , $file , $line ) : false ;
}
if ( isset ( $collectedLogs [ $message ])) {
++ $collectedLogs [ $message ][ 'count' ];
return ;
}
$backtrace = debug_backtrace ( DEBUG_BACKTRACE_IGNORE_ARGS , 3 );
// Clean the trace by removing first frames added by the error handler itself.
for ( $i = 0 ; isset ( $backtrace [ $i ]); ++ $i ) {
if ( isset ( $backtrace [ $i ][ 'file' ], $backtrace [ $i ][ 'line' ]) && $backtrace [ $i ][ 'line' ] === $line && $backtrace [ $i ][ 'file' ] === $file ) {
$backtrace = \array_slice ( $backtrace , 1 + $i );
break ;
}
}
$collectedLogs [ $message ] = array (
'type' => $type ,
'message' => $message ,
'file' => $file ,
'line' => $line ,
'trace' => $backtrace ,
'count' => 1 ,
);
});
}
try {
$container = null ;
2015-08-18 00:00:26 +00:00
$container = $this -> buildContainer ();
$container -> compile ();
2018-11-23 12:29:20 +00:00
} finally {
if ( $this -> debug && true !== $previousHandler ) {
restore_error_handler ();
2015-08-18 00:00:26 +00:00
2018-11-23 12:29:20 +00:00
file_put_contents ( $cacheDir . '/' . $class . 'Deprecations.log' , serialize ( array_values ( $collectedLogs )));
file_put_contents ( $cacheDir . '/' . $class . 'Compiler.log' , null !== $container ? implode ( " \n " , $container -> getCompiler () -> getLog ()) : '' );
}
2015-08-18 00:00:26 +00:00
}
2018-11-23 12:29:20 +00:00
if ( null === $oldContainer && file_exists ( $cache -> getPath ())) {
$errorLevel = error_reporting ( \E_ALL ^ \E_WARNING );
try {
$oldContainer = include $cache -> getPath ();
} catch ( \Throwable $e ) {
} catch ( \Exception $e ) {
} finally {
error_reporting ( $errorLevel );
}
}
$oldContainer = \is_object ( $oldContainer ) ? new \ReflectionClass ( $oldContainer ) : false ;
2015-08-18 00:00:26 +00:00
2018-11-23 12:29:20 +00:00
$this -> dumpContainer ( $cache , $container , $class , $this -> getContainerBaseClass ());
$this -> container = require $cache -> getPath ();
2015-08-18 00:00:26 +00:00
$this -> container -> set ( 'kernel' , $this );
2018-11-23 12:29:20 +00:00
if ( $oldContainer && \get_class ( $this -> container ) !== $oldContainer -> name ) {
// Because concurrent requests might still be using them,
// old container files are not removed immediately,
// but on a next dump of the container.
static $legacyContainers = array ();
$oldContainerDir = \dirname ( $oldContainer -> getFileName ());
$legacyContainers [ $oldContainerDir . '.legacy' ] = true ;
foreach ( glob ( \dirname ( $oldContainerDir ) . \DIRECTORY_SEPARATOR . '*.legacy' ) as $legacyContainer ) {
if ( ! isset ( $legacyContainers [ $legacyContainer ]) && @ unlink ( $legacyContainer )) {
( new Filesystem ()) -> remove ( substr ( $legacyContainer , 0 , - 7 ));
}
}
touch ( $oldContainerDir . '.legacy' );
}
if ( $this -> container -> has ( 'cache_warmer' )) {
2015-08-18 00:00:26 +00:00
$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 ();
2017-02-03 00:28:38 +00:00
$bundlesMetadata = array ();
2015-08-18 00:00:26 +00:00
foreach ( $this -> bundles as $name => $bundle ) {
2018-11-23 12:29:20 +00:00
$bundles [ $name ] = \get_class ( $bundle );
2017-02-03 00:28:38 +00:00
$bundlesMetadata [ $name ] = array (
'parent' => $bundle -> getParent (),
'path' => $bundle -> getPath (),
'namespace' => $bundle -> getNamespace (),
);
2015-08-18 00:00:26 +00:00
}
return array_merge (
array (
'kernel.root_dir' => realpath ( $this -> rootDir ) ? : $this -> rootDir ,
2018-11-23 12:29:20 +00:00
'kernel.project_dir' => realpath ( $this -> getProjectDir ()) ? : $this -> getProjectDir (),
2015-08-18 00:00:26 +00:00
'kernel.environment' => $this -> environment ,
'kernel.debug' => $this -> debug ,
'kernel.name' => $this -> name ,
2018-11-23 12:29:20 +00:00
'kernel.cache_dir' => realpath ( $cacheDir = $this -> warmupDir ? : $this -> getCacheDir ()) ? : $cacheDir ,
2015-08-18 00:00:26 +00:00
'kernel.logs_dir' => realpath ( $this -> getLogDir ()) ? : $this -> getLogDir (),
'kernel.bundles' => $bundles ,
2017-02-03 00:28:38 +00:00
'kernel.bundles_metadata' => $bundlesMetadata ,
2015-08-18 00:00:26 +00:00
'kernel.charset' => $this -> getCharset (),
'kernel.container_class' => $this -> getContainerClass (),
),
2018-11-23 12:29:20 +00:00
$this -> getEnvParameters ( false )
2015-08-18 00:00:26 +00:00
);
}
/**
* Gets the environment parameters .
*
* Only the parameters starting with " SYMFONY__ " are considered .
*
* @ return array An array of parameters
2018-11-23 12:29:20 +00:00
*
* @ deprecated since version 3.3 , to be removed in 4.0
2015-08-18 00:00:26 +00:00
*/
protected function getEnvParameters ()
{
2018-11-23 12:29:20 +00:00
if ( 0 === \func_num_args () || func_get_arg ( 0 )) {
@ trigger_error ( sprintf ( 'The "%s()" method is deprecated as of 3.3 and will be removed in 4.0. Use the %%env()%% syntax to get the value of any environment variable from configuration files instead.' , __METHOD__ ), E_USER_DEPRECATED );
}
2015-08-18 00:00:26 +00:00
$parameters = array ();
foreach ( $_SERVER as $key => $value ) {
if ( 0 === strpos ( $key , 'SYMFONY__' )) {
2018-11-23 12:29:20 +00:00
@ trigger_error ( sprintf ( 'The support of special environment variables that start with SYMFONY__ (such as "%s") is deprecated as of 3.3 and will be removed in 4.0. Use the %%env()%% syntax instead to get the value of environment variables in configuration files.' , $key ), E_USER_DEPRECATED );
2015-08-18 00:00:26 +00:00
$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 ()
{
2018-11-23 12:29:20 +00:00
foreach ( array ( 'cache' => $this -> warmupDir ? : $this -> getCacheDir (), 'logs' => $this -> getLogDir ()) as $name => $dir ) {
2015-08-18 00:00:26 +00:00
if ( ! is_dir ( $dir )) {
if ( false === @ mkdir ( $dir , 0777 , true ) && ! is_dir ( $dir )) {
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 );
}
2018-11-23 12:29:20 +00:00
$container -> addCompilerPass ( new AddAnnotatedClassesToCachePass ( $this ));
2015-08-18 00:00:26 +00:00
$container -> addResource ( new EnvParametersResource ( 'SYMFONY__' ));
return $container ;
}
/**
* Prepares the ContainerBuilder before it is compiled .
*/
protected function prepareContainer ( ContainerBuilder $container )
{
$extensions = array ();
foreach ( $this -> bundles as $bundle ) {
if ( $extension = $bundle -> getContainerExtension ()) {
$container -> registerExtension ( $extension );
}
if ( $this -> debug ) {
$container -> addObjectResource ( $bundle );
}
}
2018-11-23 12:29:20 +00:00
2015-08-18 00:00:26 +00:00
foreach ( $this -> bundles as $bundle ) {
$bundle -> build ( $container );
}
2018-11-23 12:29:20 +00:00
$this -> build ( $container );
foreach ( $container -> getExtensions () as $extension ) {
$extensions [] = $extension -> getAlias ();
}
2015-08-18 00:00:26 +00:00
// 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 ()
{
2018-11-23 12:29:20 +00:00
$container = new ContainerBuilder ();
$container -> getParameterBag () -> add ( $this -> getKernelParameters ());
2015-08-18 00:00:26 +00:00
2018-11-23 12:29:20 +00:00
if ( $this instanceof CompilerPassInterface ) {
$container -> addCompilerPass ( $this , PassConfig :: TYPE_BEFORE_OPTIMIZATION , - 10000 );
}
2015-08-18 00:00:26 +00:00
if ( class_exists ( 'ProxyManager\Configuration' ) && class_exists ( 'Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator' )) {
$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' ) && class_exists ( 'Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper' )) {
2018-11-23 12:29:20 +00:00
$dumper -> setProxyDumper ( new ProxyDumper ());
2015-08-18 00:00:26 +00:00
}
2018-11-23 12:29:20 +00:00
$content = $dumper -> dump ( array (
'class' => $class ,
'base_class' => $baseClass ,
'file' => $cache -> getPath (),
'as_files' => true ,
'debug' => $this -> debug ,
'inline_class_loader_parameter' => \PHP_VERSION_ID >= 70000 && ! $this -> loadClassCache && ! class_exists ( ClassCollectionLoader :: class , false ) ? 'container.dumper.inline_class_loader' : null ,
'build_time' => $container -> hasParameter ( 'kernel.container_build_time' ) ? $container -> getParameter ( 'kernel.container_build_time' ) : time (),
));
$rootCode = array_pop ( $content );
$dir = \dirname ( $cache -> getPath ()) . '/' ;
$fs = new Filesystem ();
foreach ( $content as $file => $code ) {
$fs -> dumpFile ( $dir . $file , $code );
@ chmod ( $dir . $file , 0666 & ~ umask ());
}
@ unlink ( \dirname ( $dir . $file ) . '.legacy' );
2015-08-18 00:00:26 +00:00
2018-11-23 12:29:20 +00:00
$cache -> write ( $rootCode , $container -> getResources ());
2015-08-18 00:00:26 +00:00
}
/**
* Returns a loader for the 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 ),
2018-11-23 12:29:20 +00:00
new GlobFileLoader ( $container , $locator ),
2016-04-20 16:56:34 +00:00
new DirectoryLoader ( $container , $locator ),
2015-08-18 00:00:26 +00:00
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 )
{
2018-11-23 12:29:20 +00:00
if ( ! \function_exists ( 'token_get_all' )) {
2015-08-18 00:00:26 +00:00
return $source ;
}
$rawChunk = '' ;
$output = '' ;
$tokens = token_get_all ( $source );
$ignoreSpace = false ;
2016-04-20 16:56:34 +00:00
for ( $i = 0 ; isset ( $tokens [ $i ]); ++ $i ) {
$token = $tokens [ $i ];
if ( ! isset ( $token [ 1 ]) || 'b"' === $token ) {
2015-08-18 00:00:26 +00:00
$rawChunk .= $token ;
} elseif ( T_START_HEREDOC === $token [ 0 ]) {
$output .= $rawChunk . $token [ 1 ];
do {
2016-04-20 16:56:34 +00:00
$token = $tokens [ ++ $i ];
$output .= isset ( $token [ 1 ]) && 'b"' !== $token ? $token [ 1 ] : $token ;
2018-11-23 12:29:20 +00:00
} while ( T_END_HEREDOC !== $token [ 0 ]);
2015-08-18 00:00:26 +00:00
$rawChunk = '' ;
} elseif ( T_WHITESPACE === $token [ 0 ]) {
if ( $ignoreSpace ) {
$ignoreSpace = false ;
continue ;
}
// replace multiple new lines with a single newline
$rawChunk .= preg_replace ( array ( '/\n{2,}/S' ), " \n " , $token [ 1 ]);
2018-11-23 12:29:20 +00:00
} elseif ( \in_array ( $token [ 0 ], array ( T_COMMENT , T_DOC_COMMENT ))) {
2015-08-18 00:00:26 +00:00
$ignoreSpace = true ;
} else {
$rawChunk .= $token [ 1 ];
// The PHP-open tag already has a new-line
if ( T_OPEN_TAG === $token [ 0 ]) {
$ignoreSpace = true ;
}
}
}
$output .= $rawChunk ;
2017-07-03 15:47:07 +00:00
if ( \PHP_VERSION_ID >= 70000 ) {
2016-04-20 16:56:34 +00:00
// PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098
unset ( $tokens , $rawChunk );
gc_mem_caches ();
}
2015-08-18 00:00:26 +00:00
return $output ;
}
public function serialize ()
{
return serialize ( array ( $this -> environment , $this -> debug ));
}
public function unserialize ( $data )
{
2018-11-23 12:29:20 +00:00
if ( \PHP_VERSION_ID >= 70000 ) {
list ( $environment , $debug ) = unserialize ( $data , array ( 'allowed_classes' => false ));
} else {
list ( $environment , $debug ) = unserialize ( $data );
}
2015-08-18 00:00:26 +00:00
$this -> __construct ( $environment , $debug );
}
}