+ {$change->getNewContent()|noescape} + + | Применить + + + | Текущая версия + +
diff --git a/Web/Models/Entities/Post.php b/Web/Models/Entities/Post.php index 4afb4baa..9853b3b6 100644 --- a/Web/Models/Entities/Post.php +++ b/Web/Models/Entities/Post.php @@ -174,6 +174,16 @@ class Post extends Postable $this->unwire(); $this->save(); } + + function getChangeId(): int + { + return $this->getRecord()->change_id; + } + + function getChangeType(): string + { + return $this->getRecord()->change_type == 2 ? "new" : "old"; + } use Traits\TRichText; } diff --git a/Web/Models/Entities/PostChangeRecord.php b/Web/Models/Entities/PostChangeRecord.php new file mode 100644 index 00000000..70cba43f --- /dev/null +++ b/Web/Models/Entities/PostChangeRecord.php @@ -0,0 +1,71 @@ +getRecord()->id; + } + + function getWid(): int + { + return $this->getRecord()->wall_id; + } + + function getAuthorType(): string + { + return $this->getWid() < 0 ? "club" : "user"; + } + + function getVid(): int + { + return $this->getRecord()->virtual_id; + } + + function getPost(): ?Post + { + return (new Posts)->getPostById($this->getWid(), $this->getVid()); + } + + function getAuthor() + { + if ($this->getAuthorType() === "club") + return (new Clubs)->get($this->getWid()); + + return (new Users)->get($this->getWid()); + } + + function getOldContent(): ?string + { + return $this->getRecord()->oldContent; + } + + function getNewContent(): ?string + { + return $this->getRecord()->newContent; + } + + function getCreationDate(): DateTime + { + return new DateTime($this->getRecord()->created); + } + + function canBeApplied(string $type): bool + { + $post = $this->getPost(); + + if ($post->getChangeId() == $this->getId()) + if ($post->getChangeType() == $type) return false; + + return true; + } +} diff --git a/Web/Models/Repositories/PostsChanges.php b/Web/Models/Repositories/PostsChanges.php new file mode 100644 index 00000000..5e346d5d --- /dev/null +++ b/Web/Models/Repositories/PostsChanges.php @@ -0,0 +1,45 @@ +context = DatabaseConnection::i()->getContext(); + $this->changes = $this->context->table("posts_changes"); + } + + function toChangeRecord(?ActiveRow $ar): ?PostChangeRecord + { + return is_null($ar) ? NULL : new PostChangeRecord($ar); + } + + function get(int $id): ?PostChangeRecord + { + return $this->toChangeRecord($this->changes->get($id)); + } + + function getListByWid(int $wid): \Traversable + { + foreach ($this->changes->where("wall_id", $wid)->fetch() as $record) + yield new PostChangeRecord($record); + } + + function getAllHistoryById(int $wid, int $vid): \Traversable + { + foreach($this->changes->where(["wall_id" => $wid, "virtual_id" => $vid]) as $record) + yield new PostChangeRecord($record); + } + + function getHistoryById(int $wid, int $vid, int $page = 1): \Traversable + { + foreach($this->changes->where(["wall_id" => $wid, "virtual_id" => $vid])->page($page, 5) as $record) + yield new PostChangeRecord($record); + } +} diff --git a/Web/Presenters/WallPresenter.php b/Web/Presenters/WallPresenter.php index 5dd0de58..89e01b48 100644 --- a/Web/Presenters/WallPresenter.php +++ b/Web/Presenters/WallPresenter.php @@ -1,8 +1,8 @@ posts = $posts; + $this->changes = $changes; parent::__construct(); } @@ -274,10 +276,24 @@ final class WallPresenter extends OpenVKPresenter try { if ($editTarget) { $post = $this->posts->getPostById($this->user->id, $editTarget); + + $changes_record = new PostChangeRecord; + + if (OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["logChanges"]) { + $changes_record->setWall_id($wall); + $changes_record->setVirtual_id($editTarget); + $changes_record->setOldContent($post->getText()); + $changes_record->setNewContent($this->postParam("text")); + $changes_record->setCreated(time()); + $changes_record->save(); + } + $post->setEdited(time()); $post->setContent($this->postParam("text")); $post->setFlags($flags); $post->setNsfw($this->postParam("nsfw") === "on"); + $post->setChange_id($changes_record->getId()); + $post->setChange_type(2); $post->save(); } else { $post = new Post; @@ -419,4 +435,56 @@ 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 renderPostHistory(int $wall, int $post_id): void + { + $this->assertUserLoggedIn(); + + if(!$this->user->identity->getChandlerUser()->can("access")->model("admin")->whichBelongsTo(NULL)) + $this->flashFail("err", tr("error"), tr("forbidden")); + + $post = $this->posts->getPostById($wall, $post_id); + + if (!$post) $this->notFound(); + + $this->template->post = $post; + + if ($post->getTargetWall() > 0) { + $this->template->wallOwner = (new Users)->get($post->getTargetWall()); + $this->template->isWallOfGroup = false; + if($this->template->wallOwner->isBanned()) + $this->flashFail("err", tr("error"), tr("forbidden")); + } else { + $this->template->wallOwner = (new Clubs)->get(abs($post->getTargetWall())); + $this->template->isWallOfGroup = true; + } + + $this->template->cPage = (int) ($_GET["p"] ?? 1); + $this->template->cCount = sizeof(iterator_to_array($this->changes->getAllHistoryById($wall, $post_id))); + $this->template->changes = iterator_to_array($this->changes->getHistoryById($wall, $post_id, $this->template->cPage)); + $this->template->cAmount = sizeof($this->template->changes); + } + + function renderPostHistoryRestore(int $wall, int $post_id, int $change_id, string $type): void + { + $this->assertUserLoggedIn(); + + if(!$this->user->identity->getChandlerUser()->can("access")->model("admin")->whichBelongsTo(NULL)) + $this->flashFail("err", tr("error"), tr("forbidden")); + + $post = $this->posts->getPostById($wall, $post_id); + $change = $this->changes->get($change_id); + + if ($type == "old") + $post->setContent($change->getOldContent()); + else + $post->setContent($change->getNewContent()); + + $post->setChange_Id($change->getId()); + $post->setChange_Type($type == "new" ? 2 : 1); + + $post->save(); + + $this->flashFail("succ", "Успех", "Версия #$change_id применена."); + } } diff --git a/Web/Presenters/templates/Wall/Post.xml b/Web/Presenters/templates/Wall/Post.xml index 28855d0d..f66f59c9 100644 --- a/Web/Presenters/templates/Wall/Post.xml +++ b/Web/Presenters/templates/Wall/Post.xml @@ -31,5 +31,13 @@ {/if} {_delete} + + История изменений + {/block} diff --git a/Web/Presenters/templates/Wall/PostHistory.xml b/Web/Presenters/templates/Wall/PostHistory.xml new file mode 100644 index 00000000..2f8f3841 --- /dev/null +++ b/Web/Presenters/templates/Wall/PostHistory.xml @@ -0,0 +1,35 @@ +{extends "../@layout.xml"} +{block title}{_post}{/block} + +{block header} + + {$wallOwner->getCanonicalName()} + + » + + {_wall} + + » + {_post} +{/block} + +{block content} + {include "../components/post.xml", post => $post, forceNoCommentsLink => TRUE, forceNoDeleteLink => TRUE} +
+
+ |
+
+
+
+
+ {$change->getOldContent()|noescape}
+
+ | Применить
+
+
+ | Текущая версия
+
+
+ + {$change->getNewContent()|noescape} + + | Применить + + + | Текущая версия + + |
+
+