src/Entity/User.php line 19

Open in your IDE?
  1. <?php
  2. namespace App\Entity;
  3. use App\Entity\Common\RoleInterface;
  4. use App\Entity\Traits\BaseDateAtTrait;
  5. use App\Repository\UserRepository;
  6. use Doctrine\Common\Collections\ArrayCollection;
  7. use Doctrine\Common\Collections\Collection;
  8. use Doctrine\ORM\Mapping as ORM;
  9. use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
  10. use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
  11. use Symfony\Component\Security\Core\User\UserInterface;
  12. use Symfony\Component\Validator\Constraints as Assert;
  13. #[ORM\Entity(repositoryClassUserRepository::class)]
  14. #[ORM\HasLifecycleCallbacks]
  15. #[UniqueEntity('email')]
  16. class User implements UserInterfaceRoleInterfacePasswordAuthenticatedUserInterface
  17. {
  18.     use BaseDateAtTrait;
  19.     // The list of civility
  20.     public const CIVILITY_MISSIS 1;
  21.     public const CIVILITY_MISTER 2;
  22.     // Full list
  23.     public const CIVILITY_LIST = [
  24.         self::CIVILITY_MISSIS => 'app.user.label.missis',
  25.         self::CIVILITY_MISTER => 'app.user.label.mister',
  26.     ];
  27.     
  28.     public const BINDINGS = [
  29.         '[[USER.FULLNAME]]',
  30.         '[[USER.NAME]]',
  31.         '[[USER.EMAIL]]',
  32.         '[[USER.STATUS]]',
  33.         '[[USER.UNIVERSITY]]',
  34.         '[[USER.ADMIN.REVIEW]]',
  35.     ];
  36.     #[ORM\Id]
  37.     #[ORM\GeneratedValue]
  38.     #[ORM\Column(type'integer')]
  39.     private $id;
  40.     #[ORM\Column(type'string'length180uniquetrue)]
  41.     private $username;
  42.     #[ORM\Column(type'json')]
  43.     private $roles = [];
  44.     /**
  45.      * @var string The hashed password
  46.      */
  47.     #[ORM\Column(type'string')]
  48.     private $password;
  49.     #[Assert\NotBlank(groups: ['ResetPassword''Registration''ChangePassword''AccountChangePassword'])]
  50.     #[Assert\Length(min8max4096minMessage'app.user.password.length'groups: ['Profile''ResetPassword''Registration''ChangePassword''AccountChangePassword'])]
  51.     #[Assert\Regex(pattern'/^([^0-9]*|[^A-Z]*|[a-zA-Z0-9]*)$/'message'app.user.password.rule', match: falsegroups: ['Profile''ResetPassword''Registration''ChangePassword''AccountChangePassword'])]
  52.     protected $plainPassword;
  53.     #[ORM\Column(type'smallint'nullabletrue)]
  54.     private $civility;
  55.     #[ORM\Column(type'string'length255)]
  56.     private $firstName;
  57.     #[ORM\Column(type'string'length255)]
  58.     private $lastName;
  59.     #[ORM\Column(type'string'length255uniquetrue)]
  60.     private $email;
  61.     #[ORM\Column(type'string'length255uniquetrue)]
  62.     private $uuid;
  63.     #[ORM\Column(type'datetime'nullabletrue)]
  64.     private $lastLogin;
  65.     #[ORM\OneToMany(targetEntityPersonalResource::class, mappedBy'user'cascade: ['remove'])]
  66.     private $personalResources;
  67.     #[ORM\OneToMany(targetEntityUserProject::class, mappedBy'user'cascade: ['remove'])]
  68.     private $userProjects;
  69.     #[ORM\OneToMany(targetEntityUserWorkroom::class, mappedBy'user'cascade: ['remove'])]
  70.     private $userWorkrooms;
  71.     #[ORM\OneToMany(targetEntityReadingCard::class, mappedBy'user')]
  72.     private $readingCards;
  73.     #[ORM\OneToMany(targetEntityReadingCard::class, mappedBy'lastUser')]
  74.     private $lastUserReadingCards;
  75.     #[ORM\ManyToOne(targetEntityUniversity::class, inversedBy'users')]
  76.     private $university;
  77.     #[ORM\OneToOne(targetEntityUserProfile::class, mappedBy'user'cascade: ['persist''remove'])]
  78.     private $userProfile;
  79.     #[ORM\OneToMany(targetEntityPersonalFolder::class, mappedBy'user'cascade: ['remove'])]
  80.     private $personalFolders;
  81.     #[ORM\OneToOne(targetEntityResetPasswordToken::class, mappedBy'User'cascade: ['persist','remove'])]
  82.     private $resetPasswordToken;
  83.     #[ORM\Column(type'boolean'options: ['default' => 0])]
  84.     private $isActive;
  85.     #[ORM\ManyToOne(targetEntityStatut::class)]
  86.     private $statut;
  87.     #[ORM\OneToMany(targetEntityNotification::class, mappedBy'user'cascade: ['persist''remove'])]
  88.     private $notifications;
  89.     #[ORM\Column(type'string'length500nullabletrue)]
  90.     private $adminReview;
  91.     #[ORM\Column(type'boolean'options: ['default' => 0])]
  92.     private $isDisabled;
  93.     #[ORM\OneToMany(targetEntitySectionRevision::class, mappedBy'user'cascade: ['persist'])]
  94.     private $sectionRevisions;
  95.     #[ORM\OneToMany(targetEntityWorkroomRevision::class, mappedBy'user')]
  96.     private $workroomRevisions;
  97.     #[ORM\OneToMany(targetEntityUserWorkroomArena::class, mappedBy'user'orphanRemovaltruecascade: ['remove'])]
  98.     private $userWorkroomArenas;
  99.     #[ORM\OneToMany(targetEntitySearchQuery::class, mappedBy'user'orphanRemovaltruecascade: ['remove'])]
  100.     private $searchQueries;
  101.     #[ORM\OneToMany(targetEntityHistory::class, mappedBy'user'orphanRemovaltruecascade: ['remove'])]
  102.     private $histories;
  103.     #[ORM\OneToMany(targetEntityHistoryEvent::class, mappedBy'User'orphanRemovaltruecascade: ['remove'])]
  104.     private $historyEvents;
  105.     #[ORM\ManyToOne(inversedBy'users')]
  106.     private ?Organization $organization null;
  107.     #[ORM\Column(type'string'length180nullabletrueuniquetrue)]
  108.     private $zoteroUserId;
  109.     #[ORM\Column(type'string'length255nullabletrueuniquetrue)]
  110.     private $zoteroApiKey;
  111.     /** ClĂ© API Semantic Scholar par utilisateur (https://www.semanticscholar.org/product/api). */
  112.     #[ORM\Column(type'string'length255nullabletruename'semantic_scholar_api_key')]
  113.     private ?string $semanticScholarApiKey null;
  114.     #[ORM\Column(nullabletrue)]
  115.     private ?string $twoFactorCode null;
  116.     #[ORM\Column(type'datetime'nullabletrue)]
  117.     private ?\DateTimeInterface $twoFactorExpiresAt null;
  118.     #[ORM\Column(type'boolean')]
  119.     private bool $isTwoFactorEnabled false;
  120.     /**
  121.      * User constructor.
  122.      */
  123.     public function __construct()
  124.     {
  125.         $this->personalResources = new ArrayCollection();
  126.         $this->userProjects = new ArrayCollection();
  127.         $this->userWorkrooms = new ArrayCollection();
  128.         $this->readingCards = new ArrayCollection();
  129.         $this->personalFolders = new ArrayCollection();
  130.         $this->isActive $this->isDisabled false;
  131.         $this->notifications = new ArrayCollection();
  132.         $this->workroomRevisions = new ArrayCollection();
  133.         $this->userWorkroomArenas = new ArrayCollection();
  134.         $this->searchQueries = new ArrayCollection();
  135.         $this->histories = new ArrayCollection();
  136.         $this->historyEvents = new ArrayCollection();
  137.     }
  138.     /**
  139.      * @return string
  140.      */
  141.     public function __toString()
  142.     {
  143.         return $this->firstName.' '.$this->lastName;
  144.     }
  145.     
  146.     public function getBindings(): array
  147.     {
  148.         return [
  149.             'USER.FULLNAME' => $this->getFullName(),
  150.             'USER.NAME' => strtoupper($this->getLastName()),
  151.             'USER.EMAIL' => $this->getEmail(),
  152.             'USER.STATUS' => $this->getStatut(),
  153.             'USER.UNIVERSITY' => $this->getOrganization(),
  154.             'USER.ORGANIZATION' => $this->getOrganization(),
  155.             'USER.ADMIN.REVIEW' => $this->getAdminReview()
  156.         ];
  157.     }
  158.     public function getFullName(): string
  159.     {
  160.         return $this->firstName.' '.strtoupper($this->lastName);
  161.     }
  162.     public function activate()
  163.     {
  164.         $this->setIsActive(true);
  165.         $this->addRole(RoleInterface::ROLE_USER);
  166.     }
  167.     /**
  168.      * Gets triggered only on insert.
  169.      * Set created date.
  170.      */
  171.     #[ORM\PrePersist]
  172.     public function onPrePersist()
  173.     {
  174.         $this->generateUuid();
  175.         return $this;
  176.     }
  177.     public function getId(): ?int
  178.     {
  179.         return $this->id;
  180.     }
  181.     public function isItAdmin(): bool
  182.     {
  183.         if (!empty(array_intersect(RoleInterface::ROLE_ADMINS$this->roles))) {
  184.             return true;
  185.         }
  186.         return false;
  187.     }
  188.     public function hasRoles(array $roles): bool
  189.     {
  190.         if (!empty(array_intersect($roles$this->roles))) {
  191.             return true;
  192.         }
  193.         return false;
  194.     }
  195.     /**
  196.      * A visual identifier that represents this user.
  197.      *
  198.      * @see UserInterface
  199.      */
  200.     public function getUsername(): string
  201.     {
  202.         return (string) $this->username;
  203.     }
  204.     /**
  205.      * @return $this
  206.      */
  207.     public function setUsername(string $username): self
  208.     {
  209.         $this->username $username;
  210.         return $this;
  211.     }
  212.     /**
  213.      * @see UserInterface
  214.      */
  215.     public function getRoles(): array
  216.     {
  217.         $roles $this->roles;
  218.         // guarantee every user at least has ROLE_USER
  219.         $roles[] = 'ROLE_USER';
  220.         return array_unique($roles);
  221.     }
  222.     public function addRole(string $role): User
  223.     {
  224.         if (!in_array($role$this->roles)) {
  225.             $this->roles[] = $role;
  226.         }
  227.         return $this;
  228.     }
  229.     /**
  230.      * @return $this
  231.      */
  232.     public function setRoles(array $roles): self
  233.     {
  234.         $this->roles $roles;
  235.         return $this;
  236.     }
  237.     public function hasRole(string $role): bool
  238.     {
  239.         return false !== array_search($role$this->getRoles());
  240.     }
  241.     /**
  242.      * @see UserInterface
  243.      */
  244.     public function getPassword(): string
  245.     {
  246.         return (string) $this->password;
  247.     }
  248.     /**
  249.      * @return $this
  250.      */
  251.     public function setPassword(string $password): self
  252.     {
  253.         $this->password $password;
  254.         return $this;
  255.     }
  256.     /**
  257.      * Returning a salt is only needed, if you are not using a modern
  258.      * hashing algorithm (e.g. bcrypt or sodium) in your security.yaml.
  259.      *
  260.      * @see UserInterface
  261.      */
  262.     public function getSalt(): ?string
  263.     {
  264.         return null;
  265.     }
  266.     /**
  267.      * @see UserInterface
  268.      */
  269.     public function eraseCredentials()
  270.     {
  271.         $this->plainPassword null;
  272.     }
  273.     public function getCivility(): ?int
  274.     {
  275.         return $this->civility;
  276.     }
  277.     /**
  278.      * @return $this
  279.      */
  280.     public function setCivility(?int $civility): self
  281.     {
  282.         $this->civility $civility;
  283.         return $this;
  284.     }
  285.     /**
  286.      * Provide the name of civility bases on key value.
  287.      */
  288.     public function getCivilityName(): string
  289.     {
  290.         return self::CIVILITY_LIST[$this->civility] ?? '';
  291.     }
  292.     public function getFirstName(): ?string
  293.     {
  294.         return $this->firstName;
  295.     }
  296.     /**
  297.      * @return $this
  298.      */
  299.     public function setFirstName(string $firstName): self
  300.     {
  301.         $this->firstName $firstName;
  302.         return $this;
  303.     }
  304.     public function getLastName(): ?string
  305.     {
  306.         return $this->lastName;
  307.     }
  308.     /**
  309.      * @return $this
  310.      */
  311.     public function setLastName(string $lastName): self
  312.     {
  313.         $this->lastName $lastName;
  314.         return $this;
  315.     }
  316.     public function getEmail(): ?string
  317.     {
  318.         return $this->email;
  319.     }
  320.     /**
  321.      * @return $this
  322.      */
  323.     public function setEmail(string $email): self
  324.     {
  325.         $this->email $email;
  326.         return $this;
  327.     }
  328.     public function getUuid(): ?string
  329.     {
  330.         return $this->uuid;
  331.     }
  332.     /**
  333.      * @return $this
  334.      */
  335.     public function setUuid(string $uuid): self
  336.     {
  337.         $this->uuid $uuid;
  338.         return $this;
  339.     }
  340.     /**
  341.      * @return $this
  342.      *
  343.      * @throws \Exception
  344.      */
  345.     public function generateUuid(): self
  346.     {
  347.         $this->uuid bin2hex(random_bytes(16));
  348.         return $this;
  349.     }
  350.     public function getLastLogin(): ?\DateTimeInterface
  351.     {
  352.         return $this->lastLogin;
  353.     }
  354.     /**
  355.      * @return $this
  356.      */
  357.     public function setLastLogin(?\DateTimeInterface $lastLogin): self
  358.     {
  359.         $this->lastLogin $lastLogin;
  360.         return $this;
  361.     }
  362.     /**
  363.      * @return Collection|PersonalResource[]
  364.      */
  365.     public function getPersonalResources(): Collection
  366.     {
  367.         return $this->personalResources;
  368.     }
  369.     /**
  370.      * @return $this
  371.      */
  372.     public function addPersonalResource(PersonalResource $personalResource): self
  373.     {
  374.         if (!$this->personalResources->contains($personalResource)) {
  375.             $this->personalResources[] = $personalResource;
  376.             $personalResource->setUser($this);
  377.         }
  378.         return $this;
  379.     }
  380.     /**
  381.      * @return $this
  382.      */
  383.     public function removePersonalResource(PersonalResource $personalResource): self
  384.     {
  385.         if ($this->personalResources->removeElement($personalResource)) {
  386.             // set the owning side to null (unless already changed)
  387.             if ($personalResource->getUser() === $this) {
  388.                 $personalResource->setUser(null);
  389.             }
  390.         }
  391.         return $this;
  392.     }
  393.     /**
  394.      * @return Collection|UserProject[]
  395.      */
  396.     public function getUserProjects(): Collection
  397.     {
  398.         return $this->userProjects;
  399.     }
  400.     public function addUserProject(UserProject $userProject): self
  401.     {
  402.         if (!$this->userProjects->contains($userProject)) {
  403.             $this->userProjects[] = $userProject;
  404.             $userProject->setUser($this);
  405.         }
  406.         return $this;
  407.     }
  408.     public function removeUserProject(UserProject $userProject): self
  409.     {
  410.         if ($this->userProjects->removeElement($userProject)) {
  411.             // set the owning side to null (unless already changed)
  412.             if ($userProject->getUser() === $this) {
  413.                 $userProject->setUser(null);
  414.             }
  415.         }
  416.         return $this;
  417.     }
  418.     /**
  419.      * @return Collection|UserWorkroom[]
  420.      */
  421.     public function getUserWorkrooms(): Collection
  422.     {
  423.         return $this->userWorkrooms;
  424.     }
  425.     public function addUserWorkroom(UserWorkroom $userWorkroom): self
  426.     {
  427.         if (!$this->userWorkrooms->contains($userWorkroom)) {
  428.             $this->userWorkrooms[] = $userWorkroom;
  429.             $userWorkroom->setUser($this);
  430.         }
  431.         return $this;
  432.     }
  433.     public function removeUserWorkroom(UserWorkroom $userWorkroom): self
  434.     {
  435.         if ($this->userWorkrooms->removeElement($userWorkroom)) {
  436.             // set the owning side to null (unless already changed)
  437.             if ($userWorkroom->getUser() === $this) {
  438.                 $userWorkroom->setUser(null);
  439.             }
  440.         }
  441.         return $this;
  442.     }
  443.     /**
  444.      * @return Collection|ReadingCard[]
  445.      */
  446.     public function getReadingCards(): Collection
  447.     {
  448.         return $this->readingCards;
  449.     }
  450.     public function addReadingCard(ReadingCard $readingCard): self
  451.     {
  452.         if (!$this->readingCards->contains($readingCard)) {
  453.             $this->readingCards[] = $readingCard;
  454.             $readingCard->setUser($this);
  455.         }
  456.         return $this;
  457.     }
  458.     public function removeReadingCard(ReadingCard $readingCard): self
  459.     {
  460.         if ($this->readingCards->removeElement($readingCard)) {
  461.             // set the owning side to null (unless already changed)
  462.             if ($readingCard->getUser() === $this) {
  463.                 $readingCard->setUser(null);
  464.             }
  465.         }
  466.         return $this;
  467.     }
  468.     public function getUniversity(): ?University
  469.     {
  470.         return $this->university;
  471.     }
  472.     public function setUniversity(?University $university): self
  473.     {
  474.         $this->university $university;
  475.         return $this;
  476.     }
  477.     public function getUserProfile(): ?UserProfile
  478.     {
  479.         return $this->userProfile;
  480.     }
  481.     public function setUserProfile(UserProfile $userProfile): self
  482.     {
  483.         // set the owning side of the relation if necessary
  484.         if ($userProfile->getUser() !== $this) {
  485.             $userProfile->setUser($this);
  486.         }
  487.         $this->userProfile $userProfile;
  488.         return $this;
  489.     }
  490.     /**
  491.      * @return Collection|PersonalFolder[]
  492.      */
  493.     public function getPersonalFolders(): Collection
  494.     {
  495.         return $this->personalFolders;
  496.     }
  497.     public function addPersonalFolder(PersonalFolder $personalFolder): self
  498.     {
  499.         if (!$this->personalFolders->contains($personalFolder)) {
  500.             $this->personalFolders[] = $personalFolder;
  501.             $personalFolder->setUser($this);
  502.         }
  503.         return $this;
  504.     }
  505.     public function removePersonalFolder(PersonalFolder $personalFolder): self
  506.     {
  507.         if ($this->personalFolders->removeElement($personalFolder)) {
  508.             // set the owning side to null (unless already changed)
  509.             if ($personalFolder->getUser() === $this) {
  510.                 $personalFolder->setUser(null);
  511.             }
  512.         }
  513.         return $this;
  514.     }
  515.     public function getResetPasswordToken(): ?ResetPasswordToken
  516.     {
  517.         return $this->resetPasswordToken;
  518.     }
  519.     public function setResetPasswordToken(ResetPasswordToken $resetPasswordToken): self
  520.     {
  521.         // set the owning side of the relation if necessary
  522.         if ($resetPasswordToken->getUser() !== $this) {
  523.             $resetPasswordToken->setUser($this);
  524.         }
  525.         $this->resetPasswordToken $resetPasswordToken;
  526.         return $this;
  527.     }
  528.     public function isActive(): ?bool
  529.     {
  530.         return $this->isActive;
  531.     }
  532.     public function setIsActive(bool $isActive): self
  533.     {
  534.         $this->isActive $isActive;
  535.         return $this;
  536.     }
  537.     public function getStatut(): ?Statut
  538.     {
  539.         return $this->statut;
  540.     }
  541.     public function setStatut(?Statut $statut): self
  542.     {
  543.         $this->statut $statut;
  544.         return $this;
  545.     }
  546.     /**
  547.      * @return Collection|Notification[]
  548.      */
  549.     public function getNotifications(): Collection
  550.     {
  551.         return $this->notifications;
  552.     }
  553.     public function addNotification(Notification $notification): self
  554.     {
  555.         if (!$this->notifications->contains($notification)) {
  556.             $this->notifications[] = $notification;
  557.             $notification->setUser($this);
  558.         }
  559.         return $this;
  560.     }
  561.     public function removeNotification(Notification $notification): self
  562.     {
  563.         if ($this->notifications->removeElement($notification)) {
  564.             // set the owning side to null (unless already changed)
  565.             if ($notification->getUser() === $this) {
  566.                 $notification->setUser(null);
  567.             }
  568.         }
  569.         return $this;
  570.     }
  571.     public function getAdminReview(): ?string
  572.     {
  573.         return $this->adminReview;
  574.     }
  575.     public function setAdminReview(?string $adminReview): self
  576.     {
  577.         $this->adminReview $adminReview;
  578.         return $this;
  579.     }
  580.     public function getIsDisabled(): ?bool
  581.     {
  582.         return $this->isDisabled;
  583.     }
  584.     public function setIsDisabled(bool $isDisabled): self
  585.     {
  586.         $this->isDisabled $isDisabled;
  587.         return $this;
  588.     }
  589.     /**
  590.      * @return Collection|SectionRevision[]
  591.      */
  592.     public function getSectionRevisions(): Collection
  593.     {
  594.         return $this->sectionRevisions;
  595.     }
  596.     /**
  597.      * @return $this
  598.      */
  599.     public function addSectionRevision(SectionRevision $sectionRevision): self
  600.     {
  601.         if (!$this->sectionRevisions->contains($sectionRevision)) {
  602.             $this->sectionRevisions[] = $sectionRevision;
  603.             $sectionRevision->setUser($this);
  604.         }
  605.         return $this;
  606.     }
  607.     /**
  608.      * @return $this
  609.      */
  610.     public function removeSectionRevision(SectionRevision $sectionRevision): self
  611.     {
  612.         if ($this->sectionRevisions->removeElement($sectionRevision)) {
  613.             // set the owning side to null (unless already changed)
  614.             if ($sectionRevision->getUser() === $this) {
  615.                 $sectionRevision->setUser(null);
  616.             }
  617.         }
  618.         return $this;
  619.     }
  620.     /**
  621.      * @return Collection|WorkroomRevision[]
  622.      */
  623.     public function getWorkroomRevisions(): Collection
  624.     {
  625.         return $this->workroomRevisions;
  626.     }
  627.     public function addWorkroomRevision(WorkroomRevision $workroomRevision): self
  628.     {
  629.         if (!$this->workroomRevisions->contains($workroomRevision)) {
  630.             $this->workroomRevisions[] = $workroomRevision;
  631.             $workroomRevision->setUser($this);
  632.         }
  633.         return $this;
  634.     }
  635.     public function removeWorkroomRevision(WorkroomRevision $workroomRevision): self
  636.     {
  637.         if ($this->workroomRevisions->removeElement($workroomRevision)) {
  638.             // set the owning side to null (unless already changed)
  639.             if ($workroomRevision->getUser() === $this) {
  640.                 $workroomRevision->setUser(null);
  641.             }
  642.         }
  643.         return $this;
  644.     }
  645.     /**
  646.      * @return Collection|UserWorkroomArena[]
  647.      */
  648.     public function getUserWorkroomArenas(): Collection
  649.     {
  650.         return $this->userWorkroomArenas;
  651.     }
  652.     public function addUserWorkroomArena(UserWorkroomArena $userWorkroomArena): self
  653.     {
  654.         if (!$this->userWorkroomArenas->contains($userWorkroomArena)) {
  655.             $this->userWorkroomArenas[] = $userWorkroomArena;
  656.             $userWorkroomArena->setUser($this);
  657.         }
  658.         return $this;
  659.     }
  660.     public function removeUserWorkroomArena(UserWorkroomArena $userWorkroomArena): self
  661.     {
  662.         if ($this->userWorkroomArenas->removeElement($userWorkroomArena)) {
  663.             // set the owning side to null (unless already changed)
  664.             if ($userWorkroomArena->getUser() === $this) {
  665.                 $userWorkroomArena->setUser(null);
  666.             }
  667.         }
  668.         return $this;
  669.     }
  670.     /**
  671.      * @return Collection|SearchQuery[]
  672.      */
  673.     public function getSearchQueries(): Collection
  674.     {
  675.         return $this->searchQueries;
  676.     }
  677.     public function addSearchQuery(SearchQuery $searchQuery): self
  678.     {
  679.         if (!$this->searchQueries->contains($searchQuery)) {
  680.             $this->searchQueries[] = $searchQuery;
  681.             $searchQuery->setUser($this);
  682.         }
  683.         return $this;
  684.     }
  685.     public function removeSearchQuery(SearchQuery $searchQuery): self
  686.     {
  687.         if ($this->searchQueries->removeElement($searchQuery)) {
  688.             // set the owning side to null (unless already changed)
  689.             if ($searchQuery->getUser() === $this) {
  690.                 $searchQuery->setUser(null);
  691.             }
  692.         }
  693.         return $this;
  694.     }
  695.     /**
  696.      * @return Collection|History[]
  697.      */
  698.     public function getHistories(): Collection
  699.     {
  700.         return $this->histories;
  701.     }
  702.     public function addHistory(History $history): self
  703.     {
  704.         if (!$this->histories->contains($history)) {
  705.             $this->histories[] = $history;
  706.             $history->setUser($this);
  707.         }
  708.         return $this;
  709.     }
  710.     public function removeHistory(History $history): self
  711.     {
  712.         if ($this->histories->removeElement($history)) {
  713.             // set the owning side to null (unless already changed)
  714.             if ($history->getUser() === $this) {
  715.                 $history->setUser(null);
  716.             }
  717.         }
  718.         return $this;
  719.     }
  720.     /**
  721.      * @return Collection|HistoryEvent[]
  722.      */
  723.     public function getHistoryEvents(): Collection
  724.     {
  725.         return $this->historyEvents;
  726.     }
  727.     public function addHistoryEvent(HistoryEvent $historyEvent): self
  728.     {
  729.         if (!$this->historyEvents->contains($historyEvent)) {
  730.             $this->historyEvents[] = $historyEvent;
  731.             $historyEvent->setUser($this);
  732.         }
  733.         return $this;
  734.     }
  735.     public function removeHistoryEvent(HistoryEvent $historyEvent): self
  736.     {
  737.         if ($this->historyEvents->removeElement($historyEvent)) {
  738.             // set the owning side to null (unless already changed)
  739.             if ($historyEvent->getUser() === $this) {
  740.                 $historyEvent->setUser(null);
  741.             }
  742.         }
  743.         return $this;
  744.     }
  745.     public function getUserIdentifier(): string
  746.     {
  747.         return $this->getUsername();
  748.     }
  749.     public function getOrganization(): ?Organization
  750.     {
  751.         return $this->organization;
  752.     }
  753.     public function setOrganization(?Organization $organization): static
  754.     {
  755.         $this->organization $organization;
  756.         return $this;
  757.     }
  758.     public function setZoteroApiKey(?string $zoteroApiKey): self
  759.     {
  760.         $this->zoteroApiKey $zoteroApiKey;
  761.         return $this;
  762.     }
  763.     public function getZoteroApiKey(): ?string
  764.     {
  765.         return $this->zoteroApiKey;
  766.     }
  767.     public function setZoteroUserId(?string $zoteroUserId): self
  768.     {
  769.         $this->zoteroUserId $zoteroUserId;
  770.         return $this;
  771.     }
  772.     public function getEmailDomain(): ?string
  773.     {
  774.         if (=== preg_match('/.*\@(.+)$/i'$this->email$matches) && count($matches) > 1) {
  775.             return $matches[1];
  776.         }
  777.         return null;
  778.     }
  779.     public function getZoteroUserId(): ?string
  780.     {
  781.         return $this->zoteroUserId;
  782.     }
  783.     public function getSemanticScholarApiKey(): ?string
  784.     {
  785.         return $this->semanticScholarApiKey;
  786.     }
  787.     public function setSemanticScholarApiKey(?string $semanticScholarApiKey): self
  788.     {
  789.         $this->semanticScholarApiKey $semanticScholarApiKey;
  790.         return $this;
  791.     }
  792.     public function isTwoFactorEnabled(): bool
  793.     {
  794.         return $this->isTwoFactorEnabled;
  795.     }
  796.     public function setIsTwoFactorEnabled(bool $enabled): static
  797.     {
  798.         $this->isTwoFactorEnabled $enabled;
  799.         return $this;
  800.     }
  801.     public function getTwoFactorCode(): ?string
  802.     {
  803.         return $this->twoFactorCode;
  804.     }
  805.     public function setTwoFactorCode(?string $code): static
  806.     {
  807.         $this->twoFactorCode $code;
  808.         return $this;
  809.     }
  810.     public function getTwoFactorExpiresAt(): ?\DateTimeInterface
  811.     {
  812.         return $this->twoFactorExpiresAt;
  813.     }
  814.     public function setTwoFactorExpiresAt(?\DateTimeInterface $expiresAt): static
  815.     {
  816.         $this->twoFactorExpiresAt $expiresAt;
  817.         return $this;
  818.     }
  819. }