1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @file |
4
|
|
|
* Contains \Drupal\Core\DependencyInjection\Dumper\PhpArrayDumper |
5
|
|
|
*/ |
6
|
|
|
|
7
|
|
|
namespace Drupal\Core\DependencyInjection\Dumper; |
8
|
|
|
|
9
|
|
|
use Symfony\Component\DependencyInjection\Alias; |
10
|
|
|
use Symfony\Component\DependencyInjection\ContainerInterface; |
11
|
|
|
use Symfony\Component\DependencyInjection\Definition; |
12
|
|
|
use Symfony\Component\DependencyInjection\Parameter; |
13
|
|
|
use Symfony\Component\DependencyInjection\Reference; |
14
|
|
|
use Symfony\Component\DependencyInjection\Exception\RuntimeException; |
15
|
|
|
use Symfony\Component\DependencyInjection\Dumper\Dumper; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* PhpArrayDumper dumps a service container as a serialized PHP array. |
19
|
|
|
*/ |
20
|
|
|
class PhpArrayDumper extends Dumper |
21
|
|
|
{ |
22
|
|
|
/** |
23
|
|
|
* {@inheritdoc} |
24
|
|
|
*/ |
25
|
|
|
public function dump(array $options = array()) |
26
|
|
|
{ |
27
|
|
|
return serialize($this->getArray()); |
28
|
|
|
} |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* Returns the service container as a PHP array. |
32
|
|
|
* |
33
|
|
|
* @return array |
34
|
|
|
* A PHP array represention of the service container |
35
|
|
|
*/ |
36
|
|
|
public function getArray() |
37
|
|
|
{ |
38
|
|
|
$definition = array(); |
39
|
|
|
$definition['parameters'] = $this->getParameters(); |
40
|
|
|
$definition['services'] = $this->getServiceDefinitions(); |
41
|
|
|
return $definition; |
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Returns parameters of the container as a PHP Array. |
47
|
|
|
* |
48
|
|
|
* @return array |
49
|
|
|
* The escaped and prepared parameters of the container. |
50
|
|
|
*/ |
51
|
|
View Code Duplication |
protected function getParameters() |
52
|
|
|
{ |
53
|
|
|
if (!$this->container->getParameterBag()->all()) { |
54
|
|
|
return array(); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
$parameters = $this->container->getParameterBag()->all(); |
58
|
|
|
$is_frozen = $this->container->isFrozen(); |
59
|
|
|
return $this->prepareParameters($parameters, $is_frozen); |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Returns services of the container as a PHP Array. |
64
|
|
|
* |
65
|
|
|
* @return array |
66
|
|
|
* The service definitions. |
67
|
|
|
*/ |
68
|
|
|
protected function getServiceDefinitions() |
69
|
|
|
{ |
70
|
|
|
if (!$this->container->getDefinitions()) { |
71
|
|
|
return array(); |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
$services = array(); |
75
|
|
|
foreach ($this->container->getDefinitions() as $id => $definition) { |
76
|
|
|
$services[$id] = $this->getServiceDefinition($definition); |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
$aliases = $this->container->getAliases(); |
80
|
|
View Code Duplication |
foreach ($aliases as $alias => $id) { |
|
|
|
|
81
|
|
|
while (isset($aliases[(string) $id])) { |
82
|
|
|
$id = $aliases[(string) $id]; |
83
|
|
|
} |
84
|
|
|
$services[$alias] = $this->getServiceAliasDefinition($id); |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
return $services; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* Prepares parameters. |
92
|
|
|
* |
93
|
|
|
* @param array $parameters |
94
|
|
|
* @param bool $escape |
95
|
|
|
* |
96
|
|
|
* @return array |
97
|
|
|
*/ |
98
|
|
View Code Duplication |
protected function prepareParameters($parameters, $escape = true) |
99
|
|
|
{ |
100
|
|
|
$filtered = array(); |
101
|
|
|
foreach ($parameters as $key => $value) { |
102
|
|
|
if (is_array($value)) { |
103
|
|
|
$value = $this->prepareParameters($value, $escape); |
104
|
|
|
} |
105
|
|
|
elseif ($value instanceof Reference) { |
106
|
|
|
$value = '@'.$value; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
$filtered[$key] = $value; |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
return $escape ? $this->escape($filtered) : $filtered; |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* Escapes arguments. |
117
|
|
|
* |
118
|
|
|
* @param array $arguments |
119
|
|
|
* The arguments to escape. |
120
|
|
|
* |
121
|
|
|
* @return array |
122
|
|
|
* The escaped arguments. |
123
|
|
|
*/ |
124
|
|
View Code Duplication |
protected function escape($arguments) |
125
|
|
|
{ |
126
|
|
|
$args = array(); |
127
|
|
|
foreach ($arguments as $k => $v) { |
128
|
|
|
if (is_array($v)) { |
129
|
|
|
$args[$k] = $this->escape($v); |
130
|
|
|
} |
131
|
|
|
elseif (is_string($v)) { |
132
|
|
|
$args[$k] = str_replace('%', '%%', $v); |
133
|
|
|
} |
134
|
|
|
else { |
135
|
|
|
$args[$k] = $v; |
136
|
|
|
} |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
return $args; |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* Gets a service definition as PHP array. |
144
|
|
|
* |
145
|
|
|
* @param \Symfony\Component\DependencyInjection\Definition $definition |
146
|
|
|
* The definition to process. |
147
|
|
|
* |
148
|
|
|
* @return array |
149
|
|
|
* The service definition as PHP array. |
150
|
|
|
*/ |
151
|
|
|
protected function getServiceDefinition($definition) |
152
|
|
|
{ |
153
|
|
|
$service = array(); |
154
|
|
|
if ($definition->getClass()) { |
|
|
|
|
155
|
|
|
$service['class'] = $definition->getClass(); |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
if (!$definition->isPublic()) { |
159
|
|
|
$service['public'] = FALSE; |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
$tags = $definition->getTags(); |
163
|
|
|
if (!empty($tags)) { |
164
|
|
|
foreach ($tags as $tag => $attributes) { |
165
|
|
|
$tag = ['name' => $tag]; |
166
|
|
|
foreach ($attributes as $attribute) { |
167
|
|
|
$tag += $attribute; |
168
|
|
|
} |
169
|
|
|
$service['tags'][] = $tag; |
170
|
|
|
} |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
if ($definition->getFile()) { |
|
|
|
|
174
|
|
|
$service['file'] = $definition->getFile(); |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
if ($definition->isSynthetic()) { |
178
|
|
|
$service['synthetic'] = TRUE; |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
if ($definition->isLazy()) { |
182
|
|
|
$service['lazy'] = TRUE; |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
if ($definition->getArguments()) { |
186
|
|
|
$service['arguments'] = $this->dumpValue($definition->getArguments()); |
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
if ($definition->getProperties()) { |
190
|
|
|
$service['properties'] = $this->dumpValue($definition->getProperties()); |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
if ($definition->getMethodCalls()) { |
194
|
|
|
$service['calls'] = $this->dumpValue($definition->getMethodCalls()); |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
if (($scope = $definition->getScope()) !== ContainerInterface::SCOPE_CONTAINER) { |
198
|
|
|
$service['scope'] = $scope; |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
if (($decorated = $definition->getDecoratedService()) !== NULL) { |
202
|
|
|
$service['decorates'] = $decorated; |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
if ($callable = $definition->getFactory()) { |
206
|
|
|
$service['factory'] = $this->dumpCallable($callable); |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
if ($callable = $definition->getConfigurator()) { |
210
|
|
|
$service['configurator'] = $this->dumpCallable($callable); |
211
|
|
|
} |
212
|
|
|
|
213
|
|
|
return $service; |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
/** |
217
|
|
|
* Returns a service alias definiton. |
218
|
|
|
* |
219
|
|
|
* @param string $alias |
|
|
|
|
220
|
|
|
* @param Alias $id |
221
|
|
|
* |
222
|
|
|
* @return string |
223
|
|
|
*/ |
224
|
|
|
protected function getServiceAliasDefinition($id) |
225
|
|
|
{ |
226
|
|
|
if ($id->isPublic()) { |
227
|
|
|
return array( |
228
|
|
|
'alias' => (string) $id, |
229
|
|
|
); |
230
|
|
|
} else { |
231
|
|
|
return array( |
232
|
|
|
'alias' => (string) $id, |
233
|
|
|
'public' => FALSE, |
234
|
|
|
); |
235
|
|
|
} |
236
|
|
|
} |
237
|
|
|
/** |
238
|
|
|
* Dumps callable to YAML format |
239
|
|
|
* |
240
|
|
|
* @param callable $callable |
241
|
|
|
* |
242
|
|
|
* @return callable |
243
|
|
|
*/ |
244
|
|
|
protected function dumpCallable($callable) |
245
|
|
|
{ |
246
|
|
|
if (is_array($callable)) { |
247
|
|
|
if ($callable[0] instanceof Reference) { |
248
|
|
|
$callable = array($this->getServiceCall((string) $callable[0], $callable[0]), $callable[1]); |
249
|
|
|
} |
250
|
|
|
elseif ($callable[0] instanceof Definition) { |
251
|
|
|
$callable[0] = $this->getPrivateService($callable[0]); |
252
|
|
|
$callable = array($callable[0], $callable[1]); |
253
|
|
|
} |
254
|
|
|
else { |
255
|
|
|
$callable = array($callable[0], $callable[1]); |
256
|
|
|
} |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
return $callable; |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
/** |
263
|
|
|
* Returns a private service definition in a suitable format. |
264
|
|
|
* |
265
|
|
|
* @param \Symfony\Component\DependencyInjection\Definition $definition |
266
|
|
|
* The definition to process. |
267
|
|
|
* |
268
|
|
|
* @return \stdClass |
269
|
|
|
* A very lightweight private service value object. |
270
|
|
|
*/ |
271
|
|
|
protected function getPrivateService(Definition $definition) { |
272
|
|
|
$service_definition = $this->getServiceDefinition($definition); |
273
|
|
|
$hash = sha1(serialize($service_definition)); |
274
|
|
|
return (object) array( |
275
|
|
|
'type' => 'service', |
276
|
|
|
'id' => 'private__' . $hash, |
277
|
|
|
'value' => $service_definition, |
278
|
|
|
); |
279
|
|
|
} |
280
|
|
|
|
281
|
|
|
/** |
282
|
|
|
* Dumps the value to YAML format. |
283
|
|
|
* |
284
|
|
|
* @param mixed $value |
285
|
|
|
* |
286
|
|
|
* @return mixed |
287
|
|
|
* |
288
|
|
|
* @throws RuntimeException When trying to dump object or resource |
289
|
|
|
*/ |
290
|
|
|
protected function dumpValue($value) |
291
|
|
|
{ |
292
|
|
|
if (is_array($value)) { |
293
|
|
|
$code = array(); |
294
|
|
|
foreach ($value as $k => $v) { |
295
|
|
|
$code[$k] = $this->dumpValue($v); |
296
|
|
|
} |
297
|
|
|
|
298
|
|
|
return $code; |
299
|
|
|
} elseif ($value instanceof Reference) { |
300
|
|
|
return $this->getServiceCall((string) $value, $value); |
301
|
|
|
} elseif ($value instanceof Definition) { |
302
|
|
|
return $this->getPrivateService($value); |
303
|
|
|
} elseif ($value instanceof Parameter) { |
304
|
|
|
return $this->getParameterCall((string) $value); |
305
|
|
|
} elseif ($value instanceof Expression) { |
|
|
|
|
306
|
|
|
return $this->getExpressionCall((string) $value); |
307
|
|
View Code Duplication |
} elseif (is_object($value)) { |
|
|
|
|
308
|
|
|
if (isset($value->_serviceId)) { |
309
|
|
|
return '@' . $value->_serviceId; |
310
|
|
|
} |
311
|
|
|
throw new RuntimeException('Unable to dump a service container if a parameter is an object without _serviceId.'); |
312
|
|
|
} elseif (is_resource($value)) { |
313
|
|
|
throw new RuntimeException('Unable to dump a service container if a parameter is a resource.'); |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
return $value; |
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
/** |
320
|
|
|
* Gets the service call. |
321
|
|
|
* |
322
|
|
|
* @param string $id |
323
|
|
|
* @param Reference $reference |
324
|
|
|
* |
325
|
|
|
* @return string |
326
|
|
|
*/ |
327
|
|
View Code Duplication |
protected function getServiceCall($id, Reference $reference = null) |
328
|
|
|
{ |
329
|
|
|
if (null !== $reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $reference->getInvalidBehavior()) { |
330
|
|
|
return sprintf('@?%s', $id); |
331
|
|
|
} |
332
|
|
|
|
333
|
|
|
return sprintf('@%s', $id); |
334
|
|
|
} |
335
|
|
|
|
336
|
|
|
/** |
337
|
|
|
* Gets parameter call. |
338
|
|
|
* |
339
|
|
|
* @param string $id |
340
|
|
|
* |
341
|
|
|
* @return string |
342
|
|
|
*/ |
343
|
|
|
protected function getParameterCall($id) |
344
|
|
|
{ |
345
|
|
|
return sprintf('%%%s%%', $id); |
346
|
|
|
} |
347
|
|
|
|
348
|
|
|
protected function getExpressionCall($expression) |
349
|
|
|
{ |
350
|
|
|
return sprintf('@=%s', $expression); |
351
|
|
|
} |
352
|
|
|
} |
353
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.