PluginProbe
Depicter — Popup & Slider Builder / 1.5.2
Depicter — Popup & Slider Builder v1.5.2
4.8.1 trunk 1.0.0 1.1.0 1.1.2 1.1.4 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.5 1.3.8 1.5.0 1.5.1 1.5.2 1.5.5 1.6.0 1.6.1 1.6.2 1.7.0 All 76 releases
depicter / vendor / symfony / service-contracts / ServiceLocatorTrait.php

ServiceLocatorTrait.php in Depicter — Popup & Slider Builder 1.5.2, at vendor/symfony/service-contracts/ServiceLocatorTrait.php

129 lines 3.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <[email protected]>
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\Contracts\Service;
13
14 use Psr\Container\ContainerExceptionInterface;
15 use Psr\Container\NotFoundExceptionInterface;
16
17 // Help opcache.preload discover always-needed symbols
18 class_exists(ContainerExceptionInterface::class);
19 class_exists(NotFoundExceptionInterface::class);
20
21 /**
22 * A trait to help implement ServiceProviderInterface.
23 *
24 * @author Robin Chalas <[email protected]>
25 * @author Nicolas Grekas <[email protected]>
26 */
27 trait ServiceLocatorTrait
28 {
29 private $factories;
30 private $loading = [];
31 private $providedTypes;
32
33 /**
34 * @param callable[] $factories
35 */
36 public function __construct(array $factories)
37 {
38 $this->factories = $factories;
39 }
40
41 /**
42 * {@inheritdoc}
43 *
44 * @return bool
45 */
46 public function has(string $id)
47 {
48 return isset($this->factories[$id]);
49 }
50
51 /**
52 * {@inheritdoc}
53 *
54 * @return mixed
55 */
56 public function get(string $id)
57 {
58 if (!isset($this->factories[$id])) {
59 throw $this->createNotFoundException($id);
60 }
61
62 if (isset($this->loading[$id])) {
63 $ids = array_values($this->loading);
64 $ids = \array_slice($this->loading, array_search($id, $ids));
65 $ids[] = $id;
66
67 throw $this->createCircularReferenceException($id, $ids);
68 }
69
70 $this->loading[$id] = $id;
71 try {
72 return $this->factories[$id]($this);
73 } finally {
74 unset($this->loading[$id]);
75 }
76 }
77
78 /**
79 * {@inheritdoc}
80 */
81 public function getProvidedServices(): array
82 {
83 if (null === $this->providedTypes) {
84 $this->providedTypes = [];
85
86 foreach ($this->factories as $name => $factory) {
87 if (!\is_callable($factory)) {
88 $this->providedTypes[$name] = '?';
89 } else {
90 $type = (new \ReflectionFunction($factory))->getReturnType();
91
92 $this->providedTypes[$name] = $type ? ($type->allowsNull() ? '?' : '').($type instanceof \ReflectionNamedType ? $type->getName() : $type) : '?';
93 }
94 }
95 }
96
97 return $this->providedTypes;
98 }
99
100 private function createNotFoundException(string $id): NotFoundExceptionInterface
101 {
102 if (!$alternatives = array_keys($this->factories)) {
103 $message = 'is empty...';
104 } else {
105 $last = array_pop($alternatives);
106 if ($alternatives) {
107 $message = sprintf('only knows about the "%s" and "%s" services.', implode('", "', $alternatives), $last);
108 } else {
109 $message = sprintf('only knows about the "%s" service.', $last);
110 }
111 }
112
113 if ($this->loading) {
114 $message = sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', end($this->loading), $id, $message);
115 } else {
116 $message = sprintf('Service "%s" not found: the current service locator %s', $id, $message);
117 }
118
119 return new class($message) extends \InvalidArgumentException implements NotFoundExceptionInterface {
120 };
121 }
122
123 private function createCircularReferenceException(string $id, array $path): ContainerExceptionInterface
124 {
125 return new class(sprintf('Circular reference detected for service "%s", path: "%s".', $id, implode(' -> ', $path))) extends \RuntimeException implements ContainerExceptionInterface {
126 };
127 }
128 }
129