From: Roland Häder <roland@mxchange.org>
Date: Thu, 19 Jun 2008 13:49:05 +0000 (+0000)
Subject: Update of last activitity and action in user added, refresh of auth cookies added
X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=8cfd068024443570a0f324e4271637537cff2d88;p=shipsimu.git

Update of last activitity and action in user added, refresh of auth cookies added
---

diff --git a/.gitattributes b/.gitattributes
index 0ff33d2..3fe37b7 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -230,6 +230,7 @@ inc/classes/exceptions/main/class_ResponseHeadersAlreadySentException.php -text
 inc/classes/exceptions/main/class_VariableIsNotSetException.php -text
 inc/classes/exceptions/result/.htaccess -text
 inc/classes/exceptions/result/class_InvalidDatabaseResultException.php -text
+inc/classes/exceptions/result/class_ResultUpdateException.php -text
 inc/classes/exceptions/template/.htaccess -text
 inc/classes/exceptions/template/class_BasePathIsEmptyException.php -text
 inc/classes/exceptions/template/class_BasePathIsNoDirectoryException.php -text
@@ -262,6 +263,7 @@ inc/classes/interfaces/criteria/.htaccess -text
 inc/classes/interfaces/criteria/class_Criteria.php -text
 inc/classes/interfaces/criteria/extended/.htaccess -text
 inc/classes/interfaces/criteria/extended/class_LocalSearchCriteria.php -text
+inc/classes/interfaces/criteria/extended/class_LocalUpdateCriteria.php -text
 inc/classes/interfaces/criteria/extended/class_StoreableCriteria.php -text
 inc/classes/interfaces/database/.htaccess -text
 inc/classes/interfaces/database/class_FrameworkDatabaseInterface.php -text
@@ -304,6 +306,7 @@ inc/classes/interfaces/response/.htaccess -text
 inc/classes/interfaces/response/class_Responseable.php -text
 inc/classes/interfaces/result/.htaccess -text
 inc/classes/interfaces/result/class_SearchableResult.php -text
+inc/classes/interfaces/result/class_UpdateableResult.php -text
 inc/classes/interfaces/template/.htaccess -text
 inc/classes/interfaces/template/class_CompileableTemplate.php -text
 inc/classes/interfaces/template/view/class_ViewHelper.php -text
@@ -353,6 +356,7 @@ inc/classes/main/controller/login/class_WebLoginAreaController.php -text
 inc/classes/main/criteria/.htaccess -text
 inc/classes/main/criteria/class_DataSetCriteria.php -text
 inc/classes/main/criteria/class_SearchCriteria.php -text
+inc/classes/main/criteria/class_UpdateCriteria.php -text
 inc/classes/main/crypto/.htaccess -text
 inc/classes/main/crypto/class_CryptoHelper.php -text
 inc/classes/main/database/.htaccess -text
diff --git a/inc/classes/exceptions/result/class_ResultUpdateException.php b/inc/classes/exceptions/result/class_ResultUpdateException.php
new file mode 100644
index 0000000..bbebeb5
--- /dev/null
+++ b/inc/classes/exceptions/result/class_ResultUpdateException.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * An exception thrown if the result was not updated
+ *
+ * @author		Roland Haeder <webmaster@ship-simu.org>
+ * @version		0.0.0
+ * @copyright	Copyright(c) 2007, 2008 Roland Haeder, this is free software
+ * @license		GNU GPL 3.0 or any newer version
+ * @link		http://www.ship-simu.org
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+class ResultUpdateException extends FrameworkException {
+	/**
+	 * The super constructor for all exceptions
+	 *
+	 * @param		$resultInstance		Instance of the failed result update
+	 * @param		$code		Error code
+	 * @return	void
+	 */
+	public function __construct(UpdateableResult $resultInstance, $code) {
+		// Construct the message
+		$message = sprintf("[%s:%d] Update of result instance has nothing changed.",
+			$resultInstance->__toString(),
+			$this->getLine()
+		);
+
+		// Call parent exception constructor
+		parent::__construct($message, $code);
+	}
+}
+
+// [EOF]
+?>
diff --git a/inc/classes/interfaces/auth/class_Authorizeable.php b/inc/classes/interfaces/auth/class_Authorizeable.php
index 88e383f..0ca700b 100644
--- a/inc/classes/interfaces/auth/class_Authorizeable.php
+++ b/inc/classes/interfaces/auth/class_Authorizeable.php
@@ -28,6 +28,13 @@ interface Authorizeable extends FrameworkInterface {
 	 * @return	void
 	 */
 	function destroyAuthData();
+
+	/**
+	 * Updates the authorization data and/or sets additional tracking data
+	 *
+	 * @return	void
+	 */
+	function updateAuthData ();
 }
 
 //
