<?php
namespace App\Entity;
use App\DataProcessor\UserDataProcessor;
use App\DataProvider\UserByEmailProvider;
use App\DataProvider\UserDataGetProvider;
use App\Entity\Interface\NotificationInterface;
use App\Entity\Traits\TimestampTrait;
use App\Repository\UserRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
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;
use Symfony\Component\Serializer\Annotation\Ignore;
use Symfony\Component\Serializer\Annotation\SerializedName;
use Symfony\Component\Validator\Constraints as Assert;
use ApiPlatform\Metadata as Api;
#[ORM\InheritanceType('JOINED')]
#[ORM\DiscriminatorColumn(name: 'discr', type: 'string')]
#[ORM\DiscriminatorMap(['user' => 'User', 'client' => 'App\Entity\Client'])]
#[ORM\Entity(repositoryClass: UserRepository::class)]
#[UniqueEntity(fields: ['email'], message: 'There is already an account with this email')]
#[Api\ApiResource(
normalizationContext: ['groups' => ['user.read', 'timestamp.read']],
denormalizationContext: ['groups' => ['user.write']],
security: "is_granted('IS_AUTHENTICATED_FULLY')",
)]
#[Api\Get(provider: UserDataGetProvider::class)]
#[Api\Get(
uriTemplate: '/users/by-email/{email}',
uriVariables: ['email'],
provider: UserByEmailProvider::class
)]
#[Api\Post(processor: UserDataProcessor::class)]
#[Api\Patch]
#[Api\GetCollection(security: 'is_granted("'.RoleManagement::REGULAR_ADMIN.'")')]
class User implements UserInterface, PasswordAuthenticatedUserInterface, NotificationInterface
{
use TimestampTrait;
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
#[Groups(["user.read"])]
protected $id;
#[ORM\Column(type: 'string', length: 180, unique: true)]
#[Groups(["user.read", "user.write"])]
#[Assert\NotBlank]
private $email;
#[ORM\Column(type: 'json')]
#[Ignore()]
private $roles = [];
#[ORM\Column(type: 'string')]
#[Ignore()]
private $password;
#[ORM\Column(type: 'boolean')]
#[Groups(["user.read", "user.write"])]
private $isVerified = false;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
#[Groups(["user.read", "user.write"])]
private $firstName;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
#[Groups(["user.read", "user.write"])]
private $lastName;
#[ORM\Column(type: 'boolean')]
#[Groups(["user.read", "user.write"])]
private $isActive = true;
#[ORM\Column(type: 'boolean')]
#[Groups(["user.read", "user.write"])]
private $privacyPolicy = true;
#[ORM\Column(type: 'boolean')]
#[Groups(["user.read", "user.write"])]
private $termsConditions = true;
#[ORM\Column(type: 'boolean')]
#[Groups(["user.read", "user.write"])]
private $newsletterSubscription = false;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
#[Groups(["user.read", "user.write"])]
private $phoneCountryCode;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
#[Groups(["user.read", "user.write"])]
private $phoneNo;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
#[Groups(["user.read", "user.write"])]
private $profileImage;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
#[Groups(["user.read", "user.write"])]
private $jobPosition;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
#[Ignore()]
private $userHeaderColor;
#[ORM\Column(type: 'boolean', nullable: true)]
#[Ignore()]
private $userSideNavDark = false;
#[ORM\Column(type: 'boolean', nullable: true)]
#[Ignore()]
private $userFoldedMenu = false;
#[ORM\Column(type: 'json', nullable: true)]
#[Ignore()]
private $routePermissions = [];
#[ORM\OneToMany(mappedBy: 'notificationUser', targetEntity: Notification::class, cascade: ['persist'])]
#[ORM\JoinColumn(onDelete: 'SET NULL')]
#[Ignore()]
private $notifications;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
#[Groups(["user.read", "user.write"])]
private $locale = 'lt';
#[ORM\Column(type: 'text', nullable: true)]
#[Groups(["user.read", "user.write"])]
private $comment;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
#[Groups(["user.read", "user.write"])]
private $address;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
#[Groups(["user.read", "user.write"])]
private $country;
#[ORM\Column(type: 'datetime', nullable: true)]
#[Groups(["user.read", "user.write"])]
private $dateOfBirth;
#[Groups(["user.write"])]
#[SerializedName("password")]
#[Assert\Regex('/^(?=.*?[0-9])(?=.*[A-Z]).{6,}$/')]
private $plainPassword;
#[Groups(["user.read"])]
private bool $isMe = false;
# TODO get from db
private $transactions = [];
#[ORM\OneToMany(mappedBy: 'createdByUser', targetEntity: PurchaseMessage::class)]
private $purchaseMessages;
#[ORM\ManyToMany(targetEntity: RoleManagement::class, inversedBy: 'users')]
private $userRole;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
#[Groups(["user.read", "user.write"])]
private $zipCode;
#[ORM\Column(nullable: true)]
private ?bool $isLocked = false;
#[ORM\OneToMany(mappedBy: 'user', targetEntity: UserCar::class, cascade: ['persist'])]
private Collection $userCars;
#[ORM\Column(length: 255, nullable: true)]
private ?string $verificationCode = null;
#[ORM\OneToMany(mappedBy: 'user', targetEntity: LaborAct::class)]
private Collection $laborActs;
public function toArray(): array
{
return [
'id' => $this->getId(),
'email' => $this->getEmail(),
'firstName' => $this->getFirstName(),
'lastName' => $this->getLastName(),
'isActive' => $this->getIsActive(),
'privacyPolicy' => $this->getPrivacyPolicy(),
'termsConditions' => $this->getTermsConditions(),
'newsletterSubscription' => $this->getNewsletterSubscription(),
'phoneCountryCode' => $this->getPhoneCountryCode(),
'phoneNo' => $this->getPhoneNo(),
'profileImage' => $this->getProfileImage(),
'jobPosition' => $this->getJobPosition(),
'userHeaderColor' => $this->getUserHeaderColor(),
'userSideNavDark' => $this->getUserSideNavDark(),
'userFoldedMenu' => $this->getUserFoldedMenu(),
'routePermissions' => $this->getRoutePermissions(),
'locale' => $this->getLocale(),
'comment' => $this->getComment(),
'address' => $this->getAddress(),
'country' => $this->getCountry(),
'dateOfBirth' => $this->getDateOfBirth(),
'isVerified' => $this->isVerified(),
'zipCode' => $this->getZipCode(),
'isLocked' => $this->isIsLocked(),
'verificationCode' => $this->getVerificationCode(),
'createdAt' => $this->getCreatedAt(),
'updatedAt' => $this->getUpdatedAt()
];
}
public function __construct()
{
$this->notifications = new ArrayCollection();
$this->purchaseMessages = new ArrayCollection();
$this->userRole = new ArrayCollection();
$this->userCars = new ArrayCollection();
$this->laborActs = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
/**
* A visual identifier that represents this user.
*
* @see UserInterface
*/
#[Ignore()]
public function getUserIdentifier(): string
{
return (string) $this->email;
}
/**
* @see UserInterface
*/
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;
}
/**
* @see PasswordAuthenticatedUserInterface
*/
public function getPassword(): string
{
return $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
/**
* @see UserInterface
*/
public function eraseCredentials()
{
$this->plainPassword = null;
}
public function isVerified(): bool
{
return $this->isVerified;
}
public function setIsVerified(bool $isVerified): self
{
$this->isVerified = $isVerified;
return $this;
}
public function getFirstName(): ?string
{
return $this->firstName;
}
public function setFirstName(?string $firstName): self
{
$this->firstName = $firstName;
return $this;
}
public function getLastName(): ?string
{
return $this->lastName;
}
public function setLastName(?string $lastName): self
{
$this->lastName = $lastName;
return $this;
}
public function getIsActive(): ?bool
{
return $this->isActive;
}
public function setIsActive(bool $isActive): self
{
$this->isActive = $isActive;
return $this;
}
public function getPrivacyPolicy(): ?bool
{
return $this->privacyPolicy;
}
public function setPrivacyPolicy(bool $privacyPolicy): self
{
$this->privacyPolicy = $privacyPolicy;
return $this;
}
public function getTermsConditions(): ?bool
{
return $this->termsConditions;
}
public function setTermsConditions(bool $termsConditions): self
{
$this->termsConditions = $termsConditions;
return $this;
}
public function getNewsletterSubscription(): ?bool
{
return $this->newsletterSubscription;
}
public function setNewsletterSubscription(bool $newsletterSubscription): self
{
$this->newsletterSubscription = $newsletterSubscription;
return $this;
}
public function getPhoneCountryCode(): ?string
{
return $this->phoneCountryCode;
}
public function setPhoneCountryCode(?string $phoneCountryCode): self
{
$this->phoneCountryCode = $phoneCountryCode;
return $this;
}
public function getPhoneNo(): ?string
{
return $this->phoneNo;
}
public function setPhoneNo(?string $phoneNo): self
{
$this->phoneNo = $phoneNo;
return $this;
}
public function getProfileImage(): ?string
{
return $this->profileImage;
}
public function setProfileImage(?string $profileImage): self
{
$this->profileImage = $profileImage;
return $this;
}
public function getJobPosition(): ?string
{
return $this->jobPosition;
}
public function setJobPosition(?string $jobPosition): self
{
$this->jobPosition = $jobPosition;
return $this;
}
public function getUserHeaderColor(): ?string
{
return $this->userHeaderColor;
}
public function setUserHeaderColor(?string $userHeaderColor): self
{
$this->userHeaderColor = $userHeaderColor;
return $this;
}
public function getUserSideNavDark(): ?bool
{
return $this->userSideNavDark;
}
public function setUserSideNavDark(?bool $userSideNavDark): self
{
$this->userSideNavDark = $userSideNavDark;
return $this;
}
public function getUserFoldedMenu(): ?bool
{
return $this->userFoldedMenu;
}
public function setUserFoldedMenu(?bool $userFoldedMenu): self
{
$this->userFoldedMenu = $userFoldedMenu;
return $this;
}
public function getRoutePermissions(): ?array
{
return $this->routePermissions;
}
public function setRoutePermissions(?array $routePermissions): self
{
$this->routePermissions = $routePermissions;
return $this;
}
/**
* @return Collection<int, Notification>
*/
public function getNotifications(): Collection
{
return $this->notifications;
}
public function addNotification(Notification $notification): self
{
if (!$this->notifications->contains($notification)) {
$this->notifications[] = $notification;
$notification->setNotificationUser($this);
}
return $this;
}
public function removeNotification(Notification $notification): self
{
if ($this->notifications->removeElement($notification)) {
// set the owning side to null (unless already changed)
if ($notification->getNotificationUser() === $this) {
$notification->setNotificationUser(null);
}
}
return $this;
}
public function getLocale(): ?string
{
return $this->locale;
}
public function setLocale(?string $locale): self
{
$this->locale = $locale;
return $this;
}
public function getComment(): ?string
{
return $this->comment;
}
public function setComment(?string $comment): self
{
$this->comment = $comment;
return $this;
}
/**
* @return Collection<int, RoleManagement>
*/
public function getUserRole(): Collection
{
return $this->userRole;
}
public function addUserRole(RoleManagement $userRole): self
{
if (!$this->userRole->contains($userRole)) {
$this->userRole[] = $userRole;
}
return $this;
}
public function getAddress(): ?string
{
return $this->address;
}
public function setAddress(?string $address): self
{
$this->address = $address;
return $this;
}
public function getCountry(): ?string
{
return $this->country;
}
public function setCountry(?string $country): self
{
$this->country = $country;
return $this;
}
public function getDateOfBirth(): ?\DateTimeInterface
{
return $this->dateOfBirth;
}
public function setDateOfBirth(?\DateTimeInterface $dateOfBirth): self
{
$this->dateOfBirth = $dateOfBirth;
return $this;
}
public function getZipCode(): ?string
{
return $this->zipCode;
}
public function setZipCode(?string $zipCode): self
{
$this->zipCode = $zipCode;
return $this;
}
public function getPlainPassword(): ?string
{
return $this->plainPassword;
}
public function setPlainPassword($plainPassword): void
{
$this->plainPassword = $plainPassword;
}
public function getIsMe(): bool
{
return $this->isMe;
}
public function setIsMe(bool $isMe): void
{
$this->isMe = $isMe;
}
public function getTransactions(): array
{
return $this->transactions;
}
public function setTransactions(array $transactions): void
{
$this->transactions = $transactions;
}
/**
* @return Collection<int, PurchaseMessage>
*/
public function getPurchaseMessages(): Collection
{
return $this->purchaseMessages;
}
public function addPurchaseMessage(PurchaseMessage $purchaseMessage): self
{
if (!$this->purchaseMessages->contains($purchaseMessage)) {
$this->purchaseMessages[] = $purchaseMessage;
$purchaseMessage->setCreatedByUser($this);
}
return $this;
}
public function removePurchaseMessage(PurchaseMessage $purchaseMessage): self
{
if ($this->purchaseMessages->removeElement($purchaseMessage)) {
// set the owning side to null (unless already changed)
if ($purchaseMessage->getCreatedByUser() === $this) {
$purchaseMessage->setCreatedByUser(null);
}
}
return $this;
}
public function removeUserRole(RoleManagement $userRole): self
{
$this->userRole->removeElement($userRole);
return $this;
}
public function isIsLocked(): ?bool
{
return $this->isLocked;
}
public function setIsLocked(?bool $isLocked): self
{
$this->isLocked = $isLocked;
return $this;
}
/**
* @return Collection<int, UserCar>
*/
public function getUserCars(): Collection
{
return $this->userCars;
}
public function addUserCar(UserCar $userCar): self
{
if (!$this->userCars->contains($userCar)) {
$this->userCars->add($userCar);
$userCar->setUser($this);
}
return $this;
}
public function removeUserCar(UserCar $userCar): self
{
if ($this->userCars->removeElement($userCar)) {
// set the owning side to null (unless already changed)
if ($userCar->getUser() === $this) {
$userCar->setUser(null);
}
}
return $this;
}
public function getVerificationCode(): ?string
{
return $this->verificationCode;
}
public function setVerificationCode(?string $verificationCode): self
{
$this->verificationCode = $verificationCode;
return $this;
}
/**
* @return Collection<int, LaborAct>
*/
public function getLaborActs(): Collection
{
return $this->laborActs;
}
public function addLaborAct(LaborAct $laborAct): self
{
if (!$this->laborActs->contains($laborAct)) {
$this->laborActs->add($laborAct);
$laborAct->setUser($this);
}
return $this;
}
public function removeLaborAct(LaborAct $laborAct): self
{
if ($this->laborActs->removeElement($laborAct)) {
// set the owning side to null (unless already changed)
if ($laborAct->getUser() === $this) {
$laborAct->setUser(null);
}
}
return $this;
}
}