256 lines
8.1 KiB
PHP
256 lines
8.1 KiB
PHP
<?php
|
|
|
|
require_once(LIBDIR."/autoloader/autoloader.php");
|
|
require_once(LIBDIR."/mvcfronk/mfLog/mfLoghandler.php");
|
|
|
|
/**
|
|
* This class routes incoming requests.
|
|
* It should be called by the entry script (public/index.php or CLI.php) as the entrypoint into the application.
|
|
* Looks at mod and action parameters and loads the corresponding class.
|
|
* If no parameters are given, uses default route.
|
|
* Also loads Configfile.
|
|
*
|
|
* @author fronk
|
|
* @param array of request params $request
|
|
*/
|
|
class mfRouter {
|
|
private $default=array();
|
|
private $mod;
|
|
private $action;
|
|
|
|
|
|
public function __construct($request) {
|
|
//var_dump($request);exit;
|
|
// set default route, in case no default route is defined in configfile.
|
|
$this->default['mod']="Application";
|
|
$this->default['action']="Index";
|
|
|
|
if(!defined('MFUSEFANCYURLS')) {
|
|
define('MFUSEFANCYURLS',false);
|
|
}
|
|
|
|
if(defined("DEFAULT_ROUTE") && strlen(DEFAULT_ROUTE)) {
|
|
$defroute = explode("_",DEFAULT_ROUTE);
|
|
$this->default['mod'] = $defroute[0];
|
|
if(count($defroute) > 1 && $defroute[1]) {
|
|
$this->default['action'] = $defroute[1];
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// set parameters supplied in url
|
|
$umod = "";
|
|
$uaction = "";
|
|
|
|
// get mod and action
|
|
$m = [];
|
|
if(array_key_exists("action", $request) && preg_match('/^([^_]+)(?:_(.+)?)?$/',$request['action'],$m)) {
|
|
$umod = $m[1];
|
|
$this->mod = $m[1];
|
|
$this->action = "Index";
|
|
if(count($m) > 2 && $m[2]) {
|
|
$uaction = $m[2];
|
|
$this->action = $m[2];
|
|
}
|
|
} else {
|
|
$this->mod = $this->default['mod'];
|
|
$this->action = $this->default['action'];
|
|
}
|
|
|
|
// if login request, redirect to mfLoginController
|
|
if(array_key_exists("mfLogin_action", $request) && $request['mfLogin_action'] == "mfLogin_Login") {
|
|
$this->mod = "mfLogin";
|
|
$this->action = "Login";
|
|
$classname = "mfLoginController";
|
|
} else {
|
|
// set classname of controller to load
|
|
$classname = $this->mod."Controller";
|
|
}
|
|
|
|
|
|
// get baseurl from fancy urls if used
|
|
if(MFUSEFANCYURLS) {
|
|
//var_dump($umod, $uaction, $_SERVER);
|
|
if(!$umod) {
|
|
$baseurl = $_SERVER['REQUEST_URI'];
|
|
}
|
|
if($umod && !$uaction) {
|
|
if(preg_match("#^(.+)/$umod/?\\??#i",$_SERVER['REQUEST_URI'],$m)) {
|
|
$baseurl = $m[1];
|
|
}
|
|
}
|
|
if($umod && $uaction) {
|
|
if(preg_match("#^(.+)/$umod/$uaction/?\\??#i",$_SERVER['REQUEST_URI'],$m)) {
|
|
$baseurl = $m[1];
|
|
}
|
|
}
|
|
|
|
// Special case for login, because mod/action in $request mask the real url
|
|
if($_SERVER['REQUEST_METHOD'] == "POST" && $umod == "mfLogin" && $uaction == "Login") {
|
|
// try to extract baseurl from env
|
|
// may not work on all webservers
|
|
$virtual = preg_replace('@/+(\?.*)+$@', "", $_SERVER["REQUEST_URI"]);
|
|
$real = preg_replace('@/+$@', "", $_SERVER['PHP_SELF']);
|
|
$virtual_parts = explode("/", $virtual);
|
|
$real_parts = explode("/", $real);
|
|
|
|
/*
|
|
* if there are no parts then we're good.
|
|
* Else find Action in last and Mod in second to last part.
|
|
* Action is optional.
|
|
*
|
|
* In rare cases some parts can match by accident if a folder is
|
|
* named the same as a mod or action. There is nothing we can do.
|
|
*/
|
|
$id_part_virtual = false;
|
|
$action_part = false;
|
|
$mod_part = false;
|
|
|
|
if(is_numeric($virtual_parts[count($virtual_parts) - 1]) && count($virtual_parts) > 2 && count($real_parts)) {
|
|
|
|
$id_part_virtual = $virtual_parts[count($virtual_parts) - 1];
|
|
$id_part_real = $real_parts[count($real_parts) - 1];
|
|
|
|
$action_part_virtual = $virtual_parts[count($virtual_parts) - 2];
|
|
$action_part_real = $real_parts[count($real_parts) - 2];
|
|
|
|
$mod_part_virtual = $virtual_parts[count($virtual_parts) - 3];
|
|
$mod_part_real = $real_parts[count($real_parts) - 3];
|
|
|
|
if($id_part_virtual != $id_part_real) {
|
|
$id_part = $id_part_virtual;
|
|
}
|
|
if($action_part_virtual != $action_part_real) {
|
|
$action_part = $action_part_virtual;
|
|
}
|
|
if($mod_part_virtual != $mod_part_real) {
|
|
$mod_part = $mod_part_virtual;
|
|
}
|
|
|
|
} elseif(count($virtual_parts) > 1 && count($real_parts)) {
|
|
$action_part_virtual = $virtual_parts[count($virtual_parts) - 1];
|
|
$action_part_real = $real_parts[count($real_parts) - 1];
|
|
|
|
$mod_part_virtual = $virtual_parts[count($virtual_parts) - 2];
|
|
$mod_part_real = $real_parts[count($real_parts) - 2];
|
|
|
|
if($action_part_virtual != $action_part_real) {
|
|
$action_part = $action_part_virtual;
|
|
}
|
|
if($mod_part_virtual != $mod_part_real) {
|
|
$mod_part = $mod_part_virtual;
|
|
}
|
|
|
|
} elseif(count($virtual_parts) && count($real_parts)) {
|
|
$mod_part_virtual = $virtual_parts[count($virtual_parts) - 1];
|
|
$mod_part_real = $real_parts[count($real_parts) - 1];
|
|
|
|
if($mod_part_virtual != $mod_part_real) {
|
|
$mod_part = $mod_part_virtual;
|
|
}
|
|
}
|
|
|
|
|
|
if($id_part) {
|
|
if(preg_match("#^(.+)/$mod_part/$action_part/$id_part/?\\??#i",$_SERVER['REQUEST_URI'],$m)) {
|
|
$baseurl = $m[1];
|
|
}
|
|
} elseif($mod_part) {
|
|
if(preg_match("#^(.+)/$mod_part/$action_part/?\\??#i",$_SERVER['REQUEST_URI'],$m)) {
|
|
$baseurl = $m[1];
|
|
}
|
|
} else {
|
|
if(preg_match("#^(.+)/$action_part/?\\??#i",$_SERVER['REQUEST_URI'],$m)) {
|
|
$baseurl = $m[1];
|
|
}
|
|
}
|
|
|
|
}
|
|
define("MFFANCYBASEURL",$baseurl);
|
|
}
|
|
|
|
|
|
// api call handling
|
|
if(ucfirst($this->mod) == "Api") {
|
|
//var_dump($request);exit;
|
|
$apiversion = API_VERSION;
|
|
$apicall = false;
|
|
$apimod = "";
|
|
$apiaction = "";
|
|
|
|
if($request["apiv"]) {
|
|
$apiversion = $request["apiv"];
|
|
}
|
|
if(!defined("CURRENT_API_VERSION")) {
|
|
define("CURRENT_API_VERSION", $apiversion);
|
|
}
|
|
|
|
if($request['apicall']) {
|
|
$apicall = $request['apicall'];
|
|
|
|
$m = [];
|
|
if(preg_match('/^([^_]+)(?:_(.+)?)?$/',$apicall,$m)) {
|
|
$apimod = $m[1];
|
|
$apiaction = "Call";
|
|
if(array_key_exists(2, $m) && $m[2]) {
|
|
$apiaction = $m[2];
|
|
}
|
|
}
|
|
$this->mod = ucfirst($apimod);
|
|
$this->action = $apiaction;
|
|
|
|
// set classname to apropriate Api Controller
|
|
$classname = $this->mod."Apicontroller";
|
|
}
|
|
} else {
|
|
// session only for non-api requests
|
|
if(defined("MFSESSION") && MFSESSION === true) {
|
|
session_name(MFAPPNAME."_session");
|
|
session_start();
|
|
}
|
|
|
|
// check for enabled 2FA if authentication is enabled and 2FA is forced
|
|
if(defined("MFUSELOGIN") && MFUSELOGIN && defined("TT_WORKER_FORCE_2FA") && TT_WORKER_FORCE_2FA && mfLoginController::isLoggedIn()) {
|
|
$user = new User();
|
|
$user->loadMe();
|
|
|
|
if($user->twofactor < 1 && $classname != "mfLoginController" && $classname != "UserProfileController" && $this->action != "logout" && $this->action != "Logout") {
|
|
// redirect to UserProfile
|
|
if(MFUSEFANCYURLS) {
|
|
header("Location: $baseurl/UserProfile");
|
|
} else {
|
|
header("Location: $baseurl?Mod=UserProfile");
|
|
}
|
|
exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
$request['mod'] = ucfirst($this->mod);
|
|
$request['action'] = ucfirst($this->action);
|
|
$request['http_method'] = $_SERVER['REQUEST_METHOD'];
|
|
|
|
define('MFROUTER_MOD',$this->mod);
|
|
define('MFROUTER_ACTION',$this->action);
|
|
|
|
// initiate layout instance
|
|
$Layout = Layout::singleton();
|
|
$Layout->setTemplate($this->mod."/".$this->action);
|
|
$Layout->set("Mod",$this->mod);
|
|
$Layout->set("Action",$this->action);
|
|
|
|
// load the appropriate Controller
|
|
|
|
try {
|
|
$page = new $classname($request);
|
|
} catch(Exception $e) {
|
|
require_once(LIBDIR."/mvcfronk/mfExceptionhandler/mfExceptionhandlerController.php");
|
|
$exhc = new mfExceptionhandlerController($e);
|
|
}
|
|
|
|
$Layout->display();
|
|
}
|
|
|
|
} |