'Assessment Management', 'student/assessments' => 'My Assessments', ]; public function up(): void { if (! $this->db->tableExists('nav_items')) return; $parentColumn = $this->parentColumn(); $studentAffairsId = null; if ($parentColumn !== null) { $parent = $this->db->table('nav_items')->select('id')->where('label', 'Student-Affairs')->where($parentColumn, null)->get()->getRowArray(); $studentAffairsId = $parent ? (int) $parent['id'] : null; } $adminId = $this->upsertItem(self::ITEMS['administrator/assessments'], 'administrator/assessments', $studentAffairsId, 7); $studentId = $this->upsertItem(self::ITEMS['student/assessments'], 'student/assessments', null, 80); if ($this->db->tableExists('role_nav_items') && $this->db->tableExists('roles')) { $roles = $this->db->table('roles')->select('id, name')->get()->getResultArray(); foreach ($roles as $role) { $token = strtolower(str_replace([' ', '-'], '_', trim((string) ($role['name'] ?? '')))); if (in_array($token, ['parent', 'student'], true)) { $this->grant((int) $role['id'], $studentId); } elseif (! in_array($token, ['guest', 'teacher', 'teacher_assistant', 'assistant_teacher', 'ta'], true)) { $this->grant((int) $role['id'], $adminId); } } } cache()->clean(); } public function down(): void { if (! $this->db->tableExists('nav_items')) return; foreach (array_keys(self::ITEMS) as $url) { $row = $this->db->table('nav_items')->select('id')->where('url', $url)->get()->getRowArray(); if ($row && $this->db->tableExists('role_nav_items')) { $this->db->table('role_nav_items')->where('nav_item_id', (int) $row['id'])->delete(); } $this->db->table('nav_items')->where('url', $url)->delete(); } cache()->clean(); } private function upsertItem(string $label, string $url, ?int $parentId, int $sort): int { $existing = $this->db->table('nav_items')->select('id')->where('url', $url)->get()->getRowArray(); $data = ['label' => $label, 'is_enabled' => 1, 'sort_order' => $sort, 'updated_at' => date('Y-m-d H:i:s')]; $parentColumn = $this->parentColumn(); if ($parentColumn !== null) $data[$parentColumn] = $parentId; if ($this->db->fieldExists('icon_class', 'nav_items')) $data['icon_class'] = 'bi bi-ui-checks-grid'; if ($existing) { $this->db->table('nav_items')->where('id', (int) $existing['id'])->update($data); return (int) $existing['id']; } $data += ['url' => $url, 'created_at' => date('Y-m-d H:i:s')]; $this->db->table('nav_items')->insert($data); return (int) $this->db->insertID(); } private function grant(int $roleId, int $navItemId): void { if ($roleId <= 0 || $navItemId <= 0) return; $builder = $this->db->table('role_nav_items'); if ($builder->where(['role_id' => $roleId, 'nav_item_id' => $navItemId])->countAllResults() > 0) return; $data = ['role_id' => $roleId, 'nav_item_id' => $navItemId]; if ($this->db->fieldExists('created_at', 'role_nav_items')) $data['created_at'] = date('Y-m-d H:i:s'); if ($this->db->fieldExists('updated_at', 'role_nav_items')) $data['updated_at'] = date('Y-m-d H:i:s'); $this->db->table('role_nav_items')->insert($data); } private function parentColumn(): ?string { if ($this->db->fieldExists('menu_parent_id', 'nav_items')) return 'menu_parent_id'; if ($this->db->fieldExists('parent_id', 'nav_items')) return 'parent_id'; return null; } }