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\DependencyInjection\ParameterBag ;
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException ;
use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException ;
use Symfony\Component\DependencyInjection\Exception\RuntimeException ;
/**
* Holds parameters .
*
* @ author Fabien Potencier < fabien @ symfony . com >
*/
class ParameterBag implements ParameterBagInterface
{
protected $parameters = array ();
protected $resolved = false ;
/**
* @ param array $parameters An array of parameters
*/
public function __construct ( array $parameters = array ())
{
$this -> add ( $parameters );
}
/**
* Clears all parameters .
*/
public function clear ()
{
$this -> parameters = array ();
}
/**
* Adds parameters to the service container parameters .
*
* @ param array $parameters An array of parameters
*/
public function add ( array $parameters )
{
foreach ( $parameters as $key => $value ) {
$this -> parameters [ strtolower ( $key )] = $value ;
}
}
/**
2017-02-03 00:28:38 +00:00
* { @ inheritdoc }
2015-08-18 00:00:26 +00:00
*/
public function all ()
{
return $this -> parameters ;
}
/**
2017-02-03 00:28:38 +00:00
* { @ inheritdoc }
2015-08-18 00:00:26 +00:00
*/
public function get ( $name )
{
$name = strtolower ( $name );
if ( ! array_key_exists ( $name , $this -> parameters )) {
if ( ! $name ) {
throw new ParameterNotFoundException ( $name );
}
$alternatives = array ();
foreach ( $this -> parameters as $key => $parameterValue ) {
$lev = levenshtein ( $name , $key );
if ( $lev <= strlen ( $name ) / 3 || false !== strpos ( $key , $name )) {
$alternatives [] = $key ;
}
}
throw new ParameterNotFoundException ( $name , null , null , null , $alternatives );
}
return $this -> parameters [ $name ];
}
/**
* Sets a service container parameter .
*
* @ param string $name The parameter name
* @ param mixed $value The parameter value
*/
public function set ( $name , $value )
{
$this -> parameters [ strtolower ( $name )] = $value ;
}
/**
2017-02-03 00:28:38 +00:00
* { @ inheritdoc }
2015-08-18 00:00:26 +00:00
*/
public function has ( $name )
{
return array_key_exists ( strtolower ( $name ), $this -> parameters );
}
/**
* Removes a parameter .
*
* @ param string $name The parameter name
*/
public function remove ( $name )
{
unset ( $this -> parameters [ strtolower ( $name )]);
}
/**
2017-02-03 00:28:38 +00:00
* { @ inheritdoc }
2015-08-18 00:00:26 +00:00
*/
public function resolve ()
{
if ( $this -> resolved ) {
return ;
}
$parameters = array ();
foreach ( $this -> parameters as $key => $value ) {
try {
$value = $this -> resolveValue ( $value );
$parameters [ $key ] = $this -> unescapeValue ( $value );
} catch ( ParameterNotFoundException $e ) {
$e -> setSourceKey ( $key );
throw $e ;
}
}
$this -> parameters = $parameters ;
$this -> resolved = true ;
}
/**
* Replaces parameter placeholders ( % name % ) by their values .
*
* @ param mixed $value A value
* @ param array $resolving An array of keys that are being resolved ( used internally to detect circular references )
*
* @ return mixed The resolved value
*
* @ throws ParameterNotFoundException if a placeholder references a parameter that does not exist
* @ throws ParameterCircularReferenceException if a circular reference if detected
* @ throws RuntimeException when a given parameter has a type problem .
*/
public function resolveValue ( $value , array $resolving = array ())
{
if ( is_array ( $value )) {
$args = array ();
foreach ( $value as $k => $v ) {
$args [ $this -> resolveValue ( $k , $resolving )] = $this -> resolveValue ( $v , $resolving );
}
return $args ;
}
if ( ! is_string ( $value )) {
return $value ;
}
return $this -> resolveString ( $value , $resolving );
}
/**
* Resolves parameters inside a string .
*
* @ param string $value The string to resolve
* @ param array $resolving An array of keys that are being resolved ( used internally to detect circular references )
*
* @ return string The resolved string
*
* @ throws ParameterNotFoundException if a placeholder references a parameter that does not exist
* @ throws ParameterCircularReferenceException if a circular reference if detected
* @ throws RuntimeException when a given parameter has a type problem .
*/
public function resolveString ( $value , array $resolving = array ())
{
// we do this to deal with non string values (Boolean, integer, ...)
// as the preg_replace_callback throw an exception when trying
// a non-string in a parameter value
if ( preg_match ( '/^%([^%\s]+)%$/' , $value , $match )) {
$key = strtolower ( $match [ 1 ]);
if ( isset ( $resolving [ $key ])) {
throw new ParameterCircularReferenceException ( array_keys ( $resolving ));
}
$resolving [ $key ] = true ;
return $this -> resolved ? $this -> get ( $key ) : $this -> resolveValue ( $this -> get ( $key ), $resolving );
}
$self = $this ;
return preg_replace_callback ( '/%%|%([^%\s]+)%/' , function ( $match ) use ( $self , $resolving , $value ) {
// skip %%
if ( ! isset ( $match [ 1 ])) {
return '%%' ;
}
$key = strtolower ( $match [ 1 ]);
if ( isset ( $resolving [ $key ])) {
throw new ParameterCircularReferenceException ( array_keys ( $resolving ));
}
$resolved = $self -> get ( $key );
if ( ! is_string ( $resolved ) && ! is_numeric ( $resolved )) {
throw new RuntimeException ( sprintf ( 'A string value must be composed of strings and/or numbers, but found parameter "%s" of type %s inside string value "%s".' , $key , gettype ( $resolved ), $value ));
}
$resolved = ( string ) $resolved ;
$resolving [ $key ] = true ;
return $self -> isResolved () ? $resolved : $self -> resolveString ( $resolved , $resolving );
}, $value );
}
public function isResolved ()
{
return $this -> resolved ;
}
/**
* { @ inheritdoc }
*/
public function escapeValue ( $value )
{
if ( is_string ( $value )) {
return str_replace ( '%' , '%%' , $value );
}
if ( is_array ( $value )) {
$result = array ();
foreach ( $value as $k => $v ) {
$result [ $k ] = $this -> escapeValue ( $v );
}
return $result ;
}
return $value ;
}
2017-02-03 00:28:38 +00:00
/**
* { @ inheritdoc }
*/
2015-08-18 00:00:26 +00:00
public function unescapeValue ( $value )
{
if ( is_string ( $value )) {
return str_replace ( '%%' , '%' , $value );
}
if ( is_array ( $value )) {
$result = array ();
foreach ( $value as $k => $v ) {
$result [ $k ] = $this -> unescapeValue ( $v );
}
return $result ;
}
return $value ;
}
}