diff --git a/composer.json b/composer.json index 0df9533..9fc4dfb 100644 --- a/composer.json +++ b/composer.json @@ -14,20 +14,19 @@ ], "require": { "php": "^7.1", + "psr/container": "^1.0", "selami/router": "^0.2", "selami/views": "^0.1", - "psr/container": "^1.0", - "zendframework/zend-diactoros": "~1.3.9", - "zendframework/zend-config": "^3.1", - "symfony/http-foundation": "~3.2.2" + "zendframework/zend-diactoros": "^1.3", + "zendframework/zend-servicemanager": "^3.0", + "zendframework/zend-config": "^3.1" }, "require-dev": { "phpunit/phpunit": "^6.0", "satooshi/php-coveralls": "~1.0", "phpunit/phpcov": "^4.0", "squizlabs/php_codesniffer": "^2.0", - "zendframework/zend-servicemanager": "^3.0", - "zendframework/zend-stdlib": "^3.1" + "symfony/http-foundation": "^3.2" }, "autoload": { "psr-4": { diff --git a/src/Core/App.php b/src/Foundation/App.php similarity index 67% rename from src/Core/App.php rename to src/Foundation/App.php index ff7d436..004a01a 100644 --- a/src/Core/App.php +++ b/src/Foundation/App.php @@ -9,13 +9,12 @@ */ -namespace Selami\Core; +namespace Selami\Foundation; use Selami\Router; use Psr\Container\ContainerInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; -use Symfony\Component\HttpFoundation\Session\Session as SymfonySession; use Selami\Http\Psr7Response; use Zend\Config\Config as ZendConfig; @@ -37,31 +36,32 @@ class App 'aliases' => [] ]; */ - + /** + * @var ContainerInterface + */ private $container; + /** + * @var ZendConfig + */ private $config; /** - * ServerRequest - * - * @var ServerRequestInterface + * @var array */ - private $request; private $route; - private $session; + + /** + * @var array + */ private $response; public function __construct( ZendConfig $config, - ServerRequestInterface $request, Router $router, - SymfonySession $session, ContainerInterface $container ) { - - $this->request = $request; + $this->config = $config; $this->route = $router->getRoute(); - $this->session = $session; $this->container = $container; } @@ -69,9 +69,7 @@ public static function selamiApplicationFactory(ContainerInterface $container) : { return new App( $container->get(ZendConfig::class), - $container->get(ServerRequestInterface::class), $container->get(Router::class), - $container->get(SymfonySession::class), $container ); } @@ -81,7 +79,6 @@ public function __invoke( ResponseInterface $response, callable $next = null ) : ResponseInterface { - $this->request = $request; $this->run(); $psr7Response = new Psr7Response; $response = $psr7Response($response, $this->response); @@ -93,24 +90,14 @@ public function __invoke( private function run() : void { - $this->startSession(); $this->runDispatcher($this->route['route']); } - private function startSession() :void - { - ini_set('session.use_cookies', '1'); - ini_set('session.use_only_cookies', '1'); - ini_set('session.cookie_httponly', '1'); - ini_set('session.name', 'SELAMISESSID'); - if (!$this->session->isStarted()) { - $this->session->start(); - } - } + private function runDispatcher(array $route) : void { - $this->response = new Result($this->container, $this->session); + $this->response = new Response($this->container); $defaultReturnType = $this->config->app->get('default_return_type', 'html'); switch ($route['status']) { case 405: @@ -126,23 +113,16 @@ private function runDispatcher(array $route) : void } } - private function runRoute(string $controller, string $returnType = 'html', ?array $args) : void + private function runRoute(string $controllerClass, string $returnType = 'html', ?array $args) : void { - if (!class_exists($controller)) { - $message = "Controller has not class name as {$controller}"; + if (!class_exists($controllerClass)) { + $message = "Controller has not class name as {$controllerClass}"; throw new \BadMethodCallException($message); } - $controllerInstance = new $controller($this->container, $args); - if (method_exists($controllerInstance, 'applicationLoad')) { - $controllerInstance->applicationLoad(); - } - if (method_exists($controllerInstance, 'controllerLoad')) { - $controllerInstance->controllerLoad(); - } - $functionOutput = $controllerInstance(); - + $controller = $controllerClass::factory($this->container, $args); + $functionOutput = $controller->respond(); $returnFunction = 'return' . ucfirst($returnType); - $this->response->$returnFunction($functionOutput, $controller); + $this->response->$returnFunction($functionOutput, $controllerClass); } public function getResponse() : array diff --git a/src/Core/Result.php b/src/Foundation/Response.php similarity index 61% rename from src/Core/Result.php rename to src/Foundation/Response.php index cb4acbf..6d0508f 100644 --- a/src/Core/Result.php +++ b/src/Foundation/Response.php @@ -1,7 +1,7 @@ 200, - 'headers' => [], - 'cookies' => null, - 'body' => '', - 'data' => null, - 'contentType' => 'html', - 'redirect' => null - ]; - - public function __construct(ContainerInterface $container, Session $session) + /** + * @var int + */ + private $statusCode = 200; + /** + * @var array + */ + private $headers = []; + /** + * @var array + */ + private $cookies = []; + /** + * @var string + */ + private $body = ''; + + /** + * @var array + */ + private $data = []; + /** + * @var string + */ + private $contentType = 'html'; + + /** + * @var string + */ + private $redirect; + + public function __construct(ContainerInterface $container) { $this->container = $container; $this->config = $container->get(ZendConfig::class); - $this->session =$session; } private function checkTemplateFile($template, $type, $controller) : void @@ -47,21 +67,21 @@ private function checkTemplateFile($template, $type, $controller) : void public function returnRedirect(array $functionOutput, string $controller) : void { - $this->result['contentType'] = 'redirect'; + $this->contentType = 'redirect'; if (isset($functionOutput['redirect'])) { - $this->result['contentType'] = 'redirect'; - $this->result['status'] = 301; - $this->result['redirect'] = $functionOutput['redirect']; + $this->contentType = 'redirect'; + $this->statusCode = 301; + $this->redirect = $functionOutput['redirect']; } } - public function returnJson(array $functionOutput, string $controller) : void + public function returnJson(array $functionOutput, string $controllerClass) : void { - $this->result['contentType'] = 'json'; + $this->contentType = 'json'; if (isset($functionOutput['redirect'])) { - $this->result['contentType'] = 'redirect'; - $this->result['status'] = 301; - $this->result['redirect'] = $functionOutput['redirect']; + $this->contentType = 'redirect'; + $this->statusCode = 301; + $this->redirect = $functionOutput['redirect']; } if (!is_array($functionOutput)) { $functionOutput = ['status' => 500, 'error' => 'Internal Server Error']; @@ -69,73 +89,75 @@ public function returnJson(array $functionOutput, string $controller) : void $functionOutput['status'] = 200; } $status = (int) $functionOutput['status']; - $this->result['statusCode'] = $status; - $this->result['data'] = $functionOutput; + $this->statusCode = $status; + $this->data = $functionOutput; } - public function returnHtml(array $functionOutput, string $controller) : void + public function returnHtml(array $functionOutput, string $controllerClass) : void { + $this->useSession(); $this->useView($this->container->get(ViewInterface::class)); - $paths = explode("\\", $controller); + $paths = explode("\\", $controllerClass); $templateFile = array_pop($paths); $templateFolder = array_pop($paths); $template = strtolower($templateFolder) . '/' . strtolower($templateFile) . '.twig'; if (isset($functionOutput['redirect'])) { - $this->result['contentType'] = 'redirect'; - $this->result['status'] = 301; - $this->result['redirect'] = $functionOutput['redirect']; + $this->contentType = 'redirect'; + $this->statusCode = 301; + $this->redirect = $functionOutput['redirect']; } $this->view->addGlobal('defined', get_defined_constants(true)['user'] ?? []); $this->view->addGlobal('session', $this->session->all()); - $this->checkTemplateFile($template, 'Method\'s', $controller); + $this->checkTemplateFile($template, 'Method\'s', $controllerClass); $functionOutput['data'] = $functionOutput['data'] ?? []; $functionOutput['app_content'] = $this->view->render($template, $functionOutput['data']); $mainTemplateName = $functionOutput['app_main_template'] ?? 'default'; $mainTemplate = '_' . strtolower($mainTemplateName) . '.twig'; - $this->checkTemplateFile($mainTemplate, 'Main', $controller); - $this->result['body'] = $this->view->render($mainTemplate, $functionOutput); + $this->checkTemplateFile($mainTemplate, 'Main', $controllerClass); + $this->body = $this->view->render($mainTemplate, $functionOutput); } - public function returnText(array $functionOutput, string $controller) : void + public function returnText(array $functionOutput, string $controllerClass) : void { + $this->useSession(); $this->useView($this->container->get(ViewInterface::class)); - $paths = explode("\\", $controller); + $paths = explode("\\", $controllerClass); $templateFile = array_pop($paths); $templateFolder = array_pop($paths); $template = strtolower($templateFolder) . '/' . strtolower($templateFile) . '.twig'; if (isset($functionOutput['redirect'])) { - $this->result['contentType'] = 'redirect'; - $this->result['status'] = 301; - $this->result['redirect'] = $functionOutput['redirect']; + $this->contentType = 'redirect'; + $this->statusCode = 301; + $this->redirect = $functionOutput['redirect']; } $this->view->addGlobal('defined', get_defined_constants(true)['user'] ?? []); $this->view->addGlobal('session', $this->session->all()); - $this->checkTemplateFile($template, 'Method\'s', $controller); + $this->checkTemplateFile($template, 'Method\'s', $controllerClass); $functionOutput['data'] = $functionOutput['data'] ?? []; $functionOutput['app_content'] = $this->view->render($template, $functionOutput['data']); $mainTemplateName = $functionOutput['layout'] ?? 'default'; $mainTemplate = '_' . strtolower($mainTemplateName) . '.twig'; - $this->checkTemplateFile($mainTemplate, 'Main', $controller); - $this->result['contentType'] = 'text'; - $this->result['body'] = $this->view->render($mainTemplate, $functionOutput); + $this->checkTemplateFile($mainTemplate, 'Main', $controllerClass); + $this->contentType = 'text'; + $this->body = $this->view->render($mainTemplate, $functionOutput); } public function notFound($status = 404, $returnType = 'html', $message = 'Not Found') : void { if ($returnType == 'json') { - $this->result['body'] = ['status' => $status, 'message' => $message]; + $this->body = ['status' => $status, 'message' => $message]; } else { $this->useView($this->container->get('view')); $notFoundTemplate = '_404.twig'; - $this->result['contentType'] = $returnType; - $this->result['body'] = $this->view->render( + $this->contentType = $returnType; + $this->body = $this->view->render( $notFoundTemplate, ['message' => $message, 'status' => $status] ); } - $this->result['statusCode']=$status; + $this->statusCode = $status; } private function useView(ViewInterface $view) : void @@ -143,15 +165,20 @@ private function useView(ViewInterface $view) : void $this->view = $view; } + private function useSession() : void + { + $this->session = $this->container->get(Session::class); + } + private function setHeaders() : void { - $this->result['headers']['X-Powered-By'] = 'r/selami'; - $this->result['headers']['X-Frame-Options'] = 'SAMEORIGIN'; - $this->result['headers']['X-XSS-Protection'] = '1; mode=block'; - $this->result['headers']['Strict-Transport-Security'] = 'max-age=31536000'; + $this->headers['X-Powered-By'] = 'r/selami'; + $this->headers['X-Frame-Options'] = 'SAMEORIGIN'; + $this->headers['X-XSS-Protection'] = '1; mode=block'; + $this->headers['Strict-Transport-Security'] = 'max-age=31536000'; if (array_key_exists('headers', $this->config) && is_array($this->config['headers'])) { foreach ($this->config['headers'] as $header => $value) { - $this->result['headers'][$header] = $value; + $this->headers[$header] = $value; } } } @@ -160,31 +187,39 @@ public function getResponse() : array { $headers = $this->config['headers'] ?? null; $this->setHeaders($headers); - return $this->result; + return [ + 'statusCode' => $this->statusCode, + 'headers' => $this->headers, + 'cookies' => $this->cookies, + 'body' => (string) $this->body, + 'data' => $this->data, + 'contentType' => $this->contentType, + 'redirect' => $this->redirect + ]; } public function sendResponse() : void { $response = new s\Http\Response(); - $response->setHeaders($this->result['headers']); - $response->setStatusCode($this->result['statusCode']); - switch ($this->result['contentType']) { + $response->setHeaders($this->headers); + $response->setStatusCode($this->statusCode); + switch ($this->contentType) { case 'redirect': $response->setOutputType('redirect'); - $response->setRedirect($this->result['redirect']); + $response->setRedirect($this->redirect); break; case 'json': $response->setOutputType('json'); - $response->setData($this->result['data']); + $response->setData($this->data); break; case 'text': $response->setOutputType('text'); - $response->setBody($this->result['body']); + $response->setBody($this->body); break; case 'html': default: $response->setOutputType('html'); - $response->setBody($this->result['body']); + $response->setBody($this->body); break; } $response->send(); diff --git a/src/Interfaces/Application.php b/src/Interfaces/Application.php index dfbb851..3e554ab 100644 --- a/src/Interfaces/Application.php +++ b/src/Interfaces/Application.php @@ -3,8 +3,10 @@ namespace Selami\Interfaces; +use Psr\Container\ContainerInterface; interface Application { - public function __invoke(); + public function respond(): array; + public static function factory(ContainerInterface $container, ?array $args) : Application; } \ No newline at end of file