*/ abstract protected function modelClass(): string; /** View-Prefix, z. B. 'admin.inventory.tax-rates' (erwartet .index/.form darunter). */ abstract protected function viewPrefix(): string; /** Ziel-Route nach store/update/destroy. */ abstract protected function redirectRoute(): string; /** @return class-string */ abstract protected function storeRequestClass(): string; /** @return class-string Default: identisch zum Store-Request. */ protected function updateRequestClass(): string { return $this->storeRequestClass(); } /** * Vorbelegung des leeren Models im Neu-Formular. * * @return array */ protected function newModelAttributes(): array { return ['active' => true, 'pos' => 0]; } /** * Sortierung der Index-Liste (nur für Resources mit index-Route relevant). * * @return array */ protected function indexOrder(): array { return ['pos', 'name']; } public function index(): View { $query = $this->modelClass()::query(); foreach ($this->indexOrder() as $column) { $query->orderBy($column); } return view($this->viewPrefix().'.index', [ 'values' => $query->get(), ]); } public function create(): View { $class = $this->modelClass(); return view($this->viewPrefix().'.form', [ 'model' => new $class($this->newModelAttributes()), ]); } public function store(): RedirectResponse { $this->modelClass()::create($this->validated($this->storeRequestClass())); \Session::flash('alert-save', '1'); return redirect()->route($this->redirectRoute()); } public function edit(): View { return view($this->viewPrefix().'.form', [ 'model' => $this->routeModel(), ]); } public function update(): RedirectResponse { $this->routeModel()->update($this->validated($this->updateRequestClass())); \Session::flash('alert-save', '1'); return redirect()->route($this->redirectRoute()); } public function destroy(): RedirectResponse { $model = $this->routeModel(); $guard = app(DeletionGuard::class); $blockers = $guard->blockersFor($model); if ($blockers !== []) { \Session::flash('alert-error', $guard->message($blockers)); return redirect()->route($this->redirectRoute()); } $model->delete(); \Session::flash('alert-success', __('Eintrag gelöscht')); return redirect()->route($this->redirectRoute()); } /** * Validiert den aktuellen Request über den angegebenen FormRequest * (Container-Auflösung triggert die Validierung wie bei Method-Injection). * * @param class-string $requestClass * @return array */ protected function validated(string $requestClass): array { /** @var FormRequest $request */ $request = app($requestClass); return $request->validated(); } /** * Löst das Model aus dem Resource-Routen-Parameter auf (ohne Typehint * greift kein implizites Binding, der Parameter ist die rohe ID). */ protected function routeModel(): Model { $value = array_values(request()->route()->parameters())[0] ?? null; if ($value instanceof Model) { return $value; } return $this->modelClass()::query()->findOrFail($value); } }