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

__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 7
cts 7
cp 1
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 6
nc 1
nop 2
crap 1
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