Laravel - Laravel utilizando Validator?

Estou querendo fazer minhas validações no Controller, preciso validar se a data inicial é maior que a data de término, queria saber se é possível validar utilizando o método Validator do Laravel?

Meu código:

$validator = Validator::make($request->all(),[
        'paciente' => 'required',
        'local' => 'required',
        'tipo' => 'required',
        'event_start_date'=>'required',
        'event_start_time'=>'required',
        'event_end_time'=>'required',
    ], 
    [
        'required' => 'O campo :attribute é obrigatório',
    ], [
        'paciente'      => 'Paciente',
        'Sala'     => 'Sala de Atendimento',
        'tipo'  => 'Tipo de Atendimento',
        'event_start_date'=>'Data Início',
        'event_start_time'=>'Horário Inicial',
        'event_end_time'=>'Horário Término',
    ]
  );

Quais são os campos e como vem o dado da tela, exemplo dd/mm/YYYY dias mês e ano?

Acho que deve fazer uma validador complemento, mas fique tranquilo quem tem sim como resolver

Os dados vem dessa forma dd/mm/YYYY.

1 curtida

Tem que criar validador vou implementar e posto aqui.

Qual versão do seu Laravel?

A versão é a 5.7

Existe algumas formas de fazer isso, eu particularmente prefiro construir uma classe e usar o método dela da seguinte forma:

Crie uma pasta em app com o nome de Validators, sendo que o seu namespace será <?php namespace App\Validators , veja o código:

<?php namespace App\Validators;

use Carbon\Carbon;

class MinorDateThat
{
    public function validate($attribute, $value, $parameters, $validator)
    {
        if (count($parameters) === 0)
            throw new \Exception("Parameter name not reported");
        $param = $parameters[0];
        $minorDate = Carbon::createFromFormat("d/m/Y", $value);
        $greaterDate = Carbon::createFromFormat("d/m/Y", $this->getParamValue($validator->getData(), $param));
        return ($minorDate && $greaterDate && ($minorDate->lessThanOrEqualTo($greaterDate)));
    }

    protected function getParamValue($data, $param)
    {
        if (in_array($param, array_keys($data)))
            return $data[$param];
        throw new \Exception("Not informed value");
    }
}

Após essa criação de arquivo vai na pasta app\Providers abra o arquivo AppServiceProvider.php e no seu método boot() acrescente esse código:

<?php namespace App\Providers;

use Illuminate\Support\Facades\Validator;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{

    public function boot()
    {
        Validator::extend('minordate','\App\Validators\MinorDateThat@validate');
    }

    public function register()
    {
     
    }
}

e preste atenção também nos use que tem que existir que no caso é o use Illuminate\Support\Facades\Validator; para que você possa usar o método extend como demostrado no código, e isso serve para registrar esse novo jeito de validar um dado na sua tela.

Pronto agora é na parte do Validator você deve configurar o nome minordate e seu parâmetro que é o nome do outro campo a ser utilizado para a comparação de data.

Exemplo v.blade.php

@extends('_layout')
@section('content')
    <h3 class="page-header">Verificação de Datas</h3>
    @if ($errors->any())
        <div class="alert alert-danger">
            <ul>
                @foreach ($errors->all() as $error)
                    <li>{{ $error }}</li>
                @endforeach
            </ul>
        </div>
    @endif
    <div class="table-responsive">
        <form action="{{route('data.store')}}" method="post" enctype="multipart/form-data">
            <input type="hidden" name="_token" value="{{{ csrf_token() }}}"/>
            <div class="form-group">
                <label for="datai" class="label-primary">Data Inicial</label>
                <input type="text" class="form-control" name="datai" id="datai" value="{{old('datai')}}" />
            </div>
            <div class="form-group">
                <label for="dataf" class="label-primary">Data Final</label>
                <input type="text" class="form-control" name="dataf" id="dataf"  value="{{old('dataf')}}" />
            </div>
            <div>
                <button class="btn btn-block btn-success">Enviar</button>
            </div>
        </form>
    </div>
@endsection

nesse v.blade.php tem duas datas a datai e a dataf quero que a datai seja menor ou igual a dataf e no código do Controller segue:

public function store(Request $request)
{
	$rules =  [
		'datai' => 'required|date_format:d/m/Y|minordate:dataf',
		'dataf' => 'required|date_format:d/m/Y'
	];
	$messages = [
		'datai.required' => 'Data inicial é requerida',
		'datai.date_format' => 'Data inicial está em formato inválido',
		'datai.minordate' => 'Data inicial tem que ser menor que data final',
		'dataf.required' => 'Data final é requerida',
		'dataf.date_format' => 'Data final está em formato inválido',
	];
	Validator::make($request->all(), $rules, $messages)->validate();
	return 'Ok';
}

ou seja, minordate:dataf está validando se a data é menor ou igual a dataf. Isso eu fiz de acordo com você precisava talvez ajustes a serem feitos mediante suas regras de negócio, mas, isso resolve essa parte.

