Skip to content

Instantly share code, notes, and snippets.

@smichaelsen
Last active June 9, 2021 10:56
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save smichaelsen/4bb015fafebabbb08bde2f9ff990012c to your computer and use it in GitHub Desktop.
Save smichaelsen/4bb015fafebabbb08bde2f9ff990012c to your computer and use it in GitHub Desktop.
<?php
namespace MyVendor\MyPackage\Service;
use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Use in ext_localconf.php with ExtensionManagementUtility::addTypoScript()
*
* Returns an @import TypoScript statement to a file that contains news TypoScript cache configuration.
* The file is written on demand to a cache folder and automatically cleared with "Flush frontend caches".
*
* The included TypoScript configuration will make sure all pages which include news plugins, will respect
* all news folders (starttimes, endtimes) when calculating their caching lifetime.
*/
class NewsCacheAutoConfigurationService
{
public static function constructNewsCacheDefinition(): string
{
$filePath = Environment::getVarPath() . '/cache/data/assets/newsCacheConfiguration.typoscript';
if (!file_exists($filePath)) {
$content = self::getCacheDefinition();
$fileHandle = fopen($filePath, 'w');
fwrite($fileHandle, $content);
fclose($fileHandle);
}
return '@import "' . $filePath . '"';
}
protected static function getCacheDefinition(): string
{
$newsStoragePIDs = [];
foreach (self::getPageIdsOfNewsStorageFolders() as $storageFolderUid) {
$newsStoragePIDs[] = 'tx_news_domain_model_news:' . $storageFolderUid;
}
if (empty($newsStoragePIDs)) {
return '';
}
$newsStoragePIDlist = implode(',', $newsStoragePIDs);
$cacheDefinition = [
'# Auto generated by ' . self::class,
'config.cache {',
];
$pagesWithNewsPlugins = self::getIdsOfPagesWithNewsPlugin();
if (empty($pagesWithNewsPlugins)) {
return '';
}
foreach ($pagesWithNewsPlugins as $pageWithNewsPlugins) {
$cacheDefinition[] = ' ' . $pageWithNewsPlugins . ' := addToList(' . $newsStoragePIDlist . ')';
}
$cacheDefinition[] = '}';
return implode(PHP_EOL, $cacheDefinition);
}
protected static function getIdsOfPagesWithNewsPlugin(): array
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content');
$records = $queryBuilder
->selectLiteral('DISTINCT pid')
->from('tt_content')
->where(
$queryBuilder->expr()->eq('list_type', $queryBuilder->createNamedParameter('news_pi1'))
)
->execute()
->fetchAllAssociative();
return array_column($records, 'pid');
}
protected static function getPageIdsOfNewsStorageFolders(): array
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
$records = $queryBuilder
->select('uid')
->from('pages')
->where(
$queryBuilder->expr()->eq('module', $queryBuilder->createNamedParameter('news')),
$queryBuilder->expr()->eq('sys_language_uid', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT))
)
->execute()
->fetchAllAssociative();
return array_column($records, 'uid');
}
}
@smichaelsen
Copy link
Author

@tgaertner pointed out $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['get_cache_timeout'] could be used instead.
@DanielSiepmann pointed out $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['Core/TypoScript/TemplateService']['runThroughTemplatesPostProcessing'] could be used instead.

I haven't tried it with those hooks yet, but both look promising and I might switch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment