PageRenderTime 25ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/slim/slim/Slim/Route.php

https://gitlab.com/ramos.lauty/softlord
PHP | 357 lines | 148 code | 37 blank | 172 comment | 11 complexity | bfbcf392817c0b86b5f8f7c36e3938ce MD5 | raw file
  1. <?php
  2. /**
  3. * Slim Framework (http://slimframework.com)
  4. *
  5. * @link https://github.com/slimphp/Slim
  6. * @copyright Copyright (c) 2011-2016 Josh Lockhart
  7. * @license https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
  8. */
  9. namespace Slim;
  10. use Exception;
  11. use InvalidArgumentException;
  12. use Psr\Http\Message\ServerRequestInterface;
  13. use Psr\Http\Message\ResponseInterface;
  14. use Slim\Handlers\Strategies\RequestResponse;
  15. use Slim\Interfaces\InvocationStrategyInterface;
  16. use Slim\Interfaces\RouteInterface;
  17. /**
  18. * Route
  19. */
  20. class Route extends Routable implements RouteInterface
  21. {
  22. use MiddlewareAwareTrait;
  23. /**
  24. * HTTP methods supported by this route
  25. *
  26. * @var string[]
  27. */
  28. protected $methods = [];
  29. /**
  30. * Route identifier
  31. *
  32. * @var string
  33. */
  34. protected $identifier;
  35. /**
  36. * Route name
  37. *
  38. * @var null|string
  39. */
  40. protected $name;
  41. /**
  42. * Parent route groups
  43. *
  44. * @var RouteGroup[]
  45. */
  46. protected $groups;
  47. private $finalized = false;
  48. /**
  49. * Output buffering mode
  50. *
  51. * One of: false, 'prepend' or 'append'
  52. *
  53. * @var boolean|string
  54. */
  55. protected $outputBuffering = 'append';
  56. /**
  57. * Route parameters
  58. *
  59. * @var array
  60. */
  61. protected $arguments = [];
  62. /**
  63. * Create new route
  64. *
  65. * @param string|string[] $methods The route HTTP methods
  66. * @param string $pattern The route pattern
  67. * @param callable $callable The route callable
  68. * @param RouteGroup[] $groups The parent route groups
  69. * @param int $identifier The route identifier
  70. */
  71. public function __construct($methods, $pattern, $callable, $groups = [], $identifier = 0)
  72. {
  73. $this->methods = is_string($methods) ? [$methods] : $methods;
  74. $this->pattern = $pattern;
  75. $this->callable = $callable;
  76. $this->groups = $groups;
  77. $this->identifier = 'route' . $identifier;
  78. }
  79. /**
  80. * Finalize the route in preparation for dispatching
  81. */
  82. public function finalize()
  83. {
  84. if ($this->finalized) {
  85. return;
  86. }
  87. $groupMiddleware = [];
  88. foreach ($this->getGroups() as $group) {
  89. $groupMiddleware = array_merge($group->getMiddleware(), $groupMiddleware);
  90. }
  91. $this->middleware = array_merge($this->middleware, $groupMiddleware);
  92. foreach ($this->getMiddleware() as $middleware) {
  93. $this->addMiddleware($middleware);
  94. }
  95. $this->finalized = true;
  96. }
  97. /**
  98. * Get route callable
  99. *
  100. * @return callable
  101. */
  102. public function getCallable()
  103. {
  104. return $this->callable;
  105. }
  106. /**
  107. * Get route methods
  108. *
  109. * @return string[]
  110. */
  111. public function getMethods()
  112. {
  113. return $this->methods;
  114. }
  115. /**
  116. * Get parent route groups
  117. *
  118. * @return RouteGroup[]
  119. */
  120. public function getGroups()
  121. {
  122. return $this->groups;
  123. }
  124. /**
  125. * Get route name
  126. *
  127. * @return null|string
  128. */
  129. public function getName()
  130. {
  131. return $this->name;
  132. }
  133. /**
  134. * Get route identifier
  135. *
  136. * @return string
  137. */
  138. public function getIdentifier()
  139. {
  140. return $this->identifier;
  141. }
  142. /**
  143. * Get output buffering mode
  144. *
  145. * @return boolean|string
  146. */
  147. public function getOutputBuffering()
  148. {
  149. return $this->outputBuffering;
  150. }
  151. /**
  152. * Set output buffering mode
  153. *
  154. * One of: false, 'prepend' or 'append'
  155. *
  156. * @param boolean|string $mode
  157. *
  158. * @throws InvalidArgumentException If an unknown buffering mode is specified
  159. */
  160. public function setOutputBuffering($mode)
  161. {
  162. if (!in_array($mode, [false, 'prepend', 'append'], true)) {
  163. throw new InvalidArgumentException('Unknown output buffering mode');
  164. }
  165. $this->outputBuffering = $mode;
  166. }
  167. /**
  168. * Set route name
  169. *
  170. * @param string $name
  171. *
  172. * @return self
  173. *
  174. * @throws InvalidArgumentException if the route name is not a string
  175. */
  176. public function setName($name)
  177. {
  178. if (!is_string($name)) {
  179. throw new InvalidArgumentException('Route name must be a string');
  180. }
  181. $this->name = $name;
  182. return $this;
  183. }
  184. /**
  185. * Set a route argument
  186. *
  187. * @param string $name
  188. * @param string $value
  189. *
  190. * @return self
  191. */
  192. public function setArgument($name, $value)
  193. {
  194. $this->arguments[$name] = $value;
  195. return $this;
  196. }
  197. /**
  198. * Replace route arguments
  199. *
  200. * @param array $arguments
  201. *
  202. * @return self
  203. */
  204. public function setArguments(array $arguments)
  205. {
  206. $this->arguments = $arguments;
  207. return $this;
  208. }
  209. /**
  210. * Retrieve route arguments
  211. *
  212. * @return array
  213. */
  214. public function getArguments()
  215. {
  216. return $this->arguments;
  217. }
  218. /**
  219. * Retrieve a specific route argument
  220. *
  221. * @param string $name
  222. * @param mixed $default
  223. *
  224. * @return mixed
  225. */
  226. public function getArgument($name, $default = null)
  227. {
  228. if (array_key_exists($name, $this->arguments)) {
  229. return $this->arguments[$name];
  230. }
  231. return $default;
  232. }
  233. /********************************************************************************
  234. * Route Runner
  235. *******************************************************************************/
  236. /**
  237. * Prepare the route for use
  238. *
  239. * @param ServerRequestInterface $request
  240. * @param array $arguments
  241. */
  242. public function prepare(ServerRequestInterface $request, array $arguments)
  243. {
  244. // Add the arguments
  245. foreach ($arguments as $k => $v) {
  246. $this->setArgument($k, $v);
  247. }
  248. }
  249. /**
  250. * Run route
  251. *
  252. * This method traverses the middleware stack, including the route's callable
  253. * and captures the resultant HTTP response object. It then sends the response
  254. * back to the Application.
  255. *
  256. * @param ServerRequestInterface $request
  257. * @param ResponseInterface $response
  258. *
  259. * @return ResponseInterface
  260. */
  261. public function run(ServerRequestInterface $request, ResponseInterface $response)
  262. {
  263. // Finalise route now that we are about to run it
  264. $this->finalize();
  265. // Traverse middleware stack and fetch updated response
  266. return $this->callMiddlewareStack($request, $response);
  267. }
  268. /**
  269. * Dispatch route callable against current Request and Response objects
  270. *
  271. * This method invokes the route object's callable. If middleware is
  272. * registered for the route, each callable middleware is invoked in
  273. * the order specified.
  274. *
  275. * @param ServerRequestInterface $request The current Request object
  276. * @param ResponseInterface $response The current Response object
  277. * @return \Psr\Http\Message\ResponseInterface
  278. * @throws \Exception if the route callable throws an exception
  279. */
  280. public function __invoke(ServerRequestInterface $request, ResponseInterface $response)
  281. {
  282. $this->callable = $this->resolveCallable($this->callable);
  283. /** @var InvocationStrategyInterface $handler */
  284. $handler = isset($this->container) ? $this->container->get('foundHandler') : new RequestResponse();
  285. // invoke route callable
  286. if ($this->outputBuffering === false) {
  287. $newResponse = $handler($this->callable, $request, $response, $this->arguments);
  288. } else {
  289. try {
  290. ob_start();
  291. $newResponse = $handler($this->callable, $request, $response, $this->arguments);
  292. $output = ob_get_clean();
  293. } catch (Exception $e) {
  294. ob_end_clean();
  295. throw $e;
  296. }
  297. }
  298. if ($newResponse instanceof ResponseInterface) {
  299. // if route callback returns a ResponseInterface, then use it
  300. $response = $newResponse;
  301. } elseif (is_string($newResponse)) {
  302. // if route callback returns a string, then append it to the response
  303. if ($response->getBody()->isWritable()) {
  304. $response->getBody()->write($newResponse);
  305. }
  306. }
  307. if (!empty($output) && $response->getBody()->isWritable()) {
  308. if ($this->outputBuffering === 'prepend') {
  309. // prepend output buffer content
  310. $body = new Http\Body(fopen('php://temp', 'r+'));
  311. $body->write($output . $response->getBody());
  312. $response = $response->withBody($body);
  313. } elseif ($this->outputBuffering === 'append') {
  314. // append output buffer content
  315. $response->getBody()->write($output);
  316. }
  317. }
  318. return $response;
  319. }
  320. }