CacheClearCommand.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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. ))
  34. ->setDescription('Clear the cache')
  35. ->setHelp(<<<EOF
  36. The <info>cache:clear</info> command clears the application cache for a given environment
  37. and debug mode:
  38. <info>./app/console cache:clear --env=dev</info>
  39. <info>./app/console cache:clear --env=prod --no-debug</info>
  40. EOF
  41. )
  42. ;
  43. }
  44. /**
  45. * {@inheritdoc}
  46. */
  47. protected function execute(InputInterface $input, OutputInterface $output)
  48. {
  49. $realCacheDir = $this->container->getParameter('kernel.cache_dir');
  50. $oldCacheDir = $realCacheDir.'_old';
  51. if (!is_writable($realCacheDir)) {
  52. throw new \RuntimeException(sprintf('Unable to write in the "%s" directory', $realCacheDir));
  53. }
  54. if ($input->getOption('no-warmup')) {
  55. rename($realCacheDir, $oldCacheDir);
  56. } else {
  57. $warmupDir = $realCacheDir.'_new';
  58. $this->warmup($warmupDir);
  59. rename($realCacheDir, $oldCacheDir);
  60. rename($warmupDir, $realCacheDir);
  61. }
  62. $this->container->get('filesystem')->remove($oldCacheDir);
  63. }
  64. protected function warmup($warmupDir)
  65. {
  66. $this->container->get('filesystem')->remove($warmupDir);
  67. $kernel = $this->getTempKernel($this->container->get('kernel'), $warmupDir);
  68. $kernel->boot();
  69. $warmer = $kernel->getContainer()->get('cache_warmer');
  70. $warmer->enableOptionalWarmers();
  71. $warmer->warmUp($warmupDir);
  72. // fix container files and classes
  73. $finder = new Finder();
  74. foreach ($finder->files()->name(get_class($kernel->getContainer()).'*')->in($warmupDir) as $file) {
  75. $content = file_get_contents($file);
  76. $content = preg_replace('/__.*__/', '', $content);
  77. file_put_contents(preg_replace('/__.*__/', '', $file), $content);
  78. unlink($file);
  79. }
  80. }
  81. protected function getTempKernel(KernelInterface $parent, $warmupDir)
  82. {
  83. $parentClass = get_class($parent);
  84. $namespace = '';
  85. if (false !== $pos = strrpos($parentClass, '\\')) {
  86. $namespace = substr($parentClass, 0, $pos);
  87. $parentClass = substr($parentClass, $pos + 1);
  88. }
  89. $rand = uniqid();
  90. $class = $parentClass.$rand;
  91. $rootDir = $parent->getRootDir();
  92. $code = <<<EOF
  93. <?php
  94. namespace $namespace
  95. {
  96. class $class extends $parentClass
  97. {
  98. public function getCacheDir()
  99. {
  100. return '$warmupDir';
  101. }
  102. public function getRootDir()
  103. {
  104. return '$rootDir';
  105. }
  106. protected function getContainerClass()
  107. {
  108. return parent::getContainerClass().'__{$rand}__';
  109. }
  110. }
  111. }
  112. EOF;
  113. $this->container->get('filesystem')->mkdir($warmupDir);
  114. file_put_contents($file = $warmupDir.'/kernel.tmp', $code);
  115. require_once $file;
  116. @unlink($file);
  117. $class = "$namespace\\$class";
  118. return new $class($parent->getEnvironment(), $parent->isDebug());
  119. }
  120. }