PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / trunk
Matomo Analytics – Powerful, Privacy-First Insights for WordPress vtrunk
5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / vendor / prefixed / symfony / http-kernel / Controller / ControllerResolver.php
matomo / app / vendor / prefixed / symfony / http-kernel / Controller Last commit date
ArgumentResolver 1 year ago ArgumentResolver.php 1 year ago ArgumentResolverInterface.php 2 years ago ArgumentValueResolverInterface.php 2 years ago ContainerControllerResolver.php 2 years ago ControllerReference.php 2 years ago ControllerResolver.php 1 year ago ControllerResolverInterface.php 2 years ago ErrorController.php 1 year ago TraceableArgumentResolver.php 2 years ago TraceableControllerResolver.php 2 years ago
ControllerResolver.php
178 lines
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 namespace Matomo\Dependencies\Symfony\Component\HttpKernel\Controller;
12
13 use Matomo\Dependencies\Psr\Log\LoggerInterface;
14 use Matomo\Dependencies\Symfony\Component\HttpFoundation\Request;
15 /**
16 * This implementation uses the '_controller' request attribute to determine
17 * the controller to execute.
18 *
19 * @author Fabien Potencier <fabien@symfony.com>
20 * @author Tobias Schultze <http://tobion.de>
21 */
22 class ControllerResolver implements ControllerResolverInterface
23 {
24 private $logger;
25 public function __construct(?LoggerInterface $logger = null)
26 {
27 $this->logger = $logger;
28 }
29 /**
30 * {@inheritdoc}
31 */
32 public function getController(Request $request)
33 {
34 if (!($controller = $request->attributes->get('_controller'))) {
35 if (null !== $this->logger) {
36 $this->logger->warning('Unable to look for the controller as the "_controller" parameter is missing.');
37 }
38 return \false;
39 }
40 if (\is_array($controller)) {
41 if (isset($controller[0]) && \is_string($controller[0]) && isset($controller[1])) {
42 try {
43 $controller[0] = $this->instantiateController($controller[0]);
44 } catch (\Error|\LogicException $e) {
45 try {
46 // We cannot just check is_callable but have to use reflection because a non-static method
47 // can still be called statically in PHP but we don't want that. This is deprecated in PHP 7, so we
48 // could simplify this with PHP 8.
49 if ((new \ReflectionMethod($controller[0], $controller[1]))->isStatic()) {
50 return $controller;
51 }
52 } catch (\ReflectionException $reflectionException) {
53 throw $e;
54 }
55 throw $e;
56 }
57 }
58 if (!\is_callable($controller)) {
59 throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: ', $request->getPathInfo()) . $this->getControllerError($controller));
60 }
61 return $controller;
62 }
63 if (\is_object($controller)) {
64 if (!\is_callable($controller)) {
65 throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: ', $request->getPathInfo()) . $this->getControllerError($controller));
66 }
67 return $controller;
68 }
69 if (\function_exists($controller)) {
70 return $controller;
71 }
72 try {
73 $callable = $this->createController($controller);
74 } catch (\InvalidArgumentException $e) {
75 throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: ', $request->getPathInfo()) . $e->getMessage(), 0, $e);
76 }
77 if (!\is_callable($callable)) {
78 throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: ', $request->getPathInfo()) . $this->getControllerError($callable));
79 }
80 return $callable;
81 }
82 /**
83 * Returns a callable for the given controller.
84 *
85 * @return callable
86 *
87 * @throws \InvalidArgumentException When the controller cannot be created
88 */
89 protected function createController(string $controller)
90 {
91 if (!str_contains($controller, '::')) {
92 $controller = $this->instantiateController($controller);
93 if (!\is_callable($controller)) {
94 throw new \InvalidArgumentException($this->getControllerError($controller));
95 }
96 return $controller;
97 }
98 [$class, $method] = explode('::', $controller, 2);
99 try {
100 $controller = [$this->instantiateController($class), $method];
101 } catch (\Error|\LogicException $e) {
102 try {
103 if ((new \ReflectionMethod($class, $method))->isStatic()) {
104 return $class . '::' . $method;
105 }
106 } catch (\ReflectionException $reflectionException) {
107 throw $e;
108 }
109 throw $e;
110 }
111 if (!\is_callable($controller)) {
112 throw new \InvalidArgumentException($this->getControllerError($controller));
113 }
114 return $controller;
115 }
116 /**
117 * Returns an instantiated controller.
118 *
119 * @return object
120 */
121 protected function instantiateController(string $class)
122 {
123 return new $class();
124 }
125 private function getControllerError($callable) : string
126 {
127 if (\is_string($callable)) {
128 if (str_contains($callable, '::')) {
129 $callable = explode('::', $callable, 2);
130 } else {
131 return sprintf('Function "%s" does not exist.', $callable);
132 }
133 }
134 if (\is_object($callable)) {
135 $availableMethods = $this->getClassMethodsWithoutMagicMethods($callable);
136 $alternativeMsg = $availableMethods ? sprintf(' or use one of the available methods: "%s"', implode('", "', $availableMethods)) : '';
137 return sprintf('Controller class "%s" cannot be called without a method name. You need to implement "__invoke"%s.', get_debug_type($callable), $alternativeMsg);
138 }
139 if (!\is_array($callable)) {
140 return sprintf('Invalid type for controller given, expected string, array or object, got "%s".', get_debug_type($callable));
141 }
142 if (!isset($callable[0]) || !isset($callable[1]) || 2 !== \count($callable)) {
143 return 'Invalid array callable, expected [controller, method].';
144 }
145 [$controller, $method] = $callable;
146 if (\is_string($controller) && !class_exists($controller)) {
147 return sprintf('Class "%s" does not exist.', $controller);
148 }
149 $className = \is_object($controller) ? get_debug_type($controller) : $controller;
150 if (method_exists($controller, $method)) {
151 return sprintf('Method "%s" on class "%s" should be public and non-abstract.', $method, $className);
152 }
153 $collection = $this->getClassMethodsWithoutMagicMethods($controller);
154 $alternatives = [];
155 foreach ($collection as $item) {
156 $lev = levenshtein($method, $item);
157 if ($lev <= \strlen($method) / 3 || str_contains($item, $method)) {
158 $alternatives[] = $item;
159 }
160 }
161 asort($alternatives);
162 $message = sprintf('Expected method "%s" on class "%s"', $method, $className);
163 if (\count($alternatives) > 0) {
164 $message .= sprintf(', did you mean "%s"?', implode('", "', $alternatives));
165 } else {
166 $message .= sprintf('. Available methods: "%s".', implode('", "', $collection));
167 }
168 return $message;
169 }
170 private function getClassMethodsWithoutMagicMethods($classOrObject) : array
171 {
172 $methods = get_class_methods($classOrObject);
173 return array_filter($methods, function (string $method) {
174 return 0 !== strncmp($method, '__', 2);
175 });
176 }
177 }
178