No Laravel existe até after:date que é uma validação após o problema é que essa validação tem um formato especifico e para data em formato do Brasil pode dar problema em alguns tipos de data …

estou tentando adaptar esse seu exemplo no meu código porém não estou conseguindo. vou deixar o código pra ver se vc consegue me dar uma força.
meu validator atualmente está assim… queria incluir essa sua validação na minha existente.

$validator = Validator::make($request->all(),[
        'paciente' => 'required',
        'local' => 'required',
        'event_start_date'=>'required',
        'event_start_time'=>'required',
        'event_end_time'=>'required', 
        //'event_start_date' => 'before:event_end_date',
    ], 
    [
        'required' => 'O campo :attribute é obrigatório',
    ], [
        'paciente'      => 'Paciente',
        'local'     => 'Sala de Atendimento',
        'event_start_date'=>'Data Início',
        'event_start_time'=>'Horário Inicial',
        'event_end_time'=>'Horário Término',
      // 'event_end_date'=>'Data de Término',
    ]
  );    
         $feed_back=array(); 
        if ($validator->passes()){

}

Outra forma:

<?php namespace App\Validators;

use DateTime;

class MinorDateThat
{
    public function validate($attribute, $value, $parameters, $validator)
    {
        if (count($parameters) <= 1)
        {
            throw new \Exception("Parameter name not reported");
        }

        $param = $parameters[0];
        $format = $parameters[1];
        $data = $validator->getData();

        $minorDate = $this->parseDateTime($value, $format);
        $greaterDate = $this->parseDateTime($this->getParamValue($data, $param), $format);

        return $this->isDateTimeInstance($minorDate) &&
            $this->isDateTimeInstance($greaterDate) &&
            $this->isLessThanOrEqualTo($minorDate, $greaterDate);
    }

    protected function isDateTimeInstance($datetime)
    {
        return $datetime instanceof DateTime;
    }

    protected function isLessThanOrEqualTo($dateTime1, $dateTime2)
    {
        return $dateTime1 <= $dateTime2;
    }

    protected function parseDateTime($value, $format = 'Y-m-d H:m:s')
    {
        return \DateTime::createFromFormat($format, $value);
    }

    protected function getParamValue($data, $param)
    {
        if (in_array($param, array_keys($data)))
            return $data[$param];
        throw new \Exception("Not informed value");
    }
}

Montando a regra:

$rules = [
	'datai' => 'required|date_format:d/m/Y|minordate:dataf,d/m/Y',
	'dataf' => 'required|date_format:d/m/Y'
];

minordate depois os parâmetros que são: o campo a ser comparado (dataf) e o formato que vem da tela (d/m/Y).

Essa é melhor do que a outra, eu utilizei o próprio DateTime porque ele não retorna uma exceção se a data for inválida …

Quais são os campos para comparação?

Observação: a validação é colocado de uma só vez com a separação | para cada validação acho eu que você está fazendo um validação por linha, não é isso é uma linha para cada item da tela, exemplo, se você tem um campo que é uma data e ela tem que ser digitada então a validação é

'campo' => 'required|date_format:d/m/Y'

ou seja, tudo no mesmo array para conferir

Se por acaso for aqui:

Na versão 1:

[
    'paciente' => 'required',
    'local' => 'required',
    'event_start_date'=>'required|date_format:d/m/Y|minordate:event_start_date',
    'event_start_time'=>'required',
    'event_end_time'=>'required', 
    'event_start_date' => 'required|date_format:d/m/Y',
]

Na versão 2:

[
    'paciente' => 'required',
    'local' => 'required',
    'event_start_date'=>'required|date_format:d/m/Y|minordate:event_start_date,d/m/Y',
    'event_start_time'=>'required',
    'event_end_time'=>'required', 
    'event_start_date' => 'required|date_format:d/m/Y',
]

Estou fazendo assim, os campos de comparação são o event_start_date e event_end_date:

$validator = Validator::make($request->all(),[
    'paciente' => 'required',
    'local' => 'required',
    'event_start_date'=>'required',
   
    'event_start_time'=>'required',
    'event_end_time'=>'required', 
    'event_start_date' => 'required|date_format:d/m/Y|minordate:event_end_date',
    'event_end_date' => 'required|date_format:d/m/Y'
], 
[
    'required' => 'O campo :attribute é obrigatório',
], [
    'paciente'      => 'Paciente',
    'local'     => 'Sala de Atendimento',
    'event_start_date.required' => 'Data inicial é requerida',
    'event_start_date.date_format' => 'Data inicial está em formato inválido',
    'event_start_date.minordate' => 'Data inicial tem que ser menor que data final',
    'event_end_date.required' => 'Data final é requerida',
    'event_end_date.date_format' => 'Data final está em formato inválido',
]);

Olha no meu exemplo por favor

está tudo na mesma linha. vou tirar os outros campos, pra ficar mais fácil o entendimento.

    $validator = Validator::make($request->all(),[

        'event_start_date' => 'required|date_format:d/m/Y|minordate:event_end_date',
        'event_end_date' => 'required|date_format:d/m/Y'
    ], 
 [
        'event_start_date.required' => 'Data inicial é requerida',
        'event_start_date.date_format' => 'Data inicial está em formato inválido',
        'event_start_date.minordate' => 'Data inicial tem que ser menor que data final',
        'event_end_date.required' => 'Data final é requerida',
        'event_end_date.date_format' => 'Data final está em formato inválido',
    ]);

