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()); foreach ($route->resources as $resource) { if (in_array($uriInfo['uri'], $resource->uriList)) { $route->callController($resource, $request, $uriInfo); } }; } /** * 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 ]; } /** * 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); } } }