| null */ public ?array $data = []; public ?string $previousUrl = null; public function getBreadcrumb(): string { return static::$breadcrumb ?? __('filament-panels::resources/pages/edit-record.breadcrumb'); } public function getContentTabLabel(): ?string { return __('filament-panels::resources/pages/edit-record.content.tab.label'); } public function mount(int | string $record): void { $this->record = $this->resolveRecord($record); $this->authorizeAccess(); $this->fillForm(); $this->previousUrl = url()->previous(); } protected function authorizeAccess(): void { static::authorizeResourceAccess(); abort_unless(static::getResource()::canEdit($this->getRecord()), 403); } protected function fillForm(): void { $data = $this->getRecord()->attributesToArray(); /** @internal Read the DocBlock above the following method. */ $this->fillFormWithDataAndCallHooks($data); } /** * @internal Never override or call this method. If you completely override `fillForm()`, copy the contents of this method into your override. * * @param array $data */ protected function fillFormWithDataAndCallHooks(array $data): void { $this->callHook('beforeFill'); $data = $this->mutateFormDataBeforeFill($data); $this->form->fill($data); $this->callHook('afterFill'); } /** * @param array $attributes */ protected function refreshFormData(array $attributes): void { $this->data = [ ...$this->data, ...$this->getRecord()->only($attributes), ]; } /** * @param array $data * @return array */ protected function mutateFormDataBeforeFill(array $data): array { return $data; } public function save(bool $shouldRedirect = true): void { $this->authorizeAccess(); try { /** @internal Read the DocBlock above the following method. */ $this->validateFormAndUpdateRecordAndCallHooks(); } catch (Halt $exception) { return; } /** @internal Read the DocBlock above the following method. */ $this->sendSavedNotificationAndRedirect(shouldRedirect: $shouldRedirect); } /** * @internal Never override or call this method. If you completely override `save()`, copy the contents of this method into your override. */ protected function validateFormAndUpdateRecordAndCallHooks(): void { $this->callHook('beforeValidate'); $data = $this->form->getState(); $this->callHook('afterValidate'); $data = $this->mutateFormDataBeforeSave($data); $this->callHook('beforeSave'); $this->handleRecordUpdate($this->getRecord(), $data); $this->callHook('afterSave'); } /** * @internal Never override or call this method. If you completely override `save()`, copy the contents of this method into your override. */ protected function sendSavedNotificationAndRedirect(bool $shouldRedirect = true): void { $this->getSavedNotification()?->send(); if ($shouldRedirect && ($redirectUrl = $this->getRedirectUrl())) { $this->redirect($redirectUrl); } } protected function getSavedNotification(): ?Notification { $title = $this->getSavedNotificationTitle(); if (blank($title)) { return null; } return Notification::make() ->success() ->title($this->getSavedNotificationTitle()); } protected function getSavedNotificationTitle(): ?string { return $this->getSavedNotificationMessage() ?? __('filament-panels::resources/pages/edit-record.notifications.saved.title'); } /** * @deprecated Use `getSavedNotificationTitle()` instead. */ protected function getSavedNotificationMessage(): ?string { return null; } /** * @param array $data */ protected function handleRecordUpdate(Model $record, array $data): Model { $record->update($data); return $record; } /** * @param array $data * @return array */ protected function mutateFormDataBeforeSave(array $data): array { return $data; } protected function configureAction(Action $action): void { $action ->record($this->getRecord()) ->recordTitle($this->getRecordTitle()); match (true) { $action instanceof DeleteAction => $this->configureDeleteAction($action), $action instanceof ForceDeleteAction => $this->configureForceDeleteAction($action), $action instanceof ReplicateAction => $this->configureReplicateAction($action), $action instanceof RestoreAction => $this->configureRestoreAction($action), $action instanceof ViewAction => $this->configureViewAction($action), default => null, }; } protected function configureViewAction(ViewAction $action): void { $resource = static::getResource(); $action ->authorize($resource::canView($this->getRecord())) ->infolist(fn (Infolist $infolist): Infolist => static::getResource()::infolist($infolist->columns(2))) ->form(fn (Form $form): Form => static::getResource()::form($form)); if ($resource::hasPage('view')) { $action->url(fn (): string => static::getResource()::getUrl('view', ['record' => $this->getRecord()])); } } protected function configureForceDeleteAction(ForceDeleteAction $action): void { $resource = static::getResource(); $action ->authorize($resource::canForceDelete($this->getRecord())) ->successRedirectUrl($resource::getUrl('index')); } protected function configureReplicateAction(ReplicateAction $action): void { $action ->authorize(static::getResource()::canReplicate($this->getRecord())); } protected function configureRestoreAction(RestoreAction $action): void { $action ->authorize(static::getResource()::canRestore($this->getRecord())); } protected function configureDeleteAction(DeleteAction $action): void { $resource = static::getResource(); $action ->authorize($resource::canDelete($this->getRecord())) ->successRedirectUrl($resource::getUrl('index')); } public function getTitle(): string | Htmlable { if (filled(static::$title)) { return static::$title; } return __('filament-panels::resources/pages/edit-record.title', [ 'label' => $this->getRecordTitle(), ]); } /** * @return array */ protected function getFormActions(): array { return [ $this->getSaveFormAction(), $this->getCancelFormAction(), ]; } protected function getSaveFormAction(): Action { return Action::make('save') ->label(__('filament-panels::resources/pages/edit-record.form.actions.save.label')) ->submit('save') ->keyBindings(['mod+s']); } protected function getSubmitFormAction(): Action { return $this->getSaveFormAction(); } protected function getCancelFormAction(): Action { return Action::make('cancel') ->label(__('filament-panels::resources/pages/edit-record.form.actions.cancel.label')) ->url($this->previousUrl ?? static::getResource()::getUrl()) ->color('gray'); } public function form(Form $form): Form { return $form; } /** * @return array */ protected function getForms(): array { return [ 'form' => $this->form(static::getResource()::form( $this->makeForm() ->operation('edit') ->model($this->getRecord()) ->statePath($this->getFormStatePath()) ->columns($this->hasInlineLabels() ? 1 : 2) ->inlineLabel($this->hasInlineLabels()), )), ]; } public function getFormStatePath(): ?string { return 'data'; } protected function getRedirectUrl(): ?string { return null; } protected function getMountedActionFormModel(): Model { return $this->getRecord(); } /** * @return array */ public function getWidgetData(): array { return [ 'record' => $this->getRecord(), ]; } }