forkbb/app/Models/Subscription/Model.php
2020-10-14 21:46:49 +07:00

241 lines
6.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
namespace ForkBB\Models\Subscription;
use ForkBB\Models\Model as ParentModel;
use ForkBB\Models\DataModel;
use ForkBB\Models\Forum\Model as Forum;
use ForkBB\Models\Topic\Model as Topic;
use ForkBB\Models\User\Model as User;
use PDO;
use InvalidArgumentException;
class Model extends ParentModel
{
/**
* @var array
*/
protected $forums;
/**
* @var array
*/
protected $topics;
/**
* @var array
*/
protected $users;
/**
* Проверяет список моделей на форумы/темы
* Заполняет forums, topics и users
*/
protected function check(array $models, bool $mayBeUsers = false): void
{
$this->forums = [];
$this->topics = [];
$this->users = [];
if (empty($models)) {
if ($mayBeUsers) {
throw new InvalidArgumentException('Expected at least one Forum, Topic or User');
} else {
throw new InvalidArgumentException('Expected at least one Forum or Topic');
}
}
foreach ($models as $model) {
if (
$mayBeUsers
&& $model instanceof User
) {
$this->users[$model->id] = $model->id;
} elseif ($model instanceof Forum) {
$this->forums[$model->id] = $model->id;
$mayBeUsers = false;
} elseif ($model instanceof Topic) {
$this->topics[$model->id] = $model->id;
$mayBeUsers = false;
} else {
throw new InvalidArgumentException('Expected only Forum or Topic');
}
}
}
/**
* Подписывает юзера на форум(ы)/тему(ы)
*/
public function subscribe(User $user, DataModel ...$models): bool
{
if (
$user->isGuest
|| $user->isUnverified
) {
return false;
}
$this->check($models);
$vars = [
':uid' => $user->id,
];
if (! empty($this->forums)) {
$query = 'INSERT INTO ::forum_subscriptions (user_id, forum_id)
SELECT ?i:uid, ?i:id
FROM ::groups
WHERE NOT EXISTS (
SELECT 1
FROM ::forum_subscriptions
WHERE user_id=?i:uid AND forum_id=?i:id
)
LIMIT 1';
foreach ($this->forums as $id) {
$vars[':id'] = $id;
$this->c->DB->exec($query, $vars);
}
}
if (! empty($this->topics)) {
$query = 'INSERT INTO ::topic_subscriptions (user_id, topic_id)
SELECT ?i:uid, ?i:id
FROM ::groups
WHERE NOT EXISTS (
SELECT 1
FROM ::topic_subscriptions
WHERE user_id=?i:uid AND topic_id=?i:id
)
LIMIT 1';
foreach ($this->topics as $id) {
$vars[':id'] = $id;
$this->c->DB->exec($query, $vars);
}
}
return true;
}
/**
* Отписывает юзеров от форумов/топиков
* Убирает подписки с удаляемых форумов/топиков
* Убирает подписки с удаляемых юзеров
*/
public function unsubscribe(DataModel ...$models): bool
{
$where = [];
$vars = [];
$this->check($models, true);
if (! empty($this->users)) {
if (1 === \count($this->users)) {
$where[':uid'] = 'user_id=?i:uid';
$vars[':uid'] = \reset($this->users);
} else {
$where[':uid'] = 'user_id IN(?ai:uid)';
$vars[':uid'] = $this->users;
}
}
$all = empty($this->forums) && empty($this->topics);
if ($all || ! empty($this->forums)) {
if (! empty($this->forums)) {
if (1 === \count($this->forums)) {
$where[':id'] = 'forum_id=?i:id';
$vars[':id'] = \reset($this->forums);
} else {
$where[':id'] = 'forum_id IN(?ai:id)';
$vars[':id'] = $this->forums;
}
}
$query = 'DELETE
FROM ::forum_subscriptions
WHERE ' . \implode(' AND ', $where);
$this->c->DB->exec($query, $vars);
}
unset($where[':id'], $vars[':id']);
if ($all || ! empty($this->topics)) {
if (! empty($this->topics)) {
if (1 === \count($this->topics)) {
$where[':id'] = 'topic_id=?i:id';
$vars[':id'] = \reset($this->topics);
} else {
$where[':id'] = 'topic_id IN(?ai:id)';
$vars[':id'] = $this->topics;
}
}
$query = 'DELETE
FROM ::topic_subscriptions
WHERE ' . \implode(' AND ', $where);
$this->c->DB->exec($query, $vars);
}
return true;
}
const FORUMS_DATA = 1;
const TOPICS_DATA = 2;
const ALL_DATA = 3;
/**
* Возвращает информацию по подпискам
*/
public function info(DataModel $model, int $type = self::ALL_DATA): array
{
$result = [];
if ($model instanceof User) {
$vars = [
':uid' => $model->id,
];
if (self::FORUMS_DATA & $type) {
if (
'1' != $this->c->config->o_forum_subscriptions
|| $model->isGuest
) {
$result[self::FORUMS_DATA] = null;
} else {
$query = 'SELECT forum_id
FROM ::forum_subscriptions
WHERE user_id=?i:uid';
$result[self::FORUMS_DATA] = $this->c->DB->query($query, $vars)->fetchAll(PDO::FETCH_COLUMN);
}
}
if (self::TOPICS_DATA & $type) {
if (
'1' != $this->c->config->o_topic_subscriptions
|| $model->isGuest
) {
$result[self::TOPICS_DATA] = null;
} else {
$query = 'SELECT topic_id
FROM ::topic_subscriptions
WHERE user_id=?i:uid';
$result[self::TOPICS_DATA] = $this->c->DB->query($query, $vars)->fetchAll(PDO::FETCH_COLUMN);
}
}
} else {
throw new InvalidArgumentException('Expected only User');
}
return $result;
}
}