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"}: - + diff --git a/Web/Presenters/templates/Group/View.xml b/Web/Presenters/templates/Group/View.xml index a817b72c..76c35b68 100644 --- a/Web/Presenters/templates/Group/View.xml +++ b/Web/Presenters/templates/Group/View.xml @@ -91,13 +91,18 @@ {presenter "openvk!Wall->wallEmbedded", -$club->getId()}
- + {var avatarPhoto = $club->getAvatarPhoto()} + {var avatarLink = ((is_null($avatarPhoto) ? FALSE : $avatarPhoto->isAnonymous()) ? "/photo" . ("s/" . base_convert((string) $avatarPhoto->getId(), 10, 32)) : $club->getAvatarLink())} +
- {if $correspondent->getId() === $thisUser->getId() || ($correspondent->getSubscriptionStatus($thisUser) === 3)} + {if $correspondent->getId() === $thisUser->getId() || $correspondent->getPrivacyPermission('messages.write', $thisUser)} {$thisUser->getCanonicalName()}
+
-
- - +
+
+ + +
+
+ {_fast_answers} +
+

@@ -93,17 +99,17 @@ {tr("support_greeting_hi", $ticket->getUser()->getFullName())}

- + {$comment->getText()|noescape}

- + {tr("support_greeting_regards", OPENVK_ROOT_CONF["openvk"]["appearance"]["name"])|noescape} {else} {$comment->getText()|noescape} {/if}
- + {if $comment->getUType() === 0}
{_delete} @@ -126,4 +132,12 @@ + + {/block} diff --git a/Web/Presenters/templates/User/Groups.xml b/Web/Presenters/templates/User/Groups.xml index ad80222c..18860fd8 100644 --- a/Web/Presenters/templates/User/Groups.xml +++ b/Web/Presenters/templates/User/Groups.xml @@ -51,9 +51,9 @@ {$x->getDescription()} {/block} -{var clubPinned = $thisUser->isClubPinned($x)} -{if $x->canBeModifiedBy($thisUser ?? NULL) || $clubPinned || $thisUser->getPinnedClubCount() <= 10} - {block actions} +{block actions} + {var clubPinned = $thisUser->isClubPinned($x)} + {if $x->canBeModifiedBy($thisUser ?? NULL) && ($clubPinned || $thisUser->getPinnedClubCount() <= 10)} {if $clubPinned} {_remove_from_left_menu} @@ -61,5 +61,5 @@ {_add_to_left_menu} {/if} - {/block} -{/if} \ No newline at end of file + {/if} +{/block} diff --git a/Web/Presenters/templates/User/Settings.xml b/Web/Presenters/templates/User/Settings.xml index daa7a0c3..e24e21ca 100644 --- a/Web/Presenters/templates/User/Settings.xml +++ b/Web/Presenters/templates/User/Settings.xml @@ -316,6 +316,18 @@ + + + {_privacy_setting_write_messages} + + + + + @@ -348,16 +360,40 @@ {elseif $isFinanceTU}

{_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"}