src/EventSubscriber/CacheClearSubscriber.php line 31

  1. <?php
  2. namespace Cms\EventSubscriber;
  3. use Symfony\Component\DependencyInjection\Attribute\Autowire;
  4. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  5. use Symfony\Component\Filesystem\Filesystem;
  6. use Symfony\Component\Finder\Finder;
  7. use Symfony\Component\HttpKernel\CacheClearer\CacheClearerInterface;
  8. use Symfony\Component\HttpKernel\Event\TerminateEvent;
  9. use Symfony\Component\HttpKernel\HttpKernel;
  10. use Symfony\Component\HttpKernel\HttpKernelInterface;
  11. use Symfony\Component\HttpKernel\KernelEvents;
  12. use Symfony\Component\HttpKernel\KernelInterface;
  13. use Symfony\Component\HttpKernel\RebootableInterface;
  14. class CacheClearSubscriber implements EventSubscriberInterface
  15. {
  16.     private string $buildDir;
  17.     public function __construct(
  18.         #[Autowire(service'cache_clearer')] private readonly CacheClearerInterface $cacheClearer,
  19.         private readonly KernelInterface $kernel,
  20.         private readonly Filesystem $filesystem,
  21.         #[Autowire('%kernel.cache_dir%')] private string $cacheDir,
  22.         #[Autowire('%kernel.build_dir')] ?string $buildDir null,
  23.     ) {
  24.         $this->buildDir ??= $this->cacheDir;
  25.     }
  26.     public function onKernelTerminate(TerminateEvent $event): void
  27.     {
  28.         $request $event->getRequest();
  29.         if ('cms_admin_configuration_clearcache' !== $request->attributes->get('_route')) {
  30.             return;
  31.         }
  32.         $fs $this->filesystem;
  33.         $realCacheDir $this->cacheDir;
  34.         
  35.         if ($request->query->getBoolean('force')) {
  36.             $fs->remove($realCacheDir);
  37.             return;
  38.         }
  39.         $realBuildDir $this->buildDir;
  40.         $useBuildDir $realBuildDir !== $realCacheDir;
  41.         $oldCacheDir substr($realCacheDir0, -1).(str_ends_with($realCacheDir'~') ? '+' '~');
  42.         $oldBuildDir substr($realBuildDir0, -1).(str_ends_with($realBuildDir'_') ? '-' '_');
  43.         $warmupDir substr($realBuildDir0, -1).(str_ends_with($realBuildDir'_') ? '-' '_');
  44.         $fs->remove($warmupDir);
  45.         $fs->mkdir($warmupDir);
  46.         if ($useBuildDir) {
  47.             $fs->remove($oldCacheDir);
  48.             $fs->rename($realCacheDir$oldCacheDir);
  49.             $fs->mkdir($realCacheDir);
  50.             $this->cacheClearer->clear($realBuildDir);
  51.         }
  52.         $this->cacheClearer->clear($realCacheDir);
  53.         if (! $this->kernel instanceof RebootableInterface) {
  54.             throw new \RuntimeException();
  55.         }
  56.         $this->kernel->reboot($warmupDir);
  57.         $search = [$warmupDirstr_replace('\\''\\\\'$warmupDir)];
  58.         $replace str_replace('\\''/'$realBuildDir);
  59.         foreach (Finder::create()->files()->in($warmupDir) as $file) {
  60.             $content str_replace($search$replacefile_get_contents($file), $count);
  61.             if ($count) {
  62.                 file_put_contents($file$content);
  63.             }
  64.         }
  65.         $fs->rename($realBuildDir$oldBuildDir);
  66.         $fs->rename($warmupDir$realBuildDir);
  67.         if ($useBuildDir) {
  68.             $fs->remove($oldBuildDir);
  69.         }
  70.         $fs->remove($oldCacheDir);
  71.     }
  72.     public static function getSubscribedEvents(): array
  73.     {
  74.         return [
  75.             KernelEvents::TERMINATE => 'onKernelTerminate',
  76.         ];
  77.     }
  78. }