UiElementRegistryPass::process()   A
last analyzed

Complexity

Conditions 5
Paths 7

Size

Total Lines 38
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 24
c 2
b 0
f 0
dl 0
loc 38
rs 9.2248
cc 5
nc 7
nop 1
1
<?php
2
3
/*
4
 * This file is part of Monsieur Biz' Rich Editor plugin for Sylius.
5
 *
6
 * (c) Monsieur Biz <[email protected]>
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 MonsieurBiz\SyliusRichEditorPlugin\DependencyInjection;
15
16
use MonsieurBiz\SyliusRichEditorPlugin\UiElement\Metadata;
17
use MonsieurBiz\SyliusRichEditorPlugin\UiElement\UiElement;
18
use MonsieurBiz\SyliusRichEditorPlugin\UiElement\UiElementInterface;
19
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
20
use Symfony\Component\DependencyInjection\ContainerBuilder;
21
use Symfony\Component\DependencyInjection\Definition;
22
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
23
use Symfony\Component\DependencyInjection\Reference;
24
25
final class UiElementRegistryPass implements CompilerPassInterface
26
{
27
    /**
28
     * {@inheritdoc}
29
     */
30
    public function process(ContainerBuilder $container): void
31
    {
32
        // Get required parameters and definitions in order to populate the DI
33
        try {
34
            $uiElements = $container->getParameter('monsieurbiz.richeditor.config.ui_elements');
35
            $registry = $container->findDefinition('monsieurbiz.richeditor.registry');
36
            $metadataRegistry = $container->findDefinition('monsieurbiz.richeditor.metadata_registry');
37
        } catch (InvalidArgumentException $exception) {
38
            return;
39
        }
40
41
        if (!\is_array($uiElements)) {
42
            return;
43
        }
44
45
        foreach ($uiElements as $code => $configuration) {
46
            $metadataRegistry->addMethodCall('addFromCodeAndConfiguration', [$code, $configuration]);
47
            $metadata = Metadata::fromCodeAndConfiguration($code, $configuration);
48
49
            $id = $metadata->getServiceId('richeditor.ui_element');
50
51
            $class = $metadata->getClass('ui_element');
52
            $this->validateUiElementResource($class);
53
54
            $uiElementDefinition = $container->setDefinition($id, (new Definition($class))->setAutowired(true));
55
            $uiElementDefinition->addMethodCall('setMetadata', [$this->getMetadataDefinition($metadata)]);
56
            $uiElementDefinition->addMethodCall('setTranslator', [new Reference('translator')]);
57
58
            $aliases = [
59
                UiElementInterface::class . ' $' . $metadata->getCamelCasedCode() . 'UiElement' => $id,
60
                UiElement::class . ' $' . $metadata->getCamelCasedCode() . 'UiElement' => $id,
61
            ];
62
            if (UiElement::class !== $class) {
63
                $aliases[$class . ' $' . $metadata->getCamelCasedCode() . 'UiElement'] = $id;
64
            }
65
            $container->addAliases($aliases);
66
67
            $registry->addMethodCall('addUiElement', [new Reference($id)]);
68
        }
69
    }
70
71
    /**
72
     * @param string $class
73
     *
74
     * @throws InvalidArgumentException
75
     */
76
    private function validateUiElementResource(string $class): void
77
    {
78
        $interfaces = (array) (class_implements($class) ?? []);
79
80
        if (!\in_array(UiElementInterface::class, $interfaces, true)) {
81
            throw new InvalidArgumentException(sprintf('Class "%s" must implement "%s" to be registered as a UiElement resource.', $class, UiElementInterface::class));
82
        }
83
    }
84
85
    /**
86
     * @param Metadata $metadata
87
     *
88
     * @return Definition
89
     */
90
    private function getMetadataDefinition(Metadata $metadata): Definition
91
    {
92
        $metadataDefinition = new Definition(Metadata::class);
93
        $metadataDefinition
94
            ->setFactory([new Reference('monsieurbiz.richeditor.metadata_registry'), 'get'])
95
            ->setArguments([$metadata->getCode()])
96
        ;
97
98
        return $metadataDefinition;
99
    }
100
}
101