瀏覽代碼

[DependencyInjection] refactored parameter bag parameter replacements (removed duplicated code)

Fabien Potencier 14 年之前
父節點
當前提交
6c409cac84

+ 8 - 68
src/Symfony/Component/DependencyInjection/Compiler/ResolveParameterPlaceHoldersPass.php

@@ -30,21 +30,22 @@ class ResolveParameterPlaceHoldersPass implements CompilerPassInterface
      */
     public function process(ContainerBuilder $container)
     {
-        $this->parameterBag = $container->getParameterBag();
+        $parameterBag = $container->getParameterBag();
+        $parameterBag->resolve();
 
         foreach ($container->getDefinitions() as $id => $definition) {
             try {
-                $definition->setClass($this->resolveValue($definition->getClass()));
-                $definition->setFile($this->resolveValue($definition->getFile()));
-                $definition->setArguments($this->resolveValue($definition->getArguments()));
+                $definition->setClass($parameterBag->resolveValue($definition->getClass()));
+                $definition->setFile($parameterBag->resolveValue($definition->getFile()));
+                $definition->setArguments($parameterBag->resolveValue($definition->getArguments()));
 
                 $calls = array();
                 foreach ($definition->getMethodCalls() as $name => $arguments) {
-                    $calls[$this->resolveValue($name)] = $this->resolveValue($arguments);
+                    $calls[$parameterBag->resolveValue($name)] = $parameterBag->resolveValue($arguments);
                 }
                 $definition->setMethodCalls($calls);
 
-                $definition->setProperties($this->resolveValue($definition->getProperties()));
+                $definition->setProperties($parameterBag->resolveValue($definition->getProperties()));
             } catch (ParameterNotFoundException $e) {
                 $e->setSourceId($id);
 
@@ -54,69 +55,8 @@ class ResolveParameterPlaceHoldersPass implements CompilerPassInterface
 
         $aliases = array();
         foreach ($container->getAliases() as $name => $target) {
-            $aliases[$this->resolveValue($name)] = $this->resolveValue($target);
+            $aliases[$parameterBag->resolveValue($name)] = $parameterBag->resolveValue($target);
         }
         $container->setAliases($aliases);
-
-        $parameterBag = $container->getParameterBag();
-        foreach ($parameterBag->all() as $key => $value) {
-            try {
-                $parameterBag->set($key, $this->resolveValue($value));
-            } catch (ParameterNotFoundException $e) {
-                $e->setSourceKey($key);
-
-                throw $e;
-            }
-        }
-    }
-
-    /**
-     * Expands parameters into their full values
-     *
-     * @param mixed $value The value to resolve
-     * @return mixed The resolved value
-     */
-    private function resolveValue($value)
-    {
-        if (is_array($value)) {
-            $resolved = array();
-            foreach ($value as $k => $v) {
-                $resolved[$this->resolveValue($k)] = $this->resolveValue($v);
-            }
-
-            return $resolved;
-        } else if (is_string($value)) {
-            return $this->resolveString($value);
-        }
-
-        return $value;
-    }
-
-    /**
-     * Resolves parameters inside a string
-     *
-     * @param string $value The string to resolve
-     * @return string The resolved string
-     * @throws \RuntimeException when a given parameter has a type problem.
-     */
-    public function resolveString($value)
-    {
-        if (preg_match('/^%[^%]+%$/', $value)) {
-            return $this->resolveValue($this->parameterBag->resolveValue($value));
-        }
-
-        $self = $this;
-        $parameterBag = $this->parameterBag;
-        return preg_replace_callback('/(?<!%)%[^%]+%/',
-            function($parameter) use ($self, $parameterBag) {
-                $resolved = $parameterBag->resolveValue($parameter[0]);
-                if (!is_string($resolved)) {
-                    throw new \RuntimeException('You can only embed strings in other parameters.');
-                }
-
-                return $self->resolveString($resolved);
-            },
-            $value
-        );
     }
 }

+ 28 - 14
src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php

@@ -124,9 +124,12 @@ class ParameterBag implements ParameterBagInterface
     /**
      * Replaces parameter placeholders (%name%) by their values.
      *
-     * @param  mixed $value A value
+     * @param mixed $value A value
+     *
+     * @return mixed The resolved value
      *
      * @throws ParameterNotFoundException if a placeholder references a parameter that does not exist
+     * @throws \LogicException when a given parameter has a type problem.
      */
     public function resolveValue($value)
     {
@@ -143,25 +146,36 @@ class ParameterBag implements ParameterBagInterface
             return $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
-            return $this->get(strtolower($match[1]));
-        }
-
-        return str_replace('%%', '%', preg_replace_callback(array('/(?<!%)%([^%]+)%/'), array($this, 'resolveValueCallback'), $value));
+        return $this->resolveString($value);
     }
 
     /**
-     * Value callback
+     * Resolves parameters inside a string
      *
-     * @see resolveValue
+     * @param string $value The string to resolve
+     * @return string The resolved string
      *
-     * @param array $match
-     * @return string
+     * @throws ParameterNotFoundException if a placeholder references a parameter that does not exist
+     * @throws \LogicException when a given parameter has a type problem.
      */
