| null */ public ?array $data = []; public ?string $previousUrl = null; protected static bool $canCreateAnother = true; public function getBreadcrumb(): string { return static::$breadcrumb ?? __('filament-panels::resources/pages/create-record.breadcrumb'); } public function mount(): void { $this->authorizeAccess(); $this->fillForm(); $this->previousUrl = url()->previous(); } protected function authorizeAccess(): void { static::authorizeResourceAccess(); abort_unless(static::getResource()::canCreate(), 403); } protected function fillForm(): void { /** @internal Read the DocBlock above the following method. */ $this->fillFormWithDefaultsAndCallHooks(); } /** * @internal Never override or call this method. If you completely override `fillForm()`, copy the contents of this method into your override. */ protected function fillFormWithDefaultsAndCallHooks(): void { $this->callHook('beforeFill'); $this->form->fill(); $this->callHook('afterFill'); } public function create(bool $another = false): void { $this->authorizeAccess(); try { $this->callHook('beforeValidate'); $data = $this->form->getState(); $this->callHook('afterValidate'); $data = $this->mutateFormDataBeforeCreate($data); /** @internal Read the DocBlock above the following method. */ $this->createRecordAndCallHooks($data); } catch (Halt $exception) { return; } /** @internal Read the DocBlock above the following method. */ $this->sendCreatedNotificationAndRedirect(shouldCreateAnotherInsteadOfRedirecting: $another); } /** * @internal Never override or call this method. If you completely override `create()`, copy the contents of this method into your override. * * @param array $data */ protected function createRecordAndCallHooks(array $data): void { $this->callHook('beforeCreate'); $this->record = $this->handleRecordCreation($data); $this->form->model($this->getRecord())->saveRelationships(); $this->callHook('afterCreate'); } /** * @internal Never override or call this method. If you completely override `create()`, copy the contents of this method into your override. */ protected function sendCreatedNotificationAndRedirect(bool $shouldCreateAnotherInsteadOfRedirecting = true): void { $this->getCreatedNotification()?->send(); if ($shouldCreateAnotherInsteadOfRedirecting) { // Ensure that the form record is anonymized so that relationships aren't loaded. $this->form->model($this->getRecord()::class); $this->record = null; $this->fillForm(); return; } $this->redirect($this->getRedirectUrl()); } protected function getCreatedNotification(): ?Notification { $title = $this->getCreatedNotificationTitle(); if (blank($title)) { return null; } return Notification::make() ->success() ->title($title); } protected function getCreatedNotificationTitle(): ?string { return $this->getCreatedNotificationMessage() ?? __('filament-panels::resources/pages/create-record.notifications.created.title'); } /** * @deprecated Use `getCreatedNotificationTitle()` instead. */ protected function getCreatedNotificationMessage(): ?string { return null; } public function createAnother(): void { $this->create(another: true); } /** * @param array $data */ protected function handleRecordCreation(array $data): Model { $record = new ($this->getModel())($data); if ($tenant = Filament::getTenant()) { return $this->associateRecordWithTenant($record, $tenant); } $record->save(); return $record; } protected function associateRecordWithTenant(Model $record, Model $tenant): Model { $relationship = static::getResource()::getTenantRelationship($tenant); if ($relationship instanceof HasManyThrough) { $record->save(); return $record; } return $relationship->save($record); } /** * @param array $data * @return array */ protected function mutateFormDataBeforeCreate(array $data): array { return $data; } /** * @return array */ protected function getFormActions(): array { return [ $this->getCreateFormAction(), ...(static::canCreateAnother() ? [$this->getCreateAnotherFormAction()] : []), $this->getCancelFormAction(), ]; } protected function getCreateFormAction(): Action { return Action::make('create') ->label(__('filament-panels::resources/pages/create-record.form.actions.create.label')) ->submit('create') ->keyBindings(['mod+s']); } protected function getSubmitFormAction(): Action { return $this->getCreateFormAction(); } protected function getCreateAnotherFormAction(): Action { return Action::make('createAnother') ->label(__('filament-panels::resources/pages/create-record.form.actions.create_another.label')) ->action('createAnother') ->keyBindings(['mod+shift+s']) ->color('gray'); } protected function getCancelFormAction(): Action { return Action::make('cancel') ->label(__('filament-panels::resources/pages/create-record.form.actions.cancel.label')) ->url($this->previousUrl ?? static::getResource()::getUrl()) ->color('gray'); } public function getTitle(): string | Htmlable { if (filled(static::$title)) { return static::$title; } return __('filament-panels::resources/pages/create-record.title', [ 'label' => Str::headline(static::getResource()::getModelLabel()), ]); } public function form(Form $form): Form { return $form; } /** * @return array */ protected function getForms(): array { return [ 'form' => $this->form(static::getResource()::form( $this->makeForm() ->operation('create') ->model($this->getModel()) ->statePath($this->getFormStatePath()) ->columns($this->hasInlineLabels() ? 1 : 2) ->inlineLabel($this->hasInlineLabels()), )), ]; } protected function getRedirectUrl(): string { $resource = static::getResource(); if ($resource::hasPage('view') && $resource::canView($this->getRecord())) { return $resource::getUrl('view', ['record' => $this->getRecord(), ...$this->getRedirectUrlParameters()]); } if ($resource::hasPage('edit') && $resource::canEdit($this->getRecord())) { return $resource::getUrl('edit', ['record' => $this->getRecord(), ...$this->getRedirectUrlParameters()]); } return $resource::getUrl('index'); } /** * @return array */ protected function getRedirectUrlParameters(): array { return []; } protected function getMountedActionFormModel(): string { return $this->getModel(); } public static function canCreateAnother(): bool { return static::$canCreateAnother; } public static function disableCreateAnother(): void { static::$canCreateAnother = false; } public function getFormStatePath(): ?string { return 'data'; } public function getRecord(): ?Model { return $this->record; } }