*/ public function __invoke(GetParentInvitationsQuery $query): PaginatedResult { $tenantId = TenantId::fromString($query->tenantId); $invitations = $this->invitationRepository->findAllByTenant($tenantId); if ($query->status !== null) { $filterStatus = InvitationStatus::tryFrom($query->status); if ($filterStatus !== null) { $invitations = array_filter( $invitations, static fn ($inv) => $inv->status === $filterStatus, ); } } if ($query->studentId !== null) { $filterStudentId = UserId::fromString($query->studentId); $invitations = array_filter( $invitations, static fn ($inv) => $inv->studentId->equals($filterStudentId), ); } // Build a student name cache for search and DTO enrichment $studentNames = $this->loadStudentNames($invitations); if ($query->search !== null && $query->search !== '') { $searchLower = mb_strtolower($query->search); $invitations = array_filter( $invitations, static function ($inv) use ($searchLower, $studentNames) { $studentId = (string) $inv->studentId; $firstName = $studentNames[$studentId]['firstName'] ?? ''; $lastName = $studentNames[$studentId]['lastName'] ?? ''; return str_contains(mb_strtolower((string) $inv->parentEmail), $searchLower) || str_contains(mb_strtolower($firstName), $searchLower) || str_contains(mb_strtolower($lastName), $searchLower); }, ); } $invitations = array_values($invitations); $total = count($invitations); $offset = ($query->page - 1) * $query->limit; $items = array_slice($invitations, $offset, $query->limit); return new PaginatedResult( items: array_map( static function ($inv) use ($studentNames) { $studentId = (string) $inv->studentId; return ParentInvitationDto::fromDomain( $inv, $studentNames[$studentId]['firstName'] ?? null, $studentNames[$studentId]['lastName'] ?? null, ); }, $items, ), total: $total, page: $query->page, limit: $query->limit, ); } /** * @param iterable<\App\Administration\Domain\Model\Invitation\ParentInvitation> $invitations * * @return array */ private function loadStudentNames(iterable $invitations): array { $studentIds = []; foreach ($invitations as $inv) { $studentIds[(string) $inv->studentId] = true; } $names = []; foreach ($studentIds as $id => $_) { try { $student = $this->userRepository->get(UserId::fromString($id)); $names[$id] = [ 'firstName' => $student->firstName, 'lastName' => $student->lastName, ]; } catch (Throwable) { $names[$id] = ['firstName' => '', 'lastName' => '']; } } return $names; } }