<commit_before><?php

namespace Sidus\EAVModelBundle\Validator\Constraints;

use Doctrine\Bundle\DoctrineBundle\Registry;
use Exception;
use Sidus\EAVModelBundle\Configuration\FamilyConfigurationHandler;
use Sidus\EAVModelBundle\Entity\DataInterface;
use Sidus\EAVModelBundle\Entity\DataRepository;
use Sidus\EAVModelBundle\Entity\ValueInterface;
use Sidus\EAVModelBundle\Entity\ValueRepository;
use Sidus\EAVModelBundle\Model\AttributeInterface;
use Sidus\EAVModelBundle\Model\IdentifierAttributeType;
use Sidus\EAVModelBundle\Translator\TranslatableTrait;
use Sidus\EAVModelBundle\Validator\Mapping\Loader\BaseLoader;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\ConstraintViolationInterface;
use Symfony\Component\Validator\ConstraintViolationListInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;

/**
 * @property ExecutionContextInterface $context
 */
class DataValidator extends ConstraintValidator
{
    use TranslatableTrait;

    /** @var FamilyConfigurationHandler */
    protected $familyConfigurationHandler;

    /** @var string */
    protected $dataClass;

    /** @var Registry */
    protected $doctrine;

    /**
     * @param string                     $dataClass
     * @param FamilyConfigurationHandler $familyConfigurationHandler
     * @param TranslatorInterface        $translator
     * @param Registry                   $doctrine
     */
    public function __construct(
        $dataClass,
        FamilyConfigurationHandler $familyConfigurationHandler,
        TranslatorInterface $translator,
        Registry $doctrine
    ) {
        $this->dataClass = $dataClass;
        $this->familyConfigurationHandler = $familyConfigurationHandler;
        $this->translator = $translator;
        $this->doctrine = $doctrine;
    }

    /**
     * Checks if the passed value is valid.
     *
     * @param DataInterface $data       The value that should be validated
     * @param Constraint    $constraint The constraint for the validation
     * @return ConstraintViolationListInterface
     * @throws Exception
     */
    public function validate($data, Constraint $constraint)
    {
        if (!$data instanceof $this->dataClass) {
            $class = get_class($data);
            throw new \UnexpectedValueException("Can't validate data of class {$class}");
        }
        $context = $this->context; // VERY IMPORTANT ! context will be lost otherwise
        foreach ($data->getFamily()->getAttributes() as $attribute) {
            // Dynamically append data validator for embed types
            $type = $attribute->getType();
            if ($type->isEmbedded()) {
                $attribute->addValidationRules([
                    'Valid' => [],
                ]);
            }
            if ($attribute->isRequired() && $data->isEmpty($attribute)) {
                $this->buildAttributeViolation($context, $attribute, 'required', $data->getValueData($attribute));
            }
            if ($attribute->isUnique()) {
                $this->checkUnique($context, $attribute, $data);
            }
            if (count($attribute->getValidationRules())) {
                $this->validateRules($context, $attribute, $data);
            }
        }
    }

