Route.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <?php
  2. namespace Goodquestiondev;
  3. use Illuminate\Support\Str;
  4. use Goodquestiondev\Resource;
  5. class Route
  6. {
  7. /**
  8. * The Application routers
  9. *
  10. * @var array
  11. */
  12. public $resources = [];
  13. /**
  14. * The Application instance.
  15. *
  16. * @var self
  17. */
  18. private static $instance = null;
  19. /**
  20. * The default actions for a resourceful controller.
  21. *
  22. * @var array
  23. */
  24. public $resourceDefaults = ['index', 'create', 'store', 'show', 'edit', 'update', 'destroy'];
  25. /**
  26. * The verbs used in the resource URIs.
  27. *
  28. * @var array
  29. */
  30. public static $verbs = [
  31. 'create',
  32. 'edit',
  33. ];
  34. /**
  35. * The possible resource keys
  36. *
  37. * @var array
  38. */
  39. public $resourceKeys = [];
  40. /**
  41. * The resource strings
  42. *
  43. * @var array
  44. */
  45. public $resourceStrings = [];
  46. /**
  47. * Create a new simple resource instance following singleton pattern
  48. *
  49. * @return self
  50. */
  51. public static function getInstance()
  52. {
  53. if (self::$instance == null) {
  54. self::$instance = new self();
  55. }
  56. return self::$instance;
  57. }
  58. /**
  59. * Register resource
  60. *
  61. * @param string $uri The uri string
  62. *
  63. * @return void
  64. */
  65. public static function resource(string $uri)
  66. {
  67. $route = self::getInstance();
  68. $resourceKeys = array_merge(explode(".", $uri), $route->resourceKeys);
  69. $route->resourceKeys = array_unique($resourceKeys);
  70. $route->resourceStrings[] = $uri;
  71. $route->resources[$uri] = new Resource($uri);
  72. }
  73. /**
  74. * Redirects the user to the correct controller and method based on the path
  75. *
  76. * @param string $verb The request verb
  77. * @param string $path The path string
  78. * @param string $content The request data content
  79. *
  80. * @return Resource
  81. */
  82. public static function getResource(string $verb, string $path, string $content)
  83. {
  84. $route = self::getInstance();
  85. $uriInfo = $route->getUriInfo($path);
  86. foreach ($route->resources as $resource) {
  87. if (in_array($uriInfo['uri'], $resource->uriList)) {
  88. $resource->handleRequest($verb, $path, $uriInfo, $content);
  89. }
  90. };
  91. }
  92. /**
  93. * Get URI and their params
  94. * E.q for path /users/bob/posts/999
  95. * E.q: ['uri' => 'users/{key}posts/{key}', 'params' ['users' => 'bob', 'posts' => 999]]
  96. *
  97. * @param string $path The request path
  98. *
  99. * @return arrray
  100. */
  101. public function getUriInfo($path)
  102. {
  103. $path = Str::of($path)->ltrim('/')->rtrim('/');
  104. $parts = explode("/", $path);
  105. $params = [];
  106. $uri = '';
  107. foreach ($parts as $index => $part) {
  108. $isResourceString = in_array($part, $this->resourceKeys);
  109. if ($index === 0 && ! $isResourceString) {
  110. throw new \Exception('Bad Url');
  111. }
  112. $isResourceVerb = in_array($part, self::$verbs);
  113. if ($isResourceVerb) {
  114. $uri .= $part;
  115. break;
  116. }
  117. if ($isResourceString) {
  118. $params[$part] = '';
  119. $uri .= "$part/";
  120. } else {
  121. $params[array_key_last($params)] = $part;
  122. $singular = Str::singular(array_key_last($params));
  123. $uri .= "{{$singular}}/";
  124. }
  125. }
  126. foreach ($params as $key => $value) {
  127. unset($params[$key]);
  128. $params[Str::singular($key)] = $value;
  129. }
  130. return [
  131. 'uri' => (string) Str::of($uri)->rtrim('/'),
  132. 'params' => $params
  133. ];
  134. }
  135. }