<?php
namespace App\Entity;
use App\Entity\Building\Building;
use App\Entity\Client\Client;
use App\Entity\ContractPrice\Contract;
use App\Entity\Event\Event;
use App\Entity\Extension\BlameableTrait;
use App\Entity\Extension\TimestampableTrait;
use App\Entity\Gauge\Gauge;
use App\Entity\Gauge\Invoice;
use App\Repository\FileRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Ramsey\Uuid\Uuid;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Serializer\Annotation\Groups;
use Ramsey\Uuid\UuidInterface;
/**
* @ORM\Entity(repositoryClass=FileRepository::class)
* @ORM\Table(name="files")
*/
class File
{
use BlameableTrait;
use TimestampableTrait;
public const CONTEXT_BUILDING = 1;
public const CONTEXT_GAUGE = 2;
public const CONTEXT_CLIENT = 3;
public const SHARED_WITH_NO_ONE = 0; // nikoliv
public const SHARED_WITH_ALL_CLIENT_USERS = 1; // se všemi uživateli města
public const SHARED_WITH_WORKERS = 2; // s pracovníky
public const SHARED_WITH_WORKERS_MANAGERS = 3; // s pracovníky-manažery
public const SHARED_WITH_GUESTS = 4; // s hosty
public const SHARED_WITH_GUEST_EXPERT = 5; // s hosty-experty
public static array $allSharingOptions = [
File::SHARED_WITH_NO_ONE,
File::SHARED_WITH_ALL_CLIENT_USERS,
File::SHARED_WITH_WORKERS,
File::SHARED_WITH_WORKERS_MANAGERS,
File::SHARED_WITH_GUESTS,
File::SHARED_WITH_GUEST_EXPERT
];
/**
* @var null|int
*
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private ?int $id = null;
/**
* @var null|FileCategory
*
* @ORM\ManyToOne(targetEntity="App\Entity\FileCategory", inversedBy="files")
*/
private ?FileCategory $category;
/**
* @var Collection|Building[]
*
* @ORM\ManyToMany(targetEntity="App\Entity\Building\Building", inversedBy="files", cascade={"persist"})
*/
private $buildings;
/**
* @var Collection|Gauge[]
*
* @ORM\ManyToMany(targetEntity="App\Entity\Gauge\Gauge", inversedBy="files", cascade={"persist"})
*/
private $gauges;
/**
* @var Collection|Contract[]
*
* @ORM\OneToMany(targetEntity="App\Entity\ContractPrice\Contract", mappedBy="file", cascade={"persist"})
*/
private $contracts;
/**
* @var null|int
*
* @Assert\Type("int")
* @ORM\Column(type="smallint", nullable=true)
*/
private ?int $context = null;
/**
* @var string
*
* @Assert\NotBlank()
* @Assert\Type("string")
* @ORM\Column(type="string")
*/
private string $fileName;
/**
* @var string
*
* @Assert\NotBlank()
* @Assert\Type("string")
* @ORM\Column(type="string")
*/
private string $mimeType;
/**
* @var float|null
*
* @Assert\Type("float")
* @ORM\Column(type="float", nullable=true)
*/
private ?float $size;
/**
* @var string
*
* @Assert\NotBlank()
* @Assert\Type("string")
* @ORM\Column(type="string")
*/
private string $path;
/**
* @var null|string
*
* @Assert\Type("string")
* @ORM\Column(type="string", nullable=true)
*/
private ?string $name;
/**
* @var Client|null
* @ORM\ManyToOne(targetEntity="App\Entity\Client\Client", inversedBy="files")
* @ORM\JoinColumn(name="client_id", nullable=true)
* @Groups({"list"})
*/
private ?Client $client = null;
/**
* @var null|\DateTimeInterface
*
* @ORM\Column(type="datetime", nullable=true)
*/
private ?\DateTimeInterface $initDate;
/**
* @var null|\DateTimeInterface
*
* @ORM\Column(type="datetime", nullable=true)
*/
private ?\DateTimeInterface $validTo;
/**
* @var null|string
*
* @ORM\Column(type="text", nullable=true)
* @Assert\Type(type="string")
*/
private ?string $note;
/**
* @var int
* @ORM\Column(type="smallint", nullable=false)
*/
private int $sharedWith = self::SHARED_WITH_NO_ONE;
/**
* @var bool
* @ORM\Column(type="boolean")
*/
private bool $hasEvent = false;
/**
* The internal primary identity key.
*
* @var UuidInterface
*
* @ORM\Column(type="uuid", unique=true)
*/
protected UuidInterface $token;
/**
* simple array of connected buildings
* @var array
*/
private $buildingsArray = [];
/**
* simple array of connected gauges
* @var array
*/
private $gaugesArray = [];
/**
* @var Collection|Event[]
*
* @ORM\OneToMany(targetEntity="App\Entity\Event\Event", mappedBy="file")
*/
private $events;
/**
* @var Collection|Invoice[]
*
* @ORM\OneToMany(targetEntity="App\Entity\Gauge\Invoice", mappedBy="file")
*/
private $invoices;
/**
* @var Collection|Building[]
*
* @ORM\OneToMany(targetEntity="App\Entity\Building\Building", mappedBy="photo")
*/
private $buildingPhotos;
/**
* @var Collection|Gauge[]
*
* @ORM\OneToMany(targetEntity="App\Entity\Gauge\Gauge", mappedBy="photo")
*/
private $gaugePhotos;
/**
* @var bool
* @ORM\Column(type="boolean", options={"default" : 0})
*/
private bool $common = false;
/**
* File constructor.
*/
public function __construct()
{
$this->buildings = new ArrayCollection();
$this->gauges = new ArrayCollection();
$this->contracts = new ArrayCollection();
$this->events = new ArrayCollection();
$this->invoices = new ArrayCollection();
$this->buildingPhotos = new ArrayCollection();
$this->gaugePhotos = new ArrayCollection();
$this->token = Uuid::uuid4();
}
public function __toString()
{
return $this->getName() ?? '';
}
/**
* Returns data that will be consumed by an API controller and then returned via JSON to the client.
*
* @return array
*/
public function getApiData(): array
{
return [
'id' => $this->getId(),
'fileName' => $this->getFileName(),
'size' => $this->getSize(),
'mimeType' => $this->getMimeType(),
'token' => $this->getToken(),
'name' => $this->getName()
];
}
/**
* @return int|null
*/
public function getId(): ?int
{
return $this->id;
}
/**
* @return int|null
*/
public function getContext(): ?int
{
return $this->context;
}
/**
* @param int|null $context
* @return $this
*/
public function setContext(?int $context): self
{
$this->context = $context;
return $this;
}
public function getFileName(): string
{
return $this->fileName;
}
/**
* @param string $fileName
* @return $this
*/
public function setFileName(string $fileName): self
{
$this->fileName = $fileName;
return $this;
}
/**
* @return string|null
*/
public function getName(): ?string
{
return $this->name;
}
/**
* @param string|null $name
* @return $this
*/
public function setName(?string $name): self
{
$this->name = $name;
return $this;
}
/**
* @return \DateTimeInterface|null
*/
public function getInitDate(): ?\DateTimeInterface
{
return $this->initDate;
}
/**
* @param \DateTimeInterface|null $initDate
* @return $this
*/
public function setInitDate(?\DateTimeInterface $initDate): self
{
$this->initDate = $initDate;
return $this;
}
/**
* @return \DateTimeInterface|null
*/
public function getValidTo(): ?\DateTimeInterface
{
return $this->validTo;
}
/**
* @param \DateTimeInterface|null $validTo
* @return $this
*/
public function setValidTo(?\DateTimeInterface $validTo): self
{
$this->validTo = $validTo;
return $this;
}
/**
* @return string|null
*/
public function getNote(): ?string
{
return $this->note;
}
/**
* @param string|null $note
* @return $this
*/
public function setNote(?string $note): self
{
$this->note = $note;
return $this;
}
/**
* @return null|FileCategory
*/
public function getCategory(): ?FileCategory
{
return $this->category;
}
/**
* @param null|FileCategory $category
* @return $this
*/
public function setCategory(?FileCategory $category): self
{
$this->category = $category;
return $this;
}
/**
* @return Collection|Building[]
*/
public function getBuildings(): Collection
{
return $this->buildings;
}
/**
* @param Building[]|Collection $buildings
* @return File
*/
public function setBuildings($buildings)
{
$this->buildings = $buildings;
return $this;
}
/**
* @param Gauge[]|Collection $gauges
* @return File
*/
public function setGauges($gauges): self
{
$this->gauges = is_array($gauges)
? new ArrayCollection($gauges)
: $gauges
;
foreach ($gauges as $gauge) {
$this->addBuilding($gauge->getBuilding());
}
return $this;
}
/**
* Sets gauges collection without modifying building associations.
* Used to restore gauges from snapshot without triggering addBuilding() side-effects.
*
* @param Gauge[]|Collection $gauges
*/
public function setGaugesWithoutBuildingSync($gauges): self
{
$this->gauges = is_array($gauges)
? new ArrayCollection($gauges)
: $gauges
;
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 Collection|Gauge[]
*/
public function getGauges(): Collection
{
return $this->gauges;
}
/**
* @return Collection|Contract[]
*/
public function getContracts(): Collection
{
return $this->contracts;
}
/**
* @param Gauge $gauge
* @return $this
*/
public function addGauge(Gauge $gauge): self
{
if (!$this->gauges->contains($gauge)) {
$this->gauges[] = $gauge;
$this->addBuilding($gauge->getBuilding());
}
return $this;
}
/**
* @param Gauge $gauge
* @return $this
*/
public function removeGauge(Gauge $gauge): self
{
if ($this->gauges->contains($gauge)) {
$this->gauges->removeElement($gauge);
}
return $this;
}
/**
* @return string
*/
public function getMimeType(): string
{
return $this->mimeType;
}
/**
* @param string $mimeType
* @return $this
*/
public function setMimeType(string $mimeType): self
{
$this->mimeType = $mimeType;
return $this;
}
/**
* @return float|null
*/
public function getSize(): ?float
{
return $this->size;
}
/**
* @param float|null $size
* @return File
*/
public function setSize(?float $size): File
{
$this->size = $size;
return $this;
}
/**
* @return string
*/
public function getPath(): string
{
return $this->path;
}
/**
* @param string $path
* @return $this
*/
public function setPath(string $path): self
{
$this->path = $path;
return $this;
}
/**
* @return Client|null
*/
public function getClient(): ?Client
{
return $this->client;
}
/**
* @param Client|null $client
* @return File
*/
public function setClient(?Client $client): File
{
$this->client = $client;
return $this;
}
/**
* @return int
*/
public function getSharedWith(): int
{
return $this->sharedWith;
}
/**
* @param int $sharedWith
* @return File
*/
public function setSharedWith(int $sharedWith): File
{
$this->sharedWith = $sharedWith;
return $this;
}
/**
* @return bool
*/
public function isHasEvent(): bool
{
return $this->hasEvent;
}
/**
* @param bool $hasEvent
* @return File
*/
public function setHasEvent(bool $hasEvent): File
{
$this->hasEvent = $hasEvent;
return $this;
}
/**
* @return UuidInterface
*/
public function getToken(): UuidInterface
{
return $this->token;
}
/**
* @param UuidInterface $token
* @return File
*/
public function setToken(UuidInterface $token): File
{
$this->token = $token;
return $this;
}
/**
* @param bool $fromArray
* @return array
*/
public function getBuildingsNames(bool $fromArray): array
{
$buildings = [];
if ($fromArray) {
foreach ($this->getBuildingsArray() as $building) {
$buildings[] = $building['name'];
}
} else {
foreach ($this->getBuildings() as $building) {
$buildings[] = $building->getName();
}
}
return $buildings;
}
/**
* @param bool $fromArray
* @return array
*/
public function getGaugesNames(bool $fromArray): array
{
$gauges = [];
if ($fromArray) {
foreach ($this->getGaugesArray() as $gauge) {
$gauges[] = $gauge['name'];
}
} else {
foreach ($this->getGauges() as $gauge) {
$gauges[] = $gauge->getName();
}
}
return $gauges;
}
/**
* @param bool $fromArray
* @return array
*/
public function getGaugesFilterString(): array
{
$gauges = [];
foreach ($this->getGaugesArray() as $gauge) {
$gauges[] = 'gauge' . $gauge['id'];
}
return $gauges;
}
/**
* @param string $roleName
* @return array
*/
public static function getSharedWithOptionsByRole(string $roleName): array
{
$sharedWith = [File::SHARED_WITH_ALL_CLIENT_USERS];
switch ($roleName) {
case Role::ADMIN:
case Role::ADMIN_MANAGER:
case Role::MANAGER:
case Role::CLIENT_BOSS:
$sharedWith = File::$allSharingOptions;
break;
case Role::WORKER_MANAGER:
$sharedWith[] = File::SHARED_WITH_WORKERS_MANAGERS;
$sharedWith[] = File::SHARED_WITH_WORKERS;
break;
case Role::WORKER:
$sharedWith[] = File::SHARED_WITH_WORKERS;
break;
case Role::GUEST:
$sharedWith[] = File::SHARED_WITH_GUESTS;
break;
case Role::GUEST_EXPERT:
$sharedWith[] = File::SHARED_WITH_GUEST_EXPERT;
$sharedWith[] = File::SHARED_WITH_GUESTS;
break;
}
return $sharedWith;
}
/**
* @return array
*/
public function getBuildingsArray(): array
{
return $this->buildingsArray;
}
/**
* @param array $buildingsArray (buildingsArray in array by fileId as key)
* @return File
*/
public function setBuildingsArrayByArray(array $buildingsArray): File
{
if (array_key_exists($this->getId(), $buildingsArray)) {
$this->buildingsArray = $buildingsArray[$this->getId()];
}
return $this;
}
/**
* @return array
*/
public function getGaugesArray(): array
{
return $this->gaugesArray;
}
/**
* @param array $gaugesArray (buildingsArray in array by fileId as key)
* @return File
*/
public function setGaugesArrayByArray(array $gaugesArray): File
{
if (array_key_exists($this->getId(), $gaugesArray)) {
$this->gaugesArray = $gaugesArray[$this->getId()];
}
return $this;
}
/**
* @return Event[]|Collection
*/
public function getEvents()
{
return $this->events;
}
/**
* @param Event[]|Collection $events
* @return File
*/
public function setEvents($events): File
{
$this->events = $events;
return $this;
}
/**
* @return bool
*/
public function isCommon(): bool
{
return $this->common;
}
/**
* @param bool $common
* @return File
*/
public function setCommon(bool $common): File
{
$this->common = $common;
return $this;
}
/**
* @return Invoice[]|Collection
*/
public function getInvoices()
{
return $this->invoices;
}
/**
* @return Building[]|Collection
*/
public function getBuildingPhotos()
{
return $this->buildingPhotos;
}
/**
* @return Gauge[]|Collection
*/
public function getGaugePhotos()
{
return $this->gaugePhotos;
}
/**
* method returns mapping dependencies (eg. check before deletion)
* @return bool
*/
public function hasDependencies(): bool
{
$dependencies = [
'invoices' => $this->getInvoices()->count(),
'events' => $this->getEvents()->count(),
'buildingPhotos' => $this->getBuildingPhotos()->count(),
'gaugePhotos' => $this->getGaugePhotos()->count()
];
return array_sum($dependencies) > 0;
}
/**
* @return string|null
*/
public function getFullCategoryName(): ?string
{
if ($this->getCategory() !== null) {
$catName = $this->getCategory()->getName();
$parentCat = $this->getCategory()->getParent();
return ($parentCat === null) ? $catName : sprintf('%s - %s', $parentCat->getName(), $catName);
}
return null;
}
}