Skip to content

Commit 1c3c841

Browse files
committed
Add metadata mutators
1 parent 307b7c0 commit 1c3c841

22 files changed

+615
-6
lines changed

phpstan.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ parameters:
8686
- '/Trying to invoke mixed/'
8787
- '/Method Sylius\\Bundle\\ResourceBundle\\Grid\\Controller\\ResourcesResolver\:\:getResources\(\) has no return type specified\./'
8888
- '/Parameter \#2 \$callback of function preg_replace_callback expects callable\(array\<int\|string\, string\>\): string, Closure\(array\)\: mixed given\./'
89+
- '/Parameter #2 \$configurator of method Symfony\\Component\\DependencyInjection\\ContainerBuilder::registerAttributeForAutoconfiguration\(\)/'
8990
- '/Parameter \#1 \$objectOrArray of method Symfony\\Component\\PropertyAccess\\PropertyAccessorInterface\:\:getValue\(\) expects array\|object, array\|object\|null given\./'
9091
- '/Parameter \#1 \$min \(0\) of function random_int expects lower number than parameter \#2 \$max \(int\<\-1, max\>\)\./'
9192
- '/Method Sylius\\Resource\\Model\\ResourceInterface\:\:getId\(\) has no return type specified\./'

psalm.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
<referencedFunction name="Doctrine\Persistence\ObjectManager::getClassMetadata" />
4040
<referencedFunction name="ReflectionClass::getAttributes" />
4141
<file name="src/Bundle/Form/DataTransformer/CollectionToStringTransformer.php" />
42+
<file name="src/Bundle/DependencyInjection/SyliusResourceExtension.php" />
4243
<file name="src/Component/src/Doctrine/Persistence/InMemoryRepository.php" />
4344
<file name="src/Component/src/Symfony/Request/State/Provider.php" />
4445
</errorLevel>
@@ -153,6 +154,12 @@
153154
</errorLevel>
154155
</MissingClassConstType>
155156

157+
<MissingConstructor>
158+
<errorLevel type="suppress">
159+
<file name="src/Component/src/Metadata/Mutator/ResourceMutatorCollection.php" />
160+
</errorLevel>
161+
</MissingConstructor>
162+
156163
<MissingParamType>
157164
<errorLevel type="suppress">
158165
<file name="src/Bundle/Routing/ResourceLoader.php" />

src/Bundle/DependencyInjection/SyliusResourceExtension.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,13 @@
2323
use Sylius\Component\Resource\Factory\FactoryInterface as LegacyFactoryInterface;
2424
use Sylius\Resource\Factory\Factory;
2525
use Sylius\Resource\Factory\FactoryInterface;
26+
use Sylius\Resource\Metadata\AsOperationMutator;
2627
use Sylius\Resource\Metadata\AsResource;
28+
use Sylius\Resource\Metadata\AsResourceMutator;
2729
use Sylius\Resource\Metadata\Metadata;
30+
use Sylius\Resource\Metadata\OperationMutatorInterface;
2831
use Sylius\Resource\Metadata\ResourceMetadata;
32+
use Sylius\Resource\Metadata\ResourceMutatorInterface;
2933
use Sylius\Resource\Reflection\ClassReflection;
3034
use Sylius\Resource\State\ProcessorInterface;
3135
use Sylius\Resource\State\ProviderInterface;
@@ -34,6 +38,7 @@
3438
use Symfony\Component\Config\FileLocator;
3539
use Symfony\Component\Config\Loader\LoaderInterface;
3640
use Symfony\Component\Config\Resource\DirectoryResource;
41+
use Symfony\Component\DependencyInjection\ChildDefinition;
3742
use Symfony\Component\DependencyInjection\ContainerBuilder;
3843
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
3944
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
@@ -76,6 +81,36 @@ public function load(array $configs, ContainerBuilder $container): void
7681
$this->loadPersistence($config['drivers'], $config['resources'], $loader, $container);
7782
$this->loadResources($config['resources'], $container);
7883

84+
$container->registerAttributeForAutoconfiguration(
85+
AsResourceMutator::class,
86+
static function (ChildDefinition $definition, AsResourceMutator $attribute, \Reflector $reflector): void {
87+
if (!$reflector instanceof \ReflectionClass) {
88+
return;
89+
}
90+
91+
if (!is_a($reflector->name, ResourceMutatorInterface::class, true)) {
92+
throw new RuntimeException(\sprintf('Resource mutator "%s" should implement %s', $reflector->name, ResourceMutatorInterface::class));
93+
}
94+
95+
$definition->addTag('sylius.resource_mutator', [
96+
'resourceClass' => $attribute->resourceClass,
97+
]);
98+
},
99+
);
100+
101+
$container->registerAttributeForAutoconfiguration(
102+
AsOperationMutator::class,
103+
static function (ChildDefinition $definition, AsOperationMutator $attribute, \ReflectionClass $reflector): void {
104+
if (!is_a($reflector->name, OperationMutatorInterface::class, true)) {
105+
throw new RuntimeException(\sprintf('Operation mutator "%s" should implement %s', $reflector->name, OperationMutatorInterface::class));
106+
}
107+
108+
$definition->addTag('sylius.operation_mutator', [
109+
'operationName' => $attribute->operationName,
110+
]);
111+
},
112+
);
113+
79114
$container->registerForAutoconfiguration(ProviderInterface::class)
80115
->addTag('sylius.state_provider')
81116
;

