Save.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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\Models\Action;
  11. use ForkBB\Models\User\User;
  12. use RuntimeException;
  13. class Save extends Action
  14. {
  15. /**
  16. * Обновляет данные пользователя
  17. */
  18. public function update(User $user): User
  19. {
  20. if (
  21. (! $user->isGuest && $user->id < 1)
  22. || ($user->isGuest && 0 !== $user->id)
  23. ) {
  24. throw new RuntimeException('Bad ID');
  25. }
  26. $modified = $user->getModified();
  27. if (empty($modified)) {
  28. return $user;
  29. }
  30. $values = $user->getAttrs();
  31. if ($user->isGuest) {
  32. $fileds = $this->c->dbMap->online;
  33. $table = 'online';
  34. $where = 'user_id=0 AND ident=?s';
  35. } else {
  36. $fileds = $this->c->dbMap->users;
  37. $table = 'users';
  38. $where = 'id=?i';
  39. }
  40. $set = $vars = [];
  41. $grChange = false;
  42. $nameChange = false;
  43. foreach ($modified as $name) {
  44. if (! isset($fileds[$name])) {
  45. continue;
  46. }
  47. $vars[] = $values[$name];
  48. $set[] = $name . '=?' . $fileds[$name];
  49. if ('username' === $name) {
  50. $nameChange = true;
  51. } elseif ('group_id' === $name) {
  52. $grChange = true;
  53. }
  54. }
  55. if (empty($set)) {
  56. return $user;
  57. }
  58. if (
  59. $user->isGuest
  60. && ! $user->isUnverified
  61. ) {
  62. $vars[] = $user->ip;
  63. } else {
  64. $vars[] = $user->id;
  65. }
  66. $set = \implode(', ', $set);
  67. $query = "UPDATE ::{$table}
  68. SET {$set}
  69. WHERE {$where}";
  70. $this->c->DB->exec($query, $vars);
  71. $user->resModified();
  72. if ($nameChange) {
  73. $this->updateUsernameInOtherTables($user);
  74. }
  75. if ($grChange) {
  76. $this->c->admins->reset();
  77. $this->c->stats->reset();
  78. }
  79. return $user;
  80. }
  81. /**
  82. * Добавляет новую запись в таблицу пользователей
  83. */
  84. public function insert(User $user): int
  85. {
  86. if (null !== $user->id) {
  87. throw new RuntimeException('The model has ID');
  88. } elseif (
  89. null === $user->group_id
  90. || FORK_GROUP_GUEST === $user->group_id
  91. ) {
  92. throw new RuntimeException('Unexpected guest');
  93. }
  94. // вычисление username_normal для нового пользователя
  95. $user->username_normal = $this->manager->normUsername($user->username);
  96. $attrs = $user->getAttrs();
  97. $fileds = $this->c->dbMap->users;
  98. $set = $set2 = $vars = [];
  99. foreach ($attrs as $key => $value) {
  100. if (! isset($fileds[$key])) {
  101. continue;
  102. }
  103. $vars[] = $value;
  104. $set[] = $key;
  105. $set2[] = '?' . $fileds[$key];
  106. }
  107. if (empty($set)) {
  108. throw new RuntimeException('The model is empty');
  109. }
  110. $set = \implode(', ', $set);
  111. $set2 = \implode(', ', $set2);
  112. $query = "INSERT INTO ::users ({$set})
  113. VALUES ({$set2})";
  114. $this->c->DB->exec($query, $vars);
  115. $user->id = (int) $this->c->DB->lastInsertId();
  116. $user->resModified();
  117. if ($user->isAdmin) {
  118. $this->c->admins->reset();
  119. }
  120. if (! $user->isUnverified) {
  121. $this->c->stats->reset();
  122. }
  123. return $user->id;
  124. }
  125. /**
  126. * Обновляет username по всей(?) DB
  127. */
  128. protected function updateUsernameInOtherTables(User $user): void
  129. {
  130. if ($user->isGuest) {
  131. return;
  132. }
  133. $this->c->posts->updateUsername($user);
  134. $this->c->topics->updateUsername($user);
  135. $this->c->forums->updateUsername($user);
  136. $this->c->Online->updateUsername($user);
  137. $this->c->pms->updateUsername($user);
  138. // ???? и т.д.
  139. }
  140. }