Laravel - Laravel utilizando Validator?

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…

Amigo a tag é Laravel não sei pra que isso e tem que ser feito do jeito que está não deprecie as coisas, se ele viesse aqui e não fosse Laravel eu faria diferente.

Não debuga e não entendem documentação.

Tente entender uma coisa o problema é tag Laravel não mude o enfoque, eu sei como funciona padrão de equipe…

Eu sei, só foi um conselho pra quem está perdendo horas ou dias com Laravel pra atender um requisito tão simples.

galera, obrigado pela força. é sempre bom saber outros métodos de resolver um determinado problema.
mas nesse caso resolvi da seguinte forma…
percebi que Dragoon achou que eu estava ofendendo-o de alguma forma, mas não foi a minha intenção. me expressei mal.

$validator = Validator::make($data, [
    'start_date'    => 'required|date',
    'end_date'      => 'required|date|after_or_equal:start_date',
]);