3 votes

Validation Laravel - Le format de date m/y n'accepte pas de valeur spécifique

J'ai les règles de validation suivantes pour l'authentification de base d'une méthode de paiement (les éléments avancés, comme la validation de la DCV, la carte existante, etc. sont gérés ultérieurement par Moneris).

$rules = [
    "type" => "required|in:visa,mastercard",
    "nickname" => "required",
    "credit_card_number" => "required|numeric|digits:16",
    "expiry" => "required|string|size:5|date_format:m/y|after:today",
    "cvd" => "required|numeric|digits:3"
];

La règle expiry n'accepte pas de valeur spécifique, 04/yy mais il accepte 03/yy y 05/yy Je n'ai aucune idée de la raison pour laquelle cela se produit, mais je dois y remédier. Quelqu'un a-t-il déjà rencontré ce comportement ?

Pour référence, le résultat dd($request->input(), $validator->passes(), $validator->errors()); quand je passe 04/19 est le suivant :

array:6 [
  "type" => "visa"
  "nickname" => "Testing"
  "credit_card_number" => "4242424242424242"
  "expiry" => "04/19"
  "cvd" => "123"
  "masked_pan" => "************4242"
]
false
MessageBag {#502 
  #messages: array:1 [
    "expiry" => array:1 [
      0 => "The expiry does not match the format m/y."
    ]
  ]
  #format: ":message"
}

Lorsque j'envoie 05/19 tout fonctionne bien :

array:6 [
  "type" => "visa"
  "nickname" => "Testing"
  "credit_card_number" => "4242424242424242"
  "expiry" => "05/19"
  "cvd" => "123"
  "masked_pan" => "************4242"
]
true
MessageBag {#502 
  #messages: []
  #format: ":message"
}

0voto

Tim Lewis Points 10272

Il semble qu'il y ait un problème avec le fonctionnement de cette règle de validation dans Laravel 5.4. Pour résoudre le problème, je vérifie la validité de la date de l'entrée précédée de 01/ et s'il est valide, le fusionner dans la demande, avec endOfMonth() pour gérer after:today validation :

$mergeDate = null;
$rawInput = $request->input("expiry");
try {
    $mergeDate = Carbon::createFromFormat("d/m/y", "01/".$request->input("expiry"))->endOfMonth();  
} catch(\Exception $ex){}

$request->merge([
    "masked_pan" => str_repeat("*", 12).substr($request->input("credit_card_number", ""), -4),
    "expiry" => $mergeDate ? $mergeDate->format("d/m/y") : $request->input("expiry")
]);

Donc maintenant, si je passe 04/22 Il vérifiera si 01/04/22 est valide, alors convertir en fin de mois 30/04/22 puis la remplacer par la valeur transmise à la validation (qui doit également être mise à jour).

"expiry" => "required|string|size:8|date_format:d/m/y|after:today",

Je dois également mettre à jour et passer $messages afin d'éviter toute confusion pour l'utilisateur :

$messages = [
    "expiry.size" => "The :attribute filed must be 5 characters.",
    "expiry.date_format" => "The :attribute field does not match the format m/y"
];

$validator = \Validator::make($request->all(), $rules, $messages);

Enfin, en cas d'erreur, remplacer la valeur par l'entrée brute (afin que l'utilisateur ne voie pas une valeur qu'il n'a pas saisie).

if(!$validator->passes()){
    $request->merge(["expiry" => $rawInput]);
    return back()->withErrors($validator)->withInput();
}

Tout un tas d'absurdités, mais il semble que l'on puisse s'en sortir. 04/22 et d'autres dates.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X