[BUGFIX] Support \ArrayAccess objects with getter methods in ObjectAccess 21/50521/6
authorSascha Egerer <sascha@sascha-egerer.de>
Mon, 7 Nov 2016 10:58:39 +0000 (11:58 +0100)
committerWouter Wolters <typo3@wouterwolters.nl>
Mon, 7 Nov 2016 22:12:14 +0000 (23:12 +0100)
In #66995 the extbase ObjectAccess has been cleaned up and introduced
a behavior where it is not possible anymore to call the getter of an
object that implements \ArrayAccess.
The problem is avoided by only using array-accessing if the offset
is found to exist. If not, the instance is handled as any other object.

Change-Id: Ie6b598d93fd7171d0b6c37259e424794861e31ed
Resolves: #78589
Related: #66995
Releases: master
Reviewed-on: https://review.typo3.org/50521
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
typo3/sysext/extbase/Classes/Reflection/ObjectAccess.php
typo3/sysext/extbase/Tests/Unit/Reflection/Fixture/ArrayAccessClass.php
typo3/sysext/extbase/Tests/Unit/Reflection/ObjectAccessTest.php

index c530e79..633e8db 100644 (file)
@@ -86,7 +86,7 @@ class ObjectAccess
         }
 
         // value get based on data type of $subject (possibly converted above)
-        if ($subject instanceof \ArrayAccess || is_array($subject)) {
+        if (($subject instanceof \ArrayAccess && $subject->offsetExists($propertyName)) || is_array($subject)) {
             // isset() is safe; array_key_exists would only be needed to determine
             // if the value is NULL - and that's already what we return as fallback.
             if (isset($subject[$propertyName])) {
index 905388d..b9f3dc6 100644 (file)
@@ -65,4 +65,12 @@ class ArrayAccessClass implements \ArrayAccess
     {
         unset($this->array[$offset]);
     }
+
+    /**
+     * @return mixed
+     */
+    public function getVirtual()
+    {
+        return isset($this->array['virtual']) ? $this->array['virtual'] : 'default-value';
+    }
 }
index 2fe4af1..a8b9a0f 100644 (file)
@@ -217,6 +217,26 @@ class ObjectAccessTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
     /**
      * @test
      */
+    public function getPropertyCanAccessPropertiesOfArrayAccessWithGetterMethodWhenOffsetNotExists()
+    {
+        $arrayAccessInstance = new \TYPO3\CMS\Extbase\Tests\Unit\Reflection\Fixture\ArrayAccessClass([]);
+        $actual = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getProperty($arrayAccessInstance, 'virtual');
+        $this->assertEquals('default-value', $actual, 'getProperty does not work with Array Access property.');
+    }
+
+    /**
+     * @test
+     */
+    public function getPropertyCanAccessPropertiesOfArrayAccessWithPriorityForOffsetIfOffsetExists()
+    {
+        $arrayAccessInstance = new \TYPO3\CMS\Extbase\Tests\Unit\Reflection\Fixture\ArrayAccessClass(['virtual' => 'overridden-value']);
+        $actual = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getProperty($arrayAccessInstance, 'virtual');
+        $this->assertEquals('overridden-value', $actual, 'getProperty does not work with Array Access property.');
+    }
+
+    /**
+     * @test
+     */
     public function getPropertyCanAccessPropertiesOfAnArray()
     {
         $array = ['key' => 'value'];