openvk/Web/Models/Repositories/Notifications.php
Alexander Minkin 6ec54a379d
feat: add linting of code (#1220)
* feat(lint): add php-cs-fixer for linting

Removing previous CODE_STYLE as it was not enforced anyway and using PER-CS 2.0.

This is not the reformatting commit.

* style: format code according to PER-CS 2.0 with php-cs-fixer

* ci(actions): add lint action

Resolves #1132.
2025-01-31 18:20:13 +03:00

116 lines
3.9 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;
public 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, 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;
}
public 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;
}
public 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
);
}
}
public 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,
);
}
}