getBaseURL(); if ($action === false) return $app->getBaseURL() . $controller . '/index'; if (is_null($tour)) return $app->getBaseURL() . $controller . '/' . $action; return $app->getBaseURL() . $controller . '/' . $tour->get('key') . '/' . $action; } protected static $debug_file = false; public static function debug($values) { if (!defined('DEBUG') || DEBUG !== true) return error_log('return'); if (!static::$debug_file) { $dir = dirname(__DIR__) . '/tmp'; if (!is_dir($dir)) return; static::$debug_file = fopen($dir . '/debug.log', 'a'); } if (!static::$debug_file) return; if (is_string($values)) $values = trim($values); else $values = var_export($values, true); fputs(static::$debug_file, sprintf("%s %s - %s\n", date('Y-m-d H:i:s'), $_SESSION['email'], $values)); } protected $_javascript = NULL; protected $_styles = NULL; protected $_request = NULL; protected $_response = NULL; protected $_base = NULL; protected $_is_admin = NULL; protected $_controller; protected $_action; protected $tour; protected $db; private function __construct() { global $db; $this->initSession(); $this->_request = new Request(); $this->_response = new Response(); $dsn = sprintf('%s:host=%s;dbname=%s', DBDRIVER, DBHOST, DBNAME); $db = new Database(DBDRIVER, DBHOST, DBNAME, DBUSER, DBPASS); if (defined('MAIL_ERROR')) $db->setErrorMail(MAIL_ERROR); $this->db = $db; $this->setExceptionHandler(); } public function getBaseDir() { return dirname(__DIR__) . '/'; } public function getBaseURL() { if (is_null($this->_base)) { if (strpos($this->getBaseDir(), $this->_request->getServer('DOCUMENT_ROOT')) !== 0) throw new Exception("Local directory doesn't match DOCUMENT_ROOT"); $this->_base = substr($this->getBaseDir(), strlen($this->_request->getServer('DOCUMENT_ROOT'))); } return $this->_base; } protected function initSession() { if (!defined('SESSION_PATH')) define('SESSION_PATH', '/'); if (!defined('SESSION_LIFETIME')) define('SESSION_LIFETIME', 60*60*56); session_name(SESSION_NAME); session_set_cookie_params(SESSION_LIFETIME, SESSION_PATH); session_start(); session_regenerate_id(); } protected function setExceptionHandler() { set_exception_handler(function(Throwable $e){ Application::debug($e->getTraceAsString()); $app = Application::get(); if ($app->getRequest()->isAjax()) { header('Content-type: application/json; charset="UTF-8"'); echo json_encode(['status' => false, 'error' => $e->getMessage()]); exit(); } $content = Template::render('page/error', ['title' => 'Es ist ein Problem aufgetreten', 'text' => $e->getMessage()]); header('Content-type: text/html; charset="UTF-8"'); echo Template::render('page/main', ['title' => TITLE, 'pagetitle' => TITLE, 'navigation' => '', 'favicon' => FAVICON, 'content' => $content, 'styles' => Styles::instance()->toString(), 'javascript' => JavaScript::instance()->toString()]); exit(); }); } protected function addBaseFiles() { $this->addJavascript('lib/jquery-2.1.0.min.js'); $this->addJavascript('lib/bootstrap-4.3.1-dist/js/bootstrap.js'); $this->addJavascript('touren.js'); $this->addJavascriptCode(sprintf("var tour_base_url = '%s';", $this->getBaseURL())); $this->addStyle('lib/bootstrap-4.3.1-dist/css/bootstrap.css'); $this->addStyle('touren.css'); } public function addJavascript($path) { if (is_null($this->_javascript)) $this->_javascript = JavaScript::instance(); $this->_javascript->file($path); } public function addJavascriptCode($code) { if (is_null($this->_javascript)) $this->_javascript = JavaScript::instance(); $this->_javascript->add($code); } public function addStyle($path) { if (is_null($this->_styles)) $this->_styles = Styles::instance(); $this->_styles->file($path); } public function getRequest() { return $this->_request; } public function getResponse() { return $this->_response; } public function isAdmin() { if (is_null($this->_is_admin)) { $this->_is_admin = $_SESSION['userid'] == 1; } return $this->_is_admin; } protected function route() { $controller_name = $this->_request->getControllerName() or 'index'; $this->_action = $this->_request->getActionName() or 'index'; $tour_name = $this->_request->getTourName() or NULL; if (empty($controller_name)) $controller_name = 'index'; if (empty($this->_action)) $this->_action = 'index'; $controller_name = ucfirst($controller_name) . 'Controller'; $this->_controller = new $controller_name(); if ((empty($_SESSION) || empty($_SESSION['userid'])) && !in_array($this->_action, $this->_controller->allowUnauthenticated())) { $this->_response->setLocation(sprintf('%sindex/login', $this->getBaseURL())); return; } $this->_controller->setDatabase($this->db); $this->_controller->setApplication($this); if ($this->_request->isAjax()) $method = 'ajax' . ucfirst($this->_action); else $method = $this->_action . 'Action'; if (!method_exists($this->_controller, $method)) throw new Exception("Entry point for {$this->_action} does not exist"); if (!is_null($tour_name)) { $this->tour = new Tour($tour_name, 'key'); if ($this->tour->id()) { $this->_controller->setTour($this->tour); $this->addJavascriptCode(sprintf("var tour_key = '%s';", $this->tour->get('key'))); } } if ($this->_request->isAjax()) { $this->getResponse()->setType('application/json'); $this->_controller->$method($this->_request, $this->_response, $this->_request->getPost()); } else { $this->_controller->$method($this->_request, $this->_response); } } public function process() { if (!$this->_request->isAjax()) $this->addBaseFiles(); $this->route(); if ($this->getResponse()->getLocation()) { header(sprintf('Location: %s', $this->getResponse()->getLocation())); exit(); } if ($this->getResponse()->getType() == 'application/json') { $data = $this->getResponse()->getData(); if ($data === false) $data = ['status' => false]; if ($data === true) $data = ['status' => true]; if (!array_key_exists('status', $data)) $data['status'] = true; header('Content-type: application/json; charset="UTF-8"'); echo json_encode($data); exit(); } if ($this->getResponse()->getType() != 'text/html') { header(sprintf('Content-type: %s; charset="UTF-8"'), $this->getResponse()->getType()); echo $this->getResponse()->getData(); exit(); } $nav = $this->_controller->getNavigation(); if (is_null($nav) || $nav === false || !count($nav)) $navigation = ''; else $navigation = Template::render('page/navigation', ['list' => $nav, 'tour' => $this->tour]); header('Content-type: text/html; charset="UTF-8"'); echo Template::render('page/main', ['title' => TITLE, 'pagetitle' => TITLE, 'navigation' => $navigation, 'favicon' => FAVICON, 'content' => $this->getResponse()->getData(), 'styles' => !is_null($this->_styles) ? $this->_styles->toString() : '', 'javascript' => !is_null($this->_javascript) ? $this->_javascript->toString() : '']); exit(); } }