Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like PhpDumper often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use PhpDumper, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
38 | class PhpDumper extends Dumper |
||
39 | { |
||
40 | /** |
||
41 | * Characters that might appear in the generated variable name as first character. |
||
42 | * |
||
43 | * @var string |
||
44 | */ |
||
45 | const FIRST_CHARS = 'abcdefghijklmnopqrstuvwxyz'; |
||
46 | |||
47 | /** |
||
48 | * Characters that might appear in the generated variable name as any but the first character. |
||
49 | * |
||
50 | * @var string |
||
51 | */ |
||
52 | const NON_FIRST_CHARS = 'abcdefghijklmnopqrstuvwxyz0123456789_'; |
||
53 | |||
54 | private $inlinedDefinitions; |
||
55 | private $definitionVariables; |
||
56 | private $referenceVariables; |
||
57 | private $variableCount; |
||
58 | private $reservedVariables = array('instance', 'class'); |
||
59 | private $expressionLanguage; |
||
60 | private $targetDirRegex; |
||
61 | private $targetDirMaxMatches; |
||
62 | |||
63 | /** |
||
64 | * @var ExpressionFunctionProviderInterface[] |
||
65 | */ |
||
66 | private $expressionLanguageProviders = array(); |
||
67 | |||
68 | /** |
||
69 | * @var \Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface |
||
70 | */ |
||
71 | private $proxyDumper; |
||
72 | |||
73 | /** |
||
74 | * {@inheritdoc} |
||
75 | * |
||
76 | * @api |
||
77 | */ |
||
78 | public function __construct(ContainerBuilder $container) |
||
79 | { |
||
80 | parent::__construct($container); |
||
81 | |||
82 | $this->inlinedDefinitions = new \SplObjectStorage(); |
||
83 | } |
||
84 | |||
85 | /** |
||
86 | * Sets the dumper to be used when dumping proxies in the generated container. |
||
87 | * |
||
88 | * @param ProxyDumper $proxyDumper |
||
89 | */ |
||
90 | public function setProxyDumper(ProxyDumper $proxyDumper) |
||
94 | |||
95 | /** |
||
96 | * Dumps the service container as a PHP class. |
||
97 | * |
||
98 | * Available options: |
||
99 | * |
||
100 | * * class: The class name |
||
101 | * * base_class: The base class name |
||
102 | * * namespace: The class namespace |
||
103 | * |
||
104 | * @param array $options An array of options |
||
105 | * |
||
106 | * @return string A PHP class representing of the service container |
||
107 | * |
||
108 | * @api |
||
109 | */ |
||
110 | public function dump(array $options = array()) |
||
111 | { |
||
112 | $this->targetDirRegex = null; |
||
113 | $options = array_merge(array( |
||
114 | 'class' => 'ProjectServiceContainer', |
||
115 | 'base_class' => 'Container', |
||
116 | 'namespace' => '', |
||
117 | ), $options); |
||
118 | |||
119 | if (!empty($options['file']) && is_dir($dir = dirname($options['file']))) { |
||
120 | // Build a regexp where the first root dirs are mandatory, |
||
121 | // but every other sub-dir is optional up to the full path in $dir |
||
122 | // Mandate at least 2 root dirs and not more that 5 optional dirs. |
||
123 | |||
124 | $dir = explode(DIRECTORY_SEPARATOR, realpath($dir)); |
||
125 | $i = count($dir); |
||
126 | |||
127 | if (3 <= $i) { |
||
128 | $regex = ''; |
||
129 | $lastOptionalDir = $i > 8 ? $i - 5 : 3; |
||
130 | $this->targetDirMaxMatches = $i - $lastOptionalDir; |
||
131 | |||
132 | View Code Duplication | while (--$i >= $lastOptionalDir) { |
|
|
|||
133 | $regex = sprintf('(%s%s)?', preg_quote(DIRECTORY_SEPARATOR.$dir[$i], '#'), $regex); |
||
134 | } |
||
135 | |||
136 | View Code Duplication | do { |
|
137 | $regex = preg_quote(DIRECTORY_SEPARATOR.$dir[$i], '#').$regex; |
||
138 | } while (0 < --$i); |
||
139 | |||
140 | $this->targetDirRegex = '#'.preg_quote($dir[0], '#').$regex.'#'; |
||
141 | } |
||
142 | } |
||
143 | |||
144 | $code = $this->startClass($options['class'], $options['base_class'], $options['namespace']); |
||
145 | |||
146 | if ($this->container->isFrozen()) { |
||
147 | $code .= $this->addFrozenConstructor(); |
||
148 | $code .= $this->addFrozenCompile(); |
||
149 | } else { |
||
150 | $code .= $this->addConstructor(); |
||
151 | } |
||
152 | |||
153 | $code .= |
||
154 | $this->addServices(). |
||
155 | $this->addDefaultParametersMethod(). |
||
156 | $this->endClass(). |
||
157 | $this->addProxyClasses() |
||
158 | ; |
||
159 | $this->targetDirRegex = null; |
||
160 | |||
161 | return $code; |
||
162 | } |
||
163 | |||
164 | /** |
||
165 | * Retrieves the currently set proxy dumper or instantiates one. |
||
166 | * |
||
167 | * @return ProxyDumper |
||
168 | */ |
||
169 | private function getProxyDumper() |
||
170 | { |
||
171 | if (!$this->proxyDumper) { |
||
172 | $this->proxyDumper = new NullDumper(); |
||
173 | } |
||
174 | |||
175 | return $this->proxyDumper; |
||
176 | } |
||
177 | |||
178 | /** |
||
179 | * Generates Service local temp variables. |
||
180 | * |
||
181 | * @param string $cId |
||
182 | * @param string $definition |
||
183 | * |
||
184 | * @return string |
||
185 | */ |
||
186 | private function addServiceLocalTempVariables($cId, $definition) |
||
187 | { |
||
188 | static $template = " \$%s = %s;\n"; |
||
189 | |||
190 | $localDefinitions = array_merge( |
||
191 | array($definition), |
||
192 | $this->getInlinedDefinitions($definition) |
||
193 | ); |
||
194 | |||
195 | $calls = $behavior = array(); |
||
196 | foreach ($localDefinitions as $iDefinition) { |
||
197 | $this->getServiceCallsFromArguments($iDefinition->getArguments(), $calls, $behavior); |
||
198 | $this->getServiceCallsFromArguments($iDefinition->getMethodCalls(), $calls, $behavior); |
||
199 | $this->getServiceCallsFromArguments($iDefinition->getProperties(), $calls, $behavior); |
||
200 | $this->getServiceCallsFromArguments(array($iDefinition->getConfigurator()), $calls, $behavior); |
||
201 | $this->getServiceCallsFromArguments(array($iDefinition->getFactory()), $calls, $behavior); |
||
202 | } |
||
203 | |||
204 | $code = ''; |
||
205 | foreach ($calls as $id => $callCount) { |
||
206 | if ('service_container' === $id || $id === $cId) { |
||
207 | continue; |
||
208 | } |
||
209 | |||
210 | if ($callCount > 1) { |
||
211 | $name = $this->getNextVariableName(); |
||
212 | $this->referenceVariables[$id] = new Variable($name); |
||
213 | |||
214 | if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE === $behavior[$id]) { |
||
215 | $code .= sprintf($template, $name, $this->getServiceCall($id)); |
||
216 | } else { |
||
217 | $code .= sprintf($template, $name, $this->getServiceCall($id, new Reference($id, ContainerInterface::NULL_ON_INVALID_REFERENCE))); |
||
218 | } |
||
219 | } |
||
220 | } |
||
221 | |||
222 | if ('' !== $code) { |
||
223 | $code .= "\n"; |
||
224 | } |
||
225 | |||
226 | return $code; |
||
227 | } |
||
228 | |||
229 | /** |
||
230 | * Generates code for the proxies to be attached after the container class. |
||
231 | * |
||
232 | * @return string |
||
233 | */ |
||
234 | private function addProxyClasses() |
||
235 | { |
||
236 | /* @var $definitions Definition[] */ |
||
237 | $definitions = array_filter( |
||
238 | $this->container->getDefinitions(), |
||
239 | array($this->getProxyDumper(), 'isProxyCandidate') |
||
240 | ); |
||
241 | $code = ''; |
||
242 | |||
243 | foreach ($definitions as $definition) { |
||
244 | $code .= "\n".$this->getProxyDumper()->getProxyCode($definition); |
||
245 | } |
||
246 | |||
247 | return $code; |
||
248 | } |
||
249 | |||
250 | /** |
||
251 | * Generates the require_once statement for service includes. |
||
252 | * |
||
253 | * @param string $id The service id |
||
254 | * @param Definition $definition |
||
255 | * |
||
256 | * @return string |
||
257 | */ |
||
258 | private function addServiceInclude($id, $definition) |
||
259 | { |
||
260 | $template = " require_once %s;\n"; |
||
261 | $code = ''; |
||
262 | |||
263 | View Code Duplication | if (null !== $file = $definition->getFile()) { |
|
264 | $code .= sprintf($template, $this->dumpValue($file)); |
||
265 | } |
||
266 | |||
267 | foreach ($this->getInlinedDefinitions($definition) as $definition) { |
||
268 | View Code Duplication | if (null !== $file = $definition->getFile()) { |
|
269 | $code .= sprintf($template, $this->dumpValue($file)); |
||
270 | } |
||
271 | } |
||
272 | |||
273 | if ('' !== $code) { |
||
274 | $code .= "\n"; |
||
275 | } |
||
276 | |||
277 | return $code; |
||
278 | } |
||
279 | |||
280 | /** |
||
281 | * Generates the inline definition of a service. |
||
282 | * |
||
283 | * @param string $id |
||
284 | * @param Definition $definition |
||
285 | * |
||
286 | * @return string |
||
287 | * |
||
288 | * @throws RuntimeException When the factory definition is incomplete |
||
289 | * @throws ServiceCircularReferenceException When a circular reference is detected |
||
290 | */ |
||
291 | private function addServiceInlinedDefinitions($id, $definition) |
||
292 | { |
||
293 | $code = ''; |
||
294 | $variableMap = $this->definitionVariables; |
||
295 | $nbOccurrences = new \SplObjectStorage(); |
||
296 | $processed = new \SplObjectStorage(); |
||
297 | $inlinedDefinitions = $this->getInlinedDefinitions($definition); |
||
298 | |||
299 | foreach ($inlinedDefinitions as $definition) { |
||
300 | if (false === $nbOccurrences->contains($definition)) { |
||
301 | $nbOccurrences->offsetSet($definition, 1); |
||
302 | } else { |
||
303 | $i = $nbOccurrences->offsetGet($definition); |
||
304 | $nbOccurrences->offsetSet($definition, $i + 1); |
||
305 | } |
||
306 | } |
||
307 | |||
308 | foreach ($inlinedDefinitions as $sDefinition) { |
||
309 | if ($processed->contains($sDefinition)) { |
||
310 | continue; |
||
311 | } |
||
312 | $processed->offsetSet($sDefinition); |
||
313 | |||
314 | $class = $this->dumpValue($sDefinition->getClass()); |
||
315 | if ($nbOccurrences->offsetGet($sDefinition) > 1 || $sDefinition->getMethodCalls() || $sDefinition->getProperties() || null !== $sDefinition->getConfigurator() || false !== strpos($class, '$')) { |
||
316 | $name = $this->getNextVariableName(); |
||
317 | $variableMap->offsetSet($sDefinition, new Variable($name)); |
||
318 | |||
319 | // a construct like: |
||
320 | // $a = new ServiceA(ServiceB $b); $b = new ServiceB(ServiceA $a); |
||
321 | // this is an indication for a wrong implementation, you can circumvent this problem |
||
322 | // by setting up your service structure like this: |
||
323 | // $b = new ServiceB(); |
||
324 | // $a = new ServiceA(ServiceB $b); |
||
325 | // $b->setServiceA(ServiceA $a); |
||
326 | if ($this->hasReference($id, $sDefinition->getArguments())) { |
||
327 | throw new ServiceCircularReferenceException($id, array($id)); |
||
328 | } |
||
329 | |||
330 | $code .= $this->addNewInstance($id, $sDefinition, '$'.$name, ' = '); |
||
331 | |||
332 | if (!$this->hasReference($id, $sDefinition->getMethodCalls(), true) && !$this->hasReference($id, $sDefinition->getProperties(), true)) { |
||
333 | $code .= $this->addServiceMethodCalls(null, $sDefinition, $name); |
||
334 | $code .= $this->addServiceProperties(null, $sDefinition, $name); |
||
335 | $code .= $this->addServiceConfigurator(null, $sDefinition, $name); |
||
336 | } |
||
337 | |||
338 | $code .= "\n"; |
||
339 | } |
||
340 | } |
||
341 | |||
342 | return $code; |
||
343 | } |
||
344 | |||
345 | /** |
||
346 | * Adds the service return statement. |
||
347 | * |
||
348 | * @param string $id Service id |
||
349 | * @param Definition $definition |
||
350 | * |
||
351 | * @return string |
||
352 | */ |
||
353 | private function addServiceReturn($id, $definition) |
||
354 | { |
||
355 | if ($this->isSimpleInstance($id, $definition)) { |
||
356 | return " }\n"; |
||
357 | } |
||
358 | |||
359 | return "\n return \$instance;\n }\n"; |
||
360 | } |
||
361 | |||
362 | /** |
||
363 | * Generates the service instance. |
||
364 | * |
||
365 | * @param string $id |
||
366 | * @param Definition $definition |
||
367 | * |
||
368 | * @return string |
||
369 | * |
||
370 | * @throws InvalidArgumentException |
||
371 | * @throws RuntimeException |
||
372 | */ |
||
373 | private function addServiceInstance($id, $definition) |
||
374 | { |
||
375 | $class = $this->dumpValue($definition->getClass()); |
||
376 | |||
377 | if (0 === strpos($class, "'") && !preg_match('/^\'[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) { |
||
378 | throw new InvalidArgumentException(sprintf('"%s" is not a valid class name for the "%s" service.', $class, $id)); |
||
379 | } |
||
380 | |||
381 | $simple = $this->isSimpleInstance($id, $definition); |
||
382 | $isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition); |
||
383 | $instantiation = ''; |
||
384 | |||
385 | if (!$isProxyCandidate && ContainerInterface::SCOPE_CONTAINER === $definition->getScope()) { |
||
386 | $instantiation = "\$this->services['$id'] = ".($simple ? '' : '$instance'); |
||
387 | } elseif (!$isProxyCandidate && ContainerInterface::SCOPE_PROTOTYPE !== $scope = $definition->getScope()) { |
||
388 | $instantiation = "\$this->services['$id'] = \$this->scopedServices['$scope']['$id'] = ".($simple ? '' : '$instance'); |
||
389 | } elseif (!$simple) { |
||
390 | $instantiation = '$instance'; |
||
391 | } |
||
392 | |||
393 | $return = ''; |
||
394 | if ($simple) { |
||
395 | $return = 'return '; |
||
396 | } else { |
||
397 | $instantiation .= ' = '; |
||
398 | } |
||
399 | |||
400 | $code = $this->addNewInstance($id, $definition, $return, $instantiation); |
||
401 | |||
402 | if (!$simple) { |
||
403 | $code .= "\n"; |
||
404 | } |
||
405 | |||
406 | return $code; |
||
407 | } |
||
408 | |||
409 | /** |
||
410 | * Checks if the definition is a simple instance. |
||
411 | * |
||
412 | * @param string $id |
||
413 | * @param Definition $definition |
||
414 | * |
||
415 | * @return bool |
||
416 | */ |
||
417 | private function isSimpleInstance($id, $definition) |
||
418 | { |
||
419 | foreach (array_merge(array($definition), $this->getInlinedDefinitions($definition)) as $sDefinition) { |
||
420 | if ($definition !== $sDefinition && !$this->hasReference($id, $sDefinition->getMethodCalls())) { |
||
421 | continue; |
||
422 | } |
||
423 | |||
424 | if ($sDefinition->getMethodCalls() || $sDefinition->getProperties() || $sDefinition->getConfigurator()) { |
||
425 | return false; |
||
426 | } |
||
427 | } |
||
428 | |||
429 | return true; |
||
430 | } |
||
431 | |||
432 | /** |
||
433 | * Adds method calls to a service definition. |
||
434 | * |
||
435 | * @param string $id |
||
436 | * @param Definition $definition |
||
437 | * @param string $variableName |
||
438 | * |
||
439 | * @return string |
||
440 | */ |
||
441 | private function addServiceMethodCalls($id, $definition, $variableName = 'instance') |
||
442 | { |
||
443 | $calls = ''; |
||
444 | foreach ($definition->getMethodCalls() as $call) { |
||
445 | $arguments = array(); |
||
446 | foreach ($call[1] as $value) { |
||
447 | $arguments[] = $this->dumpValue($value); |
||
448 | } |
||
449 | |||
450 | $calls .= $this->wrapServiceConditionals($call[1], sprintf(" \$%s->%s(%s);\n", $variableName, $call[0], implode(', ', $arguments))); |
||
451 | } |
||
452 | |||
453 | return $calls; |
||
454 | } |
||
455 | |||
456 | private function addServiceProperties($id, $definition, $variableName = 'instance') |
||
457 | { |
||
458 | $code = ''; |
||
459 | foreach ($definition->getProperties() as $name => $value) { |
||
460 | $code .= sprintf(" \$%s->%s = %s;\n", $variableName, $name, $this->dumpValue($value)); |
||
461 | } |
||
462 | |||
463 | return $code; |
||
464 | } |
||
465 | |||
466 | /** |
||
467 | * Generates the inline definition setup. |
||
468 | * |
||
469 | * @param string $id |
||
470 | * @param Definition $definition |
||
471 | * |
||
472 | * @return string |
||
473 | * |
||
474 | * @throws ServiceCircularReferenceException when the container contains a circular reference |
||
475 | */ |
||
476 | private function addServiceInlinedDefinitionsSetup($id, $definition) |
||
477 | { |
||
478 | $this->referenceVariables[$id] = new Variable('instance'); |
||
479 | |||
480 | $code = ''; |
||
481 | $processed = new \SplObjectStorage(); |
||
482 | foreach ($this->getInlinedDefinitions($definition) as $iDefinition) { |
||
483 | if ($processed->contains($iDefinition)) { |
||
484 | continue; |
||
485 | } |
||
486 | $processed->offsetSet($iDefinition); |
||
487 | |||
488 | if (!$this->hasReference($id, $iDefinition->getMethodCalls(), true) && !$this->hasReference($id, $iDefinition->getProperties(), true)) { |
||
489 | continue; |
||
490 | } |
||
491 | |||
492 | // if the instance is simple, the return statement has already been generated |
||
493 | // so, the only possible way to get there is because of a circular reference |
||
494 | if ($this->isSimpleInstance($id, $definition)) { |
||
495 | throw new ServiceCircularReferenceException($id, array($id)); |
||
496 | } |
||
497 | |||
498 | $name = (string) $this->definitionVariables->offsetGet($iDefinition); |
||
499 | $code .= $this->addServiceMethodCalls(null, $iDefinition, $name); |
||
500 | $code .= $this->addServiceProperties(null, $iDefinition, $name); |
||
501 | $code .= $this->addServiceConfigurator(null, $iDefinition, $name); |
||
502 | } |
||
503 | |||
504 | if ('' !== $code) { |
||
505 | $code .= "\n"; |
||
506 | } |
||
507 | |||
508 | return $code; |
||
509 | } |
||
510 | |||
511 | /** |
||
512 | * Adds configurator definition. |
||
513 | * |
||
514 | * @param string $id |
||
515 | * @param Definition $definition |
||
516 | * @param string $variableName |
||
517 | * |
||
518 | * @return string |
||
519 | */ |
||
520 | private function addServiceConfigurator($id, $definition, $variableName = 'instance') |
||
521 | { |
||
522 | if (!$callable = $definition->getConfigurator()) { |
||
523 | return ''; |
||
524 | } |
||
525 | |||
526 | if (is_array($callable)) { |
||
527 | if ($callable[0] instanceof Reference |
||
528 | || ($callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0]))) { |
||
529 | return sprintf(" %s->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); |
||
530 | } |
||
531 | |||
532 | $class = $this->dumpValue($callable[0]); |
||
533 | // If the class is a string we can optimize call_user_func away |
||
534 | if (strpos($class, "'") === 0) { |
||
535 | return sprintf(" %s::%s(\$%s);\n", $this->dumpLiteralClass($class), $callable[1], $variableName); |
||
536 | } |
||
537 | |||
538 | return sprintf(" call_user_func(array(%s, '%s'), \$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); |
||
539 | } |
||
540 | |||
541 | return sprintf(" %s(\$%s);\n", $callable, $variableName); |
||
542 | } |
||
543 | |||
544 | /** |
||
545 | * Adds a service. |
||
546 | * |
||
547 | * @param string $id |
||
548 | * @param Definition $definition |
||
549 | * |
||
550 | * @return string |
||
551 | */ |
||
552 | private function addService($id, $definition) |
||
667 | |||
668 | /** |
||
669 | * Adds multiple services. |
||
670 | * |
||
671 | * @return string |
||
672 | */ |
||
673 | private function addServices() |
||
674 | { |
||
675 | $publicServices = $privateServices = $synchronizers = ''; |
||
676 | $definitions = $this->container->getDefinitions(); |
||
677 | ksort($definitions); |
||
678 | foreach ($definitions as $id => $definition) { |
||
679 | if ($definition->isPublic()) { |
||
680 | $publicServices .= $this->addService($id, $definition); |
||
681 | } else { |
||
682 | $privateServices .= $this->addService($id, $definition); |
||
683 | } |
||
684 | |||
685 | $synchronizers .= $this->addServiceSynchronizer($id, $definition); |
||
686 | } |
||
687 | |||
688 | return $publicServices.$synchronizers.$privateServices; |
||
689 | } |
||
690 | |||
691 | /** |
||
692 | * Adds synchronizer methods. |
||
693 | * |
||
694 | * @param string $id A service identifier |
||
695 | * @param Definition $definition A Definition instance |
||
696 | * |
||
697 | * @return string|null |
||
698 | * |
||
699 | * @deprecated since version 2.7, will be removed in 3.0. |
||
700 | */ |
||
701 | private function addServiceSynchronizer($id, Definition $definition) |
||
702 | { |
||
703 | if (!$definition->isSynchronized(false)) { |
||
704 | return; |
||
705 | } |
||
706 | |||
707 | if ('request' !== $id) { |
||
708 | trigger_error('Synchronized services were deprecated in version 2.7 and won\'t work anymore in 3.0.', E_USER_DEPRECATED); |
||
709 | } |
||
710 | |||
711 | $code = ''; |
||
712 | foreach ($this->container->getDefinitions() as $definitionId => $definition) { |
||
713 | foreach ($definition->getMethodCalls() as $call) { |
||
714 | foreach ($call[1] as $argument) { |
||
715 | if ($argument instanceof Reference && $id == (string) $argument) { |
||
716 | $arguments = array(); |
||
717 | foreach ($call[1] as $value) { |
||
718 | $arguments[] = $this->dumpValue($value); |
||
719 | } |
||
720 | |||
721 | $call = $this->wrapServiceConditionals($call[1], sprintf("\$this->get('%s')->%s(%s);", $definitionId, $call[0], implode(', ', $arguments))); |
||
722 | |||
723 | $code .= <<<EOF |
||
724 | if (\$this->initialized('$definitionId')) { |
||
725 | $call |
||
726 | } |
||
727 | |||
728 | EOF; |
||
729 | } |
||
730 | } |
||
731 | } |
||
732 | } |
||
733 | |||
734 | if (!$code) { |
||
735 | return; |
||
736 | } |
||
737 | |||
738 | return <<<EOF |
||
739 | |||
740 | /** |
||
741 | * Updates the '$id' service. |
||
742 | */ |
||
743 | protected function synchronize{$this->camelize($id)}Service() |
||
744 | { |
||
745 | $code } |
||
746 | |||
747 | EOF; |
||
748 | } |
||
749 | |||
750 | private function addNewInstance($id, Definition $definition, $return, $instantiation) |
||
751 | { |
||
752 | $class = $this->dumpValue($definition->getClass()); |
||
753 | |||
754 | $arguments = array(); |
||
755 | foreach ($definition->getArguments() as $value) { |
||
756 | $arguments[] = $this->dumpValue($value); |
||
757 | } |
||
758 | |||
759 | if (null !== $definition->getFactory()) { |
||
760 | $callable = $definition->getFactory(); |
||
761 | if (is_array($callable)) { |
||
762 | if ($callable[0] instanceof Reference |
||
763 | || ($callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0]))) { |
||
764 | return sprintf(" $return{$instantiation}%s->%s(%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? implode(', ', $arguments) : ''); |
||
765 | } |
||
766 | |||
767 | $class = $this->dumpValue($callable[0]); |
||
768 | // If the class is a string we can optimize call_user_func away |
||
769 | View Code Duplication | if (strpos($class, "'") === 0) { |
|
770 | return sprintf(" $return{$instantiation}%s::%s(%s);\n", $this->dumpLiteralClass($class), $callable[1], $arguments ? implode(', ', $arguments) : ''); |
||
771 | } |
||
772 | |||
773 | return sprintf(" $return{$instantiation}call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? ', '.implode(', ', $arguments) : ''); |
||
774 | } |
||
775 | |||
776 | return sprintf(" $return{$instantiation}\\%s(%s);\n", $callable, $arguments ? implode(', ', $arguments) : ''); |
||
777 | } elseif (null !== $definition->getFactoryMethod(false)) { |
||
778 | if (null !== $definition->getFactoryClass(false)) { |
||
779 | $class = $this->dumpValue($definition->getFactoryClass(false)); |
||
780 | |||
781 | // If the class is a string we can optimize call_user_func away |
||
782 | View Code Duplication | if (strpos($class, "'") === 0) { |
|
783 | return sprintf(" $return{$instantiation}%s::%s(%s);\n", $this->dumpLiteralClass($class), $definition->getFactoryMethod(false), $arguments ? implode(', ', $arguments) : ''); |
||
784 | } |
||
785 | |||
786 | return sprintf(" $return{$instantiation}call_user_func(array(%s, '%s')%s);\n", $this->dumpValue($definition->getFactoryClass(false)), $definition->getFactoryMethod(false), $arguments ? ', '.implode(', ', $arguments) : ''); |
||
787 | } |
||
788 | |||
789 | if (null !== $definition->getFactoryService(false)) { |
||
790 | return sprintf(" $return{$instantiation}%s->%s(%s);\n", $this->getServiceCall($definition->getFactoryService(false)), $definition->getFactoryMethod(false), implode(', ', $arguments)); |
||
791 | } |
||
792 | |||
793 | throw new RuntimeException(sprintf('Factory method requires a factory service or factory class in service definition for %s', $id)); |
||
794 | } |
||
795 | |||
796 | if (false !== strpos($class, '$')) { |
||
797 | return sprintf(" \$class = %s;\n\n $return{$instantiation}new \$class(%s);\n", $class, implode(', ', $arguments)); |
||
798 | } |
||
799 | |||
800 | return sprintf(" $return{$instantiation}new %s(%s);\n", $this->dumpLiteralClass($class), implode(', ', $arguments)); |
||
801 | } |
||
802 | |||
803 | /** |
||
804 | * Adds the class headers. |
||
805 | * |
||
806 | * @param string $class Class name |
||
807 | * @param string $baseClass The name of the base class |
||
808 | * @param string $namespace The class namespace |
||
809 | * |
||
810 | * @return string |
||
811 | */ |
||
812 | private function startClass($class, $baseClass, $namespace) |
||
813 | { |
||
814 | $bagClass = $this->container->isFrozen() ? 'use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;' : 'use Symfony\Component\DependencyInjection\ParameterBag\\ParameterBag;'; |
||
815 | $namespaceLine = $namespace ? "namespace $namespace;\n" : ''; |
||
816 | |||
817 | return <<<EOF |
||
818 | <?php |
||
819 | $namespaceLine |
||
820 | use Symfony\Component\DependencyInjection\ContainerInterface; |
||
821 | use Symfony\Component\DependencyInjection\Container; |
||
822 | use Symfony\Component\DependencyInjection\Exception\InactiveScopeException; |
||
823 | use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; |
||
824 | use Symfony\Component\DependencyInjection\Exception\LogicException; |
||
825 | use Symfony\Component\DependencyInjection\Exception\RuntimeException; |
||
826 | $bagClass |
||
827 | |||
828 | /** |
||
829 | * $class. |
||
830 | * |
||
831 | * This class has been auto-generated |
||
832 | * by the Symfony Dependency Injection Component. |
||
833 | */ |
||
834 | class $class extends $baseClass |
||
835 | { |
||
836 | private \$parameters; |
||
837 | private \$targetDirs = array(); |
||
838 | |||
839 | EOF; |
||
840 | } |
||
841 | |||
842 | /** |
||
843 | * Adds the constructor. |
||
844 | * |
||
845 | * @return string |
||
846 | */ |
||
847 | private function addConstructor() |
||
848 | { |
||
849 | $targetDirs = $this->exportTargetDirs(); |
||
850 | $arguments = $this->container->getParameterBag()->all() ? 'new ParameterBag($this->getDefaultParameters())' : null; |
||
851 | |||
852 | $code = <<<EOF |
||
853 | |||
854 | /** |
||
855 | * Constructor. |
||
856 | */ |
||
857 | public function __construct() |
||
858 | {{$targetDirs} |
||
859 | parent::__construct($arguments); |
||
860 | |||
861 | EOF; |
||
862 | |||
863 | View Code Duplication | if (count($scopes = $this->container->getScopes()) > 0) { |
|
864 | $code .= "\n"; |
||
865 | $code .= " \$this->scopes = ".$this->dumpValue($scopes).";\n"; |
||
866 | $code .= " \$this->scopeChildren = ".$this->dumpValue($this->container->getScopeChildren()).";\n"; |
||
867 | } |
||
868 | |||
869 | $code .= $this->addMethodMap(); |
||
870 | $code .= $this->addAliases(); |
||
871 | |||
872 | $code .= <<<EOF |
||
873 | } |
||
874 | |||
875 | EOF; |
||
876 | |||
877 | return $code; |
||
878 | } |
||
879 | |||
880 | /** |
||
881 | * Adds the constructor for a frozen container. |
||
882 | * |
||
883 | * @return string |
||
884 | */ |
||
885 | private function addFrozenConstructor() |
||
886 | { |
||
887 | $targetDirs = $this->exportTargetDirs(); |
||
888 | |||
889 | $code = <<<EOF |
||
890 | |||
891 | /** |
||
892 | * Constructor. |
||
893 | */ |
||
894 | public function __construct() |
||
895 | {{$targetDirs} |
||
896 | EOF; |
||
897 | |||
898 | if ($this->container->getParameterBag()->all()) { |
||
899 | $code .= "\n \$this->parameters = \$this->getDefaultParameters();\n"; |
||
900 | } |
||
901 | |||
902 | $code .= <<<EOF |
||
903 | |||
904 | \$this->services = |
||
905 | \$this->scopedServices = |
||
906 | \$this->scopeStacks = array(); |
||
907 | EOF; |
||
908 | |||
909 | $code .= "\n"; |
||
910 | View Code Duplication | if (count($scopes = $this->container->getScopes()) > 0) { |
|
911 | $code .= " \$this->scopes = ".$this->dumpValue($scopes).";\n"; |
||
912 | $code .= " \$this->scopeChildren = ".$this->dumpValue($this->container->getScopeChildren()).";\n"; |
||
913 | } else { |
||
914 | $code .= " \$this->scopes = array();\n"; |
||
915 | $code .= " \$this->scopeChildren = array();\n"; |
||
916 | } |
||
917 | |||
918 | $code .= $this->addMethodMap(); |
||
919 | $code .= $this->addAliases(); |
||
920 | |||
921 | $code .= <<<EOF |
||
922 | } |
||
923 | |||
924 | EOF; |
||
925 | |||
926 | return $code; |
||
927 | } |
||
928 | |||
929 | /** |
||
930 | * Adds the constructor for a frozen container. |
||
931 | * |
||
932 | * @return string |
||
933 | */ |
||
934 | private function addFrozenCompile() |
||
935 | { |
||
936 | return <<<EOF |
||
937 | |||
938 | /** |
||
939 | * {@inheritdoc} |
||
940 | */ |
||
941 | public function compile() |
||
942 | { |
||
943 | throw new LogicException('You cannot compile a dumped frozen container.'); |
||
944 | } |
||
945 | |||
946 | EOF; |
||
947 | } |
||
948 | |||
949 | /** |
||
950 | * Adds the methodMap property definition. |
||
951 | * |
||
952 | * @return string |
||
953 | */ |
||
954 | private function addMethodMap() |
||
955 | { |
||
956 | if (!$definitions = $this->container->getDefinitions()) { |
||
957 | return ''; |
||
958 | } |
||
959 | |||
960 | $code = " \$this->methodMap = array(\n"; |
||
961 | ksort($definitions); |
||
962 | foreach ($definitions as $id => $definition) { |
||
963 | $code .= ' '.var_export($id, true).' => '.var_export('get'.$this->camelize($id).'Service', true).",\n"; |
||
964 | } |
||
965 | |||
966 | return $code." );\n"; |
||
967 | } |
||
968 | |||
969 | /** |
||
970 | * Adds the aliases property definition. |
||
971 | * |
||
972 | * @return string |
||
973 | */ |
||
974 | private function addAliases() |
||
975 | { |
||
976 | if (!$aliases = $this->container->getAliases()) { |
||
977 | if ($this->container->isFrozen()) { |
||
978 | return "\n \$this->aliases = array();\n"; |
||
979 | } else { |
||
980 | return ''; |
||
981 | } |
||
982 | } |
||
983 | |||
984 | $code = " \$this->aliases = array(\n"; |
||
985 | ksort($aliases); |
||
986 | foreach ($aliases as $alias => $id) { |
||
987 | $id = (string) $id; |
||
988 | while (isset($aliases[$id])) { |
||
989 | $id = (string) $aliases[$id]; |
||
990 | } |
||
991 | $code .= ' '.var_export($alias, true).' => '.var_export($id, true).",\n"; |
||
992 | } |
||
993 | |||
994 | return $code." );\n"; |
||
995 | } |
||
996 | |||
997 | /** |
||
998 | * Adds default parameters method. |
||
999 | * |
||
1000 | * @return string |
||
1001 | */ |
||
1002 | private function addDefaultParametersMethod() |
||
1077 | |||
1078 | /** |
||
1079 | * Exports parameters. |
||
1080 | * |
||
1081 | * @param array $parameters |
||
1082 | * @param string $path |
||
1083 | * @param int $indent |
||
1084 | * |
||
1085 | * @return string |
||
1086 | * |
||
1087 | * @throws InvalidArgumentException |
||
1088 | */ |
||
1089 | private function exportParameters($parameters, $path = '', $indent = 12) |
||
1090 | { |
||
1091 | $php = array(); |
||
1092 | foreach ($parameters as $key => $value) { |
||
1093 | if (is_array($value)) { |
||
1094 | $value = $this->exportParameters($value, $path.'/'.$key, $indent + 4); |
||
1095 | } elseif ($value instanceof Variable) { |
||
1096 | throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain variable references. Variable "%s" found in "%s".', $value, $path.'/'.$key)); |
||
1097 | } elseif ($value instanceof Definition) { |
||
1098 | throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain service definitions. Definition for "%s" found in "%s".', $value->getClass(), $path.'/'.$key)); |
||
1099 | } elseif ($value instanceof Reference) { |
||
1100 | throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain references to other services (reference to service "%s" found in "%s").', $value, $path.'/'.$key)); |
||
1101 | } elseif ($value instanceof Expression) { |
||
1102 | throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain expressions. Expression "%s" found in "%s".', $value, $path.'/'.$key)); |
||
1103 | } else { |
||
1104 | $value = $this->export($value); |
||
1105 | } |
||
1106 | |||
1107 | $php[] = sprintf('%s%s => %s,', str_repeat(' ', $indent), var_export($key, true), $value); |
||
1108 | } |
||
1109 | |||
1110 | return sprintf("array(\n%s\n%s)", implode("\n", $php), str_repeat(' ', $indent - 4)); |
||
1111 | } |
||
1112 | |||
1113 | /** |
||
1114 | * Ends the class definition. |
||
1115 | * |
||
1116 | * @return string |
||
1117 | */ |
||
1118 | private function endClass() |
||
1119 | { |
||
1120 | return <<<EOF |
||
1121 | } |
||
1122 | |||
1123 | EOF; |
||
1124 | } |
||
1125 | |||
1126 | /** |
||
1127 | * Wraps the service conditionals. |
||
1128 | * |
||
1129 | * @param string $value |
||
1130 | * @param string $code |
||
1131 | * |
||
1132 | * @return string |
||
1133 | */ |
||
1134 | private function wrapServiceConditionals($value, $code) |
||
1150 | |||
1151 | /** |
||
1152 | * Builds service calls from arguments. |
||
1153 | * |
||
1154 | * @param array $arguments |
||
1155 | * @param array &$calls By reference |
||
1156 | * @param array &$behavior By reference |
||
1157 | */ |
||
1158 | private function getServiceCallsFromArguments(array $arguments, array &$calls, array &$behavior) |
||
1159 | { |
||
1160 | foreach ($arguments as $argument) { |
||
1161 | if (is_array($argument)) { |
||
1162 | $this->getServiceCallsFromArguments($argument, $calls, $behavior); |
||
1163 | } elseif ($argument instanceof Reference) { |
||
1164 | $id = (string) $argument; |
||
1165 | |||
1166 | if (!isset($calls[$id])) { |
||
1167 | $calls[$id] = 0; |
||
1168 | } |
||
1169 | if (!isset($behavior[$id])) { |
||
1170 | $behavior[$id] = $argument->getInvalidBehavior(); |
||
1171 | } elseif (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $behavior[$id]) { |
||
1172 | $behavior[$id] = $argument->getInvalidBehavior(); |
||
1173 | } |
||
1174 | |||
1175 | ++$calls[$id]; |
||
1176 | } |
||
1177 | } |
||
1178 | } |
||
1179 | |||
1180 | /** |
||
1181 | * Returns the inline definition. |
||
1182 | * |
||
1183 | * @param Definition $definition |
||
1184 | * |
||
1185 | * @return array |
||
1186 | */ |
||
1187 | private function getInlinedDefinitions(Definition $definition) |
||
1188 | { |
||
1189 | if (false === $this->inlinedDefinitions->contains($definition)) { |
||
1190 | $definitions = array_merge( |
||
1191 | $this->getDefinitionsFromArguments($definition->getArguments()), |
||
1192 | $this->getDefinitionsFromArguments($definition->getMethodCalls()), |
||
1193 | $this->getDefinitionsFromArguments($definition->getProperties()), |
||
1194 | $this->getDefinitionsFromArguments(array($definition->getConfigurator())), |
||
1195 | $this->getDefinitionsFromArguments(array($definition->getFactory())) |
||
1196 | ); |
||
1197 | |||
1198 | $this->inlinedDefinitions->offsetSet($definition, $definitions); |
||
1199 | |||
1200 | return $definitions; |
||
1201 | } |
||
1202 | |||
1203 | return $this->inlinedDefinitions->offsetGet($definition); |
||
1204 | } |
||
1205 | |||
1206 | /** |
||
1207 | * Gets the definition from arguments. |
||
1208 | * |
||
1209 | * @param array $arguments |
||
1210 | * |
||
1211 | * @return array |
||
1212 | */ |
||
1213 | private function getDefinitionsFromArguments(array $arguments) |
||
1230 | |||
1231 | /** |
||
1232 | * Checks if a service id has a reference. |
||
1233 | * |
||
1234 | * @param string $id |
||
1235 | * @param array $arguments |
||
1236 | * @param bool $deep |
||
1237 | * @param array $visited |
||
1238 | * |
||
1239 | * @return bool |
||
1240 | */ |
||
1241 | private function hasReference($id, array $arguments, $deep = false, array &$visited = array()) |
||
1242 | { |
||
1243 | foreach ($arguments as $argument) { |
||
1244 | if (is_array($argument)) { |
||
1245 | if ($this->hasReference($id, $argument, $deep, $visited)) { |
||
1246 | return true; |
||
1247 | } |
||
1248 | } elseif ($argument instanceof Reference) { |
||
1249 | $argumentId = (string) $argument; |
||
1250 | if ($id === $argumentId) { |
||
1251 | return true; |
||
1252 | } |
||
1253 | |||
1254 | if ($deep && !isset($visited[$argumentId])) { |
||
1255 | $visited[$argumentId] = true; |
||
1256 | |||
1257 | $service = $this->container->getDefinition($argumentId); |
||
1258 | $arguments = array_merge($service->getMethodCalls(), $service->getArguments(), $service->getProperties()); |
||
1259 | |||
1260 | if ($this->hasReference($id, $arguments, $deep, $visited)) { |
||
1261 | return true; |
||
1262 | } |
||
1263 | } |
||
1264 | } |
||
1265 | } |
||
1266 | |||
1267 | return false; |
||
1268 | } |
||
1269 | |||
1270 | /** |
||
1271 | * Dumps values. |
||
1272 | * |
||
1273 | * @param mixed $value |
||
1274 | * @param bool $interpolate |
||
1275 | * |
||
1276 | * @return string |
||
1277 | * |
||
1278 | * @throws RuntimeException |
||
1279 | */ |
||
1280 | private function dumpValue($value, $interpolate = true) |
||
1281 | { |
||
1282 | if (is_array($value)) { |
||
1283 | $code = array(); |
||
1284 | foreach ($value as $k => $v) { |
||
1285 | $code[] = sprintf('%s => %s', $this->dumpValue($k, $interpolate), $this->dumpValue($v, $interpolate)); |
||
1286 | } |
||
1287 | |||
1288 | return sprintf('array(%s)', implode(', ', $code)); |
||
1289 | } elseif ($value instanceof Definition) { |
||
1290 | if (null !== $this->definitionVariables && $this->definitionVariables->contains($value)) { |
||
1291 | return $this->dumpValue($this->definitionVariables->offsetGet($value), $interpolate); |
||
1292 | } |
||
1293 | if (count($value->getMethodCalls()) > 0) { |
||
1294 | throw new RuntimeException('Cannot dump definitions which have method calls.'); |
||
1295 | } |
||
1296 | if (null !== $value->getConfigurator()) { |
||
1297 | throw new RuntimeException('Cannot dump definitions which have a configurator.'); |
||
1298 | } |
||
1299 | |||
1300 | $arguments = array(); |
||
1301 | foreach ($value->getArguments() as $argument) { |
||
1302 | $arguments[] = $this->dumpValue($argument); |
||
1303 | } |
||
1304 | $class = $this->dumpValue($value->getClass()); |
||
1305 | |||
1306 | if (false !== strpos($class, '$')) { |
||
1307 | throw new RuntimeException('Cannot dump definitions which have a variable class name.'); |
||
1308 | } |
||
1309 | |||
1310 | if (null !== $value->getFactory()) { |
||
1311 | $factory = $value->getFactory(); |
||
1312 | |||
1313 | if (is_string($factory)) { |
||
1314 | return sprintf('\\%s(%s)', $factory, implode(', ', $arguments)); |
||
1315 | } |
||
1316 | |||
1317 | if (is_array($factory)) { |
||
1318 | if (is_string($factory[0])) { |
||
1319 | return sprintf('\\%s::%s(%s)', $factory[0], $factory[1], implode(', ', $arguments)); |
||
1320 | } |
||
1321 | |||
1322 | if ($factory[0] instanceof Definition) { |
||
1323 | return sprintf("call_user_func(array(%s, '%s')%s)", $this->dumpValue($factory[0]), $factory[1], count($arguments) > 0 ? ', '.implode(', ', $arguments) : ''); |
||
1324 | } |
||
1325 | |||
1326 | if ($factory[0] instanceof Reference) { |
||
1327 | return sprintf('%s->%s(%s)', $this->dumpValue($factory[0]), $factory[1], implode(', ', $arguments)); |
||
1328 | } |
||
1329 | } |
||
1330 | |||
1331 | throw new RuntimeException('Cannot dump definition because of invalid factory'); |
||
1332 | } |
||
1333 | |||
1334 | if (null !== $value->getFactoryMethod(false)) { |
||
1335 | if (null !== $value->getFactoryClass(false)) { |
||
1336 | return sprintf("call_user_func(array(%s, '%s')%s)", $this->dumpValue($value->getFactoryClass(false)), $value->getFactoryMethod(false), count($arguments) > 0 ? ', '.implode(', ', $arguments) : ''); |
||
1337 | } elseif (null !== $value->getFactoryService(false)) { |
||
1338 | $service = $this->dumpValue($value->getFactoryService(false)); |
||
1339 | |||
1340 | return sprintf('%s->%s(%s)', 0 === strpos($service, '$') ? sprintf('$this->get(%s)', $service) : $this->getServiceCall($value->getFactoryService(false)), $value->getFactoryMethod(false), implode(', ', $arguments)); |
||
1341 | } else { |
||
1342 | throw new RuntimeException('Cannot dump definitions which have factory method without factory service or factory class.'); |
||
1343 | } |
||
1344 | } |
||
1345 | |||
1346 | return sprintf('new \\%s(%s)', substr(str_replace('\\\\', '\\', $class), 1, -1), implode(', ', $arguments)); |
||
1347 | } elseif ($value instanceof Variable) { |
||
1348 | return '$'.$value; |
||
1349 | } elseif ($value instanceof Reference) { |
||
1350 | if (null !== $this->referenceVariables && isset($this->referenceVariables[$id = (string) $value])) { |
||
1351 | return $this->dumpValue($this->referenceVariables[$id], $interpolate); |
||
1352 | } |
||
1353 | |||
1354 | return $this->getServiceCall((string) $value, $value); |
||
1355 | } elseif ($value instanceof Expression) { |
||
1356 | return $this->getExpressionLanguage()->compile((string) $value, array('this' => 'container')); |
||
1357 | } elseif ($value instanceof Parameter) { |
||
1358 | return $this->dumpParameter($value); |
||
1359 | } elseif (true === $interpolate && is_string($value)) { |
||
1360 | if (preg_match('/^%([^%]+)%$/', $value, $match)) { |
||
1361 | // we do this to deal with non string values (Boolean, integer, ...) |
||
1362 | // the preg_replace_callback converts them to strings |
||
1363 | return $this->dumpParameter(strtolower($match[1])); |
||
1364 | } else { |
||
1365 | $that = $this; |
||
1366 | $replaceParameters = function ($match) use ($that) { |
||
1367 | return "'.".$that->dumpParameter(strtolower($match[2])).".'"; |
||
1368 | }; |
||
1369 | |||
1370 | $code = str_replace('%%', '%', preg_replace_callback('/(?<!%)(%)([^%]+)\1/', $replaceParameters, $this->export($value))); |
||
1371 | |||
1372 | return $code; |
||
1373 | } |
||
1374 | } elseif (is_object($value) || is_resource($value)) { |
||
1375 | throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.'); |
||
1376 | } else { |
||
1377 | return $this->export($value); |
||
1378 | } |
||
1379 | } |
||
1380 | |||
1381 | /** |
||
1382 | * Dumps a string to a literal (aka PHP Code) class value. |
||
1383 | * |
||
1384 | * @param string $class |
||
1385 | * |
||
1386 | * @return string |
||
1387 | */ |
||
1388 | private function dumpLiteralClass($class) |
||
1392 | |||
1393 | /** |
||
1394 | * Dumps a parameter. |
||
1395 | * |
||
1396 | * @param string $name |
||
1397 | * |
||
1398 | * @return string |
||
1399 | */ |
||
1400 | public function dumpParameter($name) |
||
1401 | { |
||
1402 | if ($this->container->isFrozen() && $this->container->hasParameter($name)) { |
||
1403 | return $this->dumpValue($this->container->getParameter($name), false); |
||
1404 | } |
||
1405 | |||
1406 | return sprintf("\$this->getParameter('%s')", strtolower($name)); |
||
1407 | } |
||
1408 | |||
1409 | /** |
||
1410 | * @deprecated since version 2.6.2, to be removed in 3.0. |
||
1411 | * Use \Symfony\Component\DependencyInjection\ContainerBuilder::addExpressionLanguageProvider instead. |
||
1412 | * |
||
1413 | * @param ExpressionFunctionProviderInterface $provider |
||
1414 | */ |
||
1415 | public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider) |
||
1416 | { |
||
1417 | trigger_error('The '.__METHOD__.' method is deprecated since version 2.6.2 and will be removed in 3.0. Use the Symfony\Component\DependencyInjection\ContainerBuilder::addExpressionLanguageProvider method instead.', E_USER_DEPRECATED); |
||
1418 | |||
1419 | $this->expressionLanguageProviders[] = $provider; |
||
1420 | } |
||
1421 | |||
1422 | /** |
||
1423 | * Gets a service call. |
||
1424 | * |
||
1425 | * @param string $id |
||
1426 | * @param Reference $reference |
||
1427 | * |
||
1428 | * @return string |
||
1429 | */ |
||
1430 | private function getServiceCall($id, Reference $reference = null) |
||
1446 | |||
1447 | /** |
||
1448 | * Convert a service id to a valid PHP method name. |
||
1449 | * |
||
1450 | * @param string $id |
||
1451 | * |
||
1452 | * @return string |
||
1453 | * |
||
1454 | * @throws InvalidArgumentException |
||
1455 | */ |
||
1456 | private function camelize($id) |
||
1466 | |||
1467 | /** |
||
1468 | * Returns the next name to use. |
||
1469 | * |
||
1470 | * @return string |
||
1471 | */ |
||
1472 | private function getNextVariableName() |
||
1504 | |||
1505 | private function getExpressionLanguage() |
||
1523 | |||
1524 | private function exportTargetDirs() |
||
1534 | |||
1535 | private function export($value) |
||
1556 | } |
||
1557 |
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.