Max F před 5 roky
rodič
revize
740009b5e1

+ 6 - 0
src/App.php

@@ -285,6 +285,12 @@ class App
 	}
 
 
+	public static function isCli()
+	{
+		return (php_sapi_name() == 'cli');
+	}
+
+
 	public static function getApp()
 	{
 		if (isset(self::$instance)) {

+ 31 - 10
src/App/Middlewares/ErrorHandler.php

@@ -10,13 +10,23 @@ use \KarmaFW\App\ResponseError404;
 
 class ErrorHandler
 {
+    protected $use_internal_handler;
+    protected $use_whoops_handler;
     
+
+    public function __construct($use_internal_handler=true, $use_whoops_handler=false)
+    {
+        $this->use_internal_handler = $use_internal_handler;
+        $this->use_whoops_handler = $use_whoops_handler;
+    }
+
+
     public function __invoke(Request $request, Response $response, callable $next)
     {
         //set_error_handler(['ErrorHandler', 'display']);
         //set_exception_handler(['ExceptionHandler', 'display']);
 
-        if (false) {
+        if ($this->use_whoops_handler) {
             $whoops = new \Whoops\Run;
             $whoops->prependHandler(new \Whoops\Handler\PrettyPageHandler);
             $whoops->register();
@@ -28,21 +38,32 @@ class ErrorHandler
         } catch (\Throwable $e) {
             $code = $e->getCode();
             $error_message = $e->getMessage();
+
+            /*
+            if ($code == 404) {
+                return new ResponseError404($error_message);
+            }
+            */
+
+            if (! $this->use_internal_handler) {
+                throw $e;
+            }
             
-            //throw $e;
-            $content = null;
+            error_log("[UrlRouter] Error 500 : " . $error_message);
+
 
             if (ENV == 'dev') {
-                //$title = "ErrorHandler CATCHED EXCEPTION";
-                //$message = '<pre>' . print_r($e, true) . '</pre>';
-                //$content = '<title>' . $title . '</title><h1>' . $title . '</h1><p>' . $message . '</p>';
-            }
+                $title = "ErrorHandler CATCHED EXCEPTION";
+                $message = '<pre>' . print_r($e, true) . '</pre>';
+                $response_content = '<title>' . $title . '</title><h1>' . $title . '</h1><h2>' . $error_message . '</h2><p>' . $message . '</p>';
 
-            if ($code == 404) {
-                return new ResponseError404($error_message);
+            } else {
+                $title = "Server Error";
+                $message = 'An error has occured';
+                $response_content = '<title>' . $title . '</title><h1>' . $title . '</h1><p>' . $message . '</p>';
             }
 
-            return new ResponseError(500, $content);
+            return new ResponseError(500, $response_content);
         }
 
         return $response;

+ 11 - 1
src/App/Middlewares/GzipEncoding.php

@@ -11,8 +11,18 @@ class GzipEncoding
 	
 	public function __invoke(Request $request, Response $response, callable $next)
 	{
+		$response = $next($request, $response);
 
-		return $next($request, $response);
+		$content = (string) gzencode($response->getBody());
+
+		if (strlen($content) > 1000) {
+			$response->setBody($content);
+
+			$response->addHeader('Content-Encoding', 'gzip');
+			$response->addHeader('X-Encoding', 'gzip');
+		}
+
+		return $response;
 	}
 
 }

+ 16 - 1
src/App/Middlewares/MaintenanceMode.php

@@ -4,15 +4,30 @@ namespace KarmaFW\App\Middlewares;
 
 use \KarmaFW\App\Request;
 use \KarmaFW\App\Response;
+use \KarmaFW\App\ResponseError;
 
 
 class MaintenanceMode
 {
+	protected $maintenance_active = true;
+
 	
+	public function __construct($active=true)
+	{
+		$this->maintenance_active = $active;
+	}
+
+
 	public function __invoke(Request $request, Response $response, callable $next)
 	{
+		if (! $this->maintenance_active) {
+			return $next($request, $response);
+		}
+
+		$content = '<html><head><title>Service en maintenance</title><head><body><h1>Service en maintenance</h1></body></html>';
 
-		return $next($request, $response);
+		$response = new ResponseError(503, $content);
+		return $response;
 	}
 
 }

+ 44 - 10
src/App/Middlewares/UrlRouter.php

@@ -13,7 +13,15 @@ use \KarmaFW\Routing\Router;
 
 class UrlRouter
 {
-	
+	protected $catch_exceptions;
+
+
+	public function __construct($catch_exceptions=false)
+	{
+		$this->catch_exceptions = $catch_exceptions;
+	}
+
+
 	public function __invoke(Request $request, Response $response, callable $next)
 	{
 		// LOAD ROUTES
@@ -41,27 +49,53 @@ class UrlRouter
 		} catch (\Throwable $e) {
 			$code = $e->getCode();
 			$error_message = $e->getMessage();
+			$is_response = is_a($e, Response::class);
 
-			//throw $e;
-			$content = null;
-
-			if (ENV == 'dev') {
-				//$title = "UrlRouter CATCHED EXCEPTION";
-				//$message = '<pre>' . print_r($e, true) . '</pre>';
-				//$content = '<title>' . $title . '</title><h1>' . $title . '</h1><p>' . $message . '</p>';
-				//$error_message .= PHP_EOL . '<pre>' . print_r($e, true) . '</pre>';
+			if ($is_response) {
+				// exception is in reality a Response
+				return $e;
 			}
 
 			if (in_array($code, [301, 302, 310])) {
+				// if $code is a redirection
 				$url = $error_message;
 				return new ResponseRedirect($url, $code);
 			}
 
+			// ERROR 404
 			if ($code == 404) {
+				// if $code is a 404 page not found
+				if (empty($error_message)) {
+					$error_message = '<title>Not Found</title><h1>Not Found</h1>';
+				}
 				return new ResponseError404($error_message);
 			}
 
-			return new ResponseError(500, $error_message);
+
+			// ERROR 500
+
+			if (! $this->catch_exceptions) {
+				// on relance l'exception => pour laisser la gestion de l'erreur à un handler parent (ou le error_handler par defaut de PHP)
+				throw $e;
+			}
+
+			error_log("[UrlRouter] Error 500 : " . $error_message);
+
+
+            if (ENV == 'dev') {
+                $title = "UrlRouter CATCHED EXCEPTION";
+                $message = '<pre>' . print_r($e, true) . '</pre>';
+                $response_content = '<title>' . $title . '</title><h1>' . $title . '</h1><h2>' . $error_message . '</h2><p>' . $message . '</p>';
+
+            } else {
+                $title = "Server Error";
+                $message = 'An error has occured';
+                $response_content = '<title>' . $title . '</title><h1>' . $title . '</h1><p>' . $message . '</p>';
+            }
+
+
+			// else => error 500
+			return new ResponseError(500, $response_content);
 		}
 
 		return $response;

+ 38 - 1
src/App/Response.php

@@ -2,10 +2,12 @@
 
 namespace KarmaFW\App;
 
+use KarmaFW\App;
+
 // TODO: a remplacer par ou rendre compatible avec GuzzleHttp\Psr7\Response
 
 
-class Response
+class Response extends \Exception
 {
 	protected $headers = [];
 	protected $body = '';
@@ -14,6 +16,9 @@ class Response
 	protected $content_type = '';
 	protected $headers_sent = false;
 	protected $protocol = null;
+	protected $template_path = null;
+	protected $template_data = [];
+
 
 	/* public */ const http_status_codes = [
 		100 => 'Continue',
@@ -97,6 +102,26 @@ class Response
 		$this->content_type = $content_type;
 	}
 
+	public function getTemplatePath()
+	{
+		return $this->template_path;
+	}
+
+	public function setTemplatePath($template_path)
+	{
+		$this->template_path = $template_path;
+	}
+
+	public function getTemplateData()
+	{
+		return $this->template_data;
+	}
+
+	public function setTemplateData($template_data)
+	{
+		$this->template_data = $template_data;
+	}
+
 	public function getContent()
 	{
 		// DEPRECATED
@@ -144,6 +169,14 @@ class Response
 		//return $this->headers = $headers;
 		$this->headers = [];
 		foreach ($headers as $k => $v) {
+			if (is_numeric($k)) {
+				if (strpos($v, ':') === false) {
+					continue;
+				}
+				$parts = explode(':', $v);
+				$k = trim($parts[0]);
+				$v = trim($parts[1]);
+			}
 			$this->addHeader($k, $v);
 		}
 	}
@@ -157,6 +190,10 @@ class Response
 
 	public function sendHeaders()
 	{
+		if (App::isCli()) {
+			return;
+		}
+
 		if ($this->headers_sent) {
 			//error_log("Warning: headers already sent");
 			return;

+ 5 - 1
src/App/ResponseError.php

@@ -14,8 +14,12 @@ class ResponseError extends ResponseText
 		parent::__construct($body, $status, $content_type);
 
 		if (is_null($body)) {
-			$this->body  = '<title>' . $this->status . " " . $this->reasonPhrase . '</title>';
+			$this->body = '<html>';
+			$this->body .= '<head><title>' . $this->status . " " . $this->reasonPhrase . '</title></head>';
+			$this->body .= '<body>';
 			$this->body .= '<h1>' . $this->status . " " . $this->reasonPhrase . '</h1>';
+			$this->body .= '</body>';
+			$this->body .= '</html>';
 		}
 
 		$this->setStatus($status);

+ 2 - 2
src/App/ResponseError404.php

@@ -9,9 +9,9 @@ class ResponseError404 extends ResponseError
 	protected $status_name = 'Not Found';
 
 
-	public function __construct($content=null, $content_type='text/html')
+	public function __construct($body=null, $content_type='text/html')
 	{
-		parent::__construct($this->status, $content, $content_type);
+		parent::__construct($this->status, $body, $content_type);
 	}
 
 }

+ 6 - 0
src/App/ResponseFile.php

@@ -2,6 +2,8 @@
 
 namespace KarmaFW\App;
 
+use KarmaFW\App;
+
 
 class ResponseFile extends Response
 {
@@ -18,6 +20,10 @@ class ResponseFile extends Response
 
 	public function sendHeaders()
 	{
+		if (App::isCli()) {
+			return;
+		}
+
 		if ($this->headers_sent) {
 			// Warning: headers already sent
 			//error_log("Warning: headers already sent");

+ 12 - 5
src/App/ResponseRedirect.php

@@ -2,10 +2,12 @@
 
 namespace KarmaFW\App;
 
+use KarmaFW\App;
+
 
 class ResponseRedirect extends Response
 {
-	protected $url = null;
+	protected $redirect_url = null;
 	protected $status = 302;
 
 
@@ -13,22 +15,27 @@ class ResponseRedirect extends Response
 	{
 		parent::__construct($status);
 
-		$this->url = $url;
+		$this->redirect_url = $url;
 	}
 
 
 	public function sendHeaders()
 	{
+		if (App::isCli()) {
+			echo "# HTTP REDIRECTION " . $this->status . " TO " . $this->redirect_url . PHP_EOL;
+			return;
+		}
+
 		if ($this->headers_sent || headers_sent()) {
 			//error_log("Warning: headers already sent");
-			$this->content = '<meta http-equiv="refresh" content="0;URL=' . htmlspecialchars($this->url) . '">';
-			//$this->content = '<script>window.location.href = "' . $this->url . '";</script>';
+			$this->content = '<meta http-equiv="refresh" content="0;URL=' . htmlspecialchars($this->redirect_url) . '">';
+			//$this->content = '<script>window.location.href = "' . $this->redirect_url . '";</script>';
 			return;
 		}
 
 		$this->content = '';
 
-		$this->headers['Location'] = $this->url;
+		$this->headers['Location'] = $this->redirect_url;
 
 		parent::sendHeaders();
 	}

+ 3 - 2
src/App/ResponseText.php

@@ -8,9 +8,10 @@ class ResponseText extends Response
 
 	public function __construct($body=null, $status=200, $content_type='text/plain', $headers=[])
 	{
-		$headers['Content-Type'] = $content_type;
-
+		//$headers['Content-Type'] = $content_type;
 		parent::__construct($status, $headers, $body);
+
+		$this->content_type = $content_type;
 	}
 
 }

+ 20 - 1
src/helpers/helpers_array.php

@@ -1,6 +1,7 @@
 <?php
 
 use \KarmaFW\App;
+use \KarmaFW\App\ResponseText;
 use \PhpOffice\PhpSpreadsheet\IOFactory as PhpSpreadsheetIOFactory;
 
 
@@ -251,7 +252,8 @@ if (! function_exists('get_csv')) {
 if (! function_exists('exportToCsvFile')) {
 	function exportToCsvFile($rows, $export_filename=null, $fields=null) {
 		$csv_content = get_csv($rows, $fields);
-		
+
+		/*
 		if (! empty($export_filename)) {
 			// download file
 			header('Content-Type: text/csv');
@@ -265,6 +267,23 @@ if (! function_exists('exportToCsvFile')) {
 
 		echo $csv_content;
 		exit;
+		*/
+
+
+		if (! empty($export_filename)) {
+			$content_type = 'text/csv';
+			$headers = [
+				'Content-Disposition: attachment;filename=' . basename($export_filename),
+				"Pragma: no-cache",
+				"Expires: 0"
+			];
+
+		} else {
+			$headers = [];
+			$content_type = 'text/plain';
+		}
+
+		throw new ResponseText($csv_content, 200, $content_type, $headers);
 	}
 }
 

+ 16 - 2
src/helpers/helpers_default.php

@@ -1,5 +1,6 @@
 <?php
 
+use \KarmaFW\App\ResponseError;
 use \KarmaFW\Routing\Router;
 
 
@@ -39,10 +40,23 @@ if (! function_exists('ifEmpty')) {
 
 if (! function_exists('errorHttp')) {
 	function errorHttp($error_code, $message='An error has occured', $title='Error') {
+		/*
 		header("HTTP/1.0 " . $error_code . " " . $title);
 		echo '<h1>' . $title . '</h1>';
 		echo '<p>' . $message . '</p>';
 		exit;
+		*/
+		$content = '<html>';
+		$content .= '<head>';
+		$content .= '<title>' . $title . '</title>';
+		$content .= '</head>';
+		$content .= '<body>';
+		$content .= '<h1>' . $title . '</h1>';
+		$content .= '<p>' . $message . '</p>';
+		$content .= '</body>';
+		$content .= '</html>';
+
+		return new ResponseError($error_code, $content);
 	}
 }
 
@@ -53,9 +67,9 @@ if (! function_exists('redirect')) {
 			echo 'continue to <a href="' . $url . '">' . $url . '</a>';
 			exit;
 		}
-		header('Location: ' . $url, true, $http_code);
 		throw new \Exception($url, $http_code);
-		exit;
+		//exit;
+		//header('Location: ' . $url, true, $http_code);
 	}
 }