|
@@ -0,0 +1,155 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace Goodquestiondev;
|
|
|
+
|
|
|
+use Illuminate\Support\Str;
|
|
|
+use Goodquestiondev\Resource;
|
|
|
+
|
|
|
+class Route
|
|
|
+{
|
|
|
+ /**
|
|
|
+ * The Application routers
|
|
|
+ *
|
|
|
+ * @var array
|
|
|
+ */
|
|
|
+ public $resources = [];
|
|
|
+
|
|
|
+ /**
|
|
|
+ * The Application instance.
|
|
|
+ *
|
|
|
+ * @var self
|
|
|
+ */
|
|
|
+ private static $instance = null;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * The default actions for a resourceful controller.
|
|
|
+ *
|
|
|
+ * @var array
|
|
|
+ */
|
|
|
+ public $resourceDefaults = ['index', 'create', 'store', 'show', 'edit', 'update', 'destroy'];
|
|
|
+
|
|
|
+ /**
|
|
|
+ * The verbs used in the resource URIs.
|
|
|
+ *
|
|
|
+ * @var array
|
|
|
+ */
|
|
|
+ public static $verbs = [
|
|
|
+ 'create',
|
|
|
+ 'edit',
|
|
|
+ ];
|
|
|
+
|
|
|
+ /**
|
|
|
+ * The possible resource keys
|
|
|
+ *
|
|
|
+ * @var array
|
|
|
+ */
|
|
|
+ public $resourceKeys = [];
|
|
|
+
|
|
|
+ /**
|
|
|
+ * The resource strings
|
|
|
+ *
|
|
|
+ * @var array
|
|
|
+ */
|
|
|
+ public $resourceStrings = [];
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Create a new simple resource instance following singleton pattern
|
|
|
+ *
|
|
|
+ * @return self
|
|
|
+ */
|
|
|
+
|
|
|
+ public static function getInstance()
|
|
|
+ {
|
|
|
+ if (self::$instance == null) {
|
|
|
+ self::$instance = new self();
|
|
|
+ }
|
|
|
+
|
|
|
+ return self::$instance;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Register resource
|
|
|
+ *
|
|
|
+ * @param string $uri The uri string
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public static function resource(string $uri)
|
|
|
+ {
|
|
|
+ $route = self::getInstance();
|
|
|
+ $resourceKeys = array_merge(explode(".", $uri), $route->resourceKeys);
|
|
|
+ $route->resourceKeys = array_unique($resourceKeys);
|
|
|
+ $route->resourceStrings[] = $uri;
|
|
|
+ $route->resources[$uri] = new Resource($uri);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Redirects the user to the correct controller and method based on the path
|
|
|
+ *
|
|
|
+ * @param string $verb The request verb
|
|
|
+ * @param string $path The path string
|
|
|
+ * @param string $content The request data content
|
|
|
+ *
|
|
|
+ * @return Resource
|
|
|
+ */
|
|
|
+ public static function getResource(string $verb, string $path, string $content)
|
|
|
+ {
|
|
|
+ $route = self::getInstance();
|
|
|
+ $uriInfo = $route->getUriInfo($path);
|
|
|
+ foreach ($route->resources as $resource) {
|
|
|
+ if (in_array($uriInfo['uri'], $resource->uriList)) {
|
|
|
+ $resource->handleRequest($verb, $path, $uriInfo, $content);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Get URI and their params
|
|
|
+ * E.q for path /users/bob/posts/999
|
|
|
+ * E.q: ['uri' => 'users/{key}posts/{key}', 'params' ['users' => 'bob', 'posts' => 999]]
|
|
|
+ *
|
|
|
+ * @param string $path The request path
|
|
|
+ *
|
|
|
+ * @return arrray
|
|
|
+ */
|
|
|
+ public function getUriInfo($path)
|
|
|
+ {
|
|
|
+ $path = Str::of($path)->ltrim('/')->rtrim('/');
|
|
|
+ $parts = explode("/", $path);
|
|
|
+ $params = [];
|
|
|
+ $uri = '';
|
|
|
+
|
|
|
+ foreach ($parts as $index => $part) {
|
|
|
+ $isResourceString = in_array($part, $this->resourceKeys);
|
|
|
+ if ($index === 0 && ! $isResourceString) {
|
|
|
+ throw new \Exception('Bad Url');
|
|
|
+ }
|
|
|
+
|
|
|
+ $isResourceVerb = in_array($part, self::$verbs);
|
|
|
+
|
|
|
+ if ($isResourceVerb) {
|
|
|
+ $uri .= $part;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($isResourceString) {
|
|
|
+ $params[$part] = '';
|
|
|
+ $uri .= "$part/";
|
|
|
+ } else {
|
|
|
+ $params[array_key_last($params)] = $part;
|
|
|
+ $singular = Str::singular(array_key_last($params));
|
|
|
+ $uri .= "{{$singular}}/";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ foreach ($params as $key => $value) {
|
|
|
+ unset($params[$key]);
|
|
|
+ $params[Str::singular($key)] = $value;
|
|
|
+ }
|
|
|
+ return [
|
|
|
+ 'uri' => (string) Str::of($uri)->rtrim('/'),
|
|
|
+ 'params' => $params
|
|
|
+ ];
|
|
|
+ }
|
|
|
+}
|