diff --git a/src/Symfony/Component/Form/Tests/Fixtures/Author.php b/src/Symfony/Component/Form/Tests/Fixtures/Author.php index 583df256db..1120489469 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/Author.php +++ b/src/Symfony/Component/Form/Tests/Fixtures/Author.php @@ -17,6 +17,7 @@ class Author private $lastName; private $australian; public $child; + private $readPermissions; private $privateProperty; @@ -45,6 +46,16 @@ class Author return $this->australian; } + public function setReadPermissions($bool) + { + $this->readPermissions = $bool; + } + + public function hasReadPermissions() + { + return $this->readPermissions; + } + private function isPrivateIsser() { return true; diff --git a/src/Symfony/Component/Form/Tests/PropertyPathTest.php b/src/Symfony/Component/Form/Tests/PropertyPathTest.php index 3129a82bbf..25086b6bc8 100644 --- a/src/Symfony/Component/Form/Tests/PropertyPathTest.php +++ b/src/Symfony/Component/Form/Tests/PropertyPathTest.php @@ -169,6 +169,16 @@ class PropertyPathTest extends \PHPUnit_Framework_TestCase $this->assertFalse($path->getValue($object)); } + public function testGetValueReadHassers() + { + $path = new PropertyPath('read_permissions'); + + $object = new Author(); + $object->setReadPermissions(true); + + $this->assertTrue($path->getValue($object)); + } + public function testGetValueReadsMagicGet() { $path = new PropertyPath('magicProperty'); diff --git a/src/Symfony/Component/Form/Util/PropertyPath.php b/src/Symfony/Component/Form/Util/PropertyPath.php index 44087d933b..4babb2a5ea 100644 --- a/src/Symfony/Component/Form/Util/PropertyPath.php +++ b/src/Symfony/Component/Form/Util/PropertyPath.php @@ -216,12 +216,12 @@ class PropertyPath implements \IteratorAggregate * * This method first tries to find a public getter for each property in the * path. The name of the getter must be the camel-cased property name - * prefixed with "get" or "is". + * prefixed with "get", "is", or "has". * * If the getter does not exist, this method tries to find a public * property. The value of the property is then returned. * - * If neither is found, an exception is thrown. + * If none of them are found, an exception is thrown. * * @param object|array $objectOrArray The object or array to traverse * @@ -332,6 +332,7 @@ class PropertyPath implements \IteratorAggregate $reflClass = new \ReflectionClass($object); $getter = 'get'.$camelProp; $isser = 'is'.$camelProp; + $hasser = 'has'.$camelProp; if ($reflClass->hasMethod($getter)) { if (!$reflClass->getMethod($getter)->isPublic()) { @@ -345,6 +346,12 @@ class PropertyPath implements \IteratorAggregate } return $object->$isser(); + } elseif ($reflClass->hasMethod($hasser)) { + if (!$reflClass->getMethod($hasser)->isPublic()) { + throw new PropertyAccessDeniedException(sprintf('Method "%s()" is not public in class "%s"', $hasser, $reflClass->getName())); + } + + return $object->$hasser(); } elseif ($reflClass->hasMethod('__get')) { // needed to support magic method __get return $object->$property;