diff --git a/Web/Models/Entities/User.php b/Web/Models/Entities/User.php index e0212578..131c9bdd 100644 --- a/Web/Models/Entities/User.php +++ b/Web/Models/Entities/User.php @@ -324,7 +324,7 @@ class User extends RowModel function getAge(): ?int { - return (int)floor((time() - $this->getBirthday()->timestamp()) / mktime(0, 0, 0, 1, 1, 1971)); + return (int)floor((time() - $this->getBirthday()->timestamp()) / YEAR); } function get2faSecret(): ?string @@ -372,6 +372,7 @@ class User extends RowModel "friends.read", "friends.add", "wall.write", + "messages.write", ], ])->get($id); } @@ -540,6 +541,8 @@ class User extends RowModel $manager = $club->getManager($this); if(!is_null($manager)) return $manager->isClubPinned(); + + return false; } function getMeetings(int $page = 1): \Traversable @@ -696,16 +699,18 @@ class User extends RowModel ]); } - function ban(string $reason): void + function ban(string $reason, bool $deleteSubscriptions = true): void { - $subs = DatabaseConnection::i()->getContext()->table("subscriptions"); - $subs = $subs->where( - "follower = ? OR (target = ? AND model = ?)", - $this->getId(), - $this->getId(), - get_class($this), - ); - $subs->delete(); + if($deleteSubscriptions) { + $subs = DatabaseConnection::i()->getContext()->table("subscriptions"); + $subs = $subs->where( + "follower = ? OR (target = ? AND model = ?)", + $this->getId(), + $this->getId(), + get_class($this), + ); + $subs->delete(); + } $this->setBlock_Reason($reason); $this->save(); @@ -752,6 +757,7 @@ class User extends RowModel "friends.read", "friends.add", "wall.write", + "messages.write", ], ])->set($id, $status)->toInteger()); } diff --git a/Web/Presenters/AboutPresenter.php b/Web/Presenters/AboutPresenter.php index 4c7f916b..550fc8f0 100644 --- a/Web/Presenters/AboutPresenter.php +++ b/Web/Presenters/AboutPresenter.php @@ -83,4 +83,37 @@ final class AboutPresenter extends OpenVKPresenter { $this->template->languages = getLanguages(); } + + function renderRobotsTxt(): void + { + $text = "# robots.txt file for openvk\n" + . "#\n" + . "# this includes only those links that are not in any way\n" + . "# covered from unauthorized persons (for example, due to\n" + . "# lack of rights to access the admin panel)\n\n" + . "User-Agent: *\n" + . "Disallow: /rpc\n" + . "Disallow: /language\n" + . "Disallow: /badbrowser.php\n" + . "Disallow: /logout\n" + . "Disallow: /away.php\n" + . "Disallow: /im?\n" + . "Disallow: *query=\n" + . "Disallow: *?lg=\n" + . "Disallow: *hash=\n" + . "Disallow: *?jReturnTo=\n" + . "Disallow: /method/*\n" + . "Disallow: /token*"; + header("Content-Type: text/plain"); + exit($text); + } + + function renderHumansTxt(): void + { + // :D + + header("HTTP/1.1 302 Found"); + header("Location: https://github.com/openvk/openvk#readme"); + exit; + } } diff --git a/Web/Presenters/GroupPresenter.php b/Web/Presenters/GroupPresenter.php index 7788c09e..7b9a20f2 100644 --- a/Web/Presenters/GroupPresenter.php +++ b/Web/Presenters/GroupPresenter.php @@ -219,10 +219,17 @@ final class GroupPresenter extends OpenVKPresenter if($_FILES["ava"]["error"] === UPLOAD_ERR_OK) { $photo = new Photo; try { + $anon = OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["enable"]; + if($anon && $this->user->id === $club->getOwner()->getId()) + $anon = $club->isOwnerHidden(); + else if($anon) + $anon = $club->getManager($this->user->identity)->isHidden(); + $photo->setOwner($this->user->id); $photo->setDescription("Profile image"); $photo->setFile($_FILES["ava"]); $photo->setCreated(time()); + $photo->setAnonymous($anon); $photo->save(); (new Albums)->getClubAvatarAlbum($club)->addPhoto($photo); diff --git a/Web/Presenters/MessengerPresenter.php b/Web/Presenters/MessengerPresenter.php index 9f0066ad..fdcb934e 100644 --- a/Web/Presenters/MessengerPresenter.php +++ b/Web/Presenters/MessengerPresenter.php @@ -124,7 +124,7 @@ final class MessengerPresenter extends OpenVKPresenter } $sel = $this->getCorrespondent($sel); - if($sel->getId() !== $this->user->id && $sel->getSubscriptionStatus($this->user->identity) !== 3) + if($sel->getId() !== $this->user->id && !$sel->getPrivacyPermission('messages.write', $this->user->identity)) exit(header("HTTP/1.1 403 Forbidden")); $cor = new Correspondence($this->user->identity, $sel); diff --git a/Web/Presenters/OpenVKPresenter.php b/Web/Presenters/OpenVKPresenter.php index 18a7c14b..48d6a9af 100755 --- a/Web/Presenters/OpenVKPresenter.php +++ b/Web/Presenters/OpenVKPresenter.php @@ -39,14 +39,26 @@ abstract class OpenVKPresenter extends SimplePresenter Session::i()->set("_tempTheme", $theme); } - protected function flashFail(string $type, string $title, ?string $message = NULL, ?int $code = NULL): void + protected function flashFail(string $type, string $title, ?string $message = NULL, ?int $code = NULL, bool $json = false): void { - $this->flash($type, $title, $message, $code); - $referer = $_SERVER["HTTP_REFERER"] ?? "/"; - - header("HTTP/1.1 302 Found"); - header("Location: $referer"); - exit; + if($json) { + $this->returnJson([ + "success" => $type !== "err", + "flash" => [ + "type" => $type, + "title" => $title, + "message" => $message, + "code" => $code, + ], + ]); + } else { + $this->flash($type, $title, $message, $code); + $referer = $_SERVER["HTTP_REFERER"] ?? "/"; + + header("HTTP/1.1 302 Found"); + header("Location: $referer"); + exit; + } } protected function logInUserWithToken(): void @@ -120,18 +132,18 @@ abstract class OpenVKPresenter extends SimplePresenter $this->flashFail("err", tr("captcha_error"), tr("captcha_error_comment")); } - protected function willExecuteWriteAction(): void + protected function willExecuteWriteAction(bool $json = false): void { $ip = (new IPs)->get(CONNECTING_IP); $res = $ip->rateLimit(); if(!($res === IP::RL_RESET || $res === IP::RL_CANEXEC)) { if($res === IP::RL_BANNED && OPENVK_ROOT_CONF["openvk"]["preferences"]["security"]["rateLimits"]["autoban"]) { - $this->user->identity->ban("Account has possibly been stolen"); + $this->user->identity->ban("Account has possibly been stolen", false); exit("Хакеры? Интересно..."); } - $this->flashFail("err", tr("rate_limit_error"), tr("rate_limit_error_comment", OPENVK_ROOT_CONF["openvk"]["appearance"]["name"], $res)); + $this->flashFail("err", tr("rate_limit_error"), tr("rate_limit_error_comment", OPENVK_ROOT_CONF["openvk"]["appearance"]["name"], $res), NULL, $json); } } @@ -241,4 +253,13 @@ abstract class OpenVKPresenter extends SimplePresenter Session::i()->set("_error", NULL); } } + + protected function returnJson(array $json): void + { + $payload = json_encode($json); + $size = strlen($payload); + header("Content-Type: application/json"); + header("Content-Length: $size"); + exit($payload); + } } diff --git a/Web/Presenters/SupportPresenter.php b/Web/Presenters/SupportPresenter.php index e34eecab..a94fe855 100644 --- a/Web/Presenters/SupportPresenter.php +++ b/Web/Presenters/SupportPresenter.php @@ -164,9 +164,10 @@ final class SupportPresenter extends OpenVKPresenter $this->notFound(); $ticketComments = $this->comments->getCommentsById($id); - $this->template->ticket = $ticket; - $this->template->comments = $ticketComments; - $this->template->id = $id; + $this->template->ticket = $ticket; + $this->template->comments = $ticketComments; + $this->template->id = $id; + $this->template->fastAnswers = OPENVK_ROOT_CONF["openvk"]["preferences"]["support"]["fastAnswers"]; } function renderAnswerTicketReply(int $id): void diff --git a/Web/Presenters/UserPresenter.php b/Web/Presenters/UserPresenter.php index 52e1bfee..fde2ad01 100644 --- a/Web/Presenters/UserPresenter.php +++ b/Web/Presenters/UserPresenter.php @@ -87,7 +87,7 @@ final class UserPresenter extends OpenVKPresenter $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); else { $this->template->user = $user; - $this->template->page = $this->queryParam("p") ?? 1; + $this->template->page = (int) ($this->queryParam("p") ?? 1); $this->template->admin = $this->queryParam("act") == "managed"; } } @@ -101,11 +101,11 @@ final class UserPresenter extends OpenVKPresenter $this->notFound(); if(!$club->canBeModifiedBy($this->user->identity ?? NULL)) - $this->flashFail("err", "Ошибка доступа", "У вас недостаточно прав, чтобы изменять этот ресурс."); + $this->flashFail("err", "Ошибка доступа", "У вас недостаточно прав, чтобы изменять этот ресурс.", NULL, true); $isClubPinned = $this->user->identity->isClubPinned($club); if(!$isClubPinned && $this->user->identity->getPinnedClubCount() > 10) - $this->flashFail("err", "Ошибка", "Находится в левом меню могут максимум 10 групп"); + $this->flashFail("err", "Ошибка", "Находится в левом меню могут максимум 10 групп", NULL, true); if($club->getOwner()->getId() === $this->user->identity->getId()) { $club->setOwner_Club_Pinned(!$isClubPinned); @@ -118,10 +118,9 @@ final class UserPresenter extends OpenVKPresenter } } - if($isClubPinned) - $this->flashFail("succ", "Операция успешна", "Группа " . $club->getName() . " была успешно удалена из левого меню"); - else - $this->flashFail("succ", "Операция успешна", "Группа " . $club->getName() . " была успешно добавлена в левое меню"); + $this->returnJson([ + "success" => true + ]); } function renderEdit(): void @@ -135,7 +134,7 @@ final class UserPresenter extends OpenVKPresenter $user = $this->users->get($id); if($_SERVER["REQUEST_METHOD"] === "POST") { - $this->willExecuteWriteAction(); + $this->willExecuteWriteAction($_GET['act'] === "status"); if($_GET['act'] === "main" || $_GET['act'] == NULL) { $user->setFirst_Name(empty($this->postParam("first_name")) ? $user->getFirstName() : $this->postParam("first_name")); @@ -197,15 +196,15 @@ final class UserPresenter extends OpenVKPresenter } elseif($_GET['act'] === "status") { if(mb_strlen($this->postParam("status")) > 255) { $statusLength = (string) mb_strlen($this->postParam("status")); - $this->flashFail("err", "Ошибка", "Статус слишком длинный ($statusLength символов вместо 255 символов)"); + $this->flashFail("err", "Ошибка", "Статус слишком длинный ($statusLength символов вместо 255 символов)", NULL, true); } $user->setStatus(empty($this->postParam("status")) ? NULL : $this->postParam("status")); $user->save(); - header("HTTP/1.1 302 Found"); - header("Location: /id" . $user->getId()); - exit; + $this->returnJson([ + "success" => true + ]); } try { @@ -330,6 +329,7 @@ final class UserPresenter extends OpenVKPresenter "friends.read", "friends.add", "wall.write", + "messages.write", ]; foreach($settings as $setting) { $input = $this->postParam(str_replace(".", "_", $setting)); diff --git a/Web/Presenters/WallPresenter.php b/Web/Presenters/WallPresenter.php index acb8f633..999bf53c 100644 --- a/Web/Presenters/WallPresenter.php +++ b/Web/Presenters/WallPresenter.php @@ -320,7 +320,7 @@ final class WallPresenter extends OpenVKPresenter (new RepostNotification($post->getOwner(false), $post, $this->user->identity))->emit(); }; - exit(json_encode(["wall_owner" => $this->user->identity->getId()])); + $this->returnJson(["wall_owner" => $this->user->identity->getId()]); } function renderDelete(int $wall, int $post_id): void diff --git a/Web/Presenters/templates/About/Language.xml b/Web/Presenters/templates/About/Language.xml index de9aed87..4cb4c9ed 100644 --- a/Web/Presenters/templates/About/Language.xml +++ b/Web/Presenters/templates/About/Language.xml @@ -8,7 +8,7 @@ {block content}
{/block} diff --git a/Web/Presenters/templates/Auth/Register.xml b/Web/Presenters/templates/Auth/Register.xml index 90ae6053..bf6ba594 100644 --- a/Web/Presenters/templates/Auth/Register.xml +++ b/Web/Presenters/templates/Auth/Register.xml @@ -39,7 +39,7 @@ {_"surname"}:{_voucher_explanation} {_voucher_explanation_ex}
- + {elseif $isInterface} diff --git a/Web/Presenters/templates/User/View.xml b/Web/Presenters/templates/User/View.xml index 46a50eb6..85b53d01 100644 --- a/Web/Presenters/templates/User/View.xml +++ b/Web/Presenters/templates/User/View.xml @@ -92,6 +92,7 @@ {/if} {_send_gift} + {_"send_message"} {var subStatus = $user->getSubscriptionStatus($thisUser)} {if $subStatus === 0} @@ -116,7 +117,6 @@ {elseif $subStatus === 3} - {_"send_message"}