Events mapped to entities with automatic GC */ private \WeakMap $eventsByEntity; public function __construct() { $this->eventsByEntity = new \WeakMap(); } /** * Record a domain event for an entity */ public function recordEvent(object $entity, object $event): void { if (! isset($this->eventsByEntity[$entity])) { $this->eventsByEntity[$entity] = []; } $this->eventsByEntity[$entity][] = $event; } /** * Get all recorded domain events for an entity * * @return object[] */ public function getEventsForEntity(object $entity): array { return $this->eventsByEntity[$entity] ?? []; } /** * Clear all recorded domain events for an entity * (Optional - WeakMap handles cleanup automatically) */ public function clearEventsForEntity(object $entity): void { unset($this->eventsByEntity[$entity]); } /** * Get all recorded domain events across all entities * * @return object[] */ public function getAllEvents(): array { $allEvents = []; foreach ($this->eventsByEntity as $events) { $allEvents = array_merge($allEvents, $events); } return $allEvents; } /** * Check if there are any domain events for an entity */ public function hasEventsForEntity(object $entity): bool { return isset($this->eventsByEntity[$entity]) && ! empty($this->eventsByEntity[$entity]); } /** * Get domain events of a specific type for an entity * * @template T * @param class-string $eventClass * @return T[] */ public function getEventsOfTypeForEntity(object $entity, string $eventClass): array { $events = $this->getEventsForEntity($entity); return array_filter( $events, fn (object $event) => $event instanceof $eventClass ); } /** * Get count of events for an entity */ public function getEventCountForEntity(object $entity): int { return count($this->getEventsForEntity($entity)); } /** * Get total count of all events across all entities */ public function getTotalEventCount(): int { $total = 0; foreach ($this->eventsByEntity as $events) { $total += count($events); } return $total; } /** * Get count of tracked entities */ public function getTrackedEntityCount(): int { return count($this->eventsByEntity); } }