/**
* Database backend class for storing objects in locally created files.
*
- * This class serializes objects and saves them to local files.
+ * This class serializes arrays stored in the dataset instance and saves them
+ * to local files. Every file (except 'info') represents a single line. Every
+ * directory within the 'db' (base) directory represents a table.
*
- * @author Roland Haeder <webmaster@ship-simu.org>
+ * A configurable 'file_io_class' is being used as "storage backend".
+ *
+ * @author Roland Haeder <webmaster@shipsimu.org>
* @version 0.0.0
- * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 Core Developer Team
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2013 Core Developer Team
* @license GNU GPL 3.0 or any newer version
- * @link http://www.ship-simu.org
+ * @link http://www.shipsimu.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
* 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 LocalFileDatabase extends BaseDatabaseFrontend implements DatabaseFrontendInterface {
- // Constants for MySQL backward-compatiblity (PLEASE FIX THEM!)
- const DB_CODE_TABLE_MISSING = 0x100;
- const DB_CODE_TABLE_UNWRITEABLE = 0x101;
- const DB_CODE_DATA_FILE_CORRUPT = 0x102;
-
- // Status results
- const RESULT_OKAY = 'ok';
-
- /**
- * Save path for "file database"
- */
- private $savePath = '';
-
+class LocalFileDatabase extends BaseDatabaseBackend implements DatabaseBackend {
/**
* The file's extension
*/
private $lastContents = array();
/**
- * Wether the "connection is already up
- */
- private $alreadyConnected = false;
-
- /**
- * Last error message
- */
- private $lastError = '';
-
- /**
- * Last exception
+ * Whether the "connection is already up
*/
- private $lastException = null;
+ private $alreadyConnected = FALSE;
/**
* Table information array
/**
* Element for index
*/
- private $indexKey = "__idx";
+ private $indexKey = '__idx';
/**
* The protected constructor. Do never instance from outside! You need to
*
* @return void
*/
- protected function __construct() {
+ protected function __construct () {
// Call parent constructor
parent::__construct(__CLASS__);
-
- // Clean up a little
- $this->removeNumberFormaters();
- $this->removeSystemArray();
}
/**
- * Create an object of LocalFileDatabase and set the save path for local files.
- * This method also validates the given file path.
+ * Create an object of LocalFileDatabase and set the save path from
+ * configuration for local files.
*
- * @param $savePath The local file path string
- * @param $ioInstance The input/output handler. This
- * should be FileIoHandler
- * @return $dbInstance An instance of LocalFileDatabase
+ * @return $databaseInstance An instance of LocalFileDatabase
*/
- public final static function createLocalFileDatabase ($savePath, FileIoHandler $ioInstance) {
+ public static final function createLocalFileDatabase () {
// Get an instance
- $dbInstance = new LocalFileDatabase();
-
- // Set save path and IO instance
- $dbInstance->setSavePath($savePath);
- $dbInstance->setFileIoInstance($ioInstance);
+ $databaseInstance = new LocalFileDatabase();
- // "Connect" to the database
- $dbInstance->connectToDatabase();
+ // Get a new compressor channel instance
+ $compressorInstance = ObjectFactory::createObjectByConfiguredName('compressor_channel_class');
- // Return database instance
- return $dbInstance;
- }
+ // Set the compressor channel
+ $databaseInstance->setCompressorChannel($compressorInstance);
- /**
- * Setter for save path
- *
- * @param $savePath The local save path where we shall put our serialized classes
- * @return void
- */
- public final function setSavePath ($savePath) {
- // Secure string
- $savePath = (string) $savePath;
-
- // Set save path
- $this->savePath = $savePath;
- }
+ // Get a file IO handler
+ $fileIoInstance = ObjectFactory::createObjectByConfiguredName('file_io_class');
- /**
- * Getter for save path
- *
- * @return $savePath The local save path where we shall put our serialized classes
- */
- public final function getSavePath () {
- return $this->savePath;
- }
+ // ... and set it
+ $databaseInstance->setFileIoInstance($fileIoInstance);
- /**
- * Getter for last error message
- *
- * @return $lastError Last error message
- */
- public final function getLastError () {
- return $this->lastError;
- }
+ // "Connect" to the database
+ $databaseInstance->connectToDatabase();
- /**
- * Getter for last exception
- *
- * @return $lastException Last thrown exception
- */
- public final function getLastException () {
- return $this->lastException;
+ // Return database instance
+ return $databaseInstance;
}
/**
$this->lastFile = (string) $fqfn;
}
- /**
- * Reset the last error and exception instance. This should be done after
- * a successfull "query"
- *
- * @return void
- */
- private final function resetLastError () {
- $this->lastError = '';
- $this->lastException = null;
- }
-
/**
* Getter for last read file
*
- * @return $lastFile The last read file's name with full path
+ * @return $lastFile The last read file's name with full path
*/
public final function getLastFile () {
return $this->lastFile;
/**
* Setter for contents of the last read file
*
- * @param $contents An array with header and data elements
+ * @param $contents An array with header and data elements
* @return void
*/
private final function setLastFileContents (array $contents) {
* @return $dataArray
*/
private function getDataArrayFromFile ($fqfn) {
- // Get a file pointer
- $fileInstance = FrameworkFileInputPointer::createFrameworkFileInputPointer($fqfn);
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Reading elements from database file ' . $fqfn . ' ...');
- // Get the raw data and BASE64-decode it
- $compressedData = base64_decode($fileInstance->readLinesFromFile());
+ // Init compressed data
+ $compressedData = $this->getFileIoInstance()->loadFileContents($fqfn);
+ $compressedData = $compressedData['data'];
// Close the file and throw the instance away
- $fileInstance->closeFile();
unset($fileInstance);
// Decompress it
// Unserialize it
$dataArray = unserialize($serializedData);
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Read ' . count($dataArray) . ' elements from database file ' . $fqfn . '.');
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: dataArray=' . print_r($dataArray, TRUE));
+
// Finally return it
return $dataArray;
}
* @return void
*/
private function writeDataArrayToFqfn ($fqfn, array $dataArray) {
- // Get a file pointer instance
- $fileInstance = FrameworkFileOutputPointer::createFrameworkFileOutputPointer($fqfn, 'w');
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Flushing ' . count($dataArray) . ' elements to database file ' . $fqfn . ' ...');
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: dataArray=' . print_r($dataArray, TRUE));
// Serialize and compress it
$compressedData = $this->getCompressorChannel()->getCompressor()->compressStream(serialize($dataArray));
+ // Write data
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Writing ' . strlen($compressedData) . ' bytes ...');
+
// Write this data BASE64 encoded to the file
- $fileInstance->writeToFile(base64_encode($compressedData));
+ $this->getFileIoInstance()->saveFile($fqfn, $compressedData, $this);
- // Close the file pointer
- $fileInstance->closeFile();
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: Flushing ' . count($dataArray) . ' elements to database file completed.');
}
/**
$infoArray = array();
// Create FQFN for getting the table information file
- $fqfn = $this->getSavePath() . $dataSetInstance->getTableName() . '/info.' . $this->getFileExtension();
+ $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, 'info');
// Get the file contents
try {
$infoArray = $this->getDataArrayFromFile($fqfn);
- } catch (FileNotFoundException $e) {
+ } catch (FileIoException $e) {
// Not found, so ignore it here
}
return $infoArray;
}
+ /**
+ * Generates an FQFN from given dataset instance and string
+ *
+ * @param $dataSetInstance An instance of a database set class
+ * @param $rowName Name of the row
+ * @return $fqfn The FQFN for this row
+ */
+ private function generateFqfnFromDataSet (Criteria $dataSetInstance, $rowName) {
+ // This is the FQFN
+ $fqfn = $this->getConfigInstance()->getConfigEntry('local_db_path') . $dataSetInstance->getTableName() . '/' . $rowName . '.' . $this->getFileExtension();
+
+ // Return it
+ return $fqfn;
+ }
+
/**
* Creates the table info file from given dataset instance
*
*/
private function createTableInfoFile (StoreableCriteria $dataSetInstance) {
// Create FQFN for creating the table information file
- $fqfn = $this->getSavePath() . $dataSetInstance->getTableName() . '/info.' . $this->getFileExtension();
+ $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, 'info');
// Get the data out from dataset in a local array
$this->tableInfo[$dataSetInstance->getTableName()] = array(
$this->writeDataArrayToFqfn($fqfn, $this->tableInfo[$dataSetInstance->getTableName()]);
}
+ /**
+ * Updates the table info file from given dataset instance
+ *
+ * @param $dataSetInstance An instance of a database set class
+ * @return void
+ */
+ private function updateTableInfoFile (StoreableCriteria $dataSetInstance) {
+ // "Cache" table name
+ $tableName = $dataSetInstance->getTableName();
+
+ // Create FQFN for creating the table information file
+ $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, 'info');
+
+ // Get the data out from dataset in a local array
+ $this->tableInfo[$tableName]['primary'] = $dataSetInstance->getPrimaryKey();
+ $this->tableInfo[$tableName]['last_updated'] = time();
+
+ // Write the data to the file
+ $this->writeDataArrayToFqfn($fqfn, $this->tableInfo[$tableName]);
+ }
+
/**
* Updates the primary key information or creates the table info file if not found
*
* @return void
*/
private function updatePrimaryKey (StoreableCriteria $dataSetInstance) {
+ // "Cache" table name
+ $tableName = $dataSetInstance->getTableName();
+
// Get the information array from lower method
$infoArray = $this->getContentsFromTableInfoFile($dataSetInstance);
// Is the primary key there?
- if (!isset($this->tableInfo['primary'])) {
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: tableInfo=' . print_r($this->tableInfo, TRUE));
+ if (!isset($this->tableInfo[$tableName]['primary'])) {
// Then create the info file
$this->createTableInfoFile($dataSetInstance);
- } elseif (($this->getConfigInstance()->getConfigEntry('db_update_primary_forced') == 'Y') && ($dataSetInstance->getPrimaryKey() != $this->tableInfo['primary'])) {
+ } elseif (($this->getConfigInstance()->getConfigEntry('db_update_primary_forced') == 'Y') && ($dataSetInstance->getPrimaryKey() != $this->tableInfo[$tableName]['primary'])) {
// Set the array element
- $this->tableInfo[$dataSetInstance->getTableName()]['primary'] = $dataSetInstance->getPrimaryKey();
+ $this->tableInfo[$tableName]['primary'] = $dataSetInstance->getPrimaryKey();
// Update the entry
$this->updateTableInfoFile($dataSetInstance);
* Starts a SELECT query on the database by given return type, table name
* and search criteria
*
- * @param $resultType Result type ('array', 'object' and 'indexed' are valid)
- * @param $tableName Name of the database table
- * @param $criteria Local search criteria class
- * @return $resultData Result data of the query
+ * @param $tableName Name of the database table
+ * @param $searchInstance Local search criteria class
+ * @return $resultData Result data of the query
* @throws UnsupportedCriteriaException If the criteria is unsupported
* @throws SqlException If an 'SQL error' occurs
*/
- public function querySelect ($resultType, $tableName, LocalSearchCriteria $criteriaInstance) {
+ public function querySelect ($tableName, LocalSearchCriteria $searchInstance) {
// The result is null by any errors
- $resultData = null;
+ $resultData = NULL;
// Create full path name
- $pathName = $this->getSavePath() . $tableName . '/';
+ $pathName = $this->getConfigInstance()->getConfigEntry('local_db_path') . $tableName . '/';
// A 'select' query is not that easy on local files, so first try to
// find the 'table' which is in fact a directory on the server
// Initialize the result data, this need to be rewritten e.g. if a local file cannot be read
$resultData = array(
- 'status' => LocalfileDatabase::RESULT_OKAY,
- 'rows' => array()
+ BaseDatabaseBackend::RESULT_INDEX_STATUS => self::RESULT_OKAY,
+ BaseDatabaseBackend::RESULT_INDEX_ROWS => array()
);
// Initialize limit/skip
$idx = 1;
// Read the directory with some exceptions
- while (($dataFile = $directoryInstance->readDirectoryExcept(array('.', '..', '.htaccess', '.svn', "info." . $this->getFileExtension()))) && ($limitFound < $criteriaInstance->getLimit())) {
+ while (($dataFile = $directoryInstance->readDirectoryExcept(array('.', '..', '.htaccess', '.svn', 'info.' . $this->getFileExtension()))) && (($limitFound < $searchInstance->getLimit()) || ($searchInstance->getLimit() == 0))) {
// Does the extension match?
if (substr($dataFile, -(strlen($this->getFileExtension()))) !== $this->getFileExtension()) {
// Skip this file!
// Read the file
$dataArray = $this->getDataArrayFromFile($pathName . $dataFile);
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',dataArray='.print_r($dataArray, TRUE));
// Is this an array?
if (is_array($dataArray)) {
+ // Default is nothing found
+ $isFound = TRUE;
+
// Search in the criteria with FMFW (First Matches, First Wins)
foreach ($dataArray as $key => $value) {
- // Get criteria element
- $criteria = $criteriaInstance->getCriteriaElemnent($key);
-
- // Is the criteria met?
- if ((!is_null($criteria)) && ($criteria == $value)) {
-
- // Shall we skip this entry?
- if ($criteriaInstance->getSkip() > 0) {
- // We shall skip some entries
- if ($skipFound < $criteriaInstance->getSkip()) {
- // Skip this entry
- $skipFound++;
- break;
- } // END - if
+ // Make sure value is not bool
+ assert(!is_bool($value));
+
+ // Found one entry?
+ $isFound = (($isFound === TRUE) && ($searchInstance->isCriteriaMatching($key, $value)));
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: key=' . $key . ',value=' . $value . ',isFound=' . intval($isFound));
+ } // END - foreach
+
+ // Is all found?
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: isFound=' . intval($isFound) . ',limitFound=' . $limitFound . ',limit=' . $searchInstance->getLimit());
+ if ($isFound === TRUE) {
+ // 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
- // Set id number
- $dataArray[$this->getIndexKey()] = $idx;
+ // Set id number
+ $dataArray[$this->getIndexKey()] = $idx;
- // Entry found!
- $resultData['rows'][] = $dataArray;
+ // Entry found!
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: indexKey=' . $this->getIndexKey() . ',idx=' . $idx . ',dataArray=' . print_r($dataArray, TRUE));
+ array_push($resultData[BaseDatabaseBackend::RESULT_INDEX_ROWS], $dataArray);
- // Count found entries up
- $limitFound++;
- break;
- } // END - if
- } // END - foreach
+ // Count found entries up
+ $limitFound++;
+ } // END - if
} else {
// Throw an exception here
- throw new SqlException(array($this, sprintf("File '%s' contains invalid data.", $dataFile), self::DB_CODE_DATA_FILE_CORRUPT), self::EXCEPTION_SQL_QUERY);
+ throw new SqlException(array($this, sprintf('File '%s' contains invalid data.', $dataFile), self::DB_CODE_DATA_FILE_CORRUPT), self::EXCEPTION_SQL_QUERY);
}
// Count entry up
$directoryInstance->closeDirectory();
unset($directoryInstance);
- // Reset last error message and exception
- $this->resetLastError();
+ // Reset last exception
+ $this->resetLastException();
} catch (PathIsNoDirectoryException $e) {
// Path not found means "table not found" for real databases...
- $this->lastException = $e;
- $this->lastError = $e->getMessage();
+ $this->setLastException($e);
// So throw an SqlException here with faked error message
- throw new SqlException (array($this, sprintf("Table '%s' not found", $tableName), self::DB_CODE_TABLE_MISSING), self::EXCEPTION_SQL_QUERY);
+ throw new SqlException (array($this, sprintf('Table '%s' not found', $tableName), self::DB_CODE_TABLE_MISSING), self::EXCEPTION_SQL_QUERY);
} catch (FrameworkException $e) {
// Catch all exceptions and store them in last error
- $this->lastException = $e;
- $this->lastError = $e->getMessage();
+ $this->setLastException($e);
}
// Return the gathered result
* @throws SqlException If an SQL error occurs
*/
public function queryInsertDataSet (StoreableCriteria $dataSetInstance) {
- // Create full path name
- $fqfn = sprintf("%s%s/%s.%s",
- $this->getSavePath(),
- $dataSetInstance->getTableName(),
- md5($dataSetInstance->getUniqueValue()),
- $this->getFileExtension()
- );
-
// Try to save the request away
try {
+ // Create full path name
+ $fqfn = $this->generateFqfnFromDataSet($dataSetInstance, md5($dataSetInstance->getUniqueValue()));
+
// Write the data away
$this->writeDataArrayToFqfn($fqfn, $dataSetInstance->getCriteriaArray());
// Update the primary key
$this->updatePrimaryKey($dataSetInstance);
- // Reset last error message and exception
- $this->resetLastError();
+ // Reset last exception
+ $this->resetLastException();
} catch (FrameworkException $e) {
// Catch all exceptions and store them in last error
- $this->lastException = $e;
- $this->lastError = $e->getMessage();
+ $this->setLastException($e);
// Throw an SQL exception
- throw new SqlException (array($this, sprintf("Cannot write data to table '%s'", $tableName), self::DB_CODE_TABLE_UNWRITEABLE), self::EXCEPTION_SQL_QUERY);
+ throw new SqlException(array($this, sprintf('Cannot write data to table '%s', is the table created?', $dataSetInstance->getTableName()), self::DB_CODE_TABLE_UNWRITEABLE), self::EXCEPTION_SQL_QUERY);
}
}
*/
public function queryUpdateDataSet (StoreableCriteria $dataSetInstance) {
// Create full path name
- $pathName = $this->getSavePath() . $dataSetInstance->getTableName() . '/';
+ $pathName = $this->getConfigInstance()->getConfigEntry('local_db_path') . $dataSetInstance->getTableName() . '/';
// Try all the requests
try {
$skipFound = 0;
// Get the criteria array from the dataset
- $criteriaArray = $dataSetInstance->getCriteriaArray();
+ $searchArray = $dataSetInstance->getCriteriaArray();
// Get search criteria
$searchInstance = $dataSetInstance->getSearchInstance();
// Read the directory with some exceptions
- while (($dataFile = $directoryInstance->readDirectoryExcept(array('.', '..', '.htaccess', '.svn', "info." . $this->getFileExtension()))) && ($limitFound < $searchInstance->getLimit())) {
+ while (($dataFile = $directoryInstance->readDirectoryExcept(array('.', '..', '.htaccess', '.svn', 'info.' . $this->getFileExtension()))) && (($limitFound < $searchInstance->getLimit()) || ($searchInstance->getLimit() == 0))) {
// Does the extension match?
if (substr($dataFile, -(strlen($this->getFileExtension()))) !== $this->getFileExtension()) {
+ // Debug message
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',getFileExtension()=' . $this->getFileExtension() . ' - SKIPPED!');
// Skip this file!
continue;
- }
+ } // END - if
// Open this file for reading
$dataArray = $this->getDataArrayFromFile($pathName . $dataFile);
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: dataFile=' . $dataFile . ',dataArray='.print_r($dataArray, TRUE));
// Is this an array?
if (is_array($dataArray)) {
+ // Default is nothing found
+ $isFound = TRUE;
+
// 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
+ // Make sure value is not bool
+ assert(!is_bool($value));
+
+ // Found one entry?
+ $isFound = (($isFound === TRUE) && ($searchInstance->isCriteriaMatching($key, $value)));
+ } // END - foreach
+
+ // Is all found?
+ if ($isFound === TRUE) {
+ // 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
+ // Entry found, so update it
+ foreach ($searchArray as $searchKey => $searchValue) {
+ // Make sure the value is not bool again
+ assert(!is_bool($searchValue));
+ assert($searchKey != $this->indexKey);
- // Write the data to a local file
- $this->writeDataArrayToFqfn($pathName . $dataFile, $dataArray);
+ // Debug message + add/update it
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('DATABASE: criteriaKey=' . $searchKey . ',criteriaValue=' . $searchValue);
+ $dataArray[$searchKey] = $searchValue;
+ } // END - foreach
- // Count it
- $limitFound++;
- break;
- } // END - if
- } // END - foreach
+ // Write the data to a local file
+ $this->writeDataArrayToFqfn($pathName . $dataFile, $dataArray);
+
+ // Count found entries up
+ $limitFound++;
+ } // END - if
} // END - if
} // END - while
// Update the primary key
$this->updatePrimaryKey($dataSetInstance);
- // Reset last error message and exception
- $this->resetLastError();
+ // Reset last exception
+ $this->resetLastException();
} catch (FrameworkException $e) {
// Catch all exceptions and store them in last error
- $this->lastException = $e;
- $this->lastError = $e->getMessage();
+ $this->setLastException($e);
// Throw an SQL exception
- throw new SqlException (array($this, sprintf("Cannot write data to table '%s'", $dataSetInstance->getTableName()), self::DB_CODE_TABLE_UNWRITEABLE), self::EXCEPTION_SQL_QUERY);
+ throw new SqlException(array($this, sprintf("Cannot write data to table '%s', is the table created?", $dataSetInstance->getTableName()), self::DB_CODE_TABLE_UNWRITEABLE), self::EXCEPTION_SQL_QUERY);
}
}
*/
public function getPrimaryKeyOfTable ($tableName) {
// Default key is null
- $primaryKey = null;
+ $primaryKey = NULL;
// Does the table information exist?
if (isset($this->tableInfo[$tableName])) {
// Return the column
return $primaryKey;
}
+
+ /**
+ * Removes non-public data from given array.
+ *
+ * @param $data An array with possible non-public data that needs to be removed.
+ * @return $data A cleaned up array with only public data.
+ * @todo Add more generic non-public data for removal
+ */
+ public function removeNonPublicDataFromArray (array $data) {
+ // Remove '__idx'
+ unset($data[$this->indexKey]);
+
+ // Return it
+ return $data;
+ }
}
// [EOF]