    /**
     * @param ExecutionContextInterface $context
     * @param AttributeInterface        $attribute
     * @param DataInterface             $data
     * @throws Exception
     */
    protected function checkUnique(
        ExecutionContextInterface $context,
        AttributeInterface $attribute,
        DataInterface $data
    ) {
        $valueData = $data->get($attribute->getCode());

        if ($attribute->getType() instanceof IdentifierAttributeType) {
            /** @var DataRepository $repo */
            $repo = $this->doctrine->getRepository($data->getFamily()->getDataClass());
            $result = $repo->findByIdentifier($data->getFamily(), $valueData);
            if ($result) {
                $this->buildAttributeViolation($context, $attribute, 'unique', $valueData);
            }

            return;
        }

        /** @var ValueRepository $repo */
        $repo = $this->doctrine->getRepository($data->getFamily()->getValueClass());
        $values = $repo->findBy([
            'attributeCode' => $attribute->getCode(),
            $attribute->getType()->getDatabaseType() => $valueData,
        ]);
        /** @var ValueInterface $value */
        foreach ($values as $value) {
            if (!$value->getData()) {
                continue; // @todo log error ?
            }
            if ($value->getData()->getId() !== $data->getId()) {<commit_msg>Removing @todo comments<commit_after><?php

namespace Sidus\EAVModelBundle\Validator\Constraints;

use Doctrine\Bundle\DoctrineBundle\Registry;
use Exception;
use Sidus\EAVModelBundle\Configuration\FamilyConfigurationHandler;
use Sidus\EAVModelBundle\Entity\DataInterface;
use Sidus\EAVModelBundle\Entity\DataRepository;
use Sidus\EAVModelBundle\Entity\ValueInterface;
use Sidus\EAVModelBundle\Entity\ValueRepository;
use Sidus\EAVModelBundle\Model\AttributeInterface;
use Sidus\EAVModelBundle\Model\IdentifierAttributeType;
use Sidus\EAVModelBundle\Translator\TranslatableTrait;
use Sidus\EAVModelBundle\Validator\Mapping\Loader\BaseLoader;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\ConstraintViolationInterface;
use Symfony\Component\Validator\ConstraintViolationListInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;

/**
 * @property ExecutionContextInterface $context
 */
class DataValidator extends ConstraintValidator
{
    use TranslatableTrait;

    /** @var FamilyConfigurationHandler */
    protected $familyConfigurationHandler;

    /** @var string */
    protected $dataClass;

    /** @var Registry */
    protected $doctrine;

    /**
     * @param string                     $dataClass
     * @param FamilyConfigurationHandler $familyConfigurationHandler
     * @param TranslatorInterface        $translator
     * @param Registry                   $doctrine
     */
    public function __construct(
        $dataClass,
        FamilyConfigurationHandler $familyConfigurationHandler,
        TranslatorInterface $translator,
        Registry $doctrine
    ) {
        $this->dataClass = $dataClass;
        $this->familyConfigurationHandler = $familyConfigurationHandler;
        $this->translator = $translator;
        $this->doctrine = $doctrine;
    }

    /**
     * Checks if the passed value is valid.
     *
     * @param DataInterface $data       The value that should be validated
     * @param Constraint    $constraint The constraint for the validation
     * @return ConstraintViolationListInterface
     * @throws Exception
     */
    public function validate($data, Constraint $constraint)
    {
        if (!$data instanceof $this->dataClass) {
            $class = get_class($data);
            throw new \UnexpectedValueException("Can't validate data of class {$class}");
        }
        $context = $this->context; // VERY IMPORTANT ! context will be lost otherwise
        foreach ($data->getFamily()->getAttributes() as $attribute) {
            // Dynamically append data validator for embed types
            $type = $attribute->getType();
            if ($type->isEmbedded()) {
                $attribute->addValidationRules([
                    'Valid' => [],
                ]);
            }
            if ($attribute->isRequired() && $data->isEmpty($attribute)) {
                $this->buildAttributeViolation($context, $attribute, 'required', $data->getValueData($attribute));
            }
            if ($attribute->isUnique()) {
                $this->checkUnique($context, $attribute, $data);
            }
            if (count($attribute->getValidationRules())) {
                $this->validateRules($context, $attribute, $data);
            }
        }
    }

    /**
     * @param ExecutionContextInterface $context
     * @param AttributeInterface        $attribute
     * @param DataInterface             $data
     * @throws Exception
     */
    protected function checkUnique(
        ExecutionContextInterface $context,
        AttributeInterface $attribute,
        DataInterface $data
    ) {
        $valueData = $data->get($attribute->getCode());

        if ($attribute->getType() instanceof IdentifierAttributeType) {
            /** @var DataRepository $repo */
            $repo = $this->doctrine->getRepository($data->getFamily()->getDataClass());
            $result = $repo->findByIdentifier($data->getFamily(), $valueData);
            if ($result) {
                $this->buildAttributeViolation($context, $attribute, 'unique', $valueData);
            }

            return;
        }

        /** @var ValueRepository $repo */
        $repo = $this->doctrine->getRepository($data->getFamily()->getValueClass());
        $values = $repo->findBy([
            'attributeCode' => $attribute->getCode(),
            $attribute->getType()->getDatabaseType() => $valueData,
        ]);
        /** @var ValueInterface $value */
        foreach ($values as $value) {
            if (!$value->getData()) {
                continue; // @warning this should not occur ! Log an error
            }
            if ($value->getData()->getId() !== $data->getId()) {
{'fraction_non_alphanumeric': 0.11737040133779264, 'fraction_numerical': 0.0, 'mean_word_length': 2.6467225609756095, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 91, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '808299', 'n_tokens_mistral': 2396, 'n_tokens_neox': 2371, 'n_words': 499}