How to set only one NULLABLE out of two input fields - laravel

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.

Related

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%')],
]);

Laravel - Good practice to put query in custom request?

I use a custom query, and I add a custom rule to it too, and I wanted to know if putting eloquent queries in the rule is a "good practice"?
For me it's pretty dirty, but I don't really see how else to do it, and I haven't found any answers...
I have to make in the rule, parameters...
Edit (add code)
<?php
namespace App\Rules;
use App\Model\Laravel\Api;
use App\Model\Laravel\Package;
use App\Model\Laravel\User;
use Illuminate\Contracts\Validation\Rule;
class ApiMax implements Rule
{
protected $user;
/**
* Create a new rule instance.
*
* #param $user
*/
public function __construct($user)
{
$this->user = $user;
}
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
$maxApi = $this->getPackageInfo($this->user)->max_api - $this->sumApis($this->user);
if($value > $maxApi)
return false;
return true;
}
public function getPackageInfo(User $user)
{
return Package::where('id', $user->getPackageId())->first();
}
public function sumApis(User $user) {
return Api::where('user_id', $user->getId())->count();
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'You have reached the maximum number of apis with your current offer.';
}
}
Thank you in advance for your tips

Laravel Validation field must have 4 words

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)],
];
}

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

Laravel validation using class

I am trying to use Laravel validation : as described here
I am not going to place entire rule class, as it is straight from artisan make:rule.
PROBLEM:
When I try to test 'false' here:
function passes($attribute, $value)
{
return false; //testing 'false' logs me out
}
This is how I use it in controller:
$this->validate($request, [
'image_64' => ['required', new \App\Rules\Base64Rule]
]);
It is like redirect isn't going to form page, but index page - which in my case logs user out (among other things).
Is there any protected var to mark proper redirect route, when method 'passes' returns false?
Anyone came across something like this?
EDIT
Sam,
As I mentioned, rule class is pristine - freshly generated:
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class Base64Rule 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 false;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'The validation error message.';
}
}
If I run on top of my controller anything like:
use App\Rules\Base64Rule;
$rule = new Base64Rule;
dd($rule->passes('image_64', 'udfshjbfisuusoshgosghosh'));
I get whatever I have in rule's method passes().
If I use in rule's method passes() return true; it works right.
If I use in rule's method passes() dd('some'), I get 'some' in that controller test.
When test is 'false' and regular validation code is used:
use App\Rules\Base64Rule;
$this->validate($request, [
'image_64' => ['required', new Base64Rule]
]);
... I get redirected to index page.
I have to follow request/response and see, where Laravel fails and why ... I guess. And is it my code, or a bug.

Resources