<?php
namespace App\Entity;
use App\Entity\Utils\IntlInterface;
use App\Entity\Utils\Traits\TimestampTrait;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Class Tag.
*/
#[ORM\Table(name: 'tag')]
#[ORM\Entity(repositoryClass: \App\Repository\TagRepository::class)]
class Tag implements IntlInterface, \Stringable
{
use TimestampTrait;
/**
* Id.
*/
#[ORM\Id]
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER)]
#[ORM\GeneratedValue]
protected ?int $id = null;
/**
* Type.
*/
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255)]
#[Assert\NotBlank(message: 'form.error.required')]
#[Assert\Length(min: 2, max: 255, minMessage: 'form.error.short', maxMessage: 'form.error.long')]
protected string $type;
/**
* Global name.
*/
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255, nullable: true)]
#[Assert\Length(min: 2, max: 255, minMessage: 'form.error.short', maxMessage: 'form.error.long')]
protected ?string $globalName = null;
/**
* Global description.
*/
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
#[Assert\Length(min: 2, max: 10000, minMessage: 'form.error.short', maxMessage: 'form.error.long')]
protected ?string $globalDescription = null;
/**
* Name.
*/
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255)]
#[Assert\NotBlank(message: 'form.error.required')]
#[Assert\Length(min: 2, max: 255, minMessage: 'form.error.short', maxMessage: 'form.error.long')]
protected string $name;
/**
* Description.
*/
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::TEXT, nullable: true)]
#[Assert\Length(min: 2, max: 10000, minMessage: 'form.error.short', maxMessage: 'form.error.long')]
protected ?string $description = null;
/**
* Locale.
*/
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255)]
#[Assert\NotBlank(message: 'form.error.required')]
protected string $locale = 'en';
/**
* Translations.
*/
#[ORM\OneToMany(targetEntity: 'Tag', mappedBy: 'master', cascade: ['detach'])]
protected ?Collection $translations = null;
/**
* Master.
*/
#[ORM\ManyToOne(targetEntity: 'Tag', inversedBy: 'translations', cascade: ['detach'])]
#[ORM\JoinColumn(name: 'master_id')]
protected ?Tag $master = null;
/**
* Entities.
*/
#[Assert\Valid]
#[ORM\ManyToMany(targetEntity: 'Page', mappedBy: 'tags', cascade: ['detach'])]
protected Collection $pages;
/**
* Tag constructor.
*
* @throws \Exception
*/
public function __construct()
{
$this->translations = new \Doctrine\Common\Collections\ArrayCollection();
$this->pages = new \Doctrine\Common\Collections\ArrayCollection();
$name = date_timestamp_get(new \DateTime());
$this->setGlobalName($name);
$this->setName($name);
}
public function __toString(): string
{
return $this->globalName;
}
public function setId(int $id): void
{
$this->id = $id;
}
public function getId(): int
{
return $this->id;
}
public function getType(): string
{
return $this->type;
}
public function setType(string $type): void
{
$this->type = $type;
}
public function getGlobalName(): ?string
{
return $this->globalName;
}
public function setGlobalName(?string $globalName): void
{
$this->globalName = $globalName;
if ($this->isMaster()) {
if ($this->translations) {
/** @var Tag $translation */
foreach ($this->translations as $translation) {
$translation->setGlobalName($globalName);
}
}
}
}
/**
* @return mixed
*/
public function getGlobalDescription()
{
return $this->globalDescription;
}
public function setGlobalDescription(?string $globalDescription): void
{
$this->globalDescription = $globalDescription;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): void
{
$this->name = $name;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description): void
{
$this->description = $description;
}
public function getLocale(): string
{
return $this->locale;
}
public function setLocale(string $locale): void
{
$this->locale = $locale;
}
public function getExistingLocales(): array
{
$locales = [];
$master = $this->getMaster();
$locales[] = $master->getLocale();
/** @var Page $translation */
foreach ($this->getTranslations() as $translation) {
$locales[] = $translation->getLocale();
}
return $locales;
}
public function getTranslations(): Collection
{
$master = $this->getMaster();
return $master->translations;
}
/**
* @return mixed|null
*/
public function getTranslation(string $locale)
{
$master = $this->getMaster();
if ($master->getLocale() == $locale) {
return $master;
}
/** @var Page $translation */
foreach ($master->getTranslations() as $translation) {
if ($translation->getLocale() == $locale) {
return $translation;
}
}
return null;
}
public function addTranslation(object $translation): void
{
$this->translations[] = $translation;
/* @var Tag $translation */
$translation->setMaster($this);
}
public function removeTranslation(object $translation): void
{
$this->translations->removeElement($translation);
/* @var Tag $translation */
$translation->setMaster(null);
}
public function removeAllTranslation(): void
{
foreach ($this->translations as $translation) {
$this->removeTranslation($translation);
}
}
public function isMaster(): bool
{
return !$this->master;
}
public function getMaster(): Tag
{
if (false == $this->master) {
return $this;
}
return $this->master;
}
/**
* @param mixed $master
*/
public function setMaster($master): void
{
$this->master = $master;
}
/**
* Add pages.
*/
public function addPage(Page $page): void
{
$this->pages[] = $page;
}
/**
* Remove pages.
*/
public function removePage(Page $page): void
{
$this->pages->removeElement($page);
}
public function getPages(): Collection
{
return $this->pages;
}
public function getArrayModel(bool $partial = false): array
{
if ($partial) {
$data = [
'globalName',
'name',
'locale',
'type',
];
} else {
$data = [
'globalName',
'globalDescription',
'name',
'description',
'locale',
'type',
];
}
return $data;
}
public function import(array $data, bool $partial = false): void
{
$fields = $this->getArrayModel($partial);
foreach ($fields as $field) {
$setter = 'set'.ucfirst((string) $field);
$fields[$field] = $this->{$setter}($data[$field]);
}
}
public function export(string $locale = null): array
{
$fields = [];
foreach ($this->getArrayModel() as $field) {
$getter = 'get'.ucfirst((string) $field);
$fields[$field] = $this->{$getter}();
}
if ($locale) {
$fields['locale'] = $locale;
}
return $fields;
}
}