2021-02-24 12:19:46 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace Appwrite\Event;
|
|
|
|
|
|
|
|
|
|
use Appwrite\Database\Document;
|
|
|
|
|
use Utopia\App;
|
|
|
|
|
|
|
|
|
|
class Realtime
|
|
|
|
|
{
|
2021-02-24 17:12:38 +00:00
|
|
|
/**
|
|
|
|
|
* @var string
|
|
|
|
|
*/
|
|
|
|
|
protected $project = '';
|
|
|
|
|
|
2021-02-24 12:19:46 +00:00
|
|
|
/**
|
|
|
|
|
* @var string
|
|
|
|
|
*/
|
|
|
|
|
protected $event = '';
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @var array
|
|
|
|
|
*/
|
|
|
|
|
protected $channels = [];
|
|
|
|
|
|
2021-02-25 17:00:41 +00:00
|
|
|
/**
|
|
|
|
|
* @var array
|
|
|
|
|
*/
|
|
|
|
|
protected $permissions = [];
|
|
|
|
|
|
2021-02-24 12:19:46 +00:00
|
|
|
/**
|
|
|
|
|
* @var Document
|
|
|
|
|
*/
|
|
|
|
|
protected $payload;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Event constructor.
|
|
|
|
|
*
|
2021-02-24 17:12:38 +00:00
|
|
|
* @param string $project
|
2021-02-24 12:19:46 +00:00
|
|
|
* @param string $event
|
|
|
|
|
* @param array $payload
|
|
|
|
|
*/
|
2021-02-24 17:12:38 +00:00
|
|
|
public function __construct(string $project, string $event, array $payload)
|
2021-02-24 12:19:46 +00:00
|
|
|
{
|
2021-02-24 17:12:38 +00:00
|
|
|
$this->project = $project;
|
2021-02-24 12:19:46 +00:00
|
|
|
$this->event = $event;
|
|
|
|
|
$this->payload = new Document($payload);
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-24 17:12:38 +00:00
|
|
|
/**
|
|
|
|
|
* @param string $project
|
|
|
|
|
* return $this
|
|
|
|
|
*/
|
|
|
|
|
public function setProject(string $project): self
|
|
|
|
|
{
|
|
|
|
|
$this->project = $project;
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
public function getProject(): string
|
|
|
|
|
{
|
|
|
|
|
return $this->project;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-24 12:19:46 +00:00
|
|
|
/**
|
|
|
|
|
* @param string $event
|
|
|
|
|
* return $this
|
|
|
|
|
*/
|
|
|
|
|
public function setEvent(string $event): self
|
|
|
|
|
{
|
|
|
|
|
$this->event = $event;
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
public function getEvent(): string
|
|
|
|
|
{
|
|
|
|
|
return $this->event;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param array $payload
|
|
|
|
|
* return $this
|
|
|
|
|
*/
|
|
|
|
|
public function setPayload(array $payload): self
|
|
|
|
|
{
|
|
|
|
|
$this->payload = new Document($payload);
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return Document
|
|
|
|
|
*/
|
|
|
|
|
public function getPayload(): Document
|
|
|
|
|
{
|
|
|
|
|
return $this->payload;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Populate channels array based on the event name and payload.
|
|
|
|
|
*
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
private function prepareChannels(): void
|
|
|
|
|
{
|
|
|
|
|
switch (true) {
|
2021-03-02 18:07:58 +00:00
|
|
|
case strpos($this->event, 'account.recovery.') === 0:
|
|
|
|
|
case strpos($this->event, 'account.sessions.') === 0:
|
|
|
|
|
case strpos($this->event, 'account.verification.') === 0:
|
|
|
|
|
$this->channels[] = 'account.' . $this->payload->getAttribute('userId');
|
|
|
|
|
$this->permissions = ['user:' . $this->payload->getAttribute('userId')];
|
|
|
|
|
|
|
|
|
|
break;
|
2021-02-24 12:19:46 +00:00
|
|
|
case strpos($this->event, 'account.') === 0:
|
|
|
|
|
$this->channels[] = 'account.' . $this->payload->getId();
|
2021-02-25 17:00:41 +00:00
|
|
|
$this->permissions = ['user:' . $this->payload->getId()];
|
2021-02-24 12:19:46 +00:00
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case strpos($this->event, 'database.collections.') === 0:
|
|
|
|
|
$this->channels[] = 'collections';
|
|
|
|
|
$this->channels[] = 'collections.' . $this->payload->getId();
|
2021-02-25 17:00:41 +00:00
|
|
|
$this->permissions = $this->payload->getAttribute('$permissions.read');
|
2021-02-24 12:19:46 +00:00
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case strpos($this->event, 'database.documents.') === 0:
|
|
|
|
|
$this->channels[] = 'documents';
|
|
|
|
|
$this->channels[] = 'collections.' . $this->payload->getAttribute('$collection') . '.documents';
|
|
|
|
|
$this->channels[] = 'documents.' . $this->payload->getId();
|
2021-02-25 17:00:41 +00:00
|
|
|
$this->permissions = $this->payload->getAttribute('$permissions.read');
|
2021-02-24 12:19:46 +00:00
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case strpos($this->event, 'storage.') === 0:
|
|
|
|
|
$this->channels[] = 'files';
|
|
|
|
|
$this->channels[] = 'files.' . $this->payload->getId();
|
2021-02-25 17:00:41 +00:00
|
|
|
$this->permissions = $this->payload->getAttribute('$permissions.read');
|
2021-02-24 12:19:46 +00:00
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Execute Event.
|
|
|
|
|
*
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
public function trigger(): void
|
|
|
|
|
{
|
|
|
|
|
$this->prepareChannels();
|
|
|
|
|
if (empty($this->channels)) return;
|
|
|
|
|
|
|
|
|
|
$redis = new \Redis();
|
|
|
|
|
$redis->connect(App::getEnv('_APP_REDIS_HOST', ''), App::getEnv('_APP_REDIS_PORT', ''));
|
|
|
|
|
$redis->publish('realtime', json_encode([
|
2021-02-24 17:12:38 +00:00
|
|
|
'project' => $this->project,
|
2021-02-25 17:00:41 +00:00
|
|
|
'permissions' => $this->permissions,
|
2021-02-24 12:19:46 +00:00
|
|
|
'data' => [
|
|
|
|
|
'event' => $this->event,
|
2021-02-25 10:43:39 +00:00
|
|
|
'channels' => $this->channels,
|
2021-02-24 12:19:46 +00:00
|
|
|
'timestamp' => time(),
|
2021-02-24 17:12:38 +00:00
|
|
|
'payload' => $this->payload->getArrayCopy()
|
2021-02-24 12:19:46 +00:00
|
|
|
]
|
|
|
|
|
]));
|
|
|
|
|
|
|
|
|
|
$this->reset();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function reset(): self
|
|
|
|
|
{
|
|
|
|
|
$this->event = '';
|
|
|
|
|
$this->payload = $this->channels = [];
|
|
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
}
|