<?php
namespace App\Entity;
use App\Repository\UserRepository;
use App\Validator\PhoneNumberConstraint;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* Utilisateur et administrateurs.
*
* @UniqueEntity(fields={"username"}, message="Ce compte existe déjà")
*/
#[ORM\Table]
#[ORM\Index(name: 'username', columns: ['username'])]
#[ORM\Entity(repositoryClass: UserRepository::class)]
class User implements UserInterface, \Serializable, PasswordAuthenticatedUserInterface, TwoFactorInterface
{
// ------------- Maintainers -----------------------
/** User prospect status */
public const PROSPECT = 1;
/** User authorized status */
public const AUTHORIZED = 2;
/** User inactive status */
public const EXPIRED = 3;
// ------------- Clients -----------------------
/** Client prospect status */
public const CLIENT_PROSPECT = 4;
/** Client suspended status */
public const SUSPENDED = 5;
/** Client closed status */
public const CLOSED = 6;
/** Client status */
public const CLIENT = 7;
/** Client expired status */
public const CLIENT_EXPIRED = 8;
protected static $statusLabels = [
1 => 'Prospect',
2 => 'Authorized',
3 => 'Expired',
];
protected static $clientStatusLabels = [
4 => 'ProspectClient',
5 => 'Suspended',
6 => 'Closed',
7 => 'Client',
8 => 'Expired',
];
/**
* @Groups({"user:read"})
*/
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private $id;
/**
* @Groups({"user:read"})
*/
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $username;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $password;
/**
* @Groups({"user:read"})
*/
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $email;
#[ORM\Column(type: 'boolean', nullable: true)]
private $isActive;
#[ORM\Column(type: 'string', nullable: true)]
private $zone;
#[ORM\Column(type: 'json')]
private $roles = [];
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $hash;
#[ORM\Column(type: 'boolean', options: ['default' => false])]
private bool $admin = false;
/**
* @Groups({"user:read"})
*/
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $nom;
/**
* @Groups({"user:read"})
*/
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $prenom;
/**
* @PhoneNumberConstraint()
*
* @Groups({"user:read"})
*/
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $numtel;
#[ORM\Column(type: 'boolean', nullable: true)]
private $cgu;
/**
* @var Abonnement[]|Collection
*/
#[ORM\OneToMany(targetEntity: Abonnement::class, mappedBy: 'user', cascade: ['persist'])]
#[ORM\OrderBy(['datefin' => 'DESC'])]
private Collection $abonnements;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $civilite;
#[ORM\Column(type: 'datetime', nullable: true)]
private $naissance;
/**
* @Groups({"user:read"})
*/
#[ORM\Column(type: 'text', nullable: true)]
private $address;
/**
* @Groups({"user:read"})
*/
#[ORM\Column(type: 'string', length: 50, nullable: true)]
private $zip;
/**
* @Groups({"user:read"})
*/
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $city;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private $country;
#[ORM\Column(type: 'boolean', nullable: true)]
private $communication;
#[ORM\Column(type: 'boolean')]
private $isVerified = false;
#[ORM\Column(type: 'datetime', nullable: true)]
private $deletedAt;
#[ORM\Column(type: 'datetime', nullable: true)]
private $datecreation;
#[ORM\Column(type: 'datetime', nullable: true)]
private $datemodification;
#[ORM\Column(type: 'boolean', nullable: true)]
private $optin;
#[ORM\Column(type: 'integer', nullable: true)]
private $fantome;
#[ORM\Column(type: 'boolean', nullable: true)]
private $getemail;
/**
* @Groups({"bike:upsert"})
*/
#[ORM\Column(type: 'integer', nullable: true)]
private $iduserfo;
#[ORM\Column(type: 'integer', nullable: true)]
private $doubleauth;
#[ORM\OneToMany(targetEntity: Contact::class, mappedBy: 'utilisateur')]
private $contacts;
#[ORM\OneToMany(targetEntity: Offre::class, mappedBy: 'createur')]
private $offres;
#[ORM\OneToMany(targetEntity: Facture::class, mappedBy: 'user')]
private $factures;
#[ORM\OneToMany(targetEntity: LogsUser::class, mappedBy: 'client')]
private $logsUsersClient;
#[ORM\OneToMany(targetEntity: LogsUser::class, mappedBy: 'mainteneur')]
private $logsUsersMainteneur;
#[ORM\OneToMany(targetEntity: LogsUser::class, mappedBy: 'user', cascade: ['persist'])]
private $logsUsersUser;
#[ORM\OneToMany(targetEntity: LogsUser::class, mappedBy: 'administrateur')]
private $logsUsersAdmin;
#[ORM\Column(type: 'string', nullable: true)]
private $authCode;
#[ORM\Column(type: 'datetime', nullable: true)]
private $validityCode;
#[ORM\OneToMany(targetEntity: Notes::class, mappedBy: 'User')]
private $notes;
#[ORM\JoinColumn(nullable: true)]
#[ORM\OneToMany(targetEntity: Bike::class, mappedBy: 'user', cascade: ['persist', 'remove'], orphanRemoval: true)]
private $bikes;
/**
* @var string
*/
#[ORM\Column(name: 'id_document', type: 'string', length: 250, nullable: true)]
private $idDocument;
/**
* @var AbonnementLuckey[]|Collection
*/
#[ORM\OneToMany(targetEntity: AbonnementLuckey::class, mappedBy: 'user')]
private $abonnementsLuckey;
#[ORM\OneToOne(targetEntity: UserLuckey::class, mappedBy: 'user', cascade: ['persist', 'remove'])]
private $luckeyId;
#[ORM\OneToMany(targetEntity: LogsMail::class, mappedBy: 'user')]
private $logsMails;
#[ORM\OneToMany(targetEntity: Card::class, mappedBy: 'user')]
private $cards;
public function __construct()
{
$this->isActive = true;
$this->abonnements = new ArrayCollection();
$this->contacts = new ArrayCollection();
$this->offres = new ArrayCollection();
$this->factures = new ArrayCollection();
$this->logsUsersClient = new ArrayCollection();
$this->logsUsersMainteneur = new ArrayCollection();
$this->logsUsersUser = new ArrayCollection();
$this->logsUsersAdmin = new ArrayCollection();
$this->notes = new ArrayCollection();
$this->bikes = new ArrayCollection();
$this->abonnementsLuckey = new ArrayCollection();
$this->logsMails = new ArrayCollection();
$this->cards = new ArrayCollection();
}
public function __toString()
{
if (null !== $this->username) {
return $this->username;
}
if (null !== $this->nom) {
return $this->nom;
}
return '';
}
public function getSalt(): ?string
{
// you *may* need a real salt depending on your encoder
// see section on salt below
return null;
}
public function eraseCredentials()
{
// Nothing
}
/** @see \Serializable::serialize() */
public function serialize()
{
return serialize([
$this->id,
$this->username,
$this->password,
// see section on salt below
// $this->salt,
]);
}
/** @see \Serializable::unserialize() */
public function unserialize($serialized)
{
list(
$this->id,
$this->username,
$this->password,
// see section on salt below
// $this->salt
) = unserialize($serialized, ['allowed_classes' => false]);
}
/**
* The public representation of the user (e.g. a username, an email address, etc.).
*
* @see UserInterface
*/
public function getUserIdentifier(): string
{
return (string) $this->username;
}
public function getId()
{
return $this->id;
}
public function getUsername(): ?string
{
return $this->username;
}
public function setUsername(?string $username): self
{
$this->username = $username;
return $this;
}
public function getPassword(): ?string
{
return $this->password;
}
public function setPassword(?string $password): self
{
$this->password = $password;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(?string $email): self
{
$this->email = $email;
return $this;
}
public function getIsActive(): ?bool
{
return $this->isActive;
}
public function setIsActive(bool $isActive): self
{
$this->isActive = $isActive;
return $this;
}
public function getZone(): ?string
{
return $this->zone;
}
public function setZone(?string $zone): self
{
$this->zone = $zone;
return $this;
}
public function getHash(): ?string
{
return $this->hash;
}
public function setHash(?string $hash): self
{
$this->hash = $hash;
return $this;
}
public function getAdmin(): ?bool
{
return $this->admin;
}
public function setAdmin(bool $admin): self
{
$this->admin = $admin;
return $this;
}
public function getNom(): ?string
{
return $this->nom;
}
public function setNom(string $nom): self
{
$this->nom = $nom;
return $this;
}
public function getPrenom(): ?string
{
return $this->prenom;
}
public function setPrenom(string $prenom): self
{
$this->prenom = $prenom;
return $this;
}
public function getFullName(): string
{
return $this->prenom . ' ' . $this->nom;
}
public function getNumtel(): ?string
{
return $this->numtel;
}
public function setNumtel(?string $numtel): self
{
$this->numtel = $numtel;
return $this;
}
public function getCgu(): ?bool
{
return $this->cgu;
}
public function setCgu(?bool $cgu): self
{
$this->cgu = $cgu;
return $this;
}
/**
* @return Abonnement[]|Collection
*/
public function getAbonnements(): Collection
{
return $this->abonnements;
}
/**
* If User get One active subscription return the first one it found
* If user get no active subscription return the closest one from now
* if user don't get subscription, retur null.
*
* @throws \Exception
*/
public function getClosestSubscription(): ?Abonnement
{
$now = new \DateTime(
'now',
new \DateTimeZone('Europe/Paris')
);
if ($this->abonnements->isEmpty()) {
return null;
}
if (1 === $this->abonnements->count()) {
return $this->abonnements->first();
}
foreach ($this->abonnements as $abo) {
if ($abo->getDatedebut() <= $now && $abo->getDatefin() >= $now) {
return $abo;
}
}
// Find closest subscription beetween now and middle of interval
$res = [];
$nowTimestamp = $now->getTimestamp();
foreach ($this->abonnements as $abo) {
$timeInterval = abs(
$nowTimestamp -
(
(
$abo->getDatedebut()->getTimestamp()
+ $abo->getDatefin()->getTimestamp()
)
/ 2
)
);
$res[$timeInterval] = $abo;
}
ksort($res);
return current($res);
}
public function addAbonnement(Abonnement $abonnement): self
{
if (!$this->abonnements->contains($abonnement)) {
$this->abonnements->add($abonnement);
$abonnement->setUser($this);
}
return $this;
}
public function removeAbonnement(Abonnement $abonnement): self
{
if ($this->abonnements->removeElement($abonnement)) {
// set the owning side to null (unless already changed)
if ($abonnement->getUser() === $this) {
$abonnement->setUser(null);
}
}
return $this;
}
public function getCivilite(): ?string
{
return $this->civilite;
}
public function setCivilite(?string $civilite): self
{
$this->civilite = $civilite;
return $this;
}
public function getNaissance(): ?\DateTimeInterface
{
return $this->naissance;
}
public function setNaissance(?\DateTimeInterface $naissance): self
{
$this->naissance = $naissance;
return $this;
}
public function getAddress(): ?string
{
return $this->address;
}
public function setAddress(?string $address): self
{
$this->address = $address;
return $this;
}
public function getZip(): ?string
{
return $this->zip;
}
public function setZip(?string $zip): self
{
$this->zip = $zip;
return $this;
}
public function getCity(): ?string
{
return $this->city;
}
public function setCity(?string $city): self
{
$this->city = $city;
return $this;
}
public function getCountry(): ?string
{
return $this->country;
}
public function setCountry(?string $country): self
{
$this->country = $country;
return $this;
}
public function getCommunication(): ?bool
{
return $this->communication;
}
public function setCommunication(?bool $communication): self
{
$this->communication = $communication;
return $this;
}
public function isVerified(): bool
{
return $this->isVerified;
}
public function setIsVerified(bool $isVerified): self
{
$this->isVerified = $isVerified;
return $this;
}
public function getDeletedAt(): ?\DateTimeInterface
{
return $this->deletedAt;
}
public function setDeletedAt(?\DateTimeInterface $deletedAt): self
{
$this->deletedAt = $deletedAt;
return $this;
}
public function getDatecreation(): ?\DateTimeInterface
{
return $this->datecreation;
}
public function setDatecreation(?\DateTimeInterface $datecreation): self
{
$this->datecreation = $datecreation;
return $this;
}
public function getDatemodification(): ?\DateTimeInterface
{
return $this->datemodification;
}
public function setDatemodification(?\DateTimeInterface $datemodification): self
{
$this->datemodification = $datemodification;
return $this;
}
public function getOptin(): ?bool
{
return $this->optin;
}
public function setOptin(?bool $optin): self
{
$this->optin = $optin;
return $this;
}
public function getFantome(): ?int
{
return $this->fantome;
}
public function setFantome(?int $fantome): self
{
$this->fantome = $fantome;
return $this;
}
public function getRoles(): array
{
$roles = $this->roles;
// guarantee every user at least has ROLE_USER
// $roles[] = 'ROLE_USER';
return array_unique($roles);
}
public function setRoles(array $roles): self
{
$this->roles = $roles;
return $this;
}
public function getGetemail(): ?bool
{
return $this->getemail;
}
public function setGetemail(?bool $getemail): self
{
$this->getemail = $getemail;
return $this;
}
public function getIduserfo(): ?int
{
return $this->iduserfo;
}
public function setIduserfo(?int $iduserfo): self
{
$this->iduserfo = $iduserfo;
return $this;
}
public function getDoubleauth(): ?int
{
return $this->doubleauth;
}
public function setDoubleauth(?int $doubleauth): self
{
$this->doubleauth = $doubleauth;
return $this;
}
/**
* @return Collection|Contact[]
*/
public function getContacts(): Collection
{
return $this->contacts;
}
public function addContact(Contact $contact): self
{
if (!$this->contacts->contains($contact)) {
$this->contacts[] = $contact;
$contact->setUtilisateur($this);
}
return $this;
}
public function removeContact(Contact $contact): self
{
if ($this->contacts->removeElement($contact)) {
// set the owning side to null (unless already changed)
if ($contact->getUtilisateur() === $this) {
$contact->setUtilisateur(null);
}
}
return $this;
}
/**
* @return Collection|Offre[]
*/
public function getOffres(): Collection
{
return $this->offres;
}
public function addOffre(Offre $offre): self
{
if (!$this->offres->contains($offre)) {
$this->offres[] = $offre;
$offre->setCreateur($this);
}
return $this;
}
public function removeOffre(Offre $offre): self
{
if ($this->offres->removeElement($offre)) {
// set the owning side to null (unless already changed)
if ($offre->getCreateur() === $this) {
$offre->setCreateur(null);
}
}
return $this;
}
/**
* @return Collection<int, Facture>
*/
public function getFactures(): Collection
{
return $this->factures;
}
public function addFacture(Facture $facture): self
{
if (!$this->factures->contains($facture)) {
$this->factures[] = $facture;
$facture->setUser($this);
}
return $this;
}
public function removeFacture(Facture $facture): self
{
if ($this->factures->removeElement($facture)) {
// set the owning side to null (unless already changed)
if ($facture->getUser() === $this) {
$facture->setUser(null);
}
}
return $this;
}
/**
* @return Collection|LogsUser[]
*/
public function getLogsUsersClient(): Collection
{
return $this->logsUsersClient;
}
public function addLogsUserClient(LogsUser $logsUserClient): self
{
if (!$this->logsUsersClient->contains($logsUserClient)) {
$this->logsUsersClient[] = $logsUserClient;
$logsUserClient->setUser($this);
}
return $this;
}
public function removeLogsUserClient(LogsUser $logsUserClient): self
{
if ($this->logsUsersClient->removeElement($logsUserClient)) {
// set the owning side to null (unless already changed)
if ($logsUserClient->getUser() === $this) {
$logsUserClient->setUser(null);
}
}
return $this;
}
/**
* @return Collection|LogsUser[]
*/
public function getLogsUsersMainteneur(): Collection
{
return $this->logsUsersMainteneur;
}
public function addLogsUserMainteneur(LogsUser $logsUserMainteneur): self
{
if (!$this->logsUsersMainteneur->contains($logsUserMainteneur)) {
$this->logsUsersMainteneur[] = $logsUserMainteneur;
$logsUserMainteneur->setUser($this);
}
return $this;
}
public function removeLogsUserMainteneur(LogsUser $logsUserMainteneur): self
{
if ($this->logsUsersMainteneur->removeElement($logsUserMainteneur)) {
// set the owning side to null (unless already changed)
if ($logsUserMainteneur->getUser() === $this) {
$logsUserMainteneur->setUser(null);
}
}
return $this;
}
/**
* @return Collection|LogsUser[]
*/
public function getLogsUsersUser(): Collection
{
return $this->logsUsersUser;
}
public function addLogsUserUser(LogsUser $logsUserUser): self
{
if (!$this->logsUsersUser->contains($logsUserUser)) {
$this->logsUsersUser[] = $logsUserUser;
$logsUserUser->setUser($this);
}
return $this;
}
public function removeLogsUserUser(LogsUser $logsUserUser): self
{
if ($this->logsUsersUser->removeElement($logsUserUser)) {
// set the owning side to null (unless already changed)
if ($logsUserUser->getUser() === $this) {
$logsUserUser->setUser(null);
}
}
return $this;
}
/**
* @return Collection|LogsUser[]
*/
public function getLogsUsersAdmin(): Collection
{
return $this->logsUsersAdmin;
}
public function addLogsUserAdmin(LogsUser $logsUserAdmin): self
{
if (!$this->logsUsersAdmin->contains($logsUserAdmin)) {
$this->logsUsersAdmin[] = $logsUserAdmin;
$logsUserAdmin->setUser($this);
}
return $this;
}
public function removeLogsUserAdmin(LogsUser $logsUserAdmin): self
{
if ($this->logsUsersAdmin->removeElement($logsUserAdmin)) {
// set the owning side to null (unless already changed)
if ($logsUserAdmin->getUser() === $this) {
$logsUserAdmin->setUser(null);
}
}
return $this;
}
/** Fonctions statiques */
/**
* Get label for specific user status code.
*
* @param int $status Status index
*/
public static function getStatusLabel($status): string
{
return self::$statusLabels[$status];
}
/**
* Get user statuses array.
*/
public static function getStatusLabels(): array
{
return self::$statusLabels;
}
/**
* Get label for specific client status code.
*
* @param int $status Status index
*/
public static function getClientStatusLabel($status): string
{
return self::$clientStatusLabels[$status];
}
/**
* Get client statuses array.
*/
public static function getClientStatusLabels(): array
{
return self::$clientStatusLabels;
}
public function isEmailAuthEnabled(): bool
{
return true; // This can be a persisted field to switch email code authentication on/off
}
public function getEmailAuthRecipient(): string
{
return $this->email;
}
public function getEmailAuthCode(): string
{
if (null === $this->authCode) {
throw new \LogicException('The email authentication code was not set');
}
return $this->authCode;
}
public function setEmailAuthCode(string $authCode): void
{
$this->authCode = $authCode;
}
public function deleteEmailAuthCode(): void
{
$this->authCode = null;
}
public function getValidityCode(): ?\DateTimeInterface
{
return $this->validityCode;
}
public function setValidityCode(?\DateTimeInterface $validityCode): self
{
$this->validityCode = $validityCode;
return $this;
}
/**
* @return Collection<int, Notes>
*/
public function getNotes(): Collection
{
return $this->notes;
}
public function addNote(Notes $note): self
{
if (!$this->notes->contains($note)) {
$this->notes[] = $note;
$note->setUser($this);
}
return $this;
}
public function removeNote(Notes $note): self
{
if ($this->notes->removeElement($note)) {
// set the owning side to null (unless already changed)
if ($note->getUser() === $this) {
$note->setUser(null);
}
}
return $this;
}
/**
* @return Bike[]|\Doctrine\Common\Collections\Collection
*/
public function getBikes(): Collection
{
return $this->bikes;
}
public function addBike(Bike $bike): self
{
if (!$this->bikes->contains($bike)) {
$this->bikes[] = $bike;
$bike->setUser($this);
}
return $this;
}
public function removeBike(Bike $bike): self
{
if ($this->bikes->contains($bike)) {
$this->bikes->removeElement($bike);
// set the owning side to null (unless already changed)
if ($bike->getUser() === $this) {
$bike->setUser(null);
}
}
return $this;
}
/**
* Get the value of idDocument.
*
* @return string
*/
public function getIdDocument()
{
return $this->idDocument;
}
/**
* Set the value of idDocument.
*
* @return self
*/
public function setIdDocument(?string $idDocument)
{
$this->idDocument = $idDocument;
return $this;
}
/**
* Anonymize user.
*
* @return $this
*/
public function anonymize(): self
{
$this->setDeletedAt(new \DateTime(
'now',
new \DateTimeZone('Europe/Paris')
))
->setUsername(null)
->setPassword('')
->setEmail('')
->setIsActive(false)
->setRoles(['ROLE_CLOTURE'])
->setHash(null)
->setAdmin(false)
->setNom('')
->setPrenom('')
->setNumtel('')
->setCgu(null)
->setCivilite('')
->setNaissance(null)
->setAddress('')
->setZip(null)
->setCity('')
->setCountry('')
->setIsVerified(false)
->setDatecreation(null)
->setOptin(null)
;
return $this;
}
/**
* @return Collection<int, AbonnementLuckey>
*/
public function getAbonnementsLuckey(): Collection
{
return $this->abonnementsLuckey;
}
public function getLuckeyId(): ?UserLuckey
{
return $this->luckeyId;
}
public function setLuckeyId(UserLuckey $luckeyId): self
{
// set the owning side of the relation if necessary
if ($luckeyId->getUser() !== $this) {
$luckeyId->setUser($this);
}
$this->luckeyId = $luckeyId;
return $this;
}
/**
* @return Collection<int, LogsMail>
*/
public function getLogsMails(): Collection
{
return $this->logsMails;
}
/**
* @return Card[]|Collection
*/
public function getCards(): Collection
{
return $this->cards;
}
public function addCard(Card $card): self
{
if (!$this->cards->contains($card)) {
$this->cards[] = $card;
$card->setUser($this);
}
return $this;
}
public function removeCard(Card $card): self
{
if ($this->cards->removeElement($card)) {
// set the owning side to null (unless already changed)
if ($card->getUser() === $this) {
$card->setUser(null);
}
}
return $this;
}
}