Hey! With recent videos I have watched there is this craze about Actions/Command Pattern. I wanted to try this out in one of my project (Larave + Livewire). I am not sure if I don't this the correct way. Below are two of my action classes. CreateUser and UpdateUser, 80% of my code is the same. Actions highly implements the SOLID principles. Now here if I add an if else statement it breaks the SOLID principles. I want to know if what I am doing is correct? Is there any way I can optimize this? Thank you in advance!
<?php
declare(strict_types=1);
namespace App\Actions\User;
use App\Models\User;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\Password;
use Spatie\Permission\Models\Role;
final readonly class CreateUser
{
/**
* Create action.
*/
public function create(array $input): User
{
$this->validateInputs($input);
$data = [
'name' => $input['name'],
'is_active' => $input['active'],
'password' => $input['password'],
'email' => $input['email'],
'mobile' => $input['mobile'],
];
$user = User::query()->create($data);
$user->syncRoles($input['role']);
return $user;
}
/**
* @throws ValidationException
*/
private function validateInputs(array $input): void
{
$rules = [
'name' => ['required', 'max:255'],
'active' => ['required', Rule::in(['1', '0'])],
'password' => ['required', 'max:255', Password::defaults()],
'email' => ['required', 'max:255', 'email:rfc,dns', Rule::unique(User::class, 'email')],
'mobile' => ['required', 'numeric', 'digits:10', Rule::unique(User::class, 'mobile')],
'role' => ['required', Rule::exists(Role::class, 'name')],
];
Validator::make($input, $rules)->validate();
}
}
<?php
declare(strict_types=1);
namespace App\Actions\User;
use App\Models\User;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Spatie\Permission\Models\Role;
final readonly class UpdateUser
{
/**
* Update action.
*/
public function update(User $user, array $input): User
{
$this->validateInputs($user, $input);
$data = [
'name' => $input['name'],
'is_active' => $input['active'],
'email' => $input['email'],
'mobile' => $input['mobile'],
];
$user->update($data);
$user->syncRoles($input['role']);
return $user;
}
/**
* @throws ValidationException
*/
private function validateInputs(User $user, array $input): void
{
$rules = [
'name' => ['required', 'max:255'],
'active' => ['required', Rule::in(['1', '0'])],
'email' => ['required', 'max:255', 'email:rfc,dns', Rule::unique(User::class, 'email')->ignore($user)],
'mobile' => ['required', 'numeric', 'digits:10', Rule::unique(User::class, 'mobile')->ignore($user)],
'role' => ['required', Rule::exists(Role::class, 'name')],
];
Validator::make($input, $rules)->validate();
}
}