*/ public function findPaginated( string $tenantId, string $schoolId, ?string $search, int $page, int $limit, ): PaginatedResult { $params = [ 'tenant_id' => $tenantId, 'school_id' => $schoolId, 'status' => 'active', ]; $whereClause = 's.tenant_id = :tenant_id AND s.school_id = :school_id AND s.status = :status AND s.deleted_at IS NULL'; if ($search !== null && $search !== '') { $whereClause .= ' AND (s.name ILIKE :search OR s.code ILIKE :search)'; $params['search'] = '%' . $search . '%'; } $countSql = "SELECT COUNT(*) FROM subjects s WHERE {$whereClause}"; /** @var int|string|false $totalRaw */ $totalRaw = $this->connection->fetchOne($countSql, $params); $total = (int) $totalRaw; $offset = ($page - 1) * $limit; $selectSql = <<connection->fetchAllAssociative($selectSql, $params); $items = array_map(static function (array $row): SubjectDto { /** @var string $id */ $id = $row['id']; /** @var string $name */ $name = $row['name']; /** @var string $code */ $code = $row['code']; /** @var string|null $color */ $color = $row['color']; /** @var string|null $description */ $description = $row['description']; /** @var string $status */ $status = $row['status']; /** @var string $createdAt */ $createdAt = $row['created_at']; /** @var string $updatedAt */ $updatedAt = $row['updated_at']; /** @var int|string $teacherCountRaw */ $teacherCountRaw = $row['teacher_count'] ?? 0; /** @var int|string $classCountRaw */ $classCountRaw = $row['class_count'] ?? 0; /** @var int|string $evaluationCountRaw */ $evaluationCountRaw = $row['evaluation_count'] ?? 0; /** @var int|string $gradeCountRaw */ $gradeCountRaw = $row['grade_count'] ?? 0; return new SubjectDto( id: $id, name: $name, code: $code, color: $color, description: $description, status: $status, createdAt: new DateTimeImmutable($createdAt), updatedAt: new DateTimeImmutable($updatedAt), teacherCount: (int) $teacherCountRaw, classCount: (int) $classCountRaw, evaluationCount: (int) $evaluationCountRaw, gradeCount: (int) $gradeCountRaw, ); }, $rows); return new PaginatedResult( items: $items, total: $total, page: $page, limit: $limit, ); } }