src/Sylius/Component/User/Model/User.php line 21

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Sylius package.
  4.  *
  5.  * (c) Paweł Jędrzejewski
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. declare(strict_types=1);
  11. namespace Sylius\Component\User\Model;
  12. use Doctrine\Common\Collections\ArrayCollection;
  13. use Doctrine\Common\Collections\Collection;
  14. use Sylius\Component\Resource\Model\TimestampableTrait;
  15. use Sylius\Component\Resource\Model\ToggleableTrait;
  16. class User implements UserInterface
  17. {
  18.     use TimestampableTraitToggleableTrait;
  19.     /** @var mixed */
  20.     protected $id;
  21.     /** @var string|null */
  22.     protected $username;
  23.     /**
  24.      * Normalized representation of a username.
  25.      *
  26.      * @var string|null
  27.      */
  28.     protected $usernameCanonical;
  29.     /**
  30.      * Random data that is used as an additional input to a function that hashes a password.
  31.      *
  32.      * @var string
  33.      */
  34.     protected $salt;
  35.     /**
  36.      * Encrypted password. Must be persisted.
  37.      *
  38.      * @var string|null
  39.      */
  40.     protected $password;
  41.     /**
  42.      * Password before encryption. Used for model validation. Must not be persisted.
  43.      *
  44.      * @var string|null
  45.      */
  46.     protected $plainPassword;
  47.     /** @var \DateTimeInterface|null */
  48.     protected $lastLogin;
  49.     /**
  50.      * Random string sent to the user email address in order to verify it
  51.      *
  52.      * @var string|null
  53.      */
  54.     protected $emailVerificationToken;
  55.     /**
  56.      * Random string sent to the user email address in order to verify the password resetting request
  57.      *
  58.      * @var string|null
  59.      */
  60.     protected $passwordResetToken;
  61.     /** @var \DateTimeInterface|null */
  62.     protected $passwordRequestedAt;
  63.     /** @var \DateTimeInterface|null */
  64.     protected $verifiedAt;
  65.     /** @var bool */
  66.     protected $locked false;
  67.     /** @var \DateTimeInterface|null */
  68.     protected $expiresAt;
  69.     /** @var \DateTimeInterface|null */
  70.     protected $credentialsExpireAt;
  71.     /**
  72.      * We need at least one role to be able to authenticate
  73.      *
  74.      * @var array
  75.      */
  76.     protected $roles = [UserInterface::DEFAULT_ROLE];
  77.     /** @var Collection|UserOAuth[] */
  78.     protected $oauthAccounts;
  79.     /** @var string|null */
  80.     protected $email;
  81.     /** @var string|null */
  82.     protected $emailCanonical;
  83.     /** @var string|null */
  84.     protected $encoderName;
  85.     public function __construct()
  86.     {
  87.         $this->salt base_convert(bin2hex(random_bytes(20)), 1636);
  88.         $this->oauthAccounts = new ArrayCollection();
  89.         $this->createdAt = new \DateTime();
  90.         // Set here to overwrite default value from trait
  91.         $this->enabled false;
  92.     }
  93.     public function __toString(): string
  94.     {
  95.         return (string) $this->getUsername();
  96.     }
  97.     /**
  98.      * {@inheritdoc}
  99.      */
  100.     public function getId()
  101.     {
  102.         return $this->id;
  103.     }
  104.     /**
  105.      * {@inheritdoc}
  106.      */
  107.     public function getEmail(): ?string
  108.     {
  109.         return $this->email;
  110.     }
  111.     /**
  112.      * {@inheritdoc}
  113.      */
  114.     public function setEmail(?string $email): void
  115.     {
  116.         $this->email $email;
  117.     }
  118.     /**
  119.      * {@inheritdoc}
  120.      */
  121.     public function getEmailCanonical(): ?string
  122.     {
  123.         return $this->emailCanonical;
  124.     }
  125.     /**
  126.      * {@inheritdoc}
  127.      */
  128.     public function setEmailCanonical(?string $emailCanonical): void
  129.     {
  130.         $this->emailCanonical $emailCanonical;
  131.     }
  132.     /**
  133.      * {@inheritdoc}
  134.      */
  135.     public function getUsername(): ?string
  136.     {
  137.         return $this->username;
  138.     }
  139.     /**
  140.      * {@inheritdoc}
  141.      */
  142.     public function setUsername(?string $username): void
  143.     {
  144.         $this->username $username;
  145.     }
  146.     /**
  147.      * {@inheritdoc}
  148.      */
  149.     public function getUsernameCanonical(): ?string
  150.     {
  151.         return $this->usernameCanonical;
  152.     }
  153.     /**
  154.      * {@inheritdoc}
  155.      */
  156.     public function setUsernameCanonical(?string $usernameCanonical): void
  157.     {
  158.         $this->usernameCanonical $usernameCanonical;
  159.     }
  160.     /**
  161.      * {@inheritdoc}
  162.      */
  163.     public function getSalt(): string
  164.     {
  165.         return $this->salt;
  166.     }
  167.     /**
  168.      * {@inheritdoc}
  169.      */
  170.     public function getPlainPassword(): ?string
  171.     {
  172.         return $this->plainPassword;
  173.     }
  174.     /**
  175.      * {@inheritdoc}
  176.      */
  177.     public function setPlainPassword(?string $password): void
  178.     {
  179.         $this->plainPassword $password;
  180.     }
  181.     /**
  182.      * {@inheritdoc}
  183.      */
  184.     public function getPassword(): ?string
  185.     {
  186.         return $this->password;
  187.     }
  188.     /**
  189.      * {@inheritdoc}
  190.      */
  191.     public function setPassword(?string $password): void
  192.     {
  193.         $this->password $password;
  194.     }
  195.     /**
  196.      * {@inheritdoc}
  197.      */
  198.     public function getExpiresAt(): ?\DateTimeInterface
  199.     {
  200.         return $this->expiresAt;
  201.     }
  202.     /**
  203.      * {@inheritdoc}
  204.      */
  205.     public function setExpiresAt(?\DateTimeInterface $date): void
  206.     {
  207.         $this->expiresAt $date;
  208.     }
  209.     /**
  210.      * {@inheritdoc}
  211.      */
  212.     public function getCredentialsExpireAt(): ?\DateTimeInterface
  213.     {
  214.         return $this->credentialsExpireAt;
  215.     }
  216.     /**
  217.      * {@inheritdoc}
  218.      */
  219.     public function setCredentialsExpireAt(?\DateTimeInterface $date): void
  220.     {
  221.         $this->credentialsExpireAt $date;
  222.     }
  223.     /**
  224.      * {@inheritdoc}
  225.      */
  226.     public function getLastLogin(): ?\DateTimeInterface
  227.     {
  228.         return $this->lastLogin;
  229.     }
  230.     /**
  231.      * {@inheritdoc}
  232.      */
  233.     public function setLastLogin(?\DateTimeInterface $time): void
  234.     {
  235.         $this->lastLogin $time;
  236.     }
  237.     /**
  238.      * {@inheritdoc}
  239.      */
  240.     public function getEmailVerificationToken(): ?string
  241.     {
  242.         return $this->emailVerificationToken;
  243.     }
  244.     /**
  245.      * {@inheritdoc}
  246.      */
  247.     public function setEmailVerificationToken(?string $verificationToken): void
  248.     {
  249.         $this->emailVerificationToken $verificationToken;
  250.     }
  251.     /**
  252.      * {@inheritdoc}
  253.      */
  254.     public function getPasswordResetToken(): ?string
  255.     {
  256.         return $this->passwordResetToken;
  257.     }
  258.     /**
  259.      * {@inheritdoc}
  260.      */
  261.     public function setPasswordResetToken(?string $passwordResetToken): void
  262.     {
  263.         $this->passwordResetToken $passwordResetToken;
  264.     }
  265.     /**
  266.      * {@inheritdoc}
  267.      */
  268.     public function isCredentialsNonExpired(): bool
  269.     {
  270.         return !$this->hasExpired($this->credentialsExpireAt);
  271.     }
  272.     /**
  273.      * {@inheritdoc}
  274.      */
  275.     public function isAccountNonExpired(): bool
  276.     {
  277.         return !$this->hasExpired($this->expiresAt);
  278.     }
  279.     /**
  280.      * {@inheritdoc}
  281.      */
  282.     public function setLocked(bool $locked): void
  283.     {
  284.         $this->locked $locked;
  285.     }
  286.     /**
  287.      * {@inheritdoc}
  288.      */
  289.     public function isAccountNonLocked(): bool
  290.     {
  291.         return !$this->locked;
  292.     }
  293.     /**
  294.      * {@inheritdoc}
  295.      */
  296.     public function hasRole(string $role): bool
  297.     {
  298.         return in_array(strtoupper($role), $this->getRoles(), true);
  299.     }
  300.     /**
  301.      * {@inheritdoc}
  302.      */
  303.     public function addRole(string $role): void
  304.     {
  305.         $role strtoupper($role);
  306.         if (!in_array($role$this->rolestrue)) {
  307.             $this->roles[] = $role;
  308.         }
  309.     }
  310.     /**
  311.      * {@inheritdoc}
  312.      */
  313.     public function removeRole(string $role): void
  314.     {
  315.         if (false !== $key array_search(strtoupper($role), $this->rolestrue)) {
  316.             unset($this->roles[$key]);
  317.             $this->roles array_values($this->roles);
  318.         }
  319.     }
  320.     /**
  321.      * {@inheritdoc}
  322.      */
  323.     public function getRoles(): array
  324.     {
  325.         return $this->roles;
  326.     }
  327.     /**
  328.      * {@inheritdoc}
  329.      */
  330.     public function isPasswordRequestNonExpired(\DateInterval $ttl): bool
  331.     {
  332.         if (null === $this->passwordRequestedAt) {
  333.             return false;
  334.         }
  335.         $threshold = new \DateTime();
  336.         $threshold->sub($ttl);
  337.         return $threshold <= $this->passwordRequestedAt;
  338.     }
  339.     /**
  340.      * {@inheritdoc}
  341.      */
  342.     public function getPasswordRequestedAt(): ?\DateTimeInterface
  343.     {
  344.         return $this->passwordRequestedAt;
  345.     }
  346.     /**
  347.      * {@inheritdoc}
  348.      */
  349.     public function setPasswordRequestedAt(?\DateTimeInterface $date): void
  350.     {
  351.         $this->passwordRequestedAt $date;
  352.     }
  353.     /**
  354.      * {@inheritdoc}
  355.      */
  356.     public function isVerified(): bool
  357.     {
  358.         return null !== $this->verifiedAt;
  359.     }
  360.     /**
  361.      * {@inheritdoc}
  362.      */
  363.     public function getVerifiedAt(): ?\DateTimeInterface
  364.     {
  365.         return $this->verifiedAt;
  366.     }
  367.     /**
  368.      * {@inheritdoc}
  369.      */
  370.     public function setVerifiedAt(?\DateTimeInterface $verifiedAt): void
  371.     {
  372.         $this->verifiedAt $verifiedAt;
  373.     }
  374.     /**
  375.      * {@inheritdoc}
  376.      */
  377.     public function eraseCredentials(): void
  378.     {
  379.         $this->plainPassword null;
  380.     }
  381.     /**
  382.      * {@inheritdoc}
  383.      */
  384.     public function getOAuthAccounts(): Collection
  385.     {
  386.         return $this->oauthAccounts;
  387.     }
  388.     /**
  389.      * {@inheritdoc}
  390.      */
  391.     public function getOAuthAccount(string $provider): ?UserOAuthInterface
  392.     {
  393.         if ($this->oauthAccounts->isEmpty()) {
  394.             return null;
  395.         }
  396.         $filtered $this->oauthAccounts->filter(function (UserOAuthInterface $oauth) use ($provider): bool {
  397.             return $provider === $oauth->getProvider();
  398.         });
  399.         if ($filtered->isEmpty()) {
  400.             return null;
  401.         }
  402.         return $filtered->current();
  403.     }
  404.     /**
  405.      * {@inheritdoc}
  406.      */
  407.     public function addOAuthAccount(UserOAuthInterface $oauth): void
  408.     {
  409.         if (!$this->oauthAccounts->contains($oauth)) {
  410.             $this->oauthAccounts->add($oauth);
  411.             $oauth->setUser($this);
  412.         }
  413.     }
  414.     /**
  415.      * {@inheritdoc}
  416.      */
  417.     public function getEncoderName(): ?string
  418.     {
  419.         return $this->encoderName;
  420.     }
  421.     /**
  422.      * {@inheritdoc}
  423.      */
  424.     public function setEncoderName(?string $encoderName): void
  425.     {
  426.         $this->encoderName $encoderName;
  427.     }
  428.     /**
  429.      * The serialized data have to contain the fields used by the equals method and the username.
  430.      */
  431.     public function serialize(): string
  432.     {
  433.         return serialize([
  434.             $this->password,
  435.             $this->salt,
  436.             $this->usernameCanonical,
  437.             $this->username,
  438.             $this->locked,
  439.             $this->enabled,
  440.             $this->id,
  441.             $this->encoderName,
  442.         ]);
  443.     }
  444.     /**
  445.      * @param string $serialized
  446.      */
  447.     public function unserialize($serialized): void
  448.     {
  449.         $data unserialize($serialized);
  450.         // add a few extra elements in the array to ensure that we have enough keys when unserializing
  451.         // older data which does not include all properties.
  452.         $data array_merge($dataarray_fill(02null));
  453.         [
  454.             $this->password,
  455.             $this->salt,
  456.             $this->usernameCanonical,
  457.             $this->username,
  458.             $this->locked,
  459.             $this->enabled,
  460.             $this->id,
  461.             $this->encoderName,
  462.         ] = $data;
  463.     }
  464.     protected function hasExpired(?\DateTimeInterface $date): bool
  465.     {
  466.         return null !== $date && new \DateTime() >= $date;
  467.     }
  468. }