CacheClearCommand.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Bundle\FrameworkBundle\Command;
  11. use Symfony\Component\Console\Input\InputInterface;
  12. use Symfony\Component\Console\Input\InputOption;
  13. use Symfony\Component\Console\Output\OutputInterface;
  14. use Symfony\Component\HttpKernel\KernelInterface;
  15. use Symfony\Component\Finder\Finder;
  16. /**
  17. * Clear and Warmup the cache.
  18. *
  19. * @author Francis Besset <francis.besset@gmail.com>
  20. * @author Fabien Potencier <fabien@symfony.com>
  21. */
  22. class CacheClearCommand extends Command
  23. {
  24. /**
  25. * @see Command
  26. */
  27. protected function configure()
  28. {
  29. $this
  30. ->setName('cache:clear')
  31. ->setDefinition(array(
  32. new InputOption('no-warmup', '', InputOption::VALUE_NONE, 'Do not warm up the cache'),
  33. new InputOption('without-debug', '', InputOption::VALUE_NONE, 'If the cache is warmed up, whether to disable debugging or not'),
  34. ))
  35. ->setDescription('Clear the cache')
  36. ->setHelp(<<<EOF
  37. The <info>cache:clear</info> command clears the application cache for a given environment
  38. and debug mode:
  39. <info>./app/console cache:clear --env=dev</info>
  40. <info>./app/console cache:clear --env=prod --without-debug</info>
  41. EOF
  42. )
  43. ;
  44. }
  45. /**
  46. * {@inheritdoc}
  47. */
  48. protected function execute(InputInterface $input, OutputInterface $output)
  49. {
  50. $realCacheDir = $this->container->getParameter('kernel.cache_dir');
  51. $oldCacheDir = $realCacheDir.'_old';
  52. if (!is_writable($realCacheDir)) {
  53. throw new \RuntimeException(sprintf('Unable to write in the "%s" directory', $realCacheDir));
  54. }
  55. if ($input->getOption('no-warmup')) {
  56. rename($realCacheDir, $oldCacheDir);
  57. } else {
  58. $warmupDir = $realCacheDir.'_new';
  59. $this->warmup(!$input->getOption('without-debug'), $warmupDir);
  60. rename($realCacheDir, $oldCacheDir);
  61. rename($warmupDir, $realCacheDir);
  62. }
  63. $this->container->get('filesystem')->remove($oldCacheDir);
  64. }
  65. protected function warmup($debug, $warmupDir)
  66. {
  67. $this->container->get('filesystem')->remove($warmupDir);
  68. $kernel = $this->getTempKernel($this->container->get('kernel'), $debug, $warmupDir);
  69. $kernel->boot();
  70. $warmer = $kernel->getContainer()->get('cache_warmer');
  71. $warmer->enableOptionalWarmers();
  72. $warmer->warmUp($warmupDir);
  73. // fix container files and classes
  74. $finder = new Finder();
  75. foreach ($finder->files()->name(get_class($kernel->getContainer()).'*')->in($warmupDir) as $file) {
  76. $content = file_get_contents($file);
  77. $content = preg_replace('/__.*__/', '', $content);
  78. file_put_contents(preg_replace('/__.*__/', '', $file), $content);
  79. unlink($file);
  80. }
  81. }
  82. protected function getTempKernel(KernelInterface $parent, $debug, $warmupDir)
  83. {
  84. $parentClass = get_class($parent);
  85. $namespace = '';
  86. if (false !== $pos = strrpos($parentClass, '\\')) {
  87. $namespace = substr($parentClass, 0, $pos);
  88. $parentClass = substr($parentClass, $pos + 1);
  89. }
  90. $rand = uniqid();
  91. $class = $parentClass.$rand;
  92. $rootDir = $parent->getRootDir();
  93. $code = <<<EOF
  94. <?php
  95. namespace $namespace
  96. {
  97. class $class extends $parentClass
  98. {
  99. public function getCacheDir()
  100. {
  101. return '$warmupDir';
  102. }
  103. public function getRootDir()
  104. {
  105. return '$rootDir';
  106. }
  107. protected function getContainerClass()
  108. {
  109. return parent::getContainerClass().'__{$rand}__';
  110. }
  111. }
  112. }
  113. EOF;
  114. $this->container->get('filesystem')->mkdir($warmupDir);
  115. file_put_contents($file = $warmupDir.'/kernel.tmp', $code);
  116. require_once $file;
  117. @unlink($file);
  118. $class = "$namespace\\$class";
  119. return new $class($parent->getEnvironment(), $debug);
  120. }
  121. }