Laravel only ignore field if user id is present - laravel

If an user is logged in I need to ignore if the email field already exists in the users table. But if the user is not logged in the rule should be applied.
Naturally I only have the user id if the user is logged in. So what is your alternative to this?
public function rules(): array
{
return [
'email' => ['required', 'email:filter', Rule::unique('users')->ignore(Auth::user()->id)],
];
}

You can define the rules as a variable, and append the Rule if the Auth::user() is present:
public function rules(): array {
$rules = [
'email' => [
'required',
'email:filter'
]
];
if (Auth::user()) {
$rules['email'][] = Rule::unique('users')->ignore(Auth::user()->id);
}
return $rules;
}
However, I would expect that you still want emails to be unique within the users table of your Database, regardless if a User is logged in or not, in which case you can use a ternary:
public function rules(): array {
return [
'email' => [
'required',
'email:filter',
Auth::user() ? Rule::unique('users')->ignore(Auth::user()->id) : Rule::unique('users')
]
];
Use whatever approach works best for your scenario.

Related

Find data before validate form request laravel

I want to update the data using the request form validation with a unique email role, everything works normally.
Assume I have 3 data from id 1-3 with url:
127.0.0.1:8000/api/user/update/3
Controller:
use App\Http\Requests\Simak\User\Update;
...
public function update(Update $request, $id)
{
try {
// UPDATE DATA
return resp(200, trans('general.message.200'), true);
} catch (\Exception $e) {
// Ambil error
return $e;
}
}
FormRequest "Update":
public function rules()
{
return [
'user_akses_id' => 'required|numeric',
'nama' => 'required|max:50',
'email' => 'required|email|unique:users,email,' . $this->id,
'password' => 'required',
'foto' => 'nullable|image|max:1024|mimes:jpg,png,jpeg',
'ip' => 'nullable|ip',
'status' => 'required|boolean'
];
}
but if the updated id is not found eg:
127.0.0.1:8000/api/user/update/4
The response gets The email has already been taken.
What is the solution so that the return of the data is not found instead of validation first?
The code looks like it should work fine, sharing a few things below that may help.
Solution 1: Check if $this->id contains the id you are updating for.
Solution 2: Try using the following changes, try to get the id from the URL segment.
public function rules()
{
return [
'user_akses_id' => 'required|numeric',
'nama' => 'required|max:50',
'email' => 'required|email|unique:users,email,' . $this->segment(4),
'password' => 'required',
'foto' => 'nullable|image|max:1024|mimes:jpg,png,jpeg',
'ip' => 'nullable|ip',
'status' => 'required|boolean'
];
}
Sharing one more thing that may help you.
Some person uses Request keyword at the end of the request name. The Update sounds generic and the same as the method name you are using the request for. You can use UpdateRequest for more code readability.
What I understand from your question is, you need a way to check if the record really exists or not in the form request. If that's the case create a custom rule that will check if the record exists or not and use that rule inside your request.
CheckRecordRule
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class CheckRecordRule implements Rule
{
protected $recordId;
public function __construct($id)
{
$this->recordId = $id;
}
public function passes($attribute, $value)
{
// this will check and return true/false
return User::where('id', $this->recordId)->exists();
}
public function message()
{
return 'Record not found.';
}
}
Update form request
public function rules()
{
return [
'email' => 'required|email|unique:users,email,' . $this->id.'|'. new CheckRecordRule($this->id),
];
}
So when checking for duplicate it will also check if the record really exists or not and then redirect back with the proper message.

Validation of array in laravel

I am building a small application in Laravel 5.6 where I am having an api which takes an array in format [1,2,5,90,25] I want to validate as required field in my validation rule.
I tried creating a request and validating the same as:
public function rules()
{
return [
'ProjectType.*'=> 'required',
]
}
public function messages()
{
return [
'projectType.*.required' => 'Project type is required',
];
}
But this thing is not working out, even if an empty array [] is being passed it accepts it.
How can we achieve these kind of array format
You must validate at the top level of the array, you may want this validation:
public function rules()
{
return [
'ProjectType'=> 'required|array',
'ProjectType.*'=> 'required',
]
}
public function messages()
{
return [
'projectType.*.required' => 'Project type is required',
];
}

Right way to handle this situation using Laravel validation

i am new in Laravel and I would like to have some directive on how to handle this situation.
I have two entities: Ad and Nomination. Ad can have many Nominations.
In a controller i receive two external inputs: [ad_id] and [nomination_id] both required.
What i have to do with these two inputs is:
Check if [ad_id] is an existing Ad entity and his attribute "active" is true.
Check [nomination_id] is an existing Nomination entity.
Only if [ad_id] was an existing Ad and [nomination_id] was an existing Nomination check if this Nomination belongs to this Ad.
Can you show me an example about how to manage this using only validation class?
You can write your validation rules like this
public function rules()
{
return [
'ad_id' => [
'bail',
'required',
Rule::exists('ads')->where(function ($query) use ($request) {
$query->where([
['active' => 1],
['id' => $request->ad_id]
]);
}),
],
'nomination_id' => [
'bail',
'required',
Rule::exists('nominations')->where(function ($query) use ($request) {
$query->where([
['ad_id' => $request->ad_id],
['id' => $request->nomination_id]
]);
}),
],
];
}
Assuming you have ads and nominations are tables name and primary key field is id and ad_id as foreign key in nominations table.
It's pretty straightforward - you can write validation rules just as you listed them in your question:
$validator = Validator::make($request->only('ad_id', 'nomination_id'), [
'ad_id' => 'required|exists:ads,id,active,1',
'nomination_id' => 'required|exists:nominations,id,ad_id,' . $request->ad_id,
]);
if ($validator->fails()) {
...
}
$inputAd = <some_value>;
$inputNomination = <some_value>;
$nomination = Nomination::where(['id' => $inputNomination])->with(['ads'])->first();
if(!$nomination || !($nomination->ad_id == $inputAd)) {
// not the same
}
// same
To validate the ad_id and nomination_id, you can use laravel in rule.
FormRequest Class
public function rules()
{
return [
'ad_id' => [
'required',
Rule::in(Ad::where('active', true)->pluck('id')->toArray()),
],
'nomination_id' => [
'required',
Rule::in(Nomination::where('id', $this->nomination_id)->where('ad_id', $this->ad_id)->pluck('id')->toArray()),
],
];
}
The Rule::in(Ad::where('active', true)->pluck('id')->toArray()), rule will check if the ad_id is present in the array of ids of Ad which have active field is true.
The Rule::in(Nomination::where('id', $this->nomination_id)->where('ad_id', $this->ad_id)->pluck('id')->toArray()), rule will check if the nomination_id is present in the array of ids of Nomination which is related to Ad.

unique value with custom request laravel 5.3

i have custom request in laravel ..
this is the code
public function rules()
{
if($this->ajax())
{
return [];
}
else
{
return
[
'username'=> 'required|min:3|max:30|unique:users',
'password'=> 'required|min:6',
'email'=>'required|min:3|max:35|unique:users',
'permission'=>'required',
'phone'=>'required',
'division'=>'required',
];
}
}
and i need to to ignore the current id from validation
i tried this
public function rules()
{
if($this->ajax())
{
return [];
}
else
{
return
[
'username'=> 'required|min:3|max:30|unique:users,id'.$this->id,
'password'=> 'required|min:6',
'email'=>'required|min:3|max:35|unique:users',
'permission'=>'required',
'phone'=>'required',
'division'=>'required',
];
}
}
but its ignoring the whole user name from validation not just the current id ..
Use auth()->user()->id instead of $this->id to get current user's ID.
Also, I'm not sure about the syntax you're using when trying to add ignoring ID. From unique() rule docs:
To instruct the validator to ignore the user's ID, we'll use the Rule class to fluently define the rule. In this example, we'll also specify the validation rules as an array instead of using the | character to delimit the rules:
use Illuminate\Validation\Rule;
Validator::make($data, [
'email' => [
'required',
Rule::unique('users')->ignore($user->id),
],
]);

laravel 5.2 auth Conditions for email verify

i want to edit auth and add Additional Conditions
for check user for active or ...
where can edit authcontroller code?
First you need a status column in users table to mark the user as active or inactive.
To check the user status during login you need to modify this file:
project_folder\vendor\laravel\framework\src\Illuminate\Foundation\Auth\AuthenticatesUsers.php
You can change validateLogin() method. I assume, for active user the status code is 1 and 0 for inactive user. Your code should look like this:
protected function validateLogin(Request $request)
{
$this->validate($request, [
$this->loginUsername() => 'required', 'password' => 'required', 'status' => 1,
]);
}
In Auth\AuthController.php, add this function ( I assume the column name for user status is "is_active" ):
public function authenticated($request, $user) {
if ($user->is_active != 'Y') {
Auth::logout();
return redirect('login')->withErrors([
$this->loginUsername() => 'Your '.$this->loginUsername().' is not active. Please contact Administrators'
]);
}else {
return redirect()->intended($this->redirectPath());
}
}

Resources