updated core and modules
This commit is contained in:
@@ -27,8 +27,6 @@ namespace Symfony\Component\Validator\Mapping;
|
||||
* Although the constants currently represent a boolean switch, they are
|
||||
* implemented as bit mask in order to allow future extensions.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @see TraversalStrategy
|
||||
|
||||
+52
-7
@@ -261,7 +261,7 @@ class ClassMetadata extends ElementMetadata implements ClassMetadataInterface
|
||||
* @param string $property The name of the property
|
||||
* @param Constraint $constraint The constraint
|
||||
*
|
||||
* @return ClassMetadata This object
|
||||
* @return $this
|
||||
*/
|
||||
public function addPropertyConstraint($property, Constraint $constraint)
|
||||
{
|
||||
@@ -282,7 +282,7 @@ class ClassMetadata extends ElementMetadata implements ClassMetadataInterface
|
||||
* @param string $property
|
||||
* @param Constraint[] $constraints
|
||||
*
|
||||
* @return ClassMetadata
|
||||
* @return $this
|
||||
*/
|
||||
public function addPropertyConstraints($property, array $constraints)
|
||||
{
|
||||
@@ -299,10 +299,11 @@ class ClassMetadata extends ElementMetadata implements ClassMetadataInterface
|
||||
* The name of the getter is assumed to be the name of the property with an
|
||||
* uppercased first letter and either the prefix "get" or "is".
|
||||
*
|
||||
* @param string $property The name of the property
|
||||
* @param Constraint $constraint The constraint
|
||||
* @param string $property The name of the property
|
||||
* @param Constraint $constraint The constraint
|
||||
* @param string|null $method The method that is called to retrieve the value being validated (null for auto-detection)
|
||||
*
|
||||
* @return ClassMetadata This object
|
||||
* @return $this
|
||||
*/
|
||||
public function addGetterConstraint($property, Constraint $constraint)
|
||||
{
|
||||
@@ -319,11 +320,35 @@ class ClassMetadata extends ElementMetadata implements ClassMetadataInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a constraint to the getter of the given property.
|
||||
*
|
||||
* @param string $property The name of the property
|
||||
* @param string $method The name of the getter method
|
||||
* @param Constraint $constraint The constraint
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addGetterMethodConstraint($property, $method, Constraint $constraint)
|
||||
{
|
||||
if (!isset($this->getters[$property])) {
|
||||
$this->getters[$property] = new GetterMetadata($this->getClassName(), $property, $method);
|
||||
|
||||
$this->addPropertyMetadata($this->getters[$property]);
|
||||
}
|
||||
|
||||
$constraint->addImplicitGroupName($this->getDefaultGroup());
|
||||
|
||||
$this->getters[$property]->addConstraint($constraint);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property
|
||||
* @param Constraint[] $constraints
|
||||
*
|
||||
* @return ClassMetadata
|
||||
* @return $this
|
||||
*/
|
||||
public function addGetterConstraints($property, array $constraints)
|
||||
{
|
||||
@@ -334,6 +359,22 @@ class ClassMetadata extends ElementMetadata implements ClassMetadataInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property
|
||||
* @param string $method
|
||||
* @param Constraint[] $constraints
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addGetterMethodConstraints($property, $method, array $constraints)
|
||||
{
|
||||
foreach ($constraints as $constraint) {
|
||||
$this->addGetterMethodConstraint($property, $method, $constraint);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the constraints of the given metadata into this object.
|
||||
*
|
||||
@@ -350,6 +391,10 @@ class ClassMetadata extends ElementMetadata implements ClassMetadataInterface
|
||||
$member = clone $member;
|
||||
|
||||
foreach ($member->getConstraints() as $constraint) {
|
||||
if (in_array($constraint::DEFAULT_GROUP, $constraint->groups, true)) {
|
||||
$member->constraintsByGroup[$this->getDefaultGroup()][] = $constraint;
|
||||
}
|
||||
|
||||
$constraint->addImplicitGroupName($this->getDefaultGroup());
|
||||
}
|
||||
|
||||
@@ -447,7 +492,7 @@ class ClassMetadata extends ElementMetadata implements ClassMetadataInterface
|
||||
*
|
||||
* @param array $groupSequence An array of group names
|
||||
*
|
||||
* @return ClassMetadata
|
||||
* @return $this
|
||||
*
|
||||
* @throws GroupDefinitionException
|
||||
*/
|
||||
|
||||
@@ -24,8 +24,6 @@ use Symfony\Component\Validator\PropertyMetadataContainerInterface as LegacyProp
|
||||
* by a group sequence for that class and whether instances of that class
|
||||
* should be traversed or not.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @see MetadataInterface
|
||||
|
||||
@@ -101,8 +101,11 @@ class LazyLoadingMetadataFactory implements MetadataFactoryInterface
|
||||
return $this->loadedClasses[$class];
|
||||
}
|
||||
|
||||
if (null !== $this->cache && false !== ($this->loadedClasses[$class] = $this->cache->read($class))) {
|
||||
return $this->loadedClasses[$class];
|
||||
if (null !== $this->cache && false !== ($metadata = $this->cache->read($class))) {
|
||||
// Include constraints from the parent class
|
||||
$this->mergeConstraints($metadata);
|
||||
|
||||
return $this->loadedClasses[$class] = $metadata;
|
||||
}
|
||||
|
||||
if (!class_exists($class) && !interface_exists($class)) {
|
||||
@@ -111,19 +114,6 @@ class LazyLoadingMetadataFactory implements MetadataFactoryInterface
|
||||
|
||||
$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);
|
||||
}
|
||||
@@ -132,9 +122,46 @@ class LazyLoadingMetadataFactory implements MetadataFactoryInterface
|
||||
$this->cache->write($metadata);
|
||||
}
|
||||
|
||||
// Include constraints from the parent class
|
||||
$this->mergeConstraints($metadata);
|
||||
|
||||
return $this->loadedClasses[$class] = $metadata;
|
||||
}
|
||||
|
||||
private function mergeConstraints(ClassMetadata $metadata)
|
||||
{
|
||||
// Include constraints from the parent class
|
||||
if ($parent = $metadata->getReflectionClass()->getParentClass()) {
|
||||
$metadata->mergeConstraints($this->getMetadataFor($parent->name));
|
||||
}
|
||||
|
||||
$interfaces = $metadata->getReflectionClass()->getInterfaces();
|
||||
|
||||
$interfaces = array_filter($interfaces, function ($interface) use ($parent, $interfaces) {
|
||||
$interfaceName = $interface->getName();
|
||||
|
||||
if ($parent && $parent->implementsInterface($interfaceName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($interfaces as $i) {
|
||||
if ($i !== $interface && $i->implementsInterface($interfaceName)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
// Include constraints from all directly implemented interfaces
|
||||
foreach ($interfaces as $interface) {
|
||||
if ('Symfony\Component\Validator\GroupSequenceProviderInterface' === $interface->name) {
|
||||
continue;
|
||||
}
|
||||
$metadata->mergeConstraints($this->getMetadataFor($interface->name));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -16,8 +16,6 @@ use Symfony\Component\Validator\MetadataFactoryInterface as LegacyMetadataFactor
|
||||
/**
|
||||
* Returns {@link \Symfony\Component\Validator\Mapping\MetadataInterface} instances for values.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
interface MetadataFactoryInterface extends LegacyMetadataFactoryInterface
|
||||
|
||||
+2
-4
@@ -23,8 +23,6 @@ use Symfony\Component\Validator\ValidationVisitorInterface;
|
||||
*
|
||||
* This class supports serialization and cloning.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class GenericMetadata implements MetadataInterface
|
||||
@@ -123,7 +121,7 @@ class GenericMetadata implements MetadataInterface
|
||||
*
|
||||
* @param Constraint $constraint The constraint to add
|
||||
*
|
||||
* @return GenericMetadata This object
|
||||
* @return $this
|
||||
*
|
||||
* @throws ConstraintDefinitionException When trying to add the
|
||||
* {@link Traverse} constraint
|
||||
@@ -169,7 +167,7 @@ class GenericMetadata implements MetadataInterface
|
||||
*
|
||||
* @param Constraint[] $constraints The constraints to add
|
||||
*
|
||||
* @return GenericMetadata This object
|
||||
* @return $this
|
||||
*/
|
||||
public function addConstraints(array $constraints)
|
||||
{
|
||||
|
||||
+19
-14
@@ -35,25 +35,30 @@ class GetterMetadata extends MemberMetadata
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $class The class the getter is defined on
|
||||
* @param string $property The property which the getter returns
|
||||
* @param string $class The class the getter is defined on
|
||||
* @param string $property The property which the getter returns
|
||||
* @param string|null $method The method that is called to retrieve the value being validated (null for auto-detection)
|
||||
*
|
||||
* @throws ValidatorException
|
||||
*/
|
||||
public function __construct($class, $property)
|
||||
public function __construct($class, $property, $method = null)
|
||||
{
|
||||
$getMethod = 'get'.ucfirst($property);
|
||||
$isMethod = 'is'.ucfirst($property);
|
||||
$hasMethod = 'has'.ucfirst($property);
|
||||
if (null === $method) {
|
||||
$getMethod = 'get'.ucfirst($property);
|
||||
$isMethod = 'is'.ucfirst($property);
|
||||
$hasMethod = 'has'.ucfirst($property);
|
||||
|
||||
if (method_exists($class, $getMethod)) {
|
||||
$method = $getMethod;
|
||||
} elseif (method_exists($class, $isMethod)) {
|
||||
$method = $isMethod;
|
||||
} elseif (method_exists($class, $hasMethod)) {
|
||||
$method = $hasMethod;
|
||||
} else {
|
||||
throw new ValidatorException(sprintf('Neither of these methods exist in class %s: %s, %s, %s', $class, $getMethod, $isMethod, $hasMethod));
|
||||
if (method_exists($class, $getMethod)) {
|
||||
$method = $getMethod;
|
||||
} elseif (method_exists($class, $isMethod)) {
|
||||
$method = $isMethod;
|
||||
} elseif (method_exists($class, $hasMethod)) {
|
||||
$method = $hasMethod;
|
||||
} else {
|
||||
throw new ValidatorException(sprintf('Neither of these methods exist in class %s: %s, %s, %s', $class, $getMethod, $isMethod, $hasMethod));
|
||||
}
|
||||
} elseif (!method_exists($class, $method)) {
|
||||
throw new ValidatorException(sprintf('The %s() method does not exist in class %s.', $method, $class));
|
||||
}
|
||||
|
||||
parent::__construct($class, $method, $property);
|
||||
|
||||
@@ -79,7 +79,7 @@ class AnnotationLoader implements LoaderInterface
|
||||
$metadata->addConstraint($constraint);
|
||||
} elseif ($constraint instanceof Constraint) {
|
||||
if (preg_match('/^(get|is|has)(.+)$/i', $method->name, $matches)) {
|
||||
$metadata->addGetterConstraint(lcfirst($matches[2]), $constraint);
|
||||
$metadata->addGetterMethodConstraint(lcfirst($matches[2]), $matches[0], $constraint);
|
||||
} else {
|
||||
throw new MappingException(sprintf('The constraint on "%s::%s" cannot be added. Constraints can only be added on methods beginning with "get", "is" or "has".', $className, $method->name));
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ class XmlFileLoader extends FileLoader
|
||||
$options = array();
|
||||
}
|
||||
} elseif (strlen((string) $node) > 0) {
|
||||
$options = trim($node);
|
||||
$options = XmlUtils::phpize(trim($node));
|
||||
} else {
|
||||
$options = null;
|
||||
}
|
||||
@@ -182,13 +182,7 @@ class XmlFileLoader extends FileLoader
|
||||
return simplexml_import_dom($dom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the validation metadata from the given XML class description.
|
||||
*
|
||||
* @param ClassMetadata $metadata The metadata to load
|
||||
* @param array $classDescription The XML class description
|
||||
*/
|
||||
private function loadClassMetadataFromXml(ClassMetadata $metadata, $classDescription)
|
||||
private function loadClassMetadataFromXml(ClassMetadata $metadata, \SimpleXMLElement $classDescription)
|
||||
{
|
||||
if (count($classDescription->{'group-sequence-provider'}) > 0) {
|
||||
$metadata->setGroupSequenceProvider(true);
|
||||
|
||||
@@ -46,13 +46,7 @@ class YamlFileLoader extends FileLoader
|
||||
$this->yamlParser = new YamlParser();
|
||||
}
|
||||
|
||||
// This method may throw an exception. Do not modify the class'
|
||||
// state before it completes
|
||||
if (false === ($classes = $this->parseFile($this->file))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->classes = $classes;
|
||||
$this->classes = $this->parseFile($this->file);
|
||||
|
||||
if (isset($this->classes['namespaces'])) {
|
||||
foreach ($this->classes['namespaces'] as $alias => $namespace) {
|
||||
@@ -111,7 +105,7 @@ class YamlFileLoader extends FileLoader
|
||||
*
|
||||
* @param string $path The path of the YAML file
|
||||
*
|
||||
* @return array|null The class descriptions or null, if the file was empty
|
||||
* @return array The class descriptions
|
||||
*
|
||||
* @throws \InvalidArgumentException If the file could not be loaded or did
|
||||
* not contain a YAML array
|
||||
@@ -126,7 +120,7 @@ class YamlFileLoader extends FileLoader
|
||||
|
||||
// empty file
|
||||
if (null === $classes) {
|
||||
return;
|
||||
return array();
|
||||
}
|
||||
|
||||
// not an array
|
||||
|
||||
@@ -24,8 +24,6 @@ use Symfony\Component\Validator\MetadataInterface as LegacyMetadataInterface;
|
||||
* against their class' metadata and whether traversable objects should be
|
||||
* traversed or not.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @see CascadingStrategy
|
||||
|
||||
+7
-1
@@ -39,7 +39,7 @@ class PropertyMetadata extends MemberMetadata
|
||||
public function __construct($class, $name)
|
||||
{
|
||||
if (!property_exists($class, $name)) {
|
||||
throw new ValidatorException(sprintf('Property %s does not exist in class %s', $name, $class));
|
||||
throw new ValidatorException(sprintf('Property "%s" does not exist in class "%s"', $name, $class));
|
||||
}
|
||||
|
||||
parent::__construct($class, $name, $name);
|
||||
@@ -58,8 +58,14 @@ class PropertyMetadata extends MemberMetadata
|
||||
*/
|
||||
protected function newReflectionMember($objectOrClassName)
|
||||
{
|
||||
$originalClass = is_string($objectOrClassName) ? $objectOrClassName : get_class($objectOrClassName);
|
||||
|
||||
while (!property_exists($objectOrClassName, $this->getName())) {
|
||||
$objectOrClassName = get_parent_class($objectOrClassName);
|
||||
|
||||
if (false === $objectOrClassName) {
|
||||
throw new ValidatorException(sprintf('Property "%s" does not exist in class "%s".', $this->getName(), $originalClass));
|
||||
}
|
||||
}
|
||||
|
||||
$member = new \ReflectionProperty($objectOrClassName, $this->getName());
|
||||
|
||||
@@ -24,8 +24,6 @@ use Symfony\Component\Validator\PropertyMetadataInterface as LegacyPropertyMetad
|
||||
* should be validated against their class' metadata and whether traversable
|
||||
* objects should be traversed or not.
|
||||
*
|
||||
* @since 2.5
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @see MetadataInterface
|
||||
|
||||
@@ -23,8 +23,6 @@ namespace Symfony\Component\Validator\Mapping;
|
||||
*
|
||||
* The traversal strategy is ignored for arrays. Arrays are always iterated.
|
||||
*
|
||||
* @since 2.1
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @see CascadingStrategy
|
||||
|
||||
Reference in New Issue
Block a user