AnnotationsCacheWarmer.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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\CacheWarmer;
  11. use Doctrine\Common\Annotations\AnnotationException;
  12. use Doctrine\Common\Annotations\CachedReader;
  13. use Doctrine\Common\Annotations\Reader;
  14. use Symfony\Component\Cache\Adapter\ArrayAdapter;
  15. use Symfony\Component\Cache\DoctrineProvider;
  16. /**
  17. * Warms up annotation caches for classes found in composer's autoload class map
  18. * and declared in DI bundle extensions using the addAnnotatedClassesToCache method.
  19. *
  20. * @author Titouan Galopin <galopintitouan@gmail.com>
  21. */
  22. class AnnotationsCacheWarmer extends AbstractPhpFileCacheWarmer
  23. {
  24. private $annotationReader;
  25. private $excludeRegexp;
  26. private $debug;
  27. /**
  28. * @param string $phpArrayFile The PHP file where annotations are cached
  29. */
  30. public function __construct(Reader $annotationReader, string $phpArrayFile, string $excludeRegexp = null, bool $debug = false)
  31. {
  32. parent::__construct($phpArrayFile);
  33. $this->annotationReader = $annotationReader;
  34. $this->excludeRegexp = $excludeRegexp;
  35. $this->debug = $debug;
  36. }
  37. /**
  38. * {@inheritdoc}
  39. */
  40. protected function doWarmUp(string $cacheDir, ArrayAdapter $arrayAdapter)
  41. {
  42. $annotatedClassPatterns = $cacheDir.'/annotations.map';
  43. if (!is_file($annotatedClassPatterns)) {
  44. return true;
  45. }
  46. $annotatedClasses = include $annotatedClassPatterns;
  47. $reader = new CachedReader($this->annotationReader, new DoctrineProvider($arrayAdapter), $this->debug);
  48. foreach ($annotatedClasses as $class) {
  49. if (null !== $this->excludeRegexp && preg_match($this->excludeRegexp, $class)) {
  50. continue;
  51. }
  52. try {
  53. $this->readAllComponents($reader, $class);
  54. } catch (\Exception $e) {
  55. $this->ignoreAutoloadException($class, $e);
  56. }
  57. }
  58. return true;
  59. }
  60. private function readAllComponents(Reader $reader, string $class)
  61. {
  62. $reflectionClass = new \ReflectionClass($class);
  63. try {
  64. $reader->getClassAnnotations($reflectionClass);
  65. } catch (AnnotationException $e) {
  66. /*
  67. * Ignore any AnnotationException to not break the cache warming process if an Annotation is badly
  68. * configured or could not be found / read / etc.
  69. *
  70. * In particular cases, an Annotation in your code can be used and defined only for a specific
  71. * environment but is always added to the annotations.map file by some Symfony default behaviors,
  72. * and you always end up with a not found Annotation.
  73. */
  74. }
  75. foreach ($reflectionClass->getMethods() as $reflectionMethod) {
  76. try {
  77. $reader->getMethodAnnotations($reflectionMethod);
  78. } catch (AnnotationException $e) {
  79. }
  80. }
  81. foreach ($reflectionClass->getProperties() as $reflectionProperty) {
  82. try {
  83. $reader->getPropertyAnnotations($reflectionProperty);
  84. } catch (AnnotationException $e) {
  85. }
  86. }
  87. }
  88. }