123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- <?php
- /**
- * This file is part of the ForkBB <https://github.com/forkbb>.
- *
- * @copyright (c) Visman <mio.visman@yandex.ru, https://github.com/MioVisman>
- * @license The MIT License (MIT)
- */
- declare(strict_types=1);
- namespace ForkBB\Models\PM;
- use ForkBB\Models\Method;
- use ForkBB\Models\DataModel;
- use ForkBB\Models\PM\Cnst;
- use ForkBB\Models\PM\PPost;
- use ForkBB\Models\PM\PTopic;
- use ForkBB\Models\User\User;
- use InvalidArgumentException;
- use RuntimeException;
- class Delete extends Method
- {
- protected function deletePTopics(array $ids): void
- {
- if ($ids) {
- $vars = [
- ':ids' => $ids,
- ];
- $query = 'DELETE
- FROM ::pm_topics
- WHERE id IN (?ai:ids)';
- $this->c->DB->exec($query, $vars);
- $query = 'DELETE
- FROM ::pm_posts
- WHERE topic_id IN (?ai:ids)';
- $this->c->DB->exec($query, $vars);
- }
- }
- public function delete(DataModel ...$args): void
- {
- if (empty($args)) {
- throw new InvalidArgumentException('No arguments, expected User(s), PPost(s) or PTopic(s)');
- }
- $users = [];
- $posts = [];
- $topics = [];
- $isUser = 0;
- $isPost = 0;
- $isTopic = 0;
- $calcUsers = [];
- foreach ($args as $arg) {
- if ($arg instanceof User) {
- if ($arg->isGuest) {
- throw new RuntimeException('Guest can not be deleted');
- }
- $users[$arg->id] = $arg;
- $isUser = 1;
- } elseif ($arg instanceof PPost) {
- if (! $arg->parent instanceof PTopic) {
- throw new RuntimeException('Bad ppost');
- }
- $posts[$arg->id] = $arg;
- $isPost = 1;
- } elseif ($arg instanceof PTopic) {
- if (! $this->model->accessTopic($arg->id)) {
- throw new RuntimeException('Bad ptopic');
- }
- $topics[$arg->id] = $arg;
- $isTopic = 1;
- } else {
- throw new InvalidArgumentException('Expected User(s), PPost(s) or PTopic(s)');
- }
- }
- if ($isUser + $isPost + $isTopic > 1) {
- throw new InvalidArgumentException('Expected only User(s), PPost(s) or PTopic(s)');
- }
- if ($topics) {
- $ids = [];
- foreach ($topics as $topic) {
- $calcUsers[$topic->zpUser->id] = $topic->zpUser;
- if ($topic->isFullDeleted) {
- $ids[] = $topic->id;
- } else {
- $this->model->update(Cnst::PTOPIC, $topic);
- }
- }
- $this->deletePTopics($ids);
- }
- if ($posts) {
- $calcTopics = [];
- foreach ($posts as $post) {
- $topic = $post->parent;
- $calcTopics[$topic->id] = $topic;
- if ($topic->last_post_id === $post->id) {
- $calcUsers[$topic->ztUser->id] = $topic->ztUser;
- }
- }
- $vars = [
- ':ids' => \array_keys($posts),
- ];
- $query = 'DELETE
- FROM ::pm_posts
- WHERE id IN (?ai:ids)';
- $this->c->DB->exec($query, $vars);
- foreach ($calcTopics as $topic) {
- $this->model->update(Cnst::PTOPIC, $topic->calcStat());
- }
- }
- if ($users) {
- $vars = [
- ':ids' => \array_keys($users),
- ':status' => Cnst::PT_DELETED,
- ];
- $query = 'DELETE
- FROM ::pm_block
- WHERE bl_first_id IN (?ai:ids)';
- $this->c->DB->exec($query, $vars);
- $query = 'DELETE
- FROM ::pm_block
- WHERE bl_second_id IN (?ai:ids)';
- $this->c->DB->exec($query, $vars);
- $query = 'UPDATE ::pm_topics
- SET poster_id=0, poster_status=?i:status
- WHERE poster_id IN (?ai:ids)';
- $this->c->DB->exec($query, $vars);
- $query = 'UPDATE ::pm_topics
- SET target_id=0, target_status=?i:status
- WHERE target_id IN (?ai:ids)';
- $this->c->DB->exec($query, $vars);
- $query = 'UPDATE ::pm_posts
- SET poster_id=0
- WHERE poster_id IN (?ai:ids)';
- $this->c->DB->exec($query, $vars);
- $vars = [
- ':st1' => Cnst::PT_DELETED,
- ':st2' => Cnst::PT_NOTSENT,
- ];
- $query = 'SELECT id, poster_id, target_id
- FROM ::pm_topics
- WHERE (poster_status=?i:st1 AND target_status=?i:st1)
- OR (poster_status=?i:st1 AND target_status=?i:st2)
- OR (poster_status=?i:st2 AND target_status=?i:st1)
- OR (poster_status=?i:st2 AND target_status=?i:st2)';
- $stmt = $this->c->DB->query($query, $vars);
- $ids = [];
- $uids = [];
- while ($row = $stmt->fetch()) {
- $ids[$row['id']] = $row['id'];
- $uids[$row['poster_id']] = $row['poster_id'];
- $uids[$row['target_id']] = $row['target_id'];
- }
- $this->deletePTopics($ids);
- foreach ($this->c->users->loadByIds($uids) as $user) {
- if ($user instanceof User) {
- $calcUsers[$user->id] = $user;
- }
- }
- }
- foreach ($calcUsers as $user) {
- $this->model->recalculate($user);
- }
- }
- }
|