[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
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\HttpKernel\Controller; 13 14 use Psr\Log\LoggerInterface; 15 use Symfony\Component\HttpFoundation\Request; 16 17 /** 18 * This implementation uses the '_controller' request attribute to determine 19 * the controller to execute and uses the request attributes to determine 20 * the controller method arguments. 21 * 22 * @author Fabien Potencier <fabien@symfony.com> 23 */ 24 class ControllerResolver implements ArgumentResolverInterface, ControllerResolverInterface 25 { 26 private $logger; 27 28 /** 29 * If the ...$arg functionality is available. 30 * 31 * Requires at least PHP 5.6.0 or HHVM 3.9.1 32 * 33 * @var bool 34 */ 35 private $supportsVariadic; 36 37 /** 38 * If scalar types exists. 39 * 40 * @var bool 41 */ 42 private $supportsScalarTypes; 43 44 public function __construct(LoggerInterface $logger = null) 45 { 46 $this->logger = $logger; 47 48 $this->supportsVariadic = method_exists('ReflectionParameter', 'isVariadic'); 49 $this->supportsScalarTypes = method_exists('ReflectionParameter', 'getType'); 50 } 51 52 /** 53 * {@inheritdoc} 54 * 55 * This method looks for a '_controller' request attribute that represents 56 * the controller name (a string like ClassName::MethodName). 57 */ 58 public function getController(Request $request) 59 { 60 if (!$controller = $request->attributes->get('_controller')) { 61 if (null !== $this->logger) { 62 $this->logger->warning('Unable to look for the controller as the "_controller" parameter is missing.'); 63 } 64 65 return false; 66 } 67 68 if (\is_array($controller)) { 69 return $controller; 70 } 71 72 if (\is_object($controller)) { 73 if (method_exists($controller, '__invoke')) { 74 return $controller; 75 } 76 77 throw new \InvalidArgumentException(sprintf('Controller "%s" for URI "%s" is not callable.', \get_class($controller), $request->getPathInfo())); 78 } 79 80 if (\is_string($controller) && false === strpos($controller, ':')) { 81 if (method_exists($controller, '__invoke')) { 82 return $this->instantiateController($controller); 83 } elseif (\function_exists($controller)) { 84 return $controller; 85 } 86 } 87 88 try { 89 $callable = $this->createController($controller); 90 } catch (\InvalidArgumentException $e) { 91 throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: ', $request->getPathInfo()).$e->getMessage(), 0, $e); 92 } 93 94 return $callable; 95 } 96 97 /** 98 * {@inheritdoc} 99 * 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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |