<?php
namespace App\Entity\Whatsapp;
use App\Entity\AbstractBase;
use App\Enum\WhatsappMessageStatusEnum;
use App\Repository\Whatsapp\WhatsappMessageRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="vulco_whatsapp_message", indexes={@ORM\Index(name="whatsapp_message_wamid_idx", columns={"wam_id"})})
* @ORM\Entity(repositoryClass=WhatsappMessageRepository::class)
*
* @see https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages#successful-response
* @see https://developers.facebook.com/docs/whatsapp/cloud-api/webhooks/payload-examples#message-status-updates
* @see https://developers.facebook.com/docs/whatsapp/cloud-api/webhooks/components#statuses-object
*/
class WhatsappMessage extends AbstractBase
{
/**
* @ORM\Column(type="string", length=255, nullable=false)
*/
private string $wamId; // wam_id or wamid (WhatsApp message ID). Messages are identified by a unique ID (WAMID). You can track message in the Webhooks through its WAMID. Is returned by the API as "id" in the Response object after sending a message to the customer.
/**
* @ORM\Column(type="string", length=255, nullable=false)
*/
private string $phone; // Recipient phone number. Is returned by the API as "input" in the Response object after sending a message to the customer.
/**
* @ORM\Column(type="string", length=255, nullable=false)
*/
private string $waId; // wa_id: The customer's WhatsApp ID. A business can respond to a customer using this ID. This ID may not match the customer's phone number, which is returned by the API as "input" in the Response object after sending a message to the customer.
/**
* @ORM\OneToMany(targetEntity="WhatsappMessageStatus", mappedBy="whatsappMessage", cascade={"persist", "remove"}, orphanRemoval=true)
* @ORM\OrderBy({"date": "ASC"})
*/
private ?Collection $statuses = null;
public function __construct()
{
$this->statuses = new ArrayCollection();
}
public function getWamId(): string
{
return $this->wamId;
}
public function setWamId(string $wamId): self
{
$this->wamId = $wamId;
return $this;
}
public function getPhone(): string
{
return $this->phone;
}
public function getPhoneWithoutPlusSign(): string
{
if (str_starts_with($this->phone, '+')) {
return ltrim($this->phone, '+');
}
return $this->phone;
}
/**
* Set the recipient phone number. Is returned by the API as "input" in the Response object after sending a message to the customer.
*
* @param string $phone
* @return $this
*/
public function setPhone(string $phone): self
{
$this->phone = $phone;
return $this;
}
public function getWaId(): string
{
return $this->waId;
}
public function setWaId(string $waId): self
{
$this->waId = $waId;
return $this;
}
public function getStatuses(): Collection
{
return $this->statuses;
}
public function addStatus(WhatsappMessageStatus $status): self
{
if (!$this->getStatuses()->contains($status)) {
$status->setWhatsappMessage($this);
$this->statuses->add($status);
}
return $this;
}
public function removeStatus(WhatsappMessageStatus $status): self
{
if ($this->getStatuses()->contains($status)) {
$this->statuses->removeElement($status);
}
return $this;
}
public function isAccepted(): bool
{
/** @var WhatsappMessageStatus $status */
foreach ($this->getStatuses() as $status) {
if ($status->isAccepted()) {
return true;
}
}
return false;
}
public function isAcceptedString(): string
{
if ($this->isAccepted()) {
return WhatsappMessageStatusEnum::ACCEPTED;
}
return '';
}
public function isFailed(): bool
{
/** @var WhatsappMessageStatus $status */
foreach ($this->getStatuses() as $status) {
if ($status->isFailed()) {
return true;
}
}
return false;
}
public function isFailedString(): string
{
if ($this->isFailed()) {
return WhatsappMessageStatusEnum::FAILED;
}
return '';
}
public function isSent(): bool
{
/** @var WhatsappMessageStatus $status */
foreach ($this->getStatuses() as $status) {
if ($status->isSent()) {
return true;
}
}
return false;
}
public function isSentString(): string
{
if ($this->isSent()) {
return WhatsappMessageStatusEnum::SENT;
}
return '';
}
public function isDelivered(): bool
{
/** @var WhatsappMessageStatus $status */
foreach ($this->getStatuses() as $status) {
if ($status->isDelivered()) {
return true;
}
}
return false;
}
public function isDeliveredString(): string
{
if ($this->isDelivered()) {
return WhatsappMessageStatusEnum::DELIVERED;
}
return '';
}
public function isRead(): bool
{
/** @var WhatsappMessageStatus $status */
foreach ($this->getStatuses() as $status) {
if ($status->isRead()) {
return true;
}
}
return false;
}
public function isReadString(): string
{
if ($this->isRead()) {
return WhatsappMessageStatusEnum::READ;
}
return '';
}
/**
* Object $status collection could not be ordered by the logical sequence of whatsapp message status (see Cloud API documentation)
* @param Collection|null $statusCollection
* @param int $index
* @return WhatsappMessageStatus
*/
public function getMostRelevantStatus(?Collection $statuses = null, int $index = 0): ?WhatsappMessageStatus
{
if (is_null($statuses)) {
$statuses = $this->getStatuses();
}
/** @var WhatsappMessageStatus $status */
foreach ($statuses as $status) {
if ($status->getStatus() === WhatsappMessageStatusEnum::getArrayOrderedByStatusReverseSequence()[$index]) {
return $status;
}
}
if ($index++ < count(WhatsappMessageStatusEnum::getArrayOrderedByStatusReverseSequence())) {
return $this->getMostRelevantStatus($statuses, $index);
} else {
return null;
}
}
}