Sergio Benavides
Sergio Benavides
Laravel
Comparte:

Extraer lógica de una regla de validación a otras funciones | mensajes más específicos para la regla

Hola a todos, Actualmente estoy usando el plugin de select2 para enviar Pagos el parámetro correcto seria (Nombre de pago)-(valor del pago)-(descripción del pago (opcional) ) 
Ejm:
[ john doe-14500 , jane doe-22000-aun debe 15000  ]
las validaciones para el primer parámetro serian: string|max:50|min:4|alpha_num
las validaciones para el segundo parámetro serian: integer|max:500000|min:0
las validaciones para el primer parámetro serian: string|max:100|min:20|alpha_num

Mi regla de validación personalizada 
<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class ValidFormatPagos implements Rule
{
    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $values)
    {
      $isValid = false;

      foreach ($values as $key => $value) {
        $pagoSeparados = explode('-',$value);
        if (count($pagoSeparados) == 2) {
          if (is_string($pagoSeparados[0]) && ctype_digit($pagoSeparados[1])) {

            // validaciones parametro 1 (Nombre del pago)

            # Valida que el parámetro 1 (Nombre del pago) tenga un formato [\sa-zA-Z0-9ñÑ]
            if (preg_match('/[\sa-zA-Z0-9ñÑ]/', $pagoSeparados[0])) {
              $isValid = true;
            }else {
              // $message = "error de formato: En la etiqueta " . $key+1 . " El formato de el nombre del pago es inválido. Secuencia de caracteres aceptados [a-z A-Z 0-9 ñÑ] ";
              // $this->message($message);
              $isValid = false;
            }

            # Valida que el parámetro 1 (Nombre del pago) no se mayor a 50
            if (strlen($pagoSeparados[0]) > 50) {
              // $message = "error de formato: En la etiqueta " . $key+1 . " El nombre del pago no debe ser mayor que 50 caracteres.";
              // dd($this->message($message));
              $isValid = false;
            }elseif (strlen($pagoSeparados[0]) <= 50) {
              $isValid = true;
            }

            # Valida que el parámetro 1 (Nombre del pago) sea mayor a 4
            if (strlen($pagoSeparados[0]) < 4) {
              // $message = "error de formato: En la etiqueta " . $key+1 . " El nombre del pago debe contener al menos 4 caracteres.";
              // $this->message($message);
              $isValid = false;
            }elseif (strlen($pagoSeparados[0]) >= 4) {
              $isValid = true;
            }

            // validaciones parametro 2 (Valor del pago)

            # Valida que el parámetro 2 (Valor del pago) no sea mayor 500000
            if ((int)$pagoSeparados[1] > 500000) {
              // $message = "error de formato: En la etiqueta " . $key+1 . " El valor del pago no debe ser mayor que 500000.";
              // dd($this->message($message));
              $isValid = false;
            }elseif((int)$pagoSeparados[1] <= 500000) {
              $isValid = true;
            }

            # Valida que el parámetro 2 (Valor del pago) sea mayor o igual a 0
            if ((int)$pagoSeparados[1] < 0) {
              // $message = "error de formato: En la etiqueta " . $key+1 . " El valor del pago no debe ser mayor que 500000.";
              // dd($this->message($message));
              $isValid = false;
            }elseif((int)$pagoSeparados[1] >= 0) {
              $isValid = true;
            }

          }
        }elseif (count($pagoSeparados) > 2) {
          if (is_string($pagoSeparados[0]) && ctype_digit($pagoSeparados[1]) && is_string($pagoSeparados[2])) {

            // validaciones parametro 1 (Nombre del pago)

            # Valida que el parámetro 1 (Nombre del pago) tenga un formato [\sa-zA-Z0-9ñÑ]
            if (preg_match('/[\sa-zA-Z0-9ñÑ]/', $pagoSeparados[0])) {
              $isValid = true;
            }else {
              // $message = "error de formato: En la etiqueta " . $key+1 . " El formato de el nombre del pago es inválido. Secuencia de caracteres aceptados [a-z A-Z 0-9 ñÑ] ";
              // $this->message($message);
              $isValid = false;
            }

            # Valida que el parámetro 1 (Nombre del pago) no se mayor a 50
            if (strlen($pagoSeparados[0]) > 50) {
              // $message = "error de formato: En la etiqueta " . $key+1 . " El nombre del pago no debe ser mayor que 50 caracteres.";
              // dd($this->message($message));
              $isValid = false;
            }elseif (strlen($pagoSeparados[0]) <= 50) {
              $isValid = true;
            }

            # Valida que el parámetro 1 (Nombre del pago) sea mayor a 4
            if (strlen($pagoSeparados[0]) < 4) {
              // $message = "error de formato: En la etiqueta " . $key+1 . " El nombre del pago debe contener al menos 4 caracteres.";
              // $this->message($message);
              $isValid = false;
            }elseif (strlen($pagoSeparados[0]) >= 4) {
              $isValid = true;
            }

            // validaciones parametro 2 (Valor del pago)

            # Valida que el parámetro 2 (Valor del pago) no sea mayor 500000
            if ((int)$pagoSeparados[1] > 500000) {
              // $message = "error de formato: En la etiqueta " . $key+1 . " El valor del pago no debe ser mayor que 500000.";
              // dd($this->message($message));
              $isValid = false;
            }elseif((int)$pagoSeparados[1] <= 500000) {
              $isValid = true;
            }

            # Valida que el parámetro 2 (Valor del pago) sea mayor o igual a 0
            if ((int)$pagoSeparados[1] < 0) {
              // $message = "error de formato: En la etiqueta " . $key+1 . " El valor del pago no debe ser mayor que 500000.";
              // dd($this->message($message));
              $isValid = false;
            }elseif((int)$pagoSeparados[1] >= 0) {
              $isValid = true;
            }

            // validaciones parametro 3 (Descripción del pago)

            # Valida que el parámetro 3 (Descripción del pago) tenga un formato [\sa-zA-Z0-9ñÑ]
            if (preg_match('/[\sa-zA-Z0-9ñÑ]/', $pagoSeparados[2])) {
              $isValid = true;
            }else {
              // $message = "error de formato: En la etiqueta " . $key+1 . " El formato de el nombre del pago es inválido. Secuencia de caracteres aceptados [a-z A-Z 0-9 ñÑ] ";
              // $this->message($message);
              $isValid = false;
            }

            # Valida que el parámetro 3 (Descripción del pago) no se mayor a 100
            if (strlen($pagoSeparados[2]) > 100) {
              // $message = "error de formato: En la etiqueta " . $key+1 . " El nombre del pago no debe ser mayor que 100 caracteres.";
              // dd($this->message($message));
              $isValid = false;
            }elseif (strlen($pagoSeparados[2]) <= 100) {
              $isValid = true;
            }

            # Valida que el parámetro 3 (Descripción del pago) sea mayor a 20
            if (strlen($pagoSeparados[2]) < 20) {
              // $message = "error de formato: En la etiqueta " . $key+1 . " El nombre del pago debe contener al menos 20 caracteres.";
              // $this->message($message);
              $isValid = false;
            }elseif (strlen($pagoSeparados[2]) >= 20) {
              $isValid = true;
            }

          }
        } else {
          $isValid = false;
        }
      }

      return $isValid;
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'Error de formato';
    }
}

