'required|min_length[3]|max_length[255]', 'slug' => 'permit_empty|max_length[255]|is_unique[pages.slug,id,{id}]', 'content_json' => 'permit_empty', 'content_html' => 'permit_empty', 'status' => 'required|in_list[draft,published]', ]; protected $validationMessages = [ 'title' => [ 'required' => 'Judul halaman harus diisi.', 'min_length' => 'Judul halaman minimal 3 karakter.', 'max_length' => 'Judul halaman maksimal 255 karakter.', ], 'slug' => [ 'required' => 'Slug harus diisi.', 'is_unique' => 'Slug sudah digunakan, silakan gunakan judul yang berbeda.', ], 'content' => [ 'required' => 'Konten halaman harus diisi.', ], 'status' => [ 'required' => 'Status harus dipilih.', 'in_list' => 'Status harus draft atau published.', ], ]; protected $skipValidation = false; protected $cleanValidationRules = true; /** * Generate slug from title */ public function generateSlug(string $title, ?int $excludeId = null): string { // Convert to lowercase and replace spaces with hyphens $slug = strtolower(trim($title)); $slug = preg_replace('/[^a-z0-9-]/', '-', $slug); $slug = preg_replace('/-+/', '-', $slug); $slug = trim($slug, '-'); // If slug is empty, use timestamp if (empty($slug)) { $slug = 'page-' . time(); } // Check if slug exists $baseSlug = $slug; $counter = 1; while ($this->slugExists($slug, $excludeId)) { $slug = $baseSlug . '-' . $counter; $counter++; } return $slug; } /** * Check if slug exists */ protected function slugExists(string $slug, ?int $excludeId = null): bool { $builder = $this->where('slug', $slug); if ($excludeId !== null) { $builder->where('id !=', $excludeId); } return $builder->countAllResults() > 0; } /** * Count pages by status */ public function countByStatus(?string $status = null): int { if ($status !== null) { return $this->where('status', $status)->countAllResults(); } return $this->countAllResults(); } }