Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 5b45818

Browse filesBrowse files
committed
#30536 PropertyAccessor->getValue disable exception
1 parent 29f81b0 commit 5b45818
Copy full SHA for 5b45818

File tree

Expand file treeCollapse file tree

12 files changed

+90
-11
lines changed
Filter options
Expand file treeCollapse file tree

12 files changed

+90
-11
lines changed

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,7 @@ private function addPropertyAccessSection(ArrayNodeDefinition $rootNode)
849849
->children()
850850
->booleanNode('magic_call')->defaultFalse()->end()
851851
->booleanNode('throw_exception_on_invalid_index')->defaultFalse()->end()
852+
->booleanNode('throw_exception_on_invalid_property_path')->defaultTrue()->end()
852853
->end()
853854
->end()
854855
->end()

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,6 +1304,8 @@ private function registerPropertyAccessConfiguration(array $config, ContainerBui
13041304
->getDefinition('property_accessor')
13051305
->replaceArgument(0, $config['magic_call'])
13061306
->replaceArgument(1, $config['throw_exception_on_invalid_index'])
1307+
->replaceArgument(2, null)
1308+
->replaceArgument(3, $config['throw_exception_on_invalid_property_path'])
13071309
;
13081310
}
13091311

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/property_access.xml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/property_access.xml
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
<argument /> <!-- magicCall, set by the extension -->
1212
<argument /> <!-- throwExceptionOnInvalidIndex, set by the extension -->
1313
<argument type="service" id="cache.property_access" on-invalid="ignore" />
14+
<argument /> <!-- throwExceptionOnInvalidPropertyPath, set by the extension -->
1415
</service>
1516
<service id="Symfony\Component\PropertyAccess\PropertyAccessorInterface" alias="property_accessor" />
1617
</services>

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@
224224
<xsd:complexType name="property_access">
225225
<xsd:attribute name="magic-call" type="xsd:boolean" />
226226
<xsd:attribute name="throw-exception-on-invalid-index" type="xsd:boolean" />
227+
<xsd:attribute name="throw-exception-on-invalid-property-path" type="xsd:boolean" />
227228
</xsd:complexType>
228229

229230
<xsd:complexType name="serializer">

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ protected static function getBundleDefaultConfig()
246246
'property_access' => [
247247
'magic_call' => false,
248248
'throw_exception_on_invalid_index' => false,
249+
'throw_exception_on_invalid_property_path' => true,
249250
],
250251
'property_info' => [
251252
'enabled' => !class_exists(FullStack::class),

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/property_accessor.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/property_accessor.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
'property_access' => [
55
'magic_call' => true,
66
'throw_exception_on_invalid_index' => true,
7+
'throw_exception_on_invalid_property_path' => false,
78
],
89
]);

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/property_accessor.xml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/property_accessor.xml
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
88

99
<framework:config>
10-
<framework:property-access magic-call="true" throw-exception-on-invalid-index="true" />
10+
<framework:property-access magic-call="true" throw-exception-on-invalid-index="true" throw-exception-on-invalid-property-path="false"/>
1111
</framework:config>
1212
</container>

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/property_accessor.yml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/property_accessor.yml
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ framework:
22
property_access:
33
magic_call: true
44
throw_exception_on_invalid_index: true
5+
throw_exception_on_invalid_property_path: false

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ public function testPropertyAccessWithDefaultValue()
7777
$def = $container->getDefinition('property_accessor');
7878
$this->assertFalse($def->getArgument(0));
7979
$this->assertFalse($def->getArgument(1));
80+
$this->assertTrue($def->getArgument(3));
8081
}
8182

8283
public function testPropertyAccessWithOverriddenValues()
@@ -85,6 +86,7 @@ public function testPropertyAccessWithOverriddenValues()
8586
$def = $container->getDefinition('property_accessor');
8687
$this->assertTrue($def->getArgument(0));
8788
$this->assertTrue($def->getArgument(1));
89+
$this->assertFalse($def->getArgument(3));
8890
}
8991

9092
public function testPropertyAccessCache()

