src/Entity/User.php line 32

Open in your IDE?
  1. <?php
  2. namespace App\Entity;
  3. use App\Entity\Account\Avatar;
  4. use App\Entity\Location\City;
  5. use App\Entity\Sales\AccountCharge;
  6. use App\Entity\Sales\AccountEnrollment;
  7. use App\Entity\Sales\AccountTransaction;
  8. use App\PaymentProcessing\Exception\CurrencyMismatchException;
  9. use App\PaymentProcessing\Exception\NotEnoughMoneyException;
  10. use App\Repository\UserRepository;
  11. use App\Service\CountryCurrencyResolver;
  12. use Doctrine\Common\Collections\ArrayCollection;
  13. use Doctrine\Common\Collections\Collection;
  14. use Doctrine\ORM\Mapping as ORM;
  15. use Money\Currency;
  16. use Money\Money;
  17. use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
  18. use Symfony\Component\Serializer\Annotation\Groups;
  19. use Symfony\Component\Validator\Constraints as Assert;
  20. //use Vich\UploaderBundle\Mapping\Annotation as Vich;
  21. use Symfony\Component\Security\Core\User\UserInterface;
  22. #[ORM\Entity(repositoryClassUserRepository::class)]
  23. #[UniqueEntity(fields: ['email'], groups: ['Registration'])]
  24. #[UniqueEntity(fields: ['nickName'], groups: ['Registration'])] // //Vich\Uploadable
  25. #[ORM\HasLifecycleCallbacks]
  26. #[ORM\InheritanceType('SINGLE_TABLE')]
  27. #[ORM\DiscriminatorColumn(name'type'type'string'length12)]
  28. #[ORM\DiscriminatorMap(['advertiser' => Account\Advertiser::class, 'customer' => Account\Customer::class])]
  29. abstract class User implements UserInterface\Serializable
  30. {
  31.     public const ROLE_USER 'ROLE_USER';
  32.     #[ORM\Id]
  33.     #[ORM\GeneratedValue]
  34.     #[ORM\Column(type'integer')]
  35.     #[Groups(['comments'])]
  36.     private int $id;
  37.     
  38.     #[ORM\Column(type'string'length180uniquetrue)]
  39.     #[Assert\NotBlank(groups: ['Registration'])]
  40.     #[Assert\Email(groups: ['Registration'])]
  41.     private ?string $email null;
  42.     #[ORM\Column(type'string'length100)]
  43.     #[Assert\NotBlank(groups: ['Registration'])]
  44.     #[Assert\Length(max64groups: ['Registration'])]
  45.     #[Groups(['comments'])]
  46.     private ?string $nickName null;
  47.     #[ORM\Column(type'text'nullabletrue)]
  48.     private ?string $notes null;
  49.     #[ORM\Column(name'country_code'type'string'length2)]
  50.     private string $country;
  51.     #[ORM\JoinColumn(name'city_id'referencedColumnName'id')]
  52.     #[ORM\ManyToOne(targetEntityCity::class)]
  53.     private ?City $city null;
  54.     #[ORM\OneToOne(targetEntityAvatar::class, mappedBy'user'cascade: ['all'], orphanRemovaltrue)]
  55.     #[Groups(['comments'])]
  56.     protected ?Avatar $avatar;
  57.     #[ORM\Column(type'json')]
  58.     private array $roles = [];
  59.     /** The hashed password*/
  60.     #[ORM\Column(type'string')]
  61.     private string $password;
  62.     #[Assert\NotBlank(groups: ['Registration'])]
  63.     private ?string $plainPassword null;
  64.     #[ORM\Column(type'string'length255nullabletrue)]
  65.     private ?string $confirmationCode;
  66.     #[ORM\Column(type'string'length255nullabletrue)]
  67.     private ?string $smscCode;
  68.     #[ORM\Column(type'boolean')]
  69.     private bool $enabled;
  70.     #[ORM\Column(type'boolean')]
  71.     private bool $trusted false;
  72.     #[ORM\Column(name'credits'type'integer')]
  73.     private int $credits 0;
  74.     /**
  75.      * Валюта для финансовых операций аккаунта.
  76.      * Устанавливается при регистрации в зависимости от выбранной страны, и не может быть изменена через кабинет.
  77.      */
  78.     #[ORM\Column(name'currency_code'type'string'length3)]
  79.     private string $currencyCode;
  80.     #[ORM\Column(type'boolean'options: ['default' => 1])]
  81.     private bool $fullRegistered true;
  82.     #[ORM\Column(type'integer'options: ['default' => 0])]
  83.     private int $postRegistrationStep 0;
  84.     /** @var AccountEnrollment[] */
  85.     #[ORM\OneToMany(targetEntityAccountEnrollment::class, mappedBy'account')]
  86.     private Collection $enrollments;
  87.     /** @var AccountCharge[] */
  88.     #[ORM\OneToMany(targetEntityAccountCharge::class, mappedBy'account')]
  89.     private Collection $charges;
  90.     /** @var AccountTransaction[] */
  91.     #[ORM\OneToMany(targetEntityAccountTransaction::class, mappedBy'account')]
  92.     private Collection $transactions;
  93.     #[ORM\Column(name'created'type'datetime')]
  94.     private \DateTimeInterface $created;
  95.     #[ORM\Column(name'updated'type'datetime'nullabletrue)]
  96.     private ?\DateTimeInterface $updated;
  97.     #[ORM\Column(name'balance_low_notified_at'type'datetime'nullabletrue)]
  98.     private ?\DateTimeInterface $lowBalanceNotifiedAt;
  99.     #[ORM\Column(name'ban'type'string'length5nullabletrue)]
  100.     private ?string $ban null;
  101.     #[ORM\OneToOne(targetEntityOfferBarHidden::class, cascade: ['all'], mappedBy'account')]
  102.     private ?OfferBarHidden $offerBarHidden;
  103.     public function __construct()
  104.     {
  105.         $this->roles = [self::ROLE_USER];
  106.         $this->enabled false;
  107.         $this->enrollments = new ArrayCollection();
  108.         $this->charges = new ArrayCollection();
  109.         $this->transactions = new ArrayCollection();
  110.         //TODO temp
  111.         $this->created = new \DateTime();
  112.         $this->updated = new \DateTime();
  113.     }
  114.     public function getId(): ?int
  115.     {
  116.         return $this->id;
  117.     }
  118.     public function getEmail(): ?string
  119.     {
  120.         return $this->email;
  121.     }
  122.     public function setEmail(string $email): void
  123.     {
  124.         $this->email $email;
  125.     }
  126.     public function getNickName(): ?string
  127.     {
  128.         return $this->nickName;
  129.     }
  130.     public function setNickName(string $nickName): void
  131.     {
  132.         $this->nickName $nickName;
  133.     }
  134.     public function getCountry(): ?string
  135.     {
  136.         return $this->country;
  137.     }
  138.     public function setCountry($country): void
  139.     {
  140.         $this->country $country;
  141.     }
  142.     public function getCity(): ?City
  143.     {
  144.         return $this->city;
  145.     }
  146.     public function setCity(City $city): void
  147.     {
  148.         $this->city $city;
  149.         $this->country $city->getCountryCode();
  150.     }
  151.     /**
  152.      * A visual identifier that represents this user.
  153.      *
  154.      * @see UserInterface
  155.      */
  156.     public function getUsername(): string
  157.     {
  158.         return (string)$this->email;
  159.     }
  160.     /**
  161.      * @see UserInterface
  162.      */
  163.     public function getRoles(): array
  164.     {
  165.         $roles $this->roles;
  166.         // guarantee every user at least has ROLE_USER
  167.         $roles[] = 'ROLE_USER';
  168.         return array_unique($roles);
  169.     }
  170.     public function setRoles(array $roles): self
  171.     {
  172.         $this->roles $roles;
  173.         return $this;
  174.     }
  175.     /**
  176.      * @see UserInterface
  177.      */
  178.     public function getPassword(): string
  179.     {
  180.         return (string)$this->password;
  181.     }
  182.     public function setPassword(string $password): void
  183.     {
  184.         $this->password $password;
  185.     }
  186.     public function getPlainPassword(): ?string
  187.     {
  188.         return $this->plainPassword;
  189.     }
  190.     public function setPlainPassword(string $plainPassword): void
  191.     {
  192.         $this->plainPassword $plainPassword;
  193.     }
  194.     public function getConfirmationCode(): string
  195.     {
  196.         return $this->confirmationCode;
  197.     }
  198.     public function setConfirmationCode(string $confirmationCode): void
  199.     {
  200.         $this->confirmationCode $confirmationCode;
  201.     }
  202.     public function getSmscCode(): string
  203.     {
  204.         return $this->smscCode;
  205.     }
  206.     public function setSmscCode(string $smscCode): void
  207.     {
  208.         $this->smscCode $smscCode;
  209.     }
  210.     public function isEnabled(): bool
  211.     {
  212.         return $this->enabled;
  213.     }
  214.     public function setEnabled(bool $enabled): void
  215.     {
  216.         $this->enabled $enabled;
  217.     }
  218.     public function isTrusted(): bool
  219.     {
  220.         return $this->trusted;
  221.     }
  222.     public function setTrusted(bool $trusted): void
  223.     {
  224.         $this->trusted $trusted;
  225.     }
  226.     public function isFullRegistered(): bool
  227.     {
  228.         return $this->fullRegistered;
  229.     }
  230.     public function setFullRegistered(bool $fullRegistered): void
  231.     {
  232.         $this->fullRegistered $fullRegistered;
  233.     }
  234.     /**
  235.      * Зачисляет деньги на счет аккаунта
  236.      *
  237.      * @param Money $toEnroll
  238.      *
  239.      * @throws \DomainException Если указана отрицательная или нулевая сумма
  240.      * @throws CurrencyMismatchException Если валюты баланса и суммы зачисления не совпадают
  241.      */
  242.     public function enroll(Money $toEnroll): void
  243.     {
  244.         if ($toEnroll->isNegative() || $toEnroll->isZero()) {
  245.             throw new \DomainException('Can not enroll negative or zero amount.');
  246.         }
  247.         $currentBalance $this->getCurrentBalance();
  248.         if (!$currentBalance->isSameCurrency($toEnroll)) {
  249.             throw new CurrencyMismatchException();
  250.         }
  251.         $newBalance $currentBalance->add($toEnroll);
  252.         $this->credits $newBalance->getAmount();
  253.     }
  254.     /**
  255.      * Списывает деньги со счета аккаунта
  256.      *
  257.      * @param Money $toCharge
  258.      * @param bool  $withOverdraft Возможность делать отрицательный баланс для ручных списаний
  259.      *
  260.      * @throws \DomainException Если указана отрицательная или нулевая сумма
  261.      * @throws CurrencyMismatchException Если валюты баланса и суммы списания не совпадают
  262.      * @throws NotEnoughMoneyException Если на счету недостаточно средств
  263.      */
  264.     public function charge(Money $toChargebool $withOverdraft false): void
  265.     {
  266.         if ($toCharge->isNegative() || $toCharge->isZero()) {
  267.             throw new \DomainException('Can not charge negative or zero amount.');
  268.         }
  269.         $currentBalance $this->getCurrentBalance();
  270.         if (!$currentBalance->isSameCurrency($toCharge)) {
  271.             throw new CurrencyMismatchException();
  272.         }
  273.         if ($currentBalance->lessThan($toCharge) && !$withOverdraft) {
  274.             throw new NotEnoughMoneyException();
  275.         }
  276.         $newBalance $currentBalance->subtract($toCharge);
  277.         $this->credits $newBalance->getAmount();
  278.     }
  279.     public function getCurrentBalance(): Money
  280.     {
  281.         return new Money($this->credits, new Currency($this->currencyCode));
  282.     }
  283.     public function getCurrencyCode(): string
  284.     {
  285.         return $this->currencyCode;
  286.     }
  287.     public function resolveCurrency(CountryCurrencyResolver $currencyResolver): void
  288.     {
  289.         $this->currencyCode $currencyResolver->getCurrencyFor($this->country);
  290.     }
  291.     /**
  292.      * @return AccountEnrollment[]
  293.      */
  294.     public function getEnrollments(): Collection
  295.     {
  296.         return $this->enrollments;
  297.     }
  298.     /**
  299.      * @return AccountCharge[]
  300.      */
  301.     public function getCharges(): Collection
  302.     {
  303.         return $this->charges;
  304.     }
  305.     /**
  306.      * @return AccountTransaction[]
  307.      */
  308.     public function getTransactions(): Collection
  309.     {
  310.         return $this->transactions;
  311.     }
  312.     /**
  313.      * @see UserInterface
  314.      */
  315.     public function getSalt(): void
  316.     {
  317.         // not needed when using the "bcrypt" algorithm in security.yaml
  318.     }
  319.     /**
  320.      * @see UserInterface
  321.      */
  322.     public function eraseCredentials(): void
  323.     {
  324.         // If you store any temporary, sensitive data on the user, clear it here
  325.         $this->plainPassword null;
  326.     }
  327.     public function getCreated(): \DateTimeInterface
  328.     {
  329.         return $this->created;
  330.     }
  331.     /**
  332.      * @inheritDoc
  333.      */
  334.     public function serialize()
  335.     {
  336.         return \serialize([
  337.             $this->id,
  338.             $this->email,
  339.             $this->password,
  340.             $this->roles,
  341.             $this->enabled,
  342.         ]);
  343.     }
  344.     /**
  345.      * @inheritDoc
  346.      */
  347.     public function unserialize($serialized): void
  348.     {
  349.         list(
  350.             $this->id,
  351.             $this->email,
  352.             $this->password,
  353.             $this->roles,
  354.             $this->enabled
  355.             ) = \unserialize($serialized, ['allowed_classes' => false]);
  356.     }
  357.     public function getNotes(): ?string
  358.     {
  359.         return $this->notes;
  360.     }
  361.     public function setNotes(?string $notes): void
  362.     {
  363.         $this->notes $notes;
  364.     }
  365.     public function isBanned(): bool
  366.     {
  367.         return null != $this->ban;
  368.     }
  369.     public function getBan(): ?string
  370.     {
  371.         return $this->ban;
  372.     }
  373.     public function setBan(?string $ban): void
  374.     {
  375.         $this->ban $ban;
  376.     }
  377.     public function isLowBalanceNotified(): bool
  378.     {
  379.         return $this->lowBalanceNotifiedAt != null;
  380.     }
  381.     public function setLowBalanceNotified(?\DateTimeInterface $dateTime): void
  382.     {
  383.         $this->lowBalanceNotifiedAt $dateTime;
  384.     }
  385.     public function getAvatar(): ?Avatar
  386.     {
  387.         return $this->avatar;
  388.     }
  389.     public function setAvatar(string $path): void
  390.     {
  391.         $this->avatar = new Avatar($this$path);
  392.     }
  393.     public function getPostRegistrationStep(): int
  394.     {
  395.         return $this->postRegistrationStep;
  396.     }
  397.     public function setPostRegistrationStep(int $postRegistrationStep): void
  398.     {
  399.         $this->postRegistrationStep $postRegistrationStep;
  400.     }
  401.     public function offerBarHidden(): ?OfferBarHidden
  402.     {
  403.         return $this->offerBarHidden;
  404.     }
  405.     public function setOfferBarHidden(): void
  406.     {
  407.         if (null !== $this->offerBarHidden) {
  408.             return;
  409.         }
  410.         $this->offerBarHidden = new OfferBarHidden($this);
  411.     }
  412. }