diff --git a/composer.json b/composer.json index b519819..4a99dd3 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.11", + "version": "0.0.12", "authors": [ { "name": "Meritoo.pl", diff --git a/src/Meritoo/Common/Utilities/Reflection.php b/src/Meritoo/Common/Utilities/Reflection.php index 473ac63..d608548 100644 --- a/src/Meritoo/Common/Utilities/Reflection.php +++ b/src/Meritoo/Common/Utilities/Reflection.php @@ -417,12 +417,14 @@ class Reflection /** * Returns given object properties * - * @param array|object|string $source An array of objects, namespaces, object or namespace - * @param int $filter (optional) Filter of properties. Uses ReflectionProperty class constants. - * By default all properties are returned. + * @param array|object|string $source An array of objects, namespaces, object or namespace + * @param int $filter (optional) Filter of properties. Uses ReflectionProperty class + * constants. By default all properties are returned. + * @param bool $includeParents (optional) If is set to true, properties of parent classes are + * included (recursively). Otherwise - not. * @return array|ReflectionProperty */ - public static function getProperties($source, $filter = null) + public static function getProperties($source, $filter = null, $includeParents = false) { $className = self::getClassName($source); $reflection = new ReflectionClass($className); @@ -434,14 +436,26 @@ class Reflection + ReflectionProperty::IS_STATIC; } - return $reflection->getProperties($filter); + $properties = $reflection->getProperties($filter); + $parentProperties = []; + + if ($includeParents) { + $parent = self::getParentClass($source); + + if (false !== $parent) { + $parentClass = $parent->getName(); + $parentProperties = self::getProperties($parentClass, $filter, $includeParents); + } + } + + return array_merge($properties, $parentProperties); } /** - * Returns a parent class + * Returns a parent class or false if there is no parent class * * @param array|object|string $source An array of objects, namespaces, object or namespace - * @return ReflectionClass + * @return ReflectionClass|bool */ public static function getParentClass($source) { diff --git a/tests/Meritoo/Common/Test/Utilities/Reflection/A.php b/tests/Meritoo/Common/Test/Utilities/Reflection/A.php index af49d1a..81263b1 100644 --- a/tests/Meritoo/Common/Test/Utilities/Reflection/A.php +++ b/tests/Meritoo/Common/Test/Utilities/Reflection/A.php @@ -19,8 +19,15 @@ class A { use E; + private $count = 1; + protected function lorem() { return 'ipsum'; } + + protected function getCount() + { + return $this->count; + } } diff --git a/tests/Meritoo/Common/Test/Utilities/Reflection/B.php b/tests/Meritoo/Common/Test/Utilities/Reflection/B.php index 19496bf..3366835 100644 --- a/tests/Meritoo/Common/Test/Utilities/Reflection/B.php +++ b/tests/Meritoo/Common/Test/Utilities/Reflection/B.php @@ -17,4 +17,10 @@ namespace Meritoo\Common\Test\Utilities\Reflection; */ class B extends A { + protected $name = 'Lorem Ipsum'; + + public function getName() + { + return $this->name; + } } diff --git a/tests/Meritoo/Common/Test/Utilities/ReflectionTest.php b/tests/Meritoo/Common/Test/Utilities/ReflectionTest.php index 6983126..27bdf66 100644 --- a/tests/Meritoo/Common/Test/Utilities/ReflectionTest.php +++ b/tests/Meritoo/Common/Test/Utilities/ReflectionTest.php @@ -20,6 +20,7 @@ use Meritoo\Common\Test\Utilities\Reflection\C; use Meritoo\Common\Test\Utilities\Reflection\D; use Meritoo\Common\Test\Utilities\Reflection\E; use Meritoo\Common\Utilities\Reflection; +use ReflectionProperty; /** * Tests of the useful reflection methods @@ -176,11 +177,11 @@ class ReflectionTest extends BaseTestCase public function testGetMethods() { - self::assertEquals(0, count(Reflection::getMethods(B::class, true))); - self::assertEquals(1, count(Reflection::getMethods(B::class))); - self::assertEquals(1, count(Reflection::getMethods(A::class))); + self::assertEquals(1, count(Reflection::getMethods(B::class, true))); + self::assertEquals(3, count(Reflection::getMethods(B::class))); + self::assertEquals(2, count(Reflection::getMethods(A::class))); self::assertEquals(2, count(Reflection::getMethods(C::class, true))); - self::assertEquals(3, count(Reflection::getMethods(C::class))); + self::assertEquals(5, count(Reflection::getMethods(C::class))); } /** @@ -221,6 +222,23 @@ class ReflectionTest extends BaseTestCase self::assertFalse(Reflection::usesTrait(D::class, E::class, true)); } + public function testGetProperties() + { + self::assertCount(1, Reflection::getProperties(B::class)); + } + + public function testGetPropertiesUsingFilter() + { + self::assertCount(1, Reflection::getProperties(B::class, ReflectionProperty::IS_PROTECTED)); + self::assertCount(0, Reflection::getProperties(B::class, ReflectionProperty::IS_PRIVATE)); + self::assertCount(1, Reflection::getProperties(B::class, ReflectionProperty::IS_PRIVATE, true)); + } + + public function testGetPropertiesWithParents() + { + self::assertCount(2, Reflection::getProperties(B::class, null, true)); + } + /** * Provides invalid class and trait *