PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/vendor/laravel/framework/src/Illuminate/Routing/ResourceRegistrar.php

https://gitlab.com/phanthanh9787/crud-user
PHP | 359 lines | 132 code | 55 blank | 172 comment | 6 complexity | 6df602eb000b9bf8b1269376d97e95e4 MD5 | raw file
  1. <?php
  2. namespace Illuminate\Routing;
  3. use Illuminate\Support\Str;
  4. class ResourceRegistrar
  5. {
  6. /**
  7. * The router instance.
  8. *
  9. * @var \Illuminate\Routing\Router
  10. */
  11. protected $router;
  12. /**
  13. * The default actions for a resourceful controller.
  14. *
  15. * @var array
  16. */
  17. protected $resourceDefaults = ['index', 'create', 'store', 'show', 'edit', 'update', 'destroy'];
  18. /**
  19. * Create a new resource registrar instance.
  20. *
  21. * @param \Illuminate\Routing\Router $router
  22. * @return void
  23. */
  24. public function __construct(Router $router)
  25. {
  26. $this->router = $router;
  27. }
  28. /**
  29. * Route a resource to a controller.
  30. *
  31. * @param string $name
  32. * @param string $controller
  33. * @param array $options
  34. * @return void
  35. */
  36. public function register($name, $controller, array $options = [])
  37. {
  38. // If the resource name contains a slash, we will assume the developer wishes to
  39. // register these resource routes with a prefix so we will set that up out of
  40. // the box so they don't have to mess with it. Otherwise, we will continue.
  41. if (Str::contains($name, '/')) {
  42. $this->prefixedResource($name, $controller, $options);
  43. return;
  44. }
  45. // We need to extract the base resource from the resource name. Nested resources
  46. // are supported in the framework, but we need to know what name to use for a
  47. // place-holder on the route wildcards, which should be the base resources.
  48. $base = $this->getResourceWildcard(last(explode('.', $name)));
  49. $defaults = $this->resourceDefaults;
  50. foreach ($this->getResourceMethods($defaults, $options) as $m) {
  51. $this->{'addResource'.ucfirst($m)}($name, $base, $controller, $options);
  52. }
  53. }
  54. /**
  55. * Build a set of prefixed resource routes.
  56. *
  57. * @param string $name
  58. * @param string $controller
  59. * @param array $options
  60. * @return void
  61. */
  62. protected function prefixedResource($name, $controller, array $options)
  63. {
  64. list($name, $prefix) = $this->getResourcePrefix($name);
  65. // We need to extract the base resource from the resource name. Nested resources
  66. // are supported in the framework, but we need to know what name to use for a
  67. // place-holder on the route wildcards, which should be the base resources.
  68. $callback = function ($me) use ($name, $controller, $options) {
  69. $me->resource($name, $controller, $options);
  70. };
  71. return $this->router->group(compact('prefix'), $callback);
  72. }
  73. /**
  74. * Extract the resource and prefix from a resource name.
  75. *
  76. * @param string $name
  77. * @return array
  78. */
  79. protected function getResourcePrefix($name)
  80. {
  81. $segments = explode('/', $name);
  82. // To get the prefix, we will take all of the name segments and implode them on
  83. // a slash. This will generate a proper URI prefix for us. Then we take this
  84. // last segment, which will be considered the final resources name we use.
  85. $prefix = implode('/', array_slice($segments, 0, -1));
  86. return [end($segments), $prefix];
  87. }
  88. /**
  89. * Get the applicable resource methods.
  90. *
  91. * @param array $defaults
  92. * @param array $options
  93. * @return array
  94. */
  95. protected function getResourceMethods($defaults, $options)
  96. {
  97. if (isset($options['only'])) {
  98. return array_intersect($defaults, (array) $options['only']);
  99. } elseif (isset($options['except'])) {
  100. return array_diff($defaults, (array) $options['except']);
  101. }
  102. return $defaults;
  103. }
  104. /**
  105. * Get the base resource URI for a given resource.
  106. *
  107. * @param string $resource
  108. * @return string
  109. */
  110. public function getResourceUri($resource)
  111. {
  112. if (! Str::contains($resource, '.')) {
  113. return $resource;
  114. }
  115. // Once we have built the base URI, we'll remove the wildcard holder for this
  116. // base resource name so that the individual route adders can suffix these
  117. // paths however they need to, as some do not have any wildcards at all.
  118. $segments = explode('.', $resource);
  119. $uri = $this->getNestedResourceUri($segments);
  120. return str_replace('/{'.$this->getResourceWildcard(end($segments)).'}', '', $uri);
  121. }
  122. /**
  123. * Get the URI for a nested resource segment array.
  124. *
  125. * @param array $segments
  126. * @return string
  127. */
  128. protected function getNestedResourceUri(array $segments)
  129. {
  130. // We will spin through the segments and create a place-holder for each of the
  131. // resource segments, as well as the resource itself. Then we should get an
  132. // entire string for the resource URI that contains all nested resources.
  133. return implode('/', array_map(function ($s) {
  134. return $s.'/{'.$this->getResourceWildcard($s).'}';
  135. }, $segments));
  136. }
  137. /**
  138. * Get the action array for a resource route.
  139. *
  140. * @param string $resource
  141. * @param string $controller
  142. * @param string $method
  143. * @param array $options
  144. * @return array
  145. */
  146. protected function getResourceAction($resource, $controller, $method, $options)
  147. {
  148. $name = $this->getResourceName($resource, $method, $options);
  149. return ['as' => $name, 'uses' => $controller.'@'.$method];
  150. }
  151. /**
  152. * Get the name for a given resource.
  153. *
  154. * @param string $resource
  155. * @param string $method
  156. * @param array $options
  157. * @return string
  158. */
  159. protected function getResourceName($resource, $method, $options)
  160. {
  161. if (isset($options['names'][$method])) {
  162. return $options['names'][$method];
  163. }
  164. // If a global prefix has been assigned to all names for this resource, we will
  165. // grab that so we can prepend it onto the name when we create this name for
  166. // the resource action. Otherwise we'll just use an empty string for here.
  167. $prefix = isset($options['as']) ? $options['as'].'.' : '';
  168. if (! $this->router->hasGroupStack()) {
  169. return $prefix.$resource.'.'.$method;
  170. }
  171. return $this->getGroupResourceName($prefix, $resource, $method);
  172. }
  173. /**
  174. * Get the resource name for a grouped resource.
  175. *
  176. * @param string $prefix
  177. * @param string $resource
  178. * @param string $method
  179. * @return string
  180. */
  181. protected function getGroupResourceName($prefix, $resource, $method)
  182. {
  183. $group = trim(str_replace('/', '.', $this->router->getLastGroupPrefix()), '.');
  184. if (empty($group)) {
  185. return trim("{$prefix}{$resource}.{$method}", '.');
  186. }
  187. return trim("{$prefix}{$group}.{$resource}.{$method}", '.');
  188. }
  189. /**
  190. * Format a resource wildcard for usage.
  191. *
  192. * @param string $value
  193. * @return string
  194. */
  195. public function getResourceWildcard($value)
  196. {
  197. return str_replace('-', '_', $value);
  198. }
  199. /**
  200. * Add the index method for a resourceful route.
  201. *
  202. * @param string $name
  203. * @param string $base
  204. * @param string $controller
  205. * @param array $options
  206. * @return \Illuminate\Routing\Route
  207. */
  208. protected function addResourceIndex($name, $base, $controller, $options)
  209. {
  210. $uri = $this->getResourceUri($name);
  211. $action = $this->getResourceAction($name, $controller, 'index', $options);
  212. return $this->router->get($uri, $action);
  213. }
  214. /**
  215. * Add the create method for a resourceful route.
  216. *
  217. * @param string $name
  218. * @param string $base
  219. * @param string $controller
  220. * @param array $options
  221. * @return \Illuminate\Routing\Route
  222. */
  223. protected function addResourceCreate($name, $base, $controller, $options)
  224. {
  225. $uri = $this->getResourceUri($name).'/create';
  226. $action = $this->getResourceAction($name, $controller, 'create', $options);
  227. return $this->router->get($uri, $action);
  228. }
  229. /**
  230. * Add the store method for a resourceful route.
  231. *
  232. * @param string $name
  233. * @param string $base
  234. * @param string $controller
  235. * @param array $options
  236. * @return \Illuminate\Routing\Route
  237. */
  238. protected function addResourceStore($name, $base, $controller, $options)
  239. {
  240. $uri = $this->getResourceUri($name);
  241. $action = $this->getResourceAction($name, $controller, 'store', $options);
  242. return $this->router->post($uri, $action);
  243. }
  244. /**
  245. * Add the show method for a resourceful route.
  246. *
  247. * @param string $name
  248. * @param string $base
  249. * @param string $controller
  250. * @param array $options
  251. * @return \Illuminate\Routing\Route
  252. */
  253. protected function addResourceShow($name, $base, $controller, $options)
  254. {
  255. $uri = $this->getResourceUri($name).'/{'.$base.'}';
  256. $action = $this->getResourceAction($name, $controller, 'show', $options);
  257. return $this->router->get($uri, $action);
  258. }
  259. /**
  260. * Add the edit method for a resourceful route.
  261. *
  262. * @param string $name
  263. * @param string $base
  264. * @param string $controller
  265. * @param array $options
  266. * @return \Illuminate\Routing\Route
  267. */
  268. protected function addResourceEdit($name, $base, $controller, $options)
  269. {
  270. $uri = $this->getResourceUri($name).'/{'.$base.'}/edit';
  271. $action = $this->getResourceAction($name, $controller, 'edit', $options);
  272. return $this->router->get($uri, $action);
  273. }
  274. /**
  275. * Add the update method for a resourceful route.
  276. *
  277. * @param string $name
  278. * @param string $base
  279. * @param string $controller
  280. * @param array $options
  281. * @return void
  282. */
  283. protected function addResourceUpdate($name, $base, $controller, $options)
  284. {
  285. $uri = $this->getResourceUri($name).'/{'.$base.'}';
  286. $action = $this->getResourceAction($name, $controller, 'update', $options);
  287. return $this->router->match(['PUT', 'PATCH'], $uri, $action);
  288. }
  289. /**
  290. * Add the destroy method for a resourceful route.
  291. *
  292. * @param string $name
  293. * @param string $base
  294. * @param string $controller
  295. * @param array $options
  296. * @return \Illuminate\Routing\Route
  297. */
  298. protected function addResourceDestroy($name, $base, $controller, $options)
  299. {
  300. $uri = $this->getResourceUri($name).'/{'.$base.'}';
  301. $action = $this->getResourceAction($name, $controller, 'destroy', $options);
  302. return $this->router->delete($uri, $action);
  303. }
  304. }