Delete.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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\PM;
  10. use ForkBB\Models\Method;
  11. use ForkBB\Models\DataModel;
  12. use ForkBB\Models\PM\Cnst;
  13. use ForkBB\Models\PM\PPost;
  14. use ForkBB\Models\PM\PTopic;
  15. use ForkBB\Models\User\User;
  16. use InvalidArgumentException;
  17. use RuntimeException;
  18. class Delete extends Method
  19. {
  20. protected function deletePTopics(array $ids): void
  21. {
  22. if ($ids) {
  23. $vars = [
  24. ':ids' => $ids,
  25. ];
  26. $query = 'DELETE
  27. FROM ::pm_topics
  28. WHERE id IN (?ai:ids)';
  29. $this->c->DB->exec($query, $vars);
  30. $query = 'DELETE
  31. FROM ::pm_posts
  32. WHERE topic_id IN (?ai:ids)';
  33. $this->c->DB->exec($query, $vars);
  34. }
  35. }
  36. public function delete(DataModel ...$args): void
  37. {
  38. if (empty($args)) {
  39. throw new InvalidArgumentException('No arguments, expected User(s), PPost(s) or PTopic(s)');
  40. }
  41. $users = [];
  42. $posts = [];
  43. $topics = [];
  44. $isUser = 0;
  45. $isPost = 0;
  46. $isTopic = 0;
  47. $calcUsers = [];
  48. foreach ($args as $arg) {
  49. if ($arg instanceof User) {
  50. if ($arg->isGuest) {
  51. throw new RuntimeException('Guest can not be deleted');
  52. }
  53. $users[$arg->id] = $arg;
  54. $isUser = 1;
  55. } elseif ($arg instanceof PPost) {
  56. if (! $arg->parent instanceof PTopic) {
  57. throw new RuntimeException('Bad ppost');
  58. }
  59. $posts[$arg->id] = $arg;
  60. $isPost = 1;
  61. } elseif ($arg instanceof PTopic) {
  62. if (! $this->model->accessTopic($arg->id)) {
  63. throw new RuntimeException('Bad ptopic');
  64. }
  65. $topics[$arg->id] = $arg;
  66. $isTopic = 1;
  67. } else {
  68. throw new InvalidArgumentException('Expected User(s), PPost(s) or PTopic(s)');
  69. }
  70. }
  71. if ($isUser + $isPost + $isTopic > 1) {
  72. throw new InvalidArgumentException('Expected only User(s), PPost(s) or PTopic(s)');
  73. }
  74. if ($topics) {
  75. $ids = [];
  76. foreach ($topics as $topic) {
  77. $calcUsers[$topic->zpUser->id] = $topic->zpUser;
  78. if ($topic->isFullDeleted) {
  79. $ids[] = $topic->id;
  80. } else {
  81. $this->model->update(Cnst::PTOPIC, $topic);
  82. }
  83. }
  84. $this->deletePTopics($ids);
  85. }
  86. if ($posts) {
  87. $calcTopics = [];
  88. foreach ($posts as $post) {
  89. $topic = $post->parent;
  90. $calcTopics[$topic->id] = $topic;
  91. if ($topic->last_post_id === $post->id) {
  92. $calcUsers[$topic->ztUser->id] = $topic->ztUser;
  93. }
  94. }
  95. $vars = [
  96. ':ids' => \array_keys($posts),
  97. ];
  98. $query = 'DELETE
  99. FROM ::pm_posts
  100. WHERE id IN (?ai:ids)';
  101. $this->c->DB->exec($query, $vars);
  102. foreach ($calcTopics as $topic) {
  103. $this->model->update(Cnst::PTOPIC, $topic->calcStat());
  104. }
  105. }
  106. if ($users) {
  107. $vars = [
  108. ':ids' => \array_keys($users),
  109. ':status' => Cnst::PT_DELETED,
  110. ];
  111. $query = 'DELETE
  112. FROM ::pm_block
  113. WHERE bl_first_id IN (?ai:ids)';
  114. $this->c->DB->exec($query, $vars);
  115. $query = 'DELETE
  116. FROM ::pm_block
  117. WHERE bl_second_id IN (?ai:ids)';
  118. $this->c->DB->exec($query, $vars);
  119. $query = 'UPDATE ::pm_topics
  120. SET poster_id=0, poster_status=?i:status
  121. WHERE poster_id IN (?ai:ids)';
  122. $this->c->DB->exec($query, $vars);
  123. $query = 'UPDATE ::pm_topics
  124. SET target_id=0, target_status=?i:status
  125. WHERE target_id IN (?ai:ids)';
  126. $this->c->DB->exec($query, $vars);
  127. $query = 'UPDATE ::pm_posts
  128. SET poster_id=0
  129. WHERE poster_id IN (?ai:ids)';
  130. $this->c->DB->exec($query, $vars);
  131. $vars = [
  132. ':st1' => Cnst::PT_DELETED,
  133. ':st2' => Cnst::PT_NOTSENT,
  134. ];
  135. $query = 'SELECT id, poster_id, target_id
  136. FROM ::pm_topics
  137. WHERE (poster_status=?i:st1 AND target_status=?i:st1)
  138. OR (poster_status=?i:st1 AND target_status=?i:st2)
  139. OR (poster_status=?i:st2 AND target_status=?i:st1)
  140. OR (poster_status=?i:st2 AND target_status=?i:st2)';
  141. $stmt = $this->c->DB->query($query, $vars);
  142. $ids = [];
  143. $uids = [];
  144. while ($row = $stmt->fetch()) {
  145. $ids[$row['id']] = $row['id'];
  146. $uids[$row['poster_id']] = $row['poster_id'];
  147. $uids[$row['target_id']] = $row['target_id'];
  148. }
  149. $this->deletePTopics($ids);
  150. foreach ($this->c->users->loadByIds($uids) as $user) {
  151. if ($user instanceof User) {
  152. $calcUsers[$user->id] = $user;
  153. }
  154. }
  155. }
  156. foreach ($calcUsers as $user) {
  157. $this->model->recalculate($user);
  158. }
  159. }
  160. }