mirror of
https://github.com/openvk/openvk
synced 2024-11-14 11:09:12 +03:00
356c782f74
This commit adds discussions (forums) to groups, similar to how it was implemented in the original VK
191 lines
6.8 KiB
PHP
191 lines
6.8 KiB
PHP
<?php declare(strict_types=1);
|
||
namespace openvk\Web\Presenters;
|
||
use openvk\Web\Models\Entities\{Topic, Club, Comment, Photo, Video};
|
||
use openvk\Web\Models\Repositories\{Topics, Clubs};
|
||
|
||
final class TopicsPresenter extends OpenVKPresenter
|
||
{
|
||
private $topics;
|
||
private $clubs;
|
||
|
||
function __construct(Topics $topics, Clubs $clubs)
|
||
{
|
||
$this->topics = $topics;
|
||
$this->clubs = $clubs;
|
||
|
||
parent::__construct();
|
||
}
|
||
|
||
function renderBoard(int $id): void
|
||
{
|
||
$this->assertUserLoggedIn();
|
||
|
||
$club = $this->clubs->get($id);
|
||
if(!$club)
|
||
$this->notFound();
|
||
|
||
$this->template->club = $club;
|
||
$page = (int) ($this->queryParam("p") ?? 1);
|
||
|
||
$query = $this->queryParam("query");
|
||
if($query) {
|
||
$results = $this->topics->find($club, $query);
|
||
$this->template->topics = $results->page($page);
|
||
$this->template->count = $results->size();
|
||
} else {
|
||
$this->template->topics = $this->topics->getClubTopics($club, $page);
|
||
$this->template->count = $this->topics->getClubTopicsCount($club);
|
||
}
|
||
|
||
$this->template->paginatorConf = (object) [
|
||
"count" => $this->template->count,
|
||
"page" => $page,
|
||
"amount" => NULL,
|
||
"perPage" => OPENVK_DEFAULT_PER_PAGE,
|
||
];
|
||
}
|
||
|
||
function renderTopic(int $clubId, int $topicId): void
|
||
{
|
||
$this->assertUserLoggedIn();
|
||
|
||
$topic = $this->topics->getTopicById($clubId, $topicId);
|
||
if(!$topic)
|
||
$this->notFound();
|
||
|
||
$this->template->topic = $topic;
|
||
$this->template->club = $topic->getClub();
|
||
$this->template->count = $topic->getCommentsCount();
|
||
$this->template->page = (int) ($this->queryParam("p") ?? 1);
|
||
$this->template->comments = iterator_to_array($topic->getComments($this->template->page));
|
||
}
|
||
|
||
function renderCreate(int $clubId): void
|
||
{
|
||
$this->assertUserLoggedIn();
|
||
|
||
$club = $this->clubs->get($clubId);
|
||
if(!$club)
|
||
$this->notFound();
|
||
|
||
if(!$club->isEveryoneCanCreateTopics() && !$club->canBeModifiedBy($this->user->identity))
|
||
$this->notFound();
|
||
|
||
|
||
if($_SERVER["REQUEST_METHOD"] === "POST") {
|
||
$this->willExecuteWriteAction();
|
||
$title = $this->postParam("title");
|
||
|
||
if(!$title)
|
||
$this->flashFail("err", tr("failed_to_create_topic"), tr("no_title_specified"));
|
||
|
||
$flags = 0;
|
||
if($this->postParam("as_group") === "on")
|
||
$flags |= 0b10000000;
|
||
|
||
$topic = new Topic;
|
||
$topic->setGroup($club->getId());
|
||
$topic->setOwner($this->user->id);
|
||
$topic->setTitle(ovk_proc_strtr($title, 127));
|
||
$topic->setCreated(time());
|
||
$topic->setFlags($flags);
|
||
$topic->save();
|
||
|
||
// TODO move to trait
|
||
try {
|
||
$photo = NULL;
|
||
$video = NULL;
|
||
if($_FILES["_pic_attachment"]["error"] === UPLOAD_ERR_OK) {
|
||
$album = NULL;
|
||
if($wall > 0 && $wall === $this->user->id)
|
||
$album = (new Albums)->getUserWallAlbum($wallOwner);
|
||
|
||
$photo = Photo::fastMake($this->user->id, $this->postParam("text"), $_FILES["_pic_attachment"], $album);
|
||
}
|
||
|
||
if($_FILES["_vid_attachment"]["error"] === UPLOAD_ERR_OK) {
|
||
$video = Video::fastMake($this->user->id, $this->postParam("text"), $_FILES["_vid_attachment"]);
|
||
}
|
||
} catch(ISE $ex) {
|
||
$this->flash("err", "Не удалось опубликовать комментарий", "Файл медиаконтента повреждён или слишком велик.");
|
||
$this->redirect("/topic" . $topic->getPrettyId(), static::REDIRECT_TEMPORARY);
|
||
}
|
||
|
||
if(!empty($this->postParam("text")) || $photo || $video) {
|
||
try {
|
||
$comment = new Comment;
|
||
$comment->setOwner($this->user->id);
|
||
$comment->setModel(get_class($topic));
|
||
$comment->setTarget($topic->getId());
|
||
$comment->setContent($this->postParam("text"));
|
||
$comment->setCreated(time());
|
||
$comment->setFlags($flags);
|
||
$comment->save();
|
||
} catch (\LengthException $ex) {
|
||
$this->flash("err", "Не удалось опубликовать комментарий", "Комментарий слишком большой.");
|
||
$this->redirect("/topic" . $topic->getPrettyId(), static::REDIRECT_TEMPORARY);
|
||
}
|
||
|
||
if(!is_null($photo))
|
||
$comment->attach($photo);
|
||
|
||
if(!is_null($video))
|
||
$comment->attach($video);
|
||
}
|
||
|
||
$this->redirect("/topic" . $topic->getPrettyId(), static::REDIRECT_TEMPORARY);
|
||
}
|
||
|
||
$this->template->club = $club;
|
||
$this->template->graffiti = (bool) ovkGetQuirk("comments.allow-graffiti");
|
||
}
|
||
|
||
function renderEdit(int $clubId, int $topicId): void
|
||
{
|
||
$this->assertUserLoggedIn();
|
||
|
||
$topic = $this->topics->getTopicById($clubId, $topicId);
|
||
if(!$topic)
|
||
$this->notFound();
|
||
|
||
if(!$topic->canBeModifiedBy($this->user->identity))
|
||
$this->notFound();
|
||
|
||
if($_SERVER["REQUEST_METHOD"] === "POST") {
|
||
$this->willExecuteWriteAction();
|
||
$title = $this->postParam("title");
|
||
|
||
if(!$title)
|
||
$this->flashFail("err", tr("failed_to_change_topic"), tr("no_title_specified"));
|
||
|
||
$topic->setTitle(ovk_proc_strtr($title, 127));
|
||
$topic->setClosed(empty($this->postParam("close")) ? 0 : 1);
|
||
$topic->setPinned(empty($this->postParam("pin")) ? 0 : 1);
|
||
$topic->save();
|
||
|
||
$this->flash("succ", tr("changes_saved"), tr("topic_changes_saved_comment"));
|
||
$this->redirect("/topic" . $topic->getPrettyId(), static::REDIRECT_TEMPORARY);
|
||
}
|
||
|
||
$this->template->topic = $topic;
|
||
$this->template->club = $topic->getClub();
|
||
}
|
||
|
||
function renderDelete(int $clubId, int $topicId): void
|
||
{
|
||
$this->assertUserLoggedIn();
|
||
$this->assertNoCSRF();
|
||
|
||
$topic = $this->topics->getTopicById($clubId, $topicId);
|
||
if(!$topic)
|
||
$this->notFound();
|
||
|
||
if(!$topic->canBeModifiedBy($this->user->identity))
|
||
$this->notFound();
|
||
|
||
$this->willExecuteWriteAction();
|
||
$topic->deleteTopic();
|
||
|
||
$this->redirect("/board" . $topic->getClub()->getId(), static::REDIRECT_TEMPORARY);
|
||
}
|
||
}
|