<?php
/*
* This file is part of EC-CUBE
*
* Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
*
* http://www.ec-cube.co.jp/
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Eccube\Util;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
use Symfony\Component\HttpKernel\CacheClearer\Psr6CacheClearer;
use Symfony\Component\HttpKernel\Event\TerminateEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\KernelInterface;
/**
* キャッシュ関連のユーティリティクラス.
*/
class CacheUtil implements EventSubscriberInterface
{
public const DOCTRINE_APP_CACHE_KEY = 'doctrine.app_cache_pool';
private $clearCacheAfterResponse = false;
/**
* @var KernelInterface
*/
protected $kernel;
/**
* @var ContainerInterface
*/
private $container;
/**
* CacheUtil constructor.
*
* @param KernelInterface $kernel
* @param ContainerInterface $container
*/
public function __construct(KernelInterface $kernel, ContainerInterface $container)
{
$this->kernel = $kernel;
$this->container = $container;
}
/**
* @param string $env
*/
public function clearCache($env = null)
{
$this->clearCacheAfterResponse = $env;
}
public function forceClearCache(TerminateEvent $event)
{
if ($this->clearCacheAfterResponse === false) {
return;
}
$console = new Application($this->kernel);
$console->setAutoExit(false);
$command = [
'command' => 'cache:clear',
'--no-warmup' => true,
'--no-ansi' => true,
];
if ($this->clearCacheAfterResponse !== null) {
$command['--env'] = $this->clearCacheAfterResponse;
}
$input = new ArrayInput($command);
$output = new BufferedOutput(
OutputInterface::VERBOSITY_DEBUG,
true
);
$console->run($input, $output);
if (function_exists('opcache_reset')) {
opcache_reset();
}
if (function_exists('apc_clear_cache')) {
apc_clear_cache('user');
apc_clear_cache();
}
if (function_exists('wincache_ucache_clear')) {
wincache_ucache_clear();
}
return $output->fetch();
}
/**
* Doctrineのキャッシュを削除します.
*
* @return string
*
* @throws \Exception
*/
public function clearDoctrineCache()
{
/** @var Psr6CacheClearer $poolClearer */
$poolClearer = $this->container->get('cache.global_clearer');
if (!$poolClearer->hasPool(self::DOCTRINE_APP_CACHE_KEY)) {
return;
}
$console = new Application($this->kernel);
$console->setAutoExit(false);
$command = [
'command' => 'cache:pool:clear',
'pools' => [self::DOCTRINE_APP_CACHE_KEY],
'--no-ansi' => true,
];
$input = new ArrayInput($command);
$output = new BufferedOutput(
OutputInterface::VERBOSITY_DEBUG,
true
);
$console->run($input, $output);
return $output->fetch();
}
/**
* Twigキャッシュを削除します.
*/
public function clearTwigCache()
{
$cacheDir = $this->kernel->getCacheDir().'/twig';
$fs = new Filesystem();
$fs->remove($cacheDir);
}
/**
* キャッシュを削除する.
*
* doctrine, profiler, twig によって生成されたキャッシュディレクトリを削除する.
* キャッシュは $app['config']['root_dir'].'/app/cache' に生成されます.
*
* @param Application $app
* @param boolean $isAll .gitkeep を残してすべてのファイル・ディレクトリを削除する場合 true, 各ディレクトリのみを削除する場合 false
* @param boolean $isTwig Twigキャッシュファイルのみ削除する場合 true
*
* @return boolean 削除に成功した場合 true
*
* @deprecated CacheUtil::clearCacheを利用すること
*/
public static function clear($app, $isAll, $isTwig = false)
{
$cacheDir = $app['config']['root_dir'].'/app/cache';
$filesystem = new Filesystem();
$finder = Finder::create()->notName('.gitkeep')->files();
if ($isAll) {
$finder = $finder->in($cacheDir);
$filesystem->remove($finder);
} elseif ($isTwig) {
if (is_dir($cacheDir.'/twig')) {
$finder = $finder->in($cacheDir.'/twig');
$filesystem->remove($finder);
}
} else {
if (is_dir($cacheDir.'/doctrine')) {
$finder = $finder->in($cacheDir.'/doctrine');
$filesystem->remove($finder);
}
if (is_dir($cacheDir.'/profiler')) {
$finder = $finder->in($cacheDir.'/profiler');
$filesystem->remove($finder);
}
if (is_dir($cacheDir.'/twig')) {
$finder = $finder->in($cacheDir.'/twig');
$filesystem->remove($finder);
}
if (is_dir($cacheDir.'/translator')) {
$finder = $finder->in($cacheDir.'/translator');
$filesystem->remove($finder);
}
}
if (function_exists('opcache_reset')) {
opcache_reset();
}
if (function_exists('apc_clear_cache')) {
apc_clear_cache('user');
apc_clear_cache();
}
if (function_exists('wincache_ucache_clear')) {
wincache_ucache_clear();
}
return true;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return [KernelEvents::TERMINATE => 'forceClearCache'];
}
}