瀏覽代碼

dev 2020-10

Max F 5 年之前
父節點
當前提交
8ccaa6367e
共有 4 個文件被更改,包括 163 次插入26 次删除
  1. 27 14
      src/App/Middlewares/AuthBasic.php
  2. 7 3
      src/Http/Response.php
  3. 32 1
      src/Routing/Route.php
  4. 97 8
      src/Routing/Router.php

+ 27 - 14
src/App/Middlewares/AuthBasic.php

@@ -8,26 +8,39 @@ use \KarmaFW\Http\Response;
 
 class AuthBasic
 {
-	protected $method;
+    protected $method;
 
 
-	public function __construct($method='basic')
-	{
-		$this->method = $method;
-	}
+    public function __construct($method='basic')
+    {
+        $this->method = $method;
+    }
 
 
-	public function __invoke(Request $request, Response $response, callable $next)
-	{
-		$is_auth = false;
+    public function __invoke(Request $request, Response $response, callable $next)
+    {
+        $is_auth = 1;
 
-		//pre($request, 1);
+        $PHP_AUTH_USER = isset($request->SERVER['PHP_AUTH_USER']) ? $request->SERVER['PHP_AUTH_USER'] : null;
+        $PHP_AUTH_PW = isset($request->SERVER['PHP_AUTH_PW']) ? $request->SERVER['PHP_AUTH_PW'] : null;
 
-		if (! $is_auth) {
-			//return $response->redirect( getRouteUrl('login') );
-		}
+        if (! $PHP_AUTH_USER || ! $PHP_AUTH_PW) {
+            $is_auth = false;
+        }
 
-		return $next($request, $response);
-	}
+
+        // TODO: recuperer les identifiants valides dans une base de données ou un fichier de passwords
+
+
+        if ($is_auth) {
+            return $next($request, $response);
+
+        } else {
+            $response->addHeader('WWW-Authenticate', 'Basic realm="My Realm"');
+            $body = "Accès interdit";
+            return $response->setHtml($body, 401);
+        }
+    
+    }
 
 }

+ 7 - 3
src/Http/Response.php

@@ -168,9 +168,13 @@ class Response
 
 	public function setHtml($body, $status=200, $content_type='text/html')
 	{
-		return $this->setBody($body)
-				->setContentType($content_type)
-				->setStatus($status);
+		if (! is_null($status)) {
+			$this->setStatus($status);
+		}
+		if (! is_null($content_type)) {
+			$this->setContentType($content_type);
+		}
+		return $this->setBody($body);
 	}
 	
 	public function setJson($body, $status=200, $content_type='application/json')

+ 32 - 1
src/Routing/Route.php

@@ -19,6 +19,8 @@ class Route
 	private $get_prefix = null;
 	private $matched_prefix = '';
 	private $matched_params = [];
+	private $middlewares = [];
+	private $continue = false;
 
 
 	public function __construct()
@@ -86,6 +88,17 @@ class Route
 		return $this->matched_params;
 	}
 
+
+	public function setContinue(bool $continue)
+	{
+		$this->continue = $continue;
+	}
+
+	public function getContinue()
+	{
+		return $this->continue;
+	}
+
 	public function getMatchedPrefix()
 	{
 		return $this->matched_prefix;
@@ -103,6 +116,24 @@ class Route
 		$this->name = $name;
 	}
 
+	// Get middlewares
+	public function getMiddlewares()
+	{
+		return $this->middlewares;
+	}
+
+	// Set middlewares
+	public function setMiddlewares($middlewares)
+	{
+		$this->middlewares = $middlewares;
+	}
+
+	// Add middleware
+	public function addMiddleware($middleware)
+	{
+		$this->middlewares[] = $middleware;
+	}
+
 	// Set route callback
 	public function setCallback($callback)
 	{
@@ -156,7 +187,7 @@ class Route
 			//error500("get_prefix is not callable");
 			return null;
 		}
