openvk/Web/Models/Entities/Application.php

342 lines
8.7 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
2022-08-20 21:07:54 +03:00
namespace openvk\Web\Models\Entities;
2022-08-20 21:07:54 +03:00
use Chandler\Database\DatabaseConnection;
use Nette\Utils\Image;
use Nette\Utils\UnknownImageFileException;
use openvk\Web\Models\Repositories\Notes;
use openvk\Web\Models\Repositories\Users;
use openvk\Web\Models\RowModel;
class Application extends RowModel
{
protected $tableName = "apps";
public const PERMS = [
2022-08-20 21:07:54 +03:00
"notify",
"friends",
"photos",
"audio",
"video",
"stories",
"pages",
"status",
"notes",
"messages",
"wall",
"ads",
"docs",
"groups",
"notifications",
"stats",
"email",
"market",
];
2022-08-20 21:07:54 +03:00
private function getAvatarsDir(): string
{
$uploadSettings = OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"];
if ($uploadSettings["mode"] === "server" && $uploadSettings["server"]["kind"] === "cdn") {
2022-08-20 21:07:54 +03:00
return $uploadSettings["server"]["directory"];
} else {
2022-08-20 21:07:54 +03:00
return OPENVK_ROOT . "/storage/";
}
2022-08-20 21:07:54 +03:00
}
public function getId(): int
2022-08-20 21:07:54 +03:00
{
return $this->getRecord()->id;
}
public function getOwner(): User
2022-08-20 21:07:54 +03:00
{
return (new Users())->get($this->getRecord()->owner);
2022-08-20 21:07:54 +03:00
}
public function getName(): string
2022-08-20 21:07:54 +03:00
{
return $this->getRecord()->name;
}
public function getDescription(): string
2022-08-20 21:07:54 +03:00
{
return $this->getRecord()->description;
}
public function getAvatarUrl(): string
2022-08-20 21:07:54 +03:00
{
$serverUrl = ovk_scheme(true) . $_SERVER["HTTP_HOST"];
if (is_null($this->getRecord()->avatar_hash)) {
2022-08-20 21:07:54 +03:00
return "$serverUrl/assets/packages/static/openvk/img/camera_200.png";
}
2022-08-20 21:07:54 +03:00
$hash = $this->getRecord()->avatar_hash;
switch (OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["mode"]) {
2022-08-20 21:07:54 +03:00
default:
case "default":
case "basic":
return "$serverUrl/blob_" . substr($hash, 0, 2) . "/$hash" . "_app_avatar.png";
case "accelerated":
return "$serverUrl/openvk-datastore/$hash" . "_app_avatar.png";
2022-08-20 21:07:54 +03:00
case "server":
$settings = (object) OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["server"];
return (
$settings->protocol ?? ovk_scheme() .
"://" . $settings->host .
$settings->path .
substr($hash, 0, 2) . "/$hash" . "_app_avatar.png"
2022-08-20 21:07:54 +03:00
);
}
}
public function getNote(): ?Note
2022-08-20 21:07:54 +03:00
{
if (!$this->getRecord()->news) {
return null;
}
return (new Notes())->get($this->getRecord()->news);
2022-08-20 21:07:54 +03:00
}
public function getNoteLink(): string
2022-08-20 21:07:54 +03:00
{
$note = $this->getNote();
if (!$note) {
2022-08-20 21:07:54 +03:00
return "";
}
2022-08-20 21:07:54 +03:00
return ovk_scheme(true) . $_SERVER["HTTP_HOST"] . "/note" . $note->getPrettyId();
}
public function getBalance(): float
2022-08-20 21:07:54 +03:00
{
return $this->getRecord()->coins;
}
public function getURL(): string
2022-08-20 21:07:54 +03:00
{
return $this->getRecord()->address;
}
public function getOrigin(): string
2022-08-20 21:07:54 +03:00
{
$parsed = parse_url($this->getURL());
2022-08-20 21:07:54 +03:00
return (
($parsed["scheme"] ?? "https") . "://"
. ($parsed["host"] ?? "127.0.0.1") . ":"
. ($parsed["port"] ?? "443")
);
}
public function getUsersCount(): int
2022-08-20 21:07:54 +03:00
{
$cx = DatabaseConnection::i()->getContext();
return sizeof($cx->table("app_users")->where("app", $this->getId()));
}
public function getInstallationEntry(User $user): ?array
2022-08-20 21:07:54 +03:00
{
$cx = DatabaseConnection::i()->getContext();
$entry = $cx->table("app_users")->where([
"app" => $this->getId(),
"user" => $user->getId(),
])->fetch();
if (!$entry) {
return null;
}
2022-08-20 21:07:54 +03:00
return $entry->toArray();
}
public function getPermissions(User $user): array
2022-08-20 21:07:54 +03:00
{
$permMask = 0;
$installInfo = $this->getInstallationEntry($user);
if (!$installInfo) {
2022-08-20 21:07:54 +03:00
$this->install($user);
} else {
2022-08-20 21:07:54 +03:00
$permMask = $installInfo["access"];
}
2022-08-20 21:07:54 +03:00
$res = [];
for ($i = 0; $i < sizeof(self::PERMS); $i++) {
2022-08-20 21:07:54 +03:00
$checkVal = 1 << $i;
if (($permMask & $checkVal) > 0) {
2022-08-20 21:07:54 +03:00
$res[] = self::PERMS[$i];
}
2022-08-20 21:07:54 +03:00
}
2022-08-20 21:07:54 +03:00
return $res;
}
public function isInstalledBy(User $user): bool
2022-08-20 21:07:54 +03:00
{
return !is_null($this->getInstallationEntry($user));
}
public function setNoteLink(?string $link): bool
2022-08-20 21:07:54 +03:00
{
if (!$link) {
$this->stateChanges("news", null);
2022-08-20 21:07:54 +03:00
return true;
}
2022-08-20 21:07:54 +03:00
preg_match("%note([0-9]+)_([0-9]+)$%", $link, $matches);
if (sizeof($matches) != 3) {
2022-08-20 21:07:54 +03:00
return false;
}
2022-08-20 21:07:54 +03:00
$owner = is_null($this->getRecord()) ? $this->changes["owner"] : $this->getRecord()->owner;
[, $ownerId, $vid] = $matches;
if ($ownerId != $owner) {
2022-08-20 21:07:54 +03:00
return false;
}
$note = (new Notes())->getNoteById((int) $ownerId, (int) $vid);
if (!$note) {
2022-08-20 21:07:54 +03:00
return false;
}
2022-08-20 21:07:54 +03:00
$this->stateChanges("news", $note->getId());
2022-08-20 21:07:54 +03:00
return true;
}
public function setAvatar(array $file): int
2022-08-20 21:07:54 +03:00
{
if ($file["error"] !== UPLOAD_ERR_OK) {
2022-08-20 21:07:54 +03:00
return -1;
}
2022-08-20 21:07:54 +03:00
try {
$image = Image::fromFile($file["tmp_name"]);
} catch (UnknownImageFileException $e) {
return -2;
}
$hash = hash_file("adler32", $file["tmp_name"]);
if (!is_dir($this->getAvatarsDir() . substr($hash, 0, 2))) {
if (!mkdir($this->getAvatarsDir() . substr($hash, 0, 2))) {
2022-08-20 21:07:54 +03:00
return -3;
}
}
2022-08-20 21:07:54 +03:00
$image->resize(140, 140, Image::STRETCH);
$image->save($this->getAvatarsDir() . substr($hash, 0, 2) . "/$hash" . "_app_avatar.png");
2022-08-20 21:07:54 +03:00
$this->stateChanges("avatar_hash", $hash);
2022-08-20 21:07:54 +03:00
return 0;
}
public function setPermission(User $user, string $perm, bool $enabled): bool
2022-08-20 21:07:54 +03:00
{
$permMask = 0;
$installInfo = $this->getInstallationEntry($user);
if (!$installInfo) {
2022-08-20 21:07:54 +03:00
$this->install($user);
} else {
2022-08-20 21:07:54 +03:00
$permMask = $installInfo["access"];
}
2022-08-20 21:07:54 +03:00
$index = array_search($perm, self::PERMS);
if ($index === false) {
2022-08-20 21:07:54 +03:00
return false;
}
2022-08-20 21:07:54 +03:00
$permVal = 1 << $index;
$permMask = $enabled ? ($permMask | $permVal) : ($permMask ^ $permVal);
2022-08-20 21:07:54 +03:00
$cx = DatabaseConnection::i()->getContext();
$cx->table("app_users")->where([
"app" => $this->getId(),
"user" => $user->getId(),
])->update([
"access" => $permMask,
]);
2022-08-20 21:07:54 +03:00
return true;
}
public function isEnabled(): bool
2022-08-20 21:07:54 +03:00
{
return (bool) $this->getRecord()->enabled;
}
public function enable(): void
2022-08-20 21:07:54 +03:00
{
$this->stateChanges("enabled", 1);
$this->save();
}
public function disable(): void
2022-08-20 21:07:54 +03:00
{
$this->stateChanges("enabled", 0);
$this->save();
}
public function install(User $user): void
2022-08-20 21:07:54 +03:00
{
if (!$this->getInstallationEntry($user)) {
2022-08-20 21:07:54 +03:00
$cx = DatabaseConnection::i()->getContext();
$cx->table("app_users")->insert([
"app" => $this->getId(),
"user" => $user->getId(),
]);
}
}
public function uninstall(User $user): void
2022-08-20 21:07:54 +03:00
{
$cx = DatabaseConnection::i()->getContext();
$cx->table("app_users")->where([
"app" => $this->getId(),
"user" => $user->getId(),
])->delete();
}
public function addCoins(float $coins): float
2022-08-20 21:07:54 +03:00
{
$res = $this->getBalance() + $coins;
$this->stateChanges("coins", $res);
$this->save();
2022-08-20 21:07:54 +03:00
return $res;
}
public function withdrawCoins(): void
2022-08-20 21:07:54 +03:00
{
$balance = $this->getBalance();
$tax = ($balance / 100) * OPENVK_ROOT_CONF["openvk"]["preferences"]["apps"]["withdrawTax"];
2022-08-20 21:07:54 +03:00
$owner = $this->getOwner();
$owner->setCoins($owner->getCoins() + ($balance - $tax));
$this->setCoins(0.0);
$this->save();
$owner->save();
}
public function delete(bool $softly = true): void
2022-08-20 21:07:54 +03:00
{
if ($softly) {
throw new \UnexpectedValueException("Can't delete apps softly.");
} // why
2022-08-20 21:07:54 +03:00
$cx = DatabaseConnection::i()->getContext();
$cx->table("app_users")->where("app", $this->getId())->delete();
2022-08-20 21:07:54 +03:00
parent::delete(false);
}
public function getPublicationTime(): string
{
return tr("recently");
}
}