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

Размер файла: 4.75Kb
  1. <?php
  2.  
  3. declare(strict_types=1);
  4.  
  5. namespace App\Models;
  6.  
  7. use App\Traits\UploadTrait;
  8. use Exception;
  9. use Illuminate\Database\Eloquent\Collection;
  10. use Illuminate\Database\Eloquent\Relations\BelongsTo;
  11. use Illuminate\Database\Eloquent\Relations\HasMany;
  12. use Illuminate\Database\Eloquent\Relations\MorphMany;
  13. use Illuminate\Database\Eloquent\Relations\MorphOne;
  14. use Illuminate\Support\HtmlString;
  15.  
  16. /**
  17. * Class Article
  18. *
  19. * @property int id
  20. * @property int category_id
  21. * @property int user_id
  22. * @property string title
  23. * @property string text
  24. * @property string tags
  25. * @property int rating
  26. * @property int visits
  27. * @property int count_comments
  28. * @property int created_at
  29. * @property Collection files
  30. * @property Blog category
  31. */
  32. class Article extends BaseModel
  33. {
  34. use UploadTrait;
  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. * Директория загрузки файлов
  52. *
  53. * @var string
  54. */
  55. public $uploadPath = '/uploads/articles';
  56.  
  57. /**
  58. * Counting field
  59. *
  60. * @var string
  61. */
  62. public $countingField = 'visits';
  63.  
  64. /**
  65. * Morph name
  66. *
  67. * @var string
  68. */
  69. public static $morphName = 'articles';
  70.  
  71. /**
  72. * Возвращает комментарии блогов
  73. *
  74. * @return MorphMany
  75. */
  76. public function comments(): MorphMany
  77. {
  78. return $this->morphMany(Comment::class, 'relate')->with('relate');
  79. }
  80.  
  81. /**
  82. * Возвращает последнии комментарии к статье
  83. *
  84. * @param int $limit
  85. * @return HasMany
  86. */
  87. public function lastComments(int $limit = 15): HasMany
  88. {
  89. return $this->hasMany(Comment::class, 'relate_id')
  90. ->where('relate_type', self::$morphName)
  91. ->orderBy('created_at', 'desc')
  92. ->with('user')
  93. ->limit($limit);
  94. }
  95.  
  96. /**
  97. * Возвращает связь категории блога
  98. *
  99. * @return BelongsTo
  100. */
  101. public function category(): BelongsTo
  102. {
  103. return $this->belongsTo(Blog::class, 'category_id')->withDefault();
  104. }
  105.  
  106. /**
  107. * Возвращает загруженные файлы
  108. *
  109. * @return MorphMany
  110. */
  111. public function files(): MorphMany
  112. {
  113. return $this->morphMany(File::class, 'relate');
  114. }
  115.  
  116. /**
  117. * Возвращает связь с голосованием
  118. *
  119. * @return morphOne
  120. */
  121. public function polling(): morphOne
  122. {
  123. return $this->morphOne(Polling::class, 'relate')->where('user_id', getUser('id'));
  124. }
  125.  
  126. /**
  127. * Возвращает путь к первому файлу
  128. *
  129. * @return HtmlString|null код изображения
  130. */
  131. public function getFirstImage(): ?HtmlString
  132. {
  133. $image = $this->files->first();
  134.  
  135. if (! $image) {
  136. return null;
  137. }
  138.  
  139. return new HtmlString('<img src="' . $image->hash . '" atl="' . $this->title . '" class="card-img-top">');
  140. }
  141.  
  142. /**
  143. * Возвращает сокращенный текст статьи
  144. *
  145. * @param int $words
  146. *
  147. * @return HtmlString
  148. */
  149. public function shortText(int $words = 100): HtmlString
  150. {
  151. $more = view('app/_more', ['link' => '/articles/'. $this->id]);
  152.  
  153. if (strpos($this->text, '[cut]') !== false) {
  154. $this->text = bbCode(current(explode('[cut]', $this->text)));
  155. } else {
  156. $this->text = bbCodeTruncate($this->text, $words);
  157. }
  158.  
  159. return new HtmlString($this->text . $more);
  160. }
  161.  
  162. /**
  163. * Возвращает размер шрифта для облака тегов
  164. *
  165. * @param int $count
  166. * @param float $minCount
  167. * @param float $maxCount
  168. * @param int $minSize
  169. * @param int $maxSize
  170. *
  171. * @return int
  172. */
  173. public static function logTagSize($count, $minCount, $maxCount, $minSize = 10, $maxSize = 30): int
  174. {
  175. $minCount = log($minCount + 1);
  176. $maxCount = log($maxCount + 1);
  177.  
  178. $diffSize = $maxSize - $minSize;
  179. $diffCount = $maxCount - $minCount;
  180.  
  181. if (empty($diffCount)) {
  182. $diffCount = 1;
  183. }
  184.  
  185. return (int) round($minSize + (log(1 + $count) - $minCount) * ($diffSize / $diffCount));
  186. }
  187.  
  188. /**
  189. * Удаление статьи и загруженных файлов
  190. *
  191. * @return bool|null
  192. * @throws Exception
  193. */
  194. public function delete(): ?bool
  195. {
  196. $this->files->each(static function (File $file) {
  197. $file->delete();
  198. });
  199.  
  200. return parent::delete();
  201. }
  202. }