config = $config; // directory root of the application $this->baseDirectory = $config->getBaseDirectory(); // subdirectory/namespace part added to controller class $this->controllersDirectory = $config->getControllersDirectory(); // subdirectory to search for the view files $this->viewsDirectory = $config->getViewsDirectory(); // subdirectory/namespace part of the application $this->applicationDirectory = $config->getApplicationDirectory(); //create request object $this->request = $this->config->getRequest(); //create router object $this->router = new Router($this->config->getRouting()); //create response objcet $this->response = new Response(); //create serialization object $this->serialization = new Serialization(); //create view engines configuretion object $this->viewEngines = new ViewEngine(); //perform configuration operations $this->config->configure($this); } public function basePath(){ if(isset($this->request->path)&&$this->request->path!=''){ return strstr($_SERVER['REQUEST_URI'], $this->request->path, true); } else return explode('?',$_SERVER['REQUEST_URI'],1)[0]; } public function getServerURL(){ return (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://{$_SERVER['HTTP_HOST']}"; } public function getURL(){ return $this->getServerURL().$_SERVER['REQUEST_URI']; } public function relPath($file){ return ($this->router->depth>0 ? str_repeat("../", substr($this->request->path,-1)=='/'?$this->router->depth:$this->router->depth-1) : "" ).$file; } public function link($name, $parameters){ return $this->router->link($name, $parameters); } /* //not need - PSR-4 autoload handles that function IncludeControler($Controller){ include_once(_L3_CONTROLLER_PATH.$Controller.'.php'); }*/ public function findControllerInCallStack($search_level=5){ //search for controller, action and module if present $controller = ""; $module = ""; $action = ""; $match = array(); //analize the call stack $call_stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, $search_level); for($i=0; $i<$search_level; $i++){ if(preg_match( $pattern = '#('.$this->applicationDirectory.')(\\\\(?P.+))?\\\\'.$this->controllersDirectory.'\\\\(?P.+)#', $call_stack[$i]['class'], $match ) ){ $action = $call_stack[$i]['function']; $module = $match['module']; $controller = $match['controller']; break; } } return array( 'module' => $module, 'controller' => $controller, 'action' => $action ); } function runControllerAction($controllerAction, $parameters){ //prepare object and action name /* TODO ... if(is_object($this->controler) && (is_a($this->controler,'L2_controler') || is_subclass_of($this->controler,'L2_controler'))){ if(is_string($this->action)){ $controler_object = $this->controler; $controler_action = $this->action; } } else if(is_string($this->controler)){ if(is_string($this->action)){ $this->includeControler($this->controler); $controler_object = new $this->controler(); $controler_action = $this->action; } }*/ $field_pattern ='#^{(?[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)}$#'; if(is_array($controllerAction)){ //$this->IncludeControler($ControllerAction['controller']); if(isset($controllerAction['module'])){ if(\preg_match($field_pattern, $controllerAction['module'], $match) ){ $module = $this->router->parsedParameters[$match['field']]."\\"; } else{ $module = $controllerAction['module']."\\"; } } else{ $module = ""; } if(\preg_match($field_pattern, $controllerAction['controller'], $match) ){ $controller = $this->router->parsedParameters[$match['field']]; } else{ $controller = $controllerAction['controller']; } $controller_class = "\\".$this->applicationDirectory."\\" .$module .$this->controllersDirectory."\\" .$controller; if(class_exists($controller_class,true)){ $controller_object = new $controller_class($this); } else{ return $this->handle404($this->request); } if(\preg_match($field_pattern, $controllerAction['action'], $match) ){ $controller_action = $this->router->parsedParameters[$match['field']]; } else{ $controller_action = $controllerAction['action']; } } //fire the action if(isset($controller_object) && isset($controller_action)){ // method not found - 404 if(!method_exists($controller_object,$controller_action)){ return $this->handle404($this->request); } $this->module = $module; $this->controller = $controller; $this->action = $controller_action; // prepare args and start the action if(!isset($reflection)){ $reflection = new \ReflectionMethod($controller_object, $controller_action); } if($reflection->getNumberOfParameters()){ $fire_args=array(); foreach($reflection->getParameters() AS $arg) { if(isset($parameters[$arg->name]) || (is_array($controllerAction) && isset($controllerAction['defaults'][$arg->name]))) if(isset($parameters[$arg->name])) $fire_args[$arg->name]=$parameters[$arg->name]; else $fire_args[$arg->name]=$controllerAction['defaults'][$arg->name]; else { if($arg->isDefaultValueAvailable()){ $fire_args[$arg->name]=$arg->getDefaultValue(); } else{ $fire_args[$arg->name]=null; } } } return $reflection->invokeArgs ($controller_object , $fire_args ); } else{ return $reflection->invoke($controller_object); } } } public function handleActionResult($result){ if(is_string($result)){ $content = $result; } else if(is_object($result)){ if($result instanceof ViewModel){ if($serializationContentType = $this->serialization->match($this->request->acceptTypes, $result)){ $content = $this->serialization->serialize($serializationContentType, $result); if(is_object($content)){ if($content instanceof response){ $this->response = $content; unset($content); } } } else{ echo "Serializer not defined for Content-Type: ".$this->request->accept."
".PHP_EOL; throw new \Exception("Not implemented!"); } } else if($result instanceof View){ $content = $result->render(); } else if($result instanceof Response){ $this->response = $result; } } if(isset($content)) $this->response->withBody($content); $this->response->send(); } public function handle404($request){ if(!$this->router->is_Match404() && ($action = $this->router->setMatch404($request))){ $this->runAction($action); } else{ http_response_code(404); echo "

