<?php namespace MailPoet\Doctrine; if (!defined('ABSPATH')) exit; use MailPoet\Doctrine\EventListeners\EmojiEncodingListener; use MailPoet\Doctrine\EventListeners\LastSubscribedAtListener; use MailPoet\Doctrine\EventListeners\SubscriberListener; use MailPoet\Doctrine\EventListeners\TimestampListener; use MailPoet\Doctrine\EventListeners\ValidationListener; use MailPoet\Tracy\DoctrinePanel\DoctrinePanel; use MailPoetVendor\Doctrine\DBAL\Connection; use MailPoetVendor\Doctrine\ORM\Configuration; use MailPoetVendor\Doctrine\ORM\EntityManager; use MailPoetVendor\Doctrine\ORM\Events; use Tracy\Debugger; class EntityManagerFactory { /** @var Connection */ private $connection; /** @var Configuration */ private $configuration; /** @var TimestampListener */ private $timestampListener; /** @var ValidationListener */ private $validationListener; /** @var EmojiEncodingListener */ private $emojiEncodingListener; /** @var LastSubscribedAtListener */ private $lastSubscribedAtListener; /** @var SubscriberListener */ private $subscriberListener; public function __construct( Connection $connection, Configuration $configuration, TimestampListener $timestampListener, ValidationListener $validationListener, EmojiEncodingListener $emojiEncodingListener, LastSubscribedAtListener $lastSubscribedAtListener, SubscriberListener $subscriberListener ) { $this->connection = $connection; $this->configuration = $configuration; $this->timestampListener = $timestampListener; $this->validationListener = $validationListener; $this->emojiEncodingListener = $emojiEncodingListener; $this->lastSubscribedAtListener = $lastSubscribedAtListener; $this->subscriberListener = $subscriberListener; } public function createEntityManager(): EntityManager { $entityManager = EntityManager::create($this->connection, $this->configuration); $this->cleanupListeners($entityManager); $this->setupListeners($entityManager); if ( class_exists(Debugger::class) && class_exists(DoctrinePanel::class) ) { DoctrinePanel::init($entityManager); } return $entityManager; } /** * We sometimes work with more EntityManager in tests, and the behavior could be inconsistent with multiple listeners */ private function cleanupListeners(EntityManager $entityManager) { $eventManager = $entityManager->getEventManager(); foreach ($eventManager->getListeners() as $event => $listeners) { if (!is_array($listeners)) { $eventManager->removeEventListener($event, $listeners); continue; } foreach ($listeners as $listener) { $eventManager->removeEventListener($event, $listener); } } $entityManager->getConfiguration()->getEntityListenerResolver()->clear(SubscriberListener::class); } private function setupListeners(EntityManager $entityManager) { $entityManager->getEventManager()->addEventListener( [Events::prePersist, Events::preUpdate], $this->timestampListener ); $entityManager->getEventManager()->addEventListener( [Events::onFlush], $this->validationListener ); $entityManager->getEventManager()->addEventListener( [Events::prePersist, Events::preUpdate], $this->emojiEncodingListener ); $entityManager->getEventManager()->addEventListener( [Events::prePersist, Events::preUpdate], $this->lastSubscribedAtListener ); $entityManager->getConfiguration()->getEntityListenerResolver()->register($this->subscriberListener); } }