<commit_before><?php
namespace Graviton\RestBundle\Validation;

use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ConstraintViolationList;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Validator\LegacyValidator AS Validator;
use Graviton\RestBundle\Model\DocumentModel;

/**
 * Validator class for json inputs
 *
 * @category GravitonRestBundle
 * @package  Graviton
 * @author   <NAME> <<EMAIL>>
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
 * @link     http://swisscom.com
 *
 * @todo refactor as to not use LegacyValidator that was introduced by the 2.5 bump
 */
class JsonInput
{
    /**
     * Validator
     *
     * @var Validator
     */
    private $validator;

    /**
     * Constructor
     *
     * @param Validator $validator Validator
     *
     * @return void
     */
    public function __construct(Validator $validator)
    {
        $this->validator = $validator;
    }

    /**
     * Validate the json input values and check for non existing values
     *
     * @param string        $input Json input string
     * @param DocumentModel $model Model
     *
     * @return ConstraintViolationList $violations Constraint violation list
     */
    public function validate($input, DocumentModel $model)
    {
        // get all fields of this document
        $manager = $model->getRepository()->getDocumentManager();
        $entityFields = $manager->getClassMetadata($model->getEntityClass())
            ->getFieldNames();

        // get validation info
        $classMetadata = $this->validator->getMetadataFor($model->getEntityClass());
        $constrainedProps = $classMetadata->getConstrainedProperties();

        $input = json_decode($input, true);

        $violations = new ConstraintViolationList();

        // Validate input values
        foreach ($constrainedProps as $prop) {
            $metadata = $classMetadata->getPropertyMetadata($prop);
            $constraints = $metadata[0]->constraints;

            // if the value is set, validate...
            if (isset($input[$prop])) {
                $val = $input[$prop];
                $validationResult = $this->validator->validateValue($val, $constraints);
                $violations->addAll($this->createNewViolationList($prop, $validationResult));
            } else {
                // if it's not set but required, validate with empty value
                if ($this->isRequired($constraints)) {
                    $validationResult = $this->validator->validateValue(null, $constraints);
                    $violations->addAll($this->createNewViolationList($prop, $validationResult));
                }
            }
        }

        // Check for non existing attributes
        foreach (array_keys($input) as $key) {
            if (!in_array($key, $entityFields)) {
                $violation = new ConstraintViolation(
                    'Attribute does not exist!',
                    'Attribute does not exist!',
                    array(),
                    $key,
                    $key,
                    $key
                );

                $violations->add($violation);
            }
        }

        return $violations;
    }

    /**
     * Checks if a value is required
     *
     * @param array $constraints constraints for this value
     *
     * @return boolean $required true/false
     */
    private function isRequired($constraints)
    {
        $required = false;

        foreach ($constraints as $constraint) {
            if ($constraint instanceof NotBlank) {
                $required = true;
            }
        }

        return $required;
    }

    /**
     * Create a new violation list with the given violations
     *
     * @param string                  $prop             Property
     * @param ConstraintViolationList $validationResult Violation list
     *
     * @return ConstraintViolationList $violations Violations
     */
    private function createNewViolationList($prop, $validationResult)
    {
        $violations = new ConstraintViolationList();

        foreach ($validationResult as $violation) {
            $newViolation = new ConstraintViolation(
                $violation->getMessage(),
                $violation->getMessageTemplate(),
                $violation->getParameters(),
                $violation->getRoot(),
                $prop,
                $violation->getInvalidValue(),
                $violation->getPlural(),
                $violation->getCode()
            );

            $violations->add($newViolation);
        }

        return $violations;
    }
}
<commit_msg>php-cs fix<commit_after><?php
namespace Graviton\RestBundle\Validation;

use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ConstraintViolationList;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Validator\LegacyValidator as Validator;
use Graviton\RestBundle\Model\DocumentModel;

/**
 * Validator class for json inputs
 *
 * @category GravitonRestBundle
 * @package  Graviton
 * @author   <NAME> <<EMAIL>>
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
 * @link     http://swisscom.com
 *
 * @todo refactor as to not use LegacyValidator that was introduced by the 2.5 bump
 */
class JsonInput
{
    /**
     * Validator
     *
     * @var Validator
     */
    private $validator;

    /**
     * Constructor
     *
     * @param Validator $validator Validator
     *
     * @return void
     */
    public function __construct(Validator $validator)
    {
        $this->validator = $validator;
    }

    /**
     * Validate the json input values and check for non existing values
     *
     * @param string        $input Json input string
     * @param DocumentModel $model Model
     *
     * @return ConstraintViolationList $violations Constraint violation list
     */
    public function validate($input, DocumentModel $model)
    {
        // get all fields of this document
        $manager = $model->getRepository()->getDocumentManager();
        $entityFields = $manager->getClassMetadata($model->getEntityClass())
            ->getFieldNames();

        // get validation info
        $classMetadata = $this->validator->getMetadataFor($model->getEntityClass());
        $constrainedProps = $classMetadata->getConstrainedProperties();

        $input = json_decode($input, true);

        $violations = new ConstraintViolationList();

        // Validate input values
        foreach ($constrainedProps as $prop) {
            $metadata = $classMetadata->getPropertyMetadata($prop);
            $constraints = $metadata[0]->constraints;

            // if the value is set, validate...
            if (isset($input[$prop])) {
                $val = $input[$prop];
                $validationResult = $this->validator->validateValue($val, $constraints);
                $violations->addAll($this->createNewViolationList($prop, $validationResult));
            } else {
                // if it's not set but required, validate with empty value
                if ($this->isRequired($constraints)) {
                    $validationResult = $this->validator->validateValue(null, $constraints);
                    $violations->addAll($this->createNewViolationList($prop, $validationResult));
                }
            }
        }

        // Check for non existing attributes
        foreach (array_keys($input) as $key) {
            if (!in_array($key, $entityFields)) {
                $violation = new ConstraintViolation(
                    'Attribute does not exist!',
                    'Attribute does not exist!',
                    array(),
                    $key,
                    $key,
                    $key
                );

                $violations->add($violation);
            }
        }

        return $violations;
    }

    /**
     * Checks if a value is required
     *
     * @param array $constraints constraints for this value
     *
     * @return boolean $required true/false
     */
    private function isRequired($constraints)
    {
        $required = false;

        foreach ($constraints as $constraint) {
            if ($constraint instanceof NotBlank) {
                $required = true;
            }
        }

        return $required;
    }

    /**
     * Create a new violation list with the given violations
     *
     * @param string                  $prop             Property
     * @param ConstraintViolationList $validationResult Violation list
     *
     * @return ConstraintViolationList $violations Violations
     */
    private function createNewViolationList($prop, $validationResult)
    {
        $violations = new ConstraintViolationList();

        foreach ($validationResult as $violation) {
            $newViolation = new ConstraintViolation(
                $violation->getMessage(),
                $violation->getMessageTemplate(),
                $violation->getParameters(),
                $violation->getRoot(),
                $prop,
                $violation->getInvalidValue(),
                $violation->getPlural(),
                $violation->getCode()
            );

            $violations->add($newViolation);
        }

        return $violations;
    }
}

{'fraction_non_alphanumeric': 0.10616914359029188, 'fraction_numerical': 0.0006415053993371111, 'mean_word_length': 1.9780324737344794, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 69, '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': '3863783', 'n_tokens_mistral': 2428, 'n_tokens_neox': 2343, 'n_words': 559}