tengo demasiadas condiciones en este archivo y repito código para validar el parámetro 1 y el parámetro 2 cuando solo viene nombre-valor y cuando viene nombre-valor-descripción, quisiera saber como puedo encapsular esta lógica en otras funciones para que los pueda reutilizar
también quisiera saber si puedo dar un mensaje de error mas específico que Error de formato por ejemplo
cada vez que falle en algún parámetro decir: 
$message = "error de formato: En la etiqueta " . $key+1 . " El nombre del pago no debe ser mayor que 50 caracteres.";
$this->message($message);
Y en la función message algo así:
public function message($message)
    {
        return $message;
    }
Lo intente pero no me funciono
quisiera que me aconsejen la mejor forma de poder lograr algo así y gracias de antemano para todos los que me puedan ayudar 
Jorge García
Jorge García (2780 xp)
Hola Sergio, una solución sería guardar el mensaje de error como propiedad e irlo modificando según el error, más o menos así:

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class ValidFormatPagos implements Rule
{

    protected $message = 'Mensaje de error por defecto';
    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $values)
    {
      $isValid = false;

      foreach ($values as $key => $value) {
        $pagoSeparados = explode('-',$value);
        if (count($pagoSeparados) == 2) {
          if (is_string($pagoSeparados[0]) && ctype_digit($pagoSeparados[1])) {

            // validaciones parametro 1 (Nombre del pago)

            # Valida que el parámetro 1 (Nombre del pago) tenga un formato [\sa-zA-Z0-9ñÑ]
            if (preg_match('/[\sa-zA-Z0-9ñÑ]/', $pagoSeparados[0])) {
              $isValid = true;
            }else {
              $this->message = "error de formato: En la etiqueta " . $key+1 . " El formato de el nombre del pago es inválido. Secuencia de caracteres aceptados [a-z A-Z 0-9 ñÑ] ";
              // $this->message($message);
              $isValid = false;
            }

            # Valida que el parámetro 1 (Nombre del pago) no se mayor a 50
            if (strlen($pagoSeparados[0]) > 50) {
              $this->message = "error de formato: En la etiqueta " . $key+1 . " El nombre del pago no debe ser mayor que 50 caracteres.";
              // dd($this->message($message));
              $isValid = false;
            }elseif (strlen($pagoSeparados[0]) <= 50) {
              $isValid = true;
            }

            # Valida que el parámetro 1 (Nombre del pago) sea mayor a 4
            if (strlen($pagoSeparados[0]) < 4) {
              $this->message = "error de formato: En la etiqueta " . $key+1 . " El nombre del pago debe contener al menos 4 caracteres.";
              // $this->message($message);
              $isValid = false;
            }elseif (strlen($pagoSeparados[0]) >= 4) {
              $isValid = true;
            }

            // validaciones parametro 2 (Valor del pago)

            # Valida que el parámetro 2 (Valor del pago) no sea mayor 500000
            if ((int)$pagoSeparados[1] > 500000) {
              $this->message = "error de formato: En la etiqueta " . $key+1 . " El valor del pago no debe ser mayor que 500000.";
              // dd($this->message($message));
              $isValid = false;
            }elseif((int)$pagoSeparados[1] <= 500000) {
              $isValid = true;
            }

            # Valida que el parámetro 2 (Valor del pago) sea mayor o igual a 0
            if ((int)$pagoSeparados[1] < 0) {
              $this->message = "error de formato: En la etiqueta " . $key+1 . " El valor del pago no debe ser mayor que 500000.";
              // dd($this->message($message));
              $isValid = false;
            }elseif((int)$pagoSeparados[1] >= 0) {
              $isValid = true;
            }

          }
        }elseif (count($pagoSeparados) > 2) {
          if (is_string($pagoSeparados[0]) && ctype_digit($pagoSeparados[1]) && is_string($pagoSeparados[2])) {

            // validaciones parametro 1 (Nombre del pago)

            # Valida que el parámetro 1 (Nombre del pago) tenga un formato [\sa-zA-Z0-9ñÑ]
            if (preg_match('/[\sa-zA-Z0-9ñÑ]/', $pagoSeparados[0])) {
              $isValid = true;
            }else {
              $this->message = "error de formato: En la etiqueta " . $key+1 . " El formato de el nombre del pago es inválido. Secuencia de caracteres aceptados [a-z A-Z 0-9 ñÑ] ";
              // $this->message($message);
              $isValid = false;
            }

            # Valida que el parámetro 1 (Nombre del pago) no se mayor a 50
            if (strlen($pagoSeparados[0]) > 50) {
              $this->message = "error de formato: En la etiqueta " . $key+1 . " El nombre del pago no debe ser mayor que 50 caracteres.";
              // dd($this->message($message));
              $isValid = false;
            }elseif (strlen($pagoSeparados[0]) <= 50) {
              $isValid = true;
            }

            # Valida que el parámetro 1 (Nombre del pago) sea mayor a 4
            if (strlen($pagoSeparados[0]) < 4) {
              $this->message = "error de formato: En la etiqueta " . $key+1 . " El nombre del pago debe contener al menos 4 caracteres.";
              // $this->message($message);
              $isValid = false;
            }elseif (strlen($pagoSeparados[0]) >= 4) {
              $isValid = true;
            }

            // validaciones parametro 2 (Valor del pago)

            # Valida que el parámetro 2 (Valor del pago) no sea mayor 500000
            if ((int)$pagoSeparados[1] > 500000) {
              $this->message = "error de formato: En la etiqueta " . $key+1 . " El valor del pago no debe ser mayor que 500000.";
              // dd($this->message($message));
              $isValid = false;
            }elseif((int)$pagoSeparados[1] <= 500000) {
              $isValid = true;
            }

            # Valida que el parámetro 2 (Valor del pago) sea mayor o igual a 0
            if ((int)$pagoSeparados[1] < 0) {
              $this->message = "error de formato: En la etiqueta " . $key+1 . " El valor del pago no debe ser mayor que 500000.";
              // dd($this->message($message));
              $isValid = false;
            }elseif((int)$pagoSeparados[1] >= 0) {
              $isValid = true;
            }

            // validaciones parametro 3 (Descripción del pago)

            # Valida que el parámetro 3 (Descripción del pago) tenga un formato [\sa-zA-Z0-9ñÑ]
            if (preg_match('/[\sa-zA-Z0-9ñÑ]/', $pagoSeparados[2])) {
              $isValid = true;
            }else {
              $this->message = "error de formato: En la etiqueta " . $key+1 . " El formato de el nombre del pago es inválido. Secuencia de caracteres aceptados [a-z A-Z 0-9 ñÑ] ";
              // $this->message($message);
              $isValid = false;
            }

            # Valida que el parámetro 3 (Descripción del pago) no se mayor a 100
            if (strlen($pagoSeparados[2]) > 100) {
              $this->message = "error de formato: En la etiqueta " . $key+1 . " El nombre del pago no debe ser mayor que 100 caracteres.";
              // dd($this->message($message));
              $isValid = false;
            }elseif (strlen($pagoSeparados[2]) <= 100) {
              $isValid = true;
            }

            # Valida que el parámetro 3 (Descripción del pago) sea mayor a 20
            if (strlen($pagoSeparados[2]) < 20) {
              $this->message = "error de formato: En la etiqueta " . $key+1 . " El nombre del pago debe contener al menos 20 caracteres.";
              // $this->message($message);
              $isValid = false;
            }elseif (strlen($pagoSeparados[2]) >= 20) {
              $isValid = true;
            }

          }
        } else {
          $isValid = false;
        }
      }

      return $isValid;
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return $this->message;
    }
}

Sergio Benavides
Sergio Benavides (1352 xp)
ok voy a probar, también está correcto dejar todas estas condiciones acá o se pueden extraer a otras funciones ya que es demasiada lógica además de que repito código para algunas validaciones  ?
Sergio Benavides
Sergio Benavides (1352 xp)
cuando alguna de las condiciones que tengo alli falla por ejemplo que el primer parametro sea mayor de 4 me esta saliendo un error 

ErrorException (E_WARNING)
A non-numeric value encountered

exactamente en esta parte 

$this->message = "error de formato: En la etiqueta " . $key+1 . " El nombre del pago debe contener al menos 4 caracteres.";
Jorge García
Jorge García (2780 xp)
Al parecer $key+1 está dando error, haz un dump para verificar que key es un número, también puedes utilizar $key++ para incrementarlo.
Sergio Benavides
Sergio Benavides (1352 xp)
si imprime el numero, al parecer era el $key+1 con key++  si funciona pero no me esta mostrando el mensaje bajo el input, tampoco con el $key++ no esta aumentando