, string> */ public const RECOVERABLE = [ Page::class => 'pages', Project::class => 'projects', Service::class => 'services', Member::class => 'members', Client::class => 'clients', Testimonial::class => 'testimonials', Category::class => 'categories', // The inbox soft-deletes too, and it is gated by its own permission // below — a viewer never sees a stranger's message here either. Application::class => 'applications', ]; public static function canAccess(): bool { return Auth::user()?->can('panel.access') ?? false; } public static function getNavigationGroup(): string|UnitEnum|null { return __('panel.groups.administration'); } public static function getNavigationLabel(): string { return __('panel.trash.title'); } public function getTitle(): string|Htmlable { return __('panel.trash.title'); } public function getSubheading(): string|Htmlable|null { return __('panel.trash.subheading'); } /** * What is in the bin, grouped by what it is — and only the kinds this user * is allowed to see in the first place. * * @return Collection}> */ public function groups(): Collection { $user = Auth::user(); return collect(self::RECOVERABLE) ->filter(fn (string $resource) => $user?->can("{$resource}.view_any") ?? false) ->map(fn (string $resource, string $model) => [ 'model' => $model, 'label' => __("panel.{$resource}.plural"), 'records' => $model::onlyTrashed()->latest('deleted_at')->limit(25)->get(), ]) ->filter(fn (array $group) => $group['records']->isNotEmpty()); } public function total(): int { return $this->groups()->sum(fn (array $group) => $group['records']->count()); } /** * Put one thing back. */ public function restoreRecord(string $model, int|string $id): void { $record = $this->find($model, $id); if (! $record || ! Auth::user()?->can('restore', $record)) { return; } $record->restore(); Notification::make() ->title(__('panel.trash.restored')) ->success() ->send(); } /** * Erase one thing for good. */ public function eraseRecord(string $model, int|string $id): void { $record = $this->find($model, $id); if (! $record || ! Auth::user()?->can('forceDelete', $record)) { return; } $record->forceDelete(); Notification::make() ->title(__('panel.trash.erased')) ->warning() ->send(); } /** * How a record is described here, whatever kind it is. */ public function labelFor(Model $record): string { foreach (['name', 'title', 'author_name', 'full_name'] as $attribute) { $value = $record->getAttribute($attribute); if (blank($value)) { continue; } return is_array($value) ? (string) ($value[config('locales.default')] ?? reset($value)) : (string) $value; } return '#'.$record->getKey(); } protected function find(string $model, int|string $id): ?Model { // Only the models this page declares: an id and a class name arriving // from the browser must not be able to reach anything else. if (! array_key_exists($model, self::RECOVERABLE)) { return null; } return $model::onlyTrashed()->find($id); } public static function getNavigationBadge(): ?string { return null; } }