Browse Source

Add Models\PM\PRnd

Visman 4 years ago
parent
commit
2ea78456dd
1 changed files with 190 additions and 0 deletions
  1. 190 0
      app/Models/PM/PRnd.php

+ 190 - 0
app/Models/PM/PRnd.php

@@ -0,0 +1,190 @@
+<?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\Core\Container;
+use ForkBB\Models\Model;
+use ForkBB\Models\PM\Cnst;
+use ForkBB\Models\User\Model as User;
+use InvalidArgumentException;
+use RuntimeException;
+
+class PRnd extends Model
+{
+
+    /**
+     * Соотвествие между номерами в топике и пользователями
+     * @var array
+     */
+    protected $numToUser;
+
+    /**
+     * Соотвествие между id пользователей и их номерами в топике
+     * @var array
+     */
+    protected $idToNum;
+
+    /**
+     * @var array
+     */
+    protected $tmpList;
+
+    /**
+     * $this->list = ....
+     */
+    protected function setlist(array $list): void
+    {
+        foreach ($list as $cur) {
+            $this->list($cur['user_number'], $cur);
+        }
+    }
+
+    protected function list(int $number, /* User|array*/ $data): void
+    {
+        if ($data instanceof User) {
+            $user = $data;
+            $data = [
+                'user_number' => $number,
+                'user_id'     => $data->id,
+                'username'    => $data->username,
+                'pt_status'   => Cnst::PT_START,
+                'pt_visit'    => 0,
+            ];
+        } else {
+            $user = null;
+        }
+
+        if (isset($data['user_number'], $data['user_id'], $data['username'], $data['pt_status'], $data['pt_visit'])) {
+            if ($number !== $data['user_number']) {
+                throw new RuntimeException('Invalid serial number');
+            }
+        } else {
+            throw new RuntimeException('No all required data');
+        }
+
+        $list          = $this->getAttr('list', []);
+        $list[$number] = $data;
+
+        $this->setAttr('list', $list);
+
+        $this->idToNum[$data['user_id']] = $number;
+        $this->numToUser[$number]        = $user;
+    }
+
+    /**
+     * Устанавливает отправителя
+     */
+    public function setSender(User $user): self
+    {
+        if (isset($this->list[0])) {
+            throw new RuntimeException('Sender already set');
+        } elseif (isset($this->$idToNum[$user->id])) {
+            throw new RuntimeException('Sender already specified in the recipient');
+        }
+
+        $this->list(0, $user);
+
+        return $this;
+    }
+
+    /**
+     * Добавляет получателя
+     */
+    public function addRecipient(User $user): self
+    {
+        if (isset($this->$idToNum[$user->id])) {
+            throw new RuntimeException('This recipient is already set');
+        }
+
+        $next = 1 + \max(\array_keys($this->list));
+
+        $this->list($next, $user);
+
+        return $this;
+    }
+
+    /**
+     * Возвращает пользователя по номеру в топике
+     */
+    public function userByNum(int $number): User
+    {
+        if (isset($numToUser[$number])) {
+            return $numToUser[$number];
+        } elseif (isset($this->list[$number])) {
+            $data = $this->list[$number];
+            $user = $this->c->users->load($data['user_id']);
+
+            if (
+                ! $user instanceof User
+                && 1 !== $data['user_id'] // ???? может сменить id гостя?
+            ) {
+                $user = $this->c->users->load(1);
+            }
+
+            if (! $user instanceof User) {
+                throw new RuntimeException("No user data in post number {$data['user_id']}");
+            } elseif ($user->isGuest) {
+                $user = clone $user;
+
+                $user->__username = $data['username'];
+            }
+
+            return $numToUser[$number] = $user;
+        } else {
+            throw new RuntimeException("No user of the number {$number}");
+        }
+    }
+
+    protected function setstatus(int $status): void
+    {
+        if (! isset($this->$idToNum[$this->c->user->id])) {
+            throw new RuntimeException('Someone else\'s private topic');
+        }
+
+        $number        = $this->$idToNum[$this->c->user->id];
+        $this->tmpList = $this->getAttr('list', []);
+
+        if (0 === $number) {
+            switch ($status) {
+                case Cnst::PT_NORMAL:
+                case Cnst::PT_DELETED:
+                    $this->stFromStNs($status);
+
+                    break;
+                case Cnst::PT_ARCHIVE:
+                    $this->stFromStNs(Cnst::PT_NOTSENT);
+
+                    break;
+                case Cnst::PT_NOTSENT:
+                default:
+                    throw new InvalidArgumentException("Bad status: {$status}");
+            }
+        }
+
+        $this->tmpList[$number]['pt_status'] = $status;
+
+        $this->setAttr('list', $this->tmpList);
+    }
+
+    /**
+     * Из PT_START и PT_NOTSENT в $new
+     */
+    protected function stFromStNs(int $new): void
+    {
+        \array_walk($this->tmpList, function (&$cur, $key, $new) {
+            switch ($cur['pt_status']) {
+                case Cnst::PT_START:
+                case Cnst::PT_NOTSENT:
+                    $cur['pt_status'] = $new;
+            }
+        }, $new);
+    }
+}