request->getGet('q')); $query = $this->toolsModel()->orderBy('name', 'ASC')->limit(300); if ($q !== '') { $query->like('name', $q)->orLike('slug', $q); } return $this->render('tools_index', [ 'tools' => $query->findAll(), 'categories' => $this->categories(), 'q' => $q, ]); } public function create(): string { return $this->render('tools_form', [ 'tool' => null, 'categories' => $this->categories(), ]); } public function store(): ResponseInterface { return $this->save(null); } public function edit(int $id): string { $tool = $this->toolsModel()->find($id) ?? throw new \CodeIgniter\Exceptions\PageNotFoundException(); return $this->render('tools_form', [ 'tool' => $tool, 'categories' => $this->categories(), ]); } public function update(int $id): ResponseInterface { return $this->save($id); } private function save(?int $id): ResponseInterface { $post = $this->request->getPost(); $catId = (int) ($post['category_id'] ?? 0); try { $row = $this->toolFromInput((array) $post, $catId); } catch (\Throwable $e) { session()->setFlashdata('error', 'Could not build the tool: ' . $e->getMessage()); return redirect()->back()->withInput(); } // pre-publish SEO validation (critical checks only) $problems = []; if (trim((string) $row['seo_title']) === '') { $problems[] = 'SEO title missing'; } if (mb_strlen((string) $row['seo_description']) < 50) { $problems[] = 'SEO description too short (<50 chars)'; } if (trim((string) $row['h1']) === '') { $problems[] = 'H1 missing'; } if ($problems !== [] && ($row['status'] ?? '') === 'active') { session()->setFlashdata('error', 'Blocked from publishing: ' . implode('; ', $problems)); session()->setFlashdata('form_data', $post); return redirect()->to($id ? '/admin/tools/' . $id . '/edit' : '/admin/tools/new')->withInput(); } if ($id !== null) { $this->toolsModel()->update($id, $row); session()->setFlashdata('success', 'Tool updated.'); } else { $this->toolsModel()->insert($row); session()->setFlashdata('success', 'Tool created.'); } return redirect()->to('/admin/tools'); } public function delete(int $id): ResponseInterface { $this->toolsModel()->delete($id); service('cache')->clear(); return redirect()->to('/admin/tools'); } }