-    private function resolveValueCallback($match)
+    public function resolveString($value)
     {
-        return $this->get(strtolower($match[1]));
+        if (preg_match('/^%([^%]+)%$/', $value, $match)) {
+            // 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
+            return $this->resolveValue($this->get(strtolower($match[1])));
+        }
+
+        $self = $this;
+        return str_replace('%%', '%', preg_replace_callback('/(?<!%)%([^%]+)%/', function ($match) use ($self) {
+            $resolved = $self->get(strtolower($match[1]));
+
+            if (!is_string($resolved)) {
+                throw new \LogicException('A parameter cannot contain a non-string parameter.');
+            }
+
+            return $self->resolveString($resolved);
+        }, $value));
     }
 }

+ 13 - 3
tests/Symfony/Tests/Component/DependencyInjection/ParameterBag/ParameterBagTest.php

@@ -94,22 +94,32 @@ class ParameterBagTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals('I\'m a bar %foo bar', $bag->resolveValue('I\'m a %foo% %%foo %foo%'), '->resolveValue() supports % escaping by doubling it');
 
         $bag = new ParameterBag(array('foo' => true));
-        $this->assertTrue($bag->resolveValue('%foo%') === true, '->resolveValue() replaces arguments that are just a placeholder by their value without casting them to strings');
+        $this->assertSame(true, $bag->resolveValue('%foo%'), '->resolveValue() replaces arguments that are just a placeholder by their value without casting them to strings');
+        $bag = new ParameterBag(array('foo' => null));
+        $this->assertSame(null, $bag->resolveValue('%foo%'), '->resolveValue() replaces arguments that are just a placeholder by their value without casting them to strings');
 
         $bag = new ParameterBag(array());
         try {
-            $bag->resolveValue('%foobar%', array());
+            $bag->resolveValue('%foobar%');
             $this->fail('->resolveValue() throws an InvalidArgumentException if a placeholder references a non-existent parameter');
         } catch (ParameterNotFoundException $e) {
             $this->assertEquals('You have requested a non-existent parameter "foobar".', $e->getMessage(), '->resolveValue() throws a ParameterNotFoundException if a placeholder references a non-existent parameter');
         }
 
         try {
-            $bag->resolveValue('foo %foobar% bar', array());
+            $bag->resolveValue('foo %foobar% bar');
             $this->fail('->resolveValue() throws a ParameterNotFoundException if a placeholder references a non-existent parameter');
         } catch (ParameterNotFoundException $e) {
             $this->assertEquals('You have requested a non-existent parameter "foobar".', $e->getMessage(), '->resolveValue() throws a ParameterNotFoundException if a placeholder references a non-existent parameter');
         }
+
+        $bag = new ParameterBag(array('foo' => 'a %bar%', 'bar' => array()));
+        try {
+            $bag->resolveValue('%foo%');
+            $this->fail('->resolveValue() throws a LogicException when a parameter embeds another non-string parameter');
+        } catch (\LogicException $e) {
+            $this->assertEquals('A parameter cannot contain a non-string parameter.', $e->getMessage(), '->resolveValue() throws a LogicException when a parameter embeds another non-string parameter');
+        }
     }
 
     /**