diff --git a/composer.json b/composer.json index 4a99dd3..1d6d91a 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "meritoo/common-library", "description": "Useful classes, methods, extensions etc.", "license": "MIT", - "version": "0.0.12", + "version": "0.0.13", "authors": [ { "name": "Meritoo.pl", diff --git a/src/Meritoo/Common/Utilities/Reflection.php b/src/Meritoo/Common/Utilities/Reflection.php index d608548..eb312ad 100644 --- a/src/Meritoo/Common/Utilities/Reflection.php +++ b/src/Meritoo/Common/Utilities/Reflection.php @@ -229,17 +229,29 @@ class Reflection if ($class->hasProperty($property) || $force) { $property = Inflector::classify($property); - $methodPrefixes = [ + $getterPrefixes = [ 'get', 'has', 'is', ]; - foreach ($methodPrefixes as $prefix) { - $method = sprintf('%s%s', $prefix, $property); + foreach ($getterPrefixes as $prefix) { + $getterName = sprintf('%s%s', $prefix, $property); - if ($class->hasMethod($method)) { - $value = $object->{$method}(); + 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; } @@ -248,13 +260,14 @@ class Reflection if (!$valueFound && null !== $reflectionProperty) { /* - * Oops, we have got exception. + * Oops, value of the property is still unknown * * 3rd try: - * Let's try modify accessibility of the property and try again to get value. + * 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/Meritoo/Common/Test/Utilities/Reflection/F.php b/tests/Meritoo/Common/Test/Utilities/Reflection/F.php new file mode 100644 index 0000000..9d21d9c --- /dev/null +++ b/tests/Meritoo/Common/Test/Utilities/Reflection/F.php @@ -0,0 +1,54 @@ + + * @copyright Meritoo.pl + */ +class F +{ + protected $username; + private $accountBalance; + private $city; + private $country; + private $gInstance; + + public function __construct($accountBalance, $city, $country, $username, $firstName = 'John', $lastName = 'Scott') + { + $this->accountBalance = $accountBalance; + $this->city = $city; + $this->country = $country; + $this->username = $username; + $this->gInstance = new G($firstName, $lastName); + + /* + * Called to avoid "Unused private method getAccountBalance" warning only + */ + $this->getAccountBalance(); + } + + public function getCountry() + { + return $this->country; + } + + protected function getCity() + { + return $this->city; + } + + private function getAccountBalance() + { + return $this->accountBalance; + } +} diff --git a/tests/Meritoo/Common/Test/Utilities/Reflection/G.php b/tests/Meritoo/Common/Test/Utilities/Reflection/G.php new file mode 100644 index 0000000..e12808c --- /dev/null +++ b/tests/Meritoo/Common/Test/Utilities/Reflection/G.php @@ -0,0 +1,38 @@ + + * @copyright Meritoo.pl + */ +class G +{ + private $firstName; + private $lastName; + + public function __construct($firstName = 'John', $lastName = 'Scott') + { + $this->firstName = $firstName; + $this->lastName = $lastName; + } + + public function getFirstName() + { + return $this->firstName; + } + + public function getLastName() + { + return $this->lastName; + } +} diff --git a/tests/Meritoo/Common/Test/Utilities/ReflectionTest.php b/tests/Meritoo/Common/Test/Utilities/ReflectionTest.php index c9d758c..b50feed 100644 --- a/tests/Meritoo/Common/Test/Utilities/ReflectionTest.php +++ b/tests/Meritoo/Common/Test/Utilities/ReflectionTest.php @@ -19,6 +19,7 @@ use Meritoo\Common\Test\Utilities\Reflection\B; use Meritoo\Common\Test\Utilities\Reflection\C; use Meritoo\Common\Test\Utilities\Reflection\D; use Meritoo\Common\Test\Utilities\Reflection\E; +use Meritoo\Common\Test\Utilities\Reflection\F; use Meritoo\Common\Utilities\Reflection; use ReflectionProperty; @@ -239,6 +240,31 @@ class ReflectionTest extends BaseTestCase self::assertCount(2, Reflection::getProperties(B::class, null, true)); } + public function testGetPropertyValueWithPublicGetter() + { + $country = 'USA'; + $f = new F(1000, 'New York', $country, 'john.scott'); + + self::assertEquals($country, Reflection::getPropertyValue($f, 'country')); + } + + public function testGetPropertyValueWithProtectedGetter() + { + $city = 'New York'; + $f = new F(1000, $city, 'USA', 'john.scott'); + + self::assertEquals($city, Reflection::getPropertyValue($f, 'city')); + } + + + public function testGetPropertyValueWithPrivateGetter() + { + $accountBalance = 1000; + $f = new F($accountBalance, 'New York', 'USA', 'john.scott'); + + self::assertEquals($accountBalance, Reflection::getPropertyValue($f, 'accountBalance')); + } + /** * Provides invalid class and trait *