mirror of
https://github.com/openvk/openvk
synced 2024-11-14 11:09:12 +03:00
114 lines
4 KiB
PHP
114 lines
4 KiB
PHP
<?php declare(strict_types=1);
|
|
namespace openvk\Web\Models\Repositories;
|
|
use openvk\Web\Models\Entities\User;
|
|
use openvk\Web\Models\Entities\Notifications\Notification;
|
|
use openvk\Web\Models\Repositories\Users;
|
|
|
|
class Notifications
|
|
{
|
|
private $edbc = NULL;
|
|
private $modelCodes;
|
|
|
|
function __construct()
|
|
{
|
|
$this->modelCodes = array_flip(json_decode(file_get_contents(__DIR__ . "/../../../data/modelCodes.json"), true));
|
|
}
|
|
|
|
private function getEDB(bool $throw = true): ?object
|
|
{
|
|
$eax = $this->edbc ?? eventdb();
|
|
if(!$eax && $throw)
|
|
throw new \RuntimeException("Event database err!");
|
|
|
|
return is_null($eax) ? NULL : $eax->getConnection();
|
|
}
|
|
|
|
private function getModel(int $code, int $id): object
|
|
{
|
|
$repoClassName = str_replace("Entities", "Repositories", "\\" . $this->modelCodes[$code]) . "s";
|
|
|
|
return (new $repoClassName)->get($id);
|
|
}
|
|
|
|
private function getQuery(User $user, bool $count = false, int $offset, bool $archived = false, int $page = 1, ?int $perPage = NULL): string
|
|
{
|
|
$query = "SELECT " . ($count ? "COUNT(*) AS cnt" : "*") . " FROM notifications WHERE recipientType=0 ";
|
|
$query .= "AND timestamp " . ($archived ? "<" : ">") . "$offset AND recipientId=" . $user->getId();
|
|
if(!$count) {
|
|
$query .= " ORDER BY timestamp DESC";
|
|
$query .= " LIMIT " . ($perPage ?? OPENVK_DEFAULT_PER_PAGE);
|
|
$query .= " OFFSET " . ((($page - 1) * $perPage) ?? OPENVK_DEFAULT_PER_PAGE);
|
|
}
|
|
|
|
return $query;
|
|
}
|
|
|
|
private function assemble(int $act, int $originModelType, int $originModelId, int $targetModelType, int $targetModelId, int $recipientId, int $timestamp, $data, ?string $class = NULL): Notification
|
|
{
|
|
$class ??= 'openvk\Web\Models\Entities\Notifications\Notification';
|
|
|
|
$originModel = $this->getModel($originModelType, $originModelId);
|
|
$targetModel = $this->getModel($targetModelType, $targetModelId);
|
|
$recipient = (new Users)->get($recipientId);
|
|
|
|
$notification = new $class($recipient, $originModel, $targetModel, $timestamp, $data);
|
|
$notification->setActionCode($act);
|
|
return $notification;
|
|
}
|
|
|
|
function getNotificationCountByUser(User $user, int $offset, bool $archived = false): int
|
|
{
|
|
$db = $this->getEDB(false);
|
|
if(!$db)
|
|
return 0;
|
|
|
|
$results = $db->query($this->getQuery($user, true, $offset, $archived));
|
|
|
|
return $results->fetch()->cnt;
|
|
}
|
|
|
|
function getNotificationsByUser(User $user, int $offset, bool $archived = false, int $page = 1, ?int $perPage = NULL): \Traversable
|
|
{
|
|
$db = $this->getEDB(false);
|
|
if(!$db) {
|
|
yield from [];
|
|
return;
|
|
}
|
|
|
|
$results = $this->getEDB()->query($this->getQuery($user, false, $offset, $archived, $page, $perPage));
|
|
foreach($results->fetchAll() as $notif) {
|
|
yield $this->assemble(
|
|
$notif->modelAction,
|
|
$notif->originModelType,
|
|
$notif->originModelId,
|
|
|
|
$notif->targetModelType,
|
|
$notif->targetModelId,
|
|
|
|
$notif->recipientId,
|
|
$notif->timestamp,
|
|
$notif->additionalData
|
|
);
|
|
}
|
|
}
|
|
|
|
function fromDescriptor(string $descriptor, ?object &$parsedData = nullptr)
|
|
{
|
|
[$class, $recv, $data] = explode(",", $descriptor);
|
|
$class = str_replace(".", "\\", $class);
|
|
|
|
$parsedData = unserialize(base64_decode($data));
|
|
return $this->assemble(
|
|
$parsedData->actionCode,
|
|
$parsedData->originModelType,
|
|
$parsedData->originModelId,
|
|
|
|
$parsedData->targetModelType,
|
|
$parsedData->targetModelId,
|
|
|
|
$parsedData->recipient,
|
|
$parsedData->timestamp,
|
|
$parsedData->additionalPayload,
|
|
);
|
|
}
|
|
}
|