diff --git a/src/Symfony/Component/DependencyInjection/Exception/ParameterNotFoundException.php b/src/Symfony/Component/DependencyInjection/Exception/ParameterNotFoundException.php index ab7b86d5acc9..40c01b05081d 100644 --- a/src/Symfony/Component/DependencyInjection/Exception/ParameterNotFoundException.php +++ b/src/Symfony/Component/DependencyInjection/Exception/ParameterNotFoundException.php @@ -22,20 +22,23 @@ class ParameterNotFoundException extends InvalidArgumentException private $sourceId; private $sourceKey; private $alternatives; + private $nonNestedAlternative; /** - * @param string $key The requested parameter key - * @param string $sourceId The service id that references the non-existent parameter - * @param string $sourceKey The parameter key that references the non-existent parameter - * @param \Exception $previous The previous exception - * @param string[] $alternatives Some parameter name alternatives + * @param string $key The requested parameter key + * @param string $sourceId The service id that references the non-existent parameter + * @param string $sourceKey The parameter key that references the non-existent parameter + * @param \Exception $previous The previous exception + * @param string[] $alternatives Some parameter name alternatives + * @param string|null $nonNestedAlternative The alternative parameter name when the user expected dot notation for nested parameters */ - public function __construct($key, $sourceId = null, $sourceKey = null, \Exception $previous = null, array $alternatives = array()) + public function __construct($key, $sourceId = null, $sourceKey = null, \Exception $previous = null, array $alternatives = array(), $nonNestedAlternative = null) { $this->key = $key; $this->sourceId = $sourceId; $this->sourceKey = $sourceKey; $this->alternatives = $alternatives; + $this->nonNestedAlternative = $nonNestedAlternative; parent::__construct('', 0, $previous); @@ -59,6 +62,8 @@ public function updateRepr() $this->message .= ' Did you mean one of these: "'; } $this->message .= implode('", "', $this->alternatives).'"?'; + } elseif (null !== $this->nonNestedAlternative) { + $this->message .= ' You cannot access nested array items, do you want to inject "'.$this->nonNestedAlternative.'" instead?'; } } diff --git a/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php b/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php index 8f5972ce9acb..0f30d66b3d5f 100644 --- a/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php +++ b/src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php @@ -81,7 +81,23 @@ public function get($name) } } - throw new ParameterNotFoundException($name, null, null, null, $alternatives); + $nonNestedAlternative = null; + if (!count($alternatives) && false !== strpos($name, '.')) { + $namePartsLength = array_map('strlen', explode('.', $name)); + $key = substr($name, 0, -1 * (1 + array_pop($namePartsLength))); + while (count($namePartsLength)) { + if ($this->has($key)) { + if (is_array($this->get($key))) { + $nonNestedAlternative = $key; + } + break; + } + + $key = substr($key, 0, -1 * (1 + array_pop($namePartsLength))); + } + } + + throw new ParameterNotFoundException($name, null, null, null, $alternatives, $nonNestedAlternative); } return $this->parameters[$name]; diff --git a/src/Symfony/Component/DependencyInjection/Tests/ParameterBag/ParameterBagTest.php b/src/Symfony/Component/DependencyInjection/Tests/ParameterBag/ParameterBagTest.php index 39dfb48455b4..79a8b9f0764d 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ParameterBag/ParameterBagTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ParameterBag/ParameterBagTest.php @@ -71,37 +71,32 @@ public function testGetSet() } } - public function testGetThrowParameterNotFoundException() + /** + * @dataProvider provideGetThrowParameterNotFoundExceptionData + */ + public function testGetThrowParameterNotFoundException($parameterKey, $exceptionMessage) { $bag = new ParameterBag(array( 'foo' => 'foo', 'bar' => 'bar', 'baz' => 'baz', + 'fiz' => array('bar' => array('boo' => 12)), )); - try { - $bag->get('foo1'); - $this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist'); - } catch (\Exception $e) { - $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist'); - $this->assertEquals('You have requested a non-existent parameter "foo1". Did you mean this: "foo"?', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException with some advices'); - } + $this->setExpectedException('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException', $exceptionMessage); - try { - $bag->get('bag'); - $this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist'); - } catch (\Exception $e) { - $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist'); - $this->assertEquals('You have requested a non-existent parameter "bag". Did you mean one of these: "bar", "baz"?', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException with some advices'); - } + $bag->get($parameterKey); + } - try { - $bag->get(''); - $this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist'); - } catch (\Exception $e) { - $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist'); - $this->assertEquals('You have requested a non-existent parameter "".', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException with some advices'); - } + public function provideGetThrowParameterNotFoundExceptionData() + { + return array( + array('foo1', 'You have requested a non-existent parameter "foo1". Did you mean this: "foo"?'), + array('bag', 'You have requested a non-existent parameter "bag". Did you mean one of these: "bar", "baz"?'), + array('', 'You have requested a non-existent parameter "".'), + + array('fiz.bar.boo', 'You have requested a non-existent parameter "fiz.bar.boo". You cannot access nested array items, do you want to inject "fiz" instead?'), + ); } public function testHas()