Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

ControllerResolver.php

Zuletzt modifiziert: 02.04.2025, 15:03 - Dateigröße: 9.61 KiB


001  <?php
002   
003  /*
004   * This file is part of the Symfony package.
005   *
006   * (c) Fabien Potencier <fabien@symfony.com>
007   *
008   * For the full copyright and license information, please view the LICENSE
009   * file that was distributed with this source code.
010   */
011   
012  namespace Symfony\Component\HttpKernel\Controller;
013   
014  use Psr\Log\LoggerInterface;
015  use Symfony\Component\HttpFoundation\Request;
016   
017  /**
018   * This implementation uses the '_controller' request attribute to determine
019   * the controller to execute and uses the request attributes to determine
020   * the controller method arguments.
021   *
022   * @author Fabien Potencier <fabien@symfony.com>
023   */
024  class ControllerResolver implements ArgumentResolverInterface, ControllerResolverInterface
025  {
026      private $logger;
027   
028      /**
029       * If the ...$arg functionality is available.
030       *
031       * Requires at least PHP 5.6.0 or HHVM 3.9.1
032       *
033       * @var bool
034       */
035      private $supportsVariadic;
036   
037      /**
038       * If scalar types exists.
039       *
040       * @var bool
041       */
042      private $supportsScalarTypes;
043   
044      public function __construct(LoggerInterface $logger = null)
045      {
046          $this->logger = $logger;
047   
048          $this->supportsVariadic = method_exists('ReflectionParameter', 'isVariadic');
049          $this->supportsScalarTypes = method_exists('ReflectionParameter', 'getType');
050      }
051   
052      /**
053       * {@inheritdoc}
054       *
055       * This method looks for a '_controller' request attribute that represents
056       * the controller name (a string like ClassName::MethodName).
057       */
058      public function getController(Request $request)
059      {
060          if (!$controller = $request->attributes->get('_controller')) {
061              if (null !== $this->logger) {
062                  $this->logger->warning('Unable to look for the controller as the "_controller" parameter is missing.');
063              }
064   
065              return false;
066          }
067   
068          if (\is_array($controller)) {
069              return $controller;
070          }
071   
072          if (\is_object($controller)) {
073              if (method_exists($controller, '__invoke')) {
074                  return $controller;
075              }
076   
077              throw new \InvalidArgumentException(sprintf('Controller "%s" for URI "%s" is not callable.', \get_class($controller), $request->getPathInfo()));
078          }
079   
080          if (\is_string($controller) && false === strpos($controller, ':')) {
081              if (method_exists($controller, '__invoke')) {
082                  return $this->instantiateController($controller);
083              } elseif (\function_exists($controller)) {
084                  return $controller;
085              }
086          }
087   
088          try {
089              $callable = $this->createController($controller);
090          } catch (\InvalidArgumentException $e) {
091              throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: ', $request->getPathInfo()).$e->getMessage(), 0, $e);
092          }
093   
094          return $callable;
095      }
096   
097      /**
098       * {@inheritdoc}
099       *
100       * @deprecated This method is deprecated as of 3.1 and will be removed in 4.0. Implement the ArgumentResolverInterface and inject it in the HttpKernel instead.
101       */
102      public function getArguments(Request $request, $controller)
103      {
104          @trigger_error(sprintf('The "%s()" method is deprecated as of 3.1 and will be removed in 4.0. Implement the %s and inject it in the HttpKernel instead.', __METHOD__, ArgumentResolverInterface::class), \E_USER_DEPRECATED);
105   
106          if (\is_array($controller)) {
107              $r = new \ReflectionMethod($controller[0], $controller[1]);
108          } elseif (\is_object($controller) && !$controller instanceof \Closure) {
109              $r = new \ReflectionObject($controller);
110              $r = $r->getMethod('__invoke');
111          } else {
112              $r = new \ReflectionFunction($controller);
113          }
114   
115          return $this->doGetArguments($request, $controller, $r->getParameters());
116      }
117   
118      /**
119       * @param callable               $controller
120       * @param \ReflectionParameter[] $parameters
121       *
122       * @return array The arguments to use when calling the action
123       *
124       * @deprecated This method is deprecated as of 3.1 and will be removed in 4.0. Implement the ArgumentResolverInterface and inject it in the HttpKernel instead.
125       */
126      protected function doGetArguments(Request $request, $controller, array $parameters)
127      {
128          @trigger_error(sprintf('The "%s()" method is deprecated as of 3.1 and will be removed in 4.0. Implement the %s and inject it in the HttpKernel instead.', __METHOD__, ArgumentResolverInterface::class), \E_USER_DEPRECATED);
129   
130          $attributes = $request->attributes->all();
131          $arguments = [];
132          foreach ($parameters as $param) {
133              if (\array_key_exists($param->name, $attributes)) {
134                  if ($this->supportsVariadic && $param->isVariadic() && \is_array($attributes[$param->name])) {
135                      $arguments = array_merge($arguments, array_values($attributes[$param->name]));
136                  } else {
137                      $arguments[] = $attributes[$param->name];
138                  }
139              } elseif ($this->typeMatchesRequestClass($param, $request)) {
140                  $arguments[] = $request;
141              } elseif ($param->isDefaultValueAvailable()) {
142                  $arguments[] = $param->getDefaultValue();
143              } elseif ($this->supportsScalarTypes && $param->hasType() && $param->allowsNull()) {
144                  $arguments[] = null;
145              } else {
146                  if (\is_array($controller)) {
147                      $repr = sprintf('%s::%s()', \get_class($controller[0]), $controller[1]);
148                  } elseif (\is_object($controller)) {
149                      $repr = \get_class($controller);
150                  } else {
151                      $repr = $controller;
152                  }
153   
154                  throw new \RuntimeException(sprintf('Controller "%s" requires that you provide a value for the "$%s" argument (because there is no default value or because there is a non optional argument after this one).', $repr, $param->name));
155              }
156          }
157   
158          return $arguments;
159      }
160   
161      /**
162       * Returns a callable for the given controller.
163       *
164       * @param string $controller A Controller string
165       *
166       * @return callable A PHP callable
167       *
168       * @throws \InvalidArgumentException When the controller cannot be created
169       */
170      protected function createController($controller)
171      {
172          if (false === strpos($controller, '::')) {
173              throw new \InvalidArgumentException(sprintf('Unable to find controller "%s".', $controller));
174          }
175   
176          list($class, $method) = explode('::', $controller, 2);
177   
178          if (!class_exists($class)) {
179              throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class));
180          }
181   
182          $controller = [$this->instantiateController($class), $method];
183   
184          if (!\is_callable($controller)) {
185              throw new \InvalidArgumentException($this->getControllerError($controller));
186          }
187   
188          return $controller;
189      }
190   
191      /**
192       * Returns an instantiated controller.
193       *
194       * @param string $class A class name
195       *
196       * @return object
197       */
198      protected function instantiateController($class)
199      {
200          return new $class();
201      }
202   
203      private function getControllerError($callable)
204      {
205          if (\is_string($callable)) {
206              if (false !== strpos($callable, '::')) {
207                  $callable = explode('::', $callable);
208              }
209   
210              if (class_exists($callable) && !method_exists($callable, '__invoke')) {
211                  return sprintf('Class "%s" does not have a method "__invoke".', $callable);
212              }
213   
214              if (!\function_exists($callable)) {
215                  return sprintf('Function "%s" does not exist.', $callable);
216              }
217          }
218   
219          if (!\is_array($callable)) {
220              return sprintf('Invalid type for controller given, expected string or array, got "%s".', \gettype($callable));
221          }
222   
223          if (2 !== \count($callable)) {
224              return 'Invalid format for controller, expected [controller, method] or controller::method.';
225          }
226   
227          list($controller, $method) = $callable;
228   
229          if (\is_string($controller) && !class_exists($controller)) {
230              return sprintf('Class "%s" does not exist.', $controller);
231          }
232   
233          $className = \is_object($controller) ? \get_class($controller) : $controller;
234   
235          if (method_exists($controller, $method)) {
236              return sprintf('Method "%s" on class "%s" should be public and non-abstract.', $method, $className);
237          }
238   
239          $collection = get_class_methods($controller);
240   
241          $alternatives = [];
242   
243          foreach ($collection as $item) {
244              $lev = levenshtein($method, $item);
245   
246              if ($lev <= \strlen($method) / 3 || false !== strpos($item, $method)) {
247                  $alternatives[] = $item;
248              }
249          }
250   
251          asort($alternatives);
252   
253          $message = sprintf('Expected method "%s" on class "%s"', $method, $className);
254   
255          if (\count($alternatives) > 0) {
256              $message .= sprintf(', did you mean "%s"?', implode('", "', $alternatives));
257          } else {
258              $message .= sprintf('. Available methods: "%s".', implode('", "', $collection));
259          }
260   
261          return $message;
262      }
263   
264      /**
265       * @return bool
266       */
267      private function typeMatchesRequestClass(\ReflectionParameter $param, Request $request)
268      {
269          if (!method_exists($param, 'getType')) {
270              return $param->getClass() && $param->getClass()->isInstance($request);
271          }
272   
273          if (!($type = $param->getType()) || $type->isBuiltin()) {
274              return false;
275          }
276   
277          $class = new \ReflectionClass($type instanceof \ReflectionNamedType ? $type->getName() : (string) $type);
278   
279          return $class && $class->isInstance($request);
280      }
281  }
282