|  | @@ -4,6 +4,7 @@ namespace Luticate\Utils\Controller;
 | 
		
	
		
			
			| 4 | 4 |  
 | 
		
	
		
			
			| 5 | 5 |  use FastRoute\Dispatcher;
 | 
		
	
		
			
			| 6 | 6 |  use Luticate\Utils\Business\LuBusinessException;
 | 
		
	
		
			
			|  | 7 | +use Luticate\Utils\Business\LuInjector;
 | 
		
	
		
			
			| 7 | 8 |  use Luticate\Utils\Business\LuMethodDocParser;
 | 
		
	
		
			
			| 8 | 9 |  use Luticate\Utils\Dbo\LuDboConstraintException;
 | 
		
	
		
			
			| 9 | 10 |  use Luticate\Utils\Dbo\LuDboDeserializeException;
 | 
		
	
	
		
			
			|  | @@ -83,86 +84,42 @@ class LuRoute {
 | 
		
	
		
			
			| 83 | 84 |           * @var $middlewareDbo LuMiddlewareDbo
 | 
		
	
		
			
			| 84 | 85 |           */
 | 
		
	
		
			
			| 85 | 86 |          foreach (array_merge($this->_middlewares, $route->getMiddlewares()) as $middlewareDbo) {
 | 
		
	
		
			
			| 86 |  | -            $middlewareName = $middlewareDbo->getMiddleware();
 | 
		
	
		
			
			| 87 | 87 |              /**
 | 
		
	
		
			
			| 88 | 88 |               * @var $middleware LuAbstractMiddleware
 | 
		
	
		
			
			| 89 | 89 |               */
 | 
		
	
		
			
			|  | 90 | +            $middlewareName = $middlewareDbo->getMiddleware();
 | 
		
	
		
			
			| 90 | 91 |              $middleware = new $middlewareName();
 | 
		
	
		
			
			| 91 |  | -            $parameters["_middleware"] = $middlewareDbo->getParameters();
 | 
		
	
		
			
			| 92 |  | -            foreach ($route->getParameters() as $key => $value) {
 | 
		
	
		
			
			| 93 |  | -                $parameters["_middleware"][$key] = $value;
 | 
		
	
		
			
			|  | 92 | +
 | 
		
	
		
			
			|  | 93 | +            $args = array_merge($middlewareDbo->getParameters(), $route->getParameters());
 | 
		
	
		
			
			|  | 94 | +            $args["_route"] = $route;
 | 
		
	
		
			
			|  | 95 | +            $args["_parameters"] = $parameters;
 | 
		
	
		
			
			|  | 96 | +            $args["_all"] = $args;
 | 
		
	
		
			
			|  | 97 | +
 | 
		
	
		
			
			|  | 98 | +            if (is_callable([$middleware, "onBefore"])) {
 | 
		
	
		
			
			|  | 99 | +                $parameters = LuInjector::inject($middleware, "onBefore", $args);
 | 
		
	
		
			
			| 94 | 100 |              }
 | 
		
	
		
			
			| 95 |  | -            $parameters = $middleware->onBefore($route, $parameters);
 | 
		
	
		
			
			|  | 101 | +
 | 
		
	
		
			
			| 96 | 102 |              $middlewares[] = [
 | 
		
	
		
			
			| 97 | 103 |                  'middleware' => $middleware,
 | 
		
	
		
			
			| 98 | 104 |                  'dbo' => $middlewareDbo
 | 
		
	
		
			
			| 99 | 105 |              ];
 | 
		
	
		
			
			| 100 | 106 |          }
 | 
		
	
		
			
			| 101 |  | -        unset($parameters["_middleware"]);
 | 
		
	
		
			
			| 102 |  | -
 | 
		
	
		
			
			| 103 |  | -        $reflect = new \ReflectionMethod($route->getController(), $route->getAction());
 | 
		
	
		
			
			| 104 |  | -        $params = $reflect->getParameters();
 | 
		
	
		
			
			| 105 |  | -        $docs = new LuMethodDocParser($reflect->getDocComment());
 | 
		
	
		
			
			| 106 |  | -        $docs->parse();
 | 
		
	
		
			
			| 107 |  | -
 | 
		
	
		
			
			| 108 |  | -        $args = array();
 | 
		
	
		
			
			| 109 |  | -        foreach ($params as $param) {
 | 
		
	
		
			
			| 110 |  | -
 | 
		
	
		
			
			| 111 |  | -            try {
 | 
		
	
		
			
			| 112 |  | -                if ($param->isOptional()) {
 | 
		
	
		
			
			| 113 |  | -                    $value = null;
 | 
		
	
		
			
			| 114 |  | -                    if (array_key_exists($param->getName(), $parameters)) {
 | 
		
	
		
			
			| 115 |  | -                        $value = $this->getParam($param, $parameters[$param->getName()]);
 | 
		
	
		
			
			| 116 |  | -                    }
 | 
		
	
		
			
			| 117 |  | -                    else {
 | 
		
	
		
			
			| 118 |  | -                        $value = $param->getDefaultValue();
 | 
		
	
		
			
			| 119 |  | -                    }
 | 
		
	
		
			
			| 120 |  | -                }
 | 
		
	
		
			
			| 121 |  | -                else {
 | 
		
	
		
			
			| 122 |  | -                    if (array_key_exists($param->getName(), $parameters)) {
 | 
		
	
		
			
			| 123 |  | -                        $value = $this->getParam($param, $parameters[$param->getName()]);
 | 
		
	
		
			
			| 124 |  | -                    }
 | 
		
	
		
			
			| 125 |  | -                    else {
 | 
		
	
		
			
			| 126 |  | -                        throw new LuDboDeserializeException("Missing parameter '" . $param->getName() . "'", 400);
 | 
		
	
		
			
			| 127 |  | -                    }
 | 
		
	
		
			
			| 128 |  | -                }
 | 
		
	
		
			
			| 129 | 107 |  
 | 
		
	
		
			
			| 130 |  | -                if (array_key_exists($param->getName(), $docs->getParams())) {
 | 
		
	
		
			
			| 131 |  | -                    $doc = $docs->getParams()[$param->getName()];
 | 
		
	
		
			
			| 132 |  | -                    if (is_null($value) && $doc->isNotNull()) {
 | 
		
	
		
			
			| 133 |  | -                        throw new LuDboConstraintException("Parameter '" . $param->getName() . "' can not be null", 400);
 | 
		
	
		
			
			| 134 |  | -                    }
 | 
		
	
		
			
			| 135 |  | -
 | 
		
	
		
			
			| 136 |  | -                    if (!is_null($value)) {
 | 
		
	
		
			
			| 137 |  | -                        $value->checkConstraints($doc->getConstraints());
 | 
		
	
		
			
			| 138 |  | -                    }
 | 
		
	
		
			
			| 139 |  | -                }
 | 
		
	
		
			
			| 140 |  | -                $args[$param->getName()] = $value;
 | 
		
	
		
			
			| 141 |  | -            }
 | 
		
	
		
			
			| 142 |  | -            catch (LuDboConstraintException $e)
 | 
		
	
		
			
			| 143 |  | -            {
 | 
		
	
		
			
			| 144 |  | -                $paramName = $param->getName();
 | 
		
	
		
			
			| 145 |  | -                throw new LuBusinessException("Invalid value for '${paramName}': " . $e->getMessage(), 400, $e);
 | 
		
	
		
			
			| 146 |  | -            }
 | 
		
	
		
			
			| 147 |  | -            catch (LuDboDeserializeException $e)
 | 
		
	
		
			
			| 148 |  | -            {
 | 
		
	
		
			
			| 149 |  | -                $paramName = $param->getName();
 | 
		
	
		
			
			| 150 |  | -                throw new LuBusinessException("Failed to deserialize '${paramName}': " . $e->getMessage(), 400, $e);
 | 
		
	
		
			
			| 151 |  | -            }
 | 
		
	
		
			
			| 152 |  | -        }
 | 
		
	
		
			
			| 153 |  | -
 | 
		
	
		
			
			| 154 |  | -        $controller = $route->getController();
 | 
		
	
		
			
			| 155 |  | -        $controllerInstance = new $controller();
 | 
		
	
		
			
			| 156 |  | -        $result = call_user_func_array(array($controllerInstance, $route->getAction()), $args);
 | 
		
	
		
			
			|  | 108 | +        $result = LuInjector::inject($route->getController(), $route->getAction(), $parameters);
 | 
		
	
		
			
			| 157 | 109 |  
 | 
		
	
		
			
			| 158 | 110 |          foreach ($middlewares as $middlewareArray) {
 | 
		
	
		
			
			| 159 | 111 |              $middleware = $middlewareArray['middleware'];
 | 
		
	
		
			
			| 160 | 112 |              $middlewareDbo = $middlewareArray['dbo'];
 | 
		
	
		
			
			| 161 |  | -            $parameters["_middleware"] = $middlewareDbo->getParameters();
 | 
		
	
		
			
			| 162 |  | -            foreach ($route->getParameters() as $key => $value) {
 | 
		
	
		
			
			| 163 |  | -                $parameters["_middleware"][$key] = $value;
 | 
		
	
		
			
			|  | 113 | +
 | 
		
	
		
			
			|  | 114 | +            $args = array_merge($middlewareDbo->getParameters(), $route->getParameters());
 | 
		
	
		
			
			|  | 115 | +            $args["_route"] = $route;
 | 
		
	
		
			
			|  | 116 | +            $args["_parameters"] = $parameters;
 | 
		
	
		
			
			|  | 117 | +            $args["_result"] = $result;
 | 
		
	
		
			
			|  | 118 | +            $args["_all"] = $args;
 | 
		
	
		
			
			|  | 119 | +
 | 
		
	
		
			
			|  | 120 | +            if (is_callable([$middleware, "onAfter"])) {
 | 
		
	
		
			
			|  | 121 | +                $result = LuInjector::inject($middleware, "onAfter", $args);
 | 
		
	
		
			
			| 164 | 122 |              }
 | 
		
	
		
			
			| 165 |  | -            $result = $middleware->onAfter($route, $parameters, $result);
 | 
		
	
		
			
			| 166 | 123 |          }
 | 
		
	
		
			
			| 167 | 124 |  
 | 
		
	
		
			
			| 168 | 125 |          return $result;
 | 
		
	
	
		
			
			|  | @@ -186,36 +143,6 @@ class LuRoute {
 | 
		
	
		
			
			| 186 | 143 |          }
 | 
		
	
		
			
			| 187 | 144 |      }
 | 
		
	
		
			
			| 188 | 145 |      
 | 
		
	
		
			
			| 189 |  | -    private function getClassName(\ReflectionParameter $param) {
 | 
		
	
		
			
			| 190 |  | -        preg_match('/\[\s\<\w+?>\s([\w]+)/s', $param->__toString(), $matches);
 | 
		
	
		
			
			| 191 |  | -        return isset($matches[1]) ? $matches[1] : null;
 | 
		
	
		
			
			| 192 |  | -    }
 | 
		
	
		
			
			| 193 |  | -
 | 
		
	
		
			
			| 194 |  | -    private function getParam(\ReflectionParameter $param, $value)
 | 
		
	
		
			
			| 195 |  | -    {
 | 
		
	
		
			
			| 196 |  | -        $typedValue = null;
 | 
		
	
		
			
			| 197 |  | -        $className = $this->getClassName($param);
 | 
		
	
		
			
			| 198 |  | -        if (is_null($className)) {
 | 
		
	
		
			
			| 199 |  | -            $typedValue = $value;
 | 
		
	
		
			
			| 200 |  | -        }
 | 
		
	
		
			
			| 201 |  | -        else {
 | 
		
	
		
			
			| 202 |  | -            $class = $param->getClass();
 | 
		
	
		
			
			| 203 |  | -            try
 | 
		
	
		
			
			| 204 |  | -            {
 | 
		
	
		
			
			| 205 |  | -                $json = json_decode($value, true);
 | 
		
	
		
			
			| 206 |  | -                $typedValue = call_user_func_array(array($class->getName(), "jsonDeserialize"), array($json));
 | 
		
	
		
			
			| 207 |  | -            }
 | 
		
	
		
			
			| 208 |  | -            catch (\Exception $e)
 | 
		
	
		
			
			| 209 |  | -            {
 | 
		
	
		
			
			| 210 |  | -                if ($e instanceof LuDboDeserializeException || $e instanceof LuDboConstraintException) {
 | 
		
	
		
			
			| 211 |  | -                    throw $e;
 | 
		
	
		
			
			| 212 |  | -                }
 | 
		
	
		
			
			| 213 |  | -                throw new LuBusinessException("Unable to parse JSON value for '" . $param->getName() . "'", 400, $e);
 | 
		
	
		
			
			| 214 |  | -            }
 | 
		
	
		
			
			| 215 |  | -        }
 | 
		
	
		
			
			| 216 |  | -        return $typedValue;
 | 
		
	
		
			
			| 217 |  | -    }
 | 
		
	
		
			
			| 218 |  | -    
 | 
		
	
		
			
			| 219 | 146 |      public function addRoute2(LuRouteDbo $route) {
 | 
		
	
		
			
			| 220 | 147 |          $controller = $route->getController();
 | 
		
	
		
			
			| 221 | 148 |          if (strpos($controller, "\\") === false) {
 |