Ajout d'une extension
This commit is contained in:
236
ext/phpbbstudio/aps/core/acp.php
Normal file
236
ext/phpbbstudio/aps/core/acp.php
Normal file
@@ -0,0 +1,236 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* phpBB Studio - Advanced Points System. An extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019, phpBB Studio, https://www.phpbbstudio.com
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\aps\core;
|
||||
|
||||
/**
|
||||
* phpBB Studio - Advanced Points System ACP functions.
|
||||
*/
|
||||
class acp
|
||||
{
|
||||
/** @var \phpbbstudio\aps\core\functions */
|
||||
protected $functions;
|
||||
|
||||
/** @var \phpbb\template\template */
|
||||
protected $template;
|
||||
|
||||
/** @var array Array of action types from the service collection */
|
||||
protected $types = [];
|
||||
|
||||
/** @var \phpbbstudio\aps\points\valuator */
|
||||
protected $valuator;
|
||||
|
||||
/** @var array Array of template blocks for the action types */
|
||||
protected $blocks = [];
|
||||
|
||||
/** @var array Array of type fields defined by their scope. 0: Local, 1: Global */
|
||||
protected $fields = [0 => [], 1 => []];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \phpbbstudio\aps\core\functions $functions APS Core functions
|
||||
* @param \phpbb\template\template $template Template object
|
||||
* @param \phpbbstudio\aps\actions\type\action[] $types Array of action types from the service collection
|
||||
* @param \phpbbstudio\aps\points\valuator $valuator APS Valuator object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function __construct(
|
||||
functions $functions,
|
||||
\phpbb\template\template $template,
|
||||
$types,
|
||||
\phpbbstudio\aps\points\valuator $valuator
|
||||
)
|
||||
{
|
||||
$this->functions = $functions;
|
||||
$this->template = $template;
|
||||
$this->types = $types;
|
||||
$this->valuator = $valuator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of fields for the points list.
|
||||
*
|
||||
* @return array Array of action types from the service collection
|
||||
* @access public
|
||||
*/
|
||||
public function get_fields()
|
||||
{
|
||||
return $this->fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate a build for a points list for the in the ACP.
|
||||
*
|
||||
* @param int|null $forum_id Forum identifier
|
||||
* @param string $block_name The name for the template block
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function build($forum_id = null, $block_name = 'aps_categories')
|
||||
{
|
||||
$this->build_list(is_null($forum_id));
|
||||
|
||||
$this->assign_blocks($block_name);
|
||||
|
||||
$this->assign_values($forum_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a local|global points list for in the ACP.
|
||||
*
|
||||
* @param bool $global Whether we are building a global or local list
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function build_list($global)
|
||||
{
|
||||
/** @var \phpbbstudio\aps\actions\type\action $type */
|
||||
foreach ($this->types as $type)
|
||||
{
|
||||
if ($type->is_global() === $global)
|
||||
{
|
||||
$this->fields[(int) $type->is_global()] = array_merge($this->fields[(int) $type->is_global()], $type->get_fields());
|
||||
|
||||
if (empty($this->blocks[$type->get_category()]))
|
||||
{
|
||||
$this->blocks[$type->get_category()] = [
|
||||
$type->get_action() => $type->get_data(),
|
||||
];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (empty($this->blocks[$type->get_category()][$type->get_action()]))
|
||||
{
|
||||
$this->blocks[$type->get_category()][$type->get_action()] = $type->get_data();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->blocks[$type->get_category()][$type->get_action()] += $type->get_data();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign the points list to the template.
|
||||
*
|
||||
* @param string $block_name The name for the template block
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function assign_blocks($block_name = 'aps_categories')
|
||||
{
|
||||
foreach ($this->blocks as $category => $blocks)
|
||||
{
|
||||
$this->template->assign_block_vars($block_name, [
|
||||
'title' => $category,
|
||||
'blocks' => $blocks,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign the point values to the template.
|
||||
*
|
||||
* @param int $forum_id The forum identifier
|
||||
* @return array The point values
|
||||
* @access public
|
||||
*/
|
||||
public function assign_values($forum_id)
|
||||
{
|
||||
$values = $this->valuator->get_points($this->fields, (int) $forum_id);
|
||||
$values = $values[(int) $forum_id];
|
||||
|
||||
// Clean upon assignment, as this possible runs more often than submission
|
||||
$this->valuator->clean_points(array_keys($values), (int) $forum_id);
|
||||
|
||||
$this->template->assign_vars([
|
||||
'APS_VALUES' => $values,
|
||||
]);
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the point values for a given forum identifier.
|
||||
*
|
||||
* @param array $points The points to set
|
||||
* @param int $forum_id The forum identifier
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function set_points(array $points, $forum_id = 0)
|
||||
{
|
||||
$this->valuator->set_points($points, (int) $forum_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the point values in the database for a specific forum.
|
||||
*
|
||||
* @param int $forum_id The forum identifier
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function delete_points($forum_id)
|
||||
{
|
||||
$this->valuator->delete_points($forum_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the point values from one forum to an other.
|
||||
*
|
||||
* @param int $from The from forum identifier
|
||||
* @param int $to The to forum identifier
|
||||
* @param array $points The point values to copy
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function copy_points($from, $to, array $points)
|
||||
{
|
||||
$points = [0 => array_keys($points)];
|
||||
$points = $this->valuator->get_points($points, (int) $from);
|
||||
$points = $points[(int) $from];
|
||||
|
||||
$this->valuator->set_points($points, $to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the point values from one forum to multiple others.
|
||||
*
|
||||
* @param int $from The from forum identifier
|
||||
* @param int $to The to forum identifier
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function copy_multiple($from, $to)
|
||||
{
|
||||
$this->valuator->copy_points($from, $to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean the points table.
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function clean_points()
|
||||
{
|
||||
/** @var \phpbbstudio\aps\actions\type\action $type */
|
||||
foreach ($this->types as $type)
|
||||
{
|
||||
$this->fields[(int) $type->is_global()] = array_merge($this->fields[(int) $type->is_global()], $type->get_fields());
|
||||
}
|
||||
|
||||
$this->valuator->clean_all_points($this->fields);
|
||||
}
|
||||
}
|
||||
647
ext/phpbbstudio/aps/core/blocks.php
Normal file
647
ext/phpbbstudio/aps/core/blocks.php
Normal file
@@ -0,0 +1,647 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* phpBB Studio - Advanced Points System. An extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019, phpBB Studio, https://www.phpbbstudio.com
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\aps\core;
|
||||
|
||||
/**
|
||||
* phpBB Studio - Advanced Points System block functions.
|
||||
*/
|
||||
class blocks
|
||||
{
|
||||
/** @var \phpbb\auth\auth */
|
||||
protected $auth;
|
||||
|
||||
/** @var \phpbb\config\config */
|
||||
protected $config;
|
||||
|
||||
/** @var \phpbb\db\driver\driver_interface */
|
||||
protected $db;
|
||||
|
||||
/** @var \phpbbstudio\aps\core\dbal */
|
||||
protected $dbal;
|
||||
|
||||
/** @var \phpbbstudio\aps\core\functions */
|
||||
protected $functions;
|
||||
|
||||
/** @var \phpbb\group\helper */
|
||||
protected $group_helper;
|
||||
|
||||
/** @var \phpbb\controller\helper */
|
||||
protected $helper;
|
||||
|
||||
/** @var \phpbb\language\language */
|
||||
protected $language;
|
||||
|
||||
/** @var \phpbbstudio\aps\core\log */
|
||||
protected $log;
|
||||
|
||||
/** @var \phpbb\pagination */
|
||||
protected $pagination;
|
||||
|
||||
/** @var \phpbb\request\request */
|
||||
protected $request;
|
||||
|
||||
/** @var \phpbb\template\template */
|
||||
protected $template;
|
||||
|
||||
/** @var \phpbb\user */
|
||||
protected $user;
|
||||
|
||||
/** @var string phpBB root path */
|
||||
protected $root_path;
|
||||
|
||||
/** @var string php File extension */
|
||||
protected $php_ext;
|
||||
|
||||
/** @var string APS Logs table */
|
||||
protected $table;
|
||||
|
||||
/** @var string Localised points name */
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \phpbb\auth\auth $auth Authentication object
|
||||
* @param \phpbb\config\config $config Configuration object
|
||||
* @param \phpbb\db\driver\driver_interface $db Database object
|
||||
* @param \phpbbstudio\aps\core\dbal $dbal APS DBAL functions
|
||||
* @param \phpbbstudio\aps\core\functions $functions APS Core functions
|
||||
* @param \phpbb\group\helper $group_helper Group helper object
|
||||
* @param \phpbb\controller\helper $helper Controller helper object
|
||||
* @param \phpbb\language\language $language Language object
|
||||
* @param \phpbbstudio\aps\core\log $log APS Log object
|
||||
* @param \phpbb\pagination $pagination Pagination object
|
||||
* @param \phpbb\request\request $request Request object
|
||||
* @param \phpbb\template\template $template Template object
|
||||
* @param \phpbb\user $user User object
|
||||
* @param string $root_path phpBB root path
|
||||
* @param string $php_ext php File extension
|
||||
* @param string $table APS Logs table
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function __construct(
|
||||
\phpbb\auth\auth $auth,
|
||||
\phpbb\config\config $config,
|
||||
\phpbb\db\driver\driver_interface $db,
|
||||
dbal $dbal,
|
||||
functions $functions,
|
||||
\phpbb\group\helper $group_helper,
|
||||
\phpbb\controller\helper $helper,
|
||||
\phpbb\language\language $language,
|
||||
log $log,
|
||||
\phpbb\pagination $pagination,
|
||||
\phpbb\request\request $request,
|
||||
\phpbb\template\template $template,
|
||||
\phpbb\user $user,
|
||||
$root_path,
|
||||
$php_ext,
|
||||
$table
|
||||
)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
$this->config = $config;
|
||||
$this->db = $db;
|
||||
$this->dbal = $dbal;
|
||||
$this->functions = $functions;
|
||||
$this->group_helper = $group_helper;
|
||||
$this->helper = $helper;
|
||||
$this->language = $language;
|
||||
$this->log = $log;
|
||||
$this->pagination = $pagination;
|
||||
$this->request = $request;
|
||||
$this->template = $template;
|
||||
$this->user = $user;
|
||||
|
||||
$this->root_path = $root_path;
|
||||
$this->php_ext = $php_ext;
|
||||
$this->table = $table;
|
||||
|
||||
$this->name = $functions->get_name();
|
||||
|
||||
$log->load_lang();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the "Top users" and "Find a Member" blocks.
|
||||
*
|
||||
* @param string $block_id The block identifier
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function user_top_search($block_id)
|
||||
{
|
||||
$submit = $this->request->is_set_post('submit');
|
||||
$action = $this->request->variable('action', '', true);
|
||||
|
||||
$count = $this->request->variable('aps_user_top_count', (int) $this->config['aps_display_top_count']);
|
||||
$top_username = '';
|
||||
|
||||
$sql = 'SELECT user_id, username, username_clean, user_colour, user_points,
|
||||
user_avatar, user_avatar_type, user_avatar_width, user_avatar_height
|
||||
FROM ' . $this->functions->table('users') . '
|
||||
WHERE user_type <> ' . USER_IGNORE . '
|
||||
ORDER BY user_points DESC, username_clean ASC';
|
||||
$result = $this->db->sql_query_limit($sql, $count);
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
$top_username = empty($top_username) ? $row['username_clean'] : $top_username;
|
||||
|
||||
$this->template->assign_block_vars('top_users', [
|
||||
'NAME' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']),
|
||||
'AVATAR' => phpbb_get_user_avatar($row),
|
||||
'POINTS' => $row['user_points'],
|
||||
'U_ADJUST' => append_sid("{$this->root_path}mcp.{$this->php_ext}", 'i=-phpbbstudio-aps-mcp-main_module&mode=change&u=' . (int) $row['user_id'], true, $this->user->session_id)
|
||||
]);
|
||||
}
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
// Set up the default user to display, either this user or the top user if this user is a guest
|
||||
$default = $this->user->data['user_id'] != ANONYMOUS ? $this->user->data['username'] : $top_username;
|
||||
$username = $this->request->variable('aps_user_search', $default, true);
|
||||
|
||||
// Find the user for the provided username
|
||||
$user = $this->find_user($username);
|
||||
|
||||
// If a user was found
|
||||
if ($user !== false)
|
||||
{
|
||||
// Count the amount of users with more points than this user.
|
||||
$sql = 'SELECT COUNT(user_points) as rank
|
||||
FROM ' . $this->functions->table('users') . '
|
||||
WHERE user_points > ' . $user['user_points'];
|
||||
$result = $this->db->sql_query_limit($sql, 1);
|
||||
$user_rank = (int) $this->db->sql_fetchfield('rank');
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
// Increment by one, as the rank is the amount of users above this user
|
||||
$user_rank++;
|
||||
}
|
||||
|
||||
// Output the template variables for display
|
||||
$this->template->assign_vars([
|
||||
// Set up a default no avatar
|
||||
'APS_NO_AVATAR' => $this->functions->get_no_avatar(),
|
||||
|
||||
// The searched user data
|
||||
'APS_SEARCH_USERNAME' => $username,
|
||||
'APS_SEARCH_USER_AVATAR' => !empty($user) ? phpbb_get_user_avatar($user) : '',
|
||||
'APS_SEARCH_USER_FULL' => !empty($user) ? get_username_string('full', $user['user_id'], $user['username'], $user['user_colour']) : $this->language->lang('NO_USER'),
|
||||
'APS_SEARCH_USER_POINTS' => !empty($user) ? $user['user_points'] : 0.00,
|
||||
'APS_SEARCH_USER_RANK' => !empty($user_rank) ? $user_rank : $this->language->lang('NA'),
|
||||
'U_APS_SEARCH_USER_ADJUST' => !empty($user) ? append_sid("{$this->root_path}mcp.{$this->php_ext}", 'i=-phpbbstudio-aps-mcp-main_module&mode=change&u=' . (int) $user['user_id'], true, $this->user->session_id) : '',
|
||||
|
||||
// Amount of top users to display
|
||||
'APS_TOP_USERS_COUNT' => $count,
|
||||
|
||||
// APS Moderator
|
||||
'S_APS_USER_ADJUST' => $this->auth->acl_get('m_aps_adjust_custom') || $this->auth->acl_get('m_aps_'),
|
||||
|
||||
// Block actions
|
||||
'U_APS_ACTION_SEARCH' => $this->helper->route('phpbbstudio_aps_display', ['page' => 'overview', 'action' => 'search']),
|
||||
'U_APS_ACTION_TOP' => $this->helper->route('phpbbstudio_aps_display', ['page' => 'overview', 'action' => 'top']),
|
||||
]);
|
||||
|
||||
// Handle any AJAX actions regarding these blocks
|
||||
if ($submit && $this->request->is_ajax() && in_array($action, ['search', 'top']))
|
||||
{
|
||||
$this->template->set_filenames(['aps_body' => '@phpbbstudio_aps/blocks/base.html']);
|
||||
$this->template->assign_vars([
|
||||
'block' => [
|
||||
'ID' => $block_id,
|
||||
'TITLE' => $action === 'top' ? $this->language->lang('APS_TOP_USERS') : $this->language->lang('FIND_USERNAME'),
|
||||
'TEMPLATE' => '@phpbbstudio_aps/blocks/points_' . $action . '.html',
|
||||
],
|
||||
]);
|
||||
|
||||
$json_response = new \phpbb\json_response;
|
||||
$json_response->send([
|
||||
'body' => $this->template->assign_display('aps_body'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the "Random member" block.
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function user_random()
|
||||
{
|
||||
$sql = 'SELECT user_id, username, user_colour, user_points,
|
||||
user_avatar, user_avatar_type, user_avatar_width, user_avatar_height
|
||||
FROM ' . $this->functions->table('users') . '
|
||||
WHERE user_type <> ' . USER_IGNORE . '
|
||||
AND user_type <> ' . USER_INACTIVE . '
|
||||
ORDER BY ' . $this->dbal->random();
|
||||
|
||||
$result = $this->db->sql_query_limit($sql, 1);
|
||||
$row = $this->db->sql_fetchrow($result);
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
$this->template->assign_vars([
|
||||
'APS_RANDOM_NO_AVATAR' => $this->functions->get_no_avatar(),
|
||||
|
||||
'APS_RANDOM_USER_AVATAR' => phpbb_get_user_avatar($row),
|
||||
'APS_RANDOM_USER_FULL' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']),
|
||||
'APS_RANDOM_USER_POINTS' => $row['user_points'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the "Points actions" block.
|
||||
*
|
||||
* @param int $pagination The pagination's page number
|
||||
* @param string $block_id The block identifier
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function display_actions($pagination, $block_id)
|
||||
{
|
||||
$params = ['page' => 'actions'];
|
||||
$limit = $this->config['aps_actions_per_page'];
|
||||
|
||||
// Set up general vars
|
||||
$s_reportee = $this->auth->acl_get('u_aps_view_mod');
|
||||
$s_username = $this->auth->acl_get('u_aps_view_logs_other');
|
||||
|
||||
$forum_id = $this->request->variable('f', '');
|
||||
$topic_title = $this->request->variable('t', '', true);
|
||||
$username = $this->request->variable('u', '', true);
|
||||
$reportee = $this->request->variable('r', '', true);
|
||||
|
||||
$username = $s_username ? $username : '';
|
||||
$reportee = $s_reportee ? $reportee : '';
|
||||
|
||||
$topic_ids = $this->find_topic($topic_title);
|
||||
$user_id = $this->find_user($username, false);
|
||||
$reportee_id = $this->find_user($reportee, false);
|
||||
|
||||
$post_id = 0;
|
||||
$user_id = $s_username ? $user_id : (int) $this->user->data['user_id'];
|
||||
|
||||
// Sort keys
|
||||
$sort_days = $this->request->variable('st', 0);
|
||||
$sort_key = $this->request->variable('sk', 't');
|
||||
$sort_dir = $this->request->variable('sd', 'd');
|
||||
|
||||
// Keywords
|
||||
$keywords = $this->request->variable('keywords', '', true);
|
||||
if (!empty($keywords))
|
||||
{
|
||||
$params['keywords'] = urlencode(htmlspecialchars_decode($keywords));
|
||||
}
|
||||
|
||||
// Calculate the start (SQL offset) from the page number
|
||||
$start = ($pagination - 1) * $limit;
|
||||
|
||||
// Sorting
|
||||
$limit_days = [
|
||||
0 => $this->language->lang('APS_POINTS_ACTIONS_ALL', $this->name),
|
||||
1 => $this->language->lang('1_DAY'),
|
||||
7 => $this->language->lang('7_DAYS'),
|
||||
14 => $this->language->lang('2_WEEKS'),
|
||||
30 => $this->language->lang('1_MONTH'),
|
||||
90 => $this->language->lang('3_MONTHS'),
|
||||
180 => $this->language->lang('6_MONTHS'),
|
||||
365 => $this->language->lang('1_YEAR'),
|
||||
];
|
||||
$sort_by_text = [
|
||||
'a' => $this->language->lang('APS_POINTS_ACTION', $this->name),
|
||||
'ps' => $this->name,
|
||||
'pn' => $this->language->lang('APS_POINTS_NEW', $this->name),
|
||||
'po' => $this->language->lang('APS_POINTS_OLD', $this->name),
|
||||
'uu' => $this->language->lang('SORT_USERNAME'),
|
||||
'ru' => ucfirst($this->language->lang('FROM')),
|
||||
't' => $this->language->lang('APS_POINTS_ACTION_TIME', $this->name),
|
||||
];
|
||||
$sort_by_sql = [
|
||||
'a' => 'l.log_action',
|
||||
'ps' => 'l.points_sum',
|
||||
'pn' => 'l.points_new',
|
||||
'po' => 'l.points_old',
|
||||
'uu' => 'u.username',
|
||||
'ru' => 'r.username',
|
||||
't' => 'l.log_time',
|
||||
];
|
||||
|
||||
$s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = '';
|
||||
gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param);
|
||||
|
||||
if (!empty($u_sort_param))
|
||||
{
|
||||
$sort_params = explode('&', $u_sort_param);
|
||||
|
||||
foreach ($sort_params as $param)
|
||||
{
|
||||
list($key, $value) = explode('=', $param);
|
||||
|
||||
$params[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Define where and sort sql for use in displaying logs
|
||||
$sql_time = ($sort_days) ? (time() - ($sort_days * 86400)) : 0;
|
||||
$sql_sort = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC');
|
||||
|
||||
$rowset = $this->log->get(true, $limit, $start, $forum_id, $topic_ids, $post_id, $user_id, $reportee_id, $sql_time, $sql_sort, $keywords);
|
||||
$start = $this->log->get_valid_offset();
|
||||
$total = $this->log->get_log_count();
|
||||
|
||||
$user_ids = [];
|
||||
|
||||
foreach ($rowset as $row)
|
||||
{
|
||||
$user_ids[] = $row['user_id'];
|
||||
$this->template->assign_block_vars('aps_actions', array_merge(array_change_key_case($row, CASE_UPPER), [
|
||||
'S_AUTH_BUILD' => (bool) $this->auth->acl_get('u_aps_view_build'),
|
||||
'S_AUTH_BUILD_OTHER' => (bool) ($this->auth->acl_get('u_aps_view_build_other') || ((int) $this->user->data['user_id'] === $row['user_id'])),
|
||||
'S_AUTH_MOD' => (bool) $this->auth->acl_get('u_aps_view_mod'),
|
||||
'S_MOD' => (bool) strpos($row['action'],'_USER_') !== false,
|
||||
]));
|
||||
}
|
||||
|
||||
$avatars = $this->functions->get_avatars($user_ids);
|
||||
|
||||
if (!function_exists('make_forum_select'))
|
||||
{
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
include $this->root_path . 'includes/functions_admin.' . $this->php_ext;
|
||||
}
|
||||
|
||||
/**
|
||||
* phpBB's DocBlock expects a string but allows arrays aswell..
|
||||
* @noinspection PhpParamsInspection
|
||||
*/
|
||||
$this->pagination->generate_template_pagination(
|
||||
[
|
||||
'routes' => [
|
||||
'phpbbstudio_aps_display',
|
||||
'phpbbstudio_aps_display_pagination',
|
||||
],
|
||||
'params' => $params,
|
||||
], 'pagination', 'pagination', $total, $limit, $start);
|
||||
|
||||
$this->template->assign_vars([
|
||||
'PAGE_NUMBER' => $this->pagination->on_page($total, $limit, $start),
|
||||
'TOTAL_LOGS' => $this->language->lang('APS_POINTS_ACTIONS_TOTAL', $this->name, $total),
|
||||
|
||||
'APS_ACTIONS_AVATARS' => $avatars,
|
||||
'APS_ACTIONS_NO_AVATAR' => $this->functions->get_no_avatar(),
|
||||
|
||||
'S_AUTH_FROM' => $s_reportee,
|
||||
'S_AUTH_USER' => $s_username,
|
||||
|
||||
'S_SEARCH_TOPIC' => $topic_title,
|
||||
'S_SEARCH_FROM' => $reportee,
|
||||
'S_SEARCH_USER' => $username,
|
||||
'S_SELECT_FORUM' => make_forum_select((int) $forum_id),
|
||||
|
||||
'S_SELECT_SORT_DAYS' => $s_limit_days,
|
||||
'S_SELECT_SORT_KEY' => $s_sort_key,
|
||||
'S_SELECT_SORT_DIR' => $s_sort_dir,
|
||||
'S_KEYWORDS' => $keywords,
|
||||
|
||||
'U_APS_ACTION_LOGS' => $this->helper->route('phpbbstudio_aps_display', ['page' => 'actions', 'action' => 'search']),
|
||||
]);
|
||||
|
||||
$submit = $this->request->is_set_post('submit');
|
||||
$action = $this->request->variable('action', '', true);
|
||||
|
||||
// Handle any AJAX action regarding this block
|
||||
if ($submit && $this->request->is_ajax() && $action === 'search')
|
||||
{
|
||||
$this->template->set_filenames(['aps_body' => '@phpbbstudio_aps/blocks/base.html']);
|
||||
$this->template->assign_vars([
|
||||
'block' => [
|
||||
'ID' => $block_id,
|
||||
'TITLE' => $this->language->lang('APS_POINTS_ACTIONS', $this->name),
|
||||
'TEMPLATE' => '@phpbbstudio_aps/blocks/points_actions.html',
|
||||
],
|
||||
]);
|
||||
|
||||
$json_response = new \phpbb\json_response;
|
||||
$json_response->send([
|
||||
'body' => $this->template->assign_display('aps_body'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the "Recent adjustments" block.
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function recent_adjustments()
|
||||
{
|
||||
$user_id = !$this->auth->acl_get('u_aps_view_logs_other') ? (int) $this->user->data['user_id'] : 0;
|
||||
|
||||
$limit = (int) $this->config['aps_display_adjustments'];
|
||||
$rowset = $this->log->get(true, $limit, 0, 0, 0, 0, $user_id, 0, 0, 'l.log_time DESC', 'APS_POINTS_USER_ADJUSTED');
|
||||
|
||||
$user_ids = [];
|
||||
|
||||
foreach ($rowset as $row)
|
||||
{
|
||||
$user_ids[] = $row['user_id'];
|
||||
$this->template->assign_block_vars('aps_adjustments', array_merge(array_change_key_case($row, CASE_UPPER), [
|
||||
'S_AUTH_BUILD' => (bool) $this->auth->acl_get('u_aps_view_build'),
|
||||
'S_AUTH_BUILD_OTHER' => (bool) ($this->auth->acl_get('u_aps_view_build_other') || ((int) $this->user->data['user_id'] === $row['user_id'])),
|
||||
'S_AUTH_MOD' => (bool) $this->auth->acl_get('u_aps_view_mod'),
|
||||
'S_MOD' => (bool) strpos($row['action'],'_USER_') !== false,
|
||||
]));
|
||||
}
|
||||
|
||||
$avatars = $this->functions->get_avatars($user_ids);
|
||||
|
||||
$this->template->assign_vars([
|
||||
'APS_ADJUSTMENTS_AVATARS' => $avatars,
|
||||
'APS_ADJUSTMENTS_NO_AVATAR' => $this->functions->get_no_avatar(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the "Points per forum" block.
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function charts_forum()
|
||||
{
|
||||
$rowset = [];
|
||||
|
||||
$sql = 'SELECT forum_id, SUM(points_sum) as points
|
||||
FROM ' . $this->table . '
|
||||
WHERE log_approved = 1
|
||||
GROUP BY forum_id';
|
||||
$result = $this->db->sql_query($sql);
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
if (empty($row['points']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$rowset[(int) $row['forum_id']]['POINTS'] = $row['points'];
|
||||
}
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
$sql = 'SELECT forum_name, forum_id
|
||||
FROM ' . $this->functions->table('forums') . '
|
||||
WHERE ' . $this->db->sql_in_set('forum_id', array_keys($rowset), false, true);
|
||||
$result = $this->db->sql_query($sql);
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
$rowset[(int) $row['forum_id']]['NAME'] = utf8_decode_ncr($row['forum_name']);
|
||||
}
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
if (isset($rowset[0]))
|
||||
{
|
||||
$rowset[0]['NAME'] = $this->language->lang('APS_POINTS_GLOBAL');
|
||||
}
|
||||
|
||||
$this->template->assign_block_vars_array('aps_forums', $rowset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the "Points per group" block.
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function charts_group()
|
||||
{
|
||||
$rowset = [];
|
||||
|
||||
$sql = 'SELECT u.group_id, SUM(p.points_sum) as points
|
||||
FROM ' . $this->table . ' p,
|
||||
' . $this->functions->table('users') . ' u
|
||||
WHERE u.user_id = p.user_id
|
||||
AND p.log_approved = 1
|
||||
GROUP BY u.group_id';
|
||||
$result = $this->db->sql_query($sql);
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
$rowset[(int) $row['group_id']] = $row['points'];
|
||||
}
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
$sql = 'SELECT group_name, group_colour, group_id
|
||||
FROM ' . $this->functions->table('groups') . '
|
||||
WHERE group_name <> "BOTS"
|
||||
AND group_type <> ' . GROUP_HIDDEN . '
|
||||
AND ' . $this->db->sql_in_set('group_id', array_keys($rowset), false, true);
|
||||
$result = $this->db->sql_query($sql);
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
$this->template->assign_block_vars('aps_groups', [
|
||||
'COLOUR' => $row['group_colour'],
|
||||
'NAME' => $this->group_helper->get_name($row['group_name']),
|
||||
'POINTS' => $rowset[(int) $row['group_id']],
|
||||
]);
|
||||
}
|
||||
$this->db->sql_freeresult($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the "Points trade off" and "Points growth" blocks.
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function charts_period()
|
||||
{
|
||||
$sql = 'SELECT ' . $this->dbal->unix_to_month('log_time') . ' as month,
|
||||
' . $this->dbal->unix_to_year('log_time') . ' as year,
|
||||
SUM(' . $this->db->sql_case('points_sum < 0', 'points_sum', 0) . ') AS negative,
|
||||
SUM(' . $this->db->sql_case('points_sum > 0', 'points_sum', 0) . ') AS positive
|
||||
FROM ' . $this->table . '
|
||||
WHERE log_time > ' . strtotime('-1 year') . '
|
||||
GROUP BY ' . $this->dbal->unix_to_month('log_time') . ',
|
||||
' . $this->dbal->unix_to_year('log_time') . '
|
||||
ORDER BY ' . $this->dbal->unix_to_year('log_time') . ' ASC,
|
||||
' . $this->dbal->unix_to_month('log_time') . ' ASC';
|
||||
$result = $this->db->sql_query($sql);
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
$timestamp = $this->user->get_timestamp_from_format('m Y', $row['month'] . ' ' . $row['year']);
|
||||
$formatted = $this->user->format_date($timestamp, 'F Y');
|
||||
|
||||
$this->template->assign_block_vars('aps_period', [
|
||||
'DATE' => $formatted,
|
||||
'NEGATIVE' => -$row['negative'], // Make it positive
|
||||
'POSITIVE' => $row['positive'],
|
||||
'TOTAL' => $this->functions->equate_points($row['positive'], $row['negative']),
|
||||
]);
|
||||
}
|
||||
$this->db->sql_freeresult($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a user row for the provided username.
|
||||
*
|
||||
* @param string $username The username
|
||||
* @param bool $full Whether we want just the identifier or everything
|
||||
* @return mixed If $full is true: a user row or false if no user was found
|
||||
* If $full is false: the user identifier
|
||||
* @access protected
|
||||
*/
|
||||
protected function find_user($username, $full = true)
|
||||
{
|
||||
if (empty($username) && !$full)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
$select = !$full ? 'user_id' : 'user_id, username, username_clean, user_colour, user_points, user_avatar, user_avatar_type, user_avatar_width, user_avatar_height';
|
||||
|
||||
$sql = 'SELECT ' . $select . '
|
||||
FROM ' . $this->functions->table('users') . '
|
||||
WHERE user_type <> ' . USER_IGNORE . '
|
||||
AND (username = "' . $this->db->sql_escape($username) . '"
|
||||
OR username_clean = "' . $this->db->sql_escape(utf8_clean_string($username)) . '"
|
||||
)';
|
||||
$result = $this->db->sql_query_limit($sql, 1);
|
||||
$user = $this->db->sql_fetchrow($result);
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
return $full ? $user : (int) $user['user_id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a topic identifier for a provided topic title.
|
||||
*
|
||||
* @param string $title The topic title
|
||||
* @return array The topic identifier or 0 if no topic was found or unauthorised
|
||||
* @access protected
|
||||
*/
|
||||
protected function find_topic($title)
|
||||
{
|
||||
$topic_ids = [];
|
||||
|
||||
$sql = 'SELECT forum_id, topic_id
|
||||
FROM ' . $this->functions->table('topics') . '
|
||||
WHERE topic_title = "' . $this->db->sql_escape($title) . '"';
|
||||
$result = $this->db->sql_query($sql);
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
if ($this->auth->acl_get('f_read', (int) $row['topic_id']))
|
||||
{
|
||||
$topic_ids[] = (int) $row['topic_id'];
|
||||
}
|
||||
}
|
||||
|
||||
return $topic_ids;
|
||||
}
|
||||
}
|
||||
119
ext/phpbbstudio/aps/core/dbal.php
Normal file
119
ext/phpbbstudio/aps/core/dbal.php
Normal file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* phpBB Studio - Advanced Points System. An extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019, phpBB Studio, https://www.phpbbstudio.com
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\aps\core;
|
||||
|
||||
/**
|
||||
* phpBB Studio - Advanced Points System DBAL.
|
||||
*/
|
||||
class dbal
|
||||
{
|
||||
/** @var string The name of the sql layer */
|
||||
protected $layer;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \phpbb\db\driver\driver_interface $db Database object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function __construct(\phpbb\db\driver\driver_interface $db)
|
||||
{
|
||||
$this->layer = $db->get_sql_layer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the "random"-function for the current SQL layer.
|
||||
*
|
||||
* @return string The "random"-function
|
||||
* @access public
|
||||
*/
|
||||
public function random()
|
||||
{
|
||||
switch ($this->layer)
|
||||
{
|
||||
case 'postgres':
|
||||
return 'RANDOM()';
|
||||
break;
|
||||
|
||||
case 'mssql':
|
||||
case 'mssql_odbc':
|
||||
return 'NEWID()';
|
||||
break;
|
||||
|
||||
default:
|
||||
return 'RAND()';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the "month from a UNIX timestamp"-function for the current SQL layer.
|
||||
*
|
||||
* @param string $column The column name holding the UNIX timestamp
|
||||
* @return string The "month from a UNIX timestamp"-function
|
||||
* @access public
|
||||
*/
|
||||
public function unix_to_month($column)
|
||||
{
|
||||
switch ($this->layer)
|
||||
{
|
||||
case 'mssql':
|
||||
case 'mssql_odbc':
|
||||
case 'mssqlnative':
|
||||
return 'DATEADD(m, ' . $column . ', 19700101)';
|
||||
break;
|
||||
|
||||
case 'postgres':
|
||||
return 'extract(month from to_timestamp(' . $column . '))';
|
||||
break;
|
||||
|
||||
case 'sqlite3':
|
||||
return "strftime('%m', datetime(" . $column . ", 'unixepoch'))";
|
||||
break;
|
||||
|
||||
default:
|
||||
return 'MONTH(FROM_UNIXTIME(' . $column . '))';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the "year from a UNIX timestamp"-function for the current SQL layer.
|
||||
*
|
||||
* @param string $column The column name holding the UNIX timestamp
|
||||
* @return string The "year from a UNIX timestamp"-function
|
||||
* @access public
|
||||
*/
|
||||
public function unix_to_year($column)
|
||||
{
|
||||
switch ($this->layer)
|
||||
{
|
||||
case 'mssql':
|
||||
case 'mssql_odbc':
|
||||
case 'mssqlnative':
|
||||
return 'DATEADD(y, ' . $column . ', 19700101)';
|
||||
break;
|
||||
|
||||
case 'postgres':
|
||||
return 'extract(year from to_timestamp(' . $column . '))';
|
||||
break;
|
||||
|
||||
case 'sqlite3':
|
||||
return "strftime('%y', datetime(" . $column . ", 'unixepoch'))";
|
||||
break;
|
||||
|
||||
default:
|
||||
return 'YEAR(FROM_UNIXTIME(' . $column . '))';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
501
ext/phpbbstudio/aps/core/functions.php
Normal file
501
ext/phpbbstudio/aps/core/functions.php
Normal file
@@ -0,0 +1,501 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* phpBB Studio - Advanced Points System. An extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019, phpBB Studio, https://www.phpbbstudio.com
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\aps\core;
|
||||
|
||||
/**
|
||||
* phpBB Studio - Advanced Points System core functions.
|
||||
*/
|
||||
class functions
|
||||
{
|
||||
/** @var \phpbb\auth\auth */
|
||||
protected $auth;
|
||||
|
||||
/** @var \phpbb\config\config */
|
||||
protected $config;
|
||||
|
||||
/** @var \phpbb\db\driver\driver_interface */
|
||||
protected $db;
|
||||
|
||||
/** @var \phpbb\language\language */
|
||||
protected $language;
|
||||
|
||||
/** @var \phpbb\path_helper */
|
||||
protected $path_helper;
|
||||
|
||||
/** @var \phpbb\request\request */
|
||||
protected $request;
|
||||
|
||||
/** @var \phpbb\user */
|
||||
protected $user;
|
||||
|
||||
/** @var string Table prefix */
|
||||
protected $table_prefix;
|
||||
|
||||
/** @var array APS Constants */
|
||||
protected $constants;
|
||||
|
||||
/** @var bool Whether or not Default Avatar Extended (DAE) is enabled */
|
||||
protected $is_dae_enabled;
|
||||
|
||||
/** @var string The localised points name */
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \phpbb\auth\auth $auth Authentication object
|
||||
* @param \phpbb\config\config $config Configuration object
|
||||
* @param \phpbb\db\driver\driver_interface $db Database object
|
||||
* @param \phpbb\extension\manager $ext_manager Extension manager object
|
||||
* @param \phpbb\language\language $language Language object
|
||||
* @param \phpbb\path_helper $path_helper Path helper object
|
||||
* @param \phpbb\request\request $request Request object
|
||||
* @param \phpbb\user $user User object
|
||||
* @param string $table_prefix Table prefix
|
||||
* @param array $constants APS Constants
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function __construct(
|
||||
\phpbb\auth\auth $auth,
|
||||
\phpbb\config\config $config,
|
||||
\phpbb\db\driver\driver_interface $db,
|
||||
\phpbb\extension\manager $ext_manager,
|
||||
\phpbb\language\language $language,
|
||||
\phpbb\path_helper $path_helper,
|
||||
\phpbb\request\request $request,
|
||||
\phpbb\user $user,
|
||||
$table_prefix,
|
||||
array $constants
|
||||
)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
$this->config = $config;
|
||||
$this->db = $db;
|
||||
$this->language = $language;
|
||||
$this->path_helper = $path_helper;
|
||||
$this->request = $request;
|
||||
$this->user = $user;
|
||||
|
||||
$this->table_prefix = $table_prefix;
|
||||
$this->constants = $constants;
|
||||
|
||||
$this->is_dae_enabled = $ext_manager->is_enabled('threedi/dae') && $config['threedi_default_avatar_extended'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefix a table name.
|
||||
*
|
||||
* This is to not rely on constants.
|
||||
*
|
||||
* @param string $name The table name to prefix
|
||||
* @return string The prefixed table name
|
||||
* @access public
|
||||
*/
|
||||
public function table($name)
|
||||
{
|
||||
return $this->table_prefix . $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a forum name for a specific forum identifier.
|
||||
*
|
||||
* @param int $forum_id The forum identifier
|
||||
* @return string The forum name
|
||||
* @access public
|
||||
*/
|
||||
public function forum_name($forum_id)
|
||||
{
|
||||
$sql = 'SELECT forum_name FROM ' . $this->table('forums') . ' WHERE forum_id = ' . (int) $forum_id;
|
||||
$result = $this->db->sql_query_limit($sql, 1);
|
||||
$forum_name = $this->db->sql_fetchfield('forum_name');
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
return $forum_name;
|
||||
}
|
||||
|
||||
public function post_data($post_id)
|
||||
{
|
||||
$sql = 'SELECT t.topic_first_post_id, p.poster_id
|
||||
FROM ' . $this->table('posts') . ' p,
|
||||
' . $this->table('topics') . ' t
|
||||
WHERE p.topic_id = t.topic_id
|
||||
AND p.post_id = ' . (int) $post_id;
|
||||
$result = $this->db->sql_query_limit($sql, 1);
|
||||
$post_data = $this->db->sql_fetchrow($result);
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
return $post_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get topic and post locked status.
|
||||
*
|
||||
* Called when a moderator edits a post.
|
||||
*
|
||||
* @param int $post_id The post identifier
|
||||
* @return array The database row
|
||||
* @access public
|
||||
*/
|
||||
public function topic_post_locked($post_id)
|
||||
{
|
||||
$sql = 'SELECT t.topic_poster, t.topic_status, p.post_edit_locked
|
||||
FROM ' . $this->table('posts') . ' p,
|
||||
' . $this->table('topics') . ' t
|
||||
WHERE p.topic_id = t.topic_id
|
||||
AND post_id = ' . (int) $post_id;
|
||||
$result = $this->db->sql_query_limit($sql, 1);
|
||||
$row = $this->db->sql_fetchrow($result);
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get avatars for provided user identifiers.
|
||||
*
|
||||
* @param array $user_ids The user identifiers.
|
||||
* @return array Array of the users' avatars indexed per user identifier
|
||||
* @access public
|
||||
*/
|
||||
public function get_avatars($user_ids)
|
||||
{
|
||||
$avatars = [];
|
||||
|
||||
$sql = 'SELECT user_id, user_avatar, user_avatar_type, user_avatar_width, user_avatar_height
|
||||
FROM ' . $this->table('users') . '
|
||||
WHERE ' . $this->db->sql_in_set('user_id', $user_ids, false, true) . '
|
||||
AND user_type <> ' . USER_IGNORE;
|
||||
$result = $this->db->sql_query($sql);
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
$avatars[(int) $row['user_id']] = phpbb_get_user_avatar($row);
|
||||
}
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
return $avatars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether Advanced Points System is ran in Safe Mode,
|
||||
* meaning that exceptions will be caught and logged instead of thrown.
|
||||
* Safe mode should be turned "off" when testing and developing.
|
||||
*
|
||||
* @return bool Whether APS is ran in Safe Mode or not.
|
||||
* @access public
|
||||
*/
|
||||
public function safe_mode()
|
||||
{
|
||||
return (bool) $this->config['aps_points_safe_mode'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a formatted points string according to the settings.
|
||||
*
|
||||
* @param double $points The points to display
|
||||
* @param bool $icon Whether or not to also display the points icon
|
||||
* @return string The formatted points for display
|
||||
* @access public
|
||||
*/
|
||||
public function display_points($points, $icon = true)
|
||||
{
|
||||
$separator_dec = htmlspecialchars_decode($this->config['aps_points_separator_dec']);
|
||||
$separator_thou = htmlspecialchars_decode($this->config['aps_points_separator_thou']);
|
||||
|
||||
$points = number_format((double) $points, (int) $this->config['aps_points_decimals'], (string) $separator_dec, (string) $separator_thou);
|
||||
|
||||
// If we do not want the icon, return now
|
||||
if (!$icon)
|
||||
{
|
||||
return $points;
|
||||
}
|
||||
|
||||
// Get the icon side
|
||||
$right = (bool) $this->config['aps_points_icon_position'];
|
||||
|
||||
return $right ? ($points . ' ' . $this->get_icon()) : ($this->get_icon() . ' ' . $points);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format points for usage in input fields
|
||||
*
|
||||
* @param double $points The points to format
|
||||
* @return double
|
||||
* @access public
|
||||
*/
|
||||
public function format_points($points)
|
||||
{
|
||||
return (double) round($points, (int) $this->config['aps_points_decimals']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the points icon for display.
|
||||
*
|
||||
* @param bool $force_fa Whether to force FA icon
|
||||
* @return string The HTML formatted points icon
|
||||
* @access public
|
||||
*/
|
||||
public function get_icon($force_fa = false)
|
||||
{
|
||||
if (!$force_fa && $this->config['aps_points_icon_img'])
|
||||
{
|
||||
$board_url = defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH;
|
||||
$base_path = $board_url || $this->request->is_ajax() ? generate_board_url() . '/' : $this->path_helper->get_web_root_path();
|
||||
|
||||
$source = $base_path . 'images/' . (string) $this->config['aps_points_icon_img'];
|
||||
|
||||
return '<span class="icon fa-fw"><img src="' . $source . '" alt="' . $this->get_name() . '" style="width: auto; height: 1em;"></span>';
|
||||
}
|
||||
|
||||
return '<i class="icon ' . (string) $this->config['aps_points_icon'] . ' fa-fw" title="' . $this->get_name() . '" aria-hidden="true"></i>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the localised points name.
|
||||
*
|
||||
* @return string The localised points name
|
||||
* @access public
|
||||
*/
|
||||
public function get_name()
|
||||
{
|
||||
if (empty($this->name))
|
||||
{
|
||||
$key = 'aps_points_name_';
|
||||
|
||||
$name = !empty($this->config[$key . $this->user->lang_name]) ? $this->config[$key . $this->user->lang_name] : $this->config[$key . $this->config['default_lang']];
|
||||
|
||||
// Fallback
|
||||
$name = !empty($name) ? $name : 'Points';
|
||||
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function get_auth($name, $forum_id)
|
||||
{
|
||||
// Fix for template functions
|
||||
$forum_id = $forum_id === true ? 0 : $forum_id;
|
||||
|
||||
return $this->auth->acl_get($name, $forum_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an config value for given config name.
|
||||
*
|
||||
* @param string $name The APS config name
|
||||
* @return string The APS config value
|
||||
* @access public
|
||||
*/
|
||||
public function get_config($name)
|
||||
{
|
||||
return $this->config->offsetGet($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the step amount for a numeric input field.
|
||||
*
|
||||
* @return double
|
||||
* @access public
|
||||
*/
|
||||
public function get_step()
|
||||
{
|
||||
return round(substr_replace('001', '.', (3 - (int) $this->config['aps_points_decimals']), 0), $this->config['aps_points_decimals']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Equates an array of points to a single points value.
|
||||
*
|
||||
* @param array $array The array to equate
|
||||
* @param string $operator The equation operator
|
||||
* @return double The equated points value
|
||||
* @access public
|
||||
*/
|
||||
public function equate_array(array $array, $operator = '+')
|
||||
{
|
||||
$result = array_reduce(
|
||||
$array,
|
||||
function($a, $b) use ($operator)
|
||||
{
|
||||
return $this->equate_points($a, $b, $operator);
|
||||
},
|
||||
0.00);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Equate two points by reference.
|
||||
*
|
||||
* @param double $a The referenced points value
|
||||
* @param double $b The points value to equate
|
||||
* @param string $operator The equation operator
|
||||
* @return void Passed by reference
|
||||
* @access public
|
||||
*/
|
||||
public function equate_reference(&$a, $b, $operator = '+')
|
||||
{
|
||||
$a = $this->equate_points($a, $b, $operator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Equate two points.
|
||||
*
|
||||
* @param double $a The points value to equate
|
||||
* @param double $b The points value to equate
|
||||
* @param string $operator The equation operator
|
||||
* @return double The equated points value
|
||||
* @access public
|
||||
*/
|
||||
public function equate_points($a, $b, $operator = '+')
|
||||
{
|
||||
$b = $this->is_points($b) ? $b : 0;
|
||||
|
||||
switch ($operator)
|
||||
{
|
||||
# Multiply
|
||||
case 'x':
|
||||
case '*';
|
||||
$a *= $b;
|
||||
break;
|
||||
|
||||
# Divide
|
||||
case '÷':
|
||||
case '/':
|
||||
$a = $b ? $a / $b : 0;
|
||||
break;
|
||||
|
||||
# Subtract
|
||||
case '-':
|
||||
$a -= $b;
|
||||
break;
|
||||
|
||||
# Add
|
||||
case '+':
|
||||
default:
|
||||
$a += $b;
|
||||
break;
|
||||
}
|
||||
|
||||
return (double) $a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a points value is numeric.
|
||||
*
|
||||
* @param mixed $points The points value
|
||||
* @return bool Whether the value is numeric or not
|
||||
* @access public
|
||||
*/
|
||||
public function is_points($points)
|
||||
{
|
||||
return is_numeric($points);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a user's points are within the Min. and Max. allowed points.
|
||||
*
|
||||
* @param double $points The new total
|
||||
* @return double The new total that is within the boundaries
|
||||
* @access public
|
||||
*/
|
||||
public function boundaries($points)
|
||||
{
|
||||
// Check if the new total is lower than the minimum value, has to be '' as 0 is a valid minimum value.
|
||||
if (($min = $this->config['aps_points_min']) !== '')
|
||||
{
|
||||
$min = (double) $min;
|
||||
$points = $points < $min ? $min : $points;
|
||||
}
|
||||
|
||||
// Check if the new total is higher than the maximum value, has to be '' as 0 is a valid maximum value.
|
||||
if (($max = $this->config['aps_points_max']) !== '')
|
||||
{
|
||||
$max = (double) $max;
|
||||
$points = $points > $max ? $max : $points;
|
||||
}
|
||||
|
||||
return $points;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a default no_avatar HTML string.
|
||||
*
|
||||
* @return string HTML formatted no_avatar string
|
||||
* @access public
|
||||
*/
|
||||
public function get_no_avatar()
|
||||
{
|
||||
// If DAE is enabled we do not have to set up a default avatar
|
||||
if ($this->is_dae_enabled())
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
$board_url = generate_board_url() . '/';
|
||||
$corrected_path = $this->path_helper->get_web_root_path();
|
||||
$web_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? $board_url : $corrected_path;
|
||||
$theme_path = "{$web_path}styles/" . rawurlencode($this->user->style['style_path']) . '/theme';
|
||||
|
||||
$no_avatar = '<img class="avatar" src="' . $theme_path . '/images/no_avatar.gif" alt="' . $this->language->lang('USER_AVATAR') . '" />';
|
||||
|
||||
return $no_avatar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether Default Avatar Extended (DAE) is enabled or not.
|
||||
*
|
||||
* @return bool Whether DAE is enabled or not.
|
||||
* @access public
|
||||
*/
|
||||
public function is_dae_enabled()
|
||||
{
|
||||
return (bool) ($this->is_dae_enabled && $this->config['threedi_default_avatar_extended']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get link locations.
|
||||
*
|
||||
* @param string $key The config key
|
||||
* @return array The link locations data
|
||||
*/
|
||||
public function get_link_locations($key = 'aps_link_locations')
|
||||
{
|
||||
$links = [];
|
||||
|
||||
foreach($this->constants['locations'] as $location => $flag)
|
||||
{
|
||||
$links[$location] = (bool) ((int) $this->config[$key] & $flag);
|
||||
}
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set link locations
|
||||
*
|
||||
* @param array $locations The link locations data
|
||||
* @param string $key The config key
|
||||
* @return void
|
||||
*/
|
||||
public function set_link_locations(array $locations, $key = 'aps_link_locations')
|
||||
{
|
||||
$flags = 0;
|
||||
|
||||
foreach ($locations as $location => $status)
|
||||
{
|
||||
$flags += $status ? (int) $this->constants['locations'][$location] : 0;
|
||||
}
|
||||
|
||||
$this->config->set($key, (int) $flags);
|
||||
}
|
||||
}
|
||||
106
ext/phpbbstudio/aps/core/language.php
Normal file
106
ext/phpbbstudio/aps/core/language.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* phpBB Studio - Advanced Points System. An extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019, phpBB Studio, https://www.phpbbstudio.com
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\aps\core;
|
||||
|
||||
/**
|
||||
* phpBB Studio - Advanced Points System language functions.
|
||||
*/
|
||||
class language
|
||||
{
|
||||
/** @var \phpbb\config\config */
|
||||
protected $config;
|
||||
|
||||
/** @var \phpbb\language\language */
|
||||
protected $language;
|
||||
|
||||
/** @var \phpbb\extension\manager */
|
||||
protected $manager;
|
||||
|
||||
/** @var \phpbb\user */
|
||||
protected $user;
|
||||
|
||||
/** @var string php file extension */
|
||||
protected $php_ext;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \phpbb\config\config $config Configuration object
|
||||
* @param \phpbb\language\language $language Language object
|
||||
* @param \phpbb\extension\manager $manager Extension manager object
|
||||
* @param \phpbb\user $user User object
|
||||
* @param string $php_ext php file extension
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function __construct(
|
||||
\phpbb\config\config $config,
|
||||
\phpbb\language\language $language,
|
||||
\phpbb\extension\manager $manager,
|
||||
\phpbb\user $user,
|
||||
$php_ext
|
||||
)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->language = $language;
|
||||
$this->manager = $manager;
|
||||
$this->user = $user;
|
||||
|
||||
$this->php_ext = $php_ext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all language files used for the Advanced Points System.
|
||||
*
|
||||
* @see \p_master::add_mod_info()
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function load()
|
||||
{
|
||||
$finder = $this->manager->get_finder();
|
||||
|
||||
$finder->prefix('phpbbstudio_aps_')
|
||||
->suffix('.' . $this->php_ext);
|
||||
|
||||
// We grab the language files from the default, English and user's language.
|
||||
// So we can fall back to the other files like we do when using add_lang()
|
||||
$default_lang_files = $english_lang_files = $user_lang_files = [];
|
||||
|
||||
// Search for board default language if it's not the user language
|
||||
if ($this->config['default_lang'] != $this->user->lang_name)
|
||||
{
|
||||
$default_lang_files = $finder
|
||||
->extension_directory('/language/' . basename($this->config['default_lang']))
|
||||
->find();
|
||||
}
|
||||
|
||||
// Search for english, if its not the default or user language
|
||||
if ($this->config['default_lang'] != 'en' && $this->user->lang_name != 'en')
|
||||
{
|
||||
$english_lang_files = $finder
|
||||
->extension_directory('/language/en')
|
||||
->find();
|
||||
}
|
||||
|
||||
// Find files in the user's language
|
||||
$user_lang_files = $finder
|
||||
->extension_directory('/language/' . $this->user->lang_name)
|
||||
->find();
|
||||
|
||||
$lang_files = array_merge($english_lang_files, $default_lang_files, $user_lang_files);
|
||||
foreach ($lang_files as $lang_file => $ext_name)
|
||||
{
|
||||
$this->language->add_lang($lang_file, $ext_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
560
ext/phpbbstudio/aps/core/log.php
Normal file
560
ext/phpbbstudio/aps/core/log.php
Normal file
@@ -0,0 +1,560 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* phpBB Studio - Advanced Points System. An extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019, phpBB Studio, https://www.phpbbstudio.com
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\aps\core;
|
||||
|
||||
/**
|
||||
* phpBB Studio - Advanced Points System log functions.
|
||||
*/
|
||||
class log
|
||||
{
|
||||
/** @var \phpbb\auth\auth */
|
||||
protected $auth;
|
||||
|
||||
/** @var \phpbb\config\config */
|
||||
protected $config;
|
||||
|
||||
/** @var \phpbb\db\driver\driver_interface */
|
||||
protected $db;
|
||||
|
||||
/** @var \phpbbstudio\aps\core\functions */
|
||||
protected $functions;
|
||||
|
||||
/** @var \phpbb\language\language */
|
||||
protected $language;
|
||||
|
||||
/** @var \phpbbstudio\aps\core\language */
|
||||
protected $lang_aps;
|
||||
|
||||
/** @var \phpbb\user */
|
||||
protected $user;
|
||||
|
||||
/** @var string APS Logs table */
|
||||
protected $table;
|
||||
|
||||
/** @var string phpBB root path */
|
||||
protected $root_path;
|
||||
|
||||
/** @var string phpBB admin path */
|
||||
protected $admin_path;
|
||||
|
||||
/** @var string php file extension */
|
||||
protected $php_ext;
|
||||
|
||||
/** @var bool Whether called from the ACP or not */
|
||||
protected $is_in_admin;
|
||||
|
||||
/** @var int Total log entries for a get query */
|
||||
protected $entries_count;
|
||||
|
||||
/** @var int Last page offset for pagination */
|
||||
protected $last_page_offset;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \phpbb\auth\auth $auth Authentication object
|
||||
* @param \phpbb\config\config $config Configuration object
|
||||
* @param \phpbb\db\driver\driver_interface $db Database object
|
||||
* @param \phpbbstudio\aps\core\functions $functions APS Core functions
|
||||
* @param \phpbb\language\language $language phpBB Language object
|
||||
* @param \phpbbstudio\aps\core\language $lang_aps APS Language object
|
||||
* @param \phpbb\user $user User object
|
||||
* @param string $table APS Logs table
|
||||
* @param string $root_path phpBB root path
|
||||
* @param string $admin_path phpBB relative admin path
|
||||
* @param string $php_ext php File extension
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function __construct(
|
||||
\phpbb\auth\auth $auth,
|
||||
\phpbb\config\config $config,
|
||||
\phpbb\db\driver\driver_interface $db,
|
||||
functions $functions,
|
||||
\phpbb\language\language $language,
|
||||
language $lang_aps,
|
||||
\phpbb\user $user,
|
||||
$table,
|
||||
$root_path,
|
||||
$admin_path,
|
||||
$php_ext
|
||||
)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
$this->config = $config;
|
||||
$this->db = $db;
|
||||
$this->functions = $functions;
|
||||
$this->language = $language;
|
||||
$this->lang_aps = $lang_aps;
|
||||
$this->user = $user;
|
||||
$this->table = $table;
|
||||
|
||||
$this->root_path = $root_path;
|
||||
$this->admin_path = $root_path . $admin_path;
|
||||
$this->php_ext = $php_ext;
|
||||
|
||||
$this->set_is_admin((defined('ADMIN_START') && ADMIN_START) || (defined('IN_ADMIN') && IN_ADMIN));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set is_in_admin in order to return administrative user profile links in get().
|
||||
*
|
||||
* @param bool $is_in_admin Called from within the acp?
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function set_is_admin($is_in_admin)
|
||||
{
|
||||
$this->is_in_admin = (bool) $is_in_admin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the is_in_admin option.
|
||||
*
|
||||
* @return bool Called from within the acp?
|
||||
* @access public
|
||||
*/
|
||||
public function get_is_admin()
|
||||
{
|
||||
return $this->is_in_admin;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function get_log_count()
|
||||
{
|
||||
return ($this->entries_count) ? $this->entries_count : 0;
|
||||
}
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function get_valid_offset()
|
||||
{
|
||||
return ($this->last_page_offset) ? $this->last_page_offset : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the language files used by the Advanced Points System.
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function load_lang()
|
||||
{
|
||||
$this->lang_aps->load();
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a points action.
|
||||
*
|
||||
* @param array $data The array to log
|
||||
* @param int $time The time to log
|
||||
* @return bool|int False on error, new log entry identifier otherwise
|
||||
* @access public
|
||||
*/
|
||||
public function add(array $data, $time = 0)
|
||||
{
|
||||
// We need to have at least the log action, points gained/lost and either the old or new user points.
|
||||
if ($this->check_row($data))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$row = $this->prepare_row($data, $time);
|
||||
|
||||
$sql = 'INSERT INTO ' . $this->table . ' ' . $this->db->sql_build_array('UPDATE', $row);
|
||||
$this->db->sql_query($sql);
|
||||
|
||||
return $this->db->sql_nextid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Log multiple points actions at once.
|
||||
*
|
||||
* @param array $data The arrays to log
|
||||
* @param int $time The time to log
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
public function add_multi(array $data, $time = 0)
|
||||
{
|
||||
$logs = [];
|
||||
|
||||
foreach ($data as $row)
|
||||
{
|
||||
// We need to have at least the log action, points gained/lost and either the old or new user points.
|
||||
if ($this->check_row($row))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$logs[] = $this->prepare_row($row, $time);
|
||||
}
|
||||
|
||||
$this->db->sql_multi_insert($this->table, $logs);
|
||||
|
||||
return (bool) !empty($logs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a log row has the minimal required information.
|
||||
*
|
||||
* @param array $row The log row the check
|
||||
* @return bool Whether this log row is eligible or not
|
||||
* @access public
|
||||
*/
|
||||
public function check_row(array $row)
|
||||
{
|
||||
return (bool) (empty($row['action']) || in_array($row['points_sum'], [0, 0.0, 0.00]) || (!isset($row['points_old']) && !isset($row['points_new'])));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare a log row for inserting in the database table.
|
||||
*
|
||||
* @param array $row The log row to prepare
|
||||
* @param int $time The time to log
|
||||
* @return array The prepared log row
|
||||
* @access public
|
||||
*/
|
||||
public function prepare_row(array $row, $time)
|
||||
{
|
||||
return [
|
||||
'log_action' => $row['action'],
|
||||
'log_actions' => !empty($row['actions']) ? serialize($row['actions']) : '',
|
||||
'log_time' => $time ? $time : time(),
|
||||
'log_approved' => isset($row['approved']) ? (bool) $row['approved'] : true,
|
||||
'forum_id' => !empty($row['forum_id']) ? (int) $row['forum_id'] : 0,
|
||||
'topic_id' => !empty($row['topic_id']) ? (int) $row['topic_id'] : 0,
|
||||
'post_id' => !empty($row['post_id']) ? (int) $row['post_id'] : 0,
|
||||
'user_id' => !empty($row['user_id']) ? (int) $row['user_id'] : (int) $this->user->data['user_id'],
|
||||
'reportee_id' => !empty($row['reportee_id']) ? (int) $row['reportee_id'] : (int) $this->user->data['user_id'],
|
||||
'reportee_ip' => !empty($row['reportee_ip']) ? (string) $row['reportee_ip'] : (string) $this->user->ip,
|
||||
'points_old' => isset($row['points_old']) ? (double) $row['points_old'] : $this->functions->equate_points($row['points_new'], $row['points_sum'], '-'),
|
||||
'points_sum' => (double) $row['points_sum'],
|
||||
'points_new' => isset($row['points_new']) ? (double) $this->functions->boundaries($row['points_new']) : $this->functions->boundaries($this->functions->equate_points($row['points_old'], $row['points_sum'], '+')),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a points action from the logs depending on the conditions.
|
||||
*
|
||||
* @param array $conditions The delete conditions
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function delete(array $conditions)
|
||||
{
|
||||
// Need an "empty" sql where to begin with
|
||||
$sql_where = '';
|
||||
|
||||
if (isset($conditions['keywords']))
|
||||
{
|
||||
$sql_where .= $this->generate_sql_keyword($conditions['keywords'], '');
|
||||
unset($conditions['keywords']);
|
||||
}
|
||||
|
||||
foreach ($conditions as $field => $field_value)
|
||||
{
|
||||
$sql_where .= ' AND ';
|
||||
|
||||
if (is_array($field_value) && count($field_value) == 2 && !is_array($field_value[1]))
|
||||
{
|
||||
$sql_where .= $field . ' ' . $field_value[0] . ' ' . $field_value[1];
|
||||
}
|
||||
else if (is_array($field_value) && isset($field_value['IN']) && is_array($field_value['IN']))
|
||||
{
|
||||
$sql_where .= $this->db->sql_in_set($field, $field_value['IN']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sql_where .= $field . ' = ' . $field_value;
|
||||
}
|
||||
}
|
||||
|
||||
$sql = 'DELETE FROM ' . $this->table . ' WHERE log_id <> 0 ' . $sql_where;
|
||||
$this->db->sql_query($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the logged point values for a given user id and post ids combination.
|
||||
*
|
||||
* @param int $user_id The user identifier
|
||||
* @param array $post_ids The post identifiers
|
||||
* @param bool $approved Whether the logged entries are set to approved or not
|
||||
* @return array The array of point values indexed per post identifier
|
||||
* @access public
|
||||
*/
|
||||
public function get_values($user_id, array $post_ids, $approved = true)
|
||||
{
|
||||
$points = [];
|
||||
|
||||
$sql = 'SELECT points_sum, post_id
|
||||
FROM ' . $this->table . '
|
||||
WHERE user_id = ' . (int) $user_id . '
|
||||
AND log_approved = ' . (int) $approved . '
|
||||
AND ' . $this->db->sql_in_set('post_id', $post_ids, false, true);
|
||||
$result = $this->db->sql_query($sql);
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
$points[(int) $row['post_id']] = $row['points_sum'];
|
||||
}
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
return $points;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets logged entries to approved for a given user id and post ids combination.
|
||||
*
|
||||
* @param int $user_id The user identifier
|
||||
* @param array $post_ids The post identifiers
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function approve($user_id, array $post_ids)
|
||||
{
|
||||
$sql = 'UPDATE ' . $this->table . '
|
||||
SET log_approved = 1
|
||||
WHERE log_approved = 0
|
||||
AND user_id = ' . (int) $user_id . '
|
||||
AND ' . $this->db->sql_in_set('post_id', $post_ids, false, true);
|
||||
$this->db->sql_query($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get logged point actions for a certain combination.
|
||||
*
|
||||
* @param bool $count Whether we should count the total amount of logged entries for this combination.
|
||||
* @param int $limit The amount of rows to return
|
||||
* @param int $offset The amount of rows from the start to return
|
||||
* @param int|string $forum_id The forum identifier (set to '' as 0 is a valid choice)
|
||||
* @param int|array $topic_id The topic identifier
|
||||
* @param int $post_id The post identifier
|
||||
* @param int $user_id The user identifier
|
||||
* @param int $reportee_id The reportee identifier (from user)
|
||||
* @param int $time The logged time
|
||||
* @param string $sort_by The ORDER BY clause
|
||||
* @param string $keywords The keywords to search for
|
||||
* @return array The found logged point actions for this combination
|
||||
* @access public
|
||||
*/
|
||||
public function get($count = true, $limit = 0, $offset = 0, $forum_id = '', $topic_id = 0, $post_id = 0, $user_id = 0, $reportee_id = 0, $time = 0, $sort_by = 'l.log_time DESC', $keywords = '')
|
||||
{
|
||||
$this->entries_count = 0;
|
||||
$this->last_page_offset = $offset;
|
||||
|
||||
$limit = !empty($limit) ? $limit : $this->config['aps_actions_per_page'];
|
||||
|
||||
$profile_url = ($this->get_is_admin() && $this->admin_path) ? append_sid("{$this->admin_path}index.{$this->php_ext}", 'i=users&mode=overview') : append_sid("{$this->root_path}memberlist.{$this->php_ext}", 'mode=viewprofile');
|
||||
|
||||
$sql_where = 'l.user_id = u.user_id';
|
||||
$sql_where .= $time ? ' AND l.log_time >= ' . (int) $time : '';
|
||||
$sql_where .= $forum_id !== '' ? ' AND l.forum_id = ' . (int) $forum_id : '';
|
||||
$sql_where .= $topic_id ? (is_array($topic_id) ? ' AND ' . $this->db->sql_in_set('l.topic_id', $topic_id) : ' AND l.topic_id = ' . (int) $topic_id) : '';
|
||||
$sql_where .= $post_id ? ' AND l.post_id = ' . (int) $post_id : '';
|
||||
$sql_where .= $user_id ? ' AND l.user_id = ' . (int) $user_id : '';
|
||||
$sql_where .= $reportee_id ? ' AND l.reportee_id = ' . (int) $reportee_id : '';
|
||||
$sql_where .= $this->get_is_admin() ? '' : ' AND l.log_approved = 1';
|
||||
|
||||
$sql_keywords = '';
|
||||
if (!empty($keywords))
|
||||
{
|
||||
// Get the SQL condition for our keywords
|
||||
$sql_keywords = $this->generate_sql_keyword($keywords);
|
||||
}
|
||||
|
||||
$sql_ary = [
|
||||
'SELECT' => 'l.*,
|
||||
u.user_id, u.username, u.user_colour,
|
||||
r.user_id as reportee_id, r.username as reportee_name, r.user_colour as reportee_colour,
|
||||
f.forum_name, t.topic_title, p.post_subject',
|
||||
'FROM' => [
|
||||
$this->table => 'l',
|
||||
USERS_TABLE => 'u',
|
||||
],
|
||||
'LEFT_JOIN' => [
|
||||
[
|
||||
'FROM' => [USERS_TABLE => 'r'],
|
||||
'ON' => 'l.reportee_id = r.user_id',
|
||||
],
|
||||
[
|
||||
'FROM' => [FORUMS_TABLE => 'f'],
|
||||
'ON' => 'l.forum_id = f.forum_id',
|
||||
],
|
||||
[
|
||||
'FROM' => [TOPICS_TABLE => 't'],
|
||||
'ON' => 'l.topic_id = t.topic_id',
|
||||
],
|
||||
[
|
||||
'FROM' => [POSTS_TABLE => 'p'],
|
||||
'ON' => 'l.post_id = p.post_id AND t.topic_first_post_id != p.post_id',
|
||||
],
|
||||
],
|
||||
'WHERE' => $sql_where . $sql_keywords,
|
||||
'ORDER_BY' => $sort_by,
|
||||
];
|
||||
|
||||
// Provide moderator anonymity, exclude any "_MOD_" actions
|
||||
if (!$this->auth->acl_get('u_aps_view_mod'))
|
||||
{
|
||||
$sql_ary['WHERE'] .= ' AND log_action ' . $this->db->sql_not_like_expression($this->db->get_any_char() . '_MOD_' . $this->db->get_any_char());
|
||||
}
|
||||
|
||||
if ($count)
|
||||
{
|
||||
$count_array = $sql_ary;
|
||||
|
||||
$count_array['SELECT'] = 'COUNT(log_id) as count';
|
||||
unset($count_array['LEFT_JOIN'], $count_array['ORDER_BY']);
|
||||
|
||||
$sql = $this->db->sql_build_query('SELECT', $count_array);
|
||||
$result = $this->db->sql_query($sql);
|
||||
$this->entries_count = (int) $this->db->sql_fetchfield('count');
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
if ($this->entries_count === 0)
|
||||
{
|
||||
$this->last_page_offset = 0;
|
||||
return [];
|
||||
}
|
||||
|
||||
while ($this->last_page_offset >= $this->entries_count)
|
||||
{
|
||||
$this->last_page_offset = max(0, $this->last_page_offset - $limit);
|
||||
}
|
||||
}
|
||||
|
||||
$logs = [];
|
||||
|
||||
$sql = $this->db->sql_build_query('SELECT', $sql_ary);
|
||||
$result = $this->db->sql_query_limit($sql, $limit, $this->last_page_offset);
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
$s_authed = (bool) ($row['forum_id'] && $this->auth->acl_get('f_read', (int) $row['forum_id']));
|
||||
|
||||
// append_sid() will ignore params with a NULL value
|
||||
$forum_params = ['f' => ($row['forum_id'] ? (int) $row['forum_id'] : null)];
|
||||
$topic_params = ['t' => ($row['topic_id'] ? (int) $row['topic_id'] : null)];
|
||||
|
||||
$s_points = ($this->auth->acl_get('a_forum') && $this->auth->acl_get('a_aps_points'));
|
||||
$points_forum = append_sid("{$this->admin_path}index.{$this->php_ext}", ['i' => 'acp_forums', 'mode' => 'manage', 'action' => 'edit', 'f' => (int) $row['forum_id'], '#' => 'aps_points']);
|
||||
$points_global = append_sid("{$this->admin_path}index.{$this->php_ext}", ['i' => '-phpbbstudio-aps-acp-main_module', 'mode' => 'points']);
|
||||
|
||||
$logs[] = [
|
||||
'id' => (int) $row['log_id'],
|
||||
|
||||
'user' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour'], false, $profile_url),
|
||||
'user_id' => (int) $row['user_id'],
|
||||
'reportee' => $row['reportee_id'] != ANONYMOUS ? get_username_string('full', $row['reportee_id'], $row['reportee_name'], $row['reportee_colour'], false, $profile_url) : '',
|
||||
'reportee_id' => (int) $row['reportee_id'],
|
||||
's_self' => (bool) ((int) $row['user_id'] === (int) $row['reportee_id']),
|
||||
|
||||
'ip' => (string) $row['reportee_ip'],
|
||||
'time' => (int) $row['log_time'],
|
||||
'action' => (string) $row['log_action'],
|
||||
'actions' => unserialize($row['log_actions']),
|
||||
|
||||
'approved' => (bool) $row['log_approved'],
|
||||
|
||||
'forum_id' => (int) $row['forum_id'],
|
||||
'forum_name' => (string) $row['forum_name'],
|
||||
'u_forum' => ($row['forum_id'] && $s_authed) ? append_sid("{$this->root_path}viewforum.{$this->php_ext}", $forum_params) : '',
|
||||
|
||||
'topic_id' => (int) $row['topic_id'],
|
||||
'topic_title' => (string) $row['topic_title'],
|
||||
'u_topic' => ($row['topic_id'] && $s_authed) ? append_sid("{$this->root_path}viewtopic.{$this->php_ext}", array_merge($forum_params, $topic_params)) : '',
|
||||
|
||||
'post_id' => (int) $row['post_id'],
|
||||
'post_subject' => (string) $row['post_subject'],
|
||||
'u_post' => ($row['post_id'] && $s_authed) ? append_sid("{$this->root_path}viewtopic.{$this->php_ext}", array_merge($forum_params, $topic_params, ['p' => (int) $row['post_id'], '#' => 'p' . (int) $row['post_id']])) : '',
|
||||
|
||||
'points_old' => $row['points_old'] !== '0.00' ? (double) $row['points_old'] : $this->functions->equate_points((double) $row['points_new'], $row['points_sum'], '-'),
|
||||
'points_sum' => (double) $row['points_sum'],
|
||||
'points_new' => $row['points_new'] !== '0.00' ? (double) $row['points_new'] : $this->functions->equate_points((double) $row['points_old'], $row['points_sum'], '+'),
|
||||
'u_points' => $s_points ? ($row['forum_id'] ? $points_forum : $points_global) : '',
|
||||
];
|
||||
}
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
return $logs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a sql condition for the specified keywords
|
||||
*
|
||||
* @param string $keywords The keywords the user specified to search for
|
||||
* @param string $table_alias The alias of the logs' table ('l.' by default)
|
||||
* @param string $statement_operator The operator used to prefix the statement ('AND' by default)
|
||||
* @return string Returns the SQL condition searching for the keywords
|
||||
* @access protected
|
||||
*/
|
||||
protected function generate_sql_keyword($keywords, $table_alias = 'l.', $statement_operator = 'AND')
|
||||
{
|
||||
// Use no preg_quote for $keywords because this would lead to sole
|
||||
// backslashes being added. We also use an OR connection here for
|
||||
// spaces and the | string. Currently, regex is not supported for
|
||||
// searching (but may come later).
|
||||
$keywords = preg_split('#[\s|]+#u', utf8_strtolower($keywords), 0, PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
$sql_keywords = '';
|
||||
|
||||
if (!empty($keywords))
|
||||
{
|
||||
$keywords_pattern = [];
|
||||
|
||||
// Build pattern and keywords...
|
||||
for ($i = 0, $num_keywords = count($keywords); $i < $num_keywords; $i++)
|
||||
{
|
||||
$keywords_pattern[] = preg_quote($keywords[$i], '#');
|
||||
}
|
||||
|
||||
$keywords_pattern = '#' . implode('|', $keywords_pattern) . '#ui';
|
||||
|
||||
$operations = [];
|
||||
|
||||
foreach ($this->language->get_lang_array() as $key => $value)
|
||||
{
|
||||
if (substr($key, 0, 4) == 'APS_')
|
||||
{
|
||||
if (is_array($value))
|
||||
{
|
||||
foreach ($value as $plural_value)
|
||||
{
|
||||
if (preg_match($keywords_pattern, $plural_value))
|
||||
{
|
||||
$operations[] = $key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (preg_match($keywords_pattern, $value))
|
||||
{
|
||||
$operations[] = $key;
|
||||
}
|
||||
else if (preg_match($keywords_pattern, $key))
|
||||
{
|
||||
$operations[] = $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($operations))
|
||||
{
|
||||
$sql_keywords = ' ' . $statement_operator . ' (';
|
||||
$sql_keywords .= $this->db->sql_in_set($table_alias . 'log_action', $operations);
|
||||
$sql_keywords .= ')';
|
||||
}
|
||||
}
|
||||
|
||||
return $sql_keywords;
|
||||
}
|
||||
}
|
||||
104
ext/phpbbstudio/aps/core/template.php
Normal file
104
ext/phpbbstudio/aps/core/template.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* phpBB Studio - Advanced Points System. An extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019, phpBB Studio, https://www.phpbbstudio.com
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\aps\core;
|
||||
|
||||
/**
|
||||
* phpBB Studio - Advanced Points System twig extension.
|
||||
*/
|
||||
class template extends \Twig_Extension
|
||||
{
|
||||
/** @var \phpbbstudio\aps\core\functions */
|
||||
protected $functions;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \phpbbstudio\aps\core\functions $functions APS Core functions
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function __construct(functions $functions)
|
||||
{
|
||||
$this->functions = $functions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of this extension
|
||||
*
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'phpbbstudio_aps';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of global functions to add to the existing list.
|
||||
*
|
||||
* @return array An array of global functions
|
||||
* @access public
|
||||
*/
|
||||
public function getFunctions()
|
||||
{
|
||||
return [
|
||||
// Template functions prefixed with "aps_" come here
|
||||
new \Twig_SimpleFunction('aps_*', [$this, 'aps_handle']),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the called template function.
|
||||
*
|
||||
* @param string $function The APS Core function name
|
||||
* @param mixed $points First parameter from the called template function
|
||||
* @param bool $boolean Second parameter from the called template function
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
public function aps_handle($function, $points = 0, $boolean = true)
|
||||
{
|
||||
switch ($function)
|
||||
{
|
||||
case 'auth':
|
||||
return $this->functions->get_auth($points, $boolean);
|
||||
break;
|
||||
|
||||
case 'config':
|
||||
return $this->functions->get_config($points);
|
||||
break;
|
||||
|
||||
case 'display':
|
||||
return $this->functions->display_points($points, $boolean);
|
||||
break;
|
||||
|
||||
case 'format':
|
||||
return $this->functions->format_points($points);
|
||||
break;
|
||||
|
||||
case 'icon':
|
||||
return $this->functions->get_icon($points);
|
||||
break;
|
||||
|
||||
case 'name';
|
||||
return $this->functions->get_name();
|
||||
break;
|
||||
|
||||
case 'step':
|
||||
return $this->functions->get_step();
|
||||
break;
|
||||
|
||||
default:
|
||||
return '';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user