Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TASK] Clean up cache:flush command #910

Merged
merged 1 commit into from May 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
91 changes: 19 additions & 72 deletions Classes/Console/Command/Cache/CacheFlushCommand.php
Expand Up @@ -14,18 +14,18 @@
*
*/

use Helhum\Typo3Console\Command\AbstractConvertedCommand;
use Helhum\Typo3Console\Core\Booting\RunLevel;
use Helhum\Typo3Console\Mvc\Cli\Symfony\Application;
use Helhum\Typo3Console\Service\CacheLowLevelCleaner;
use Helhum\Typo3Console\Service\CacheService;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Install\Service\ClearCacheService;

class CacheFlushCommand extends AbstractConvertedCommand
class CacheFlushCommand extends Command
{
protected function configure()
{
Expand All @@ -35,93 +35,40 @@ protected function configure()
Flushes TYPO3 core caches first and after that, flushes caches from extensions.
EOH
);
/** @deprecated Will be removed with 6.0 */
$this->setDefinition($this->createCompleteInputDefinition());
}

/**
* @deprecated Will be removed with 6.0
*/
protected function createNativeDefinition(): array
{
return [
new InputOption(
'files-only',
null,
InputOption::VALUE_NONE,
'Only file caches are flushed'
),
];
$this->setDefinition(
[
new InputOption(
'files-only',
null,
InputOption::VALUE_NONE,
'Only file caches are flushed'
),
]
);
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$filesOnly = $input->getOption('files-only');
$application = $this->getApplication();
if (!$application instanceof Application) {
throw new \RuntimeException('Fatal error. Application is not properly initialized.', 1546617606);
}
$filesOnly = $filesOnly || !$application->isFullyCapable();

$io = new SymfonyStyle($input, $output);

$lowLevelCleaner = new CacheLowLevelCleaner();
$lowLevelCleaner->forceFlushCachesFiles();
$filesOnly = $input->getOption('files-only') || !$application->isFullyCapable();
if ($filesOnly) {
$lowLevelCleaner = new CacheLowLevelCleaner();
$lowLevelCleaner->forceFlushCachesFiles();
$io->writeln('Flushed all file caches.');
// No need to proceed, as files only flush is requested
return 0;
}

$lowLevelCleaner->forceFlushDatabaseCacheTables();
$application->boot(RunLevel::LEVEL_FULL);

$coreCacheService = GeneralUtility::makeInstance(ClearCacheService::class);
$coreCacheService->clearAll();
$cacheService = new CacheService();
$cacheService->flush();
$cacheService->flushCachesWithDataHandler();

$io->writeln('Flushed all caches.');

return 0;
}

/**
* @deprecated will be removed with 6.0
*
* @return array
*/
protected function createDeprecatedDefinition(): array
{
return [
new InputOption(
'force',
null,
InputOption::VALUE_NONE,
'Cache is forcibly flushed (low level operations are performed)'
),
new InputArgument(
'force',
null,
'Cache is forcibly flushed (low level operations are performed)',
false
),
new InputArgument(
'filesOnly',
null,
'Only file caches are flushed',
false
),
];
}

/**
* @deprecated will be removed with 6.0
*/
protected function handleDeprecatedArgumentsAndOptions(InputInterface $input, OutputInterface $output)
{
if ($input->getOption('force')) {
$io = new SymfonyStyle($input, $output);
$io->getErrorStyle()->writeln('<warning>Using "--force" is deprecated and has no effect any more.</warning>');
}
}
}
31 changes: 4 additions & 27 deletions Classes/Console/Service/CacheLowLevelCleaner.php
Expand Up @@ -15,7 +15,6 @@
*/

use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;

/**
Expand All @@ -26,33 +25,11 @@ class CacheLowLevelCleaner
/**
* Recursively delete cache directory
*/
public function forceFlushCachesFiles()
public function forceFlushCachesFiles(): void
{
GeneralUtility::flushDirectory(Environment::getVarPath() . '/cache', true);
}

