I have an order detail that includes multiple product listings. I want to ensure that users cannot select the same product for a single order. For example, here is the result of the dd($request) function.
+request: SymfonyComponentHttpFoundationInputBag {#45
#parameters: array:16 [
"_token" => "El3iq45CsoEPRXxwaAOv072O0bWARb5WUNx3Lmfe"
"warehouse_id" => "1"
"customer_id" => "1"
"order_date" => "2023-08-24 19:20"
"shipping_address" => "q"
"product_id0" => "1"
"qty0" => "1"
"stock_outstanding0" => "99"
"unit_price0" => "65000"
"total_price0" => "65000"
"count_item" => "1"
"product_id1" => "1"
"qty1" => "1"
"stock_outstanding1" => "100"
"unit_price1" => "65000"
"total_price1" => "65000"
]
}
As you can see, there are two product IDs, product_id0 and product_id1, that have the same value.
"product_id0" => "1"
"product_id1" => "1"
I want a validator to check if it has the same value, it will abort the order. I have implemented validation, but it still seems to be incorrect. This is because if product_id0 and product_id1 have different values, such as
"product_id0" => "1"
"product_id1" => "2"
It keep send the message Validation Work
Here the validation i made
$isValid = true;
for ($g = 0; $g <= $request->count_item; $g++) {
$validator = Validator::make($request->all(), [
'warehouse_id' => 'required',
'customer_id' => 'required',
'order_date' => 'required',
'shipping_address' => 'required',
"product_id{$g}.*" => 'distinct',
]);
if ($validator->fails()) {
$isValid = false;
break;
}
}
if ($isValid) {
return response()->json([
'status' => true,
'message' => 'Validation Work',
]);
} else {
return response()->json([
'status' => false,
'message' => 'Validation Failed',
]);
}
Also i made another validation but still dont work
$tempId = [];
$tempArray = [];
for ($g=0; $g <= $request->count_item; $g++) {
$tempId[] = $request['product_id' . $g];
if(in_array($tempId, $tempArray)){
return response()->json([
'status' => true,
'message' => 'True validation work',
]);
}else{
return response()->json([
'status' => false,
'message' => 'False validation failed',
]);
$tempArray[] = $tempId;
dd($tempArray);
exit;
}
}
2
Answers
You’re validating each product at a time, so it won’t be able to match it against the others. Instead, build up the validation array before you actually validate it.
product_id{$g}
is a single item, so don’t use.*
, since that’s used for arrays.You could also turn your products in your form to be an array with
products[]
, then use'products.*'=> 'distinct'
instead of building up the rules based on the item count.The
distinct
rule only works on arrays of values. You’re not using an array, as you’ve put each value in it’s own variable (product_id0
vsproduct_id[0]
).I would suggest changing your request to use an array so you can take advantage of the
distinct
rule.Change the name on your input to
product[0][id]
andproduct[1][id]
, and then your validation rule would beproduct.*.id => 'distinct'
. Also, you’d have a valid array of products to loop through, instead of having to dynamically build variable names.If you can’t modify the request coming in, you could build up a new array to validate on the server side. However, if you do this, the error bag keys won’t match the inputs on the screen, so you’d need to account for that if you’re trying to show error messages for the fields on the screen.
Finally, if neither of these is a valid option, you can use the
different
validation. This will be a little trickier if you can have a dynamic amount of products. Thedifferent
validation lets you specify that one field must be different than another, so you’d need to specify that p0 is different than p1, p2, …, pN, and then p1 is different than p2, p3, …, pN, etc.NB: all untested code. May contain syntax/logic errors.