Feature #20689 » 11438_v3.diff
t3lib/stddb/tables.sql (working copy) | ||
---|---|---|
);
|
||
#
|
||
# Table structure for table 'sys_registry'
|
||
#
|
||
CREATE TABLE sys_registry (
|
||
uid int(11) unsigned NOT NULL auto_increment,
|
||
entry_namespace varchar(128) DEFAULT '' NOT NULL,
|
||
entry_key varchar(128) DEFAULT '' NOT NULL,
|
||
entry_value longtext,
|
||
PRIMARY KEY (uid),
|
||
UNIQUE KEY entry_identifier (entry_namespace,entry_key)
|
||
);
|
||
#
|
||
# Table structure for table 'sys_be_shortcuts'
|
||
#
|
||
CREATE TABLE sys_be_shortcuts (
|
t3lib/core_autoload.php (working copy) | ||
---|---|---|
't3lib_readmail' => PATH_t3lib . 'class.t3lib_readmail.php',
|
||
't3lib_recordlist' => PATH_t3lib . 'class.t3lib_recordlist.php',
|
||
't3lib_refindex' => PATH_t3lib . 'class.t3lib_refindex.php',
|
||
't3lib_registry' => PATH_t3lib . 'class.t3lib_registry.php',
|
||
't3lib_rteapi' => PATH_t3lib . 'class.t3lib_rteapi.php',
|
||
't3lib_scbase' => PATH_t3lib . 'class.t3lib_scbase.php',
|
||
't3lib_softrefproc' => PATH_t3lib . 'class.t3lib_softrefproc.php',
|
t3lib/class.t3lib_registry.php (revision 0) | ||
---|---|---|
<?php
|
||
/***************************************************************
|
||
* Copyright notice
|
||
*
|
||
* (c) 2009 Ingo Renner <ingo@typo3.org>
|
||
*
|
||
* All rights reserved
|
||
*
|
||
* This script is part of the TYPO3 project. The TYPO3 project 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.
|
||
*
|
||
* The GNU General Public License can be found at
|
||
* http://www.gnu.org/copyleft/gpl.html.
|
||
* A copy is found in the textfile GPL.txt and important notices to the license
|
||
* from the author is found in LICENSE.txt distributed with these scripts.
|
||
*
|
||
*
|
||
* This script 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.
|
||
*
|
||
* This copyright notice MUST APPEAR in all copies of the script!
|
||
***************************************************************/
|
||
/**
|
||
* A class to store and retrieve entries in a registry database table.
|
||
* Credits: Heavily inspired by Drupal's variable_*() functions.
|
||
*
|
||
* @author Ingo Renner <ingo@typo3.org>
|
||
* @package TYPO3
|
||
* @subpackage t3lib
|
||
*/
|
||
class t3lib_Registry implements t3lib_Singleton {
|
||
/**
|
||
* @var array
|
||
*/
|
||
protected $entries = array();
|
||
/**
|
||
* Returns a persistent entry.
|
||
*
|
||
* @param string Extension key for extensions starting with 'tx_' / 'user_' or 'core' for core registry entries
|
||
* @param string The key of the entry to return.
|
||
* @param mixed The default value to use if this entry has never been set.
|
||
* @return mixed The value of the entry.
|
||
* @throws InvalidArgumentException Throws an exception if the given namespace is not valid
|
||
*/
|
||
public function get($namespace, $key, $defaultValue = NULL) {
|
||
$this->validateNamespace($namespace);
|
||
if (!isset($this->entries[$namespace][$key])) {
|
||
$this->loadEntriesByNamespace($namespace);
|
||
}
|
||
return isset($this->entries[$namespace][$key]) ? $this->entries[$namespace][$key] : $defaultValue;
|
||
}
|
||
/**
|
||
* Sets a persistent entry.
|
||
*
|
||
* @param string Extension key for extensions starting with 'tx_' / 'user_' or 'core' for core registry entries
|
||
* @param string The key of the entry to set. Must be namespaced by prepending the key with the extension key for extensions or 'core' for core registry entries. Example: tx_myext.my.entry
|
||
* @param mixed The value to set. This can be any PHP data type; this class takes care of serialization as necessary.
|
||
* @return void
|
||
* @throws InvalidArgumentException Throws an exception if the given namespace is not valid
|
||
*/
|
||
public function set($namespace, $key, $value) {
|
||
$this->validateNamespace($namespace);
|
||
$serializedValue = serialize($value);
|
||
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
|
||
'uid',
|
||
'sys_registry',
|
||
'entry_namespace = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($namespace, 'sys_registry') .
|
||
' AND entry_key = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($key, 'sys_registry')
|
||
);
|
||
if ($GLOBALS['TYPO3_DB']->sql_num_rows($res) < 1) {
|
||
$GLOBALS['TYPO3_DB']->exec_INSERTquery(
|
||
'sys_registry',
|
||
array(
|
||
'entry_namespace' => $namespace,
|
||
'entry_key' => $key,
|
||
'entry_value' => $serializedValue
|
||
)
|
||
);
|
||
} else {
|
||
$GLOBALS['TYPO3_DB']->exec_UPDATEquery(
|
||
'sys_registry',
|
||
'entry_namespace = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($namespace, 'sys_registry') .
|
||
' AND entry_key = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($key, 'sys_registry'),
|
||
array(
|
||
'entry_value' => $serializedValue
|
||
)
|
||
);
|
||
}
|
||
$this->entries[$namespace][$key] = $value;
|
||
}
|
||
/**
|
||
* Unsets a persistent entry.
|
||
*
|
||
* @param string Namespace. extension key for extensions or 'core' for core registry entries
|
||
* @param string The key of the entry to unset.
|
||
* @return void
|
||
* @throws InvalidArgumentException Throws an exception if the given namespace is not valid
|
||
*/
|
||
public function remove($namespace, $key) {
|
||
$this->validateNamespace($namespace);
|
||
$GLOBALS['TYPO3_DB']->exec_DELETEquery(
|
||
'sys_registry',
|
||
'entry_namespace = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($namespace, 'sys_registry') .
|
||
' AND entry_key = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($key, 'sys_registry')
|
||
);
|
||
unset($this->entries[$namespace][$key]);
|
||
}
|
||
/**
|
||
* Unsets all persistent entries of the given namespace.
|
||
*
|
||
* @param string Namespace. extension key for extensions or 'core' for core registry entries
|
||
* @return void
|
||
* @throws InvalidArgumentException Throws an exception if the given namespace is not valid
|
||
*/
|
||
public function removeAll($namespace) {
|
||
$this->validateNamespace($namespace);
|
||
$GLOBALS['TYPO3_DB']->exec_DELETEquery(
|
||
'sys_registry',
|
||
'entry_namespace = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($namespace, 'sys_registry')
|
||
);
|
||
unset($this->entries[$namespace]);
|
||
}
|
||
/**
|
||
* Loads all entries of the given namespace into the internal $entries cache.
|
||
*
|
||
* @param string Namespace. extension key for extensions or 'core' for core registry entries
|
||
* @return void
|
||
* @throws InvalidArgumentException Throws an exception if the given namespace is not valid
|
||
*/
|
||
protected function loadEntriesByNamespace($namespace) {
|
||
$this->validateNamespace($namespace);
|
||
$storedEntries = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
|
||
'*',
|
||
'sys_registry',
|
||
'entry_namespace = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($namespace, 'sys_registry')
|
||
);
|
||
foreach ($storedEntries as $storedEntry) {
|
||
$key = $storedEntry['entry_key'];
|
||
$this->entries[$namespace][$key] = unserialize($storedEntry['entry_value']);
|
||
}
|
||
}
|
||
/**
|
||
* Checks the given namespace. If it does not have a valid format an exception is thrown.
|
||
* Allowed namespaces are 'core', 'tx_*' and 'user_*'
|
||
*
|
||
* @param string Namespace. extension key for extensions or 'core' for core registry entries
|
||
* @return void
|
||
* @throws InvalidArgumentException Throws an exception if the given namespace is not valid
|
||
*/
|
||
protected function validateNamespace($namespace) {
|
||
if (t3lib_div::isFirstPartOfStr($namespace, 'tx_') || t3lib_div::isFirstPartOfStr($namespace, 'user_')) {
|
||
return;
|
||
}
|
||
if ($namespace !== 'core') {
|
||
throw new InvalidArgumentException(
|
||
'"' . $namespace . '" is no valid Namespace. The namespace has to be prefixed with "tx_", "user_" or must be equal to "core"',
|
||
1249755131
|
||
);
|
||
}
|
||
}
|
||
}
|
||
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_registry.php']) {
|
||
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_registry.php']);
|
||
}
|
||
?>
|
tests/t3lib/t3lib_registry_testcase.php (revision 0) | ||
---|---|---|
<?php
|
||
/***************************************************************
|
||
* Copyright notice
|
||
*
|
||
* (c) 2009 Ingo Renner <ingo@typo3.org>
|
||
* All rights reserved
|
||
*
|
||
* This script is part of the TYPO3 project. The TYPO3 project 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.
|
||
*
|
||
* The GNU General Public License can be found at
|
||
* http://www.gnu.org/copyleft/gpl.html.
|
||
*
|
||
* This script 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.
|
||
*
|
||
* This copyright notice MUST APPEAR in all copies of the script!
|
||
***************************************************************/
|
||
/**
|
||
* Testcase for class t3lib_Registry
|
||
*
|
||
* @author Ingo Renner <ingo@typo3.org>
|
||
* @package TYPO3
|
||
* @subpackage t3lib
|
||
*/
|
||
class t3lib_Registry_testcase extends tx_phpunit_testcase {
|
||
/**
|
||
* @var t3lib_Registry
|
||
*/
|
||
protected $registry;
|
||
/**
|
||
* @var t3lib_DB
|
||
*/
|
||
protected $typo3DbBackup;
|
||
/**
|
||
* Sets up this testcase
|
||
*/
|
||
public function setUp() {
|
||
$this->typo3DbBackup = $GLOBALS['TYPO3_DB'];
|
||
$GLOBALS['TYPO3_DB'] = $this->getMock('t3lib_DB', array());
|
||
$GLOBALS['TYPO3_DB']->expects($this->any())
|
||
->method('fullQuoteStr')
|
||
->will($this->onConsecutiveCalls('\'tx_phpunit\'', '\'someKey\'', '\'tx_phpunit\'', '\'someKey\''));
|
||
$this->registry = new t3lib_Registry();
|
||
}
|
||
/**
|
||
* Tears down this testcase
|
||
*/
|
||
public function tearDown() {
|
||
$GLOBALS['TYPO3_DB'] = $this->typo3DbBackup;
|
||
}
|
||
/**
|
||
* @test
|
||
* @expectedException InvalidArgumentException
|
||
*/
|
||
public function getThrowsExceptionForInvalidNamespaces() {
|
||
$this->registry->get('invalidNamespace', 'someKey');
|
||
}
|
||
/**
|
||
* @test
|
||
*/
|
||
public function getRetrievesTheCorrectEntry() {
|
||
$testKey = 't3lib_Registry_testcase.testData.getRetrievesTheCorrectEntry';
|
||
$testValue = 'getRetrievesTheCorrectEntry';
|
||
$GLOBALS['TYPO3_DB']->expects($this->once())
|
||
->method('exec_SELECTgetRows')
|
||
->with('*', 'sys_registry', 'entry_namespace = \'tx_phpunit\'')
|
||
->will(
|
||
$this->returnValue(
|
||
array(
|
||
array('entry_key' => $testKey, 'entry_value' => serialize($testValue))
|
||
)
|
||
)
|
||
);
|
||
$this->assertEquals(
|
||
$this->registry->get('tx_phpunit', $testKey),
|
||
$testValue,
|
||
'The actual data did not match the expected data.'
|
||
);
|
||
}
|
||
/**
|
||
* @test
|
||
*/
|
||
public function getLazyLoadsEntriesOfOneNamespace() {
|
||
$testKey1 = 't3lib_Registry_testcase.testData.getLazyLoadsEntriesOfOneNamespace1';
|
||
$testValue1 = 'getLazyLoadsEntriesOfOneNamespace1';
|
||
$testKey2 = 't3lib_Registry_testcase.testData.getLazyLoadsEntriesOfOneNamespace2';
|
||
$testValue2 = 'getLazyLoadsEntriesOfOneNamespace2';
|
||
$GLOBALS['TYPO3_DB']->expects($this->once())
|
||
->method('exec_SELECTgetRows')
|
||
->with('*', 'sys_registry', 'entry_namespace = \'tx_phpunit\'')
|
||
->will(
|
||
$this->returnValue(
|
||
array(
|
||
array('entry_key' => $testKey1, 'entry_value' => serialize($testValue1)),
|
||
array('entry_key' => $testKey2, 'entry_value' => serialize($testValue2))
|
||
)
|
||
)
|
||
);
|
||
$this->assertEquals(
|
||
$this->registry->get('tx_phpunit', $testKey1),
|
||
$testValue1,
|
||
'The actual data did not match the expected data.'
|
||
);
|
||
$this->assertEquals(
|
||
$this->registry->get('tx_phpunit', $testKey2),
|
||
$testValue2,
|
||
'The actual data did not match the expected data.'
|
||
);
|
||
}
|
||
/**
|
||
* @test
|
||
*/
|
||
public function getReturnsTheDefaultValueIfTheRequestedKeyWasNotFound() {
|
||
$defaultValue = 'getReturnsTheDefaultValueIfTheRequestedKeyWasNotFound';
|
||
$GLOBALS['TYPO3_DB']->expects($this->once())
|
||
->method('exec_SELECTgetRows')
|
||
->with('*', 'sys_registry', 'entry_namespace = \'tx_phpunit\'')
|
||
->will(
|
||
$this->returnValue(
|
||
array(
|
||
array('entry_key' => 'foo', 'entry_value' => 'bar'),
|
||
)
|
||
)
|
||
);
|
||
$this->assertEquals(
|
||
$defaultValue,
|
||
$this->registry->get('tx_phpunit', 'someNonExistingKey', $defaultValue),
|
||
'A value other than the default value was returned.'
|
||
);
|
||
}
|
||
/**
|
||
* @test
|
||
* @expectedException InvalidArgumentException
|
||
*/
|
||
public function setThrowsAnExceptionOnEmptyNamespace() {
|
||
$this->registry->set('', 'someKey', 'someValue');
|
||
}
|
||
/**
|
||
* @test
|
||
* @expectedException InvalidArgumentException
|
||
*/
|
||
public function setThrowsAnExceptionOnWrongNamespace() {
|
||
$this->registry->set('invalidNamespace', 'someKey', 'someValue');
|
||
}
|
||
/**
|
||
* @test
|
||
*/
|
||
public function setAllowsValidNamespaces() {
|
||
$this->registry->set('tx_thisIsValid', 'someKey', 'someValue');
|
||
$this->registry->set('user_soIsThis', 'someKey', 'someValue');
|
||
$this->registry->set('core', 'someKey', 'someValue');
|
||
}
|
||
/**
|
||
* @test
|
||
*/
|
||
public function setReallySavesTheGivenValueToTheDatabase() {
|
||
$GLOBALS['TYPO3_DB']->expects($this->once())
|
||
->method('exec_INSERTquery')
|
||
->with(
|
||
'sys_registry',
|
||
array(
|
||
'entry_namespace' => 'tx_phpunit',
|
||
'entry_key' => 'someKey',
|
||
'entry_value' => serialize('someValue')
|
||
)
|
||
);
|
||
$this->registry->set('tx_phpunit', 'someKey', 'someValue');
|
||
}
|
||
/**
|
||
* @test
|
||
*/
|
||
public function setUpdatesExistingKeys() {
|
||
$GLOBALS['TYPO3_DB']->expects($this->once())
|
||
->method('exec_SELECTquery')
|
||
->with(
|
||
'uid',
|
||
'sys_registry',
|
||
'entry_namespace = \'tx_phpunit\' AND entry_key = \'someKey\''
|
||
)
|
||
->will(
|
||
$this->returnValue('DBResource')
|
||
);
|
||
$GLOBALS['TYPO3_DB']->expects($this->once())
|
||
->method('sql_num_rows')
|
||
->with('DBResource')
|
||
->will(
|
||
$this->returnValue(1)
|
||
);
|
||
$GLOBALS['TYPO3_DB']->expects($this->once())
|
||
->method('exec_UPDATEquery')
|
||
->with(
|
||
'sys_registry',
|
||
'entry_namespace = \'tx_phpunit\' AND entry_key = \'someKey\'',
|
||
array(
|
||
'entry_value' => serialize('someValue')
|
||
)
|
||
);
|
||
$GLOBALS['TYPO3_DB']->expects($this->never())
|
||
->method('exec_INSERTquery');
|
||
$this->registry->set('tx_phpunit', 'someKey', 'someValue');
|
||
}
|
||
/**
|
||
* @test
|
||
*/
|
||
public function setStoresValueInTheInternalEntriesCache() {
|
||
$registry = $this->getMock('t3lib_Registry', array('loadEntriesByNamespace'));
|
||
$registry->expects($this->never())
|
||
->method('loadEntriesByNamespace');
|
||
$registry->set('tx_phpunit', 'someKey', 'someValue');
|
||
$this->assertEquals(
|
||
'someValue',
|
||
$registry->get('tx_phpunit', 'someKey'),
|
||
'The actual data did not match the expected data.'
|
||
);
|
||
}
|
||
/**
|
||
* @test
|
||
* @expectedException InvalidArgumentException
|
||
*/
|
||
public function removeThrowsAnExceptionOnWrongNamespace() {
|
||
$this->registry->remove('coreInvalid', 'someKey');
|
||
}
|
||
/**
|
||
* @test
|
||
*/
|
||
public function removeReallyRemovesTheEntryFromTheDatabase() {
|
||
$GLOBALS['TYPO3_DB']->expects($this->once())
|
||
->method('exec_DELETEquery')
|
||
->with(
|
||
'sys_registry',
|
||
'entry_namespace = \'tx_phpunit\' AND entry_key = \'someKey\''
|
||
);
|
||
$this->registry->remove('tx_phpunit', 'someKey');
|
||
}
|
||
/**
|
||
* @test
|
||
*/
|
||
public function removeUnsetsValueFromTheInternalEntriesCache() {
|
||
$registry = $this->getMock('t3lib_Registry', array('loadEntriesByNamespace'));
|
||
$registry->set('tx_phpunit', 'someKey', 'someValue');
|
||
$registry->set('tx_phpunit', 'someOtherKey', 'someOtherValue');
|
||
$registry->set('tx_otherNamespace', 'someKey', 'someValueInOtherNamespace');
|
||
$registry->remove('tx_phpunit', 'someKey');
|
||
$this->assertEquals(
|
||
'defaultValue',
|
||
$registry->get('tx_phpunit', 'someKey', 'defaultValue'),
|
||
'A value other than the default value was returned, thus the entry was still present.'
|
||
);
|
||
$this->assertEquals(
|
||
'someOtherValue',
|
||
$registry->get('tx_phpunit', 'someOtherKey', 'defaultValue'),
|
||
'A value other than the stored value was returned, thus the entry was removed.'
|
||
);
|
||
$this->assertEquals(
|
||
'someValueInOtherNamespace',
|
||
$registry->get('tx_otherNamespace', 'someKey', 'defaultValue'),
|
||
'A value other than the stored value was returned, thus the entry was removed.'
|
||
);
|
||
}
|
||
/**
|
||
* @test
|
||
* @expectedException InvalidArgumentException
|
||
*/
|
||
public function removeAllThrowsAnExceptionOnWrongNamespace() {
|
||
$this->registry->removeAll('');
|
||
}
|
||
/**
|
||
* @test
|
||
*/
|
||
public function removeAllReallyRemovesAllEntriesOfTheSpecifiedNamespaceFromTheDatabase() {
|
||
$GLOBALS['TYPO3_DB']->expects($this->once())
|
||
->method('exec_DELETEquery')
|
||
->with(
|
||
'sys_registry',
|
||
'entry_namespace = \'tx_phpunit\''
|
||
);
|
||
$this->registry->removeAll('tx_phpunit');
|
||
}
|
||
/**
|
||
* @test
|
||
*/
|
||
public function removeAllUnsetsValuesOfTheSpecifiedNamespaceFromTheInternalEntriesCache() {
|
||
$registry = $this->getMock('t3lib_Registry', array('loadEntriesByNamespace'));
|
||
$registry->set('tx_phpunit', 'someKey', 'someValue');
|
||
$registry->set('tx_phpunit', 'someOtherKey', 'someOtherValue');
|
||
$registry->set('tx_otherNamespace', 'someKey', 'someValueInOtherNamespace');
|
||
$registry->removeAll('tx_phpunit');
|
||
$this->assertEquals(
|
||
'defaultValue',
|
||
$registry->get('tx_phpunit', 'someKey', 'defaultValue'),
|
||
'A value other than the default value was returned, thus the entry was still present.'
|
||
);
|
||
$this->assertEquals(
|
||
'defaultValue',
|
||
$registry->get('tx_phpunit', 'someOtherKey', 'defaultValue'),
|
||
'A value other than the default value was returned, thus the entry was still present.'
|
||
);
|
||
$this->assertEquals(
|
||
'someValueInOtherNamespace',
|
||
$registry->get('tx_otherNamespace', 'someKey', 'defaultValue'),
|
||
'A value other than the stored value was returned, thus the entry was removed.'
|
||
);
|
||
}
|
||
}
|
||
?>
|