I've got the following model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $guarded = ['id'];
public static function rules()
{
return [
'created_at' => 'nullable',
'updated_at' => 'nullable',
'name' => 'required|string|between:1,255',
'description' => 'required|string|between:1,255',
'date_added' => 'nullable',
'date_edited' => 'nullable',
'unit' => 'required|string|between:1,255',
'unit_type' => 'required|integer',
'stock' => 'nullable|string|between:0,255',
'barcode' => 'nullable|string|between:0,32',
'tax' => 'nullable|float',
'price' => 'nullable|float',
'category_id' => 'required|integer|gt:0'
];
}
}
And there's a controller ProductController
that has an action insertProduct
.
class class ProductController extends ApiController { // controller class
public function insertProduct(Request $request) {
$inputJson = $request->input('data_json', null);
if(empty($inputJson)) {
$inputJson = $request->getContent();
if(empty($inputJson)) {
return $this->errorResponse(
'Either data_json formdata parameter or request body should contain a JSON string.'
);
}
}
try {
$product = $this->extractProductFromJSON($inputJson);
} catch(\Exception $e) {
return $this->errorResponse($e->getMessage(), 400);
}
// When I dump the Product ($product) instance using dd(), it is just as expected and its
// properties contain the right values.
$validator = Validator::make($product, Product::rules());
/* Above line causes exception:
TypeError: Argument 1 passed to Illuminate\Validation\Factory::make() must be of the type
array, object given,
called in /.../vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php
on line 261 in file /.../vendor/laravel/framework/src/Illuminate/Validation/Factory.php
on line 98
*/
if($validator->fails()) {
return $this->errorResponse($validator->errors()->first());
}
// ...
}
// How I extract the data from the JSON string (which is input).
// Although I don't think this has anything to do with my problem.
private function extractProductFromJSON(string $json) {
$data = \json_decode($json);
if(\json_last_error() != JSON_ERROR_NONE) {
throw new \Exception('Error parsing JSON: ' . \json_last_error_msg());
}
try {
$productData = $data->product;
$productId = empty($productData->id) ? null : $productData->id;
// Product id is allowed to be absent
$product = new Product(); // My \App\Product model instance.
$product->id = $productId;
$product->name = $productData->name;
$product->description = $productData->description;
$product->date_added = $productData->date_added;
$product->date_edited = $productData->date_edited;
$product->unit = $productData->unit;
$product->unit_type = $productData->unit_type;
$product->stock = $productData->stock;
$product->barcode = $productData->barcode;
$product->tax = $productData->tax;
$product->price = $productData->price;
$product->category_id = $productData->category_id;
return $product;
} catch(\Exception $e) {
echo 'EXCEPTION...';
}
}
} // end of controller class
It seems pretty clear there's something wrong with the following line:
$validator = Validator::make($product, Product::rules());
The simplest cause I can think of, is that the validator simply does not accept objects and only wants arrays.
If not, what could be the problem?
If Laravel's validation only works with arrays, is it somehow possible to validate an object?
validator = Validator::make($product, Product::rules());
the problem is not Product::rules()
but $product
. Product::rules()
is correct because it's return an array, but $product
is an object instead of an array. You should change/convert $product
to an array an example:
validator = Validator::make((array)$product, Product::rules());