Просмотр файла app/Models/Topic.php

Размер файла: 5.09Kb
  1. <?php
  2.  
  3. declare(strict_types=1);
  4.  
  5. namespace App\Models;
  6.  
  7. use Illuminate\Database\Eloquent\Collection;
  8. use Illuminate\Database\Eloquent\Relations\BelongsTo;
  9. use Illuminate\Database\Eloquent\Relations\HasMany;
  10. use Illuminate\Database\Eloquent\Relations\HasOne;
  11. use Illuminate\Support\HtmlString;
  12.  
  13. /**
  14. * Class Topic
  15. *
  16. * @property int id
  17. * @property int forum_id
  18. * @property string title
  19. * @property int user_id
  20. * @property int closed
  21. * @property int locked
  22. * @property int count_posts
  23. * @property int visits
  24. * @property int updated_at
  25. * @property string|null moderators
  26. * @property string note
  27. * @property int last_post_id
  28. * @property int close_user_id
  29. * @property int created_at
  30. * @property Forum forum
  31. * @property Collection posts
  32. * @property Vote vote
  33. */
  34. class Topic extends BaseModel
  35. {
  36. /**
  37. * Indicates if the model should be timestamped.
  38. *
  39. * @var bool
  40. */
  41. public $timestamps = false;
  42.  
  43. /**
  44. * The attributes that aren't mass assignable.
  45. *
  46. * @var array
  47. */
  48. protected $guarded = [];
  49.  
  50. /**
  51. * Counting field
  52. *
  53. * @var string
  54. */
  55. public $countingField = 'visits';
  56.  
  57. /**
  58. * Morph name
  59. *
  60. * @var string
  61. */
  62. public static $morphName = 'topics';
  63.  
  64. /**
  65. * Возвращает сообщения
  66. *
  67. * @return HasMany
  68. */
  69. public function posts(): HasMany
  70. {
  71. return $this->hasMany(Post::class, 'topic_id');
  72. }
  73.  
  74. /**
  75. * Возвращает закладки
  76. *
  77. * @return HasMany
  78. */
  79. public function bookmarks(): HasMany
  80. {
  81. return $this->hasMany(Bookmark::class, 'topic_id');
  82. }
  83.  
  84. /**
  85. * Возвращает голосование
  86. *
  87. * @return hasOne
  88. */
  89. public function vote(): hasOne
  90. {
  91. return $this->hasOne(Vote::class, 'topic_id')->withDefault();
  92. }
  93.  
  94. /**
  95. * Возвращает последнее сообщение
  96. *
  97. * @return BelongsTo
  98. */
  99. public function lastPost(): BelongsTo
  100. {
  101. return $this->belongsTo(Post::class, 'last_post_id')->withDefault();
  102. }
  103.  
  104. /**
  105. * Возвращает раздел форума
  106. *
  107. * @return BelongsTo
  108. */
  109. public function forum(): BelongsTo
  110. {
  111. return $this->belongsTo(Forum::class, 'forum_id')->withDefault();
  112. }
  113.  
  114. /**
  115. * Возвращает связь пользователей
  116. *
  117. * @return BelongsTo
  118. */
  119. public function closeUser(): BelongsTo
  120. {
  121. return $this->belongsTo(User::class, 'close_user_id')->withDefault();
  122. }
  123.  
  124. /**
  125. * Возвращает иконку в зависимости от статуса
  126. *
  127. * @return string иконка топика
  128. */
  129. public function getIcon(): string
  130. {
  131. if ($this->closed) {
  132. $icon = 'fa-lock';
  133. } elseif ($this->locked) {
  134. $icon = 'fa-thumbtack';
  135. } else {
  136. $icon = 'fa-folder-open';
  137. }
  138.  
  139. return $icon;
  140. }
  141.  
  142. /**
  143. * Генерирует постраничную навигация для форума
  144. *
  145. * @param string $url
  146. * @return HtmlString|null сформированный блок
  147. */
  148. public function pagination(string $url = '/topics'): ?HtmlString
  149. {
  150. if (! $this->count_posts) {
  151. return null;
  152. }
  153.  
  154. $pages = [];
  155. $link = $url . '/' . $this->id;
  156.  
  157. $pg_cnt = ceil($this->count_posts / setting('forumpost'));
  158.  
  159. for ($i = 1; $i <= 5; $i++) {
  160. if ($i <= $pg_cnt) {
  161. $pages[] = [
  162. 'page' => $i,
  163. 'title' => $i . ' страница',
  164. 'name' => $i,
  165. ];
  166. }
  167. }
  168.  
  169. if (5 < $pg_cnt) {
  170. if (6 < $pg_cnt) {
  171. $pages[] = [
  172. 'separator' => true,
  173. 'name' => ' ... ',
  174. ];
  175. }
  176.  
  177. $pages[] = [
  178. 'page' => $pg_cnt,
  179. 'title' => $pg_cnt . ' страница',
  180. 'name' => $pg_cnt,
  181. ];
  182. }
  183.  
  184. return new HtmlString(view('forums/_pagination', compact('pages', 'link')));
  185. }
  186.  
  187. /**
  188. * Пересчет темы
  189. *
  190. * @return void
  191. */
  192. public function restatement(): void
  193. {
  194. $lastPost = Post::query()
  195. ->where('topic_id', $this->id)
  196. ->orderByDesc('updated_at')
  197. ->first();
  198.  
  199. $countPosts = Post::query()->where('topic_id', $this->id)->count();
  200.  
  201. $this->update([
  202. 'count_posts' => $countPosts,
  203. 'last_post_id' => $lastPost->id ?? 0,
  204. ]);
  205.  
  206. $this->forum->restatement();
  207. }
  208.  
  209. /**
  210. * Get count posts
  211. *
  212. * @return HtmlString
  213. */
  214. public function getCountPosts(): HtmlString
  215. {
  216. $newPosts = null;
  217. if (isset($this->bookmark_posts) && $this->count_posts > $this->bookmark_posts) {
  218. $newPosts = ' <span style="color:#00aa00">+' . ($this->count_posts - $this->bookmark_posts) . '</span>';
  219. }
  220.  
  221.  
  222. return new HtmlString($this->count_posts . $newPosts);
  223. }
  224. }