Вход Регистрация
Файл: symfony-2.7/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php
Строк: 272
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace SymfonyBridgeDoctrineValidatorConstraints;

use 
DoctrineCommonPersistenceManagerRegistry;
use 
SymfonyComponentValidatorContextExecutionContextInterface;
use 
SymfonyComponentValidatorConstraint;
use 
SymfonyComponentValidatorExceptionUnexpectedTypeException;
use 
SymfonyComponentValidatorExceptionConstraintDefinitionException;
use 
SymfonyComponentValidatorConstraintValidator;

/**
 * Unique Entity Validator checks if one or a set of fields contain unique values.
 *
 * @author Benjamin Eberlei <kontakt@beberlei.de>
 */
class UniqueEntityValidator extends ConstraintValidator
{
    
/**
     * @var ManagerRegistry
     */
    
private $registry;

    public function 
__construct(ManagerRegistry $registry)
    {
        
$this->registry $registry;
    }

    
/**
     * @param object     $entity
     * @param Constraint $constraint
     *
     * @throws UnexpectedTypeException
     * @throws ConstraintDefinitionException
     */
    
public function validate($entityConstraint $constraint)
    {
        if (!
$constraint instanceof UniqueEntity) {
            throw new 
UnexpectedTypeException($constraint__NAMESPACE__.'UniqueEntity');
        }

        if (!
is_array($constraint->fields) && !is_string($constraint->fields)) {
            throw new 
UnexpectedTypeException($constraint->fields'array');
        }

        if (
null !== $constraint->errorPath && !is_string($constraint->errorPath)) {
            throw new 
UnexpectedTypeException($constraint->errorPath'string or null');
        }

        
$fields = (array) $constraint->fields;

        if (
=== count($fields)) {
            throw new 
ConstraintDefinitionException('At least one field has to be specified.');
        }

        if (
$constraint->em) {
            
$em $this->registry->getManager($constraint->em);

            if (!
$em) {
                throw new 
ConstraintDefinitionException(sprintf('Object manager "%s" does not exist.'$constraint->em));
            }
        } else {
            
$em $this->registry->getManagerForClass(get_class($entity));

            if (!
$em) {
                throw new 
ConstraintDefinitionException(sprintf('Unable to find the object manager associated with an entity of class "%s".'get_class($entity)));
            }
        }

        
$class $em->getClassMetadata(get_class($entity));
        
/* @var $class DoctrineCommonPersistenceMappingClassMetadata */

        
$criteria = array();
        foreach (
$fields as $fieldName) {
            if (!
$class->hasField($fieldName) && !$class->hasAssociation($fieldName)) {
                throw new 
ConstraintDefinitionException(sprintf("The field '%s' is not mapped by Doctrine, so it cannot be validated for uniqueness."$fieldName));
            }

            
$criteria[$fieldName] = $class->reflFields[$fieldName]->getValue($entity);

            if (
$constraint->ignoreNull && null === $criteria[$fieldName]) {
                return;
            }

            if (
null !== $criteria[$fieldName] && $class->hasAssociation($fieldName)) {
                
/* Ensure the Proxy is initialized before using reflection to
                 * read its identifiers. This is necessary because the wrapped
                 * getter methods in the Proxy are being bypassed.
                 */
                
$em->initializeObject($criteria[$fieldName]);

                
$relatedClass $em->getClassMetadata($class->getAssociationTargetClass($fieldName));
                
$relatedId $relatedClass->getIdentifierValues($criteria[$fieldName]);

                if (
count($relatedId) > 1) {
                    throw new 
ConstraintDefinitionException(
                        
"Associated entities are not allowed to have more than one identifier field to be ".
                        
"part of a unique constraint in: ".$class->getName()."#".$fieldName
                    
);
                }
                
$criteria[$fieldName] = array_pop($relatedId);
            }
        }

        
$repository $em->getRepository(get_class($entity));
        
$result $repository->{$constraint->repositoryMethod}($criteria);

        
/* If the result is a MongoCursor, it must be advanced to the first
         * element. Rewinding should have no ill effect if $result is another
         * iterator implementation.
         */
        
if ($result instanceof Iterator) {
            
$result->rewind();
        } elseif (
is_array($result)) {
            
reset($result);
        }

        
/* If no entity matched the query criteria or a single entity matched,
         * which is the same as the entity being validated, the criteria is
         * unique.
         */
        
if (=== count($result) || (=== count($result) && $entity === ($result instanceof Iterator $result->current() : current($result)))) {
            return;
        }

        
$errorPath null !== $constraint->errorPath $constraint->errorPath $fields[0];

        if (
$this->context instanceof ExecutionContextInterface) {
            
$this->context->buildViolation($constraint->message)
                ->
atPath($errorPath)
                ->
setInvalidValue($criteria[$fields[0]])
                ->
addViolation();
        } else {
            
$this->buildViolation($constraint->message)
                ->
atPath($errorPath)
                ->
setInvalidValue($criteria[$fields[0]])
                ->
addViolation();
        }
    }
}
Онлайн: 1
Реклама