- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
159 lines
4.7 KiB
PHP
159 lines
4.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Framework\Database\Events;
|
|
|
|
use App\Framework\Core\Events\EventDispatcher;
|
|
use App\Framework\Core\ValueObjects\Timestamp;
|
|
use App\Framework\DateTime\Clock;
|
|
|
|
/**
|
|
* Manages entity lifecycle events and coordinates with the core event system
|
|
*/
|
|
final class EntityEventManager
|
|
{
|
|
public function __construct(
|
|
private readonly EventDispatcher $eventDispatcher,
|
|
private readonly DomainEventCollector $domainEventCollector,
|
|
private readonly Clock $clock
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* Dispatch an entity lifecycle event
|
|
*/
|
|
public function dispatchLifecycleEvent(object $event): void
|
|
{
|
|
$this->eventDispatcher->dispatch($event);
|
|
}
|
|
|
|
/**
|
|
* Record a domain event for later dispatch
|
|
*/
|
|
public function recordDomainEvent(object $entity, object $event): void
|
|
{
|
|
$this->domainEventCollector->recordEvent($entity, $event);
|
|
}
|
|
|
|
/**
|
|
* Dispatch all domain events for an entity and clear them
|
|
*/
|
|
public function dispatchDomainEventsForEntity(object $entity): void
|
|
{
|
|
$events = $this->domainEventCollector->getEventsForEntity($entity);
|
|
|
|
foreach ($events as $event) {
|
|
$this->eventDispatcher->dispatch($event);
|
|
}
|
|
|
|
$this->domainEventCollector->clearEventsForEntity($entity);
|
|
}
|
|
|
|
/**
|
|
* Dispatch all domain events across all entities and clear them
|
|
*/
|
|
public function dispatchAllDomainEvents(): void
|
|
{
|
|
$allEvents = $this->domainEventCollector->getAllEvents();
|
|
|
|
foreach ($allEvents as $event) {
|
|
$this->eventDispatcher->dispatch($event);
|
|
}
|
|
|
|
// Events are automatically cleared when entities are garbage collected
|
|
// But we can manually clear for immediate cleanup
|
|
foreach ($this->domainEventCollector->getAllEvents() as $entity) {
|
|
$this->domainEventCollector->clearEventsForEntity($entity);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create and dispatch an EntityCreatedEvent
|
|
*/
|
|
public function entityCreated(object $entity, string $entityClass, mixed $entityId, array $data = []): void
|
|
{
|
|
$timestamp = Timestamp::fromClock($this->clock);
|
|
$event = new EntityCreatedEvent($entity, $entityClass, $entityId, $data, $timestamp);
|
|
$this->dispatchLifecycleEvent($event);
|
|
}
|
|
|
|
/**
|
|
* Create and dispatch an EntityUpdatedEvent
|
|
*/
|
|
public function entityUpdated(
|
|
object $entity,
|
|
string $entityClass,
|
|
mixed $entityId,
|
|
array $changes = [],
|
|
array $oldValues = [],
|
|
array $newValues = []
|
|
): void {
|
|
$timestamp = Timestamp::fromClock($this->clock);
|
|
$event = new EntityUpdatedEvent($entity, $entityClass, $entityId, $changes, $oldValues, $newValues, $timestamp);
|
|
$this->dispatchLifecycleEvent($event);
|
|
}
|
|
|
|
/**
|
|
* Create and dispatch an EntityDeletedEvent
|
|
*/
|
|
public function entityDeleted(object $entity, string $entityClass, mixed $entityId, array $deletedData = []): void
|
|
{
|
|
$timestamp = Timestamp::fromClock($this->clock);
|
|
$event = new EntityDeletedEvent($entity, $entityClass, $entityId, $deletedData, $timestamp);
|
|
$this->dispatchLifecycleEvent($event);
|
|
}
|
|
|
|
/**
|
|
* Create and dispatch an EntityLoadedEvent
|
|
*/
|
|
public function entityLoaded(
|
|
object $entity,
|
|
string $entityClass,
|
|
mixed $entityId,
|
|
array $loadedData = [],
|
|
bool $wasLazy = false
|
|
): void {
|
|
$timestamp = Timestamp::fromClock($this->clock);
|
|
$event = new EntityLoadedEvent($entity, $entityClass, $entityId, $loadedData, $wasLazy, $timestamp);
|
|
$this->dispatchLifecycleEvent($event);
|
|
}
|
|
|
|
/**
|
|
* Create and dispatch an EntityDetachedEvent
|
|
*/
|
|
public function entityDetached(object $entity, string $entityClass, mixed $entityId): void
|
|
{
|
|
$timestamp = Timestamp::fromClock($this->clock);
|
|
$event = new EntityDetachedEvent($entity, $entityClass, $entityId, $timestamp);
|
|
$this->dispatchLifecycleEvent($event);
|
|
}
|
|
|
|
/**
|
|
* Get domain event collector for advanced usage
|
|
*/
|
|
public function getDomainEventCollector(): DomainEventCollector
|
|
{
|
|
return $this->domainEventCollector;
|
|
}
|
|
|
|
/**
|
|
* Get core event dispatcher for advanced usage
|
|
*/
|
|
public function getEventDispatcher(): EventDispatcher
|
|
{
|
|
return $this->eventDispatcher;
|
|
}
|
|
|
|
/**
|
|
* Get statistics about domain events
|
|
*/
|
|
public function getDomainEventStats(): array
|
|
{
|
|
return [
|
|
'tracked_entities' => $this->domainEventCollector->getTrackedEntityCount(),
|
|
'total_events' => $this->domainEventCollector->getTotalEventCount(),
|
|
];
|
|
}
|
|
}
|