<?php
namespace Products\NotificationsBundle\Entity\Notifications;
use App\Entity\System\SocialAccounts\FacebookSocialAccount;
use App\Entity\System\SocialAccounts\InstagramSocialAccount;
use App\Entity\System\SocialAccounts\TwitterSocialAccount;
use Cms\ContainerBundle\Entity\Containers\GenericContainer;
use Cms\CoreBundle\Model\Interfaces\Loggable\LoggableInterface;
use Cms\TenantBundle\Entity\TenantedEntity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Products\NotificationsBundle\Entity\AbstractList;
use Products\NotificationsBundle\Entity\Notifications\Channels\ChannelsInterface;
use Products\NotificationsBundle\Entity\Notifications\Channels\ServiceChannelsInterface;
use Products\NotificationsBundle\Entity\Notifications\Channels\ServiceChannelsTrait;
use Products\NotificationsBundle\Entity\Notifications\Channels\TransactionalChannelsInterface;
use Products\NotificationsBundle\Entity\Notifications\Channels\TransactionalChannelsTrait;
use Products\NotificationsBundle\Entity\Notifications\Translations\Translation;
use Reinder83\BinaryFlags\Bits;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ORM\Entity(
* repositoryClass = "Products\NotificationsBundle\Doctrine\Repository\Notifications\TemplateRepository",
* )
* @ORM\Table(
* name = "notis__template",
* )
*/
class Template extends TenantedEntity implements NotificationInterface, TransactionalChannelsInterface, ServiceChannelsInterface, LoggableInterface
{
public const DEFAULT_PREFIX = 'DEFAULT ';
public const DEFAULT_GENERAL_NAME = self::DEFAULT_PREFIX . 'GENERAL';
public const DEFAULT_URGENT_NAME = self::DEFAULT_PREFIX . 'URGENT';
public const STATUSES = [
'draft' => self::STATUSES__DRAFT,
'sendable' => self::STATUSES__SENDABLE,
];
public const STATUSES__DRAFT = 0;
public const STATUSES__SENDABLE = Bits::BIT_1;
public const TYPES = [
'general' => self::TYPES__GENERAL,
'urgent' => self::TYPES__URGENT,
'automation' => self::TYPES__AUTOMATION,
];
public const TYPES__GENERAL = Bits::BIT_1;
public const TYPES__URGENT = Bits::BIT_2;
public const TYPES__AUTOMATION = Bits::BIT_3;
public const VALID_CHANNELS = [
self::TYPES__GENERAL => [
ChannelsInterface::CHANNELS__FACEBOOK,
ChannelsInterface::CHANNELS__TWITTER,
ChannelsInterface::CHANNELS__INSTAGRAM,
ChannelsInterface::CHANNELS__WEBSITE,
ChannelsInterface::CHANNELS__EMAIL,
ChannelsInterface::CHANNELS__SMS,
ChannelsInterface::CHANNELS__APP,
],
self::TYPES__URGENT => [
ChannelsInterface::CHANNELS__FACEBOOK,
ChannelsInterface::CHANNELS__TWITTER,
ChannelsInterface::CHANNELS__INSTAGRAM,
ChannelsInterface::CHANNELS__WEBSITE,
ChannelsInterface::CHANNELS__EMAIL,
ChannelsInterface::CHANNELS__SMS,
ChannelsInterface::CHANNELS__APP,
ChannelsInterface::CHANNELS__VOICE,
],
self::TYPES__AUTOMATION => [
ChannelsInterface::CHANNELS__EMAIL,
ChannelsInterface::CHANNELS__SMS,
ChannelsInterface::CHANNELS__APP,
ChannelsInterface::CHANNELS__VOICE,
],
];
use NotificationTrait;
use TransactionalChannelsTrait;
use ServiceChannelsTrait;
/**
* @var Collection|AbstractList[]|null
*
* @ORM\ManyToMany(
* targetEntity = "Products\NotificationsBundle\Entity\AbstractList",
* )
* @ORM\JoinTable(
* name = "notis__template_x_list",
* joinColumns = {
* @ORM\JoinColumn(
* name = "template",
* referencedColumnName = "id",
* onDelete = "CASCADE",
* ),
* },
* inverseJoinColumns = {
* @ORM\JoinColumn(
* name = "list",
* referencedColumnName = "id",
* onDelete = "CASCADE",
* ),
* },
* )
*
* @Groups("template_details")
*/
protected ?Collection $lists = null;
/**
* @var Collection|GenericContainer[]|null
*
* @ORM\ManyToMany(
* targetEntity = "Cms\ContainerBundle\Entity\Containers\GenericContainer",
* )
* @ORM\JoinTable(
* name = "notis__template_x_department",
* joinColumns = {
* @ORM\JoinColumn(
* name = "template",
* referencedColumnName = "id",
* onDelete = "CASCADE",
* ),
* },
* inverseJoinColumns = {
* @ORM\JoinColumn(
* name = "department",
* referencedColumnName = "id",
* onDelete = "CASCADE",
* ),
* },
* )
*
* @Groups("template_details")
*/
protected ?Collection $websiteDepartments = null;
/**
* @var Collection|FacebookSocialAccount[]|null
*
* @ORM\ManyToMany(
* targetEntity = "App\Entity\System\SocialAccounts\FacebookSocialAccount",
* )
* @ORM\JoinTable(
* name = "notis__template_x_facebook_social_account",
* joinColumns = {
* @ORM\JoinColumn(
* name = "template",
* referencedColumnName = "id",
* onDelete = "CASCADE",
* ),
* },
* inverseJoinColumns = {
* @ORM\JoinColumn(
* name = "facebookSocialAccount",
* referencedColumnName = "id",
* onDelete = "CASCADE",
* ),
* },
* )
*
* @Groups("template_details")
*/
protected ?Collection $facebookSocialAccounts = null;
/**
* @var Collection|InstagramSocialAccount[]|null
*
* @ORM\ManyToMany(
* targetEntity = "App\Entity\System\SocialAccounts\InstagramSocialAccount",
* )
* @ORM\JoinTable(
* name = "notis__template_x_instagram_social_account",
* joinColumns = {
* @ORM\JoinColumn(
* name = "template",
* referencedColumnName = "id",
* onDelete = "CASCADE",
* ),
* },
* inverseJoinColumns = {
* @ORM\JoinColumn(
* name = "instagramSocialAccount",
* referencedColumnName = "id",
* onDelete = "CASCADE",
* ),
* },
* )
*
* @Groups("template_details")
*/
protected ?Collection $instagramSocialAccounts = null;
/**
* @var Collection|TwitterSocialAccount[]|null
*
* @ORM\ManyToMany(
* targetEntity = "App\Entity\System\SocialAccounts\TwitterSocialAccount",
* )
* @ORM\JoinTable(
* name = "notis__template_x_twitter_social_account",
* joinColumns = {
* @ORM\JoinColumn(
* name = "template",
* referencedColumnName = "id",
* onDelete = "CASCADE",
* ),
* },
* inverseJoinColumns = {
* @ORM\JoinColumn(
* name = "twitterSocialAccount",
* referencedColumnName = "id",
* onDelete = "CASCADE",
* ),
* },
* )
*
* @Groups("template_details")
*/
protected ?Collection $twitterSocialAccounts = null;
/**
* @var bool
*
* @ORM\Column(
* type = "boolean",
* nullable = false,
* options = {
* "default" = false,
* },
* )
*/
protected bool $urgent = false;
/**
* @var int
*
* @ORM\Column(
* type = "bigint",
* nullable = false,
* options = {
* "default" = 0,
* },
* )
*
* @Groups("template_details")
*/
protected int $status = 0;
/**
* @var string|null
*
* @ORM\Column(
* type = "string",
* nullable = false,
* )
*
* @Groups("template_details")
*/
private ?string $name = null;
/**
* @var bool
*
* @ORM\Column(
* type = "boolean",
* nullable = false,
* options = {
* "default" = false,
* },
* )
*/
private bool $forAutomations = false;
/**
* @var Collection|Translation[]
*
* @ORM\OneToMany(
* targetEntity = Translation::class,
* mappedBy = "template",
* )
*/
protected Collection $translations;
public function __construct()
{
$this->lists = new ArrayCollection();
$this->facebookSocialAccounts = new ArrayCollection();
$this->instagramSocialAccounts = new ArrayCollection();
$this->twitterSocialAccounts = new ArrayCollection();
$this->websiteDepartments = new ArrayCollection();
}
/**
* @return int
*/
public function getType(): int
{
switch (true) {
case $this->isForAutomations():
return self::TYPES__AUTOMATION;
case $this->isUrgent():
return self::TYPES__URGENT;
case !$this->isUrgent():
return self::TYPES__GENERAL;
default:
throw new \RuntimeException();
}
}
/**
* @return string
*/
public function getTypeName(): string
{
$name = array_search($this->getType(), self::TYPES, true);
if ( ! $name) {
throw new \RuntimeException();
}
return $name;
}
/**
* @return bool
*/
public function isForAutomations(): bool
{
return $this->forAutomations;
}
/**
* @param bool $forAutomations
* @return $this
*/
public function setForAutomations(bool $forAutomations): self
{
$this->forAutomations = $forAutomations;
return $this;
}
/**
* @return bool
*/
public function isUrgent(): bool
{
return $this->urgent;
}
/**
* @return bool
*/
public function supportsVoice(): bool
{
return $this->isUrgent() || $this->isForAutomations();
}
/**
* @param bool $urgent
* @return $this
*/
public function setUrgent(bool $urgent): self
{
$this->urgent = $urgent;
return $this;
}
/**
* @return int
*/
public function getStatus(): int
{
return $this->status;
}
/**
* @param int $status
* @return bool
*/
public function isStatus(int $status): bool
{
if ($status === 0) {
return ($this->getStatus() === $status);
} else {
if ($status > 0) {
if ($this->getStatus() < 0) {
return false;
}
return (($this->getStatus() & $status) === $status);
} else {
if ($this->getStatus() > 0) {
return false;
}
return ((~$this->getStatus() & ~$status) === ~$status);
}
}
}
/**
* @param int $status
* @return $this
*/
public function setStatus(int $status): self
{
$this->status = $status;
return $this;
}
/**
* @return string|null
*/
public function getName(): ?string
{
return $this->name;
}
/**
* @param string $name
* @return $this
*/
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
/**
* @return bool
*/
public function isDraft(): bool
{
return $this->isStatus(self::STATUSES__DRAFT);
}
/**
* @return bool
*/
public function isSendable(): bool
{
return $this->isStatus(self::STATUSES__SENDABLE);
}
/**
* @return array<int>
*/
public function getValidChannels(): array
{
return self::VALID_CHANNELS[$this->getType()];
}
/**
* @param int $channel
* @return bool
*/
public function isValidChannel(int $channel): bool
{
return in_array($channel, $this->getValidChannels(), true);
}
/**
* {@inheritDoc}
*/
public function getLoggableDetails(): array
{
return [
'id' => (string) $this->getId(),
'title' => $this->getTitle(),
];
}
/**
* @return Collection
*/
public function getTranslations(): Collection
{
return $this->translations;
}
/**
* @param Collection $translations
* @return self
*/
public function setTranslations(Collection $translations): self
{
$this->translations = $translations;
return $this;
}
}