Resource not found!


".PHP_EOL; echo "
";
            var_dump($request);
            echo "
"; if($this->router->is_Match404()) throw new \Exception("The 404 controller or action not found!"); else throw new \Exception("The 404 (not found) route not set!"); } } public function beforeAction(){ if(!empty($this->router->routeInfo->beforeAction)){ foreach($this->router->routeInfo->beforeAction as $event_handler){ $this->router->routeInfo::eventHandlerFormatCheck($event_handler, $eh); if(isset($eh['class'])){ $object = new $eh['class']; $reflection = new \ReflectionMethod($object, $eh['function']); $fire_args = array(); $fire_args[] = $this; if(isset($eh['arguments'])){ $this->router->routeInfo::eventHandlerArgumentsFormatCheck($eh['arguments'], $args); $field_pattern ='#^{(?[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)}$#'; foreach($args as $index => $param){ if(\preg_match($field_pattern, $param, $match) ){ $args[$index] = $this->router->parsedParameters[$match['field']]; } } $fire_args = array_merge($fire_args, $args); } $result = $reflection->invokeArgs ($object , $fire_args ); } else if (is_callable($eh['function'])){ throw new \Exception("Not implemented!"); } if(isset($result)){ if(is_object($result)){ if($result instanceof Response){ $this->handleActionResult($result); exit(); } } } } } } public function runAction($action){ // routing match found decide what to do next... // BeforeAction event $this->beforeAction(); // function -> call it... if(is_callable($action)){ $reflection = new \ReflectionFunction($action); if($reflection->getNumberOfParameters()){ $fire_args=array(); foreach($reflection->getParameters() AS $arg) { if(isset($this->router->parsedParameters[$arg->name])) $fire_args[$arg->name]=$this->router->parsedParameters[$arg->name]; else $fire_args[$arg->name]=null; } $result = call_user_func_array($action, $fire_args); } else{ $result = call_user_func($action); } } else if(is_object($action) && is_a($action, 'L2_controler_info')){ // not implemented yet. throw new \Exception("Not implemented!"); ///$action->runControlerAction($this->routing->param); } // array with controller, and action -> run the controller action else if(is_array($action) && array_key_exists('controller',$action) && array_key_exists('action', $action)){ $result = $this->runControllerAction($action, $this->router->parsedParameters); } // string else if(is_string($action)){ $result = $action; } // Handle the action result if(isset($result)){ $this->handleActionResult($result); } } public function run(){ // Check if routing path is found if($action = $this->router->match($this->request)){ $this->runAction($action); } // routing path not found -> generate 404 response else{ $this->handle404($this->request); } } }