1b7661ed |
<?php
namespace elanpl\L3;
class Application{
|
c6173b1c |
public $config; // L3 Config object
public $request; // build from received HTTP request or created in L3 Config object
public $response; // response to be send
public $router; // routing engine
public $serialization; // serialization engine
|
cdfe8eaf |
public $viewEngines; // view engines configuration
|
9b815c0a |
public $baseDirectory; // directory root of the application
|
0621d624 |
public $controllersDirectory; // subdirectory/namespace part added to controller class
public $viewsDirectory; // subdirectory to search for the view files
|
c6173b1c |
public $applicationDirectory; // subdirectory/namespace part of the application
|
840fc5a6 |
public $controller; //Active controller
public $module; //Active module
public $action; //Active action
|
1b7661ed |
|
a2bd90a3 |
public function __construct($config){
//set L3 application config
|
c6173b1c |
$this->config = $config;
|
02246d64 |
// directory root of the application
|
9b815c0a |
$this->baseDirectory = $config->getBaseDirectory();
|
02246d64 |
// subdirectory/namespace part added to controller class
|
0621d624 |
$this->controllersDirectory = $config->getControllersDirectory();
|
02246d64 |
// subdirectory to search for the view files
|
0621d624 |
$this->viewsDirectory = $config->getViewsDirectory();
|
02246d64 |
// subdirectory/namespace part of the application
|
c6173b1c |
$this->applicationDirectory = $config->getApplicationDirectory();
|
1b7661ed |
//create request object
|
c6173b1c |
$this->request = $this->config->getRequest();
|
a2bd90a3 |
//create router object
|
c6173b1c |
$this->router = new Router($this->config->getRouting());
|
1b7661ed |
//create response objcet
|
c6173b1c |
$this->response = new Response();
|
a2bd90a3 |
|
1b7661ed |
//create serialization object
|
c6173b1c |
$this->serialization = new Serialization();
|
cdfe8eaf |
//create view engines configuretion object
$this->viewEngines = new ViewEngine();
//perform configuration operations
$this->config->configure($this);
|
1b7661ed |
}
public function basePath(){
|
c6173b1c |
return strstr($_SERVER['REQUEST_URI'], $this->request->path, true);
|
1b7661ed |
}
|
b0b06371 |
public function getServerURL(){
return (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://{$_SERVER['HTTP_HOST']}";
}
public function getURL(){
return $this->getServerURL().$_SERVER['REQUEST_URI'];
}
|
1b7661ed |
public function relPath($file){
|
c6173b1c |
return ($this->router->depth>0 ? str_repeat("../", substr($this->request->path,-1)=='/'?$this->router->depth:$this->router->depth-1) : "" ).$file;
|
1b7661ed |
}
public function link($name, $parameters){
|
c6173b1c |
return $this->router->link($name, $parameters);
|
1b7661ed |
}
/*
//not need - PSR-4 autoload handles that
function IncludeControler($Controller){
include_once(_L3_CONTROLLER_PATH.$Controller.'.php');
}*/
|
c6173b1c |
public function findControllerInCallStack($search_level=5){
|
1b7661ed |
//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(
|
d7ac946b |
$pattern = '#('.$this->applicationDirectory.')(\\\\(?P<module>.+))?\\\\'.$this->controllersDirectory.'\\\\(?P<controller>.+)#',
|
1b7661ed |
$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
);
}
|
c6173b1c |
function runControllerAction($controllerAction, $parameters){
|
1b7661ed |
//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;
}
}*/
|
fae0882f |
$field_pattern ='#^{(?<field>[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)}$#';
|
931621db |
|
c6173b1c |
if(is_array($controllerAction)){
|
1b7661ed |
//$this->IncludeControler($ControllerAction['controller']);
|
931621db |
if(isset($controllerAction['module'])){
if(\preg_match($field_pattern, $controllerAction['module'], $match) ){
|
e71573cb |
$module = $this->router->parsedParameters[$match['field']]."\\";
|
931621db |
}
else{
$module = $controllerAction['module']."\\";
}
}
else{
$module = "";
}
if(\preg_match($field_pattern, $controllerAction['controller'], $match) ){
$controller = $this->router->parsedParameters[$match['field']];
}
else{
$controller = $controllerAction['controller'];
}
|
c6173b1c |
$controller_class = "\\".$this->applicationDirectory."\\"
|
931621db |
.$module
|
d7ac946b |
.$this->controllersDirectory."\\"
|
931621db |
.$controller;
|
d32f9a3a |
if(class_exists($controller_class,true)){
|
6f062c47 |
$controller_object = new $controller_class($this);
|
af738874 |
}
|
d32f9a3a |
else{
return $this->handle404($this->request);
|
af738874 |
}
|
931621db |
if(\preg_match($field_pattern, $controllerAction['action'], $match) ){
$controller_action = $this->router->parsedParameters[$match['field']];
}
else{
$controller_action = $controllerAction['action'];
}
|
1b7661ed |
}
//fire the action
if(isset($controller_object) && isset($controller_action)){
|
931621db |
// method not found - 404
if(!method_exists($controller_object,$controller_action)){
|
6f062c47 |
return $this->handle404($this->request);
|
931621db |
}
|
840fc5a6 |
$this->module = $module;
$this->controller = $controller;
|
c6173b1c |
$this->action = $controller_action;
|
1b7661ed |
// 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)
{
|
c6173b1c |
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];
|
1b7661ed |
else
|
c6173b1c |
$fire_args[$arg->name]=$controllerAction['defaults'][$arg->name];
|
1b7661ed |
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);
}
}
}
|
c6173b1c |
public function handleActionResult($result){
|
1b7661ed |
if(is_string($result)){
$content = $result;
}
else if(is_object($result)){
if($result instanceof ViewModel){
|
c6173b1c |
if($serializationContentType = $this->serialization->match($this->request->acceptTypes, $result)){
$content = $this->serialization->serialize($serializationContentType, $result);
|
1b7661ed |
if(is_object($content)){
|
c6173b1c |
if($content instanceof response){
$this->response = $content;
|
1b7661ed |
unset($content);
}
}
}
else{
|
c6173b1c |
echo "Serializer not defined for Content-Type: ".$this->request->accept."<br>".PHP_EOL;
|
1b7661ed |
throw new \Exception("Not implemented!");
}
}
else if($result instanceof View){
$content = $result->render();
}
else if($result instanceof Response){
|
c6173b1c |
$this->response = $result;
|
1b7661ed |
}
}
if(isset($content))
|
c6173b1c |
$this->response->withBody($content);
$this->response->send();
|
1b7661ed |
}
|
931621db |
public function handle404($request){
|
9317964e |
if(!$this->router->is_Match404() && ($action = $this->router->setMatch404($request))){
|
2eec4418 |
$this->runAction($action);
}
else{
|
9317964e |
http_response_code(404);
echo "<h1>Resource not found!</h1><br>".PHP_EOL;
|
2eec4418 |
echo "<pre>";
var_dump($request);
echo "</pre>";
|
9317964e |
if($this->router->is_Match404())
|
5541c781 |
throw new \Exception("The 404 controller or action not found!");
else
throw new \Exception("The 404 (not found) route not set!");
|
2eec4418 |
}
|
931621db |
}
|
c6173b1c |
public function beforeAction(){
if(!empty($this->router->routeInfo->beforeAction)){
foreach($this->router->routeInfo->beforeAction as $event_handler){
$this->router->routeInfo::eventHandlerFormatCheck($event_handler, $eh);
|
1b7661ed |
if(isset($eh['class'])){
$object = new $eh['class'];
$reflection = new \ReflectionMethod($object, $eh['function']);
$fire_args = array();
|
c6173b1c |
$fire_args[] = $this->request;
$fire_args[] = $this->router->routeInfo;
|
1b7661ed |
if(isset($eh['arguments'])){
|
c6173b1c |
$this->router->routeInfo::eventHandlerArgumentsFormatCheck($eh['arguments'], $args);
|
1b7661ed |
$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){
|
c6173b1c |
$this->handleActionResult($result);
|
1b7661ed |
exit();
}
}
}
}
}
}
|
2eec4418 |
public function runAction($action){
// routing match found decide what to do next...
// BeforeAction event
$this->beforeAction();
|
1b7661ed |
|
2eec4418 |
// 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;
|
1b7661ed |
}
|
2eec4418 |
$result = call_user_func_array($action, $fire_args);
|
1b7661ed |
}
|
2eec4418 |
else{
$result = call_user_func($action);
|
1b7661ed |
}
|
2eec4418 |
}
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;
}
|
1b7661ed |
|
2eec4418 |
// 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);
|
1b7661ed |
}
// routing path not found -> generate 404 response
else{
|
931621db |
$this->handle404($this->request);
|
1b7661ed |
}
}
}
|