diff --git a/app/Http/Requests/DomainUpdateRequest.php b/app/Http/Requests/DomainUpdateRequest.php index ed49cf16b..a77f692f4 100644 --- a/app/Http/Requests/DomainUpdateRequest.php +++ b/app/Http/Requests/DomainUpdateRequest.php @@ -33,7 +33,20 @@ public function authorize(): bool public function rules(): array { return [ - 'description' => 'required|string', + 'id_project' => 'required|exists:projects,id', + 'description' => [ + 'required', + 'string', + 'regex:/^[\pL\s]+$/u', + 'max:255', + ], + ]; + } + + public function messages(): array + { + return [ + 'description.regex' => 'A descrição deve conter apenas palavras.', ]; } } diff --git a/app/Http/Requests/KeywordUpdateRequest.php b/app/Http/Requests/KeywordUpdateRequest.php index 5553930ec..2e2a2593d 100644 --- a/app/Http/Requests/KeywordUpdateRequest.php +++ b/app/Http/Requests/KeywordUpdateRequest.php @@ -25,7 +25,12 @@ public function authorize() public function rules() { return [ - 'description' => 'required|string', + 'description' => [ + 'required', + 'string', + 'regex:/^[\pL\s]+$/u', + 'max:255', + ], ]; } } diff --git a/app/Livewire/Planning/Criteria/Criteria.php b/app/Livewire/Planning/Criteria/Criteria.php index 2e2cc3e6f..6db1f660a 100644 --- a/app/Livewire/Planning/Criteria/Criteria.php +++ b/app/Livewire/Planning/Criteria/Criteria.php @@ -47,8 +47,9 @@ protected function rules() return [ 'currentProject' => 'required', 'criteriaId' => 'required|string|max:20|regex:/^[a-zA-Z0-9]+$/', - 'description' => 'required|string|max:255', - 'type.value' => 'required|in:Inclusion,Exclusion' + 'description' => 'required|string|regex:/^[\pL\s]+$/u|max:255', + 'type' => 'required|array', + 'type.*.value' => 'string' ]; } diff --git a/app/Livewire/Planning/DataExtraction/Option.php b/app/Livewire/Planning/DataExtraction/Option.php index c7ce10177..7e31f32d7 100644 --- a/app/Livewire/Planning/DataExtraction/Option.php +++ b/app/Livewire/Planning/DataExtraction/Option.php @@ -39,7 +39,11 @@ class Option extends Component * Validation rules. */ protected $rules = [ - 'description' => 'required|string', + 'description' => [ + 'required', + 'string', + 'regex:/^[a-zA-ZÀ-ÿ0-9\s]+$/u', + ], 'questionId' => 'required|array', 'questionId.*.value' => 'exists:question_extraction,id', ]; diff --git a/app/Livewire/Planning/DataExtraction/Question.php b/app/Livewire/Planning/DataExtraction/Question.php index 3f0e6286c..a7650b901 100644 --- a/app/Livewire/Planning/DataExtraction/Question.php +++ b/app/Livewire/Planning/DataExtraction/Question.php @@ -40,12 +40,30 @@ class Question extends Component /** * Validation rules. */ - public function rules() + protected $rules = [ + 'description' => [ + 'required', + 'string', + 'regex:/^[a-zA-ZÀ-ÿ0-9\s]+$/u', + ], + 'questionId' => [ + 'required', + 'numeric', + ], + 'type' => 'required|array', + ]; + + /** + * Custom error messages for the validation rules. + */ + protected function messages() { return [ - 'questionId' => ['required', 'regex:/^[a-zA-Z0-9]+$/'], - 'description' => 'required', - 'type' => 'required' + 'questionId.required' => 'O campo ID é obrigatório.', + 'questionId.numeric' => 'O ID deve conter apenas números.', + 'description.required' => 'Este campo é obrigatório', + 'description.regex' => 'A descrição só pode conter letras, números e espaços.', + 'type.required' => 'Este campo é obrigatório', ]; } diff --git a/app/Livewire/Planning/QualityAssessment/QuestionQuality.php b/app/Livewire/Planning/QualityAssessment/QuestionQuality.php index c2146d7e8..58e656691 100644 --- a/app/Livewire/Planning/QualityAssessment/QuestionQuality.php +++ b/app/Livewire/Planning/QualityAssessment/QuestionQuality.php @@ -42,8 +42,8 @@ class QuestionQuality extends Component protected $rules = [ 'currentProject' => 'required', 'questionId' => 'required|string|max:10|regex:/^[a-zA-Z0-9]+$/', - 'description' => 'required|string|max:255', - 'weight' => 'required|numeric', + 'description' => 'required|string|max:255|regex:/^[a-zA-Z0-9]+$/', + 'weight' => 'required|regex:/^\d+(\.\d{1,2})?$/', ]; /** diff --git a/app/Livewire/Planning/QualityAssessment/QuestionRanges.php b/app/Livewire/Planning/QualityAssessment/QuestionRanges.php index b778c226f..458420088 100644 --- a/app/Livewire/Planning/QualityAssessment/QuestionRanges.php +++ b/app/Livewire/Planning/QualityAssessment/QuestionRanges.php @@ -23,6 +23,23 @@ class QuestionRanges extends Component public $intervals = 5; private $toastMessages = 'project/planning.quality-assessment.general-score.livewire.toasts'; + protected $rules = [ + 'items.*.description' => 'required|string|regex:/^[a-zA-ZÀ-ÿ0-9\s]+$/u', + 'intervals' => 'required|integer|min:2|max:10', + ]; + + protected function messages() + { + return [ + 'items.*.description.required' => 'O campo descrição é obrigatório.', + 'items.*.description.regex' => 'A descrição só pode conter letras, números e espaços.', + 'intervals.required' => 'O número de intervalos é obrigatório.', + 'intervals.integer' => 'O número de intervalos deve ser um número inteiro.', + 'intervals.min' => 'O número de intervalos deve ser no mínimo 2.', + 'intervals.max' => 'O número de intervalos deve ser no máximo 10.', + ]; + } + public function populateItems() { $projectId = $this->currentProject->id_project; @@ -162,6 +179,10 @@ public function updateLabel($index) } try { + $this->validate([ + "items.$index.description" => 'required|string|regex:/^[a-zA-ZÀ-ÿ0-9\s]+$/u', + ]); + $idGeneralScore = $this->items[$index]['id_general_score']; $value = $this->items[$index]['description']; diff --git a/app/Livewire/Planning/QualityAssessment/QuestionScore.php b/app/Livewire/Planning/QualityAssessment/QuestionScore.php index e92e739b8..5166faaf8 100644 --- a/app/Livewire/Planning/QualityAssessment/QuestionScore.php +++ b/app/Livewire/Planning/QualityAssessment/QuestionScore.php @@ -44,9 +44,9 @@ class QuestionScore extends Component */ protected $rules = [ 'questionId' => 'array|required', - 'scoreRule' => 'required|string|max:25', + 'scoreRule' => 'required|string|max:25|regex:/^[a-zA-ZÀ-ÿ\s]+$/u', 'score' => 'required|numeric', - 'description' => 'required|string|max:255', + 'description' => 'required|string|max:255|regex:/^[a-zA-ZÀ-ÿ0-9\s]+$/u', ]; /** @@ -58,9 +58,11 @@ protected function messages() 'questionId.required' => __('common.required'), 'questionId.array' => __('common.required'), 'scoreRule.required' => __('common.required'), + 'scoreRule.regex' => 'A regra de pontuação só pode conter letras e espaços.', 'score.required' => __('common.required'), 'description.required' => __('common.required'), - ]; + 'description.regex' => 'A descrição só pode conter letras, números e espaços.', + ]; } public function mount() diff --git a/app/Livewire/Planning/Questions/ResearchQuestions.php b/app/Livewire/Planning/Questions/ResearchQuestions.php index d317c4473..937349ee2 100644 --- a/app/Livewire/Planning/Questions/ResearchQuestions.php +++ b/app/Livewire/Planning/Questions/ResearchQuestions.php @@ -39,16 +39,19 @@ class ResearchQuestions extends Component protected $rules = [ 'currentProject' => 'required', 'questionId' => 'required|string|max:20|regex:/^[a-zA-Z0-9]+$/', - 'description' => 'required|string|max:255', + 'description' => 'required|string|regex:/^[\pL\s]+$/u|max:255', ]; /** * Custom error messages for the validation rules. */ protected $messages = [ - 'description.required' => 'The description field is required.', - 'questionId.required' => 'The ID field is required.', - 'questionId.regex' => 'The ID field must contain only letters and numbers.', + 'description.required' => 'O campo descrição é obrigatório.', + 'description.regex' => 'A descrição deve conter apenas letras e espaços.', + 'description.max' => 'A descrição não pode ter mais de 255 caracteres.', + 'questionId.required' => 'O campo ID é obrigatório.', + 'questionId.regex' => 'O campo ID deve conter apenas letras e números.', + 'questionId.max' => 'O campo ID não pode ter mais de 20 caracteres.', ]; /** diff --git a/app/Livewire/Planning/SearchStrategy/Strategy.php b/app/Livewire/Planning/SearchStrategy/Strategy.php index 112904e9f..f23eccc14 100644 --- a/app/Livewire/Planning/SearchStrategy/Strategy.php +++ b/app/Livewire/Planning/SearchStrategy/Strategy.php @@ -22,7 +22,15 @@ class Strategy extends Component protected $rules = [ - 'currentDescription' => 'required|string', + 'currentDescription' => [ + 'required', + 'string', + ], + ]; + + protected $messages = [ + 'currentDescription.required' => 'O campo descrição é obrigatório.', + 'currentDescription.regex' => 'A descrição deve conter pelo menos uma letra e não pode conter apenas caracteres especiais ou números.', ]; public function mount() @@ -44,13 +52,15 @@ public function toast(string $message, string $type) public function submit() { + $this->validate([ + 'currentDescription' => 'required|string', + ]); - if (!$this->checkEditPermission($this->toastMessages . '.denied')) { + if (!$this->isValidDescription($this->currentDescription)) { + $this->addError('currentDescription', 'A descrição deve conter pelo menos uma letra e não pode conter apenas caracteres especiais ou números.'); return; } - $this->validate(); - try { $project = ProjectModel::findOrFail($this->projectId); $project->searchStrategy() @@ -74,6 +84,23 @@ public function submit() } } + private function isValidDescription(string $description): bool + { + $trimmedDescription = trim($description); + + // Verifica se contém pelo menos uma letra + if (!preg_match('/[a-zA-ZÀ-ÿ]/', $trimmedDescription)) { + return false; + } + + // Verifica se é composta apenas por números e/ou caracteres especiais + if (preg_match('/^[\d\W]+$/', $trimmedDescription)) { + return false; + } + + return true; + } + public function render() { return view('livewire.planning.search-strategy.strategy'); diff --git a/app/Livewire/Planning/SearchString/SearchTerm.php b/app/Livewire/Planning/SearchString/SearchTerm.php index fb124dc21..cb51dd8ff 100644 --- a/app/Livewire/Planning/SearchString/SearchTerm.php +++ b/app/Livewire/Planning/SearchString/SearchTerm.php @@ -51,7 +51,8 @@ class SearchTerm extends Component */ protected $rules = [ 'currentProject' => 'required', - 'description' => 'required|string|max:255', + 'description' => 'required|string|regex:/^[\pL\s]+$/u|max:255', + 'synonym' => 'nullable|string|regex:/^[\pL\s]+$/u|max:255', ]; /** @@ -60,7 +61,11 @@ class SearchTerm extends Component protected function messages() { return [ - 'description.required' => __($this->translationPath . '.description.required'), + 'description.required' => __('O campo descrição é obrigatório.'), + 'description.regex' => __('A descrição deve conter apenas letras e espaços.'), + 'description.max' => __('A descrição não pode ter mais de 255 caracteres.'), + 'synonym.regex' => __('O sinônimo deve conter apenas letras e espaços.'), + 'synonym.max' => __('O sinônimo não pode ter mais de 255 caracteres.'), ]; } @@ -217,10 +222,7 @@ public function delete(string $termId) public function addSynonyms() { - - if (!$this->checkEditPermission($this->toastMessages . '.denied')) { - return; - } + $this->validateOnly('synonym'); if (!$this->termId['value'] || !$this->synonym) { $this->addError('termId', 'The term id is required'); diff --git a/resources/views/livewire/planning/criteria/criteria.blade.php b/resources/views/livewire/planning/criteria/criteria.blade.php index 298b90f9f..72955d790 100644 --- a/resources/views/livewire/planning/criteria/criteria.blade.php +++ b/resources/views/livewire/planning/criteria/criteria.blade.php @@ -34,6 +34,7 @@ label="{{ __('project/planning.criteria.form.description') }}" wire:model="description" placeholder="{{ __('project/planning.criteria.form.enter_description') }}" + pattern="[A-Za-zÀ-ÿ\s]+" required /> @error("description") diff --git a/resources/views/livewire/planning/data-extraction/option.blade.php b/resources/views/livewire/planning/data-extraction/option.blade.php index 5dd2637d0..328759883 100644 --- a/resources/views/livewire/planning/data-extraction/option.blade.php +++ b/resources/views/livewire/planning/data-extraction/option.blade.php @@ -43,6 +43,7 @@ wire:model="description" placeholder="" maxlength="255" + pattern="[a-zA-ZÀ-ÿ0-9\s]+" required /> @error("description") diff --git a/resources/views/livewire/planning/data-extraction/question.blade.php b/resources/views/livewire/planning/data-extraction/question.blade.php index 18df6138f..0165d6a84 100644 --- a/resources/views/livewire/planning/data-extraction/question.blade.php +++ b/resources/views/livewire/planning/data-extraction/question.blade.php @@ -14,9 +14,9 @@ id="questionId" label="{{ __('project/planning.data-extraction.question-form.id') }}" wire:model="questionId" - placeholder="Não utilize caracteres especiais" + placeholder="Digite o ID da questão" maxlength="255" - pattern="[a-zA-Z0-9]+" + pattern="\d+" required /> @error("questionId") @@ -31,6 +31,7 @@ wire:model="description" placeholder="" maxlength="255" + pattern="[a-zA-ZÀ-ÿ0-9\s]+" required /> @error("description") diff --git a/resources/views/livewire/planning/overall/domains.blade.php b/resources/views/livewire/planning/overall/domains.blade.php index 99295d8c9..9ef4263c8 100644 --- a/resources/views/livewire/planning/overall/domains.blade.php +++ b/resources/views/livewire/planning/overall/domains.blade.php @@ -15,6 +15,7 @@ wire:model="description" placeholder="{{ __('project/planning.overall.domain.list.headers.enter_description') }}" maxlength="255" + pattern="[A-Za-zÀ-ÿ\s]+" required /> @error("description") diff --git a/resources/views/livewire/planning/overall/keywords.blade.php b/resources/views/livewire/planning/overall/keywords.blade.php index 46e3748f9..70680a145 100644 --- a/resources/views/livewire/planning/overall/keywords.blade.php +++ b/resources/views/livewire/planning/overall/keywords.blade.php @@ -14,6 +14,8 @@ label="{{ __('project/planning.overall.keyword.description') }}" wire:model="description" placeholder="{{ __('project/planning.overall.keyword.enter_description') }}" + maxlength="255" + pattern="[A-Za-zÀ-ÿ\s]+" required /> @error("description") diff --git a/resources/views/livewire/planning/quality-assessment/question-quality.blade.php b/resources/views/livewire/planning/quality-assessment/question-quality.blade.php index 08e64af46..600a1e733 100644 --- a/resources/views/livewire/planning/quality-assessment/question-quality.blade.php +++ b/resources/views/livewire/planning/quality-assessment/question-quality.blade.php @@ -15,6 +15,7 @@ label="{{ __('project/planning.quality-assessment.question-quality.id') }}" placeholder="QA01" wire:model="questionId" + pattern="[a-zA-ZÀ-ÿ0-9\s]+" required /> @error("questionId") @@ -33,6 +34,7 @@ min="0" placeholder="2" wire:model="weight" + pattern="[0-9]+" required /> @error("weight") @@ -53,6 +55,7 @@ class="form-control" rows="2" placeholder="{{ __("project/planning.research-questions.form.enter_description") }}" wire:model="description" + pattern="[a-zA-ZÀ-ÿ0-9\s]+" required > @error("description") diff --git a/resources/views/livewire/planning/quality-assessment/question-ranges.blade.php b/resources/views/livewire/planning/quality-assessment/question-ranges.blade.php index bd92a07ad..73049a007 100644 --- a/resources/views/livewire/planning/quality-assessment/question-ranges.blade.php +++ b/resources/views/livewire/planning/quality-assessment/question-ranges.blade.php @@ -39,6 +39,7 @@ label="Label" placeholder="Good" class="max-input" + pattern="[a-zA-ZÀ-ÿ0-9\s]+" style=" min-width: 75px; border-radius: 10px 0 0 10px; diff --git a/resources/views/livewire/planning/quality-assessment/question-score.blade.php b/resources/views/livewire/planning/quality-assessment/question-score.blade.php index 6cfc61294..e99a053bf 100644 --- a/resources/views/livewire/planning/quality-assessment/question-score.blade.php +++ b/resources/views/livewire/planning/quality-assessment/question-score.blade.php @@ -47,6 +47,7 @@ class="modal-sm" min="0" placeholder="Partial" wire:model="scoreRule" + pattern="[a-zA-ZÀ-ÿ\s]+" required /> @error("scoreRule") @@ -102,6 +103,7 @@ class="form-control" maxlength="255" rows="2" placeholder="{{ __("project/planning.research-questions.form.enter_description") }}" + pattern="[a-zA-ZÀ-ÿ0-9\s]+" required > @error("description") diff --git a/resources/views/livewire/planning/questions/research-questions.blade.php b/resources/views/livewire/planning/questions/research-questions.blade.php index a00c04fc6..3a8b1b8a8 100644 --- a/resources/views/livewire/planning/questions/research-questions.blade.php +++ b/resources/views/livewire/planning/questions/research-questions.blade.php @@ -36,9 +36,11 @@ class="form-control" maxlength="255" rows="4" id="description" - label="{{ __("project/planning.research-questions.form.description") }}" wire:model="description" placeholder="{{ __("project/planning.research-questions.form.enter_description") }}" + pattern="[A-Za-zÀ-ÿ\s]+" + title="A descrição deve conter apenas letras e espaços." + required > @error("description") diff --git a/resources/views/livewire/planning/search-strategy/strategy.blade.php b/resources/views/livewire/planning/search-strategy/strategy.blade.php index fb37db4c0..92feb8f1e 100644 --- a/resources/views/livewire/planning/search-strategy/strategy.blade.php +++ b/resources/views/livewire/planning/search-strategy/strategy.blade.php @@ -43,13 +43,17 @@ class="form-control-label mx-0 mb-1 required"
{!! $currentDescription !!}
diff --git a/resources/views/livewire/planning/search-string/search-term.blade.php b/resources/views/livewire/planning/search-string/search-term.blade.php index bb101325c..547fe982a 100644 --- a/resources/views/livewire/planning/search-string/search-term.blade.php +++ b/resources/views/livewire/planning/search-string/search-term.blade.php @@ -17,6 +17,7 @@ class="w-md-25 w-100" label="{{ __('project/planning.search-string.term.form.title') }}" wire:model="description" placeholder="{{ __('project/planning.search-string.term.form.placeholder') }}" + pattern="[A-Za-zÀ-ÿ\s]+" required /> @error("description") @@ -60,14 +61,14 @@ class="w-md-25 w-100" @endforeach - @error("language") + @error("termId") {{ $message }} @enderror
@@ -79,6 +80,7 @@ class="w-100" label="{{ __('project/planning.search-string.synonym.form.title') }}" wire:model="synonym" placeholder="{{ __('project/planning.search-string.synonym.form.placeholder') }}" + pattern="[A-Za-zÀ-ÿ\s]+" required /> @error("synonym")