|
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
|
|
|
class DeclarativeEnumCollectorCompilerPass implements CompilerPassInterface |
|
22
|
|
|
{ |
|
23
|
|
|
/** |
|
24
|
|
|
* @var string |
|
25
|
|
|
*/ |
|
26
|
|
|
private $bundleDir; |
|
27
|
|
|
|
|
28
|
|
|
/** |
|
29
|
|
|
* @var string |
|
30
|
|
|
*/ |
|
31
|
|
|
private $bundleNamespace; |
|
32
|
|
|
|
|
33
|
|
|
/** |
|
34
|
|
|
* @var string |
|
35
|
|
|
*/ |
|
36
|
|
|
private $bundleName; |
|
37
|
|
|
|
|
38
|
|
|
/** |
|
39
|
|
|
* @var string |
|
40
|
|
|
*/ |
|
41
|
|
|
private $transDomain; |
|
42
|
|
|
|
|
43
|
|
|
/** |
|
44
|
|
|
* @param string $bundle |
|
45
|
|
|
* @param string|null $transDomain |
|
46
|
|
|
*/ |
|
47
|
3 |
|
public function __construct($bundle, $transDomain = null) |
|
48
|
|
|
{ |
|
49
|
3 |
|
$reflection = new ReflectionClass($bundle); |
|
50
|
3 |
|
$this->bundleDir = dirname($reflection->getFileName()); |
|
51
|
3 |
|
$this->bundleNamespace = $reflection->getNamespaceName(); |
|
52
|
3 |
|
$this->bundleName = $reflection->getShortName(); |
|
53
|
|
|
|
|
54
|
3 |
|
$this->transDomain = $transDomain; |
|
55
|
3 |
|
} |
|
56
|
|
|
|
|
57
|
|
|
/** |
|
58
|
|
|
* @inheritdoc |
|
59
|
|
|
*/ |
|
60
|
3 |
|
public function process(ContainerBuilder $container) |
|
61
|
|
|
{ |
|
62
|
3 |
|
if (!class_exists('Symfony\Component\Finder\Finder')) { |
|
63
|
|
|
throw new RuntimeException('You need the symfony/finder component to register enums.'); |
|
64
|
|
|
} |
|
65
|
|
|
|
|
66
|
3 |
|
$enumDir = $this->bundleDir . '/Enum'; |
|
67
|
|
|
|
|
68
|
3 |
|
if (!is_dir($enumDir)) { |
|
69
|
|
|
return; |
|
70
|
|
|
} |
|
71
|
|
|
|
|
72
|
3 |
|
$finder = new Finder(); |
|
73
|
3 |
|
$finder->files()->name('*Enum.php')->in($enumDir); |
|
74
|
|
|
|
|
75
|
3 |
|
foreach ($finder as $file) { |
|
76
|
|
|
/** @var SplFileInfo $file */ |
|
77
|
3 |
|
$enumNamespace = $this->bundleNamespace . '\\Enum'; |
|
78
|
3 |
|
if ($relativePath = $file->getRelativePath()) { |
|
79
|
3 |
|
$enumNamespace .= '\\' . strtr($relativePath, '/', '\\'); |
|
80
|
|
|
} |
|
81
|
|
|
|
|
82
|
3 |
|
$enumClass = $enumNamespace . '\\' . $file->getBasename('.php'); |
|
83
|
3 |
|
$enumReflection = new ReflectionClass($enumClass); |
|
84
|
|
|
|
|
85
|
3 |
|
if (!$enumReflection->isSubclassOf(EnumInterface::class) || $enumReflection->isAbstract()) { |
|
86
|
|
|
continue; //Not an enum or abstract enum |
|
87
|
|
|
} |
|
88
|
|
|
|
|
89
|
3 |
|
$definition = null; |
|
90
|
3 |
|
$requiredParameters = 0; |
|
91
|
3 |
|
if ($enumReflection->getConstructor()) { |
|
92
|
3 |
|
$requiredParameters = $enumReflection->getConstructor()->getNumberOfRequiredParameters(); |
|
93
|
|
|
} |
|
94
|
|
|
|
|
95
|
3 |
|
if ($requiredParameters === 0) { |
|
96
|
3 |
|
$definition = new Definition($enumClass); |
|
97
|
3 |
|
} elseif ($requiredParameters === 2 && $enumReflection->isSubclassOf(AbstractTranslatedEnum::class)) { |
|
98
|
3 |
|
if (class_exists('Symfony\Component\DependencyInjection\ChildDefinition')) { |
|
99
|
|
|
// ChildDefinition was introduced as Symfony 3.3 |
|
100
|
3 |
|
$definition = new ChildDefinition('enum.abstract_translated'); |
|
101
|
|
|
} else { |
|
102
|
|
|
// DefinitionDecorator was deprecated as Symfony 3.3 |
|
103
|
|
|
$definition = new DefinitionDecorator('enum.abstract_translated'); |
|
|
|
|
|
|
104
|
|
|
} |
|
105
|
3 |
|
$definition->setClass($enumClass); |
|
106
|
3 |
|
$definition->addArgument( |
|
107
|
3 |
|
$this->getTransPattern($enumClass) |
|
108
|
|
|
); |
|
109
|
|
|
|
|
110
|
3 |
|
if ($this->transDomain) { |
|
111
|
|
|
$definition->addMethodCall( |
|
112
|
|
|
'setTransDomain', |
|
113
|
|
|
[ |
|
114
|
|
|
$this->transDomain |
|
115
|
|
|
] |
|
116
|
|
|
); |
|
117
|
|
|
} |
|
118
|
|
|
} |
|
119
|
|
|
|
|
120
|
3 |
|
if (!$definition) { |
|
121
|
|
|
continue; //Could not determine how to create definition for the enum |
|
122
|
|
|
} |
|
123
|
|
|
|
|
124
|
3 |
|
$definition->addTag('enum'); |
|
125
|
|
|
|
|
126
|
3 |
|
$container->setDefinition( |
|
127
|
3 |
|
$this->getServiceId($enumClass), |
|
128
|
3 |
|
$definition |
|
129
|
|
|
); |
|
130
|
|
|
} |
|
131
|
3 |
|
} |
|
132
|
|
|
|
|
133
|
|
|
/** |
|
134
|
|
|
* @param string $enumClass |
|
135
|
|
|
* |
|
136
|
|
|
* @return string |
|
137
|
|
|
*/ |
|
138
|
3 |
|
private function getServiceId($enumClass) |
|
139
|
|
|
{ |
|
140
|
3 |
|
$enumNamespace = $this->bundleNamespace.'\\Enum\\'; |
|
141
|
|
|
|
|
142
|
3 |
|
return sprintf('%s.enum.%s', |
|
143
|
3 |
|
Container::underscore( |
|
144
|
3 |
|
substr($this->bundleName, 0, -6) |
|
145
|
|
|
), |
|
146
|
3 |
|
Container::underscore( |
|
147
|
3 |
|
str_replace( |
|
148
|
3 |
|
'\\', |
|
149
|
3 |
|
'', |
|
150
|
3 |
|
str_replace( |
|
151
|
3 |
|
$enumNamespace, |
|
152
|
3 |
|
'', |
|
153
|
3 |
|
substr($enumClass, 0, -4) |
|
154
|
|
|
) |
|
155
|
|
|
) |
|
156
|
|
|
) |
|
157
|
|
|
); |
|
158
|
|
|
} |
|
159
|
|
|
|
|
160
|
|
|
/** |
|
161
|
|
|
* @param string $enumClass |
|
162
|
|
|
* |
|
163
|
|
|
* @return string |
|
164
|
|
|
*/ |
|
165
|
3 |
|
private function getTransPattern($enumClass) |
|
166
|
|
|
{ |
|
167
|
3 |
|
$parts = array_filter( |
|
168
|
3 |
|
array_map( |
|
169
|
3 |
|
[$this, 'underscore'], |
|
170
|
3 |
|
explode( |
|
171
|
3 |
|
'\\', |
|
172
|
3 |
|
str_replace( |
|
173
|
3 |
|
$this->bundleNamespace . '\\', |
|
174
|
3 |
|
'', |
|
175
|
3 |
|
$enumClass |
|
176
|
|
|
) |
|
177
|
|
|
) |
|
178
|
|
|
) |
|
179
|
|
|
); |
|
180
|
|
|
|
|
181
|
3 |
|
$enum = array_pop($parts); |
|
182
|
|
|
|
|
183
|
3 |
|
return implode('_', $parts) . '.' . $enum . '.label_%s'; |
|
184
|
|
|
} |
|
185
|
|
|
|
|
186
|
|
|
/** |
|
187
|
|
|
* @param string $input |
|
188
|
|
|
* |
|
189
|
|
|
* @return string |
|
190
|
|
|
*/ |
|
191
|
3 |
|
private function underscore($input) |
|
192
|
|
|
{ |
|
193
|
3 |
|
return strtolower( |
|
194
|
3 |
|
preg_replace( |
|
195
|
3 |
|
'~(?<=\\w)([A-Z])~', '_$1', |
|
196
|
3 |
|
preg_replace( |
|
197
|
3 |
|
'~(Enum|Bundle)~', |
|
198
|
3 |
|
'', |
|
199
|
3 |
|
$input |
|
200
|
|
|
) |
|
201
|
|
|
) |
|
202
|
|
|
); |
|
203
|
|
|
} |
|
204
|
|
|
} |
|
205
|
|
|
|
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.