I read the official page about validation in laravel http://laravel.com/docs/validation#working-with-error-messages and I followed them. So my code is
$input = Input::all();
$validation = Validator::make($input, Restaurant::$rules);
if ($validation->passes())
{
Restaurant::create($input);
return Redirect::route('users.index');
}
else{
$messages = $validation->messages();
foreach ($messages->all() as $message)
{
echo $message + "</br>";
}
}
I can see the error message but it is just 00. Is there a better way to know in which form's field the error is and what is the error description?
I already have rules and I now the input is breaking the rules but I need to read the error message
$messages = $validation->messages();
foreach ($messages->all('<li>:message</li>') as $message)
{
echo $message;
}
Official Documentation
After calling the messages method on a Validator instance, you will receive a MessageBag instance, which has a variety of convenient methods for working with error messages.
According to the MessageBag documentation the function all Get all of the messages for every key in the bag.
You can access errors through the errors() object, and loop through the all rules' keys.
Something like this:
Route::get('error', function(){
$inputs = array(
'id' => 5,
'parentID' => 'string',
'title' => 'abc',
);
$rules = array(
'id' => 'required|integer',
'parentID' => 'required|integer|min:1',
'title' => 'required|min:5',
);
$validation = Validator::make($inputs, $rules);
if($validation->passes()) {
return 'passed!';
} else {
$errors = $validation->errors(); //here's the magic
$out = '';
foreach($rules as $key => $value) {
if($errors->has($key)) { //checks whether that input has an error.
$out.= '<p>'$key.' field has this error:'.$errors->first($key).'</p>'; //echo out the first error of that input
}
}
return $out;
}
});
Related
I have a method in parent class
Controller.php
public function invalidError($errors = [], $code = 422)
{
return response()->json([
'errors' => $errors
], $code);
}
I am passing this method the following:
if($validator->fails()) {
return $this->invalidError([
array('key' => 'Some key')
]);
}
When the response comes in the errors message is always empty array like the following:
{
"errors": []
}
What am I missing?
To get the errors array from a validator, use failed()
if($validator->fails()) {
return $this->invalidError($validator->failed());
}
If you wants the messages from the failed rules use messages()
if($validator->fails()) {
return $this->invalidError($validator->messages());
}
For more information, you can check the documentation
I have a situation and unfortunately not sure how to sort it out in proper way. I have below script
$validator = Validator::make(
$request->all(),
[
'game_id' => 'required|integer'
],
$messages
);
if ($validator->fails()) {
$response = $validator->messages();
}else{
$response = $gameService->setStatus($request);
}
Now each game has different type, I wanted to add validation on behalf of type. For example if a game is Task Based then I would add validation for time which would be mandatory only for Task based game otherwise it would be an optional for other types.
I have three types of games
1 - level_based
2 - task_based
3 - time_based
In the type table, each game has type.
So is there any way to add validation? I want to do it, inside validation function.
Thank you so much.
You can write your conditions before the validation.
$data = $request->all();
if ($data['game_id'] == 1) {
$rules = [
// level_based validation
];
} else if($data['game_id'] == 2) {
$rules = [
// task_based validation
];
} else {
$rules = [
// time_based validation
];
}
$validator = Validator::make($data, $rules);
Hope it helps. Cheers.
I would go with the required_if validation rule.
So in your case, will send two fields, the type can be a hidden field for example, then on the game_id you will add
'game_id' => 'required_if:type,1'
and so on.. And of course you can customize the error messages.
Try this code snippet
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class CreateGameRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
try {
$request = $this->request->all();
$rule_array = collect();
$rule1 = [
'game_id' => 'required|integer'
]
$rule_array = $rule_array->merge($rule1);
if(isset($request->task_id))
{
$rule2 = [
'task_id' => 'required|integer'
]
}
$rule_array = $rule_array->merge($rule2);
return $rule_array->all();
} catch (Exception $e) {
return $e;
}
}
public function messages(){
return [
'game_id' => 'Please select valid game',
'task_id' => 'Please select valid task'
];
}
}
then invoke this request class in controller function as
use App\Http\Requests\CreateGameRequest;
public function game(CreateGameRequest $request)
{
}
I have a form that contains a field for user to enter amount value of certain payment. This field is input of type number.
The validation rule in Laravel for this input is:
'amount' => 'required|numeric'
When I enter the amount in English as: 1500 => The validation passes and everything is OK.
But when I enter the amount in Arabic as: ١٥٠٠ => The validation fails with the following error message:
"validation.numeric"
Should I validate this field manually or is there another solution to this problem?
Maybe you can create your own validation type.
You can add something like this to your boot method in app/Providers/AppServiceProvider.php.
Validator::extend('arabic_numbers', function ($attributes, $value, $parameters, $validation) {
$arabic_numbers = [
'٥',
'١',
// add more
];
$input = $value;
if (!$input) {
return false;
}
$chars = preg_split('//u', $input, -1, PREG_SPLIT_NO_EMPTY);
foreach ($chars as $char) {
if (!in_array($char, $arabic_numbers)) {
return false;
}
}
return true;
});
You can add to your existing rule, e.g. required|arabic_numbers.
Or use something like this:
$input = '١';
$validator = Validator::make([
'user_input' => $input,
], [
'user_input' => 'required|arabic_numbers'
];
if ($validator->fails()) {
//
}
Also you can use in many other ways for example in a custom request:
public function rules()
{
return [
'something' => 'required|arabic_numbers',
];
}
Hope this helps.
I'm building an api using laravel, the issue is when the client requests my api by calling create() function, and the create()function will call a getValidatedData() function which I want to return validation errors to the client if validation fails or return the validated data to insert database if validation passes, my getValidatedData function is like below so far
protected function getValidatedData(array $data)
{
// don't format this class since the rule:in should avoid space
$validator = Validator::make($data, [
'ID' => 'required',
'weight' => 'required',
]);
if ($validator->fails()) {
exit(Response::make(['message' => 'validation fails', 'errors' => $validator->errors()]));
}
return $data;
}
I don't think exit() is a good way to return the errors message to clients. are there any other ways I can return the laravel Response to clients directly in an inner function. use throwing Exception?
This was what worked for me in Laravel 5.4
protected function innerFunction()
{
$params = [
'error' => 'inner_error_code',
'error_description' => 'inner error full description'
];
response()->json($params, 503)->send();
}
What you can do is using send method, so you can use:
if ($validator->fails()) {
Response::make(['message' => 'validation fails', 'errors' => $validator->errors()])->send();
}
but be aware this is not the best solution, better would be for example throwing exception with those data and adding handling it in Handler class.
EDIT
As sample of usage:
public function index()
{
$this->xxx();
}
protected function xxx()
{
\Response::make(['message' => 'validation fails', 'errors' => ['b']])->send();
dd('xxx');
}
assuming that index method is method in controller you will get as response json and dd('xxx'); won't be executed
You can use this method
public static function Validate($request ,$rolse)
{
// validation data
$validator = Validator::make($request->all(),$rolse);
$errors = $validator->getMessageBag()->toArray();
$first_error = array_key_first($errors);
if (count($errors) > 0)
return 'invalid input params , ' . $errors[$first_error][0];
return false;
}
in controller :
$validate = ValidationHelper::Validate($request,
['title' => 'required']);
if ($validate)
return response()->json(['message' =>'validation fails' , 'error'=> $validate], 403);
I use the following rules for validation on creating a new user:
protected $rules= [
'name' => 'required',
'email' => [
'required',
'unique:user',
'email'
]
];
When updating an existing user I use the same ruleset as shown above
but don't want a validation error if the user didn't change his email at all.
I currently resolve this by using the following:
if (!User::changed('email')) {
unset($user->email);
}
It feels like a dirty workaround to me so I was wondering if there are better alternatives.
Also note that the changed method is something I wrote myself. Does anyone know if there
is a native Laravel 4 method for checking whether a model property has changed?
Thanks!
The unique validation rule allows to ignore a given ID, which in your case is the ID of the data set you are updating.
'email' => 'unique:users,email_address,10'
http://four.laravel.com/docs/validation#rule-unique
One approach is to create a validation function in the model and call it with the controller passing in the input, scenario and id (to ignore).
public function validate($input, $scenario, $id = null)
{
$rules = [];
switch($scenario)
{
case 'store':
$rules = [
'name' => 'required|min:5|unique:users',
'email' => 'required|email|unique:users',
'password' => 'required|min:4|confirmed'
];
break;
case 'update';
$rules = [
'name' => 'required|min:5|unique:users' .',name,' . $id,
'email' => 'required|email|unique:users' .',email,' . $id,
'password' => 'min:4|confirmed'
];
break;
}
return Validator::make($input, $rules);
}
Then in the controller:
$input = Input::all();
$validation = $user->validate($input, 'update', $user->id);
if ($validation->fails())
{
// Do stuff
}
else
{
// Validation passes
// Do other stuff
}
As others mentioned, the 3rd parameter of the unique rule specifies an id to ignore. You can add other cases, such as 'login' to reuse the validation function.
Alternatively, Jeffrey Way at Tuts Premium has a great series of lessons in "What's New In Laravel 4" which includes a couple of other approaches to handling validation using services and listeners.
See the documentation on http://four.laravel.com/docs/validation#rule-unique
You can exclude the users own id
protected $rules= [
'name' => 'required',
'email' => [
'required',
'unique:user,email,THE_USERS_USER_ID',
'email'
]
];
As of 2014-01-14, you can use sometimes attribute, I believe Taylor added them 2 days ago to Laravel 4.1
$v = Validator::make($data, array(
'email' => 'sometimes|required|email',
));
sometimes only validate input if it exists. this may or may not suit your exact scenario, if you don't have a default value for insert.
http://laravel.com/docs/validation#conditionally-adding-rules
I handle this sort of thing in my validator function. My validators array is setup as a class variable. I then do something like this:
public function validate()
{
//exclude the current user id from 'unqiue' validators
if( $this->id > 0 )
{
$usernameUnique = 'unique:users,username,'.$this->id;
$emailUnique = 'unique:users,email,'.$this->id;
$apiUnique = 'unique:users,api_key,'.$this->id;
}
else
{
$usernameUnique = 'unique:users,username';
$emailUnique = 'unique:users,email';
$apiUnique = 'unique:users,api_key';
}
$this->validators['username'] = array('required', 'max:32', $usernameUnique);
$this->validators['email'] = array('required', 'max:32', $emailUnique);
$this->validators['api_key'] = array('required', 'max:32', $apiUnique);
$val = Validator::make($this->attributes, $this->validators);
if ($val->fails())
{
throw new ValidationException($val);
}
}
I have solved this by having different rules for update and create on models that need to do so, like Users.
I have a Model class that extends Eloquent, where I define the validation, and then all child models that extend the Model can have have both the $rules and $update_rules defined. If you define only $rules, it will be used both for create and update.
class Model extends Eloquent {
protected $errors;
protected static $rules = array();
protected $validator;
public function __construct(array $attributes = array(), Validator $validator = null) {
parent::__construct($attributes);
$this->validator = $validator ?: \App::make('validator');
}
protected static function boot() {
parent::boot();
# call validatie when createing
static::creating(function($model) {
return $model->validate();
});
# call validatie when updating with $is_update = true param
static::updating(function($model) {
return $model->validate(true);
});
}
public function validate($is_update = false) {
# if we have $update_rules defined in the child model, and save is an update
if ($is_update and isset(static::$update_rules)) {
$v = $this->validator->make($this->attributes, static::$update_rules);
}
else {
$v = $this->validator->make($this->attributes, static::$rules);
}
if ($v->passes()) {
return true;
}
$this->setErrors($v->messages());
return false;
}
protected function setErrors($errors) {
$this->errors = $errors;
}
public function getErrors() {
return $this->errors;
}
public function hasErrors() {
return ! empty($this->errors);
}
}