<?php
namespace Products\NotificationsBundle\Entity;
use App\Entity\Content\Common\DiscriminatorInterface;
use App\Entity\Content\Common\DiscriminatorTrait;
use Cms\CoreBundle\Util\DateTimeUtils;
use Cms\TenantBundle\Entity\TenantedEntity;
use DateInterval;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
/**
* Class AbstractContactAttempt
* @package Products\NotificationsBundle\Entity
*
* @ORM\Entity(
* repositoryClass = "Products\NotificationsBundle\Doctrine\Repository\ContactAttemptRepository",
* )
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(
* name = "discr",
* type = "string",
* )
* @ORM\DiscriminatorMap({
* ContactAttempts\EmailContactAttempt::DISCR = "Products\NotificationsBundle\Entity\ContactAttempts\EmailContactAttempt",
* ContactAttempts\SmsContactAttempt::DISCR = "Products\NotificationsBundle\Entity\ContactAttempts\SmsContactAttempt",
* ContactAttempts\VoiceContactAttempt::DISCR = "Products\NotificationsBundle\Entity\ContactAttempts\VoiceContactAttempt",
* ContactAttempts\AppContactAttempt::DISCR = "Products\NotificationsBundle\Entity\ContactAttempts\AppContactAttempt",
* ContactAttempts\WebsiteContactAttempt::DISCR = "Products\NotificationsBundle\Entity\ContactAttempts\WebsiteContactAttempt",
* ContactAttempts\FacebookContactAttempt::DISCR = "Products\NotificationsBundle\Entity\ContactAttempts\FacebookContactAttempt",
* ContactAttempts\TwitterContactAttempt::DISCR = "Products\NotificationsBundle\Entity\ContactAttempts\TwitterContactAttempt",
* ContactAttempts\InstagramContactAttempt::DISCR = "Products\NotificationsBundle\Entity\ContactAttempts\InstagramContactAttempt",
*
* })
* @ORM\Table(
* name = "notis__contact_attempt",
* uniqueConstraints = {
* },
* indexes = {
* @ORM\Index(
* name = "idx__external_id",
* columns = {
* "externalId",
* },
* ),
* },
* )
*/
abstract class AbstractContactAttempt extends TenantedEntity implements DiscriminatorInterface
{
const DISCRS = [
ContactAttempts\EmailContactAttempt::DISCR => ContactAttempts\EmailContactAttempt::class,
ContactAttempts\SmsContactAttempt::DISCR => ContactAttempts\SmsContactAttempt::class,
ContactAttempts\VoiceContactAttempt::DISCR => ContactAttempts\VoiceContactAttempt::class,
ContactAttempts\AppContactAttempt::DISCR => ContactAttempts\AppContactAttempt::class,
ContactAttempts\WebsiteContactAttempt::DISCR => ContactAttempts\WebsiteContactAttempt::class,
ContactAttempts\FacebookContactAttempt::DISCR => ContactAttempts\FacebookContactAttempt::class,
ContactAttempts\TwitterContactAttempt::DISCR => ContactAttempts\TwitterContactAttempt::class,
ContactAttempts\InstagramContactAttempt::DISCR => ContactAttempts\InstagramContactAttempt::class,
];
const DISCR = null;
const ALL_STATUSES = [
...self::STATUSES,
...ContactAttempts\EmailContactAttempt::STATUSES,
...ContactAttempts\SmsContactAttempt::STATUSES,
...ContactAttempts\VoiceContactAttempt::STATUSES,
...ContactAttempts\AppContactAttempt::STATUSES,
...ContactAttempts\WebsiteContactAttempt::STATUSES,
...ContactAttempts\FacebookContactAttempt::STATUSES,
...ContactAttempts\TwitterContactAttempt::STATUSES,
...ContactAttempts\InstagramContactAttempt::STATUSES,
];
const STATUSES = [
...self::PENDING_STATUSES,
...self::SUCCESSFUL_STATUSES,
...self::FAILED_STATUSES,
];
const ALL_PENDING_STATUSES = [
...self::PENDING_STATUSES,
...ContactAttempts\EmailContactAttempt::PENDING_STATUSES,
...ContactAttempts\SmsContactAttempt::PENDING_STATUSES,
...ContactAttempts\VoiceContactAttempt::PENDING_STATUSES,
...ContactAttempts\AppContactAttempt::PENDING_STATUSES,
...ContactAttempts\WebsiteContactAttempt::PENDING_STATUSES,
...ContactAttempts\FacebookContactAttempt::PENDING_STATUSES,
...ContactAttempts\TwitterContactAttempt::PENDING_STATUSES,
...ContactAttempts\InstagramContactAttempt::PENDING_STATUSES,
];
const PENDING_STATUSES = [
'attempt.queued',
'attempt.attempted',
];
const ALL_SUCCESSFUL_STATUSES = [
...self::SUCCESSFUL_STATUSES,
...ContactAttempts\EmailContactAttempt::SUCCESSFUL_STATUSES,
...ContactAttempts\SmsContactAttempt::SUCCESSFUL_STATUSES,
...ContactAttempts\VoiceContactAttempt::SUCCESSFUL_STATUSES,
...ContactAttempts\AppContactAttempt::SUCCESSFUL_STATUSES,
...ContactAttempts\WebsiteContactAttempt::SUCCESSFUL_STATUSES,
...ContactAttempts\FacebookContactAttempt::SUCCESSFUL_STATUSES,
...ContactAttempts\TwitterContactAttempt::SUCCESSFUL_STATUSES,
...ContactAttempts\InstagramContactAttempt::SUCCESSFUL_STATUSES,
];
const SUCCESSFUL_STATUSES = [
'attempt.successful',
];
const ALL_FAILED_STATUSES = [
...self::FAILED_STATUSES,
...ContactAttempts\EmailContactAttempt::FAILED_STATUSES,
...ContactAttempts\SmsContactAttempt::FAILED_STATUSES,
...ContactAttempts\VoiceContactAttempt::FAILED_STATUSES,
...ContactAttempts\AppContactAttempt::FAILED_STATUSES,
...ContactAttempts\WebsiteContactAttempt::FAILED_STATUSES,
...ContactAttempts\FacebookContactAttempt::FAILED_STATUSES,
...ContactAttempts\TwitterContactAttempt::FAILED_STATUSES,
...ContactAttempts\InstagramContactAttempt::FAILED_STATUSES,
];
const FAILED_STATUSES = [
'attempt.failed',
];
use DiscriminatorTrait;
/**
* @var string|null
*
* @ORM\Column(
* type = "string",
* nullable = true,
* )
*/
protected ?string $externalId = null;
/**
* @var string|null
*
* @ORM\Column(
* type = "string",
* nullable = false,
* options = {
* "default" = "attempt.queued",
* },
* )
*/
protected string $event = 'attempt.queued';
/**
* @var array|null
*
* @ORM\Column(
* type = "json",
* nullable = true,
* )
*/
protected ?array $error = null;
/**
* @var DateTime|null
*
* @ORM\Column(
* type = "datetime",
* nullable = true,
* )
*/
protected ?DateTime $triggeredAt = null;
/**
* @var AbstractNotification|null
*
* @ORM\ManyToOne(
* targetEntity = "Products\NotificationsBundle\Entity\AbstractNotification",
* )
* @ORM\JoinColumn(
* name = "message",
* referencedColumnName = "id",
* nullable = false,
* onDelete = "CASCADE",
* )
*/
protected ?AbstractNotification $message = null;
/**
* @var Job|null
*
* @ORM\ManyToOne(
* targetEntity = "Products\NotificationsBundle\Entity\Job",
* )
* @ORM\JoinColumn(
* name = "job",
* referencedColumnName = "id",
* nullable = true,
* onDelete = "SET NULL",
*
* )
*/
protected ?Job $job = null;
/**
* @var int|null
*
* @ORM\Column(
* type = "integer",
* nullable = true,
* )
*/
protected ?int $apiWait = null;
/**
* @var AbstractRecipient|null
*
* @ORM\ManyToOne(
* targetEntity = "Products\NotificationsBundle\Entity\AbstractRecipient",
* )
* @ORM\JoinColumn(
* name = "recipient",
* referencedColumnName = "id",
* nullable = true,
* onDelete = "SET NULL",
* )
*
* NOTE:
* While the join column allows nulls, that is only to support the other attempt classes in the hierarchy.
* Attempts of this kind should always have the recipient set...
*/
protected ?AbstractRecipient $recipient = null;
/**
* @var Student|null
*
* @ORM\ManyToOne(
* targetEntity = "Products\NotificationsBundle\Entity\Student",
* )
* @ORM\JoinColumn(
* name = "student",
* referencedColumnName = "id",
* nullable = true,
* onDelete = "SET NULL",
* )
*/
protected ?Student $student = null;
/**
* @var Profile|null
*
* @ORM\ManyToOne(
* targetEntity = "Products\NotificationsBundle\Entity\Profile",
* )
* @ORM\JoinColumn(
* name = "profile",
* referencedColumnName = "id",
* nullable = true,
* onDelete = "SET NULL",
* )
*/
protected ?Profile $profile = null;
/**
* @return AbstractRecipient|null
*/
public function getRecipient(): ?AbstractRecipient
{
return $this->recipient;
}
/**
* @param AbstractRecipient $recipient
* @return $this
*/
public function setRecipient(AbstractRecipient $recipient): self
{
$this->recipient = $recipient;
return $this;
}
/**
* @return bool
*/
public function isPending(): bool
{
return in_array($this->getEvent(), static::PENDING_STATUSES);
}
/**
* @return bool
*/
public function isSuccessful(): bool
{
return in_array($this->getEvent(), static::SUCCESSFUL_STATUSES);
}
/**
* @return bool
*/
public function isFailed(): bool
{
return in_array($this->getEvent(), static::FAILED_STATUSES);
}
/**
* @return DateInterval
*/
public function getTimespan(): DateInterval
{
$start = $this->getTriggeredAt();
if (empty($start)) {
$start = DateTimeUtils::now();
}
return date_diff($start, $this->getCreatedAt());
}
/**
* @return DateTime|null
*/
public function getTriggeredAt(): ?DateTime
{
return $this->triggeredAt;
}
/**
* @param DateTime $triggeredAt
* @return $this
*/
public function setTriggeredAt(DateTime $triggeredAt): self
{
$this->triggeredAt = $triggeredAt;
return $this;
}
/**
* @return string|null
*/
public function getExternalId(): ?string
{
return $this->externalId;
}
/**
* @param string $externalId
* @return $this
*/
public function setExternalId(string $externalId): self
{
$this->externalId = $externalId;
return $this;
}
/**
* @return array|null
*/
public function getError(): ?array
{
return $this->error ?: null;
}
/**
* @param array|null $error
* @return $this
*/
public function setError(?array $error): self
{
$this->error = $error ?: null;
return $this;
}
/**
* @return string|null
*/
public function getEvent(): ?string
{
return $this->event;
}
/**
* @param string $event
* @return $this
*/
public function setEvent(string $event): self
{
$this->event = $event;
return $this;
}
/**
* @return AbstractNotification
*/
public function getMessage(): AbstractNotification
{
return $this->message;
}
/**
* @return Job
*/
public function getJob(): Job
{
return $this->job;
}
/**
* @param Job $job
* @return $this
*/
public function setJob(Job $job): self
{
$this->job = $job;
$this->message = $job->getMessage();// forcing the message to be tied to the job
return $this;
}
/**
* @return array|string[]
*/
public function getExtras(): array
{
return [];
}
/**
* @return int|null
*/
public function getApiWait(): ?int
{
return $this->apiWait;
}
/**
* @param int $apiWait
* @return $this
*/
public function setApiWait(int $apiWait): self
{
$this->apiWait = $apiWait;
return $this;
}
/**
* @return Student|null
*/
public function getStudent(): ?Student
{
return $this->student;
}
/**
* @param Student|null $student
* @return self
*/
public function setStudent(?Student $student): self
{
$this->student = $student;
return $this;
}
/**
* @return Profile|null
*/
public function getProfile(): ?Profile
{
return $this->profile;
}
/**
* @param Profile|null $profile
* @return self
*/
public function setProfile(?Profile $profile): self
{
$this->profile = $profile;
return $this;
}
}