2019-05-09 06:54:39 +00:00
|
|
|
<?php
|
|
|
|
|
|
2020-03-24 17:56:32 +00:00
|
|
|
namespace Appwrite\Event;
|
2019-05-09 06:54:39 +00:00
|
|
|
|
2022-03-29 08:30:57 +00:00
|
|
|
use InvalidArgumentException;
|
2022-04-04 06:30:07 +00:00
|
|
|
use Utopia\Database\Document;
|
2025-01-29 14:13:58 +00:00
|
|
|
use Utopia\Queue\Publisher;
|
|
|
|
|
use Utopia\Queue\Queue;
|
2019-05-09 06:54:39 +00:00
|
|
|
|
|
|
|
|
class Event
|
|
|
|
|
{
|
2023-10-17 04:23:33 +00:00
|
|
|
public const DATABASE_QUEUE_NAME = 'v1-database';
|
2022-06-02 13:03:37 +00:00
|
|
|
public const DATABASE_CLASS_NAME = 'DatabaseV1';
|
2021-06-17 18:22:06 +00:00
|
|
|
|
2022-06-02 13:03:37 +00:00
|
|
|
public const DELETE_QUEUE_NAME = 'v1-deletes';
|
|
|
|
|
public const DELETE_CLASS_NAME = 'DeletesV1';
|
2020-12-22 12:51:46 +00:00
|
|
|
|
2022-06-02 13:03:37 +00:00
|
|
|
public const AUDITS_QUEUE_NAME = 'v1-audits';
|
|
|
|
|
public const AUDITS_CLASS_NAME = 'AuditsV1';
|
2020-12-22 12:51:46 +00:00
|
|
|
|
2022-06-02 13:03:37 +00:00
|
|
|
public const MAILS_QUEUE_NAME = 'v1-mails';
|
|
|
|
|
public const MAILS_CLASS_NAME = 'MailsV1';
|
2020-12-27 17:57:35 +00:00
|
|
|
|
2022-06-02 13:03:37 +00:00
|
|
|
public const FUNCTIONS_QUEUE_NAME = 'v1-functions';
|
|
|
|
|
public const FUNCTIONS_CLASS_NAME = 'FunctionsV1';
|
2020-12-27 17:57:35 +00:00
|
|
|
|
2025-01-30 04:06:57 +00:00
|
|
|
public const STATS_RESOURCES_QUEUE_NAME = 'v1-stats-resources';
|
2025-02-05 09:28:44 +00:00
|
|
|
public const STATS_RESOURCES_CLASS_NAME = 'StatsResourcesV1';
|
2025-01-30 04:06:57 +00:00
|
|
|
|
2025-01-30 07:07:10 +00:00
|
|
|
public const STATS_USAGE_QUEUE_NAME = 'v1-stats-usage';
|
|
|
|
|
public const STATS_USAGE_CLASS_NAME = 'StatsUsageV1';
|
|
|
|
|
|
2022-06-02 13:03:37 +00:00
|
|
|
public const WEBHOOK_QUEUE_NAME = 'v1-webhooks';
|
|
|
|
|
public const WEBHOOK_CLASS_NAME = 'WebhooksV1';
|
2020-12-27 17:57:35 +00:00
|
|
|
|
2022-06-02 13:03:37 +00:00
|
|
|
public const CERTIFICATES_QUEUE_NAME = 'v1-certificates';
|
|
|
|
|
public const CERTIFICATES_CLASS_NAME = 'CertificatesV1';
|
2022-01-31 09:46:24 +00:00
|
|
|
|
2022-06-02 13:03:37 +00:00
|
|
|
public const BUILDS_QUEUE_NAME = 'v1-builds';
|
|
|
|
|
public const BUILDS_CLASS_NAME = 'BuildsV1';
|
2019-05-09 06:54:39 +00:00
|
|
|
|
2022-06-08 13:57:34 +00:00
|
|
|
public const MESSAGING_QUEUE_NAME = 'v1-messaging';
|
|
|
|
|
public const MESSAGING_CLASS_NAME = 'MessagingV1';
|
|
|
|
|
|
2023-08-04 16:21:41 +00:00
|
|
|
public const MIGRATIONS_QUEUE_NAME = 'v1-migrations';
|
|
|
|
|
public const MIGRATIONS_CLASS_NAME = 'MigrationsV1';
|
|
|
|
|
|
2022-03-29 08:30:57 +00:00
|
|
|
protected string $queue = '';
|
|
|
|
|
protected string $class = '';
|
2022-04-04 06:30:07 +00:00
|
|
|
protected string $event = '';
|
2022-03-29 08:30:57 +00:00
|
|
|
protected array $params = [];
|
2024-04-03 03:36:21 +00:00
|
|
|
protected array $sensitive = [];
|
2022-04-04 06:30:07 +00:00
|
|
|
protected array $payload = [];
|
2022-06-22 10:51:49 +00:00
|
|
|
protected array $context = [];
|
2025-12-07 20:29:45 +00:00
|
|
|
protected array $platform = [];
|
2022-04-04 06:30:07 +00:00
|
|
|
protected ?Document $project = null;
|
|
|
|
|
protected ?Document $user = null;
|
2024-09-07 10:20:23 +00:00
|
|
|
protected ?string $userId = null;
|
2025-12-07 20:29:45 +00:00
|
|
|
|
2023-10-17 19:08:01 +00:00
|
|
|
protected bool $paused = false;
|
2019-05-09 06:54:39 +00:00
|
|
|
|
2025-04-23 14:42:39 +00:00
|
|
|
/** @var bool Non-critical events will not throw an exception when enqueuing of the event fails. */
|
|
|
|
|
protected bool $critical = true;
|
|
|
|
|
|
2019-05-09 06:54:39 +00:00
|
|
|
/**
|
2025-01-29 14:13:58 +00:00
|
|
|
* @param Publisher $publisher
|
2022-03-29 08:30:57 +00:00
|
|
|
* @return void
|
2019-05-09 06:54:39 +00:00
|
|
|
*/
|
2025-01-29 14:13:58 +00:00
|
|
|
public function __construct(protected Publisher $publisher)
|
2023-06-04 08:19:49 +00:00
|
|
|
{
|
|
|
|
|
}
|
2019-05-09 06:54:39 +00:00
|
|
|
|
2024-11-08 20:55:53 +00:00
|
|
|
/**
|
|
|
|
|
* Set paused state for this event.
|
|
|
|
|
*/
|
|
|
|
|
public function setPaused(bool $paused): self
|
|
|
|
|
{
|
|
|
|
|
$this->paused = $paused;
|
|
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get paused state for this event.
|
|
|
|
|
*/
|
|
|
|
|
public function getPaused(): bool
|
|
|
|
|
{
|
|
|
|
|
return $this->paused;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-07 08:51:12 +00:00
|
|
|
/**
|
2022-03-29 08:30:57 +00:00
|
|
|
* Set queue used for this event.
|
|
|
|
|
*
|
2020-12-07 08:51:12 +00:00
|
|
|
* @param string $queue
|
2022-03-29 08:30:57 +00:00
|
|
|
* @return Event
|
2020-12-07 08:51:12 +00:00
|
|
|
*/
|
|
|
|
|
public function setQueue(string $queue): self
|
|
|
|
|
{
|
|
|
|
|
$this->queue = $queue;
|
2022-04-04 06:30:07 +00:00
|
|
|
|
2020-12-07 08:51:12 +00:00
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2022-03-29 08:30:57 +00:00
|
|
|
* Get queue used for this event.
|
|
|
|
|
*
|
2020-12-07 08:51:12 +00:00
|
|
|
* @return string
|
|
|
|
|
*/
|
2022-03-29 08:30:57 +00:00
|
|
|
public function getQueue(): string
|
2020-12-07 08:51:12 +00:00
|
|
|
{
|
|
|
|
|
return $this->queue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-04 06:30:07 +00:00
|
|
|
/**
|
|
|
|
|
* Set event name used for this event.
|
|
|
|
|
* @param string $event
|
|
|
|
|
* @return Event
|
|
|
|
|
*/
|
|
|
|
|
public function setEvent(string $event): self
|
|
|
|
|
{
|
|
|
|
|
$this->event = $event;
|
|
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get event name used for this event.
|
|
|
|
|
*
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
public function getEvent(): string
|
|
|
|
|
{
|
|
|
|
|
return $this->event;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-10 13:03:34 +00:00
|
|
|
/**
|
|
|
|
|
* Set project for this event.
|
|
|
|
|
*
|
|
|
|
|
* @param Document $project
|
|
|
|
|
* @return self
|
|
|
|
|
*/
|
2022-04-04 06:30:07 +00:00
|
|
|
public function setProject(Document $project): self
|
2025-01-16 07:44:47 +00:00
|
|
|
{
|
|
|
|
|
$this->project = $project;
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-10 13:03:34 +00:00
|
|
|
/**
|
|
|
|
|
* Get project for this event.
|
|
|
|
|
*
|
2022-11-16 17:32:35 +00:00
|
|
|
* @return ?Document
|
2022-05-10 13:03:34 +00:00
|
|
|
*/
|
2022-11-16 17:32:35 +00:00
|
|
|
public function getProject(): ?Document
|
2022-04-04 06:30:07 +00:00
|
|
|
{
|
2022-04-13 12:39:31 +00:00
|
|
|
return $this->project;
|
2022-04-04 06:30:07 +00:00
|
|
|
}
|
|
|
|
|
|
2025-12-07 20:29:45 +00:00
|
|
|
/**
|
|
|
|
|
* Set platform for this event.
|
|
|
|
|
*
|
|
|
|
|
* @param array $platform
|
|
|
|
|
* @return self
|
|
|
|
|
*/
|
|
|
|
|
public function setPlatform(array $platform): self
|
|
|
|
|
{
|
|
|
|
|
$this->platform = $platform;
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get platform for this event.
|
|
|
|
|
*
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
|
|
|
|
public function getPlatform(): array
|
|
|
|
|
{
|
|
|
|
|
return $this->platform;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-10 13:03:34 +00:00
|
|
|
/**
|
|
|
|
|
* Set user for this event.
|
|
|
|
|
*
|
|
|
|
|
* @param Document $user
|
|
|
|
|
* @return self
|
|
|
|
|
*/
|
2022-04-04 06:30:07 +00:00
|
|
|
public function setUser(Document $user): self
|
|
|
|
|
{
|
2022-04-13 12:39:31 +00:00
|
|
|
$this->user = $user;
|
2022-04-04 06:30:07 +00:00
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-07 10:20:23 +00:00
|
|
|
/**
|
|
|
|
|
* Set user ID for this event.
|
|
|
|
|
*
|
|
|
|
|
* @return self
|
|
|
|
|
*/
|
|
|
|
|
public function setUserId(string $userId): self
|
|
|
|
|
{
|
|
|
|
|
$this->userId = $userId;
|
|
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-10 13:03:34 +00:00
|
|
|
/**
|
2022-11-16 17:32:35 +00:00
|
|
|
* Get user responsible for triggering this event.
|
2022-05-10 13:03:34 +00:00
|
|
|
*
|
2022-11-16 17:32:35 +00:00
|
|
|
* @return ?Document
|
2022-05-10 13:03:34 +00:00
|
|
|
*/
|
2022-11-16 17:32:35 +00:00
|
|
|
public function getUser(): ?Document
|
2022-04-04 06:30:07 +00:00
|
|
|
{
|
2022-04-13 12:39:31 +00:00
|
|
|
return $this->user;
|
2022-04-04 06:30:07 +00:00
|
|
|
}
|
|
|
|
|
|
2024-09-07 10:20:23 +00:00
|
|
|
/**
|
|
|
|
|
* Get user responsible for triggering this event.
|
|
|
|
|
*/
|
|
|
|
|
public function getUserId(): ?string
|
|
|
|
|
{
|
|
|
|
|
return $this->userId;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-10 13:03:34 +00:00
|
|
|
/**
|
|
|
|
|
* Set payload for this event.
|
|
|
|
|
*
|
2022-05-16 17:15:38 +00:00
|
|
|
* @param array $payload
|
2024-04-03 03:36:21 +00:00
|
|
|
* @param array $sensitive
|
2022-05-10 13:03:34 +00:00
|
|
|
* @return self
|
|
|
|
|
*/
|
2024-04-03 03:36:21 +00:00
|
|
|
public function setPayload(array $payload, array $sensitive = []): self
|
2022-04-04 06:30:07 +00:00
|
|
|
{
|
|
|
|
|
$this->payload = $payload;
|
|
|
|
|
|
2024-04-03 03:36:21 +00:00
|
|
|
foreach ($sensitive as $key) {
|
|
|
|
|
$this->sensitive[$key] = true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-04 06:30:07 +00:00
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-10 13:03:34 +00:00
|
|
|
/**
|
|
|
|
|
* Get payload for this event.
|
|
|
|
|
*
|
2022-05-16 17:15:38 +00:00
|
|
|
* @return array
|
2022-05-10 13:03:34 +00:00
|
|
|
*/
|
2022-04-04 06:30:07 +00:00
|
|
|
public function getPayload(): array
|
|
|
|
|
{
|
|
|
|
|
return $this->payload;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-10 13:03:34 +00:00
|
|
|
/**
|
|
|
|
|
* Set context for this event.
|
|
|
|
|
*
|
2022-06-22 10:51:49 +00:00
|
|
|
* @param string $key
|
2022-05-10 13:03:34 +00:00
|
|
|
* @param Document $context
|
|
|
|
|
* @return self
|
|
|
|
|
*/
|
2022-06-22 10:51:49 +00:00
|
|
|
public function setContext(string $key, Document $context): self
|
2022-04-04 06:30:07 +00:00
|
|
|
{
|
2022-06-22 10:51:49 +00:00
|
|
|
$this->context[$key] = $context;
|
2022-04-04 06:30:07 +00:00
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-10 13:03:34 +00:00
|
|
|
/**
|
|
|
|
|
* Get context for this event.
|
|
|
|
|
*
|
2022-06-22 10:51:49 +00:00
|
|
|
* @param string $key
|
|
|
|
|
*
|
2022-05-16 17:16:08 +00:00
|
|
|
* @return null|Document
|
2022-05-10 13:03:34 +00:00
|
|
|
*/
|
2022-06-22 10:51:49 +00:00
|
|
|
public function getContext(string $key): ?Document
|
2022-04-04 06:30:07 +00:00
|
|
|
{
|
2022-06-22 10:51:49 +00:00
|
|
|
return $this->context[$key] ?? null;
|
2022-04-04 06:30:07 +00:00
|
|
|
}
|
|
|
|
|
|
2020-12-07 08:51:12 +00:00
|
|
|
/**
|
2022-03-29 08:30:57 +00:00
|
|
|
* Set class used for this event.
|
2020-12-07 08:51:12 +00:00
|
|
|
* @param string $class
|
2022-05-10 13:03:34 +00:00
|
|
|
* @return self
|
2020-12-07 08:51:12 +00:00
|
|
|
*/
|
|
|
|
|
public function setClass(string $class): self
|
|
|
|
|
{
|
|
|
|
|
$this->class = $class;
|
2022-04-04 06:30:07 +00:00
|
|
|
|
2020-12-07 08:51:12 +00:00
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2022-03-29 08:30:57 +00:00
|
|
|
* Get class used for this event.
|
|
|
|
|
*
|
2020-12-07 08:51:12 +00:00
|
|
|
* @return string
|
|
|
|
|
*/
|
2022-03-29 08:30:57 +00:00
|
|
|
public function getClass(): string
|
2020-12-07 08:51:12 +00:00
|
|
|
{
|
|
|
|
|
return $this->class;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-09 06:54:39 +00:00
|
|
|
/**
|
2022-03-29 08:30:57 +00:00
|
|
|
* Set param of event.
|
2019-09-06 17:04:26 +00:00
|
|
|
*
|
2022-03-29 08:30:57 +00:00
|
|
|
* @param string $key
|
|
|
|
|
* @param mixed $value
|
2022-05-10 13:03:34 +00:00
|
|
|
* @return self
|
2019-05-09 06:54:39 +00:00
|
|
|
*/
|
2022-03-29 08:30:57 +00:00
|
|
|
public function setParam(string $key, mixed $value): self
|
2019-05-09 06:54:39 +00:00
|
|
|
{
|
|
|
|
|
$this->params[$key] = $value;
|
2019-09-06 17:04:26 +00:00
|
|
|
|
2019-05-09 06:54:39 +00:00
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2022-03-29 08:30:57 +00:00
|
|
|
* Get param of event.
|
2019-09-06 17:04:26 +00:00
|
|
|
*
|
2022-03-29 08:30:57 +00:00
|
|
|
* @param string $key
|
|
|
|
|
* @return mixed
|
2019-05-09 06:54:39 +00:00
|
|
|
*/
|
2022-03-29 08:30:57 +00:00
|
|
|
public function getParam(string $key): mixed
|
2019-05-09 06:54:39 +00:00
|
|
|
{
|
2022-03-29 08:30:57 +00:00
|
|
|
return $this->params[$key] ?? null;
|
2019-05-09 06:54:39 +00:00
|
|
|
}
|
|
|
|
|
|
2022-04-04 06:30:07 +00:00
|
|
|
/**
|
|
|
|
|
* Get all params of the event.
|
|
|
|
|
*
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
|
|
|
|
public function getParams(): array
|
|
|
|
|
{
|
|
|
|
|
return $this->params;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 05:08:39 +00:00
|
|
|
/**
|
|
|
|
|
* Get trimmed values for sensitive/large payload fields.
|
|
|
|
|
* Override this method in child classes to add more fields to trim.
|
|
|
|
|
*
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
|
|
|
|
protected function trimPayload(): array
|
|
|
|
|
{
|
|
|
|
|
$trimmed = [];
|
|
|
|
|
|
|
|
|
|
if ($this->project) {
|
|
|
|
|
$trimmed['project'] = new Document([
|
|
|
|
|
'$id' => $this->project->getId(),
|
2025-05-26 05:42:11 +00:00
|
|
|
'$sequence' => $this->project->getSequence(),
|
2025-01-17 05:08:39 +00:00
|
|
|
'database' => $this->project->getAttribute('database')
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $trimmed;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-09 06:54:39 +00:00
|
|
|
/**
|
2019-09-06 17:04:26 +00:00
|
|
|
* Execute Event.
|
2022-03-29 08:30:57 +00:00
|
|
|
*
|
2022-04-04 06:30:07 +00:00
|
|
|
* @return string|bool
|
2022-03-29 08:30:57 +00:00
|
|
|
* @throws InvalidArgumentException
|
2019-05-09 06:54:39 +00:00
|
|
|
*/
|
2022-04-04 06:30:07 +00:00
|
|
|
public function trigger(): string|bool
|
2019-05-09 06:54:39 +00:00
|
|
|
{
|
2025-04-11 14:52:19 +00:00
|
|
|
|
2024-11-08 20:55:53 +00:00
|
|
|
if ($this->paused) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 05:12:06 +00:00
|
|
|
/** The getter is required since events like Databases need to override the queue name depending on the project */
|
2025-01-29 14:13:58 +00:00
|
|
|
$queue = new Queue($this->getQueue());
|
2025-01-16 07:44:47 +00:00
|
|
|
|
2025-01-17 05:08:39 +00:00
|
|
|
// Merge the base payload with any trimmed values
|
|
|
|
|
$payload = array_merge($this->preparePayload(), $this->trimPayload());
|
2025-04-11 14:52:19 +00:00
|
|
|
|
2025-04-23 14:42:39 +00:00
|
|
|
try {
|
|
|
|
|
return $this->publisher->enqueue($queue, $payload);
|
|
|
|
|
} catch (\Throwable $th) {
|
|
|
|
|
if ($this->critical) {
|
|
|
|
|
throw $th;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2025-01-17 05:08:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Prepare payload for queue. Can be overridden by child classes to customize payload.
|
|
|
|
|
*
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
|
|
|
|
protected function preparePayload(): array
|
|
|
|
|
{
|
|
|
|
|
return [
|
2022-04-13 12:39:31 +00:00
|
|
|
'project' => $this->project,
|
|
|
|
|
'user' => $this->user,
|
2024-09-07 10:20:23 +00:00
|
|
|
'userId' => $this->userId,
|
2022-04-04 06:30:07 +00:00
|
|
|
'payload' => $this->payload,
|
2022-04-18 16:21:45 +00:00
|
|
|
'context' => $this->context,
|
2022-04-04 06:30:07 +00:00
|
|
|
'events' => Event::generateEvents($this->getEvent(), $this->getParams())
|
2025-01-17 05:08:39 +00:00
|
|
|
];
|
2020-07-04 13:06:23 +00:00
|
|
|
}
|
|
|
|
|
|
2022-03-29 08:30:57 +00:00
|
|
|
/**
|
|
|
|
|
* Resets event.
|
|
|
|
|
*
|
2022-05-10 13:03:34 +00:00
|
|
|
* @return self
|
2022-03-29 08:30:57 +00:00
|
|
|
*/
|
2020-07-04 13:06:23 +00:00
|
|
|
public function reset(): self
|
|
|
|
|
{
|
|
|
|
|
$this->params = [];
|
2024-04-03 03:36:21 +00:00
|
|
|
$this->sensitive = [];
|
2025-08-05 06:22:58 +00:00
|
|
|
$this->event = '';
|
|
|
|
|
$this->payload = [];
|
2020-07-04 13:06:23 +00:00
|
|
|
|
|
|
|
|
return $this;
|
2019-05-09 06:54:39 +00:00
|
|
|
}
|
2022-03-29 08:30:57 +00:00
|
|
|
|
2022-04-18 16:21:45 +00:00
|
|
|
/**
|
|
|
|
|
* Parses event pattern and returns the parts in their respective section.
|
|
|
|
|
*
|
|
|
|
|
* @param string $pattern
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
2022-04-04 06:30:07 +00:00
|
|
|
public static function parseEventPattern(string $pattern): array
|
2022-03-29 08:30:57 +00:00
|
|
|
{
|
|
|
|
|
$parts = \explode('.', $pattern);
|
|
|
|
|
$count = \count($parts);
|
|
|
|
|
|
|
|
|
|
/**
|
2022-05-10 13:03:34 +00:00
|
|
|
* Identify all sections of the pattern.
|
2022-03-29 08:30:57 +00:00
|
|
|
*/
|
2022-04-04 06:30:07 +00:00
|
|
|
$type = $parts[0] ?? false;
|
|
|
|
|
$resource = $parts[1] ?? false;
|
|
|
|
|
$hasSubResource = $count > 3 && \str_starts_with($parts[3], '[');
|
2022-06-22 10:51:49 +00:00
|
|
|
$hasSubSubResource = $count > 5 && \str_starts_with($parts[5], '[') && $hasSubResource;
|
2022-03-29 08:30:57 +00:00
|
|
|
|
2022-04-04 06:30:07 +00:00
|
|
|
if ($hasSubResource) {
|
2022-03-29 08:30:57 +00:00
|
|
|
$subType = $parts[2];
|
|
|
|
|
$subResource = $parts[3];
|
2022-06-22 10:51:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($hasSubSubResource) {
|
|
|
|
|
$subSubType = $parts[4];
|
|
|
|
|
$subSubResource = $parts[5];
|
|
|
|
|
if ($count == 8) {
|
|
|
|
|
$attribute = $parts[7];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($hasSubResource && !$hasSubSubResource) {
|
2022-03-29 08:30:57 +00:00
|
|
|
if ($count === 6) {
|
|
|
|
|
$attribute = $parts[5];
|
|
|
|
|
}
|
2022-06-22 10:51:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!$hasSubResource) {
|
2022-03-29 08:30:57 +00:00
|
|
|
if ($count === 4) {
|
|
|
|
|
$attribute = $parts[3];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-04 06:30:07 +00:00
|
|
|
$subType ??= false;
|
|
|
|
|
$subResource ??= false;
|
2022-06-22 10:51:49 +00:00
|
|
|
$subSubType ??= false;
|
|
|
|
|
$subSubResource ??= false;
|
2022-04-04 06:30:07 +00:00
|
|
|
$attribute ??= false;
|
|
|
|
|
$action = match (true) {
|
|
|
|
|
!$hasSubResource && $count > 2 => $parts[2],
|
2022-06-22 10:51:49 +00:00
|
|
|
$hasSubSubResource => $parts[6] ?? false,
|
2022-04-04 06:30:07 +00:00
|
|
|
$hasSubResource && $count > 4 => $parts[4],
|
|
|
|
|
default => false
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
'type' => $type,
|
|
|
|
|
'resource' => $resource,
|
|
|
|
|
'subType' => $subType,
|
|
|
|
|
'subResource' => $subResource,
|
2022-06-22 10:51:49 +00:00
|
|
|
'subSubType' => $subSubType,
|
|
|
|
|
'subSubResource' => $subSubResource,
|
2022-04-04 06:30:07 +00:00
|
|
|
'action' => $action,
|
|
|
|
|
'attribute' => $attribute,
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-18 16:21:45 +00:00
|
|
|
/**
|
|
|
|
|
* Generates all possible events from a pattern.
|
|
|
|
|
*
|
|
|
|
|
* @param string $pattern
|
|
|
|
|
* @param array $params
|
|
|
|
|
* @return array
|
|
|
|
|
* @throws \InvalidArgumentException
|
|
|
|
|
*/
|
2022-06-02 13:09:04 +00:00
|
|
|
public static function generateEvents(string $pattern, array $params = []): array
|
2022-04-04 06:30:07 +00:00
|
|
|
{
|
2022-05-10 13:03:34 +00:00
|
|
|
// $params = \array_filter($params, fn($param) => !\is_array($param));
|
2022-03-29 08:30:57 +00:00
|
|
|
$paramKeys = \array_keys($params);
|
|
|
|
|
$paramValues = \array_values($params);
|
|
|
|
|
|
|
|
|
|
$patterns = [];
|
|
|
|
|
|
2022-04-04 06:30:07 +00:00
|
|
|
$parsed = self::parseEventPattern($pattern);
|
|
|
|
|
$type = $parsed['type'];
|
|
|
|
|
$resource = $parsed['resource'];
|
|
|
|
|
$subType = $parsed['subType'];
|
|
|
|
|
$subResource = $parsed['subResource'];
|
2022-06-22 10:51:49 +00:00
|
|
|
$subSubType = $parsed['subSubType'];
|
|
|
|
|
$subSubResource = $parsed['subSubResource'];
|
2022-04-04 06:30:07 +00:00
|
|
|
$action = $parsed['action'];
|
|
|
|
|
$attribute = $parsed['attribute'];
|
2022-03-29 08:30:57 +00:00
|
|
|
|
2022-04-13 12:39:31 +00:00
|
|
|
if ($resource && !\in_array(\trim($resource, "\[\]"), $paramKeys)) {
|
2022-03-29 08:30:57 +00:00
|
|
|
throw new InvalidArgumentException("{$resource} is missing from the params.");
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-13 12:39:31 +00:00
|
|
|
if ($subResource && !\in_array(\trim($subResource, "\[\]"), $paramKeys)) {
|
2022-03-29 08:30:57 +00:00
|
|
|
throw new InvalidArgumentException("{$subResource} is missing from the params.");
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-22 10:51:49 +00:00
|
|
|
if ($subSubResource && !\in_array(\trim($subSubResource, "\[\]"), $paramKeys)) {
|
|
|
|
|
throw new InvalidArgumentException("{$subSubResource} is missing from the params.");
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-29 08:30:57 +00:00
|
|
|
/**
|
|
|
|
|
* Create all possible patterns including placeholders.
|
|
|
|
|
*/
|
|
|
|
|
if ($action) {
|
2022-06-22 10:51:49 +00:00
|
|
|
if ($subSubResource) {
|
|
|
|
|
if ($attribute) {
|
|
|
|
|
$patterns[] = \implode('.', [$type, $resource, $subType, $subResource, $subSubType, $subSubResource, $action, $attribute]);
|
|
|
|
|
}
|
|
|
|
|
$patterns[] = \implode('.', [$type, $resource, $subType, $subResource, $subSubType, $subSubResource, $action]);
|
|
|
|
|
$patterns[] = \implode('.', [$type, $resource, $subType, $subResource, $subSubType, $subSubResource]);
|
|
|
|
|
} elseif ($subResource) {
|
2022-03-29 08:30:57 +00:00
|
|
|
if ($attribute) {
|
|
|
|
|
$patterns[] = \implode('.', [$type, $resource, $subType, $subResource, $action, $attribute]);
|
|
|
|
|
}
|
|
|
|
|
$patterns[] = \implode('.', [$type, $resource, $subType, $subResource, $action]);
|
|
|
|
|
$patterns[] = \implode('.', [$type, $resource, $subType, $subResource]);
|
|
|
|
|
} else {
|
|
|
|
|
$patterns[] = \implode('.', [$type, $resource, $action]);
|
2022-04-18 16:21:45 +00:00
|
|
|
}
|
|
|
|
|
if ($attribute) {
|
|
|
|
|
$patterns[] = \implode('.', [$type, $resource, $action, $attribute]);
|
2022-03-29 08:30:57 +00:00
|
|
|
}
|
|
|
|
|
}
|
2022-06-22 10:51:49 +00:00
|
|
|
if ($subSubResource) {
|
|
|
|
|
$patterns[] = \implode('.', [$type, $resource, $subType, $subResource, $subSubType, $subSubResource]);
|
|
|
|
|
}
|
2022-03-29 08:30:57 +00:00
|
|
|
if ($subResource) {
|
|
|
|
|
$patterns[] = \implode('.', [$type, $resource, $subType, $subResource]);
|
|
|
|
|
}
|
2022-04-18 16:21:45 +00:00
|
|
|
$patterns[] = \implode('.', [$type, $resource]);
|
2022-03-29 08:30:57 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Removes all duplicates.
|
|
|
|
|
*/
|
|
|
|
|
$patterns = \array_unique($patterns);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Set all possible values of the patterns and replace placeholders.
|
|
|
|
|
*/
|
|
|
|
|
$events = [];
|
|
|
|
|
foreach ($patterns as $eventPattern) {
|
|
|
|
|
$events[] = \str_replace($paramKeys, $paramValues, $eventPattern);
|
|
|
|
|
$events[] = \str_replace($paramKeys, '*', $eventPattern);
|
|
|
|
|
foreach ($paramKeys as $key) {
|
|
|
|
|
foreach ($paramKeys as $current) {
|
2022-06-22 10:51:49 +00:00
|
|
|
if ($subSubResource) {
|
|
|
|
|
foreach ($paramKeys as $subCurrent) {
|
|
|
|
|
if ($subCurrent === $current || $subCurrent === $key) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2024-03-06 17:34:21 +00:00
|
|
|
$filtered1 = \array_filter($paramKeys, fn (string $k) => $k === $subCurrent);
|
2022-06-22 10:51:49 +00:00
|
|
|
$events[] = \str_replace($paramKeys, $paramValues, \str_replace($filtered1, '*', $eventPattern));
|
2024-03-06 17:34:21 +00:00
|
|
|
$filtered2 = \array_filter($paramKeys, fn (string $k) => $k === $current);
|
2022-06-22 10:51:49 +00:00
|
|
|
$events[] = \str_replace($paramKeys, $paramValues, \str_replace($filtered2, '*', \str_replace($filtered1, '*', $eventPattern)));
|
|
|
|
|
$events[] = \str_replace($paramKeys, $paramValues, \str_replace($filtered2, '*', $eventPattern));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if ($current === $key) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2024-03-06 17:34:21 +00:00
|
|
|
$filtered = \array_filter($paramKeys, fn (string $k) => $k === $current);
|
2022-06-22 10:51:49 +00:00
|
|
|
$events[] = \str_replace($paramKeys, $paramValues, \str_replace($filtered, '*', $eventPattern));
|
2022-05-23 14:54:50 +00:00
|
|
|
}
|
2022-03-29 08:30:57 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Remove [] from the events.
|
|
|
|
|
*/
|
|
|
|
|
$events = \array_map(fn (string $event) => \str_replace(['[', ']'], '', $event), $events);
|
2022-04-04 06:30:07 +00:00
|
|
|
$events = \array_unique($events);
|
2022-03-29 08:30:57 +00:00
|
|
|
|
2022-06-22 14:44:30 +00:00
|
|
|
/**
|
|
|
|
|
* Force a non-assoc array.
|
|
|
|
|
*/
|
2025-06-11 06:51:48 +00:00
|
|
|
$eventValues = \array_values($events);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return a combined list of table, collection events.
|
|
|
|
|
*/
|
|
|
|
|
return Event::mirrorCollectionEvents($pattern, $eventValues[0], $eventValues);
|
2022-03-29 08:30:57 +00:00
|
|
|
}
|
2023-10-17 19:08:01 +00:00
|
|
|
|
2024-10-30 18:01:12 +00:00
|
|
|
/**
|
2024-11-01 15:24:29 +00:00
|
|
|
* Generate a function event from a base event
|
|
|
|
|
*
|
|
|
|
|
* @param Event $event
|
|
|
|
|
*
|
|
|
|
|
* @return self
|
|
|
|
|
*
|
2024-10-30 18:01:12 +00:00
|
|
|
*/
|
2024-11-01 15:24:29 +00:00
|
|
|
public function from(Event $event): self
|
2024-10-30 18:01:12 +00:00
|
|
|
{
|
2024-11-01 15:24:29 +00:00
|
|
|
$this->project = $event->getProject();
|
|
|
|
|
$this->user = $event->getUser();
|
|
|
|
|
$this->payload = $event->getPayload();
|
2025-10-02 12:57:20 +00:00
|
|
|
$this->sensitive = $event->sensitive;
|
2024-11-01 15:24:29 +00:00
|
|
|
$this->event = $event->getEvent();
|
|
|
|
|
$this->params = $event->getParams();
|
2024-11-05 14:50:32 +00:00
|
|
|
$this->context = $event->context;
|
2024-11-01 15:24:29 +00:00
|
|
|
return $this;
|
2024-10-30 18:01:12 +00:00
|
|
|
}
|
2025-06-11 06:51:48 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Adds `table` events for `collection` events.
|
|
|
|
|
*
|
|
|
|
|
* Example:
|
|
|
|
|
*
|
|
|
|
|
* `databases.*.collections.*.documents.*.update` →\
|
|
|
|
|
* `[databases.*.collections.*.documents.*.update, databases.*.tables.*.rows.*.update]`
|
|
|
|
|
*/
|
|
|
|
|
private static function mirrorCollectionEvents(string $pattern, string $firstEvent, array $events): array
|
|
|
|
|
{
|
|
|
|
|
$tableEventMap = [
|
|
|
|
|
'documents' => 'rows',
|
|
|
|
|
'collections' => 'tables',
|
|
|
|
|
'attributes' => 'columns',
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
str_contains($pattern, 'databases.') &&
|
|
|
|
|
str_contains($firstEvent, 'collections')
|
|
|
|
|
) {
|
|
|
|
|
$pairedEvents = [];
|
|
|
|
|
|
|
|
|
|
foreach ($events as $event) {
|
|
|
|
|
$pairedEvents[] = $event;
|
|
|
|
|
|
|
|
|
|
if (str_contains($event, 'collections')) {
|
|
|
|
|
$tableSideEvent = str_replace(
|
|
|
|
|
array_keys($tableEventMap),
|
|
|
|
|
array_values($tableEventMap),
|
|
|
|
|
$event
|
|
|
|
|
);
|
|
|
|
|
$pairedEvents[] = $tableSideEvent;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$events = $pairedEvents;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $events;
|
|
|
|
|
}
|
2025-09-01 14:03:49 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the size of the queue.
|
|
|
|
|
*
|
|
|
|
|
* @param bool $failed Whether to include failed events in the count.
|
|
|
|
|
* @return int The size of the queue.
|
|
|
|
|
*/
|
|
|
|
|
public function getSize(bool $failed = false): int
|
|
|
|
|
{
|
|
|
|
|
$queue = new Queue($this->getQueue());
|
|
|
|
|
return $this->publisher->getQueueSize($queue, $failed);
|
|
|
|
|
}
|
2019-09-06 17:04:26 +00:00
|
|
|
}
|