8000 Use access flags for accessor and mutator · symfony/symfony@3877283 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3877283

Browse files
committed
Use access flags for accessor and mutator
1 parent 5ce5837 commit 3877283

File tree

2 files changed

+76
-45
lines changed

2 files changed

+76
-45
lines changed

src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php

Lines changed: 59 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp
5959
private $accessorPrefixes;
6060
private $arrayMutatorPrefixes;
6161
private $enableConstructorExtraction;
62-
private $accessFlags;
62+
private $methodReflectionFlags;
63+
private $propertyReflectionFlags;
6364

6465
/**
6566
* @param string[]|null $mutatorPrefixes
@@ -72,7 +73,8 @@ public function __construct(array $mutatorPrefixes = null, array $accessorPrefix
7273
$this->accessorPrefixes = null !== $accessorPrefixes ? $accessorPrefixes : self::$defaultAccessorPrefixes;
7374
$this->arrayMutatorPrefixes = null !== $arrayMutatorPrefixes ? $arrayMutatorPrefixes : self::$defaultArrayMutatorPrefixes;
7475
$this->enableConstructorExtraction = $enableConstructorExtraction;
75-
$this->accessFlags = $accessFlags;
76+
$this->methodReflectionFlags = $this->getMethodsFlags($accessFlags);
77+
$this->propertyReflectionFlags = $this->getPropertyFlags($accessFlags);
7678
}
7779

7880
/**
@@ -86,34 +88,16 @@ public function getProperties($class, array $context = [])
8688
return;
8789
}
8890

89-
$propertyFlags = 0;
90-
$methodFlags = 0;
91-
92-
if ($this->accessFlags & self::ALLOW_PUBLIC) {
93-
$propertyFlags = $propertyFlags | \ReflectionProperty::IS_PUBLIC;
94-
$methodFlags = $methodFlags | \ReflectionMethod::IS_PUBLIC;
95-
}
96-
97-
if ($this->accessFlags & self::ALLOW_PRIVATE) {
98-
$propertyFlags = $propertyFlags | \ReflectionProperty::IS_PRIVATE;
99-
$methodFlags = $methodFlags | \ReflectionMethod::IS_PRIVATE;
100-
}
101-
102-
if ($this->accessFlags & self::ALLOW_PROTECTED) {
103-
$propertyFlags = $propertyFlags | \ReflectionProperty::IS_PROTECTED;
104-
$methodFlags = $methodFlags | \ReflectionMethod::IS_PROTECTED;
105-
}
106-
10791
$reflectionProperties = $reflectionClass->getProperties();
10892

10993
$properties = [];
11094
foreach ($reflectionProperties as $reflectionProperty) {
111-
if ($reflectionProperty->getModifiers() & $propertyFlags) {
95+
if ($reflectionProperty->getModifiers() & $this->propertyReflectionFlags) {
11296
$properties[$reflectionProperty->name] = $reflectionProperty->name;
11397
}
11498
}
11599

116-
foreach ($reflectionClass->getMethods($methodFlags) as $reflectionMethod) {
100+
foreach ($reflectionClass->getMethods($this->methodReflectionFlags) as $reflectionMethod) {
117101
if ($reflectionMethod->isStatic()) {
118102
continue;
119103
}
@@ -232,26 +216,26 @@ public function getReadAccessor(string $class, string $property, array $context
232216
$accessPrivate = false;
233217
$accessStatic = false;
234218

235-
if ($reflClass->hasMethod($getter) && $reflClass->getMethod($getter)->isPublic()) {
219+
if ($reflClass->hasMethod($getter) && ($reflClass->getMethod($getter)->getModifiers() & $this->methodReflectionFlags)) {
236220
$accessType = ReadAccessor::TYPE_METHOD;
237221
$accessName = $getter;
238222
$accessStatic = $reflClass->getMethod($getter)->isStatic();
239-
} elseif ($reflClass->hasMethod($getsetter) && $reflClass->getMethod($getsetter)->isPublic()) {
223+
} elseif ($reflClass->hasMethod($getsetter) && ($reflClass->getMethod($getsetter)->getModifiers< 6D4E /span>() & $this->methodReflectionFlags)) {
240224
$accessType = ReadAccessor::TYPE_METHOD;
241225
$accessName = $getsetter;
242226
$accessStatic = $reflClass->getMethod($getsetter)->isStatic();
243-
} elseif ($reflClass->hasMethod($isser) && $reflClass->getMethod($isser)->isPublic()) {
227+
} elseif ($reflClass->hasMethod($isser) && ($reflClass->getMethod($isser)->getModifiers() & $this->methodReflectionFlags)) {
244228
$accessType = ReadAccessor::TYPE_METHOD;
245229
$accessName = $isser;
246230
$accessStatic = $reflClass->getMethod($isser)->isStatic();
247-
} elseif ($reflClass->hasMethod($hasser) && $reflClass->getMethod($hasser)->isPublic()) {
231+
} elseif ($reflClass->hasMethod($hasser) && ($reflClass->getMethod($hasser)->getModifiers() & $this->methodReflectionFlags)) {
248232
$accessType = ReadAccessor::TYPE_METHOD;
249233
$accessName = $hasser;
250234
$accessStatic = $reflClass->getMethod($hasser)->isStatic();
251-
} elseif ($reflClass->hasMethod('__get') && $reflClass->getMethod('__get')->isPublic()) {
235+
} elseif ($reflClass->hasMethod('__get') && ($reflClass->getMethod('__get')->getModifiers() & $this->methodReflectionFlags)) {
252236
$accessType = ReadAccessor::TYPE_PROPERTY;
253237
$accessName = $property;
254-
} elseif ($hasProperty) {
238+
} elseif ($hasProperty && ($reflClass->getProperty($property)->getModifiers() & $this->propertyReflectionFlags)) {
255239
$accessType = ReadAccessor::TYPE_PROPERTY;
256240
$accessName = $property;
257241
$accessStatic = $reflClass->getProperty($property)->isStatic();
@@ -315,7 +299,7 @@ public function getWriteMutator(string $class, string $property, array $context
315299
} elseif ($this->isMethodAccessible($reflClass, '__set', 2)) {
316300
$accessType = WriteMutator::TYPE_PROPERTY;
317301
$accessName = $property;
318-
} elseif ($hasProperty) {
302+
} elseif ($hasProperty && ($reflClass->getProperty($property)->getModifiers() & $this->propertyReflectionFlags)) {
319303
$accessType = WriteMutator::TYPE_PROPERTY;
320304
$accessName = $property;
321305
$accessPrivate = !$reflClass->getProperty($property)->isPublic();
@@ -464,19 +448,7 @@ private function isAllowedProperty(string $class, string $property): bool
464448
try {
465449
$reflectionProperty = new \ReflectionProperty($class, $property);
466450

467-
if ($this->accessFlags & self::ALLOW_PUBLIC && $reflectionProperty->isPublic()) {
468-
return true;
469-
}
470-
471-
if ($this->accessFlags & self::ALLOW_PROTECTED && $reflectionProperty->isProtected()) {
472-
return true;
473-
}
474-
475-
if ($this->accessFlags & self::ALLOW_PRIVATE && $reflectionProperty->isPrivate()) {
476-
return true;
477-
}
478-
479-
return false;
451+
return $reflectionProperty->getModifiers() & $this->propertyReflectionFlags;
480452
} catch (\ReflectionException $e) {
481453
// Return false if the property doesn't exist
482454
}
@@ -601,7 +573,7 @@ private function isMethodAccessible(\ReflectionClass $class, string $methodName,
601573
if ($class->hasMethod($methodName)) {
602574
$method = $class->getMethod($methodName);
603575

604-
if ($method->isPublic()
576+
if (($method->getModifiers() & $this->methodReflectionFlags)
605577
&& $method->getNumberOfRequiredParameters() <= $parameters
606578
&& $method->getNumberOfParameters() >= $parameters) {
607579
return true;
@@ -618,4 +590,48 @@ private function camelize(string $string): string
618590
{
619591
return str_replace(' ', '', ucwords(str_replace('_', ' ', $string)));
620592
}
593+
594+
/**
595+
* Return allowed reflection method flags
596+
*/
597+
private function getMethodsFlags(int $accessFlags): int
598+
{
599+
$methodFlags = 0;
600+
601+
if ($accessFlags & self::ALLOW_PUBLIC) {
602+
$methodFlags |= \ReflectionMethod::IS_PUBLIC;
603+
}
604+
605+
if ($accessFlags & self::ALLOW_PRIVATE) {
606+
$methodFlags |= \ReflectionMethod::IS_PRIVATE;
607+
}
608+
609+
if ($accessFlags & self::ALLOW_PROTECTED) {
610+
$methodFlags |= \ReflectionMethod::IS_PROTECTED;
611+
}
612+
613+
return $methodFlags;
614+
}
615+
616+
/**
617+
* Return allowed reflection property flags
618+
*/
619+
private function getPropertyFlags(int $accessFlags): int
620+
{
621+
$propertyFlags = 0;
622+
623+
if ($accessFlags & self::ALLOW_PUBLIC) {
624+
$propertyFlags |= \ReflectionProperty::IS_PUBLIC;
625+
}
626+
627+
if ($accessFlags & self::ALLOW_PRIVATE) {
628+
$propertyFlags |= \ReflectionProperty::IS_PRIVATE;
629+
}
630+
631+
if ($accessFlags & self::ALLOW_PROTECTED) {
632+
$propertyFlags |= \ReflectionProperty::IS_PROTECTED;
633+
}
634+
635+
return $propertyFlags;
636+
}
621637
}

