Add loadByIds() to Topic\Manager
This commit is contained in:
parent
177f08674c
commit
448ac9e070
3 changed files with 109 additions and 50 deletions
|
@ -3,16 +3,44 @@
|
|||
namespace ForkBB\Models\Topic;
|
||||
|
||||
use ForkBB\Models\Action;
|
||||
use ForkBB\Models\Forum\Model as Forum;
|
||||
use ForkBB\Models\Topic\Model as Topic;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class Load extends Action
|
||||
{
|
||||
/**
|
||||
* Создает текст запрос
|
||||
*/
|
||||
protected function getSql(string $where, bool $full): string
|
||||
{
|
||||
if ($this->c->user->isGuest) {
|
||||
$sql = 'SELECT t.*
|
||||
FROM ::topics AS t
|
||||
WHERE ' . $where;
|
||||
} elseif ($full) {
|
||||
$sql = 'SELECT t.*, s.user_id AS is_subscribed, mof.mf_mark_all_read, mot.mt_last_visit, mot.mt_last_read
|
||||
FROM ::topics AS t
|
||||
LEFT JOIN ::topic_subscriptions AS s ON (t.id=s.topic_id AND s.user_id=?i:uid)
|
||||
LEFT JOIN ::mark_of_forum AS mof ON (mof.uid=?i:uid AND t.forum_id=mof.fid)
|
||||
LEFT JOIN ::mark_of_topic AS mot ON (mot.uid=?i:uid AND t.id=mot.tid)
|
||||
WHERE ' . $where;
|
||||
} else {
|
||||
$sql = 'SELECT t.*, mot.mt_last_visit, mot.mt_last_read
|
||||
FROM ::topics AS t
|
||||
LEFT JOIN ::mark_of_topic AS mot ON (mot.uid=?i:uid AND t.id=mot.tid)
|
||||
WHERE ' . $where;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Загружает тему из БД
|
||||
*
|
||||
* @param int $id
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return null|Topic
|
||||
*/
|
||||
public function load(int $id): ?Topic
|
||||
|
@ -25,20 +53,7 @@ class Load extends Action
|
|||
':tid' => $id,
|
||||
':uid' => $this->c->user->id,
|
||||
];
|
||||
if ($this->c->user->isGuest) {
|
||||
$sql = 'SELECT t.*
|
||||
FROM ::topics AS t
|
||||
WHERE t.id=?i:tid';
|
||||
|
||||
} else {
|
||||
$sql = 'SELECT t.*, s.user_id AS is_subscribed, mof.mf_mark_all_read, mot.mt_last_visit, mot.mt_last_read
|
||||
FROM ::topics AS t
|
||||
LEFT JOIN ::topic_subscriptions AS s ON (t.id=s.topic_id AND s.user_id=?i:uid)
|
||||
LEFT JOIN ::mark_of_forum AS mof ON (mof.uid=?i:uid AND t.forum_id=mof.fid)
|
||||
LEFT JOIN ::mark_of_topic AS mot ON (mot.uid=?i:uid AND t.id=mot.tid)
|
||||
WHERE t.id=?i:tid';
|
||||
}
|
||||
|
||||
$sql = $this->getSql('t.id=?i:tid', true);
|
||||
$data = $this->c->DB->query($sql, $vars)->fetch();
|
||||
|
||||
// тема отсутствует или недоступна
|
||||
|
@ -48,7 +63,7 @@ class Load extends Action
|
|||
|
||||
$topic = $this->manager->create($data);
|
||||
|
||||
if (! $topic->parent) {
|
||||
if (! $topic->parent instanceof Forum) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -56,4 +71,39 @@ class Load extends Action
|
|||
|
||||
return $topic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Загружает список тем из БД
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function loadByIds(array $ids, bool $full): array
|
||||
{
|
||||
foreach ($ids as $id) {
|
||||
if (! \is_int($id) || $id < 1) {
|
||||
throw new InvalidArgumentException('Expected a positive topic id');
|
||||
}
|
||||
}
|
||||
|
||||
$vars = [
|
||||
':ids' => $ids,
|
||||
':uid' => $this->c->user->id,
|
||||
];
|
||||
$sql = $this->getSql('t.id IN (?ai:ids)', $full);
|
||||
$stmt = $this->c->DB->query($sql, $vars);
|
||||
|
||||
$result = [];
|
||||
while ($row = $stmt->fetch()) {
|
||||
$topic = $this->manager->create($row);
|
||||
|
||||
if ($topic->parent instanceof Forum) {
|
||||
$result[] = $topic;
|
||||
|
||||
if (! empty($row['mf_mark_all_read'])) {
|
||||
$topic->parent->__mf_mark_all_read = $row['mf_mark_all_read'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ class Manager extends ManagerModel
|
|||
}
|
||||
|
||||
/**
|
||||
* Загружает тему из БД
|
||||
* Получает тему по id
|
||||
*
|
||||
* @param int $id
|
||||
*
|
||||
|
@ -37,6 +37,38 @@ class Manager extends ManagerModel
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получает массив тем по ids
|
||||
*/
|
||||
public function loadByIds(array $ids, bool $full = true): array
|
||||
{
|
||||
$result = [];
|
||||
$data = [];
|
||||
|
||||
foreach ($ids as $id) {
|
||||
if ($this->isset($id)) {
|
||||
$result[$id] = $this->get($id);
|
||||
} else {
|
||||
$result[$id] = null;
|
||||
$data[] = $id;
|
||||
$this->set($id, null);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($data)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
foreach ($this->Load->loadByIds($data, $full) as $topic) {
|
||||
if ($topic instanceof Topic) {
|
||||
$result[$topic->id] = $topic;
|
||||
$this->set($topic->id, $topic);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновляет тему в БД
|
||||
*
|
||||
|
|
|
@ -25,9 +25,9 @@ class View extends Action
|
|||
public function view($arg): array
|
||||
{
|
||||
if ($arg instanceof Forum) {
|
||||
$expanded = false;
|
||||
$full = false;
|
||||
} elseif ($arg instanceof Search) {
|
||||
$expanded = true;
|
||||
$full = true;
|
||||
} else {
|
||||
throw new InvalidArgumentException('Expected Forum or Search');
|
||||
}
|
||||
|
@ -36,46 +36,23 @@ class View extends Action
|
|||
throw new RuntimeException('Model does not contain of topics list for display');
|
||||
}
|
||||
|
||||
$vars = [
|
||||
':uid' => $this->c->user->id,
|
||||
':ids' => $arg->idsList,
|
||||
];
|
||||
$result = $this->c->topics->loadByIds($arg->idsList, $full);
|
||||
|
||||
if (! $this->c->user->isGuest && '1' == $this->c->config->o_show_dot) {
|
||||
$vars = [
|
||||
':uid' => $this->c->user->id,
|
||||
':ids' => $arg->idsList,
|
||||
];
|
||||
$sql = 'SELECT p.topic_id
|
||||
FROM ::posts AS p
|
||||
WHERE p.poster_id=?i:uid AND p.topic_id IN (?ai:ids)
|
||||
GROUP BY p.topic_id';
|
||||
$dots = $this->c->DB->query($sql, $vars)->fetchAll(PDO::FETCH_COLUMN);
|
||||
$dots = \array_flip($dots);
|
||||
} else {
|
||||
$dots = [];
|
||||
}
|
||||
|
||||
if ($this->c->user->isGuest) {
|
||||
$sql = 'SELECT t.*
|
||||
FROM ::topics AS t
|
||||
WHERE t.id IN(?ai:ids)';
|
||||
} elseif ($expanded) {
|
||||
$sql = 'SELECT t.*, mof.mf_mark_all_read, mot.mt_last_visit, mot.mt_last_read
|
||||
FROM ::topics AS t
|
||||
LEFT JOIN ::mark_of_forum AS mof ON (mof.uid=?i:uid AND t.forum_id=mof.fid)
|
||||
LEFT JOIN ::mark_of_topic AS mot ON (mot.uid=?i:uid AND t.id=mot.tid)
|
||||
WHERE t.id IN (?ai:ids)';
|
||||
} else {
|
||||
$sql = 'SELECT t.*, mot.mt_last_visit, mot.mt_last_read
|
||||
FROM ::topics AS t
|
||||
LEFT JOIN ::mark_of_topic AS mot ON (mot.uid=?i:uid AND t.id=mot.tid)
|
||||
WHERE t.id IN (?ai:ids)';
|
||||
}
|
||||
$stmt = $this->c->DB->query($sql, $vars);
|
||||
|
||||
$result = \array_flip($arg->idsList);
|
||||
while ($row = $stmt->fetch()) {
|
||||
$row['dot'] = isset($dots[$row['id']]);
|
||||
$result[$row['id']] = $this->manager->create($row);
|
||||
if ($expanded && ! $this->c->user->isGuest) {
|
||||
$result[$row['id']]->parent->__mf_mark_all_read = $row['mf_mark_all_read'];
|
||||
foreach ($dots as $id) {
|
||||
if (isset($result[$id]) && $result[$id] instanceof Topic) {
|
||||
$result[$id]->__dot = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue