src/EventSubscriber/CacheClearSubscriber.php line 31
<?php
namespace Cms\EventSubscriber;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
use Symfony\Component\HttpKernel\CacheClearer\CacheClearerInterface;
use Symfony\Component\HttpKernel\Event\TerminateEvent;
use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\HttpKernel\RebootableInterface;
class CacheClearSubscriber implements EventSubscriberInterface
{
private string $buildDir;
public function __construct(
#[Autowire(service: 'cache_clearer')] private readonly CacheClearerInterface $cacheClearer,
private readonly KernelInterface $kernel,
private readonly Filesystem $filesystem,
#[Autowire('%kernel.cache_dir%')] private string $cacheDir,
#[Autowire('%kernel.build_dir')] ?string $buildDir = null,
) {
$this->buildDir ??= $this->cacheDir;
}
public function onKernelTerminate(TerminateEvent $event): void
{
$request = $event->getRequest();
if ('cms_admin_configuration_clearcache' !== $request->attributes->get('_route')) {
return;
}
$fs = $this->filesystem;
$realCacheDir = $this->cacheDir;
if ($request->query->getBoolean('force')) {
$fs->remove($realCacheDir);
return;
}
$realBuildDir = $this->buildDir;
$useBuildDir = $realBuildDir !== $realCacheDir;
$oldCacheDir = substr($realCacheDir, 0, -1).(str_ends_with($realCacheDir, '~') ? '+' : '~');
$oldBuildDir = substr($realBuildDir, 0, -1).(str_ends_with($realBuildDir, '_') ? '-' : '_');
$warmupDir = substr($realBuildDir, 0, -1).(str_ends_with($realBuildDir, '_') ? '-' : '_');
$fs->remove($warmupDir);
$fs->mkdir($warmupDir);
if ($useBuildDir) {
$fs->remove($oldCacheDir);
$fs->rename($realCacheDir, $oldCacheDir);
$fs->mkdir($realCacheDir);
$this->cacheClearer->clear($realBuildDir);
}
$this->cacheClearer->clear($realCacheDir);
if (! $this->kernel instanceof RebootableInterface) {
throw new \RuntimeException();
}
$this->kernel->reboot($warmupDir);
$search = [$warmupDir, str_replace('\\', '\\\\', $warmupDir)];
$replace = str_replace('\\', '/', $realBuildDir);
foreach (Finder::create()->files()->in($warmupDir) as $file) {
$content = str_replace($search, $replace, file_get_contents($file), $count);
if ($count) {
file_put_contents($file, $content);
}
}
$fs->rename($realBuildDir, $oldBuildDir);
$fs->rename($warmupDir, $realBuildDir);
if ($useBuildDir) {
$fs->remove($oldBuildDir);
}
$fs->remove($oldCacheDir);
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::TERMINATE => 'onKernelTerminate',
];
}
}