Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / vendor / symfony / dependency-injection / Definition.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\DependencyInjection;
13
14 use Symfony\Component\DependencyInjection\Argument\BoundArgument;
15 use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
16 use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException;
17
18 /**
19  * Definition represents a service definition.
20  *
21  * @author Fabien Potencier <fabien@symfony.com>
22  */
23 class Definition
24 {
25     private $class;
26     private $file;
27     private $factory;
28     private $shared = true;
29     private $deprecated = false;
30     private $deprecationTemplate;
31     private $properties = array();
32     private $calls = array();
33     private $instanceof = array();
34     private $autoconfigured = false;
35     private $configurator;
36     private $tags = array();
37     private $public = true;
38     private $private = true;
39     private $synthetic = false;
40     private $abstract = false;
41     private $lazy = false;
42     private $decoratedService;
43     private $autowired = false;
44     private $autowiringTypes = array();
45     private $changes = array();
46     private $bindings = array();
47     private $errors = array();
48
49     protected $arguments = array();
50
51     private static $defaultDeprecationTemplate = 'The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.';
52
53     /**
54      * @param string|null $class     The service class
55      * @param array       $arguments An array of arguments to pass to the service constructor
56      */
57     public function __construct($class = null, array $arguments = array())
58     {
59         if (null !== $class) {
60             $this->setClass($class);
61         }
62         $this->arguments = $arguments;
63     }
64
65     /**
66      * Returns all changes tracked for the Definition object.
67      *
68      * @return array An array of changes for this Definition
69      */
70     public function getChanges()
71     {
72         return $this->changes;
73     }
74
75     /**
76      * Sets the tracked changes for the Definition object.
77      *
78      * @param array $changes An array of changes for this Definition
79      *
80      * @return $this
81      */
82     public function setChanges(array $changes)
83     {
84         $this->changes = $changes;
85
86         return $this;
87     }
88
89     /**
90      * Sets a factory.
91      *
92      * @param string|array $factory A PHP function or an array containing a class/Reference and a method to call
93      *
94      * @return $this
95      */
96     public function setFactory($factory)
97     {
98         $this->changes['factory'] = true;
99
100         if (\is_string($factory) && false !== strpos($factory, '::')) {
101             $factory = explode('::', $factory, 2);
102         }
103
104         $this->factory = $factory;
105
106         return $this;
107     }
108
109     /**
110      * Gets the factory.
111      *
112      * @return string|array|null The PHP function or an array containing a class/Reference and a method to call
113      */
114     public function getFactory()
115     {
116         return $this->factory;
117     }
118
119     /**
120      * Sets the service that this service is decorating.
121      *
122      * @param string|null $id        The decorated service id, use null to remove decoration
123      * @param string|null $renamedId The new decorated service id
124      * @param int         $priority  The priority of decoration
125      *
126      * @return $this
127      *
128      * @throws InvalidArgumentException in case the decorated service id and the new decorated service id are equals
129      */
130     public function setDecoratedService($id, $renamedId = null, $priority = 0)
131     {
132         if ($renamedId && $id === $renamedId) {
133             throw new InvalidArgumentException(sprintf('The decorated service inner name for "%s" must be different than the service name itself.', $id));
134         }
135
136         $this->changes['decorated_service'] = true;
137
138         if (null === $id) {
139             $this->decoratedService = null;
140         } else {
141             $this->decoratedService = array($id, $renamedId, (int) $priority);
142         }
143
144         return $this;
145     }
146
147     /**
148      * Gets the service that this service is decorating.
149      *
150      * @return array|null An array composed of the decorated service id, the new id for it and the priority of decoration, null if no service is decorated
151      */
152     public function getDecoratedService()
153     {
154         return $this->decoratedService;
155     }
156
157     /**
158      * Sets the service class.
159      *
160      * @param string $class The service class
161      *
162      * @return $this
163      */
164     public function setClass($class)
165     {
166         $this->changes['class'] = true;
167
168         $this->class = $class;
169
170         return $this;
171     }
172
173     /**
174      * Gets the service class.
175      *
176      * @return string|null The service class
177      */
178     public function getClass()
179     {
180         return $this->class;
181     }
182
183     /**
184      * Sets the arguments to pass to the service constructor/factory method.
185      *
186      * @return $this
187      */
188     public function setArguments(array $arguments)
189     {
190         $this->arguments = $arguments;
191
192         return $this;
193     }
194
195     /**
196      * Sets the properties to define when creating the service.
197      *
198      * @return $this
199      */
200     public function setProperties(array $properties)
201     {
202         $this->properties = $properties;
203
204         return $this;
205     }
206
207     /**
208      * Gets the properties to define when creating the service.
209      *
210      * @return array
211      */
212     public function getProperties()
213     {
214         return $this->properties;
215     }
216
217     /**
218      * Sets a specific property.
219      *
220      * @param string $name
221      * @param mixed  $value
222      *
223      * @return $this
224      */
225     public function setProperty($name, $value)
226     {
227         $this->properties[$name] = $value;
228
229         return $this;
230     }
231
232     /**
233      * Adds an argument to pass to the service constructor/factory method.
234      *
235      * @param mixed $argument An argument
236      *
237      * @return $this
238      */
239     public function addArgument($argument)
240     {
241         $this->arguments[] = $argument;
242
243         return $this;
244     }
245
246     /**
247      * Replaces a specific argument.
248      *
249      * @param int|string $index
250      * @param mixed      $argument
251      *
252      * @return $this
253      *
254      * @throws OutOfBoundsException When the replaced argument does not exist
255      */
256     public function replaceArgument($index, $argument)
257     {
258         if (0 === \count($this->arguments)) {
259             throw new OutOfBoundsException('Cannot replace arguments if none have been configured yet.');
260         }
261
262         if (\is_int($index) && ($index < 0 || $index > \count($this->arguments) - 1)) {
263             throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, \count($this->arguments) - 1));
264         }
265
266         if (!array_key_exists($index, $this->arguments)) {
267             throw new OutOfBoundsException(sprintf('The argument "%s" doesn\'t exist.', $index));
268         }
269
270         $this->arguments[$index] = $argument;
271
272         return $this;
273     }
274
275     /**
276      * Sets a specific argument.
277      *
278      * @param int|string $key
279      * @param mixed      $value
280      *
281      * @return $this
282      */
283     public function setArgument($key, $value)
284     {
285         $this->arguments[$key] = $value;
286
287         return $this;
288     }
289
290     /**
291      * Gets the arguments to pass to the service constructor/factory method.
292      *
293      * @return array The array of arguments
294      */
295     public function getArguments()
296     {
297         return $this->arguments;
298     }
299
300     /**
301      * Gets an argument to pass to the service constructor/factory method.
302      *
303      * @param int|string $index
304      *
305      * @return mixed The argument value
306      *
307      * @throws OutOfBoundsException When the argument does not exist
308      */
309     public function getArgument($index)
310     {
311         if (!array_key_exists($index, $this->arguments)) {
312             throw new OutOfBoundsException(sprintf('The argument "%s" doesn\'t exist.', $index));
313         }
314
315         return $this->arguments[$index];
316     }
317
318     /**
319      * Sets the methods to call after service initialization.
320      *
321      * @return $this
322      */
323     public function setMethodCalls(array $calls = array())
324     {
325         $this->calls = array();
326         foreach ($calls as $call) {
327             $this->addMethodCall($call[0], $call[1]);
328         }
329
330         return $this;
331     }
332
333     /**
334      * Adds a method to call after service initialization.
335      *
336      * @param string $method    The method name to call
337      * @param array  $arguments An array of arguments to pass to the method call
338      *
339      * @return $this
340      *
341      * @throws InvalidArgumentException on empty $method param
342      */
343     public function addMethodCall($method, array $arguments = array())
344     {
345         if (empty($method)) {
346             throw new InvalidArgumentException('Method name cannot be empty.');
347         }
348         $this->calls[] = array($method, $arguments);
349
350         return $this;
351     }
352
353     /**
354      * Removes a method to call after service initialization.
355      *
356      * @param string $method The method name to remove
357      *
358      * @return $this
359      */
360     public function removeMethodCall($method)
361     {
362         foreach ($this->calls as $i => $call) {
363             if ($call[0] === $method) {
364                 unset($this->calls[$i]);
365                 break;
366             }
367         }
368
369         return $this;
370     }
371
372     /**
373      * Check if the current definition has a given method to call after service initialization.
374      *
375      * @param string $method The method name to search for
376      *
377      * @return bool
378      */
379     public function hasMethodCall($method)
380     {
381         foreach ($this->calls as $call) {
382             if ($call[0] === $method) {
383                 return true;
384             }
385         }
386
387         return false;
388     }
389
390     /**
391      * Gets the methods to call after service initialization.
392      *
393      * @return array An array of method calls
394      */
395     public function getMethodCalls()
396     {
397         return $this->calls;
398     }
399
400     /**
401      * Sets the definition templates to conditionally apply on the current definition, keyed by parent interface/class.
402      *
403      * @param $instanceof ChildDefinition[]
404      *
405      * @return $this
406      */
407     public function setInstanceofConditionals(array $instanceof)
408     {
409         $this->instanceof = $instanceof;
410
411         return $this;
412     }
413
414     /**
415      * Gets the definition templates to conditionally apply on the current definition, keyed by parent interface/class.
416      *
417      * @return ChildDefinition[]
418      */
419     public function getInstanceofConditionals()
420     {
421         return $this->instanceof;
422     }
423
424     /**
425      * Sets whether or not instanceof conditionals should be prepended with a global set.
426      *
427      * @param bool $autoconfigured
428      *
429      * @return $this
430      */
431     public function setAutoconfigured($autoconfigured)
432     {
433         $this->changes['autoconfigured'] = true;
434
435         $this->autoconfigured = $autoconfigured;
436
437         return $this;
438     }
439
440     /**
441      * @return bool
442      */
443     public function isAutoconfigured()
444     {
445         return $this->autoconfigured;
446     }
447
448     /**
449      * Sets tags for this definition.
450      *
451      * @return $this
452      */
453     public function setTags(array $tags)
454     {
455         $this->tags = $tags;
456
457         return $this;
458     }
459
460     /**
461      * Returns all tags.
462      *
463      * @return array An array of tags
464      */
465     public function getTags()
466     {
467         return $this->tags;
468     }
469
470     /**
471      * Gets a tag by name.
472      *
473      * @param string $name The tag name
474      *
475      * @return array An array of attributes
476      */
477     public function getTag($name)
478     {
479         return isset($this->tags[$name]) ? $this->tags[$name] : array();
480     }
481
482     /**
483      * Adds a tag for this definition.
484      *
485      * @param string $name       The tag name
486      * @param array  $attributes An array of attributes
487      *
488      * @return $this
489      */
490     public function addTag($name, array $attributes = array())
491     {
492         $this->tags[$name][] = $attributes;
493
494         return $this;
495     }
496
497     /**
498      * Whether this definition has a tag with the given name.
499      *
500      * @param string $name
501      *
502      * @return bool
503      */
504     public function hasTag($name)
505     {
506         return isset($this->tags[$name]);
507     }
508
509     /**
510      * Clears all tags for a given name.
511      *
512      * @param string $name The tag name
513      *
514      * @return $this
515      */
516     public function clearTag($name)
517     {
518         unset($this->tags[$name]);
519
520         return $this;
521     }
522
523     /**
524      * Clears the tags for this definition.
525      *
526      * @return $this
527      */
528     public function clearTags()
529     {
530         $this->tags = array();
531
532         return $this;
533     }
534
535     /**
536      * Sets a file to require before creating the service.
537      *
538      * @param string $file A full pathname to include
539      *
540      * @return $this
541      */
542     public function setFile($file)
543     {
544         $this->changes['file'] = true;
545
546         $this->file = $file;
547
548         return $this;
549     }
550
551     /**
552      * Gets the file to require before creating the service.
553      *
554      * @return string|null The full pathname to include
555      */
556     public function getFile()
557     {
558         return $this->file;
559     }
560
561     /**
562      * Sets if the service must be shared or not.
563      *
564      * @param bool $shared Whether the service must be shared or not
565      *
566      * @return $this
567      */
568     public function setShared($shared)
569     {
570         $this->changes['shared'] = true;
571
572         $this->shared = (bool) $shared;
573
574         return $this;
575     }
576
577     /**
578      * Whether this service is shared.
579      *
580      * @return bool
581      */
582     public function isShared()
583     {
584         return $this->shared;
585     }
586
587     /**
588      * Sets the visibility of this service.
589      *
590      * @param bool $boolean
591      *
592      * @return $this
593      */
594     public function setPublic($boolean)
595     {
596         $this->changes['public'] = true;
597
598         $this->public = (bool) $boolean;
599         $this->private = false;
600
601         return $this;
602     }
603
604     /**
605      * Whether this service is public facing.
606      *
607      * @return bool
608      */
609     public function isPublic()
610     {
611         return $this->public;
612     }
613
614     /**
615      * Sets if this service is private.
616      *
617      * When set, the "private" state has a higher precedence than "public".
618      * In version 3.4, a "private" service always remains publicly accessible,
619      * but triggers a deprecation notice when accessed from the container,
620      * so that the service can be made really private in 4.0.
621      *
622      * @param bool $boolean
623      *
624      * @return $this
625      */
626     public function setPrivate($boolean)
627     {
628         $this->private = (bool) $boolean;
629
630         return $this;
631     }
632
633     /**
634      * Whether this service is private.
635      *
636      * @return bool
637      */
638     public function isPrivate()
639     {
640         return $this->private;
641     }
642
643     /**
644      * Sets the lazy flag of this service.
645      *
646      * @param bool $lazy
647      *
648      * @return $this
649      */
650     public function setLazy($lazy)
651     {
652         $this->changes['lazy'] = true;
653
654         $this->lazy = (bool) $lazy;
655
656         return $this;
657     }
658
659     /**
660      * Whether this service is lazy.
661      *
662      * @return bool
663      */
664     public function isLazy()
665     {
666         return $this->lazy;
667     }
668
669     /**
670      * Sets whether this definition is synthetic, that is not constructed by the
671      * container, but dynamically injected.
672      *
673      * @param bool $boolean
674      *
675      * @return $this
676      */
677     public function setSynthetic($boolean)
678     {
679         $this->synthetic = (bool) $boolean;
680
681         return $this;
682     }
683
684     /**
685      * Whether this definition is synthetic, that is not constructed by the
686      * container, but dynamically injected.
687      *
688      * @return bool
689      */
690     public function isSynthetic()
691     {
692         return $this->synthetic;
693     }
694
695     /**
696      * Whether this definition is abstract, that means it merely serves as a
697      * template for other definitions.
698      *
699      * @param bool $boolean
700      *
701      * @return $this
702      */
703     public function setAbstract($boolean)
704     {
705         $this->abstract = (bool) $boolean;
706
707         return $this;
708     }
709
710     /**
711      * Whether this definition is abstract, that means it merely serves as a
712      * template for other definitions.
713      *
714      * @return bool
715      */
716     public function isAbstract()
717     {
718         return $this->abstract;
719     }
720
721     /**
722      * Whether this definition is deprecated, that means it should not be called
723      * anymore.
724      *
725      * @param bool   $status
726      * @param string $template Template message to use if the definition is deprecated
727      *
728      * @return $this
729      *
730      * @throws InvalidArgumentException when the message template is invalid
731      */
732     public function setDeprecated($status = true, $template = null)
733     {
734         if (null !== $template) {
735             if (preg_match('#[\r\n]|\*/#', $template)) {
736                 throw new InvalidArgumentException('Invalid characters found in deprecation template.');
737             }
738
739             if (false === strpos($template, '%service_id%')) {
740                 throw new InvalidArgumentException('The deprecation template must contain the "%service_id%" placeholder.');
741             }
742
743             $this->deprecationTemplate = $template;
744         }
745
746         $this->changes['deprecated'] = true;
747
748         $this->deprecated = (bool) $status;
749
750         return $this;
751     }
752
753     /**
754      * Whether this definition is deprecated, that means it should not be called
755      * anymore.
756      *
757      * @return bool
758      */
759     public function isDeprecated()
760     {
761         return $this->deprecated;
762     }
763
764     /**
765      * Message to use if this definition is deprecated.
766      *
767      * @param string $id Service id relying on this definition
768      *
769      * @return string
770      */
771     public function getDeprecationMessage($id)
772     {
773         return str_replace('%service_id%', $id, $this->deprecationTemplate ?: self::$defaultDeprecationTemplate);
774     }
775
776     /**
777      * Sets a configurator to call after the service is fully initialized.
778      *
779      * @param string|array $configurator A PHP callable
780      *
781      * @return $this
782      */
783     public function setConfigurator($configurator)
784     {
785         $this->changes['configurator'] = true;
786
787         if (\is_string($configurator) && false !== strpos($configurator, '::')) {
788             $configurator = explode('::', $configurator, 2);
789         }
790
791         $this->configurator = $configurator;
792
793         return $this;
794     }
795
796     /**
797      * Gets the configurator to call after the service is fully initialized.
798      *
799      * @return callable|null The PHP callable to call
800      */
801     public function getConfigurator()
802     {
803         return $this->configurator;
804     }
805
806     /**
807      * Sets types that will default to this definition.
808      *
809      * @param string[] $types
810      *
811      * @return $this
812      *
813      * @deprecated since version 3.3, to be removed in 4.0.
814      */
815     public function setAutowiringTypes(array $types)
816     {
817         @trigger_error('Autowiring-types are deprecated since Symfony 3.3 and will be removed in 4.0. Use aliases instead.', E_USER_DEPRECATED);
818
819         $this->autowiringTypes = array();
820
821         foreach ($types as $type) {
822             $this->autowiringTypes[$type] = true;
823         }
824
825         return $this;
826     }
827
828     /**
829      * Is the definition autowired?
830      *
831      * @return bool
832      */
833     public function isAutowired()
834     {
835         return $this->autowired;
836     }
837
838     /**
839      * Enables/disables autowiring.
840      *
841      * @param bool $autowired
842      *
843      * @return $this
844      */
845     public function setAutowired($autowired)
846     {
847         $this->changes['autowired'] = true;
848
849         $this->autowired = (bool) $autowired;
850
851         return $this;
852     }
853
854     /**
855      * Gets autowiring types that will default to this definition.
856      *
857      * @return string[]
858      *
859      * @deprecated since version 3.3, to be removed in 4.0.
860      */
861     public function getAutowiringTypes(/*$triggerDeprecation = true*/)
862     {
863         if (1 > \func_num_args() || func_get_arg(0)) {
864             @trigger_error('Autowiring-types are deprecated since Symfony 3.3 and will be removed in 4.0. Use aliases instead.', E_USER_DEPRECATED);
865         }
866
867         return array_keys($this->autowiringTypes);
868     }
869
870     /**
871      * Adds a type that will default to this definition.
872      *
873      * @param string $type
874      *
875      * @return $this
876      *
877      * @deprecated since version 3.3, to be removed in 4.0.
878      */
879     public function addAutowiringType($type)
880     {
881         @trigger_error(sprintf('Autowiring-types are deprecated since Symfony 3.3 and will be removed in 4.0. Use aliases instead for "%s".', $type), E_USER_DEPRECATED);
882
883         $this->autowiringTypes[$type] = true;
884
885         return $this;
886     }
887
888     /**
889      * Removes a type.
890      *
891      * @param string $type
892      *
893      * @return $this
894      *
895      * @deprecated since version 3.3, to be removed in 4.0.
896      */
897     public function removeAutowiringType($type)
898     {
899         @trigger_error(sprintf('Autowiring-types are deprecated since Symfony 3.3 and will be removed in 4.0. Use aliases instead for "%s".', $type), E_USER_DEPRECATED);
900
901         unset($this->autowiringTypes[$type]);
902
903         return $this;
904     }
905
906     /**
907      * Will this definition default for the given type?
908      *
909      * @param string $type
910      *
911      * @return bool
912      *
913      * @deprecated since version 3.3, to be removed in 4.0.
914      */
915     public function hasAutowiringType($type)
916     {
917         @trigger_error(sprintf('Autowiring-types are deprecated since Symfony 3.3 and will be removed in 4.0. Use aliases instead for "%s".', $type), E_USER_DEPRECATED);
918
919         return isset($this->autowiringTypes[$type]);
920     }
921
922     /**
923      * Gets bindings.
924      *
925      * @return array
926      */
927     public function getBindings()
928     {
929         return $this->bindings;
930     }
931
932     /**
933      * Sets bindings.
934      *
935      * Bindings map $named or FQCN arguments to values that should be
936      * injected in the matching parameters (of the constructor, of methods
937      * called and of controller actions).
938      *
939      * @param array $bindings
940      *
941      * @return $this
942      */
943     public function setBindings(array $bindings)
944     {
945         foreach ($bindings as $key => $binding) {
946             if (!$binding instanceof BoundArgument) {
947                 $bindings[$key] = new BoundArgument($binding);
948             }
949         }
950
951         $this->bindings = $bindings;
952
953         return $this;
954     }
955
956     /**
957      * Add an error that occurred when building this Definition.
958      *
959      * @param string $error
960      */
961     public function addError($error)
962     {
963         $this->errors[] = $error;
964     }
965
966     /**
967      * Returns any errors that occurred while building this Definition.
968      *
969      * @return array
970      */
971     public function getErrors()
972     {
973         return $this->errors;
974     }
975 }