getRecord()->id; } public function getOwner(): User { return (new Users())->get($this->getRecord()->owner); } public function getName(): string { return $this->getRecord()->name; } public function getDescription(): string { return $this->getRecord()->description; } public function getAvatarUrl(): string { $serverUrl = ovk_scheme(true) . $_SERVER["HTTP_HOST"]; if (is_null($this->getRecord()->avatar_hash)) { return "$serverUrl/assets/packages/static/openvk/img/camera_200.png"; } $hash = $this->getRecord()->avatar_hash; switch (OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["mode"]) { 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"; 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" ); } } public function getNote(): ?Note { if (!$this->getRecord()->news) { return null; } return (new Notes())->get($this->getRecord()->news); } public function getNoteLink(): string { $note = $this->getNote(); if (!$note) { return ""; } return ovk_scheme(true) . $_SERVER["HTTP_HOST"] . "/note" . $note->getPrettyId(); } public function getBalance(): float { return $this->getRecord()->coins; } public function getURL(): string { return $this->getRecord()->address; } public function getOrigin(): string { $parsed = parse_url($this->getURL()); return ( ($parsed["scheme"] ?? "https") . "://" . ($parsed["host"] ?? "127.0.0.1") . ":" . ($parsed["port"] ?? "443") ); } public function getUsersCount(): int { $cx = DatabaseConnection::i()->getContext(); return sizeof($cx->table("app_users")->where("app", $this->getId())); } public function getInstallationEntry(User $user): ?array { $cx = DatabaseConnection::i()->getContext(); $entry = $cx->table("app_users")->where([ "app" => $this->getId(), "user" => $user->getId(), ])->fetch(); if (!$entry) { return null; } return $entry->toArray(); } public function getPermissions(User $user): array { $permMask = 0; $installInfo = $this->getInstallationEntry($user); if (!$installInfo) { $this->install($user); } else { $permMask = $installInfo["access"]; } $res = []; for ($i = 0; $i < sizeof(self::PERMS); $i++) { $checkVal = 1 << $i; if (($permMask & $checkVal) > 0) { $res[] = self::PERMS[$i]; } } return $res; } public function isInstalledBy(User $user): bool { return !is_null($this->getInstallationEntry($user)); } public function setNoteLink(?string $link): bool { if (!$link) { $this->stateChanges("news", null); return true; } preg_match("%note([0-9]+)_([0-9]+)$%", $link, $matches); if (sizeof($matches) != 3) { return false; } $owner = is_null($this->getRecord()) ? $this->changes["owner"] : $this->getRecord()->owner; [, $ownerId, $vid] = $matches; if ($ownerId != $owner) { return false; } $note = (new Notes())->getNoteById((int) $ownerId, (int) $vid); if (!$note) { return false; } $this->stateChanges("news", $note->getId()); return true; } public function setAvatar(array $file): int { if ($file["error"] !== UPLOAD_ERR_OK) { return -1; } 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))) { return -3; } } $image->resize(140, 140, Image::STRETCH); $image->save($this->getAvatarsDir() . substr($hash, 0, 2) . "/$hash" . "_app_avatar.png"); $this->stateChanges("avatar_hash", $hash); return 0; } public function setPermission(User $user, string $perm, bool $enabled): bool { $permMask = 0; $installInfo = $this->getInstallationEntry($user); if (!$installInfo) { $this->install($user); } else { $permMask = $installInfo["access"]; } $index = array_search($perm, self::PERMS); if ($index === false) { return false; } $permVal = 1 << $index; $permMask = $enabled ? ($permMask | $permVal) : ($permMask ^ $permVal); $cx = DatabaseConnection::i()->getContext(); $cx->table("app_users")->where([ "app" => $this->getId(), "user" => $user->getId(), ])->update([ "access" => $permMask, ]); return true; } public function isEnabled(): bool { return (bool) $this->getRecord()->enabled; } public function enable(): void { $this->stateChanges("enabled", 1); $this->save(); } public function disable(): void { $this->stateChanges("enabled", 0); $this->save(); } public function install(User $user): void { if (!$this->getInstallationEntry($user)) { $cx = DatabaseConnection::i()->getContext(); $cx->table("app_users")->insert([ "app" => $this->getId(), "user" => $user->getId(), ]); } } public function uninstall(User $user): void { $cx = DatabaseConnection::i()->getContext(); $cx->table("app_users")->where([ "app" => $this->getId(), "user" => $user->getId(), ])->delete(); } public function addCoins(float $coins): float { $res = $this->getBalance() + $coins; $this->stateChanges("coins", $res); $this->save(); return $res; } public function withdrawCoins(): void { $balance = $this->getBalance(); $tax = ($balance / 100) * OPENVK_ROOT_CONF["openvk"]["preferences"]["apps"]["withdrawTax"]; $owner = $this->getOwner(); $owner->setCoins($owner->getCoins() + ($balance - $tax)); $this->setCoins(0.0); $this->save(); $owner->save(); } public function delete(bool $softly = true): void { if ($softly) { throw new \UnexpectedValueException("Can't delete apps softly."); } // why $cx = DatabaseConnection::i()->getContext(); $cx->table("app_users")->where("app", $this->getId())->delete(); parent::delete(false); } public function getPublicationTime(): string { return tr("recently"); } }