I am building a Laravel-based eCommerce solution with a shopping cart. I have a page for each product where you can choose a product option, whether you want to subscribe, how often you want to receive shipments, the quantity you want, and then add it to your shopping cart. I want to validate this combination of choices before adding to the customer's shopping cart. To validate, I need to check against the database for this product option to make sure that it can be subscribed to, that the quantity chosen is below the maximum quantity allowed for that product, etc.
With CodeIgniter, I would write a custom callback, pull in the inputs from the POST request, and check everything in one call to the database. If there was a validation failure, I would then output a relevant conditional message for what caused the validation to fail. (i.e. "You can't subscribe to that product" or "The quantity you selected is more than the maximum quantity allowed for the product.")
This seems a little more difficult to accomplish with Laravel. I was looking through the documentation and articles online, and I found an approach that seems to work.
I have my validation method in my model, CartLine. Then, in a new Form Request, I overwrite the getValidatorInstance method with the following:
public function getValidatorInstance()
{
$validator = parent::getValidatorInstance();
$validator->after(function() use ($validator) {
$cartLine = new CartLine;
$cartLine->validate($this->all());
if (!$cartLine->valid()) {
$validator->errors()->add('product', $cartLine->errors());
}
});
return $validator;
}
I have a couple of questions:
When I first experimented with this solution, I tried to use method injection for the instance of CarLine inside the closure, like so:
$validator->after(function(Validator $validator, CartLine $cartLine) use ($validator) { $cartLine->validate($this->all()); if (!$cartLine->valid()) { $validator->errors()->add('product', $cartLine->errors()); } });But I kept getting an error saying that the closure was expecting an instance of CartLine and none was given. I fixed this by newing up CartLine inside the closure, but it's obviously not as elegant. Why doesn't method injection work here?
Does anyone have a better or more elegant solution for how to accomplish this type of custom validation with conditional error messages in Laravel?
Custom Validation Rulespart to create a custom validation. - wayne