+ Delete user(s)

This commit is contained in:
Visman 2018-09-09 21:22:18 +07:00
parent 64a309f558
commit 8b9dbb3423
9 changed files with 387 additions and 140 deletions

View file

@ -4,6 +4,7 @@ namespace ForkBB\Models\Forum;
use ForkBB\Models\Action;
use ForkBB\Models\Forum\Model as Forum;
use ForkBB\Models\User\Model as User;
use InvalidArgumentException;
use RuntimeException;
@ -20,14 +21,23 @@ class Delete extends Action
public function delete(...$args)
{
if (empty($args)) {
throw new InvalidArgumentException('No arguments, expected forum(s)');
throw new InvalidArgumentException('No arguments, expected User(s) or Forum(s)');
}
$forums = [];
$all = [];
$users = [];
$forums = [];
$all = [];
$isUser = 0;
$isForum = 0;
foreach ($args as $arg) {
if ($arg instanceof Forum) {
if ($arg instanceof User) {
if ($arg->isGuest) {
throw new RuntimeException('Guest can not be deleted');
}
$users[] = $arg->id;
$isUser = 1;
} elseif ($arg instanceof Forum) {
if (! $this->c->forums->get($arg->id) instanceof Forum) {
throw new RuntimeException('Forum unavailable');
}
@ -36,32 +46,49 @@ class Delete extends Action
foreach (\array_keys($arg->descendants) as $id) { //???? а если не админ?
$all[$id] = true;
}
$isForum = 1;
} else {
throw new InvalidArgumentException('Expected forum(s)');
throw new InvalidArgumentException('Expected User(s) or Forum(s)');
}
}
if ($isUser + $isForum > 1) {
throw new InvalidArgumentException('Expected only User(s) or Forum(s)');
}
if (\array_diff_key($all, $forums)) {
throw new RuntimeException('Descendants should not be or they should be deleted too');
}
$this->c->topics->delete(...$args);
//???? подписки, опросы, предупреждения, метки посещения тем
//???? подписки, опросы, предупреждения
foreach ($forums as $forum) {
$this->c->groups->Perm->reset($forum);
if ($users) {
$vars = [
':users' => $users,
];
$sql = 'DELETE FROM ::mark_of_forum
WHERE uid IN (?ai:users)';
$this->c->DB->exec($sql, $vars);
//???? удаление модераторов из разделов
}
if ($forums) {
foreach ($forums as $forum) {
$this->c->groups->Perm->reset($forum);
}
$vars = [
':forums' => \array_keys($forums),
];
$sql = 'DELETE FROM ::mark_of_forum
WHERE fid IN (?ai:forums)';
$this->c->DB->exec($sql, $vars);
$vars = [
':forums' => \array_keys($forums),
];
$sql = 'DELETE FROM ::mark_of_forum
WHERE fid IN (?ai:forums)';
$this->c->DB->exec($sql, $vars);
$sql = 'DELETE FROM ::forums
WHERE id IN (?ai:forums)';
$this->c->DB->exec($sql, $vars);
$sql = 'DELETE FROM ::forums
WHERE id IN (?ai:forums)';
$this->c->DB->exec($sql, $vars);
}
}
}

View file

@ -8,6 +8,23 @@ use RuntimeException;
class Action extends Users
{
/**
* Возвращает список имен пользователей
*
* @param array $users
*
* @return array
*/
protected function nameList(array $users)
{
$result = [];
foreach ($users as $user) {
$result[] = $user->username;
}
\sort($result, \SORT_STRING | \SORT_FLAG_CASE);
return $result;
}
/**
* Подготавливает данные для шаблона(ов) действия
*
@ -77,7 +94,38 @@ class Action extends Users
*/
protected function delete(array $args, $method)
{
if ('POST' === $method) {
$v = $this->c->Validator->reset()
->addRules([
'token' => 'token:AdminUsersAction',
'confirm' => 'required|integer|in:0,1',
'delete_posts' => 'required|integer|in:0,1',
'delete' => 'string',
])->addAliases([
])->addArguments([
'token' => $args,
]);
if (! $v->validation($_POST) || $v->confirm !== 1) {
return $this->c->Redirect->page('AdminUsers')->message('No confirm redirect');
}
if (1 === $v->delete_posts) {
foreach ($this->userList as $user) {
$user->__deleteAllPost = true;
}
}
$this->c->DB->beginTransaction();
$this->c->users->delete(...$this->userList);
$this->c->DB->commit();
$this->c->Cache->delete('stats');
return $this->c->Redirect->page('AdminUsers')->message('Users delete redirect');
}
$this->nameTpl = 'admin/form';
$this->classForm = 'delete-users';
@ -86,24 +134,6 @@ class Action extends Users
$this->form = $this->formDelete($args);
return $this;
}
/**
* Возвращает список имен пользователей
*
* @param array $users
*
* @return array
*/
protected function nameList(array $users)
{
$result = [];
foreach ($users as $user) {
$result[] = $user->username;
}
\sort($result, \SORT_STRING | \SORT_FLAG_CASE);
return $result;
}
/**

View file

@ -86,7 +86,7 @@ abstract class Profile extends Page
}
if ($this->rules->deleteUser) {
$btns['delete-user'] = [
$this->c->Router->link('', ['id' => $this->curUser->id]),
$this->c->Router->link('AdminUsersAction', ['action' => 'delete', 'ids' => $this->curUser->id]), // ????
\ForkBB\__('Delete user'),
];
}

View file

@ -6,6 +6,7 @@ use ForkBB\Models\Action;
use ForkBB\Models\Forum\Model as Forum;
use ForkBB\Models\Post\Model as Post;
use ForkBB\Models\Topic\Model as Topic;
use ForkBB\Models\User\Model as User;
use PDO;
use InvalidArgumentException;
use RuntimeException;
@ -23,84 +24,102 @@ class Delete extends Action
public function delete(...$args)
{
if (empty($args)) {
throw new InvalidArgumentException('No arguments, expected forum, topic or post');
throw new InvalidArgumentException('No arguments, expected User(s), Forum(s), Topic(s) or Post(s)');
}
$posts = [];
$parents = [];
$topics = [];
$forums = [];
$users = [];
$usersToGuest = [];
$usersDel = [];
$forums = [];
$topics = [];
$posts = [];
$parents = [];
$isUser = 0;
$isForum = 0;
$isTopic = 0;
$isPost = 0;
foreach ($args as $arg) {
if ($arg instanceof Post) {
if (! $arg->parent instanceof Topic || ! $arg->parent->parent instanceof Forum) {
throw new RuntimeException('Parents unavailable');
if ($arg instanceof User) {
if ($arg->isGuest) {
throw new RuntimeException('Guest can not be deleted');
}
$posts[$arg->id] = $arg;
$parents[$arg->topic_id] = $arg->parent;
} elseif ($arg instanceof Topic) {
if (! $arg->parent instanceof Forum) {
throw new RuntimeException('Parent unavailable');
if (true === $arg->deleteAllPost) {
$usersDel[] = $arg->id;
} else {
$usersToGuest[] = $arg->id;
}
$topics[$arg->id] = $arg;
$isUser = 1;
} elseif ($arg instanceof Forum) {
if (! $this->c->forums->get($arg->id) instanceof Forum) {
throw new RuntimeException('Forum unavailable');
}
$forums[$arg->id] = $arg;
$isForum = 1;
} elseif ($arg instanceof Topic) {
if (! $arg->parent instanceof Forum) {
throw new RuntimeException('Parent unavailable');
}
$topics[$arg->id] = $arg;
$isTopic = 1;
} elseif ($arg instanceof Post) {
if (! $arg->parent instanceof Topic || ! $arg->parent->parent instanceof Forum) {
throw new RuntimeException('Parents unavailable');
}
$posts[$arg->id] = $arg->id;
$parents[$arg->topic_id] = $arg->parent;
$users[$post->poster_id] = $post->poster_id;
$isPost = 1;
} else {
throw new InvalidArgumentException('Expected forum, topic or post');
throw new InvalidArgumentException('Expected User(s), Forum(s), Topic(s) or Post(s)');
}
}
if (! empty($posts) + ! empty($topics) + ! empty($forums) > 1) {
throw new InvalidArgumentException('Expected only forum, topic or post');
if ($isUser + $isForum + $isTopic + $isPost > 1) {
throw new InvalidArgumentException('Expected only User(s), Forum(s), Topic(s) or Post(s)');
}
$this->c->search->delete(...$args);
//???? подписки, опросы, предупреждения метки посещения тем
$users = [];
if ($posts) {
foreach ($posts as $post) {
$users[$post->poster_id] = true;
}
$users = \array_keys($users);
//???? подписки, опросы, предупреждения
if ($usersToGuest) {
$vars = [
':posts' => \array_keys($posts),
':users' => $usersToGuest,
];
$sql = 'DELETE FROM ::posts
WHERE id IN (?ai:posts)';
$sql = 'UPDATE ::posts
SET poster_id=1
WHERE poster_id IN (?ai:users)';
$this->c->DB->exec($sql, $vars);
$topics = $parents;
$parents = [];
foreach ($topics as $topic) {
$parents[$topic->forum_id] = $topic->parent;
$this->c->topics->update($topic->calcStat());
}
foreach($parents as $forum) {
$this->c->forums->update($forum->calcStat());
}
} elseif ($topics) {
}
if ($usersDel) {
$vars = [
':topics' => \array_keys($topics),
':users' => $usersDel,
];
$sql = 'SELECT p.poster_id
FROM ::posts AS p
WHERE p.topic_id IN (?ai:topics)
GROUP BY p.poster_id';
$users = $this->c->DB->query($sql, $vars)->fetchAll(PDO::FETCH_COLUMN);
$sql = 'SELECT p.topic_id
FROM ::posts as p
WHERE p.poster_id IN (?ai:users)
GROUP BY p.topic_id';
$parents = $this->c->DB->query($sql, $vars)->fetchAll(PDO::FETCH_COLUMN);
$sql = 'SELECT t.id
FROM ::topics AS t
INNER JOIN ::posts AS p ON t.first_post_id=p.id
WHERE p.poster_id IN (?ai:users)';
$notUse = $this->c->DB->query($sql, $vars)->fetchAll(PDO::FETCH_COLUMN);
$parents = \array_diff($parents, $notUse); //????
$sql = 'DELETE FROM ::posts
WHERE topic_id IN (?ai:topics)';
WHERE poster_id IN (?ai:users)';
$this->c->DB->exec($sql, $vars);
} elseif ($forums) {
foreach ($parents as &$parent) {
$parent = $this->c->topics->load($parent); //???? ааааАААААААААААААА О_о
}
unset($parent);
}
if ($forums) {
$vars = [
':forums' => \array_keys($forums),
];
@ -119,7 +138,43 @@ class Delete extends Action
)';
$this->c->DB->exec($sql, $vars);
}
if ($topics) {
$vars = [
':topics' => \array_keys($topics),
];
$sql = 'SELECT p.poster_id
FROM ::posts AS p
WHERE p.topic_id IN (?ai:topics)
GROUP BY p.poster_id';
$users = $this->c->DB->query($sql, $vars)->fetchAll(PDO::FETCH_COLUMN);
$this->c->users->updateCountPosts(...$users);
$sql = 'DELETE FROM ::posts
WHERE topic_id IN (?ai:topics)';
$this->c->DB->exec($sql, $vars);
}
if ($posts) {
$vars = [
':posts' => $posts,
];
$sql = 'DELETE FROM ::posts
WHERE id IN (?ai:posts)';
$this->c->DB->exec($sql, $vars);
}
if ($parents) {
$topics = $parents;
$parents = [];
foreach ($topics as $topic) {
$parents[$topic->forum_id] = $topic->parent;
$this->c->topics->update($topic->calcStat());
}
foreach($parents as $forum) {
$this->c->forums->update($forum->calcStat());
}
}
if ($users) {
$this->c->users->updateCountPosts(...$users);
}
}
}

View file

@ -46,7 +46,7 @@ class Model extends DataModel
$user = $this->c->users->get($this->poster_id);
if (! $user instanceof User) {
throw new RuntimeException('No user data');
throw new RuntimeException('No user data in post number ' . $this->id);
} elseif (1 === $this->poster_id) {
$user = clone $user;
$user->__email = $this->poster_email;

View file

@ -6,6 +6,7 @@ use ForkBB\Models\Method;
use ForkBB\Models\Forum\Model as Forum;
use ForkBB\Models\Post\Model as Post;
use ForkBB\Models\Topic\Model as Topic;
use ForkBB\Models\User\Model as User;
use PDO;
use InvalidArgumentException;
use RuntimeException;
@ -23,56 +24,68 @@ class Delete extends Method
public function delete(...$args)
{
if (empty($args)) {
throw new InvalidArgumentException('No arguments, expected forum, topic or post');
throw new InvalidArgumentException('No arguments, expected User(s), Forum(s), Topic(s) or Post(s)');
}
$posts = [];
$parents = [];
$topics = [];
$users = [];
$forums = [];
// ?????
$topics = [];
$posts = [];
$isUser = 0;
$isForum = 0;
$isTopic = 0;
$isPost = 0;
foreach ($args as $arg) {
if ($arg instanceof Post) {
if (! $arg->parent instanceof Topic || ! $arg->parent->parent instanceof Forum) {
throw new RuntimeException('Parents unavailable');
if ($arg instanceof User) {
if ($arg->isGuest) {
throw new RuntimeException('Guest can not be deleted');
}
$posts[$arg->id] = $arg;
} elseif ($arg instanceof Topic) {
if (! $arg->parent instanceof Forum) {
throw new RuntimeException('Parent unavailable');
if (true === $arg->deleteAllPost) {
$users[] = $arg->id;
}
$topics[$arg->id] = $arg;
$isUser = 1;
} elseif ($arg instanceof Forum) {
if (! $this->c->forums->get($arg->id) instanceof Forum) {
throw new RuntimeException('Forum unavailable');
}
$forums[$arg->id] = $arg;
$isForum = 1;
} elseif ($arg instanceof Topic) {
if (! $arg->parent instanceof Forum) {
throw new RuntimeException('Parent unavailable');
}
$topics[$arg->id] = $arg;
$isTopic = 1;
} elseif ($arg instanceof Post) {
if (! $arg->parent instanceof Topic || ! $arg->parent->parent instanceof Forum) {
throw new RuntimeException('Parents unavailable');
}
$posts[$arg->id] = $arg;
$isPost = 1;
} else {
throw new InvalidArgumentException('Expected forum, topic or post');
throw new InvalidArgumentException('Expected User(s), Forum(s), Topic(s) or Post(s)');
}
}
if (! empty($posts) + ! empty($topics) + ! empty($forums) > 1) {
throw new InvalidArgumentException('Expected only forum, topic or post');
if ($isUser + $isForum + $isTopic + $isPost > 1) {
throw new InvalidArgumentException('Expected only User(s), Forum(s), Topic(s) or Post(s)');
}
if ($posts) {
$sql = null;
if ($users) {
$vars = [
':posts' => \array_keys($posts),
];
$sql = 'DELETE FROM ::search_matches
WHERE post_id IN (?ai:posts)';
} elseif ($topics) {
$vars = [
':topics' => \array_keys($topics),
':users' => $users,
];
$sql = 'DELETE FROM ::search_matches
WHERE post_id IN (
SELECT p.id
FROM ::posts AS p
WHERE p.topic_id IN (?ai:topics)
WHERE p.poster_id IN (?ai:users)
)';
} elseif ($forums) {
}
if ($forums) {
$vars = [
':forums' => \array_keys($forums),
];
@ -84,6 +97,26 @@ class Delete extends Method
WHERE t.forum_id IN (?ai:forums)
)';
}
$this->c->DB->exec($sql, $vars);
if ($topics) {
$vars = [
':topics' => \array_keys($topics),
];
$sql = 'DELETE FROM ::search_matches
WHERE post_id IN (
SELECT p.id
FROM ::posts AS p
WHERE p.topic_id IN (?ai:topics)
)';
}
if ($posts) {
$vars = [
':posts' => \array_keys($posts),
];
$sql = 'DELETE FROM ::search_matches
WHERE post_id IN (?ai:posts)';
}
if ($sql) {
$this->c->DB->exec($sql, $vars);
}
}
}

View file

@ -5,6 +5,8 @@ namespace ForkBB\Models\Topic;
use ForkBB\Models\Action;
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;
use RuntimeException;
@ -21,54 +23,83 @@ class Delete extends Action
public function delete(...$args)
{
if (empty($args)) {
throw new InvalidArgumentException('No arguments, expected forum or topic');
throw new InvalidArgumentException('No arguments, expected User(s), Forum(s) or Topic(s)');
}
$topics = [];
$parents = [];
$forums = [];
$users = [];
$usersDel = [];
$forums = [];
$topics = [];
$parents = [];
$isUser = 0;
$isForum = 0;
$isTopic = 0;
foreach ($args as $arg) {
if ($arg instanceof Topic) {
if (! $arg->parent instanceof Forum) {
throw new RuntimeException('Parent unavailable');
if ($arg instanceof User) {
if ($arg->isGuest) {
throw new RuntimeException('Guest can not be deleted');
}
$topics[$arg->id] = $arg;
$parents[$arg->forum_id] = $arg->parent;
if (true === $arg->deleteAllPost) {
$usersDel[] = $arg->id;
}
$users[] = $arg->id;
$isUser = 1;
} elseif ($arg instanceof Forum) {
if (! $this->c->forums->get($arg->id) instanceof Forum) {
throw new RuntimeException('Forum unavailable');
}
$forums[$arg->id] = $arg;
$isForum = 1;
} elseif ($arg instanceof Topic) {
if (! $arg->parent instanceof Forum) {
throw new RuntimeException('Parent unavailable');
}
$topics[$arg->id] = $arg;
$parents[$arg->forum_id] = $arg->parent;
$isTopic = 1;
} else {
throw new InvalidArgumentException('Expected forum or topic');
throw new InvalidArgumentException('Expected User(s), Forum(s) or Topic(s)');
}
}
if (! empty($topics) + ! empty($forums) > 1) {
throw new InvalidArgumentException('Expected only forum or topic');
if ($isUser + $isForum + $isTopic > 1) {
throw new InvalidArgumentException('Expected only User(s), Forum(s) or Topic(s)');
}
if ($usersDel) {
$vars = [
':users' => $usersDel,
];
$sql = 'SELECT t.id, t.forum_id
FROM ::topics AS t
INNER JOIN ::posts AS p ON t.first_post_id=p.id
WHERE p.poster_id IN (?ai:users)';
$topics = $this->c->DB->query($sql, $vars)->fetchAll(PDO::FETCH_KEY_PAIR); //????
if ($topics) {
foreach ($topics as $value) { // ????
if (isset($parents[$value])) {
continue;
}
$parents[$value] = $this->c->forums->get($value);
}
}
}
$this->c->posts->delete(...$args);
//???? подписки, опросы, предупреждения, метки посещения тем
//???? подписки, опросы, предупреждения
if ($topics) {
if ($users) {
$vars = [
':topics' => \array_keys($topics),
':users' => $users,
];
$sql = 'DELETE FROM ::mark_of_topic
WHERE tid IN (?ai:topics)';
WHERE uid IN (?ai:users)';
$this->c->DB->exec($sql, $vars);
$sql = 'DELETE FROM ::topics
WHERE id IN (?ai:topics)';
$this->c->DB->exec($sql, $vars);
foreach($parents as $forum) {
$this->c->forums->update($forum->calcStat());
}
} elseif ($forums) {
}
if ($forums) {
$vars = [
':forums' => \array_keys($forums),
];
@ -84,5 +115,21 @@ class Delete extends Action
WHERE forum_id IN (?ai:forums)';
$this->c->DB->exec($sql, $vars);
}
if ($topics) {
$vars = [
':topics' => \array_keys($topics),
];
$sql = 'DELETE FROM ::mark_of_topic
WHERE tid IN (?ai:topics)';
$this->c->DB->exec($sql, $vars);
$sql = 'DELETE FROM ::topics
WHERE id IN (?ai:topics)';
$this->c->DB->exec($sql, $vars);
foreach($parents as $forum) {
$this->c->forums->update($forum->calcStat());
}
}
}
}

View file

@ -0,0 +1,54 @@
<?php
namespace ForkBB\Models\User;
use ForkBB\Models\Action;
use ForkBB\Models\User\Model as User;
use InvalidArgumentException;
use RuntimeException;
class Delete extends Action
{
/**
* Удаляет пользователя(ей)
*
* @param mixed ...$args
*
* @throws InvalidArgumentException
* @throws RuntimeException
*/
public function delete(...$args)
{
if (empty($args)) {
throw new InvalidArgumentException('No arguments, expected User(s)');
}
$users = [];
foreach ($args as $arg) {
if ($arg instanceof User) {
if ($arg->isGuest) {
throw new RuntimeException('Guest can not be deleted');
}
$users[] = $arg->id;
} else {
throw new InvalidArgumentException('Expected User');
}
}
$this->c->forums->delete(...$args);
//???? подписки, опросы, предупреждения
foreach ($args as $user) {
$this->c->Online->delete($user);
}
$vars = [
':users' => $users,
];
$sql = 'DELETE FROM ::users
WHERE id IN (?ai:users)';
$this->c->DB->exec($sql, $vars);
}
}

View file

@ -212,6 +212,7 @@ return [
'UserManagerUsersNumber' => \ForkBB\Models\User\UsersNumber::class,
'UserManagerPromote' => \ForkBB\Models\User\Promote::class,
'UserManagerFilter' => \ForkBB\Models\User\Filter::class,
'UserManagerDelete' => \ForkBB\Models\User\Delete::class,
'ForumModel' => \ForkBB\Models\Forum\Model::class,
'ForumModelCalcStat' => \ForkBB\Models\Forum\CalcStat::class,