ldc-supportweb/app/Console/Commands/MakeUser.php

160 lines
4.5 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
namespace App\Console\Commands;
use App\Models\User;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Date;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Illuminate\Validation\Rules\Password;
use Illuminate\Validation\ValidationException;
use Uwil\LaravelBackend\Support\UserRoleRegistry;
/**
* Artisan command to create a support admin user.
*/
class MakeUser extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
#[\Override]
protected $signature = 'support:make:user';
/**
* The console command description.
*
* @var string
*/
#[\Override]
protected $description = 'Create a new Support user.';
/**
* Execute the console command.
*/
public function handle(): void
{
$this->components->info('Creating a new <comment>Support user</comment>...');
$firstName = $this->askValid(
'first_name',
'First name',
'Admin',
['required', 'min:3', 'max:255'],
);
$lastName = $this->askValid(
'last_name',
'Last name',
'Saïtama',
['required', 'min:3', 'max:255'],
);
$email = $this->askValid(
'email',
'Email',
'equipe.web@ldc.fr',
['required', 'unique:users,email', 'email:rfc,strict,dns,spoof,filter'],
);
$role = $this->askRole();
$password = $this->askPassword();
$user = new User([
'first_name' => $firstName,
'last_name' => $lastName,
'email' => $email,
'role' => $role->value,
'published' => true,
'published_at' => Date::now(),
]);
$user->saveOrFail();
$user->userPassword()->create([
'password' => bcrypt($password),
]);
$this->components->success("User <comment>{$firstName} {$lastName}</comment> created successfully.");
}
/**
* Ask for a value and validate it, re-prompting on failure.
*
* @param array<int, string> $rules
*/
private function askValid(string $field, string $label, string $default, array $rules): string
{
try {
$value = $this->ask(sprintf('Type the wanted user %s', $label), $default);
$validator = Validator::make([$field => $value], [$field => $rules]);
$validator->validate();
return $value;
} catch (ValidationException $e) {
$this->components->error(
collect($e->errors())->flatten()->first()
);
return $this->askValid($field, $label, $default, $rules);
}
}
/**
* Ask for a role and return the corresponding RoleEnum.
*
2026-05-19 12:25:21 +02:00
* @return object{name: string, value: int|string, label: string}
*/
private function askRole(): object
{
2026-05-19 12:25:21 +02:00
$roles = UserRoleRegistry::all();
$defaultRole = UserRoleRegistry::get('client');
$options = collect($roles)->mapWithKeys(
fn (object $role) => [Str::ucFirst($role->label) => $role]
2026-05-26 13:12:45 +02:00
);
2026-05-19 12:25:21 +02:00
$choice = $this->choice(
'Role',
$options->keys()->all(),
Str::ucFirst($defaultRole->label),
);
$choiceKey = is_string($choice) ? $choice : (string) $choice[0];
2026-05-19 12:25:21 +02:00
return $options->get($choiceKey) ?? $defaultRole;
}
/**
* Ask for a password and confirmation password.
*/
private function askPassword(): string
{
$password = $this->secret('Type the wanted user Password');
$passwordConfirmation = $this->secret('Confirm the password');
try {
Validator::make(
[
'password' => $password,
'password_confirmation' => $passwordConfirmation,
],
[
'password' => [
'required',
'confirmed',
'max:255',
Password::min(8)->letters()->mixedCase()->numbers()->symbols()->uncompromised(),
],
]
)->validate();
return $password;
} catch (ValidationException $e) {
$this->components->error(collect($e->errors())->flatten()->first());
return $this->askPassword();
}
}
}