PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/dingo/api/src/Routing/Route.php

https://bitbucket.org/mauro014/ownakaunting
PHP | 632 lines | 261 code | 85 blank | 286 comment | 20 complexity | e236d66c7572ebff17df2fe06ae71739 MD5 | raw file
Possible License(s): MIT, BSD-3-Clause, LGPL-2.0, LGPL-2.1, MPL-2.0-no-copyleft-exception
  1. <?php
  2. namespace Dingo\Api\Routing;
  3. use Closure;
  4. use Illuminate\Support\Arr;
  5. use Illuminate\Support\Str;
  6. use Illuminate\Http\Request;
  7. use Illuminate\Container\Container;
  8. use Dingo\Api\Contract\Routing\Adapter;
  9. class Route
  10. {
  11. /**
  12. * Routing adapter instance.
  13. *
  14. * @var \Dingo\Api\Contract\Routing\Adapter
  15. */
  16. protected $adapter;
  17. /**
  18. * Container instance.
  19. *
  20. * @var \Illuminate\Container\Container
  21. */
  22. protected $container;
  23. protected $route;
  24. /**
  25. * Route URI.
  26. *
  27. * @var string
  28. */
  29. protected $uri;
  30. /**
  31. * Array of HTTP methods.
  32. *
  33. * @var array
  34. */
  35. protected $methods;
  36. /**
  37. * Array of route action attributes.
  38. *
  39. * @var array
  40. */
  41. protected $action;
  42. /**
  43. * Array of versions this route will respond to.
  44. *
  45. * @var array
  46. */
  47. protected $versions;
  48. /**
  49. * Array of scopes for OAuth 2.0 authentication.
  50. *
  51. * @var array
  52. */
  53. protected $scopes;
  54. /**
  55. * Array of authentication providers.
  56. *
  57. * @var array
  58. */
  59. protected $authenticationProviders;
  60. /**
  61. * The rate limit for this route.
  62. *
  63. * @var int
  64. */
  65. protected $rateLimit;
  66. /**
  67. * The expiration time for any rate limit set on this rate.
  68. *
  69. * @var int
  70. */
  71. protected $rateExpiration;
  72. /**
  73. * The throttle used by the route, takes precedence over rate limits.
  74. *
  75. * @return string|\Dingo\Api\Contract\Http\RateLimit\Throttle
  76. */
  77. protected $throttle;
  78. /**
  79. * Controller instance.
  80. *
  81. * @var object
  82. */
  83. protected $controller;
  84. /**
  85. * Controller method name.
  86. *
  87. * @var string
  88. */
  89. protected $controllerMethod;
  90. /**
  91. * Controller class name.
  92. *
  93. * @var string
  94. */
  95. protected $controllerClass;
  96. /**
  97. * Indicates if the request is conditional.
  98. *
  99. * @var bool
  100. */
  101. protected $conditionalRequest = true;
  102. /**
  103. * Middleware applied to route.
  104. *
  105. * @var array
  106. */
  107. protected $middleware;
  108. /**
  109. * Create a new route instance.
  110. *
  111. * @param \Dingo\Api\Contract\Routing\Adapter $adapter
  112. * @param \Illuminate\Container\Container $container
  113. * @param \Illuminate\Http\Request $request
  114. * @param array|\Illuminate\Routing\Route $route
  115. *
  116. * @return void
  117. */
  118. public function __construct(Adapter $adapter, Container $container, Request $request, $route)
  119. {
  120. $this->adapter = $adapter;
  121. $this->container = $container;
  122. $this->route = $route;
  123. $this->setupRouteProperties($request, $route);
  124. }
  125. /**
  126. * Setup the route properties.
  127. */
  128. protected function setupRouteProperties(Request $request, $route)
  129. {
  130. list($this->uri, $this->methods, $this->action) = $this->adapter->getRouteProperties($route, $request);
  131. $this->versions = Arr::pull($this->action, 'version');
  132. $this->conditionalRequest = Arr::pull($this->action, 'conditionalRequest', true);
  133. $this->middleware = (array) Arr::pull($this->action, 'middleware', []);
  134. $this->throttle = Arr::pull($this->action, 'throttle');
  135. $this->scopes = Arr::pull($this->action, 'scopes', []);
  136. $this->authenticationProviders = Arr::pull($this->action, 'providers', []);
  137. $this->rateLimit = Arr::pull($this->action, 'limit', 0);
  138. $this->rateExpiration = Arr::pull($this->action, 'expires', 0);
  139. // Now that the default route properties have been set we'll go ahead and merge
  140. // any controller properties to fully configure the route.
  141. $this->mergeControllerProperties();
  142. // If we have a string based throttle then we'll new up an instance of the
  143. // throttle through the container.
  144. if (is_string($this->throttle)) {
  145. $this->throttle = $this->container->make($this->throttle);
  146. }
  147. }
  148. /**
  149. * Merge the controller properties onto the route properties.
  150. */
  151. protected function mergeControllerProperties()
  152. {
  153. if (isset($this->action['uses']) && is_string($this->action['uses']) && Str::contains($this->action['uses'], '@')) {
  154. $this->action['controller'] = $this->action['uses'];
  155. $this->makeControllerInstance();
  156. }
  157. if (! $this->controllerUsesHelpersTrait()) {
  158. return;
  159. }
  160. $controller = $this->getControllerInstance();
  161. $controllerMiddleware = [];
  162. if (method_exists($controller, 'getMiddleware')) {
  163. $controllerMiddleware = $controller->getMiddleware();
  164. } elseif (method_exists($controller, 'getMiddlewareForMethod')) {
  165. $controllerMiddleware = $controller->getMiddlewareForMethod($this->controllerMethod);
  166. }
  167. $this->middleware = array_merge($this->middleware, $controllerMiddleware);
  168. if ($property = $this->findControllerPropertyOptions('throttles')) {
  169. $this->throttle = $property['class'];
  170. }
  171. if ($property = $this->findControllerPropertyOptions('scopes')) {
  172. $this->scopes = array_merge($this->scopes, $property['scopes']);
  173. }
  174. if ($property = $this->findControllerPropertyOptions('authenticationProviders')) {
  175. $this->authenticationProviders = array_merge($this->authenticationProviders, $property['providers']);
  176. }
  177. if ($property = $this->findControllerPropertyOptions('rateLimit')) {
  178. $this->rateLimit = $property['limit'];
  179. $this->rateExpiration = $property['expires'];
  180. }
  181. }
  182. /**
  183. * Find the controller options and whether or not it will apply to this routes controller method.
  184. *
  185. * @param string $name
  186. *
  187. * @return array
  188. */
  189. protected function findControllerPropertyOptions($name)
  190. {
  191. $properties = [];
  192. foreach ($this->getControllerInstance()->{'get'.ucfirst($name)}() as $property) {
  193. if (isset($property['options']) && ! $this->optionsApplyToControllerMethod($property['options'])) {
  194. continue;
  195. }
  196. unset($property['options']);
  197. $properties = array_merge_recursive($properties, $property);
  198. }
  199. return $properties;
  200. }
  201. /**
  202. * Determine if a controller method is in an array of options.
  203. *
  204. * @param array $options
  205. *
  206. * @return bool
  207. */
  208. protected function optionsApplyToControllerMethod(array $options)
  209. {
  210. if (empty($options)) {
  211. return true;
  212. } elseif (isset($options['only']) && in_array($this->controllerMethod, $this->explodeOnPipes($options['only']))) {
  213. return true;
  214. } elseif (isset($options['except'])) {
  215. return ! in_array($this->controllerMethod, $this->explodeOnPipes($options['except']));
  216. } elseif (in_array($this->controllerMethod, $this->explodeOnPipes($options))) {
  217. return true;
  218. }
  219. return false;
  220. }
  221. /**
  222. * Explode a value on a pipe delimiter.
  223. *
  224. * @param string|array $value
  225. *
  226. * @return array
  227. */
  228. protected function explodeOnPipes($value)
  229. {
  230. return is_string($value) ? explode('|', $value) : $value;
  231. }
  232. /**
  233. * Determine if the controller instance uses the helpers trait.
  234. *
  235. * @return bool
  236. */
  237. protected function controllerUsesHelpersTrait()
  238. {
  239. if (! $controller = $this->getControllerInstance()) {
  240. return false;
  241. }
  242. $traits = [];
  243. do {
  244. $traits = array_merge(class_uses($controller, false), $traits);
  245. } while ($controller = get_parent_class($controller));
  246. foreach ($traits as $trait => $same) {
  247. $traits = array_merge(class_uses($trait, false), $traits);
  248. }
  249. return isset($traits[Helpers::class]);
  250. }
  251. /**
  252. * Get the routes controller instance.
  253. *
  254. * @return null|\Illuminate\Routing\Controller|\Laravel\Lumen\Routing\Controller
  255. */
  256. public function getControllerInstance()
  257. {
  258. return $this->controller;
  259. }
  260. /**
  261. * Make a new controller instance through the container.
  262. *
  263. * @return \Illuminate\Routing\Controller|\Laravel\Lumen\Routing\Controller
  264. */
  265. protected function makeControllerInstance()
  266. {
  267. list($this->controllerClass, $this->controllerMethod) = explode('@', $this->action['uses']);
  268. $this->container->instance($this->controllerClass, $this->controller = $this->container->make($this->controllerClass));
  269. return $this->controller;
  270. }
  271. /**
  272. * Get the middleware for this route.
  273. *
  274. * @return array
  275. */
  276. public function middleware()
  277. {
  278. return $this->middleware;
  279. }
  280. /**
  281. * Get the middleware for this route.
  282. *
  283. * @return array
  284. */
  285. public function getMiddleware()
  286. {
  287. return $this->middleware;
  288. }
  289. /**
  290. * Determine if the route is protected.
  291. *
  292. * @return bool
  293. */
  294. public function isProtected()
  295. {
  296. if (isset($this->middleware['api.auth']) || in_array('api.auth', $this->middleware)) {
  297. if ($this->controller && isset($this->middleware['api.auth'])) {
  298. return $this->optionsApplyToControllerMethod($this->middleware['api.auth']);
  299. }
  300. return true;
  301. }
  302. return false;
  303. }
  304. /**
  305. * Determine if the route has a throttle.
  306. *
  307. * @return bool
  308. */
  309. public function hasThrottle()
  310. {
  311. return ! is_null($this->throttle);
  312. }
  313. /**
  314. * Get the route throttle.
  315. *
  316. * @return string|\Dingo\Api\Http\RateLimit\Throttle\Throttle
  317. */
  318. public function throttle()
  319. {
  320. return $this->throttle;
  321. }
  322. /**
  323. * Get the route throttle.
  324. *
  325. * @return string|\Dingo\Api\Http\RateLimit\Throttle\Throttle
  326. */
  327. public function getThrottle()
  328. {
  329. return $this->throttle;
  330. }
  331. /**
  332. * Get the route scopes.
  333. *
  334. * @return array
  335. */
  336. public function scopes()
  337. {
  338. return $this->scopes;
  339. }
  340. /**
  341. * Get the route scopes.
  342. *
  343. * @return array
  344. */
  345. public function getScopes()
  346. {
  347. return $this->scopes;
  348. }
  349. /**
  350. * Check if route requires all scopes or any scope to be valid.
  351. *
  352. * @return bool
  353. */
  354. public function scopeStrict()
  355. {
  356. return Arr::get($this->action, 'scopeStrict', false);
  357. }
  358. /**
  359. * Get the route authentication providers.
  360. *
  361. * @return array
  362. */
  363. public function authenticationProviders()
  364. {
  365. return $this->authenticationProviders;
  366. }
  367. /**
  368. * Get the route authentication providers.
  369. *
  370. * @return array
  371. */
  372. public function getAuthenticationProviders()
  373. {
  374. return $this->authenticationProviders;
  375. }
  376. /**
  377. * Get the rate limit for this route.
  378. *
  379. * @return int
  380. */
  381. public function rateLimit()
  382. {
  383. return $this->rateLimit;
  384. }
  385. /**
  386. * Get the rate limit for this route.
  387. *
  388. * @return int
  389. */
  390. public function getRateLimit()
  391. {
  392. return $this->rateLimit;
  393. }
  394. /**
  395. * Get the rate limit expiration time for this route.
  396. *
  397. * @return int
  398. */
  399. public function rateLimitExpiration()
  400. {
  401. return $this->rateExpiration;
  402. }
  403. /**
  404. * Get the rate limit expiration time for this route.
  405. *
  406. * @return int
  407. */
  408. public function getRateLimitExpiration()
  409. {
  410. return $this->rateExpiration;
  411. }
  412. /**
  413. * Get the name of the route.
  414. *
  415. * @return string
  416. */
  417. public function getName()
  418. {
  419. return Arr::get($this->action, 'as', null);
  420. }
  421. /**
  422. * Determine if the request is conditional.
  423. *
  424. * @return bool
  425. */
  426. public function requestIsConditional()
  427. {
  428. return $this->conditionalRequest === true;
  429. }
  430. /**
  431. * Get the route action.
  432. *
  433. * @return array
  434. */
  435. public function getAction()
  436. {
  437. return $this->action;
  438. }
  439. /**
  440. * Get the action name for the route.
  441. *
  442. * @return string
  443. */
  444. public function getActionName()
  445. {
  446. return Arr::get($this->action, 'controller', Arr::get($this->action, 'uses', 'Closure'));
  447. }
  448. /**
  449. * Get the versions for the route.
  450. *
  451. * @return array
  452. */
  453. public function getVersions()
  454. {
  455. return $this->versions;
  456. }
  457. /**
  458. * Get the versions for the route.
  459. *
  460. * @return array
  461. */
  462. public function versions()
  463. {
  464. return $this->getVersions();
  465. }
  466. /**
  467. * Get the URI associated with the route.
  468. *
  469. * @return string
  470. */
  471. public function getPath()
  472. {
  473. return $this->uri();
  474. }
  475. /**
  476. * Get the URI associated with the route.
  477. *
  478. * @return string
  479. */
  480. public function uri()
  481. {
  482. return $this->uri;
  483. }
  484. /**
  485. * Get the HTTP verbs the route responds to.
  486. *
  487. * @return array
  488. */
  489. public function getMethods()
  490. {
  491. return $this->methods();
  492. }
  493. /**
  494. * Get the HTTP verbs the route responds to.
  495. *
  496. * @return array
  497. */
  498. public function methods()
  499. {
  500. return $this->methods;
  501. }
  502. /**
  503. * Determine if the route only responds to HTTP requests.
  504. *
  505. * @return bool
  506. */
  507. public function httpOnly()
  508. {
  509. return in_array('http', $this->action, true);
  510. }
  511. /**
  512. * Determine if the route only responds to HTTPS requests.
  513. *
  514. * @return bool
  515. */
  516. public function httpsOnly()
  517. {
  518. return $this->secure();
  519. }
  520. /**
  521. * Determine if the route only responds to HTTPS requests.
  522. *
  523. * @return bool
  524. */
  525. public function secure()
  526. {
  527. return in_array('https', $this->action, true);
  528. }
  529. /**
  530. * Get the domain defined for the route.
  531. *
  532. * @return string|null
  533. */
  534. public function domain()
  535. {
  536. return Arr::get($this->action, 'domain');
  537. }
  538. /**
  539. * Get the original route.
  540. *
  541. * @return array|\Illuminate\Routing\Route
  542. */
  543. public function getOriginalRoute()
  544. {
  545. return $this->route;
  546. }
  547. }