diff --git a/inc/classes/interfaces/criteria/extended/class_LocalUpdateCriteria.php b/inc/classes/interfaces/criteria/extended/class_LocalUpdateCriteria.php
new file mode 100644
index 0000000..17956a8
--- /dev/null
+++ b/inc/classes/interfaces/criteria/extended/class_LocalUpdateCriteria.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * An interface for local criterias
+ *
+ * @author		Roland Haeder <webmaster@ship-simu.org>
+ * @version		0.0.0
+ * @copyright	Copyright(c) 2007, 2008 Roland Haeder, this is free software
+ * @license		GNU GPL 3.0 or any newer version
+ * @link		http://www.ship-simu.org
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+interface LocalUpdateCriteria extends Criteria {
+}
+
+//
+?>
diff --git a/inc/classes/interfaces/database/frontend/class_DatabaseFrontendInterface.php b/inc/classes/interfaces/database/frontend/class_DatabaseFrontendInterface.php
index 7621713..81ca81d 100644
--- a/inc/classes/interfaces/database/frontend/class_DatabaseFrontendInterface.php
+++ b/inc/classes/interfaces/database/frontend/class_DatabaseFrontendInterface.php
@@ -66,6 +66,15 @@ interface DatabaseFrontendInterface extends FrameworkDatabaseInterface {
 	 * @throws	SqlException	If an SQL error occurs
 	 */
 	function queryInsertDataSet (StoreableCriteria $dataSetInstance);
+
+	/**
+	 * "Updates" a data set instance with a database layer
+	 *
+	 * @param	$dataSetInstance	A storeable data set
+	 * @return	void
+	 * @throws	SqlException	If an SQL error occurs
+	 */
+	function queryUpdateDataSet (StoreableCriteria $dataSetInstance);
 }
 
 // [EOF]
diff --git a/inc/classes/interfaces/response/class_Responseable.php b/inc/classes/interfaces/response/class_Responseable.php
index 1904b14..6186d71 100644
--- a/inc/classes/interfaces/response/class_Responseable.php
+++ b/inc/classes/interfaces/response/class_Responseable.php
@@ -95,6 +95,14 @@ interface Responseable extends FrameworkInterface {
 	 * @return	void
 	 */
 	function expireCookie ($cookieName);
+
+	/**
+	 * Refreshs a given cookie. This will make the cookie live longer
+	 *
+	 * @param	$cookieName		Cookie to refresh
+	 * @return	void
+	 */
+	function refreshCookie ($cookieName);
 }
 
 //
diff --git a/inc/classes/interfaces/result/class_UpdateableResult.php b/inc/classes/interfaces/result/class_UpdateableResult.php
new file mode 100644
index 0000000..05a3968
--- /dev/null
+++ b/inc/classes/interfaces/result/class_UpdateableResult.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * An interface for searchable results
+ *
+ * @author		Roland Haeder <webmaster@ship-simu.org>
+ * @version		0.0.0
+ * @copyright	Copyright(c) 2007, 2008 Roland Haeder, this is free software
+ * @license		GNU GPL 3.0 or any newer version
+ * @link		http://www.ship-simu.org
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+interface UpdateableResult extends FrameworkInterface {
+	/**
+	 * Adds an update request to the database result for writing it to the
+	 * database layer
+	 *
+	 * @param	$criteriaInstance	An instance of a updateable criteria
+	 * @return	void
+	 * @throws	ResultUpdateException	If no result was updated
+	 */
+	function add2UpdateQueue (LocalUpdateCriteria $criteriaInstance);
+
+	/**
+	 * Adds registration elements to a given dataset instance
+	 *
+	 * @param	$criteriaInstance	An instance of a storeable criteria
+	 * @return	void
+	 */
+	function addElementsToDataSet (StoreableCriteria $criteriaInstance);
+}
+
+// [EOF]
+?>
diff --git a/inc/classes/main/auth/class_CookieAuth.php b/inc/classes/main/auth/class_CookieAuth.php
index 6b1bf3f..881d0d1 100644
--- a/inc/classes/main/auth/class_CookieAuth.php
+++ b/inc/classes/main/auth/class_CookieAuth.php
@@ -115,6 +115,17 @@ class CookieAuth extends BaseFrameworkSystem implements Authorizeable, Registera
 		$this->getResponseInstance()->expireCookie('username');
 		$this->getResponseInstance()->expireCookie('u_hash');
 	}
+
+	/**
+	 * Updates the authorization data and/or sets additional tracking data
+	 *
+	 * @param	$requestInstance	An instance of a Requestable class
+	 * @return	void
+	 */
+	public function updateAuthData () {
+		$this->getResponseInstance()->refreshCookie('username');
+		$this->getResponseInstance()->refreshCookie('u_hash');
+	}
 }
 
 // [EOF]
diff --git a/inc/classes/main/class_BaseFrameworkSystem.php b/inc/classes/main/class_BaseFrameworkSystem.php
index 3484a4e..ade2a9c 100644
--- a/inc/classes/main/class_BaseFrameworkSystem.php
+++ b/inc/classes/main/class_BaseFrameworkSystem.php
@@ -32,6 +32,7 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
 	 * The language instance for the template loader
 	 */
 	private static $langInstance = null;
+
 	/**
 	 * Instance of a request class
 	 */
@@ -42,6 +43,11 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
 	 */
 	private $responseInstance = null;
 
+	/**
+	 * Search criteria instance
+	 */
+	private $searchInstance = null;
+
 	/**
 	 * The real class name
 	 */
@@ -961,6 +967,25 @@ class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
 		print "</pre>";
 		exit;
 	}
