PluginProbe
Cookiebot by Usercentrics – Automatic Cookie Banner for GDPR/CCPA & Google Consent Mode / 3.1.0
Cookiebot by Usercentrics – Automatic Cookie Banner for GDPR/CCPA & Google Consent Mode v3.1.0
4.7.3 4.7.2 4.7.1 trunk 2.3.0 2.4.0 2.4.1 2.4.2 2.5.0 3.0.0 3.0.1 3.1.0 3.10.0 3.10.1 3.11.1 3.11.2 3.11.3 3.2.0 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 All 93 releases
cookiebot / addons / lib / ioc / php-di / invoker / src / CallableResolver.php

CallableResolver.php in Cookiebot by Usercentrics – Automatic Cookie Banner for GDPR/CCPA & Google Consent Mode 3.1.0, at addons/lib/ioc/php-di/invoker/src/CallableResolver.php

128 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 namespace Invoker;
4
5 use Interop\Container\ContainerInterface;
6 use Interop\Container\Exception\NotFoundException;
7 use Invoker\Exception\NotCallableException;
8
9 /**
10 * Resolves a callable from a container.
11 *
12 * @author Matthieu Napoli <matthieu@mnapoli.fr>
13 */
14 class CallableResolver
15 {
16 /**
17 * @var ContainerInterface
18 */
19 private $container;
20
21 public function __construct(ContainerInterface $container)
22 {
23 $this->container = $container;
24 }
25
26 /**
27 * Resolve the given callable into a real PHP callable.
28 *
29 * @param callable|string|array $callable
30 *
31 * @return callable Real PHP callable.
32 *
33 * @throws NotCallableException
34 */
35 public function resolve($callable)
36 {
37 if (is_string($callable) && strpos($callable, '::') !== false) {
38 $callable = explode('::', $callable, 2);
39 }
40
41 $callable = $this->resolveFromContainer($callable);
42
43 if (! is_callable($callable)) {
44 throw NotCallableException::fromInvalidCallable($callable, true);
45 }
46
47 return $callable;
48 }
49
50 /**
51 * @param callable|string|array $callable
52 * @return callable
53 * @throws NotCallableException
54 */
55 private function resolveFromContainer($callable)
56 {
57 // Shortcut for a very common use case
58 if ($callable instanceof \Closure) {
59 return $callable;
60 }
61
62 $isStaticCallToNonStaticMethod = false;
63
64 // If it's already a callable there is nothing to do
65 if (is_callable($callable)) {
66 $isStaticCallToNonStaticMethod = $this->isStaticCallToNonStaticMethod($callable);
67 if (! $isStaticCallToNonStaticMethod) {
68 return $callable;
69 }
70 }
71
72 // The callable is a container entry name
73 if (is_string($callable)) {
74 try {
75 return $this->container->get($callable);
76 } catch (NotFoundException $e) {
77 throw NotCallableException::fromInvalidCallable($callable, true);
78 }
79 }
80
81 // The callable is an array whose first item is a container entry name
82 // e.g. ['some-container-entry', 'methodToCall']
83 if (is_array($callable) && is_string($callable[0])) {
84 try {
85 // Replace the container entry name by the actual object
86 $callable[0] = $this->container->get($callable[0]);
87 return $callable;
88 } catch (NotFoundException $e) {
89 if ($isStaticCallToNonStaticMethod) {
90 throw new NotCallableException(sprintf(
91 'Cannot call %s::%s() because %s() is not a static method and "%s" is not a container entry',
92 $callable[0],
93 $callable[1],
94 $callable[1],
95 $callable[0]
96 ));
97 }
98 throw new NotCallableException(sprintf(
99 'Cannot call %s on %s because it is not a class nor a valid container entry',
100 $callable[1],
101 $callable[0]
102 ));
103 }
104 }
105
106 // Unrecognized stuff, we let it fail later
107 return $callable;
108 }
109
110 /**
111 * Check if the callable represents a static call to a non-static method.
112 *
113 * @param mixed $callable
114 * @return bool
115 */
116 private function isStaticCallToNonStaticMethod($callable)
117 {
118 if (is_array($callable) && is_string($callable[0])) {
119 list($class, $method) = $callable;
120 $reflection = new \ReflectionMethod($class, $method);
121
122 return ! $reflection->isStatic();
123 }
124
125 return false;
126 }
127 }
128