<?php
namespace App\Entity\Documents;
use App\Annotation\SiteAware;
use App\Entity\AbstractBase;
use App\Entity\Interfaces\DocumentInterface;
use App\Entity\Interfaces\SiteInterface;
use App\Entity\MiniAbstractBase;
use App\Entity\Traits\HasDocumentTrait;
use App\Entity\Traits\NameTrait;
use App\Entity\Traits\PublishedTrait;
use App\Entity\Traits\SiteTrait;
use App\Entity\User;
use App\Entity\UserGroup;
use App\Repository\Documents\DocumentRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* @ORM\Table(name="vulco_document", indexes={@ORM\Index(name="document_site_idx", columns={"site"})})
* @ORM\Entity(repositoryClass=DocumentRepository::class)
* @Gedmo\SoftDeleteable(fieldName="removedAt", timeAware=false)
* @SiteAware(siteFieldName="site")
* @Vich\Uploadable
*/
class Document extends AbstractBase implements SiteInterface, DocumentInterface
{
use HasDocumentTrait;
use NameTrait;
use PublishedTrait;
use SiteTrait;
/**
* @ORM\Column(type="string", length=255, nullable=false)
*/
private string $name;
/**
* @ORM\Column(type="integer", nullable=false, options={"default": 0})
*/
private int $numDownloads = 0;
/**
* @Vich\UploadableField(mapping="document_document", fileNameProperty="documentName")
*/
private ?File $document = null;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Documents\DocumentCategory", inversedBy="documents")
* @ORM\JoinColumn(name="document_category_id", referencedColumnName="id")
*/
private ?DocumentCategory $documentCategory = null;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Documents\DocumentDownload", mappedBy="document", cascade={"persist", "remove"}, orphanRemoval=true)
* @ORM\OrderBy({"createdAt": "DESC"})
*/
private ?Collection $downloads;
/**
* @ORM\ManyToMany(targetEntity="App\Entity\UserGroup", inversedBy="documents")
* @ORM\JoinTable(name="vulco_documents_user_groups",
* joinColumns={@ORM\JoinColumn(name="document_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="user_group_id", referencedColumnName="id")}
* )
*/
private ?Collection $userGroups;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="pointMovements")
*
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private ?User $user = null;
public function __construct()
{
$this->downloads = new ArrayCollection();
$this->userGroups = new ArrayCollection();
}
public function getNumDownloads(): int
{
return $this->numDownloads;
}
public function setNumDownloads(int $numDownloads): self
{
$this->numDownloads = $numDownloads;
return $this;
}
public function getDocumentCategory(): ?DocumentCategory
{
return $this->documentCategory;
}
public function setDocumentCategory(?DocumentCategory $documentCategory): self
{
$this->documentCategory = $documentCategory;
return $this;
}
public function getDownloads(): ?Collection
{
return $this->downloads;
}
public function setDownloads(?Collection $downloads): self
{
$this->downloads = $downloads;
return $this;
}
public function existsDownload(User $user): bool
{
$result = false;
$download = new DocumentDownload();
$download->setDocument($this);
$download->setUser($user);
$predicate = function ($key, DocumentDownload $element) use ($download) {
return ($element->getDocument()->getId() === $download->getDocument()->getId()) &&
($element->getUser()->getId() === $download->getUser()->getId());
};
if ($this->downloads->exists($predicate)) {
$result = true;
}
return $result;
}
public function addDownload(DocumentDownload $download): self
{
$predicate = function ($key, DocumentDownload $element) use ($download) {
return ($element->getDocument()->getId() === $download->getDocument()->getId()) &&
($element->getUser()->getId() === $download->getUser()->getId());
};
if (!$this->downloads->exists($predicate)) {
$this->downloads->add($download);
$this->setNumDownloads($this->getNumDownloads() + 1);
}
return $this;
}
public function removeDownload(DocumentDownload $download): self
{
if ($this->downloads->contains($download)) {
$this->downloads->removeElement($download);
$this->setNumDownloads($this->getNumDownloads() - 1);
}
return $this;
}
public function getUserGroups(): ?Collection
{
return $this->userGroups;
}
public function setUserGroups(?Collection $userGroups): self
{
$this->userGroups = $userGroups;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
public function isPrivate(): bool
{
return (bool)$this->user;
}
public function addUserGroup(UserGroup $userGroup): self
{
if (!$this->userGroups->contains($userGroup)) {
$this->userGroups->add($userGroup);
$userGroup->addDocument($this);
}
return $this;
}
public function removeUserGroup(UserGroup $userGroup): self
{
if ($this->userGroups->contains($userGroup)) {
$this->userGroups->removeElement($userGroup);
}
return $this;
}
public function isExcludedFor(User $user): bool
{
$result = false;
// check if the user received as an argument belongs to an excluded userGroup
if (null !== $this->userGroups) {
/** @var UserGroup $userGroup */
foreach ($this->userGroups as $userGroup) {
if ((null !== $user->getUserGroup()) && $userGroup->getId() === $user->getUserGroup()->getId()) {
$result = true;
break;
}
}
}
// check if the document is exclusive to a specific user other than the user received as an argument.
if ((null !== $this->user) && $this->user->getId() !== $user->getId()) {
$result = true;
}
return $result;
}
public function __toString(): string
{
return $this->id ? $this->getName() : MiniAbstractBase::DEFAULT_EMPTY_STRING;
}
}