<?php
namespace App\Entity;
use App\Entity\Building\Building;
use App\Entity\Building\BuildingListField;
use App\Entity\Client\Client;
use App\Entity\Client\ClientGroup;
use App\Entity\Common\UrlDomain;
use App\Entity\Extension\DisabledTrait;
use App\Entity\Extension\TimestampableTrait;
use App\Entity\Gauge\Gauge;
use App\Entity\Gauge\GaugeListField;
use App\Repository\UserRepository;
use App\Utils\Units;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ORM\Entity(repositoryClass=UserRepository::class)
* @ORM\Table(name="users")
*
* @UniqueEntity("username")
* @UniqueEntity("email")
*/
class User implements UserInterface, PasswordAuthenticatedUserInterface
{
use TimestampableTrait;
use DisabledTrait;
/**
* @var null|int
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
* @Groups({"list"})
*/
private ?int $id = null;
/**
* @var string
* @ORM\Column(type="string", length=180, unique=true)
*
* @Assert\NotBlank
* @Assert\Type(type="string")
* @Assert\Email
* @Groups({"profile", "list"})
*/
private string $email;
/**
* @var string
* @ORM\Column(type="string", unique=true)
*
* @Assert\NotBlank
* @Assert\Type(type="string")
*/
private string $username;
/**
* @var string The hashed password
* @ORM\Column(type="string")
*
* @Assert\NotBlank
* @Assert\Type(type="string")
*/
private string $password;
/**
* @var bool
* @ORM\Column(type="boolean")
*
* @Assert\NotNull
* @Assert\Type(type="boolean")
* @Groups({"profile"})
*/
private bool $hasDarkMode;
/**
* @var Role
* @ORM\ManyToOne(targetEntity="App\Entity\Role", inversedBy="users")
* @ORM\JoinColumn(name="role_id", referencedColumnName="id", nullable=false)
* @Assert\NotBlank
*/
private Role $role;
/**
* @var string|null
* @ORM\Column(type="string", nullable=true)
* @Groups({"list"})
*/
private ?string $firstname;
/**
* @var string|null
* @ORM\Column(type="string", nullable=true)
* @Groups({"list"})
*/
private ?string $lastname;
/**
* @var string|null
* @ORM\Column(type="string", nullable=true)
* @Groups({"list"})
* @Assert\Length(
* min = 9,
* max = 13,
* minMessage = "Telefon musí mít alespoň {{ limit }} znaků (bez mezer).",
* maxMessage = "Telefon musí může mít maximálně {{ limit }} znaků."
* )
*/
private ?string $phone;
/**
* @var Client
* @ORM\ManyToOne(targetEntity="App\Entity\Client\Client", inversedBy="users")
* @ORM\JoinColumn(name="client_id", nullable=false)
* @Groups({"list"})
*/
private Client $client;
/**
* @var ClientGroup|null
* @ORM\ManyToOne(targetEntity="App\Entity\Client\ClientGroup", inversedBy="users")
*/
private ?ClientGroup $clientGroup;
/**
* @var boolean
* @ORM\Column(type="boolean")
* @Groups({"list"})
*/
private bool $enabled;
/**
* @var string|null
* @ORM\Column(type="string", nullable=true)
*/
private ?string $entryPage = null;
/**
* @var Gauge|null
* @ORM\ManyToOne(targetEntity="App\Entity\Gauge\Gauge")
* @ORM\JoinColumn(name="entry_page_gauge_id", referencedColumnName="id", nullable=true)
*/
private ?Gauge $entryPageGauge = null;
/**
* @var int
* @ORM\Column(type="integer")
*/
private int $primaryUnit = Units::KWH_VALUE; // default unit
/**
* @var Collection|Building[]
* @ORM\ManyToMany(targetEntity="App\Entity\Building\Building", inversedBy="users", cascade={"persist"})
* @ORM\OrderBy({"name" = "ASC"})
* @ORM\JoinTable(name="users_buildings")
*/
private $buildings;
/**
* @var Collection|BuildingListField[]
* @ORM\OneToMany(targetEntity="App\Entity\Building\BuildingListField", mappedBy="user", cascade={"persist"}, orphanRemoval=true)
* @ORM\OrderBy({"position" = "ASC"})
* @Groups("user")
*/
private $buildingListFields;
/**
* @var Collection|GaugeListField[]
* @ORM\OneToMany(targetEntity="App\Entity\Gauge\GaugeListField", mappedBy="user", cascade={"persist"}, orphanRemoval=true)
* @ORM\OrderBy({"position" = "ASC"})
* @Groups("user")
*/
private $gaugeListFields;
/**
* @var Collection|ActivityLog[]
* @ORM\OneToMany(targetEntity="App\Entity\ActivityLog", mappedBy="user")
*/
private $activities;
/**
* just for creating form (not in dtb)
* @var boolean
*/
private bool $sendInitMail = false;
/**
* @var boolean
* @ORM\Column(type="boolean")
*/
private bool $emailReporting;
/**
* @var boolean
* @ORM\Column(type="boolean")
*/
private bool $smsReporting;
/**
* @var boolean
* @ORM\Column(type="boolean", options={"default": 0})
*/
private bool $incidentEmailReporting;
/**
* @var boolean
* @ORM\Column(type="boolean", options={"default" : 1})
*/
private bool $emailReminder;
/**
* @var Client|null
* @ORM\OneToOne(targetEntity="App\Entity\Client\Client", mappedBy="mainManager")
*/
private ?Client $mainManagerOf;
/**
* @var Collection|UserWidget[]
* @ORM\OneToMany(targetEntity="App\Entity\UserWidget", mappedBy="user")
*/
private $widgets;
/**
* @var \DateTime|null
*
* @ORM\Column(name="agreement_at", type="datetime", nullable=true)
*/
private ?\DateTime $agreementAt;
/**
* @var Collection|UrlDomain[]
* @ORM\ManyToMany(targetEntity="App\Entity\Common\UrlDomain", inversedBy="users", cascade={"persist"})
* @ORM\OrderBy({"name" = "ASC"})
*/
private Collection $allowedDomains;
/**
* @var \DateTimeInterface|null
*
* @ORM\Column(name="last_activity_at", type="datetime", nullable=true)
*/
protected ?\DateTimeInterface $lastActivity;
public function __construct()
{
$this->email = '';
$this->username = '';
$this->password = '';
$this->enabled = false;
$this->emailReporting = true;
$this->smsReporting = false;
$this->incidentEmailReporting = false;
$this->hasDarkMode = false;
$this->emailReminder = true;
$this->buildings = new ArrayCollection();
$this->buildingListFields = new ArrayCollection();
$this->activities = new ArrayCollection();
$this->widgets = new ArrayCollection();
$this->allowedDomains = new ArrayCollection();
}
/**
* @return int|null
*/
public function getId(): ?int
{
return $this->id;
}
/**
* A visual identifier that represents this user.
*
* @see UserInterface
*/
public function getUsername(): string
{
return $this->username ?? '';
}
/**
* @param string $username
* @return $this
*/
public function setUsername(string $username): self
{
$this->username = $username;
return $this;
}
/**
* @see UserInterface
*/
public function getPassword(): string
{
return $this->password;
}
/**
* @param string $password
* @return $this
*/
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
/**
* @see UserInterface
*/
public function getSalt(): ?string
{
return null;
// not needed when using the "bcrypt" algorithm in security.yaml
}
/**
* @see UserInterface
*/
public function eraseCredentials(): void
{
// If you store any temporary, sensitive data on the user, clear it here
// $this->plainPassword = null;
}
/**
* @return string
*/
public function getEmail(): string
{
return $this->email;
}
/**
* @param string $email
* @return User
*/
public function setEmail(string $email): User
{
$this->email = $email;
return $this;
}
/**
* @return bool|null
*/
public function getHasDarkMode(): ?bool
{
return $this->hasDarkMode;
}
/**
* @param bool $hasDarkMode
* @return $this
*/
public function setHasDarkMode(bool $hasDarkMode): self
{
$this->hasDarkMode = $hasDarkMode;
return $this;
}
/**
* @return string|null
*/
public function getFirstname(): ?string
{
return $this->firstname;
}
/**
* @param string|null $firstname
* @return User
*/
public function setFirstname(?string $firstname): User
{
$this->firstname = $firstname;
return $this;
}
/**
* @return string|null
*/
public function getLastname(): ?string
{
return $this->lastname;
}
/**
* @param string|null $lastname
* @return User
*/
public function setLastname(?string $lastname): User
{
$this->lastname = $lastname;
return $this;
}
/**
* @return string
*/
public function getName(): string
{
return $this->firstname . ' ' . $this->lastname;
}
/**
* @return string|null
*/
public function getPhone(): ?string
{
return $this->phone;
}
/**
* @param string|null $phone
* @return User
*/
public function setPhone(?string $phone): User
{
$this->phone = $phone;
return $this;
}
/**
* @return Client
*/
public function getClient(): Client
{
return $this->client;
}
/**
* @param Client $client
* @return User
*/
public function setClient(Client $client): User
{
$this->client = $client;
return $this;
}
/**
* @return ClientGroup|null
*/
public function getClientGroup(): ?ClientGroup
{
return $this->clientGroup;
}
/**
* @param ClientGroup|null $clientGroup
* @return User
*/
public function setClientGroup(?ClientGroup $clientGroup): User
{
$this->clientGroup = $clientGroup;
return $this;
}
/**
* @return bool
*/
public function isEnabled(): bool
{
return $this->enabled;
}
/**
* @param bool $enabled
* @return User
*/
public function setEnabled(bool $enabled): User
{
$this->enabled = $enabled;
return $this;
}
/**
* @return string|null
*/
public function getEntryPage(): ?string
{
return $this->entryPage;
}
/**
* @param string|null $entryPage
* @return User
*/
public function setEntryPage(?string $entryPage): User
{
$this->entryPage = $entryPage;
return $this;
}
/**
* @return Gauge|null
*/
public function getEntryPageGauge(): ?Gauge
{
return $this->entryPageGauge;
}
/**
* @param Gauge|null $entryPageGauge
* @return User
*/
public function setEntryPageGauge(?Gauge $entryPageGauge): User
{
$this->entryPageGauge = $entryPageGauge;
return $this;
}
/**
* @return int
*/
public function getPrimaryUnit(): int
{
return $this->primaryUnit;
}
/**
* @param int $primaryUnit
* @return User
*/
public function setPrimaryUnit(int $primaryUnit): User
{
$this->primaryUnit = $primaryUnit;
return $this;
}
/**
* @return Building[]|Collection
*/
public function getBuildings()
{
return $this->buildings;
}
/**
* @param Building[]|Collection $buildings
* @return User
*/
public function setBuildings($buildings): User
{
$this->buildings = $buildings;
return $this;
}
/**
* @return bool
*/
public function isEmailReporting(): bool
{
return $this->emailReporting;
}
/**
* @param bool $emailReporting
* @return User
*/
public function setEmailReporting(bool $emailReporting): User
{
$this->emailReporting = $emailReporting;
return $this;
}
/**
* @return bool
*/
public function isSmsReporting(): bool
{
return $this->smsReporting;
}
/**
* @param bool $smsReporting
* @return User
*/
public function setSmsReporting(bool $smsReporting): User
{
$this->smsReporting = $smsReporting;
return $this;
}
/**
* @return bool|null
*/
public function getEnabled(): ?bool
{
return $this->enabled;
}
/**
* @return bool|null
*/
public function getEmailReporting(): ?bool
{
return $this->emailReporting;
}
/**
* @return bool|null
*/
public function getSmsReporting(): ?bool
{
return $this->smsReporting;
}
/**
* @return bool
*/
public function isIncidentEmailReporting(): bool
{
return $this->incidentEmailReporting;
}
/**
* @return bool|null
*/
public function getIncidentEmailReporting(): ?bool
{
return $this->incidentEmailReporting;
}
/**
* @param bool $incidentEmailReporting
* @return User
*/
public function setIncidentEmailReporting(bool $incidentEmailReporting): User
{
$this->incidentEmailReporting = $incidentEmailReporting;
return $this;
}
/**
* @param Building $building
* @return $this
*/
public function addBuilding(Building $building): self
{
if (!$this->buildings->contains($building)) {
$this->buildings[] = $building;
}
return $this;
}
/**
* @param Building $building
* @return $this
*/
public function removeBuilding(Building $building): self
{
if ($this->buildings->contains($building)) {
$this->buildings->removeElement($building);
}
return $this;
}
/**
* @return BuildingListField[]|Collection
*/
public function getBuildingListFields()
{
return $this->buildingListFields;
}
/**
* @param BuildingListField[]|Collection $buildingListFields
* @return User
*/
public function setBuildingListFields($buildingListFields): self
{
$this->buildingListFields = $buildingListFields;
return $this;
}
/**
* @return Role
*/
public function getRole(): Role
{
return $this->role;
}
/**
* @param Role $role
* @return User
*/
public function setRole(Role $role): User
{
$this->role = $role;
return $this;
}
/**
* @return string[]
*/
public function getRoles(): array
{
$roles = [];
$roles[] = $this->getRole()->getName();
// guarantee every user at least has ROLE_USER
if (!in_array('ROLE_USER', $roles, true)) {
$roles[] = 'ROLE_USER';
}
return array_unique($roles);
}
/**
* @return Collection|ActivityLog[]
*/
public function getActivities(): Collection
{
return $this->activities;
}
/**
* @return GaugeListField[]|Collection
*/
public function getGaugeListFields()
{
return $this->gaugeListFields;
}
/**
* @param GaugeListField[]|Collection $gaugeListFields
* @return User
*/
public function setGaugeListFields($gaugeListFields)
{
$this->gaugeListFields = $gaugeListFields;
return $this;
}
/***
* @return string
*/
public function __toString() :string
{
return $this->getName();
}
/**
* @return Client|null
*/
public function getMainManagerOf(): ?Client
{
return $this->mainManagerOf;
}
/**
* @param Client|null $mainManagerOf
* @return User
*/
public function setMainManagerOf(?Client $mainManagerOf): User
{
$this->mainManagerOf = $mainManagerOf;
return $this;
}
/**
* @return bool
*/
public function isSendInitMail(): bool
{
return $this->sendInitMail;
}
/**
* @param bool $sendInitMail
* @return User
*/
public function setSendInitMail(bool $sendInitMail): User
{
$this->sendInitMail = $sendInitMail;
return $this;
}
/**
* @return string
*/
public function getUserIdentifier(): string
{
return $this->getUsername();
}
/**
* @return bool
*/
public function isEmailReminder(): bool
{
return $this->emailReminder;
}
/**
* @param bool $emailReminder
* @return User
*/
public function setEmailReminder(bool $emailReminder): User
{
$this->emailReminder = $emailReminder;
return $this;
}
/**
* @return UserWidget[]|Collection
*/
public function getWidgets()
{
return $this->widgets;
}
/**
* @param UserWidget $userWidget
* @return $this
*/
public function addWidget(UserWidget $userWidget): User
{
$userWidget->setUser($this);
if (!$this->widgets->contains($userWidget)) {
$this->widgets[] = $userWidget;
}
return $this;
}
/**
* @return \DateTime|null
*/
public function getAgreementAt(): ?\DateTime
{
return $this->agreementAt;
}
/**
* @param \DateTime|null $agreementAt
* @return User
*/
public function setAgreementAt(?\DateTime $agreementAt): User
{
$this->agreementAt = $agreementAt;
return $this;
}
/**
* @return Building[]|Collection
*/
public function getAllowedBuildings()
{
if ($this->getRole()->hasPermission('ROLE_CAN_SEE_ALL_BUILDINGS')) {
return $this->getClient()->getBuildings();
}
return $this->getBuildings();
}
/**
* @return array
*/
public function getAllowedGauges():array
{
$gauges = [];
foreach ($this->getAllowedBuildings() as $building) {
foreach ($building->getGauges() as $gauge) {
$gauges[] = $gauge;
}
}
return $gauges;
}
public function getAllowedDomains(): Collection
{
return $this->allowedDomains;
}
public function setAllowedDomains(Collection $allowedDomains): User
{
$this->allowedDomains = $allowedDomains;
return $this;
}
public function addAllowedDomain(UrlDomain $domain): User
{
if (!$this->allowedDomains->contains($domain)) {
$this->allowedDomains->add($domain);
}
return $this;
}
public function hasAccessToDomain(string $hostDomain):bool
{
foreach ($this->allowedDomains as $domainOnj) {
if (in_array($hostDomain, $domainOnj->getAliases(), true)) {
return true;
}
}
return false;
}
public function getDefaultDomain(): UrlDomain
{
foreach ($this->allowedDomains as $domain) {
if ($domain->getName() === UrlDomain::DEFAULT_DOMAIN) {
return $domain;
}
}
return $this->allowedDomains->first();
}
public function getLastActivity(): ?\DateTimeInterface
{
return $this->lastActivity;
}
public function setLastActivity(?\DateTimeInterface $lastActivity): User
{
$this->lastActivity = $lastActivity;
return $this;
}
}