Задача: разработать страницу для создания учётной записи в AD в рамках проекта на Filament 3 и Laravel 12. На этой странице пользователь сможет ввести свои ФИО, а после нажатия кнопки «Получить файлик» — получить файл с данными об учётной записи, включая логин и сгенерированный пароль.

Решение
Шаг 1: создание хелпера
Создайте хелпер для генерации паролей. Например, в папке app/Helpers
создайте файл TransliterationHelper.php
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <?php namespace App\Helpers; class TransliterationHelper { private array $transliterationMap = [ 'а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd', 'е' => 'e', 'ё' => 'e', 'ж' => 'zh', 'з' => 'z', 'и' => 'i', 'й' => 'y', 'к' => 'k', 'л' => 'l', 'м' => 'm', 'н' => 'n', 'о' => 'o', 'п' => 'p', 'р' => 'r', 'с' => 's', 'т' => 't', 'у' => 'u', 'ф' => 'f', 'х' => 'h', 'ц' => 'ts', 'ч' => 'ch', 'ш' => 'sh', 'щ' => 'sch', 'ъ' => '', 'ы' => 'y', 'ь' => '', 'э' => 'e', 'ю' => 'yu', 'я' => 'ya' ]; public function transliterate(string $text): string { $text = mb_strtolower($text); $result = ''; for ($i = 0; $i < mb_strlen($text); $i++) { $char = mb_substr($text, $i, 1); $result .= $this->transliterationMap[$char] ?? $char; } return ucfirst(trim($result)); } } |
Шаг 2: создание сервиса
Создайте сервис для работы с учётными записями AD. Например, в папке app/Services
создайте файл AdAccountService.php
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | <?php namespace App\Services; use App\Helpers\TransliterationHelper; class ADUserService { private TransliterationHelper $transliterator; public function __construct(TransliterationHelper $transliterator) { $this->transliterator = $transliterator; } public function generateAttributes(array $userData): array { $lastName = $this->transliterator->transliterate($userData['last_name']); $firstName = $this->transliterator->transliterate($userData['first_name']); //$middleName = $this->transliterator->transliterate($userData['middle_name']); $ruLastName = trim($userData['last_name']); $ruFirstName = trim($userData['first_name']); $ruMiddleName = trim($userData['middle_name']); $num = rand(100,999); $shuffledPwd = $this->shuffleWord("{$lastName}{$num}"); return [ 'userPrincipalName' => "{$lastName}.{$firstName}@aist.med", 'unicodePwd' => $shuffledPwd, 'cn' => "{$ruLastName} {$ruFirstName} {$ruMiddleName}", 'name' => "{$ruLastName} {$ruFirstName} {$ruMiddleName}", 'displayname' => "{$ruLastName} {$ruFirstName} {$ruMiddleName}", 'givenname' => "{$ruFirstName} {$ruMiddleName}", 'sn' => $ruLastName, 'samaccountname' => "{$lastName}.{$firstName}", 'description' => trim($userData['description']) ]; } private function encodePassword(string $password): string { return iconv('UTF-8', 'UTF-16LE', '"' . $password . '"'); } private function shuffleWord($word) { $letters = str_split($word); shuffle($letters); return implode('', $letters); } } |
Он будет принимать массив с данными от пользователя на кириллице и возвращать новый с логином и сгенерированным паролем.
Шаг 4: создание Livewire элемента
Чтобы создать новый компонент Livewire для отображения формы и обработки данных, запустите следующую команду Artisan:
1 | php artisan make:livewire NewUserADForm |
Где
— имя вашего нового компонента.NewUserADForm
Эта команда создаст два файла:
- Класс компонента (
app/Livewire/
)NewUserADForm
.php - Представление компонента (
resources/views/livewire/new-user-a-d-form.blade.php
)
NewUserADForm.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | <?php namespace App\Livewire; use App\Services\ADUserService; use Filament\Forms\Components\Actions\Action; use Livewire\Component; use Filament\Forms\Form; use Filament\Forms\Components\Textarea; use Filament\Forms\Set; use Filament\Forms\Concerns\InteractsWithForms; use Filament\Forms\Contracts\HasForms; use Filament\Forms\Components\TextInput; use Filament\Forms\Components\Section; use Filament\Forms\Components\Split; use Filament\Notifications\Notification; use LdapRecord\Models\ActiveDirectory\User; class NewUserADForm extends Component implements HasForms { use InteractsWithForms; public ?array $data = []; public $res =''; public function mount(): void { $this->form->fill(); } public function form(Form $form): Form { return $form ->schema([ Split::make([ Section::make('Данные пользователя') ->schema([ TextInput::make('last_name') ->label('Фамилия') ->suffixAction( Action::make('splitByFields') ->icon('heroicon-m-queue-list') ->requiresConfirmation() ->action(function (Set $set, $state) { $parts = explode(' ', trim($state)); if (count($parts) === 3) { $set('last_name', $parts[0]); $set('first_name', $parts[1]); $set('middle_name', $parts[2]); } }) ) ->required(), TextInput::make('first_name') ->label('Имя') ->required(), TextInput::make('middle_name') ->label('Отчество') ->required(), TextInput::make('description') ->label('Описание') ->live(onBlur: true) ->afterStateUpdated(fn (Set $set) => $this->updateTotals($set)) ->required(), ]), Section::make([ Textarea::make('result') ->rows(15) ]), ])->from('md') ])->statePath('data'); } public function create() { try { $validated = $this->form->getState(); $adService = app(ADUserService::class); $attributes = $adService->generateAttributes($validated); // Сохранение результата в файл $filename = "{$attributes['samaccountname']}.txt"; $content = "Имя: {$attributes['givenname']}\n" . "Фамилия: {$attributes['sn']}\n" . "Полное имя: {$attributes['cn']}\n" . "Логин: {$attributes['samaccountname']}\n" . "Пароль: {$attributes['unicodePwd']}\n" . "Описание: {$attributes['description']}\n"; // Запись в файл $filePath = storage_path("app/{$filename}"); file_put_contents($filePath, $content); //$user->save(); Notification::make() ->title('Пользователь создан') ->body($content) ->success() ->send(); // Отправка файла на скачивание return response()->download($filePath)->deleteFileAfterSend(true); } catch (\Exception $e) { Notification::make() ->title('Ошибка при создании пользователя') ->body($e->getMessage()) ->danger() ->send(); } } public function updateTotals(Set $set): void { $text = ''; $validated = $this->form->getState(); $adService = app(ADUserService::class); $attributes = $adService->generateAttributes($validated); foreach ($attributes as $key => $value) { $text = $text."{$key}: {$value}\n"; } $set('result', $text); } public function render() { return view('livewire.new-user-a-d-form'); } } |
new-user-a-d-form.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <x-filament::section> <x-slot name="heading"> Введите данные пользователя </x-slot> <x-slot name="description"> <form wire:submit="create"> {{ $this->form }} <x-filament::button color="success" type="submit" size="xl" icon="heroicon-m-arrow-down-tray" icon-position="before"> Получить файлик </x-filament> </form> <x-filament-actions::modals /> </x-slot> </x-filament::section> |
Т.к класс NewUserADForm использует библиотеку InteractsWithForms , то можно легко создать через конструктор форм Filament форму и функционал разбивки по полям
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | TextInput::make('last_name') ->label('Фамилия') ->suffixAction( Action::make('splitByFields') ->icon('heroicon-m-queue-list') ->requiresConfirmation() ->action(function (Set $set, $state) { $parts = explode(' ', trim($state)); if (count($parts) === 3) { $set('last_name', $parts[0]); $set('first_name', $parts[1]); $set('middle_name', $parts[2]); } }) ) ->required(), |
В метод create() добавлен функционал отправки данных формы в генератор данных AD и сохранение полученного результата в текстовый файл
Шаг 5: добавление livewire элемента на страницу Filament
Чтобы создать новую страницу в админке Filament, запустите следующую команду Artisan:
1 | php artisan make:filament-page CreateADUser |
Эта команда создаст два файла: класс страницы в каталоге /Pages каталога Filament и представление в каталоге /pages каталога представлений Filament.
resources\views\filament\pages\create-a-d-user.blade.php
1 2 3 | <x-filament-panels::page> <livewire:NewUserADForm /> </x-filament-panels::page> |
app\Filament\Pages\CreateADUser.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php namespace App\Filament\Pages; use Filament\Forms\Components\TextInput; use Filament\Forms\Concerns\InteractsWithForms; use Filament\Forms\Contracts\HasForms; use Filament\Pages\Page; class CreateADUser extends Page { protected static ?string $navigationIcon = 'heroicon-o-user-plus'; protected static ?string $title = 'Создать пользователя AD'; protected static ?string $navigationLabel = 'Новый пользователь AD'; protected static string $view = 'filament.pages.create-a-d-user'; } |
Заключение
В рамках проекта на Filament 3 и Laravel 12 была разработана страница для создания учётной записи в Active Directory (AD). Пользователь может ввести свои ФИО, а после нажатия кнопки «Получить файлик» — получить файл с данными об учётной записи, включая логин и сгенерированный пароль.
Для дальнейшего развития проекта можно рассмотреть возможность интеграции функционала создания пользователя через библиотеку LDAP Record. Это позволит упростить процесс добавления новых пользователей в AD и повысить эффективность работы с учётными записями.