Initial commit: CloudOps infrastructure platform
This commit is contained in:
@@ -0,0 +1,263 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\ChannelBundle\Entity;
|
||||
|
||||
use ApiPlatform\Metadata\ApiResource;
|
||||
use ApiPlatform\Metadata\Delete;
|
||||
use ApiPlatform\Metadata\Get;
|
||||
use ApiPlatform\Metadata\GetCollection;
|
||||
use ApiPlatform\Metadata\Patch;
|
||||
use ApiPlatform\Metadata\Post;
|
||||
use ApiPlatform\Metadata\Put;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Mautic\ApiBundle\Serializer\Driver\ApiMetadataDriver;
|
||||
use Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder;
|
||||
use Mautic\CoreBundle\Entity\CommonEntity;
|
||||
use Mautic\CoreBundle\Entity\UuidInterface;
|
||||
use Mautic\CoreBundle\Entity\UuidTrait;
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
|
||||
#[ApiResource(
|
||||
operations: [
|
||||
new GetCollection(security: "is_granted('channel:messages:viewown')"),
|
||||
new Post(security: "is_granted('channel:messages:create')"),
|
||||
new Get(security: "is_granted('channel:messages:viewown')"),
|
||||
new Put(security: "is_granted('channel:messages:editown')"),
|
||||
new Patch(security: "is_granted('channel:messages:editother')"),
|
||||
new Delete(security: "is_granted('channel:messages:deleteown')"),
|
||||
],
|
||||
normalizationContext: [
|
||||
'groups' => ['channel:read'],
|
||||
'swagger_definition_name' => 'Read',
|
||||
'api_included' => ['message'],
|
||||
],
|
||||
denormalizationContext: [
|
||||
'groups' => ['channel:write'],
|
||||
'swagger_definition_name' => 'Write',
|
||||
]
|
||||
)]
|
||||
class Channel extends CommonEntity implements UuidInterface
|
||||
{
|
||||
use UuidTrait;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
#[Groups(['channel:read'])]
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
#[Groups(['channel:read', 'channel:write', 'message:read'])]
|
||||
private $channel;
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
*/
|
||||
#[Groups(['channel:read', 'channel:write'])]
|
||||
private $channelId;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
#[Groups(['channel:read', 'message:read'])]
|
||||
private $channelName;
|
||||
|
||||
/**
|
||||
* @var Message
|
||||
*/
|
||||
#[Groups(['channel:read', 'channel:write'])]
|
||||
private $message;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
#[Groups(['channel:read', 'channel:write'])]
|
||||
private $properties = [];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
#[Groups(['channel:read', 'channel:write', 'message:read'])]
|
||||
private $isEnabled = false;
|
||||
|
||||
public static function loadMetadata(ClassMetadata $metadata): void
|
||||
{
|
||||
$builder = new ClassMetadataBuilder($metadata);
|
||||
|
||||
$builder->setTable('message_channels')
|
||||
->addIndex(['channel', 'channel_id'], 'channel_entity_index')
|
||||
->addIndex(['channel', 'is_enabled'], 'channel_enabled_index')
|
||||
->addUniqueConstraint(['message_id', 'channel'], 'channel_index');
|
||||
|
||||
$builder
|
||||
->addId()
|
||||
->addField('channel', 'string')
|
||||
->addNamedField('channelId', 'integer', 'channel_id', true)
|
||||
->addField('properties', Types::JSON)
|
||||
->createField('isEnabled', 'boolean')
|
||||
->columnName('is_enabled')
|
||||
->build();
|
||||
|
||||
$builder->createManyToOne('message', Message::class)
|
||||
->addJoinColumn('message_id', 'id', false, false, 'CASCADE')
|
||||
->inversedBy('channels')
|
||||
->build();
|
||||
|
||||
static::addUuidField($builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the metadata for API usage.
|
||||
*/
|
||||
public static function loadApiMetadata(ApiMetadataDriver $metadata): void
|
||||
{
|
||||
$metadata->setGroupPrefix('messageChannel')
|
||||
->addListProperties(
|
||||
[
|
||||
'id',
|
||||
'channel',
|
||||
'channelId',
|
||||
'channelName',
|
||||
'isEnabled',
|
||||
]
|
||||
)
|
||||
->addProperties(
|
||||
[
|
||||
'properties',
|
||||
'message',
|
||||
]
|
||||
)
|
||||
->build();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getChannel()
|
||||
{
|
||||
return $this->channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $channel
|
||||
*
|
||||
* @return Channel
|
||||
*/
|
||||
public function setChannel($channel)
|
||||
{
|
||||
$this->channel = $channel;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getChannelId()
|
||||
{
|
||||
return $this->channelId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $channelId
|
||||
*
|
||||
* @return Channel
|
||||
*/
|
||||
public function setChannelId($channelId)
|
||||
{
|
||||
if (empty($channelId)) {
|
||||
$channelId = null;
|
||||
}
|
||||
|
||||
$this->channelId = $channelId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getChannelName()
|
||||
{
|
||||
return $this->channelName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $channelName
|
||||
*
|
||||
* @return Channel
|
||||
*/
|
||||
public function setChannelName($channelName)
|
||||
{
|
||||
$this->channelName = $channelName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Message
|
||||
*/
|
||||
public function getMessage()
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Channel
|
||||
*/
|
||||
public function setMessage(Message $message)
|
||||
{
|
||||
$this->message = $message;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getProperties()
|
||||
{
|
||||
return $this->properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Channel
|
||||
*/
|
||||
public function setProperties(array $properties)
|
||||
{
|
||||
$this->properties = $properties;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isEnabled()
|
||||
{
|
||||
return $this->isEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $isEnabled
|
||||
*
|
||||
* @return Channel
|
||||
*/
|
||||
public function setIsEnabled($isEnabled)
|
||||
{
|
||||
$this->isEnabled = $isEnabled;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\ChannelBundle\Entity;
|
||||
|
||||
use ApiPlatform\Metadata\ApiResource;
|
||||
use ApiPlatform\Metadata\Delete;
|
||||
use ApiPlatform\Metadata\Get;
|
||||
use ApiPlatform\Metadata\GetCollection;
|
||||
use ApiPlatform\Metadata\Patch;
|
||||
use ApiPlatform\Metadata\Post;
|
||||
use ApiPlatform\Metadata\Put;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Mautic\ApiBundle\Serializer\Driver\ApiMetadataDriver;
|
||||
use Mautic\CategoryBundle\Entity\Category;
|
||||
use Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder;
|
||||
use Mautic\CoreBundle\Entity\FormEntity;
|
||||
use Mautic\CoreBundle\Entity\UuidInterface;
|
||||
use Mautic\CoreBundle\Entity\UuidTrait;
|
||||
use Mautic\ProjectBundle\Entity\ProjectTrait;
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||
use Symfony\Component\Validator\Mapping\ClassMetadata as ValidationClassMetadata;
|
||||
|
||||
#[ApiResource(
|
||||
operations: [
|
||||
new GetCollection(security: "is_granted('channel:messages:viewown')"),
|
||||
new Post(security: "is_granted('channel:messages:create')"),
|
||||
new Get(security: "is_granted('channel:messages:viewown')"),
|
||||
new Put(security: "is_granted('channel:messages:editown')"),
|
||||
new Patch(security: "is_granted('channel:messages:editother')"),
|
||||
new Delete(security: "is_granted('channel:messages:deleteown')"),
|
||||
],
|
||||
normalizationContext: [
|
||||
'groups' => ['message:read'],
|
||||
'swagger_definition_name' => 'Read',
|
||||
'api_included' => ['category', 'channels'],
|
||||
],
|
||||
denormalizationContext: [
|
||||
'groups' => ['message:write'],
|
||||
'swagger_definition_name' => 'Write',
|
||||
]
|
||||
)]
|
||||
class Message extends FormEntity implements UuidInterface
|
||||
{
|
||||
use UuidTrait;
|
||||
use ProjectTrait;
|
||||
|
||||
/**
|
||||
* @var ?int
|
||||
*/
|
||||
#[Groups(['message:read'])]
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
#[Groups(['message:read', 'message:write', 'channel:read'])]
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var ?string
|
||||
*/
|
||||
#[Groups(['message:read', 'message:write'])]
|
||||
private $description;
|
||||
|
||||
/**
|
||||
* @var ?\DateTimeInterface
|
||||
*/
|
||||
#[Groups(['message:read', 'message:write'])]
|
||||
private $publishUp;
|
||||
|
||||
/**
|
||||
* @var ?\DateTimeInterface
|
||||
*/
|
||||
#[Groups(['message:read', 'message:write'])]
|
||||
private $publishDown;
|
||||
|
||||
/**
|
||||
* @var ?Category
|
||||
*/
|
||||
#[Groups(['message:read', 'message:write'])]
|
||||
private $category;
|
||||
|
||||
/**
|
||||
* @var ArrayCollection<int,Channel>
|
||||
*/
|
||||
#[Groups(['message:read', 'message:write'])]
|
||||
private $channels;
|
||||
|
||||
public function __clone()
|
||||
{
|
||||
$this->id = null;
|
||||
}
|
||||
|
||||
public static function loadMetadata(ClassMetadata $metadata): void
|
||||
{
|
||||
$builder = new ClassMetadataBuilder($metadata);
|
||||
|
||||
$builder->setTable('messages')
|
||||
->setCustomRepositoryClass(MessageRepository::class)
|
||||
->addIndex(['date_added'], 'date_message_added');
|
||||
|
||||
$builder
|
||||
->addIdColumns()
|
||||
->addPublishDates()
|
||||
->addCategory();
|
||||
|
||||
$builder->createOneToMany('channels', Channel::class)
|
||||
->setIndexBy('channel')
|
||||
->orphanRemoval()
|
||||
->mappedBy('message')
|
||||
->cascadeMerge()
|
||||
->cascadePersist()
|
||||
->cascadeDetach()
|
||||
->build();
|
||||
|
||||
static::addUuidField($builder);
|
||||
self::addProjectsField($builder, 'message_projects_xref', 'message_id');
|
||||
}
|
||||
|
||||
public static function loadValidatorMetadata(ValidationClassMetadata $metadata): void
|
||||
{
|
||||
$metadata->addPropertyConstraint('name', new NotBlank([
|
||||
'message' => 'mautic.core.name.required',
|
||||
]));
|
||||
}
|
||||
|
||||
public static function loadApiMetadata(ApiMetadataDriver $metadata): void
|
||||
{
|
||||
$metadata->setGroupPrefix('message')
|
||||
->addListProperties(
|
||||
[
|
||||
'id',
|
||||
'name',
|
||||
'description',
|
||||
]
|
||||
)
|
||||
->addProperties(
|
||||
[
|
||||
'publishUp',
|
||||
'publishDown',
|
||||
'channels',
|
||||
'category',
|
||||
]
|
||||
)
|
||||
->build();
|
||||
|
||||
self::addProjectsInLoadApiMetadata($metadata, 'message');
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->channels = new ArrayCollection();
|
||||
$this->initializeProjects();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ?int
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ?string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ?string $name
|
||||
*
|
||||
* @return Message
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->isChanged('name', $name);
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ?string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ?string $description
|
||||
*
|
||||
* @return Message
|
||||
*/
|
||||
public function setDescription($description)
|
||||
{
|
||||
$this->isChanged('description', $description);
|
||||
$this->description = $description;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ?\DateTimeInterface
|
||||
*/
|
||||
public function getPublishUp()
|
||||
{
|
||||
return $this->publishUp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ?\DateTime $publishUp
|
||||
*
|
||||
* @return Message
|
||||
*/
|
||||
public function setPublishUp($publishUp)
|
||||
{
|
||||
$this->isChanged('publishUp', $publishUp);
|
||||
$this->publishUp = $publishUp;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ?\DateTimeInterface
|
||||
*/
|
||||
public function getPublishDown()
|
||||
{
|
||||
return $this->publishDown;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ?\DateTime $publishDown
|
||||
*
|
||||
* @return Message
|
||||
*/
|
||||
public function setPublishDown($publishDown)
|
||||
{
|
||||
$this->isChanged('publishDown', $publishDown);
|
||||
$this->publishDown = $publishDown;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ?Category
|
||||
*/
|
||||
public function getCategory()
|
||||
{
|
||||
return $this->category;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ?Category $category
|
||||
*
|
||||
* @return Message
|
||||
*/
|
||||
public function setCategory($category)
|
||||
{
|
||||
$this->isChanged('category', $category);
|
||||
$this->category = $category;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ArrayCollection<int,Channel>
|
||||
*/
|
||||
public function getChannels()
|
||||
{
|
||||
return $this->channels;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ArrayCollection<int,Channel> $channels
|
||||
*
|
||||
* @return Message
|
||||
*/
|
||||
public function setChannels($channels)
|
||||
{
|
||||
$this->isChanged('channels', $channels);
|
||||
$this->channels = $channels;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addChannel(Channel $channel): void
|
||||
{
|
||||
if (!$this->channels->contains($channel)) {
|
||||
$channel->setMessage($this);
|
||||
$this->isChanged('channels', $channel);
|
||||
|
||||
$this->channels[$channel->getChannel()] = $channel;
|
||||
}
|
||||
}
|
||||
|
||||
public function removeChannel(Channel $channel): void
|
||||
{
|
||||
if ($channel->getId()) {
|
||||
$this->isChanged('channels', $channel->getId());
|
||||
}
|
||||
$this->channels->removeElement($channel);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,483 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\ChannelBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Mautic\CampaignBundle\Entity\Event;
|
||||
use Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder;
|
||||
use Mautic\LeadBundle\Entity\Lead;
|
||||
|
||||
class MessageQueue
|
||||
{
|
||||
public const STATUS_RESCHEDULED = 'rescheduled';
|
||||
|
||||
public const STATUS_PENDING = 'pending';
|
||||
|
||||
public const STATUS_SENT = 'sent';
|
||||
|
||||
public const STATUS_CANCELLED = 'cancelled';
|
||||
|
||||
public const PRIORITY_NORMAL = 2;
|
||||
|
||||
public const PRIORITY_HIGH = 1;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $channel;
|
||||
|
||||
private $channelId;
|
||||
|
||||
/**
|
||||
* @var Event|null
|
||||
*/
|
||||
private $event;
|
||||
|
||||
/**
|
||||
* @var Lead
|
||||
*/
|
||||
private $lead;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $priority = 2;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $maxAttempts = 3;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $attempts = 0;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $success = false;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $status = self::STATUS_PENDING;
|
||||
|
||||
/**
|
||||
* @var \DateTimeInterface
|
||||
**/
|
||||
private $datePublished;
|
||||
|
||||
/**
|
||||
* @var \DateTimeInterface|null
|
||||
*/
|
||||
private $scheduledDate;
|
||||
|
||||
/**
|
||||
* @var \DateTimeInterface|null
|
||||
*/
|
||||
private $lastAttempt;
|
||||
|
||||
/**
|
||||
* @var \DateTimeInterface|null
|
||||
*/
|
||||
private $dateSent;
|
||||
|
||||
private $options = [];
|
||||
|
||||
/**
|
||||
* Used by listeners to note if the message had been processed in bulk.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $processed = false;
|
||||
|
||||
/**
|
||||
* Used by listeners to tell the event dispatcher the message needs to be retried in 15 minutes.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $failed = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $metadataUpdated = false;
|
||||
|
||||
public static function loadMetadata(ORM\ClassMetadata $metadata): void
|
||||
{
|
||||
$builder = new ClassMetadataBuilder($metadata);
|
||||
|
||||
$builder->setTable('message_queue')
|
||||
->setCustomRepositoryClass(MessageQueueRepository::class)
|
||||
->addIndex(['status'], 'message_status_search')
|
||||
->addIndex(['date_sent'], 'message_date_sent')
|
||||
->addIndex(['scheduled_date'], 'message_scheduled_date')
|
||||
->addIndex(['priority'], 'message_priority')
|
||||
->addIndex(['success'], 'message_success')
|
||||
->addIndex(['channel', 'channel_id'], 'message_channel_search')
|
||||
->addIndex(['date_published'], 'message_queue_date_published');
|
||||
|
||||
$builder->addBigIntIdField();
|
||||
|
||||
$builder->addField('channel', 'string');
|
||||
$builder->addNamedField('channelId', 'integer', 'channel_id');
|
||||
|
||||
$builder->createManyToOne('event', Event::class)
|
||||
->addJoinColumn('event_id', 'id', true, false, 'CASCADE')
|
||||
->build();
|
||||
|
||||
$builder->addLead(false, 'CASCADE', false);
|
||||
|
||||
$builder->createField('priority', 'smallint')
|
||||
->columnName('priority')
|
||||
->build();
|
||||
|
||||
$builder->createField('maxAttempts', 'smallint')
|
||||
->columnName('max_attempts')
|
||||
->build();
|
||||
|
||||
$builder->createField('attempts', 'smallint')
|
||||
->columnName('attempts')
|
||||
->build();
|
||||
|
||||
$builder->createField('success', 'boolean')
|
||||
->columnName('success')
|
||||
->build();
|
||||
|
||||
$builder->createField('status', 'string')
|
||||
->columnName('status')
|
||||
->build();
|
||||
|
||||
$builder->createField('datePublished', 'datetime')
|
||||
->columnName('date_published')
|
||||
->nullable()
|
||||
->build();
|
||||
|
||||
$builder->createField('scheduledDate', 'datetime')
|
||||
->columnName('scheduled_date')
|
||||
->nullable()
|
||||
->build();
|
||||
|
||||
$builder->createField('lastAttempt', 'datetime')
|
||||
->columnName('last_attempt')
|
||||
->nullable()
|
||||
->build();
|
||||
|
||||
$builder->createField('dateSent', 'datetime')
|
||||
->columnName('date_sent')
|
||||
->nullable()
|
||||
->build();
|
||||
|
||||
$builder->createField('options', 'array')
|
||||
->nullable()
|
||||
->build();
|
||||
}
|
||||
|
||||
public function getId(): int
|
||||
{
|
||||
return (int) $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getAttempts()
|
||||
{
|
||||
return $this->attempts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $attempts
|
||||
*/
|
||||
public function setAttempts($attempts): void
|
||||
{
|
||||
$this->attempts = $attempts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
*/
|
||||
public function setOptions($options): void
|
||||
{
|
||||
$this->options[] = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getChannel()
|
||||
{
|
||||
return $this->channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $channel
|
||||
*/
|
||||
public function setChannel($channel): void
|
||||
{
|
||||
$this->channel = $channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getChannelId()
|
||||
{
|
||||
return $this->channelId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $channelId
|
||||
*
|
||||
* @return MessageQueue
|
||||
*/
|
||||
public function setChannelId($channelId)
|
||||
{
|
||||
$this->channelId = $channelId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Event|null
|
||||
*/
|
||||
public function getEvent()
|
||||
{
|
||||
return $this->event;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MessageQueue
|
||||
*/
|
||||
public function setEvent(Event $event)
|
||||
{
|
||||
$this->event = $event;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTimeInterface
|
||||
*/
|
||||
public function getDatePublished()
|
||||
{
|
||||
return $this->datePublished;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $datePublished
|
||||
*/
|
||||
public function setDatePublished($datePublished): void
|
||||
{
|
||||
$this->datePublished = $datePublished;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTimeInterface
|
||||
*/
|
||||
public function getDateSent()
|
||||
{
|
||||
return $this->dateSent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $dateSent
|
||||
*/
|
||||
public function setDateSent($dateSent): void
|
||||
{
|
||||
$this->dateSent = $dateSent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTimeInterface
|
||||
*/
|
||||
public function getLastAttempt()
|
||||
{
|
||||
return $this->lastAttempt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $lastAttempt
|
||||
*/
|
||||
public function setLastAttempt($lastAttempt): void
|
||||
{
|
||||
$this->lastAttempt = $lastAttempt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Lead
|
||||
*/
|
||||
public function getLead()
|
||||
{
|
||||
return $this->lead;
|
||||
}
|
||||
|
||||
public function setLead(Lead $lead): void
|
||||
{
|
||||
$this->lead = $lead;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getMaxAttempts()
|
||||
{
|
||||
return $this->maxAttempts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $maxAttempts
|
||||
*/
|
||||
public function setMaxAttempts($maxAttempts): void
|
||||
{
|
||||
$this->maxAttempts = $maxAttempts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getPriority()
|
||||
{
|
||||
return $this->priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $priority
|
||||
*/
|
||||
public function setPriority($priority): void
|
||||
{
|
||||
$this->priority = $priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTimeInterface
|
||||
*/
|
||||
public function getScheduledDate()
|
||||
{
|
||||
return $this->scheduledDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $scheduledDate
|
||||
*/
|
||||
public function setScheduledDate($scheduledDate): void
|
||||
{
|
||||
$this->scheduledDate = $scheduledDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getStatus()
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $status
|
||||
*/
|
||||
public function setStatus($status): void
|
||||
{
|
||||
$this->status = $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getSuccess()
|
||||
{
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isSuccess()
|
||||
{
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $success
|
||||
*/
|
||||
public function setSuccess($success = true): void
|
||||
{
|
||||
$this->success = $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isFailed()
|
||||
{
|
||||
return $this->failed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $failed
|
||||
*
|
||||
* @return MessageQueue
|
||||
*/
|
||||
public function setFailed($failed = true)
|
||||
{
|
||||
$this->failed = $failed;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isProcessed()
|
||||
{
|
||||
return $this->processed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $processed
|
||||
*
|
||||
* @return MessageQueue
|
||||
*/
|
||||
public function setProcessed($processed = true)
|
||||
{
|
||||
$this->processed = $processed;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function getMetadata()
|
||||
{
|
||||
return $this->options['metadata'] ?? [];
|
||||
}
|
||||
|
||||
public function setMetadata(array $metadata = []): void
|
||||
{
|
||||
$this->metadataUpdated = true;
|
||||
$this->options['metadata'] = $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function wasMetadataUpdated()
|
||||
{
|
||||
return $this->metadataUpdated;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\ChannelBundle\Entity;
|
||||
|
||||
use Doctrine\Common\Collections\Order;
|
||||
use Doctrine\DBAL\ArrayParameterType;
|
||||
use Mautic\CoreBundle\Entity\CommonRepository;
|
||||
use Mautic\LeadBundle\Entity\TimelineTrait;
|
||||
|
||||
/**
|
||||
* @extends CommonRepository<MessageQueue>
|
||||
*/
|
||||
class MessageQueueRepository extends CommonRepository
|
||||
{
|
||||
use TimelineTrait;
|
||||
|
||||
public function findMessage($channel, $channelId, $leadId)
|
||||
{
|
||||
$results = $this->createQueryBuilder('mq')
|
||||
->where('IDENTITY(mq.lead) = :leadId')
|
||||
->andWhere('mq.channel = :channel')
|
||||
->andWhere('mq.channelId = :channelId')
|
||||
->setParameter('leadId', $leadId)
|
||||
->setParameter('channel', $channel)
|
||||
->setParameter('channelId', $channelId)
|
||||
->getQuery()
|
||||
->getResult();
|
||||
|
||||
return ($results) ? $results[0] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, MessageQueue>
|
||||
*/
|
||||
public function getQueuedMessages($limit, $processStarted, $channel = null, $channelId = null)
|
||||
{
|
||||
$q = $this->createQueryBuilder('mq');
|
||||
|
||||
$q->where($q->expr()->eq('mq.success', ':success'))
|
||||
->andWhere($q->expr()->lt('mq.attempts', 'mq.maxAttempts'))
|
||||
->andWhere('mq.lastAttempt is null or mq.lastAttempt < :processStarted')
|
||||
->andWhere('mq.scheduledDate <= :processStarted')
|
||||
->setParameter('success', false, 'boolean')
|
||||
->setParameter('processStarted', $processStarted)
|
||||
->indexBy('mq', 'mq.id');
|
||||
|
||||
$q->orderBy('mq.priority, mq.scheduledDate', Order::Ascending->value);
|
||||
|
||||
if ($limit) {
|
||||
$q->setMaxResults((int) $limit);
|
||||
}
|
||||
|
||||
if ($channel) {
|
||||
$q->andWhere($q->expr()->eq('mq.channel', ':channel'))
|
||||
->setParameter('channel', $channel);
|
||||
|
||||
if ($channelId) {
|
||||
$q->andWhere($q->expr()->eq('mq.channelId', (int) $channelId));
|
||||
}
|
||||
}
|
||||
|
||||
return $q->getQuery()->getResult();
|
||||
}
|
||||
|
||||
public function getQueuedChannelCount($channel, ?array $ids = null): int
|
||||
{
|
||||
$q = $this->getEntityManager()->getConnection()->createQueryBuilder();
|
||||
|
||||
$expr = $q->expr()->and(
|
||||
$q->expr()->eq($this->getTableAlias().'.channel', ':channel'),
|
||||
$q->expr()->neq($this->getTableAlias().'.status', ':status')
|
||||
);
|
||||
|
||||
if (!empty($ids)) {
|
||||
$expr = $expr->with(
|
||||
$q->expr()->in($this->getTableAlias().'.channel_id', $ids)
|
||||
);
|
||||
}
|
||||
|
||||
return (int) $q->select('count(*)')
|
||||
->from(MAUTIC_TABLE_PREFIX.'message_queue', $this->getTableAlias())
|
||||
->where($expr)
|
||||
->setParameter('channel', $channel)
|
||||
->setParameter('status', MessageQueue::STATUS_SENT)
|
||||
->setParameter('ids', $ids, ArrayParameterType::INTEGER)
|
||||
->executeQuery()
|
||||
->fetchOne();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a lead's point log.
|
||||
*
|
||||
* @param int|null $leadId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLeadTimelineEvents($leadId = null, array $options = [])
|
||||
{
|
||||
$query = $this->getEntityManager()->getConnection()->createQueryBuilder()
|
||||
->from(MAUTIC_TABLE_PREFIX.'message_queue', 'mq')
|
||||
->select('mq.id, mq.lead_id, mq.channel as channelName, mq.channel_id as channelId,
|
||||
mq.priority as priority, mq.attempts, mq.success, mq.status, mq.date_published as dateAdded,
|
||||
mq.scheduled_date as scheduledDate, mq.last_attempt as lastAttempt, mq.date_sent as dateSent');
|
||||
|
||||
if ($leadId) {
|
||||
$query->where('mq.lead_id = :leadId')
|
||||
->setParameter('leadId', $leadId);
|
||||
}
|
||||
|
||||
if (isset($options['search']) && $options['search']) {
|
||||
$query->andWhere(
|
||||
$query->expr()->like('mq.channel', ':search')
|
||||
)->setParameter('search', '%'.$options['search'].'%');
|
||||
}
|
||||
|
||||
return $this->getTimelineResults($query, $options, 'mq.channel', 'mq.date_published', [], ['dateAdded'], null, 'mq.id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\ChannelBundle\Entity;
|
||||
|
||||
use Mautic\CategoryBundle\Entity\Category;
|
||||
use Mautic\CoreBundle\Entity\CommonRepository;
|
||||
use Mautic\ProjectBundle\Entity\ProjectRepositoryTrait;
|
||||
|
||||
/**
|
||||
* @extends CommonRepository<Message>
|
||||
*/
|
||||
class MessageRepository extends CommonRepository
|
||||
{
|
||||
use ProjectRepositoryTrait;
|
||||
|
||||
/**
|
||||
* @return \Doctrine\ORM\Tools\Pagination\Paginator
|
||||
*/
|
||||
public function getEntities(array $args = [])
|
||||
{
|
||||
$qb = $this->createQueryBuilder($this->getTableAlias());
|
||||
// Because of this inner join pagination is not working properly. Removing this doesn't seem to break any feature.
|
||||
// $qb->join(Channel::class, 'channel', 'WITH', 'channel.message = '.$this->getTableAlias().'.id');
|
||||
$qb->leftJoin(Category::class, 'cat', 'WITH', 'cat.id = '.$this->getTableAlias().'.category');
|
||||
$qb->groupBy($this->getTableAlias().'.id');
|
||||
|
||||
$args['qb'] = $qb;
|
||||
|
||||
return parent::getEntities($args);
|
||||
}
|
||||
|
||||
public function getTableAlias(): string
|
||||
{
|
||||
return 'm';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $search
|
||||
* @param int $limit
|
||||
* @param int $start
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMessageList($search = '', $limit = 10, $start = 0)
|
||||
{
|
||||
$alias = $this->getTableAlias();
|
||||
$q = $this->createQueryBuilder($this->getTableAlias());
|
||||
$q->select('partial '.$alias.'.{id, name, description}');
|
||||
|
||||
if (!empty($search)) {
|
||||
if (is_array($search)) {
|
||||
$search = array_map('intval', $search);
|
||||
$q->andWhere($q->expr()->in($alias.'.id', ':search'))
|
||||
->setParameter('search', $search);
|
||||
} else {
|
||||
$q->andWhere($q->expr()->like($alias.'.name', ':search'))
|
||||
->setParameter('search', "%{$search}%");
|
||||
}
|
||||
}
|
||||
$q->andWhere($q->expr()->eq($alias.'.isPublished', true));
|
||||
|
||||
if (!empty($limit)) {
|
||||
$q->setFirstResult($start)
|
||||
->setMaxResults($limit);
|
||||
}
|
||||
|
||||
return $q->getQuery()->getArrayResult();
|
||||
}
|
||||
|
||||
public function getMessageChannels($messageId): array
|
||||
{
|
||||
$q = $this->_em->getConnection()->createQueryBuilder();
|
||||
$q->from(MAUTIC_TABLE_PREFIX.'message_channels', 'mc')
|
||||
->select('id, channel, channel_id, properties')
|
||||
->where($q->expr()->eq('message_id', ':messageId'))
|
||||
->setParameter('messageId', $messageId)
|
||||
->andWhere($q->expr()->eq('is_enabled', true));
|
||||
|
||||
$results = $q->executeQuery()->fetchAllAssociative();
|
||||
|
||||
$channels = [];
|
||||
foreach ($results as $result) {
|
||||
$result['properties'] = json_decode($result['properties'], true);
|
||||
$channels[$result['channel']] = $result;
|
||||
}
|
||||
|
||||
return $channels;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getChannelMessageByChannelId($channelId)
|
||||
{
|
||||
$q = $this->_em->getConnection()->createQueryBuilder();
|
||||
$q->from(MAUTIC_TABLE_PREFIX.'message_channels', 'mc')
|
||||
->select('id, channel, channel_id, properties, message_id')
|
||||
->where($q->expr()->eq('id', ':channelId'))
|
||||
->setParameter('channelId', $channelId)
|
||||
->andWhere($q->expr()->eq('is_enabled', true));
|
||||
|
||||
return $q->executeQuery()->fetchAssociative();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $filter
|
||||
*
|
||||
* @return mixed[]
|
||||
*/
|
||||
protected function addSearchCommandWhereClause($q, $filter): array
|
||||
{
|
||||
return match ($filter->command) {
|
||||
$this->translator->trans('mautic.project.searchcommand.name'),
|
||||
$this->translator->trans('mautic.project.searchcommand.name', [], null, 'en_US') => $this->handleProjectFilter(
|
||||
$this->_em->getConnection()->createQueryBuilder(),
|
||||
'message_id',
|
||||
'message_projects_xref',
|
||||
$this->getTableAlias(),
|
||||
$filter->string,
|
||||
$filter->not
|
||||
),
|
||||
default => $this->addStandardSearchCommandWhereClause($q, $filter),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getSearchCommands(): array
|
||||
{
|
||||
return array_merge([
|
||||
'mautic.core.searchcommand.ispublished',
|
||||
'mautic.core.searchcommand.isunpublished',
|
||||
'mautic.core.searchcommand.ismine',
|
||||
'mautic.core.searchcommand.isuncategorized',
|
||||
'mautic.project.searchcommand.name',
|
||||
], parent::getSearchCommands());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user