Creating two seperate validation messages for the same attribute - php

I'm trying to create two separate validation messages for the same validation attribute.
There are two rules that use "before_or_equal" - the end_time has to be "before_or_equal" start_time and also the end_time has to be after 5:00 (time). The validation works, but I can't seem to find a way to create a working custom message for the latter.
I tried to specify the rule by including it literally with the value, but it doesn't seem to work.
This is what the custom request validation looks like for the end_time at the moment.
public function rules()
{
return [
'end_time' => ['after_or_equal:start_time', 'after_or_equal:5:00'],
];
}
public function messages()
{
return [
'end_time.after_or_equal' => 'Message 1',
'end_time.after_or_equal:5:00' => 'Message 2',
];
}

You can use :date for your custom error messages.
Example:
public function rules()
{
return [
'end_time' => ['after_or_equal:start_time', 'after_or_equal:5:00'],
];
}
public function messages()
{
return [
'end_time.after_or_equal' => 'the :attribute time must be after :date',
];
}
The replaced value is actual value of first input of the validator

i don't know if i understand your question correctly, but are you looking for something like this ?
public function rules()
{
return $this->messages("end_time", [
"after_or_equal",
"after_or_equal:5:00",
]);
}
public function messages(string $Key, array $CustomAttributes)
{
$Exceptions = [
"end_time" => [
"after_or_equal" => "Message 1",
"after_or_equal:5:00" => "Message 2"
]
];
$Exception = [
$Key => []
];
foreach ($CustomAttributes as $Attribute) {
array_push($Exception[$Key], $Exceptions[$Key][$Attribute]);
}
return $Exception;
}

Related

Laravel how to validate distinct rule only between inner array

'variants' => ['nullable', 'array'],
'variants.*.name' => ['required', 'string'],
'variants.*.options' => ['required', 'array', 'min:1'],
'variants.*.options.*.code' => ['required', 'string', 'distinct'],
I'm having a validation rules above. What I'm trying to achieve is the distinct of the value only for between inner array, but somehow I'm getting an error like this with the input
input:
{
variants: [
{
name: "outer array 1",
options: [
{
code: "A"
},
{
code: "B"
}
]
},
{
name: "outer array 2",
options: [
{
code: "A"
},
]
}
]
}
result:
"error": {
"variants.0.options.0.code": [
"The variants.0.options.0.code field has a duplicate value."
],
"variants.1.options.0.code": [
"The variants.1.options.0.code field has a duplicate value."
]
}
Question: Any way to distinct only between the inner array but not every array?
using custom validation rule:
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class Distinct implements Rule
{
protected string $message;
protected string $strict = '';
public function __construct(bool $strict)
{
$this->strict = $strict ? ':strict' : '';
}
/**
* #param string $attribute
* #param array $value
* #return bool
*/
public function passes($attribute, $value)
{
try {
$validation = \Validator::make(['array' => $value], [
'array.*' => ["distinct{$this->strict}"]
]);
$this->message = 'The field has a duplicate value.';
return !$validation->fails();
} catch (\Exception $exception) {
$this->message = "array error";
return false;
}
}
public function message()
{
return $this->message;
}
}
Not sure if you've already worked it out, but I encountered the same issue and here is my workaround:
$rule = [
...,
'variants.*.options.0.code' => ['required', 'string', 'distinct'],
'variants.*.options.1.code' => ['required', 'string', 'distinct'],
]
If you want to apply 'distinct' rule on each individual item's array elements, you need to specify index specifically. If validating like 'variants.*.options.*.code' => ['required', 'string', 'distinct'], it will take into account array elements of other items too.
At the moment, I am not figuring out the reason why it behaves like that as when using dd($validator->getRules()), the rules processed by the validator is the same.
Any additional insight on this would be much appreciated.

Yii2 prevent TimestampBehavior

