diff --git a/composer.json b/composer.json index c55483c..576c212 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,8 @@ "require": { "php": "^7.1", "psr/container": "^1.0", - "selami/router": "^0.5", + "selami/stdlib": "^1.2", + "selami/router": "^0.6", "selami/views": "^0.2", "zendframework/zend-diactoros": "^1.3", "zendframework/zend-servicemanager": "^3.0", diff --git a/src/Foundation/App.php b/src/Foundation/App.php index 0234afb..1b190d4 100644 --- a/src/Foundation/App.php +++ b/src/Foundation/App.php @@ -95,18 +95,14 @@ private function runDispatcher(array $route) : void } } - private function runRoute(string $controllerClass, int $returnType = Response::HTML, ?array $args = null) : void + private function runRoute($controller, int $returnType = Response::HTML, ?array $args = null) : void { - if (!class_exists($controllerClass)) { - $message = "Controller has not class name as {$controllerClass}"; - throw new \BadMethodCallException($message); - } - $controller = $controllerClass::factory($this->container, $args); - $actionOutput = $controller->respond(); - if (isset($actionOutput['meta']['type']) && $actionOutput['meta']['type'] === Dispatcher::REDIRECT) { - $returnType = Router::REDIRECT; - } - $this->response->setResponse($returnType, $actionOutput, $controllerClass); + $controller = new Controller($this->container, $controller, $returnType, $args); + $this->response->setResponse( + $controller->getReturnType(), + $controller->getActionOutput(), + $controller->getControllerClass() + ); } public function getResponse() : array diff --git a/src/Foundation/Controller.php b/src/Foundation/Controller.php new file mode 100644 index 0000000..aa8b1db --- /dev/null +++ b/src/Foundation/Controller.php @@ -0,0 +1,85 @@ +container = $container; + $this->controller = $controller; + $this->returnType = $returnType; + $this->args = $args; + + $this->autowiredResponse(); + } + + public function getControllerClass() : string + { + return $this->controllerClass; + } + + public function getActionOutput() : array + { + return $this->actionOutput; + } + + public function getReturnType() : int + { + return $this->returnType; + } + + private function autowiredResponse() : void + { + $this->controllerClass = $this->controller; + if (!class_exists($this->controllerClass)) { + $message = "Controller has not class name as {$this->controllerClass}"; + throw new BadMethodCallException($message); + } + $controllerConstructorArguments = Resolver::getParameterHints($this->controllerClass, '__construct'); + $arguments = []; + foreach ($controllerConstructorArguments as $argumentName =>$argumentType) { + $arguments[] = $this->getArgument($argumentName, $argumentType); + } + $reflectionClass = new ReflectionClass($this->controllerClass); + $controller = $reflectionClass->newInstanceArgs($arguments); + $this->actionOutput = $controller->__invoke(); + if (isset($this->actionOutput['meta']['type']) && $this->actionOutput['meta']['type'] === Dispatcher::REDIRECT) { + $this->returnType = Router::REDIRECT; + } + } + + private function getArgument(string $argumentName, string $argumentType) + { + if ($argumentType === Resolver::ARRAY) { + return $this->{$argumentName}; + } + return $this->container->get($argumentType); + } + +} \ No newline at end of file diff --git a/src/Foundation/Response.php b/src/Foundation/Response.php index 3ce7fd4..f38d78d 100644 --- a/src/Foundation/Response.php +++ b/src/Foundation/Response.php @@ -7,6 +7,7 @@ use Zend\Config\Config as ZendConfig; use Psr\Container\ContainerInterface; use Selami\View\ViewInterface; +use Selami\Stdlib\CaseConverter; use Symfony\Component\HttpFoundation\Session\Session; class Response @@ -115,6 +116,7 @@ public function setDownloadResponse(array $actionOutput) : void $this->downloadFileName = $actionOutput['meta']['download_file_name'] ?? date('Ymdhis'); } } + public function setJsonResponse(array $actionOutput) : void { $this->contentType = Selami\Router::JSON; @@ -145,7 +147,7 @@ private function renderResponse(int $returnType, array $actionOutput, string $co $paths = explode("\\", $controllerClass); $templateFile = array_pop($paths); $templateFolder = array_pop($paths); - $template = strtolower($templateFolder) . '/' . strtolower($templateFile) . '.twig'; + $template = CaseConverter::toSnakeCase($templateFolder) . '/' . CaseConverter::toSnakeCase($templateFile) . '.twig'; $this->checkTemplateFile($template, 'Method\'s', $controllerClass); $actionOutput['data'] = $actionOutput['data'] ?? []; $output = [ @@ -155,7 +157,7 @@ private function renderResponse(int $returnType, array $actionOutput, string $co ]; $output['app']['_content'] = $this->view->render($template, $actionOutput['data']); $mainTemplateName = $actionOutput['meta']['layout'] ?? 'default'; - $mainTemplate = '_' . strtolower($mainTemplateName) . '.twig'; + $mainTemplate = '_' . CaseConverter::toSnakeCase($mainTemplateName) . '.twig'; $this->checkTemplateFile($mainTemplate, 'Layout', $controllerClass); $this->contentType = $returnType; if ($returnType === Selami\Router::CUSTOM) { @@ -164,7 +166,6 @@ private function renderResponse(int $returnType, array $actionOutput, string $co $this->body = $this->view->render($mainTemplate, $output); } - public function notFound($status = 404, $returnType = Selami\Router::HTML, $message = 'Not Found') : void { if ($returnType === Selami\Router::JSON) { diff --git a/src/Interfaces/Application.php b/src/Interfaces/Application.php index e469534..83437af 100644 --- a/src/Interfaces/Application.php +++ b/src/Interfaces/Application.php @@ -7,6 +7,5 @@ interface Application { - public function respond(): array; - public static function factory(ContainerInterface $container, ?array $args) : Application; + public function __invoke(): array; }