schema([ FileUpload::make('file') ->label(__('admin.common.csv_file')) ->acceptedFileTypes(['text/csv', 'text/plain']) ->directory('imports') ->required(), ]); } public function doImport(): void { $this->validate(); $path = $this->form->getState()['file'] ?? null; if (! $path || ! Storage::disk('public')->exists($path)) { Notification::make()->danger()->title(__('admin.notifications.file_not_found'))->send(); return; } $fullPath = Storage::disk('public')->path($path); [$ok, $fail] = $this->importTasksCsv($fullPath); Notification::make() ->success() ->title(__('admin.notifications.imported_rows', ['count' => $ok])) ->body($fail ? __('admin.notifications.failed_count', ['count' => $fail]) : null) ->send(); } public function getHeading(): string { return __('admin.tasks.import.heading'); } private function importTasksCsv(string $file): array { $handle = fopen($file, 'r'); if (! $handle) { return [0, 0]; } $ok = 0; $fail = 0; $headers = fgetcsv($handle, 0, ','); if (! $headers) { return [0, 0]; } $map = array_flip($headers); while (($row = fgetcsv($handle, 0, ',')) !== false) { try { DB::transaction(function () use ($row, $map, &$ok) { $emotionName = trim($row[$map['emotion_name']] ?? ''); $emotionNameDe = trim($row[$map['emotion_name_de']] ?? ''); $emotionNameEn = trim($row[$map['emotion_name_en']] ?? ''); $emotionId = null; if ($emotionName) { $emotionId = DB::table('emotions')->where('name', $emotionName)->value('id'); } elseif ($emotionNameDe) { $emotionId = DB::table('emotions')->where('name->de', $emotionNameDe)->value('id'); } elseif ($emotionNameEn) { $emotionId = DB::table('emotions')->where('name->en', $emotionNameEn)->value('id'); } if (! $emotionId) { throw new \Exception('Emotion not found.'); } $eventTypeId = null; $eventTypeSlug = trim($row[$map['event_type_slug']] ?? ''); if ($eventTypeSlug) { $eventTypeId = DB::table('event_types')->where('slug', $eventTypeSlug)->value('id'); } $task = Task::create([ 'emotion_id' => $emotionId, 'event_type_id' => $eventTypeId, 'title' => [ 'de' => $row[$map['title_de']] ?? null, 'en' => $row[$map['title_en']] ?? null, ], 'description' => [ 'de' => $row[$map['description_de']] ?? null, 'en' => $row[$map['description_en']] ?? null, ], 'difficulty' => $row[$map['difficulty']] ?? 'easy', 'example_text' => [ 'de' => $row[$map['example_text_de']] ?? null, 'en' => $row[$map['example_text_en']] ?? null, ], 'sort_order' => (int) ($row[$map['sort_order']] ?? 0), 'is_active' => (int) ($row[$map['is_active']] ?? 1) ? 1 : 0, ]); app(SuperAdminAuditLogger::class)->recordModelMutation( 'created', $task, SuperAdminAuditLogger::fieldsMetadata($task->getChanges()), source: static::class ); $ok++; }); } catch (\Throwable $e) { $fail++; } } fclose($handle); return [$ok, $fail]; } }