<?php namespace App\Listener; use App\Entity\AccountAdherent; use App\Entity\AccountComptoir; use App\Entity\AccountGroupe; use App\Entity\AccountPrestataire; use App\Entity\AccountSiege; use App\Entity\Adherent; use App\Entity\Comptoir; use App\Entity\Flux; use App\Entity\Groupe; use App\Entity\Prestataire; use App\Entity\Siege; use App\Entity\User; use App\Enum\CurrencyEnum; use Doctrine\Common\EventSubscriber; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Event\OnFlushEventArgs; use Doctrine\ORM\Events; use Symfony\Component\Security\Core\Security; class FluxListener implements EventSubscriber { private $em; private $security; public function __construct(EntityManagerInterface $em, Security $security) { $this->em = $em; $this->security = $security; } public function getSubscribedEvents() { return [Events::onFlush]; } private function persistAndCompute($em, $entity) { $em->persist($entity); $class = $em->getClassMetadata(get_class($entity)); $em->getUnitOfWork()->computeChangeSet($class, $entity); } /** * @deprecated */ public function onFlush(OnFlushEventArgs $args) { $em = $args->getEntityManager(); $uow = $em->getUnitOfWork(); $inserted = $uow->getScheduledEntityInsertions(); /* * @deprecated OLD operate() system ! */ // $em->getConnection()->beginTransaction(); // suspend auto-commit // try { // foreach ($inserted as $entity) { // // if ($entity instanceof Flux) { // // $topersists = $entity->operate($em); // // foreach ($topersists as $topersist) { // // $class = $em->getClassMetadata(get_class($topersist)); // // $em->persist($topersist); // // $em->getUnitOfWork()->computeChangeSet($class, $topersist); // // } // // // @TODO : do something (log, save somewhere else...) on flux persist // // // => @tag sur un service ? // // } // } // $em->getConnection()->commit(); // } catch (\Exception $e) { // $em->getConnection()->rollBack(); // // @TODO : better exception management // throw $e; // } $em->getConnection()->beginTransaction(); $updated = $uow->getScheduledEntityUpdates(); try { foreach ($updated as $entity) { // Create account(s) if needed ! if ($entity instanceof Adherent) { $account = $this->em->getRepository(AccountAdherent::class)->findOneBy(['adherent' => $entity, 'currency' => CurrencyEnum::CURRENCY_EMLC]); if (null == $account) { $account = new AccountAdherent(); $account ->setCurrency(CurrencyEnum::CURRENCY_EMLC) ; $entity->addAccount($account); $this->persistAndCompute($em, $account); $this->persistAndCompute($em, $entity); } } elseif ($entity instanceof Prestataire) { $account = $this->em->getRepository(AccountPrestataire::class)->findOneBy(['prestataire' => $entity, 'currency' => CurrencyEnum::CURRENCY_EMLC]); if (null == $account) { $account = new AccountPrestataire(); $account ->setCurrency(CurrencyEnum::CURRENCY_EMLC) ; $entity->addAccount($account); $this->persistAndCompute($em, $account); if ($entity->isMlc()) { $accountEuro = $this->em->getRepository(AccountPrestataire::class)->findOneBy(['prestataire' => $entity, 'currency' => CurrencyEnum::CURRENCY_EURO]); if (null == $accountEuro) { // Ajout du compte de fonctionnement euro pour le prestataire MLC $accountEuro = new AccountPrestataire(); $accountEuro ->setCurrency(CurrencyEnum::CURRENCY_EURO) ; $entity->addAccount($accountEuro); $this->persistAndCompute($em, $accountEuro); } } $this->persistAndCompute($em, $entity); } } elseif ($entity instanceof Groupe) { $account = $this->em->getRepository(AccountGroupe::class)->findOneBy(['groupe' => $entity, 'currency' => CurrencyEnum::CURRENCY_MLC]); if (null == $account) { $account = new AccountGroupe(); $account ->setCurrency(CurrencyEnum::CURRENCY_MLC) ; $entity->addAccount($account); $this->persistAndCompute($em, $account); $this->persistAndCompute($em, $entity); } } elseif ($entity instanceof Comptoir) { $account = $this->em->getRepository(AccountComptoir::class)->findOneBy(['comptoir' => $entity, 'currency' => CurrencyEnum::CURRENCY_MLC]); if (null == $account) { $account = new AccountComptoir(); $account ->setCurrency(CurrencyEnum::CURRENCY_MLC) ; $entity->addAccount($account); $this->persistAndCompute($em, $account); $this->persistAndCompute($em, $entity); } } elseif ($entity instanceof Siege) { $account = $this->em->getRepository(AccountSiege::class)->findOneBy(['siege' => $entity, 'currency' => CurrencyEnum::CURRENCY_MLC]); if (null == $account) { $account = new AccountSiege(); $account ->setCurrency(CurrencyEnum::CURRENCY_MLC) ; $entity->addAccount($account); $this->persistAndCompute($em, $account); } $account = $this->em->getRepository(AccountSiege::class)->findOneBy(['siege' => $entity, 'currency' => CurrencyEnum::CURRENCY_EMLC]); if (null == $account) { $account = new AccountSiege(); $account ->setCurrency(CurrencyEnum::CURRENCY_EMLC) ; $entity->addAccount($account); $this->persistAndCompute($em, $account); } $account = $this->em->getRepository(AccountSiege::class)->findOneBy(['siege' => $entity, 'currency' => CurrencyEnum::CURRENCY_MLC_NANTIE]); if (null == $account) { $account = new AccountSiege(); $account ->setCurrency(CurrencyEnum::CURRENCY_MLC_NANTIE) ; $entity->addAccount($account); $this->persistAndCompute($em, $account); } $this->persistAndCompute($em, $entity); } // if ($entity instanceof Flux) { // $changeset = $uow->getEntityChangeSet($entity); // // if ($entity->getParentType() == Flux::TYPE_DEMANDE_ACHAT && isset($changeset['reconverti'])) { // // $operateur = null; // // if ($changeset['reconverti'][0] === true) { // // throw new \Exception("Opération impossible ! Vous ne pouvez pas invalider un achat de monnaie !"); // // } // // // Si l'opérateur a changé // // if (isset($changeset['operateur']) && $changeset['operateur'][1] != null && $changeset['operateur'][1] instanceof User) { // // $operateur = $changeset['operateur'][1]; // // if (!$operateur->hasRole('ROLE_VALIDE_ACHAT')) { // // $operateur = null; // // } // // } // // $em->refresh($entity->getOperateur()); // // if ($operateur == null && $entity->getOperateur() != null && $entity->getOperateur() instanceof User && $entity->getOperateur()->hasRole('ROLE_VALIDE_ACHAT')) { // // $operateur = $entity->getOperateur(); // // } // // if ($operateur != null) { // // // Validate and Operate the transaction = buy e-MLC // // // Increment siege's ecompte nantie of e-MLC // // $entity->getExpediteur()->addEcompteNantie($entity->getMontant()); // // // Increment account of adherent/prestataire // // $entity->getDestinataire()->addEcompte($entity->getMontant()); // // $class = $em->getClassMetadata(get_class($entity->getExpediteur())); // // $em->persist($entity->getExpediteur()); // // $uow->computeChangeSet($class, $entity->getExpediteur()); // // $class = $em->getClassMetadata(get_class($entity->getDestinataire())); // // $em->persist($entity->getDestinataire()); // // $uow->computeChangeSet($class, $entity->getDestinataire()); // // } else { // // throw new \Exception("Opération impossible ! Vous n'avez pas les droits pour valider cet achat de monnaie !"); // // } // // } // // Update hash with new value from flux updated // // @TODO : re calculate hash only if validate and needed ! => check permissions / actions and data updated // $entity->updateHash(); // $class = $em->getClassMetadata(get_class($entity)); // $em->persist($entity); // } } $em->getConnection()->commit(); } catch (\Exception $e) { $em->getConnection()->rollBack(); // @TODO : better exception management throw $e; } } }