+
+	/**
+	 * Setter for search instance
+	 *
+	 * @param	$searchInstance		Searchable criteria instance
+	 * @return	void
+	 */
+	public final function setSearchInstance (LocalSearchCriteria $searchInstance) {
+		$this->searchInstance = $searchInstance;
+	}
+
+	/**
+	 * Getter for search instance
+	 *
+	 * @return	$searchInstance		Searchable criteria instance
+	 */
+	public final function getSearchInstance () {
+		return $this->searchInstance;
+	}
 }
 
 // [EOF]
diff --git a/inc/classes/main/criteria/class_SearchCriteria.php b/inc/classes/main/criteria/class_SearchCriteria.php
index fc5b1ad..f6d7378 100644
--- a/inc/classes/main/criteria/class_SearchCriteria.php
+++ b/inc/classes/main/criteria/class_SearchCriteria.php
@@ -109,7 +109,6 @@ class SearchCriteria extends BaseFrameworkSystem implements LocalSearchCriteria
 	/**
 	 * Getter for limit
 	 *
-	 * @param	
 	 * @return	$limit	Search limit
 	 */
 	public final function getLimit () {
@@ -129,7 +128,6 @@ class SearchCriteria extends BaseFrameworkSystem implements LocalSearchCriteria
 	/**
 	 * Getter for skip
 	 *
-	 * @param	
 	 * @return	$skip	Search skip
 	 */
 	public final function getSkip () {
@@ -183,6 +181,36 @@ class SearchCriteria extends BaseFrameworkSystem implements LocalSearchCriteria
 		// Return the value
 		return $value;
 	}
+
+	/**
+	 * Checks wether given array entry matches
+	 *
+	 * @param	$entryArray		Array with the entries to find
+	 * @return	$matches		Wether the entry matches or not
+	 */
+	public function ifEntryMatches (array $entryArray) {
+		// First nothing matches and nothing is counted
+		$matches = false;
+		$counted = 0;
+
+		// Walk through all entries
+		foreach ($entryArray as $key=>$entry) {
+			// Then walk through all search criteria
+			foreach ($this->searchCriteria as $criteriaKey=>$criteriaValue) {
+				// Is the element found and does it match?
+				if (($key == $criteriaKey) && ($criteriaValue == $entry)) {
+					// Then count this one up
+					$counted++;
+				} // END - if
+			} // END - foreach
+		} // END - foreach
+
+		// Now check if the criteria matches
+		$matches = ($counted == count($this->searchCriteria));
+
+		// Return the result
+		return $matches;
+	}
 }
 
 // [EOF]
diff --git a/inc/classes/main/criteria/class_UpdateCriteria.php b/inc/classes/main/criteria/class_UpdateCriteria.php
new file mode 100644
index 0000000..c53f687
--- /dev/null
+++ b/inc/classes/main/criteria/class_UpdateCriteria.php
@@ -0,0 +1,110 @@
+<?php
+/**
+ * Search criteria for e.g. searching in databases. Do not use this class if
+ * you are looking for a ship or company, or what ever. Instead use this class
+ * for looking in storages like the database.
+ *
+ * @author		Roland Haeder <webmaster@ship-simu.org>
+ * @version		0.0.0
+ * @copyright	Copyright(c) 2007, 2008 Roland Haeder, this is free software
+ * @license		GNU GPL 3.0 or any newer version
+ * @link		http://www.ship-simu.org
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+class UpdateCriteria extends BaseFrameworkSystem implements LocalUpdateCriteria {
+	/**
+	 * Criteria to handle
+	 */
+	private $updateCriteria = array();
+
+	/**
+	 * Limitation for the update
+	 */
+	private $limit = 0;
+
+	/**
+	 * Skip these entries before using them
+	 */
+	private $skip = 0;
+
+	/**
+	 * Protected constructor
+	 *
+	 * @return	void
+	 */
+	protected function __construct () {
+		// Call parent constructor
+		parent::__construct(__CLASS__);
+
+		// Set part description
+		$this->setObjectDescription("Update criteria class");
+
+		// Create unique ID number
+		$this->generateUniqueId();
+
+		// Clean up a little
+		$this->removeNumberFormaters();
+		$this->removeSystemArray();
+	}
+
+	/**
+	 * Create an instance of this class
+	 *
+	 * @return	$criteriaInstance	An instance of this criteria
+	 */
+	public final static function createUpdateCriteria () {
+		// Get a new instance
+		$criteriaInstance = new UpdateCriteria();
+
+		// Return this instance
+		return $criteriaInstance;
+	}
+
+	/**
+	 * Add criteria
+	 *
+	 * @param	$criteriaKey	Criteria key
+	 * @param	$criteriaValue	Criteria value
+	 * @return	void
+	 */
+	public function addCriteria ($criteriaKey, $criteriaValue) {
+		$this->updateCriteria[$criteriaKey] = $criteriaValue;
+	}
+
+	/**
+	 * Add configured criteria
+	 *
+	 * @param	$criteriaKey	Criteria key
+	 * @param	$configEntry	Configuration entry
+	 * @return	void
+	 */
+	public function addConfiguredCriteria ($criteriaKey, $configEntry) {
+		// Add the configuration entry as a criteria
+		$value = $this->getConfigInstance()->readConfig($configEntry);
+		$this->addCriteria($criteriaKey, $value);
+	}
+
+	/**
+	 * Getter for update criteria array
+	 *
+	 * @return	$updateCriteria		Array holding the update criteria
+	 */
+	public final function getUpdateCriteria () {
+		return $this->updateCriteria;
+	}
+}
+
+// [EOF]
+?>
diff --git a/inc/classes/main/crypto/class_CryptoHelper.php b/inc/classes/main/crypto/class_CryptoHelper.php
index 93502cb..182d870 100644
--- a/inc/classes/main/crypto/class_CryptoHelper.php
+++ b/inc/classes/main/crypto/class_CryptoHelper.php
@@ -142,10 +142,10 @@ class CryptoHelper extends BaseFrameworkSystem {
 		}
 
 		// Hash the password with salt
