Completed
Push — master ( c18e77...cd2879 )
by Maxime
13s queued 11s
created

ElaoEnumExtension::resolveDbalType()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.8333
c 0
b 0
f 0
cc 4
nc 6
nop 2
1
<?php
2
3
/*
4
 * This file is part of the "elao/enum" package.
5
 *
6
 * Copyright (C) Elao
7
 *
8
 * @author Elao <[email protected]>
9
 */
10
11
namespace Elao\Enum\Bridge\Symfony\Bundle\DependencyInjection;
12
13
use ApiPlatform\Core\JsonSchema\TypeFactory;
14
use Elao\Enum\Bridge\ApiPlatform\Core\JsonSchema\Type\ElaoEnumType;
15
use Elao\Enum\Bridge\Doctrine\DBAL\Types\TypesDumper;
16
use Elao\Enum\Bridge\Symfony\Console\Command\DumpJsEnumsCommand;
17
use Elao\Enum\Bridge\Symfony\HttpKernel\Controller\ArgumentResolver\EnumValueResolver;
18
use Elao\Enum\Bridge\Symfony\Serializer\Normalizer\EnumNormalizer;
19
use Elao\Enum\Bridge\Symfony\Translation\Extractor\EnumExtractor;
20
use Elao\Enum\FlaggedEnum;
21
use Symfony\Component\Config\FileLocator;
22
use Symfony\Component\DependencyInjection\ContainerBuilder;
23
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
24
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
25
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
26
27
class ElaoEnumExtension extends Extension implements PrependExtensionInterface
28
{
29
    public function prepend(ContainerBuilder $container)
30
    {
31
        $bundles = $container->getParameter('kernel.bundles');
32
        if (!isset($bundles['DoctrineBundle'])) {
33
            return;
34
        }
35
36
        $configs = $container->getExtensionConfig($this->getAlias());
37
        $config = $this->processConfiguration($this->getConfiguration($configs, $container), $configs);
0 ignored issues
show
Documentation introduced by
$this->getConfiguration($configs, $container) is of type null|object, but the function expects a object<Symfony\Component...ConfigurationInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
38
39
        if (!($types = $config['doctrine']['types'] ?? false)) {
40
            return;
41
        }
42
43
        $doctrineTypesConfig = [];
44
        foreach ($types as $name => $value) {
45
            $doctrineTypesConfig[$name] = TypesDumper::getTypeClassname($value['class'], $this->resolveDbalType(
46
                $value,
47
                $this->usesEnumSQLDeclaration($config)
48
            ));
49
        }
50
51
        $container->prependExtensionConfig('doctrine', [
52
            'dbal' => [
53
                'types' => $doctrineTypesConfig,
54
                'mapping_types' => ['enum' => 'string'],
55
            ],
56
        ]);
57
    }
58
59
    public function load(array $configs, ContainerBuilder $container)
60
    {
61
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
62
        $loader->load('services.xml');
63
64
        $config = $this->processConfiguration($this->getConfiguration($configs, $container), $configs);
0 ignored issues
show
Documentation introduced by
$this->getConfiguration($configs, $container) is of type null|object, but the function expects a object<Symfony\Component...ConfigurationInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
65
66
        if (!$this->isConfigEnabled($container, $config['argument_value_resolver'])) {
67
            $container->removeDefinition(EnumValueResolver::class);
68
        }
69
70
        if (!$this->isConfigEnabled($container, $config['serializer'])) {
71
            $container->removeDefinition(EnumNormalizer::class);
72
        }
73
74
        if (!$this->isConfigEnabled($container, $config['translation_extractor'])) {
75
            $container->removeDefinition(EnumExtractor::class);
76
        } else {
77
            $this->registerTranslationExtractorConfiguration($config['translation_extractor'], $container);
78
        }
79
80
        if (!class_exists(TypeFactory::class)) {
81
            $container->removeDefinition(ElaoEnumType::class);
82
        }
83
84
        if ($types = $config['doctrine']['types'] ?? false) {
85
            $container->setParameter(
86
                '.elao_enum.doctrine_types',
87
                array_map(function (string $name, array $v) use ($config): array {
88
                    return [$v['class'], $this->resolveDbalType($v, $this->usesEnumSQLDeclaration($config)), $name];
89
                }, array_keys($types), $types)
90
            );
91
        }
92
93
        $jsEnums = $config['js'];
94
        $container->getDefinition(DumpJsEnumsCommand::class)
95
            ->replaceArgument(0, $jsEnums['paths'])
96
            ->replaceArgument(1, $jsEnums['base_dir'])
97
            ->replaceArgument(2, $jsEnums['lib_path'])
98
        ;
99
    }
100
101
    public function getNamespace()
102
    {
103
        return 'http://elao.com/schema/dic/elao_enum';
104
    }
105
106
    public function getXsdValidationBasePath()
107
    {
108
        return __DIR__ . '/../Resources/config/schema';
109
    }
110
111
    private function resolveDbalType(array $config, bool $useEnumSQLDeclaration): string
112
    {
113
        $type = $config['type'];
114
        $class = $config['class'];
115
116
        $defaultStringType = $useEnumSQLDeclaration ? 'enum' : 'string';
117
118
        if (null === $type) {
119
            $type = is_a($class, FlaggedEnum::class, true) ? $type = 'int' : $defaultStringType;
120
        }
121
122
        return $type;
123
    }
124
125
    private function usesEnumSQLDeclaration($config): bool
126
    {
127
        return $config['doctrine']['enum_sql_declaration'];
128
    }
129
130
    private function registerTranslationExtractorConfiguration(array $config, ContainerBuilder $container)
131
    {
132
        $definition = $container->getDefinition(EnumExtractor::class);
133
134
        $definition->replaceArgument(0, $config['paths']);
135
        $definition->replaceArgument(1, $config['domain']);
136
        $definition->replaceArgument(2, $config['filename_pattern']);
137
        $definition->replaceArgument(3, $config['ignore']);
138
    }
139
}
140