Add Models\PM\Load

This commit is contained in:
Visman 2021-03-20 22:37:36 +07:00
parent 45d5498a86
commit c42018faf4

221
app/Models/PM/Load.php Normal file
View file

@ -0,0 +1,221 @@
<?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\Model as ParentModel;
use ForkBB\Models\PM\Cnst;
use ForkBB\Models\PM\PPost;
use ForkBB\Models\PM\PTopic;
use InvalidArgumentException;
use RuntimeException;
class Load extends Method
{
/**
* @var array
*/
protected $userIds;
/**
* Создает текст запрос
*/
protected function getSql(int $type, bool $solo = true): string
{
switch ($type) {
case Cnst::PRND:
$where = $solo ? 'pr.topic_id=?i:tid' : 'pr.topic_id IN (?ai:ids)';
return "SELECT * FROM pm_rnd AS pr WHERE {$where}";
case Cnst::PTOPIC:
$where = $solo ? 'pt.id=?i:tid' : 'pt.id IN (?ai:ids)';
return "SELECT * FROM pm_topics AS pt WHERE {$where}";
case Cnst::PPOST:
$where = $solo ? 'pp.id=?i:pid' : 'pp.id IN (?ai:ids)';
return "SELECT * FROM pm_posts AS pp WHERE {$where}";
default:
throw new RuntimeException('Unknown request type');
}
}
/**
* Группирует данные пользователей по приватным тема (можно было и в PDO получить, но...)
* и выбирает все id пользователей
*/
protected function calc(array $data): array
{
$this->userIds = [];
$result = [];
foreach ($data as $row) {
$uid = $row['user_id'];
$tid = $row['topic_id'];
unset($row['topic_id']);
$this->userIds[$uid] = $uid;
if (empty($result[$tid])) {
$result[$tid] = [];
}
$result[$tid][$row['user_number']] = $row;
}
return $result;
}
public function load(int $type, int $id): ?ParentModel
{
switch ($type) {
case Cnst::PTOPIC:
return $this->loadTopic($id);
case Cnst::PPOST:
return $this->loadPost($id);
default:
return null;
}
}
public function loadByIds(int $type, array $ids): array
{
switch ($type) {
case Cnst::PTOPIC:
return $this->loadTopics($ids);
case Cnst::PPOST:
return $this->loadPosts($ids);
default:
return [];
}
}
/**
* Загружает приватную тему из БД
*/
protected function loadTopic(int $id): ?PTopic
{
if ($id < 1) {
throw new InvalidArgumentException('Expected a positive ptopic id');
}
$vars = [
':tid' => $id,
];
$query = $this->getSql(Cnst::PTOPIC);
$data = $this->c->DB->query($query, $vars)->fetch();
// тема отсутствует
if (empty($data)) {
return null;
}
$topic = $this->model->create(Cnst::PTOPIC, $data);
$query = $this->getSql(Cnst::PRND);
$dataU = $this->calc($this->c->DB->query($query, $vars)->fetchAll());
$rnd = $this->model->create(Cnst::PRND);
$rnd->list = $dataU[$id];
$topic->rnd = $rnd;
$this->c->users->loadByIds($this->userIds);
return $topic;
}
/**
* Загружает приватное сообщение из БД
*/
protected function loadPost(int $id): ?PPost
{
if ($id < 1) {
throw new InvalidArgumentException('Expected a positive ppost id');
}
$vars = [
':pid' => $id,
];
$query = $this->getSql(Cnst::PPOST);
$data = $this->c->DB->query($query, $vars)->fetch();
if (empty($data)) {
return null;
} else {
return $this->model->create(Cnst::PPOST, $data);
}
}
/**
* Загружает список приватных тем из БД
*/
protected function loadTopics(array $ids): array
{
foreach ($ids as $id) {
if (
! \is_int($id)
|| $id < 1
) {
throw new InvalidArgumentException('Expected a positive ptopic id');
}
}
$vars = [
':ids' => $ids,
];
$query = $this->getSql(Cnst::PRND, false);
$dataU = $this->calc($this->c->DB->query($query, $vars)->fetchAll());
$this->c->users->loadByIds($this->userIds);
$query = $this->getSql(Cnst::PTOPIC, false);
$stmt = $this->c->DB->query($query, $vars);
$result = [];
while ($row = $stmt->fetch()) {
$topic = $this->model->create(Cnst::PTOPIC, $row);
$rnd = $this->model->create(Cnst::PRND);
$rnd->list = $dataU[$row['id']];
$topic->rnd = $rnd;
$result[] = $topic;
}
return $result;
}
/**
* Загружает список приватных сообщений из БД
*/
protected function loadPosts(array $ids): array
{
foreach ($ids as $id) {
if (
! \is_int($id)
|| $id < 1
) {
throw new InvalidArgumentException('Expected a positive ppost id');
}
}
$vars = [
':ids' => $ids,
];
$query = $this->getSql(Cnst::PPOST, false);
$stmt = $this->c->DB->query($query, $vars);
$result = [];
while ($row = $stmt->fetch()) {
$result[] = $this->model->create(Cnst::PPOST, $row);
}
return $result;
}
}