‎src/Symfony/Component/PropertyAccess/PropertyAccessor.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/PropertyAccess/PropertyAccessor.php
+10-9Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class PropertyAccessor implements PropertyAccessorInterface
5656
*/
5757
private $magicCall;
5858
private $ignoreInvalidIndices;
59+
private $ignoreInvalidProperty;
5960

6061
/**
6162
* @var CacheItemPoolInterface
@@ -70,11 +71,12 @@ class PropertyAccessor implements PropertyAccessorInterface
7071
* Should not be used by application code. Use
7172
* {@link PropertyAccess::createPropertyAccessor()} instead.
7273
*/
73-
public function __construct(bool $magicCall = false, bool $throwExceptionOnInvalidIndex = false, CacheItemPoolInterface $cacheItemPool = null)
74+
public function __construct(bool $magicCall = false, bool $throwExceptionOnInvalidIndex = false, CacheItemPoolInterface $cacheItemPool = null, bool $throwExceptionOnInvalidPropertyPath = true)
7475
{
7576
$this->magicCall = $magicCall;
7677
$this->ignoreInvalidIndices = !$throwExceptionOnInvalidIndex;
7778
$this->cacheItemPool = $cacheItemPool instanceof NullAdapter ? null : $cacheItemPool; // Replace the NullAdapter by the null value
79+
$this->ignoreInvalidProperty = !$throwExceptionOnInvalidPropertyPath;
7880
}
7981