src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,12 +364,26 @@ public function constructorTypesProvider(): array
364364
];
365365
}
366366

367+
public function testNullOnPrivateProtectedAccessor()
368+
{
369+
$barAcessor = $this->extractor->getReadAccessor(Dummy::class, 'bar');
370+
$barMutator = $this->extractor->getWriteMutator(Dummy::class, 'bar');
371+
$bazAcessor = $this->extractor->getReadAccessor(Dummy::class, 'baz');
372+
$bazMutator = $this->extractor->getWriteMutator(Dummy::class, 'baz');
373+
374+
$this->assertNull($barAcessor);
375+
$this->assertNull($barMutator);
376+
$this->assertNull($bazAcessor);
377+
$this->assertNull($bazMutator);
378+
}
379+
367380
/**
368381
* @dataProvider readAccessorProvider
369382
*/
370383
public function testGetReadAccessor($class, $property, $found, $type, $name, $private, $static)
371384
{
372-
$readAcessor = $this->extractor->getReadAccessor($class, $property);
385+
$extractor = new ReflectionExtractor(null, null, null, true, ReflectionExtractor::ALLOW_PUBLIC | ReflectionExtractor::ALLOW_PROTECTED | ReflectionExtractor::ALLOW_PRIVATE);
386+
$readAcessor = $extractor->getReadAccessor($class, $property);
373387

374388
if (!$found) {
375389
$this->assertNull($readAcessor);
@@ -403,7 +417,8 @@ public function readAccessorProvider(): array
403417
*/
404418
public function testGetWriteMutator($class, $property, $allowConstruct, $found, $type, $name, $addName, $removeName, $private, $static, $hasParameter)
405419
{
406-
$writeMutator = $this->extractor->getWriteMutator($class, $property, [
420+
$extractor = new ReflectionExtractor(null, null, null, true, ReflectionExtractor::ALLOW_PUBLIC | ReflectionExtractor::ALLOW_PROTECTED | ReflectionExtractor::ALLOW_PRIVATE);
421+
$writeMutator = $extractor->getWriteMutator($class, $property, [
407422
'enable_constructor_extraction' => $allowConstruct,
408423
]);
409424

0 commit comments

Comments
 (0)
0