-		//* DEBUG: */ echo $salt."/".$plainPassword."/".$this->rngInstance->getExtraSalt()."<br />\n";
+		//* DEBUG: */ echo "salt=".$salt."/plain=".$plainPassword."<br />\n";
 		$hashed = $salt . md5(sprintf($this->getConfigInstance()->readConfig('hash_mask'),
 			$salt,
-			$this->rngInstance->getExtraSalt(),
+			$this->rngInstance->getFixedSalt(),
 			$plainPassword
 		));
 
diff --git a/inc/classes/main/database/databases/class_LocalFileDatabase.php b/inc/classes/main/database/databases/class_LocalFileDatabase.php
index 610843a..27ba98e 100644
--- a/inc/classes/main/database/databases/class_LocalFileDatabase.php
+++ b/inc/classes/main/database/databases/class_LocalFileDatabase.php
@@ -28,6 +28,7 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend
 	// Constants for MySQL backward-compatiblity (PLEASE FIX THEM!)
 	const DB_CODE_TABLE_MISSING     = 0x010;
 	const DB_CODE_TABLE_UNWRITEABLE = 0x011;
+	const DB_CODE_DATA_FILE_CORRUPT = 0x012;
 
 	/**
 	 * Save path for "file database"
@@ -155,6 +156,7 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend
 	 *
 	 * @param	$object					The object we shall save to the local file system
 	 * @return	void
+	 * @deprecated
 	 */
 	public final function saveObject (FrameworkInterface $object) {
 		// Get a string containing the serialized object. We cannot exchange
@@ -179,6 +181,7 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend
 	 * @see		ObjectLimits	An object holding limition information
 	 * @see		SerializationContainer	A special container class for e.g.
 	 *									attributes from limited objects
+	 * @deprecated
 	 */
 	private function serializeObject (FrameworkInterface $object) {
 		// If there is no limiter instance we serialize the whole object
@@ -473,6 +476,54 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend
 		return $contents;
 	}
 
+	/**
+	 * Reads a local data file  and returns it's contents in an array
+	 *
+	 * @param	$fqfn	The FQFN for the requested file
+	 * @return	$dataArray
+	 */
+	private function getDataArrayFromFile ($fqfn) {
+		// Get a file pointer
+		$fileInstance = FrameworkFileInputPointer::createFrameworkFileInputPointer($fqfn);
+
+		// Get the raw data and BASE64-decode it
+		$compressedData = base64_decode($fileInstance->readLinesFromFile());
+
+		// Close the file and throw the instance away
+		$fileInstance->closeFile();
+		unset($fileInstance);
+
+		// Decompress it
+		$serializedData = $this->getCompressorChannel()->getCompressor()->decompressStream($compressedData);
+
+		// Unserialize it
+		$dataArray = unserialize($serializedData);
+
+		// Finally return it
+		return $dataArray;
+	}
+
+	/**
+	 * Writes data array to local file
+	 *
+	 * @param	$fqfn		The FQFN of the local file
+	 * @param	$dataArray	An array with all the data we shall write
+	 * @return	void
+	 */
+	private function writeDataArrayToFqfn ($fqfn, array $dataArray) {
+		// Get a file pointer instance
+		$fileInstance = FrameworkFileOutputPointer::createFrameworkFileOutputPointer($fqfn, 'w');
+
+		// Serialize and compress it
+		$compressedData = $this->getCompressorChannel()->getCompressor()->compressStream(serialize($dataArray));
+
+		// Write this data BASE64 encoded to the file
+		$fileInstance->writeToFile(base64_encode($compressedData));
+
+		// Close the file pointer
+		$fileInstance->closeFile();
+	}
+
 	/**
 	 * Makes sure that the database connection is alive
 	 *
@@ -559,21 +610,8 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend
 
 			// Read the directory with some exceptions
 			while (($dataFile = $directoryInstance->readDirectoryExcept(array(".", "..", ".htaccess", ".svn"))) && ($limitFound < $criteriaInstance->getLimit())) {
-				// Open this file for reading
-				$filePointer = FrameworkFileInputPointer::createFrameworkFileInputPointer($pathName . $dataFile);
-
-				// Get the raw data and BASE64-decode it
-				$compressedData = base64_decode($filePointer->readLinesFromFile());
-
-				// Close the file and throw the instance away
-				$filePointer->closeFile();
-				unset($filePointer);
-
-				// Decompress it
-				$serializedData = $this->getCompressorChannel()->getCompressor()->decompressStream($compressedData);
-
-				// Unserialize it
-				$dataArray = unserialize($serializedData);
+				// Read the file
+				$dataArray = $this->getDataArrayFromFile($pathName . $dataFile);
 
 				// Is this an array?
 				if (is_array($dataArray)) {
@@ -596,12 +634,15 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend
 							} // END - if
 
 							// Entry found!
-							$resultData['rows'][]	 = $dataArray;
+							$resultData['rows'][] = $dataArray;
 							$limitFound++;
 							break;
 						} // END - if
 					} // END - foreach
-				} // END - if
+				} else {
+					// Throw an exception here
+					throw new SqlException(sprintf("File &#39;%s&#39; contains invalid data.", $dataFile), self::DB_CODE_DATA_FILE_CORRUPT);
+				}
 			} // END - while
 
 			// Close directory and throw the instance away
@@ -644,21 +685,90 @@ class LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontend
 		);
 
 		// Try to save the request away
+		try {
+			// Write the data away
+			$this->writeDataArrayToFqfn($fqfn, $dataSetInstance->getCriteriaArray());
+
+			// Reset last error message and exception
+			$this->resetLastError();
+		} catch (FrameworkException $e) {
+			// Catch all exceptions and store them in last error
+			$this->lastException = $e;
+			$this->lastError = $e->getMessage();
+
+			// Throw an SQL exception
+			throw new SqlException (array($this, sprintf("Cannot write data to table &#39;%s&#39;", $tableName), self::DB_CODE_TABLE_UNWRITEABLE), self::EXCEPTION_SQL_QUERY);
+		}
+	}
+
+	/**
+	 * "Updates" a data set instance with a database layer
+	 *
+	 * @param	$dataSetInstance	A storeable data set
+	 * @return	void
+	 * @throws	SqlException	If an SQL error occurs
+	 */
+	public function queryUpdateDataSet (StoreableCriteria $dataSetInstance) {
+		// Create full path name
+		$pathName = $this->getSavePath() . $dataSetInstance->getTableName() . '/';
+
+		// Try all the requests
 		try {
 			// Get a file pointer instance
-			$filePointer = FrameworkFileOutputPointer::createFrameworkFileOutputPointer($fqfn, 'w');
+			$directoryInstance = FrameworkDirectoryPointer::createFrameworkDirectoryPointer($pathName);
+
+			// Initialize limit/skip
+			$limitFound = 0; $skipFound = 0;
 
 			// Get the criteria array from the dataset
 			$criteriaArray = $dataSetInstance->getCriteriaArray();
 
-			// Serialize and compress it
-			$compressedData = $this->getCompressorChannel()->getCompressor()->compressStream(serialize($criteriaArray));
+			// Get search criteria
+			$searchInstance = $dataSetInstance->getSearchInstance();
+
+			// Read the directory with some exceptions
+			while (($dataFile = $directoryInstance->readDirectoryExcept(array(".", "..", ".htaccess", ".svn"))) && ($limitFound < $searchInstance->getLimit())) {
+				// Open this file for reading
+				$dataArray = $this->getDataArrayFromFile($pathName . $dataFile);
+
+				// Is this an array?
+				if (is_array($dataArray)) {
+					// Search in the criteria with FMFW (First Matches, First Wins)
+					foreach ($dataArray as $key=>$value) {
+						// Get criteria element
+						$criteria = $searchInstance->getCriteriaElemnent($key);
+
+						// Is the criteria met?
+						if ((!is_null($criteria)) && ($criteria == $value))  {
+
+							// Shall we skip this entry?
+							if ($searchInstance->getSkip() > 0) {
+								// We shall skip some entries
+								if ($skipFound < $searchInstance->getSkip()) {
+									// Skip this entry
+									$skipFound++;
+									break;
+								} // END - if
+							} // END - if
+
+							// Entry found, so update it
+							foreach ($criteriaArray as $criteriaKey=>$criteriaValue) {
+								$dataArray[$criteriaKey] = $criteriaValue;
+							} // END - foreach
+
+							// Write the data to a local file
+							$this->writeDataArrayToFqfn($pathName . $dataFile, $dataArray);
 
-			// Write this data BASE64 encoded to the file
-			$filePointer->writeToFile(base64_encode($compressedData));
+							// Count it
+							$limitFound++;
+							break;
+						} // END - if
+					} // END - foreach
+				} // END - if
+			} // END - while
 
 			// Close the file pointer
-			$filePointer->closeFile();
+			$directoryInstance->closeDirectory();
 
 			// Reset last error message and exception
 			$this->resetLastError();
diff --git a/inc/classes/main/database/wrapper/class_UserDatabaseWrapper.php b/inc/classes/main/database/wrapper/class_UserDatabaseWrapper.php
index 5fc62e2..e2ff935 100644
--- a/inc/classes/main/database/wrapper/class_UserDatabaseWrapper.php
+++ b/inc/classes/main/database/wrapper/class_UserDatabaseWrapper.php
@@ -141,6 +141,30 @@ class UserDatabaseWrapper extends BaseDatabaseWrapper {
 		// "Insert" this request instance completely into the database
 		$this->getDatabaseInstance()->queryInsertDataSet($dataSetInstance);
 	}
+
+	/**
+	 * Updates an user database entry with given result
+	 *
+	 * @param	$resultInstance		An instance of a Updateable database result
+	 * @return	void
+	 */
+	public function doUpdateByResult (UpdateableResult $resultInstance) {
+		// Generate a data set object
+		$dataSetInstance = ObjectFactory::createObjectByConfiguredName('dataset_criteria_class');
+		$dataSetInstance->setTableName(self::DB_TABLE_USER);
+
+		// Add all update criteria to the database set
+		$resultInstance->addElementsToDataSet($dataSetInstance);
+
+		// Add seach criteria
+		$dataSetInstance->setSearchInstance($resultInstance->getSearchInstance());
+
+		// Add the primary key
+		$dataSetInstance->setUniqueKey('username');
+
+		// "Update" this request with the database
+		$this->getDatabaseInstance()->queryUpdateDataSet($dataSetInstance);
+	}
 }
 
 // [EOF]
diff --git a/inc/classes/main/filter/update/class_UserUpdateFilter.php b/inc/classes/main/filter/update/class_UserUpdateFilter.php
index b8f598f..0da323c 100644
--- a/inc/classes/main/filter/update/class_UserUpdateFilter.php
+++ b/inc/classes/main/filter/update/class_UserUpdateFilter.php
@@ -68,9 +68,12 @@ class UserUpdateFilter extends BaseFrameworkSystem implements Filterable {
 		$userInstance = Registry::getRegistry()->getInstance('user');
 
 		// Now update last activity
-		$userInstance->updateLastActivity();
+		$userInstance->updateLastActivity($requestInstance);
 
 		// Update auth data as well
+		$authInstance = Registry::getRegistry()->getInstance('auth');
+		$authInstance->updateAuthData();
+
 		/* @TODO Add more user updates here */
 
 		// Write all updates to the database
diff --git a/inc/classes/main/response/class_HttpResponse.php b/inc/classes/main/response/class_HttpResponse.php
index 57e4eb7..7e78b43 100644
--- a/inc/classes/main/response/class_HttpResponse.php
+++ b/inc/classes/main/response/class_HttpResponse.php
@@ -345,6 +345,20 @@ class HttpResponse extends BaseFrameworkSystem implements Responseable {
 			unset($_COOKIE[$cookieName]);
 		} // END - if
 	}
+
+	/**
+	 * Refreshs a given cookie. This will make the cookie live longer
+	 *
+	 * @param	$cookieName		Cookie to refresh
+	 * @return	void
+	 */
+	public function refreshCookie ($cookieName) {
+		// Only update existing cookies
+		if (isset($_COOKIE[$cookieName])) {
+			// Update the cookie
+			$this->addCookie($cookieName, $_COOKIE[$cookieName], false);
+		} // END - if
+	}
 }
 
 // [EOF]
diff --git a/inc/classes/main/result/class_DatabaseResult.php b/inc/classes/main/result/class_DatabaseResult.php
index fb02af3..75948a6 100644
--- a/inc/classes/main/result/class_DatabaseResult.php
+++ b/inc/classes/main/result/class_DatabaseResult.php
@@ -21,9 +21,10 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-class DatabaseResult extends BaseFrameworkSystem implements SearchableResult, SeekableIterator {
+class DatabaseResult extends BaseFrameworkSystem implements SearchableResult, UpdateableResult, SeekableIterator {
 	// Exception constants
 	const EXCEPTION_INVALID_DATABASE_RESULT = 0x0b0;
+	const EXCEPTION_RESULT_UPDATE_FAILED    = 0x0b1;
 
 	/**
 	 * Current position in array
@@ -40,6 +41,16 @@ class DatabaseResult extends BaseFrameworkSystem implements SearchableResult, Se
 	 */
 	private $resultArray = array();
 
+	/**
+	 * Array of out-dated entries
+	 */
+	private $outDated = array();
+
+	/**
+	 * Affected rows
+	 */
+	private $affectedRows = 0;
+
 	/**
 	 * Protected constructor
 	 *
@@ -87,6 +98,26 @@ class DatabaseResult extends BaseFrameworkSystem implements SearchableResult, Se
 		$this->resultArray = $resultArray;
 	}
 
+	/**
+	 * Updates the current entry by given update criteria
+	 *
+	 * @param	$updateInstance		An instance of an Updateable criteria
+	 * @return	void
+	 */
+	private function updateCurrentEntryByCriteria (LocalUpdateCriteria $updateInstance) {
+		// Get the current entry key
+		$entryKey = $this->key();
+
+		// Now get the update criteria array and update all entries
+		foreach ($updateInstance->getUpdateCriteria() as $criteriaKey=>$criteriaValue) {
+			// Update data
+			$this->resultArray['rows'][$entryKey][$criteriaKey] = $criteriaValue;
+
+			// Mark it as out-dated
+			$this->outDated[$criteriaKey] = 1;
+		} // END - foreach
+	}
+
 	/**
 	 * "Iterator" method next() to advance to the next valid entry. This method
 	 * does also check if the result is invalid
@@ -192,7 +223,109 @@ class DatabaseResult extends BaseFrameworkSystem implements SearchableResult, Se
 	 * @return	$result				Found result entry
 	 */
 	public function searchEntry (LocalSearchCriteria $criteriaInstance) {
-		die(__METHOD__.": OK");
+		die(__METHOD__.": Unfinished!");
+	}
+
+	/**
+	 * Adds an update request to the database result for writing it to the
+	 * database layer
+	 *
+	 * @param	$criteriaInstance	An instance of a updateable criteria
+	 * @return	void
+	 * @throws	ResultUpdateException	If no result was updated
+	 */
+	public function add2UpdateQueue (LocalUpdateCriteria $criteriaInstance) {
+		// Rewind the pointer
+		$this->rewind();
+
+		// Get search criteria
+		$searchInstance = $criteriaInstance->getSearchInstance();
+
+		// And start looking for the result
+		$foundEntries = 0;
+		while (($this->valid()) && ($foundEntries < $searchInstance->getLimit())) {
+			// Get next entry
+			$this->next();
+			$currentEntry = $this->current();
+
+			// Is this entry found?
+			if ($searchInstance->ifEntryMatches($currentEntry)) {
+				// Update this entry
+				$this->updateCurrentEntryByCriteria($criteriaInstance);
+
+				// Count one up
+				$foundEntries++;
+			} // END - if
+		} // END - while
+
+		// Set affected rows
+		$this->setAffectedRows($foundEntries);
+
+		// If no entry is found/updated throw an exception
+		if ($foundEntries == 0) {
+			// Throw an exception here
+			throw new ResultUpdateException($this, self::EXCEPTION_RESULT_UPDATE_FAILED);
+		} // END - if
+
+		// Set search instance
+		$this->setSearchInstance($searchInstance);
+	}
+
+	/**
+	 * Setter for affected rows
+	 *
+	 * @param	$rows	Number of affected rows
+	 * @return	void
+	 */
+	public final function setAffectedRows ($rows) {
+		$this->affectedRows = $rows;
+	}
+
+	/**
+	 * Getter for affected rows
+	 *
+	 * @return	$rows	Number of affected rows
+	 */
+	public final function getAffectedRows () {
+		return $this->affectedRows;
+	}
+
+	/**
+	 * Checks wether we have out-dated entries or not
+	 *
+	 * @return	$needsUpdate	Wether we have out-dated entries
+	 */
+	public function ifDataNeedsFlush () {
+		$needsUpdate = (count($this->outDated) > 0);
+		return $needsUpdate;
+	}
+
+	/**
+	 * Adds registration elements to a given dataset instance
+	 *
+	 * @param	$criteriaInstance	An instance of a storeable criteria
+	 * @return	void
+	 */
+	public function addElementsToDataSet (StoreableCriteria $criteriaInstance) {
+		// Rewind the pointer
+		$this->rewind();
+
+		// Walk through all entries
+		while ($this->valid()) {
+			// Get next entry
+			$this->next();
+			$currentEntry = $this->current();
+
+			// Walk only through out-dated columns
+			foreach ($this->outDated as $key=>$dummy) {
+				// Does this key exist?
+				//* DEBUG: */ echo "outDated: {$key}<br />\n";
+				if (isset($currentEntry[$key])) {
+					// Then update it
+					$criteriaInstance->addCriteria($key, $currentEntry[$key]);
+				} // END - foreach
+			} // END - foreach
+		} // END - while
 	}
 }
 
diff --git a/inc/classes/main/rng/class_RandomNumberGenerator.php b/inc/classes/main/rng/class_RandomNumberGenerator.php
index 12e1c01..2439ffb 100644
--- a/inc/classes/main/rng/class_RandomNumberGenerator.php
+++ b/inc/classes/main/rng/class_RandomNumberGenerator.php
@@ -37,6 +37,11 @@ class RandomNumberGenerator extends BaseFrameworkSystem {
 	 */
 	private $extraSalt = "";
 
+	/**
+	 * Fixed salt for secured hashing
+	 */
+	private $fixedSalt = "";
+
 	/**
 	 * Maximum length for random string
 	 */
@@ -102,11 +107,14 @@ class RandomNumberGenerator extends BaseFrameworkSystem {
 		if ($this->getConfigInstance()->readConfig('is_single_server') == "Y") {
 			// Then use that IP for extra security
 			$serverIp = getenv('SERVER_ADDR');
-		}
+		} // END - if
+
+		// Yet-another fixed salt. This is not dependend on server software or date
+		$this->fixedSalt = sha1($serverIp . ":" . serialize($this->getDatabaseInstance()->getConnectionData()));
 
 		// One-way data we need for "extra-salting" the random number
 		/* @TODO Add site key for stronger salt! */
-		$this->extraSalt = sha1($serverIp . ":" . getenv('SERVER_SOFTWARE') . ":" . $this->getConfigInstance()->readConfig('date_key') . ":" . serialize($this->getDatabaseInstance()->getConnectionData()));
+		$this->extraSalt = sha1($this->fixedSalt . ":" . getenv('SERVER_SOFTWARE') . ":" . $this->getConfigInstance()->readConfig('date_key'));
 
 		// Get config entry for max salt length
 		$this->rndStrLen = $this->getConfigInstance()->readConfig('rnd_str_length');
@@ -131,7 +139,7 @@ class RandomNumberGenerator extends BaseFrameworkSystem {
 			$randomString .= chr($this->randomNumnber(0, 255));
 		}
 
-		// Return the random string mixed up
+		// Return the random string a little mixed up
 		return str_shuffle($randomString);
 	}
 
@@ -143,7 +151,7 @@ class RandomNumberGenerator extends BaseFrameworkSystem {
 	 * @return	$num	Pseudo-random number
 	 */
 	public function randomNumnber ($min, $max) {
-		/* @TODO I had a better random number generator here */
+		/* @TODO I had a better random number generator here but now it is somewhere lost :( */
 		return mt_rand($min, $max);
 	}
 
@@ -155,6 +163,15 @@ class RandomNumberGenerator extends BaseFrameworkSystem {
 	public final function getExtraSalt () {
 		return $this->extraSalt;
 	}
+
+	/**
+	 * Getter for fixed salt
+	 *
+	 * @return	$fixedSalt
+	 */
+	public final function getFixedSalt () {
+		return $this->fixedSalt;
+	}
 }
 
 // [EOF]
diff --git a/inc/classes/main/user/class_User.php b/inc/classes/main/user/class_User.php
index 2221111..49b285f 100644
--- a/inc/classes/main/user/class_User.php
+++ b/inc/classes/main/user/class_User.php
@@ -285,6 +285,7 @@ class User extends BaseFrameworkSystem implements ManageableUser, Registerable {
 			$entry = $this->resultInstance->current();
 
 			// So does the hashes match?
+			//* DEBUG: */ echo $requestInstance->getRequestElement('pass_hash')."/".$entry['pass_hash'];
 			$matches = ($requestInstance->getRequestElement('pass_hash') === $entry['pass_hash']);
 		} // END - if
 
@@ -324,6 +325,60 @@ class User extends BaseFrameworkSystem implements ManageableUser, Registerable {
 		// And return the hash
 		return $passHash;
 	}
+
+	/**
+	 * Updates the last activity timestamp and last performed action in the
+	 * database result. You should call flushUpdates() to flush these updates
+	 * to the database layer.
+	 *
+	 * @param	$requestInstance	A requestable class instance
+	 * @return	void
+	 */
+	public function updateLastActivity (Requestable $requestInstance) {
+		// Set last action
+		$lastAction = $requestInstance->getRequestElement('action');
+
+		// If there is no action use the default on
+		if (is_null($lastAction)) {
+			$lastAction = $this->getConfigInstance()->readConfig('login_default_action');
+		} // END - if
+
+		// Get a critieria instance
+		$searchInstance = ObjectFactory::createObjectByConfiguredName('search_criteria_class');
+
+		// Add search criteria
+		$searchInstance->addCriteria(UserDatabaseWrapper::DB_COLUMN_USERNAME, $this->getUserName());
+		$searchInstance->setLimit(1);
+
+		// Now get another criteria
+		$updateInstance = ObjectFactory::createObjectByConfiguredName('update_criteria_class');
+
+		// And add our both entries
+		$updateInstance->addCriteria('last_activity', date("Y-m-d H:i:s", time()));
+		$updateInstance->addCriteria('last_action', $lastAction);
+
+		// Add the search criteria for searching for the right entry
+		$updateInstance->setSearchInstance($searchInstance);
+
+		// Remember the update in database result
+		$this->resultInstance->add2UpdateQueue($updateInstance);
+	}
+
+	/**
+	 * Flushs all updated entries to the database layer
+	 *
+	 * @return	void
+	 */
+	public function flushUpdates () {
+		// Get a database wrapper
+		$wrapperInstance = ObjectFactory::createObjectByConfiguredName('user_db_wrapper_class');
+
+		// Do we have data to update?
+		if ($this->resultInstance->ifDataNeedsFlush()) {
+			// Yes, then send the whole result to the database layer
+			$wrapperInstance->doUpdateByResult($this->resultInstance);
+		} // END - if
+	}
 }
 
 // [EOF]
diff --git a/inc/classes/middleware/database/class_DatabaseConnection.php b/inc/classes/middleware/database/class_DatabaseConnection.php
index fc8ea91..7a9300f 100644
--- a/inc/classes/middleware/database/class_DatabaseConnection.php
+++ b/inc/classes/middleware/database/class_DatabaseConnection.php
@@ -165,6 +165,20 @@ class DatabaseConnection extends BaseMiddleware implements DatabaseConnector, Re
 		// Ask the database layer
 		$this->dbLayer->queryInsertDataSet($dataSetInstance);
 	}
+
+	/**
+	 * "Updates" a data set instance with a database layer
+	 *
+	 * @param	$dataSetInstance	A storeable data set
+	 * @return	void
+	 */
+	public function queryUpdateDataSet (StoreableCriteria $dataSetInstance) {
+		// Connect to the database
+		$this->dbLayer->connectToDatabase();
+
+		// Ask the database layer
+		$this->dbLayer->queryUpdateDataSet($dataSetInstance);
+	}
 }
 
 // [EOF]
diff --git a/inc/config.php b/inc/config.php
index 0c75800..08052ad 100644
--- a/inc/config.php
+++ b/inc/config.php
@@ -158,6 +158,9 @@ $cfg->setConfigEntry('search_criteria_class', "SearchCriteria");
 // CFG: DATASET-CRITERIA
 $cfg->setConfigEntry('dataset_criteria_class', "DataSetCriteria");
 
+// CFG: UPDATE-CRITERIA
+$cfg->setConfigEntry('update_criteria_class', "UpdateCriteria");
+
 // CFG: FILE-IO-HANDLER
 $cfg->setConfigEntry('file_io_class', "FileIoHandler");