123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- <?php
- namespace Goodquestiondev;
- use Illuminate\Support\Str;
- use Goodquestiondev\Resource;
- use Goodquestiondev\Controllers\Controller;
- use Symfony\Component\HttpFoundation\Request;
- 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 Request $request The request data content
- *
- * @return Resource
- */
- public static function getResource($request)
- {
- $route = self::getInstance();
- $uriInfo = $route->getUriInfo($request->getPathInfo());
- $resourceExists = false;
- foreach ($route->resources as $resource) {
- if (in_array($uriInfo['uri'], $resource->uriList)) {
- $route->callController($resource, $request, $uriInfo);
- $resourceExists = true;
- }
- }
- if (! $resourceExists) {
- throw new \Exception('Error getting the Resource: ' . __FUNCTION__);
- }
- }
- /**
- * 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 array
- */
- 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
- ];
- }
- /**
- * Find controller and instantiate it
- *
- * @param Resource $resource The Resource verb
- * @param Request $request The request
- * @param array $uriInfo The url info
- *
- * @return void
- */
- public function callController(Resource $resource, Request $request, array $uriInfo)
- {
- $app = Application::getInstance();
- try {
- $controllerClassName = $app->controllerUris[$resource->uri];
- $controllerName = "Goodquestiondev\\Controllers\\{$controllerClassName}";
- $controller = new $controllerName;
- } catch (\Exception $e) {
- throw new \Exception('Error getting Controller');
- }
- $this->callAction($controller, $resource, $request, $uriInfo);
- }
- /**
- * Call the Controller method
- *
- * @param Controller $controller The controller
- * @param Resource $resource The Resource verb
- * @param Request $request The request
- *
- * @return void
- */
- public function callAction(Controller $controller, Resource $resource, Request $request, array $uriInfo)
- {
- $path = $request->getPathInfo();
- switch ($request->getMethod()) {
- case 'GET':
- if (Str::contains($path, 'create')) {
- $controller->create();
- break;
- }
- if (Str::contains($path, 'edit')) {
- $controller->edit($uriInfo['params']);
- break;
- }
- if (Str::contains($uriInfo['uri'], '{')) {
- $controller->show($uriInfo['params']);
- break;
- }
- $controller->index();
- break;
- case 'POST':
- $controller->store($request);
- break;
- case 'PUT':
- case 'PATCH':
- $controller->update($request, $uriInfo['params']);
- break;
- case 'DELETE':
- $controller->destroy($uriInfo['params']);
- break;
- default:
- $controller->error($request);
- }
- }
- }
|