* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Validator\Mapping; use Symfony\Component\Validator\MetadataFactoryInterface; use Symfony\Component\Validator\Exception\NoSuchMetadataException; use Symfony\Component\Validator\Mapping\Loader\LoaderInterface; use Symfony\Component\Validator\Mapping\Cache\CacheInterface; /** * A factory for creating metadata for PHP classes. * * @author Bernhard Schussek */ class ClassMetadataFactory implements MetadataFactoryInterface { /** * The loader for loading the class metadata * @var LoaderInterface */ protected $loader; /** * The cache for caching class metadata * @var CacheInterface */ protected $cache; protected $loadedClasses = array(); public function __construct(LoaderInterface $loader = null, CacheInterface $cache = null) { $this->loader = $loader; $this->cache = $cache; } /** * {@inheritdoc} */ public function getMetadataFor($value) { if (!is_object($value) && !is_string($value)) { throw new NoSuchMetadataException(sprintf('Cannot create metadata for non-objects. Got: %s', gettype($value))); } $class = ltrim(is_object($value) ? get_class($value) : $value, '\\'); if (isset($this->loadedClasses[$class])) { return $this->loadedClasses[$class]; } if (null !== $this->cache && false !== ($this->loadedClasses[$class] = $this->cache->read($class))) { return $this->loadedClasses[$class]; } if (!class_exists($class) && !interface_exists($class)) { throw new NoSuchMetadataException(sprintf('The class or interface "%s" does not exist.', $class)); } $metadata = new ClassMetadata($class); // Include constraints from the parent class if ($parent = $metadata->getReflectionClass()->getParentClass()) { $metadata->mergeConstraints($this->getMetadataFor($parent->name)); } // Include constraints from all implemented interfaces foreach ($metadata->getReflectionClass()->getInterfaces() as $interface) { if ('Symfony\Component\Validator\GroupSequenceProviderInterface' === $interface->name) { continue; } $metadata->mergeConstraints($this->getMetadataFor($interface->name)); } if (null !== $this->loader) { $this->loader->loadClassMetadata($metadata); } if (null !== $this->cache) { $this->cache->write($metadata); } return $this->loadedClasses[$class] = $metadata; } /** * {@inheritdoc} */ public function hasMetadataFor($value) { if (!is_object($value) && !is_string($value)) { return false; } $class = ltrim(is_object($value) ? get_class($value) : $value, '\\'); if (class_exists($class) || interface_exists($class)) { return true; } return false; } }