123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
- <?php
- /**
- * This file is part of the ForkBB <https://github.com/forkbb>.
- *
- * @copyright (c) Visman <mio.visman@yandex.ru, https://github.com/MioVisman>
- * @license The MIT License (MIT)
- */
- declare(strict_types=1);
- namespace ForkBB\Models\Forum;
- use ForkBB\Models\DataModel;
- use ForkBB\Models\User\User;
- use PDO;
- use RuntimeException;
- use InvalidArgumentException;
- class Forum extends DataModel
- {
- /**
- * Ключ модели для контейнера
- * @var string
- */
- protected $cKey = 'Forum';
- /**
- * Получение родительского раздела
- */
- protected function getparent(): ?Forum
- {
- if (
- null === $this->parent_forum_id
- && 0 !== $this->id
- ) {
- throw new RuntimeException('Parent is not defined');
- }
- return $this->c->forums->get($this->parent_forum_id);
- }
- /**
- * Возвращает название раздела
- */
- protected function getname(): ?string
- {
- return $this->forum_name;
- }
- /**
- * Статус возможности создания новой темы
- */
- protected function getcanCreateTopic(): bool
- {
- $user = $this->c->user;
- return 1 === $this->post_topics
- || (
- null === $this->post_topics
- && 1 === $user->g_post_topics
- )
- || $user->isAdmin
- || $user->isModerator($this);
- }
- /**
- * Статус возможности пометки всех тем прочтенными
- */
- protected function getcanMarkRead(): bool
- {
- return ! $this->c->user->isGuest
- && ! $this->c->user->isUnverified;
- }
- /**
- * Статус возможности использования подписок
- */
- protected function getcanSubscription(): bool
- {
- return 1 === $this->c->config->b_forum_subscriptions
- && $this->id > 0
- && ! $this->c->user->isGuest
- && ! $this->c->user->isUnverified;
- }
- /**
- * Получение массива подразделов
- */
- protected function getsubforums(): array
- {
- $sub = [];
- $attr = $this->getAttr('subforums');
- if (\is_array($attr)) {
- foreach ($attr as $id) {
- $sub[$id] = $this->c->forums->get($id);
- }
- }
- return $sub;
- }
- /**
- * Получение массива всех дочерних разделов
- */
- protected function getdescendants(): array
- {
- $all = [];
- $attr = $this->getAttr('descendants');
- if (\is_array($attr)) {
- foreach ($attr as $id) {
- $all[$id] = $this->c->forums->get($id);
- }
- }
- return $all;
- }
- /**
- * Ссылка на раздел
- */
- protected function getlink(): string
- {
- if (0 === $this->id) {
- return $this->c->Router->link('Index');
- } else {
- return $this->c->Router->link(
- 'Forum',
- [
- 'id' => $this->id,
- 'name' => $this->forum_name,
- ]
- );
- }
- }
- /**
- * Ссылка на поиск новых сообщений
- */
- protected function getlinkNew(): string
- {
- if (0 === $this->id) {
- return $this->c->Router->link(
- 'SearchAction',
- [
- 'action' => 'new',
- ]
- );
- } else {
- return $this->c->Router->link(
- 'SearchAction',
- [
- 'action' => 'new',
- 'forum' => $this->id,
- ]
- );
- }
- }
- /**
- * Ссылка на последнее сообщение в разделе
- */
- protected function getlinkLast(): string
- {
- if ($this->last_post_id < 1) {
- return '';
- } else {
- return $this->c->Router->link(
- 'ViewPost',
- [
- 'id' => $this->last_post_id,
- ]
- );
- }
- }
- /**
- * Ссылка на создание новой темы
- */
- protected function getlinkCreateTopic(): string
- {
- return $this->c->Router->link(
- 'NewTopic',
- [
- 'id' => $this->id,
- ]
- );
- }
- /**
- * Ссылка на пометку всех тем прочтенными
- */
- protected function getlinkMarkRead(): string
- {
- return $this->c->Router->link(
- 'MarkRead',
- [
- 'id' => $this->id,
- ]
- );
- }
- /**
- * Ссылка на подписку
- */
- protected function getlinkSubscribe(): string
- {
- if ($this->id < 1) {
- return '';
- } else {
- return $this->c->Router->link(
- 'ForumSubscription',
- [
- 'fid' => $this->id,
- 'type' => 'subscribe',
- ]
- );
- }
- }
- /**
- * Ссылка на отписку
- */
- protected function getlinkUnsubscribe(): string
- {
- if ($this->id < 1) {
- return '';
- } else {
- return $this->c->Router->link(
- 'ForumSubscription',
- [
- 'fid' => $this->id,
- 'type' => 'unsubscribe',
- ]
- );
- }
- }
- /**
- * Получение массива модераторов
- */
- protected function getmoderators(): array
- {
- $attr = $this->getAttr('moderators');
- if (
- empty($attr)
- || ! \is_array($attr)
- ) {
- return [];
- }
- $viewUsers = $this->c->user->viewUsers;
- foreach ($attr as $id => &$cur) {
- $cur = [
- 'name' => $cur,
- 'link' => $viewUsers ?
- $this->c->Router->link(
- 'User',
- [
- 'id' => $id,
- 'name' => $cur,
- ]
- )
- : null,
- ];
- }
- unset($cur);
- return $attr;
- }
- /**
- * Добавляет указанных пользователей в список модераторов
- */
- public function modAdd(User ...$users): void
- {
- $attr = $this->getAttr('moderators');
- if (
- empty($attr)
- || ! \is_array($attr)
- ) {
- $attr = [];
- }
- foreach ($users as $user) {
- if (! $user instanceof User) {
- throw new InvalidArgumentException('Expected User');
- }
- $attr[$user->id] = $user->username;
- }
- $this->moderators = $attr;
- }
- /**
- * Удаляет указанных пользователей из списка модераторов
- */
- public function modDelete(User ...$users): void
- {
- $attr = $this->getAttr('moderators');
- if (
- empty($attr)
- || ! \is_array($attr)
- ) {
- return;
- }
- foreach ($users as $user) {
- if (! $user instanceof User) {
- throw new InvalidArgumentException('Expected User');
- }
- unset($attr[$user->id]);
- }
- $this->moderators = $attr;
- }
- /**
- * Возвращает общую статистику по дереву разделов с корнем в текущем разделе
- */
- protected function gettree(): Forum
- {
- $attr = $this->getAttr('tree');
- if (empty($attr)) { //????
- $numT = (int) $this->num_topics;
- $numP = (int) $this->num_posts;
- $time = (int) $this->last_post;
- $postId = (int) $this->last_post_id;
- $poster = $this->last_poster;
- $topic = $this->last_topic;
- $fnew = $this->newMessages;
- foreach ($this->descendants as $chId => $children) {
- $fnew = $fnew || $children->newMessages;
- $numT += $children->num_topics;
- $numP += $children->num_posts;
- if ($children->last_post > $time) {
- $time = $children->last_post;
- $postId = $children->last_post_id;
- $poster = $children->last_poster;
- $topic = $children->last_topic;
- }
- }
- $attr = $this->c->forums->create([
- 'num_topics' => $numT,
- 'num_posts' => $numP,
- 'last_post' => $time,
- 'last_post_id' => $postId,
- 'last_poster' => $poster,
- 'last_topic' => $topic,
- 'newMessages' => $fnew,
- ]);
- $this->setAttr('tree', $attr);
- }
- return $attr;
- }
- /**
- * Количество страниц в разделе
- */
- protected function getnumPages(): int
- {
- if (! \is_int($this->num_topics)) {
- throw new RuntimeException('The model does not have the required data');
- }
- return (int) \ceil(($this->num_topics ?: 1) / $this->c->user->disp_topics);
- }
- /**
- * Массив страниц раздела
- */
- protected function getpagination(): array
- {
- return $this->c->Func->paginate(
- $this->numPages,
- $this->page,
- 'Forum',
- [
- 'id' => $this->id,
- 'name' => $this->forum_name,
- ]
- );
- }
- /**
- * Статус наличия установленной страницы в разделе
- */
- public function hasPage(): bool
- {
- return $this->page > 0 && $this->page <= $this->numPages;
- }
- /**
- * Возвращает массив тем с установленной страницы
- */
- public function pageData(): array
- {
- if (! $this->hasPage()) {
- throw new InvalidArgumentException('Bad number of displayed page');
- }
- if (empty($this->num_topics)) {
- return [];
- }
- switch ($this->sort_by) {
- case 1:
- $sortBy = 't.posted DESC';
- break;
- case 2:
- $sortBy = 't.subject ASC';
- break;
- default:
- $sortBy = 't.last_post DESC';
- break;
- }
- $vars = [
- ':fid' => $this->id,
- ':offset' => ($this->page - 1) * $this->c->user->disp_topics,
- ':rows' => $this->c->user->disp_topics,
- ];
- $query = "SELECT t.id
- FROM ::topics AS t
- WHERE t.forum_id=?i:fid
- ORDER BY t.sticky DESC, {$sortBy}, t.id DESC
- LIMIT ?i:rows OFFSET ?i:offset";
- $this->idsList = $this->c->DB->query($query, $vars)->fetchAll(PDO::FETCH_COLUMN);
- return empty($this->idsList) ? [] : $this->c->topics->view($this);
- }
- /**
- * Возвращает значения свойств в массиве
- */
- public function getAttrs(): array
- {
- $data = parent::getAttrs();
- $data['moderators'] = empty($data['moderators']) || ! \is_array($data['moderators'])
- ? ''
- : \json_encode($data['moderators']);
- return $data;
- }
- }
|