-		//pre($func, 1);
+		//pre($func); exit;
 		return $func();
 	}
 

+ 97 - 8
src/Routing/Router.php

@@ -3,6 +3,7 @@
 namespace KarmaFW\Routing;
 
 use \KarmaFW\WebApp;
+use \KarmaFW\App\Pipe;
 use \KarmaFW\Http\Request;
 use \KarmaFW\Http\Response;
 
@@ -12,6 +13,7 @@ class Router
 	private static $routes = [];
 	private static $routed_url = null;
 	private static $config = [];
+	private static $matched_route = null;
 
 
 	public static function config($config)
@@ -33,6 +35,8 @@ class Router
 	{
 		$old_config = self::$config;
 
+		//$middlewares = isset($config['middlewares']) ? $config['middlewares'] : [];
+
 		self::$config = $config;
 		$callable();
 		self::$config = $old_config;
@@ -44,18 +48,23 @@ class Router
 	{
 		$route = new Route();
 
+		$default_get_prefix = null;
+		$default_get_prefix = function () {
+			return Router::getMatchedRoute()->getMatchedPrefix();
+		};
+
 		if (! empty(self::$config['prefix'])) {
 			// ex: $prefix == "/fr"
 			$route->setPrefix(self::$config['prefix'], 'exact', self::$config['prefix']);
 		
 		} else if (! empty(self::$config['prefix_regex'])) {
 			// ex: $prefix == "/[a-zA-Z0-9-]+"
-			$get_prefix = empty(self::$config['get_prefix']) ? null : self::$config['get_prefix'];
+			$get_prefix = empty(self::$config['get_prefix']) ? $default_get_prefix : self::$config['get_prefix'];
 			$route->setPrefix(self::$config['prefix_regex'], 'regex', $get_prefix);
 
 		} else if (! empty(self::$config['prefix_array'])) {
 			// ex: $prefix == ["/fr", "/us"]
-			$get_prefix = empty(self::$config['get_prefix']) ? null : self::$config['get_prefix'];
+			$get_prefix = empty(self::$config['get_prefix']) ? $default_get_prefix : self::$config['get_prefix'];
 			$route->setPrefix(self::$config['prefix_array'], 'array', $get_prefix);
 		}
 
@@ -63,6 +72,14 @@ class Router
 			$route->setBeforeCallback(self::$config['before_callback']);
 		}
 
+		if (! empty(self::$config['middlewares'])) {
+			$route->setMiddlewares(self::$config['middlewares']);
+		}
+
+		if (isset(self::$config['continue'])) {
+			$route->setContinue(self::$config['continue']);
+		}
+
 		$route->setMatchUrl($url_match);
 		$route->setCallback($callback);
 		$route->setMatchType($type_match);
@@ -154,6 +171,8 @@ class Router
 					echo " => MATCH !<br />" . PHP_EOL;
 				}
 
+				self::$matched_route = $route;
+
 				$before_callback = $route->getBeforeCallback();
 				if (! empty($before_callback)) {
 					$before_callback($route);
@@ -216,6 +235,8 @@ class Router
 			$match = $route->match($request_method, $request_uri);
 
 			if ($match) {
+				self::$matched_route = $route;
+
 				$request->setRoute($route);
 
 				$before_callback = $route->getBeforeCallback();
@@ -227,17 +248,49 @@ class Router
 				if (empty($callback)) {
 					// route found but no callback defined
 					//return 0;
+
+					$continue = $request->getRoute()->getContinue();
+					
+					$response = self::requestRouteRun($route, null, $request, $response);
+					
+					//$middlewares_result = true; // TODO: $request->getRoute()->getMiddlewaresResult();
+
+					if ($continue && $response->getStatus() == 200) {
+						//$response = $response_old;
+						continue;
+					}
+
+					if ($response->getStatus() !== 200) {
+						return $response;
+					}
+
 					return $response->setHtml('<h1>Page not Found</h1><p>Warning: route found but no callback defined</p>', 404);
 
 				} else if (is_callable($callback)) {
 					// OK !
 					self::$routed_url = $route;
+					//$response_old = clone $response;
 					$response = self::requestRouteRun($route, $callback, $request, $response);
+					//pre($response, 1); exit;
+
+					if ($request->getRoute()->getContinue() && $response->getStatus() == 200) {
+						//$response = $response_old;
+						continue;
+					}
+
 					return $response;
 
 				} else {
 					// route found but callback is not callable
 					//return null;
+
+					$response = self::requestRouteRun($route, null, $request, $response);
+
+					if ($request->getRoute()->getContinue() && $response->getStatus() == 200) {
+						//$response = $response_old;
+						continue;
+					}
+
 					return $response->setHtml('<h1>Page not Found</h1><p>Warning: route callback is not callable</p>', 404);
 				}
 
@@ -251,22 +304,48 @@ class Router
 	}
 
 
-	public static function requestRouteRun(Route $route, callable $callback, Request $request, Response $response)
+	public static function requestRouteRun(Route $route, callable $callback=null, Request $request, Response $response)
 	{
 		$matched_params = $route->getMatchedParams();
+		$middlewares_result = ['success' => false];
 
-		if (gettype($callback) == 'array') {
+		if (empty($callback)) {
+			// do nothing
+			$route->addMiddleware(function () use ($request, $response, &$middlewares_result) {
+				$middlewares_result['success'] = true;
+				return $response;
+			});
+
+		} else if (gettype($callback) == 'array') {
 			//echo " => ARRAY !<br />" . PHP_EOL;
 			//pre($callback, 1);
 			$controller = new $callback[0]($request, $response);
 			WebApp::$controller = $controller;
 
-			$route_response = call_user_func([$controller, $callback[1]], $matched_params);
+			//$route_response = call_user_func([$controller, $callback[1]], $matched_params);
+			$route->addMiddleware(function () use ($controller, $callback, $matched_params, &$middlewares_result) {
+				$middlewares_result['success'] = true;
+				return call_user_func([$controller, $callback[1]], $matched_params);
+			});
 
 		} else {
 			//echo " => FUNCTION !<br />" . PHP_EOL;
 			//pre($callback, 1);
-			$route_response = $callback($request, $response, $matched_params);
+			//$route_response = $callback($request, $response, $matched_params);
+			$route->addMiddleware(function () use ($callback, $request, $response, $matched_params, &$middlewares_result) {
+				$middlewares_result['success'] = true;
+				return $callback($request, $response, $matched_params);
+			});
+		}
+
+		$pipe = new Pipe($route->getMiddlewares());
+		$route_response = $pipe->next($request, $response);
+
+		//pre($middlewares_result);
+		if (! $middlewares_result['success']) {
+			// TODO
+			$request->getRoute()->setContinue(false); // ?
+			//$request->getRoute()->setMiddlewaresResult(true); // ?
 		}
 
 		if (is_object($route_response) && get_class($route_response) === Response::class) {
@@ -318,8 +397,12 @@ class Router
 		//pre($route, 1);
 
 
-		$get_prefix = $route->getCallbackGetPrefix();
-		//pre($get_prefix, 0, 'get_prefix: ');
+		$get_prefix = null;
+		if (true) {
+			//$get_prefix = self::$matched_route->getCallbackGetPrefix();
+			$get_prefix = $route->getCallbackGetPrefix();
+			//pre($get_prefix, 0, 'get_prefix: ');
+		}
 
 		$link = $route->getMatchUrl();
 		if ($get_prefix) {
@@ -366,4 +449,10 @@ class Router
 		return self::$routed_url;
 	}
 
+
+	public static function getMatchedRoute()
+	{
+		return self::$matched_route;
+	}
+
 }