<?php namespace App\Entity; use App\Entity\EntityTrait\EnablableEntityTrait; use App\Flux\AccountInterface; use Doctrine\Common\Persistence\Event\LifecycleEventArgs; use Doctrine\ORM\Mapping as ORM; use Gedmo\Timestampable\Traits\TimestampableEntity; use Ramsey\Uuid\Doctrine\UuidGenerator; /** * @ORM\MappedSuperclass * @ORM\HasLifecycleCallbacks */ abstract class Account implements AccountInterface { use EnablableEntityTrait; use TimeStampableEntity; /** * @var \Ramsey\Uuid\UuidInterface * * @ORM\Id * @ORM\Column(type="uuid", unique=true) * @ORM\GeneratedValue(strategy="CUSTOM") * @ORM\CustomIdGenerator(class=UuidGenerator::class) */ protected $id; /** * @ORM\Column(name="balance", type="decimal", scale=2, options={"default": 0.00}) */ protected $balance = 0.00; /** * @var string * * @ORM\Column(name="currency", type="string", length=25, options={"default" : ""}) */ protected $currency = ''; /** * Hash => permet de vérifier l'intégrité des données. * * @var text * * @ORM\Column(name="hash", type="text", options={"default" : "tmp"}) */ protected $hash = 'tmp'; protected $operations; public function getId() { return $this->id; } public function getBalance(): ?float { return $this->balance; } public function setBalance(float $balance): self { $this->balance = $balance; return $this; } /** * Can be negative amount. * * @param float $montant [description] */ public function addAmount(float $montant): self { $this->balance += $montant; return $this; } public function getCurrency(): string { return $this->currency; } /** * Set currency. * * @return $this */ public function setCurrency(string $currency): self { $this->currency = $currency; return $this; } public function getHash(): ?string { return $this->hash; } public function setHash(string $hash): self { $this->hash = $hash; return $this; } /** * @ORM\PreUpdate * * @param LifecycleEventArgs $event */ public function preUpdate(LifecycleEventArgs $event): void { $this->updateHash($event); } /** * @ORM\PostPersist * * @param LifecycleEventArgs $event */ public function postPersist(LifecycleEventArgs $event): void { $this->updateHash($event); $account = $event->getEntity(); $event->getEntityManager()->persist($account); $event->getEntityManager()->flush(); } private function updateHash(LifecycleEventArgs $event): void { $account = $event->getEntity(); if ($account->getBalance() < 0) { throw new \Exception('[ACCOUNT] Opération impossible ! Balance inférieure ou égal à zéro !'); } // @TODO : generation du hash du account gourmand en ressource => voir pour optimiser ou le faire en async ! $hash = password_hash($account->getAllInfosUncrypted(), PASSWORD_BCRYPT, ['cost' => 5]); $account->setHash($hash); } public function getAllInfosUncrypted() { return $_ENV['APP_SECRET'] . $this->getId() . (0 == $this->getBalance() ? 0 : $this->getBalance()) . $this->getCurrency(); } /** * Get operations. * * @return Operation[]|ArrayCollection */ public function getOperations() { return $this->operations; } /** * Set operations. * * @return $this */ public function setOperations($operations) { $this->operations = $operations; return $this; } /** * @param Operation $operation * * @return $this */ public function addOperation(Operation $operation) { if (!$this->operations->contains($operation)) { $this->operations[] = $operation; $operation->setAccount($this); } return $this; } /** * @param Operation $operation * * @return $this */ public function removeOperation(Operation $operation) { if ($this->operations->contains($operation)) { $this->operations->removeElement($operation); $operation->setAccount(null); } return $this; } }