ClassMetadataFactory.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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\Component\Serializer\Mapping\Factory;
  11. use Doctrine\Common\Cache\Cache;
  12. use Symfony\Component\Serializer\Exception\InvalidArgumentException;
  13. use Symfony\Component\Serializer\Mapping\ClassMetadata;
  14. use Symfony\Component\Serializer\Mapping\Loader\LoaderInterface;
  15. /**
  16. * Returns a {@link ClassMetadata}.
  17. *
  18. * @author Kévin Dunglas <dunglas@gmail.com>
  19. */
  20. class ClassMetadataFactory implements ClassMetadataFactoryInterface
  21. {
  22. use ClassResolverTrait;
  23. /**
  24. * @var LoaderInterface
  25. */
  26. private $loader;
  27. /**
  28. * @var Cache
  29. */
  30. private $cache;
  31. /**
  32. * @var array
  33. */
  34. private $loadedClasses;
  35. /**
  36. * @param LoaderInterface $loader
  37. * @param Cache|null $cache
  38. */
  39. public function __construct(LoaderInterface $loader, Cache $cache = null)
  40. {
  41. $this->loader = $loader;
  42. $this->cache = $cache;
  43. if (null !== $cache) {
  44. @trigger_error(sprintf('Passing a Doctrine Cache instance as 2nd parameter of the "%s" constructor is deprecated since version 3.1. This parameter will be removed in Symfony 4.0. Use the "%s" class instead.', __CLASS__, CacheClassMetadataFactory::class), E_USER_DEPRECATED);
  45. }
  46. }
  47. /**
  48. * {@inheritdoc}
  49. */
  50. public function getMetadataFor($value)
  51. {
  52. $class = $this->getClass($value);
  53. if (isset($this->loadedClasses[$class])) {
  54. return $this->loadedClasses[$class];
  55. }
  56. if ($this->cache && ($this->loadedClasses[$class] = $this->cache->fetch($class))) {
  57. return $this->loadedClasses[$class];
  58. }
  59. $classMetadata = new ClassMetadata($class);
  60. $this->loader->loadClassMetadata($classMetadata);
  61. $reflectionClass = $classMetadata->getReflectionClass();
  62. // Include metadata from the parent class
  63. if ($parent = $reflectionClass->getParentClass()) {
  64. $classMetadata->merge($this->getMetadataFor($parent->name));
  65. }
  66. // Include metadata from all implemented interfaces
  67. foreach ($reflectionClass->getInterfaces() as $interface) {
  68. $classMetadata->merge($this->getMetadataFor($interface->name));
  69. }
  70. if ($this->cache) {
  71. $this->cache->save($class, $classMetadata);
  72. }
  73. return $this->loadedClasses[$class] = $classMetadata;
  74. }
  75. /**
  76. * {@inheritdoc}
  77. */
  78. public function hasMetadataFor($value)
  79. {
  80. try {
  81. $this->getClass($value);
  82. return true;
  83. } catch (InvalidArgumentException $invalidArgumentException) {
  84. // Return false in case of exception
  85. }
  86. return false;
  87. }
  88. }