Skip to content

Commit

Permalink
Merge branch '6.4' into 7.1
Browse files Browse the repository at this point in the history
* 6.4:
  remove conflict with symfony/serializer < 6.4
  Reviewed and Translated zh_CN
  [PropertyInfo] Fix write visibility for Asymmetric Visibility and Virtual Properties
  [Translation] [Bridge][Lokalise] Fix empty keys array in PUT, DELETE requests causing Lokalise API error
  • Loading branch information
nicolas-grekas committed Nov 27, 2024
2 parents 17a97fd + 739b5e3 commit e9a7b2a
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 7 deletions.
30 changes: 25 additions & 5 deletions Extractor/ReflectionExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -700,12 +700,18 @@ private function isAllowedProperty(string $class, string $property, bool $writeA
try {
$reflectionProperty = new \ReflectionProperty($class, $property);

if ($writeAccessRequired && $reflectionProperty->isReadOnly()) {
return false;
}
if ($writeAccessRequired) {
if ($reflectionProperty->isReadOnly()) {
return false;
}

if (\PHP_VERSION_ID >= 80400 && ($reflectionProperty->isProtectedSet() || $reflectionProperty->isPrivateSet())) {
return false;
}

if (\PHP_VERSION_ID >= 80400 && $writeAccessRequired && ($reflectionProperty->isProtectedSet() || $reflectionProperty->isPrivateSet())) {
return false;
if (\PHP_VERSION_ID >= 80400 &&$reflectionProperty->isVirtual() && !$reflectionProperty->hasHook(\PropertyHookType::Set)) {
return false;
}
}

return (bool) ($reflectionProperty->getModifiers() & $this->propertyReflectionFlags);
Expand Down Expand Up @@ -946,6 +952,20 @@ private function getReadVisiblityForMethod(\ReflectionMethod $reflectionMethod):

private function getWriteVisiblityForProperty(\ReflectionProperty $reflectionProperty): string
{
if (\PHP_VERSION_ID >= 80400) {
if ($reflectionProperty->isVirtual() && !$reflectionProperty->hasHook(\PropertyHookType::Set)) {
return PropertyWriteInfo::VISIBILITY_PRIVATE;
}

if ($reflectionProperty->isPrivateSet()) {
return PropertyWriteInfo::VISIBILITY_PRIVATE;
}

if ($reflectionProperty->isProtectedSet()) {
return PropertyWriteInfo::VISIBILITY_PROTECTED;
}
}

if ($reflectionProperty->isPrivate()) {
return PropertyWriteInfo::VISIBILITY_PRIVATE;
}
Expand Down
64 changes: 64 additions & 0 deletions Tests/Extractor/ReflectionExtractorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
use Symfony\Component\PropertyInfo\Tests\Fixtures\Php81Dummy;
use Symfony\Component\PropertyInfo\Tests\Fixtures\Php82Dummy;
use Symfony\Component\PropertyInfo\Tests\Fixtures\SnakeCaseDummy;
use Symfony\Component\PropertyInfo\Tests\Fixtures\VirtualProperties;
use Symfony\Component\PropertyInfo\Type as LegacyType;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\Type\NullableType;
Expand Down Expand Up @@ -703,6 +704,69 @@ public function testAsymmetricVisibility()
$this->assertFalse($this->extractor->isWritable(AsymmetricVisibility::class, 'protectedPrivate'));
}

/**
* @requires PHP 8.4
*/
public function testVirtualProperties()
{
$this->assertTrue($this->extractor->isReadable(VirtualProperties::class, 'virtualNoSetHook'));
$this->assertTrue($this->extractor->isReadable(VirtualProperties::class, 'virtualSetHookOnly'));
$this->assertTrue($this->extractor->isReadable(VirtualProperties::class, 'virtualHook'));
$this->assertFalse($this->extractor->isWritable(VirtualProperties::class, 'virtualNoSetHook'));
$this->assertTrue($this->extractor->isWritable(VirtualProperties::class, 'virtualSetHookOnly'));
$this->assertTrue($this->extractor->isWritable(VirtualProperties::class, 'virtualHook'));
}

/**
* @dataProvider provideAsymmetricVisibilityMutator
* @requires PHP 8.4
*/
public function testAsymmetricVisibilityMutator(string $property, string $readVisibility, string $writeVisibility)
{
$extractor = new ReflectionExtractor(null, null, null, true, ReflectionExtractor::ALLOW_PUBLIC | ReflectionExtractor::ALLOW_PROTECTED | ReflectionExtractor::ALLOW_PRIVATE);
$readMutator = $extractor->getReadInfo(AsymmetricVisibility::class, $property);
$writeMutator = $extractor->getWriteInfo(AsymmetricVisibility::class, $property, [
'enable_getter_setter_extraction' => true,
]);

$this->assertSame(PropertyReadInfo::TYPE_PROPERTY, $readMutator->getType());
$this->assertSame(PropertyWriteInfo::TYPE_PROPERTY, $writeMutator->getType());
$this->assertSame($readVisibility, $readMutator->getVisibility());
$this->assertSame($writeVisibility, $writeMutator->getVisibility());
}

public static function provideAsymmetricVisibilityMutator(): iterable
{
yield ['publicPrivate', PropertyReadInfo::VISIBILITY_PUBLIC, PropertyWriteInfo::VISIBILITY_PRIVATE];
yield ['publicProtected', PropertyReadInfo::VISIBILITY_PUBLIC, PropertyWriteInfo::VISIBILITY_PROTECTED];
yield ['protectedPrivate', PropertyReadInfo::VISIBILITY_PROTECTED, PropertyWriteInfo::VISIBILITY_PRIVATE];
}

/**
* @dataProvider provideVirtualPropertiesMutator
* @requires PHP 8.4
*/
public function testVirtualPropertiesMutator(string $property, string $readVisibility, string $writeVisibility)
{
$extractor = new ReflectionExtractor(null, null, null, true, ReflectionExtractor::ALLOW_PUBLIC | ReflectionExtractor::ALLOW_PROTECTED | ReflectionExtractor::ALLOW_PRIVATE);
$readMutator = $extractor->getReadInfo(VirtualProperties::class, $property);
$writeMutator = $extractor->getWriteInfo(VirtualProperties::class, $property, [
'enable_getter_setter_extraction' => true,
]);

$this->assertSame(PropertyReadInfo::TYPE_PROPERTY, $readMutator->getType());
$this->assertSame(PropertyWriteInfo::TYPE_PROPERTY, $writeMutator->getType());
$this->assertSame($readVisibility, $readMutator->getVisibility());
$this->assertSame($writeVisibility, $writeMutator->getVisibility());
}

public static function provideVirtualPropertiesMutator(): iterable
{
yield ['virtualNoSetHook', PropertyReadInfo::VISIBILITY_PUBLIC, PropertyWriteInfo::VISIBILITY_PRIVATE];
yield ['virtualSetHookOnly', PropertyReadInfo::VISIBILITY_PUBLIC, PropertyWriteInfo::VISIBILITY_PUBLIC];
yield ['virtualHook', PropertyReadInfo::VISIBILITY_PUBLIC, PropertyWriteInfo::VISIBILITY_PUBLIC];
}

/**
* @dataProvider typesProvider
*/
Expand Down
19 changes: 19 additions & 0 deletions Tests/Fixtures/VirtualProperties.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\PropertyInfo\Tests\Fixtures;

class VirtualProperties
{
public bool $virtualNoSetHook { get => true; }
public bool $virtualSetHookOnly { set => $value; }
public bool $virtualHook { get => true; set => $value; }
}
3 changes: 1 addition & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@
"conflict": {
"phpdocumentor/reflection-docblock": "<5.2",
"phpdocumentor/type-resolver": "<1.5.1",
"symfony/dependency-injection": "<6.4",
"symfony/serializer": "<6.4"
"symfony/dependency-injection": "<6.4"
},
"autoload": {
"psr-4": { "Symfony\\Component\\PropertyInfo\\": "" },
Expand Down

0 comments on commit e9a7b2a

Please sign in to comment.