2015-08-17 17:00:26 -07: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\DependencyInjection\Compiler ;
use Symfony\Component\DependencyInjection\ContainerInterface ;
use Symfony\Component\DependencyInjection\Reference ;
use Symfony\Component\DependencyInjection\ContainerBuilder ;
use Symfony\Component\DependencyInjection\Exception\RuntimeException ;
/**
* Emulates the invalid behavior if the reference is not found within the
* container .
*
* @ author Johannes M . Schmitt < schmittjoh @ gmail . com >
*/
class ResolveInvalidReferencesPass implements CompilerPassInterface
{
private $container ;
/**
* Process the ContainerBuilder to resolve invalid references .
*
* @ param ContainerBuilder $container
*/
public function process ( ContainerBuilder $container )
{
$this -> container = $container ;
foreach ( $container -> getDefinitions () as $definition ) {
if ( $definition -> isSynthetic () || $definition -> isAbstract ()) {
continue ;
}
$definition -> setArguments (
$this -> processArguments ( $definition -> getArguments ())
);
$calls = array ();
foreach ( $definition -> getMethodCalls () as $call ) {
try {
$calls [] = array ( $call [ 0 ], $this -> processArguments ( $call [ 1 ], true ));
2015-08-27 12:03:05 -07:00
} catch ( RuntimeException $e ) {
2015-08-17 17:00:26 -07:00
// this call is simply removed
}
}
$definition -> setMethodCalls ( $calls );
$properties = array ();
foreach ( $definition -> getProperties () as $name => $value ) {
try {
$value = $this -> processArguments ( array ( $value ), true );
$properties [ $name ] = reset ( $value );
2015-08-27 12:03:05 -07:00
} catch ( RuntimeException $e ) {
2015-08-17 17:00:26 -07:00
// ignore property
}
}
$definition -> setProperties ( $properties );
}
}
/**
* Processes arguments to determine invalid references .
*
* @ param array $arguments An array of Reference objects
* @ param bool $inMethodCall
*
* @ return array
*
* @ throws RuntimeException When the config is invalid
*/
private function processArguments ( array $arguments , $inMethodCall = false )
{
foreach ( $arguments as $k => $argument ) {
if ( is_array ( $argument )) {
$arguments [ $k ] = $this -> processArguments ( $argument , $inMethodCall );
} elseif ( $argument instanceof Reference ) {
$id = ( string ) $argument ;
$invalidBehavior = $argument -> getInvalidBehavior ();
$exists = $this -> container -> has ( $id );
// resolve invalid behavior
if ( ! $exists && ContainerInterface :: NULL_ON_INVALID_REFERENCE === $invalidBehavior ) {
$arguments [ $k ] = null ;
} elseif ( ! $exists && ContainerInterface :: IGNORE_ON_INVALID_REFERENCE === $invalidBehavior ) {
if ( $inMethodCall ) {
throw new RuntimeException ( 'Method shouldn\'t be called.' );
}
$arguments [ $k ] = null ;
}
}
}
return $arguments ;
}
}