src/Bundle/Resources/config/services/metadata/extractor.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
<?xml version="1.0" ?>
2+
3+
<!--
4+
5+
This file is part of the Sylius package.
6+
7+
(c) Sylius Sp. z o.o.
8+
9+
For the full copyright and license information, please view the LICENSE
10+
file that was distributed with this source code.
11+
12+
-->
13+
114
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
215
<services>
316
<service id="sylius.metadata.resource_extractor.php_file" class="Sylius\Resource\Metadata\Extractor\PhpFileResourceExtractor" public="false">
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" ?>
2+
3+
<!--
4+
5+
This file is part of the Sylius package.
6+
7+
(c) Sylius Sp. z o.o.
8+
9+
For the full copyright and license information, please view the LICENSE
10+
file that was distributed with this source code.
11+
12+
-->
13+
14+
<container xmlns="http://symfony.com/schema/dic/services"
15+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
16+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
17+
18+
<services>
19+
<service id="sylius.metadata.mutator_collection.resource" class="Sylius\Resource\Metadata\Mutator\ResourceMutatorCollection" public="false" />
20+
21+
<service id="sylius.metadata.mutator_collection.operation" class="Sylius\Resource\Metadata\Mutator\OperationMutatorCollection" public="false" />
22+
</services>
23+
</container>

src/Bundle/Resources/config/services/metadata/resource_metadata_collection.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@
3636
<argument type="service" id=".inner" />
3737
</service>
3838

39+
<service id="sylius.metadata.resource.metadata_collection_factory.mutator"
40+
class="Sylius\Resource\Metadata\Resource\Factory\MutatorResourceMetadataCollectionFactory"
41+
decorates="sylius.resource_metadata_collection.factory"
42+
decoration-priority="400">
43+
<argument type="service" id="sylius.metadata.mutator_collection.resource" />
44+
<argument type="service" id="sylius.metadata.mutator_collection.operation" />
45+
<argument type="service" id=".inner" />
46+
</service>
47+
3948
<service id="sylius.resource_metadata_collection.factory.state_machine"
4049
class="Sylius\Resource\Metadata\Resource\Factory\StateMachineResourceMetadataCollectionFactory"
4150
decorates="sylius.resource_metadata_collection.factory"

src/Bundle/SyliusResourceBundle.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
use Sylius\Bundle\ResourceBundle\DependencyInjection\PagerfantaExtension;
3232
use Sylius\Resource\Symfony\DependencyInjection\Compiler\DisableMetadataCachePass;
3333
use Sylius\Resource\Symfony\DependencyInjection\Compiler\FallbackToKernelDefaultLocalePass;
34+
use Sylius\Resource\Symfony\DependencyInjection\Compiler\MetadataMutatorPass;
3435
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
3536
use Symfony\Component\DependencyInjection\ContainerBuilder;
3637
use Symfony\Component\HttpKernel\Bundle\Bundle;
@@ -54,6 +55,7 @@ public function build(ContainerBuilder $container): void
5455
$container->addCompilerPass(new FallbackToKernelDefaultLocalePass());
5556
$container->addCompilerPass(new DoctrineContainerRepositoryFactoryPass());
5657
$container->addCompilerPass(new DoctrineTargetEntitiesResolverPass(new TargetEntitiesResolver()), PassConfig::TYPE_BEFORE_OPTIMIZATION, 1);
58+
$container->addCompilerPass(new MetadataMutatorPass());
5759
$container->addCompilerPass(new RegisterFormBuilderPass());
5860
$container->addCompilerPass(new RegisterFqcnControllersPass());
5961
$container->addCompilerPass(new RegisterResourceRepositoryPass());
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Sylius package.
5+
*
6+
* (c) Sylius Sp. z o.o.
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+
declare(strict_types=1);
13+
14+
namespace Sylius\Resource\Metadata;
15+
16+
#[\Attribute(\Attribute::TARGET_CLASS)]
17+
class AsOperationMutator
18+
{
19+
public function __construct(
20+
public readonly string $operationName,
21+
) {
22+
}
23+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Sylius package.
5+
*
6+
* (c) Sylius Sp. z o.o.
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+
declare(strict_types=1);
13+
14+
namespace Sylius\Resource\Metadata;
15+
16+
#[\Attribute(\Attribute::TARGET_CLASS)]
17+
class AsResourceMutator
18+
{
19+
/**
20+
* @param class-string $resourceClass
21+
*/
22+
public function __construct(
23+
public readonly string $resourceClass,
24+
) {
25+
}
26+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Sylius package.
5+
*
6+
* (c) Sylius Sp. z o.o.
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+
declare(strict_types=1);
13+
14+
namespace Sylius\Resource\Metadata\Mutator;
15+
16+
use Sylius\Resource\Metadata\OperationMutatorInterface;
17+
18+
/**
19+
* @internal
20+
*/
21+
final class OperationMutatorCollection implements OperationMutatorCollectionInterface
22+
{
23+
private array $mutators = [];
24+
25+
/**
26+
* Adds a mutator to the container for a given operation name.
27+
*/
28+
public function add(string $operationName, OperationMutatorInterface $mutator): void
29+
{
30+
$this->mutators[$operationName][] = $mutator;
31+
}
32+
33+
public function get(string $id): array
34+
{
35+
return $this->mutators[$id] ?? [];
36+
}
37+
38+
public function has(string $id): bool
39+
{
40+
return isset($this->mutators[$id]);
41+
}
42+
}

0 commit comments

Comments
 (0)