/**
* Truncate all DB tables prefixed with 'cf_'
*/
public function forceFlushDatabaseCacheTables()
{
// Get all table names from Default connection starting with 'cf_' and truncate them
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
$connection = $connectionPool->getConnectionByName('Default');
$tableNames = $connection->getSchemaManager()->listTableNames();
foreach ($tableNames as $tableName) {
if ($tableName === 'cache_treelist' || strpos($tableName, 'cf_') === 0) {
$connection->truncate($tableName);
}
}
// Check tables on other connections
$remappedTables = isset($GLOBALS['TYPO3_CONF_VARS']['DB']['TableMapping'])
? array_keys((array)$GLOBALS['TYPO3_CONF_VARS']['DB']['TableMapping'])
: [];
foreach ($remappedTables as $tableName) {
if ($tableName === 'cache_treelist' || strpos($tableName, 'cf_') === 0) {
$connectionPool->getConnectionForTable($tableName)->truncate($tableName);
}
$cacheDirPattern = Environment::getVarPath() . '/cache/*/*';
foreach (glob($cacheDirPattern) as $path) {
GeneralUtility::flushDirectory($path, true);
}
}
}
32 changes: 18 additions & 14 deletions Classes/Console/Service/CacheService.php
Expand Up @@ -14,8 +14,10 @@
*
*/

use TYPO3\CMS\Core\Authentication\CommandLineUserAuthentication;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Cache\Exception\NoSuchCacheGroupException;
use TYPO3\CMS\Core\Core\Bootstrap;
use TYPO3\CMS\Core\DataHandling\DataHandler;
use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
Expand Down Expand Up @@ -54,19 +56,19 @@ public function flush()
/**
* Flushes caches using the data handler.
* Although we trigger the cache flush API here, the real intention is to trigger
* hook subscribers, so that they can do their job (flushing "other" caches when cache is flushed.
* For example realurl subscribes to these hooks.
* hook subscribers, so that they can do their job (flushing "other" caches when cache is flushed).
*
* We use "all" because this method is only called from "flush" command which is indeed meant
* to flush all caches. Besides that, "all" is really all caches starting from TYPO3 8.x
* thus it would make sense for the hook subscribers to act on that cache clear type.
*
* However if you find a valid use case for us to also call "pages" here, then please create
* a pull request and describe this case. "system" or "temp_cached" will not be added however
* because these are deprecated since TYPO3 8.x
* a pull request and describe this case.
*/
public function flushCachesWithDataHandler()
public function flushCachesWithDataHandler(): void
{
Bootstrap::initializeBackendUser(CommandLineUserAuthentication::class);
Bootstrap::initializeBackendAuthentication();
$dataHandler = GeneralUtility::makeInstance(DataHandler::class);
$dataHandler->start([], []);
$dataHandler->clear_cacheCmd('all');
Expand All @@ -77,8 +79,9 @@ public function flushCachesWithDataHandler()
*
* @param array $groups
* @throws NoSuchCacheGroupException
* @return void
*/
public function flushGroups(array $groups)
public function flushGroups(array $groups): void
{
$this->ensureCacheGroupsExist($groups);
foreach ($groups as $group) {
Expand All @@ -91,8 +94,10 @@ public function flushGroups(array $groups)
*
* @param array $tags
* @param string $group
* @throws NoSuchCacheGroupException
* @return void
*/
public function flushByTags(array $tags, $group = null)
public function flushByTags(array $tags, $group = null): void
{
foreach ($tags as $tag) {
if ($group === null) {
Expand All @@ -108,8 +113,10 @@ public function flushByTags(array $tags, $group = null)
*
* @param array $tags
* @param array $groups
* @throws NoSuchCacheGroupException
* @return void
*/
public function flushByTagsAndGroups(array $tags, array $groups = null)
public function flushByTagsAndGroups(array $tags, array $groups = null): void
{
if ($groups === null) {
$this->flushByTags($tags);
Expand All @@ -121,10 +128,7 @@ public function flushByTagsAndGroups(array $tags, array $groups = null)
}
}

/**
* @return array
*/
public function getValidCacheGroups()
public function getValidCacheGroups(): array
{
$validGroups = [];
foreach ($this->cacheConfiguration as $cacheConfiguration) {
Expand All @@ -138,9 +142,9 @@ public function getValidCacheGroups()

/**
* @param array $groups
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheGroupException
* @throws NoSuchCacheGroupException
*/
private function ensureCacheGroupsExist($groups)
private function ensureCacheGroupsExist($groups): void
{
$validGroups = $this->getValidCacheGroups();
$sanitizedGroups = array_intersect($groups, $validGroups);
Expand Down