mailpoet
/
vendor-prefixed
/
symfony
/
validator
/
Mapping
/
Factory
/
LazyLoadingMetadataFactory.php
BlackHoleMetadataFactory.php
4 years ago
LazyLoadingMetadataFactory.php
1 year ago
MetadataFactoryInterface.php
4 years ago
index.php
3 years ago
LazyLoadingMetadataFactory.php
85 lines
| 1 | <?php |
| 2 | namespace MailPoetVendor\Symfony\Component\Validator\Mapping\Factory; |
| 3 | if (!defined('ABSPATH')) exit; |
| 4 | use MailPoetVendor\Psr\Cache\CacheItemPoolInterface; |
| 5 | use MailPoetVendor\Symfony\Component\Validator\Exception\NoSuchMetadataException; |
| 6 | use MailPoetVendor\Symfony\Component\Validator\Mapping\ClassMetadata; |
| 7 | use MailPoetVendor\Symfony\Component\Validator\Mapping\Loader\LoaderInterface; |
| 8 | class LazyLoadingMetadataFactory implements MetadataFactoryInterface |
| 9 | { |
| 10 | protected $loader; |
| 11 | protected $cache; |
| 12 | protected $loadedClasses = []; |
| 13 | public function __construct(?LoaderInterface $loader = null, ?CacheItemPoolInterface $cache = null) |
| 14 | { |
| 15 | $this->loader = $loader; |
| 16 | $this->cache = $cache; |
| 17 | } |
| 18 | public function getMetadataFor($value) |
| 19 | { |
| 20 | if (!\is_object($value) && !\is_string($value)) { |
| 21 | throw new NoSuchMetadataException(\sprintf('Cannot create metadata for non-objects. Got: "%s".', \get_debug_type($value))); |
| 22 | } |
| 23 | $class = \ltrim(\is_object($value) ? \get_class($value) : $value, '\\'); |
| 24 | if (isset($this->loadedClasses[$class])) { |
| 25 | return $this->loadedClasses[$class]; |
| 26 | } |
| 27 | if (!\class_exists($class) && !\interface_exists($class, \false)) { |
| 28 | throw new NoSuchMetadataException(\sprintf('The class or interface "%s" does not exist.', $class)); |
| 29 | } |
| 30 | $cacheItem = null === $this->cache ? null : $this->cache->getItem($this->escapeClassName($class)); |
| 31 | if ($cacheItem && $cacheItem->isHit()) { |
| 32 | $metadata = $cacheItem->get(); |
| 33 | // Include constraints from the parent class |
| 34 | $this->mergeConstraints($metadata); |
| 35 | return $this->loadedClasses[$class] = $metadata; |
| 36 | } |
| 37 | $metadata = new ClassMetadata($class); |
| 38 | if (null !== $this->loader) { |
| 39 | $this->loader->loadClassMetadata($metadata); |
| 40 | } |
| 41 | if (null !== $cacheItem) { |
| 42 | $this->cache->save($cacheItem->set($metadata)); |
| 43 | } |
| 44 | // Include constraints from the parent class |
| 45 | $this->mergeConstraints($metadata); |
| 46 | return $this->loadedClasses[$class] = $metadata; |
| 47 | } |
| 48 | private function mergeConstraints(ClassMetadata $metadata) |
| 49 | { |
| 50 | if ($metadata->getReflectionClass()->isInterface()) { |
| 51 | return; |
| 52 | } |
| 53 | // Include constraints from the parent class |
| 54 | if ($parent = $metadata->getReflectionClass()->getParentClass()) { |
| 55 | $metadata->mergeConstraints($this->getMetadataFor($parent->name)); |
| 56 | } |
| 57 | // Include constraints from all directly implemented interfaces |
| 58 | foreach ($metadata->getReflectionClass()->getInterfaces() as $interface) { |
| 59 | if ('Symfony\\Component\\Validator\\GroupSequenceProviderInterface' === $interface->name) { |
| 60 | continue; |
| 61 | } |
| 62 | if ($parent && \in_array($interface->getName(), $parent->getInterfaceNames(), \true)) { |
| 63 | continue; |
| 64 | } |
| 65 | $metadata->mergeConstraints($this->getMetadataFor($interface->name)); |
| 66 | } |
| 67 | } |
| 68 | public function hasMetadataFor($value) |
| 69 | { |
| 70 | if (!\is_object($value) && !\is_string($value)) { |
| 71 | return \false; |
| 72 | } |
| 73 | $class = \ltrim(\is_object($value) ? \get_class($value) : $value, '\\'); |
| 74 | return \class_exists($class) || \interface_exists($class, \false); |
| 75 | } |
| 76 | private function escapeClassName(string $class) : string |
| 77 | { |
| 78 | if (\str_contains($class, '@')) { |
| 79 | // anonymous class: replace all PSR6-reserved characters |
| 80 | return \str_replace(["\x00", '\\', '/', '@', ':', '{', '}', '(', ')'], '.', $class); |
| 81 | } |
| 82 | return \str_replace('\\', '.', $class); |
| 83 | } |
| 84 | } |
| 85 |