Browse Source

[Form] Added support for __get and __set in PropertyPath

GordonsLondon 14 năm trước cách đây
mục cha
commit
23ac47e011

+ 2 - 2
src/Symfony/Component/Form/PropertyPath.php

@@ -324,7 +324,7 @@ class PropertyPath implements \IteratorAggregate
                 }
 
                 return $object->$property;
-            } else if (property_exists($object, $property)) {
+            } else if (property_exists($object, $property) || $reflClass->hasMethod('__get')) {
                 // needed to support \stdClass instances
                 return $object->$property;
             } else {
@@ -367,7 +367,7 @@ class PropertyPath implements \IteratorAggregate
                 }
 
                 $objectOrArray->$property = $value;
-            } else if (property_exists($objectOrArray, $property)) {
+            } else if (property_exists($objectOrArray, $property) || $reflClass->hasMethod('__get')) {
                 // needed to support \stdClass instances
                 $objectOrArray->$property = $value;
             } else {

+ 18 - 0
tests/Symfony/Tests/Component/Form/Fixtures/Magician.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace Symfony\Tests\Component\Form\Fixtures;
+
+class Magician
+{
+    private $properties = array();
+
+    public function __set($name, $value)
+    {
+        $this->properties[$name] = $value;
+    }
+
+    public function __get($name)
+    {
+        return isset($this->properties[$name]) ? $this->properties[$name] : null;
+    }
+}

+ 22 - 0
tests/Symfony/Tests/Component/Form/PropertyPathTest.php

@@ -3,9 +3,11 @@
 namespace Symfony\Tests\Component\Form;
 
 require_once __DIR__ . '/Fixtures/Author.php';
+require_once __DIR__ . '/Fixtures/Magician.php';
 
 use Symfony\Component\Form\PropertyPath;
 use Symfony\Tests\Component\Form\Fixtures\Author;
+use Symfony\Tests\Component\Form\Fixtures\Magician;
 
 class PropertyPathTest extends \PHPUnit_Framework_TestCase
 {
@@ -135,6 +137,16 @@ class PropertyPathTest extends \PHPUnit_Framework_TestCase
         $this->assertSame(false, $path->getValue($object));
     }
 
+    public function testGetValueReadsMagicGet()
+    {
+        $path = new PropertyPath('magicProperty');
+
+        $object = new Magician();
+        $object->__set('magicProperty', 'foobar');
+
+        $this->assertSame('foobar', $path->getValue($object));
+    }
+
     public function testGetValueThrowsExceptionIfIsserIsNotPublic()
     {
         $path = new PropertyPath('privateIsser');
@@ -205,6 +217,16 @@ class PropertyPathTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals('Bernhard', $object['firstName']);
     }
 
+    public function testSetValueUpdateMagicSet()
+    {
+        $object = new Magician();
+
+        $path = new PropertyPath('magicProperty');
+        $path->setValue($object, 'foobar');
+
+        $this->assertEquals('foobar', $object->__get('magicProperty'));
+    }
+
     public function testSetValueThrowsExceptionIfArrayAccessExpected()
     {
         $path = new PropertyPath('[firstName]');