mirror of
https://github.com/phpbb/phpbb.git
synced 2025-06-07 20:08:53 +00:00
[ticket/9687] Add more useful methods to the new ban manger
PHPBB3-9687
This commit is contained in:
parent
c8b8675dff
commit
9373fa3edb
6 changed files with 209 additions and 36 deletions
20
phpBB/phpbb/ban/exception/ban_insert_failed_exception.php
Normal file
20
phpBB/phpbb/ban/exception/ban_insert_failed_exception.php
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\ban\exception;
|
||||
|
||||
use phpbb\exception\runtime_exception;
|
||||
|
||||
class ban_insert_failed_exception extends runtime_exception
|
||||
{
|
||||
}
|
20
phpBB/phpbb/ban/exception/no_items_specified_exception.php
Normal file
20
phpBB/phpbb/ban/exception/no_items_specified_exception.php
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\ban\exception;
|
||||
|
||||
use phpbb\exception\runtime_exception;
|
||||
|
||||
class no_items_specified_exception extends runtime_exception
|
||||
{
|
||||
}
|
|
@ -13,12 +13,15 @@
|
|||
|
||||
namespace phpbb\ban;
|
||||
|
||||
use phpbb\ban\exception\ban_insert_failed_exception;
|
||||
use phpbb\ban\exception\invalid_length_exception;
|
||||
use phpbb\ban\exception\no_items_specified_exception;
|
||||
use phpbb\ban\exception\type_not_found_exception;
|
||||
|
||||
class manager
|
||||
{
|
||||
const CACHE_KEY = '_ban_info';
|
||||
const CACHE_KEY_INFO = '_ban_info';
|
||||
const CACHE_KEY_USERS = '_banned_users';
|
||||
const CACHE_TTL = 3600;
|
||||
|
||||
protected $ban_table;
|
||||
|
@ -65,13 +68,14 @@ class manager
|
|||
{
|
||||
throw new type_not_found_exception(); // TODO
|
||||
}
|
||||
$this->tidy();
|
||||
|
||||
$ban_items = $ban_mode->prepare_for_storage($items);
|
||||
|
||||
// Prevent duplicate bans
|
||||
$sql = 'DELETE FROM ' . $this->ban_table . "
|
||||
WHERE ban_mode = '" . $this->db->sql_escape($mode) . "'
|
||||
AND " . $this->db->sql_in_set('ban_item', $ban_items); // TODO (what if empty?)
|
||||
AND " . $this->db->sql_in_set('ban_item', $ban_items, false, true);
|
||||
$this->db->sql_query($sql);
|
||||
|
||||
$insert_array = [];
|
||||
|
@ -89,14 +93,13 @@ class manager
|
|||
|
||||
if (empty($insert_array))
|
||||
{
|
||||
return; // TODO
|
||||
throw new no_items_specified_exception(); // TODO
|
||||
}
|
||||
|
||||
$result = $this->db->sql_multi_insert($this->ban_table, $insert_array);
|
||||
if ($result === false)
|
||||
{
|
||||
// Something went wrong
|
||||
// TODO throw exception
|
||||
throw new ban_insert_failed_exception(); // TODO
|
||||
}
|
||||
|
||||
if ($ban_mode->get_ban_log_string() !== false)
|
||||
|
@ -173,10 +176,11 @@ class manager
|
|||
}
|
||||
}
|
||||
|
||||
$this->cache->destroy(self::CACHE_KEY);
|
||||
$this->cache->destroy(self::CACHE_KEY_INFO);
|
||||
$this->cache->destroy(self::CACHE_KEY_USERS);
|
||||
}
|
||||
|
||||
public function unban($mode, array $items)
|
||||
public function unban($mode, array $items, $logging = true)
|
||||
{
|
||||
/** @var \phpbb\ban\type\type_interface $ban_mode */
|
||||
$ban_mode = $this->find_type($mode);
|
||||
|
@ -184,6 +188,7 @@ class manager
|
|||
{
|
||||
throw new type_not_found_exception(); // TODO
|
||||
}
|
||||
$this->tidy();
|
||||
|
||||
$sql_ids = array_map('intval', $items);
|
||||
$sql = 'SELECT ban_item
|
||||
|
@ -202,7 +207,7 @@ class manager
|
|||
WHERE ' . $this->db->sql_in_set('ban_id', $sql_ids);
|
||||
$this->db->sql_query($sql);
|
||||
|
||||
if ($ban_mode->get_unban_log_string() !== false)
|
||||
if ($logging && $ban_mode->get_unban_log_string() !== false)
|
||||
{
|
||||
$unban_items_log = implode(', ', $unbanned_items);
|
||||
|
||||
|
@ -216,10 +221,12 @@ class manager
|
|||
|
||||
$unban_data = [
|
||||
'items' => $unbanned_items,
|
||||
'logging' => $logging,
|
||||
];
|
||||
$ban_mode->after_unban($unban_data);
|
||||
|
||||
$this->cache->destroy(self::CACHE_KEY);
|
||||
$this->cache->destroy(self::CACHE_KEY_INFO);
|
||||
$this->cache->destroy(self::CACHE_KEY_USERS);
|
||||
}
|
||||
|
||||
public function check(array $user_data = [])
|
||||
|
@ -229,33 +236,7 @@ class manager
|
|||
$user_data = $this->user->data;
|
||||
}
|
||||
|
||||
$ban_info = $this->cache->get(self::CACHE_KEY);
|
||||
if ($ban_info === false)
|
||||
{
|
||||
$sql = 'SELECT ban_mode, ban_item, ban_end, ban_reason_display
|
||||
FROM ' . $this->ban_table . '
|
||||
WHERE 1';
|
||||
$result = $this->db->sql_query($sql);
|
||||
|
||||
$ban_info = [];
|
||||
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
if (!isset($ban_info[$row['ban_mode']]))
|
||||
{
|
||||
$ban_info[$row['ban_mode']] = [];
|
||||
}
|
||||
|
||||
$ban_info[$row['ban_mode']][] = [
|
||||
'item' => $row['ban_item'],
|
||||
'end' => $row['ban_end'],
|
||||
'reason' => $row['ban_reason_display'],
|
||||
];
|
||||
}
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
$this->cache->put(self::CACHE_KEY, $ban_info, self::CACHE_TTL);
|
||||
}
|
||||
$ban_info = $this->get_info_cache();
|
||||
|
||||
foreach ($ban_info as $mode => $ban_rows)
|
||||
{
|
||||
|
@ -305,6 +286,100 @@ class manager
|
|||
return false;
|
||||
}
|
||||
|
||||
public function get_bans($mode)
|
||||
{
|
||||
/** @var \phpbb\ban\type\type_interface $ban_mode */
|
||||
$ban_mode = $this->find_type($mode);
|
||||
if ($ban_mode === false)
|
||||
{
|
||||
throw new type_not_found_exception(); // TODO
|
||||
}
|
||||
$this->tidy();
|
||||
|
||||
$sql = 'SELECT ban_id, ban_item, ban_start, ban_end, ban_reason, ban_reason_display
|
||||
FROM ' . $this->ban_table . "
|
||||
WHERE ban_mode = '" . $this->db->sql_escape($mode) . "'
|
||||
AND (ban_end <= 0 OR ban_end >= " . (int) time() . ')';
|
||||
$result = $this->db->sql_query($sql);
|
||||
$rowset = $this->db->sql_fetchrowset($result);
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
return $rowset;
|
||||
}
|
||||
|
||||
public function get_banned_users()
|
||||
{
|
||||
$banned_users = $this->cache->get(self::CACHE_KEY_USERS);
|
||||
if ($banned_users === false)
|
||||
{
|
||||
$manual_modes = [];
|
||||
$where_array = [];
|
||||
|
||||
/** @var \phpbb\ban\type\type_interface $ban_mode */
|
||||
foreach ($this->types as $ban_mode)
|
||||
{
|
||||
$user_column = $ban_mode->get_user_column();
|
||||
if (empty($user_column))
|
||||
{
|
||||
$manual_modes[] = $ban_mode;
|
||||
continue;
|
||||
}
|
||||
$where_array[] = ['AND',
|
||||
[
|
||||
['b.ban_item', '=', 'u.' . $user_column],
|
||||
['b.ban_mode', '=', $ban_mode->get_type()],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
$sql_array = [
|
||||
'SELECT' => 'u.user_id, b.ban_end',
|
||||
'FROM' => [
|
||||
$this->ban_table => 'b',
|
||||
$this->users_table => 'u',
|
||||
],
|
||||
'WHERE' => ['OR',
|
||||
$where_array,
|
||||
],
|
||||
];
|
||||
$sql = $this->db->sql_build_query('SELECT', $sql_array);
|
||||
$result = $this->db->sql_query($sql);
|
||||
|
||||
$banned_users = [];
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
$user_id = (int) $row['user_id'];
|
||||
$end = (int) $row['ban_end'];
|
||||
if (!isset($banned_users[$user_id]) || ($banned_users[$user_id] > 0 && $banned_users[$user_id] < $end))
|
||||
{
|
||||
$banned_users[$user_id] = $end;
|
||||
}
|
||||
}
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
/** @var \phpbb\ban\type\type_interface $manual_mode */
|
||||
foreach ($manual_modes as $manual_mode)
|
||||
{
|
||||
$mode_banned_users = $manual_mode->get_banned_users();
|
||||
foreach ($mode_banned_users as $user_id => $end)
|
||||
{
|
||||
$user_id = (int) $user_id;
|
||||
$end = (int) $end;
|
||||
if (!isset($banned_users[$user_id]) || ($banned_users[$user_id] > 0 && $banned_users[$user_id] < $end))
|
||||
{
|
||||
$banned_users[$user_id] = $end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->cache->put(self::CACHE_KEY_USERS, $banned_users, self::CACHE_TTL);
|
||||
}
|
||||
|
||||
return array_filter($banned_users, function ($end) {
|
||||
return $end <= 0 || $end > time();
|
||||
});
|
||||
}
|
||||
|
||||
public function tidy()
|
||||
{
|
||||
// Delete stale bans
|
||||
|
@ -332,4 +407,37 @@ class manager
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function get_info_cache()
|
||||
{
|
||||
$ban_info = $this->cache->get(self::CACHE_KEY_INFO);
|
||||
if ($ban_info === false)
|
||||
{
|
||||
$sql = 'SELECT ban_mode, ban_item, ban_end, ban_reason_display
|
||||
FROM ' . $this->ban_table . '
|
||||
WHERE 1';
|
||||
$result = $this->db->sql_query($sql);
|
||||
|
||||
$ban_info = [];
|
||||
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
if (!isset($ban_info[$row['ban_mode']]))
|
||||
{
|
||||
$ban_info[$row['ban_mode']] = [];
|
||||
}
|
||||
|
||||
$ban_info[$row['ban_mode']][] = [
|
||||
'item' => $row['ban_item'],
|
||||
'end' => $row['ban_end'],
|
||||
'reason' => $row['ban_reason_display'],
|
||||
];
|
||||
}
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
$this->cache->put(self::CACHE_KEY_INFO, $ban_info, self::CACHE_TTL);
|
||||
}
|
||||
|
||||
return $ban_info;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,6 +64,14 @@ abstract class base implements type_interface
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function get_banned_users()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries users that are excluded from banning (like founders)
|
||||
* from the database and saves them in $this->excluded array.
|
||||
|
|
|
@ -96,6 +96,18 @@ interface type_interface
|
|||
*/
|
||||
public function check(array $ban_rows, array $user_data);
|
||||
|
||||
/**
|
||||
* In case get_user_column() returns no string, this method will be called
|
||||
* when a list of banned users is retrieved.
|
||||
* Returns a list of banned users.
|
||||
* The result is cached and is not used for ban checking, so the accuracy
|
||||
* of the results is not as important as when *really* checking in check()
|
||||
*
|
||||
* @return array An array of banned users, where the user ids are the keys
|
||||
* and the value is the end of the ban (or 0 if permanent)
|
||||
*/
|
||||
public function get_banned_users();
|
||||
|
||||
/**
|
||||
* Prepares the given ban items before saving them in the database
|
||||
*
|
||||
|
|
|
@ -94,6 +94,11 @@ class user extends base
|
|||
*/
|
||||
public function after_unban(array $data)
|
||||
{
|
||||
if (empty($data['logging']))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$user_ids = array_map('intval', $data['items']);
|
||||
|
||||
$sql = 'SELECT user_id, username
|
||||
|
|
Loading…
Add table
Reference in a new issue