commit 953e0c4399ae9a55116f8a6b6ddfbe81f22b0174
parent a09b09c8a618284def9100193970b39fdbfd9c37
Author: Jan Dankert <develop@jandankert.de>
Date: Mon, 20 May 2019 00:34:19 +0200
Refactoring: Datenbankverbindung im Dispatcher erstellen. Bisher wurde in der Loginaction die DB-Verbindung aufgebaut, was dort falsch aufgehoben war.
Diffstat:
15 files changed, 3757 insertions(+), 3988 deletions(-)
diff --git a/modules/cms-core/Dispatcher.class.php b/modules/cms-core/Dispatcher.class.php
@@ -1,412 +1,444 @@
-<?php
-
-/*
- * Loading and calling the action class (the "controller").
- */
-namespace cms;
-
-use BadMethodCallException;
-use cms\action\Action;
-use cms\action\RequestParams;
-use ConfigurationLoader;
-use DomainException;
-use Http;
-use http\Exception;
-use language\Language;
-use Logger;
-use LogicException;
-use ObjectNotFoundException;
-use OpenRatException;
-use SecurityException;
-use Session;
-use Spyc;
-
-
-/**
- * Dispatcher for all cms actions.
- *
- * @package cms
- */
-class Dispatcher
-{
- /**
- * @var RequestParams
- */
- public $request;
-
- /**
- * Vollständige Abarbeitug einer Aktion.
- * Führt die gesamte Abarbeitung einer Aktion durch, incl. Datenbank-Transaktionssteuerung.
- *
- * @return array data for the client
- */
- public function doAction()
- {
- // Start the session. All classes should have been loaded up to now.
- session_start();
-
- $this->checkConfiguration();
-
- // Vorhandene Konfiguration aus der Sitzung lesen.
- global $conf;
- $conf = Session::getConfig();
-
- define('PRODUCTION', Conf()->is('production'));
- define('DEVELOPMENT', !PRODUCTION);
-
- if( DEVELOPMENT)
- {
- ini_set('display_errors', 1);
- ini_set('display_startup_errors', 1);
- error_reporting(E_ALL);
- }else {
- ini_set('display_errors', 0);
- ini_set('display_startup_errors', 0);
- error_reporting(0);
- }
-
- $this->setContentLanguageHeader();
-
- // Nachdem die Konfiguration gelesen wurde, kann nun der Logger benutzt werden.
- require_once(OR_MODULES_DIR . "logger/require." . PHP_EXT);
- $this->initializeLogger();
-
- // Sollte nur 1x pro Sitzung ausgeführt werden. Wie ermitteln wir das?
- //if ( DEVELOPMENT )
- // Logger::debug( "Effective configuration:\n".Spyc::YAMLDump($conf) );
-
- if (!empty($conf['security']['umask']))
- umask(octdec($conf['security']['umask']));
-
- if (!empty($conf['interface']['timeout']))
- set_time_limit(intval($conf['interface']['timeout']));
-
- $this->checkPostToken();
-
- define('FILE_SEP', $conf['interface']['file_separator']);
-
- $this->connectToDatabase();
- $this->startDatabaseTransaction();
-
- try{
-
- $result = $this->callActionMethod();
- }
- catch(Exception $e)
- {
- // In case of exception, rolling back the transaction
- try
- {
- $this->rollbackDatabaseTransaction();
- }
- catch(Exception $re)
- {
- Logger::warn("rollback failed:".$e->getMessage());
- }
-
- throw $e;
- }
-
- $this->commitDatabaseTransaction();
-
- if ( DEVELOPMENT )
- 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';
-
-
- // Yes, closing the session flushes the session data and unlocks other waiting requests.
- // Now another request is able to be executed.
- Session::close();
-
- // Ablaufzeit für den Inhalt auf aktuelle Zeit setzen.
- header('Expires: ' . substr(date('r', time() - date('Z')), 0, -5) . 'GMT', false);
-
- return $result;
- }
-
- /**
- * Prüft, ob die Actionklasse aufgerufen werden darf.
- *
- * @param $do Action
- * @throws SecurityException falls der Aufruf nicht erlaubt ist.
- */
- private function checkAccess($do)
- {
- switch (@$do->security) {
- case Action::SECURITY_GUEST:
- // Ok.
- break;
- case Action::SECURITY_USER:
- if (!is_object($do->currentUser))
- throw new SecurityException('No user logged in, but this action requires a valid user');
- break;
- case Action::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:
- }
-
- }
-
- private function checkPostToken()
- {
- 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?');
- throw new SecurityException("Token mismatch");
- }
- }
-
- /**
- * Logger initialisieren.
- */
- private function initializeLogger()
- {
-
- $logConfig = config('log');
-
- $logFile = $logConfig['file'];
-
- // Wenn Logfile relativ angegeben wurde, dann muss dies relativ zum Root der Anwendung sein.
- if ( !empty($logFile) && $logFile[0] != '/' )
- $logFile = __DIR__.'/../../'.$logFile;
- //$logFile = __DIR__.'/../../'.$logFile;
-
- Logger::$messageFormat = $logConfig['format'];
- Logger::$filename = $logFile;
- Logger::$dateFormat = $logConfig['date_format'];
- Logger::$nsLookup = $logConfig['ns_lookup'];
-
- $cname = 'LOGGER_LOG_' . strtoupper($logConfig['level']);
- if (defined($cname))
- Logger::$level = constant($cname);
-
-
- Logger::$messageCallback = function () {
-
- $action = Session::get('action');
- if (empty($action))
- $action = '-';
-
- $user = Session::getUser();
- if (is_object($user))
- $username = $user->name;
- else
- $username = '-';
-
- return array('user' => $username, 'action' => $action);
- };
- Logger::init();
- }
-
- private function checkConfiguration()
- {
- $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.
- $configLoader = new ConfigurationLoader( __DIR__.'/../../config/config.yml' );
-
- if (!is_array($conf) || $conf['config']['auto_reload'] && $configLoader->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();
-
- // Fest eingebaute Standard-Konfiguration laden.
- require(OR_MODULES_DIR . 'util/config-default.php');
- $conf = createDefaultConfig();
-
- $customConfig = $configLoader->load();
- $conf = array_replace_recursive($conf, $customConfig);
-
- // Sprache lesen
-
- 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;
-
- // 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; // language is not configured as available.
-
- $isProduction = $conf['production'];
- $language = new \language\Language();
- $lang = $language->getLanguage( $l,$isProduction);
- $conf['language'] = $lang;
- $conf['language']['language_code'] = $l;
- break;
- }
-
-
- if (!isset($conf['language']))
- throw new \LogicException('no language found! (languages=' . implode(',', $languages) . ')');
-
- // Schreibt die Konfiguration in die Sitzung. Diese wird anschliessend nicht
- // mehr veraendert.
- Session::setConfig($conf);
- }
-
- }
-
- /**
- * Aufruf der Action-Methode.
- * Diese Methode muss public sein, da sie für Embedded-Actions aus dem UI direkt aufgerufen wird.
- *
- * @return array Vollständige Rückgabe aller Daten als assoziatives Array
- */
- public function callActionMethod()
- {
- global $REQ;
- $actionClassName = ucfirst($this->request->action) . 'Action';
- $actionClassNameWithNamespace = 'cms\\action\\' . $actionClassName;
-
- if (!class_exists($actionClassNameWithNamespace))
- {
- // Laden der Action-Klasse.
- $success = include_once(__DIR__. '/action/' . $actionClassName . '.class.php');
-
- if ( !$success)
- throw new LogicException("Action '$this->request->action' is not available");
- }
-
- // Erzeugen der Action-Klasse
- /* @type $do \cms\action\Action */
- $do = new $actionClassNameWithNamespace;
-
- $do->request = $this->request;
- $do->init();
-
- if(!defined('OR_ID'))
- //if (isset($REQ[REQ_PARAM_ID]))
- define('OR_ID', $this->request->id);
- //else
- // define('OR_ID', '');
-
- $this->checkAccess($do);
-
- // POST-Request => ...Post() wird aufgerufen.
- // GET-Request => ...View() wird aufgerufen.
- $methodSuffix = $this->request->isAction ? 'Post' : 'View';
- $subactionMethodName = $this->request->method . $methodSuffix;
-
- // Daten werden nur angezeigt, die Sitzung kann also schon geschlossen werden.
- // Halt! In Index-Action können Benutzer-Logins gesetzt werden.
- if ( ! $this->request->isAction && $this->request->action != 'index' )
- Session::close();
-
- Logger::debug("Dispatcher executing {$this->request->action}/{$this->request->method}/" . @$REQ[REQ_PARAM_ID].' -> '.$actionClassName.'#'.$subactionMethodName.'() embed='.$this->request->isEmbedded);
-
-
- try {
- $method = new \ReflectionMethod($do,$subactionMethodName);
- $declaredClassName = $method->getDeclaringClass()->getShortName();
- $declaredActionName = strtolower(substr($declaredClassName,0,strpos($declaredClassName,'Action')));
-
- $method->invoke($do); // <== Executing the Action
- }
- catch (\ValidationException $ve)
- {
- $do->addValidationError( $ve->fieldName );
- }
- catch (\ReflectionException $re)
- {
- throw new BadMethodCallException("Method '$subactionMethodName' does not exist",0,$re);
- }
-
- // The action is able to change its method name.
- $this->request = $do->request;
- $this->request->action = $declaredActionName;
-
- $result = $do->getOutputData();
-
- return $result;
- }
-
- /**
- * Startet die Verbindung zur Datenbank.
- */
- private function connectToDatabase()
- {
- // Connect to database
- //
- $db = Session::getDatabase();
-
- if (is_object($db)) {
-
- $db->connect(); // throws exception if error.
-
- Session::setDatabase($db);
- }
-
- }
-
-
- /**
- * Eröffnet eine Transaktion.
- */
- private function startDatabaseTransaction()
- {
- // Verbindung zur Datenbank
- //
- $db = Session::getDatabase();
-
- if (is_object($db)) {
- // Transactions are only needed for POST-Request
- // GET-Request do only read from the database and have no need for transactions.
- if ( $this->request->isAction )
- $db->start();
- }
-
- }
-
-
- private function commitDatabaseTransaction()
- {
- $db = db_connection();
-
- if (is_object($db))
- // Transactions were only started for POST-Request
- if($this->request->isAction)
- $db->commit();
- }
-
-
-
- private function rollbackDatabaseTransaction()
- {
- $db = db_connection();
-
- if (is_object($db))
- // Transactions were only started for POST-Request
- if($this->request->isAction)
- $db->rollback();
- }
-
-
- /**
- * Sets the "Content-Language"-HTTP-Header with the user language.
- */
- private function setContentLanguageHeader()
- {
- header('Content-Language: ' . Conf()->subset('language')->get('language_code') );
- }
+<?php
+
+/*
+ * Loading and calling the action class (the "controller").
+ */
+namespace cms;
+
+use BadMethodCallException;
+use cms\action\Action;
+use cms\action\RequestParams;
+use ConfigurationLoader;
+use database\Database;
+use DomainException;
+use Http;
+use http\Exception;
+use language\Language;
+use Logger;
+use LogicException;
+use ObjectNotFoundException;
+use OpenRatException;
+use SecurityException;
+use Session;
+use Spyc;
+use template_engine\components\ElseComponent;
+
+
+/**
+ * Dispatcher for all cms actions.
+ *
+ * @package cms
+ */
+class Dispatcher
+{
+ /**
+ * @var RequestParams
+ */
+ public $request;
+
+ /**
+ * Vollständige Abarbeitug einer Aktion.
+ * Führt die gesamte Abarbeitung einer Aktion durch, incl. Datenbank-Transaktionssteuerung.
+ *
+ * @return array data for the client
+ */
+ public function doAction()
+ {
+ // Start the session. All classes should have been loaded up to now.
+ session_start();
+
+ $this->checkConfiguration();
+
+ // Vorhandene Konfiguration aus der Sitzung lesen.
+ global $conf;
+ $conf = Session::getConfig();
+
+ define('PRODUCTION', Conf()->is('production'));
+ define('DEVELOPMENT', !PRODUCTION);
+
+ if( DEVELOPMENT)
+ {
+ ini_set('display_errors', 1);
+ ini_set('display_startup_errors', 1);
+ error_reporting(E_ALL);
+ }else {
+ ini_set('display_errors', 0);
+ ini_set('display_startup_errors', 0);
+ error_reporting(0);
+ }
+
+ $this->setContentLanguageHeader();
+
+ // Nachdem die Konfiguration gelesen wurde, kann nun der Logger benutzt werden.
+ require_once(OR_MODULES_DIR . "logger/require." . PHP_EXT);
+ $this->initializeLogger();
+
+ // Sollte nur 1x pro Sitzung ausgeführt werden. Wie ermitteln wir das?
+ //if ( DEVELOPMENT )
+ // Logger::debug( "Effective configuration:\n".Spyc::YAMLDump($conf) );
+
+ if (!empty($conf['security']['umask']))
+ umask(octdec($conf['security']['umask']));
+
+ if (!empty($conf['interface']['timeout']))
+ set_time_limit(intval($conf['interface']['timeout']));
+
+ $this->checkPostToken();
+
+ define('FILE_SEP', $conf['interface']['file_separator']);
+
+ $this->connectToDatabase();
+ $this->startDatabaseTransaction();
+
+ try{
+
+ $result = $this->callActionMethod();
+ }
+ catch(Exception $e)
+ {
+ // In case of exception, rolling back the transaction
+ try
+ {
+ $this->rollbackDatabaseTransaction();
+ }
+ catch(Exception $re)
+ {
+ Logger::warn("rollback failed:".$e->getMessage());
+ }
+
+ throw $e;
+ }
+
+ $this->commitDatabaseTransaction();
+
+ if ( DEVELOPMENT )
+ 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';
+
+
+ // Yes, closing the session flushes the session data and unlocks other waiting requests.
+ // Now another request is able to be executed.
+ Session::close();
+
+ // Ablaufzeit für den Inhalt auf aktuelle Zeit setzen.
+ header('Expires: ' . substr(date('r', time() - date('Z')), 0, -5) . 'GMT', false);
+
+ return $result;
+ }
+
+ /**
+ * Prüft, ob die Actionklasse aufgerufen werden darf.
+ *
+ * @param $do Action
+ * @throws SecurityException falls der Aufruf nicht erlaubt ist.
+ */
+ private function checkAccess($do)
+ {
+ switch (@$do->security) {
+ case Action::SECURITY_GUEST:
+ // Ok.
+ break;
+ case Action::SECURITY_USER:
+ if (!is_object($do->currentUser))
+ throw new SecurityException('No user logged in, but this action requires a valid user');
+ break;
+ case Action::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:
+ }
+
+ }
+
+ private function checkPostToken()
+ {
+ 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?');
+ throw new SecurityException("Token mismatch");
+ }
+ }
+
+ /**
+ * Logger initialisieren.
+ */
+ private function initializeLogger()
+ {
+
+ $logConfig = config('log');
+
+ $logFile = $logConfig['file'];
+
+ // Wenn Logfile relativ angegeben wurde, dann muss dies relativ zum Root der Anwendung sein.
+ if ( !empty($logFile) && $logFile[0] != '/' )
+ $logFile = __DIR__.'/../../'.$logFile;
+ //$logFile = __DIR__.'/../../'.$logFile;
+
+ Logger::$messageFormat = $logConfig['format'];
+ Logger::$filename = $logFile;
+ Logger::$dateFormat = $logConfig['date_format'];
+ Logger::$nsLookup = $logConfig['ns_lookup'];
+
+ $cname = 'LOGGER_LOG_' . strtoupper($logConfig['level']);
+ if (defined($cname))
+ Logger::$level = constant($cname);
+
+
+ Logger::$messageCallback = function () {
+
+ $action = Session::get('action');
+ if (empty($action))
+ $action = '-';
+
+ $user = Session::getUser();
+ if (is_object($user))
+ $username = $user->name;
+ else
+ $username = '-';
+
+ return array('user' => $username, 'action' => $action);
+ };
+ Logger::init();
+ }
+
+ private function checkConfiguration()
+ {
+ $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.
+ $configLoader = new ConfigurationLoader( __DIR__.'/../../config/config.yml' );
+
+ if (!is_array($conf) || $conf['config']['auto_reload'] && $configLoader->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();
+
+ // Fest eingebaute Standard-Konfiguration laden.
+ require(OR_MODULES_DIR . 'util/config-default.php');
+ $conf = createDefaultConfig();
+
+ $customConfig = $configLoader->load();
+ $conf = array_replace_recursive($conf, $customConfig);
+
+ // Sprache lesen
+
+ 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;
+
+ // 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; // language is not configured as available.
+
+ $isProduction = $conf['production'];
+ $language = new \language\Language();
+ $lang = $language->getLanguage( $l,$isProduction);
+ $conf['language'] = $lang;
+ $conf['language']['language_code'] = $l;
+ break;
+ }
+
+
+ if (!isset($conf['language']))
+ throw new \LogicException('no language found! (languages=' . implode(',', $languages) . ')');
+
+ // Schreibt die Konfiguration in die Sitzung. Diese wird anschliessend nicht
+ // mehr veraendert.
+ Session::setConfig($conf);
+ }
+
+ }
+
+ /**
+ * Aufruf der Action-Methode.
+ * Diese Methode muss public sein, da sie für Embedded-Actions aus dem UI direkt aufgerufen wird.
+ *
+ * @return array Vollständige Rückgabe aller Daten als assoziatives Array
+ */
+ public function callActionMethod()
+ {
+ global $REQ;
+ $actionClassName = ucfirst($this->request->action) . 'Action';
+ $actionClassNameWithNamespace = 'cms\\action\\' . $actionClassName;
+
+ if (!class_exists($actionClassNameWithNamespace))
+ {
+ // Laden der Action-Klasse.
+ $success = include_once(__DIR__. '/action/' . $actionClassName . '.class.php');
+
+ if ( !$success)
+ throw new LogicException("Action '$this->request->action' is not available");
+ }
+
+ // Erzeugen der Action-Klasse
+ /* @type $do \cms\action\Action */
+ $do = new $actionClassNameWithNamespace;
+
+ $do->request = $this->request;
+ $do->init();
+
+ if(!defined('OR_ID'))
+ //if (isset($REQ[REQ_PARAM_ID]))
+ define('OR_ID', $this->request->id);
+ //else
+ // define('OR_ID', '');
+
+ $this->checkAccess($do);
+
+ // POST-Request => ...Post() wird aufgerufen.
+ // GET-Request => ...View() wird aufgerufen.
+ $methodSuffix = $this->request->isAction ? 'Post' : 'View';
+ $subactionMethodName = $this->request->method . $methodSuffix;
+
+ // Daten werden nur angezeigt, die Sitzung kann also schon geschlossen werden.
+ // Halt! In Index-Action können Benutzer-Logins gesetzt werden.
+ if ( ! $this->request->isAction && $this->request->action != 'index' )
+ Session::close();
+
+ Logger::debug("Dispatcher executing {$this->request->action}/{$this->request->method}/" . @$REQ[REQ_PARAM_ID].' -> '.$actionClassName.'#'.$subactionMethodName.'() embed='.$this->request->isEmbedded);
+
+
+ try {
+ $method = new \ReflectionMethod($do,$subactionMethodName);
+ $declaredClassName = $method->getDeclaringClass()->getShortName();
+ $declaredActionName = strtolower(substr($declaredClassName,0,strpos($declaredClassName,'Action')));
+
+ $method->invoke($do); // <== Executing the Action
+ }
+ catch (\ValidationException $ve)
+ {
+ $do->addValidationError( $ve->fieldName );
+ }
+ catch (\ReflectionException $re)
+ {
+ throw new BadMethodCallException("Method '$subactionMethodName' does not exist",0,$re);
+ }
+
+ // The action is able to change its method name.
+ $this->request = $do->request;
+ $this->request->action = $declaredActionName;
+
+ $result = $do->getOutputData();
+
+ return $result;
+ }
+
+ /**
+ * Startet die Verbindung zur Datenbank.
+ */
+ private function connectToDatabase()
+ {
+ if ( $this->request->hasRequestVar('dbid') )
+ $dbid = $this->request->getRequestVar('dbid',OR_FILTER_ALPHANUM);
+ elseif ( !empty( Session::getDatabaseId()))
+ $dbid = Session::getDatabaseId();
+ elseif ( isset($_COOKIE['or_dbid']) )
+ $dbid = $_COOKIE['or_dbid'];
+ else {
+ //throw new LogicException('No DBID available');
+ // some actions do not need a database
+ // f.e. the login dialog.
+ // so this is NOT an error.
+ return;
+ }
+
+
+ $dbConfig = config()->subset('database');
+
+ if ( ! $dbConfig->has( $dbid ) )
+ throw new \LogicException( 'unknown DB-Id: '.$dbid );
+
+ $dbConfig = $dbConfig->subset($dbid );
+
+ try
+ {
+ $key = $this->request->isAction?'write':'read';
+
+ $db = new Database( $dbConfig->subset($key)->getConfig() + $dbConfig->getConfig() );
+ $db->id = $dbid;
+
+ Session::setDatabaseId( $dbid );
+ Session::setDatabase( $db );
+ }catch(\Exception $e)
+ {
+ throw new OpenRatException('DATABASE_ERROR_CONNECTION',$e->getMessage() );
+ }
+ }
+
+
+ /**
+ * Eröffnet eine Transaktion.
+ */
+ private function startDatabaseTransaction()
+ {
+ // Verbindung zur Datenbank
+ //
+ $db = Session::getDatabase();
+
+ if (is_object($db)) {
+ // Transactions are only needed for POST-Request
+ // GET-Request do only read from the database and have no need for transactions.
+ if ( $this->request->isAction )
+ {
+ $db->start();
+
+ //register_shutdown_function( function() {
+ // $this->rollbackDatabaseTransaction();
+ //});
+ }
+ }
+
+ }
+
+
+ private function commitDatabaseTransaction()
+ {
+ $db = Session::getDatabase();
+
+ if (is_object($db))
+ // Transactions were only started for POST-Request
+ if($this->request->isAction)
+ $db->commit();
+ }
+
+
+
+ private function rollbackDatabaseTransaction()
+ {
+ $db = Session::getDatabase();
+
+ if (is_object($db))
+ // Transactions were only started for POST-Request
+ if($this->request->isAction)
+ $db->rollback();
+ }
+
+
+ /**
+ * Sets the "Content-Language"-HTTP-Header with the user language.
+ */
+ private function setContentLanguageHeader()
+ {
+ header('Content-Language: ' . Conf()->subset('language')->get('language_code') );
+ }
}
\ No newline at end of file
diff --git a/modules/cms-core/action/LoginAction.class.php b/modules/cms-core/action/LoginAction.class.php
@@ -1,1766 +1,1495 @@
-<?php
-
-namespace cms\action;
-
-
-use cms\model\User;
-use cms\model\Project;
-use cms\model\Group;
-use cms\model\Value;
-use cms\model\Element;
-use cms\model\Page;
-use cms\model\BaseObject;
-use cms\model\Language;
-use cms\model\Model;
-
-
-use \database\Database;
-use \DB;
-use \DbUpdate;
-use \Exception;
-use \Http;
-use \InternalAuth;
-use \Logger;
-use \ObjectNotFoundException;
-use \OpenRatException;
-use \security\Password;
-use \Session;
-use \Html;
-use \Mail;
-use \Text;
-
-
-// OpenRat Content Management System
-// Copyright (C) 2002-2007 Jan Dankert, jandankert@jandankert.de
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; version 2.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-
-define('PROJECTID_ADMIN',-1);
-
-/**
- * Action-Klasse fuer die Start-Action
- * @author $Author$
- * @version $Revision$
- * @package openrat.actions
- */
-
-class LoginAction extends Action
-{
- public $security = Action::SECURITY_GUEST;
-
-
- public function __construct()
- {
- parent::__construct();
- }
-
- /**
- * Eine Datenbankverbindugn wird aufgebaut und initalisiert.
- *
- * @param $dbid Datenbank-Id
- * @throws OpenRatException
- */
- private function setDb( $dbid )
- {
- global $conf;
-
- if ( !isset($conf['database'][$dbid] ))
- throw new \LogicException( 'unknown DB-Id: '.$dbid );
-
- try{
-
- $db = db();
-
- $db->rollback();
- $db->disconnect(); // Bäm. This seems to be necessary. WTF?
- //$db = null;
- //Session::setDatabase( null );
- }
- catch( Exception $e) {
- // happens if we have no db connection.
- }
-
- try
- {
- $db = new Database( $conf['database'][$dbid] );
- $db->id = $dbid;
- $db->start(); // Transaktion starten.
- Session::setDatabase( $db );
- }catch(\Exception $e)
- {
- throw new OpenRatException('DATABASE_ERROR_CONNECTION',$e->getMessage() );
- }
- }
-
-
- /**
- * Prueft, ob der Parameter 'dbid' übergeben wurde.
- * @throws OpenRatException
- */
- function checkForDb()
- {
- global $conf;
- $dbid = $this->getRequestVar('dbid');
-
- if ( $dbid != '' )
- $this->setDb( $dbid );
- }
-
-
- /**
- * @throws OpenRatException
- */
- function setDefaultDb()
- {
- if ( $this->hasRequestVar(REQ_PARAM_DATABASE_ID) )
- {
- $dbid = $this->getRequestVar(REQ_PARAM_DATABASE_ID);
- }
- else
- {
- global $conf;
-
- if ( !isset($conf['database']['default']) )
- throw new \LogicException('default-database not set');
-
- $dbid = $conf['database']['default'];
- }
-
- $this->setDb( $dbid );
- }
-
-
- /**
- * Führt ein Login durch.
- * @param $name string Benutzername
- * @param $pw string Password
- * @param $pw1 string new Password
- * @param $pw2 string new Password repeated
- * @return bool
- * @throws ObjectNotFoundException
- */
- private function checkLogin($name, $pw, $pw1, $pw2 )
- {
- Logger::debug( "Login user: '$name'.'" );
-
- global $conf;
- global $SESS;
-
- unset( $SESS['user'] );
-
-
- $db = db_connection();
-
- if ( !is_object($db) )
- {
- $this->addNotice('database','','DATABASE_CONNECTION_ERROR',OR_NOTICE_ERROR,array(),array('no connection'));
- //$this->callSubAction('showlogin');
- return false;
- }
-
- if ( !$db->available )
- {
- $this->addNotice('database',$db->conf['description'],'DATABASE_CONNECTION_ERROR',OR_NOTICE_ERROR,array(),array('Database Error: '.$db->error));
- //$this->callSubAction('showlogin');
- return false;
- }
-
- $ip = getenv("REMOTE_ADDR");
-
- $user = new User();
- $user->name = $name;
-
- $ok = $user->checkPassword( $pw );
-
- $mustChangePassword = $user->mustChangePassword;
-
- if ( $mustChangePassword )
- {
- // Der Benutzer hat zwar ein richtiges Kennwort eingegeben, aber dieses ist abgelaufen.
- // Wir versuchen hier, das neue zu setzen (sofern eingegeben).
- if ( empty($pw1) )
- {
- }
- elseif ( $pw1 != $pw2 )
- {
- $this->addValidationError('password1','PASSWORDS_DO_NOT_MATCH');
- $this->addValidationError('password2','');
- }
- elseif ( strlen($pw2) < $conf['security']['password']['min_length'] )
- {
- $this->addValidationError('password1','PASSWORD_MINLENGTH',array('minlength'=>$conf['security']['password']['min_length']));
- $this->addValidationError('password2','');
- }
- else
- {
- // Kennw?rter identisch und lang genug.
- $user->setPassword( $pw1,true );
-
- // Das neue Kennwort ist gesetzt, die Anmeldung ist also doch noch gelungen.
- $ok = true;
- $mustChangePassword = false;
-
- $pw = $pw1;
- }
- }
-
- // Falls Login erfolgreich
- if ( $ok )
- {
- // Login war erfolgreich!
- $user->load();
- $user->setCurrent();
-
- if ($user->passwordAlgo != Password::bestAlgoAvailable() )
- // Re-Hash the password with a better hash algo.
- $user->setPassword($pw);
-
-
- Logger::info( "login successful for {$user->name} from IP $ip" );
-
- return true;
- }
- else
- {
- Logger::info( "login failed for user {$user->name} from IP $ip" );
-
- return false;
- }
- }
-
-
- /**
- * Anzeigen der Loginmaske.
- *
- * Es wird nur die Loginmaske angezeigt.
- * @throws OpenRatException
- */
- function loginView()
- {
- // Hier nie "304 not modified" setzen, da sonst keine
- // Login-Fehlermeldung erscheinen kann.
- global $conf;
-
- $sso = $conf['security']['sso'];
- $ssl = $conf['security']['ssl'];
-
- $ssl_trust = false;
- $ssl_user_var = '';
- extract( $ssl, EXTR_PREFIX_ALL, 'ssl' );
-
- if ( $sso['enable'] )
- {
- $authid = $this->getRequestVar( $sso['auth_param_name']);
-
- if ( empty( $authid) )
- throw new \SecurityException( 'no authorization data (no auth-id)');
-
- if ( $sso['auth_param_serialized'] )
- $authid = unserialize( $authid );
-
- $purl = parse_url($sso['url']);
- // Verbindung zu URL herstellen.
- $errno=0; $errstr='';
- $fp = fsockopen ($purl['host'],80, $errno, $errstr, 30);
- if ( !$fp )
- {
- echo "Connection failed: $errstr ($errno)";
- }
- else
- {
- $http_get = $purl['path'];
- if ( !empty($purl['query']) )
- $http_get .= '?'.$purl['query'];
-
- $header = array();
-
- $header[] = "GET $http_get HTTP/1.0";
- $header[] ="Host: ".$purl['host'];
- $header[] = "User-Agent: Mozilla/5.0 (OpenRat CMS Single Sign-on Check)";
- $header[] = "Connection: Close";
-
- if ( $sso['cookie'] )
- {
- $cookie = 'Cookie: ';
- if ( is_array($authid))
- foreach( $authid as $cookiename=>$cookievalue)
- $cookie .= $cookiename.'='.$cookievalue."; ";
- else
- $cookie .= $sso['cookie_name'].'='.$authid;
-
- $header[] = $cookie;
- }
-
-// Html::debug($header);
- fputs ($fp, implode("\r\n",$header)."\r\n\r\n");
-
- $inhalt=array();
- while (!feof($fp)) {
- $inhalt[] = fgets($fp,128);
- }
- fclose($fp);
-
- $html = implode('',$inhalt);
-// Html::debug($html);
- if ( !preg_match($sso['expect_regexp'],$html) )
- throw new \SecurityException('auth failed');
- $treffer=0;
- if ( !preg_match($sso['username_regexp'],$html,$treffer) )
- throw new \SecurityException('auth failed');
- if ( !isset($treffer[1]) )
- throw new \SecurityException('authorization failed');
-
- $username = $treffer[1];
-
-// Html::debug( $treffer );
- $this->setDefaultDb();
-
- $user = User::loadWithName( $username );
-
- if ( ! $user->isValid( ))
- throw new \SecurityException('authorization failed: user not found: '.$username);
-
- $user->setCurrent();
-
- $this->callSubAction('show');
- }
- }
-
- elseif ( $ssl_trust )
- {
- if ( empty($ssl_user_var) )
- throw new \LogicException( 'please set environment variable name in ssl-configuration.' );
-
- $username = getenv( $ssl_user_var );
-
- if ( empty($username) )
- throw new \SecurityException( 'no username in client certificate ('.$ssl_user_var.') (or there is no client certificate...?)' );
-
- $this->setDefaultDb();
-
- $user = User::loadWithName( $username );
-
- if ( !$user->isValid() )
- throw new \LogicException( 'unknown username: '.$username );
-
- $user->setCurrent();
-
- $this->callSubAction('show');
- }
-
- $dbids = array();
-
- $databases = Conf()->get('database');
-
- if ( !is_array($databases))
- throw new \LogicException("Corrupt configuration: Databases configuration must be an array.");
-
-
- foreach( $databases as $dbid => $dbconf )
- {
- if ( !is_array($dbconf))
- throw new \LogicException("Corrup configuration: Database configuration '".$dbid."' must be an array.'");
-
- $dbconf += $conf['database-default']['defaults']; // Add Default-Values
-
- if ( is_array($dbconf) && $dbconf['enabled'] ) // Database-Connection is enabled
- $dbids[$dbid] = array(
- 'key' => $dbid,
- 'value' => empty($dbconf['name']) ? $dbid : Text::maxLength($dbconf['name']),
- 'title' => $dbconf['description']
- );
- }
-
-
- if ( empty($dbids) )
- $this->addNotice('','','no_database_configuration',OR_NOTICE_WARN);
-
- if ( !isset($this->templateVars['login_name']) && isset($_COOKIE['or_username']) )
- $this->setTemplateVar('login_name',$_COOKIE['or_username']);
-
- if ( !isset($this->templateVars['login_name']) )
- $this->setTemplateVar('login_name',@$conf['security']['default']['username']);
-
- if ( @$this->templateVars['login_name']== @$conf['security']['default']['username'])
- $this->setTemplateVar('login_password',@$conf['security']['default']['password']);
-
- $this->setTemplateVar( 'dbids',$dbids );
-
- // Vorausgewählte Datenbank-Id ermiteln
- $db = Session::getDatabase();
- if ( is_object($db) )
- // Datenbankverbindung ist noch in Sitzung, diese verwenden.
- $this->setTemplateVar('dbid',$db->id);
- elseif ( isset($_COOKIE['or_dbid']) && isset($dbids[$_COOKIE['or_dbid']]) )
- // DB-Id aus dem Cookie lesen.
- $this->setTemplateVar('dbid',$_COOKIE['or_dbid'] );
- elseif ( ! empty($conf['database-default']['default-id']) && isset($dbids[$conf['database-default']['default-id']]))
- // Default-Datenbankverbindung ist konfiguriert und vorhanden.
- $this->setTemplateVar('dbid',$conf['database-default']['default-id']);
- elseif ( count($dbids) > 0)
- // Datenbankverbindungen sind vorhanden, wir nehmen die erste.
- $this->setTemplateVar('dbid',array_keys($dbids)[0]);
- else
- // Keine Datenbankverbindung vorhanden. Fallback:
- $this->setTemplateVar('dbid','');
-
-
- // Den Benutzernamen aus dem Client-Zertifikat lesen und in die Loginmaske eintragen.
- $ssl_user_var = $conf['security']['ssl']['client_cert_dn_env'];
- if ( !empty($ssl_user_var) )
- {
- $username = getenv( $ssl_user_var );
-
- if ( empty($username) )
- {
- // Nothing to do.
- // if user has no valid client cert he could not access this form.
- }
- else {
-
- // Benutzername ist in Eingabemaske unver�nderlich
- $this->setTemplateVar('force_username',true);
- $this->setTemplateVar('login_name' ,$username);
- }
-
- }
-
- $this->setTemplateVar('objectid' ,$this->getRequestVar('objectid' ,OR_FILTER_NUMBER) );
- $this->setTemplateVar('projectid' ,$this->getRequestVar('projectid' ,OR_FILTER_NUMBER) );
- $this->setTemplateVar('modelid' ,$this->getRequestVar('modelid' ,OR_FILTER_NUMBER) );
- $this->setTemplateVar('languageid',$this->getRequestVar('languageid',OR_FILTER_NUMBER) );
-
- $this->setTemplateVar('register' ,$conf['login' ]['register' ]);
- $this->setTemplateVar('send_password',$conf['login' ]['send_password']);
-
- // Versuchen, einen Benutzernamen zu ermitteln, der im Eingabeformular vorausgewählt wird.
- $modules = explode(',',$conf['security']['modules']['preselect']);
-
- $username = '';
- foreach( $modules as $module)
- {
- Logger::debug('Preselecting module: '.$module);
- $moduleClass = $module.'Auth';
- /** @var \Auth $auth */
- $auth = new $moduleClass;
- $username = $auth->username();
-
- if ( !empty($username) )
- {
- Logger::debug('Preselecting User '.$username);
- break; // Benutzername gefunden.
- }
- }
-
- $this->setTemplateVar('login_name',$username);
- }
-
-
-
- /**
- * Anzeigen der Loginmaske.
- *
- * Es wird nur die Loginmaske angezeigt.
- * Hier nie "304 not modified" setzen, da sonst keine
- * Login-Fehlermeldung erscheinen kann
- */
- function openidView()
- {
- global $conf;
-
- foreach( $conf['database'] as $dbname=>$dbconf )
- {
- if ( is_array($dbconf) && $dbconf['enabled'] )
- $dbids[$dbname] = array('key' =>$dbname,
- 'value'=>Text::maxLength($dbconf['description']),
- 'title'=>$dbconf['description'].(isset($dbconf['host'])?' ('.$dbconf['host'].')':'') );
- }
-
- $openid_provider = array();
- foreach( explode(',',$conf['security']['openid']['provider']['name']) as $provider )
- $openid_provider[$provider] = config('security','openid','provider.'.$provider.'.name');
- $this->setTemplateVar('openid_providers',$openid_provider);
- $this->setTemplateVar('openid_user_identity',config('security','openid','user_identity'));
- //$this->setTemplateVar('openid_provider','identity');
-
-
- if ( empty($dbids) )
- $this->addNotice('','','no_database_configuration',OR_NOTICE_WARN);
-
- if ( !isset($_COOKIE['or_username']) )
- $this->setTemplateVar('login_name',$_COOKIE['or_username']);
- else
- $this->setTemplateVar('login_name',$conf['security']['default']['username']);
-
- $this->setTemplateVar( 'dbids',$dbids );
-
- $db = Session::getDatabase();
- if ( is_object($db) )
- $this->setTemplateVar('actdbid',$db->id);
- else
- $this->setTemplateVar('actdbid',$conf['database']['default']);
-
- $this->setTemplateVar('objectid' ,$this->getRequestVar('objectid' ,OR_FILTER_NUMBER) );
- $this->setTemplateVar('projectid' ,$this->getRequestVar('projectid' ,OR_FILTER_NUMBER) );
- $this->setTemplateVar('modelid' ,$this->getRequestVar('modelid' ,OR_FILTER_NUMBER) );
- $this->setTemplateVar('languageid',$this->getRequestVar('languageid',OR_FILTER_NUMBER) );
-
- }
-
-
-
- /**
- * Erzeugt ein Projekt-Auswahlmenue.
- */
- function projectmenu()
- {
- $user = Session::getUser();
-
- if ( $user->mustChangePassword )
- {
- $this->addNotice( 'user',$user->name,'PASSWORD_TIMEOUT','warn' );
- $this->callSubAction( 'changepassword' ); // Zwang, das Kennwort zu ?ndern.
- }
-
-
- // Diese Seite gilt pro Sitzung.
- $this->lastModified( $user->loginDate );
-
- // Projekte ermitteln
- $projects = $user->projects;
-
- $list = array();
-
- foreach( $projects as $id=>$name )
- {
- $p = array();
- $p['url' ] = Html::url('index','project',$id);
- $p['name'] = $name;
- $p['id' ] = $id;
-
- $tmpProject = new Project( $id );
- $p['defaultmodelid' ] = $tmpProject->getDefaultModelId();
- $p['defaultlanguageid'] = $tmpProject->getDefaultLanguageId();
- $p['models' ] = $tmpProject->getModels();
- $p['languages' ] = $tmpProject->getLanguages();
-
- $list[] = $p;
- }
-
- $this->setTemplateVar('projects',$list);
-
- if ( empty($list) )
- {
- // Kein Projekt vorhanden. Eine Hinweismeldung ausgeben.
- if ( $this->userIsAdmin() )
- // Administratoren bekommen bescheid, dass sie ein Projekt anlegen sollen
- $this->addNotice('','','ADMIN_NO_PROJECTS_AVAILABLE',OR_NOTICE_WARN);
- else
- // Normale Benutzer erhalten eine Meldung, dass kein Projekt zur Verf?gung steht
- $this->addNotice('','','NO_PROJECTS_AVAILABLE',OR_NOTICE_WARN);
- }
-
- }
-
-
-
- /**
- * Erzeugt eine Anwendungsliste.
- */
- function applications()
- {
- global $conf;
-
- // Diese Seite gilt pro Sitzung.
- $user = Session::getUser();
- $userGroups = $user->getGroups();
- $this->lastModified( $user->loginDate );
-
- // Applikationen ermitteln
- $list = array();
- foreach( $conf['applications'] as $id=>$app )
- {
- if ( !is_array($app) )
- continue;
-
- if ( isset($app['group']) )
- if ( !in_array($app['group'],$userGroups) )
- continue; // Keine Berechtigung, da Benutzer nicht in Gruppe vorhanden.
-
- $p = array();
- $p['url'] = $app['url'];
- $p['description'] = @$app['description'];
- if ( isset($app['param']) )
- {
- $p['url'] .= strpos($p['url'],'?')!==false?'&':'?';
- $p['url'] .= $app['param'].'='.session_id();
- }
- $p['name'] = $app['name'];
-
- $list[] = $p;
- }
-
-
- $this->setTemplateVar('applications',$list);
- }
-
-
-
-
- /**
- * Open-Id Login, ?berpr?fen der Anmeldung.<br>
- * Spezifikation: http://openid.net/specs/openid-authentication-1_1.html<br>
- * Kapitel "4.4. check_authentication"<br>
- * <br>
- * Im 2. Schritt (Mode "id_res") erfolgte ein Redirect vom Open-Id Provider an OpenRat zur?ck.<br>
- * Wir befinden uns nun im darauf folgenden Request des Browsers.<br>
- * <br>
- * Es muss noch beim OpenId-Provider die Best?tigung eingeholt werden, danach ist der
- * Benutzer angemeldet.<br>
- */
- public function openidloginView()
- {
- global $conf;
- $openId = Session::get('openid');
-
- if ( !$openId->checkAuthentication() )
- {
- throw new \SecurityException('OpenId-Login failed' );
- }
-
- //Html::debug($openId);
-
- // Anmeldung wurde mit "is_valid:true" best?tigt.
- // Der Benutzer ist jetzt eingeloggt.
- $username = $openId->getUserFromIdentiy();
-
- Logger::debug("OpenId-Login successful for $username");
-
- if ( empty($username) )
- {
- // Es konnte kein Benutzername ermittelt werden.
- throw new \SecurityException('no username supplied by openid provider' );
- }
-
- $user = User::loadWithName( $username );
-
- if ( $user->userid <=0)
- {
- // Benutzer ist (noch) nicht vorhanden.
- if ( $conf['security']['openid']['add']) // Anlegen?
- {
- $user->name = $username;
- $user->add();
-
- $user->mail = @$openId->info['email'];
- $user->fullname = @$openId->info['fullname'];
- $user->save(); // Um E-Mail zu speichern (wird bei add() nicht gemacht)
- }
- else
- {
- Logger::debug("OpenId-Login failed for $username");
- // Benutzer ist nicht in Benutzertabelle vorhanden (und angelegt werden soll er auch nicht).
- throw new \SecurityException('user',$username,'LOGIN_OPENID_FAILED','error',array('name'=>$username) );
- }
- }
- else
- {
- // Benutzer ist bereits vorhanden.
- if ( @$conf['security']['openid']['update_user'])
- {
- $user->fullname = @$openId->info['fullname'];
- $user->mail = @$openId->info['email'];
- $user->save();
- }
- }
-
- Logger::info("User login successful: ".$username);
- $user->setCurrent(); // Benutzer ist jetzt in der Sitzung.
-
- $this->setStyle( $user->style );
-
- $server = Http::getServer();
- Logger::debug("Redirecting to $server");
- header('Location: '.slashify($server) );
- exit();
- }
-
-
- /**
- * Login.
- */
- function openidPost()
- {
- global $conf;
-
- $this->checkForDb();
- Session::setUser('');
-
- if ( $conf['login']['nologin'] )
- throw new \SecurityException('login disabled');
-
- $openid_user = $this->getRequestVar('openid_url' );
- $loginName = $this->getRequestVar('login_name' ,OR_FILTER_ALPHANUM);
- $loginPassword = $this->getRequestVar('login_password',OR_FILTER_ALPHANUM);
- $newPassword1 = $this->getRequestVar('password1' ,OR_FILTER_ALPHANUM);
- $newPassword2 = $this->getRequestVar('password2' ,OR_FILTER_ALPHANUM);
-
- // Cookie setzen
- $this->setCookie('or_username',$loginName );
-
- // Login mit Open-Id.
- if ( $this->hasRequestVar('openid_provider') && ($this->getRequestVar('openid_provider') != 'identity' || !empty($openid_user)) )
- {
- $openId = new OpenId($this->getRequestVar('openid_provider'),$openid_user);
-
- if ( ! $openId->login() )
- {
- $this->addNotice('user',$openid_user,'LOGIN_OPENID_FAILED','error',array('name'=>$openid_user),array($openId->error) );
- $this->addValidationError('openid_url','');
- $this->callSubAction('showlogin');
- return;
- }
-
- Session::set('openid',$openId);
- $this->redirect( $openId->getRedirectUrl() );
- return;
- }
- }
-
-
- /**
- * Synchronisiert die bisherigen Gruppen des Benutzers mit den Gruppen, die sich aus der Authentifzierung ergeben haben.
- *
- * @param $user User Benutzerobjekt
- * @param $groups array $groups Einfaches Array von Gruppennamen.
- */
- private function checkGroups($user, $groups)
- {
- if ( $groups == null )
- return;
-
- $oldGroups = $user->getGroups();
-
- foreach( $oldGroups as $id=>$name)
- {
- if ( !in_array($name,$groups) )
- $user->delGroup($id);
- }
-
- foreach( $groups as $name)
- {
- if ( ! in_array($name,$oldGroups))
- {
- try
- {
- $group = Group::loadWithName( $name );
- $user->addGroup($group->groupid);
- }
- catch (ObjectNotFoundException $e)
- {
- // Gruppe fehlt. Anlegen?
- if ( config('ldap','authorize','auto_add' ) )
- {
- // Die Gruppe in der OpenRat-Datenbank hinzufuegen.
- $g = new Group();
- $g->name = $group;
- $g->add(); // Gruppe hinzufuegen
- $user->addGroup($g->groupid); // Und Gruppe dem Benutzer hinzufuegen.
- }
-
- }
- }
- }
- }
-
-
- /**
- * Login.
- * Zuerst wird die Datenbankverbindung aufgebaut und falls notwendig, aktualisiert.
- */
- function loginPost()
- {
- global $conf;
-
- Logger::info("DBID: ".$this->getRequestVar('dbid'));
- if ( $this->hasRequestVar('dbid'))
- {
- $dbid = $this->getRequestVar('dbid');
-
- if ( !is_array($conf['database'][$dbid]) )
- $this->addValidationError('dbid');
-
- $this->updateDatabase($dbid); // Updating...
- }
-
- $this->checkForDb();
-
- Session::setUser(''); // Altes Login entfernen.
-
- if ( $conf['login']['nologin'] )
- throw new \SecurityException('login disabled');
-
- $loginName = $this->getRequestVar('login_name' ,OR_FILTER_ALPHANUM);
- $loginPassword = $this->getRequestVar('login_password',OR_FILTER_ALPHANUM);
- $newPassword1 = $this->getRequestVar('password1' ,OR_FILTER_ALPHANUM);
- $newPassword2 = $this->getRequestVar('password2' ,OR_FILTER_ALPHANUM);
- $token = $this->getRequestVar('user_token' ,OR_FILTER_ALPHANUM);
-
- // Der Benutzer hat zwar ein richtiges Kennwort eingegeben, aber dieses ist abgelaufen.
- // Wir versuchen hier, das neue zu setzen (sofern eingegeben).
- if ( empty($newPassword1) )
- {
- // Kein neues Kennwort,
- // nichts zu tun...
- }
- else
- {
- $auth = new InternalAuth();
-
- if ( $auth->login($loginName, $loginPassword,$token) || $auth->mustChangePassword )
- {
- if ( $newPassword1 != $newPassword2 )
- {
- $this->addValidationError('password1','PASSWORDS_DO_NOT_MATCH');
- $this->addValidationError('password2','');
- return;
- }
- elseif ( strlen($newPassword1) < $conf['security']['password']['min_length'] )
- {
- $this->addValidationError('password1','PASSWORD_MINLENGTH',array('minlength'=>$conf['security']['password']['min_length']));
- $this->addValidationError('password2','');
- return;
- }
- else
- {
- // Kennwoerter identisch und lang genug.
- $user = User::loadWithName($loginName);
- $user->setPassword( $newPassword1,true );
-
- // Das neue gesetzte Kennwort für die weitere Authentifizierung benutzen.
- $loginPassword = $newPassword1;
- }
- }
- else
- {
- // Anmeldung gescheitert.
- $this->addNotice('user',$loginName,'LOGIN_FAILED','error',array('name'=>$loginName) );
- $this->addValidationError('login_name' ,'');
- $this->addValidationError('login_password','');
- return;
- }
- }
-
- // Cookie setzen
- $this->setCookie('or_username',$loginName );
- $this->setCookie('or_dbid' ,$this->getRequestVar('dbid'));
-
- // Authentifzierungs-Module.
- $modules = explode(',',$conf['security']['modules']['authenticate']);
-
- $loginOk = false;
- $mustChangePassword = false;
- $tokenFailed = false;
- $groups = null;
- $lastModule = null;
-
- // Jedes Authentifizierungsmodul durchlaufen, bis ein Login erfolgreich ist.
- foreach( $modules as $module)
- {
- $moduleClass = $module.'Auth';
- $auth = new $moduleClass;
- Logger::info('Trying to login with module '.$moduleClass);
- $loginStatus = $auth->login( $loginName,$loginPassword, $token );
- $loginOk = $loginStatus === true || $loginStatus === OR_AUTH_STATUS_SUCCESS;
-
- if ( $loginStatus === OR_AUTH_STATUS_PW_EXPIRED )
- $mustChangePassword = true;
- if ( $loginStatus === OR_AUTH_STATUS_TOKEN_NEEDED )
- $tokenFailed = true;
-
- if ( $loginOk )
- {
- Logger::info('Login successful for '.$loginName);
- $lastModule = $module;
-
- if ( isset($auth->groups ) )
- $groups = $auth->groups;
-
- break; // Login erfolgreich, erstes Modul gewinnt.
- }
- }
-
- /*
- $loginOk = $this->checkLogin( $loginName,
- $loginPassword,
- $newPassword1,
- $newPassword2 );
- */
-
-
- if ( $loginOk )
- {
-
- try
- {
- // Benutzer über den Benutzernamen laden.
- $user = User::loadWithName($loginName);
- $user->loginModuleName = $lastModule;
-// Session::setUser($user);
- $user->setCurrent();
-
- if ($user->passwordAlgo != Password::bestAlgoAvailable() )
- // Re-Hash the password with a better hash algo.
- $user->setPassword($loginPassword);
-
- }
- catch( ObjectNotFoundException $ex )
- {
- // Benutzer wurde zwar authentifiziert, ist aber in der
- // internen Datenbank nicht vorhanden
- if ( $conf['security']['newuser']['autoadd'] )
- {
- // Neue Benutzer in die interne Datenbank uebernehmen.
- $user = new User();
- $user->name = $loginName;
- $user->fullname = $loginName;
- $user->add();
- $user->save();
- }
- else
- {
- // Benutzer soll nicht angelegt werden.
- // Daher ist die Anmeldung hier gescheitert.
- $loginOk = false;
- }
- }
- }
-
- Password::delay();
-
- $ip = getenv("REMOTE_ADDR");
-
- if ( !$loginOk )
- {
- // Anmeldung nicht erfolgreich
-
- Logger::debug("Login failed for user '$loginName' from IP $ip");
-
- if ( $tokenFailed )
- {
- // Token falsch.
- $this->addNotice('user',$loginName,'LOGIN_FAILED_TOKEN_FAILED','error' );
- $this->addValidationError('user_token','');
- }
- elseif ( $mustChangePassword )
- {
- // Anmeldung gescheitert, Benutzer muss Kennwort ?ndern.
- $this->addNotice('user',$loginName,'LOGIN_FAILED_MUSTCHANGEPASSWORD','error' );
- $this->addValidationError('password1','');
- $this->addValidationError('password2','');
- }
- else
- {
- // Anmeldung gescheitert.
- $this->addNotice('user',$loginName,'LOGIN_FAILED','error',array('name'=>$loginName) );
- $this->addValidationError('login_name' ,'');
- $this->addValidationError('login_password','');
- }
-
-
- //$this->callSubAction('login');
- return;
- }
- else
- {
-
- Logger::debug("Login successful for user '$loginName' from IP $ip");
-
- $this->checkGroups( $user, $groups );
-
- if ( $this->hasRequestVar('remember') )
- {
- // Cookie setzen
- $this->setCookie('or_username',$user->name );
- $this->setCookie('or_token' ,$user->loginToken() );
- }
-
- // Anmeldung erfolgreich.
- if ( config('security','renew_session_login') )
- $this->recreateSession();
-
- $this->addNotice('user',$user->name,'LOGIN_OK',OR_NOTICE_OK,array('name'=>$user->fullname));
-
- $this->setStyle( $user->style ); // Benutzer-Style setzen
-
- $config = Session::getConfig();
- $language = new \language\Language();
- $config['language'] = $language->getLanguage($user->language);
- $config['language']['language_code'] = $user->language;
- Session::setConfig( $config );
-
-
-
- // Entscheiden, welche Perspektive als erstes angezeigt werden soll.
-
- $allProjects = Project::getAllProjects();
- }
-
- }
-
-
- /**
- * Benutzer meldet sich ab.
- */
- function logoutPost()
- {
- global $conf;
-
- $user = Session::getUser();
- if ( is_object($user) )
- $this->setTemplateVar('login_username',$user->name);
-
- if ( config('security','renew_session_logout') )
- $this->recreateSession();
-
- session_unset();
-
- if ( @$conf['theme']['compiler']['compile_at_logout'] )
- {
- foreach( $conf['action'] as $actionName => $actionConfig )
- {
- foreach( $actionConfig as $subActionName=>$subaction )
- {
- if ( is_array($subaction) &&
- !isset($subaction['goto' ]) &&
- !isset($subaction['direct']) &&
- !isset($subaction['action']) &&
- !isset($subaction['async' ]) &&
- !isset($subaction['alias' ]) &&
- $subActionName != 'menu' )
- {
- $engine = new template_engine\TemplateEngine();
- $engine->compile( strtolower(str_replace('Action','',$actionName)).'/'.$subActionName);
- }
- }
- }
- }
-
- // Login-Token löschen:
- // Wenn der Benutzer sich abmelden will, dann soll auch die automatische
- // Anmeldung deaktiviert werden.
- $this->setCookie('or_token' ,null );
-
- // Umleiten auf eine definierte URL.s
- $redirect_url = @$conf['security']['logout']['redirect_url'];
-
- if ( !empty($redirect_url) )
- {
- $this->redirect($redirect_url);
- }
-
- // Style zurücksetzen.
- // Der Style des Benutzers koennte auch stehen bleiben. Aber dann gäbe es Rückschlüsse darauf, wer zuletzt angemeldet war (Sicherheit!).
- $this->setStyle( config('interface','style','default') );
- }
-
-
-
- /**
- * Benutzer meldet sich ab.
- */
- function logoutView()
- {
- }
-
-
- /**
- * Ausgeben von maschinenlesbaren Benutzerinformationen.
- *
- * Diese Funktion dient dem Single-Signon f?r fremde Anwendungen, welche
- * die Benutzerinformationen des angemeldeten Benutzers aus dieser
- * Anwendung auslesen k?nnen.
- */
- function userinfo()
- {
- $user = Session::getUser();
- $info = array('username' => $user->name,
- 'fullname' => $user->fullname,
- 'mail' => $user->mail,
- 'telephone' => $user->tel,
- 'style' => $user->style,
- 'admin' => $user->isAdmin?'true':'false',
- 'ldap' => $user->ldap_dn,
- 'groups' => implode(',',$user->getGroups()),
- 'description'=> $user->desc
- );
-
- // Wenn der HTTP-Parameter "xml" vorhanden ist, dann geben wir die
- // Informationen per XML aus.
- if ( $this->hasRequestVar('xml') )
- {
- header('Content-Type: text/xml');
- echo '<userinfo>';
- foreach( $info as $n=>$i )
- echo '<'.$n.'>'.$i.'</'.$n.'>'."\n";
- echo '</userinfo>';
-
- }
-
- // Sonst normale Textausgabe im INI-Datei-Format.
- else
- {
- header('Content-Type: text/plain');
- foreach( $info as $n=>$i )
- echo $n.'="'.$i."\"\n";
- }
-
- exit; // Fertig.
- }
-
-
- function project()
- {
- $user = Session::getUser();
- if ( ! is_object($user) )
- {
- $this->callSubAction('show');
- return;
- }
-
- $this->evaluateRequestVars( array('projectid'=>$this->getRequestId()) );
-
- Session::setUser( $user );
- }
-
-
- function object()
- {
- $user = Session::getUser();
- if ( ! is_object($user) )
- {
- $this->callSubAction('show');
- return;
- }
-
- $this->evaluateRequestVars( array('objectid'=>$this->getRequestId()) );
-
- Session::setUser( $user );
- }
-
-
- function language()
- {
- $user = Session::getUser();
- if ( ! is_object($user) )
- {
- $this->callSubAction('show');
- return;
- }
-
- $this->evaluateRequestVars( array(REQ_PARAM_LANGUAGE_ID=>$this->getRequestId()) );
- }
-
-
- function model()
- {
- $user = Session::getUser();
- if ( ! is_object($user) )
- {
- $this->callSubAction('show');
- return;
- }
-
- $this->evaluateRequestVars( array(REQ_PARAM_MODEL_ID=>$this->getRequestId()) );
-
- $user = Session::getUser();
- }
-
-
- /**
- * Auswerten der Request-Variablen.
- *
- * @param Array $add
- */
- function evaluateRequestVars( $add = array() )
- {
- }
-
-
- function showtree()
- {
- Session::set('showtree',true );
- }
-
-
- function hidetree()
- {
- Session::set('showtree',false );
- }
-
-
- function switchuser()
- {
- $user = Session::getUser();
-
- if ( ! $user->isAdmin )
- throw new \SecurityException("Switching the user is only possible for admins.");
-
- $this->recreateSession();
-
- $newUser = new User( $this->getRequestId() );
- $newUser->load();
-
- $newUser->setCurrent();
- }
-
-
- function show()
- {
- global $conf;
- global $PHP_AUTH_USER;
- global $PHP_AUTH_PW;
-
- $user = Session::getUser();
- // Gast-Login
- if ( ! is_object($user) )
- {
- if ( $conf['security']['guest']['enable'] )
- {
- $this->setDefaultDb();
- $username = $conf['security']['guest']['user'];
- $user = User::loadWithName($username);
- if ( $user->userid > 0 )
- $user->setCurrent();
- else
- {
- Logger::warn('Guest login failed, user not found: '.$username);
- $this->addNotice('user',$username,'LOGIN_FAILED',OR_NOTICE_WARN,array('name'=>$username) );
- $user = null;
- }
- }
- }
-
- if ( ! is_object($user) )
- {
- switch( $conf['security']['login']['type'] )
- {
-
- // Authorization ueber HTTP
- //
- case 'http':
- $ok = false;
-
- if ( isset($_SERVER['PHP_AUTH_USER']) )
- {
- $this->setDefaultDb();
- $ok = $this->checkLogin( $_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW'] );
- }
-
- if ( ! $ok )
- {
- header( 'WWW-Authenticate: Basic realm="'.OR_TITLE.' - '.lang('HTTP_REALM').'"' );
- header( 'HTTP/1.0 401 Unauthorized' );
- echo 'Authorization Required!';
- exit;
- }
- break;
-
- case 'form':
- // Benutzer ist nicht angemeldet
- $this->callSubAction( 'showlogin' ); // Anzeigen der Login-Maske
- return;
- break;
-
- default:
- throw new \LogicException('Unknown auth-type: '.$conf['security']['login']['type'].'. Please check the configuration setting /security/login/type' );
- }
- }
-
- if ( $user->mustChangePassword )
- {
- $this->addNotice( 'user',$user->name,'PASSWORD_TIMEOUT','warn' );
- $this->callSubAction( 'changepassword' ); // Zwang, das Kennwort zu ?ndern.
- }
-
- // Seite ?ndert sich nur 1x pro Session
- $this->lastModified( $user->loginDate );
-
- }
-
-
-
- function checkMenu( $name )
- {
- global $conf;
-
- switch( $name )
- {
- case 'applications':
- // Men?punkt "Anwendungen" wird nur angezeigt, wenn weitere Anwendungen
- // konfiguriert sind.
- return count(@$conf['applications']) > 0;
-
- case 'register': // Registrierung
- // Nur, wenn aktiviert und gegen eigene Datenbank authentisiert wird.
- return @$conf['login']['register'] && @$conf['security']['auth']['type'] == 'database';
-
- case 'password': // Kennwort vergessen
- // Nur, wenn aktiviert und gegen eigene Datenbank authentisiert wird.
- // Deaktiviert, falls LDAP-Lookup aktiviert ist.
- return @$conf['login']['send_password'] && @$conf['security']['auth']['type'] == 'database'
- && !@$conf['security']['auth']['userdn'];
-
- case 'administration':
- // "Administration" nat?rlich nur f?r Administratoren.
- return $this->userIsAdmin();
-
- case 'login':
- return !@$conf['login']['nologin'];
-
- case 'logout':
- return true;
-
- case 'projectmenu':
- return true;
-
- default:
- return false;
- }
- }
-
-
- /**
- * Maske anzeigen, um Benutzer zu registrieren.
- */
- public function registerView()
- {
-
- }
-
-
- /**
- * Registriercode erzeugen und per E-Mail dem Benutzer mitteilen.
- * Maske anzeigen, damit Benuter Registriercode anzeigen kann.
- */
- public function registercodeView()
- {
- global $conf;
- foreach( $conf['database'] as $dbname=>$dbconf )
- {
- if ( is_array($dbconf) && $dbconf['enabled'] )
- $dbids[$dbname] = $dbconf['description'];
- }
-
- $this->setTemplateVar( 'dbids',$dbids );
-
- $db = Session::getDatabase();
- if ( is_object($db) )
- $this->setTemplateVar('actdbid',$db->id);
- else
- $this->setTemplateVar('actdbid',$conf['database']['default']);
-
-
-
- }
-
-
-
- public function registerPost()
- {
- global $conf;
-
- Session::set('registerMail',$this->getRequestVar('mail') );
-
- srand ((double)microtime()*1000003);
- $registerCode = rand();
-
- Session::set('registerCode',$registerCode );
-
- $email_address = $this->getRequestVar('mail',OR_FILTER_MAIL);
-
- if ( ! Mail::checkAddress($email_address) )
- {
- $this->addValidationError('mail');
- return;
- }
-
- // E-Mail and die eingegebene Adresse verschicken
- $mail = new Mail($email_address,
- 'register_commit_code','register_commit_code');
- $mail->setVar('code',$registerCode); // Registrierungscode als Text-Variable
-
- if ( $mail->send() )
- {
- $this->addNotice('','','mail_sent',OR_NOTICE_OK);
- }
- else
- {
- $this->addNotice('','','mail_not_sent',OR_NOTICE_ERROR,array(),$mail->error);
- return;
- }
- }
-
-
- /**
- * Benutzerregistierung.
- * Benutzer hat Best?tigungscode erhalten und eingegeben.
- */
- function registercodePost()
- {
- global $conf;
- $this->checkForDb();
-
- $origRegisterCode = Session::get('registerCode');
- $inputRegisterCode = $this->getRequestVar('code');
-
- if ( $origRegisterCode != $inputRegisterCode )
- {
- // Best?tigungscode stimmt nicht.
- $this->addValidationError('code','code_not_match');
- return;
- }
-
- // Best?tigungscode stimmt ?berein.
- // Neuen Benutzer anlegen.
-
- if ( !$this->hasRequestVar('username') )
- {
- $this->addValidationError('username');
- return;
- }
-
- $user = User::loadWithName( $this->getRequestVar('username') );
- if ( $user->isValid() )
- {
- $this->addValidationError('username','USER_ALREADY_IN_DATABASE');
- return;
- }
-
- if ( strlen($this->getRequestVar('password')) < $conf['security']['password']['min_length'] )
- {
- $this->addValidationError('password','password_minlength',array('minlength'=>$conf['security']['password']['min_length']));
- return;
- }
-
- $newUser = new User();
- $newUser->name = $this->getRequestVar('username');
- $newUser->add();
-
- $newUser->mail = Session::get('registerMail');
- $newUser->save();
-
- $newUser->setPassword( $this->getRequestVar('password'),true );
-
- $this->addNotice('user',$newUser->name,'user_added','ok');
- }
-
-
-
- /**
- * Vergessenes Kennwort zusenden lassen.
- */
- function passwordView()
- {
- // TODO: Attribut "Password" abfragen
- foreach( config('database') as $dbname=>$dbconf )
- {
- $dbconf = $dbconf + config('database-default','defaults');
- if ( $dbconf['enabled'] )
- $dbids[$dbname] = $dbconf['description'];
- }
-
- $this->setTemplateVar( 'dbids',$dbids );
-
-
- $db = Session::getDatabase();
-
- if ( is_object($db) )
- $this->setTemplateVar('actdbid',$db->id);
- else
- $this->setTemplateVar('actdbid',config('database-default','default-id'));
- }
-
-
- /*
- function changepassword()
- {
- }
- */
-
-
- /*
- function setnewpassword()
- {
- $oldPw = $this->getRequestVar('password_old' );
- $newPw1 = $this->getRequestVar('password_new_1');
- $newPw2 = $this->getRequestVar('password_new_2');
-
- if ( $newPw1 == $newPw2 )
- {
- // Aktuellen Benutzer aus der Sitzung ermitteln
- $user = $this->getUserFromSession();
-
- // Altes Kennwort pr?fen.
- $ok = $user->checkPassword( $oldPw );
-
- if ( $ok ) // Altes Kennwort ist ok.
- {
- $user->setPassword( $newPw1 ); // Setze neues Kennwort
- $user->mustChangePassword = false;
- Session::setUser($user);
- $this->addNotice('user',$user->name,'password_set','ok');
- }
- else
- {
- // Altes Kennwort falsch.
- $this->addNotice('user',$user->name,'password_error','error');
- }
- }
- else
- {
- // Beide neuen Kennw?rter stimmen nicht ?berein
- $this->addNotice('user',$user->name,'passwords_not_match','error');
- }
- }
- */
-
-
- /**
- * Einen Kennwort-Anforderungscode an den Benutzer senden.
- */
- function passwordPost()
- {
- if ( !$this->hasRequestVar('username') )
- {
- $this->addValidationError('username');
- return;
- }
-
- $this->checkForDb();
-
- $user = User::loadWithName( $this->getRequestVar("username") );
- // Html::debug($user);
- Password::delay();
- if ( $user->isValid() )
- {
- srand ((double)microtime()*1000003);
- $code = rand();
- $this->setSessionVar("password_commit_code",$code);
-
- $eMail = new Mail( $user->mail,'password_commit_code' );
- $eMail->setVar('name',$user->getName());
- $eMail->setVar('code',$code);
- if ( $eMail->send() )
- $this->addNotice('user',$user->getName(),'mail_sent',OR_NOTICE_OK);
- else
- $this->addNotice('user',$user->getName(),'mail_not_sent',OR_NOTICE_ERROR,array(),$eMail->error);
-
- }
- else
- {
- //$this->addNotice('','user','username_not_found');
- // Trotzdem vort?uschen, eine E-Mail zu senden, damit die G?ltigkeit
- // eines Benutzernamens nicht von au?en gepr?ft werden kann.
- //
- $this->addNotice('user',$this->getRequestVar("username"),'mail_sent');
-
- }
-
- $this->setSessionVar("password_commit_name",$user->name);
- }
-
-
-
- /**
- * Anzeige Formular zum Eingeben des Kennwort-Codes.
- *
- */
- function passwordcodeView()
- {
-
- }
-
-
- /**
- * Neues Kennwort erzeugen und dem Benutzer zusenden.
- */
- function passwordcodePost()
- {
- $username = $this->getSessionVar("password_commit_name");
-
- if ( $this->getRequestVar("code")=='' ||
- $this->getSessionVar("password_commit_code") != $this->getRequestVar("code") )
- {
- $this->addValidationError('code','PASSWORDCODE_NOT_MATCH');
- return;
- }
-
- $user = User::loadWithName( $username );
-
- if ( !$user->isValid() )
- {
- // Benutzer konnte nicht geladen werden.
- $this->addNotice('user',$username,'error',OR_NOTICE_ERROR);
- return;
- }
-
- $newPw = User::createPassword(); // Neues Kennwort erzeugen.
-
- $eMail = new Mail( $user->mail,'password_new' );
- $eMail->setVar('name' ,$user->getName());
- $eMail->setVar('password',$newPw );
-
- if ( $eMail->send() )
- {
- $user->setPassword( $newPw, false ); // Kennwort muss beim n?. Login ge?ndert werden.
- $this->addNotice('user',$username,'mail_sent',OR_NOTICE_OK);
- }
- else
- {
- // Sollte eigentlich nicht vorkommen, da der Benutzer ja auch schon den
- // Code per E-Mail erhalten hat.
- $this->addNotice('user',$username,'error',OR_NOTICE_ERROR,array(),$eMail->error);
- }
- }
-
-
- /**
- * Erzeugt eine neue Sitzung.
- */
- function recreateSession()
- {
-
- // PHP < 4.3.2 kennt die Funktion session_regenerate_id() nicht.
- if ( version_compare(phpversion(),"4.3.2","<") )
- {
- $randlen = 32;
- $randval = "0123456789abcdefghijklmnopqrstuvwxyz";
- $newid = "";
- for ($i = 1; $i <= $randlen; $i++)
- {
- $newid .= substr($randval, rand(0,(strlen($randval) - 1)), 1);
- }
- session_id( $newid );
- }
- elseif( version_compare(phpversion(),"4.3.2","==") )
- {
- session_regenerate_id();
-
- // Bug in PHP 4.3.2: Session-Cookie wird nicht neu gesetzt.
- if ( ini_get("session.use_cookies") )
- $this->setCookie( session_name(),session_id() );
- }
- elseif ( version_compare(phpversion(),"5.1.0",">") )
- {
- session_regenerate_id(true);
- }
- else
- {
- // 5.1.0 > PHP >= 4.3.3
- }
- }
-
-
- function licenseView()
- {
- $software = array();
-
- $software[] = array('name' =>'OpenRat Content Management System',
- 'url' =>'http://www.openrat.de/',
- 'license'=>'GPL v2');
- $software[] = array('name' =>'jQuery Core Javascript Framework',
- 'url' =>'http://jquery.com/',
- 'license'=>'MPL, GPL v2');
- $software[] = array('name' =>'jQuery UI Javascript Framework',
- 'url' =>'http://jqueryui.com/',
- 'license'=>'MPL, GPL v2');
- $software[] = array('name' =>'GeSHi - Generic Syntax Highlighter',
- 'url' =>'http://qbnz.com/highlighter/',
- 'license'=>'GPL v2');
- $software[] = array('name' =>'TAR file format',
- 'url' =>'http://www.phpclasses.org/package/529',
- 'license'=>'LGPL');
- $software[] = array('name' =>'JSON file format',
- 'url' =>'http://pear.php.net/pepr/pepr-proposal-show.php?id=198',
- 'license'=>'BSD');
-
- $this->setTemplateVar('software',$software);
-
-
-
- $this->setTemplateVar('time' ,date('r') );
- $this->setTemplateVar('os' ,php_uname('s') );
- $this->setTemplateVar('release' ,php_uname('r') );
- $this->setTemplateVar('machine' ,php_uname('m') );
- $this->setTemplateVar('version' , phpversion() );
-
- $this->setTemplateVar('cms_name' , Conf()->subset('application')->get('name' ) );
- $this->setTemplateVar('cms_version' , Conf()->subset('application')->get('version' ) );
- $this->setTemplateVar('cms_operator', Conf()->subset('application')->get('operator') );
-
- $user = Session::getUser();
- if ( !empty($user) )
- {
- $this->setTemplateVar('user_login' , $user->loginDate );
- $this->setTemplateVar('user_name' , $user->name );
- $this->setTemplateVar('user_fullname', $user->fullname );
- }
-
- }
-
-
- function pingView()
- {
- echo "1";
- }
-
- /**
- * Updating the database.
- *
- * @param $dbid integer
- * @throws OpenRatException
- */
- private function updateDatabase($dbid)
- {
- try {
- $adminDbConfig = Conf()->subset('database')->subset($dbid);
-
- $adminDb = new Database( config('database',$dbid), true);
- $adminDb->id = $dbid;
- } catch (Exception $e) {
-
- throw new OpenRatException('DATABASE_ERROR_CONNECTION', $e->getMessage());
- }
-
- $updater = new DbUpdate();
- $updater->update($adminDb);
-
- // Try to close the PDO connection. PDO doc:
- // To close the connection, you need to destroy the object by ensuring that all
- // remaining references to it are deleted—you do this by assigning NULL to the variable that holds the object.
- // If you don't do this explicitly, PHP will automatically close the connection when your script ends.
- $adminDb = null;
- unset($adminDb);
- }
-
-
- public function showView() {
- $this->nextSubAction('login');
- }
-}
-
-
-?>-
\ No newline at end of file
+<?php
+
+namespace cms\action;
+
+
+use cms\model\User;
+use cms\model\Project;
+use cms\model\Group;
+use cms\model\Value;
+use cms\model\Element;
+use cms\model\Page;
+use cms\model\BaseObject;
+use cms\model\Language;
+use cms\model\Model;
+
+
+use \database\Database;
+use \DB;
+use \DbUpdate;
+use \Exception;
+use \Http;
+use \InternalAuth;
+use \Logger;
+use \ObjectNotFoundException;
+use \OpenRatException;
+use \security\Password;
+use \Session;
+use \Html;
+use \Mail;
+use \Text;
+
+
+// OpenRat Content Management System
+// Copyright (C) 2002-2007 Jan Dankert, jandankert@jandankert.de
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+define('PROJECTID_ADMIN',-1);
+
+/**
+ * Action-Klasse fuer die Start-Action
+ * @author $Author$
+ * @version $Revision$
+ * @package openrat.actions
+ */
+
+class LoginAction extends Action
+{
+ public $security = Action::SECURITY_GUEST;
+
+
+ public function __construct()
+ {
+ parent::__construct();
+ }
+
+
+
+ /**
+ * Führt ein Login durch.
+ * @param $name string Benutzername
+ * @param $pw string Password
+ * @param $pw1 string new Password
+ * @param $pw2 string new Password repeated
+ * @return bool
+ * @throws ObjectNotFoundException
+ */
+ private function checkLogin($name, $pw, $pw1, $pw2 )
+ {
+ Logger::debug( "Login user: '$name'.'" );
+
+ global $conf;
+ global $SESS;
+
+ unset( $SESS['user'] );
+
+
+ $db = db_connection();
+
+ if ( !is_object($db) )
+ {
+ $this->addNotice('database','','DATABASE_CONNECTION_ERROR',OR_NOTICE_ERROR,array(),array('no connection'));
+ //$this->callSubAction('showlogin');
+ return false;
+ }
+
+ if ( !$db->available )
+ {
+ $this->addNotice('database',$db->conf['description'],'DATABASE_CONNECTION_ERROR',OR_NOTICE_ERROR,array(),array('Database Error: '.$db->error));
+ //$this->callSubAction('showlogin');
+ return false;
+ }
+
+ $ip = getenv("REMOTE_ADDR");
+
+ $user = new User();
+ $user->name = $name;
+
+ $ok = $user->checkPassword( $pw );
+
+ $mustChangePassword = $user->mustChangePassword;
+
+ if ( $mustChangePassword )
+ {
+ // Der Benutzer hat zwar ein richtiges Kennwort eingegeben, aber dieses ist abgelaufen.
+ // Wir versuchen hier, das neue zu setzen (sofern eingegeben).
+ if ( empty($pw1) )
+ {
+ }
+ elseif ( $pw1 != $pw2 )
+ {
+ $this->addValidationError('password1','PASSWORDS_DO_NOT_MATCH');
+ $this->addValidationError('password2','');
+ }
+ elseif ( strlen($pw2) < $conf['security']['password']['min_length'] )
+ {
+ $this->addValidationError('password1','PASSWORD_MINLENGTH',array('minlength'=>$conf['security']['password']['min_length']));
+ $this->addValidationError('password2','');
+ }
+ else
+ {
+ // Kennw?rter identisch und lang genug.
+ $user->setPassword( $pw1,true );
+
+ // Das neue Kennwort ist gesetzt, die Anmeldung ist also doch noch gelungen.
+ $ok = true;
+ $mustChangePassword = false;
+
+ $pw = $pw1;
+ }
+ }
+
+ // Falls Login erfolgreich
+ if ( $ok )
+ {
+ // Login war erfolgreich!
+ $user->load();
+ $user->setCurrent();
+
+ if ($user->passwordAlgo != Password::bestAlgoAvailable() )
+ // Re-Hash the password with a better hash algo.
+ $user->setPassword($pw);
+
+
+ Logger::info( "login successful for {$user->name} from IP $ip" );
+
+ return true;
+ }
+ else
+ {
+ Logger::info( "login failed for user {$user->name} from IP $ip" );
+
+ return false;
+ }
+ }
+
+
+ /**
+ * Anzeigen der Loginmaske.
+ *
+ * Es wird nur die Loginmaske angezeigt.
+ * @throws OpenRatException
+ */
+ function loginView()
+ {
+ // Hier nie "304 not modified" setzen, da sonst keine
+ // Login-Fehlermeldung erscheinen kann.
+ global $conf;
+
+ $sso = $conf['security']['sso'];
+ $ssl = $conf['security']['ssl'];
+
+ $ssl_trust = false;
+ $ssl_user_var = '';
+ extract( $ssl, EXTR_PREFIX_ALL, 'ssl' );
+
+ if ( $sso['enable'] )
+ {
+ $authid = $this->getRequestVar( $sso['auth_param_name']);
+
+ if ( empty( $authid) )
+ throw new \SecurityException( 'no authorization data (no auth-id)');
+
+ if ( $sso['auth_param_serialized'] )
+ $authid = unserialize( $authid );
+
+ $purl = parse_url($sso['url']);
+ // Verbindung zu URL herstellen.
+ $errno=0; $errstr='';
+ $fp = fsockopen ($purl['host'],80, $errno, $errstr, 30);
+ if ( !$fp )
+ {
+ echo "Connection failed: $errstr ($errno)";
+ }
+ else
+ {
+ $http_get = $purl['path'];
+ if ( !empty($purl['query']) )
+ $http_get .= '?'.$purl['query'];
+
+ $header = array();
+
+ $header[] = "GET $http_get HTTP/1.0";
+ $header[] ="Host: ".$purl['host'];
+ $header[] = "User-Agent: Mozilla/5.0 (OpenRat CMS Single Sign-on Check)";
+ $header[] = "Connection: Close";
+
+ if ( $sso['cookie'] )
+ {
+ $cookie = 'Cookie: ';
+ if ( is_array($authid))
+ foreach( $authid as $cookiename=>$cookievalue)
+ $cookie .= $cookiename.'='.$cookievalue."; ";
+ else
+ $cookie .= $sso['cookie_name'].'='.$authid;
+
+ $header[] = $cookie;
+ }
+
+ fputs ($fp, implode("\r\n",$header)."\r\n\r\n");
+
+ $inhalt=array();
+ while (!feof($fp)) {
+ $inhalt[] = fgets($fp,128);
+ }
+ fclose($fp);
+
+ $html = implode('',$inhalt);
+ if ( !preg_match($sso['expect_regexp'],$html) )
+ throw new \SecurityException('auth failed');
+ $treffer=0;
+ if ( !preg_match($sso['username_regexp'],$html,$treffer) )
+ throw new \SecurityException('auth failed');
+ if ( !isset($treffer[1]) )
+ throw new \SecurityException('authorization failed');
+
+ $username = $treffer[1];
+
+ $user = User::loadWithName( $username );
+
+ if ( ! $user->isValid( ))
+ throw new \SecurityException('authorization failed: user not found: '.$username);
+
+ $user->setCurrent();
+
+ $this->callSubAction('show');
+ }
+ }
+
+ elseif ( $ssl_trust )
+ {
+ if ( empty($ssl_user_var) )
+ throw new \LogicException( 'please set environment variable name in ssl-configuration.' );
+
+ $username = getenv( $ssl_user_var );
+
+ if ( empty($username) )
+ throw new \SecurityException( 'no username in client certificate ('.$ssl_user_var.') (or there is no client certificate...?)' );
+
+ $user = User::loadWithName( $username );
+
+ if ( !$user->isValid() )
+ throw new \LogicException( 'unknown username: '.$username );
+
+ $user->setCurrent();
+
+ $this->callSubAction('show');
+ }
+
+ $dbids = array();
+
+ $databases = Conf()->get('database');
+
+ if ( !is_array($databases))
+ throw new \LogicException("Corrupt configuration: Databases configuration must be an array.");
+
+
+ foreach( $databases as $dbid => $dbconf )
+ {
+ if ( !is_array($dbconf))
+ throw new \LogicException("Corrup configuration: Database configuration '".$dbid."' must be an array.'");
+
+ $dbconf += $conf['database-default']['defaults']; // Add Default-Values
+
+ if ( is_array($dbconf) && $dbconf['enabled'] ) // Database-Connection is enabled
+ $dbids[$dbid] = array(
+ 'key' => $dbid,
+ 'value' => empty($dbconf['name']) ? $dbid : Text::maxLength($dbconf['name']),
+ 'title' => $dbconf['description']
+ );
+ }
+
+
+ if ( empty($dbids) )
+ $this->addNotice('','','no_database_configuration',OR_NOTICE_WARN);
+
+ if ( !isset($this->templateVars['login_name']) && isset($_COOKIE['or_username']) )
+ $this->setTemplateVar('login_name',$_COOKIE['or_username']);
+
+ if ( !isset($this->templateVars['login_name']) )
+ $this->setTemplateVar('login_name',@$conf['security']['default']['username']);
+
+ if ( @$this->templateVars['login_name']== @$conf['security']['default']['username'])
+ $this->setTemplateVar('login_password',@$conf['security']['default']['password']);
+
+ $this->setTemplateVar( 'dbids',$dbids );
+
+ // Vorausgewählte Datenbank-Id ermiteln
+ $db = Session::getDatabase();
+ if ( is_object($db) )
+ // Datenbankverbindung ist noch in Sitzung, diese verwenden.
+ $this->setTemplateVar('dbid',$db->id);
+ elseif ( isset($_COOKIE['or_dbid']) && isset($dbids[$_COOKIE['or_dbid']]) )
+ // DB-Id aus dem Cookie lesen.
+ $this->setTemplateVar('dbid',$_COOKIE['or_dbid'] );
+ elseif ( ! empty($conf['database-default']['default-id']) && isset($dbids[$conf['database-default']['default-id']]))
+ // Default-Datenbankverbindung ist konfiguriert und vorhanden.
+ $this->setTemplateVar('dbid',$conf['database-default']['default-id']);
+ elseif ( count($dbids) > 0)
+ // Datenbankverbindungen sind vorhanden, wir nehmen die erste.
+ $this->setTemplateVar('dbid',array_keys($dbids)[0]);
+ else
+ // Keine Datenbankverbindung vorhanden. Fallback:
+ $this->setTemplateVar('dbid','');
+
+
+ // Den Benutzernamen aus dem Client-Zertifikat lesen und in die Loginmaske eintragen.
+ $ssl_user_var = $conf['security']['ssl']['client_cert_dn_env'];
+ if ( !empty($ssl_user_var) )
+ {
+ $username = getenv( $ssl_user_var );
+
+ if ( empty($username) )
+ {
+ // Nothing to do.
+ // if user has no valid client cert he could not access this form.
+ }
+ else {
+
+ // Benutzername ist in Eingabemaske unver�nderlich
+ $this->setTemplateVar('force_username',true);
+ $this->setTemplateVar('login_name' ,$username);
+ }
+
+ }
+
+ $this->setTemplateVar('objectid' ,$this->getRequestVar('objectid' ,OR_FILTER_NUMBER) );
+ $this->setTemplateVar('projectid' ,$this->getRequestVar('projectid' ,OR_FILTER_NUMBER) );
+ $this->setTemplateVar('modelid' ,$this->getRequestVar('modelid' ,OR_FILTER_NUMBER) );
+ $this->setTemplateVar('languageid',$this->getRequestVar('languageid',OR_FILTER_NUMBER) );
+
+ $this->setTemplateVar('register' ,$conf['login' ]['register' ]);
+ $this->setTemplateVar('send_password',$conf['login' ]['send_password']);
+
+ // Versuchen, einen Benutzernamen zu ermitteln, der im Eingabeformular vorausgewählt wird.
+ $modules = explode(',',$conf['security']['modules']['preselect']);
+
+ $username = '';
+ foreach( $modules as $module)
+ {
+ Logger::debug('Preselecting module: '.$module);
+ $moduleClass = $module.'Auth';
+ /** @var \Auth $auth */
+ $auth = new $moduleClass;
+ $username = $auth->username();
+
+ if ( !empty($username) )
+ {
+ Logger::debug('Preselecting User '.$username);
+ break; // Benutzername gefunden.
+ }
+ }
+
+ $this->setTemplateVar('login_name',$username);
+ }
+
+
+
+ /**
+ * Anzeigen der Loginmaske.
+ *
+ * Es wird nur die Loginmaske angezeigt.
+ * Hier nie "304 not modified" setzen, da sonst keine
+ * Login-Fehlermeldung erscheinen kann
+ */
+ function openidView()
+ {
+ global $conf;
+
+ foreach( $conf['database'] as $dbname=>$dbconf )
+ {
+ if ( is_array($dbconf) && $dbconf['enabled'] )
+ $dbids[$dbname] = array('key' =>$dbname,
+ 'value'=>Text::maxLength($dbconf['description']),
+ 'title'=>$dbconf['description'].(isset($dbconf['host'])?' ('.$dbconf['host'].')':'') );
+ }
+
+ $openid_provider = array();
+ foreach( explode(',',$conf['security']['openid']['provider']['name']) as $provider )
+ $openid_provider[$provider] = config('security','openid','provider.'.$provider.'.name');
+ $this->setTemplateVar('openid_providers',$openid_provider);
+ $this->setTemplateVar('openid_user_identity',config('security','openid','user_identity'));
+ //$this->setTemplateVar('openid_provider','identity');
+
+
+ if ( empty($dbids) )
+ $this->addNotice('','','no_database_configuration',OR_NOTICE_WARN);
+
+ if ( !isset($_COOKIE['or_username']) )
+ $this->setTemplateVar('login_name',$_COOKIE['or_username']);
+ else
+ $this->setTemplateVar('login_name',$conf['security']['default']['username']);
+
+ $this->setTemplateVar( 'dbids',$dbids );
+
+ $db = db();
+ if ( is_object($db) )
+ $this->setTemplateVar('actdbid',$db->id);
+ else
+ $this->setTemplateVar('actdbid',$conf['database']['default']);
+
+ $this->setTemplateVar('objectid' ,$this->getRequestVar('objectid' ,OR_FILTER_NUMBER) );
+ $this->setTemplateVar('projectid' ,$this->getRequestVar('projectid' ,OR_FILTER_NUMBER) );
+ $this->setTemplateVar('modelid' ,$this->getRequestVar('modelid' ,OR_FILTER_NUMBER) );
+ $this->setTemplateVar('languageid',$this->getRequestVar('languageid',OR_FILTER_NUMBER) );
+
+ }
+
+
+
+ /**
+ * Erzeugt eine Anwendungsliste.
+ * TODO: unused at the moment
+ */
+ function applications()
+ {
+ global $conf;
+
+ // Diese Seite gilt pro Sitzung.
+ $user = Session::getUser();
+ $userGroups = $user->getGroups();
+ $this->lastModified( $user->loginDate );
+
+ // Applikationen ermitteln
+ $list = array();
+ foreach( $conf['applications'] as $id=>$app )
+ {
+ if ( !is_array($app) )
+ continue;
+
+ if ( isset($app['group']) )
+ if ( !in_array($app['group'],$userGroups) )
+ continue; // Keine Berechtigung, da Benutzer nicht in Gruppe vorhanden.
+
+ $p = array();
+ $p['url'] = $app['url'];
+ $p['description'] = @$app['description'];
+ if ( isset($app['param']) )
+ {
+ $p['url'] .= strpos($p['url'],'?')!==false?'&':'?';
+ $p['url'] .= $app['param'].'='.session_id();
+ }
+ $p['name'] = $app['name'];
+
+ $list[] = $p;
+ }
+
+
+ $this->setTemplateVar('applications',$list);
+ }
+
+
+
+
+ /**
+ * Open-Id Login, ?berpr?fen der Anmeldung.<br>
+ * Spezifikation: http://openid.net/specs/openid-authentication-1_1.html<br>
+ * Kapitel "4.4. check_authentication"<br>
+ * <br>
+ * Im 2. Schritt (Mode "id_res") erfolgte ein Redirect vom Open-Id Provider an OpenRat zur?ck.<br>
+ * Wir befinden uns nun im darauf folgenden Request des Browsers.<br>
+ * <br>
+ * Es muss noch beim OpenId-Provider die Best?tigung eingeholt werden, danach ist der
+ * Benutzer angemeldet.<br>
+ */
+ public function openidloginView()
+ {
+ global $conf;
+ $openId = Session::get('openid');
+
+ if ( !$openId->checkAuthentication() )
+ {
+ throw new \SecurityException('OpenId-Login failed' );
+ }
+
+ //Html::debug($openId);
+
+ // Anmeldung wurde mit "is_valid:true" best?tigt.
+ // Der Benutzer ist jetzt eingeloggt.
+ $username = $openId->getUserFromIdentiy();
+
+ Logger::debug("OpenId-Login successful for $username");
+
+ if ( empty($username) )
+ {
+ // Es konnte kein Benutzername ermittelt werden.
+ throw new \SecurityException('no username supplied by openid provider' );
+ }
+
+ $user = User::loadWithName( $username );
+
+ if ( $user->userid <=0)
+ {
+ // Benutzer ist (noch) nicht vorhanden.
+ if ( $conf['security']['openid']['add']) // Anlegen?
+ {
+ $user->name = $username;
+ $user->add();
+
+ $user->mail = @$openId->info['email'];
+ $user->fullname = @$openId->info['fullname'];
+ $user->save(); // Um E-Mail zu speichern (wird bei add() nicht gemacht)
+ }
+ else
+ {
+ Logger::debug("OpenId-Login failed for $username");
+ // Benutzer ist nicht in Benutzertabelle vorhanden (und angelegt werden soll er auch nicht).
+ throw new \SecurityException('user',$username,'LOGIN_OPENID_FAILED','error',array('name'=>$username) );
+ }
+ }
+ else
+ {
+ // Benutzer ist bereits vorhanden.
+ if ( @$conf['security']['openid']['update_user'])
+ {
+ $user->fullname = @$openId->info['fullname'];
+ $user->mail = @$openId->info['email'];
+ $user->save();
+ }
+ }
+
+ Logger::info("User login successful: ".$username);
+ $user->setCurrent(); // Benutzer ist jetzt in der Sitzung.
+
+ $this->setStyle( $user->style );
+
+ $server = Http::getServer();
+ Logger::debug("Redirecting to $server");
+ header('Location: '.slashify($server) );
+ exit();
+ }
+
+
+ /**
+ * Login.
+ */
+ function openidPost()
+ {
+ global $conf;
+
+ Session::setUser('');
+
+ if ( $conf['login']['nologin'] )
+ throw new \SecurityException('login disabled');
+
+ $openid_user = $this->getRequestVar('openid_url' );
+ $loginName = $this->getRequestVar('login_name' ,OR_FILTER_ALPHANUM);
+ $loginPassword = $this->getRequestVar('login_password',OR_FILTER_ALPHANUM);
+ $newPassword1 = $this->getRequestVar('password1' ,OR_FILTER_ALPHANUM);
+ $newPassword2 = $this->getRequestVar('password2' ,OR_FILTER_ALPHANUM);
+
+ // Cookie setzen
+ $this->setCookie('or_username',$loginName );
+
+ // Login mit Open-Id.
+ if ( $this->hasRequestVar('openid_provider') && ($this->getRequestVar('openid_provider') != 'identity' || !empty($openid_user)) )
+ {
+ $openId = new OpenId($this->getRequestVar('openid_provider'),$openid_user);
+
+ if ( ! $openId->login() )
+ {
+ $this->addNotice('user',$openid_user,'LOGIN_OPENID_FAILED','error',array('name'=>$openid_user),array($openId->error) );
+ $this->addValidationError('openid_url','');
+ $this->callSubAction('showlogin');
+ return;
+ }
+
+ Session::set('openid',$openId);
+ $this->redirect( $openId->getRedirectUrl() );
+ return;
+ }
+ }
+
+
+ /**
+ * Synchronisiert die bisherigen Gruppen des Benutzers mit den Gruppen, die sich aus der Authentifzierung ergeben haben.
+ *
+ * @param $user User Benutzerobjekt
+ * @param $groups array $groups Einfaches Array von Gruppennamen.
+ */
+ private function checkGroups($user, $groups)
+ {
+ if ( $groups == null )
+ return;
+
+ $oldGroups = $user->getGroups();
+
+ foreach( $oldGroups as $id=>$name)
+ {
+ if ( !in_array($name,$groups) )
+ $user->delGroup($id);
+ }
+
+ foreach( $groups as $name)
+ {
+ if ( ! in_array($name,$oldGroups))
+ {
+ try
+ {
+ $group = Group::loadWithName( $name );
+ $user->addGroup($group->groupid);
+ }
+ catch (ObjectNotFoundException $e)
+ {
+ // Gruppe fehlt. Anlegen?
+ if ( config('ldap','authorize','auto_add' ) )
+ {
+ // Die Gruppe in der OpenRat-Datenbank hinzufuegen.
+ $g = new Group();
+ $g->name = $group;
+ $g->add(); // Gruppe hinzufuegen
+ $user->addGroup($g->groupid); // Und Gruppe dem Benutzer hinzufuegen.
+ }
+
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Login.
+ * Zuerst wird die Datenbankverbindung aufgebaut und falls notwendig, aktualisiert.
+ */
+ function loginPost()
+ {
+ global $conf;
+
+ $db = db(); // throws Exception, if database is not available.
+ {
+ $dbid = $db->id;
+
+ $this->updateDatabase($dbid); // Updating...
+ }
+
+ Session::setUser(''); // Altes Login entfernen.
+
+ if ( $conf['login']['nologin'] )
+ throw new \SecurityException('login disabled');
+
+ $loginName = $this->getRequestVar('login_name' ,OR_FILTER_ALPHANUM);
+ $loginPassword = $this->getRequestVar('login_password',OR_FILTER_ALPHANUM);
+ $newPassword1 = $this->getRequestVar('password1' ,OR_FILTER_ALPHANUM);
+ $newPassword2 = $this->getRequestVar('password2' ,OR_FILTER_ALPHANUM);
+ $token = $this->getRequestVar('user_token' ,OR_FILTER_ALPHANUM);
+
+ // Der Benutzer hat zwar ein richtiges Kennwort eingegeben, aber dieses ist abgelaufen.
+ // Wir versuchen hier, das neue zu setzen (sofern eingegeben).
+ if ( empty($newPassword1) )
+ {
+ // Kein neues Kennwort,
+ // nichts zu tun...
+ }
+ else
+ {
+ $auth = new InternalAuth();
+
+ if ( $auth->login($loginName, $loginPassword,$token) || $auth->mustChangePassword )
+ {
+ if ( $newPassword1 != $newPassword2 )
+ {
+ $this->addValidationError('password1','PASSWORDS_DO_NOT_MATCH');
+ $this->addValidationError('password2','');
+ return;
+ }
+ elseif ( strlen($newPassword1) < $conf['security']['password']['min_length'] )
+ {
+ $this->addValidationError('password1','PASSWORD_MINLENGTH',array('minlength'=>$conf['security']['password']['min_length']));
+ $this->addValidationError('password2','');
+ return;
+ }
+ else
+ {
+ // Kennwoerter identisch und lang genug.
+ $user = User::loadWithName($loginName);
+ $user->setPassword( $newPassword1,true );
+
+ // Das neue gesetzte Kennwort für die weitere Authentifizierung benutzen.
+ $loginPassword = $newPassword1;
+ }
+ }
+ else
+ {
+ // Anmeldung gescheitert.
+ $this->addNotice('user',$loginName,'LOGIN_FAILED','error',array('name'=>$loginName) );
+ $this->addValidationError('login_name' ,'');
+ $this->addValidationError('login_password','');
+ return;
+ }
+ }
+
+ // Cookie setzen
+ $this->setCookie('or_username',$loginName );
+ $this->setCookie('or_dbid' ,$this->getRequestVar('dbid'));
+
+ // Authentifzierungs-Module.
+ $modules = explode(',',$conf['security']['modules']['authenticate']);
+
+ $loginOk = false;
+ $mustChangePassword = false;
+ $tokenFailed = false;
+ $groups = null;
+ $lastModule = null;
+
+ // Jedes Authentifizierungsmodul durchlaufen, bis ein Login erfolgreich ist.
+ foreach( $modules as $module)
+ {
+ $moduleClass = $module.'Auth';
+ $auth = new $moduleClass;
+ Logger::info('Trying to login with module '.$moduleClass);
+ $loginStatus = $auth->login( $loginName,$loginPassword, $token );
+ $loginOk = $loginStatus === true || $loginStatus === OR_AUTH_STATUS_SUCCESS;
+
+ if ( $loginStatus === OR_AUTH_STATUS_PW_EXPIRED )
+ $mustChangePassword = true;
+ if ( $loginStatus === OR_AUTH_STATUS_TOKEN_NEEDED )
+ $tokenFailed = true;
+
+ if ( $loginOk )
+ {
+ Logger::info('Login successful for '.$loginName);
+ $lastModule = $module;
+
+ if ( isset($auth->groups ) )
+ $groups = $auth->groups;
+
+ break; // Login erfolgreich, erstes Modul gewinnt.
+ }
+ }
+
+ /*
+ $loginOk = $this->checkLogin( $loginName,
+ $loginPassword,
+ $newPassword1,
+ $newPassword2 );
+ */
+
+
+ if ( $loginOk )
+ {
+
+ try
+ {
+ // Benutzer über den Benutzernamen laden.
+ $user = User::loadWithName($loginName);
+ $user->loginModuleName = $lastModule;
+ $user->setCurrent();
+
+ if ($user->passwordAlgo != Password::bestAlgoAvailable() )
+ // Re-Hash the password with a better hash algo.
+ $user->setPassword($loginPassword);
+
+ }
+ catch( ObjectNotFoundException $ex )
+ {
+ // Benutzer wurde zwar authentifiziert, ist aber in der
+ // internen Datenbank nicht vorhanden
+ if ( $conf['security']['newuser']['autoadd'] )
+ {
+ // Neue Benutzer in die interne Datenbank uebernehmen.
+ $user = new User();
+ $user->name = $loginName;
+ $user->fullname = $loginName;
+ $user->add();
+ $user->save();
+ }
+ else
+ {
+ // Benutzer soll nicht angelegt werden.
+ // Daher ist die Anmeldung hier gescheitert.
+ $loginOk = false;
+ }
+ }
+ }
+
+ Password::delay();
+
+ $ip = getenv("REMOTE_ADDR");
+
+ if ( !$loginOk )
+ {
+ // Anmeldung nicht erfolgreich
+
+ Logger::debug("Login failed for user '$loginName' from IP $ip");
+
+ if ( $tokenFailed )
+ {
+ // Token falsch.
+ $this->addNotice('user',$loginName,'LOGIN_FAILED_TOKEN_FAILED','error' );
+ $this->addValidationError('user_token','');
+ }
+ elseif ( $mustChangePassword )
+ {
+ // Anmeldung gescheitert, Benutzer muss Kennwort ?ndern.
+ $this->addNotice('user',$loginName,'LOGIN_FAILED_MUSTCHANGEPASSWORD','error' );
+ $this->addValidationError('password1','');
+ $this->addValidationError('password2','');
+ }
+ else
+ {
+ // Anmeldung gescheitert.
+ $this->addNotice('user',$loginName,'LOGIN_FAILED','error',array('name'=>$loginName) );
+ $this->addValidationError('login_name' ,'');
+ $this->addValidationError('login_password','');
+ }
+
+ return;
+ }
+ else
+ {
+
+ Logger::debug("Login successful for user '$loginName' from IP $ip");
+
+ $this->checkGroups( $user, $groups );
+
+ if ( $this->hasRequestVar('remember') )
+ {
+ // Cookie setzen
+ $this->setCookie('or_username',$user->name );
+ $this->setCookie('or_token' ,$user->loginToken() );
+ }
+
+ // Anmeldung erfolgreich.
+ if ( config()->subset('security')->is('renew_session_login',false) )
+ $this->recreateSession();
+
+ $this->addNotice('user',$user->name,'LOGIN_OK',OR_NOTICE_OK,array('name'=>$user->fullname));
+
+ $this->setStyle( $user->style ); // Benutzer-Style setzen
+
+ $config = Session::getConfig();
+ $language = new \language\Language();
+ $config['language'] = $language->getLanguage($user->language);
+ $config['language']['language_code'] = $user->language;
+ Session::setConfig( $config );
+ }
+
+ }
+
+
+ /**
+ * Benutzer meldet sich ab.
+ */
+ function logoutPost()
+ {
+ global $conf;
+
+ $user = Session::getUser();
+ if ( is_object($user) )
+ $this->setTemplateVar('login_username',$user->name);
+
+ if ( config()->subset('security')->is('renew_session_logout',false) )
+ $this->recreateSession();
+
+ session_unset();
+
+ if ( @$conf['theme']['compiler']['compile_at_logout'] )
+ {
+ foreach( $conf['action'] as $actionName => $actionConfig )
+ {
+ foreach( $actionConfig as $subActionName=>$subaction )
+ {
+ if ( is_array($subaction) &&
+ !isset($subaction['goto' ]) &&
+ !isset($subaction['direct']) &&
+ !isset($subaction['action']) &&
+ !isset($subaction['async' ]) &&
+ !isset($subaction['alias' ]) &&
+ $subActionName != 'menu' )
+ {
+ $engine = new template_engine\TemplateEngine();
+ $engine->compile( strtolower(str_replace('Action','',$actionName)).'/'.$subActionName);
+ }
+ }
+ }
+ }
+
+ // Login-Token löschen:
+ // Wenn der Benutzer sich abmelden will, dann soll auch die automatische
+ // Anmeldung deaktiviert werden.
+ $this->setCookie('or_token' ,null );
+
+ // Umleiten auf eine definierte URL.s
+ $redirect_url = @$conf['security']['logout']['redirect_url'];
+
+ if ( !empty($redirect_url) )
+ {
+ $this->redirect($redirect_url);
+ }
+
+ // Style zurücksetzen.
+ // Der Style des Benutzers koennte auch stehen bleiben. Aber dann gäbe es Rückschlüsse darauf, wer zuletzt angemeldet war (Sicherheit!).
+ $this->setStyle( config('interface','style','default') );
+ }
+
+
+
+ /**
+ * Benutzer meldet sich ab.
+ */
+ function logoutView()
+ {
+ }
+
+
+ /**
+ * Ausgeben von maschinenlesbaren Benutzerinformationen.
+ *
+ * Diese Funktion dient dem Single-Signon f?r fremde Anwendungen, welche
+ * die Benutzerinformationen des angemeldeten Benutzers aus dieser
+ * Anwendung auslesen k?nnen.
+ */
+ function userinfo()
+ {
+ $user = Session::getUser();
+ $info = array('username' => $user->name,
+ 'fullname' => $user->fullname,
+ 'mail' => $user->mail,
+ 'telephone' => $user->tel,
+ 'style' => $user->style,
+ 'admin' => $user->isAdmin?'true':'false',
+ 'ldap' => $user->ldap_dn,
+ 'groups' => implode(',',$user->getGroups()),
+ 'description'=> $user->desc
+ );
+
+ // Wenn der HTTP-Parameter "xml" vorhanden ist, dann geben wir die
+ // Informationen per XML aus.
+ if ( $this->hasRequestVar('xml') )
+ {
+ header('Content-Type: text/xml');
+ echo '<userinfo>';
+ foreach( $info as $n=>$i )
+ echo '<'.$n.'>'.$i.'</'.$n.'>'."\n";
+ echo '</userinfo>';
+
+ }
+
+ // Sonst normale Textausgabe im INI-Datei-Format.
+ else
+ {
+ header('Content-Type: text/plain');
+ foreach( $info as $n=>$i )
+ echo $n.'="'.$i."\"\n";
+ }
+
+ exit; // Fertig.
+ }
+
+
+ function project()
+ {
+ $user = Session::getUser();
+ if ( ! is_object($user) )
+ {
+ $this->callSubAction('show');
+ return;
+ }
+
+ $this->evaluateRequestVars( array('projectid'=>$this->getRequestId()) );
+
+ Session::setUser( $user );
+ }
+
+
+ function object()
+ {
+ $user = Session::getUser();
+ if ( ! is_object($user) )
+ {
+ $this->callSubAction('show');
+ return;
+ }
+
+ $this->evaluateRequestVars( array('objectid'=>$this->getRequestId()) );
+
+ Session::setUser( $user );
+ }
+
+
+ function language()
+ {
+ $user = Session::getUser();
+ if ( ! is_object($user) )
+ {
+ $this->callSubAction('show');
+ return;
+ }
+
+ $this->evaluateRequestVars( array(REQ_PARAM_LANGUAGE_ID=>$this->getRequestId()) );
+ }
+
+
+ function model()
+ {
+ $user = Session::getUser();
+ if ( ! is_object($user) )
+ {
+ $this->callSubAction('show');
+ return;
+ }
+
+ $this->evaluateRequestVars( array(REQ_PARAM_MODEL_ID=>$this->getRequestId()) );
+
+ $user = Session::getUser();
+ }
+
+
+ /**
+ * Auswerten der Request-Variablen.
+ *
+ * @param Array $add
+ */
+ function evaluateRequestVars( $add = array() )
+ {
+ }
+
+
+ function showtree()
+ {
+ Session::set('showtree',true );
+ }
+
+
+ function hidetree()
+ {
+ Session::set('showtree',false );
+ }
+
+
+ function switchuser()
+ {
+ $user = Session::getUser();
+
+ if ( ! $user->isAdmin )
+ throw new \SecurityException("Switching the user is only possible for admins.");
+
+ $this->recreateSession();
+
+ $newUser = new User( $this->getRequestId() );
+ $newUser->load();
+
+ $newUser->setCurrent();
+ }
+
+
+ function show()
+ {
+ global $conf;
+ global $PHP_AUTH_USER;
+ global $PHP_AUTH_PW;
+
+ $user = Session::getUser();
+ // Gast-Login
+ if ( ! is_object($user) )
+ {
+ if ( $conf['security']['guest']['enable'] )
+ {
+ $username = $conf['security']['guest']['user'];
+ $user = User::loadWithName($username);
+ if ( $user->userid > 0 )
+ $user->setCurrent();
+ else
+ {
+ Logger::warn('Guest login failed, user not found: '.$username);
+ $this->addNotice('user',$username,'LOGIN_FAILED',OR_NOTICE_WARN,array('name'=>$username) );
+ $user = null;
+ }
+ }
+ }
+
+ if ( ! is_object($user) )
+ {
+ switch( $conf['security']['login']['type'] )
+ {
+
+ // Authorization ueber HTTP
+ //
+ case 'http':
+ $ok = false;
+
+ if ( isset($_SERVER['PHP_AUTH_USER']) )
+ {
+ $ok = $this->checkLogin( $_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW'] );
+ }
+
+ if ( ! $ok )
+ {
+ header( 'WWW-Authenticate: Basic realm="'.OR_TITLE.' - '.lang('HTTP_REALM').'"' );
+ header( 'HTTP/1.0 401 Unauthorized' );
+ echo 'Authorization Required!';
+ exit;
+ }
+ break;
+
+ case 'form':
+ // Benutzer ist nicht angemeldet
+ $this->callSubAction( 'showlogin' ); // Anzeigen der Login-Maske
+ return;
+ break;
+
+ default:
+ throw new \LogicException('Unknown auth-type: '.$conf['security']['login']['type'].'. Please check the configuration setting /security/login/type' );
+ }
+ }
+
+ if ( $user->mustChangePassword )
+ {
+ $this->addNotice( 'user',$user->name,'PASSWORD_TIMEOUT','warn' );
+ $this->callSubAction( 'changepassword' ); // Zwang, das Kennwort zu ?ndern.
+ }
+
+ // Seite ?ndert sich nur 1x pro Session
+ $this->lastModified( $user->loginDate );
+
+ }
+
+
+
+ /**
+ * Maske anzeigen, um Benutzer zu registrieren.
+ */
+ public function registerView()
+ {
+
+ }
+
+
+ /**
+ * Registriercode erzeugen und per E-Mail dem Benutzer mitteilen.
+ * Maske anzeigen, damit Benuter Registriercode anzeigen kann.
+ */
+ public function registercodeView()
+ {
+ global $conf;
+ foreach( $conf['database'] as $dbname=>$dbconf )
+ {
+ if ( is_array($dbconf) && $dbconf['enabled'] )
+ $dbids[$dbname] = $dbconf['description'];
+ }
+
+ $this->setTemplateVar( 'dbids',$dbids );
+
+ $db = db();
+ if ( is_object($db) )
+ $this->setTemplateVar('actdbid',$db->id);
+ else
+ $this->setTemplateVar('actdbid',$conf['database-defaults']['default-id']);
+
+
+
+ }
+
+
+
+ public function registerPost()
+ {
+ global $conf;
+
+ Session::set('registerMail',$this->getRequestVar('mail') );
+
+ srand ((double)microtime()*1000003);
+ $registerCode = rand();
+
+ Session::set('registerCode',$registerCode );
+
+ $email_address = $this->getRequestVar('mail',OR_FILTER_MAIL);
+
+ if ( ! Mail::checkAddress($email_address) )
+ {
+ $this->addValidationError('mail');
+ return;
+ }
+
+ // E-Mail and die eingegebene Adresse verschicken
+ $mail = new Mail($email_address,
+ 'register_commit_code','register_commit_code');
+ $mail->setVar('code',$registerCode); // Registrierungscode als Text-Variable
+
+ if ( $mail->send() )
+ {
+ $this->addNotice('','','mail_sent',OR_NOTICE_OK);
+ }
+ else
+ {
+ $this->addNotice('','','mail_not_sent',OR_NOTICE_ERROR,array(),$mail->error);
+ return;
+ }
+ }
+
+
+ /**
+ * Benutzerregistierung.
+ * Benutzer hat Best?tigungscode erhalten und eingegeben.
+ */
+ function registercodePost()
+ {
+ global $conf;
+
+ $origRegisterCode = Session::get('registerCode');
+ $inputRegisterCode = $this->getRequestVar('code');
+
+ if ( $origRegisterCode != $inputRegisterCode )
+ {
+ // Best?tigungscode stimmt nicht.
+ $this->addValidationError('code','code_not_match');
+ return;
+ }
+
+ // Best?tigungscode stimmt ?berein.
+ // Neuen Benutzer anlegen.
+
+ if ( !$this->hasRequestVar('username') )
+ {
+ $this->addValidationError('username');
+ return;
+ }
+
+ $user = User::loadWithName( $this->getRequestVar('username') );
+ if ( $user->isValid() )
+ {
+ $this->addValidationError('username','USER_ALREADY_IN_DATABASE');
+ return;
+ }
+
+ if ( strlen($this->getRequestVar('password')) < $conf['security']['password']['min_length'] )
+ {
+ $this->addValidationError('password','password_minlength',array('minlength'=>$conf['security']['password']['min_length']));
+ return;
+ }
+
+ $newUser = new User();
+ $newUser->name = $this->getRequestVar('username');
+ $newUser->add();
+
+ $newUser->mail = Session::get('registerMail');
+ $newUser->save();
+
+ $newUser->setPassword( $this->getRequestVar('password'),true );
+
+ $this->addNotice('user',$newUser->name,'user_added','ok');
+ }
+
+
+
+ /**
+ * Vergessenes Kennwort zusenden lassen.
+ */
+ function passwordView()
+ {
+ // TODO: Attribut "Password" abfragen
+ foreach( config('database') as $dbname=>$dbconf )
+ {
+ $dbconf = $dbconf + config('database-default','defaults');
+ if ( $dbconf['enabled'] )
+ $dbids[$dbname] = $dbconf['description'];
+ }
+
+ $this->setTemplateVar( 'dbids',$dbids );
+
+
+ $db = db();
+
+ if ( is_object($db) )
+ $this->setTemplateVar('actdbid',$db->id);
+ else
+ $this->setTemplateVar('actdbid',config('database-default','default-id'));
+ }
+
+
+
+ /**
+ * Einen Kennwort-Anforderungscode an den Benutzer senden.
+ */
+ function passwordPost()
+ {
+ if ( !$this->hasRequestVar('username') )
+ {
+ $this->addValidationError('username');
+ return;
+ }
+
+ $user = User::loadWithName( $this->getRequestVar("username") );
+ // Html::debug($user);
+ Password::delay();
+ if ( $user->isValid() )
+ {
+ srand ((double)microtime()*1000003);
+ $code = rand();
+ $this->setSessionVar("password_commit_code",$code);
+
+ $eMail = new Mail( $user->mail,'password_commit_code' );
+ $eMail->setVar('name',$user->getName());
+ $eMail->setVar('code',$code);
+ if ( $eMail->send() )
+ $this->addNotice('user',$user->getName(),'mail_sent',OR_NOTICE_OK);
+ else
+ $this->addNotice('user',$user->getName(),'mail_not_sent',OR_NOTICE_ERROR,array(),$eMail->error);
+
+ }
+ else
+ {
+ //$this->addNotice('','user','username_not_found');
+ // Trotzdem vort?uschen, eine E-Mail zu senden, damit die G?ltigkeit
+ // eines Benutzernamens nicht von au?en gepr?ft werden kann.
+ //
+ $this->addNotice('user',$this->getRequestVar("username"),'mail_sent');
+
+ }
+
+ $this->setSessionVar("password_commit_name",$user->name);
+ }
+
+
+
+ /**
+ * Anzeige Formular zum Eingeben des Kennwort-Codes.
+ *
+ */
+ function passwordcodeView()
+ {
+
+ }
+
+
+ /**
+ * Neues Kennwort erzeugen und dem Benutzer zusenden.
+ */
+ function passwordcodePost()
+ {
+ $username = $this->getSessionVar("password_commit_name");
+
+ if ( $this->getRequestVar("code")=='' ||
+ $this->getSessionVar("password_commit_code") != $this->getRequestVar("code") )
+ {
+ $this->addValidationError('code','PASSWORDCODE_NOT_MATCH');
+ return;
+ }
+
+ $user = User::loadWithName( $username );
+
+ if ( !$user->isValid() )
+ {
+ // Benutzer konnte nicht geladen werden.
+ $this->addNotice('user',$username,'error',OR_NOTICE_ERROR);
+ return;
+ }
+
+ $newPw = User::createPassword(); // Neues Kennwort erzeugen.
+
+ $eMail = new Mail( $user->mail,'password_new' );
+ $eMail->setVar('name' ,$user->getName());
+ $eMail->setVar('password',$newPw );
+
+ if ( $eMail->send() )
+ {
+ $user->setPassword( $newPw, false ); // Kennwort muss beim n?. Login ge?ndert werden.
+ $this->addNotice('user',$username,'mail_sent',OR_NOTICE_OK);
+ }
+ else
+ {
+ // Sollte eigentlich nicht vorkommen, da der Benutzer ja auch schon den
+ // Code per E-Mail erhalten hat.
+ $this->addNotice('user',$username,'error',OR_NOTICE_ERROR,array(),$eMail->error);
+ }
+ }
+
+
+ /**
+ * Erzeugt eine neue Sitzung.
+ */
+ function recreateSession()
+ {
+
+ session_regenerate_id(true);
+ }
+
+
+ function licenseView()
+ {
+ $software = array();
+
+ $software[] = array('name' =>'OpenRat Content Management System',
+ 'url' =>'http://www.openrat.de/',
+ 'license'=>'GPL v2');
+ $software[] = array('name' =>'jQuery Core Javascript Framework',
+ 'url' =>'http://jquery.com/',
+ 'license'=>'MPL, GPL v2');
+ $software[] = array('name' =>'jQuery UI Javascript Framework',
+ 'url' =>'http://jqueryui.com/',
+ 'license'=>'MPL, GPL v2');
+ $software[] = array('name' =>'GeSHi - Generic Syntax Highlighter',
+ 'url' =>'http://qbnz.com/highlighter/',
+ 'license'=>'GPL v2');
+ $software[] = array('name' =>'TAR file format',
+ 'url' =>'http://www.phpclasses.org/package/529',
+ 'license'=>'LGPL');
+ $software[] = array('name' =>'JSON file format',
+ 'url' =>'http://pear.php.net/pepr/pepr-proposal-show.php?id=198',
+ 'license'=>'BSD');
+
+ $this->setTemplateVar('software',$software);
+
+
+
+ $this->setTemplateVar('time' ,date('r') );
+ $this->setTemplateVar('os' ,php_uname('s') );
+ $this->setTemplateVar('release' ,php_uname('r') );
+ $this->setTemplateVar('machine' ,php_uname('m') );
+ $this->setTemplateVar('version' , phpversion() );
+
+ $this->setTemplateVar('cms_name' , Conf()->subset('application')->get('name' ) );
+ $this->setTemplateVar('cms_version' , Conf()->subset('application')->get('version' ) );
+ $this->setTemplateVar('cms_operator', Conf()->subset('application')->get('operator') );
+
+ $user = Session::getUser();
+ if ( !empty($user) )
+ {
+ $this->setTemplateVar('user_login' , $user->loginDate );
+ $this->setTemplateVar('user_name' , $user->name );
+ $this->setTemplateVar('user_fullname', $user->fullname );
+ }
+
+ }
+
+
+
+ /**
+ * Updating the database.
+ *
+ * @param $dbid integer
+ * @throws OpenRatException
+ */
+ private function updateDatabase($dbid)
+ {
+ try {
+ $dbConfig = Conf()->subset('database')->subset($dbid);
+
+ if ( ! $dbConfig->is('check_version',false))
+ return; // Check for DB version is disabled.
+
+ $adminDb = new Database( $dbConfig->subset('admin')->getConfig() + $dbConfig->getConfig() );
+ $adminDb->id = $dbid;
+ } catch (Exception $e) {
+
+ throw new OpenRatException('DATABASE_ERROR_CONNECTION', $e->getMessage());
+ }
+
+ $updater = new DbUpdate();
+ $updater->update($adminDb);
+
+ // Try to close the PDO connection. PDO doc:
+ // To close the connection, you need to destroy the object by ensuring that all
+ // remaining references to it are deleted—you do this by assigning NULL to the variable that holds the object.
+ // If you don't do this explicitly, PHP will automatically close the connection when your script ends.
+ $adminDb = null;
+ unset($adminDb);
+ }
+
+
+}
+
+
diff --git a/modules/cms-core/functions/common.inc.php b/modules/cms-core/functions/common.inc.php
@@ -1,178 +1,176 @@
-<?php
-
-
-/**
- * F�gt einen Slash ("/") an das Ende an, sofern nicht bereits vorhanden.
- *
- * @param String $pfad
- * @return Pfad mit angeh�ngtem Slash.
- */
-function slashify($pfad)
-{
- if ( substr($pfad,-1,1) == '/')
- return $pfad;
- else
- return $pfad.'/';
-}
-
-function convertToXmlAttribute( $value )
-{
- return utf8_encode( htmlspecialchars( $value ) ) ;
-}
-
-
-/**
- * Ermittelt die aktuelle Systemzeit als Unix-Timestamp.<br>
- * Unix-Timestamp ist immer bezogen auf GMT.
- * -
- * @return Unix-Timestamp der aktuellen Zeit
- */
-function now()
-{
- return time();
-}
-
-
-
-/**
- * Erzeugt f�r eine Zahl eine Schreibweise mit Vorzeichen.<br>
- * '-2' bleibt '-2'<br>
- * '2' wird zu '+2'<br>
- */
-function vorzeichen( $nr )
-{
- return intval($nr)<0 ? $nr : '+'.$nr;
-}
-
-
-
-/**
- * Stellt fest, ob das System in einem schreibgeschuetzten Zustand ist.
- *
- * @return boolean true, falls schreibgeschuetzt, sonst false
- */
-function readonly()
-{
- global $conf;
-
- // Gesamtes CMS ist readonly.
- if ( config('security','readonly') )
- return true;
-
- // Aktuelle Datenbankverbindung ist readonly.
- $db = Session::getDatabase();
- if ( isset($db->conf['readonly']) && $db->conf['readonly'] )
- return true;
-
- return false;
-}
-
-
-
-
-
-/**
- * Generiert aus der Session-Id einen Token.
- * @return Token
- */
-function token()
-{
- return substr(session_id(),-10);
-}
-
-
-/**
- * Ermittelt, ob der Wert 'true' oder 'false' entspricht.
- *
- * Anders als beim PHP-Cast auf boolean wird hier auch die
- * Zeichenkette 'true' als wahr betrachtet.
- *
- * @param val mixed
- * @return boolean
- */
-function istrue( $val )
-{
- if ( is_bool($val) )
- return $val;
- elseif( is_numeric($val) )
- return $val != 0;
- elseif( is_string($val) )
- return $val == 'true' || $val == 'yes' || $val == '1';
- else
- return false;
-}
-
-
-
-/**
- * Erzeugt einen Link auf die OpenRat-lokale CSS-Datei
- * @param $name Name der Style-Konfiguration. Default: 'default'.
- */
-function css_link( $name='default' )
-{
- global $conf;
-
- // Falls Style-Konfiguration unbekannt, dann Fallback auf default.
- if ( ! isset($conf['style'][$name]))
- $name = $conf['interface']['style']['default'];
-
-
- return encode_array($conf['style'][$name]);
-}
-
-
-/**
- * Encodiert ein Array für eine URL.
- *
- * @param $args URL-Parameter
- */
-function encode_array( $args )
-{
- if ( !is_array($args) )
- return '';
-
- $out = array();
-
- foreach( $args as $name => $value )
- $out[] = $name.'='.urlencode($value);
-
- return implode('&',$out);
-}
-
-
-function not($var) {
- return !$var;
-}
-
-/**
- * Liefert die Datenbankverbindung fuer die aktuelle Sitzung.
- *
- * @return \database\Database
- * @deprecated use db()
- */
-function db_connection()
-{
-
- return db();
-}
-
-/**
- * Liefert die Datenbankverbindung fuer die aktuelle Sitzung.
- *
- * @return \database\Database
- */
-function db()
-{
-
- $db = Session::getDatabase();
-
- if ( ! is_object($db))
- throw new RuntimeException('no database available');
-
- return $db;
-}
-
-
-
-
+<?php
+
+
+/**
+ * F�gt einen Slash ("/") an das Ende an, sofern nicht bereits vorhanden.
+ *
+ * @param String $pfad
+ * @return Pfad mit angeh�ngtem Slash.
+ */
+function slashify($pfad)
+{
+ if ( substr($pfad,-1,1) == '/')
+ return $pfad;
+ else
+ return $pfad.'/';
+}
+
+function convertToXmlAttribute( $value )
+{
+ return utf8_encode( htmlspecialchars( $value ) ) ;
+}
+
+
+/**
+ * Ermittelt die aktuelle Systemzeit als Unix-Timestamp.<br>
+ * Unix-Timestamp ist immer bezogen auf GMT.
+ * -
+ * @return Unix-Timestamp der aktuellen Zeit
+ */
+function now()
+{
+ return time();
+}
+
+
+
+/**
+ * Erzeugt f�r eine Zahl eine Schreibweise mit Vorzeichen.<br>
+ * '-2' bleibt '-2'<br>
+ * '2' wird zu '+2'<br>
+ */
+function vorzeichen( $nr )
+{
+ return intval($nr)<0 ? $nr : '+'.$nr;
+}
+
+
+
+/**
+ * Stellt fest, ob das System in einem schreibgeschuetzten Zustand ist.
+ *
+ * @return boolean true, falls schreibgeschuetzt, sonst false
+ */
+function readonly()
+{
+ // Gesamtes CMS ist readonly.
+ if ( config('security','readonly') )
+ return true;
+
+ // Aktuelle Datenbankverbindung ist readonly.
+ $db = db();
+ if ( isset($db->conf['readonly']) && $db->conf['readonly'] )
+ return true;
+
+ return false;
+}
+
+
+
+
+
+/**
+ * Generiert aus der Session-Id einen Token.
+ * @return Token
+ */
+function token()
+{
+ return substr(session_id(),-10);
+}
+
+
+/**
+ * Ermittelt, ob der Wert 'true' oder 'false' entspricht.
+ *
+ * Anders als beim PHP-Cast auf boolean wird hier auch die
+ * Zeichenkette 'true' als wahr betrachtet.
+ *
+ * @param val mixed
+ * @return boolean
+ */
+function istrue( $val )
+{
+ if ( is_bool($val) )
+ return $val;
+ elseif( is_numeric($val) )
+ return $val != 0;
+ elseif( is_string($val) )
+ return $val == 'true' || $val == 'yes' || $val == '1';
+ else
+ return false;
+}
+
+
+
+/**
+ * Erzeugt einen Link auf die OpenRat-lokale CSS-Datei
+ * @param $name Name der Style-Konfiguration. Default: 'default'.
+ */
+function css_link( $name='default' )
+{
+ global $conf;
+
+ // Falls Style-Konfiguration unbekannt, dann Fallback auf default.
+ if ( ! isset($conf['style'][$name]))
+ $name = $conf['interface']['style']['default'];
+
+
+ return encode_array($conf['style'][$name]);
+}
+
+
+/**
+ * Encodiert ein Array für eine URL.
+ *
+ * @param $args URL-Parameter
+ */
+function encode_array( $args )
+{
+ if ( !is_array($args) )
+ return '';
+
+ $out = array();
+
+ foreach( $args as $name => $value )
+ $out[] = $name.'='.urlencode($value);
+
+ return implode('&',$out);
+}
+
+
+function not($var) {
+ return !$var;
+}
+
+/**
+ * Liefert die Datenbankverbindung fuer die aktuelle Sitzung.
+ *
+ * @return \database\Database
+ * @deprecated use db()
+ */
+function db_connection()
+{
+
+ return db();
+}
+
+/**
+ * Liefert die Datenbankverbindung fuer die aktuelle Sitzung.
+ *
+ * @return \database\Database
+ */
+function db()
+{
+
+ $db = Session::getDatabase();
+
+ if ( ! is_object($db))
+ throw new RuntimeException('no database available');
+
+ return $db;
+}
+
+
+
+
?>
\ No newline at end of file
diff --git a/modules/cms-core/model/BaseObject.class.php b/modules/cms-core/model/BaseObject.class.php
@@ -1194,14 +1194,12 @@ SQL
*/
public function parentObjectFileNames( $with_root = false, $with_self = false )
{
- $db = \Session::getDatabase();
-
$foid = $this->id;
$idCache = array();
while( intval($foid)!=0 )
{
- $sql = $db->sql( <<<SQL
+ $sql = db()->sql( <<<SQL
SELECT parentid,id,filename
FROM {{object}}
@@ -1230,14 +1228,12 @@ SQL
public function parentObjectNames( $with_root = false, $with_self = false )
{
- $db = \Session::getDatabase();
-
$foid = $this->id;
$idCache = array();
while( intval($foid)!=0 )
{
- $sql = $db->sql( <<<SQL
+ $sql = db()->sql( <<<SQL
SELECT {{object}}.parentid,{{object}}.id,{{object}}.filename,{{name}}.name FROM {{object}}
LEFT JOIN {{name}}
diff --git a/modules/cms-core/model/Language.class.php b/modules/cms-core/model/Language.class.php
@@ -1,218 +1,216 @@
-<?php
-namespace cms\model;
-// OpenRat Content Management System
-// Copyright (C) 2002-2012 Jan Dankert, cms@jandankert.de
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-
-/**
- * Darstellen einer Sprache. Jeder Seiteninhalt wird einer Sprache zugeordnet.
- *
- * @version $Revision$
- * @author $Author$
- * @package openrat.objects
- */
-class Language
-{
- public $languageid;
- public $projectid;
-
- public $name;
- public $isoCode;
- public $isDefault = false;
-
-
- // Konstruktor
- function __construct( $languageid='' )
- {
- if ( is_numeric($languageid) )
- $this->languageid = $languageid;
- }
-
-
-
- /**
- * Stellt fest, ob die angegebene Id existiert.
- */
- function available( $id )
- {
- $db = db_connection();
-
- $sql = $db->sql('SELECT 1 FROM {{language}} '.
- ' WHERE id={id}');
- $sql->setInt('id' ,$id );
-
- return intval($sql->getOne()) == 1;
- }
-
-
-
- /**
- * Lesen aus der Datenbank.
- *
- */
- public function load()
- {
- $db = \Session::getDatabase();
-
- $sql = $db->sql( 'SELECT * FROM {{language}}'.
- ' WHERE id={languageid}' );
- $sql->setInt( 'languageid',$this->languageid );
-
- $row = $sql->getRow();
-
- if ( count($row) > 0 )
- {
- $this->name = $row['name' ];
- $this->isoCode = $row['isocode' ];
- $this->projectid = intval( $row['projectid'] );
-
- $this->isDefault = ( $row['is_default'] == '1' );
- }
- }
-
-
- /**
- * Speichern der Sprache in der Datenbank
- */
- public function save()
- {
- $db = db_connection();
-
- // Gruppe speichern
- $sql = $db->sql( 'UPDATE {{language}} '.
- 'SET name = {name}, '.
- ' isocode = {isocode} '.
- 'WHERE id={languageid}' );
- $sql->setString( 'name' ,$this->name );
- $sql->setString( 'isocode' ,$this->isoCode );
-
- $sql->setInt( 'languageid',$this->languageid );
-
- // Datenbankabfrage ausfuehren
- $sql->query();
- }
-
-
- /**
- * Ermitteln aller Eigenschaften dieser Sprache
- * @return Array
- */
- function getProperties()
- {
- return Array( 'name' =>$this->name,
- 'isocode'=>$this->isoCode );
- }
-
-
- /**
- * Neue Sprache hinzuf?gen
- */
- function add( $isocode='' )
- {
- global $SESS;
- global $iso;
- $db = db_connection();
-
- if ( $isocode != '' )
- {
- // Kleiner Trick, damit "no" (Norwegen) in der .ini-Datei stehen kann
- $isocode = str_replace('_','',$isocode);
-
- $this->isocode = $isocode;
- $codes = \GlobalFunctions::getIsoCodes();
- $this->name = $codes[ $isocode ];
- }
-
- $sql = $db->sql('SELECT MAX(id) FROM {{language}}');
- $this->languageid = intval($sql->getOne())+1;
-
- // Sprache hinzuf?gen
- $sql = $db->sql( 'INSERT INTO {{language}} '.
- '(id,projectid,name,isocode,is_default) VALUES( {languageid},{projectid},{name},{isocode},0 )');
- $sql->setInt ('languageid',$this->languageid );
- $sql->setInt ('projectid' ,$this->projectid );
- $sql->setString('name' ,$this->name );
- $sql->setString('isocode' ,$this->isoCode );
-
- // Datenbankbefehl ausfuehren
- $sql->query();
- }
-
-
- // Diese Sprache als 'default' markieren.
- function setDefault()
- {
- global $SESS;
- $db = db_connection();
-
- // Zuerst alle auf nicht-Standard setzen
- $sql = $db->sql( 'UPDATE {{language}} '.
- ' SET is_default = 0 '.
- ' WHERE projectid={projectid}' );
- $sql->setInt('projectid',$this->projectid );
- $sql->query();
-
- // Jetzt die gew?nschte Sprachvariante auf Standard setzen
- $sql = $db->sql( 'UPDATE {{language}} '.
- ' SET is_default = 1 '.
- ' WHERE id={languageid}' );
- $sql->setInt('languageid',$this->languageid );
- $sql->query();
- }
-
-
- // Sprache entfernen
- function delete()
- {
- $db = db_connection();
-
- // Sprache l?schen
-// $sql = $db->sql( 'SELECT COUNT(*) FROM {{language}} WHERE projectid={projectid}' );
-// $sql->setInt( 'projectid',$this->projectid );
-// $count = $sql->getOne( $sql );
-//
-// // Nur l?schen, wenn es mindestens 2 Sprachen gibt
-// if ( $count >= 2 )
-// {
- // Inhalte mit dieser Sprache l?schen
- $sql = $db->sql( 'DELETE FROM {{value}} WHERE languageid={languageid}' );
- $sql->setInt( 'languageid',$this->languageid );
- $sql->query();
-
- // Inhalte mit dieser Sprache l?schen
- $sql = $db->sql( 'DELETE FROM {{name}} WHERE languageid={languageid}' );
- $sql->setInt( 'languageid',$this->languageid );
- $sql->query();
-
- // Sprache l?schen
- $sql = $db->sql( 'DELETE FROM {{language}} WHERE id={languageid}' );
- $sql->setInt( 'languageid',$this->languageid );
- $sql->query();
-
- // Andere Sprache auf "Default" setzen
- $sql = $db->sql( 'SELECT id FROM {{language}} WHERE projectid={projectid}' );
- $sql->setInt( 'projectid',$this->projectid );
- $new_default_languageid = $sql->getOne();
-
- $sql = $db->sql( 'UPDATE {{language}} SET is_default=1 WHERE id={languageid}' );
- $sql->setInt( 'languageid',$new_default_languageid );
- $sql->query();
-// }
- }
-}
-
+<?php
+namespace cms\model;
+// OpenRat Content Management System
+// Copyright (C) 2002-2012 Jan Dankert, cms@jandankert.de
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+/**
+ * Darstellen einer Sprache. Jeder Seiteninhalt wird einer Sprache zugeordnet.
+ *
+ * @version $Revision$
+ * @author $Author$
+ * @package openrat.objects
+ */
+class Language
+{
+ public $languageid;
+ public $projectid;
+
+ public $name;
+ public $isoCode;
+ public $isDefault = false;
+
+
+ // Konstruktor
+ function __construct( $languageid='' )
+ {
+ if ( is_numeric($languageid) )
+ $this->languageid = $languageid;
+ }
+
+
+
+ /**
+ * Stellt fest, ob die angegebene Id existiert.
+ */
+ function available( $id )
+ {
+ $db = db_connection();
+
+ $sql = $db->sql('SELECT 1 FROM {{language}} '.
+ ' WHERE id={id}');
+ $sql->setInt('id' ,$id );
+
+ return intval($sql->getOne()) == 1;
+ }
+
+
+
+ /**
+ * Lesen aus der Datenbank.
+ *
+ */
+ public function load()
+ {
+ $stmt = db()->sql( 'SELECT * FROM {{language}}'.
+ ' WHERE id={languageid}' );
+ $stmt->setInt( 'languageid',$this->languageid );
+
+ $row = $stmt->getRow();
+
+ if ( count($row) > 0 )
+ {
+ $this->name = $row['name' ];
+ $this->isoCode = $row['isocode' ];
+ $this->projectid = intval( $row['projectid'] );
+
+ $this->isDefault = ( $row['is_default'] == '1' );
+ }
+ }
+
+
+ /**
+ * Speichern der Sprache in der Datenbank
+ */
+ public function save()
+ {
+ $db = db_connection();
+
+ // Gruppe speichern
+ $sql = $db->sql( 'UPDATE {{language}} '.
+ 'SET name = {name}, '.
+ ' isocode = {isocode} '.
+ 'WHERE id={languageid}' );
+ $sql->setString( 'name' ,$this->name );
+ $sql->setString( 'isocode' ,$this->isoCode );
+
+ $sql->setInt( 'languageid',$this->languageid );
+
+ // Datenbankabfrage ausfuehren
+ $sql->query();
+ }
+
+
+ /**
+ * Ermitteln aller Eigenschaften dieser Sprache
+ * @return Array
+ */
+ function getProperties()
+ {
+ return Array( 'name' =>$this->name,
+ 'isocode'=>$this->isoCode );
+ }
+
+
+ /**
+ * Neue Sprache hinzuf?gen
+ */
+ function add( $isocode='' )
+ {
+ global $SESS;
+ global $iso;
+ $db = db_connection();
+
+ if ( $isocode != '' )
+ {
+ // Kleiner Trick, damit "no" (Norwegen) in der .ini-Datei stehen kann
+ $isocode = str_replace('_','',$isocode);
+
+ $this->isocode = $isocode;
+ $codes = \GlobalFunctions::getIsoCodes();
+ $this->name = $codes[ $isocode ];
+ }
+
+ $sql = $db->sql('SELECT MAX(id) FROM {{language}}');
+ $this->languageid = intval($sql->getOne())+1;
+
+ // Sprache hinzuf?gen
+ $sql = $db->sql( 'INSERT INTO {{language}} '.
+ '(id,projectid,name,isocode,is_default) VALUES( {languageid},{projectid},{name},{isocode},0 )');
+ $sql->setInt ('languageid',$this->languageid );
+ $sql->setInt ('projectid' ,$this->projectid );
+ $sql->setString('name' ,$this->name );
+ $sql->setString('isocode' ,$this->isoCode );
+
+ // Datenbankbefehl ausfuehren
+ $sql->query();
+ }
+
+
+ // Diese Sprache als 'default' markieren.
+ function setDefault()
+ {
+ global $SESS;
+ $db = db_connection();
+
+ // Zuerst alle auf nicht-Standard setzen
+ $sql = $db->sql( 'UPDATE {{language}} '.
+ ' SET is_default = 0 '.
+ ' WHERE projectid={projectid}' );
+ $sql->setInt('projectid',$this->projectid );
+ $sql->query();
+
+ // Jetzt die gew?nschte Sprachvariante auf Standard setzen
+ $sql = $db->sql( 'UPDATE {{language}} '.
+ ' SET is_default = 1 '.
+ ' WHERE id={languageid}' );
+ $sql->setInt('languageid',$this->languageid );
+ $sql->query();
+ }
+
+
+ // Sprache entfernen
+ function delete()
+ {
+ $db = db_connection();
+
+ // Sprache l?schen
+// $sql = $db->sql( 'SELECT COUNT(*) FROM {{language}} WHERE projectid={projectid}' );
+// $sql->setInt( 'projectid',$this->projectid );
+// $count = $sql->getOne( $sql );
+//
+// // Nur l?schen, wenn es mindestens 2 Sprachen gibt
+// if ( $count >= 2 )
+// {
+ // Inhalte mit dieser Sprache l?schen
+ $sql = $db->sql( 'DELETE FROM {{value}} WHERE languageid={languageid}' );
+ $sql->setInt( 'languageid',$this->languageid );
+ $sql->query();
+
+ // Inhalte mit dieser Sprache l?schen
+ $sql = $db->sql( 'DELETE FROM {{name}} WHERE languageid={languageid}' );
+ $sql->setInt( 'languageid',$this->languageid );
+ $sql->query();
+
+ // Sprache l?schen
+ $sql = $db->sql( 'DELETE FROM {{language}} WHERE id={languageid}' );
+ $sql->setInt( 'languageid',$this->languageid );
+ $sql->query();
+
+ // Andere Sprache auf "Default" setzen
+ $sql = $db->sql( 'SELECT id FROM {{language}} WHERE projectid={projectid}' );
+ $sql->setInt( 'projectid',$this->projectid );
+ $new_default_languageid = $sql->getOne();
+
+ $sql = $db->sql( 'UPDATE {{language}} SET is_default=1 WHERE id={languageid}' );
+ $sql->setInt( 'languageid',$new_default_languageid );
+ $sql->query();
+// }
+ }
+}
+
?>
\ No newline at end of file
diff --git a/modules/cms-core/model/Project.class.php b/modules/cms-core/model/Project.class.php
@@ -1,1029 +1,1023 @@
-<?php
-
-namespace cms\model;
-
-define('PROJECT_FLAG_CUT_INDEX',1);
-define('PROJECT_FLAG_CONTENT_NEGOTIATION',2);
-define('PROJECT_FLAG_PUBLISH_FILE_EXTENSION',4);
-define('PROJECT_FLAG_PUBLISH_PAGE_EXTENSION',8);
-
-use database\Database;
-use Session;
-
-
-/**
- * Darstellen eines Projektes
- *
- * @author Jan Dankert
- * @package openrat.objects
- */
-class Project extends ModelBase
-{
- // Eigenschaften
- public $projectid;
- public $name;
- public $target_dir;
- public $ftp_url;
-
- /**
- * Hostname
- * @var string
- */
- public $url;
-
- public $ftp_passive;
- public $cmd_after_publish;
-
-
- /**
- * @var boolean
- */
- public $content_negotiation = false;
-
- /**
- * @var boolean
- */
- public $cut_index = false;
-
- /**
- * @var boolean
- */
- public $publishFileExtension = true;
-
- /**
- * @var boolean
- */
- public $publishPageExtension = true;
-
- public $log = array();
-
-
-
- // Konstruktor
- public function __construct( $projectid='' )
- {
- if ( intval($projectid) != 0 )
- $this->projectid = $projectid;
- }
-
-
- private static $cache = array();
-
- /**
- * @param $projectid
- * @return Project
- * @throws \ObjectNotFoundException
- */
- public static function create($projectid)
- {
- if ( empty( Project::$cache[ $projectid ] ) )
- {
- $project = new Project( $projectid );
-
- Project::$cache[ $projectid ] = $project->load();
- }
- return Project::$cache[ $projectid ];
- }
-
-
- /**
- * Stellt fest, ob die angegebene Projekt-Id existiert.
- * @param $id int Projekt-Id
- * @return boolean
- *
- */
- public function isAvailable($id )
- {
- $db = db_connection();
-
- $sql = $db->sql('SELECT 1 FROM {{project}} '.
- ' WHERE id={id}');
- $sql->setInt('id' ,$id );
-
- return intval($sql->getOne()) == 1;
- }
-
-
- /**
- * Liefert alle verf?gbaren Projekte.
- * @return array
- */
- public static function getAllProjects()
- {
- $db = db_connection();
- $sql = $db->sql( 'SELECT id,name FROM {{project}} '.
- ' ORDER BY name' );
-
- return $sql->getAssoc();
- }
-
-
- // Liefert alle verf?gbaren Projekt-Ids
- public function getAllProjectIds()
- {
- $db = db_connection();
- $sql = $db->sql( 'SELECT id FROM {{project}} '.
- ' ORDER BY name' );
-
- return $sql->getCol();
- }
-
-
- /**
- * Liefert die Sprachen des Projektes.
- *
- * @return array Id->Name
- */
- public function getLanguages()
- {
- $db = db_connection();
-
- $sql = $db->sql( 'SELECT id,name FROM {{language}}'.
- ' WHERE projectid={projectid} '.
- ' ORDER BY name' );
- $sql->setInt ('projectid',$this->projectid);
-
- return $sql->getAssoc();
- }
-
-
- public function getLanguageIds()
- {
- return array_keys( $this->getLanguages() );
- }
-
-
- /**
- * Liefert die Projektmodelle als Array mit ID->Name.
- *
- * @return array
- */
- public function getModels()
- {
- $db = db_connection();
-
- $sql = $db->sql( 'SELECT id,name FROM {{projectmodel}}'.
- ' WHERE projectid= {projectid} '.
- ' ORDER BY name' );
- $sql->setInt ('projectid',$this->projectid);
-
- return $sql->getAssoc();
- }
-
-
- public function getModelIds()
- {
- return array_keys( $this->getModels() );
- }
-
-
- public function getTemplateIds()
- {
- $db = db_connection();
-
- $sql = $db->sql( 'SELECT id FROM {{template}}'.
- ' WHERE projectid= {projectid} ' );
- $sql->setInt ('projectid',$this->projectid);
-
- return $sql->getCol();
- }
-
-
- public function getTemplates()
- {
- $db = db_connection();
-
- $sql = $db->sql( 'SELECT id,name FROM {{template}}'.
- ' WHERE projectid= {projectid} ' );
- $sql->setInt ('projectid',$this->projectid);
-
- return $sql->getAssoc();
- }
-
-
- /**
- * Ermitteln des Wurzel-Ordners fuer dieses Projekt.
- *
- * Der Wurzelordner ist der einzige Ordnerhat in diesem
- * Projekt, der kein Elternelement besitzt.
- *
- * @return Objekt-Id des Wurzelordners
- */
- public function getRootObjectId()
- {
- $db = db_connection();
-
- $sql = $db->sql('SELECT id FROM {{object}}'.
- ' WHERE parentid IS NULL'.
- ' AND projectid={projectid}' );
-
- $sql->setInt('projectid',$this->projectid);
-
- return( $sql->getOne() );
- }
-
-
-
- // Laden
-
- /**
- * @throws \ObjectNotFoundException
- */
- public function load()
- {
- $sql = db()->sql( 'SELECT * FROM {{project}} '.
- ' WHERE id={projectid}' );
- $sql->setInt( 'projectid',$this->projectid );
-
- $row = $sql->getRow();
-
- if ( empty($row) )
- throw new \ObjectNotFoundException('project '.$this->projectid.' not found');
-
- $this->name = $row['name' ];
- $this->url = $row['url' ];
- $this->target_dir = $row['target_dir' ];
- $this->ftp_url = $row['ftp_url' ];
- $this->ftp_passive = $row['ftp_passive' ];
- $this->cmd_after_publish = $row['cmd_after_publish' ];
- $this->cut_index = $row['flags']&PROJECT_FLAG_CUT_INDEX;
- $this->content_negotiation = $row['flags']&PROJECT_FLAG_CONTENT_NEGOTIATION;
- $this->publishFileExtension = $row['flags']&PROJECT_FLAG_PUBLISH_FILE_EXTENSION;
- $this->publishPageExtension = $row['flags']&PROJECT_FLAG_PUBLISH_PAGE_EXTENSION;
-
- return $this;
- }
-
-
- // Laden
- public function loadByName()
- {
- $db = db_connection();
-
- $sql = $db->sql( 'SELECT * FROM {{project}} '.
- ' WHERE name={projectname}' );
- $sql->setString( 'projectname',$this->name );
-
- $row = $sql->getRow();
-
- $this->projectid = $row['id' ];
- $this->target_dir = $row['target_dir' ];
- $this->ftp_url = $row['ftp_url' ];
- $this->url = $row['url' ];
- $this->ftp_passive = $row['ftp_passive' ];
- $this->cmd_after_publish = $row['cmd_after_publish' ];
- $this->cut_index = $row['flags']&PROJECT_FLAG_CUT_INDEX;
- $this->content_negotiation = $row['flags']&PROJECT_FLAG_CONTENT_NEGOTIATION;
- $this->publishFileExtension = $row['flags']&PROJECT_FLAG_PUBLISH_FILE_EXTENSION;
- $this->publishPageExtension = $row['flags']&PROJECT_FLAG_PUBLISH_PAGE_EXTENSION;
- }
-
-
- // Speichern
- public function save()
- {
- $db = db_connection();
-
- $sql = $db->sql( <<<SQL
- UPDATE {{project}}
- SET name = {name},
- target_dir = {target_dir},
- ftp_url = {ftp_url},
- ftp_passive = {ftp_passive},
- url = {url},
- flags = {flags},
- cmd_after_publish = {cmd_after_publish}
- WHERE id= {projectid}
-SQL
-);
-
- $sql->setString('ftp_url' ,$this->ftp_url );
- $sql->setString('url' ,$this->url );
- $sql->setString('name' ,$this->name );
- $sql->setString('target_dir' ,$this->target_dir );
- $sql->setInt ('ftp_passive' ,$this->ftp_passive );
- $sql->setString('cmd_after_publish' ,$this->cmd_after_publish );
-
- $flags = 0;
- if( $this->cut_index) $flags |= PROJECT_FLAG_CUT_INDEX;
- if( $this->content_negotiation) $flags |= PROJECT_FLAG_CONTENT_NEGOTIATION;
- if( $this->publishFileExtension) $flags |= PROJECT_FLAG_PUBLISH_FILE_EXTENSION;
- if( $this->publishPageExtension) $flags |= PROJECT_FLAG_PUBLISH_PAGE_EXTENSION;
-
- $sql->setInt ('flags' ,$flags );
- $sql->setInt ('projectid' ,$this->projectid );
-
- $sql->query();
-
- try
- {
- $rootFolder = new Folder( $this->getRootObjectId() );
- $rootFolder->load();
- $rootFolder->filename = $this->name;
- $rootFolder->save();
- }
- catch( \Exception $e )
- {
- \Logger::warn('Project '.$this->projectid.' has not a root folder'."\n".$e->getTraceAsString());
- }
- }
-
-
- /**
- * Liefert alle Eigenschaften des Projektes.
- */
- public function getProperties()
- {
- return parent::getProperties();
- }
-
-
- /**
- * Add a project to the database.
- */
- public function add()
- {
- $db = db_connection();
-
- $sql = $db->sql('SELECT MAX(id) FROM {{project}}');
- $this->projectid = intval($sql->getOne())+1;
-
-
- // Projekt hinzuf?gen
- $sql = $db->sql( 'INSERT INTO {{project}} (id,name,target_dir,ftp_url,ftp_passive,cmd_after_publish,flags) '.
- " VALUES( {projectid},{name},'','',0,'',0 ) " );
- $sql->setInt ('projectid',$this->projectid );
- $sql->setString('name' ,$this->name );
-
- $sql->query();
-
- // Modell anlegen
- $model = new Model();
- $model->projectid = $this->projectid;
- $model->name = 'html';
- $model->add();
-
- // Sprache anlegen
- $language = new Language();
- $language->projectid = $this->projectid;
- $language->isoCode = 'en';
- $language->name = 'english';
- $language->add();
-
- // Haupt-Ordner anlegen
- $folder = new Folder();
- $folder->isRoot = true;
- $folder->projectid = $this->projectid;
- $folder->languageid = $language->languageid;
- $folder->filename = $this->name;
- $folder->name = $this->name;
- $folder->isRoot = true;
- $folder->add();
-
- // Template anlegen
- $template = new Template();
- $template->projectid = $this->projectid;
- $template->name = '';
- $template->modelid = $model->modelid;
- $template->languageid = $language->languageid;
- $template->extension = 'html';
- $template->src = '<html><body><h1>Hello world</h1><hr><p>Hello, World.</p></body></html>';
- $template->add();
- $template->save();
-
- // Beispiel-Seite anlegen
- $page = new Page();
- $page->parentid = $folder->objectid;
- $page->projectid = $this->projectid;
- $page->languageid = $language->languageid;
- $page->templateid = $template->templateid;
- $page->filename = '';
- $page->name = 'OpenRat';
- $page->add();
- }
-
-
- // Projekt aus Datenbank entfernen
- public function delete()
- {
- $db = db_connection();
-
- // Root-Ordner rekursiv samt Inhalten loeschen
- $folder = new Folder( $this->getRootObjectId() );
- $folder->deleteAll();
-
-
- foreach( $this->getLanguageIds() as $languageid )
- {
- $language = new Language( $languageid );
- $language->delete();
- }
-
-
- foreach( $this->getTemplateIds() as $templateid )
- {
- $template = new Template( $templateid );
- $template->delete();
- }
-
-
- foreach( $this->getModelIds() as $modelid )
- {
- $model = new Model( $modelid );
- $model->delete();
- }
-
-
- // Deleting the project
- $sql = $db->sql( 'DELETE FROM {{project}}'.
- ' WHERE id= {projectid} ' );
- $sql->setInt( 'projectid',$this->projectid );
- $sql->query();
- }
-
-
- /**
- * Liefert die Standard-Sprach-Id. If there is no default language, the first language-id will be used.
- * @return String
- */
- public function getDefaultLanguageId()
- {
- $db = Session::getDatabase();
-
- // ORDER BY deswegen, damit immer mind. eine Sprache
- // gelesen wird
- $sql = $db->sql( 'SELECT id FROM {{language}} '.
- ' WHERE projectid={projectid}'.
- ' ORDER BY is_default DESC, name ASC' );
-
- $sql->setInt('projectid',$this->projectid );
-
- return $sql->getOne();
- }
-
-
- public function getDefaultModelId()
- {
- $db = Session::getDatabase();
-
- // ORDER BY deswegen, damit immer mind. eine Sprache
- // gelesen wird
- $sql = $db->sql( 'SELECT id FROM {{projectmodel}} '.
- ' WHERE projectid={projectid}'.
- ' ORDER BY is_default DESC' );
- $sql->setInt('projectid',$this->projectid );
-
- return $sql->getOne();
- }
-
-
-
- /**
- * Entfernt nicht mehr notwendige Inhalte aus dem Archiv.
- */
- public function checkLimit()
- {
- $root = new Folder( $this->getRootObjectId() );
- $root->projectid = $this->projectid;
-
- $pages = $this->getAllObjectIds( array('page') );
- $languages = $this->getLanguageIds();
-
- foreach( $pages as $objectid )
- {
- $page = new Page( $objectid );
- $page->load();
- foreach( $page->getElementIds() as $eid )
- {
- foreach( $languages as $lid )
- {
- $value = new Value();
- $value->element = new Element($eid);
- $value->pageid = $page->pageid;
- $value->languageid = $lid;
-
- $value->checkLimit();
- }
- }
- }
-
- }
-
-
-
- /**
- * Testet die Integrität der Datenbank.
- */
- public function checkLostFiles()
- {
- $this->log = array();
-
- $db = Session::getDatabase();
-
- // Ordnerstruktur prüfen.
- $sql = $db->sql( <<<EOF
-SELECT thistab.id FROM {{object}} AS thistab
- LEFT JOIN {{object}} AS parenttab
- ON parenttab.id = thistab.parentid
- WHERE thistab.projectid={projectid} AND thistab.parentid IS NOT NULL AND parenttab.id IS NULL
-EOF
-);
- $sql->setInt('projectid',$this->projectid);
-
- $idList = $sql->getCol();
-
- if ( count( $idList ) > 0 )
- {
- $lostAndFoundFolder = new Folder();
- $lostAndFoundFolder->projectid = $this->projectid;
- $lostAndFoundFolder->languageid = $this->getDefaultLanguageId();
- $lostAndFoundFolder->filename = "lostandfound";
- $lostAndFoundFolder->name = 'Lost+found';
- $lostAndFoundFolder->parentid = $this->getRootObjectId();
- $lostAndFoundFolder->add();
-
- foreach( $idList as $id )
- {
- $this->log[] = 'Lost file! Moving '.$id.' to lost+found.';
- $obj = new BaseObject( $id );
- $obj->setParentId( $lostAndFoundFolder->objectid );
- }
- }
-
-
- // Prüfe, ob die Verbindung Projekt->Template->Templatemodell->Projectmodell->Projekt konsistent ist.
- $sql = $db->sql( <<<EOF
-SELECT DISTINCT projectid FROM {{projectmodel}} WHERE id IN (SELECT projectmodelid from {{templatemodel}} WHERE templateid in (SELECT id from {{template}} WHERE projectid={projectid}))
-EOF
-);
- $sql->setInt('projectid',$this->projectid);
-
- $idList = $sql->getCol();
-
- if ( count( $idList ) > 1 )
- {
- \Logger::warn('Inconsistence found: Reference circle project<->template<->templatemodel<->projectmodel<->project is not consistent.');
- $this->log[] = 'Inconsistence found: Reference circle project<->template<->templatemodel<->projectmodel<->project is not consistent.';
- }
-
- }
-
-
- /**
- * Synchronisation des Projektinhaltes mit dem Dateisystem.
- */
- public function sync()
- {
- global $conf;
- $syncConf = $conf['sync'];
-
- if ( ! $syncConf['enabled'] )
- return;
-
- $syncDir = slashify($syncConf['directory']).$this->name;
-
- }
-
- /**
- * Kopiert ein Projekt von einer Datenbank zu einer anderen.<br>
- * <br>
- * Alle Projektinhalte werden kopiert, die Fremdschluesselbeziehungen werden entsprechend angepasst.<br>
- * <br>
- * Alle Beziehungen zu Benutzern, z.B. "Zuletzt geaendert von", "angelegt von" sowie<br>
- * alle Berechtigungsinformationen gehen verloren!<br>
- *
- * @param string $dbid_destination ID der Ziel-Datenbank
- * @param string $name
- */
- public function copy( $dbid_destination,$name='' )
- {
- \Logger::debug( 'Copying project '.$this->name.' to database '.$dbid_destination );
-
- global $conf;
- $zeit = date('Y-m-d\TH:i:sO');
-
- $db_src = db_connection();
- $db_dest = new Database( $conf['database'][$dbid_destination] );
- $db_dest->id = $dbid_destination;
- $db_dest->start();
-
- $sameDB = ( $db_dest->id == $db_src->id );
-
- // -------------------------------------------------------
- $mapping = array();
- $ids = array('project' => array('foreign_keys'=>array(),
- 'primary_key' =>'id',
- 'unique_idx' =>'name',
- 'erase' =>array()
- ),
- 'language' => array('foreign_keys'=>array('projectid'=>'project'),
- 'primary_key' =>'id'
- ),
- 'projectmodel' => array('foreign_keys'=>array('projectid'=>'project'),
- 'primary_key' =>'id'
- ),
- 'template' => array('foreign_keys'=>array('projectid'=>'project'),
- 'primary_key' =>'id'
- ),
- 'object' => array('foreign_keys'=>array('projectid' =>'project' ),
- 'self_key' =>'parentid',
- 'primary_key' =>'id',
- 'erase' =>array('create_userid','lastchange_userid')
- ),
- 'element' => array('foreign_keys'=>array('templateid' =>'template',
- 'folderobjectid' =>'object',
- 'default_objectid'=>'object' ),
- 'primary_key' =>'id'
- ),
- 'templatemodel'=> array('foreign_keys'=>array('projectmodelid'=>'projectmodel',
- 'templateid' =>'template' ),
- 'primary_key' =>'id',
- 'replace' =>array('text'=>'element')
- ),
- 'name' => array('foreign_keys'=>array('objectid' =>'object',
- 'languageid'=>'language' ),
- 'primary_key' =>'id'
- ),
- 'page' => array('foreign_keys'=>array('objectid' =>'object',
- 'templateid'=>'template' ),
- 'primary_key' =>'id'
- ),
- 'value' => array('foreign_keys'=>array('pageid' =>'page',
- 'languageid'=>'language',
- 'elementid'=>'element',
- 'linkobjectid'=>'object' ),
- 'erase' =>array('lastchange_userid'),
- 'replace' =>array('text'=>'object'),
- 'primary_key' =>'id'
- ),
- 'link' => array('foreign_keys'=>array('objectid' =>'object',
- 'link_objectid'=>'object' ),
- 'primary_key' =>'id'
- ),
- 'folder' => array('foreign_keys'=>array('objectid' =>'object' ),
- 'primary_key' =>'id'
- ),
- 'file' => array('foreign_keys'=>array('objectid' =>'object' ),
- 'primary_key' =>'id',
- 'binary' =>'value'
- ),
-
- );
-
- if ( $sameDB )
- $ids['acl'] = array('foreign_keys'=>array('objectid' => 'object',
- 'languageid' => 'language' ),
- 'primary_key' =>'id'
- );
-
- foreach( $ids as $tabelle=>$data )
- {
- \Logger::debug( 'Copying table '.$tabelle.' ...' );
- $mapping[$tabelle] = array();
- $idcolumn = $data['primary_key'];
-
- // Naechste freie Id in der Zieltabelle ermitteln.
- $stmt = $db_dest->sql( 'SELECT MAX('.$idcolumn.') FROM {t_'.$tabelle.'}');
- $maxid = intval($stmt->getOne());
- $nextid = $maxid;
-
- // Zu �bertragende IDs ermitteln.
- if ( count($data['foreign_keys'])==0 )
- {
- $where = ' WHERE id='.$this->projectid;
- }
- else
- {
- foreach( $data['foreign_keys'] as $fkey_column=>$target_tabelle )
- {
- $where = ' WHERE '.$fkey_column.' IN ('.join(array_keys($mapping[$target_tabelle]),',').')';
- break;
- }
- }
- $stmt = $db_src->sql( 'SELECT '.$idcolumn.' FROM {t_'.$tabelle.'} '.$where);
-
- foreach( $stmt->getCol() as $srcid )
- {
- \Logger::debug('Id '.$srcid.' of table '.$tabelle);
- $mapping[$tabelle][$srcid] = ++$nextid;
-
- $stmt = $db_src->sql( 'SELECT * FROM {t_'.$tabelle.'} WHERE id={id}');
- $stmt->setInt('id',$srcid);
- $row = $stmt->getRow();
-
- // Wert des Prim�rschl�ssels �ndern.
- $row[$idcolumn] = $mapping[$tabelle][$srcid];
-
- // Fremdschl�sselbeziehungen auf neue IDn korrigieren.
- foreach( $data['foreign_keys'] as $fkey_column=>$target_tabelle)
- {
- \Logger::debug($fkey_column.' '.$target_tabelle.' '.$row[$fkey_column]);
-
- if ( intval($row[$fkey_column]) != 0 )
- $row[$fkey_column] = $mapping[$target_tabelle][$row[$fkey_column]];
- }
-
- foreach( array_keys($row) as $key )
- {
- if ( isset($data['unique_idx']) && $key == $data['unique_idx'] )
- {
- // Nachschauen, ob es einen UNIQUE-Key in der Zieltabelle schon gibt.
- $stmt = $db_dest->sql( 'SELECT 1 FROM {t_'.$tabelle.'} WHERE '.$key."='".$row[$key]."'");
-
- if ( intval($stmt->getOne()) == 1 )
- $row[$key] = $row[$key].$zeit;
-
- }
-
- if ( !$sameDB && isset($data['erase']) && in_array($key,$data['erase']) )
- $row[$key] = null;
-
- if ( isset($data['self_key']) && $key == $data['self_key'] && intval($row[$key]) > 0 )
- $row[$key] = $row[$key]+$maxid;
- }
-
- if ( isset($data['replace']) )
- {
- foreach( $data['replace'] as $repl_column=>$repl_tabelle)
- foreach( $mapping[$repl_tabelle] as $oldid=>$newid)
- {
- $row[$repl_column] = str_replace('{'.$oldid.'}','{'.$newid.'}' ,$row[$repl_column]);
- $row[$repl_column] = str_replace('"'.$oldid.'"','"'.$newid.'"' ,$row[$repl_column]);
- $row[$repl_column] = str_replace('->'.$oldid ,'->"'.$newid.'"',$row[$repl_column]);
- }
- }
-
- if ( isset($data['binary']) )
- {
- if ( !$db_src->conf['base64'] && $db_dest->conf['base64'] )
- $row[$data['binary']] = base64_encode($row[$data['binary']]);
- elseif ( $db_src->conf['base64'] && !$db_dest->conf['base64'] )
- $row[$data['binary']] = base64_decode($row[$data['binary']]);
- }
-
- // Daten in Zieltabelle einf�gen.
- $stmt = $db_dest->sql( 'INSERT INTO {t_'.$tabelle.'} ('.join(array_keys($row),',').') VALUES({'.join(array_keys($row),'},{').'})',$dbid_destination);
- foreach( $row as $key=>$value )
- {
- if ( !$sameDB && isset($data['erase']) && in_array($key,$data['erase']) )
- $stmt->setNull($key);
- else
- {
- if(is_bool($value))
- $stmt->setBoolean($key,$value);
- elseif(is_int($value))
- $stmt->setInt($key,$value);
- elseif(is_string($value))
- $stmt->setString($key,$value);
- }
- }
- //$sql = $db->sql( 'INSERT INTO {t_'.$tabelle.'} ('.join(array_keys($row),',').') VALUES('.join($row,',').')',$dbid_destination);
- $stmt->query();
- }
-
- if ( isset($data['self_key']) )
- {
- foreach( $mapping[$tabelle] as $oldid=>$newid )
- {
- $stmt = $db_dest->sql( 'UPDATE {t_'.$tabelle.'} SET '.$data['self_key'].'='.$newid.' WHERE '.$data['self_key'].'='.($oldid+$maxid),$dbid_destination );
- $stmt->query();
- }
- }
- }
-
- \Logger::debug( 'Finished copying project' );
-
- $db_dest->commit();
- }
-
-
-
- /**
- * Ermittelt die Anzahl aller Objekte in diesem Projekt.
- * @return int Anzahl
- */
- public function countObjects()
- {
- $db = db_connection();
- $sql = $db->sql( 'SELECT COUNT(*) FROM {{object}} '.
- ' WHERE projectid = {projectid}' );
- $sql->setInt( 'projectid', $this->projectid );
-
- return $sql->getOne();
-
- }
-
-
-
- /**
- * Ermittelt die Gr��e aller Dateien in diesem Projekt.
- * @return int Summe aller Dateigroessen
- */
- public function size()
- {
- $db = db_connection();
-
- $sql = $db->sql( <<<SQL
- SELECT SUM(size) FROM {{file}}
- LEFT JOIN {{object}}
- ON {{file}}.objectid = {{object}}.id
- WHERE projectid = {projectid}
-SQL
-);
- $sql->setInt( 'projectid', $this->projectid );
-
- return $sql->getOne();
- }
-
-
-
- /**
- * Liefert alle verf?gbaren Projekt-Ids
- */
- public function info()
- {
- $info = array();
-
- $info['count_objects'] = $this->countObjects();
- $info['sum_filesize' ] = $this->size();
-
-
- return $info;
- }
-
-
-
-
- /**
- * Ermittelt projektübergreifend die letzten Änderungen des angemeldeten Benutzers.
- *
- * @return array <string, unknown>
- */
- public function getMyLastChanges()
- {
-
- $db = db_connection();
-
-
- $sql = $db->sql( <<<SQL
- SELECT {{object}}.id as objectid,
- {{object}}.filename as filename,
- {{object}}.typeid as typeid,
- {{object}}.lastchange_date as lastchange_date,
- {{name}}.name as name
- FROM {{object}}
- LEFT JOIN {{name}}
- ON {{name}}.objectid = {{object}}.id
- AND {{name}}.languageid = {languageid}
- LEFT JOIN {{project}}
- ON {{object}}.projectid = {{project}}.id
- WHERE {{object}}.projectid = {projectid}
- AND {{object}}.lastchange_userid = {userid}
- ORDER BY {{object}}.lastchange_date DESC;
-SQL
- );
-
- // Variablen setzen.
- $sql->setInt( 'projectid', $this->projectid );
-
- $sql->setInt( 'languageid', 0 );
-
- $user = Session::getUser();
- $sql->setInt( 'userid', $user->userid );
-
- return $sql->getAll();
- }
-
-
- /**
- * Ermittelt projektübergreifend die letzten Änderungen.
- *
- * @return array
- */
- public static function getAllLastChanges()
- {
- $db = db_connection();
-
- $sql = $db->sql( <<<SQL
- SELECT {{object}}.id as objectid,
- {{object}}.lastchange_date as lastchange_date,
- {{object}}.filename as filename,
- {{project}}.id as projectid,
- {{project}}.name as projectname,
- {{user}}.name as username,
- {{user}}.id as userid,
- {{user}}.mail as usermail,
- {{user}}.fullname as userfullname
- FROM {{object}}
- LEFT JOIN {{project}}
- ON {{object}}.projectid = {{project}}.id
- LEFT JOIN {{user}}
- ON {{user}}.id = {{object}}.lastchange_userid
- ORDER BY {{object}}.lastchange_date DESC
- LIMIT 50
-SQL
- );
-
- return $sql->getAll();
- }
-
-
-
- /**
- * Ermittelt die letzten Änderung im Projekt.
- * @return array
- */
- public function getLastChanges()
- {
-
- $db = db_connection();
-
- $sql = $db->sql( <<<SQL
- SELECT {{object}}.id as objectid,
- {{object}}.lastchange_date as lastchange_date,
- {{object}}.filename as filename,
- {{object}}.typeid as typeid,
- {{name}}.name as name,
- {{user}}.name as username,
- {{user}}.id as userid,
- {{user}}.mail as usermail,
- {{user}}.fullname as userfullname
- FROM {{object}}
- LEFT JOIN {{name}}
- ON {{name}}.objectid = {{object}}.id
- AND {{name}}.languageid = {languageid}
- LEFT JOIN {{user}}
- ON {{user}}.id = {{object}}.lastchange_userid
- WHERE {{object}}.projectid = {projectid}
- ORDER BY {{object}}.lastchange_date DESC
-SQL
- );
-
- // Variablen setzen.
- $sql->setInt( 'projectid', $this->projectid );
-
- $languageid = $this->getDefaultLanguageId();
- $sql->setInt( 'languageid', $languageid );
-
- return $sql->getAll();
- }
-
- /**
- * Ermittelt alle Objekte vom gew�nschten Typ, die sic in
- * diesem Projekt befinden.
- *
- * @see objectClasses/Object#getAllObjectIds()
- * @param types Array
- * @return Liste von Object-Ids
- */
- public function getAllObjectIds( $types=array('folder','page','link','file','image','url','text') )
- {
- $stmt = db()->sql( <<<SQL
- SELECT id FROM {{object}}
- WHERE projectid={projectid}
- AND ( typeid ={is_folder}
- OR typeid ={is_file}
- OR typeid ={is_image}
- OR typeid ={is_text}
- OR typeid ={is_page}
- OR typeid ={is_link}
- OR typeid ={is_url} )
- ORDER BY orderid ASC
-SQL
- );
-
- $stmt->setInt('projectid',$this->projectid );
- $stmt->setInt('is_folder',in_array('folder',$types)?BaseObject::TYPEID_FOLDER:0);
- $stmt->setInt('is_file' ,in_array('file' ,$types)?BaseObject::TYPEID_FILE :0);
- $stmt->setInt('is_image' ,in_array('image' ,$types)?BaseObject::TYPEID_IMAGE :0);
- $stmt->setInt('is_text' ,in_array('text' ,$types)?BaseObject::TYPEID_TEXT :0);
- $stmt->setInt('is_page' ,in_array('page' ,$types)?BaseObject::TYPEID_PAGE :0);
- $stmt->setInt('is_link' ,in_array('link' ,$types)?BaseObject::TYPEID_LINK :0);
- $stmt->setInt('is_url' ,in_array('url' ,$types)?BaseObject::TYPEID_URL :0);
-
- return( $stmt->getCol() );
- }
-
-
- /**
- * Liefert die Ids aller Ordner in diesem Projekt.
- *
- * @return array
- */
- public function getAllFolders()
- {
- $db = db_connection();
-
- $stmt = $db->sql('SELECT id FROM {{object}}'.
- ' WHERE typeid='.BaseObject::TYPEID_FOLDER.
- ' AND projectid={projectid}' );
-
- $stmt->setInt( 'projectid',$this->projectid );
-
- return( $stmt->getCol() );
- }
-
-
-}
-
+<?php
+
+namespace cms\model;
+
+define('PROJECT_FLAG_CUT_INDEX',1);
+define('PROJECT_FLAG_CONTENT_NEGOTIATION',2);
+define('PROJECT_FLAG_PUBLISH_FILE_EXTENSION',4);
+define('PROJECT_FLAG_PUBLISH_PAGE_EXTENSION',8);
+
+use database\Database;
+use Session;
+
+
+/**
+ * Darstellen eines Projektes
+ *
+ * @author Jan Dankert
+ * @package openrat.objects
+ */
+class Project extends ModelBase
+{
+ // Eigenschaften
+ public $projectid;
+ public $name;
+ public $target_dir;
+ public $ftp_url;
+
+ /**
+ * Hostname
+ * @var string
+ */
+ public $url;
+
+ public $ftp_passive;
+ public $cmd_after_publish;
+
+
+ /**
+ * @var boolean
+ */
+ public $content_negotiation = false;
+
+ /**
+ * @var boolean
+ */
+ public $cut_index = false;
+
+ /**
+ * @var boolean
+ */
+ public $publishFileExtension = true;
+
+ /**
+ * @var boolean
+ */
+ public $publishPageExtension = true;
+
+ public $log = array();
+
+
+
+ // Konstruktor
+ public function __construct( $projectid='' )
+ {
+ if ( intval($projectid) != 0 )
+ $this->projectid = $projectid;
+ }
+
+
+ private static $cache = array();
+
+ /**
+ * @param $projectid
+ * @return Project
+ * @throws \ObjectNotFoundException
+ */
+ public static function create($projectid)
+ {
+ if ( empty( Project::$cache[ $projectid ] ) )
+ {
+ $project = new Project( $projectid );
+
+ Project::$cache[ $projectid ] = $project->load();
+ }
+ return Project::$cache[ $projectid ];
+ }
+
+
+ /**
+ * Stellt fest, ob die angegebene Projekt-Id existiert.
+ * @param $id int Projekt-Id
+ * @return boolean
+ *
+ */
+ public function isAvailable($id )
+ {
+ $db = db_connection();
+
+ $sql = $db->sql('SELECT 1 FROM {{project}} '.
+ ' WHERE id={id}');
+ $sql->setInt('id' ,$id );
+
+ return intval($sql->getOne()) == 1;
+ }
+
+
+ /**
+ * Liefert alle verf?gbaren Projekte.
+ * @return array
+ */
+ public static function getAllProjects()
+ {
+ $db = db_connection();
+ $sql = $db->sql( 'SELECT id,name FROM {{project}} '.
+ ' ORDER BY name' );
+
+ return $sql->getAssoc();
+ }
+
+
+ // Liefert alle verf?gbaren Projekt-Ids
+ public function getAllProjectIds()
+ {
+ $db = db_connection();
+ $sql = $db->sql( 'SELECT id FROM {{project}} '.
+ ' ORDER BY name' );
+
+ return $sql->getCol();
+ }
+
+
+ /**
+ * Liefert die Sprachen des Projektes.
+ *
+ * @return array Id->Name
+ */
+ public function getLanguages()
+ {
+ $db = db_connection();
+
+ $sql = $db->sql( 'SELECT id,name FROM {{language}}'.
+ ' WHERE projectid={projectid} '.
+ ' ORDER BY name' );
+ $sql->setInt ('projectid',$this->projectid);
+
+ return $sql->getAssoc();
+ }
+
+
+ public function getLanguageIds()
+ {
+ return array_keys( $this->getLanguages() );
+ }
+
+
+ /**
+ * Liefert die Projektmodelle als Array mit ID->Name.
+ *
+ * @return array
+ */
+ public function getModels()
+ {
+ $db = db_connection();
+
+ $sql = $db->sql( 'SELECT id,name FROM {{projectmodel}}'.
+ ' WHERE projectid= {projectid} '.
+ ' ORDER BY name' );
+ $sql->setInt ('projectid',$this->projectid);
+
+ return $sql->getAssoc();
+ }
+
+
+ public function getModelIds()
+ {
+ return array_keys( $this->getModels() );
+ }
+
+
+ public function getTemplateIds()
+ {
+ $db = db_connection();
+
+ $sql = $db->sql( 'SELECT id FROM {{template}}'.
+ ' WHERE projectid= {projectid} ' );
+ $sql->setInt ('projectid',$this->projectid);
+
+ return $sql->getCol();
+ }
+
+
+ public function getTemplates()
+ {
+ $db = db_connection();
+
+ $sql = $db->sql( 'SELECT id,name FROM {{template}}'.
+ ' WHERE projectid= {projectid} ' );
+ $sql->setInt ('projectid',$this->projectid);
+
+ return $sql->getAssoc();
+ }
+
+
+ /**
+ * Ermitteln des Wurzel-Ordners fuer dieses Projekt.
+ *
+ * Der Wurzelordner ist der einzige Ordnerhat in diesem
+ * Projekt, der kein Elternelement besitzt.
+ *
+ * @return Objekt-Id des Wurzelordners
+ */
+ public function getRootObjectId()
+ {
+ $db = db_connection();
+
+ $sql = $db->sql('SELECT id FROM {{object}}'.
+ ' WHERE parentid IS NULL'.
+ ' AND projectid={projectid}' );
+
+ $sql->setInt('projectid',$this->projectid);
+
+ return( $sql->getOne() );
+ }
+
+
+
+ // Laden
+
+ /**
+ * @throws \ObjectNotFoundException
+ */
+ public function load()
+ {
+ $sql = db()->sql( 'SELECT * FROM {{project}} '.
+ ' WHERE id={projectid}' );
+ $sql->setInt( 'projectid',$this->projectid );
+
+ $row = $sql->getRow();
+
+ if ( empty($row) )
+ throw new \ObjectNotFoundException('project '.$this->projectid.' not found');
+
+ $this->name = $row['name' ];
+ $this->url = $row['url' ];
+ $this->target_dir = $row['target_dir' ];
+ $this->ftp_url = $row['ftp_url' ];
+ $this->ftp_passive = $row['ftp_passive' ];
+ $this->cmd_after_publish = $row['cmd_after_publish' ];
+ $this->cut_index = $row['flags']&PROJECT_FLAG_CUT_INDEX;
+ $this->content_negotiation = $row['flags']&PROJECT_FLAG_CONTENT_NEGOTIATION;
+ $this->publishFileExtension = $row['flags']&PROJECT_FLAG_PUBLISH_FILE_EXTENSION;
+ $this->publishPageExtension = $row['flags']&PROJECT_FLAG_PUBLISH_PAGE_EXTENSION;
+
+ return $this;
+ }
+
+
+ // Laden
+ public function loadByName()
+ {
+ $db = db_connection();
+
+ $sql = $db->sql( 'SELECT * FROM {{project}} '.
+ ' WHERE name={projectname}' );
+ $sql->setString( 'projectname',$this->name );
+
+ $row = $sql->getRow();
+
+ $this->projectid = $row['id' ];
+ $this->target_dir = $row['target_dir' ];
+ $this->ftp_url = $row['ftp_url' ];
+ $this->url = $row['url' ];
+ $this->ftp_passive = $row['ftp_passive' ];
+ $this->cmd_after_publish = $row['cmd_after_publish' ];
+ $this->cut_index = $row['flags']&PROJECT_FLAG_CUT_INDEX;
+ $this->content_negotiation = $row['flags']&PROJECT_FLAG_CONTENT_NEGOTIATION;
+ $this->publishFileExtension = $row['flags']&PROJECT_FLAG_PUBLISH_FILE_EXTENSION;
+ $this->publishPageExtension = $row['flags']&PROJECT_FLAG_PUBLISH_PAGE_EXTENSION;
+ }
+
+
+ // Speichern
+ public function save()
+ {
+ $db = db_connection();
+
+ $sql = $db->sql( <<<SQL
+ UPDATE {{project}}
+ SET name = {name},
+ target_dir = {target_dir},
+ ftp_url = {ftp_url},
+ ftp_passive = {ftp_passive},
+ url = {url},
+ flags = {flags},
+ cmd_after_publish = {cmd_after_publish}
+ WHERE id= {projectid}
+SQL
+);
+
+ $sql->setString('ftp_url' ,$this->ftp_url );
+ $sql->setString('url' ,$this->url );
+ $sql->setString('name' ,$this->name );
+ $sql->setString('target_dir' ,$this->target_dir );
+ $sql->setInt ('ftp_passive' ,$this->ftp_passive );
+ $sql->setString('cmd_after_publish' ,$this->cmd_after_publish );
+
+ $flags = 0;
+ if( $this->cut_index) $flags |= PROJECT_FLAG_CUT_INDEX;
+ if( $this->content_negotiation) $flags |= PROJECT_FLAG_CONTENT_NEGOTIATION;
+ if( $this->publishFileExtension) $flags |= PROJECT_FLAG_PUBLISH_FILE_EXTENSION;
+ if( $this->publishPageExtension) $flags |= PROJECT_FLAG_PUBLISH_PAGE_EXTENSION;
+
+ $sql->setInt ('flags' ,$flags );
+ $sql->setInt ('projectid' ,$this->projectid );
+
+ $sql->query();
+
+ try
+ {
+ $rootFolder = new Folder( $this->getRootObjectId() );
+ $rootFolder->load();
+ $rootFolder->filename = $this->name;
+ $rootFolder->save();
+ }
+ catch( \Exception $e )
+ {
+ \Logger::warn('Project '.$this->projectid.' has not a root folder'."\n".$e->getTraceAsString());
+ }
+ }
+
+
+ /**
+ * Liefert alle Eigenschaften des Projektes.
+ */
+ public function getProperties()
+ {
+ return parent::getProperties();
+ }
+
+
+ /**
+ * Add a project to the database.
+ */
+ public function add()
+ {
+ $db = db_connection();
+
+ $sql = $db->sql('SELECT MAX(id) FROM {{project}}');
+ $this->projectid = intval($sql->getOne())+1;
+
+
+ // Projekt hinzuf?gen
+ $sql = $db->sql( 'INSERT INTO {{project}} (id,name,target_dir,ftp_url,ftp_passive,cmd_after_publish,flags) '.
+ " VALUES( {projectid},{name},'','',0,'',0 ) " );
+ $sql->setInt ('projectid',$this->projectid );
+ $sql->setString('name' ,$this->name );
+
+ $sql->query();
+
+ // Modell anlegen
+ $model = new Model();
+ $model->projectid = $this->projectid;
+ $model->name = 'html';
+ $model->add();
+
+ // Sprache anlegen
+ $language = new Language();
+ $language->projectid = $this->projectid;
+ $language->isoCode = 'en';
+ $language->name = 'english';
+ $language->add();
+
+ // Haupt-Ordner anlegen
+ $folder = new Folder();
+ $folder->isRoot = true;
+ $folder->projectid = $this->projectid;
+ $folder->languageid = $language->languageid;
+ $folder->filename = $this->name;
+ $folder->name = $this->name;
+ $folder->isRoot = true;
+ $folder->add();
+
+ // Template anlegen
+ $template = new Template();
+ $template->projectid = $this->projectid;
+ $template->name = '';
+ $template->modelid = $model->modelid;
+ $template->languageid = $language->languageid;
+ $template->extension = 'html';
+ $template->src = '<html><body><h1>Hello world</h1><hr><p>Hello, World.</p></body></html>';
+ $template->add();
+ $template->save();
+
+ // Beispiel-Seite anlegen
+ $page = new Page();
+ $page->parentid = $folder->objectid;
+ $page->projectid = $this->projectid;
+ $page->languageid = $language->languageid;
+ $page->templateid = $template->templateid;
+ $page->filename = '';
+ $page->name = 'OpenRat';
+ $page->add();
+ }
+
+
+ // Projekt aus Datenbank entfernen
+ public function delete()
+ {
+ $db = db_connection();
+
+ // Root-Ordner rekursiv samt Inhalten loeschen
+ $folder = new Folder( $this->getRootObjectId() );
+ $folder->deleteAll();
+
+
+ foreach( $this->getLanguageIds() as $languageid )
+ {
+ $language = new Language( $languageid );
+ $language->delete();
+ }
+
+
+ foreach( $this->getTemplateIds() as $templateid )
+ {
+ $template = new Template( $templateid );
+ $template->delete();
+ }
+
+
+ foreach( $this->getModelIds() as $modelid )
+ {
+ $model = new Model( $modelid );
+ $model->delete();
+ }
+
+
+ // Deleting the project
+ $sql = $db->sql( 'DELETE FROM {{project}}'.
+ ' WHERE id= {projectid} ' );
+ $sql->setInt( 'projectid',$this->projectid );
+ $sql->query();
+ }
+
+
+ /**
+ * Liefert die Standard-Sprach-Id. If there is no default language, the first language-id will be used.
+ * @return String
+ */
+ public function getDefaultLanguageId()
+ {
+ // ORDER BY deswegen, damit immer mind. eine Sprache
+ // gelesen wird
+ $sql = db()->sql( 'SELECT id FROM {{language}} '.
+ ' WHERE projectid={projectid}'.
+ ' ORDER BY is_default DESC, name ASC' );
+
+ $sql->setInt('projectid',$this->projectid );
+
+ return $sql->getOne();
+ }
+
+
+ public function getDefaultModelId()
+ {
+ // ORDER BY deswegen, damit immer mind. eine Sprache
+ // gelesen wird
+ $sql = db()->sql( 'SELECT id FROM {{projectmodel}} '.
+ ' WHERE projectid={projectid}'.
+ ' ORDER BY is_default DESC' );
+ $sql->setInt('projectid',$this->projectid );
+
+ return $sql->getOne();
+ }
+
+
+
+ /**
+ * Entfernt nicht mehr notwendige Inhalte aus dem Archiv.
+ */
+ public function checkLimit()
+ {
+ $root = new Folder( $this->getRootObjectId() );
+ $root->projectid = $this->projectid;
+
+ $pages = $this->getAllObjectIds( array('page') );
+ $languages = $this->getLanguageIds();
+
+ foreach( $pages as $objectid )
+ {
+ $page = new Page( $objectid );
+ $page->load();
+ foreach( $page->getElementIds() as $eid )
+ {
+ foreach( $languages as $lid )
+ {
+ $value = new Value();
+ $value->element = new Element($eid);
+ $value->pageid = $page->pageid;
+ $value->languageid = $lid;
+
+ $value->checkLimit();
+ }
+ }
+ }
+
+ }
+
+
+
+ /**
+ * Testet die Integrität der Datenbank.
+ */
+ public function checkLostFiles()
+ {
+ $this->log = array();
+
+ // Ordnerstruktur prüfen.
+ $stmt = db()->sql( <<<EOF
+SELECT thistab.id FROM {{object}} AS thistab
+ LEFT JOIN {{object}} AS parenttab
+ ON parenttab.id = thistab.parentid
+ WHERE thistab.projectid={projectid} AND thistab.parentid IS NOT NULL AND parenttab.id IS NULL
+EOF
+);
+ $stmt->setInt('projectid',$this->projectid);
+
+ $idList = $stmt->getCol();
+
+ if ( count( $idList ) > 0 )
+ {
+ $lostAndFoundFolder = new Folder();
+ $lostAndFoundFolder->projectid = $this->projectid;
+ $lostAndFoundFolder->languageid = $this->getDefaultLanguageId();
+ $lostAndFoundFolder->filename = "lostandfound";
+ $lostAndFoundFolder->name = 'Lost+found';
+ $lostAndFoundFolder->parentid = $this->getRootObjectId();
+ $lostAndFoundFolder->add();
+
+ foreach( $idList as $id )
+ {
+ $this->log[] = 'Lost file! Moving '.$id.' to lost+found.';
+ $obj = new BaseObject( $id );
+ $obj->setParentId( $lostAndFoundFolder->objectid );
+ }
+ }
+
+
+ // Prüfe, ob die Verbindung Projekt->Template->Templatemodell->Projectmodell->Projekt konsistent ist.
+ $stmt = db()->sql( <<<EOF
+SELECT DISTINCT projectid FROM {{projectmodel}} WHERE id IN (SELECT projectmodelid from {{templatemodel}} WHERE templateid in (SELECT id from {{template}} WHERE projectid={projectid}))
+EOF
+);
+ $stmt->setInt('projectid',$this->projectid);
+
+ $idList = $stmt->getCol();
+
+ if ( count( $idList ) > 1 )
+ {
+ \Logger::warn('Inconsistence found: Reference circle project<->template<->templatemodel<->projectmodel<->project is not consistent.');
+ $this->log[] = 'Inconsistence found: Reference circle project<->template<->templatemodel<->projectmodel<->project is not consistent.';
+ }
+
+ }
+
+
+ /**
+ * Synchronisation des Projektinhaltes mit dem Dateisystem.
+ */
+ public function sync()
+ {
+ global $conf;
+ $syncConf = $conf['sync'];
+
+ if ( ! $syncConf['enabled'] )
+ return;
+
+ $syncDir = slashify($syncConf['directory']).$this->name;
+
+ }
+
+ /**
+ * Kopiert ein Projekt von einer Datenbank zu einer anderen.<br>
+ * <br>
+ * Alle Projektinhalte werden kopiert, die Fremdschluesselbeziehungen werden entsprechend angepasst.<br>
+ * <br>
+ * Alle Beziehungen zu Benutzern, z.B. "Zuletzt geaendert von", "angelegt von" sowie<br>
+ * alle Berechtigungsinformationen gehen verloren!<br>
+ *
+ * @param string $dbid_destination ID der Ziel-Datenbank
+ * @param string $name
+ */
+ public function copy( $dbid_destination,$name='' )
+ {
+ \Logger::debug( 'Copying project '.$this->name.' to database '.$dbid_destination );
+
+ global $conf;
+ $zeit = date('Y-m-d\TH:i:sO');
+
+ $db_src = db_connection();
+ $db_dest = new Database( $conf['database'][$dbid_destination] );
+ $db_dest->id = $dbid_destination;
+ $db_dest->start();
+
+ $sameDB = ( $db_dest->id == $db_src->id );
+
+ // -------------------------------------------------------
+ $mapping = array();
+ $ids = array('project' => array('foreign_keys'=>array(),
+ 'primary_key' =>'id',
+ 'unique_idx' =>'name',
+ 'erase' =>array()
+ ),
+ 'language' => array('foreign_keys'=>array('projectid'=>'project'),
+ 'primary_key' =>'id'
+ ),
+ 'projectmodel' => array('foreign_keys'=>array('projectid'=>'project'),
+ 'primary_key' =>'id'
+ ),
+ 'template' => array('foreign_keys'=>array('projectid'=>'project'),
+ 'primary_key' =>'id'
+ ),
+ 'object' => array('foreign_keys'=>array('projectid' =>'project' ),
+ 'self_key' =>'parentid',
+ 'primary_key' =>'id',
+ 'erase' =>array('create_userid','lastchange_userid')
+ ),
+ 'element' => array('foreign_keys'=>array('templateid' =>'template',
+ 'folderobjectid' =>'object',
+ 'default_objectid'=>'object' ),
+ 'primary_key' =>'id'
+ ),
+ 'templatemodel'=> array('foreign_keys'=>array('projectmodelid'=>'projectmodel',
+ 'templateid' =>'template' ),
+ 'primary_key' =>'id',
+ 'replace' =>array('text'=>'element')
+ ),
+ 'name' => array('foreign_keys'=>array('objectid' =>'object',
+ 'languageid'=>'language' ),
+ 'primary_key' =>'id'
+ ),
+ 'page' => array('foreign_keys'=>array('objectid' =>'object',
+ 'templateid'=>'template' ),
+ 'primary_key' =>'id'
+ ),
+ 'value' => array('foreign_keys'=>array('pageid' =>'page',
+ 'languageid'=>'language',
+ 'elementid'=>'element',
+ 'linkobjectid'=>'object' ),
+ 'erase' =>array('lastchange_userid'),
+ 'replace' =>array('text'=>'object'),
+ 'primary_key' =>'id'
+ ),
+ 'link' => array('foreign_keys'=>array('objectid' =>'object',
+ 'link_objectid'=>'object' ),
+ 'primary_key' =>'id'
+ ),
+ 'folder' => array('foreign_keys'=>array('objectid' =>'object' ),
+ 'primary_key' =>'id'
+ ),
+ 'file' => array('foreign_keys'=>array('objectid' =>'object' ),
+ 'primary_key' =>'id',
+ 'binary' =>'value'
+ ),
+
+ );
+
+ if ( $sameDB )
+ $ids['acl'] = array('foreign_keys'=>array('objectid' => 'object',
+ 'languageid' => 'language' ),
+ 'primary_key' =>'id'
+ );
+
+ foreach( $ids as $tabelle=>$data )
+ {
+ \Logger::debug( 'Copying table '.$tabelle.' ...' );
+ $mapping[$tabelle] = array();
+ $idcolumn = $data['primary_key'];
+
+ // Naechste freie Id in der Zieltabelle ermitteln.
+ $stmt = $db_dest->sql( 'SELECT MAX('.$idcolumn.') FROM {t_'.$tabelle.'}');
+ $maxid = intval($stmt->getOne());
+ $nextid = $maxid;
+
+ // Zu �bertragende IDs ermitteln.
+ if ( count($data['foreign_keys'])==0 )
+ {
+ $where = ' WHERE id='.$this->projectid;
+ }
+ else
+ {
+ foreach( $data['foreign_keys'] as $fkey_column=>$target_tabelle )
+ {
+ $where = ' WHERE '.$fkey_column.' IN ('.join(array_keys($mapping[$target_tabelle]),',').')';
+ break;
+ }
+ }
+ $stmt = $db_src->sql( 'SELECT '.$idcolumn.' FROM {t_'.$tabelle.'} '.$where);
+
+ foreach( $stmt->getCol() as $srcid )
+ {
+ \Logger::debug('Id '.$srcid.' of table '.$tabelle);
+ $mapping[$tabelle][$srcid] = ++$nextid;
+
+ $stmt = $db_src->sql( 'SELECT * FROM {t_'.$tabelle.'} WHERE id={id}');
+ $stmt->setInt('id',$srcid);
+ $row = $stmt->getRow();
+
+ // Wert des Prim�rschl�ssels �ndern.
+ $row[$idcolumn] = $mapping[$tabelle][$srcid];
+
+ // Fremdschl�sselbeziehungen auf neue IDn korrigieren.
+ foreach( $data['foreign_keys'] as $fkey_column=>$target_tabelle)
+ {
+ \Logger::debug($fkey_column.' '.$target_tabelle.' '.$row[$fkey_column]);
+
+ if ( intval($row[$fkey_column]) != 0 )
+ $row[$fkey_column] = $mapping[$target_tabelle][$row[$fkey_column]];
+ }
+
+ foreach( array_keys($row) as $key )
+ {
+ if ( isset($data['unique_idx']) && $key == $data['unique_idx'] )
+ {
+ // Nachschauen, ob es einen UNIQUE-Key in der Zieltabelle schon gibt.
+ $stmt = $db_dest->sql( 'SELECT 1 FROM {t_'.$tabelle.'} WHERE '.$key."='".$row[$key]."'");
+
+ if ( intval($stmt->getOne()) == 1 )
+ $row[$key] = $row[$key].$zeit;
+
+ }
+
+ if ( !$sameDB && isset($data['erase']) && in_array($key,$data['erase']) )
+ $row[$key] = null;
+
+ if ( isset($data['self_key']) && $key == $data['self_key'] && intval($row[$key]) > 0 )
+ $row[$key] = $row[$key]+$maxid;
+ }
+
+ if ( isset($data['replace']) )
+ {
+ foreach( $data['replace'] as $repl_column=>$repl_tabelle)
+ foreach( $mapping[$repl_tabelle] as $oldid=>$newid)
+ {
+ $row[$repl_column] = str_replace('{'.$oldid.'}','{'.$newid.'}' ,$row[$repl_column]);
+ $row[$repl_column] = str_replace('"'.$oldid.'"','"'.$newid.'"' ,$row[$repl_column]);
+ $row[$repl_column] = str_replace('->'.$oldid ,'->"'.$newid.'"',$row[$repl_column]);
+ }
+ }
+
+ if ( isset($data['binary']) )
+ {
+ if ( !$db_src->conf['base64'] && $db_dest->conf['base64'] )
+ $row[$data['binary']] = base64_encode($row[$data['binary']]);
+ elseif ( $db_src->conf['base64'] && !$db_dest->conf['base64'] )
+ $row[$data['binary']] = base64_decode($row[$data['binary']]);
+ }
+
+ // Daten in Zieltabelle einf�gen.
+ $stmt = $db_dest->sql( 'INSERT INTO {t_'.$tabelle.'} ('.join(array_keys($row),',').') VALUES({'.join(array_keys($row),'},{').'})',$dbid_destination);
+ foreach( $row as $key=>$value )
+ {
+ if ( !$sameDB && isset($data['erase']) && in_array($key,$data['erase']) )
+ $stmt->setNull($key);
+ else
+ {
+ if(is_bool($value))
+ $stmt->setBoolean($key,$value);
+ elseif(is_int($value))
+ $stmt->setInt($key,$value);
+ elseif(is_string($value))
+ $stmt->setString($key,$value);
+ }
+ }
+ //$sql = $db->sql( 'INSERT INTO {t_'.$tabelle.'} ('.join(array_keys($row),',').') VALUES('.join($row,',').')',$dbid_destination);
+ $stmt->query();
+ }
+
+ if ( isset($data['self_key']) )
+ {
+ foreach( $mapping[$tabelle] as $oldid=>$newid )
+ {
+ $stmt = $db_dest->sql( 'UPDATE {t_'.$tabelle.'} SET '.$data['self_key'].'='.$newid.' WHERE '.$data['self_key'].'='.($oldid+$maxid),$dbid_destination );
+ $stmt->query();
+ }
+ }
+ }
+
+ \Logger::debug( 'Finished copying project' );
+
+ $db_dest->commit();
+ }
+
+
+
+ /**
+ * Ermittelt die Anzahl aller Objekte in diesem Projekt.
+ * @return int Anzahl
+ */
+ public function countObjects()
+ {
+ $db = db_connection();
+ $sql = $db->sql( 'SELECT COUNT(*) FROM {{object}} '.
+ ' WHERE projectid = {projectid}' );
+ $sql->setInt( 'projectid', $this->projectid );
+
+ return $sql->getOne();
+
+ }
+
+
+
+ /**
+ * Ermittelt die Gr��e aller Dateien in diesem Projekt.
+ * @return int Summe aller Dateigroessen
+ */
+ public function size()
+ {
+ $db = db_connection();
+
+ $sql = $db->sql( <<<SQL
+ SELECT SUM(size) FROM {{file}}
+ LEFT JOIN {{object}}
+ ON {{file}}.objectid = {{object}}.id
+ WHERE projectid = {projectid}
+SQL
+);
+ $sql->setInt( 'projectid', $this->projectid );
+
+ return $sql->getOne();
+ }
+
+
+
+ /**
+ * Liefert alle verf?gbaren Projekt-Ids
+ */
+ public function info()
+ {
+ $info = array();
+
+ $info['count_objects'] = $this->countObjects();
+ $info['sum_filesize' ] = $this->size();
+
+
+ return $info;
+ }
+
+
+
+
+ /**
+ * Ermittelt projektübergreifend die letzten Änderungen des angemeldeten Benutzers.
+ *
+ * @return array <string, unknown>
+ */
+ public function getMyLastChanges()
+ {
+
+ $db = db_connection();
+
+
+ $sql = $db->sql( <<<SQL
+ SELECT {{object}}.id as objectid,
+ {{object}}.filename as filename,
+ {{object}}.typeid as typeid,
+ {{object}}.lastchange_date as lastchange_date,
+ {{name}}.name as name
+ FROM {{object}}
+ LEFT JOIN {{name}}
+ ON {{name}}.objectid = {{object}}.id
+ AND {{name}}.languageid = {languageid}
+ LEFT JOIN {{project}}
+ ON {{object}}.projectid = {{project}}.id
+ WHERE {{object}}.projectid = {projectid}
+ AND {{object}}.lastchange_userid = {userid}
+ ORDER BY {{object}}.lastchange_date DESC;
+SQL
+ );
+
+ // Variablen setzen.
+ $sql->setInt( 'projectid', $this->projectid );
+
+ $sql->setInt( 'languageid', 0 );
+
+ $user = Session::getUser();
+ $sql->setInt( 'userid', $user->userid );
+
+ return $sql->getAll();
+ }
+
+
+ /**
+ * Ermittelt projektübergreifend die letzten Änderungen.
+ *
+ * @return array
+ */
+ public static function getAllLastChanges()
+ {
+ $db = db_connection();
+
+ $sql = $db->sql( <<<SQL
+ SELECT {{object}}.id as objectid,
+ {{object}}.lastchange_date as lastchange_date,
+ {{object}}.filename as filename,
+ {{project}}.id as projectid,
+ {{project}}.name as projectname,
+ {{user}}.name as username,
+ {{user}}.id as userid,
+ {{user}}.mail as usermail,
+ {{user}}.fullname as userfullname
+ FROM {{object}}
+ LEFT JOIN {{project}}
+ ON {{object}}.projectid = {{project}}.id
+ LEFT JOIN {{user}}
+ ON {{user}}.id = {{object}}.lastchange_userid
+ ORDER BY {{object}}.lastchange_date DESC
+ LIMIT 50
+SQL
+ );
+
+ return $sql->getAll();
+ }
+
+
+
+ /**
+ * Ermittelt die letzten Änderung im Projekt.
+ * @return array
+ */
+ public function getLastChanges()
+ {
+
+ $db = db_connection();
+
+ $sql = $db->sql( <<<SQL
+ SELECT {{object}}.id as objectid,
+ {{object}}.lastchange_date as lastchange_date,
+ {{object}}.filename as filename,
+ {{object}}.typeid as typeid,
+ {{name}}.name as name,
+ {{user}}.name as username,
+ {{user}}.id as userid,
+ {{user}}.mail as usermail,
+ {{user}}.fullname as userfullname
+ FROM {{object}}
+ LEFT JOIN {{name}}
+ ON {{name}}.objectid = {{object}}.id
+ AND {{name}}.languageid = {languageid}
+ LEFT JOIN {{user}}
+ ON {{user}}.id = {{object}}.lastchange_userid
+ WHERE {{object}}.projectid = {projectid}
+ ORDER BY {{object}}.lastchange_date DESC
+SQL
+ );
+
+ // Variablen setzen.
+ $sql->setInt( 'projectid', $this->projectid );
+
+ $languageid = $this->getDefaultLanguageId();
+ $sql->setInt( 'languageid', $languageid );
+
+ return $sql->getAll();
+ }
+
+ /**
+ * Ermittelt alle Objekte vom gew�nschten Typ, die sic in
+ * diesem Projekt befinden.
+ *
+ * @see objectClasses/Object#getAllObjectIds()
+ * @param types Array
+ * @return Liste von Object-Ids
+ */
+ public function getAllObjectIds( $types=array('folder','page','link','file','image','url','text') )
+ {
+ $stmt = db()->sql( <<<SQL
+ SELECT id FROM {{object}}
+ WHERE projectid={projectid}
+ AND ( typeid ={is_folder}
+ OR typeid ={is_file}
+ OR typeid ={is_image}
+ OR typeid ={is_text}
+ OR typeid ={is_page}
+ OR typeid ={is_link}
+ OR typeid ={is_url} )
+ ORDER BY orderid ASC
+SQL
+ );
+
+ $stmt->setInt('projectid',$this->projectid );
+ $stmt->setInt('is_folder',in_array('folder',$types)?BaseObject::TYPEID_FOLDER:0);
+ $stmt->setInt('is_file' ,in_array('file' ,$types)?BaseObject::TYPEID_FILE :0);
+ $stmt->setInt('is_image' ,in_array('image' ,$types)?BaseObject::TYPEID_IMAGE :0);
+ $stmt->setInt('is_text' ,in_array('text' ,$types)?BaseObject::TYPEID_TEXT :0);
+ $stmt->setInt('is_page' ,in_array('page' ,$types)?BaseObject::TYPEID_PAGE :0);
+ $stmt->setInt('is_link' ,in_array('link' ,$types)?BaseObject::TYPEID_LINK :0);
+ $stmt->setInt('is_url' ,in_array('url' ,$types)?BaseObject::TYPEID_URL :0);
+
+ return( $stmt->getCol() );
+ }
+
+
+ /**
+ * Liefert die Ids aller Ordner in diesem Projekt.
+ *
+ * @return array
+ */
+ public function getAllFolders()
+ {
+ $db = db_connection();
+
+ $stmt = $db->sql('SELECT id FROM {{object}}'.
+ ' WHERE typeid='.BaseObject::TYPEID_FOLDER.
+ ' AND projectid={projectid}' );
+
+ $stmt->setInt( 'projectid',$this->projectid );
+
+ return( $stmt->getCol() );
+ }
+
+
+}
+
?>
\ No newline at end of file
diff --git a/modules/cms-core/model/User.class.php b/modules/cms-core/model/User.class.php
@@ -39,7 +39,6 @@ class User extends ModelBase
var $desc;
var $style;
var $isAdmin;
- var $projects = array();
var $rights;
var $loginDate = 0;
@@ -112,24 +111,21 @@ class User extends ModelBase
*/
public function setCurrent()
{
- $this->loadProjects();
$this->loginDate = time();
\Session::setUser( $this );
- $db = db_connection();
-
- $sql = $db->sql( <<<SQL
+ $stmt = db()->sql( <<<SQL
UPDATE {{user}}
SET last_login={time}
WHERE id={userid}
SQL
);
- $sql->setInt( 'time' ,time() );
- $sql->setInt( 'userid',$this->userid );
+ $stmt->setInt( 'time' ,time() );
+ $stmt->setInt( 'userid',$this->userid );
// Datenbankabfrage ausfuehren
- $sql->query();
+ $stmt->query();
}
@@ -202,16 +198,6 @@ SQL
}
- /**
- * Lädt die Liste alle Projekte, fuer die der Benutzer berechtigt ist und
- * speichert diese in diesem Benutzerobjekt.
- */
- function loadProjects()
- {
- $this->projects = $this->getReadableProjects();
- }
-
-
/**
* Ermittelt zu diesem Benutzer den Login-Token.
@@ -260,11 +246,8 @@ SQL
*/
public static function loadWithName( $name )
{
- global $conf;
- $db = db_connection();
-
// Benutzer �ber Namen suchen
- $sql = $db->sql( 'SELECT id FROM {{user}}'.
+ $sql = db()->sql( 'SELECT id FROM {{user}}'.
' WHERE name={name}' );
//Html::debug($sql);
$sql->setString( 'name',$name );
diff --git a/modules/cms-core/model/Value.class.php b/modules/cms-core/model/Value.class.php
@@ -1466,7 +1466,7 @@ SQL
if ( substr($inhalt,-4) == 'api/' )
$inhalt = substr($inhalt,0,-4);
- $db = \Session::getDatabase();
+ $db = db();
$params = array('dbid' =>$db->id,
'objectid' =>$this->page->objectid,
'modelid' =>$this->page->modelid,
diff --git a/modules/cms-ui/action/TitleAction.class.php b/modules/cms-ui/action/TitleAction.class.php
@@ -1,116 +1,116 @@
-<?php
-
-namespace cms\action;
-
-use cms\model\Project;
-use cms\model\BaseObject;
-use cms\model\Language;
-use cms\model\Model;
-
-use Session;
-use \Html;
-// OpenRat Content Management System
-// Copyright (C) 2002-2009 Jan Dankert, jandankert@jandankert.de
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-
-/**
- * Actionklasse zum Anzeigen der Titelleiste.
- *
- * @author Jan Dankert
- * @package openrat.actions
- */
-class TitleAction extends Action
-{
- public $security = Action::SECURITY_GUEST;
-
- /**
- * Fuellen der Variablen und Anzeigen der Titelleiste
- */
- public function showView()
- {
- $this->setTemplateVar('buildinfo',OR_TITLE.' '.OR_VERSION.' - build '.config('build','build') );
-
- $user = Session::getUser();
-
- if ( !is_object($user) )
- {
- $this->setTemplateVar('isLoggedIn' ,false );
- $this->setTemplateVar('userfullname',lang('NOT_LOGGED_IN') );
- return; // Kein Benutzer angemeldet.
- }
-
- $this->setTemplateVar('isLoggedIn',true );
-
- $db = Session::getDatabase();
- $this->setTemplateVar('dbname',$db->conf['name'].(readonly()?' ('.lang('readonly').')':''));
- $this->setTemplateVar('dbid' ,$db->id);
-
- $databases = array();
-
- $this->setTemplateVar('username' ,$user->name );
- $this->setTemplateVar('userfullname',$user->fullname);
-
- // Urls zum Benutzerprofil und zum Abmelden
- //$this->setTemplateVar('profile_url',Html::url( 'profile' ));
- //$this->setTemplateVar('logout_url' ,Html::url( 'index','logout' ));
- $this->setTemplateVar('isAdmin',$this->userIsAdmin() );
-
- if ( config('interface','session','auto_extend') )
- {
- $this->setTemplateVar('ping_url' ,Html::url('title','ping') );
- $this->setTemplateVar('ping_timeout',ini_get('session.gc_maxlifetime')-60 );
- }
- }
-
-
- public function pingView()
- {
- $this->setTemplateVar('ping',true );
- $this->setTemplateVar('time',date('r') );
- }
-
-
- public function historyView()
- {
- $resultList = array();
-
- $history = Session::get('history');
-
- if ( is_array($history) )
- {
- foreach( array_reverse($history) as $objectid )
- {
- $o = new BaseObject( $objectid );
- $o->load();
- $resultList[$objectid] = array();
- $resultList[$objectid]['url'] = Html::url($o->getType(),'',$objectid);
- $resultList[$objectid]['type'] = $o->getType();
- $resultList[$objectid]['name'] = $o->name;
- $resultList[$objectid]['lastchange_date'] = $o->lastchangeDate;
-
- if ( $o->desc != '' )
- $resultList[$objectid]['desc'] = $o->desc;
- else
- $resultList[$objectid]['desc'] = lang('NO_DESCRIPTION_AVAILABLE');
- }
- }
-
- $this->setTemplateVar( 'history',$resultList );
- }
-}
-
+<?php
+
+namespace cms\action;
+
+use cms\model\Project;
+use cms\model\BaseObject;
+use cms\model\Language;
+use cms\model\Model;
+
+use Session;
+use \Html;
+// OpenRat Content Management System
+// Copyright (C) 2002-2009 Jan Dankert, jandankert@jandankert.de
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+/**
+ * Actionklasse zum Anzeigen der Titelleiste.
+ *
+ * @author Jan Dankert
+ * @package openrat.actions
+ */
+class TitleAction extends Action
+{
+ public $security = Action::SECURITY_GUEST;
+
+ /**
+ * Fuellen der Variablen und Anzeigen der Titelleiste
+ */
+ public function showView()
+ {
+ $this->setTemplateVar('buildinfo',OR_TITLE.' '.OR_VERSION.' - build '.config('build','build') );
+
+ $user = Session::getUser();
+
+ if ( !is_object($user) )
+ {
+ $this->setTemplateVar('isLoggedIn' ,false );
+ $this->setTemplateVar('userfullname',lang('NOT_LOGGED_IN') );
+ return; // Kein Benutzer angemeldet.
+ }
+
+ $this->setTemplateVar('isLoggedIn',true );
+
+ $db = db();
+ $this->setTemplateVar('dbname',$db->conf['name'].(readonly()?' ('.lang('readonly').')':''));
+ $this->setTemplateVar('dbid' ,$db->id);
+
+ $databases = array();
+
+ $this->setTemplateVar('username' ,$user->name );
+ $this->setTemplateVar('userfullname',$user->fullname);
+
+ // Urls zum Benutzerprofil und zum Abmelden
+ //$this->setTemplateVar('profile_url',Html::url( 'profile' ));
+ //$this->setTemplateVar('logout_url' ,Html::url( 'index','logout' ));
+ $this->setTemplateVar('isAdmin',$this->userIsAdmin() );
+
+ if ( config('interface','session','auto_extend') )
+ {
+ $this->setTemplateVar('ping_url' ,Html::url('title','ping') );
+ $this->setTemplateVar('ping_timeout',ini_get('session.gc_maxlifetime')-60 );
+ }
+ }
+
+
+ public function pingView()
+ {
+ $this->setTemplateVar('ping',true );
+ $this->setTemplateVar('time',date('r') );
+ }
+
+
+ public function historyView()
+ {
+ $resultList = array();
+
+ $history = Session::get('history');
+
+ if ( is_array($history) )
+ {
+ foreach( array_reverse($history) as $objectid )
+ {
+ $o = new BaseObject( $objectid );
+ $o->load();
+ $resultList[$objectid] = array();
+ $resultList[$objectid]['url'] = Html::url($o->getType(),'',$objectid);
+ $resultList[$objectid]['type'] = $o->getType();
+ $resultList[$objectid]['name'] = $o->name;
+ $resultList[$objectid]['lastchange_date'] = $o->lastchangeDate;
+
+ if ( $o->desc != '' )
+ $resultList[$objectid]['desc'] = $o->desc;
+ else
+ $resultList[$objectid]['desc'] = lang('NO_DESCRIPTION_AVAILABLE');
+ }
+ }
+
+ $this->setTemplateVar( 'history',$resultList );
+ }
+}
+
?>
\ No newline at end of file
diff --git a/modules/configuration/Configuration.class.php b/modules/configuration/Configuration.class.php
@@ -78,6 +78,11 @@ class Config
}
+ /**
+ * @param $name
+ * @param null $default
+ * @return mixed|null
+ */
public function get( $name, $default = null )
{
if ( isset( $this->config[ $name ] ) )
@@ -96,6 +101,21 @@ class Config
}
+ /**
+ * @param $name
+ * @return bool
+ */
+ public function has( $name )
+ {
+ return isset( $this->config[ $name ] );
+ }
+
+
+ /**
+ * @param $name
+ * @param bool $default
+ * @return bool
+ */
public function is( $name, $default = false )
{
if ( isset( $this->config[ $name ] ) )
@@ -105,4 +125,13 @@ class Config
}
+ /**
+ * @return array
+ */
+ public function getConfig() {
+
+ return $this->config;
+ }
+
+
}
\ No newline at end of file
diff --git a/modules/configuration/ConfigurationLoader.class.php b/modules/configuration/ConfigurationLoader.class.php
@@ -86,7 +86,7 @@ class ConfigurationLoader
// Load include files.
foreach ($customConfig['include'] as $key => $file) {
- if ( $file[0] == '/')
+ if ( $file[0] == '/') // File begins with '?'
; // File has an absolute path - do not change.
else
// Prepend file path with our config directory.
diff --git a/modules/database/Database.class.php b/modules/database/Database.class.php
@@ -1,231 +1,224 @@
-<?php
-// OpenRat Content Management System
-// Copyright (C) 2002-2006 Jan Dankert, jandankert@jandankert.de
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-namespace database;
-use database\driver\PDODriver;
-use Logger;
-use RuntimeException;
-
-/**
- * Darstellung einer Datenbank-Verbindung.
- *
- * Fuer die echten DB-Aufrufe werden die entsprechenden
- * Methoden des passenden Clients aufgerufen.
- *
- * Diese Klasse stammt urspruenglich aus dem PHP-Pear-DB-Projekt, wurde hier aber intensiv veraendert.
- *
- * @author Jan Dankert
- * @package openrat.database
- */
-class Database
-{
- /**
- * Datenbank-Id.
- *
- * @var String
- */
- var $id;
-
- /**
- * Konfiguration der Datenbank-Verbindung
- *
- * @var array
- */
- var $conf;
-
- /**
- * Kennzeichen, ob die Datenbank verf�gbar ist.
- *
- * @var Boolean
- */
- var $available;
-
- /**
- * Enth�lt eine Fehlermeldung (sofern verf�gbar).
- *
- * @var String
- */
- var $error;
-
- /**
- * Client.
- *
- * @var PDODriver
- */
- var $client;
-
- /**
- * Schalter, ob eine Transaktion begonnen wurde.
- * @var boolean
- */
- var $transactionInProgress = false;
-
-
- /**
- * Kontruktor.
- * Erwartet die Datenbank-Konfiguration als Parameter.
- *
- * @param array Konfiguration der Verbindung
- * @param boolean admin Wenn es eine Admin-DB-Verbindung werden soll, die auch DDL ausfuehren darf
- */
- public function __construct( $dbconf,$admin=false )
- {
- global $conf;
-
- $this->conf = $dbconf + $conf['database-default']['defaults']; // linksstehender Operator hat Priorität!
-
- if ( $admin )
- {
- // Bevorzugung der Unter-Konfiguration 'update'
- if ( isset($this->conf['update']) )
- $this->conf = $this->conf['update'] + $this->conf; // linksstehender Operator hat Priorität!
- }
-
- $this->connect();
- }
-
-
- /**
- * Verbindung zur Datenbank aufbauen.
- *
- * @return bool Status
- */
- public function connect()
- {
- // Ausfuehren des Systemkommandos vor Verbindungsaufbau
- if (!empty($this->conf['cmd']))
- $this->executeSystemCommand( $this->conf['cmd'] );
-
- // Client instanziieren
- $this->client = new PDODriver();
-
- // Verbindung aufbauen
- $this->client->connect( $this->conf );
-
- // SQL nach Verbindungsaufbau ausfuehren.
- if ( ! empty($this->conf['connection_sql']) )
- {
- $cmd = $this->conf['connection_sql'];
-
- $stmt = $this->sql($cmd);
-
- $ok = $stmt->execute();
-
- if ( ! $ok )
- {
- throw new RuntimeException( "Could not execute connection-query '".$cmd."'");
- }
- }
-
- // Setting isolation level to "read committed".
- // if another session is committing data, we want to read that immediatly
- if ( $this->conf['persistent'])
- {
-// $sql = $this->sql('ROLLBACK');
-// $sql->execute();
-// $sql = $this->sql('SET TRANSACTION ISOLATION LEVEL READ COMMITTED');
-// $sql->execute();
- }
-
-
- Logger::debug('Database connection established');
-
- $this->available = true;
- }
-
- /**
- * Startet eine Transaktion.
- * Falls der Schalter 'transaction' nicht gesetzt ist, passiert nichts.
- */
- public function start()
- {
- Logger::debug("Starting database transaction!");
- $this->transactionInProgress = true;
- $this->client->start();
- }
-
-
- /**
- * Beendet und bestaetigt eine Transaktion.
- * Falls der Schalter 'transaction' nicht gesetzt ist, passiert nichts.
- */
- public function commit()
- {
- if ( $this->transactionInProgress )
- {
- Logger::debug("Committing database transaction!");
- $this->client->commit();
- $this->transactionInProgress = false;
- } else {
- Logger::warn("No Transaction in progress, ignoring commit request.");
- }
- }
-
-
-
- /**
- * Setzt eine Transaktion zurueck.
- * Falls der Schalter 'transaction' nicht gesetzt ist, passiert nichts.
- */
- public function rollback()
- {
- if ( $this->transactionInProgress )
- {
- Logger::debug("Rolling back database transaction!");
- $this->client->rollback();
- $this->transactionInProgress = false;
- } else {
- Logger::warn("No Transaction in progress, ignoring rollback request.");
- }
- }
-
-
- public function disconnect()
- {
- $this->client->disconnect();
- }
- /**
- * @param $sql string das SQL
- * @return Statement
- */
- public function sql($sql )
- {
- return new Statement( $sql,$this->client,$this->conf);
- }
-
-
- private function executeSystemCommand( $cmd )
- {
- $ausgabe = array();
- $rc = false;
-
- Logger::debug("Database command executing: " . $this->conf['cmd']);
- exec($cmd, $ausgabe, $rc);
-
- foreach ($ausgabe as $zeile)
- Logger::debug("Database command output: " . $zeile);
-
- if ($rc != 0) {
- throw new RuntimeException('Command failed: ' . implode("", $ausgabe));
- }
- }
-
-}
-
-
+<?php
+// OpenRat Content Management System
+// Copyright (C) 2002-2006 Jan Dankert, jandankert@jandankert.de
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+namespace database;
+use database\driver\PDODriver;
+use Logger;
+use RuntimeException;
+
+/**
+ * Darstellung einer Datenbank-Verbindung.
+ *
+ * Fuer die echten DB-Aufrufe werden die entsprechenden
+ * Methoden des passenden Clients aufgerufen.
+ *
+ * Diese Klasse stammt urspruenglich aus dem PHP-Pear-DB-Projekt, wurde hier aber intensiv veraendert.
+ *
+ * @author Jan Dankert
+ * @package openrat.database
+ */
+class Database
+{
+ /**
+ * Datenbank-Id.
+ *
+ * @var String
+ */
+ var $id;
+
+ /**
+ * Konfiguration der Datenbank-Verbindung
+ *
+ * @var array
+ */
+ var $conf;
+
+ /**
+ * Kennzeichen, ob die Datenbank verf�gbar ist.
+ *
+ * @var Boolean
+ */
+ var $available;
+
+ /**
+ * Enth�lt eine Fehlermeldung (sofern verf�gbar).
+ *
+ * @var String
+ */
+ var $error;
+
+ /**
+ * Client.
+ *
+ * @var PDODriver
+ */
+ var $client;
+
+ /**
+ * Schalter, ob eine Transaktion begonnen wurde.
+ * @var boolean
+ */
+ var $transactionInProgress = false;
+
+
+ /**
+ * Kontruktor.
+ * Erwartet die Datenbank-Konfiguration als Parameter.
+ *
+ * @param array Konfiguration der Verbindung
+ * @param boolean admin Wenn es eine Admin-DB-Verbindung werden soll, die auch DDL ausfuehren darf
+ */
+ public function __construct( $dbconf )
+ {
+ global $conf;
+
+ $this->conf = $dbconf + $conf['database-default']['defaults']; // linksstehender Operator hat Priorität!
+
+ $this->connect();
+ }
+
+
+ /**
+ * Verbindung zur Datenbank aufbauen.
+ *
+ * @return bool Status
+ */
+ public function connect()
+ {
+ // Ausfuehren des Systemkommandos vor Verbindungsaufbau
+ if (!empty($this->conf['cmd']))
+ $this->executeSystemCommand( $this->conf['cmd'] );
+
+ // Client instanziieren
+ $this->client = new PDODriver();
+
+ // Verbindung aufbauen
+ $this->client->connect( $this->conf );
+
+ // SQL nach Verbindungsaufbau ausfuehren.
+ if ( ! empty($this->conf['connection_sql']) )
+ {
+ $cmd = $this->conf['connection_sql'];
+
+ $stmt = $this->sql($cmd);
+
+ $ok = $stmt->execute();
+
+ if ( ! $ok )
+ {
+ throw new RuntimeException( "Could not execute connection-query '".$cmd."'");
+ }
+ }
+
+ // Setting isolation level to "read committed".
+ // if another session is committing data, we want to read that immediatly
+ if ( $this->conf['persistent'])
+ {
+// $sql = $this->sql('ROLLBACK');
+// $sql->execute();
+// $sql = $this->sql('SET TRANSACTION ISOLATION LEVEL READ COMMITTED');
+// $sql->execute();
+ }
+
+
+ Logger::debug('Database connection established');
+
+ $this->available = true;
+ }
+
+ /**
+ * Startet eine Transaktion.
+ * Falls der Schalter 'transaction' nicht gesetzt ist, passiert nichts.
+ */
+ public function start()
+ {
+ Logger::debug("Starting database transaction!");
+ $this->transactionInProgress = true;
+ $this->client->start();
+ }
+
+
+ /**
+ * Beendet und bestaetigt eine Transaktion.
+ * Falls der Schalter 'transaction' nicht gesetzt ist, passiert nichts.
+ */
+ public function commit()
+ {
+ if ( $this->transactionInProgress )
+ {
+ Logger::debug("Committing database transaction!");
+ $this->client->commit();
+ $this->transactionInProgress = false;
+ } else {
+ Logger::warn("No Transaction in progress, ignoring commit request.");
+ }
+ }
+
+
+
+ /**
+ * Setzt eine Transaktion zurueck.
+ * Falls der Schalter 'transaction' nicht gesetzt ist, passiert nichts.
+ */
+ public function rollback()
+ {
+ if ( $this->transactionInProgress )
+ {
+ Logger::debug("Rolling back database transaction!");
+ $this->client->rollback();
+ $this->transactionInProgress = false;
+ } else {
+ Logger::warn("No Transaction in progress, ignoring rollback request.");
+ }
+ }
+
+
+ public function disconnect()
+ {
+ $this->client->disconnect();
+ }
+ /**
+ * @param $sql string das SQL
+ * @return Statement
+ */
+ public function sql($sql )
+ {
+ return new Statement( $sql,$this->client,$this->conf);
+ }
+
+
+ private function executeSystemCommand( $cmd )
+ {
+ $ausgabe = array();
+ $rc = false;
+
+ Logger::debug("Database command executing: " . $this->conf['cmd']);
+ exec($cmd, $ausgabe, $rc);
+
+ foreach ($ausgabe as $zeile)
+ Logger::debug("Database command output: " . $zeile);
+
+ if ($rc != 0) {
+ throw new RuntimeException('Command failed: ' . implode("", $ausgabe));
+ }
+ }
+
+}
+
+
?>
\ No newline at end of file
diff --git a/modules/util/Http.class.php b/modules/util/Http.class.php
@@ -426,7 +426,7 @@ class Http
{
if ( class_exists('Session'))
{
- $db = Session::getDatabase();
+ $db = db();
if ( is_object( $db ) )
$db->rollback();
}
diff --git a/modules/util/Session.class.php b/modules/util/Session.class.php
@@ -21,12 +21,18 @@ use cms\model\User;
class Session
{
+ const KEY_DBID = 'dbid';
+ const KEY_DB = 'database';
+ const KEY_USER = 'userObject';
+ const KEY_CONFIG = 'config';
+ const PRAEFIX = 'ors_';
+
public static function get( $var )
{
$SESS = &$_SESSION;
- if ( isset($SESS['ors_'.$var]) )
- return $SESS['ors_'.$var];
+ if ( isset($SESS[self::PRAEFIX.$var]) )
+ return $SESS[self::PRAEFIX.$var];
else
return '';
}
@@ -34,7 +40,7 @@ class Session
public static function set( $var,$value )
{
$SESS = &$_SESSION;
- $SESS[ 'ors_'.$var ] = $value;
+ $SESS[ self::PRAEFIX.$var ] = $value;
}
@@ -43,12 +49,12 @@ class Session
*/
public static function getConfig()
{
- return Session::get('config');
+ return Session::get(self::KEY_CONFIG);
}
public static function setConfig( $var )
{
- Session::set('config',$var);
+ Session::set(self::KEY_CONFIG,$var);
}
@@ -59,12 +65,12 @@ class Session
*/
public static function getUser()
{
- return Session::get('userObject');
+ return Session::get(self::KEY_USER);
}
public static function setUser( $var )
{
- Session::set('userObject',$var);
+ Session::set(self::KEY_USER,$var);
}
@@ -73,12 +79,26 @@ class Session
*/
public static function getDatabase()
{
- return Session::get('database');
+ return Session::get(self::KEY_DB);
}
public static function setDatabase( $var )
{
- Session::set('database',$var);
+ Session::set(self::KEY_DB,$var);
+ }
+
+
+ /**
+ * @return String DB-Id
+ */
+ public static function getDatabaseId()
+ {
+ return Session::get(self::KEY_DBID);
+ }
+
+ public static function setDatabaseId( $var )
+ {
+ Session::set(self::KEY_DBID,$var);
}
@@ -86,7 +106,7 @@ class Session
* Schliesst die aktuelle Session
*
* Diese Funktion sollte so schnell wie moeglich aufgerufen werden, da vorher
- * keine andere Seite (im Frameset!) geladen werden kann
+ * keine andere Seite (im Frameset oder parallele AJAX-Requests) geladen werden kann
* Nach Aufruf dieser Methode sind keine Session-Zugriffe ueber diese Klasse mehr
* moeglich.
*/
diff --git a/modules/util/config-default.php b/modules/util/config-default.php
@@ -733,8 +733,6 @@ function createDefaultConfig()
$conf['security']['disable_dynamic_code']=true;
$conf['security']['show_system_info']=true;
$conf['security']['use_post_token']=true;
- $conf['security']['renew_session_login']=false;
- $conf['security']['renew_session_logout']=false;
$conf['security']['default'] = array();
$conf['security']['default']['username']='';
$conf['security']['default']['password']='';