I am creating a custom Identity interface without created_at property. I got an error :
"name": "Unknown Property",
"message": "Setting unknown property: api\\common\\models\\User::created_at",
I tried to comment the TimestampBehavior, but I got the following error:
"name": "PHP Warning",
"message": "Invalid argument supplied for foreach()",
I want to know where is the problem.
Model class:
class User extends ActiveRecord implements IdentityInterface
{
public static function tableName()
{
return '{{%user}}';
}
public function behaviors()
{
// return [
// TimestampBehavior::className(),
// ];
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['purpose'], 'required'],
[['status'], 'integer'],
];
}
}
for the rest controller the action is
public function actionLogin(){
.
.
.
$api_user = new User();
$api_user->purpose="app";
$api_user->status=User::STATUS_ACTIVE;
if($api_user->save()){
$success = true;
}
}
This will automatically resolve the issue. BlameableBehavior and TimestampBehavior
// Include these on the start
use yii\behaviors\BlameableBehavior;
use yii\behaviors\TimestampBehavior;
use Carbon\Carbon;
// Paste this function inside the class.
/**
* #return array
*/
public function behaviors()
{
return [
'blameable' => [
'class' => BlameableBehavior::className(),
'createdByAttribute' => 'created_by',
'updatedByAttribute' => 'updated_by',
],
'timestamp' => [
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'created_at',
'updatedAtAttribute' => 'updated_at',
'value' => Carbon::now(),
],
];
}
NOTE: If you are not using updated_at or updated_by then remove it
form the above code
change your Behavior in your model to:
public function behaviors()
{
return [
'timestamp' => [
'class' => 'yii\behaviors\TimestampBehavior',
'attributes' => [
ActiveRecord::EVENT_BEFORE_INSERT => ['updated_at'],
ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'],
],
'value' => new Expression('NOW()'),
],
];
}
if you haven't updated_at also delete it from attributes.
You were getting following warning because you've completely removed the return in the behaviors() method.
"name": "PHP Warning",
"message": "Invalid argument supplied for foreach()",
The behaviors method must return an array. If you don't want to use any behavior your behaviors() method should return empty array like this:
public function behaviors()
{
return [];
}
This is also default implementation of behaviors() method in yii\base\Component so if you don't need to use any behavior you can simply remove the behaviors() method from your model.
Attaching TimestampBehavior to your model when you are not using it means that you add unnecessary overhead.
Example: Rename and prevent time recording or remove properties. Also change the value
Rename or delete properties or change value.
public function behaviors()
{
return [
[
'class' => \yii\behaviors\TimestampBehavior::className(),
'createdAtAttribute' => 'created_at',
// 'createdAtAttribute' => 'c_time', //Change the name of the field
'updatedAtAttribute' => false, //false if you do not want to record the creation time.
// 'value' => new Expression('NOW()'), // Change the value
],
];
}
Or
'class' => \yii\behaviors\TimestampBehavior::className(),
'attributes' => [
\yii\db\ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
// \yii\db\ActiveRecord::EVENT_BEFORE_UPDATE => [],
],
$createdAtAttribute: The attribute that will receive timestamp value Set this property to false if you do not want to record the creation time.
$attributes: List of attributes that are to be automatically filled with the value specified via $value. The array keys are the ActiveRecord events upon which the attributes are to be updated, and the array values are the corresponding attribute(s) to be updated. You can use a string to represent a single attribute, or an array to represent a list of attributes. For example,
[
ActiveRecord::EVENT_BEFORE_INSERT => ['attribute1', 'attribute2'],
ActiveRecord::EVENT_BEFORE_UPDATE => 'attribute2',
]

Laravel date validation literal 'after' value

I have created a form request file which validates my start_date form input.
public function rules()
{
return [
'start_date' => 'required|date|after:2017-06-31',
];
}
I have placed a literal value in the after value, this however doesn't look like its working. Can someone advise the best way to do this?
Edit:
This is the dump from my $request->all();
{
"_token": "tZa4e39ejrGHtrlpOYrUPfZ8PgSeD8FelY4voKni",
"start_date": "2017-07-01"
}
This is my form request validation:
public function rules()
{
return [
'start_date' => 'required|date_format:Y-m-d|after:2017-06-31',
];
}
I am using Laravel v5.4
The dates will be passed into the PHP strtotime function so change
your date format to Y-m-d .
public function rules()
{
return [
'start_date' => 'required|date|date_format:Y-m-d|after:2017-06-31',
];
}

Laravel 5 - Conditional statements within FormRequest rules

Using Laravel 5.0, within a form request, validation rules can be made as such:
class MyCustomRequest extends Request {
public function authorize()
{
return Auth::check();
}
public function rules()
{
$rules = [
'title' => 'required|max:255',
];
return $rules;
}
}
How do I create a rule that tests a conditional statement such as:
'user_id' === \Auth::id();
where user_id is an item from the requests parameter bag
You can use exists rule in your rule array.
https://laravel.com/docs/5.2/validation#rule-exists
public function rules()
{
$rules = [
'title' => 'required|max:255',
'user' => 'exists:users',
];
return $rules;
}
Edit: If you trying to check if a submitted value matches with your values you can use the rule "in".
https://laravel.com/docs/5.2/validation#rule-in
You need to provide ids in a comma separated string. Not tested but you can try something like this.
public function rules()
{
$ids = implode(",", DB::table('users')->all()->pluck('id'));
$rules = [
'user_id' => 'in:'. $ids,
];
return $rules;
}
If you just trying to check with current user id then this should work.
public function rules()
{
$rules = [
'user_id' => 'in:'. Auth::user()->id,
];
return $rules;
}

Custom error message is not working laravel5.1 form request?

Custom error message in form request class in not working, my form request class given below,
class FileRequest extends Request {
protected $rules = [
'title' => ['required', 'max:125'],
'category_id' => ['required', 'integer', 'exists:file_categories,id']
];
public function authorize() {
return true;
}
public function rules() {
return $this->rules;
}
public function message() {
return [
"category_id.required" => 'Category required',
];
}
}
Here when category_id is null, showing error message category id is required instead of Category required in laravel 5.1?
It is messages, not message.
Change
public function message()
to
public function messages()
You do not need to create any functions to change these messages. In the file /resources/lang/en/validation.php you can add translations for the field names you are using in the attributes array.
In your case, you would do the following:
return [
'attributes' => [
'category_id' => 'Category'
],
];
Now, whenever the category_id doesn't pass the validations, the error message will display this simply as Category.

Categories