8082
/**
@@ -87,7 +89,7 @@ public function getValue($objectOrArray, $propertyPath)
8789
];
8890

8991
if (\is_object($objectOrArray) && false === strpbrk((string) $propertyPath, '.[')) {
90-
return $this->readProperty($zval, $propertyPath)[self::VALUE];
92+
return $this->readProperty($zval, $propertyPath, $this->ignoreInvalidProperty)[self::VALUE];
9193
}
9294

9395
$propertyPath = $this->getPropertyPath($propertyPath);
@@ -313,7 +315,7 @@ private function readPropertiesUntil($zval, PropertyPathInterface $propertyPath,
313315

314316
$zval = $this->readIndex($zval, $property);
315317
} else {
316-
$zval = $this->readProperty($zval, $property);
318+
$zval = $this->readProperty($zval, $property, $this->ignoreInvalidProperty);
317319
}
318320

319321
// the final value of the path must not be validated
@@ -372,14 +374,13 @@ private function readIndex($zval, $index)
372374
/**
373375
* Reads the a property from an object.
374376
*
375-
* @param array $zval The array containing the object to read from
376-
* @param string $property The property to read
377+
* @param array $zval The array containing the object to read from
378+
* @param string $property The property to read
379+
* @param bool $ignoreInvalidProperty Whether to ignore invalid property or throw an exception
377380
*
378381
* @return array The array containing the value of the property
379-
*
380-
* @throws NoSuchPropertyException if the property does not exist or is not public
381382
*/
382-
private function readProperty($zval, $property)
383+
private function readProperty($zval, $property, bool $ignoreInvalidProperty = false)
383384
{
384385
if (!\is_object($zval[self::VALUE])) {
385386
throw new NoSuchPropertyException(sprintf('Cannot read property "%s" from an array. Maybe you intended to write the property path as "[%1$s]" instead.', $property));
@@ -411,7 +412,7 @@ private function readProperty($zval, $property)
411412
} elseif (self::ACCESS_TYPE_MAGIC === $access[self::ACCESS_TYPE]) {
412413
// we call the getter and hope the __call do the job
413414
$result[self::VALUE] = $object->{$access[self::ACCESS_NAME]}();
414-
} else {
415+
} elseif (!$ignoreInvalidProperty) {
415416
throw new NoSuchPropertyException($access[self::ACCESS_NAME]);
416417
}
417418

‎src/Symfony/Component/PropertyAccess/PropertyAccessorBuilder.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/PropertyAccess/PropertyAccessorBuilder.php
+39-1Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class PropertyAccessorBuilder
2222
{
2323
private $magicCall = false;
2424
private $throwExceptionOnInvalidIndex = false;
25+
private $throwExceptionOnInvalidPropertyPath = true;
2526

2627
/**
2728
* @var CacheItemPoolInterface|null
@@ -97,6 +98,43 @@ public function isExceptionOnInvalidIndexEnabled()
9798
return $this->throwExceptionOnInvalidIndex;
9899
}
99100

101+
/**
102+
* Enables exceptions when reading a non-existing property.
103+
*
104+
* This has no influence on writing non-existing indices with PropertyAccessorInterface::setValue()
105+
* which are always created on-the-fly.
106+
*
107+
* @return $this
108+
*/
109+
public function enableExceptionOnInvalidPropertyPath()
110+
{
111+
$this->throwExceptionOnInvalidPropertyPath = true;
112+
113+
return $this;
114+
}
115+
116+
/**
117+
* Disables exceptions when reading a non-existing index.
118+
*
119+
* Instead, null is returned when calling PropertyAccessorInterface::getValue() on a non-existing index.
120+
*
121+
* @return $this
122+
*/
123+
public function disableExceptionOnInvalidPropertyPath()
124+
{
125+
$this->throwExceptionOnInvalidPropertyPath = false;
126+
127+
return $this;
128+
}
129+
130+
/**
131+
* @return bool whether an exception is thrown or null is returned when reading a non-existing property
132+
*/
133+
public function isExceptionOnInvalidPropertyPath()
134+
{
135+
return $this->throwExceptionOnInvalidPropertyPath;
136+
}
137+
100138
/**
101139
* Sets a cache system.
102140
*
@@ -128,6 +166,6 @@ public function getCacheItemPool()
128166
*/
129167
public function getPropertyAccessor()
130168
{
131-
return new PropertyAccessor($this->magicCall, $this->throwExceptionOnInvalidIndex, $this->cacheItemPool);
169+
return new PropertyAccessor($this->magicCall, $this->throwExceptionOnInvalidIndex, $this->cacheItemPool, $this->throwExceptionOnInvalidPropertyPath);
132170
}
133171
}

‎src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php
+30Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Cache\Adapter\ArrayAdapter;
1616
use Symfony\Component\PropertyAccess\Exception\NoSuchIndexException;
17+
use Symfony\Component\PropertyAccess\PropertyAccess;
1718
use Symfony\Component\PropertyAccess\PropertyAccessor;
1819
use Symfony\Component\PropertyAccess\Tests\Fixtures\ReturnTyped;
1920
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClass;
@@ -100,6 +101,16 @@ public function testGetValueThrowsExceptionIfPropertyNotFound($objectOrArray, $p
100101
$this->propertyAccessor->getValue($objectOrArray, $path);
101102
}
102103

104+
/**
105+
* @dataProvider getPathsWithMissingProperty
106+
*/
107+
public function testGetValueReturnsNullIfPropertyNotFoundAndExceptionIsDisabled($objectOrArray, $path)
108+
{
109+
$this->propertyAccessor = PropertyAccess::createPropertyAccessorBuilder()->disableExceptionOnInvalidPropertyPath()->getPropertyAccessor();
110+
111+
$this->assertNull($this->propertyAccessor->getValue($objectOrArray, $path), $path);
112+
}
113+
103114
/**
104115
* @dataProvider getPathsWithMissingIndex
105116
*/
@@ -617,6 +628,25 @@ public function testAnonymousClassRead()
617628
$this->assertEquals($value, $propertyAccessor->getValue($obj, 'foo'));
618629
}
619630

631+
/**
632+
* @expectedException \Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException
633+
*/
634+
public function testAnonymousClassReadThrowExceptionOnInvalidPropertyPath()
635+
{
636+
$obj = $this->generateAnonymousClass('bar');
637+
638+
$this->propertyAccessor->getValue($obj, 'invalid_property');
639+
}
640+
641+
public function testAnonymousClassReadReturnsNullOnInvalidPropertyWithDisabledException()
642+
{
643+
$obj = $this->generateAnonymousClass('bar');
644+
645+
$this->propertyAccessor = PropertyAccess::createPropertyAccessorBuilder()->disableExceptionOnInvalidPropertyPath()->getPropertyAccessor();
646+
647+
$this->assertNull($this->propertyAccessor->getValue($obj, 'invalid_property'));
648+
}
649+
620650
public function testAnonymousClassWrite()
621651
{
622652
$value = 'bar';

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.