User.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. <?php
  2. /**
  3. * This file is part of the ForkBB <https://github.com/forkbb>.
  4. *
  5. * @copyright (c) Visman <mio.visman@yandex.ru, https://github.com/MioVisman>
  6. * @license The MIT License (MIT)
  7. */
  8. declare(strict_types=1);
  9. namespace ForkBB\Models\User;
  10. use ForkBB\Core\Container;
  11. use ForkBB\Models\DataModel;
  12. use ForkBB\Models\Model;
  13. use ForkBB\Models\Forum\Forum;
  14. use ForkBB\Models\Post\Post;
  15. use RuntimeException;
  16. use function \ForkBB\__;
  17. class User extends DataModel
  18. {
  19. /**
  20. * Ключ модели для контейнера
  21. * @var string
  22. */
  23. protected $cKey = 'User';
  24. public function __construct(Container $container)
  25. {
  26. parent::__construct($container);
  27. $this->zDepend = [
  28. 'group_id' => ['isUnverified', 'isGuest', 'isAdmin', 'isAdmMod', 'isBanByName', 'link', 'viewUsers', 'showPostCount', 'searchUsers', 'usePoll', 'usePM'],
  29. 'id' => ['isGuest', 'link', 'online'],
  30. 'last_visit' => ['currentVisit'],
  31. 'show_sig' => ['showSignature'],
  32. 'show_avatars' => ['showAvatar'],
  33. 'signature' => ['isSignature'],
  34. 'email' => ['email_normal'],
  35. 'username' => ['username_normal'],
  36. 'g_pm' => ['usePM'],
  37. ];
  38. }
  39. /**
  40. * Статус неподтвержденного
  41. */
  42. protected function getisUnverified(): bool
  43. {
  44. return FORK_GROUP_UNVERIFIED === $this->group_id;
  45. }
  46. /**
  47. * Статус гостя
  48. */
  49. protected function getisGuest(): bool
  50. {
  51. return FORK_GROUP_GUEST === $this->group_id
  52. || null === $this->group_id
  53. || $this->id < 1;
  54. }
  55. /**
  56. * Статус админа
  57. */
  58. protected function getisAdmin(): bool
  59. {
  60. return FORK_GROUP_ADMIN === $this->group_id;
  61. }
  62. /**
  63. * Статус админа/модератора
  64. */
  65. protected function getisAdmMod(): bool
  66. {
  67. return $this->isAdmin || 1 === $this->g_moderator;
  68. }
  69. /**
  70. * Статус бана по имени пользователя
  71. */
  72. protected function getisBanByName(): bool
  73. {
  74. return ! $this->isAdmin
  75. && $this->c->bans->banFromName($this->username) > 0;
  76. }
  77. /**
  78. * Статус модератора для указанной модели
  79. */
  80. public function isModerator(Model $model): bool
  81. {
  82. if (1 !== $this->g_moderator) {
  83. return false;
  84. }
  85. while (! $model instanceof Forum) {
  86. $model = $model->parent;
  87. if (! $model instanceof Model) {
  88. throw new RuntimeException('Moderator\'s rights can not be found');
  89. }
  90. }
  91. return isset($model->moderators[$this->id]);
  92. }
  93. /**
  94. * Время последнего (или текущего) визита
  95. */
  96. protected function getcurrentVisit(): int
  97. {
  98. return $this->c->Online->currentVisit($this) ?? $this->last_visit;
  99. }
  100. /**
  101. * Текущий язык пользователя
  102. */
  103. protected function getlanguage(): string
  104. {
  105. $langs = $this->c->Func->getLangs();
  106. $lang = $this->getAttr('language');
  107. if (
  108. empty($lang)
  109. || ! isset($langs[$lang])
  110. ) {
  111. $lang = $this->c->config->o_default_lang;
  112. }
  113. if (isset($langs[$lang])) {
  114. return $lang;
  115. } else {
  116. return \reset($langs) ?: 'en';
  117. }
  118. }
  119. /**
  120. * Текущий стиль отображения
  121. */
  122. protected function getstyle(): string
  123. {
  124. $styles = $this->c->Func->getStyles();
  125. $style = $this->getAttr('style');
  126. if (
  127. $this->isGuest
  128. || empty($style)
  129. || ! isset($styles[$style])
  130. ) {
  131. $style = $this->c->config->o_default_style;
  132. }
  133. if (isset($styles[$style])) {
  134. return $style;
  135. } else {
  136. return \reset($styles) ?: 'ForkBB';
  137. }
  138. }
  139. /**
  140. * Ссылка на профиль пользователя
  141. */
  142. protected function getlink(): ?string
  143. {
  144. if ($this->isGuest) {
  145. return null;
  146. } else {
  147. return $this->c->Router->link(
  148. 'User',
  149. [
  150. 'id' => $this->id,
  151. 'name' => $this->username,
  152. ]
  153. );
  154. }
  155. }
  156. /**
  157. * Ссылка на аватару пользователя
  158. */
  159. protected function getavatar(): ?string
  160. {
  161. $file = $this->getAttr('avatar');
  162. if (! empty($file)) {
  163. $file = $this->c->config->o_avatars_dir . '/' . $file;
  164. $path = $this->c->DIR_PUBLIC . $file;
  165. if (\is_file($path)) {
  166. return $this->c->PUBLIC_URL . $file;
  167. }
  168. }
  169. return null;
  170. }
  171. /**
  172. * Удаляет аватару пользователя
  173. */
  174. public function deleteAvatar(): void
  175. {
  176. $file = $this->getAttr('avatar');
  177. if (! empty($file)) {
  178. $path = $this->c->DIR_PUBLIC . "{$this->c->config->o_avatars_dir}/{$file}";
  179. if (\is_file($path)) {
  180. \unlink($path);
  181. }
  182. $this->avatar = '';
  183. }
  184. }
  185. /**
  186. * Титул пользователя
  187. */
  188. public function title(): string
  189. {
  190. if ($this->isBanByName) {
  191. return __('Banned');
  192. } elseif ('' != $this->title) {
  193. return $this->censorTitle;
  194. } elseif ('' != $this->g_user_title) {
  195. return $this->censorG_user_title;
  196. } elseif ($this->isGuest) {
  197. return __('Guest');
  198. } elseif ($this->isUnverified) {
  199. return __('Unverified');
  200. } else {
  201. return __('Member');
  202. }
  203. }
  204. /**
  205. * Статус online
  206. */
  207. protected function getonline(): bool
  208. {
  209. return $this->c->Online->isOnline($this);
  210. }
  211. /**
  212. * Статус наличия подписи
  213. */
  214. protected function getisSignature(): bool
  215. {
  216. return $this->g_sig_length > 0
  217. && $this->g_sig_lines > 0
  218. && '' != $this->signature;
  219. }
  220. /**
  221. * HTML код подписи
  222. */
  223. protected function gethtmlSign(): string
  224. {
  225. return $this->isSignature
  226. ? $this->c->censorship->censor($this->c->Parser->parseSignature($this->signature))
  227. : '';
  228. }
  229. /**
  230. * Статус видимости профилей пользователей
  231. */
  232. protected function getviewUsers(): bool
  233. {
  234. return 1 === $this->g_view_users || $this->isAdmin;
  235. }
  236. /**
  237. * Статус поиска пользователей
  238. */
  239. protected function getsearchUsers(): bool
  240. {
  241. return 1 === $this->g_search_users || $this->isAdmin;
  242. }
  243. /**
  244. * Статус показа аватаров
  245. */
  246. protected function getshowAvatar(): bool
  247. {
  248. return 1 === $this->c->config->b_avatars && 1 === $this->show_avatars;
  249. }
  250. /**
  251. * Статус показа информации пользователя
  252. */
  253. protected function getshowUserInfo(): bool
  254. {
  255. return 1 === $this->c->config->b_show_user_info;
  256. }
  257. /**
  258. * Статус показа подписи
  259. */
  260. protected function getshowSignature(): bool
  261. {
  262. return 1 === $this->show_sig;
  263. }
  264. /**
  265. * Статус показа количества сообщений
  266. */
  267. protected function getshowPostCount(): bool
  268. {
  269. return 1 === $this->c->config->b_show_post_count || $this->isAdmMod;
  270. }
  271. /**
  272. * Число тем на одну страницу
  273. */
  274. protected function getdisp_topics(): int
  275. {
  276. $attr = $this->getAttr('disp_topics');
  277. if ($attr < 10) {
  278. $attr = $this->c->config->i_disp_topics_default;
  279. }
  280. return $attr;
  281. }
  282. /**
  283. * Число сообщений на одну страницу
  284. */
  285. protected function getdisp_posts(): int
  286. {
  287. $attr = $this->getAttr('disp_topics');
  288. if ($attr < 10) {
  289. $attr = $this->c->config->i_disp_posts_default;
  290. }
  291. return $attr;
  292. }
  293. /**
  294. * Ссылка для продвижения пользователя из указанного сообщения
  295. */
  296. public function linkPromote(Post $post): ?string
  297. {
  298. if (
  299. (
  300. $this->isAdmin
  301. || (
  302. $this->isAdmMod
  303. && 1 === $this->g_mod_promote_users
  304. )
  305. )
  306. && $this->id !== $post->user->id //????
  307. && 0 < $post->user->g_promote_min_posts * $post->user->g_promote_next_group
  308. && ! $post->user->isBanByName
  309. ) {
  310. return $this->c->Router->link(
  311. 'AdminUserPromote',
  312. [
  313. 'uid' => $post->user->id,
  314. 'pid' => $post->id,
  315. ]
  316. );
  317. } else {
  318. return null;
  319. }
  320. }
  321. /**
  322. * Вычисляет нормализованный email
  323. */
  324. protected function getemail_normal(): string
  325. {
  326. return $this->c->NormEmail->normalize($this->email);
  327. }
  328. /**
  329. * Вычисляет нормализованный username
  330. */
  331. protected function getusername_normal(): string
  332. {
  333. return $this->c->users->normUsername($this->username);
  334. }
  335. /**
  336. * Возвращает значения свойств в массиве
  337. */
  338. public function getAttrs(): array
  339. {
  340. foreach (['email_normal', 'username_normal'] as $key) {
  341. if (isset($this->zModFlags[$key])) {
  342. $this->setAttr($key, $this->$key);
  343. }
  344. }
  345. return parent::getAttrs();
  346. }
  347. /**
  348. * Статус возможности использования опросов
  349. */
  350. protected function getusePoll(): bool
  351. {
  352. return 1 === $this->c->config->b_poll_enabled && ! $this->isGuest;
  353. }
  354. public function fLog(): string
  355. {
  356. return "id:{$this->id} gid:{$this->group_id} name:{$this->username}";
  357. }
  358. /**
  359. * Статус возможности использования приватных сообщений
  360. */
  361. protected function getusePM(): bool
  362. {
  363. return 1 === $this->c->config->b_pm
  364. && (
  365. 1 === $this->g_pm
  366. || $this->isAdmin
  367. );
  368. }
  369. }