diff --git a/CHANGELOG.md b/CHANGELOG.md index de7526b..7cf80c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Common and useful classes, methods, exceptions etc. 1. Travis CI > run many tasks using Phing > update configuration 2. Template with placeholders > verification of placeholders without values > make stronger and point out which are missing +3. Reflection > getPropertyValue() method > look for the property in parent classes # 1.0.2 diff --git a/src/Utilities/Reflection.php b/src/Utilities/Reflection.php index d783cb7..3336cf2 100644 --- a/src/Utilities/Reflection.php +++ b/src/Utilities/Reflection.php @@ -217,54 +217,76 @@ class Reflection } catch (\ReflectionException $exception) { /* * 2nd try: - * Look for the get / has / is methods + * Look for the property in parent classes */ - $class = new \ReflectionObject($object); - $valueFound = false; - - if ($force || $class->hasProperty($property)) { - $property = Inflector::classify($property); - - $getterPrefixes = [ - 'get', - 'has', - 'is', - ]; - - foreach ($getterPrefixes as $prefix) { - $getterName = sprintf('%s%s', $prefix, $property); - - if ($class->hasMethod($getterName)) { - $method = new \ReflectionMethod($object, $getterName); - - /* - * Getter is not accessible publicly? - * I have to skip it, to avoid an error like this: - * - * Call to protected method My\ExtraClass::getExtraProperty() from context 'My\ExtraClass' - */ - if ($method->isProtected() || $method->isPrivate()) { - continue; - } - - $value = $object->{$getterName}(); - $valueFound = true; + if (null === $reflectionProperty) { + $propertyFound = false; + $reflectionProperties = self::getProperties($object, null, true); + foreach ($reflectionProperties as $reflectionProperty) { + if ($reflectionProperty->getName() === $property) { + $propertyFound = true; break; } } - } - if (!$valueFound && null !== $reflectionProperty) { + if ($propertyFound && null !== $reflectionProperty) { + $reflectionProperty->setAccessible(true); + $value = $reflectionProperty->getValue($object); + $reflectionProperty->setAccessible(false); + } + } else { /* - * Oops, value of the property is still unknown - * * 3rd try: - * Let's modify accessibility of the property and try again to get value + * Look for the get / has / is methods */ - $reflectionProperty->setAccessible(true); - $value = $reflectionProperty->getValue($object); - $reflectionProperty->setAccessible(false); + $class = new \ReflectionObject($object); + $valueFound = false; + + if ($force || $class->hasProperty($property)) { + $property = Inflector::classify($property); + + $getterPrefixes = [ + 'get', + 'has', + 'is', + ]; + + foreach ($getterPrefixes as $prefix) { + $getterName = sprintf('%s%s', $prefix, $property); + + if ($class->hasMethod($getterName)) { + $method = new \ReflectionMethod($object, $getterName); + + /* + * Getter is not accessible publicly? + * I have to skip it, to avoid an error like this: + * + * Call to protected method My\ExtraClass::getExtraProperty() from context 'My\ExtraClass' + */ + if ($method->isProtected() || $method->isPrivate()) { + continue; + } + + $value = $object->{$getterName}(); + $valueFound = true; + + break; + } + } + } + + if (!$valueFound) { + /* + * Oops, value of the property is still unknown + * + * 4th try: + * Let's modify accessibility of the property and try again to get value + */ + $reflectionProperty->setAccessible(true); + $value = $reflectionProperty->getValue($object); + $reflectionProperty->setAccessible(false); + } } } } diff --git a/tests/Utilities/ReflectionTest.php b/tests/Utilities/ReflectionTest.php index 9b136e9..2d1770c 100644 --- a/tests/Utilities/ReflectionTest.php +++ b/tests/Utilities/ReflectionTest.php @@ -309,6 +309,12 @@ class ReflectionTest extends BaseTestCase self::assertEquals($username, Reflection::getPropertyValue($f, 'username')); } + public function testGetPropertyValueFromParentClass(): void + { + $c = new C(); + self::assertEquals(1, Reflection::getPropertyValue($c, 'count', true)); + } + public function testGetPropertyValuesFromEmptySource() { self::assertEquals([], Reflection::getPropertyValues([], 'something'));