Laravel Validation field must have 4 words - laravel

i want make field name be written in a quadrilateral
same
"andy hosam rami entaida"
or
"حسام احممد محمد متولى"
i tray
'name' => 'regex:/^[\wء-ي]+\s[\wء-ي]+\s[\wء-ي]+\s[\wء-ي]+/
in english all true put in arabic is false
regex is true i test it hear regexr.com/57s61
i can do with php in another way , so how can write in laravel ?
if(count(explode(' ',$name)) < 4)
{
$error[] ='enter full name with 4 words';
}

You can make a custom Rule class to do custom validation, in an encapsulated manner.
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class NumWords implements Rule
{
private $attribute;
private $expected;
public function __construct(int $expected)
{
$this->expected = $expected;
}
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
$this->attribute = $attribute;
$trimmed = trim($value);
$numWords = count(explode(' ', $trimmed));
return $numWords === $this->expected;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'The '.$this->attribute.' field must have exactly '.$this->expected.' words';
}
}
Then you can use it anywhere in validation, as below:
public function rules()
{
return [
'name' => [ 'required', 'string', new NumWords(4)],
];
}

Related

Validating Nest JSON with Parameters

I am trying to validate a nested JSON object in Laravel. I have created a custom rule to do this however I have an issue currently, I want to be able to pass the object at the current array index to my custom validator:
<?php
namespace App\Http\Requests\App;
use App\Rules\CheckoutDepatureCheck;
use App\Rules\SeatIsAvailable;
use Illuminate\Foundation\Http\FormRequest;
class CheckoutRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
"company" => "required",
"seats" => "required|array",
"seats.*.seat_no" => ['required', new SeatIsAvailable()], // would like to pass seat.* to the constructor of my custom validator here
"seats.*.schedule_id" => "required|numeric",
"seats.*.date" => "required|date"
];
}
}
The point for this is my custom validator needs schedule_id and data as well as the seat_no to successfully validate the request.
How do I do this in Laravel?
You can dynamically add rules depending on the length of the seats' array input
<?php
namespace App\Http\Requests\App;
use App\Rules\CheckoutDepatureCheck;
use App\Rules\SeatIsAvailable;
use Illuminate\Foundation\Http\FormRequest;
class CheckoutRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
$rules = [
'company' => 'required',
'seats' => 'required|array',
];
return array_merge($rules, $this->seatsRules());
}
private function seatsRules(): array
{
$rules = [];
foreach ((array) $this->request->get('seats') as $key => $seat) {
$rules["seats.$key.seat_no"] = ['required', new SeatIsAvailable($seat)];
$rules["seats.$key.schedule_id"] = 'required|numeric';
$rules["seats.$key.date"] = 'required|date';
}
return $rules;
}
}

Laravel validator required specific word

I need to validate a string must contains a specific word in the controller.
Something Like this ("%name%" is necessary):
$request->validate([
'pattern' => ['required', 'must_contains:%name%'],
]);
You can create a Custom Rule. To create the custome rule you can do:
php artisan make:rule StrMustContain
Setup class like so:
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class StrMustContain implements Rule
{
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
return str_contains('Magic Phrase', $value);
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'The expected pattern does not match.';
}
}
Then you can use like:
$request->validate([
'pattern' => ['required', new StrMustContain],
]);
I created a custom validation using this command:
php artisan make:rule StrMustContain
And then changed the class like this:
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class StrMustContain implements Rule
{
public $str;
/**
* Create a new rule instance.
*
* #return void
*/
public function __construct($str)
{
$this->str = $str;
}
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
return str_contains($value, $this->str);
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'The phrase '.$this->str.' is required.';
}
}
Then I used that:
$request->validate([
'pattern' => ['required', new StrMustContain('%name%')],
]);

How to set only one NULLABLE out of two input fields

I have two input fields one as mobile_no and other as email, i want to set a condition that out of two fields if mobile_no is not given them email must be required and vice versa.
How to set nullable condition on laravel validation that only one field out of two must be required.
You can create a custom rule. So your need is opposite of what required_if rule does, so please try this one and let me know.
First create custom rule, I call it NullableIf
php artisan make:rule NullableIf
Then the implementation should be something like this:
class NullableIf implements Rule
{
private $otherField;
/**
* Create a new rule instance.
*
* #return void
*/
public function __construct( $otherField )
{
$this->otherField = $otherField;
}
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
if($this->otherField === null)
{
return $value !== null;
}
return true;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'The validation error message.';
}
}
To use it you do:
$request->validate([
'field1' => [ new NullableIf(request('field2')) ],
'field2' => [ new NullableIf(request('field1')) ]
]);
I hope at least it gives you direction unless this exact implementation does not suits your needs.

How to validate images array type using rule object with custom message in Laravel

