. * * @copyright (c) Visman * @license The MIT License (MIT) */ declare(strict_types=1); namespace ForkBB\Models\Pages; use ForkBB\Core\Validator; use ForkBB\Models\Model; use ForkBB\Models\Page; use ForkBB\Models\Topic\Topic; use function \ForkBB\__; class Post extends Page { use PostFormTrait; use PostValidatorTrait; /** * Создание новой темы */ public function newTopic(array $args, string $method): Page { $forum = $this->c->forums->get($args['id']); if ( empty($forum) || $forum->redirect_url || ! $forum->canCreateTopic ) { return $this->c->Message->message('Bad request'); } $this->c->Lang->load('post'); if (1 === $this->c->config->b_poll_enabled) { $this->c->Lang->load('poll'); } $this->onlinePos = 'forum-' . $forum->id; if ('POST' === $method) { $v = $this->messageValidator($forum, 'NewTopic', $args, false, true); if ($this->user->isGuest) { $v = $this->c->Test->beforeValidation($v); } if ( $v->validation($_POST, $this->user->isGuest) //???? && null === $v->preview && null !== $v->submit ) { return $this->endPost($forum, $v); } $this->fIswev = $v->getErrors(); $args['_vars'] = $v->getData(); if ( null !== $v->preview && ! $v->getErrors() ) { $this->previewHtml = $this->c->censorship->censor( $this->c->Parser->parseMessage(null, (bool) $v->hide_smilies) ); if ( $this->user->usePoll && $v->poll_enable ) { $this->poll = $this->c->polls->create($v->poll); $this->c->polls->revision($this->poll, true); } } } $this->nameTpl = 'post'; $this->canonical = $this->c->Router->link( 'NewTopic', [ 'id' => $forum->id, ] ); $this->robots = 'noindex'; $this->formTitle = 'Post new topic'; $this->crumbs = $this->crumbs($this->formTitle, $forum); $this->form = $this->messageForm($forum, 'NewTopic', $args, false, true, false); return $this; } /** * Подготовка данных для шаблона создания сообщения */ public function newReply(array $args, string $method): Page { $topic = $this->c->topics->load($args['id']); if ( ! $topic instanceof Topic || ! $topic->canReply ) { return $this->c->Message->message('Bad request'); } $this->c->Lang->load('post'); $this->onlinePos = 'topic-' . $topic->id; if ('POST' === $method) { $v = $this->messageValidator($topic, 'NewReply', $args, false, false); if ($this->user->isGuest) { $v = $this->c->Test->beforeValidation($v); } if ( $v->validation($_POST, $this->user->isGuest) //???? && null === $v->preview && null !== $v->submit ) { return $this->endPost($topic, $v); } $this->fIswev = $v->getErrors(); $args['_vars'] = $v->getData(); //???? if ( null !== $v->preview && ! $v->getErrors() ) { $this->previewHtml = $this->c->Parser->parseMessage(null, (bool) $v->hide_smilies); } } elseif (isset($args['quote'])) { $post = $this->c->posts->load($args['quote'], $topic->id); if (empty($post)) { return $this->c->Message->message('Bad request'); } $args['_vars'] = [ 'message' => "[quote=\"{$post->poster}\"]{$post->message}[/quote]", ]; unset($args['quote']); } $this->nameTpl = 'post'; $this->canonical = $this->c->Router->link( 'NewReply', [ 'id' => $topic->id, ] ); $this->robots = 'noindex'; $this->formTitle = 'Post a reply'; $this->crumbs = $this->crumbs($this->formTitle, $topic); $this->form = $this->messageForm($topic, 'NewReply', $args, false, false, false); $this->postsTitle = 'Topic review'; $this->posts = $topic->review(); return $this; } /** * Создание темы/сообщения */ protected function endPost(Model $model, Validator $v): Page { $this->c->Online->calc($this); // для подписок $now = \time(); $username = $this->user->isGuest ? $v->username : $this->user->username; $merge = false; $executive = $this->user->isAdmin || $this->user->isModerator($model); // подготовка к объединению/сохранению сообщения if (null === $v->subject) { $createTopic = false; $forum = $model->parent; $topic = $model; if ( ! $this->user->isGuest && $topic->last_poster_id === $this->user->id ) { if ($executive) { if ($v->merge_post) { $merge = true; } } else { $merge = true; } } // создание темы } else { $createTopic = true; $forum = $model; $topic = $this->c->topics->create(); $topic->subject = $v->subject; $topic->poster = $username; $topic->poster_id = $this->user->id; $topic->last_poster = $username; $topic->last_poster_id = $this->user->id; $topic->posted = $now; $topic->last_post = $now; $topic->sticky = $v->stick_topic ? 1 : 0; $topic->stick_fp = $v->stick_fp ? 1 : 0; $this->c->topics->insert($topic); } // попытка объеденить новое сообщение с крайним в теме if ($merge) { $lastPost = $this->c->posts->load($topic->last_post_id, $topic->id); $newLength = \mb_strlen($lastPost->message . $v->message, 'UTF-8'); if ($newLength < $this->c->MAX_POST_SIZE - 100) { $lastPost->message = $lastPost->message . "\n[after=" . ($now - $topic->last_post) . "]\n" . $v->message; //???? $lastPost->edited = $now; $lastPost->editor = $username; // ???? может копировать из poster $lastPost->editor_id = $this->user->id; // ???? может копировать из poster_id $this->c->posts->update($lastPost); } else { $merge = false; } } // создание нового сообщения if (! $merge) { $post = $this->c->posts->create(); $post->poster = $username; $post->poster_id = $this->user->id; $post->poster_ip = $this->user->ip; $post->poster_email = (string) $v->email; $post->message = $v->message; //????? $post->hide_smilies = $v->hide_smilies ? 1 : 0; # $post->edit_post = $post->posted = $now; # $post->edited = # $post->editor = # $post->editor_id = $post->user_agent = \mb_substr($this->user->userAgent, 0, 255, 'UTF-8'); $post->topic_id = $topic->id; $this->c->posts->insert($post); } if ($createTopic) { $topic->forum_id = $forum->id; $topic->first_post_id = $post->id; if ( $this->user->usePoll && $v->poll_enable ) { $topic->poll_type = $v->poll['duration'] > 0 ? 1000 + $v->poll['duration'] : 1; // ???? перенести в модель poll? $topic->poll_time = $now; $topic->poll_term = $v->poll['hide_result'] ? $this->c->config->i_poll_term : 0; $poll = $this->c->polls->create([ 'tid' => $topic->id, 'question' => $v->poll['question'], 'answer' => $v->poll['answer'], 'type' => $v->poll['type'], ]); $this->c->polls->insert($poll); } } // обновление данных в теме и разделе $this->c->topics->update($topic->calcStat()); $this->c->forums->update($forum->calcStat()); // обновление данных текущего пользователя if ( ! $merge && ! $this->user->isGuest ) { if (0 == $forum->no_sum_mess) { $this->user->num_posts = $this->user->num_posts + 1; if ( $this->user->g_promote_next_group > 0 && $this->user->num_posts >= $this->user->g_promote_min_posts ) { $this->user->group_id = $this->user->g_promote_next_group; } } if ($createTopic) { $this->user->num_topics = $this->user->num_topics + 1; } } $this->user->last_post = $now; $this->c->users->update($this->user); if (1 === $this->c->config->b_topic_subscriptions) { // ???? if ( $v->subscribe && ! $topic->is_subscribed ) { $this->c->subscriptions->subscribe($this->user, $topic); } elseif ( ! $v->subscribe && $topic->is_subscribed ) { $this->c->subscriptions->unsubscribe($this->user, $topic); } } if ($merge) { $this->c->search->index($lastPost, 'merge'); } else { $this->c->search->index($post); if ($createTopic) { if (1 === $this->c->config->b_forum_subscriptions) { // ???? $this->c->subscriptions->send($post, $topic); } } else { if (1 === $this->c->config->b_topic_subscriptions) { // ???? $this->c->subscriptions->send($post); } } } return $this->c->Redirect->url($merge ? $lastPost->link : $post->link)->message('Post redirect'); } }