middleware('auth'); } /** List the current user's requests */ public function index(Request $request) { $requests = SummaryRequest::where('user_id', $request->user()->id) ->orderByDesc('created_at') ->paginate(12); return view('requests.index', [ 'requests' => $requests, ]); } /** Show the create form */ public function create(Request $request) { $prefill = [ 'gutenberg' => $request->query('gutenberg'), 'title' => $request->query('title'), ]; return view('requests.create', $prefill); } /** Store the request */ public function store(Request $request) { $data = $request->validate([ 'gutenberg' => 'required|string|max:255', // can be URL or ID 'title' => 'nullable|string|max:255', 'notes' => 'nullable|string|max:2000', ]); $gutenbergId = $this->parseGutenbergId($data['gutenberg']); if (!$gutenbergId) { return back()->withErrors(['gutenberg' => 'Please provide a valid Project Gutenberg URL or numeric ID.'])->withInput(); } $requestModel = SummaryRequest::firstOrCreate([ 'user_id' => $request->user()->id, 'gutenberg_id' => $gutenbergId, ], [ 'title' => $data['title'] ?? null, 'notes' => $data['notes'] ?? null, 'status' => 'pending', ]); // If already exists, update title/notes to latest provided if (!$requestModel->wasRecentlyCreated) { $requestModel->update([ 'title' => $data['title'] ?? $requestModel->title, 'notes' => $data['notes'] ?? $requestModel->notes, ]); } return redirect()->route('requests.index')->with('success', 'Your summary request has been submitted. We will process it soon.'); } private function parseGutenbergId(string $input): ?int { $input = trim($input); // If pure number if (ctype_digit($input)) { return (int) $input; } // Try to extract from URL $patterns = [ '/gutenberg\.org\/(?:ebooks|etext)\/(\d+)/i', // https://www.gutenberg.org/ebooks/1342 '/gutenberg\.org\/(?:files)\/(\d+)\//i', // https://www.gutenberg.org/files/1342/1342-h/1342-h.htm ]; foreach ($patterns as $pattern) { if (preg_match($pattern, $input, $m)) { return (int) $m[1]; } } return null; } }