OK, mas, o que aconteceu, qual o problema? Cara seja claro…

atualmente para validar os outros campos eu fiz assim, que irá exibir o erro na tela caso encontre algum problema no preenchimento do formulário.
minha ideia é adaptar a sua lógica das validações da data nessa minha lógica.


$validator = Validator::make($request->all(),[
        'paciente' => 'required',
        'local' => 'required',
        'event_start_date'=>'required',
        'event_start_time'=>'required',
        'event_end_time'=>'required', 
        //'event_start_date' => 'before:event_end_date',
    ], 
    [
        'required' => 'O campo :attribute é obrigatório',
    ], [
        'paciente'      => 'Paciente',
        'local'     => 'Sala de Atendimento',
        'event_start_date'=>'Data Início',
        'event_start_time'=>'Horário Inicial',
        'event_end_time'=>'Horário Término',
      // 'event_end_date'=>'Data de Término',
    ]
  );    

         $feed_back=array(); 
        if ($validator->passes()){
            
        $feed_back = new Event();  

        $feed_back->pac_codigo = $request->input('paciente');
        $feed_back->psi_codigo = $request->input('respAte');
        $feed_back->sal_codigo = $request->input('local');
        $feed_back->ate_codigo = $request->input('tipo');
        $feed_back->event_start_date = implode("-", array_reverse(explode("/", $request->input('event_start_date'))));
        $feed_back->event_end_date = implode("-", array_reverse(explode("/", $request->input('event_end_date'))));
        $feed_back->event_start_time = $request->input('event_start_time');
        $feed_back->event_end_time = $request->input('event_end_time');
        $feed_back->event_description = $request->input('event_description');
         //Event::create($request->all());
            $feed_back->save();
           $feed_back['type']='alert-success';
           $feed_back['message']='Consulta marcada com sucesso!';
           $feed_back['error']=array();    
         
        }
        else{
         $feed_back['type']='alert-danger';
          $feed_back['error']=  $validator->errors()->all();
        }
        

         return json_encode($feed_back);

Você seguiu todos os passos?
Você olhou a primeira resposta?
Você fez como está proposto?
O que aconteceu quando fez / se fez?

fiz tudo o que vc falou, não acontece nada…
tirei tudo o que eu fiz anteriormente e continua não acontecendo nada.
veja se a lógica é realmente essa, se vc reparar no código abaixo estou passando a variável $validator no if, onde irá exibir a uma mensagem de erro que, a única diferença da sua lógica agora pra minha é essa.

      $rules = [

        'event_start_date' => 'required|date_format:d/m/Y|minordate:event_end_date',
        'event_end_date' => 'required|date_format:d/m/Y'
    ];
      $messages = [
        'event_start_date.required' => 'Data inicial é requerida',
        'event_start_date.date_format' => 'Data inicial está em formato inválido',
        'event_start_date.minordate' => 'Data inicial tem que ser menor que data final',
        'event_end_date.required' => 'Data final é requerida',
        'event_end_date.date_format' => 'Data final está em formato inválido',
    ];
    $validator=Validator::make($request->all(), $rules, $messages)->validate();
         $feed_back=array(); 
        if ($validator->passes()){

O código passado a você foi testado, se você não conseguiu adaptar o problema não é no meu código que ratificando foi testado, agora você dizer que não aconteceu nada é estranho você não pode dizer isso assim dessa forma dessa maneira como se tivesse certeza daquilo que pelo visto não tem, o que você realmente fez, diga o seu passo a passo que ai posso encontrar o problema, porque, sinceridade se você colocou e não gerou erro ou a validação não surtou efeito tem algo que não estou conseguindo ver no seu jeito de programar!

Isso é tão simples de fazer em PHP puro que nem precisava esquentar a cabeça com Laravel. Mas se quer usar e seu projeto está estruturado assim, o colega acima já deu uma baita aula pra você aqui. É questão de parar o projeto e estudar isoladamente tutoriais. Depois que dominar adapte o que aprendeu no seu projeto.

1 curtida

O problema na minha visão, não é fazer isso como se fosse independente, porque o código é PHP puro, o grande problema na minha visão é a falta de ler a documentação e quando a gente coloca um código testado, funcional e padrão o cara diz que não está funcionando e não te aponta o problema real.

Falta mesmo ler a documentação e é melhor que faça dentro do código do Framework, porque? Por causa da visualização das validações e manter um padrão.

Bom já fiz o papel de até construir o código, falta mesmo entender aonde o amigo tem problema, mas, fica a dica, nunca dizem o que acontece.

O padrão pode ser o que cada equipe definir, pode ser com ou sem framework. Claro, se ele escolheu Laravel então tem que encarar mesmo. Problema que a galera vem aqui e nem debuga…