diff --git a/VKAPI/Handlers/Notes.php b/VKAPI/Handlers/Notes.php index ce26baae..7c9c9fec 100644 --- a/VKAPI/Handlers/Notes.php +++ b/VKAPI/Handlers/Notes.php @@ -211,7 +211,7 @@ final class Notes extends VKAPIRequestHandler $items = []; $note = (new NotesRepo)->getNoteById((int)$id[0], (int)$id[1]); - if($note) { + if($note && !$note->isDeleted()) { $nodez->notes[] = $note->toVkApiStruct(); } } diff --git a/Web/Models/Entities/Comment.php b/Web/Models/Entities/Comment.php index d813d6be..d64a2763 100644 --- a/Web/Models/Entities/Comment.php +++ b/Web/Models/Entities/Comment.php @@ -90,4 +90,12 @@ class Comment extends Post { return "/wall" . $this->getTarget()->getPrettyId() . "#_comment" . $this->getId(); } + + function canBeEditedBy(?User $user = NULL): bool + { + if(!$user) + return false; + + return $user->getId() == $this->getOwner(false)->getId(); + } } diff --git a/Web/Models/Entities/Note.php b/Web/Models/Entities/Note.php index 37d9ac29..83082bf3 100644 --- a/Web/Models/Entities/Note.php +++ b/Web/Models/Entities/Note.php @@ -124,7 +124,7 @@ class Note extends Postable $res = (object) []; $res->type = "note"; - $res->id = $this->getId(); + $res->id = $this->getVirtualId(); $res->owner_id = $this->getOwner()->getId(); $res->title = $this->getName(); $res->text = $this->getText(); diff --git a/Web/Models/Entities/Post.php b/Web/Models/Entities/Post.php index 42941901..6d0fe8cf 100644 --- a/Web/Models/Entities/Post.php +++ b/Web/Models/Entities/Post.php @@ -245,6 +245,20 @@ class Post extends Postable $this->unwire(); $this->save(); } + + function canBeEditedBy(?User $user = NULL): bool + { + if(!$user) + return false; + + if($this->isDeactivationMessage() || $this->isUpdateAvatarMessage()) + return false; + + if($this->getTargetWall() > 0) + return $this->getPublicationTime()->timestamp() + WEEK > time() && $user->getId() == $this->getOwner(false)->getId(); + + return $user->getId() == $this->getOwner(false)->getId(); + } use Traits\TRichText; } diff --git a/Web/Models/Entities/Postable.php b/Web/Models/Entities/Postable.php index 23981cc1..ffbf480c 100644 --- a/Web/Models/Entities/Postable.php +++ b/Web/Models/Entities/Postable.php @@ -167,9 +167,9 @@ abstract class Postable extends Attachable $this->stateChanges("created", time()); $this->stateChanges("virtual_id", $pCount + 1); - } else { + } /*else { $this->stateChanges("edited", time()); - } + }*/ parent::save(); } diff --git a/Web/Models/Entities/Report.php b/Web/Models/Entities/Report.php index 4070952e..d449a2e8 100644 --- a/Web/Models/Entities/Report.php +++ b/Web/Models/Entities/Report.php @@ -3,6 +3,7 @@ namespace openvk\Web\Models\Entities; use openvk\Web\Util\DateTime; use Nette\Database\Table\ActiveRow; use openvk\Web\Models\RowModel; +use openvk\Web\Models\Entities\Club; use Chandler\Database\DatabaseConnection; use openvk\Web\Models\Repositories\{Applications, Comments, Notes, Reports, Users, Posts, Photos, Videos, Clubs}; use Chandler\Database\DatabaseConnection as DB; @@ -96,8 +97,19 @@ class Report extends RowModel { if ($this->getContentType() !== "user") { $pubTime = $this->getContentObject()->getPublicationTime(); - $name = $this->getContentObject()->getName(); - $this->getAuthor()->adminNotify("Ваш контент, который вы опубликовали $pubTime ($name) был удалён модераторами инстанса. За повторные или серьёзные нарушения вас могут заблокировать."); + if (method_exists($this->getContentObject(), "getName")) { + $name = $this->getContentObject()->getName(); + $placeholder = "$pubTime ($name)"; + } else { + $placeholder = "$pubTime"; + } + + if ($this->getAuthor() instanceof Club) { + $name = $this->getAuthor()->getName(); + $this->getAuthor()->getOwner()->adminNotify("Ваш контент, который опубликовали $placeholder в созданной вами группе \"$name\" был удалён модераторами инстанса. За повторные или серьёзные нарушения группу могут заблокировать."); + } else { + $this->getAuthor()->adminNotify("Ваш контент, который вы опубликовали $placeholder был удалён модераторами инстанса. За повторные или серьёзные нарушения вас могут заблокировать."); + } $this->getContentObject()->delete($this->getContentType() !== "app"); } diff --git a/Web/Models/Entities/User.php b/Web/Models/Entities/User.php index e5b8da06..aaf00ec9 100644 --- a/Web/Models/Entities/User.php +++ b/Web/Models/Entities/User.php @@ -462,6 +462,7 @@ class User extends RowModel "news", "links", "poster", + "apps" ], ])->get($id); } @@ -1026,6 +1027,7 @@ class User extends RowModel "news", "links", "poster", + "apps" ], ])->set($id, (int) $status)->toInteger(); diff --git a/Web/Presenters/AdminPresenter.php b/Web/Presenters/AdminPresenter.php index f5c6b22e..14fbbc74 100644 --- a/Web/Presenters/AdminPresenter.php +++ b/Web/Presenters/AdminPresenter.php @@ -363,7 +363,7 @@ final class AdminPresenter extends OpenVKPresenter if (str_contains($this->queryParam("reason"), "*")) exit(json_encode([ "error" => "Incorrect reason" ])); - $unban_time = strtotime($this->queryParam("date")) ?: NULL; + $unban_time = strtotime($this->queryParam("date")) ?: "permanent"; $user = $this->users->get($id); if(!$user) diff --git a/Web/Presenters/NoSpamPresenter.php b/Web/Presenters/NoSpamPresenter.php index 1560ba63..8164d05e 100644 --- a/Web/Presenters/NoSpamPresenter.php +++ b/Web/Presenters/NoSpamPresenter.php @@ -177,26 +177,25 @@ final class NoSpamPresenter extends OpenVKPresenter if ($conditions) { $logs = $db->query("SELECT * FROM `ChandlerLogs` $whereStart $conditions GROUP BY `object_id`, `object_model`"); - if (!$where) { - foreach ($logs as $log) { - $log = (new Logs)->get($log->id); - $response[] = $log->getObject()->unwrap(); - } - } else { - foreach ($logs as $log) { - $log = (new Logs)->get($log->id); - $object = $log->getObject()->unwrap(); + foreach ($logs as $log) { + $log = (new Logs)->get($log->id); + $object = $log->getObject()->unwrap(); - if (!$object) continue; + if (!$object) continue; + if ($where) { if (str_starts_with($where, " AND")) { $where = substr_replace($where, "", 0, strlen(" AND")); } - foreach ($db->query("SELECT * FROM `$table` WHERE $where")->fetchAll() as $o) { - if ($object->id === $o["id"]) { + $a = $db->query("SELECT * FROM `$table` WHERE $where")->fetchAll(); + foreach ($a as $o) { + if ($object->id == $o["id"]) { $response[] = $object; } } + + } else { + $response[] = $object; } } } @@ -206,70 +205,72 @@ final class NoSpamPresenter extends OpenVKPresenter } try { - $response = []; - $processed = 0; + $response = []; + $processed = 0; - $where = $this->postParam("where"); - $ip = $this->postParam("ip"); - $useragent = $this->postParam("useragent"); - $searchTerm = $this->postParam("q"); - $ts = (int)$this->postParam("ts"); - $te = (int)$this->postParam("te"); - $user = $this->postParam("user"); + $where = $this->postParam("where"); + $ip = addslashes($this->postParam("ip")); + $useragent = addslashes($this->postParam("useragent")); + $searchTerm = addslashes($this->postParam("q")); + $ts = (int)$this->postParam("ts"); + $te = (int)$this->postParam("te"); + $user = addslashes($this->postParam("user")); - if (!$ip && !$useragent && !$searchTerm && !$ts && !$te && !$where && !$searchTerm && !$user) - $this->returnJson(["success" => false, "error" => "Нет запроса. Заполните поле \"подстрока\" или введите запрос \"WHERE\" в поле под ним."]); - - $models = explode(",", $this->postParam("models")); - - foreach ($models as $_model) { - $model_name = NoSpamPresenter::ENTITIES_NAMESPACE . "\\" . $_model; - if (!class_exists($model_name)) { - continue; + if ($where) { + $where = explode(";", $where)[0]; } - $model = new $model_name; + if (!$ip && !$useragent && !$searchTerm && !$ts && !$te && !$where && !$searchTerm && !$user) + $this->returnJson(["success" => false, "error" => "Нет запроса. Заполните поле \"подстрока\" или введите запрос \"WHERE\" в поле под ним."]); - $c = new \ReflectionClass($model_name); - if ($c->isAbstract() || $c->getName() == NoSpamPresenter::ENTITIES_NAMESPACE . "\\Correspondence") { - continue; - } + $models = explode(",", $this->postParam("models")); - $db = DatabaseConnection::i()->getContext(); - $table = $model->getTableName(); - $columns = $db->getStructure()->getColumns($table); - - if ($searchTerm) { - $conditions = []; - $need_deleted = false; - foreach ($columns as $column) { - if ($column["name"] == "deleted") { - $need_deleted = true; - } else { - $conditions[] = "`$column[name]` REGEXP '$searchTerm'"; - } + foreach ($models as $_model) { + $model_name = NoSpamPresenter::ENTITIES_NAMESPACE . "\\" . $_model; + if (!class_exists($model_name)) { + continue; } - $conditions = implode(" OR ", $conditions); - $where = ($this->postParam("where") ? " AND ($conditions)" : "($conditions)"); - if ($need_deleted) $where .= " AND (`deleted` = 0)"; - } + $model = new $model_name; - $rows = []; - if ($ip || $useragent || $ts || $te || $user) { - $rows = searchByAdditionalParams($table, $where, $ip, $useragent, $ts, $te, $user); - } + $c = new \ReflectionClass($model_name); + if ($c->isAbstract() || $c->getName() == NoSpamPresenter::ENTITIES_NAMESPACE . "\\Correspondence") { + continue; + } - if (count($rows) === 0) { - if (!$searchTerm) { - if (str_starts_with($where, " AND")) { - if ($searchTerm && !$this->postParam("where")) { - $where = substr_replace($where, "", 0, strlen(" AND")); + $db = DatabaseConnection::i()->getContext(); + $table = $model->getTableName(); + $columns = $db->getStructure()->getColumns($table); + + if ($searchTerm) { + $conditions = []; + $need_deleted = false; + foreach ($columns as $column) { + if ($column["name"] == "deleted") { + $need_deleted = true; } else { - $where = "(" . $this->postParam("where") . ")" . $where; + $conditions[] = "`$column[name]` REGEXP '$searchTerm'"; } } + $conditions = implode(" OR ", $conditions); + $where = ($this->postParam("where") ? " AND ($conditions)" : "($conditions)"); + if ($need_deleted) $where .= " AND (`deleted` = 0)"; + } + + $rows = []; + + if (str_starts_with($where, " AND")) { + if ($searchTerm && !$this->postParam("where")) { + $where = substr_replace($where, "", 0, strlen(" AND")); + } else { + $where = "(" . $this->postParam("where") . ")" . $where; + } + } + + if ($ip || $useragent || $ts || $te || $user) { + $rows = searchByAdditionalParams($table, $where, $ip, $useragent, $ts, $te, $user); + } else { if (!$where) { $rows = []; } else { @@ -277,99 +278,105 @@ final class NoSpamPresenter extends OpenVKPresenter $rows = $result->fetchAll(); } } - } - if (!in_array((int)$this->postParam("ban"), [1, 2, 3])) { - foreach ($rows as $key => $object) { - $object = (array)$object; - $_obj = []; - foreach ($object as $key => $value) { - foreach ($columns as $column) { - if ($column["name"] === $key && in_array(strtoupper($column["nativetype"]), ["BLOB", "BINARY", "VARBINARY", "TINYBLOB", "MEDIUMBLOB", "LONGBLOB"])) { - $value = "[BINARY]"; - break; - } - } - - $_obj[$key] = $value; - $_obj["__model_name"] = $_model; - } - $response[] = $_obj; - } - } else { - $ids = []; - - foreach ($rows as $object) { - $object = new $model_name($db->table($table)->get($object->id)); - if (!$object) continue; - $ids[] = $object->getId(); - } - - $log = new NoSpamLog; - $log->setUser($this->user->id); - $log->setModel($_model); - if ($searchTerm) { - $log->setRegex($searchTerm); - } else { - $log->setRequest($where); - } - $log->setBan_Type((int)$this->postParam("ban")); - $log->setCount(count($rows)); - $log->setTime(time()); - $log->setItems(implode(",", $ids)); - $log->save(); - - $banned_ids = []; - foreach ($rows as $object) { - $object = new $model_name($db->table($table)->get($object->id)); - if (!$object) continue; - - $owner = NULL; - $methods = ["getOwner", "getUser", "getRecipient", "getInitiator"]; - - if (method_exists($object, "ban")) { - $owner = $object; - } else { - foreach ($methods as $method) { - if (method_exists($object, $method)) { - $owner = $object->$method(); - break; - } - } - } - - if ($owner instanceof User && $owner->getId() === $this->user->id) { - if (count($rows) === 1) { - $this->returnJson(["success" => false, "error" => "\"Производственная травма\" — Вы не можете блокировать или удалять свой же контент"]); - } else { - continue; - } - } - - if (in_array((int)$this->postParam("ban"), [2, 3])) { - if ($owner) { - $_id = ($owner instanceof Club ? $owner->getId() * -1 : $owner->getId()); - if (!in_array($_id, $banned_ids)) { - if ($owner instanceof User) { - $owner->ban("**content-noSpamTemplate-" . $log->getId() . "**", false, time() + $owner->getNewBanTime(), $this->user->id); - } else { - $owner->ban("Подозрительная активность"); + if (!in_array((int)$this->postParam("ban"), [1, 2, 3])) { + foreach ($rows as $key => $object) { + $object = (array)$object; + $_obj = []; + foreach ($object as $key => $value) { + foreach ($columns as $column) { + if ($column["name"] === $key && in_array(strtoupper($column["nativetype"]), ["BLOB", "BINARY", "VARBINARY", "TINYBLOB", "MEDIUMBLOB", "LONGBLOB"])) { + $value = "[BINARY]"; + break; } - - $banned_ids[] = $_id; } + + $_obj[$key] = $value; + $_obj["__model_name"] = $_model; } + $response[] = $_obj; + } + } else { + $ids = []; + + foreach ($rows as $object) { + $object = new $model_name($db->table($table)->get($object->id)); + if (!$object) continue; + $ids[] = $object->getId(); } - if (in_array((int)$this->postParam("ban"), [1, 3])) - $object->delete(); + $log = new NoSpamLog; + $log->setUser($this->user->id); + $log->setModel($_model); + if ($searchTerm) { + $log->setRegex($searchTerm); + } else { + $log->setRequest($where); + } + $log->setBan_Type((int)$this->postParam("ban")); + $log->setCount(count($rows)); + $log->setTime(time()); + $log->setItems(implode(",", $ids)); + $log->save(); + + $banned_ids = []; + foreach ($rows as $object) { + $object = new $model_name($db->table($table)->get($object->id)); + if (!$object) continue; + + $owner = NULL; + $methods = ["getOwner", "getUser", "getRecipient", "getInitiator"]; + + if (method_exists($object, "ban")) { + $owner = $object; + } else { + foreach ($methods as $method) { + if (method_exists($object, $method)) { + $owner = $object->$method(); + break; + } + } + } + + if ($owner instanceof User && $owner->getId() === $this->user->id) { + if (count($rows) === 1) { + $this->returnJson(["success" => false, "error" => "\"Производственная травма\" — Вы не можете блокировать или удалять свой же контент"]); + } else { + continue; + } + } + + if (in_array((int)$this->postParam("ban"), [2, 3])) { + $reason = mb_strlen(trim($this->postParam("ban_reason"))) > 0 ? addslashes($this->postParam("ban_reason")) : ("**content-noSpamTemplate-" . $log->getId() . "**"); + $is_forever = (string)$this->postParam("is_forever") === "true"; + $unban_time = $is_forever ? 0 : (int)$this->postParam("unban_time") ?? NULL; + + if ($owner) { + $_id = ($owner instanceof Club ? $owner->getId() * -1 : $owner->getId()); + if (!in_array($_id, $banned_ids)) { + if ($owner instanceof User) { + if (!$unban_time && !$is_forever) + $unban_time = time() + $owner->getNewBanTime(); + + $owner->ban($reason, false, $unban_time, $this->user->id); + } else { + $owner->ban("Подозрительная активность"); + } + + $banned_ids[] = $_id; + } + } + } + + if (in_array((int)$this->postParam("ban"), [1, 3])) + $object->delete(); + } + + $processed++; } - - $processed++; } - } - $this->returnJson(["success" => true, "processed" => $processed, "count" => count($response), "list" => $response]); + $this->returnJson(["success" => true, "processed" => $processed, "count" => count($response), "list" => $response]); } catch (\Throwable $e) { $this->returnJson(["success" => false, "error" => $e->getMessage()]); } diff --git a/Web/Presenters/PhotosPresenter.php b/Web/Presenters/PhotosPresenter.php index 437f8ec5..bef984b7 100644 --- a/Web/Presenters/PhotosPresenter.php +++ b/Web/Presenters/PhotosPresenter.php @@ -1,6 +1,6 @@ notFound(); if (!$user->getPrivacyPermission('photos.read', $this->user->identity ?? NULL)) $this->flashFail("err", tr("forbidden"), tr("forbidden_comment")); - $this->template->albums = $this->albums->getUserAlbums($user, $this->queryParam("p") ?? 1); + $this->template->albums = $this->albums->getUserAlbums($user, (int)($this->queryParam("p") ?? 1)); $this->template->count = $this->albums->getUserAlbumsCount($user); $this->template->owner = $user; $this->template->canEdit = false; @@ -36,7 +36,7 @@ final class PhotosPresenter extends OpenVKPresenter } else { $club = (new Clubs)->get(abs($owner)); if(!$club) $this->notFound(); - $this->template->albums = $this->albums->getClubAlbums($club, $this->queryParam("p") ?? 1); + $this->template->albums = $this->albums->getClubAlbums($club, (int)($this->queryParam("p") ?? 1)); $this->template->count = $this->albums->getClubAlbumsCount($club); $this->template->owner = $club; $this->template->canEdit = false; @@ -46,7 +46,7 @@ final class PhotosPresenter extends OpenVKPresenter $this->template->paginatorConf = (object) [ "count" => $this->template->count, - "page" => $this->queryParam("p") ?? 1, + "page" => (int)($this->queryParam("p") ?? 1), "amount" => NULL, "perPage" => OPENVK_DEFAULT_PER_PAGE, ]; @@ -147,7 +147,7 @@ final class PhotosPresenter extends OpenVKPresenter $this->template->photos = iterator_to_array( $album->getPhotos( (int) ($this->queryParam("p") ?? 1), 20) ); $this->template->paginatorConf = (object) [ "count" => $album->getPhotosCount(), - "page" => $this->queryParam("p") ?? 1, + "page" => (int)($this->queryParam("p") ?? 1), "amount" => sizeof($this->template->photos), "perPage" => 20, "atBottom" => true @@ -221,39 +221,74 @@ final class PhotosPresenter extends OpenVKPresenter function renderUploadPhoto(): void { $this->assertUserLoggedIn(); - $this->willExecuteWriteAction(); + $this->willExecuteWriteAction(true); if(is_null($this->queryParam("album"))) - $this->flashFail("err", tr("error"), tr("error_adding_to_deleted")); + $this->flashFail("err", tr("error"), tr("error_adding_to_deleted"), 500, true); [$owner, $id] = explode("_", $this->queryParam("album")); $album = $this->albums->get((int) $id); if(!$album) - $this->flashFail("err", tr("error"), tr("error_adding_to_deleted")); + $this->flashFail("err", tr("error"), tr("error_adding_to_deleted"), 500, true); if(is_null($this->user) || !$album->canBeModifiedBy($this->user->identity)) - $this->flashFail("err", tr("error_access_denied_short"), tr("error_access_denied")); + $this->flashFail("err", tr("error_access_denied_short"), tr("error_access_denied"), 500, true); if($_SERVER["REQUEST_METHOD"] === "POST") { - if(!isset($_FILES["blob"])) - $this->flashFail("err", tr("no_photo"), tr("select_file")); - - try { - $photo = new Photo; - $photo->setOwner($this->user->id); - $photo->setDescription($this->postParam("desc")); - $photo->setFile($_FILES["blob"]); - $photo->setCreated(time()); - $photo->save(); - } catch(ISE $ex) { - $name = $album->getName(); - $this->flashFail("err", tr("no_photo"), tr("error_adding_to_x", $name)); - } - - $album->addPhoto($photo); - $album->setEdited(time()); - $album->save(); + if($this->queryParam("act") == "finish") { + $result = json_decode($this->postParam("photos"), true); + + foreach($result as $photoId => $description) { + $phot = $this->photos->get($photoId); - $this->redirect("/photo" . $photo->getPrettyId() . "?from=album" . $album->getId()); + if(!$phot || $phot->isDeleted() || $phot->getOwner()->getId() != $this->user->id) + continue; + + if(iconv_strlen($description) > 255) + $this->flashFail("err", tr("error"), tr("description_too_long"), 500, true); + + $phot->setDescription($description); + $phot->save(); + + $album = $phot->getAlbum(); + } + + $this->returnJson(["success" => true, + "album" => $album->getId(), + "owner" => $album->getOwner() instanceof User ? $album->getOwner()->getId() : $album->getOwner()->getId() * -1]); + } + + if(!isset($_FILES)) + $this->flashFail("err", tr("no_photo"), tr("select_file"), 500, true); + + $photos = []; + for($i = 0; $i < $this->postParam("count"); $i++) { + try { + $photo = new Photo; + $photo->setOwner($this->user->id); + $photo->setDescription(""); + $photo->setFile($_FILES["photo_".$i]); + $photo->setCreated(time()); + $photo->save(); + + $photos[] = [ + "url" => $photo->getURLBySizeId("tiny"), + "id" => $photo->getId(), + "vid" => $photo->getVirtualId(), + "owner" => $photo->getOwner()->getId(), + "link" => $photo->getURL() + ]; + } catch(ISE $ex) { + $name = $album->getName(); + $this->flashFail("err", "Неизвестная ошибка", "Не удалось сохранить фотографию в $name.", 500, true); + } + + $album->addPhoto($photo); + $album->setEdited(time()); + $album->save(); + } + + $this->returnJson(["success" => true, + "photos" => $photos]); } else { $this->template->album = $album; } @@ -285,18 +320,23 @@ final class PhotosPresenter extends OpenVKPresenter function renderDeletePhoto(int $ownerId, int $photoId): void { $this->assertUserLoggedIn(); - $this->willExecuteWriteAction(); + $this->willExecuteWriteAction($_SERVER["REQUEST_METHOD"] === "POST"); $this->assertNoCSRF(); $photo = $this->photos->getByOwnerAndVID($ownerId, $photoId); if(!$photo) $this->notFound(); if(is_null($this->user) || $this->user->id != $ownerId) $this->flashFail("err", tr("error_access_denied_short"), tr("error_access_denied")); - + + $redirect = $photo->getAlbum()->getOwner() instanceof User ? "/id0" : "/club" . $ownerId; + $photo->isolate(); $photo->delete(); + if($_SERVER["REQUEST_METHOD"] === "POST") + $this->returnJson(["success" => true]); + $this->flash("succ", tr("photo_is_deleted"), tr("photo_is_deleted_desc")); - $this->redirect("/id0"); + $this->redirect($redirect); } } diff --git a/Web/Presenters/UserPresenter.php b/Web/Presenters/UserPresenter.php index dd7ac854..51ddc6aa 100644 --- a/Web/Presenters/UserPresenter.php +++ b/Web/Presenters/UserPresenter.php @@ -481,6 +481,7 @@ final class UserPresenter extends OpenVKPresenter "menu_novajoj" => "news", "menu_ligiloj" => "links", "menu_standardo" => "poster", + "menu_aplikoj" => "apps" ]; foreach($settings as $checkbox => $setting) $user->setLeftMenuItemStatus($setting, $this->checkbox($checkbox)); diff --git a/Web/Presenters/WallPresenter.php b/Web/Presenters/WallPresenter.php index b20389ad..32ac421e 100644 --- a/Web/Presenters/WallPresenter.php +++ b/Web/Presenters/WallPresenter.php @@ -3,7 +3,7 @@ namespace openvk\Web\Presenters; use openvk\Web\Models\Exceptions\TooMuchOptionsException; use openvk\Web\Models\Entities\{Poll, Post, Photo, Video, Club, User}; use openvk\Web\Models\Entities\Notifications\{MentionNotification, RepostNotification, WallPostNotification}; -use openvk\Web\Models\Repositories\{Posts, Users, Clubs, Albums, Notes}; +use openvk\Web\Models\Repositories\{Posts, Users, Clubs, Albums, Notes, Comments}; use Chandler\Database\DatabaseConnection; use Nette\InvalidStateException as ISE; use Bhaktaraz\RSSGenerator\Item; @@ -498,4 +498,64 @@ final class WallPresenter extends OpenVKPresenter # TODO localize message based on language and ?act=(un)pin $this->flashFail("succ", tr("information_-1"), tr("changes_saved_comment")); } + + function renderEdit() + { + $this->assertUserLoggedIn(); + $this->willExecuteWriteAction(); + + if($_SERVER["REQUEST_METHOD"] !== "POST") + $this->redirect("/id0"); + + if($this->postParam("type") == "post") + $post = $this->posts->get((int)$this->postParam("postid")); + else + $post = (new Comments)->get((int)$this->postParam("postid")); + + if(!$post || $post->isDeleted()) + $this->returnJson(["error" => "Invalid post"]); + + if(!$post->canBeEditedBy($this->user->identity)) + $this->returnJson(["error" => "Access denied"]); + + $attachmentsCount = sizeof(iterator_to_array($post->getChildren())); + + if(empty($this->postParam("newContent")) && $attachmentsCount < 1) + $this->returnJson(["error" => "Empty post"]); + + $post->setEdited(time()); + + try { + $post->setContent($this->postParam("newContent")); + } catch(\LengthException $e) { + $this->returnJson(["error" => $e->getMessage()]); + } + + if($this->postParam("type") === "post") { + $post->setNsfw($this->postParam("nsfw") == "true"); + $flags = 0; + + if($post->getTargetWall() < 0 && $post->getWallOwner()->canBeModifiedBy($this->user->identity)) { + if($this->postParam("fromgroup") == "true") { + $flags |= 0b10000000; + $post->setFlags($flags); + } else + $post->setFlags($flags); + } + } + + $post->save(true); + + $this->returnJson(["error" => "no", + "new_content" => $post->getText(), + "new_edited" => (string)$post->getEditTime(), + "nsfw" => $this->postParam("type") === "post" ? (int)$post->isExplicit() : 0, + "from_group" => $this->postParam("type") === "post" && $post->getTargetWall() < 0 ? + ((int)$post->isPostedOnBehalfOfGroup()) : "false", + "new_text" => $post->getText(false), + "author" => [ + "name" => $post->getOwner()->getCanonicalName(), + "avatar" => $post->getOwner()->getAvatarUrl() + ]]); + } } diff --git a/Web/Presenters/templates/@layout.xml b/Web/Presenters/templates/@layout.xml index 0ed9519e..f8a975e0 100644 --- a/Web/Presenters/templates/@layout.xml +++ b/Web/Presenters/templates/@layout.xml @@ -175,7 +175,7 @@ {_my_page} {_my_friends} @@ -195,7 +195,7 @@ ({$thisUser->getNotificationsCount()}) {/if} - {_my_apps} + {_my_apps} {_my_settings} {var $canAccessAdminPanel = $thisUser->getChandlerUser()->can("access")->model("admin")->whichBelongsTo(NULL)} @@ -300,7 +300,7 @@ {ifset $thisUser} - {if !$thisUser->isBanned()} + {if !$thisUser->isBanned() && !$thisUser->isDeleted()} {/if} {/ifset} diff --git a/Web/Presenters/templates/NoSpam/Index.xml b/Web/Presenters/templates/NoSpam/Index.xml index 2d56c83f..2bf9d1df 100644 --- a/Web/Presenters/templates/NoSpam/Index.xml +++ b/Web/Presenters/templates/NoSpam/Index.xml @@ -106,13 +106,31 @@ {_block_params}: