Completed
Pull Request — master (#28)
by Yann
02:07
created

DeclarativeEnumCollectorCompilerPass::process()   C

Complexity

Conditions 14
Paths 53

Size

Total Lines 77
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 35
CRAP Score 15.2612

Importance

Changes 0
Metric Value
dl 0
loc 77
ccs 35
cts 43
cp 0.8139
rs 5.2115
c 0
b 0
f 0
cc 14
eloc 43
nc 53
nop 1
crap 15.2612

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Yokai\EnumBundle\DependencyInjection\CompilerPass;
4
5
use ReflectionClass;
6
use RuntimeException;
7
use Symfony\Component\DependencyInjection\ChildDefinition;
8
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
9
use Symfony\Component\DependencyInjection\Container;
10
use Symfony\Component\DependencyInjection\ContainerBuilder;
11
use Symfony\Component\DependencyInjection\Definition;
12
use Symfony\Component\DependencyInjection\DefinitionDecorator;
13
use Symfony\Component\Finder\Finder;
14
use Symfony\Component\Finder\SplFileInfo;
15
use Yokai\EnumBundle\Enum\AbstractTranslatedEnum;
16
use Yokai\EnumBundle\Enum\EnumInterface;
17
18
/**
19
 * @author Yann Eugoné <[email protected]>
20
 *
21
 * @deprecated
22
 */
23
class DeclarativeEnumCollectorCompilerPass implements CompilerPassInterface
24
{
25
    /**
26
     * @var string
27
     */
28
    private $bundleDir;
29
30
    /**
31
     * @var string
32
     */
33
    private $bundleNamespace;
34
35
    /**
36
     * @var string
37
     */
38
    private $bundleName;
39
40
    /**
41
     * @var string
42
     */
43
    private $transDomain;
44
45
    /**
46
     * @param string      $bundle
47
     * @param string|null $transDomain
48
     */
49 3
    public function __construct($bundle, $transDomain = null)
50
    {
51 3
        $reflection = new ReflectionClass($bundle);
52 3
        $this->bundleDir = dirname($reflection->getFileName());
53 3
        $this->bundleNamespace = $reflection->getNamespaceName();
54 3
        $this->bundleName = $reflection->getShortName();
55
56 3
        $this->transDomain = $transDomain;
57 3
    }
58
59
    /**
60
     * @inheritdoc
61
     */
62 3
    public function process(ContainerBuilder $container)
63
    {
64 3
        @trigger_error(
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
65 3
            '"' . __CLASS__ . '" is deprecated since v2.2. Please use Symfony\'s PSR4 Service discovery instead.',
66 3
            E_USER_DEPRECATED
67
        );
68
69 3
        if (!class_exists('Symfony\Component\Finder\Finder')) {
70
            throw new RuntimeException('You need the symfony/finder component to register enums.');
71
        }
72
73 3
        $enumDir = $this->bundleDir . '/Enum';
74
75 3
        if (!is_dir($enumDir)) {
76
            return;
77
        }
78
79 3
        $finder = new Finder();
80 3
        $finder->files()->name('*Enum.php')->in($enumDir);
81
82 3
        foreach ($finder as $file) {
83
            /** @var SplFileInfo $file */
84 3
            $enumNamespace = $this->bundleNamespace . '\\Enum';
85 3
            if ($relativePath = $file->getRelativePath()) {
86 3
                $enumNamespace .= '\\' . strtr($relativePath, '/', '\\');
87
            }
88
89 3
            $enumClass = $enumNamespace . '\\' . $file->getBasename('.php');
90 3
            $enumReflection = new ReflectionClass($enumClass);
91
92 3
            if (!$enumReflection->isSubclassOf(EnumInterface::class) || $enumReflection->isAbstract()) {
93
                continue; //Not an enum or abstract enum
94
            }
95
96 3
            $definition = null;
97 3
            $requiredParameters = 0;
98 3
            if ($enumReflection->getConstructor()) {
99 3
                $requiredParameters = $enumReflection->getConstructor()->getNumberOfRequiredParameters();
100
            }
101
102 3
            if ($requiredParameters === 0) {
103 3
                $definition = new Definition($enumClass);
104 3
            } elseif ($requiredParameters === 2 && $enumReflection->isSubclassOf(AbstractTranslatedEnum::class)) {
105 3
                if (class_exists('Symfony\Component\DependencyInjection\ChildDefinition')) {
106
                    // ChildDefinition was introduced as Symfony 3.3
107
                    $definition = new ChildDefinition('enum.abstract_translated');
108
                } else {
109
                    // DefinitionDecorator was deprecated as Symfony 3.3
110 3
                    $definition = new DefinitionDecorator('enum.abstract_translated');
111
                }
112 3
                $definition->setClass($enumClass);
113 3
                $definition->addArgument(
114 3
                    $this->getTransPattern($enumClass)
115
                );
116
117 3
                if ($this->transDomain) {
118
                    $definition->addMethodCall(
119
                        'setTransDomain',
120
                        [
121
                            $this->transDomain
122
                        ]
123
                    );
124
                }
125
            }
126
127 3
            if (!$definition) {
128
                continue; //Could not determine how to create definition for the enum
129
            }
130
131 3
            $definition->addTag('enum');
132
133 3
            $container->setDefinition(
134 3
                $this->getServiceId($enumClass),
135 3
                $definition
136
            );
137
        }
138 3
    }
139
140
    /**
141
     * @param string $enumClass
142
     *
143
     * @return string
144
     */
145 3
    private function getServiceId($enumClass)
146
    {
147 3
        $enumNamespace = $this->bundleNamespace.'\\Enum\\';
148
149 3
        return sprintf('%s.enum.%s',
150 3
            Container::underscore(
151 3
                substr($this->bundleName, 0, -6)
152
            ),
153 3
            Container::underscore(
154 3
                str_replace(
155 3
                    '\\',
156 3
                    '',
157 3
                    str_replace(
158 3
                        $enumNamespace,
159 3
                        '',
160 3
                        substr($enumClass, 0, -4)
161
                    )
162
                )
163
            )
164
        );
165
    }
166
167
    /**
168
     * @param string $enumClass
169
     *
170
     * @return string
171
     */
172 3
    private function getTransPattern($enumClass)
173
    {
174 3
        $parts = array_filter(
175 3
            array_map(
176 3
                [$this, 'underscore'],
177 3
                explode(
178 3
                    '\\',
179 3
                    str_replace(
180 3
                        $this->bundleNamespace . '\\',
181 3
                        '',
182 3
                        $enumClass
183
                    )
184
                )
185
            )
186
        );
187
188 3
        $enum = array_pop($parts);
189
190 3
        return implode('_', $parts) . '.' . $enum . '.label_%s';
191
    }
192
193
    /**
194
     * @param string $input
195
     *
196
     * @return string
197
     */
198 3
    private function underscore($input)
199
    {
200 3
        return strtolower(
201 3
            preg_replace(
202 3
                '~(?<=\\w)([A-Z])~', '_$1',
203 3
                preg_replace(
204 3
                    '~(Enum|Bundle)~',
205 3
                    '',
206 3
                    $input
207
                )
208
            )
209
        );
210
    }
211
}
212