Laravel validator passing array when null - laravel

I've got basic laravel validator for my request:
$validator = Validator::make($request->all(), [
'speciality' => 'required|array|min:1',
]);
if ($validator->fails()) {
return response([
'status' => 'error',
'error' => 'invalid.credentials',
'message' => 'error validation'
], 400);
}
speciality should be an array, so I define it as required|array|min:1
The problem is when my request has an empty array with null inside: speciality: [ null ] and this somehow passes my validator.
How can I correct it to catch this case?

Using dot to access the underlying elements/values:
$validator = Validator::make($request->all(), [
'speciality' => 'required|array|min:1',
'speciality.*' => 'required' //ensures its not null
]);
See the Validation: Validating Arrays section of the documentation.
Notice that [null] in not an empty array, that's why your initial validation was passed. You can verify this doing:
dd(empty([null]));
This will output:
false

Related

Laravel validating that key in array is in an array of given strings

I'm building an API that takes in an array of 'additional_data' but I want some control over the fields that can be passed in.
Take the following JSON:
{
"name": "Joe Bloggs",
"additional_data": {
"type": "example",
"other_type": "example"
}
}
My current validation attempt:
return [
'name' => ['required'],
'additional_data.*' => ['sometimes', Rule::in(['type'])]
];
This always fails validation, what I'm looking for is to validate the key of the array so I can make sure the keys passed in are part of a 'whitelist'.
What you do now is you try to validate content of additional_data.type and additional_data.other_type.
You can do this by adding a custom validator. For example
Validator::extend('check_additional_data_keys', function($attribute, $value, $parameters, $validator) {
return is_array($value) && array_diff(array_keys($value), ['type', 'other_type']) === 0);
});
and use it inside your current rules
return [
'name' => ['required'],
'additional_data' => ['check_additional_data_keys'],
'additional_data.*' => ['required', 'string'],
];
Just specify your whitelist keys using the array validation rule:
return [
'name' => 'required',
'additional_data' => [
'sometimes',
'array:type',
],
];
1- In case you want applay same validation on all arrays' keys you can use the following:
return [
'name' => 'required',
'additional_data' => ['array', Rule::in(['type'])]
];
2- In case each key in the array needs different validation use the following:
return [
'name' => 'required',
'additional_data' => 'array',
'additional_data.ky1' => ['your validation here'],
'additional_data.ky2' => ['your validation here'],
];

how to decode json object in laravel which is passed as form_data in postman

In first image you can see how I am sending a json object as form data in order_details parameter
In second image I am getting a response while decoding it in Laravel 7
public function makeOrder(Request $request)
{
$validator = Validator::make($request->all(), [
'table_id' => 'required',
'date' => 'required',
'time_slot' => 'required|string',
'product_ids' => 'required|array',
'total_bill' => 'required'
]);
if ($validator->fails()) {
return response()->json(['error' => $validator->messages()->first(), 'code' => 404], 404);
}
return response()->json(['order' => json_decode($request->order_details), 'code' => 200], 200);
}
I am getting the error while decoding the json data.
json_decode() expects parameter 1 to be string, array given
json_decode decodes a JSON string, you probably meant to use json_encode instead:
return response()->json(['order' => json_encode($request->order_details), 'code' => 200], 200);
The order details in the request body is an array, access first index and return it in the response
return response([
'order' => json_decode($request->order_details[0]),
'code' => 200,
]);
This in turn gives this structure in postman, which I assume is what you want

Laravel: how to use validator for single elements?

I'm trying to make validation of $id and $offer_id inside my function:
public function getMessagesForOffer($id, $offer_id)
{
$validator = Validator::make($request->all(), [
'id' => 'required|numeric',
'offer_id' => 'required|numeric',
]);
if ($validator->fails()) {
return response([
'status' => 'error',
'error' => 'invalid.credentials',
'message' => 'Invalid credentials'
], 400);
}
}
This is throwing an error: "message": "Undefined variable: request",
And I see that it's incorrect coded, how can I correct it to work with single elements when there is no request inside my function?
$request->all() would just return array, so you can also use array here, so instead of $request->all() you can use:
['id' => $id, 'offer_id' => $offer_id]
or shorter:
compact('id', 'offer_id')

Why PHP Laravel returns `500 Server Error` for Rule->unique()?

I am using the following validation in the controller:
$request->validate([
'name' => [
'required',
'max:50',
Rule::unique('center_classes')
]
]);
I also tried the following:
$request->validate([
'name' => [
'required',
'max:50',
Rule::unique('center_classes', 'The class name exist.')
]
]);
I have the following line in the validation.php:
'unique' => 'The :attribute has already been taken.',
The rest of errors are working properly but Rule->unique() is the only one which causes Error Server instead of passing message.
[HTTP/1.1 500 Internal Server Error 287ms]
You need to send validation error manually into your code like this
//use first
use Validator;
$response = array('response' => '', 'success'=>false);
$rules = array('name' => 'unique:center_classes,name');
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
$response['response'] = $validator->messages();
}else{
//process the request
}
return response()->json($response);

Laravel 5 : Customize HTML Form validation in controller file

I am using following code in controller file. I have an element name title in view form. Following code is showing correct validation. But, i need to customize this error.
$v = Validator::make($request->all(), [
'title' => 'required|max:255',
]);
if ($v->fails())
{
return redirect()->back()->withErrors($v->errors());
}
You can pass as third argument of Validator your custom messages.
$messages = [
'title.required' => 'You need to insert a pretty title'
];
v = Validator::make($request->all(), [
'title' => 'required|max:255',
], $messages
);

Resources