<?php
namespace App\Entity;
use App\Component\Serializer\Normalizer\ProxyAwareObjectNormalizer;
use DateTime;
use DateTimeInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation as SA;
/**
* User
*
* @ORM\Table(name="users", indexes={@ORM\Index(name="type", columns={"type"})})
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="type", type="string")
* @ORM\DiscriminatorMap({"api" = "UserApi", "interactive" = "UserInteractive"})
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
*/
class User extends Entity
{
public const TYPE = [
'interactive' => 'interactive',
'api' => 'api'
];
public const SENTRY_LOGGING = [
'default' => 'default',
'off' => 'off'
];
public const SERIALIZATION_GROUP = [
User::class,
UserAllowedClient::class,
];
public const ADMIN_SERIALIZATION_GROUP = [
User::class,
UserInteractive::class,
UserApi::class,
Account::class,
Role::class,
UserAllowedClient::class
];
public const SERIALIZATION_CONTEXT = [
'read' => ['groups' => ['user_general', 'user_details'], ProxyAwareObjectNormalizer::RESOLVE_PROXY_CLASSES => self::SERIALIZATION_GROUP],
'delete' => ['groups' => ['user_general']],
'search' => ['groups' => ['user_general', 'user_search'], ProxyAwareObjectNormalizer::RESOLVE_PROXY_CLASSES => self::SEARCH_SERIALIZATION_GROUP],
'admin_read' => ['groups' => ['user_general', 'user_details', 'user_search', 'user_read'], ProxyAwareObjectNormalizer::RESOLVE_PROXY_CLASSES => self::ADMIN_SERIALIZATION_GROUP]
];
const SEARCH_SERIALIZATION_GROUP = [Role::class, Account::class, UserInteractive::class];
/**
* @var int
*
* @ORM\Column(name="id", type="bigint", nullable=false, options={"unsigned"=true})
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
* @SA\Groups({"user_general", "account_search"})
*/
private $id;
/**
* @var DateTime
*
* @ORM\Column(name="created", type="datetime", nullable=false, options={"default"="CURRENT_TIMESTAMP"})
* @SA\Groups({"user_general"})
*/
private $created = null;
/**
* @var string
*
* @ORM\Column(name="status", type="string", length=0, nullable=false, options={"default"="inactive"})
* @SA\Groups({"user_general"})
*/
private $status = self::STATUS['inactive'];
/**
* @var string
*
* @ORM\Column(name="sentry_logging", type="string", length=0, nullable=false, options={"default"="default"})
* @SA\Groups({"user_general"})
*/
private $sentryLogging = self::SENTRY_LOGGING['default'];
/**
* @var ArrayCollection
*
* @ORM\OneToMany(targetEntity="Role", mappedBy="user", cascade={"PERSIST"})
* @SA\Ignore
*/
private $roles;
/**
* @var ArrayCollection|UserAllowedClient[]
*
* @ORM\OneToMany(targetEntity="UserAllowedClient", mappedBy="user", cascade={"PERSIST"})
* @SA\Groups({"user_details"})
*/
private $allowedClients;
public function __construct(Account $account, ?string $roleName = null, ?string $sentryLogging = null)
{
$this->roles = new ArrayCollection();
$this->allowedClients = new ArrayCollection();
$this->created = new DateTime();
$this->status = self::STATUS['active'];
$this->sentryLogging = $sentryLogging ?? $this->sentryLogging;
$roleName ??= Role::ROLES['owner'];
$role = new Role($account, $this, $roleName);
$this->addRole($role);
}
public function getId(): ?int
{
return $this->id;
}
public function getCreated(): ?DateTimeInterface
{
return $this->created;
}
public function setCreated(DateTimeInterface $created): self
{
$this->created = $created;
return $this;
}
public function getStatus(): ?string
{
return $this->status;
}
public function setStatus(string $status): self
{
$this->status = $status;
return $this;
}
public function getType(): ?string
{
return $this instanceof UserApi ? self::TYPE['api'] : self::TYPE['interactive'];
}
public function getSentryLogging(): ?string
{
return $this->sentryLogging;
}
public function setSentryLogging(string $sentryLogging): self
{
$this->sentryLogging = $sentryLogging;
return $this;
}
/**
* @return ArrayCollection<int, Role>|Role[]
*/
public function getRoles(): Collection
{
return $this->roles;
}
public function addRole(Role $role): self
{
if (!$this->roles->contains($role)) {
$this->roles[] = $role;
$role->setUser($this);
}
return $this;
}
public function removeRole(Role $role): self
{
if ($this->roles->removeElement($role)) {
// set the owning side to null (unless already changed)
if ($role->getUser() === $this) {
$role->setUser(null);
}
}
return $this;
}
public function addAllowedClient(UserAllowedClient $client)
{
if (!$this->allowedClients->contains($client)) {
$this->allowedClients->add($client);
$client->setUser($this);
}
}
public function removeAllowedClient(UserAllowedClient $client)
{
if ($this->allowedClients->contains($client)) {
$this->allowedClients->removeElement($client);
$client->setUser(null);
}
}
/**
* @return UserAllowedClient[]|ArrayCollection
*/
public function getAllowedClients()
{
return $this->allowedClients;
}
public function softDelete(): Entity
{
$this->setStatus(self::STATUS['inactive']);
foreach ($this->getRoles()->matching(Criteria::create()->where(Criteria::expr()->eq('status', self::STATUS['active']))) as $role) {
$role->softDelete();
}
return $this;
}
/**
* @SA\Groups({"user_search", "user_read"})
* @return Collection<int, Account>|Account[]
*/
public function getAccounts(): Collection
{
return $this->getRoles()->map(function (Role $role) {
return $role->getAccount();
});
}
}