diff --git a/src/Symfony/Components/DependencyInjection/Container.php b/src/Symfony/Components/DependencyInjection/Container.php
index 48415b202773..5aa62f8a1359 100644
--- a/src/Symfony/Components/DependencyInjection/Container.php
+++ b/src/Symfony/Components/DependencyInjection/Container.php
@@ -72,10 +72,17 @@ public function __construct(ParameterBagInterface $parameterBag = null)
}
/**
- * Freezes the container parameter bag.
+ * Freezes the container.
+ *
+ * This method does two things:
+ *
+ * * Parameter values are resolved;
+ * * The parameter bag is freezed.
*/
public function freeze()
{
+ $this->parameterBag->resolve();
+
$this->parameterBag = new FrozenParameterBag($this->parameterBag->all());
}
diff --git a/src/Symfony/Components/DependencyInjection/ContainerBuilder.php b/src/Symfony/Components/DependencyInjection/ContainerBuilder.php
index ec46a30888a8..5e4611d5e8a0 100644
--- a/src/Symfony/Components/DependencyInjection/ContainerBuilder.php
+++ b/src/Symfony/Components/DependencyInjection/ContainerBuilder.php
@@ -79,6 +79,10 @@ public function addObjectResource($object)
*/
public function loadFromExtension(LoaderExtensionInterface $extension, $tag, array $values = array())
{
+ if (true === $this->isFrozen()) {
+ throw new \LogicException('Cannot load from an extension on a frozen container.');
+ }
+
$namespace = $extension->getAlias();
$this->addObjectResource($extension);
@@ -187,6 +191,10 @@ public function get($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INV
*/
public function merge(ContainerBuilder $container)
{
+ if (true === $this->isFrozen()) {
+ throw new \LogicException('Cannot merge on a frozen container.');
+ }
+
$this->addDefinitions($container->getDefinitions());
$this->addAliases($container->getAliases());
$this->parameterBag->add($container->getParameterBag()->all());
@@ -215,10 +223,16 @@ public function getExtensionContainers()
}
/**
- * Commits the extension configuration into the main configuration
- * and resolves parameter values.
+ * Freezes the container.
+ *
+ * This method does four things:
+ *
+ * * The extension configurations are merged;
+ * * Parameter values are resolved;
+ * * The parameter bag is freezed;
+ * * Extension loading is disabled.
*/
- public function commit()
+ public function freeze()
{
$parameters = $this->parameterBag->all();
$definitions = $this->definitions;
@@ -233,9 +247,7 @@ public function commit()
$this->addAliases($aliases);
$this->parameterBag->add($parameters);
- foreach ($this->parameterBag->all() as $key => $value) {
- $this->parameterBag->set($key, $this->getParameterBag()->resolveValue($value));
- }
+ parent::freeze();
}
/**
diff --git a/src/Symfony/Components/DependencyInjection/Dumper/XmlDumper.php b/src/Symfony/Components/DependencyInjection/Dumper/XmlDumper.php
index 62bf2c64e72a..13954f4f4bc7 100644
--- a/src/Symfony/Components/DependencyInjection/Dumper/XmlDumper.php
+++ b/src/Symfony/Components/DependencyInjection/Dumper/XmlDumper.php
@@ -42,7 +42,13 @@ protected function addParameters()
return '';
}
- return sprintf(" \n%s \n", $this->convertParameters($this->escape($this->container->getParameterBag()->all()), 'parameter', 4));
+ if ($this->container->isFrozen()) {
+ $parameters = $this->escape($this->container->getParameterBag()->all());
+ } else {
+ $parameters = $this->container->getParameterBag()->all();
+ }
+
+ return sprintf(" \n%s \n", $this->convertParameters($parameters, 'parameter', 4));
}
protected function addService($id, $definition)
diff --git a/src/Symfony/Components/DependencyInjection/Dumper/YamlDumper.php b/src/Symfony/Components/DependencyInjection/Dumper/YamlDumper.php
index 65c9c0c63245..d2f528744f19 100644
--- a/src/Symfony/Components/DependencyInjection/Dumper/YamlDumper.php
+++ b/src/Symfony/Components/DependencyInjection/Dumper/YamlDumper.php
@@ -128,7 +128,13 @@ protected function addParameters()
return '';
}
- return Yaml::dump(array('parameters' => $this->prepareParameters($this->container->getParameterBag()->all())), 2);
+ if ($this->container->isFrozen()) {
+ $parameters = $this->prepareParameters($this->container->getParameterBag()->all());
+ } else {
+ $parameters = $this->container->getParameterBag()->all();
+ }
+
+ return Yaml::dump(array('parameters' => $parameters), 2);
}
/**
diff --git a/src/Symfony/Components/DependencyInjection/ParameterBag/ParameterBag.php b/src/Symfony/Components/DependencyInjection/ParameterBag/ParameterBag.php
index 5132ab8dfe84..e9afe168ebca 100644
--- a/src/Symfony/Components/DependencyInjection/ParameterBag/ParameterBag.php
+++ b/src/Symfony/Components/DependencyInjection/ParameterBag/ParameterBag.php
@@ -105,6 +105,16 @@ public function has($name)
return array_key_exists(strtolower($name), $this->parameters);
}
+ /**
+ * Replaces parameter placeholders (%name%) by their values for all parameters.
+ */
+ public function resolve()
+ {
+ foreach ($this->parameters as $key => $value) {
+ $this->parameters[$key] = $this->resolveValue($value);
+ }
+ }
+
/**
* Replaces parameter placeholders (%name%) by their values.
*
@@ -120,31 +130,24 @@ public function resolveValue($value)
$args[$this->resolveValue($k)] = $this->resolveValue($v);
}
- $value = $args;
- } else if (is_string($value)) {
- if (preg_match('/^%([^%]+)%$/', $value, $match)) {
- // we do this to deal with non string values (boolean, integer, ...)
- // the preg_replace_callback converts them to strings
- if (!array_key_exists($name = strtolower($match[1]), $this->parameters)) {
- throw new \RuntimeException(sprintf('The parameter "%s" must be defined.', $name));
- }
-
- $value = $this->parameters[$name];
- } else {
- $parameters = $this->parameters;
- $replaceParameter = function ($match) use ($parameters, $value)
- {
- if (!array_key_exists($name = strtolower($match[2]), $parameters)) {
- throw new \RuntimeException(sprintf('The parameter "%s" must be defined (used in the following expression: "%s").', $name, $value));
- }
-
- return $parameters[$name];
- };
-
- $value = str_replace('%%', '%', preg_replace_callback('/(?get(strtolower($match[1]));
+ }
+
+ return str_replace('%%', '%', preg_replace_callback(array('/(?get(strtolower($match[1]));
}
}
diff --git a/tests/Symfony/Tests/Components/DependencyInjection/ContainerBuilderTest.php b/tests/Symfony/Tests/Components/DependencyInjection/ContainerBuilderTest.php
index 9115ca7c1f39..cd73f5eb3b4c 100644
--- a/tests/Symfony/Tests/Components/DependencyInjection/ContainerBuilderTest.php
+++ b/tests/Symfony/Tests/Components/DependencyInjection/ContainerBuilderTest.php
@@ -313,14 +313,14 @@ public function testMerge()
$config = new ContainerBuilder(new ParameterBag(array('foo' => '%bar%')));
$container->merge($config);
////// FIXME
- $container->commit();
+ $container->freeze();
$this->assertEquals(array('bar' => 'foo', 'foo' => 'foo'), $container->getParameterBag()->all(), '->merge() evaluates the values of the parameters towards already defined ones');
$container = new ContainerBuilder(new ParameterBag(array('bar' => 'foo')));
$config = new ContainerBuilder(new ParameterBag(array('foo' => '%bar%', 'baz' => '%foo%')));
$container->merge($config);
////// FIXME
- $container->commit();
+ $container->freeze();
$this->assertEquals(array('bar' => 'foo', 'foo' => 'foo', 'baz' => 'foo'), $container->getParameterBag()->all(), '->merge() evaluates the values of the parameters towards already defined ones');
$container = new ContainerBuilder();
diff --git a/tests/Symfony/Tests/Components/DependencyInjection/CrossCheckTest.php b/tests/Symfony/Tests/Components/DependencyInjection/CrossCheckTest.php
index 4c0349595c3e..eae20d6dca58 100644
--- a/tests/Symfony/Tests/Components/DependencyInjection/CrossCheckTest.php
+++ b/tests/Symfony/Tests/Components/DependencyInjection/CrossCheckTest.php
@@ -32,22 +32,24 @@ public function testCrossCheck($fixture, $type)
$loaderClass = 'Symfony\\Components\\DependencyInjection\\Loader\\'.ucfirst($type).'FileLoader';
$dumperClass = 'Symfony\\Components\\DependencyInjection\\Dumper\\'.ucfirst($type).'Dumper';
- $container1 = new ContainerBuilder();
- $loader1 = new $loaderClass($container1);
- $loader1->load(self::$fixturesPath.'/'.$type.'/'.$fixture);
- $container1->setParameter('path', self::$fixturesPath.'/includes');
+ $tmp = tempnam('sf_service_container', 'sf');
+
+ $loader1 = new $loaderClass();
+ file_put_contents($tmp, file_get_contents(self::$fixturesPath.'/'.$type.'/'.$fixture));
+ $container1 = $loader1->load($tmp);
$dumper = new $dumperClass($container1);
- $tmp = tempnam('sf_service_container', 'sf');
file_put_contents($tmp, $dumper->dump());
- $container2 = new ContainerBuilder();
- $loader2 = new $loaderClass($container2);
- $loader2->load($tmp);
- $container2->setParameter('path', self::$fixturesPath.'/includes');
+ $loader2 = new $loaderClass();
+ $container2 = $loader2->load($tmp);
unlink($tmp);
+ $this->assertEquals($container2->getAliases(), $container1->getAliases(), 'loading a dump from a previously loaded container returns the same container');
+ $this->assertEquals($container2->getDefinitions(), $container1->getDefinitions(), 'loading a dump from a previously loaded container returns the same container');
+ $this->assertEquals($container2->getParameterBag()->all(), $container1->getParameterBag()->all(), '->getParameterBag() returns the same value for both containers');
+
$this->assertEquals(serialize($container2), serialize($container1), 'loading a dump from a previously loaded container returns the same container');
$this->assertEquals($container2->getParameterBag()->all(), $container1->getParameterBag()->all(), '->getParameterBag() returns the same value for both containers');
diff --git a/tests/Symfony/Tests/Components/DependencyInjection/Fixtures/containers/container8.php b/tests/Symfony/Tests/Components/DependencyInjection/Fixtures/containers/container8.php
index 59331078f6b6..44c9b51686e9 100644
--- a/tests/Symfony/Tests/Components/DependencyInjection/Fixtures/containers/container8.php
+++ b/tests/Symfony/Tests/Components/DependencyInjection/Fixtures/containers/container8.php
@@ -4,8 +4,9 @@
use Symfony\Components\DependencyInjection\ParameterBag\ParameterBag;
$container = new ContainerBuilder(new ParameterBag(array(
- 'FOO' => 'bar',
- 'bar' => 'foo is %foo bar',
+ 'FOO' => '%baz%',
+ 'baz' => 'bar',
+ 'bar' => 'foo is %%foo bar',
'values' => array(true, false, null, 0, 1000.3, 'true', 'false', 'null'),
)));
diff --git a/tests/Symfony/Tests/Components/DependencyInjection/Fixtures/php/services8.php b/tests/Symfony/Tests/Components/DependencyInjection/Fixtures/php/services8.php
index 4a6e266dcd2b..3ec1a8deff60 100644
--- a/tests/Symfony/Tests/Components/DependencyInjection/Fixtures/php/services8.php
+++ b/tests/Symfony/Tests/Components/DependencyInjection/Fixtures/php/services8.php
@@ -47,8 +47,9 @@ public function findAnnotatedServiceIds($name)
protected function getDefaultParameters()
{
return array(
- 'foo' => 'bar',
- 'bar' => 'foo is %foo bar',
+ 'foo' => '%baz%',
+ 'baz' => 'bar',
+ 'bar' => 'foo is %%foo bar',
'values' => array(
0 => true,
1 => false,
diff --git a/tests/Symfony/Tests/Components/DependencyInjection/Fixtures/xml/services8.xml b/tests/Symfony/Tests/Components/DependencyInjection/Fixtures/xml/services8.xml
index 59dba00c1d62..f21f290eb3e3 100644
--- a/tests/Symfony/Tests/Components/DependencyInjection/Fixtures/xml/services8.xml
+++ b/tests/Symfony/Tests/Components/DependencyInjection/Fixtures/xml/services8.xml
@@ -4,7 +4,8 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd">
- bar
+ %baz%
+ bar
foo is %%foo bar
true
diff --git a/tests/Symfony/Tests/Components/DependencyInjection/Fixtures/yaml/services8.yml b/tests/Symfony/Tests/Components/DependencyInjection/Fixtures/yaml/services8.yml
index c1cd7a91483f..c09e9d9da4f9 100644
--- a/tests/Symfony/Tests/Components/DependencyInjection/Fixtures/yaml/services8.yml
+++ b/tests/Symfony/Tests/Components/DependencyInjection/Fixtures/yaml/services8.yml
@@ -1,5 +1,6 @@
parameters:
- foo: bar
+ foo: '%baz%'
+ baz: bar
bar: 'foo is %%foo bar'
values: [true, false, null, 0, 1000.3, 'true', 'false', 'null']
diff --git a/tests/Symfony/Tests/Components/DependencyInjection/Loader/XmlFileLoaderTest.php b/tests/Symfony/Tests/Components/DependencyInjection/Loader/XmlFileLoaderTest.php
index a2933c4cb6fb..2e993a6a2057 100644
--- a/tests/Symfony/Tests/Components/DependencyInjection/Loader/XmlFileLoaderTest.php
+++ b/tests/Symfony/Tests/Components/DependencyInjection/Loader/XmlFileLoaderTest.php
@@ -173,7 +173,7 @@ public function testExtensions()
// extension without an XSD
$config = $loader->load('extensions/services1.xml');
- $config->commit();
+ $config->freeze();
$services = $config->getDefinitions();
$parameters = $config->getParameterBag()->all();
@@ -185,7 +185,7 @@ public function testExtensions()
// extension with an XSD
$config = $loader->load('extensions/services2.xml');
- $config->commit();
+ $config->freeze();
$services = $config->getDefinitions();
$parameters = $config->getParameterBag()->all();
diff --git a/tests/Symfony/Tests/Components/DependencyInjection/Loader/YamlFileLoaderTest.php b/tests/Symfony/Tests/Components/DependencyInjection/Loader/YamlFileLoaderTest.php
index 0ef6173654a5..f1de7625843b 100644
--- a/tests/Symfony/Tests/Components/DependencyInjection/Loader/YamlFileLoaderTest.php
+++ b/tests/Symfony/Tests/Components/DependencyInjection/Loader/YamlFileLoaderTest.php
@@ -107,7 +107,7 @@ public function testExtensions()
$loader = new ProjectLoader3(self::$fixturesPath.'/yaml');
$config = $loader->load('services10.yml');
- $config->commit();
+ $config->freeze();
$services = $config->getDefinitions();
$parameters = $config->getParameterBag()->all();
diff --git a/tests/Symfony/Tests/Components/DependencyInjection/ParameterBag/ParameterBagTest.php b/tests/Symfony/Tests/Components/DependencyInjection/ParameterBag/ParameterBagTest.php
index 3aa93f28528f..539fdb6fb084 100644
--- a/tests/Symfony/Tests/Components/DependencyInjection/ParameterBag/ParameterBagTest.php
+++ b/tests/Symfony/Tests/Components/DependencyInjection/ParameterBag/ParameterBagTest.php
@@ -97,18 +97,18 @@ public function testResolveValue()
$bag = new ParameterBag(array());
try {
$bag->resolveValue('%foobar%', array());
- $this->fail('->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
+ $this->fail('->resolveValue() throws an InvalidArgumentException if a placeholder references a non-existant parameter');
} catch (\Exception $e) {
- $this->assertInstanceOf('\RuntimeException', $e, '->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
- $this->assertEquals('The parameter "foobar" must be defined.', $e->getMessage(), '->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
+ $this->assertInstanceOf('\InvalidArgumentException', $e, '->resolveValue() throws an InvalidArgumentException if a placeholder references a non-existant parameter');
+ $this->assertEquals('The parameter "foobar" must be defined.', $e->getMessage(), '->resolveValue() throws an InvalidArgumentException if a placeholder references a non-existant parameter');
}
try {
$bag->resolveValue('foo %foobar% bar', array());
- $this->fail('->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
+ $this->fail('->resolveValue() throws an InvalidArgumentException if a placeholder references a non-existant parameter');
} catch (\Exception $e) {
- $this->assertInstanceOf('\RuntimeException', $e, '->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
- $this->assertEquals('The parameter "foobar" must be defined (used in the following expression: "foo %foobar% bar").', $e->getMessage(), '->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
+ $this->assertInstanceOf('\InvalidArgumentException', $e, '->resolveValue() throws an InvalidArgumentException if a placeholder references a non-existant parameter');
+ $this->assertEquals('The parameter "foobar" must be defined.', $e->getMessage(), '->resolveValue() throws an InvalidArgumentException if a placeholder references a non-existant parameter');
}
}
}