Project

General

Profile

Bug #20566 » 11265_v2.diff

Administrator Admin, 2009-06-05 22:07

View differences:

t3lib/config_default.php (Arbeitskopie)
'options' => array(
'cacheTable' => 'cache_pagesection'
)
),
'cache_treelist' => array(
'backend' => 't3lib_cache_backend_DbBackend',
'options' => array(
'cacheTable' => 'cache_treelist'
)
)
/*
For memcached, use:
t3lib/class.t3lib_cache.php (Arbeitskopie)
// do nothing, a cache_hash cache already exists
}
}
/**
* initializes the cache_treelist cache
*
* @return void
*/
public static function initTreeListCache() {
try {
$GLOBALS['typo3CacheFactory']->create(
'cache_treelist',
't3lib_cache_frontend_VariableFrontend',
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_treelist']['backend'],
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_treelist']['options']
);
} catch(t3lib_cache_exception_DuplicateIdentifier $e) {
// do nothing, a cache_hash cache already exists
}
}
}
t3lib/class.t3lib_tcemain.php (Arbeitskopie)
// clear all caches that use the t3lib_cache framework
$GLOBALS['typo3CacheManager']->flushCaches();
if (t3lib_extMgm::isLoaded('cms')) {
$GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_treelist', '');
}
// Clearing additional cache tables:
if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearAllCache_additionalTables'])) {
foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearAllCache_additionalTables'] as $tableName) {
typo3/init.php (Arbeitskopie)
t3lib_cache::initPageCache();
t3lib_cache::initPageSectionCache();
t3lib_cache::initContentHashCache();
t3lib_cache::initTreeListCache();
unset($cacheFactoryClass);
// *************************
typo3/sysext/cms/ext_tables.sql (Arbeitskopie)
# Table structure for table 'cache_treelist'
#
CREATE TABLE cache_treelist (
md5hash char(32) DEFAULT '' NOT NULL,
pid int(11) DEFAULT '0' NOT NULL,
treelist text,
tstamp int(11) DEFAULT '0' NOT NULL,
expires int(11) unsigned DEFAULT '0' NOT NULL,
PRIMARY KEY (md5hash)
identifier varchar(250) DEFAULT '' NOT NULL,
crdate int(11) unsigned DEFAULT '0' NOT NULL,
content mediumtext,
tags text,
lifetime int(11) unsigned DEFAULT '0' NOT NULL,
PRIMARY KEY (identifier)
) ENGINE=InnoDB;
typo3/sysext/cms/tslib/class.tslib_fe.php (Arbeitskopie)
t3lib_cache::initPageSectionCache();
t3lib_cache::initContentHashCache();
t3lib_cache::initTreeListCache();
$GLOBALS['TT']->pull();
}
typo3/sysext/cms/tslib/hooks/class.tx_cms_treelistcacheupdate.php (Arbeitskopie)
* @param t3lib_TCEmain TCEmain parent object
*/
public function processDatamap_afterDatabaseOperations($status, $table, $recordId, array $updatedFields, t3lib_TCEmain $tceMain) {
if ($table == 'pages' && $this->requiresUpdate($updatedFields)) {
$affectedPagePid = 0;
$affectedPageUid = 0;
if ($status == 'new') {
// detect new pages
// resolve the uid
$affectedPageUid = $tceMain->substNEWwithIDs[$recordId];
$affectedPagePid = $updatedFields['pid'];
} elseif ($status == 'update') {
// detect updated pages
$affectedPageUid = $recordId;
/*
detect updated pages
when updating a page the pid is not directly available so we
need to retrieve it ourselves.
*/
......
);
$this->processClearCacheActions(
$affectedPageUid,
$affectedPagePid,
$updatedFields,
$clearCacheActions
);
}
......
false
);
$affectedPageUid = $deletedRecord['uid'];
$affectedPagePid = $deletedRecord['pid'];
// faking the updated fields
$updatedFields = array('deleted' => 1);
......
);
$this->processClearCacheActions(
$affectedPageUid,
$affectedPagePid,
$updatedFields,
$clearCacheActions
);
}
......
if ($table == 'pages' && $this->requiresUpdate($updatedFields)) {
$affectedPageUid = $recordId;
$affectedPageOldPid = $movedRecord['pid'];
$affectedPageNewPid = $updatedFields['pid'];
......
// clear treelist entries for old parent page
$this->processClearCacheActions(
$affectedPageUid,
$affectedPageOldPid,
$updatedFields,
$clearCacheActions
);
// clear treelist entries for new parent page
$this->processClearCacheActions(
$affectedPageUid,
$affectedPageNewPid,
$updatedFields,
$clearCacheActions
);
}
......
if ($table == 'pages' && $this->requiresUpdate($updatedFields)) {
$affectedPageUid = $recordId;
$affectedPageOldPid = $movedRecord['pid'];
$affectedPageNewPid = $updatedFields['pid'];
......
// clear treelist entries for old parent page
$this->processClearCacheActions(
$affectedPageUid,
$affectedPageOldPid,
$updatedFields,
$clearCacheActions
);
// clear treelist entries for new parent page
$this->processClearCacheActions(
$affectedPageUid,
$affectedPageNewPid,
$updatedFields,
$clearCacheActions
);
}
......
/**
* calls the cache maintainance functions according to the determined actions
*
* @param integer uid of the affected page
* @param integer parent uid of the affected page
* @param array array of updated fields and their new values
* @param array array of actions to carry out
*/
protected function processClearCacheActions($affectedPage, $affectedParentPage, $updatedFields, array $actions) {
protected function processClearCacheActions($affectedParentPage, array $actions) {
$actionNames = array_keys($actions);
foreach ($actionNames as $actionName) {
switch ($actionName) {
case 'allParents':
$this->clearCacheForAllParents($affectedParentPage);
break;
case 'setExpiration':
// only used when setting an end time for a page
$expirationTime = $updatedFields['endtime'];
$this->setCacheExpiration($affectedPage, $expirationTime);
case 'flush':
$this->clearTreeListCache();
break;
case 'uidInTreelist':
$this->clearCacheWhereUidInTreelist($affectedPage);
break;
}
}
}
// from time to time clean the cache from expired entries
// (theoretically every 1000 calls)
$randomNumber = rand(1, 1000);
if ($randomNumber == 500) {
$this->removeExpiredCacheEntries();
}
/**
* clears the treelist cache.
*
*/
protected function clearTreeListCache() {
$GLOBALS['typo3CacheManager']->getCache('cache_treelist')->flush();
}
/**
......
protected function clearCacheForAllParents($affectedParentPage) {
$rootline = t3lib_BEfunc::BEgetRootLine($affectedParentPage);
$rootlineIds = array();
$tags = array();
foreach ($rootline as $page) {
if($page['uid'] != 0) {
$rootlineIds[] = $page['uid'];
$tags[] = 'treeListID_'.$page['uid'];
}
}
if (!empty($rootlineIds)) {
$rootlineIdsImploded = implode(',', $rootlineIds);
$GLOBALS['TYPO3_DB']->exec_DELETEquery(
'cache_treelist',
'pid IN(' . $rootlineIdsImploded . ')'
);
if (!empty($tags)) {
$GLOBALS['typo3CacheManager']->getCache('cache_treelist')->flushByTags($tags);
}
}
/**
* clears the treelist cache for all pages where the affected page is found
* in the treelist
*
* @param integer Id of the changed page
*/
protected function clearCacheWhereUidInTreelist($affectedPage) {
$GLOBALS['TYPO3_DB']->exec_DELETEquery(
'cache_treelist',
$GLOBALS['TYPO3_DB']->listQuery(
'treelist',
$affectedPage,
'cache_treelist'
)
);
}
/**
* sets an expiration time for all cache entries having the changed page in
* the treelist.
*
* @param integer uid of the changed page
*/
protected function setCacheExpiration($affectedPage, $expirationTime) {
$GLOBALS['TYPO3_DB']->exec_UPDATEquery(
'cache_treelist',
$GLOBALS['TYPO3_DB']->listQuery(
'treelist',
$affectedPage,
'cache_treelist'
),
array(
'expires' => $expirationTime
)
);
}
/**
* removes all expired treelist cache entries
*
*/
protected function removeExpiredCacheEntries() {
$GLOBALS['TYPO3_DB']->exec_DELETEquery(
'cache_treelist',
'expires <= ' . time()
);
}
/**
* determines what happened to the page record, this is necessary to clear
* as less cache entries as needed later
*
......
$actions['allParents'] = true;
} elseif ($status == 'update') {
$updatedFieldNames = array_keys($updatedFields);
foreach ($updatedFieldNames as $updatedFieldName) {
switch ($updatedFieldName) {
case 'pid':
// page moved
$actions['allParents'] = true;
$actions['uidInTreelist'] = true;
break;
case $GLOBALS['TCA']['pages']['ctrl']['enablecolumns']['disabled']:
case $GLOBALS['TCA']['pages']['ctrl']['enablecolumns']['fe_group']:
case $GLOBALS['TCA']['pages']['ctrl']['delete']:
case 'extendToSubpages':
case 'php_tree_stop':
// page hidden / unhidden / deleted / extendToSubpages set
// php_tree_stop and/or FE groups set
$actions['uidInTreelist'] = true;
break;
case $GLOBALS['TCA']['pages']['ctrl']['enablecolumns']['starttime']:
/*
start time set/unset
Doesn't matter whether it was set or unset, in both
cases the cache needs to be cleared. When setting a
start time the page must be removed from the
treelist. When unsetting the start time it must
become listed in the tree list again.
*/
$actions['uidInTreelist'] = true;
break;
case $GLOBALS['TCA']['pages']['ctrl']['enablecolumns']['endtime']:
/*
end time set/unset
When setting an end time the cache entry needs an
expiration time. When unsetting the end time the
page must become listed in the treelist again.
*/
if($updatedFields['endtime'] > 0) {
$actions['setExpiration'] = true;
} else {
$actions['uidInTreelist'] = true;
}
break;
default:
if (in_array($updatedFieldName, $this->updateRequiringFields)) {
$actions['uidInTreelist'] = true;
}
}
if (count(array_intersect($this->updateRequiringFields,$updatedFieldNames))) {
$actions['flush'] = true;
}
}
return $actions;
}
typo3/sysext/cms/tslib/class.tslib_content.php (Arbeitskopie)
$id = intval($id);
$theList = '';
$addId = 0;
$requestHash = '';
if ($id) {
......
$moreWhereClauses,
$prevId_array
);
$requestHash = md5(serialize($parameters));
$cacheEntry = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
'treelist',
'cache_treelist',
'md5hash = \'' . $requestHash . '\' AND ( expires > ' . time() . ' OR expires = 0 )'
);
$identifier = md5(serialize($parameters));
$theList = $GLOBALS['typo3CacheManager']->getCache('cache_treelist')->get($identifier);
if (!empty($cacheEntry[0]['treelist'])) {
if (!empty($theList)) {
// cache hit
t3lib_div::devLog('Cache Treelist: HIT', 'tslib_cObj');
return $cacheEntry[0]['treelist'];
} else {
// cache miss
t3lib_div::devLog('Cache Treelist: MISS', 'tslib_cObj');
return $theList;
}
// If Id less than zero it means we should add the real id to list:
......
}
}
$GLOBALS['TYPO3_DB']->exec_INSERTquery(
'cache_treelist',
array(
'md5hash' => $requestHash,
'pid' => $id,
'treelist' => $theList,
'tstamp' => time()
)
);
$GLOBALS['typo3CacheManager']->getCache('cache_treelist')->set($identifier, $theList, array('treeListID_'.$id), 0);
}
// Return list:
return $theList;
(1-1/2)