commit f8683ef383bc5c6f30ae58a7737d0e878e6ccaf5
parent be4931b20b1077141c70b6980cbdd281a86044d1
Author: Jan Dankert <devnull@localhost>
Date: Sat, 30 Dec 2017 20:48:09 +0100
Exceptions im cms-core nicht fangen, sondern an UI oder API weiterreichen. Diese sollen dann entscheiden, was zu tun ist.
Diffstat:
1 file changed, 170 insertions(+), 180 deletions(-)
diff --git a/modules/cms-core/Dispatcher.class.php b/modules/cms-core/Dispatcher.class.php
@@ -5,6 +5,7 @@
*/
namespace cms;
+use BadMethodCallException;
use Configuration;
use DomainException;
use Http;
@@ -25,246 +26,235 @@ class Dispatcher
public $action;
public $subaction;
+ /**
+ * @return array
+ */
public function doAction()
{
- try {
-
- // Jetzt erst die Sitzung starten (nachdem alle Klassen zur Verfügung stehen).
- session_start();
+ // Jetzt erst die Sitzung starten (nachdem alle Klassen zur Verfügung stehen).
+ session_start();
- global $SESS;
- $SESS = &$_SESSION;
+ global $SESS;
+ $SESS = &$_SESSION;
- global $FILES;
- $FILES = &$_FILES;
+ global $FILES;
+ $FILES = &$_FILES;
- // Vorhandene Konfiguration aus der Sitzung lesen.
- global $conf;
- $conf = Session::getConfig();
+ // Vorhandene Konfiguration aus der Sitzung lesen.
+ global $conf;
+ $conf = Session::getConfig();
- // Konfiguration lesen.
- // Wenn Konfiguration noch nicht in Session vorhanden oder die Konfiguration geändert wurde (erkennbar anhand des Datei-Datums)
- // dann die Konfiguration neu einlesen.
- if (!is_array($conf) || $conf['config']['auto_reload'] && Configuration::lastModificationTime() > $conf['config']['last_modification_time']) {
+ // Konfiguration lesen.
+ // Wenn Konfiguration noch nicht in Session vorhanden oder die Konfiguration geändert wurde (erkennbar anhand des Datei-Datums)
+ // dann die Konfiguration neu einlesen.
+ if (!is_array($conf) || $conf['config']['auto_reload'] && Configuration::lastModificationTime() > $conf['config']['last_modification_time']) {
- // Da die Konfiguration neu eingelesen wird, sollten wir auch die Sitzung komplett leeren.
- if (is_array($conf) && $conf['config']['session_destroy_on_config_reload'])
- session_unset();
+ // Da die Konfiguration neu eingelesen wird, sollten wir auch die Sitzung komplett leeren.
+ if (is_array($conf) && $conf['config']['session_destroy_on_config_reload'])
+ session_unset();
- // Fest eingebaute Standard-Konfiguration laden.
- require(OR_MODULES_DIR . 'util/config-default.php');
- $conf = createDefaultConfig();
+ // Fest eingebaute Standard-Konfiguration laden.
+ require(OR_MODULES_DIR . 'util/config-default.php');
+ $conf = createDefaultConfig();
- $customConfig = Configuration::load();
- $conf = array_replace_recursive($conf, $customConfig);
+ $customConfig = Configuration::load();
+ $conf = array_replace_recursive($conf, $customConfig);
- $conf['build'] = parse_ini_file('build.ini');
- $conf['version'] = parse_ini_file('version.ini');
- // Sprache lesen
+ $conf['build'] = parse_ini_file('build.ini');
+ $conf['version'] = parse_ini_file('version.ini');
+ // Sprache lesen
- if ($conf['i18n']['use_http'])
- // Die vom Browser angeforderten Sprachen ermitteln
- $languages = Http::getLanguages();
- else
- // Nur Default-Sprache erlauben
- $languages = array();
+ if ($conf['i18n']['use_http'])
+ // Die vom Browser angeforderten Sprachen ermitteln
+ $languages = Http::getLanguages();
+ else
+ // Nur Default-Sprache erlauben
+ $languages = array();
- if (isset($_COOKIE['or_language']))
- $languages = array($_COOKIE['or_language']) + $languages;
+ if (isset($_COOKIE['or_language']))
+ $languages = array($_COOKIE['or_language']) + $languages;
- // Default-Sprache hinzufuegen.
- // Wird dann verwendet, wenn die vom Browser angeforderten Sprachen
- // nicht vorhanden sind
- $languages[] = $conf['i18n']['default'];
- $available = explode(',', $conf['i18n']['available']);
+ // Default-Sprache hinzufuegen.
+ // Wird dann verwendet, wenn die vom Browser angeforderten Sprachen
+ // nicht vorhanden sind
+ $languages[] = $conf['i18n']['default'];
+ $available = explode(',', $conf['i18n']['available']);
- foreach ($languages as $l) {
- if (!in_array($l, $available))
- continue;
+ foreach ($languages as $l) {
+ if (!in_array($l, $available))
+ continue;
- // Pruefen, ob Sprache vorhanden ist.
- $langFile = OR_LANGUAGE_DIR . 'lang-' . $l . '.' . PHP_EXT;
+ // Pruefen, ob Sprache vorhanden ist.
+ $langFile = OR_LANGUAGE_DIR . 'lang-' . $l . '.' . PHP_EXT;
- if (!file_exists($langFile))
- throw new LogicException("File does not exist: " . $langFile);
+ if (!file_exists($langFile))
+ throw new LogicException("File does not exist: " . $langFile);
- require($langFile);
- $conf['language'] = $lang;
- $conf['language']['language_code'] = $l;
- break;
- }
+ require($langFile);
+ $conf['language'] = $lang;
+ $conf['language']['language_code'] = $l;
+ break;
+ }
- if (!isset($conf['language']))
- Http::serverError('no language found! (languages=' . implode(',', $languages) . ')');
+ if (!isset($conf['language']))
+ Http::serverError('no language found! (languages=' . implode(',', $languages) . ')');
- // Schreibt die Konfiguration in die Sitzung. Diese wird anschliessend nicht
- // mehr veraendert.
- Session::setConfig($conf);
- }
+ // Schreibt die Konfiguration in die Sitzung. Diese wird anschliessend nicht
+ // mehr veraendert.
+ Session::setConfig($conf);
+ }
// Nachdem die Konfiguration gelesen wurde, kann nun der Logger benutzt werden.
- require_once(OR_MODULES_DIR . "logger/require." . PHP_EXT);
+ require_once(OR_MODULES_DIR . "logger/require." . PHP_EXT);
// Logger initialisieren
- Logger::$messageFormat = $conf['log']['format'];
- Logger::$filename = $conf['log']['file'];
- Logger::$dateFormat = $conf['log']['date_format'];
- Logger::$nsLookup = $conf['log']['ns_lookup'];
+ Logger::$messageFormat = $conf['log']['format'];
+ Logger::$filename = $conf['log']['file'];
+ Logger::$dateFormat = $conf['log']['date_format'];
+ Logger::$nsLookup = $conf['log']['ns_lookup'];
- $cname = 'LOGGER_LOG_' . strtoupper($conf['log']['level']);
- if (defined($cname))
- Logger::$level = constant($cname);
+ $cname = 'LOGGER_LOG_' . strtoupper($conf['log']['level']);
+ if (defined($cname))
+ Logger::$level = constant($cname);
- Logger::$messageCallback = function () {
- $action = Session::get('action');
- if (empty($action))
- $action = '-';
+ Logger::$messageCallback = function () {
+ $action = Session::get('action');
+ if (empty($action))
+ $action = '-';
- $action = Session::get('action');
- if (empty($action))
- $action = '-';
+ $action = Session::get('action');
+ if (empty($action))
+ $action = '-';
- $user = Session::getUser();
- if (is_object($user))
- $username = $user->name;
- else
- $username = '-';
+ $user = Session::getUser();
+ if (is_object($user))
+ $username = $user->name;
+ else
+ $username = '-';
- return array('user' => $username, 'action' => $action);
- };
- Logger::init();
+ return array('user' => $username, 'action' => $action);
+ };
+ Logger::init();
- if (!empty($conf['security']['umask']))
- umask(octdec($conf['security']['umask']));
+ if (!empty($conf['security']['umask']))
+ umask(octdec($conf['security']['umask']));
- if (!empty($conf['interface']['timeout']))
- set_time_limit(intval($conf['interface']['timeout']));
-
- global $REQ;
- if (config('security', 'use_post_token') && $_SERVER['REQUEST_METHOD'] == 'POST' && @$REQ[REQ_PARAM_TOKEN] != token()) {
- Logger::error('Token mismatch: Needed ' . token() . ' but got ' . @$REQ[REQ_PARAM_TOKEN] . '. Maybe an attacker?');
- Http::notAuthorized("Token mismatch", "Token mismatch");
- }
+ if (!empty($conf['interface']['timeout']))
+ set_time_limit(intval($conf['interface']['timeout']));
+ global $REQ;
+ if (config('security', 'use_post_token') && $_SERVER['REQUEST_METHOD'] == 'POST' && @$REQ[REQ_PARAM_TOKEN] != token()) {
+ Logger::error('Token mismatch: Needed ' . token() . ' but got ' . @$REQ[REQ_PARAM_TOKEN] . '. Maybe an attacker?');
+ Http::notAuthorized("Token mismatch", "Token mismatch");
+ }
- define('FILE_SEP', $conf['interface']['file_separator']);
- define('TEMPLATE_DIR', OR_THEMES_DIR . $conf['interface']['theme'] . '/templates');
- define('CSS_DIR', OR_THEMES_DIR . $conf['interface']['theme'] . '/css');
- define('IMAGE_DIR', OR_THEMES_DIR . $conf['interface']['theme'] . '/images');
+ define('FILE_SEP', $conf['interface']['file_separator']);
- define('PRODUCTION', $conf['production']);
- define('DEVELOPMENT', !PRODUCTION);
+ define('TEMPLATE_DIR', OR_THEMES_DIR . $conf['interface']['theme'] . '/templates');
+ define('CSS_DIR', OR_THEMES_DIR . $conf['interface']['theme'] . '/css');
+ define('IMAGE_DIR', OR_THEMES_DIR . $conf['interface']['theme'] . '/images');
- // Verbindung zur Datenbank
- //
- $db = Session::getDatabase();
- if (is_object($db)) {
- $ok = $db->connect();
- if (!$ok)
- throw new DomainException('Database is not available: ' . $db->error);
+ define('PRODUCTION', $conf['production']);
+ define('DEVELOPMENT', !PRODUCTION);
- Session::setDatabase($db);
- $db->start();
- }
+ // Verbindung zur Datenbank
+ //
+ $db = Session::getDatabase();
+ if (is_object($db)) {
+ $ok = $db->connect();
+ if (!$ok)
+ throw new DomainException('Database is not available: ' . $db->error);
+ Session::setDatabase($db);
+ $db->start();
+ }
- $actionClassName = ucfirst($this->action) . 'Action';
- $actionClassNameWithNamespace = 'cms\\action\\' . $actionClassName;
- // Laden der Action-Klasse.
- require_once(OR_ACTIONCLASSES_DIR . '/' . $actionClassName . '.class.php');
+ $actionClassName = ucfirst($this->action) . 'Action';
+ $actionClassNameWithNamespace = 'cms\\action\\' . $actionClassName;
- // Erzeugen der Action-Klasse
- try {
- /* @type $do \cms\action\Action */
- $do = new $actionClassNameWithNamespace;
- } catch (ObjectNotFoundException $e) {
- Logger::debug("Object not found: " . $e->__toString());
- Http::noContent();
- }
+ // Laden der Action-Klasse.
+ require_once(OR_ACTIONCLASSES_DIR . '/' . $actionClassName . '.class.php');
- $do->actionClassName = $actionClassName;
- $do->actionName = $this->action;
- $do->subActionName = $this->subaction;
+ // Erzeugen der Action-Klasse
+ try {
+ /* @type $do \cms\action\Action */
+ $do = new $actionClassNameWithNamespace;
+ } catch (ObjectNotFoundException $e) {
+ Logger::debug("Object not found: " . $e->__toString());
+ throw $e;
+ }
- if (isset($REQ[REQ_PARAM_ID]))
- define('OR_ID', $REQ[REQ_PARAM_ID]);
- else
- define('OR_ID', '');
-
- $do->init();
-
-
- switch (@$do->security) {
- case SECURITY_GUEST:
- // Ok.
- break;
- case SECURITY_USER:
- if (!is_object($do->currentUser))
- throw new SecurityException('No user logged in, but this action requires a valid user');
- break;
- case SECURITY_ADMIN:
- if (!is_object($do->currentUser) || !$do->currentUser->isAdmin)
- throw new SecurityException('This action requires administration privileges, but user ' . $do->currentUser->name . ' is not an admin');
- break;
- default:
- }
+ $do->actionClassName = $actionClassName;
+ $do->actionName = $this->action;
+ $do->subActionName = $this->subaction;
+
+ if (isset($REQ[REQ_PARAM_ID]))
+ define('OR_ID', $REQ[REQ_PARAM_ID]);
+ else
+ define('OR_ID', '');
+
+ $do->init();
+
+
+ switch (@$do->security) {
+ case SECURITY_GUEST:
+ // Ok.
+ break;
+ case SECURITY_USER:
+ if (!is_object($do->currentUser))
+ throw new SecurityException('No user logged in, but this action requires a valid user');
+ break;
+ case SECURITY_ADMIN:
+ if (!is_object($do->currentUser) || !$do->currentUser->isAdmin)
+ throw new SecurityException('This action requires administration privileges, but user ' . $do->currentUser->name . ' is not an admin');
+ break;
+ default:
+ }
- $isAction = $_SERVER['REQUEST_METHOD'] == 'POST';
+ $isAction = $_SERVER['REQUEST_METHOD'] == 'POST';
- if ($isAction) {
- // POST-Request => ...Post() wird aufgerufen.
- $subactionMethodName = $this->subaction . 'Post';
- } else {
- // GET-Request => ...View() wird aufgerufen.
- $subactionMethodName = $this->subaction . 'View';
- // Daten werden nur angezeigt, die Sitzung kann also schon geschlossen werden.
- if ($this->action != 'index') // In Index wird die Perspektive manipuliert.
- Session::close();
- }
+ if ($isAction) {
+ // POST-Request => ...Post() wird aufgerufen.
+ $subactionMethodName = $this->subaction . 'Post';
+ } else {
+ // GET-Request => ...View() wird aufgerufen.
+ $subactionMethodName = $this->subaction . 'View';
+ // Daten werden nur angezeigt, die Sitzung kann also schon geschlossen werden.
+ if ($this->action != 'index') // In Index wird die Perspektive manipuliert.
+ Session::close();
+ }
- Logger::debug("Executing {$this->action}/{$this->subaction}/" . @$REQ[REQ_PARAM_ID]);
+ Logger::debug("Executing {$this->action}/{$this->subaction}/" . @$REQ[REQ_PARAM_ID]);
- if (!method_exists($do, $subactionMethodName))
- Http::noContent();
+ if (!method_exists($do, $subactionMethodName))
+ throw new BadMethodCallException("Method '$subactionMethodName' does not exist");
- $result = $do->$subactionMethodName(); // <== Executing the Action
+ $result = $do->$subactionMethodName(); // <== Executing the Action
- // The action is able to change its method name.
- $this->subaction = $do->subActionName;
+ // The action is able to change its method name.
+ $this->subaction = $do->subActionName;
- Logger::trace('Output' . "\n" . print_r($result, true));
+ Logger::trace('Output' . "\n" . print_r($result, true));
- // Weitere Variablen anreichern.
- $result['session'] = array('name' => session_name(), 'id' => session_id(), 'token' => token());
- $result['version'] = OR_VERSION;
- $result['api'] = '2';
+ // Weitere Variablen anreichern.
+ $result['session'] = array('name' => session_name(), 'id' => session_id(), 'token' => token());
+ $result['version'] = OR_VERSION;
+ $result['api'] = '2';
- $do->handleResult($result);
+ $do->handleResult($result);
- $this->cleanup();
+ $this->cleanup();
- return $do->getOutputData();
- } catch
- (ObjectNotFoundException $e) {
- Logger::warn("Object not found: " . $e->__toString()); // Nur Debug, da dies bei gelöschten Objekten vorkommen kann.
- Http::noContent();
- } catch (OpenRatException $e) {
- Http::serverError(lang($e->key), $e->__toString());
- } catch (SecurityException $e) {
- Logger::info($e->getMessage());
- Http::notAuthorized("You are not allowed to execute this action.");
- } catch (Exception $e) {
- Http::serverError("Internal CMS error", $e->__toString());
- }
+ return $do->getOutputData();
}