8000 [PropertyInfo][FrameworkBundle] Allow defining accessors and mutators… · symfony/symfony@bb0f56d · GitHub
[go: up one dir, main page]

Skip to content

Commit bb0f56d

Browse files
committed
[PropertyInfo][FrameworkBundle] Allow defining accessors and mutators via an attribute
1 parent f1fa5c7 commit bb0f56d

29 files changed

+1169
-25
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@
140140
use Symfony\Component\PropertyInfo\Extractor\ConstructorArgumentTypeExtractorInterface;
141141
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
142142
use Symfony\Component\PropertyInfo\Extractor\PhpStanExtractor;
143+
use Symfony\Component\PropertyInfo\Mapping\Factory\ClassMetadataFactoryInterface;
143144
use Symfony\Component\PropertyInfo\PropertyAccessExtractorInterface;
144145
use Symfony\Component\PropertyInfo\PropertyDescriptionExtractorInterface;
145146
use Symfony\Component\PropertyInfo\PropertyInfoExtractorInterface;
@@ -2076,6 +2077,16 @@ private function registerPropertyInfoConfiguration(array $config, ContainerBuild
20762077

20772078
if ($container->getParameter('kernel.debug')) {
20782079
$container->removeDefinition('property_info.cache');
2080+
$container->removeDefinition('property_info.mapping.cached_class_metadata_factory');
2081+
}
2082+
2083+
if (!interface_exists(ClassMetadataFactoryInterface::class)) {
2084+
$container->removeDefinition('property_info.mapping.attribute_loader');
2085+
$container->removeDefinition('property_info.mapping.class_metadata_factory');
2086+
$container->removeDefinition('property_info.mapping.cached_class_metadata_factory');
2087+
} else {
2088+
$container->getDefinition('property_info.reflection_extractor')
2089+
->setArgument('$classMetadataFactory', new Reference('property_info.mapping.class_metadata_factory'));
20792090
}
20802091
}
20812092

src/Symfony/Bundle/FrameworkBundle/Resources/config/property_info.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313

1414
use Symfony\Component\PropertyInfo\Extractor\ConstructorExtractor;
1515
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
16+
use Symfony\Component\PropertyInfo\Mapping\Factory\CachedClassMetadataFactory;
17+
use Symfony\Component\PropertyInfo\Mapping\Factory\ClassMetadataFactory;
18+
use Symfony\Component\PropertyInfo\Mapping\Loader\AttributeLoader;
1619
use Symfony\Component\PropertyInfo\PropertyAccessExtractorInterface;
1720
use Symfony\Component\PropertyInfo\PropertyDescriptionExtractorInterface;
1821
use Symfony\Component\PropertyInfo\PropertyInfoCacheExtractor;
@@ -40,6 +43,18 @@
4043
->decorate('property_info')
4144
->args([service('property_info.cache.inner'), service('cache.property_info')])
4245

46+
->set('property_info.mapping.attribute_loader', AttributeLoader::class)
47+
48+
->set('property_info.mapping.class_metadata_factory', ClassMetadataFactory::class)
49+
->args([service('property_info.mapping.attribute_loader')])
50+
51+
->set('property_info.mapping.cached_class_metadata_factory', CachedClassMetadataFactory::class)
52+
->decorate('property_info.mapping.class_metadata_factory')
53+
->args([
54+
service('property_info.mapping.cached_class_metadata_factory.inner'),
55+
service('cache.property_info'),
56+
])
57+
4358
// Extractor
4459
->set('property_info.reflection_extractor', ReflectionExtractor::class)
4560
->tag('property_info.list_extractor', ['priority' => -1000])
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\PropertyInfo\Attribute;
13+
14+
use Symfony\Component\PropertyInfo\Exception\LogicException;
15+
16+
#[\Attribute(\Attribute::TARGET_PROPERTY)]
17+
final readonly class WithAccessors
18+
{
19+
public function __construct(
20+
public ?string $getter = null,
21+
public ?string $setter = null,
22+
public ?string $adder = null,
23+
public ?string $remover = null,
24+
) {
25+
if (!($this->getter || $this->setter || $this->adder || $this->remover)) {
26+
throw new LogicException('You need to have at least one method name set.');
27+
}
28+
if ($this->adder xor $this->remover) {
29+
throw new LogicException('You need to have both an adder and remover set.');
30+
}
31+
}
32+
}

src/Symfony/Component/PropertyInfo/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CHANGELOG
66

77
* Add support for `non-positive-int`, `non-negative-int` and `non-zero-int` PHPStan types to `PhpStanExtractor`
88
* Add `PropertyDescriptionExtractorInterface` to `PhpStanExtractor`
9+
* Allow defining accessors and mutators via the `#[WithAccessors]` attribute
910

1011
7.1
1112
---
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\PropertyInfo\Exception;
13+
14+
interface ExceptionInterface extends \Throwable
15+
{
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\PropertyInfo\Exception;
13+
14+
class LogicException extends \LogicException implements ExceptionInterface
15+
{
16+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\PropertyInfo\Exception;
13+
14+
class MappingException extends RuntimeException
15+
{
16+
/**
17+
* @param list<string> $invalidMethods
18+
*/
19+
public function __construct(
20+
string $message,
21+
public readonly string $forClass,
22+
public readonly array $invalidMethods,
23+
?\Throwable $previous = null,
24+
) {
25+
parent::__construct($message, 0, $previous);
26+
}
27+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\PropertyInfo\Exception;
13+
14+
class RuntimeException extends \RuntimeException implements ExceptionInterface
15+
{
16+
}

0 commit comments

Comments
 (0)
0