Actually, I tried to create rule object which is able to validate every image type in array of images and not only enough but also, I must to show custom message in override message function in rule object.
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class ImagesArray implements Rule
{
/**
* Create a new rule instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
return [$attribute => 'mimes:jpeg,jpg,png' ];
here i need to validate these file types.
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'The validation error message.';
here, I need to show my custom messgae.
}
}
You should use Request.
For example, create q request class: php artisan make:request MyRequest.
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class MyRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'image' => 'mimes:jpeg,jpg,png',
];
}
public function messages()
{
return [
'image.mimes' => 'This image is not supported.',
];
}
}
In your controller import class MyRequest and in the method use MyRequest
e.g:
public function store(MyRequest $request)
{ // your code
}
Let me know if that was helpful. Thanks!
When validating arrays or nested parameters, you should use . in your rules access a specific array index. but if you want to apply a rule to every index on that array, you can use .*.
$validator = Validator::make($request->all(), [
'image.*' => 'mimes:jpeg,jpg,png',
], [
'image.*' => 'Invalid file type.',
]);
Or if you're using Request Forms
public function rules(){
return [
'image.*' => 'mimes:jpeg,jpg,png',
];
}
public function mesages(){
return [
'image.*' => 'Invalid file type.',
];
}
For more info, see Laravel's Documentation on Validation Arrays

How to change Laravel Validation message for max file size in MB instead of KB?

Laravel comes with this validation message that shows file size in kilobytes:
file' => 'The :attribute may not be greater than :max kilobytes.',
I want to customize it in a way that it shows megabytes instead of kilobytes.
So for the user it would look like:
"The document may not be greater than 10 megabytes."
How can I do that?
We might be on different page, here is what I am trying to say. I hope this helps. Cheers!
public function rules()
{
return [
'file' => 'max:10240',
];
}
public function messages()
{
return [
'file.max' => 'The document may not be greater than 10 megabytes'
];
}
You can extend the validator to add your own rule and use the same logic without the conversion to kb. You can add a call to Validator::extend to your AppServiceProvider.
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
Validator::extend('max_mb', function($attribute, $value, $parameters, $validator) {
$this->requireParameterCount(1, $parameters, 'max_mb');
if ($value instanceof UploadedFile && ! $value->isValid()) {
return false;
}
// If call getSize()/1024/1024 on $value here it'll be numeric and not
// get divided by 1024 once in the Validator::getSize() method.
$megabytes = $value->getSize() / 1024 / 1024;
return $this->getSize($attribute, $megabytes) <= $parameters[0];
});
}
}
Then to add the error message you can just add it to your validation lang file.
See the section on custom validation rules in the manual
File: app/Providers/AppServiceProvider.php
public function boot()
{
Validator::extend('max_mb', function ($attribute, $value, $parameters, $validator) {
if ($value instanceof UploadedFile && ! $value->isValid()) {
return false;
}
// SplFileInfo::getSize returns filesize in bytes
$size = $value->getSize() / 1024 / 1024;
return $size <= $parameters[0];
});
Validator::replacer('max_mb', function ($message, $attribute, $rule, $parameters) {
return str_replace(':' . $rule, $parameters[0], $message);
});
}
Don't forget to import proper class.
File: resources/lang/en/validation.php
'max_mb' => 'The :attribute may not be greater than :max_mb MB.',
'accepted' => 'The :attribute must be accepted.',
'active_url' => 'The :attribute is not a valid URL.',
...
Change config('upload.max_size') accordingly.
This is how I would do validation using Request with custom validation messages in MB instead of KB:
Create a Request file called StoreTrackRequest.php in App\HTTP\Requests folder with the following content
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
class StoreTrackRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
"name" => "required",
"preview_file" => "required|max:10240",
"download_file" => "required|max:10240"
];
}
/**
* Get the error messages that should be displayed if validation fails.
*
* #return array
*/
public function messages()
{
return [
'preview_file.max' => 'The preview file may not be greater than 10 megabytes.',
'download_file.max' => 'The download file may not be greater than 10 megabytes.'
];
}
}
Inside the controller make sure the validation is performed through StoreTrackRequest request:
public function store($artist_id, StoreTrackRequest $request)
{
// Your controller code
}
This function works
public function getSize()
{
$mb = 1000 * 1024;
if ($this->size > $mb)
return #round($this->size / $mb, 2) . ' MB';
return #round($this->size / 1000, 2) . ' KB';
}
In Laravel 8
To generate a new validation rule.
php artisan make:rule MaxSizeRule
Edit your rule as follows.
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class MaxSizeRule implements Rule
{
private $maxSizeMb;
/**
* Create a new rule instance.
*
* #return void
*/
public function __construct($maxSizeMb = 8)
{
$this->maxSizeMb = $maxSizeMb;
}
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
$megabytes = $value->getSize() / 1024 / 1024;
return $megabytes < $this->maxSizeMb;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'The :attribute may not be greater than ' . $this->maxSizeMb . ' MB.';
}
}
Use in your validation request as follow
return [
...
'banner_image' => ['required', 'file', 'mimes:jpeg,png,jpg,svg', new MaxSizeRule(10)],
...
];
Change the string in resources\lang\en\validation.php to
'file' => 'The :attribute may not be greater than 10 Megabytes.',
and define the $rule as
$rules = array(
'file'=>'max:10000',
);

Resources