Skip to content

Commit

Permalink
[BUGFIX] Remove expired cache_treelist entries during runtime
Browse files Browse the repository at this point in the history
When \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::getTreeList
checked for an existing cache_treelist entry, the given md5hash and the
expiry timestamp had been compared. As caches do not expire at all by
default, there a very few cases when an entry is actually expired.

However, if a cache entry has been expired, the cache entry hasn't been
removed and therefore the creation of a new cache entry with the same
md5hash identifier resulted in a duplicate entry exception.

To solve this, the affected, expired entry will be removed during runtime.

Releases: master, 8.7
Resolves: #86028
Resolves: #86491
Change-Id: If1a907607db29f7edd0fa77a8bb47a69bdfc0df9
Reviewed-on: https://review.typo3.org/59031
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Markus Klein <markus.klein@typo3.org>
  • Loading branch information
alexanderschnitzler authored and liayn committed Dec 4, 2018
1 parent b612265 commit 7e83f87
Showing 1 changed file with 22 additions and 16 deletions.
Expand Up @@ -6806,30 +6806,36 @@ public function getTreeList($id, $depth, $begin = 0, $dontCheckEnableFields = fa
$tsfe->gr_list
];
$requestHash = md5(serialize($parameters));
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('cache_treelist');
$cacheEntry = $queryBuilder->select('treelist')

$cacheTreeListConnection = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('cache_treelist');

$queryBuilder = $cacheTreeListConnection->createQueryBuilder();
$query = $queryBuilder->select('treelist', 'expires')
->from('cache_treelist')
->where(
$queryBuilder->expr()->eq(
'md5hash',
$queryBuilder->createNamedParameter($requestHash, \PDO::PARAM_STR)
),
$queryBuilder->expr()->orX(
$queryBuilder->expr()->gt(
'expires',
$queryBuilder->createNamedParameter($GLOBALS['EXEC_TIME'], \PDO::PARAM_INT)
),
$queryBuilder->expr()->eq('expires', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT))
)
)
->setMaxResults(1)
->execute()
->fetch();
->setMaxResults(1);

$cacheEntry = $query->execute()->fetch();
$cacheEntryExists = is_array($cacheEntry);
$cacheEntryIsExpired = $cacheEntry['expires'] <= $GLOBALS['EXEC_TIME'];

if (is_array($cacheEntry)) {
// Cache hit
return $cacheEntry['treelist'];
if ($cacheEntryExists) {
if (!$cacheEntryIsExpired) {
// Cache hit
return $cacheEntry['treelist'];
}
$cacheTreeListConnection->delete(
'cache_treelist',
[
'md5hash' => $requestHash
]
);
}
// If Id less than zero it means we should add the real id to list:
if ($id < 0) {
Expand Down

0 comments on commit 7e83f87

Please sign in to comment.