openvk/Web/Presenters/GroupPresenter.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

562 lines
21 KiB
PHP

<?php
declare(strict_types=1);
namespace openvk\Web\Presenters;
use openvk\Web\Models\Entities\{Club, Photo, Post};
use Nette\InvalidStateException;
use openvk\Web\Models\Entities\Notifications\ClubModeratorNotification;
use openvk\Web\Models\Repositories\{Clubs, Users, Albums, Managers, Topics, Audios, Posts, Documents};
use Chandler\Security\Authenticator;
final class GroupPresenter extends OpenVKPresenter
{
private $clubs;
protected $presenterName = "group";
public function __construct(Clubs $clubs)
{
$this->clubs = $clubs;
parent::__construct();
}
public function renderView(int $id): void
{
$club = $this->clubs->get($id);
if (!$club) {
$this->notFound();
} else {
if ($club->isBanned()) {
$this->template->_template = "Group/Banned.xml";
} else {
$docs = (new Documents())->getDocumentsByOwner($club->getRealId());
$this->template->albums = (new Albums())->getClubAlbums($club, 1, 3);
$this->template->albumsCount = (new Albums())->getClubAlbumsCount($club);
$this->template->topics = (new Topics())->getLastTopics($club, 3);
$this->template->topicsCount = (new Topics())->getClubTopicsCount($club);
$this->template->audios = (new Audios())->getRandomThreeAudiosByEntityId($club->getRealId());
$this->template->audiosCount = (new Audios())->getClubCollectionSize($club);
$this->template->docsCount = $docs->size();
$this->template->docs = $docs->offsetLimit(0, 2);
}
if (!is_null($this->user->identity) && $club->getWallType() == 2) {
if (!$club->canBeModifiedBy($this->user->identity)) {
$this->template->suggestedPostsCountByUser = (new Posts())->getSuggestedPostsCountByUser($club->getId(), $this->user->id);
} else {
$this->template->suggestedPostsCountByEveryone = (new Posts())->getSuggestedPostsCount($club->getId());
}
}
$this->template->club = $club;
$this->template->ignore_status = $club->isIgnoredBy($this->user->identity);
}
}
public function renderCreate(): void
{
$this->assertUserLoggedIn();
$this->willExecuteWriteAction();
if ($_SERVER["REQUEST_METHOD"] === "POST") {
if (!empty($this->postParam("name")) && mb_strlen(trim($this->postParam("name"))) > 0) {
$club = new Club();
$club->setName($this->postParam("name"));
$club->setAbout(empty($this->postParam("about")) ? null : $this->postParam("about"));
$club->setOwner($this->user->id);
try {
$club->save();
} catch (\PDOException $ex) {
if ($ex->getCode() == 23000) {
$this->flashFail("err", tr("error"), tr("error_on_server_side"));
} else {
throw $ex;
}
}
$club->toggleSubscription($this->user->identity);
$this->redirect("/club" . $club->getId());
} else {
$this->flashFail("err", tr("error"), tr("error_no_group_name"));
}
}
}
public function renderSub(): void
{
$this->assertUserLoggedIn();
$this->willExecuteWriteAction();
if ($_SERVER["REQUEST_METHOD"] !== "POST") {
exit("Invalid state");
}
$club = $this->clubs->get((int) $this->postParam("id"));
if (!$club) {
exit("Invalid state");
}
if ($club->isBanned()) {
$this->flashFail("err", tr("error"), tr("forbidden"));
}
$club->toggleSubscription($this->user->identity);
$this->redirect($club->getURL());
}
public function renderFollowers(int $id): void
{
$this->assertUserLoggedIn();
$this->template->club = $this->clubs->get($id);
if ($this->template->club->isBanned()) {
$this->flashFail("err", tr("error"), tr("forbidden"));
}
$this->template->onlyShowManagers = $this->queryParam("onlyAdmins") == "1";
if ($this->template->onlyShowManagers) {
$this->template->followers = null;
$this->template->managers = $this->template->club->getManagers((int) ($this->queryParam("p") ?? 1), !$this->template->club->canBeModifiedBy($this->user->identity));
if ($this->template->club->canBeModifiedBy($this->user->identity) || !$this->template->club->isOwnerHidden()) {
$this->template->managers = array_merge([$this->template->club->getOwner()], iterator_to_array($this->template->managers));
}
$this->template->count = $this->template->club->getManagersCount();
} else {
$this->template->followers = $this->template->club->getFollowers((int) ($this->queryParam("p") ?? 1));
$this->template->managers = null;
$this->template->count = $this->template->club->getFollowersCount();
}
$this->template->paginatorConf = (object) [
"count" => $this->template->count,
"page" => $this->queryParam("p") ?? 1,
"amount" => 10,
"perPage" => OPENVK_DEFAULT_PER_PAGE,
];
}
public function renderModifyAdmin(int $id): void
{
$user = is_null($this->queryParam("user")) ? $this->postParam("user") : $this->queryParam("user");
$comment = $this->postParam("comment");
$removeComment = $this->postParam("removeComment") === "1";
$hidden = ["0" => false, "1" => true][$this->queryParam("hidden")] ?? null;
//$index = $this->queryParam("index");
if (!$user) {
$this->badRequest();
}
$club = $this->clubs->get($id);
if ($club->isBanned()) {
$this->flashFail("err", tr("error"), tr("forbidden"));
}
$user = (new Users())->get((int) $user);
if (!$user || !$club) {
$this->notFound();
}
if (!$club->canBeModifiedBy($this->user->identity ?? null)) {
$this->flashFail("err", tr("error_access_denied_short"), tr("error_access_denied"));
}
if (!is_null($hidden)) {
if ($club->getOwner()->getId() == $user->getId()) {
$club->setOwner_Hidden($hidden);
$club->save();
} else {
$manager = (new Managers())->getByUserAndClub($user->getId(), $club->getId());
$manager->setHidden($hidden);
$manager->save();
}
if ($club->getManagersCount(true) == 0) {
$club->setAdministrators_List_Display(2);
$club->save();
}
if ($hidden) {
$this->flashFail("succ", tr("success_action"), tr("x_is_now_hidden", $user->getCanonicalName()));
} else {
$this->flashFail("succ", tr("success_action"), tr("x_is_now_showed", $user->getCanonicalName()));
}
} elseif ($removeComment) {
if ($club->getOwner()->getId() == $user->getId()) {
$club->setOwner_Comment(null);
$club->save();
} else {
$manager = (new Managers())->getByUserAndClub($user->getId(), $club->getId());
$manager->setComment(null);
$manager->save();
}
$this->flashFail("succ", tr("success_action"), tr("comment_is_deleted"));
} elseif ($comment) {
if (mb_strlen($comment) > 36) {
$commentLength = (string) mb_strlen($comment);
$this->flashFail("err", tr("error"), tr("comment_is_too_long", $commentLength));
}
if ($club->getOwner()->getId() == $user->getId()) {
$club->setOwner_Comment($comment);
$club->save();
} else {
$manager = (new Managers())->getByUserAndClub($user->getId(), $club->getId());
$manager->setComment($comment);
$manager->save();
}
$this->flashFail("succ", tr("success_action"), tr("comment_is_changed"));
} else {
if ($club->canBeModifiedBy($user)) {
$club->removeManager($user);
$this->flashFail("succ", tr("success_action"), tr("x_no_more_admin", $user->getCanonicalName()));
} else {
$club->addManager($user);
(new ClubModeratorNotification($user, $club, $this->user->identity))->emit();
$this->flashFail("succ", tr("success_action"), tr("x_is_admin", $user->getCanonicalName()));
}
}
}
public function renderEdit(int $id): void
{
$this->assertUserLoggedIn();
$this->willExecuteWriteAction();
$club = $this->clubs->get($id);
if (!$club || !$club->canBeModifiedBy($this->user->identity)) {
$this->notFound();
} elseif ($club->isBanned()) {
$this->flashFail("err", tr("error"), tr("forbidden"));
} else {
$this->template->club = $club;
}
if ($_SERVER["REQUEST_METHOD"] === "POST") {
if (!$club->setShortcode(empty($this->postParam("shortcode")) ? null : $this->postParam("shortcode"))) {
$this->flashFail("err", tr("error"), tr("error_shorturl_incorrect"));
}
$club->setName((empty($this->postParam("name")) || mb_strlen(trim($this->postParam("name"))) === 0) ? $club->getName() : $this->postParam("name"));
$club->setAbout(empty($this->postParam("about")) ? null : $this->postParam("about"));
try {
$club->setWall(empty($this->postParam("wall")) ? 0 : (int) $this->postParam("wall"));
} catch (\Exception $e) {
$this->flashFail("err", tr("error"), tr("error_invalid_wall_value"));
}
$club->setAdministrators_List_Display(empty($this->postParam("administrators_list_display")) ? 0 : $this->postParam("administrators_list_display"));
$club->setEveryone_Can_Create_Topics(empty($this->postParam("everyone_can_create_topics")) ? 0 : 1);
$club->setDisplay_Topics_Above_Wall(empty($this->postParam("display_topics_above_wall")) ? 0 : 1);
$club->setEveryone_can_upload_audios(empty($this->postParam("upload_audios")) ? 0 : 1);
if (!$club->isHidingFromGlobalFeedEnforced()) {
$club->setHide_From_Global_Feed(empty($this->postParam("hide_from_global_feed") ? 0 : 1));
}
$website = $this->postParam("website") ?? "";
if (empty($website)) {
$club->setWebsite(null);
} else {
$club->setWebsite((!parse_url($website, PHP_URL_SCHEME) ? "https://" : "") . $website);
}
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();
} elseif ($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);
} catch (ISE $ex) {
$name = $album->getName();
$this->flashFail("err", tr("error"), tr("error_when_uploading_photo"));
}
}
try {
$club->save();
} catch (\PDOException $ex) {
if ($ex->getCode() == 23000) {
$this->flashFail("err", tr("error"), tr("error_on_server_side"));
} else {
throw $ex;
}
}
$this->flash("succ", tr("changes_saved"), tr("new_changes_desc"));
}
}
public function renderSetAvatar(int $id)
{
$this->assertUserLoggedIn();
$this->willExecuteWriteAction();
$club = $this->clubs->get($id);
if (!$club || $club->isBanned() || !$club->canBeModifiedBy($this->user->identity)) {
$this->flashFail("err", tr("error"), tr("forbidden"), null, true);
}
if ($_SERVER["REQUEST_METHOD"] === "POST" && $_FILES["blob"]["error"] === UPLOAD_ERR_OK) {
try {
$photo = new Photo();
$anon = OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["enable"];
if ($anon && $this->user->id === $club->getOwner()->getId()) {
$anon = $club->isOwnerHidden();
} elseif ($anon) {
$anon = $club->getManager($this->user->identity)->isHidden();
}
$photo->setOwner($this->user->id);
$photo->setDescription("Club image");
$photo->setFile($_FILES["blob"]);
$photo->setCreated(time());
$photo->setAnonymous($anon);
$photo->save();
(new Albums())->getClubAvatarAlbum($club)->addPhoto($photo);
if ($this->postParam("on_wall") == 1) {
$post = new Post();
$post->setOwner($this->user->id);
$post->setWall($club->getId() * -1);
$post->setCreated(time());
$post->setContent("");
$flags = 0;
$flags |= 0b00010000;
$flags |= 0b10000000;
$post->setFlags($flags);
$post->save();
$post->attach($photo);
}
} catch (\Throwable $ex) {
$this->flashFail("err", tr("error"), tr("error_when_uploading_photo"), null, true);
}
$this->returnJson([
"success" => true,
"new_photo" => $photo->getPrettyId(),
"url" => $photo->getURL(),
]);
} else {
return " ";
}
}
public function renderDeleteAvatar(int $id)
{
$this->assertUserLoggedIn();
$this->willExecuteWriteAction();
$club = $this->clubs->get($id);
if (!$club || $club->isBanned() || !$club->canBeModifiedBy($this->user->identity)) {
$this->flashFail("err", tr("error"), tr("forbidden"), null, true);
}
$avatar = $club->getAvatarPhoto();
if (!$avatar) {
$this->flashFail("succ", tr("error"), "no avatar bro", null, true);
}
$avatar->isolate();
$newAvatar = $club->getAvatarPhoto();
if (!$newAvatar) {
$this->returnJson([
"success" => true,
"has_new_photo" => false,
"new_photo" => null,
"url" => "/assets/packages/static/openvk/img/camera_200.png",
]);
} else {
$this->returnJson([
"success" => true,
"has_new_photo" => true,
"new_photo" => $newAvatar->getPrettyId(),
"url" => $newAvatar->getURL(),
]);
}
}
public function renderEditBackdrop(int $id): void
{
$this->assertUserLoggedIn();
$this->willExecuteWriteAction();
$club = $this->clubs->get($id);
if (!$club || !$club->canBeModifiedBy($this->user->identity)) {
$this->notFound();
} else {
$this->template->club = $club;
}
if ($_SERVER["REQUEST_METHOD"] !== "POST") {
return;
}
if ($this->postParam("subact") === "remove") {
$club->unsetBackDropPictures();
$club->save();
$this->flashFail("succ", tr("backdrop_succ_rem"), tr("backdrop_succ_desc")); # will exit
}
$pic1 = $pic2 = null;
try {
if ($_FILES["backdrop1"]["error"] !== UPLOAD_ERR_NO_FILE) {
$pic1 = Photo::fastMake($this->user->id, "Profile backdrop (system)", $_FILES["backdrop1"]);
}
if ($_FILES["backdrop2"]["error"] !== UPLOAD_ERR_NO_FILE) {
$pic2 = Photo::fastMake($this->user->id, "Profile backdrop (system)", $_FILES["backdrop2"]);
}
} catch (InvalidStateException $e) {
$this->flashFail("err", tr("backdrop_error_title"), tr("backdrop_error_no_media"));
}
if ($pic1 == $pic2 && is_null($pic1)) {
$this->flashFail("err", tr("backdrop_error_title"), tr("backdrop_error_no_media"));
}
$club->setBackDropPictures($pic1, $pic2);
$club->save();
$this->flashFail("succ", tr("backdrop_succ"), tr("backdrop_succ_desc"));
}
public function renderStatistics(int $id): void
{
$this->assertUserLoggedIn();
if (!eventdb()) {
$this->flashFail("err", tr("connection_error"), tr("connection_error_desc"));
}
$club = $this->clubs->get($id);
if (!$club->canBeModifiedBy($this->user->identity)) {
$this->notFound();
} elseif ($club->isBanned()) {
$this->flashFail("err", tr("error"), tr("forbidden"));
} else {
$this->template->club = $club;
}
$this->template->reach = $club->getPostViewStats(true);
$this->template->views = $club->getPostViewStats(false);
}
public function renderAdmin(int $clb, int $id): void
{
$this->assertUserLoggedIn();
$manager = (new Managers())->get($id);
if ($manager->getClub()->canBeModifiedBy($this->user->identity)) {
$this->template->manager = $manager;
$this->template->club = $manager->getClub();
} else {
$this->notFound();
}
}
public function renderChangeOwner(int $id, int $newOwnerId): void
{
$this->assertUserLoggedIn();
$this->willExecuteWriteAction();
if ($_SERVER['REQUEST_METHOD'] !== "POST") {
$this->redirect("/groups" . $this->user->id);
}
if (!Authenticator::verifyHash($this->postParam("password"), $this->user->identity->getChandlerUser()->getRaw()->passwordHash)) {
$this->flashFail("err", tr("error"), tr("incorrect_password"));
}
$club = $this->clubs->get($id);
if ($club->isBanned()) {
$this->flashFail("err", tr("error"), tr("forbidden"));
}
$newOwner = (new Users())->get($newOwnerId);
if ($this->user->id !== $club->getOwner()->getId()) {
$this->flashFail("err", tr("error"), tr("forbidden"));
}
$club->setOwner($newOwnerId);
$club->addManager($this->user->identity);
$oldOwnerManager = $club->getManager($this->user->identity);
$oldOwnerManager->setHidden($club->isOwnerHidden());
$oldOwnerManager->setComment($club->getOwnerComment());
$oldOwnerManager->save();
$newOwnerManager = $club->getManager($newOwner);
$club->setOwner_Hidden($newOwnerManager->isHidden());
$club->setOwner_Comment($newOwnerManager->getComment());
$club->removeManager($newOwner);
$club->save();
$this->flashFail("succ", tr("information_-1"), tr("group_owner_setted", $newOwner->getCanonicalName(), $club->getName()));
}
public function renderSuggested(int $id): void
{
$this->assertUserLoggedIn();
$club = $this->clubs->get($id);
if (!$club) {
$this->notFound();
} else {
$this->template->club = $club;
}
if ($club->getWallType() == 0) {
$this->flash("err", tr("error_suggestions"), tr("error_suggestions_closed"));
$this->redirect("/club" . $club->getId());
}
if ($club->getWallType() == 1) {
$this->flash("err", tr("error_suggestions"), tr("error_suggestions_open"));
$this->redirect("/club" . $club->getId());
}
if (!$club->canBeModifiedBy($this->user->identity)) {
$this->template->posts = iterator_to_array((new Posts())->getSuggestedPostsByUser($club->getId(), $this->user->id, (int) ($this->queryParam("p") ?? 1)));
$this->template->count = (new Posts())->getSuggestedPostsCountByUser($club->getId(), $this->user->id);
$this->template->type = "my";
} else {
$this->template->posts = iterator_to_array((new Posts())->getSuggestedPosts($club->getId(), (int) ($this->queryParam("p") ?? 1)));
$this->template->count = (new Posts())->getSuggestedPostsCount($club->getId());
$this->template->type = "everyone";
}
$this->template->page = (int) ($this->queryParam("p") ?? 1);
}
}