<commit_before><?php

namespace AV\LaravelForm\ValidatorExtension;

use AV\Form\FormError;
use AV\Form\FormHandler;
use AV\Form\ValidatorExtension\ValidatorExtensionInterface;

class LaravelValidatorExtension implements ValidatorExtensionInterface
{
    /**
     * @var FormHandler
     */
    private $formHandler;

    /**
     * @var bool
     */
    private $isValid = true;

    /**
     * @var \Illuminate\Validation\Validator
     */
    private $validator;

    /**
     * Sets the form handler
     *
     * @param \AV\Form\FormHandler $formHandler
     * @return mixed
     */
    public function setFormHandler(FormHandler $formHandler)
    {
        $this->formHandler = $formHandler;
    }

    /**
     * Validate the form
     *
     * @param null $scope
     * @param null $options
     * @return mixed
     * @throws \Exception
     */
    private function validate()
    {
        if (isset($this->validator)) {
            throw new \Exception('Cannot validate the same form twice, use the existing result');
        }

        $fieldRules = $this->getFieldValidationRules($this->formHandler->getFormBlueprint()->getAll());

        $validationRules = $fieldRules['rules'];
        $validationAttributeNames = $fieldRules['names'];

        // Get validation rules from any assigned entities (models)
        foreach ($this->formHandler->getEntities() as $entity) {
            if (is_callable([$entity['entity'], 'getValidationRules'])) {

                try {
                    $entityRules = $entity['entity']->getValidationRules();
                } catch (\BadMethodCallException $e) {
                    $entityRules = [];
                }

                foreach ($entityRules as $field => $entityRule) {
                    // If we already have rules for that parameter, concatenate them
                    if (isset($validationRules[$field])) {
                        $validationRules[$field] .= '|'.$entityRule;
                    }
                    // Rules for a parameter that doesn't have any yet
                    else {
                        $validationRules[$field] = $entityRule;
                    }
                }
            }
        }

        $this->validator = \Validator::make($this->formHandler->getData(), $validationRules);

        $this->validator->setAttributeNames($validationAttributeNames);

        $this->isValid = $this->validator->passes();
    }

    /**
     * Recursively read in the validation rules from the form fields and convert the field names to dot notation
     * 
     * @param $fields
     * @return array
     */
    private function getFieldValidationRules($fields)
    {
        $results = ['rules' => [], 'names' => []];

        foreach ($fields as $field) {
            if (isset($field['options']['validation'])) {
                if (!isset($field['original_name'])) {
                    $paramName = $field['name'];
                } else {
                    $paramName = $this->fieldNameToDot($field['original_name']);
                }

                $results['rules'][$paramName] = $field['options']['validation'];

                if (isset($field['options']['label'])) {
                    $results['names'][$paramName] = $field['options']['label'];
                }
            }

            if (isset($field['fields'])) {
                $results = array_merge_recursive($results, $this->getFieldValidationRules($field['fields']));
            }
        }

        return $results;
    }

    /**
     * Convert a form field name to dot notation for the Laravel validator
     * 
     * @param $fieldName
     * @return string
     */
    private function fieldNameToDot($fieldName)
    {
        $fieldName = trim(str_replace(['][', '[', ']'], '.', $fieldName), '.');

        return $fieldName;
    }

    /**
     * Check if the form is valid or not
     *
     * @param $scope
     * @param $options
     * @return mixed
     */
    public function isValid($scope, $options)
    {
        if (!isset($this->validator)) {<commit_msg>Update LaravelValidatorExtension to support custom error messages<commit_after><?php

namespace AV\LaravelForm\ValidatorExtension;

use AV\Form\FormError;
use AV\Form\FormHandler;
use AV\Form\ValidatorExtension\ValidatorExtensionInterface;

class LaravelValidatorExtension implements ValidatorExtensionInterface
{
    /**
     * @var FormHandler
     */
    private $formHandler;

    /**
     * @var bool
     */
    private $isValid = true;

    /**
     * @var \Illuminate\Validation\Validator
     */
    private $validator;

    /**
     * Sets the form handler
     *
     * @param \AV\Form\FormHandler $formHandler
     * @return mixed
     */
    public function setFormHandler(FormHandler $formHandler)
    {
        $this->formHandler = $formHandler;
    }

    /**
     * Validate the form
     *
     * @param null $scope
     * @param null $options
     * @return mixed
     * @throws \Exception
     */
    private function validate()
    {
        if (isset($this->validator)) {
            throw new \Exception('Cannot validate the same form twice, use the existing result');
        }

        $fieldRules = $this->getFieldValidationRules($this->formHandler->getFormBlueprint()->getAll());

        $validationRules = $fieldRules['rules'];
        $validationAttributeNames = $fieldRules['names'];

        // Get validation rules from any assigned entities (models)
        foreach ($this->formHandler->getEntities() as $entity) {
            if (is_callable([$entity['entity'], 'getValidationRules'])) {

                try {
                    $entityRules = $entity['entity']->getValidationRules();
                } catch (\BadMethodCallException $e) {
                    $entityRules = [];
                }

                foreach ($entityRules as $field => $entityRule) {
                    // If we already have rules for that parameter, concatenate them
                    if (isset($validationRules[$field])) {
                        $validationRules[$field] .= '|'.$entityRule;
                    }
                    // Rules for a parameter that doesn't have any yet
                    else {
                        $validationRules[$field] = $entityRule;
                    }
                }
            }
        }

        $this->validator = \Validator::make($this->formHandler->getData(), $validationRules, $fieldRules['messages']);

        $this->validator->setAttributeNames($validationAttributeNames);

        $this->isValid = $this->validator->passes();
    }

    /**
     * Recursively read in the validation rules from the form fields and convert the field names to dot notation
     *
     * @param $fields
     * @return array
     */
    private function getFieldValidationRules($fields)
    {
        $results = ['rules' => [], 'names' => [], 'messages' => []];

        foreach ($fields as $field) {
            if (isset($field['options']['validation'])) {
                if (!isset($field['original_name'])) {
                    $paramName = $field['name'];
                } else {
                    $paramName = $this->fieldNameToDot($field['original_name']);
                }

                $results['rules'][$paramName] = $field['options']['validation'];

                if (isset($field['options']['label'])) {
                    $results['names'][$paramName] = $field['options']['label'];
                }

                if (isset($field['options']['validation_messages'])) {
                    foreach ($field['options']['validation_messages'] as $validation => $message) {
                        $results['messages']["$paramName.$validation"] = $field['options']['validation_messages'];
                    }
                }
            }

            if (isset($field['fields'])) {
                $results = array_merge_recursive($results, $this->getFieldValidationRules($field['fields']));
            }
        }

        return $results;
    }

    /**
     * Convert a form field name to dot notation for the Laravel validator
     *
     * @param $fieldName
     * @return string
     */
    private function fieldNameToDot($fieldName)
    {
        $fieldName = trim(str_replace(['][', '[', ']'], '.', $fieldName), '.');

        return $fieldName;
    }

    /**
     * Check if the form is valid or not
     *
     * @param $scope
     * @param $options
     * @return mixed
     */
    public function isValid($scope, $options)
    {
        if (!isset($this->validator)) {
{'fraction_non_alphanumeric': 0.1360544217687075, 'fraction_numerical': 0.0, 'mean_word_length': 1.9142173615857827, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 51, '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': '1883989', 'n_tokens_mistral': 2204, 'n_tokens_neox': 2129, 'n_words': 485}