Chris@0: Chris@0: * Chris@0: * For the full copyright and license information, please view the LICENSE Chris@0: * file that was distributed with this source code. Chris@0: */ Chris@0: Chris@0: namespace Symfony\Component\Serializer\Mapping\Factory; Chris@0: Chris@0: use Doctrine\Common\Cache\Cache; Chris@0: use Symfony\Component\Serializer\Exception\InvalidArgumentException; Chris@0: use Symfony\Component\Serializer\Mapping\ClassMetadata; Chris@0: use Symfony\Component\Serializer\Mapping\Loader\LoaderInterface; Chris@0: Chris@0: /** Chris@0: * Returns a {@link ClassMetadata}. Chris@0: * Chris@0: * @author Kévin Dunglas Chris@0: */ Chris@0: class ClassMetadataFactory implements ClassMetadataFactoryInterface Chris@0: { Chris@0: use ClassResolverTrait; Chris@0: Chris@0: private $loader; Chris@0: private $cache; Chris@0: private $loadedClasses; Chris@0: Chris@0: public function __construct(LoaderInterface $loader, Cache $cache = null) Chris@0: { Chris@0: $this->loader = $loader; Chris@0: $this->cache = $cache; Chris@0: Chris@0: if (null !== $cache) { Chris@14: @trigger_error(sprintf('Passing a Doctrine Cache instance as 2nd parameter of the "%s" constructor is deprecated since Symfony 3.1. This parameter will be removed in Symfony 4.0. Use the "%s" class instead.', __CLASS__, CacheClassMetadataFactory::class), E_USER_DEPRECATED); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function getMetadataFor($value) Chris@0: { Chris@0: $class = $this->getClass($value); Chris@0: Chris@0: if (isset($this->loadedClasses[$class])) { Chris@0: return $this->loadedClasses[$class]; Chris@0: } Chris@0: Chris@0: if ($this->cache && ($this->loadedClasses[$class] = $this->cache->fetch($class))) { Chris@0: return $this->loadedClasses[$class]; Chris@0: } Chris@0: Chris@0: $classMetadata = new ClassMetadata($class); Chris@0: $this->loader->loadClassMetadata($classMetadata); Chris@0: Chris@0: $reflectionClass = $classMetadata->getReflectionClass(); Chris@0: Chris@0: // Include metadata from the parent class Chris@0: if ($parent = $reflectionClass->getParentClass()) { Chris@0: $classMetadata->merge($this->getMetadataFor($parent->name)); Chris@0: } Chris@0: Chris@0: // Include metadata from all implemented interfaces Chris@0: foreach ($reflectionClass->getInterfaces() as $interface) { Chris@0: $classMetadata->merge($this->getMetadataFor($interface->name)); Chris@0: } Chris@0: Chris@0: if ($this->cache) { Chris@0: $this->cache->save($class, $classMetadata); Chris@0: } Chris@0: Chris@0: return $this->loadedClasses[$class] = $classMetadata; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function hasMetadataFor($value) Chris@0: { Chris@0: try { Chris@0: $this->getClass($value); Chris@0: Chris@0: return true; Chris@0: } catch (InvalidArgumentException $invalidArgumentException) { Chris@0: // Return false in case of exception Chris@0: } Chris@0: Chris@0: return false; Chris@0: } Chris@0: }