2010-01-04 14:26:20 +00:00
< ? php
2011-01-15 13:29:43 +00:00
/*
* This file is part of the Symfony package .
*
2011-03-06 11:40:06 +00:00
* ( c ) Fabien Potencier < fabien @ symfony . com >
2011-01-15 13:29:43 +00:00
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
2010-08-20 22:09:55 +01:00
namespace Symfony\Component\DependencyInjection\Dumper ;
2010-01-04 14:26:20 +00:00
2011-01-05 11:13:27 +00:00
use Symfony\Component\DependencyInjection\Variable ;
use Symfony\Component\DependencyInjection\Definition ;
2010-08-20 22:09:55 +01:00
use Symfony\Component\DependencyInjection\ContainerBuilder ;
use Symfony\Component\DependencyInjection\Container ;
use Symfony\Component\DependencyInjection\ContainerInterface ;
use Symfony\Component\DependencyInjection\Reference ;
use Symfony\Component\DependencyInjection\Parameter ;
2011-12-04 23:51:22 +00:00
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException ;
use Symfony\Component\DependencyInjection\Exception\RuntimeException ;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException ;
2013-03-29 23:21:12 +00:00
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface as ProxyDumper ;
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper ;
2013-09-02 11:46:47 +01:00
use Symfony\Component\DependencyInjection\ExpressionLanguage ;
use Symfony\Component\ExpressionLanguage\Expression ;
2014-09-23 16:21:57 +01:00
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface ;
2016-03-07 15:45:39 +00:00
use Symfony\Component\HttpKernel\Kernel ;
2010-01-04 14:26:20 +00:00
/**
* PhpDumper dumps a service container as a PHP class .
*
2011-03-06 11:40:06 +00:00
* @ author Fabien Potencier < fabien @ symfony . com >
2011-01-05 11:13:27 +00:00
* @ author Johannes M . Schmitt < schmittjoh @ gmail . com >
2010-01-04 14:26:20 +00:00
*/
class PhpDumper extends Dumper
{
2011-01-05 11:13:27 +00:00
/**
2014-12-21 17:00:50 +00:00
* Characters that might appear in the generated variable name as first character .
*
2011-01-05 11:13:27 +00:00
* @ var string
*/
const FIRST_CHARS = 'abcdefghijklmnopqrstuvwxyz' ;
/**
2014-12-21 17:00:50 +00:00
* Characters that might appear in the generated variable name as any but the first character .
*
2011-01-05 11:13:27 +00:00
* @ var string
*/
const NON_FIRST_CHARS = 'abcdefghijklmnopqrstuvwxyz0123456789_' ;
2011-03-11 13:50:46 +00:00
private $inlinedDefinitions ;
private $definitionVariables ;
private $referenceVariables ;
private $variableCount ;
private $reservedVariables = array ( 'instance' , 'class' );
2013-09-02 11:46:47 +01:00
private $expressionLanguage ;
2014-12-02 21:48:32 +00:00
private $targetDirRegex ;
private $targetDirMaxMatches ;
2016-03-07 15:45:39 +00:00
private $docStar ;
2011-01-05 11:13:27 +00:00
2014-09-23 16:21:57 +01:00
/**
* @ var ExpressionFunctionProviderInterface []
*/
private $expressionLanguageProviders = array ();
2013-03-29 23:21:12 +00:00
/**
* @ var \Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface
*/
private $proxyDumper ;
2011-02-13 18:06:41 +00:00
/**
2014-04-15 06:57:34 +01:00
* { @ inheritdoc }
2011-02-13 18:06:41 +00:00
*/
2011-01-05 11:13:27 +00:00
public function __construct ( ContainerBuilder $container )
{
parent :: __construct ( $container );
2014-02-11 07:51:18 +00:00
$this -> inlinedDefinitions = new \SplObjectStorage ();
2011-01-05 11:13:27 +00:00
}
2013-03-29 23:21:12 +00:00
/**
* Sets the dumper to be used when dumping proxies in the generated container .
*
* @ param ProxyDumper $proxyDumper
*/
public function setProxyDumper ( ProxyDumper $proxyDumper )
{
$this -> proxyDumper = $proxyDumper ;
}
2010-05-06 12:25:53 +01:00
/**
* Dumps the service container as a PHP class .
*
* Available options :
*
* * class : The class name
* * base_class : The base class name
2013-05-22 20:21:30 +01:00
* * namespace : The class namespace
2010-05-06 12:25:53 +01:00
*
2012-05-15 21:19:31 +01:00
* @ param array $options An array of options
2010-05-06 12:25:53 +01:00
*
* @ return string A PHP class representing of the service container
*/
public function dump ( array $options = array ())
{
2014-11-30 15:07:59 +00:00
$this -> targetDirRegex = null ;
2010-05-06 12:25:53 +01:00
$options = array_merge ( array (
2014-10-22 19:27:13 +01:00
'class' => 'ProjectServiceContainer' ,
2010-05-06 12:25:53 +01:00
'base_class' => 'Container' ,
2013-05-22 20:21:30 +01:00
'namespace' => '' ,
2016-03-07 15:45:39 +00:00
'debug' => true ,
2010-05-06 12:25:53 +01:00
), $options );
2016-03-07 15:45:39 +00:00
$this -> docStar = $options [ 'debug' ] ? '*' : '' ;
2010-05-06 12:25:53 +01:00
2014-12-02 21:48:32 +00:00
if ( ! empty ( $options [ 'file' ]) && is_dir ( $dir = dirname ( $options [ 'file' ]))) {
2014-12-04 18:27:52 +00:00
// Build a regexp where the first root dirs are mandatory,
2014-12-02 21:48:32 +00:00
// but every other sub-dir is optional up to the full path in $dir
2014-12-04 18:27:52 +00:00
// Mandate at least 2 root dirs and not more that 5 optional dirs.
2014-12-02 21:48:32 +00:00
$dir = explode ( DIRECTORY_SEPARATOR , realpath ( $dir ));
$i = count ( $dir );
if ( 3 <= $i ) {
$regex = '' ;
2014-12-04 18:27:52 +00:00
$lastOptionalDir = $i > 8 ? $i - 5 : 3 ;
$this -> targetDirMaxMatches = $i - $lastOptionalDir ;
2014-12-02 21:48:32 +00:00
2014-12-04 18:27:52 +00:00
while ( -- $i >= $lastOptionalDir ) {
2014-12-02 21:48:32 +00:00
$regex = sprintf ( '(%s%s)?' , preg_quote ( DIRECTORY_SEPARATOR . $dir [ $i ], '#' ), $regex );
}
do {
$regex = preg_quote ( DIRECTORY_SEPARATOR . $dir [ $i ], '#' ) . $regex ;
} while ( 0 < -- $i );
$this -> targetDirRegex = '#' . preg_quote ( $dir [ 0 ], '#' ) . $regex . '#' ;
}
}
2013-05-22 20:21:30 +01:00
$code = $this -> startClass ( $options [ 'class' ], $options [ 'base_class' ], $options [ 'namespace' ]);
2011-01-30 14:06:45 +00:00
if ( $this -> container -> isFrozen ()) {
$code .= $this -> addFrozenConstructor ();
2014-09-05 10:37:47 +01:00
$code .= $this -> addFrozenCompile ();
2011-01-30 14:06:45 +00:00
} else {
$code .= $this -> addConstructor ();
}
$code .=
2010-05-06 12:25:53 +01:00
$this -> addServices () .
$this -> addDefaultParametersMethod () .
2013-03-29 23:21:12 +00:00
$this -> endClass () .
$this -> addProxyClasses ()
2010-05-06 12:25:53 +01:00
;
2014-11-30 15:07:59 +00:00
$this -> targetDirRegex = null ;
2011-01-30 14:06:45 +00:00
return $code ;
2010-05-06 12:25:53 +01:00
}
2013-03-29 23:21:12 +00:00
/**
* Retrieves the currently set proxy dumper or instantiates one .
*
* @ return ProxyDumper
*/
private function getProxyDumper ()
{
if ( ! $this -> proxyDumper ) {
$this -> proxyDumper = new NullDumper ();
}
return $this -> proxyDumper ;
}
2011-02-13 18:06:41 +00:00
/**
* Generates Service local temp variables .
*
2011-03-04 14:26:00 +00:00
* @ param string $cId
* @ param string $definition
2011-12-13 07:50:54 +00:00
*
2011-02-13 18:06:41 +00:00
* @ return string
*/
2011-03-11 13:50:46 +00:00
private function addServiceLocalTempVariables ( $cId , $definition )
2011-01-05 11:13:27 +00:00
{
static $template = " \$ %s = %s; \n " ;
$localDefinitions = array_merge (
array ( $definition ),
$this -> getInlinedDefinitions ( $definition )
);
$calls = $behavior = array ();
foreach ( $localDefinitions as $iDefinition ) {
$this -> getServiceCallsFromArguments ( $iDefinition -> getArguments (), $calls , $behavior );
$this -> getServiceCallsFromArguments ( $iDefinition -> getMethodCalls (), $calls , $behavior );
2011-03-04 14:26:00 +00:00
$this -> getServiceCallsFromArguments ( $iDefinition -> getProperties (), $calls , $behavior );
2013-11-02 12:45:44 +00:00
$this -> getServiceCallsFromArguments ( array ( $iDefinition -> getConfigurator ()), $calls , $behavior );
2014-04-13 16:18:39 +01:00
$this -> getServiceCallsFromArguments ( array ( $iDefinition -> getFactory ()), $calls , $behavior );
2011-01-05 11:13:27 +00:00
}
$code = '' ;
foreach ( $calls as $id => $callCount ) {
if ( 'service_container' === $id || $id === $cId ) {
continue ;
}
if ( $callCount > 1 ) {
$name = $this -> getNextVariableName ();
$this -> referenceVariables [ $id ] = new Variable ( $name );
if ( ContainerInterface :: EXCEPTION_ON_INVALID_REFERENCE === $behavior [ $id ]) {
$code .= sprintf ( $template , $name , $this -> getServiceCall ( $id ));
} else {
$code .= sprintf ( $template , $name , $this -> getServiceCall ( $id , new Reference ( $id , ContainerInterface :: NULL_ON_INVALID_REFERENCE )));
}
}
}
if ( '' !== $code ) {
$code .= " \n " ;
}
return $code ;
}
2013-03-29 23:21:12 +00:00
/**
2014-12-21 17:00:50 +00:00
* Generates code for the proxies to be attached after the container class .
2013-03-29 23:21:12 +00:00
*
* @ return string
*/
private function addProxyClasses ()
{
2013-12-01 19:41:11 +00:00
/* @var $definitions Definition[] */
2013-03-29 23:21:12 +00:00
$definitions = array_filter (
$this -> container -> getDefinitions (),
array ( $this -> getProxyDumper (), 'isProxyCandidate' )
);
$code = '' ;
2016-03-07 15:45:39 +00:00
$strip = '' === $this -> docStar && method_exists ( 'Symfony\Component\HttpKernel\Kernel' , 'stripComments' );
2013-03-29 23:21:12 +00:00
foreach ( $definitions as $definition ) {
2016-03-07 15:45:39 +00:00
$proxyCode = " \n " . $this -> getProxyDumper () -> getProxyCode ( $definition );
if ( $strip ) {
$proxyCode = " <?php \n " . $proxyCode ;
$proxyCode = substr ( Kernel :: stripComments ( $proxyCode ), 5 );
}
$code .= $proxyCode ;
2013-03-29 23:21:12 +00:00
}
return $code ;
}
2011-02-13 18:06:41 +00:00
/**
* Generates the require_once statement for service includes .
*
2012-05-18 18:41:48 +01:00
* @ param string $id The service id
2011-03-04 14:26:00 +00:00
* @ param Definition $definition
2011-12-13 07:50:54 +00:00
*
2011-02-13 18:06:41 +00:00
* @ return string
*/
2011-03-11 13:50:46 +00:00
private function addServiceInclude ( $id , $definition )
2010-05-06 12:25:53 +01:00
{
2011-01-05 11:13:27 +00:00
$template = " require_once %s; \n " ;
$code = '' ;
if ( null !== $file = $definition -> getFile ()) {
$code .= sprintf ( $template , $this -> dumpValue ( $file ));
}
foreach ( $this -> getInlinedDefinitions ( $definition ) as $definition ) {
if ( null !== $file = $definition -> getFile ()) {
$code .= sprintf ( $template , $this -> dumpValue ( $file ));
}
}
if ( '' !== $code ) {
$code .= " \n " ;
}
return $code ;
}
2011-02-13 18:06:41 +00:00
/**
* Generates the inline definition of a service .
*
2012-05-18 18:41:48 +01:00
* @ param string $id
2011-03-04 14:26:00 +00:00
* @ param Definition $definition
2011-12-13 07:50:54 +00:00
*
2011-02-13 18:06:41 +00:00
* @ return string
2012-09-07 23:56:45 +01:00
*
2014-11-30 13:33:44 +00:00
* @ throws RuntimeException When the factory definition is incomplete
2012-09-07 23:56:45 +01:00
* @ throws ServiceCircularReferenceException When a circular reference is detected
2011-02-13 18:06:41 +00:00
*/
2011-03-11 13:50:46 +00:00
private function addServiceInlinedDefinitions ( $id , $definition )
2011-01-05 11:13:27 +00:00
{
$code = '' ;
$variableMap = $this -> definitionVariables ;
2011-01-09 13:57:17 +00:00
$nbOccurrences = new \SplObjectStorage ();
$processed = new \SplObjectStorage ();
$inlinedDefinitions = $this -> getInlinedDefinitions ( $definition );
foreach ( $inlinedDefinitions as $definition ) {
if ( false === $nbOccurrences -> contains ( $definition )) {
$nbOccurrences -> offsetSet ( $definition , 1 );
} else {
$i = $nbOccurrences -> offsetGet ( $definition );
2013-01-05 08:01:42 +00:00
$nbOccurrences -> offsetSet ( $definition , $i + 1 );
2011-01-09 13:57:17 +00:00
}
}
foreach ( $inlinedDefinitions as $sDefinition ) {
if ( $processed -> contains ( $sDefinition )) {
continue ;
}
$processed -> offsetSet ( $sDefinition );
2011-01-05 11:13:27 +00:00
$class = $this -> dumpValue ( $sDefinition -> getClass ());
2013-01-05 08:01:42 +00:00
if ( $nbOccurrences -> offsetGet ( $sDefinition ) > 1 || $sDefinition -> getMethodCalls () || $sDefinition -> getProperties () || null !== $sDefinition -> getConfigurator () || false !== strpos ( $class , '$' )) {
2011-01-05 11:13:27 +00:00
$name = $this -> getNextVariableName ();
$variableMap -> offsetSet ( $sDefinition , new Variable ( $name ));
// a construct like:
// $a = new ServiceA(ServiceB $b); $b = new ServiceB(ServiceA $a);
// this is an indication for a wrong implementation, you can circumvent this problem
// by setting up your service structure like this:
// $b = new ServiceB();
// $a = new ServiceA(ServiceB $b);
// $b->setServiceA(ServiceA $a);
if ( $this -> hasReference ( $id , $sDefinition -> getArguments ())) {
2011-05-25 08:46:30 +01:00
throw new ServiceCircularReferenceException ( $id , array ( $id ));
2011-01-05 11:13:27 +00:00
}
2013-01-06 07:52:07 +00:00
$code .= $this -> addNewInstance ( $id , $sDefinition , '$' . $name , ' = ' );
2011-01-05 11:13:27 +00:00
2013-01-05 09:16:41 +00:00
if ( ! $this -> hasReference ( $id , $sDefinition -> getMethodCalls (), true ) && ! $this -> hasReference ( $id , $sDefinition -> getProperties (), true )) {
2011-01-05 11:13:27 +00:00
$code .= $this -> addServiceMethodCalls ( null , $sDefinition , $name );
2011-03-04 14:26:00 +00:00
$code .= $this -> addServiceProperties ( null , $sDefinition , $name );
2011-01-05 11:13:27 +00:00
$code .= $this -> addServiceConfigurator ( null , $sDefinition , $name );
}
$code .= " \n " ;
}
2010-05-06 12:25:53 +01:00
}
2011-01-05 11:13:27 +00:00
return $code ;
2010-01-04 14:26:20 +00:00
}
2011-02-13 18:06:41 +00:00
/**
* Adds the service return statement .
*
2012-05-18 18:41:48 +01:00
* @ param string $id Service id
2011-03-04 14:26:00 +00:00
* @ param Definition $definition
2011-12-13 07:50:54 +00:00
*
2011-02-13 18:06:41 +00:00
* @ return string
*/
2011-03-11 13:50:46 +00:00
private function addServiceReturn ( $id , $definition )
2010-05-06 12:25:53 +01:00
{
2011-01-05 11:13:27 +00:00
if ( $this -> isSimpleInstance ( $id , $definition )) {
2010-11-24 07:27:22 +00:00
return " } \n " ;
}
2010-01-04 14:26:20 +00:00
2010-11-24 07:27:22 +00:00
return " \n return \$ instance; \n } \n " ;
2010-01-04 14:26:20 +00:00
}
2011-02-13 18:06:41 +00:00
/**
* Generates the service instance .
*
2012-05-18 18:41:48 +01:00
* @ param string $id
2011-03-04 14:26:00 +00:00
* @ param Definition $definition
2011-12-13 07:50:54 +00:00
*
2011-02-13 18:06:41 +00:00
* @ return string
*
2011-12-04 23:51:22 +00:00
* @ throws InvalidArgumentException
* @ throws RuntimeException
2011-02-13 18:06:41 +00:00
*/
2011-03-11 13:50:46 +00:00
private function addServiceInstance ( $id , $definition )
2010-01-04 14:26:20 +00:00
{
2015-07-28 08:17:47 +01:00
$class = $definition -> getClass ();
if ( '\\' === substr ( $class , 0 , 1 )) {
$class = substr ( $class , 1 );
}
$class = $this -> dumpValue ( $class );
2010-03-01 17:37:22 +00:00
2010-07-16 19:59:38 +01:00
if ( 0 === strpos ( $class , " ' " ) && ! preg_match ( '/^\'[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/' , $class )) {
2011-12-04 23:51:22 +00:00
throw new InvalidArgumentException ( sprintf ( '"%s" is not a valid class name for the "%s" service.' , $class , $id ));
2010-07-16 16:45:10 +01:00
}
2014-10-22 19:27:13 +01:00
$simple = $this -> isSimpleInstance ( $id , $definition );
2013-03-29 23:21:12 +00:00
$isProxyCandidate = $this -> getProxyDumper () -> isProxyCandidate ( $definition );
2014-10-22 19:27:13 +01:00
$instantiation = '' ;
2010-11-24 07:27:22 +00:00
2013-03-29 23:21:12 +00:00
if ( ! $isProxyCandidate && ContainerInterface :: SCOPE_CONTAINER === $definition -> getScope ()) {
2010-11-24 07:27:22 +00:00
$instantiation = " \$ this->services[' $id '] = " . ( $simple ? '' : '$instance' );
2013-03-29 23:21:12 +00:00
} elseif ( ! $isProxyCandidate && ContainerInterface :: SCOPE_PROTOTYPE !== $scope = $definition -> getScope ()) {
2011-01-17 22:28:59 +00:00
$instantiation = " \$ this->services[' $id '] = \$ this->scopedServices[' $scope '][' $id '] = " . ( $simple ? '' : '$instance' );
2010-11-24 07:27:22 +00:00
} elseif ( ! $simple ) {
$instantiation = '$instance' ;
}
$return = '' ;
if ( $simple ) {
$return = 'return ' ;
2010-11-23 21:43:09 +00:00
} else {
2010-11-24 07:27:22 +00:00
$instantiation .= ' = ' ;
2010-11-23 21:43:09 +00:00
}
2013-01-06 07:52:07 +00:00
$code = $this -> addNewInstance ( $id , $definition , $return , $instantiation );
2010-01-04 14:26:20 +00:00
2011-01-05 11:13:27 +00:00
if ( ! $simple ) {
$code .= " \n " ;
}
2010-05-06 12:25:53 +01:00
return $code ;
2010-01-04 14:26:20 +00:00
}
2011-02-13 18:06:41 +00:00
/**
* Checks if the definition is a simple instance .
*
2012-05-18 18:41:48 +01:00
* @ param string $id
2011-03-04 14:26:00 +00:00
* @ param Definition $definition
2011-12-13 07:50:54 +00:00
*
2014-04-16 11:30:19 +01:00
* @ return bool
2011-02-13 18:06:41 +00:00
*/
2011-03-11 13:50:46 +00:00
private function isSimpleInstance ( $id , $definition )
2011-01-05 11:13:27 +00:00
{
foreach ( array_merge ( array ( $definition ), $this -> getInlinedDefinitions ( $definition )) as $sDefinition ) {
if ( $definition !== $sDefinition && ! $this -> hasReference ( $id , $sDefinition -> getMethodCalls ())) {
continue ;
}
2011-03-04 14:26:00 +00:00
if ( $sDefinition -> getMethodCalls () || $sDefinition -> getProperties () || $sDefinition -> getConfigurator ()) {
2011-01-05 11:13:27 +00:00
return false ;
}
}
return true ;
}
2011-02-13 18:06:41 +00:00
/**
* Adds method calls to a service definition .
*
2012-05-18 18:41:48 +01:00
* @ param string $id
2011-03-04 14:26:00 +00:00
* @ param Definition $definition
2012-05-18 18:41:48 +01:00
* @ param string $variableName
2011-12-13 07:50:54 +00:00
*
2011-02-13 18:06:41 +00:00
* @ return string
*/
2011-03-11 13:50:46 +00:00
private function addServiceMethodCalls ( $id , $definition , $variableName = 'instance' )
2010-01-04 14:26:20 +00:00
{
2010-05-06 12:25:53 +01:00
$calls = '' ;
2010-05-07 15:09:11 +01:00
foreach ( $definition -> getMethodCalls () as $call ) {
2010-05-06 12:25:53 +01:00
$arguments = array ();
2010-05-07 15:09:11 +01:00
foreach ( $call [ 1 ] as $value ) {
2010-05-06 12:25:53 +01:00
$arguments [] = $this -> dumpValue ( $value );
}
2010-01-04 14:26:20 +00:00
2011-01-05 11:13:27 +00:00
$calls .= $this -> wrapServiceConditionals ( $call [ 1 ], sprintf ( " \$ %s->%s(%s); \n " , $variableName , $call [ 0 ], implode ( ', ' , $arguments )));
2010-05-06 12:25:53 +01:00
}
2010-01-04 14:26:20 +00:00
2010-05-06 12:25:53 +01:00
return $calls ;
}
2010-01-04 14:26:20 +00:00
2011-03-11 13:50:46 +00:00
private function addServiceProperties ( $id , $definition , $variableName = 'instance' )
2011-03-04 14:26:00 +00:00
{
$code = '' ;
foreach ( $definition -> getProperties () as $name => $value ) {
2011-06-27 07:28:54 +01:00
$code .= sprintf ( " \$ %s->%s = %s; \n " , $variableName , $name , $this -> dumpValue ( $value ));
2011-03-04 14:26:00 +00:00
}
return $code ;
}
2011-02-13 18:06:41 +00:00
/**
* Generates the inline definition setup .
*
2012-05-18 18:41:48 +01:00
* @ param string $id
2011-03-04 14:26:00 +00:00
* @ param Definition $definition
2014-07-26 13:09:47 +01:00
*
2011-02-13 18:06:41 +00:00
* @ return string
2014-07-26 13:09:47 +01:00
*
* @ throws ServiceCircularReferenceException when the container contains a circular reference
2011-02-13 18:06:41 +00:00
*/
2011-03-11 13:50:46 +00:00
private function addServiceInlinedDefinitionsSetup ( $id , $definition )
2011-01-05 11:13:27 +00:00
{
$this -> referenceVariables [ $id ] = new Variable ( 'instance' );
$code = '' ;
2011-01-09 13:57:17 +00:00
$processed = new \SplObjectStorage ();
2011-01-05 11:13:27 +00:00
foreach ( $this -> getInlinedDefinitions ( $definition ) as $iDefinition ) {
2011-01-09 13:57:17 +00:00
if ( $processed -> contains ( $iDefinition )) {
continue ;
}
$processed -> offsetSet ( $iDefinition );
2013-01-05 09:16:41 +00:00
if ( ! $this -> hasReference ( $id , $iDefinition -> getMethodCalls (), true ) && ! $this -> hasReference ( $id , $iDefinition -> getProperties (), true )) {
2011-01-05 11:13:27 +00:00
continue ;
}
2013-09-12 07:52:33 +01:00
// if the instance is simple, the return statement has already been generated
// so, the only possible way to get there is because of a circular reference
if ( $this -> isSimpleInstance ( $id , $definition )) {
throw new ServiceCircularReferenceException ( $id , array ( $id ));
}
2013-01-05 08:13:52 +00:00
$name = ( string ) $this -> definitionVariables -> offsetGet ( $iDefinition );
$code .= $this -> addServiceMethodCalls ( null , $iDefinition , $name );
$code .= $this -> addServiceProperties ( null , $iDefinition , $name );
$code .= $this -> addServiceConfigurator ( null , $iDefinition , $name );
2011-01-05 11:13:27 +00:00
}
if ( '' !== $code ) {
$code .= " \n " ;
}
return $code ;
}
2011-02-13 18:06:41 +00:00
/**
2014-12-21 17:00:50 +00:00
* Adds configurator definition .
2011-02-13 18:06:41 +00:00
*
2012-05-18 18:41:48 +01:00
* @ param string $id
2011-03-04 14:26:00 +00:00
* @ param Definition $definition
2012-05-18 18:41:48 +01:00
* @ param string $variableName
2011-12-13 07:50:54 +00:00
*
2011-02-13 18:06:41 +00:00
* @ return string
*/
2011-03-11 13:50:46 +00:00
private function addServiceConfigurator ( $id , $definition , $variableName = 'instance' )
2010-01-04 14:26:20 +00:00
{
2010-05-07 15:09:11 +01:00
if ( ! $callable = $definition -> getConfigurator ()) {
2010-05-06 12:25:53 +01:00
return '' ;
}
2010-01-04 14:26:20 +00:00
2010-05-07 15:09:11 +01:00
if ( is_array ( $callable )) {
2013-11-02 12:45:44 +00:00
if ( $callable [ 0 ] instanceof Reference
|| ( $callable [ 0 ] instanceof Definition && $this -> definitionVariables -> contains ( $callable [ 0 ]))) {
return sprintf ( " %s->%s( \$ %s); \n " , $this -> dumpValue ( $callable [ 0 ]), $callable [ 1 ], $variableName );
2010-05-06 12:25:53 +01:00
}
2011-02-27 17:27:22 +00:00
2013-12-17 21:00:35 +00:00
$class = $this -> dumpValue ( $callable [ 0 ]);
// If the class is a string we can optimize call_user_func away
if ( strpos ( $class , " ' " ) === 0 ) {
2013-12-18 17:52:54 +00:00
return sprintf ( " %s::%s( \$ %s); \n " , $this -> dumpLiteralClass ( $class ), $callable [ 1 ], $variableName );
2013-12-17 21:00:35 +00:00
}
2011-02-27 17:27:22 +00:00
return sprintf ( " call_user_func(array(%s, '%s'), \$ %s); \n " , $this -> dumpValue ( $callable [ 0 ]), $callable [ 1 ], $variableName );
2010-05-06 12:25:53 +01:00
}
2011-02-27 17:27:22 +00:00
return sprintf ( " %s( \$ %s); \n " , $callable , $variableName );
2010-01-04 14:26:20 +00:00
}
2011-02-13 18:06:41 +00:00
/**
2014-12-21 17:00:50 +00:00
* Adds a service .
2011-02-13 18:06:41 +00:00
*
2012-05-18 18:41:48 +01:00
* @ param string $id
2011-03-04 14:26:00 +00:00
* @ param Definition $definition
2011-12-13 07:50:54 +00:00
*
2011-02-13 18:06:41 +00:00
* @ return string
*/
2011-03-11 13:50:46 +00:00
private function addService ( $id , $definition )
2010-05-06 12:25:53 +01:00
{
2011-01-05 11:13:27 +00:00
$this -> definitionVariables = new \SplObjectStorage ();
$this -> referenceVariables = array ();
$this -> variableCount = 0 ;
2010-07-04 17:56:48 +01:00
2013-01-23 11:25:17 +00:00
$return = array ();
2011-01-23 11:06:23 +00:00
if ( $definition -> isSynthetic ()) {
2013-01-23 11:25:17 +00:00
$return [] = '@throws RuntimeException always since this service is expected to be injected dynamically' ;
2011-02-02 17:22:27 +00:00
} elseif ( $class = $definition -> getClass ()) {
2015-07-28 08:17:47 +01:00
$return [] = sprintf ( '@return %s A %s instance.' , 0 === strpos ( $class , '%' ) ? 'object' : '\\' . ltrim ( $class , '\\' ), ltrim ( $class , '\\' ));
2014-04-13 16:18:39 +01:00
} elseif ( $definition -> getFactory ()) {
$factory = $definition -> getFactory ();
if ( is_string ( $factory )) {
$return [] = sprintf ( '@return object An instance returned by %s().' , $factory );
} elseif ( is_array ( $factory ) && ( is_string ( $factory [ 0 ]) || $factory [ 0 ] instanceof Definition || $factory [ 0 ] instanceof Reference )) {
2014-09-24 07:35:53 +01:00
if ( is_string ( $factory [ 0 ]) || $factory [ 0 ] instanceof Reference ) {
2014-04-13 16:18:39 +01:00
$return [] = sprintf ( '@return object An instance returned by %s::%s().' , ( string ) $factory [ 0 ], $factory [ 1 ]);
} elseif ( $factory [ 0 ] instanceof Definition ) {
$return [] = sprintf ( '@return object An instance returned by %s::%s().' , $factory [ 0 ] -> getClass (), $factory [ 1 ]);
}
}
2015-01-06 18:57:38 +00:00
} elseif ( $definition -> getFactoryClass ( false )) {
$return [] = sprintf ( '@return object An instance returned by %s::%s().' , $definition -> getFactoryClass ( false ), $definition -> getFactoryMethod ( false ));
} elseif ( $definition -> getFactoryService ( false )) {
$return [] = sprintf ( '@return object An instance returned by %s::%s().' , $definition -> getFactoryService ( false ), $definition -> getFactoryMethod ( false ));
2013-01-23 11:25:17 +00:00
}
$scope = $definition -> getScope ();
if ( ! in_array ( $scope , array ( ContainerInterface :: SCOPE_CONTAINER , ContainerInterface :: SCOPE_PROTOTYPE ))) {
if ( $return && 0 === strpos ( $return [ count ( $return ) - 1 ], '@return' )) {
$return [] = '' ;
}
$return [] = sprintf ( " @throws InactiveScopeException when the '%s' service is requested while the '%s' scope is not active " , $id , $scope );
2010-07-04 17:56:48 +01:00
}
2010-01-04 14:26:20 +00:00
2013-01-23 11:25:17 +00:00
$return = implode ( " \n * " , $return );
2010-05-06 12:25:53 +01:00
$doc = '' ;
2013-01-23 11:25:17 +00:00
if ( ContainerInterface :: SCOPE_PROTOTYPE !== $scope ) {
2015-12-21 11:01:57 +00:00
$doc .= <<< 'EOF'
2010-01-04 14:26:20 +00:00
2010-05-06 12:25:53 +01:00
*
* This service is shared .
* This method always returns the same instance of the service .
2010-01-04 14:26:20 +00:00
EOF ;
2010-05-06 12:25:53 +01:00
}
2010-01-04 14:26:20 +00:00
2011-01-05 11:13:27 +00:00
if ( ! $definition -> isPublic ()) {
2015-12-21 11:01:57 +00:00
$doc .= <<< 'EOF'
2011-01-05 11:13:27 +00:00
*
* This service is private .
* If you want to be able to request this service from the container directly ,
* make it public , otherwise you might end up with broken code .
EOF ;
}
2013-03-29 23:21:12 +00:00
if ( $definition -> isLazy ()) {
2014-10-22 19:27:13 +01:00
$lazyInitialization = '$lazyLoad = true' ;
2014-04-12 18:54:57 +01:00
$lazyInitializationDoc = " \n * @param bool \$ lazyLoad whether to try lazy-loading the service with a proxy \n * " ;
2013-03-29 23:21:12 +00:00
} else {
2014-10-22 19:27:13 +01:00
$lazyInitialization = '' ;
2013-03-29 23:21:12 +00:00
$lazyInitializationDoc = '' ;
}
// with proxies, for 5.3.3 compatibility, the getter must be public to be accessible to the initializer
$isProxyCandidate = $this -> getProxyDumper () -> isProxyCandidate ( $definition );
2014-10-22 19:27:13 +01:00
$visibility = $isProxyCandidate ? 'public' : 'protected' ;
$code = <<< EOF
2010-01-04 14:26:20 +00:00
2016-03-07 15:45:39 +00:00
/* { $this -> docStar }
2010-05-06 12:25:53 +01:00
* Gets the '$id' service . $doc
2013-03-29 23:21:12 +00:00
* $lazyInitializationDoc
2010-07-04 17:56:48 +01:00
* $return
2010-05-06 12:25:53 +01:00
*/
2013-07-19 08:14:04 +01:00
{ $visibility } function get { $this -> camelize ( $id )} Service ( $lazyInitialization )
2010-05-06 12:25:53 +01:00
{
2010-01-04 14:26:20 +00:00
2010-05-06 12:25:53 +01:00
EOF ;
2010-01-04 14:26:20 +00:00
2013-03-29 23:21:12 +00:00
$code .= $isProxyCandidate ? $this -> getProxyDumper () -> getProxyFactoryCode ( $definition , $id ) : '' ;
2013-01-23 11:25:17 +00:00
if ( ! in_array ( $scope , array ( ContainerInterface :: SCOPE_CONTAINER , ContainerInterface :: SCOPE_PROTOTYPE ))) {
2011-01-17 22:28:59 +00:00
$code .= <<< EOF
if ( ! isset ( \ $this -> scopedServices [ '$scope' ])) {
2011-03-14 20:12:42 +00:00
throw new InactiveScopeException ( '$id' , '$scope' );
2011-01-17 22:28:59 +00:00
}
EOF ;
}
2011-01-23 11:06:23 +00:00
if ( $definition -> isSynthetic ()) {
2011-12-05 18:04:50 +00:00
$code .= sprintf ( " throw new RuntimeException('You have requested a synthetic service ( \" %s \" ). The DIC does not know how to construct this service.'); \n } \n " , $id );
2011-01-23 11:06:23 +00:00
} else {
$code .=
$this -> addServiceInclude ( $id , $definition ) .
$this -> addServiceLocalTempVariables ( $id , $definition ) .
$this -> addServiceInlinedDefinitions ( $id , $definition ) .
$this -> addServiceInstance ( $id , $definition ) .
$this -> addServiceInlinedDefinitionsSetup ( $id , $definition ) .
$this -> addServiceMethodCalls ( $id , $definition ) .
2011-03-04 14:26:00 +00:00
$this -> addServiceProperties ( $id , $definition ) .
2011-01-23 11:06:23 +00:00
$this -> addServiceConfigurator ( $id , $definition ) .
$this -> addServiceReturn ( $id , $definition )
;
}
2010-05-06 12:25:53 +01:00
2011-01-05 11:13:27 +00:00
$this -> definitionVariables = null ;
$this -> referenceVariables = null ;
2010-05-06 12:25:53 +01:00
return $code ;
2010-01-04 14:26:20 +00:00
}
2011-02-13 18:06:41 +00:00
/**
2014-12-21 17:00:50 +00:00
* Adds multiple services .
2011-02-13 18:06:41 +00:00
*
* @ return string
*/
2011-03-11 13:50:46 +00:00
private function addServices ()
2010-02-09 08:45:23 +00:00
{
2013-06-04 13:31:04 +01:00
$publicServices = $privateServices = $synchronizers = '' ;
2011-01-26 23:14:31 +00:00
$definitions = $this -> container -> getDefinitions ();
ksort ( $definitions );
foreach ( $definitions as $id => $definition ) {
2011-01-05 11:13:27 +00:00
if ( $definition -> isPublic ()) {
$publicServices .= $this -> addService ( $id , $definition );
} else {
$privateServices .= $this -> addService ( $id , $definition );
}
2013-02-06 20:42:01 +00:00
$synchronizers .= $this -> addServiceSynchronizer ( $id , $definition );
2010-02-09 08:45:23 +00:00
}
2013-06-04 13:31:04 +01:00
return $publicServices . $synchronizers . $privateServices ;
2013-02-06 20:42:01 +00:00
}
/**
* Adds synchronizer methods .
*
* @ param string $id A service identifier
* @ param Definition $definition A Definition instance
2014-07-26 13:09:47 +01:00
*
* @ return string | null
2015-01-06 16:17:37 +00:00
*
* @ deprecated since version 2.7 , will be removed in 3.0 .
2013-02-06 20:42:01 +00:00
*/
private function addServiceSynchronizer ( $id , Definition $definition )
{
2015-01-06 16:17:37 +00:00
if ( ! $definition -> isSynchronized ( false )) {
2013-02-06 20:42:01 +00:00
return ;
}
2015-01-06 16:17:37 +00:00
if ( 'request' !== $id ) {
2015-06-07 07:33:05 +01:00
@ trigger_error ( 'Synchronized services were deprecated in version 2.7 and won\'t work anymore in 3.0.' , E_USER_DEPRECATED );
2015-01-06 16:17:37 +00:00
}
2013-02-06 20:42:01 +00:00
$code = '' ;
foreach ( $this -> container -> getDefinitions () as $definitionId => $definition ) {
foreach ( $definition -> getMethodCalls () as $call ) {
foreach ( $call [ 1 ] as $argument ) {
if ( $argument instanceof Reference && $id == ( string ) $argument ) {
$arguments = array ();
foreach ( $call [ 1 ] as $value ) {
$arguments [] = $this -> dumpValue ( $value );
}
$call = $this -> wrapServiceConditionals ( $call [ 1 ], sprintf ( " \$ this->get('%s')->%s(%s); " , $definitionId , $call [ 0 ], implode ( ', ' , $arguments )));
$code .= <<< EOF
if ( \ $this -> initialized ( '$definitionId' )) {
$call
}
EOF ;
}
}
}
}
if ( ! $code ) {
return ;
}
return <<< EOF
2016-03-07 15:45:39 +00:00
/* { $this -> docStar }
2013-02-06 20:42:01 +00:00
* Updates the '$id' service .
*/
2013-07-19 08:14:04 +01:00
protected function synchronize { $this -> camelize ( $id )} Service ()
2013-02-06 20:42:01 +00:00
{
$code }
EOF ;
2010-05-06 12:25:53 +01:00
}
2010-02-09 08:45:23 +00:00
2013-01-06 07:52:07 +00:00
private function addNewInstance ( $id , Definition $definition , $return , $instantiation )
{
$class = $this -> dumpValue ( $definition -> getClass ());
$arguments = array ();
foreach ( $definition -> getArguments () as $value ) {
$arguments [] = $this -> dumpValue ( $value );
}
2014-04-13 16:18:39 +01:00
if ( null !== $definition -> getFactory ()) {
$callable = $definition -> getFactory ();
if ( is_array ( $callable )) {
2015-12-02 16:08:27 +00:00
if ( ! preg_match ( '/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/' , $callable [ 1 ])) {
throw new RuntimeException ( sprintf ( 'Cannot dump definition because of invalid factory method (%s)' , $callable [ 1 ] ? : 'n/a' ));
}
2014-04-13 16:18:39 +01:00
if ( $callable [ 0 ] instanceof Reference
|| ( $callable [ 0 ] instanceof Definition && $this -> definitionVariables -> contains ( $callable [ 0 ]))) {
return sprintf ( " $return { $instantiation } %s->%s(%s); \n " , $this -> dumpValue ( $callable [ 0 ]), $callable [ 1 ], $arguments ? implode ( ', ' , $arguments ) : '' );
}
$class = $this -> dumpValue ( $callable [ 0 ]);
// If the class is a string we can optimize call_user_func away
if ( strpos ( $class , " ' " ) === 0 ) {
2014-09-27 17:06:30 +01:00
return sprintf ( " $return { $instantiation } %s::%s(%s); \n " , $this -> dumpLiteralClass ( $class ), $callable [ 1 ], $arguments ? implode ( ', ' , $arguments ) : '' );
2014-04-13 16:18:39 +01:00
}
2014-09-27 17:06:30 +01:00
return sprintf ( " $return { $instantiation } call_user_func(array(%s, '%s')%s); \n " , $this -> dumpValue ( $callable [ 0 ]), $callable [ 1 ], $arguments ? ', ' . implode ( ', ' , $arguments ) : '' );
2014-04-13 16:18:39 +01:00
}
2014-09-27 17:06:30 +01:00
return sprintf ( " $return { $instantiation } \\ %s(%s); \n " , $callable , $arguments ? implode ( ', ' , $arguments ) : '' );
2015-01-06 18:57:38 +00:00
} elseif ( null !== $definition -> getFactoryMethod ( false )) {
if ( null !== $definition -> getFactoryClass ( false )) {
$class = $this -> dumpValue ( $definition -> getFactoryClass ( false ));
2013-12-17 21:00:35 +00:00
// If the class is a string we can optimize call_user_func away
if ( strpos ( $class , " ' " ) === 0 ) {
2015-01-06 18:57:38 +00:00
return sprintf ( " $return { $instantiation } %s::%s(%s); \n " , $this -> dumpLiteralClass ( $class ), $definition -> getFactoryMethod ( false ), $arguments ? implode ( ', ' , $arguments ) : '' );
2013-12-17 21:00:35 +00:00
}
2015-01-06 18:57:38 +00:00
return sprintf ( " $return { $instantiation } call_user_func(array(%s, '%s')%s); \n " , $this -> dumpValue ( $definition -> getFactoryClass ( false )), $definition -> getFactoryMethod ( false ), $arguments ? ', ' . implode ( ', ' , $arguments ) : '' );
2013-01-06 07:52:07 +00:00
}
2015-01-06 18:57:38 +00:00
if ( null !== $definition -> getFactoryService ( false )) {
return sprintf ( " $return { $instantiation } %s->%s(%s); \n " , $this -> getServiceCall ( $definition -> getFactoryService ( false )), $definition -> getFactoryMethod ( false ), implode ( ', ' , $arguments ));
2013-01-06 07:52:07 +00:00
}
2013-04-10 11:24:37 +01:00
throw new RuntimeException ( sprintf ( 'Factory method requires a factory service or factory class in service definition for %s' , $id ));
2013-01-06 07:52:07 +00:00
}
if ( false !== strpos ( $class , '$' )) {
return sprintf ( " \$ class = %s; \n \n $return { $instantiation } new \$ class(%s); \n " , $class , implode ( ', ' , $arguments ));
}
2013-12-18 17:52:54 +00:00
return sprintf ( " $return { $instantiation } new %s(%s); \n " , $this -> dumpLiteralClass ( $class ), implode ( ', ' , $arguments ));
2013-01-06 07:52:07 +00:00
}
2011-02-13 18:06:41 +00:00
/**
* Adds the class headers .
*
2012-05-15 21:19:31 +01:00
* @ param string $class Class name
2011-02-13 18:06:41 +00:00
* @ param string $baseClass The name of the base class
2013-05-22 20:21:30 +01:00
* @ param string $namespace The class namespace
2011-12-13 07:50:54 +00:00
*
2011-02-13 18:06:41 +00:00
* @ return string
*/
2013-05-22 20:21:30 +01:00
private function startClass ( $class , $baseClass , $namespace )
2010-01-04 14:26:20 +00:00
{
2011-07-16 14:52:02 +01:00
$bagClass = $this -> container -> isFrozen () ? 'use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;' : 'use Symfony\Component\DependencyInjection\ParameterBag\\ParameterBag;' ;
2013-05-22 20:21:30 +01:00
$namespaceLine = $namespace ? " namespace $namespace ; \n " : '' ;
2010-06-27 17:28:29 +01:00
2010-05-06 12:25:53 +01:00
return <<< EOF
2010-01-04 14:26:20 +00:00
< ? php
2013-05-22 20:21:30 +01:00
$namespaceLine
2010-08-20 22:09:55 +01:00
use Symfony\Component\DependencyInjection\ContainerInterface ;
use Symfony\Component\DependencyInjection\Container ;
2011-03-14 20:12:42 +00:00
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException ;
2011-12-05 18:04:50 +00:00
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException ;
use Symfony\Component\DependencyInjection\Exception\LogicException ;
use Symfony\Component\DependencyInjection\Exception\RuntimeException ;
2011-01-30 14:06:45 +00:00
$bagClass
2010-01-04 14:26:20 +00:00
2016-03-07 15:45:39 +00:00
/* { $this -> docStar }
2015-03-24 21:20:39 +00:00
* $class .
2010-01-04 14:26:20 +00:00
*
* This class has been auto - generated
2010-07-05 10:08:27 +01:00
* by the Symfony Dependency Injection Component .
2010-01-04 14:26:20 +00:00
*/
2011-01-17 10:40:04 +00:00
class $ class extends $baseClass
2010-01-04 14:26:20 +00:00
{
2014-12-03 09:22:11 +00:00
private \ $parameters ;
2014-12-04 20:13:58 +00:00
private \ $targetDirs = array ();
2014-12-03 09:22:11 +00:00
2010-01-04 14:26:20 +00:00
EOF ;
2010-05-06 12:25:53 +01:00
}
2010-01-04 14:26:20 +00:00
2011-02-13 18:06:41 +00:00
/**
* Adds the constructor .
*
* @ return string
*/
2011-03-11 13:50:46 +00:00
private function addConstructor ()
2010-01-04 14:26:20 +00:00
{
2014-12-04 18:27:52 +00:00
$targetDirs = $this -> exportTargetDirs ();
2012-01-06 20:20:08 +00:00
$arguments = $this -> container -> getParameterBag () -> all () ? 'new ParameterBag($this->getDefaultParameters())' : null ;
2011-01-17 22:28:59 +00:00
$code = <<< EOF
2010-01-04 14:26:20 +00:00
2016-03-07 15:45:39 +00:00
/* { $this -> docStar }
2010-05-06 12:25:53 +01:00
* Constructor .
*/
public function __construct ()
2014-12-04 18:27:52 +00:00
{{ $targetDirs }
2012-01-06 20:20:08 +00:00
parent :: __construct ( $arguments );
2011-01-17 22:28:59 +00:00
EOF ;
if ( count ( $scopes = $this -> container -> getScopes ()) > 0 ) {
$code .= " \n " ;
2015-07-05 15:01:47 +01:00
$code .= ' $this->scopes = ' . $this -> dumpValue ( $scopes ) . " ; \n " ;
$code .= ' $this->scopeChildren = ' . $this -> dumpValue ( $this -> container -> getScopeChildren ()) . " ; \n " ;
2011-01-17 22:28:59 +00:00
}
2013-06-04 13:28:00 +01:00
$code .= $this -> addMethodMap ();
$code .= $this -> addAliases ();
2015-12-21 11:01:57 +00:00
$code .= <<< 'EOF'
2010-05-06 12:25:53 +01:00
}
2010-01-04 14:26:20 +00:00
2011-01-30 14:06:45 +00:00
EOF ;
return $code ;
}
2011-02-13 18:06:41 +00:00
/**
* Adds the constructor for a frozen container .
*
* @ return string
*/
2011-03-11 13:50:46 +00:00
private function addFrozenConstructor ()
2011-01-30 14:06:45 +00:00
{
2014-12-04 18:27:52 +00:00
$targetDirs = $this -> exportTargetDirs ();
2011-01-30 14:06:45 +00:00
2014-12-03 09:22:11 +00:00
$code = <<< EOF
2013-12-01 06:04:55 +00:00
2016-03-07 15:45:39 +00:00
/* { $this -> docStar }
2011-01-30 14:06:45 +00:00
* Constructor .
*/
public function __construct ()
2014-12-04 18:27:52 +00:00
{{ $targetDirs }
2012-08-10 12:48:23 +01:00
EOF ;
if ( $this -> container -> getParameterBag () -> all ()) {
$code .= " \n \$ this->parameters = \$ this->getDefaultParameters(); \n " ;
}
2015-12-21 11:01:57 +00:00
$code .= <<< 'EOF'
2011-01-30 14:06:45 +00:00
2015-12-21 11:01:57 +00:00
$this -> services =
$this -> scopedServices =
$this -> scopeStacks = array ();
2011-01-30 14:06:45 +00:00
EOF ;
$code .= " \n " ;
if ( count ( $scopes = $this -> container -> getScopes ()) > 0 ) {
2015-07-05 15:01:47 +01:00
$code .= ' $this->scopes = ' . $this -> dumpValue ( $scopes ) . " ; \n " ;
$code .= ' $this->scopeChildren = ' . $this -> dumpValue ( $this -> container -> getScopeChildren ()) . " ; \n " ;
2011-01-30 14:06:45 +00:00
} else {
$code .= " \$ this->scopes = array(); \n " ;
$code .= " \$ this->scopeChildren = array(); \n " ;
}
2013-06-04 13:28:00 +01:00
$code .= $this -> addMethodMap ();
$code .= $this -> addAliases ();
2015-12-21 11:01:57 +00:00
$code .= <<< 'EOF'
2013-06-04 13:28:00 +01:00
}
EOF ;
return $code ;
}
2014-09-05 10:37:47 +01:00
/**
* Adds the constructor for a frozen container .
*
* @ return string
*/
private function addFrozenCompile ()
{
return <<< EOF
2016-03-10 10:49:29 +00:00
/* { $this -> docStar }
2014-09-05 10:37:47 +01:00
* { @ inheritdoc }
*/
public function compile ()
{
2014-09-22 16:52:38 +01:00
throw new LogicException ( 'You cannot compile a dumped frozen container.' );
2014-09-05 10:37:47 +01:00
}
EOF ;
}
2013-06-04 13:28:00 +01:00
/**
2014-12-21 17:00:50 +00:00
* Adds the methodMap property definition .
2013-06-04 13:28:00 +01:00
*
* @ return string
*/
private function addMethodMap ()
{
if ( ! $definitions = $this -> container -> getDefinitions ()) {
return '' ;
}
$code = " \$ this->methodMap = array( \n " ;
2013-05-05 11:11:01 +01:00
ksort ( $definitions );
foreach ( $definitions as $id => $definition ) {
2013-07-19 08:14:04 +01:00
$code .= ' ' . var_export ( $id , true ) . ' => ' . var_export ( 'get' . $this -> camelize ( $id ) . 'Service' , true ) . " , \n " ;
2013-05-05 11:11:01 +01:00
}
2014-09-21 19:53:12 +01:00
return $code . " ); \n " ;
2011-01-30 14:06:45 +00:00
}
2013-06-04 13:28:00 +01:00
/**
2014-12-21 17:00:50 +00:00
* Adds the aliases property definition .
2013-06-04 13:28:00 +01:00
*
* @ return string
*/
private function addAliases ()
{
if ( ! $aliases = $this -> container -> getAliases ()) {
2013-07-07 13:58:42 +01:00
if ( $this -> container -> isFrozen ()) {
return " \n \$ this->aliases = array(); \n " ;
} else {
return '' ;
}
2013-06-04 13:28:00 +01:00
}
2011-01-17 22:28:59 +00:00
2013-06-04 13:28:00 +01:00
$code = " \$ this->aliases = array( \n " ;
ksort ( $aliases );
foreach ( $aliases as $alias => $id ) {
2013-06-05 10:51:05 +01:00
$id = ( string ) $id ;
while ( isset ( $aliases [ $id ])) {
$id = ( string ) $aliases [ $id ];
}
$code .= ' ' . var_export ( $alias , true ) . ' => ' . var_export ( $id , true ) . " , \n " ;
2013-06-04 13:28:00 +01:00
}
2014-09-21 19:53:12 +01:00
return $code . " ); \n " ;
2010-01-04 14:26:20 +00:00
}
2011-02-13 18:06:41 +00:00
/**
* Adds default parameters method .
*
* @ return string
*/
2011-03-11 13:50:46 +00:00
private function addDefaultParametersMethod ()
2010-05-06 12:25:53 +01:00
{
2010-06-27 17:28:29 +01:00
if ( ! $this -> container -> getParameterBag () -> all ()) {
2010-05-06 12:25:53 +01:00
return '' ;
}
2010-01-04 14:26:20 +00:00
2010-06-27 17:28:29 +01:00
$parameters = $this -> exportParameters ( $this -> container -> getParameterBag () -> all ());
2010-01-04 14:26:20 +00:00
2011-01-30 14:06:45 +00:00
$code = '' ;
if ( $this -> container -> isFrozen ()) {
2015-12-21 11:01:57 +00:00
$code .= <<< 'EOF'
2011-01-30 14:06:45 +00:00
/**
* { @ inheritdoc }
*/
2015-12-21 11:01:57 +00:00
public function getParameter ( $name )
2011-01-30 14:06:45 +00:00
{
2015-12-21 11:01:57 +00:00
$name = strtolower ( $name );
2011-01-30 14:06:45 +00:00
2015-12-21 11:01:57 +00:00
if ( ! ( isset ( $this -> parameters [ $name ]) || array_key_exists ( $name , $this -> parameters ))) {
throw new InvalidArgumentException ( sprintf ( 'The parameter "%s" must be defined.' , $name ));
2011-01-30 14:06:45 +00:00
}
2015-12-21 11:01:57 +00:00
return $this -> parameters [ $name ];
2011-01-30 14:06:45 +00:00
}
/**
* { @ inheritdoc }
*/
2015-12-21 11:01:57 +00:00
public function hasParameter ( $name )
2011-01-30 14:06:45 +00:00
{
2015-12-21 11:01:57 +00:00
$name = strtolower ( $name );
2013-01-13 19:19:05 +00:00
2015-12-21 11:01:57 +00:00
return isset ( $this -> parameters [ $name ]) || array_key_exists ( $name , $this -> parameters );
2011-01-30 14:06:45 +00:00
}
/**
* { @ inheritdoc }
*/
2015-12-21 11:01:57 +00:00
public function setParameter ( $name , $value )
2011-01-30 14:06:45 +00:00
{
2011-12-05 18:04:50 +00:00
throw new LogicException ( 'Impossible to call set() on a frozen ParameterBag.' );
2011-01-30 14:06:45 +00:00
}
2011-07-16 14:52:02 +01:00
/**
2014-04-15 06:57:34 +01:00
* { @ inheritdoc }
2011-07-16 14:52:02 +01:00
*/
public function getParameterBag ()
{
2015-12-21 11:01:57 +00:00
if ( null === $this -> parameterBag ) {
$this -> parameterBag = new FrozenParameterBag ( $this -> parameters );
2011-07-16 14:52:02 +01:00
}
2015-12-21 11:01:57 +00:00
return $this -> parameterBag ;
2011-07-16 14:52:02 +01:00
}
2014-12-03 08:59:38 +00:00
EOF ;
2016-03-07 15:45:39 +00:00
if ( '' === $this -> docStar ) {
$code = str_replace ( '/**' , '/*' , $code );
}
2014-12-03 09:22:11 +00:00
}
2014-12-03 08:59:38 +00:00
2011-01-30 14:06:45 +00:00
$code .= <<< EOF
2010-01-04 14:26:20 +00:00
2016-03-07 15:45:39 +00:00
/* { $this -> docStar }
2010-05-06 12:25:53 +01:00
* Gets the default parameters .
*
* @ return array An array of the default parameters
*/
protected function getDefaultParameters ()
2010-01-04 14:26:20 +00:00
{
2010-05-06 12:25:53 +01:00
return $parameters ;
2010-01-04 14:26:20 +00:00
}
EOF ;
2011-01-30 14:06:45 +00:00
return $code ;
2010-01-04 14:26:20 +00:00
}
2011-02-13 18:06:41 +00:00
/**
* Exports parameters .
*
2014-11-30 13:33:44 +00:00
* @ param array $parameters
* @ param string $path
* @ param int $indent
2011-12-13 07:50:54 +00:00
*
2011-02-13 18:06:41 +00:00
* @ return string
2012-12-16 12:02:54 +00:00
*
* @ throws InvalidArgumentException
2011-02-13 18:06:41 +00:00
*/
2011-05-13 11:52:44 +01:00
private function exportParameters ( $parameters , $path = '' , $indent = 12 )
2010-01-04 14:26:20 +00:00
{
2010-05-06 12:25:53 +01:00
$php = array ();
2010-05-07 15:09:11 +01:00
foreach ( $parameters as $key => $value ) {
2010-05-08 14:32:30 +01:00
if ( is_array ( $value )) {
2011-05-13 11:52:44 +01:00
$value = $this -> exportParameters ( $value , $path . '/' . $key , $indent + 4 );
2011-01-05 11:13:27 +00:00
} elseif ( $value instanceof Variable ) {
2011-12-04 23:51:22 +00:00
throw new InvalidArgumentException ( sprintf ( 'You cannot dump a container with parameters that contain variable references. Variable "%s" found in "%s".' , $value , $path . '/' . $key ));
2011-01-05 11:13:27 +00:00
} elseif ( $value instanceof Definition ) {
2011-12-04 23:51:22 +00:00
throw new InvalidArgumentException ( sprintf ( 'You cannot dump a container with parameters that contain service definitions. Definition for "%s" found in "%s".' , $value -> getClass (), $path . '/' . $key ));
2010-05-07 15:09:11 +01:00
} elseif ( $value instanceof Reference ) {
2011-12-04 23:51:22 +00:00
throw new InvalidArgumentException ( sprintf ( 'You cannot dump a container with parameters that contain references to other services (reference to service "%s" found in "%s").' , $value , $path . '/' . $key ));
2013-12-04 21:23:04 +00:00
} elseif ( $value instanceof Expression ) {
throw new InvalidArgumentException ( sprintf ( 'You cannot dump a container with parameters that contain expressions. Expression "%s" found in "%s".' , $value , $path . '/' . $key ));
2010-05-07 15:09:11 +01:00
} else {
2014-11-30 15:07:59 +00:00
$value = $this -> export ( $value );
2010-05-06 12:25:53 +01:00
}
$php [] = sprintf ( '%s%s => %s,' , str_repeat ( ' ' , $indent ), var_export ( $key , true ), $value );
}
2010-01-04 14:26:20 +00:00
2010-05-06 12:25:53 +01:00
return sprintf ( " array( \n %s \n %s) " , implode ( " \n " , $php ), str_repeat ( ' ' , $indent - 4 ));
}
2010-01-04 14:26:20 +00:00
2011-02-13 18:06:41 +00:00
/**
* Ends the class definition .
*
2011-06-04 16:30:56 +01:00
* @ return string
2011-02-13 18:06:41 +00:00
*/
2011-03-11 13:50:46 +00:00
private function endClass ()
2010-01-04 14:26:20 +00:00
{
2015-12-21 11:01:57 +00:00
return <<< 'EOF'
2010-05-06 12:25:53 +01:00
}
2010-01-04 14:26:20 +00:00
2010-05-06 12:25:53 +01:00
EOF ;
2010-01-04 14:26:20 +00:00
}
2010-05-06 12:25:53 +01:00
2011-02-13 18:06:41 +00:00
/**
* Wraps the service conditionals .
*
2011-03-04 14:26:00 +00:00
* @ param string $value
* @ param string $code
2011-12-13 07:50:54 +00:00
*
2011-02-13 18:06:41 +00:00
* @ return string
*/
2011-03-11 13:50:46 +00:00
private function wrapServiceConditionals ( $value , $code )
2010-01-04 14:26:20 +00:00
{
2010-07-15 14:11:33 +01:00
if ( ! $services = ContainerBuilder :: getServiceConditionals ( $value )) {
2010-05-06 12:25:53 +01:00
return $code ;
}
2010-01-04 14:26:20 +00:00
2010-05-06 12:25:53 +01:00
$conditions = array ();
2010-05-07 15:09:11 +01:00
foreach ( $services as $service ) {
2010-06-27 17:28:29 +01:00
$conditions [] = sprintf ( " \$ this->has('%s') " , $service );
2010-05-06 12:25:53 +01:00
}
2010-01-04 14:26:20 +00:00
2010-05-06 12:25:53 +01:00
// re-indent the wrapped code
$code = implode ( " \n " , array_map ( function ( $line ) { return $line ? ' ' . $line : $line ; }, explode ( " \n " , $code )));
2010-01-04 14:26:20 +00:00
2010-05-07 15:09:11 +01:00
return sprintf ( " if (%s) { \n %s } \n " , implode ( ' && ' , $conditions ), $code );
2010-01-04 14:26:20 +00:00
}
2011-02-13 18:06:41 +00:00
/**
2013-04-21 13:26:17 +01:00
* Builds service calls from arguments .
2011-02-13 18:06:41 +00:00
*
2014-11-30 13:33:44 +00:00
* @ param array $arguments
* @ param array & $calls By reference
* @ param array & $behavior By reference
2011-02-13 18:06:41 +00:00
*/
2011-03-11 13:50:46 +00:00
private function getServiceCallsFromArguments ( array $arguments , array & $calls , array & $behavior )
2011-01-05 11:13:27 +00:00
{
foreach ( $arguments as $argument ) {
if ( is_array ( $argument )) {
$this -> getServiceCallsFromArguments ( $argument , $calls , $behavior );
2011-12-18 13:42:59 +00:00
} elseif ( $argument instanceof Reference ) {
2011-01-05 11:13:27 +00:00
$id = ( string ) $argument ;
if ( ! isset ( $calls [ $id ])) {
$calls [ $id ] = 0 ;
}
if ( ! isset ( $behavior [ $id ])) {
$behavior [ $id ] = $argument -> getInvalidBehavior ();
2011-12-18 13:42:59 +00:00
} elseif ( ContainerInterface :: EXCEPTION_ON_INVALID_REFERENCE !== $behavior [ $id ]) {
2011-01-05 11:13:27 +00:00
$behavior [ $id ] = $argument -> getInvalidBehavior ();
}
2015-03-06 19:37:36 +00:00
++ $calls [ $id ];
2011-01-05 11:13:27 +00:00
}
}
}
2011-02-13 18:06:41 +00:00
/**
2013-04-21 13:26:17 +01:00
* Returns the inline definition .
2011-02-13 18:06:41 +00:00
*
2011-03-04 14:26:00 +00:00
* @ param Definition $definition
2011-12-13 07:50:54 +00:00
*
2011-03-21 10:28:38 +00:00
* @ return array
2011-02-13 18:06:41 +00:00
*/
2011-03-11 13:50:46 +00:00
private function getInlinedDefinitions ( Definition $definition )
2011-01-05 11:13:27 +00:00
{
if ( false === $this -> inlinedDefinitions -> contains ( $definition )) {
2011-03-04 14:26:00 +00:00
$definitions = array_merge (
$this -> getDefinitionsFromArguments ( $definition -> getArguments ()),
$this -> getDefinitionsFromArguments ( $definition -> getMethodCalls ()),
2013-11-02 12:45:44 +00:00
$this -> getDefinitionsFromArguments ( $definition -> getProperties ()),
2014-04-13 16:18:39 +01:00
$this -> getDefinitionsFromArguments ( array ( $definition -> getConfigurator ())),
$this -> getDefinitionsFromArguments ( array ( $definition -> getFactory ()))
2011-03-04 14:26:00 +00:00
);
2011-01-05 11:13:27 +00:00
$this -> inlinedDefinitions -> offsetSet ( $definition , $definitions );
return $definitions ;
}
return $this -> inlinedDefinitions -> offsetGet ( $definition );
}
2011-02-13 18:06:41 +00:00
/**
2013-04-21 13:26:17 +01:00
* Gets the definition from arguments .
2011-02-13 18:06:41 +00:00
*
2011-03-04 14:26:00 +00:00
* @ param array $arguments
2011-12-13 07:50:54 +00:00
*
2011-02-13 18:06:41 +00:00
* @ return array
*/
2011-03-11 13:50:46 +00:00
private function getDefinitionsFromArguments ( array $arguments )
2011-01-05 11:13:27 +00:00
{
$definitions = array ();
foreach ( $arguments as $argument ) {
if ( is_array ( $argument )) {
$definitions = array_merge ( $definitions , $this -> getDefinitionsFromArguments ( $argument ));
2011-12-18 13:42:59 +00:00
} elseif ( $argument instanceof Definition ) {
2011-01-05 11:13:27 +00:00
$definitions = array_merge (
$definitions ,
$this -> getInlinedDefinitions ( $argument ),
array ( $argument )
);
}
}
return $definitions ;
}
2011-02-13 18:06:41 +00:00
/**
2013-04-21 13:26:17 +01:00
* Checks if a service id has a reference .
2011-02-13 18:06:41 +00:00
*
2014-11-30 13:33:44 +00:00
* @ param string $id
* @ param array $arguments
* @ param bool $deep
* @ param array $visited
2011-12-13 07:50:54 +00:00
*
2014-04-16 11:30:19 +01:00
* @ return bool
2011-02-13 18:06:41 +00:00
*/
2015-03-24 17:00:37 +00:00
private function hasReference ( $id , array $arguments , $deep = false , array & $visited = array ())
2011-01-05 11:13:27 +00:00
{
foreach ( $arguments as $argument ) {
if ( is_array ( $argument )) {
2013-02-04 11:10:17 +00:00
if ( $this -> hasReference ( $id , $argument , $deep , $visited )) {
2011-01-05 11:13:27 +00:00
return true ;
}
2011-12-18 13:42:59 +00:00
} elseif ( $argument instanceof Reference ) {
2013-06-05 00:48:30 +01:00
$argumentId = ( string ) $argument ;
if ( $id === $argumentId ) {
2011-01-05 11:13:27 +00:00
return true ;
}
2013-01-05 09:16:41 +00:00
2013-06-05 00:48:30 +01:00
if ( $deep && ! isset ( $visited [ $argumentId ])) {
$visited [ $argumentId ] = true ;
2013-02-04 11:10:17 +00:00
2013-06-05 00:48:30 +01:00
$service = $this -> container -> getDefinition ( $argumentId );
2013-01-05 09:16:41 +00:00
$arguments = array_merge ( $service -> getMethodCalls (), $service -> getArguments (), $service -> getProperties ());
2013-02-04 11:10:17 +00:00
if ( $this -> hasReference ( $id , $arguments , $deep , $visited )) {
2013-01-05 09:16:41 +00:00
return true ;
}
}
2011-01-05 11:13:27 +00:00
}
}
return false ;
}
2011-02-13 18:06:41 +00:00
/**
* Dumps values .
*
2014-12-02 20:19:20 +00:00
* @ param mixed $value
2014-11-30 13:33:44 +00:00
* @ param bool $interpolate
2011-12-13 07:50:54 +00:00
*
2011-02-13 18:06:41 +00:00
* @ return string
2012-12-16 12:02:54 +00:00
*
* @ throws RuntimeException
2011-02-13 18:06:41 +00:00
*/
2011-03-11 13:50:46 +00:00
private function dumpValue ( $value , $interpolate = true )
2010-01-04 14:26:20 +00:00
{
2010-05-07 15:09:11 +01:00
if ( is_array ( $value )) {
2010-05-06 12:25:53 +01:00
$code = array ();
2010-05-07 15:09:11 +01:00
foreach ( $value as $k => $v ) {
2010-06-27 17:28:29 +01:00
$code [] = sprintf ( '%s => %s' , $this -> dumpValue ( $k , $interpolate ), $this -> dumpValue ( $v , $interpolate ));
2010-05-06 12:25:53 +01:00
}
2010-01-04 14:26:20 +00:00
2010-05-06 12:25:53 +01:00
return sprintf ( 'array(%s)' , implode ( ', ' , $code ));
2012-11-18 20:27:35 +00:00
} elseif ( $value instanceof Definition ) {
2011-01-05 11:13:27 +00:00
if ( null !== $this -> definitionVariables && $this -> definitionVariables -> contains ( $value )) {
return $this -> dumpValue ( $this -> definitionVariables -> offsetGet ( $value ), $interpolate );
}
if ( count ( $value -> getMethodCalls ()) > 0 ) {
2011-12-04 23:51:22 +00:00
throw new RuntimeException ( 'Cannot dump definitions which have method calls.' );
2011-01-05 11:13:27 +00:00
}
if ( null !== $value -> getConfigurator ()) {
2011-12-04 23:51:22 +00:00
throw new RuntimeException ( 'Cannot dump definitions which have a configurator.' );
2011-01-05 11:13:27 +00:00
}
$arguments = array ();
foreach ( $value -> getArguments () as $argument ) {
$arguments [] = $this -> dumpValue ( $argument );
}
2014-09-27 17:06:30 +01:00
if ( null !== $value -> getFactory ()) {
$factory = $value -> getFactory ();
if ( is_string ( $factory )) {
return sprintf ( '\\%s(%s)' , $factory , implode ( ', ' , $arguments ));
}
if ( is_array ( $factory )) {
2015-12-02 16:08:27 +00:00
if ( ! preg_match ( '/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/' , $factory [ 1 ])) {
throw new RuntimeException ( sprintf ( 'Cannot dump definition because of invalid factory method (%s)' , $factory [ 1 ] ? : 'n/a' ));
}
2014-09-27 17:06:30 +01:00
if ( is_string ( $factory [ 0 ])) {
2015-12-02 16:08:27 +00:00
return sprintf ( '%s::%s(%s)' , $this -> dumpLiteralClass ( $this -> dumpValue ( $factory [ 0 ])), $factory [ 1 ], implode ( ', ' , $arguments ));
2014-09-27 17:06:30 +01:00
}
if ( $factory [ 0 ] instanceof Definition ) {
return sprintf ( " call_user_func(array(%s, '%s')%s) " , $this -> dumpValue ( $factory [ 0 ]), $factory [ 1 ], count ( $arguments ) > 0 ? ', ' . implode ( ', ' , $arguments ) : '' );
}
if ( $factory [ 0 ] instanceof Reference ) {
return sprintf ( '%s->%s(%s)' , $this -> dumpValue ( $factory [ 0 ]), $factory [ 1 ], implode ( ', ' , $arguments ));
}
}
throw new RuntimeException ( 'Cannot dump definition because of invalid factory' );
}
2015-01-06 18:57:38 +00:00
if ( null !== $value -> getFactoryMethod ( false )) {
if ( null !== $value -> getFactoryClass ( false )) {
return sprintf ( " call_user_func(array(%s, '%s')%s) " , $this -> dumpValue ( $value -> getFactoryClass ( false )), $value -> getFactoryMethod ( false ), count ( $arguments ) > 0 ? ', ' . implode ( ', ' , $arguments ) : '' );
} elseif ( null !== $value -> getFactoryService ( false )) {
2015-03-15 19:44:07 +00:00
$service = $this -> dumpValue ( $value -> getFactoryService ( false ));
2015-01-25 07:08:53 +00:00
2015-03-22 16:57:18 +00:00
return sprintf ( '%s->%s(%s)' , 0 === strpos ( $service , '$' ) ? sprintf ( '$this->get(%s)' , $service ) : $this -> getServiceCall ( $value -> getFactoryService ( false )), $value -> getFactoryMethod ( false ), implode ( ', ' , $arguments ));
2011-01-05 11:13:27 +00:00
} else {
2011-12-04 23:51:22 +00:00
throw new RuntimeException ( 'Cannot dump definitions which have factory method without factory service or factory class.' );
2011-01-05 11:13:27 +00:00
}
}
2015-06-24 09:29:42 +01:00
$class = $value -> getClass ();
if ( null === $class ) {
throw new RuntimeException ( 'Cannot dump definitions which have no class nor factory.' );
}
2015-12-02 16:08:27 +00:00
return sprintf ( 'new %s(%s)' , $this -> dumpLiteralClass ( $this -> dumpValue ( $class )), implode ( ', ' , $arguments ));
2012-11-18 20:27:35 +00:00
} elseif ( $value instanceof Variable ) {
2011-01-05 11:13:27 +00:00
return '$' . $value ;
2012-11-18 20:27:35 +00:00
} elseif ( $value instanceof Reference ) {
2011-01-05 11:13:27 +00:00
if ( null !== $this -> referenceVariables && isset ( $this -> referenceVariables [ $id = ( string ) $value ])) {
return $this -> dumpValue ( $this -> referenceVariables [ $id ], $interpolate );
}
2010-05-06 12:25:53 +01:00
return $this -> getServiceCall (( string ) $value , $value );
2013-09-02 11:46:47 +01:00
} elseif ( $value instanceof Expression ) {
2014-09-25 08:50:05 +01:00
return $this -> getExpressionLanguage () -> compile (( string ) $value , array ( 'this' => 'container' ));
2012-11-18 20:27:35 +00:00
} elseif ( $value instanceof Parameter ) {
2010-06-27 17:28:29 +01:00
return $this -> dumpParameter ( $value );
} elseif ( true === $interpolate && is_string ( $value )) {
2010-05-08 14:32:30 +01:00
if ( preg_match ( '/^%([^%]+)%$/' , $value , $match )) {
2011-01-21 01:39:28 +00:00
// we do this to deal with non string values (Boolean, integer, ...)
2010-05-06 12:25:53 +01:00
// the preg_replace_callback converts them to strings
2010-06-27 17:28:29 +01:00
return $this -> dumpParameter ( strtolower ( $match [ 1 ]));
2010-05-07 15:09:11 +01:00
} else {
2010-06-27 17:28:29 +01:00
$that = $this ;
2012-05-20 17:15:10 +01:00
$replaceParameters = function ( $match ) use ( $that ) {
2011-05-26 07:22:16 +01:00
return " '. " . $that -> dumpParameter ( strtolower ( $match [ 2 ])) . " .' " ;
2010-05-06 12:25:53 +01:00
};
2014-11-30 15:07:59 +00:00
$code = str_replace ( '%%' , '%' , preg_replace_callback ( '/(?<!%)(%)([^%]+)\1/' , $replaceParameters , $this -> export ( $value )));
2010-05-06 12:25:53 +01:00
return $code ;
}
2010-05-07 15:09:11 +01:00
} elseif ( is_object ( $value ) || is_resource ( $value )) {
2011-12-04 23:51:22 +00:00
throw new RuntimeException ( 'Unable to dump a service container if a parameter is an object or a resource.' );
2010-05-07 15:09:11 +01:00
} else {
2014-11-30 15:07:59 +00:00
return $this -> export ( $value );
2010-05-06 12:25:53 +01:00
}
2010-01-04 14:26:20 +00:00
}
2010-05-06 12:25:53 +01:00
2013-12-18 17:52:54 +00:00
/**
* Dumps a string to a literal ( aka PHP Code ) class value .
*
* @ param string $class
*
* @ return string
2015-12-02 16:08:27 +00:00
*
* @ throws RuntimeException
2013-12-18 17:52:54 +00:00
*/
private function dumpLiteralClass ( $class )
{
2015-12-02 16:08:27 +00:00
if ( false !== strpos ( $class , '$' )) {
throw new RuntimeException ( 'Cannot dump definitions which have a variable class name.' );
}
if ( 0 !== strpos ( $class , " ' " ) || ! preg_match ( '/^\'[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/' , $class )) {
throw new RuntimeException ( sprintf ( 'Cannot dump definition because of invalid class name (%s)' , $class ? : 'n/a' ));
}
2014-09-22 10:14:18 +01:00
return '\\' . substr ( str_replace ( '\\\\' , '\\' , $class ), 1 , - 1 );
2013-12-18 17:52:54 +00:00
}
2011-02-13 18:06:41 +00:00
/**
2014-12-21 17:00:50 +00:00
* Dumps a parameter .
2011-02-13 18:06:41 +00:00
*
2011-03-04 14:26:00 +00:00
* @ param string $name
2011-12-13 07:50:54 +00:00
*
2011-02-13 18:06:41 +00:00
* @ return string
*/
2010-06-27 17:28:29 +01:00
public function dumpParameter ( $name )
{
2010-09-03 15:18:04 +01:00
if ( $this -> container -> isFrozen () && $this -> container -> hasParameter ( $name )) {
2010-06-27 17:28:29 +01:00
return $this -> dumpValue ( $this -> container -> getParameter ( $name ), false );
}
return sprintf ( " \$ this->getParameter('%s') " , strtolower ( $name ));
}
2014-12-17 09:56:43 +00:00
/**
2014-12-29 23:26:56 +00:00
* @ deprecated since version 2.6 . 2 , to be removed in 3.0 .
* Use \Symfony\Component\DependencyInjection\ContainerBuilder :: addExpressionLanguageProvider instead .
2014-12-17 09:56:43 +00:00
*
* @ param ExpressionFunctionProviderInterface $provider
*/
2014-09-23 16:21:57 +01:00
public function addExpressionLanguageProvider ( ExpressionFunctionProviderInterface $provider )
{
2015-06-07 07:33:05 +01:00
@ trigger_error ( 'The ' . __METHOD__ . ' method is deprecated since version 2.6.2 and will be removed in 3.0. Use the Symfony\Component\DependencyInjection\ContainerBuilder::addExpressionLanguageProvider method instead.' , E_USER_DEPRECATED );
2014-12-21 11:39:54 +00:00
2014-09-23 16:21:57 +01:00
$this -> expressionLanguageProviders [] = $provider ;
}
2011-02-13 18:06:41 +00:00
/**
2014-12-21 17:00:50 +00:00
* Gets a service call .
2011-02-13 18:06:41 +00:00
*
2011-04-23 16:05:44 +01:00
* @ param string $id
2011-03-04 14:26:00 +00:00
* @ param Reference $reference
2011-12-13 07:50:54 +00:00
*
2011-02-13 18:06:41 +00:00
* @ return string
*/
2011-03-11 13:50:46 +00:00
private function getServiceCall ( $id , Reference $reference = null )
2010-01-04 14:26:20 +00:00
{
2010-05-07 15:09:11 +01:00
if ( 'service_container' === $id ) {
2010-05-06 12:25:53 +01:00
return '$this' ;
}
2010-06-27 17:28:29 +01:00
if ( null !== $reference && ContainerInterface :: EXCEPTION_ON_INVALID_REFERENCE !== $reference -> getInvalidBehavior ()) {
return sprintf ( '$this->get(\'%s\', ContainerInterface::NULL_ON_INVALID_REFERENCE)' , $id );
2010-05-07 15:09:11 +01:00
} else {
2010-05-08 14:32:30 +01:00
if ( $this -> container -> hasAlias ( $id )) {
2011-01-07 14:44:29 +00:00
$id = ( string ) $this -> container -> getAlias ( $id );
2010-05-06 12:25:53 +01:00
}
2010-01-21 20:59:59 +00:00
2010-06-27 17:28:29 +01:00
return sprintf ( '$this->get(\'%s\')' , $id );
2010-05-06 12:25:53 +01:00
}
2010-01-04 14:26:20 +00:00
}
2011-01-05 11:13:27 +00:00
2013-07-19 08:14:04 +01:00
/**
* Convert a service id to a valid PHP method name .
*
* @ param string $id
*
* @ return string
*
* @ throws InvalidArgumentException
*/
private function camelize ( $id )
{
$name = Container :: camelize ( $id );
if ( ! preg_match ( '/^[a-zA-Z0-9_\x7f-\xff]+$/' , $name )) {
throw new InvalidArgumentException ( sprintf ( 'Service id "%s" cannot be converted to a valid PHP method name.' , $id ));
}
return $name ;
}
2011-01-05 11:13:27 +00:00
/**
2014-12-21 17:00:50 +00:00
* Returns the next name to use .
2011-01-05 11:13:27 +00:00
*
* @ return string
*/
2011-03-11 13:50:46 +00:00
private function getNextVariableName ()
2011-01-05 11:13:27 +00:00
{
$firstChars = self :: FIRST_CHARS ;
$firstCharsLength = strlen ( $firstChars );
$nonFirstChars = self :: NON_FIRST_CHARS ;
$nonFirstCharsLength = strlen ( $nonFirstChars );
2011-02-27 19:56:29 +00:00
while ( true ) {
2011-01-05 11:13:27 +00:00
$name = '' ;
$i = $this -> variableCount ;
2011-02-27 19:56:29 +00:00
if ( '' === $name ) {
2015-03-27 22:05:05 +00:00
$name .= $firstChars [ $i % $firstCharsLength ];
$i = ( int ) ( $i / $firstCharsLength );
2011-01-05 11:13:27 +00:00
}
2011-02-27 19:56:29 +00:00
while ( $i > 0 ) {
2015-03-06 19:37:36 +00:00
-- $i ;
2015-03-27 22:05:05 +00:00
$name .= $nonFirstChars [ $i % $nonFirstCharsLength ];
$i = ( int ) ( $i / $nonFirstCharsLength );
2011-01-05 11:13:27 +00:00
}
2015-03-06 19:37:36 +00:00
++ $this -> variableCount ;
2011-01-05 11:13:27 +00:00
// check that the name is not reserved
if ( in_array ( $name , $this -> reservedVariables , true )) {
continue ;
}
return $name ;
}
}
2013-09-02 11:46:47 +01:00
private function getExpressionLanguage ()
{
if ( null === $this -> expressionLanguage ) {
if ( ! class_exists ( 'Symfony\Component\ExpressionLanguage\ExpressionLanguage' )) {
throw new RuntimeException ( 'Unable to use expressions as the Symfony ExpressionLanguage component is not installed.' );
}
2014-12-17 09:56:43 +00:00
$providers = array_merge ( $this -> container -> getExpressionLanguageProviders (), $this -> expressionLanguageProviders );
$this -> expressionLanguage = new ExpressionLanguage ( null , $providers );
2014-12-19 11:05:09 +00:00
if ( $this -> container -> isTrackingResources ()) {
foreach ( $providers as $provider ) {
$this -> container -> addObjectResource ( $provider );
}
}
2013-09-02 11:46:47 +01:00
}
return $this -> expressionLanguage ;
}
2014-12-02 21:48:32 +00:00
2014-12-04 18:27:52 +00:00
private function exportTargetDirs ()
{
return null === $this -> targetDirRegex ? '' : <<< EOF
\ $dir = __DIR__ ;
for ( \ $i = 1 ; \ $i <= { $this -> targetDirMaxMatches }; ++ \ $i ) {
\ $this -> targetDirs [ \ $i ] = \ $dir = dirname ( \ $dir );
}
EOF ;
}
2014-12-02 21:48:32 +00:00
private function export ( $value )
{
if ( null !== $this -> targetDirRegex && is_string ( $value ) && preg_match ( $this -> targetDirRegex , $value , $matches , PREG_OFFSET_CAPTURE )) {
$prefix = $matches [ 0 ][ 1 ] ? var_export ( substr ( $value , 0 , $matches [ 0 ][ 1 ]), true ) . '.' : '' ;
$suffix = $matches [ 0 ][ 1 ] + strlen ( $matches [ 0 ][ 0 ]);
$suffix = isset ( $value [ $suffix ]) ? '.' . var_export ( substr ( $value , $suffix ), true ) : '' ;
$dirname = '__DIR__' ;
2014-12-04 20:13:58 +00:00
if ( 0 < $offset = 1 + $this -> targetDirMaxMatches - count ( $matches )) {
$dirname = sprintf ( '$this->targetDirs[%d]' , $offset );
2014-12-02 21:48:32 +00:00
}
if ( $prefix || $suffix ) {
return sprintf ( '(%s%s%s)' , $prefix , $dirname , $suffix );
}
return $dirname ;
}
return var_export ( $value , true );
}
2010-01-04 14:26:20 +00:00
}