On repart de zéro...

This commit is contained in:
Gauvain Boiché
2020-04-06 16:19:02 +02:00
parent 5740cf635a
commit e1f9171201
675 changed files with 0 additions and 69676 deletions

View File

@@ -1,47 +0,0 @@
<?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\acp;
/**
* phpBB Studio - Advanced Points System ACP module info.
*/
class main_info
{
public function module()
{
return [
'filename' => '\phpbbstudio\aps\acp\main_module',
'title' => 'ACP_APS_POINTS',
'modes' => [
'settings' => [
'title' => 'ACP_APS_MODE_SETTINGS',
'auth' => 'ext_phpbbstudio/aps && acl_a_aps_settings',
'cat' => ['ACP_APS_POINTS']
],
'display' => [
'title' => 'ACP_APS_MODE_DISPLAY',
'auth' => 'ext_phpbbstudio/aps && acl_a_aps_display',
'cat' => ['ACP_APS_POINTS'],
],
'points' => [
'title' => 'ACP_APS_MODE_POINTS',
'auth' => 'ext_phpbbstudio/aps && (acl_a_aps_points || acl_a_aps_reasons)',
'cat' => ['ACP_APS_POINTS'],
],
'logs' => [
'title' => 'ACP_APS_MODE_LOGS',
'auth' => 'ext_phpbbstudio/aps && acl_a_aps_logs',
'cat' => ['ACP_APS_POINTS'],
]
],
];
}
}

View File

@@ -1,192 +0,0 @@
<?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\acp;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* phpBB Studio - Advanced Points System ACP module.
*/
class main_module
{
/** @var string ACP Page title */
public $page_title;
/** @var string ACP Page template */
public $tpl_name;
/** @var string Custom form action */
public $u_action;
/** @var ContainerInterface */
protected $container;
/** @var \phpbb\language\language */
protected $language;
public function main($id, $mode)
{
/** @var ContainerInterface $phpbb_container */
global $phpbb_container;
$this->container = $phpbb_container;
$this->language = $this->container->get('language');
/** @var \phpbbstudio\aps\controller\acp_controller $controller */
$controller = $this->container->get('phpbbstudio.aps.controller.acp');
/** @var \phpbbstudio\aps\core\functions $functions */
$functions = $this->container->get('phpbbstudio.aps.functions');
// Set the page title and template
$this->tpl_name = 'aps_' . $mode;
$this->page_title = $this->language->lang('ACP_APS_POINTS') . ' &bull; ' . $this->language->lang('ACP_APS_MODE_' . utf8_strtoupper($mode), $functions->get_name());
// Make the custom form action available in the controller and handle the mode
$controller->set_page_url($this->u_action)->{$mode}();
}
/**
* Build configuration template for custom points actions.
*
* @param string $action The custom points action
* @param bool $ajax The AJAX request indicator
* @return string The configuration template
* @access public
*/
public function set_action($action, $ajax = true)
{
return '<label><a class="aps-button-green" href="' . $this->u_action . '&action='. $action . ($ajax ? '" data-ajax="true' : '') . '">' . $this->language->lang('RUN') . '</a></label>';
}
/**
* Build configuration template for the points separator.
*
* @param string $value The config value
* @return string The HTML formatted select options
* @access public
*/
public function build_separator_select($value)
{
$space = htmlspecialchars('&nbsp;');
$narrow = htmlspecialchars('&#8239;');
$separators = [
',' => 'ACP_APS_SEPARATOR_COMMA',
'.' => 'ACP_APS_SEPARATOR_PERIOD',
'-' => 'ACP_APS_SEPARATOR_DASH',
'_' => 'ACP_APS_SEPARATOR_UNDERSCORE',
$space => 'ACP_APS_SEPARATOR_SPACE',
$narrow => 'ACP_APS_SEPARATOR_SPACE_NARROW',
];
return build_select($separators, $value);
}
/**
* Build configuration template for the points icon image.
*
* @param string $value The config value
* @param string $key The config key
* @return string The configuration template
* @access public
*/
public function build_icon_image_select($value, $key = '')
{
$directory = $this->container->getParameter('core.root_path') . '/images';
$files = array_diff(scandir($directory), ['.', '..']);
$images = array_filter($files, function($file) use ($directory)
{
$file = "{$directory}/{$file}";
return is_file($file) && filesize($file) && preg_match('#\.gif|jpg|jpeg|png|svg$#i', $file);
});
$select = '<select id="' . $key . '" name="config[' . $key . ']">';
$select .= '<option value="">' . $this->language->lang('ACP_APS_POINTS_ICON_IMG_NO') . '</option>';
foreach ($images as $image)
{
$selected = $value === $image;
$select .= '<option value="' . $image . ($selected ? '" selected="selected' : '') . '">' . $image . '</option>';
}
$select .= '</select>';
return $select;
}
/**
* Build configuration template for the points icon position.
*
* @param string $value The config value
* @param string $key The config key
* @return string The configuration template
* @access public
*/
public function build_position_radio($value, $key = '')
{
return $this->build_radio($value, $key, [
0 => 'ACP_APS_POINTS_ICON_POSITION_LEFT',
1 => 'ACP_APS_POINTS_ICON_POSITION_RIGHT',
]);
}
/**
* Build configuration template for the points decimals.
*
* @param string $value The config value
* @return string The configuration template
* @access public
*/
public function build_decimal_select($value)
{
$options = '';
for ($i = 0; $i <= 2; $i++)
{
$options .= '<option value="' . $i . ((int) $value === $i ? '" selected' : '"') . '>' . $i . '</option>';
}
return $options;
}
public function build_ignore_criteria_radio($value, $key = '')
{
return $this->build_radio($value, $key, array_map(function($constant)
{
return 'ACP_APS_IGNORE_' . utf8_strtoupper($constant);
}, array_flip($this->container->getParameter('phpbbstudio.aps.constants')['ignore'])));
}
protected function build_radio($value, $key, $options)
{
$html = '';
$s_id = false;
foreach ($options as $val => $title)
{
$check = $value === $val ? ' checked' : '';
$id = $s_id ? ' id="' . $key . '"' : '';
$html .= '<label>';
$html .= '<input class="radio aps-radio"' . $id . ' name="config[' . $key . ']" type="radio" value="' . $val . '"' . $check . '>';
$html .= '<span class="aps-button-blue">' . $this->language->lang($title) . '</span>';
$html .= '</label>';
$s_id = true;
}
return $html;
}
}

View File

@@ -1,593 +0,0 @@
<?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\actions;
/**
* phpBB Studio - Advanced Points System points actions manager.
*/
class manager
{
/** @var \phpbb\di\service_collection Array of action types from the service collection */
protected $actions;
/** @var \phpbbstudio\aps\points\distributor */
protected $distributor;
/** @var \phpbbstudio\aps\core\functions */
protected $functions;
/** @var \phpbb\language\language */
protected $lang;
/** @var \phpbb\log\log */
protected $log;
/** @var \phpbbstudio\aps\points\valuator */
protected $valuator;
/** @var \phpbb\user */
protected $user;
/** @var array Array of points fields for the triggered action types */
protected $fields;
/** @var array Array of action types that are triggered */
protected $types;
/** @var array Array of users that can receive points for the triggered action */
protected $users;
/** @var array Array of point values required for the triggered action types */
protected $values;
/**
* Constructor.
*
* @param \phpbb\di\service_collection $actions Array of action types from the service collection
* @param \phpbbstudio\aps\points\distributor $distributor APS Distributor object
* @param \phpbbstudio\aps\core\functions $functions APS Core functions
* @param \phpbb\language\language $lang Language object
* @param \phpbb\log\log $log phpBB Log object
* @param \phpbbstudio\aps\points\valuator $valuator APS Valuator
* @param \phpbb\user $user User object
* @return void
* @access public
*/
public function __construct($actions, \phpbbstudio\aps\points\distributor $distributor, \phpbbstudio\aps\core\functions $functions, \phpbb\language\language $lang, \phpbb\log\log $log, \phpbbstudio\aps\points\valuator $valuator, \phpbb\user $user)
{
$this->distributor = $distributor;
$this->functions = $functions;
$this->lang = $lang;
$this->log = $log;
$this->valuator = $valuator;
$this->user = $user;
$this->actions = $actions;
}
/**
* Get the APS Distributor object.
*
* @return \phpbbstudio\aps\points\distributor
* @access public
*/
public function get_distributor()
{
return $this->distributor;
}
/**
* Get the APS Core functions.
*
* @return \phpbbstudio\aps\core\functions
* @access public
*/
public function get_functions()
{
return $this->functions;
}
/**
* Get the APS Valuator.
*
* @return \phpbbstudio\aps\points\valuator
* @access public
*/
public function get_valuator()
{
return $this->valuator;
}
/**
* Get the localised points name.
*
* @return string The localised points name
* @access public
*/
public function get_name()
{
return $this->functions->get_name();
}
/**
* Clean an array from a listener, turns an object into an array.
*
* @param mixed $event The event to clean
* @return array The event data
* @access public
*/
public function clean_event($event)
{
if ($event instanceof \phpbb\event\data)
{
return (array) $event->get_data();
}
else
{
return (array) $event;
}
}
/**
* Get all values for the provided key in an array.
*
* @param array $array The array to retrieve the values from
* @param string $key The keys of which to return the values
* @return array Array of unique integers
* @access public
*/
public function get_identifiers(array $array, $key)
{
return (array) array_map('intval', array_unique(array_filter(array_column($array, $key))));
}
/**
* Trigger a point action and calculate users' points.
*
* This is the "main" function for this extension.
*
* $action
* Calling this with an $action will trigger all action type which have their get_action() set to $action.
*
* $user_ids
* User identifiers are for the users who can receive points by this action, this user ($this->user) is
* automatically added to the list. If it was already present in the list, it's filtered out.
*
* $event
* An array with data that was available from the event (or any other occurrence) that triggered this action.
* For instance, phpBB's event object that is available in a listener. If indeed phpBB's event object is
* send it is automatically 'cleaned', which means the object is turned into an array.
*
* $forum_ids
* A list of forum identifiers for which the point values should be retrieved, as those values are necessary
* to require the amount of points for the users. If it's left empty it will assume that the triggered action
* is a "global" action, which means the forum_id = 0.
*
* @param string $action The action to trigger
* @param array|int $user_ids The user identifiers that can receive points
* @param array $event The event data
* @param array|int $forum_ids The forum identifiers (array or single value)
* @return void
* @access public
*/
public function trigger($action, $user_ids = [], $event = [], $forum_ids = 0)
{
// 1. Initialise arrays
$this->initialise_arrays();
// 2. Get action types
$this->get_types_and_fields($action);
// 3. Get values
$this->get_values($forum_ids);
// 4. Set users
$this->set_users($user_ids);
// 5. Calculate
$this->calculate($this->clean_event($event));
// 6. Distribute
$this->distribute();
}
/**
* Initialise the array fields used by this points manager.
*
* Has to be declared per each trigger() call, as otherwise types are carried over in chained calls.
*
* @return void
* @access protected
*/
protected function initialise_arrays()
{
// Array of points fields for the triggered action types
$this->fields = [0 => [], 1 => []];
// Array of action types that are triggered
$this->types = [];
// Array of users that can receive points for the triggered action
$this->users = [];
// Array of point values required for the triggered action types
$this->values = [];
}
/**
* Get all action types and their fields for the trigger action.
*
* $types
* While the $this->actions array holds ALL the registered action types,
* only a certain few are required. Only the required once are added to $this->types.
*
* $fields
* Each action type has an array of point value keys with a language string as value.
* Those keys are used for storing the points values set by the Administrator in the database.
* Therefore a list is generated with all the fields that need to be retrieved from the database.
*
* @param string $action The action that is triggered
* @return void
* @access protected
*/
protected function get_types_and_fields($action)
{
/** @var \phpbbstudio\aps\actions\type\action $type */
foreach ($this->actions as $name => $type)
{
// Only add action types that are listed under this $action
if ($type->get_action() === $action)
{
// Add this service to the action types
$this->types[$name] = $type;
// Get scope: 0 = local | 1 = global
$key = (int) $type->is_global();
// Get the type fields indexed by the scope
$this->fields[$key] = array_merge($type->get_fields(), $this->fields[$key]);
}
}
}
/**
* Get all point values required by the triggered action types from the database.
*
* $values
* Get all point values from the database that are in the $fields array and
* have their forum identifier set to one provided in the $forum_ids array.
* The values array will contain all point values indexed by the forum identifier,
* if the fields are global, the forum identifier is set to 0.
*
* @param array|int $forum_ids The forum identifiers
* @return void
* @access protected
*/
protected function get_values($forum_ids)
{
// Create array filled with integers
$forum_ids = is_array($forum_ids) ? array_map('intval', $forum_ids) : [(int) $forum_ids];
// Make sure there are only unique and non-empty forum identifiers
$forum_ids = array_unique($forum_ids);
$this->values = $this->valuator->get_points($this->fields, $forum_ids);
}
/**
* Set all users available for receiving points by the triggered action.
*
* $user_ids
* The array of user identifiers provided from the place where the action is triggered.
* This user's ($this->user) identifier is automatically added.
*
* $users
* The array of users that are able to receive points, with a base array to make sure all keys are set,
* aswell as all the users' current points.
*
* @param array|int $user_ids The user identifiers
* @return void
* @access protected
*/
protected function set_users($user_ids)
{
// Create array filled with integers
$user_ids = is_array($user_ids) ? array_map('intval', $user_ids) : [(int) $user_ids];
// Make sure to include this user ($this->user)
$user_ids[] = (int) $this->user->data['user_id'];
// Make sure only unique users are set
$user_ids = array_unique(array_filter($user_ids));
// If there is only one user, that will be this user, so no need to query
if (count($user_ids) === 1)
{
// Build the base user array for this user
$this->users[(int) $this->user->data['user_id']] = $this->user_array($this->user->data['user_points']);
}
else
{
// Grab all the current point values for these users
$user_points = $this->valuator->users($user_ids);
foreach ($user_ids as $user_id)
{
if (isset($user_points[$user_id]))
{
// Build the base user arrays
$this->users[$user_id] = $this->user_array($user_points[$user_id]);
}
}
}
// Lets make sure the anonymous user is never used
unset($this->users[ANONYMOUS]);
}
/**
* Let all the required action types calculate their user points.
*
* @param array $data Array of event data
* @return void
* @access protected
*/
protected function calculate(array $data)
{
/** @var \phpbbstudio\aps\actions\type\action $type */
foreach ($this->types as $type)
{
// Make the functions object available
$type->set_functions($this->functions);
// Set the users
$type->set_users($this->users);
// Check if APS is in Safe Mode
if ($this->functions->safe_mode())
{
// If so, catch any exceptions and log them
try
{
$type->calculate($data, $this->values);
}
catch (\Exception $e)
{
// Catch any error in the action type and log it!
$this->log->add('critical', $this->user->data['user_id'], $this->user->ip, 'LOG_ACP_APS_CALCULATION_ERROR', time(), [$e->getMessage(), $e->getFile(), $e->getLine(), $this->functions->get_name()]);
}
}
else
{
// If not, calculate and let the exceptions do their thing.
$type->calculate($data, $this->values);
}
// Iterate over all the users
foreach (array_keys($this->users) as $user_id)
{
// Get all received points for this user from this action type
$this->users[$user_id]['actions'][] = $type->get_points($user_id);
// Check for logs that need approving
if ($approve = $type->get_approve($user_id))
{
$this->users[$user_id]['approve'] = array_merge($this->users[$user_id]['approve'], $approve);
}
// Check for logs that need disapproving
if ($disapprove = $type->get_disapprove($user_id))
{
$this->users[$user_id]['disapprove'] = array_merge($this->users[$user_id]['disapprove'], $disapprove);
}
}
}
}
/**
* Distribute the points gained for all the users
*
* @return void
* @access protected
*/
protected function distribute()
{
// Iterate over all the users
foreach ($this->users as $user_id => $user_row)
{
// Iterate over all the action types
foreach ($user_row['actions'] as $actions)
{
// Iterate over the arrays added per action type
foreach ($actions as $action)
{
if ($action['approved'])
{
// Calculate the total points gained for this user
$this->functions->equate_reference($this->users[$user_id]['total'], $action['points']);
}
// Grab the post identifier, as we group the logs per post id
$post_id = (int) $action['post_id'];
// Set the logs for this user
$this->set_logs($user_id, $post_id, $action);
}
}
// And send it off: update user points and add log entries
$this->distributor->distribute(
$user_id,
$this->users[$user_id]['total'],
$this->users[$user_id]['logs'],
$this->users[$user_id]['current']
);
// Approve logs
if ($user_row['approve'])
{
$user_points = $this->functions->equate_points($this->users[$user_id]['total'], $this->users[$user_id]['current']);
$this->distributor->approve($user_id, array_unique(array_filter($user_row['approve'])), $user_points);
}
// Disapprove logs
if ($user_row['disapprove'])
{
$this->distributor->disapprove($user_id, array_unique(array_filter($user_row['disapprove'])));
}
}
}
/**
* Set the log entries for this user and index per post identifier.
*
* @param int $user_id The user identifier
* @param int $post_id The post identifier
* @param array $row The log array
* @return void
* @access protected
*/
protected function set_logs($user_id, $post_id, array $row)
{
// Get the logs in a local variable for easier coding
$logs = $this->users[$user_id]['logs'];
// Filter out the empty values except the first key
if (empty($logs[$post_id]))
{
$first = array_splice($row['logs'], 0, 1);
$row['logs'] = array_filter($row['logs']);
$row['logs'] = $first + $row['logs'];
}
else
{
$row['logs'] = array_filter($row['logs']);
}
// If there are no logs entries yet under this post identifier
if (empty($logs[$post_id]))
{
$logs[$post_id] = [
'action' => (string) $this->main_log($row['logs']),
'actions' => (array) $row['logs'],
'approved' => (bool) $row['approved'],
'forum_id' => (int) $row['forum_id'],
'topic_id' => (int) $row['topic_id'],
'post_id' => (int) $row['post_id'],
'user_id' => (int) $user_id,
'reportee_id' => (int) $this->user->data['user_id'],
'reportee_ip' => (string) $this->user->ip,
'points_old' => (double) $this->users[$user_id]['current'],
'points_sum' => (double) $row['points'],
'points_new' => (double) $this->functions->equate_points($this->users[$user_id]['current'], $row['points']),
];
}
else
{
// Else there already exists log entries under this post identifier, so merge this one in
$this->merge_logs($logs[$post_id]['actions'], $row['logs']);
// Equate (by reference) the points gained ('sum') and the new total ('new').
$this->functions->equate_reference($logs[$post_id]['points_sum'], $row['points']);
$this->functions->equate_reference($logs[$post_id]['points_new'], $row['points']);
}
// Set the logs in the global variable again
$this->users[$user_id]['logs'] = $logs;
}
/**
* Get the "main" log entry, the first key of the array.
*
* @param array $logs The logs array
* @return string The main log entry string
* @access protected
*/
protected function main_log(array $logs)
{
reset($logs);
$action = key($logs);
return $action;
}
/**
* Merge a log entry into existing log entries.
*
* Log entries are language strings (key) with point values (value).
* array('APS_SOME_ACTION' => 5.00)
*
* If logs are merged, an array is created which has to be equated.
* array('APS_SOME_ACTION' => array(5.00, 2.00)
*
* @param array $logs The existing log entries
* @param array $array The log entry to merge in
* @return void Passed by reference
* @access protected
*/
protected function merge_logs(array &$logs, array $array)
{
// Merge the array in to the existing entries
$logs = array_merge_recursive($logs, $array);
// Iterate over the logged actions
foreach ($logs as $key => $value)
{
// If the logged action is no longer a single points value, equate it.
if (is_array($value))
{
$logs[$key] = $this->functions->equate_array($value);
}
}
}
/**
* Set up a base array for this user.
*
* 'current
* The user's current points
*
* 'actions'
* Array that will be filled with arrays added by all the action types.
*
* 'points'
* Array that will be filled with points added by all the action types.
*
* 'approve'
* Array that will be filled with post identifiers that need to be approved from the logs table.
*
* 'disapprove'
* Array that will be filled with post identifiers that need to be disapproved from the logs table.
*
* 'logs'
* Array of log entries that are going to be added for this user.
*
* 'total'
* The total points gained for this user, summing up all points per action type.
*
* @param double $points The user's current points
* @return array The user's base array
* @access protected
*/
protected function user_array($points)
{
return [
'current' => (double) $points,
'actions' => [],
'points' => [],
'approve' => [],
'disapprove' => [],
'logs' => [],
'total' => 0.00,
];
}
}

View File

@@ -1,116 +0,0 @@
<?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\actions\type;
/**
* phpBB Studio - Advanced Points System action: Base
*/
interface action
{
/**
* Get action name.
*
* @abstract This function MUST be present in all extending classes
* @return string The name of the action this type belongs to
* @access public
*/
public function get_action();
/**
* Get global state.
*
* @abstract This function MUST be present in all extending classes
* @return bool If this type is global or local (per-forum basis)
* @access public
*/
public function is_global();
/**
* Get type category under which it will be listed in the ACP.
*
* @abstract This function MUST be present in all extending classes
* @return string The name of the category this type belongs to
* @access public
*/
public function get_category();
/**
* Get type data.
*
* @abstract This function MUST be present in all extending classes
* @return array An array of value names and their language string
* @access public
*/
public function get_data();
/**
* Calculate points for this type.
*
* @abstract This function MUST be present in all extending classes
* @param array $data The data available from the $event that triggered this action
* @param array $values The point values available, indexed per forum_id and 0 for global values
* @return void
*/
public function calculate($data, $values);
/**
* Get type value names.
*
* @return array An array of value names, the keys from get_data()
* @access public
*/
public function get_fields();
/**
* Set APS functions.
*
* @param \phpbbstudio\aps\core\functions $functions Common APS functions
* @return void
* @access public
*/
public function set_functions($functions);
/**
* Set users that are available for this action.
*
* @param array $users
* @return void
* @access public
*/
public function set_users($users);
/**
* Get the calculated points from this type for a given user identifier.
*
* @param int $user_id The user identifier
* @return array The calculated points array(s)
* @access public
*/
public function get_points($user_id);
/**
* Get the post identifiers that need to be approved for this user.
*
* @param int $user_id The user identifier
* @return array Array of post identifiers to approve for this user
* @access protected
*/
public function get_approve($user_id);
/**
* Get the post identifiers that need to be disapproved for this user.
*
* @param int $user_id The user identifier
* @return array Array of post identifiers to disapprove for this user
* @access protected
*/
public function get_disapprove($user_id);
}

View File

@@ -1,159 +0,0 @@
<?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\actions\type;
/**
* phpBB Studio - Advanced Points System action: Base interface
*/
abstract class base implements action
{
/** @var \phpbbstudio\aps\core\functions */
protected $functions;
/** @var array The users available for this action */
protected $users;
/**
* {@inheritdoc}
*/
abstract public function get_action();
/**
* {@inheritdoc}
*/
abstract public function is_global();
/**
* {@inheritdoc}
*/
abstract public function get_category();
/**
* {@inheritdoc}
*/
abstract public function get_data();
/**
* {@inheritdoc}
*/
abstract public function calculate($data, $values);
/**
* {@inheritdoc}
*/
public function get_fields()
{
return array_keys($this->get_data());
}
/**
* {@inheritdoc}
*/
public function set_functions($functions)
{
$this->functions = $functions;
}
/**
* {@inheritdoc}
*/
public function set_users($users)
{
$this->users = $users;
}
/**
* {@inheritdoc}
*/
public function get_points($user_id)
{
return $this->users[(int) $user_id]['points'];
}
/**
* {@inheritdoc}
*/
public function get_approve($user_id)
{
return $this->users[(int) $user_id]['approve'];
}
/**
* {@inheritdoc}
*/
public function get_disapprove($user_id)
{
return $this->users[(int) $user_id]['disapprove'];
}
/**
* Adds a points array from calculation to the provided user id.
*
* @param int $user_id The user identifier
* @param array $points_array The points array to add
* @return void
* @access protected
*/
protected function add($user_id, array $points_array)
{
// Make sure everything is set
$array = array_merge([
'approved' => true,
'forum_id' => 0,
'topic_id' => 0,
'post_id' => 0,
'points' => 0.00,
'logs' => [],
], $points_array);
$this->users[(int) $user_id]['points'][] = $array;
}
/**
* Adds a post id to the array of logs to approve.
*
* @param int $user_id The user identifier
* @param int $post_id The post identifier
* @return void
* @access protected
*/
protected function approve($user_id, $post_id)
{
$this->users[(int) $user_id]['approve'][] = (int) $post_id;
}
/**
* Adds a post id to the array of logs to disapprove.
*
* @param int $user_id The user identifier
* @param int $post_id The post identifier
* @return void
* @access protected
*/
protected function disapprove($user_id, $post_id)
{
$this->users[(int) $user_id]['disapprove'][] = (int) $post_id;
}
/**
* Equate two numbers.
*
* @param double $a The first number
* @param double $b The second number
* @param string $operator The equation operator
* @return double The result of the equation
* @access protected
*/
protected function equate($a, $b, $operator = '+')
{
return $this->functions->equate_points($a, $b, $operator);
}
}

View File

@@ -1,109 +0,0 @@
<?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\actions\type;
/**
* phpBB Studio - Advanced Points System action: Birthday
*/
class birthday extends base
{
/** @var \phpbb\user */
protected $user;
/**
* Constructor.
*
* @param \phpbb\user $user User object
* @return void
* @access public
*/
public function __construct(\phpbb\user $user)
{
$this->user = $user;
}
/**
* Get action name.
*
* @return string The name of the action this type belongs to
* @access public
*/
public function get_action()
{
return 'birthday';
}
/**
* Get global state.
*
* @return bool If this type is global or local (per-forum basis)
* @access public
*/
public function is_global()
{
return true;
}
/**
* Get type category under which it will be listed in the ACP.
*
* @return string The name of the category this type belongs to
* @access public
*/
public function get_category()
{
return 'ACP_APS_POINTS_MISC';
}
/**
* Get type data.
*
* @return array An array of value names and their language string
* @access public
*/
public function get_data()
{
return [
'aps_birthday' => 'APS_POINTS_BIRTHDAY',
];
}
/**
* Calculate points for this type.
*
* @param array $data The data available from the $event that triggered this action
* @param array $values The point values available, indexed per forum_id and 0 for global values
* @retrun void
*/
public function calculate($data, $values)
{
$value = $values[0];
$logs = $this->get_data();
$date = $data['day'] . '-' . $data['month'];
foreach (array_keys($this->users) as $user_id)
{
// This user is automatically added by the manager, so make sure it's actually their birthday
if ($user_id == $this->user->data['user_id'] && substr($this->user->data['user_birthday'], 0, 5) !== $date)
{
continue;
}
$points = [
'points' => (double) $value['aps_birthday'],
'logs' => [$logs['aps_birthday'] => $value['aps_birthday']],
];
$this->add($user_id, $points);
}
}
}

View File

@@ -1,101 +0,0 @@
<?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\actions\type;
/**
* phpBB Studio - Advanced Points System action: Change author
*/
class change extends base
{
/**
* Get action name.
*
* @return string The name of the action this type belongs to
* @access public
*/
public function get_action()
{
return 'change';
}
/**
* Get global state.
*
* @return bool If this type is global or local (per-forum basis)
* @access public
*/
public function is_global()
{
return false;
}
/**
* Get type category under which it will be listed in the ACP.
*
* @return string The name of the category this type belongs to
* @access public
*/
public function get_category()
{
return 'MODERATE';
}
/**
* Get type data.
*
* @return array An array of value names and their language string
* @access public
*/
public function get_data()
{
return [
'aps_mod_change' => 'APS_POINTS_MOD_CHANGE',
'aps_user_change_from' => 'APS_POINTS_USER_CHANGE_FROM',
'aps_user_change_to' => 'APS_POINTS_USER_CHANGE_TO',
];
}
/**
* Calculate points for this type.
*
* @param array $data The data available from the $event that triggered this action
* @param array $values The point values available, indexed per forum_id and 0 for global values
* @retrun void
*/
public function calculate($data, $values)
{
// Grab the data we need from the event
$forum_id = (int) $data['post_info']['forum_id'];
$topic_id = (int) $data['post_info']['topic_id'];
$post_id = (int) $data['post_info']['post_id'];
$from_id = (int) $data['post_info']['poster_id'];
$to_id = (int) $data['userdata']['user_id'];
// Get some base variables
$value = $values[$forum_id];
$logs = $this->get_data();
foreach (array_keys($this->users) as $user_id)
{
$action = in_array($user_id, [$from_id, $to_id]) ? ($user_id == $from_id ? 'aps_user_change_from' : 'aps_user_change_to') : 'aps_mod_change';
$points = [
'points' => (double) $value[$action],
'forum_id' => (int) $forum_id,
'topic_id' => (int) $topic_id,
'post_id' => (int) $post_id,
'logs' => [$logs[$action] => $value[$action]],
];
$this->add($user_id, $points);
}
}
}

View File

@@ -1,95 +0,0 @@
<?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\actions\type;
/**
* phpBB Studio - Advanced Points System action: Copy
*/
class copy extends base
{
/**
* Get action name.
*
* @return string The name of the action this type belongs to
* @access public
*/
public function get_action()
{
return 'copy';
}
/**
* Get global state.
*
* @return bool If this type is global or local (per-forum basis)
* @access public
*/
public function is_global()
{
return false;
}
/**
* Get type category under which it will be listed in the ACP.
*
* @return string The name of the category this type belongs to
* @access public
*/
public function get_category()
{
return 'MODERATE';
}
/**
* Get type data.
*
* @return array An array of value names and their language string
* @access public
*/
public function get_data()
{
return [
'aps_mod_copy' => 'APS_POINTS_MOD_COPY',
'aps_user_copy' => 'APS_POINTS_USER_COPY',
];
}
/**
* Calculate points for this type.
*
* @param array $data The data available from the $event that triggered this action
* @param array $values The point values available, indexed per forum_id and 0 for global values
* @retrun void
*/
public function calculate($data, $values)
{
// Grab the data we need from the event
$forum_id = (int) $data['topic_row']['forum_id'];
$poster_id = (int) $data['topic_row']['topic_poster'];
// Get some base variables
$value = $values[$forum_id];
$logs = $this->get_data();
foreach (array_keys($this->users) as $user_id)
{
$action = ($user_id == $poster_id) ? 'aps_user_copy' : 'aps_mod_copy';
$points = [
'points' => (double) $value[$action],
'forum_id' => (int) $forum_id,
'logs' => [$logs[$action] => $value[$action]],
];
$this->add($user_id, $points);
}
}
}

View File

@@ -1,131 +0,0 @@
<?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\actions\type;
/**
* phpBB Studio - Advanced Points System action: Delete
*/
class delete extends base
{
/** @var \phpbb\user */
protected $user;
/**
* Constructor.
*
* @param \phpbb\user $user User object
* @return void
* @access public
*/
public function __construct(\phpbb\user $user)
{
$this->user = $user;
}
/**
* Get action name.
*
* @return string The name of the action this type belongs to
* @access public
*/
public function get_action()
{
return 'delete';
}
/**
* Get global state.
*
* @return bool If this type is global or local (per-forum basis)
* @access public
*/
public function is_global()
{
return false;
}
/**
* Get type category under which it will be listed in the ACP.
*
* @return string The name of the category this type belongs to
* @access public
*/
public function get_category()
{
return 'MODERATE';
}
/**
* Get type data.
*
* @return array An array of value names and their language string
* @access public
*/
public function get_data()
{
return [
'aps_mod_delete_topic' => 'APS_POINTS_MOD_DELETE_TOPIC',
'aps_user_delete_topic' => 'APS_POINTS_USER_DELETE_TOPIC',
'aps_mod_delete_soft_topic' => 'APS_POINTS_MOD_DELETE_SOFT_TOPIC',
'aps_user_delete_soft_topic' => 'APS_POINTS_USER_DELETE_SOFT_TOPIC',
'aps_mod_delete_post' => 'APS_POINTS_MOD_DELETE_POST',
'aps_user_delete_post' => 'APS_POINTS_USER_DELETE_POST',
'aps_mod_delete_soft_post' => 'APS_POINTS_MOD_DELETE_SOFT_POST',
'aps_user_delete_soft_post' => 'APS_POINTS_USER_DELETE_SOFT_POST',
];
}
/**
* Calculate points for this type.
*
* @param array $data The data available from the $event that triggered this action
* @param array $values The point values available, indexed per forum_id and 0 for global values
* @retrun void
*/
public function calculate($data, $values)
{
$action = $data['action'];
$posts = $action === 'topic' ? $data['topics'] : $data['posts'];
$is_soft = isset($data['is_soft']) ? $data['is_soft'] : false;
$key_user = 'aps_user_delete_' . ($is_soft ? 'soft_' : '') . $action;
$key_mod = 'aps_mod_delete_' . ($is_soft ? 'soft_' : '') . $action;
$strings = $this->get_data();
foreach ($posts as $post_data)
{
$forum_id = $post_data['forum_id'];
$topic_id = $post_data['topic_id'];
$post_id = $action === 'topic' ? $post_data['topic_first_post_id'] : $post_data['post_id'];
$user_id = $action === 'topic' ? $post_data['topic_poster'] : $post_data['poster_id'];
$this->add($user_id, [
'forum_id' => $forum_id,
'topic_id' => $topic_id,
'post_id' => $post_id,
'points' => $values[$forum_id][$key_user],
'logs' => [
$strings[$key_user] => $values[$forum_id][$key_user],
],
]);
$this->add($this->user->data['user_id'], [
'forum_id' => $forum_id,
'topic_id' => $topic_id,
'post_id' => $post_id,
'points' => $values[$forum_id][$key_mod],
'logs' => [
$strings[$key_mod] => $values[$forum_id][$key_mod],
],
]);
}
}
}

View File

@@ -1,95 +0,0 @@
<?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\actions\type;
/**
* phpBB Studio - Advanced Points System action: Edit
*/
class edit extends base
{
/**
* Get action name.
*
* @return string The name of the action this type belongs to
* @access public
*/
public function get_action()
{
return 'edit';
}
/**
* Get global state.
*
* @return bool If this type is global or local (per-forum basis)
* @access public
*/
public function is_global()
{
return false;
}
/**
* Get type category under which it will be listed in the ACP.
*
* @return string The name of the category this type belongs to
* @access public
*/
public function get_category()
{
return 'MODERATE';
}
/**
* Get type data.
*
* @return array An array of value names and their language string
* @access public
*/
public function get_data()
{
return [
'aps_mod_edit' => 'APS_POINTS_MOD_EDIT',
'aps_user_edit' => 'APS_POINTS_USER_EDIT',
];
}
/**
* Calculate points for this type.
*
* @param array $data The data available from the $event that triggered this action
* @param array $values The point values available, indexed per forum_id and 0 for global values
* @retrun void
*/
public function calculate($data, $values)
{
// Grab the data we need from the event
$forum_id = (int) $data['data']['forum_id'];
$poster_id = (int) $data['data']['poster_id'];
// Get some base variables
$value = $values[$forum_id];
$logs = $this->get_data();
foreach (array_keys($this->users) as $user_id)
{
$action = ($user_id == $poster_id) ? 'aps_user_edit' : 'aps_mod_edit';
$points = [
'points' => (double) $value[$action],
'forum_id' => (int) $forum_id,
'logs' => [$logs[$action] => $value[$action]],
];
$this->add($user_id, $points);
}
}
}

View File

@@ -1,131 +0,0 @@
<?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\actions\type;
/**
* phpBB Studio - Advanced Points System action: Lock
*/
class lock extends base
{
/** @var \phpbb\user */
protected $user;
/**
* Constructor.
*
* @param \phpbb\user $user User object
* @return void
* @access public
*/
public function __construct(\phpbb\user $user)
{
$this->user = $user;
}
/**
* Get action name.
*
* @return string The name of the action this type belongs to
* @access public
*/
public function get_action()
{
return 'lock';
}
/**
* Get global state.
*
* @return bool If this type is global or local (per-forum basis)
* @access public
*/
public function is_global()
{
return false;
}
/**
* Get type category under which it will be listed in the ACP.
*
* @return string The name of the category this type belongs to
* @access public
*/
public function get_category()
{
return 'MODERATE';
}
/**
* Get type data.
*
* @return array An array of value names and their language string
* @access public
*/
public function get_data()
{
return [
'aps_mod_lock' => 'APS_POINTS_MOD_LOCK',
'aps_user_lock' => 'APS_POINTS_USER_LOCK',
'aps_mod_lock_post' => 'APS_POINTS_MOD_LOCK_POST',
'aps_user_lock_post' => 'APS_POINTS_USER_LOCK_POST',
'aps_mod_unlock' => 'APS_POINTS_MOD_UNLOCK',
'aps_user_unlock' => 'APS_POINTS_USER_UNLOCK',
'aps_mod_unlock_post' => 'APS_POINTS_MOD_UNLOCK_POST',
'aps_user_unlock_post' => 'APS_POINTS_USER_UNLOCK_POST',
];
}
/**
* Calculate points for this type.
*
* @param array $data The data available from the $event that triggered this action
* @param array $values The point values available, indexed per forum_id and 0 for global values
* @retrun void
*/
public function calculate($data, $values)
{
$action = $data['action'];
$posts = $data['data'];
$s_topic = in_array($action, ['lock', 'unlock']);
$key_user = 'aps_user_' . $action;
$key_mod = 'aps_mod_' . $action;
$strings = $this->get_data();
foreach ($posts as $post_data)
{
$forum_id = $post_data['forum_id'];
$topic_id = $post_data['topic_id'];
$post_id = $s_topic ? $post_data['topic_first_post_id'] : $post_data['post_id'];
$user_id = $s_topic ? $post_data['topic_poster'] : $post_data['poster_id'];
$this->add($user_id, [
'forum_id' => $forum_id,
'topic_id' => $topic_id,
'post_id' => $post_id,
'points' => $values[$forum_id][$key_user],
'logs' => [
$strings[$key_user] => $values[$forum_id][$key_user],
],
]);
$this->add($this->user->data['user_id'], [
'forum_id' => $forum_id,
'topic_id' => $topic_id,
'post_id' => $post_id,
'points' => $values[$forum_id][$key_mod],
'logs' => [
$strings[$key_mod] => $values[$forum_id][$key_mod],
],
]);
}
}
}

View File

@@ -1,113 +0,0 @@
<?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\actions\type;
/**
* phpBB Studio - Advanced Points System action: Merge
*/
class merge extends base
{
/** @var \phpbb\user */
protected $user;
/**
* Constructor.
*
* @param \phpbb\user $user User object
* @return void
* @access public
*/
public function __construct(\phpbb\user $user)
{
$this->user = $user;
}
/**
* Get action name.
*
* @return string The name of the action this type belongs to
* @access public
*/
public function get_action()
{
return 'merge';
}
/**
* Get global state.
*
* @return bool If this type is global or local (per-forum basis)
* @access public
*/
public function is_global()
{
return false;
}
/**
* Get type category under which it will be listed in the ACP.
*
* @return string The name of the category this type belongs to
* @access public
*/
public function get_category()
{
return 'MODERATE';
}
/**
* Get type data.
*
* @return array An array of value names and their language string
* @access public
*/
public function get_data()
{
return [
'aps_mod_merge' => 'APS_POINTS_MOD_MERGE',
'aps_user_merge' => 'APS_POINTS_USER_MERGE',
];
}
/**
* Calculate points for this type.
*
* @param array $data The data available from the $event that triggered this action
* @param array $values The point values available, indexed per forum_id and 0 for global values
* @retrun void
*/
public function calculate($data, $values)
{
$topics = $data['all_topic_data'];
$topic_id = $data['to_topic_id'];
$forum_id = $topics[$topic_id]['forum_id'];
$values = $values[$forum_id];
$strings = $this->get_data();
foreach ($topics as $topic)
{
$this->add($topic['topic_poster'], [
'forum_id' => (int) $forum_id,
'topic_id' => (int) $topic_id,
'points' => $values['aps_user_merge'],
'logs' => [$strings['aps_user_merge'] => $values['aps_user_merge']],
]);
$this->add($this->user->data['user_id'], [
'forum_id' => (int) $forum_id,
'topic_id' => (int) $topic_id,
'points' => $values['aps_mod_merge'],
'logs' => [$strings['aps_mod_merge'] => $values['aps_mod_merge']],
]);
}
}
}

View File

@@ -1,127 +0,0 @@
<?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\actions\type;
/**
* phpBB Studio - Advanced Points System action: Move
*/
class move extends base
{
/** @var \phpbb\user */
protected $user;
/**
* Constructor.
*
* @param \phpbb\user $user User object
* @return void
* @access public
*/
public function __construct(\phpbb\user $user)
{
$this->user = $user;
}
/**
* Get action name.
*
* @return string The name of the action this type belongs to
* @access public
*/
public function get_action()
{
return 'move';
}
/**
* Get global state.
*
* @return bool If this type is global or local (per-forum basis)
* @access public
*/
public function is_global()
{
return false;
}
/**
* Get type category under which it will be listed in the ACP.
*
* @return string The name of the category this type belongs to
* @access public
*/
public function get_category()
{
return 'MODERATE';
}
/**
* Get type data.
*
* @return array An array of value names and their language string
* @access public
*/
public function get_data()
{
return [
'aps_mod_move_post' => 'APS_POINTS_MOD_MOVE_POST',
'aps_user_move_post' => 'APS_POINTS_USER_MOVE_POST',
'aps_mod_move_topic' => 'APS_POINTS_MOD_MOVE_TOPIC',
'aps_user_move_topic' => 'APS_POINTS_USER_MOVE_TOPIC',
];
}
/**
* Calculate points for this type.
*
* @param array $data The data available from the $event that triggered this action
* @param array $values The point values available, indexed per forum_id and 0 for global values
* @retrun void
*/
public function calculate($data, $values)
{
$action = $data['action'];
$s_topic = $action === 'topic';
$posts = $s_topic ? $data['topics'] : $data['posts'];
$key_user = 'aps_user_move_' . $action;
$key_mod = 'aps_mod_move_' . $action;
$strings = $this->get_data();
foreach ($posts as $post)
{
$forum_id = $post['forum_id'];
$topic_id = $post['topic_id'];
$post_id = $s_topic ? $post['topic_first_post_id'] : $post['post_id'];
$user_id = $s_topic ? $post['topic_poster'] : $post['poster_id'];
$this->add($user_id, [
'forum_id' => $forum_id,
'topic_id' => $topic_id,
'post_id' => $post_id,
'points' => $values[$forum_id][$key_user],
'logs' => [
$strings[$key_user] => $values[$forum_id][$key_user],
],
]);
$this->add($this->user->data['user_id'], [
'forum_id' => $forum_id,
'topic_id' => $topic_id,
'post_id' => $post_id,
'points' => $values[$forum_id][$key_mod],
'logs' => [
$strings[$key_mod] => $values[$forum_id][$key_mod],
],
]);
}
}
}

View File

@@ -1,202 +0,0 @@
<?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\actions\type;
/**
* phpBB Studio - Advanced Points System action: Private message
*/
class pm extends base
{
/** @var \phpbb\config\config */
protected $config;
/** @var \phpbb\textformatter\s9e\utils */
protected $utils;
/** @var array Ignore criteria constants */
protected $ignore;
/**
* Constructor.
*
* @param \phpbb\config\config $config Config object
* @param \phpbb\textformatter\s9e\utils $utils s9e Textformatter utilities object
* @param array $constants APS Constants
* @return void
* @access public
*/
public function __construct(\phpbb\config\config $config, \phpbb\textformatter\s9e\utils $utils, array $constants)
{
$this->config = $config;
$this->utils = $utils;
$this->ignore = $constants['ignore'];
}
/**
* Get action name.
*
* @return string The name of the action this type belongs to
* @access public
*/
public function get_action()
{
return 'pm';
}
/**
* Get global state.
*
* @return bool If this type is global or local (per-forum basis)
* @access public
*/
public function is_global()
{
return true;
}
/**
* Get type category under which it will be listed in the ACP.
*
* @return string The name of the category this type belongs to
* @access public
*/
public function get_category()
{
return 'PRIVATE_MESSAGE';
}
/**
* Get type data.
*
* @return array An array of value names and their language string
* @access public
*/
public function get_data()
{
return [
// Initial points
'aps_pm_base' => 'APS_POINTS_PM',
// Recipients points
'aps_pm_per_recipient' => 'APS_POINTS_PM_PER_RECIPIENT',
// Text points
'aps_pm_per_char' => 'APS_POINTS_PER_CHAR',
'aps_pm_per_word' => 'APS_POINTS_PER_WORD',
'aps_pm_per_quote' => 'APS_POINTS_PER_QUOTE',
// Attachment points
'aps_pm_has_attach' => 'APS_POINTS_ATTACH_HAS',
'aps_pm_per_attach' => 'APS_POINTS_ATTACH_PER',
// Modification points
'aps_pm_edit' => 'APS_POINTS_EDIT',
];
}
/**
* Calculate points for this type.
*
* @param array $data The data available from the $event that triggered this action
* @param array $values The point values available, indexed per forum_id and 0 for global values
* @retrun void
*/
public function calculate($data, $values)
{
// Grab event data
$mode = $data['mode'];
$message = $data['data']['message'];
$attachments = !empty($data['data']['attachment_data']) ? $data['data']['attachment_data'] : [];
$recipients = $data['pm_data']['recipients'];
$logs = [];
$values = $values[0];
$strings = $this->get_data();
switch ($mode)
{
case 'edit':
$points = $logs[$strings['aps_pm_' . $mode]] = $values['aps_pm_' . $mode];
break;
default:
// Initial points
$points = $logs[$strings['aps_pm_base']] = $values['aps_pm_base'];
// Recipient points
$points += $logs[$strings['aps_pm_per_recipient']] = $this->equate($values['aps_pm_per_recipient'], count($recipients), '*');
// Text points
$quotes = $this->utils->get_outermost_quote_authors($message);
$message = $this->utils->remove_bbcode($message, 'quote');
$message = $this->utils->remove_bbcode($message, 'attachment');
$message = $this->utils->clean_formatting($message);
$words = $exclude_words = array_filter(preg_split('/[\s]+/', $message));
$chars = $exclude_chars = implode('', $words);
if ($min = $this->config['aps_points_exclude_words'])
{
$exclude_words = array_filter($words, function($word) use ($min)
{
return strlen($word) > $min;
});
if ($this->config['aps_points_exclude_chars'])
{
$exclude_chars = implode('', $exclude_words);
}
}
// Check ignore criteria
if ($this->config['aps_ignore_criteria'])
{
$ignore_words = $this->config['aps_ignore_excluded_words'] ? $exclude_words : $words;
$ignore_chars = $this->config['aps_ignore_excluded_chars'] ? $exclude_chars : $chars;
$ignore_words = count($ignore_words) < $this->config['aps_ignore_min_words'];
$ignore_chars = strlen($ignore_chars) < $this->config['aps_ignore_min_chars'];
if (($this->config['aps_ignore_criteria'] == $this->ignore['both'] && $ignore_words && $ignore_chars)
|| ($this->config['aps_ignore_criteria'] == $this->ignore['words'] && $ignore_words)
|| ($this->config['aps_ignore_criteria'] == $this->ignore['chars'] && $ignore_chars))
{
$points = 0;
// Break out of calculation
break;
}
}
$words = $exclude_words;
$chars = $exclude_chars;
$points += $logs[$strings['aps_pm_per_quote']] = $this->equate($values['aps_pm_per_quote'], count($quotes), '*');
$points += $logs[$strings['aps_pm_per_word']] = $this->equate($values['aps_pm_per_word'], count($words), '*');
$points += $logs[$strings['aps_pm_per_char']] = $this->equate($values['aps_pm_per_char'], strlen($chars), '*');
// Attachment points
if (!empty($attachments))
{
$points += $logs[$strings['aps_pm_has_attach']] = $values['aps_pm_has_attach'];
$points += $logs[$strings['aps_pm_per_attach']] = $this->equate($values['aps_pm_per_attach'], count($attachments), '*');
}
break;
}
foreach (array_keys($this->users) as $user_id)
{
$this->add($user_id, [
'points' => $points,
'logs' => $logs,
]);
}
}
}

View File

@@ -1,211 +0,0 @@
<?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\actions\type;
/**
* phpBB Studio - Advanced Points System action: Post
*/
class post extends base
{
/** @var \phpbb\config\config */
protected $config;
/** @var \phpbb\textformatter\s9e\utils */
protected $utils;
/** @var array Ignore criteria constants */
protected $ignore;
/**
* Constructor.
*
* @param \phpbb\config\config $config Config object
* @param \phpbb\textformatter\s9e\utils $utils s9e Textformatter utilities object
* @param array $constants APS Constants
* @return void
* @access public
*/
public function __construct(\phpbb\config\config $config, \phpbb\textformatter\s9e\utils $utils, array $constants)
{
$this->config = $config;
$this->utils = $utils;
$this->ignore = $constants['ignore'];
}
/**
* Get action name.
*
* @return string The name of the action this type belongs to
* @access public
*/
public function get_action()
{
return 'post';
}
/**
* Get global state.
*
* @return bool If this type is global or local (per-forum basis)
* @access public
*/
public function is_global()
{
return false;
}
/**
* Get type category under which it will be listed in the ACP.
*
* @return string The name of the category this type belongs to
* @access public
*/
public function get_category()
{
return 'POST';
}
/**
* Get type data.
*
* @return array An array of value names and their language string
* @access public
*/
public function get_data()
{
return [
// Initial points
'aps_post_base' => 'APS_POINTS_POST',
// Text points
'aps_post_per_char' => 'APS_POINTS_PER_CHAR',
'aps_post_per_word' => 'APS_POINTS_PER_WORD',
'aps_post_per_quote' => 'APS_POINTS_PER_QUOTE',
// Attachment points
'aps_post_has_attach' => 'APS_POINTS_ATTACH_HAS',
'aps_post_per_attach' => 'APS_POINTS_ATTACH_PER',
// Modification points
'aps_post_edit' => 'APS_POINTS_EDIT',
'aps_post_delete' => 'APS_POINTS_DELETE',
'aps_post_delete_soft' => 'APS_POINTS_DELETE_SOFT',
];
}
/**
* Calculate points for this type.
*
* @param array $data The data available from the $event that triggered this action
* @param array $values The point values available, indexed per forum_id and 0 for global values
* @retrun void
*/
public function calculate($data, $values)
{
// Grab event data
$mode = $data['mode'];
$s_delete = in_array($mode, ['delete', 'soft_delete']);
$forum_id = $s_delete ? $data['forum_id'] : $data['data']['forum_id'];
$topic_id = $s_delete ? $data['topic_id'] : $data['data']['topic_id'];
$post_id = $s_delete ? $data['post_id'] : $data['data']['post_id'];
$message = $s_delete ? '' : $data['data']['message'];
$s_approved = !$s_delete ? $data['post_visibility'] == ITEM_APPROVED : true;
$attachments = $s_delete ? [] : $data['data']['attachment_data'];
$logs = [];
$values = $values[$forum_id];
$strings = $this->get_data();
switch ($mode)
{
/** @noinspection PhpMissingBreakStatementInspection */
case 'soft_delete':
$mode = 'delete_soft';
// no break;
case 'edit':
case 'delete':
$points = $logs[$strings['aps_post_' . $mode]] = $values['aps_post_' . $mode];
break;
default:
// Initial points
$points = $logs[$strings['aps_post_base']] = $values['aps_post_base'];
// Text points
$quotes = $this->utils->get_outermost_quote_authors($message);
$message = $this->utils->remove_bbcode($message, 'quote');
$message = $this->utils->remove_bbcode($message, 'attachment');
$message = $this->utils->clean_formatting($message);
$words = $exclude_words = array_filter(preg_split('/[\s]+/', $message));
$chars = $exclude_chars = implode('', $words);
if ($min = $this->config['aps_points_exclude_words'])
{
$exclude_words = array_filter($words, function($word) use ($min)
{
return strlen($word) > $min;
});
if ($this->config['aps_points_exclude_chars'])
{
$exclude_chars = implode('', $exclude_words);
}
}
// Check ignore criteria
if ($this->config['aps_ignore_criteria'])
{
$ignore_words = $this->config['aps_ignore_excluded_words'] ? $exclude_words : $words;
$ignore_chars = $this->config['aps_ignore_excluded_chars'] ? $exclude_chars : $chars;
$ignore_words = count($ignore_words) < $this->config['aps_ignore_min_words'];
$ignore_chars = strlen($ignore_chars) < $this->config['aps_ignore_min_chars'];
if (($this->config['aps_ignore_criteria'] == $this->ignore['both'] && $ignore_words && $ignore_chars)
|| ($this->config['aps_ignore_criteria'] == $this->ignore['words'] && $ignore_words)
|| ($this->config['aps_ignore_criteria'] == $this->ignore['chars'] && $ignore_chars))
{
$points = 0;
// Break out of calculation
break;
}
}
$words = $exclude_words;
$chars = $exclude_chars;
$points += $logs[$strings['aps_post_per_quote']] = $this->equate($values['aps_post_per_quote'], count($quotes), '*');
$points += $logs[$strings['aps_post_per_word']] = $this->equate($values['aps_post_per_word'], count($words), '*');
$points += $logs[$strings['aps_post_per_char']] = $this->equate($values['aps_post_per_char'], strlen($chars), '*');
// Attachment points
if (!empty($attachments))
{
$points += $logs[$strings['aps_post_has_attach']] = $values['aps_post_has_attach'];
$points += $logs[$strings['aps_post_per_attach']] = $this->equate($values['aps_post_per_attach'], count($attachments), '*');
}
break;
}
foreach (array_keys($this->users) as $user_id)
{
$this->add($user_id, [
'approved' => $s_approved,
'forum_id' => $forum_id,
'topic_id' => $topic_id,
'post_id' => $post_id,
'points' => $points,
'logs' => $logs,
]);
}
}
}

View File

@@ -1,140 +0,0 @@
<?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\actions\type;
/**
* phpBB Studio - Advanced Points System action: Queue
*/
class queue extends base
{
/** @var \phpbb\user */
protected $user;
/**
* Constructor.
*
* @param \phpbb\user $user User object
* @return void
* @access public
*/
public function __construct(\phpbb\user $user)
{
$this->user = $user;
}
/**
* Get action name.
*
* @return string The name of the action this type belongs to
* @access public
*/
public function get_action()
{
return 'queue';
}
/**
* Get global state.
*
* @return bool If this type is global or local (per-forum basis)
* @access public
*/
public function is_global()
{
return false;
}
/**
* Get type category under which it will be listed in the ACP.
*
* @return string The name of the category this type belongs to
* @access public
*/
public function get_category()
{
return 'MODERATE';
}
/**
* Get type data.
*
* @return array An array of value names and their language string
* @access public
*/
public function get_data()
{
return [
'aps_mod_restore' => 'APS_POINTS_MOD_RESTORE',
'aps_mod_approve' => 'APS_POINTS_MOD_APPROVE',
'aps_mod_disapprove' => 'APS_POINTS_MOD_DISAPPROVE',
'aps_user_restore' => 'APS_POINTS_USER_RESTORE',
'aps_user_approve' => 'APS_POINTS_USER_APPROVE',
'aps_user_disapprove' => 'APS_POINTS_USER_DISAPPROVE',
];
}
/**
* Calculate points for this type.
*
* @param array $data The data available from the $event that triggered this action
* @param array $values The point values available, indexed per forum_id and 0 for global values
* @retrun void
*/
public function calculate($data, $values)
{
$action = $data['mode'];
$s_post = isset($data['post_info']);
$posts = $s_post ? $data['post_info'] : $data['topic_info'];
$key_user = 'aps_user_' . $action;
$key_mod = 'aps_mod_' . $action;
$strings = $this->get_data();
foreach ($posts as $post_id => $post_data)
{
$user_id = $s_post ? $post_data['poster_id'] : $post_data['topic_poster'];
$topic_id = $post_data['topic_id'];
$forum_id = $post_data['forum_id'];
$logs = [];
$points = $logs[$strings[$key_user]] = $values[$forum_id][$key_user];
switch ($action)
{
case 'approve':
$this->approve($user_id, $post_id);
break;
case 'disapprove':
$this->disapprove($user_id, $post_id);
break;
}
$this->add($user_id, [
'forum_id' => $forum_id,
'topic_id' => $topic_id,
'post_id' => $post_id,
'points' => $points,
'logs' => $logs,
]);
$this->add($this->user->data['user_id'], [
'forum_id' => $forum_id,
'topic_id' => $topic_id,
'post_id' => $post_id,
'points' => $values[$forum_id][$key_mod],
'logs' => [
$strings[$key_mod] => $values[$forum_id][$key_mod],
],
]);
}
}
}

View File

@@ -1,91 +0,0 @@
<?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\actions\type;
/**
* phpBB Studio - Advanced Points System action: Register
*/
class register extends base
{
/**
* Get action name.
*
* @return string The name of the action this type belongs to
* @access public
*/
public function get_action()
{
return 'register';
}
/**
* Get global state.
*
* @return bool If this type is global or local (per-forum basis)
* @access public
*/
public function is_global()
{
return true;
}
/**
* Get type category under which it will be listed in the ACP.
*
* @return string The name of the category this type belongs to
* @access public
*/
public function get_category()
{
return 'ACP_APS_POINTS_MISC';
}
/**
* Get type data.
*
* @return array An array of value names and their language string
* @access public
*/
public function get_data()
{
return [
'aps_register' => 'APS_POINTS_REGISTER',
];
}
/**
* Calculate points for this type.
*
* @param array $data The data available from the $event that triggered this action
* @param array $values The point values available, indexed per forum_id and 0 for global values
* @retrun void
*/
public function calculate($data, $values)
{
$value = $values[0];
$logs = $this->get_data();
foreach (array_keys($this->users) as $user_id)
{
if ($user_id == ANONYMOUS)
{
continue;
}
$points = [
'points' => (double) $value['aps_register'],
'logs' => [$logs['aps_register'] => $value['aps_register']],
];
$this->add($user_id, $points);
}
}
}

View File

@@ -1,243 +0,0 @@
<?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\actions\type;
/**
* phpBB Studio - Advanced Points System action: Topic
*/
class topic extends base
{
/** @var \phpbb\config\config */
protected $config;
/** @var \phpbb\textformatter\s9e\utils */
protected $utils;
/** @var array Ignore criteria constants */
protected $ignore;
/**
* Constructor.
*
* @param \phpbb\config\config $config Config object
* @param \phpbb\textformatter\s9e\utils $utils s9e Textformatter utilities object
* @param array $constants APS Constants
* @return void
* @access public
*/
public function __construct(\phpbb\config\config $config, \phpbb\textformatter\s9e\utils $utils, array $constants)
{
$this->config = $config;
$this->utils = $utils;
$this->ignore = $constants['ignore'];
}
/**
* Get action name.
*
* @return string The name of the action this type belongs to
* @access public
*/
public function get_action()
{
return 'topic';
}
/**
* Get global state.
*
* @return bool If this type is global or local (per-forum basis)
* @access public
*/
public function is_global()
{
return false;
}
/**
* Get type category under which it will be listed in the ACP.
*
* @return string The name of the category this type belongs to
* @access public
*/
public function get_category()
{
return 'TOPIC';
}
/**
* Get type data.
*
* @return array An array of value names and their language string
* @access public
*/
public function get_data()
{
return [
// Type points
'aps_topic_base' => 'APS_POINTS_TOPIC',
'aps_topic_sticky' => 'APS_POINTS_STICKY',
'aps_topic_announce' => 'APS_POINTS_ANNOUNCE',
'aps_topic_global' => 'APS_POINTS_GLOBAL',
// Text points
'aps_topic_per_char' => 'APS_POINTS_PER_CHAR',
'aps_topic_per_word' => 'APS_POINTS_PER_WORD',
'aps_topic_per_quote' => 'APS_POINTS_PER_QUOTE',
// Attachment points
'aps_topic_has_attach' => 'APS_POINTS_ATTACH_HAS',
'aps_topic_per_attach' => 'APS_POINTS_ATTACH_PER',
// Poll points
'aps_topic_has_poll' => 'APS_POINTS_POLL_HAS',
'aps_topic_per_option' => 'APS_POINTS_POLL_OPTION',
// Miscellaneous
'aps_topic_bump' => 'APS_POINTS_BUMP',
'aps_topic_edit' => 'APS_POINTS_EDIT',
];
}
/**
* Calculate points for this type.
*
* @param array $data The data available from the $event that triggered this action
* @param array $values The point values available, indexed per forum_id and 0 for global values
* @retrun void
*/
public function calculate($data, $values)
{
$mode = $data['mode'];
$s_bump = $mode === 'bump';
$type = !$s_bump ? $data['topic_type'] : '';
$post_data = !$s_bump ? $data['data'] : $data['post_data'];
$s_approved = isset($data['post_visibility']) ? $data['post_visibility'] == ITEM_APPROVED : true;
$poll = isset($data['poll']['poll_options']) ? $data['poll']['poll_options'] : [];
$forum_id = $post_data['forum_id'];
$topic_id = $post_data['topic_id'];
$post_id = !$s_bump ? $post_data['post_id'] : 0;
$message = !$s_bump ? $post_data['message'] : '';
$attachments = !$s_bump ? $post_data['attachment_data'] : [];
$logs = [];
$values = $values[$forum_id];
$strings = $this->get_data();
switch ($mode)
{
case 'bump':
case 'edit':
$points = $logs[$strings['aps_topic_' . $mode]] = $values['aps_topic_' . $mode];
break;
default:
// Initial type points
switch ($type)
{
default:
case POST_NORMAL:
$points = $logs[$strings['aps_topic_base']] = $values['aps_topic_base'];
break;
case POST_STICKY:
$points = $logs[$strings['aps_topic_sticky']] = $values['aps_topic_sticky'];
break;
case POST_ANNOUNCE:
$points = $logs[$strings['aps_topic_announce']] = $values['aps_topic_announce'];
break;
case POST_GLOBAL:
$points = $logs[$strings['aps_topic_global']] = $values['aps_topic_global'];
break;
}
// Text points
$quotes = $this->utils->get_outermost_quote_authors($message);
$message = $this->utils->remove_bbcode($message, 'quote');
$message = $this->utils->remove_bbcode($message, 'attachment');
$message = $this->utils->clean_formatting($message);
$words = $exclude_words = array_filter(preg_split('/[\s]+/', $message));
$chars = $exclude_chars = implode('', $words);
if ($min = $this->config['aps_points_exclude_words'])
{
$exclude_words = array_filter($words, function($word) use ($min)
{
return strlen($word) > $min;
});
if ($this->config['aps_points_exclude_chars'])
{
$exclude_chars = implode('', $exclude_words);
}
}
// Check ignore criteria
if ($this->config['aps_ignore_criteria'])
{
$ignore_words = $this->config['aps_ignore_excluded_words'] ? $exclude_words : $words;
$ignore_chars = $this->config['aps_ignore_excluded_chars'] ? $exclude_chars : $chars;
$ignore_words = count($ignore_words) < $this->config['aps_ignore_min_words'];
$ignore_chars = strlen($ignore_chars) < $this->config['aps_ignore_min_chars'];
if (($this->config['aps_ignore_criteria'] == $this->ignore['both'] && $ignore_words && $ignore_chars)
|| ($this->config['aps_ignore_criteria'] == $this->ignore['words'] && $ignore_words)
|| ($this->config['aps_ignore_criteria'] == $this->ignore['chars'] && $ignore_chars))
{
$points = 0;
// Break out of calculation
break;
}
}
$words = $exclude_words;
$chars = $exclude_chars;
$points += $logs[$strings['aps_topic_per_quote']] = $this->equate($values['aps_topic_per_quote'], count($quotes), '*');
$points += $logs[$strings['aps_topic_per_word']] = $this->equate($values['aps_topic_per_word'], count($words), '*');
$points += $logs[$strings['aps_topic_per_char']] = $this->equate($values['aps_topic_per_char'], strlen($chars), '*');
// Attachment points
if (!empty($attachments))
{
$points += $logs[$strings['aps_topic_has_attach']] = $values['aps_topic_has_attach'];
$points += $logs[$strings['aps_topic_per_attach']] = $this->equate($values['aps_topic_per_attach'], count($attachments), '*');
}
// Poll points
if ($poll)
{
$points += $logs[$strings['aps_topic_has_poll']] = $values['aps_topic_has_poll'];
$points += $logs[$strings['aps_topic_per_option']] = $this->equate($values['aps_topic_per_option'], count($poll), '*');
}
break;
}
foreach (array_keys($this->users) as $user_id)
{
$this->add($user_id, [
'approved' => $s_approved,
'forum_id' => $forum_id,
'topic_id' => $topic_id,
'post_id' => $post_id,
'points' => $points,
'logs' => $logs,
]);
}
}
}

View File

@@ -1,132 +0,0 @@
<?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\actions\type;
/**
* phpBB Studio - Advanced Points System action: Topic type
*/
class topic_type extends base
{
/**
* Get action name.
*
* @return string The name of the action this type belongs to
* @access public
*/
public function get_action()
{
return 'topic_type';
}
/**
* Get global state.
*
* @return bool If this type is global or local (per-forum basis)
* @access public
*/
public function is_global()
{
return false;
}
/**
* Get type category under which it will be listed in the ACP.
*
* @return string The name of the category this type belongs to
* @access public
*/
public function get_category()
{
return 'ACP_APS_TOPIC_TYPES';
}
/**
* Get type data.
*
* @return array An array of value names and their language string
* @access public
*/
public function get_data()
{
return [
'aps_mod_normal_sticky' => 'APS_POINTS_MOD_NORMAL_STICKY',
'aps_mod_normal_announce' => 'APS_POINTS_MOD_NORMAL_ANNOUNCE',
'aps_mod_normal_global' => 'APS_POINTS_MOD_NORMAL_GLOBAL',
'aps_mod_sticky_normal' => 'APS_POINTS_MOD_STICKY_NORMAL',
'aps_mod_sticky_announce' => 'APS_POINTS_MOD_STICKY_ANNOUNCE',
'aps_mod_sticky_global' => 'APS_POINTS_MOD_STICKY_GLOBAL',
'aps_mod_announce_normal' => 'APS_POINTS_MOD_ANNOUNCE_NORMAL',
'aps_mod_announce_sticky' => 'APS_POINTS_MOD_ANNOUNCE_STICKY',
'aps_mod_announce_global' => 'APS_POINTS_MOD_ANNOUNCE_GLOBAL',
'aps_mod_global_normal' => 'APS_POINTS_MOD_GLOBAL_NORMAL',
'aps_mod_global_sticky' => 'APS_POINTS_MOD_GLOBAL_STICKY',
'aps_mod_global_announce' => 'APS_POINTS_MOD_GLOBAL_ANNOUNCE',
'aps_user_normal_sticky' => 'APS_POINTS_USER_NORMAL_STICKY',
'aps_user_normal_announce' => 'APS_POINTS_USER_NORMAL_ANNOUNCE',
'aps_user_normal_global' => 'APS_POINTS_USER_NORMAL_GLOBAL',
'aps_user_sticky_normal' => 'APS_POINTS_USER_STICKY_NORMAL',
'aps_user_sticky_announce' => 'APS_POINTS_USER_STICKY_ANNOUNCE',
'aps_user_sticky_global' => 'APS_POINTS_USER_STICKY_GLOBAL',
'aps_user_announce_normal' => 'APS_POINTS_USER_ANNOUNCE_NORMAL',
'aps_user_announce_sticky' => 'APS_POINTS_USER_ANNOUNCE_STICKY',
'aps_user_announce_global' => 'APS_POINTS_USER_ANNOUNCE_GLOBAL',
'aps_user_global_normal' => 'APS_POINTS_USER_GLOBAL_NORMAL',
'aps_user_global_sticky' => 'APS_POINTS_USER_GLOBAL_STICKY',
'aps_user_global_announce' => 'APS_POINTS_USER_GLOBAL_ANNOUNCE',
];
}
/**
* Calculate points for this type.
*
* @param array $data The data available from the $event that triggered this action
* @param array $values The point values available, indexed per forum_id and 0 for global values
* @retrun void
*/
public function calculate($data, $values)
{
// Grab the data we need from the event
$forum_id = (int) $data['data']['forum_id'];
$topic_id = (int) $data['data']['topic_id'];
$post_id = (int) $data['data']['post_id'];
$poster_id = (int) $data['post_data']['topic_poster'];
$type_from = (int) $data['type_from'];
$type_to = (int) $data['type_to'];
$types = [
POST_NORMAL => 'normal',
POST_STICKY => 'sticky',
POST_ANNOUNCE => 'announce',
POST_GLOBAL => 'global',
];
// Get some base variables
$value = $values[$forum_id];
$logs = $this->get_data();
foreach (array_keys($this->users) as $user_id)
{
$action = ($user_id == $poster_id) ? 'aps_user_' : 'aps_mod_';
$action .= $types[$type_from] . '_' . $types[$type_to];
$points = [
'points' => (double) $value[$action],
'forum_id' => (int) $forum_id,
'topic_id' => (int) $topic_id,
'post_id' => (int) $post_id,
'logs' => [$logs[$action] => $value[$action]],
];
$this->add($user_id, $points);
}
}
}

View File

@@ -1,117 +0,0 @@
<?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\actions\type;
/**
* phpBB Studio - Advanced Points System action: Vote
*/
class vote extends base
{
/**
* Get action name.
*
* @return string The name of the action this type belongs to
* @access public
*/
public function get_action()
{
return 'vote';
}
/**
* Get global state.
*
* @return bool If this type is global or local (per-forum basis)
* @access public
*/
public function is_global()
{
return false;
}
/**
* Get type category under which it will be listed in the ACP.
*
* @return string The name of the category this type belongs to
* @access public
*/
public function get_category()
{
return 'ACP_APS_POINTS_MISC';
}
/**
* Get type data.
*
* @return array An array of value names and their language string
* @access public
*/
public function get_data()
{
return [
'aps_vote' => 'APS_POINTS_PER_VOTE',
];
}
/**
* Calculate points for this type.
*
* @param array $data The data available from the $event that triggered this action
* @param array $values The point values available, indexed per forum_id and 0 for global values
* @retrun void
*/
public function calculate($data, $values)
{
$votes = $data['vote_counts'];
$options = $data['poll_info'];
$forum_id = $data['forum_id'];
$topic_id = $data['topic_data']['topic_id'];
$value = $values[$forum_id]['aps_vote'];
$i = 0;
foreach ($options as $option)
{
$new = $votes[$option['poll_option_id']];
$old = $option['poll_option_total'];
if ($new > $old)
{
$i++;
}
else if ($new < $old)
{
$i--;
}
}
if ($i !== 0)
{
$points = $this->equate($value, $i, '*');
foreach ($this->users as $user_id => $user_data)
{
$string = $points > 0 ? 'APS_POINTS_VOTE_ADDED' : 'APS_POINTS_VOTE_REMOVED';
$this->add($user_id, [
'forum_id' => $forum_id,
'topic_id' => $topic_id,
'post_id' => 0,
'points' => $points,
'logs' => [
$string => $points,
'APS_POINTS_VOTE_AMOUNT' => $i,
],
]);
}
}
}
}

View File

@@ -1,104 +0,0 @@
<?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\actions\type;
/**
* phpBB Studio - Advanced Points System action: Warn
*/
class warn extends base
{
/** @var \phpbb\user */
protected $user;
/**
* Constructor.
*
* @param \phpbb\user $user User object
* @return void
* @access public
*/
public function __construct(\phpbb\user $user)
{
$this->user = $user;
}
/**
* Get action name.
*
* @return string The name of the action this type belongs to
* @access public
*/
public function get_action()
{
return 'warn';
}
/**
* Get global state.
*
* @return bool If this type is global or local (per-forum basis)
* @access public
*/
public function is_global()
{
return true;
}
/**
* Get type category under which it will be listed in the ACP.
*
* @return string The name of the category this type belongs to
* @access public
*/
public function get_category()
{
return 'ACP_APS_POINTS_MISC';
}
/**
* Get type data.
*
* @return array An array of value names and their language string
* @access public
*/
public function get_data()
{
return [
'aps_mod_warn' => 'APS_POINTS_MOD_WARN',
'aps_user_warn' => 'APS_POINTS_USER_WARN',
];
}
/**
* Calculate points for this type.
*
* @param array $data The data available from the $event that triggered this action
* @param array $values The point values available, indexed per forum_id and 0 for global values
* @retrun void
*/
public function calculate($data, $values)
{
$value = $values[0];
$logs = $this->get_data();
foreach (array_keys($this->users) as $user_id)
{
$mode = $user_id == $this->user->data['user_id'] ? 'mod' : 'user';
$points = [
'points' => (double) $value['aps_' . $mode . '_warn'],
'logs' => [$logs['aps_' . $mode . '_warn'] => $value['aps_' . $mode . '_warn']],
];
$this->add($user_id, $points);
}
}
}

View File

@@ -1,117 +0,0 @@
{% include 'overall_header.html' %}
{% INCLUDECSS '@phpbbstudio_aps/css/aps_form.css' %}
<h1>{{ PAGE_TITLE }}</h1>
<p>{{ lang('ACP_APS_DISPLAY_EXPLAIN', aps_name()) }}</p>
{% if S_ERROR %}
<div class="errorbox">
<h3>{{ lang('WARNING') }}</h3>
<p>{{ ERROR_MSG }}</p>
</div>
{% endif %}
<form class="aps-form" id="aps_display" name="aps_display" action="{{ U_ACTION }}" method="post">
{% EVENT phpbbstudio_aps_acp_display_before %}
<fieldset>
<legend>{{ lang('GENERAL_SETTINGS') }}</legend>
{% EVENT phpbbstudio_aps_acp_display_prepend %}
<dl>
<dt>
<label for="aps_display_top_change_yes">{{ lang('ACP_APS_DISPLAY_TOP_CHANGE') }}</label><br />
<span class="explain">{{ lang('ACP_APS_DISPLAY_TOP_CHANGE_DESC') }}</span>
</dt>
<dd>
<label>
<input class="radio aps-bool" id="aps_display_top_change_yes" name="aps_display_top_change" value="1" type="radio"{{ APS_DISPLAY_TOP_CHANGE ? ' checked' : '' }} />
<span class="aps-button-green">{{ lang('YES') }}</span>
</label>
<label>
<input class="radio aps-bool" id="aps_display_top_change_no" name="aps_display_top_change" value="0" type="radio"{{ APS_DISPLAY_TOP_CHANGE ? '' : ' checked' }} />
<span class="aps-button-red">{{ lang('NO') }}</span>
</label>
</dd>
</dl>
<dl>
<dt>
<label for="aps_display_top_count">{{ lang('ACP_APS_DISPLAY_TOP_COUNT') }}</label><br />
<span class="explain">{{ lang('ACP_APS_DISPLAY_TOP_COUNT_DESC') }}</span>
</dt>
<dd><input class="autowidth" id="aps_display_top_count" name="aps_display_top_count" type="number" value="{{ APS_DISPLAY_TOP_COUNT }}" min="1" required /></dd>
</dl>
<dl>
<dt>
<label for="aps_display_adjustments">{{ lang('ACP_APS_DISPLAY_ADJUSTMENTS') }}</label><br />
<span class="explain">{{ lang('ACP_APS_DISPLAY_ADJUSTMENTS_DESC') }}</span>
</dt>
<dd><input class="autowidth" id="aps_display_adjustments" name="aps_display_adjustments" type="number" value="{{ APS_DISPLAY_ADJUSTMENTS }}" min="1" required /></dd>
</dl>
<dl>
<dt>
<label for="aps_display_graph_time">{{ lang('ACP_APS_DISPLAY_GRAPH_TIME') }}</label><br />
<span class="explain">{{ lang('ACP_APS_DISPLAY_GRAPH_TIME_DESC') }}</span>
</dt>
<dd><input class="autowidth" id="aps_display_graph_time" name="aps_display_graph_time" type="number" min="0" value="{{ APS_DISPLAY_GRAPH_TIME }}" required /></dd>
</dl>
{% EVENT phpbbstudio_aps_acp_display_append %}
</fieldset>
{% EVENT phpbbstudio_aps_acp_display_after %}
<fieldset class="aps-pages notice" data-aps-sortable="true">
{% for page in aps_pages %}
<fieldset>
<dl>
<dt><strong>{{ page.TITLE }}</strong></dt>
<dd>
<label>
<span class="aps-button-blue"><i class="icon fa-arrows-v fa-fw"></i></span>
</label>
</dd>
</dl>
<fieldset data-aps-sortable="true">
{% for block in page.blocks %}
<dl>
<dt><strong>{{ block.TITLE }}</strong></dt>
<dd>
<label>
<input class="radio aps-bool" name="aps_blocks[{{ page.ID }}][{{ loop.index }}]" value="{{ block.ID }}" type="radio"{{ block.S_ACTIVE ? ' checked' : '' }} />
<span class="aps-button-green">{{ lang('ENABLED') }}</span>
</label>
<label>
<input class="radio aps-bool" name="aps_blocks[{{ page.ID }}][{{ loop.index }}]" value="" type="radio"{{ block.S_ACTIVE ? '' : ' checked' }} />
<span class="aps-button-red">{{ lang('DISABLED') }}</span>
</label>
<label>
<span class="aps-button-blue"><i class="icon fa-arrows-v fa-fw"></i></span>
</label>
</dd>
</dl>
{% endfor %}
</fieldset>
</fieldset>
{% endfor %}
</fieldset>
<fieldset>
<legend>{{ lang('ACP_SUBMIT_CHANGES') }}</legend>
<p class="submit-buttons">
<input class="button1" id="submit" name="submit" type="submit" value="{{ lang('SUBMIT') }}">&nbsp;
<input class="button2" id="reset" name="reset" type="reset" value="{{ lang('RESET') }}">
{{ S_FORM_TOKEN }}
</p>
</fieldset>
</form>
{% INCLUDEJS '@phpbbstudio_aps/js/jquery-ui-sortable.min.js' %}
{% INCLUDEJS '@phpbbstudio_aps/js/aps_display.js' %}
{% include 'overall_footer.html' %}

View File

@@ -1,81 +0,0 @@
{% macro location(name, status) %}
<label class="aps-location"><input id="{{ name }}" name="{{ name }}" value="1" type="checkbox"{% if status %} checked{% endif %}><span class="aps-button-green">{{ lang('YES') }}</span><span class="aps-button-red">{{ lang('NO') }}</span></label>
{% endmacro %}
{% from _self import location as location %}
{% INCLUDECSS '@phpbbstudio_aps/css/aps_locations.css' %}
<fieldset class="quick"><a href="{{ U_ACTION }}"><i class="icon fa-reply fa-fw" aria-hidden="true"></i> <span>{{ lang('BACK_TO_PREV') }}</span></a></fieldset>
<form class="aps-form" id="aps_settings" name="aps_settings" action="{{ U_ACTION }}" method="post">
<div class="aps-locations">
<div class="navbar">
<ul>
<li class="has-dropdown">
<i class="icon fa-bars fa-fw" aria-hidden="true"></i> <span>{{ lang('QUICK_LINKS') }}</span>
<div class="dropdown quick-links">
<div class="pointer"></div>
<div class="dropdown-contents">
<div>{{ location('navbar_header_quick_links_before', navbar_header_quick_links_before) }}</div>
<div>{{ lang('QUICK_LINKS') }}</div>
<div>{{ location('navbar_header_quick_links_after', navbar_header_quick_links_after) }}</div>
</div>
</div>
</li>
<li>{{ location('overall_header_navigation_prepend', overall_header_navigation_prepend) }}</li>
<li><i class="icon fa-info-circle fa-fw" aria-hidden="true"></i> <span>{{ lang('FAQ') }}</span></li>
<li>{{ location('overall_header_navigation_append', overall_header_navigation_append) }}</li>
<li><i class="icon fa-cogs fa-fw" aria-hidden="true"></i> <span>{{ lang('ACP_SHORT') }}</span></li>
<li class="right-side">{{ location('navbar_header_user_profile_prepend', navbar_header_user_profile_prepend) }}</li>
<li class="right-side has-dropdown">
<i class="icon fa-user-circle-o fa-fw" aria-hidden="true"></i> <span>{{ USERNAME }}</span>
<div class="dropdown user">
<div class="pointer"></div>
<div class="dropdown-contents">
<div>{{ location('navbar_header_profile_list_before', navbar_header_profile_list_before) }}</div>
<div>{{ lang('UCP') }}</div>
<div>{{ lang('READ_PROFILE') }}</div>
<div>{{ location('navbar_header_profile_list_after', navbar_header_profile_list_after) }}</div>
<div>{{ lang('LOGOUT') }}</div>
</div>
</div>
</li>
<li class="right-side"><i class="icon fa-inbox fa-fw" aria-hidden="true"></i> <span>{{ lang('PRIVATE_MESSAGES') }}</span></li>
<li class="right-side"><i class="icon fa-bell fa-fw" aria-hidden="true"></i> <span>{{ lang('NOTIFICATIONS') }}</span></li>
<li class="right-side">{{ location('navbar_header_user_profile_append', navbar_header_user_profile_append) }}</li>
</ul>
</div>
<p>{{ lang('ACP_APS_LOCATIONS_EXPLAIN') }}</p>
<div class="navbar clearfix">
<ul>
<li><i class="icon fa-home fa-fw" aria-hidden="true"></i> <span>{{ lang('FORUM_INDEX') }}</span></li>
<li>{{ location('overall_footer_breadcrumb_append', overall_footer_breadcrumb_append) }}</li>
<li class="right-side">{{ location('overall_footer_timezone_before', overall_footer_timezone_before) }}</li>
<li class="right-side"><span>{{ lang('ALL_TIMES', "now"|date('TO'), "now"|date('e')) }}</span></li>
<li class="right-side">{{ location('overall_footer_timezone_after', overall_footer_timezone_after) }}</li>
<li class="right-side"><i class="icon fa-trash fa-fw" aria-hidden="true"></i> <span>{{ lang('DELETE_COOKIES') }}</span></li>
<li class="right-side"><i class="icon fa-users fa-fw" aria-hidden="true"></i> <span>{{ lang('MEMBERLIST') }}</span></li>
<li class="right-side">{{ location('overall_footer_teamlink_before', overall_footer_teamlink_before) }}</li>
<li class="right-side"><i class="icon fa-shield fa-fw" aria-hidden="true"></i> <span>{{ lang('THE_TEAM') }}</span></li>
<li class="right-side">{{ location('overall_footer_teamlink_after', overall_footer_teamlink_after) }}</li>
<li class="right-side"><i class="icon fa-envelope fa-fw" aria-hidden="true"></i> <span>{{ lang('CONTACT_US') }}</span></li>
</ul>
</div>
</div>
<fieldset>
<legend>{{ lang('ACP_SUBMIT_CHANGES') }}</legend>
<p class="submit-buttons">
<input type="hidden" name="action" value="locations">
<button class="aps-button-green" type="submit" name="submit_locations"><i class="icon fa-paper-plane fa-fw" aria-hidden="true"></i> <span>{{ lang('SUBMIT') }}</span></button>
<button class="aps-button-red" type="reset" name="reset"><i class="icon fa-refresh fa-fw" aria-hidden="true"></i> <span>{{ lang('RESET') }}</span></button>
</p>
</fieldset>
<fieldset class="quick">
<a href="{{ U_ACTION }}"><i class="icon fa-reply fa-fw" aria-hidden="true"></i> <span>{{ lang('BACK_TO_PREV') }}</span></a>
</fieldset>
</form>

View File

@@ -1,42 +0,0 @@
{% include 'overall_header.html' %}
{% INCLUDECSS '@phpbbstudio_aps/css/aps_common.css' %}
<h1>{{ PAGE_TITLE }}</h1>
<p>{{ lang('ACP_APS_LOGS_EXPLAIN', aps_name()) }}</p>
<form id="aps_logs" name="aps_logs" action="{{ U_ACTION }}" method="post">
<fieldset class="display-options search-box">
<label for="keywords">{{ lang('SEARCH_KEYWORDS') ~ lang('COLON') }}</label> <input type="text" id="keywords" name="keywords" value="{{ S_KEYWORDS }}" />&nbsp;<input type="submit" class="button2" name="filter" value="{{ lang('SEARCH') }}" />
</fieldset>
{% if pagination %}
<div class="pagination top-pagination">
{% include 'pagination.html' %}
</div>
{% endif %}
{% include '@phpbbstudio_aps/aps_logs_list.html' with {'s_include_mark': true} %}
{% if pagination %}
<div class="pagination">
{% include 'pagination.html' %}
</div>
{% endif %}
<fieldset class="display-options">
{{ lang('DISPLAY_LOG') ~ lang('COLON') }} {{ S_LIMIT_DAYS }} &nbsp;
{{ lang('SORT_BY') ~ lang('COLON') }} {{ S_SORT_KEY }} {{ S_SORT_DIR }}
<input class="button2" type="submit" value="{{ lang('GO') }}" name="sort" />
{{ S_FORM_TOKEN }}
</fieldset>
<hr>
<fieldset class="quick">
<input class="button2" type="submit" name="del_all" value="{{ lang('DELETE_ALL') }}" />&nbsp;
<input class="button2" type="submit" name="del_marked" value="{{ lang('DELETE_MARKED') }}" /><br />
<p class="small"><a href="#" onclick="marklist('aps_logs', 'mark', true); return false;">{{ lang('MARK_ALL') }}</a> &bull; <a href="#" onclick="marklist('aps_logs', 'mark', false); return false;">{{ lang('UNMARK_ALL') }}</a></p>
</fieldset>
</form>
{% include 'overall_footer.html' %}

View File

@@ -1,50 +0,0 @@
<table class="table1 zebra-table fixed-width-table">
<thead>
<tr>
<th class="aps-logs-user">{{ lang('USERNAME') }}</th>
<th class="aps-logs-time">{{ lang('TIME') }}</th>
<th class="aps-logs-points centered-text">{{ lang('APS_POINTS_OLD', aps_name()) }}</th>
<th class="aps-logs-points centered-text">{{ lang('APS_POINTS_DIFF', aps_name()) }}</th>
<th class="aps-logs-points centered-text">{{ lang('APS_POINTS_NEW', aps_name()) }}</th>
<th>{{ lang('ACTION') }}</th>
{% if s_include_mark %}
<th class="aps-logs-mark actions">{{ lang('MARK') }}</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for log in logs %}
<tr>
<td>{{ log.USER }}{% if not log.S_SELF and log.REPORTEE %}<br>&raquo; {{ lang('FROM') ~ ' ' ~ log.REPORTEE }}{% endif %}</td>
<td>{{ user.format_date(log.TIME) }}</td>
<td class="centered-text">{{ aps_display(log.POINTS_OLD, false) }}</td>
<td class="centered-text {{ log.POINTS_SUM > 0 ? 'yes' : 'never' }}">{{ aps_display(log.POINTS_SUM, false) }}</td>
<td class="centered-text">{{ aps_display(log.POINTS_NEW, false) }}<br></td>
<td>
<span class="aps-logs-edit" onclick="phpbb.toggleDisplay('aps-logs-info-{{ loop.index }}', 0)"><i class="icon fa-info-circle fa-fw" aria-hidden="true"></i></span>
<strong class="aps-logs-action">{{ lang(log.ACTION, aps_name()) }}</strong>
<div id="aps-logs-info-{{ loop.index }}" class="hidden">
{% for action, points in log.ACTIONS %}
&raquo; {{ lang(action, aps_name()) }}: {{ aps_display(points, false) }}<br>
{% endfor %}
{% if log.U_POINTS %}<a class="button2 aps-logs-edit" href="{{ log.U_POINTS }}">{{ aps_icon() }} {{ lang('EDIT') }}</a>{% endif %}
</div>
{% if log.FORUM_NAME %}&raquo; <a href="{{ log.U_FORUM }}" title="{{ lang('FORUM') }}">{{ log.FORUM_NAME }}</a>{% endif %}
{% if log.TOPIC_TITLE %}&raquo; <a href="{{ log.U_TOPIC }}" title="{{ lang('TOPIC') }}">{{ log.TOPIC_TITLE }}</a>{% endif %}
{% if log.POST_SUBJECT %}&raquo; <a href="{{ log.U_POST }}" title="{{ lang('POST') }}">{{ log.POST_SUBJECT }}</a>{% endif %}
</td>
{% if s_include_mark %}
<td class="aps-logs-mark actions"><label for="mark_{{ log.ID }}"><input class="checkbox" id="mark_{{ log.ID }}" name="mark[]" type="checkbox" title="{{ lang('MARK') }}" value="{{ log.ID }}" /></label></td>
{% endif %}
</tr>
{% else %}
<tr>
<td colspan="{{ s_include_mark ? 7 : 6 }}">
<div class="errorbox">
<p>{{ lang('NO_ENTRIES') }}</p>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>

View File

@@ -1,99 +0,0 @@
{% include 'overall_header.html' %}
{% INCLUDECSS '@phpbbstudio_aps/css/aps_common.css' %}
{% INCLUDECSS '@phpbbstudio_aps/css/aps_form.css' %}
<h1>{{ APS_TITLE }}</h1>
<p>{{ lang('ACP_APS_POINTS_EXPLAIN', aps_name()) }}</p>
<form class="aps-form" id="acp_aps_points" name="acp_aps_points" method="post" action="{{ U_APS_ACTION }}">
<fieldset{% if S_APS_ACTION not in ['add', 'edit'] %} class="panel"{% endif %}>
{% if S_ERRORS %}
<div class="errorbox"><p class="error">{{ ERROR_MSG }}</p></div>
{% endif %}
{% if S_APS_ACTION in ['add', 'edit'] %}
{% if S_APS_REASONS %}
<dl>
<dt><label for="title">{{ lang('SUBJECT') }}</label></dt>
<dd><input class="medium" id="title" name="title" type="text" value="{{ REASON_TITLE }}" required></dd>
</dl>
<dl>
<dt><label for="description">{{ lang('REASON') }}</label></dt>
<dd>
<textarea class="inputbox" id="description" name="description">{{ REASON_DESC }}</textarea>
</dd>
</dl>
<dl>
<dt><label for="points">{{ aps_name() }}</label></dt>
<dd><input class="tiny" id="points" name="points" type="number" value="{{ REASON_POINTS }}" step="0.01" required></dd>
</dl>
{% endif %}
{% else %}
{% if S_APS_REASONS %}
<table class="table1 forums responsive">
<thead>
<tr>
<th class="centered-text">{{ aps_name() }}</th>
<th>{{ lang('REASON') }}</th>
<th class="centered-text">{{ lang('ACTIONS') }}</th>
</tr>
</thead>
<tbody>
{% for reason in aps_reasons %}
<tr>
<td class="actions {{ reason.POINTS > 0 ? 'yes' : 'never' }}">
{{ aps_format(reason.POINTS) }}
</td>
<td>
<strong>{{ reason.TITLE }}</strong><br />
{{ reason.DESC }}
</td>
<td class="actions">
<span class="up-disabled hidden">{{ ICON_MOVE_UP_DISABLED }}</span>
<span class="up"><a href="{{ reason.U_MOVE_UP }}" data-ajax="row_up">{{ ICON_MOVE_UP }}</a></span>
<span class="down-disabled hidden">{{ ICON_MOVE_DOWN_DISABLED }}</span>
<span class="down"><a href="{{ reason.U_MOVE_DOWN }}" data-ajax="row_down">{{ ICON_MOVE_DOWN }}</a></span>
<a href="{{ reason.U_EDIT }}">{{ ICON_EDIT }}</a>
<a href="{{ reason.U_DELETE }}" data-ajax="row_delete">{{ ICON_DELETE }}</a>
</td>
</tr>
{% else %}
<tr>
<td class="centered-text" colspan="3">{{ lang('ACP_NO_ITEMS') }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<hr />
<fieldset class="quick">
<a class="aps-button-green" href="{{ U_APS_REASON_ADD }}">{{ lang('ADD') }}</a>
</fieldset>
</fieldset>
<fieldset>
{% endif %}
{% if S_APS_POINTS %}
<legend>{{ aps_name() }}</legend>
{% include '@phpbbstudio_aps/aps_points_list.html' %}
{% endif %}
{% endif %}
</fieldset>
<fieldset>
<legend>{{ lang('ACP_SUBMIT_CHANGES') }}</legend>
<p class="submit-buttons">
<input class="button1" id="submit" name="submit" type="submit" value="{{ lang('SUBMIT') }}">&nbsp;
<input class="button2" id="reset" name="reset" type="reset" value="{{ lang('RESET') }}">
{{ S_FORM_TOKEN }}
</p>
</fieldset>
</form>
{% include 'overall_footer.html' %}

View File

@@ -1,37 +0,0 @@
<form class="aps-form" id="aps_points_copy" name="aps_points_copy" method="post" action="{{ U_APS_ACTION_COPY }}" data-ajax="true">
<div class="centered-text clearfix">
<div class="column1">
<h5>{{ lang('ACP_APS_POINTS_COPY', aps_name()) }}</h5>
<hr />
<label>
<select id="aps_forums_from" name="aps_forums_from">
{{ S_APS_FORUMS }}
</select>
</label>
</div>
<div class="column2">
<h5>{{ lang('ACP_APS_POINTS_COPY_TO', aps_name()) }}</h5>
<hr />
<label>
<select id="aps_forums_to" name="aps_forums_to[]" multiple>
{{ S_APS_FORUMS }}
</select>
</label>
<p><em>{{ lang('LOOK_UP_FORUMS_EXPLAIN') }}</em></p>
</div>
</div>
<fieldset class="submit-buttons">
<hr />
{{ S_FORM_TOKEN }}
<input class="button1" id="submit_copy" name="submit_copy" type="submit" value="{{ lang('SUBMIT') }}">&nbsp;
<input class="button2" id="reset" name="reset" type="reset" value="{{ lang('RESET') }}">
</fieldset>
</form>
<script>
phpbb.ajaxify({
selector: '#aps_points_copy',
refresh: false,
callback: null,
});
</script>

View File

@@ -1,17 +0,0 @@
<div id="aps_points" class="aps-tabs aps-form">
{% for category in aps_categories %}
<input class="aps-tab-input" id="aps-tab-{{ loop.index }}" name="aps-tabs" type="radio"{% if loop.first %} checked{% endif %}>
<label class="aps-tab-label" for="aps-tab-{{ loop.index }}">{{ lang(category.title) }}</label>
<fieldset class="aps-tab-panel">
{% for fields in category.blocks %}
{% for field, title in fields %}
<dl>
<dt><label for="{{ field }}">{{ lang(title, aps_name()) ~ lang('COLON') }}</label>{% if lang(title ~ '_DESC') != title ~ '_DESC' %}<br><span class="explain">{{ lang(title ~ '_DESC', aps_name()) }}</span>{% endif %}</dt>
<dd><input class="autowidth" id="{{ field }}" name="aps_values[{{ field }}]" type="number" value="{{ aps_format(APS_VALUES[field]) }}" step="{{ aps_step() }}"></dd>
</dl>
{% endfor %}
{% if not loop.last %}<hr>{% endif %}
{% endfor %}
</fieldset>
{% endfor %}
</div>

View File

@@ -1,54 +0,0 @@
{% include 'overall_header.html' %}
{% INCLUDECSS '@phpbbstudio_aps/css/fontawesome-iconpicker.min.css' %}
{% INCLUDECSS '@phpbbstudio_aps/css/aps_common.css' %}
{% INCLUDECSS '@phpbbstudio_aps/css/aps_form.css' %}
{% INCLUDECSS '@phpbbstudio_aps/css/aps_iconpicker.css' %}
<h1>{{ PAGE_TITLE }}</h1>
<p>{{ lang('ACP_APS_SETTINGS_EXPLAIN', aps_name()) }}</p>
{% if S_ERROR %}
<div class="errorbox">
<h3>{{ lang('WARNING') }}</h3>
<p>{{ ERROR_MSG }}</p>
</div>
{% endif %}
{% if S_APS_COPY %}
{% include '@phpbbstudio_aps/aps_points_copy.html' %}
{% elseif S_APS_LOCATIONS %}
{% include '@phpbbstudio_aps/aps_locations.html' %}
{% else %}
<form class="aps-form" id="aps_settings" name="aps_settings" action="{{ U_ACTION }}" method="post">
{% for setting in settings %}
{% if setting.S_LEGEND %}
{% if not loop.first %}</fieldset>{% endif %}
<fieldset class="{{ setting.CLASS }}">
<legend>{{ lang(setting.LEGEND, aps_name()) }}</legend>
{% else %}
<dl>
<dt><label for="{{ setting.KEY }}">{{ lang(setting.TITLE, aps_name()) }}</label>{% if setting.S_EXPLAIN %}<br><span class="explain">{{ lang(setting.TITLE ~ '_DESC', aps_name()) }}</span>{% endif %}</dt>
<dd>{{ setting.CONTENT }}</dd>
</dl>
{% endif %}
{% if loop.last %}</fieldset>{% endif %}
{% endfor %}
<fieldset>
<legend>{{ lang('ACP_SUBMIT_CHANGES') }}</legend>
<p class="submit-buttons">
<input class="button1" id="submit" name="submit" type="submit" value="{{ lang('SUBMIT') }}">&nbsp;
<input class="button2" id="reset" name="reset" type="reset" value="{{ lang('RESET') }}">
{{ S_FORM_TOKEN }}
</p>
</fieldset>
</form>
{% endif %}
{% INCLUDEJS '@phpbbstudio_aps/js/fontawesome-iconpicker.min.js' %}
{% INCLUDEJS '@phpbbstudio_aps/js/aps_common.js' %}
{% include 'overall_footer.html' %}

View File

@@ -1,115 +0,0 @@
.nojs .aps-ajax {
display: none;
}
.aps-tabs {
background: #e5e5e5;
border-top: 1px solid #d7d7d7;
border-right: 1px solid #cccccc;
border-bottom: 1px solid #cccccc;
border-left: 1px solid #d7d7d7;
border-radius: 3px;
display: flex;
flex-wrap: wrap;
}
.aps-tab-input {
opacity: 0;
position: absolute;
}
.aps-tab-label {
font-size: 1.2em;
font-weight: bold;
background: #e5e5e5;
border-right: 1px solid transparent;
border-left: 1px solid transparent;
color: #7f7f7f;
width: 100%;
padding: 10px 20px;
cursor: pointer;
transition: all 0.2s ease-in;
}
.aps-tab-label:first-of-type { border-top-left-radius: 3px; }
.aps-tab-label:last-of-type { border-top-right-radius: 3px; }
.aps-tab-label:hover { background: #d8d8d8; }
.aps-tab-label:active { background: #cccccc; }
.aps-tab-input:checked + .aps-tab-label {
background: #ffffff;
border-color: #cccccc;
color: #000000;
}
.aps-tab-input:checked:first-of-type + .aps-tab-label {
border-left-color: transparent;
}
@media (min-width: 600px) {
.aps-tab-label {
width: auto;
}
}
.aps-tab-panel {
background: #ffffff;
border: none;
border-top-left-radius: 0;
border-top-right-radius: 0;
display: none;
width: 100%;
margin: 0;
}
@media (min-width: 600px) {
.aps-tab-panel {
order: 99;
}
}
.aps-tab-input:checked + .aps-tab-label + .aps-tab-panel {
display: block;
}
.aps-tabs h3 {
font-size: 1.2em;
color: #115098;
margin: 5px 0 10px;
}
.aps-tabs small {
font-size: 90%;
}
/* aps logs */
table th.aps-logs-mark,
table td.aps-logs-mark { width: 50px; }
.aps-logs-user { width: 15%; }
.aps-logs-time { width: 20%; }
.aps-logs-points { width: 10%; }
.aps-logs-action {
display: block;
}
.aps-logs-edit {
font-size: 120%;
text-decoration: none;
float: right;
margin-right: 5px;
}
.aps-logs-mark label {
display: block;
padding: 0;
}
@media all and (max-width: 700px) {
.aps-logs-edit {
margin-right: 0;
}
.aps-logs-mark label {
display: inline-block;
}
}

View File

@@ -1,211 +0,0 @@
.aps-form *,
.aps-form *:before,
.aps-form *:after {
box-sizing: border-box;
}
.aps-bool {
display: none;
}
.aps-radio { display: none; }
.aps-radio:checked + .aps-button-blue {
background: #12a3eb;
border-color: #12a3eb;
color: #ffffff;
}
/* Fix for double borders due to border-box */
.aps-form dt {
border-right: none;
}
.aps-form dd,
.aps-form dd label {
font-size: 14px;
line-height: 1.42857143;
}
.aps-form dd label {
display: inline-block;
height: 34px;
padding: 6px 6px 6px 0;
}
.aps-form dd label input[type="radio"] {
height: initial;
margin-right: 3px;
}
.aps-button-red,
.aps-button-blue,
.aps-button-green,
.aps-form input:not(.iconpicker-search),
.aps-form select,
.aps-form textarea {
font-size: 14px;
line-height: 1.42857143;
color: #555555;
height: 34px;
padding: 6px 12px;
}
.aps-button-red,
.aps-button-blue,
.aps-button-green,
.aps-form input[type="text"],
.aps-form input[type="number"],
.aps-form input[type="submit"],
.aps-form input[type="reset"],
.aps-form select,
.aps-form textarea {
background-color: #ffffff;
background-image: none;
border: 1px solid #cccccc;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-webkit-transition: border-color ease-in-out 0.15s, -webkit-box-shadow ease-in-out 0.15s;
-o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
}
.aps-form input:not([type="checkbox"]):not([type="radio"]):focus,
.aps-form select:focus,
.aps-form textarea:focus {
border-color: #66afe9;
outline: 0;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
}
.aps-form select:focus {
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.aps-form select[multiple] {
height: auto;
min-height: 170px;
}
.has-js select[multiple] {
max-height: 340px;
}
.aps-form textarea {
height: auto;
resize: vertical;
}
/* Buttons */
.aps-button-green,
a.aps-button-green,
.aps-form input[type="submit"] {
border-color: #28a745;
color: #28a745;
}
.aps-bool:checked + .aps-button-green,
.aps-button-green:hover,
a.aps-button-green:hover,
.aps-form input[type="submit"]:hover {
background-color: #28a745;
color: #ffffff;
}
.aps-button-red,
a.aps-button-red,
.aps-form input[type="reset"] {
border-color: #d31141;
color: #d31141;
}
.aps-bool:checked + .aps-button-red,
.aps-button-red:hover,
a.aps-button-red:hover,
.aps-form input[type="reset"]:hover {
background-color: #d31141;
color: #ffffff;
}
.aps-button-blue {
border-color: #12a3eb;
color: #12a3eb;
}
.aps-button-blue:hover {
background-color: #12a3eb;
color: #ffffff;
}
.aps-button-red,
.aps-button-blue,
.aps-button-green {
text-decoration: none !important;
cursor: pointer;
}
/* Point names height toggle */
.aps-points-names {
overflow: hidden;
max-height: 100px;
padding-bottom: 20px;
}
.aps-points-names dl:not(:first-of-type) {
opacity: 0;
}
.aps-points-full {
max-height: 100%;
padding-bottom: 30px;
}
.aps-points-full dl:not(:first-of-type) {
opacity: 1;
}
@media all and (max-width: 700px) {
fieldset.aps-points-names:not(.aps-points-full) dl:first-of-type {
border-bottom: none;
}
}
.aps-names-toggle {
font-weight: bold;
text-decoration: none !important;
border: 1px solid #cccccc;
border-bottom: none;
border-radius: 4px 4px 0 0;
opacity: 1;
position: absolute;
z-index: 1;
bottom: 0;
left: 45%;
padding: 5px 10px;
cursor: pointer;
user-select: none;
transform: translateX(-50%);
}
/* Multiple select scrollbar */
.aps-form select[multiple] {
scrollbar-color: #666666 #cccccc;
scrollbar-width: 10px;
}
.aps-form select[multiple]::-webkit-scrollbar {
width: 10px;
}
.aps-form select[multiple]::-webkit-scrollbar-thumb {
background: #666666;
border-radius: 0 4px 4px 0;
}
.aps-form select[multiple]::-webkit-scrollbar-track {
background: #cccccc;
border-radius: 0 4px 4px 0;
}

View File

@@ -1,78 +0,0 @@
.aps-icon-picker,
#aps_points_icon {
border-top-right-radius: 0 !important;
border-bottom-right-radius: 0 !important;
}
.aps-icon-picker + i,
#aps_points_icon + i {
font-size: 14px;
line-height: 1.42857143;
vertical-align: -1px;
background-color: #f3f3f3;
border: 1px solid #cccccc;
border-left: none;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
color: #555555;
display: inline-block;
width: auto;
height: 34px;
padding: 6px 12px;
cursor: pointer;
}
.aps-icon-picker:focus,
#aps_points_icon:focus {
border-right-color: #cccccc;
}
.aps-icon-picker:focus + i,
#aps_points_icon:focus + i {
border-color: #66afe9;
outline: 0;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
}
.iconpicker-popover.popover {
border: 1px solid #cccccc;
border-radius: 4px;
}
.iconpicker-popover .arrow:after {
border-bottom-color: #f7f7f7 !important;
}
.iconpicker-popover .iconpicker-item {
margin: 0 11px 11px 0;
}
.iconpicker-search,
.iconpicker-search:hover,
.iconpicker-search:focus {
background-color: #ffffff;
border-radius: 4px;
max-width: calc(100% - 16px);
padding: 5px 8px;
}
.iconpicker-popover ::-webkit-scrollbar {
background: transparent;
width: 5px;
height: 5px;
}
.iconpicker-popover ::-webkit-scrollbar-corner {
background: transparent;
}
.iconpicker-popover ::-webkit-scrollbar-thumb {
background: #333333;
border-radius: 10px;
}
.iconpicker-popover ::-webkit-scrollbar-track {
background: #f3f3f3;
border-radius: 10px;
}

View File

@@ -1,94 +0,0 @@
.aps-locations {
background-color: #ffffff;
border: 1px solid #e6e9ed;
border-radius: 8px;
padding: 15px;
}
.aps-locations > p {
text-align: center;
margin: 5rem 160px;
}
.aps-location input {
display: none;
}
.aps-location input ~ span {
line-height: 16px;
text-align: center;
color: #ffffff;
display: none;
min-width: 50px;
height: 30px;
}
.aps-location input:not(:checked) ~ .aps-button-red,
.aps-location input:checked ~ .aps-button-green { display: inline-block; }
.aps-location .aps-button-green { background-color: #28a745; }
.aps-location .aps-button-red { background-color: #d31141; }
.navbar {
background-color: #cadceb;
border-radius: 7px;
overflow: visible;
height: 40px;
padding: 3px 10px;
}
.navbar > ul {
display: block;
margin: 0;
padding: 2px 0;
list-style-type: none;
}
.navbar > ul > li {
font-size: 1.1em;
line-height: 2.2em;
float: left;
width: auto;
margin-right: 7px;
padding-top: 1px;
list-style-type: none;
}
.navbar > ul > .right-side {
text-align: right;
float: right;
margin-right: 0;
margin-left: 7px;
}
.has-dropdown {
position: relative;
}
.dropdown {
text-align: left;
z-index: 10;
top: 25px;
min-width: 150px;
}
.dropdown.quick-links {
left: -15px;
}
.dropdown.user {
right: -10px;
left: unset;
}
.dropdown .pointer {
border-color: #ffffff transparent;
}
.dropdown.user .pointer {
right: 10px;
left: unset;
}
.dropdown .dropdown-contents {
padding: 10px 5px;
}

File diff suppressed because one or more lines are too long

View File

@@ -1,47 +0,0 @@
{% if S_APS_POINTS %}
<fieldset class="aps-form">
<legend>{{ aps_name() }}</legend>
{# We can only AJAX copy and reset if the forum already exists #}
{% if not S_ADD_ACTION %}
{# Include the JS file #}
{% INCLUDEJS '@phpbbstudio_aps/js/aps_forum.js' %}
<dl>
<dt><label for="aps_points_reset">{{ lang('ACP_APS_POINTS_RESET', aps_name()) }}</label><br><span>{{ lang('ACP_APS_POINTS_RESET_EXPLAIN', aps_name()) }}</span></dt>
<dd>
<noscript>
<label>
<input class="radio aps-bool" id="aps_points_reset" name="aps_points_reset" type="checkbox" value="1">
<span class="aps-button-red">{{ lang('RESET') }}</span>
</label>
</noscript>
<label class="aps-ajax">
<a class="aps-button-red" id="aps_points_reset_ajax" type="button" href="{{ U_APS_RESET }}" data-ajax="aps_points_reset">
{{ lang('RESET') }}
</a>
</label>
</dd>
</dl>
{% endif %}
<dl>
<dt><label for="aps_points_copy">{{ lang('ACP_APS_POINTS_COPY', aps_name()) }}</label><br><span>{{ lang('ACP_APS_POINTS_COPY_EXPLAIN', aps_name()) }}</span></dt>
<dd>
<select id="aps_points_copy" name="aps_points_copy">
<option value="0">{{ lang('ACP_APS_POINTS_COPY_NOT', aps_name()) }}</option>
{{ S_FORUM_OPTIONS }}
</select>
{% if not S_ADD_ACTION %}
<button class="aps-button-green aps-ajax" id="aps_points_copy_ajax" type="button">{{ lang('ACP_APS_POINTS_COPY_TITLE', aps_name()) }}</button>
{% endif %}
</dd>
</dl>
{% INCLUDECSS '@phpbbstudio_aps/css/aps_common.css' %}
{% INCLUDECSS '@phpbbstudio_aps/css/aps_form.css' %}
{% include '@phpbbstudio_aps/aps_points_list.html' %}
</fieldset>
{% endif %}

View File

@@ -1,4 +0,0 @@
<dl>
<dt><label>{{ aps_name() ~ lang('COLON') }}</label></dt>
<dd>{{ aps_display(APS_POINTS) }}</dd>
</dl>

View File

@@ -1,13 +0,0 @@
jQuery(function($) {
$('.aps-names-toggle').on('click', function() {
$(this).parents('fieldset').toggleClass('aps-points-full');
let altText = $(this).data('text');
$(this).data('text', $(this).text()).text(altText);
});
$('#aps_points_icon').iconpicker({
collision: true,
placement: 'bottomRight',
component: '#aps_points_icon + i',
});
});

View File

@@ -1,12 +0,0 @@
jQuery(function($) {
$('[data-aps-sortable]').sortable({
axis: 'y',
containment: $(this).selector,
cursor: 'move',
delay: 150,
handle: '.aps-button-blue',
forcePlaceholderSize: true,
placeholder: 'panel',
tolerance: 'pointer',
});
});

View File

@@ -1,83 +0,0 @@
jQuery(function($) {
let $button = $('#aps_points_copy_ajax'),
$select = $('#aps_points_copy'),
$form = $button.parents('form'),
action = $form.attr('action').replace('&amp;', '&');
let callback = 'aps_points_copy',
$dark = $('#darkenwrapper');
$button.on('click', function(e) {
/**
* Handler for AJAX errors
*/
function errorHandler(jqXHR, textStatus, errorThrown) {
if (typeof console !== 'undefined' && console.log) {
console.log('AJAX error. status: ' + textStatus + ', message: ' + errorThrown);
}
phpbb.clearLoadingTimeout();
let responseText, errorText = false;
try {
responseText = JSON.parse(jqXHR.responseText);
responseText = responseText.message;
} catch (e) {}
if (typeof responseText === 'string' && responseText.length > 0) {
errorText = responseText;
} else if (typeof errorThrown === 'string' && errorThrown.length > 0) {
errorText = errorThrown;
} else {
errorText = $dark.attr('data-ajax-error-text-' + textStatus);
if (typeof errorText !== 'string' || !errorText.length) {
errorText = $dark.attr('data-ajax-error-text');
}
}
phpbb.alert($dark.attr('data-ajax-error-title'), errorText);
}
let request = $.ajax({
url: action,
type: 'post',
data: {'aps_action': 'copy', 'aps_points_copy': $select.val()},
success: function(response) {
/**
* @param {string} response.MESSAGE_TITLE
* @param {string} response.MESSAGE_TEXT
*/
phpbb.alert(response.MESSAGE_TITLE, response.MESSAGE_TEXT);
if (typeof phpbb.ajaxCallbacks[callback] === 'function') {
phpbb.ajaxCallbacks[callback].call(this, response);
}
},
error: errorHandler,
cache: false
});
request.always(function() {
let $loadingIndicator = phpbb.loadingIndicator();
if ($loadingIndicator && $loadingIndicator.is(':visible')) {
$loadingIndicator.fadeOut(phpbb.alertTime);
}
});
e.preventDefault();
});
phpbb.addAjaxCallback('aps_points_copy', function(response) {
$select.val(0);
/**
* @param {array} response.APS_VALUES
*/
$.each(response.APS_VALUES, function(name, value) {
$('#' + name).val(value);
});
});
phpbb.addAjaxCallback('aps_points_reset', function() {
$('[name*="aps_values"]').each(function() {
$(this).val(0);
});
});
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,32 +0,0 @@
{
"name": "phpbbstudio/aps",
"type": "phpbb-extension",
"description": "A fully integrated and extendable points extension for the phpBB Forum Software.",
"homepage": "https://www.phpbbstudio.com",
"version": "1.0.6-RC",
"time": "2020-03-11",
"license": "GPL-2.0-only",
"authors": [
{
"name": "phpBB Studio",
"email": "info@phpbbstudio.com",
"homepage": "https://www.phpbbstudio.com",
"role": "Lead Developer"
}
],
"require": {
"php": ">=5.5.0",
"composer/installers": "~1.0"
},
"extra": {
"display-name": "phpBB Studio - Advanced Points System",
"soft-require": {
"phpbb/phpbb": ">=3.2.8,<4.0.0@dev"
},
"version-check": {
"host": "3d-i.github.io",
"directory": "/site/vchecks",
"filename": "advpoints.json"
}
}
}

View File

@@ -1,139 +0,0 @@
services:
# Service collection
phpbbstudio.aps.actions_collection:
class: phpbb\di\ordered_service_collection
arguments:
- '@service_container'
tags:
- { name: service_collection, tag: phpbbstudio.aps.action }
# Base class
phpbbstudio.aps.action.base:
abstract: true
# GLOBAL
phpbbstudio.aps.action.pm:
class: phpbbstudio\aps\actions\type\pm
shared: false
arguments:
- '@config'
- '@text_formatter.utils'
- '%phpbbstudio.aps.constants%'
tags:
- { name: phpbbstudio.aps.action, order: -4 }
phpbbstudio.aps.action.birthday:
class: phpbbstudio\aps\actions\type\birthday
shared: false
arguments:
- '@user'
tags:
- { name: phpbbstudio.aps.action, order: -3 }
phpbbstudio.aps.action.register:
class: phpbbstudio\aps\actions\type\register
shared: false
tags:
- { name: phpbbstudio.aps.action, order: -2 }
phpbbstudio.aps.action.warn:
class: phpbbstudio\aps\actions\type\warn
shared: false
arguments:
- '@user'
tags:
- { name: phpbbstudio.aps.action, order: -1 }
# LOCAL - Topic
phpbbstudio.aps.action.topic:
class: phpbbstudio\aps\actions\type\topic
shared: false
arguments:
- '@config'
- '@text_formatter.utils'
- '%phpbbstudio.aps.constants%'
tags:
- { name: phpbbstudio.aps.action, order: -4 }
# LOCAL - Post
phpbbstudio.aps.action.post:
class: phpbbstudio\aps\actions\type\post
shared: false
arguments:
- '@config'
- '@text_formatter.utils'
- '%phpbbstudio.aps.constants%'
tags:
- { name: phpbbstudio.aps.action, order: -3 }
# LOCAL - Moderate
phpbbstudio.aps.action.copy:
class: phpbbstudio\aps\actions\type\copy
shared: false
tags:
- { name: phpbbstudio.aps.action, order: -2 }
phpbbstudio.aps.action.change:
class: phpbbstudio\aps\actions\type\change
shared: false
tags:
- { name: phpbbstudio.aps.action, order: -2 }
phpbbstudio.aps.action.delete:
class: phpbbstudio\aps\actions\type\delete
shared: false
arguments:
- '@user'
tags:
- { name: phpbbstudio.aps.action, order: -2 }
phpbbstudio.aps.action.edit:
class: phpbbstudio\aps\actions\type\edit
shared: false
tags:
- { name: phpbbstudio.aps.action, order: -2 }
phpbbstudio.aps.action.lock:
class: phpbbstudio\aps\actions\type\lock
shared: false
arguments:
- '@user'
tags:
- { name: phpbbstudio.aps.action, order: -2 }
phpbbstudio.aps.action.merge:
class: phpbbstudio\aps\actions\type\merge
shared: false
arguments:
- '@user'
tags:
- { name: phpbbstudio.aps.action, order: -2 }
phpbbstudio.aps.action.move:
class: phpbbstudio\aps\actions\type\move
shared: false
arguments:
- '@user'
tags:
- { name: phpbbstudio.aps.action, order: -1 }
phpbbstudio.aps.action.queue:
class: phpbbstudio\aps\actions\type\queue
shared: false
arguments:
- '@user'
tags:
- { name: phpbbstudio.aps.action, order: -1 }
phpbbstudio.aps.action.topic_type:
class: phpbbstudio\aps\actions\type\topic_type
shared: false
tags:
- { name: phpbbstudio.aps.action, order: -1 }
# LOCAL - Misc.
phpbbstudio.aps.action.vote:
class: phpbbstudio\aps\actions\type\vote
shared: false
tags:
- { name: phpbbstudio.aps.action, order: 0 }

View File

@@ -1,21 +0,0 @@
parameters:
phpbbstudio.aps.constants:
ignore:
none: 0
both: 1
words: 2
chars: 3
locations:
navbar_header_quick_links_before: 1
navbar_header_quick_links_after: 2
navbar_header_user_profile_prepend: 4
navbar_header_user_profile_append: 8
navbar_header_profile_list_before: 16
navbar_header_profile_list_after: 32
overall_header_navigation_prepend: 64
overall_header_navigation_append: 128
overall_footer_breadcrumb_append: 256
overall_footer_timezone_before: 512
overall_footer_timezone_after: 1024
overall_footer_teamlink_before: 2048
overall_footer_teamlink_after: 4096

View File

@@ -1,5 +0,0 @@
parameters:
phpbbstudio.aps.tables.display: '%core.table_prefix%aps_display'
phpbbstudio.aps.tables.logs: '%core.table_prefix%aps_logs'
phpbbstudio.aps.tables.points: '%core.table_prefix%aps_points'
phpbbstudio.aps.tables.reasons: '%core.table_prefix%aps_reasons'

View File

@@ -1,17 +0,0 @@
phpbbstudio_aps_display_pagination:
path: /aps/{page}/page-{pagination}
defaults:
_controller: phpbbstudio.aps.controller.main:display
page: overview
requirements:
page: "^((?!shop|inventory|purchase).)*$"
pagination: \d+
phpbbstudio_aps_display:
path: /aps/{page}
defaults:
_controller: phpbbstudio.aps.controller.main:display
page: overview
pagination: 1
requirements:
page: "^((?!shop|inventory|purchase).)*$"

View File

@@ -1,73 +0,0 @@
imports:
- { resource: actions.yml }
- { resource: constants.yml }
- { resource: parameters.yml }
- { resource: services_controllers.yml }
- { resource: services_core.yml }
- { resource: services_listeners.yml }
services:
phpbbstudio.aps.manager:
class: phpbbstudio\aps\actions\manager
arguments:
- '@phpbbstudio.aps.actions_collection'
- '@phpbbstudio.aps.distributor'
- '@phpbbstudio.aps.functions'
- '@language'
- '@log'
- '@phpbbstudio.aps.valuator'
- '@user'
phpbbstudio.aps.blockader:
class: phpbbstudio\aps\points\blockader
arguments:
- '@dbal.conn'
- '%phpbbstudio.aps.tables.display%'
phpbbstudio.aps.distributor:
class: phpbbstudio\aps\points\distributor
arguments:
- '@config'
- '@dbal.conn'
- '@dispatcher'
- '@phpbbstudio.aps.functions'
- '@phpbbstudio.aps.log'
- '@user'
- '@phpbbstudio.aps.valuator'
phpbbstudio.aps.reasoner:
class: phpbbstudio\aps\points\reasoner
arguments:
- '@dbal.conn'
- '%phpbbstudio.aps.tables.reasons%'
phpbbstudio.aps.valuator:
class: phpbbstudio\aps\points\valuator
arguments:
- '@dbal.conn'
- '@phpbbstudio.aps.functions'
- '@user'
- '%phpbbstudio.aps.tables.points%'
phpbbstudio.aps.birthday:
class: phpbbstudio\aps\cron\task\birthday
arguments:
- '@config'
- '@dbal.conn'
- '@phpbbstudio.aps.functions'
- '@phpbbstudio.aps.manager'
calls:
- [set_name, [phpbbstudio.aps.cron.task.birthday]]
tags:
- { name: cron.task }
phpbbstudio.aps.notification.type.adjust:
class: phpbbstudio\aps\notification\type\adjust
shared: false # service MUST not be shared for this to work!
parent: notification.type.base
calls:
- [set_auth, ['@auth']]
- [set_controller_helper, ['@controller.helper']]
- [set_user_loader, ['@user_loader']]
tags:
- { name: notification.type }

View File

@@ -1,58 +0,0 @@
services:
phpbbstudio.aps.controller.acp:
class: phpbbstudio\aps\controller\acp_controller
arguments:
- '@phpbbstudio.aps.acp'
- '@auth'
- '@phpbbstudio.aps.blockader'
- '@config'
- '@phpbbstudio.aps.controller.main'
- '@dbal.conn'
- '@dispatcher'
- '@phpbbstudio.aps.functions'
- '@language'
- '@log'
- '@phpbbstudio.aps.log'
- '@pagination'
- '@phpbbstudio.aps.reasoner'
- '@request'
- '@template'
- '@user'
phpbbstudio.aps.controller.mcp:
class: phpbbstudio\aps\controller\mcp_controller
arguments:
- '@auth'
- '@config'
- '@dbal.conn'
- '@dispatcher'
- '@phpbbstudio.aps.distributor'
- '@phpbbstudio.aps.functions'
- '@group_helper'
- '@language'
- '@phpbbstudio.aps.log'
- '@notification_manager'
- '@pagination'
- '@phpbbstudio.aps.reasoner'
- '@request'
- '@template'
- '@user'
- '@phpbbstudio.aps.valuator'
- '%core.root_path%'
- '%core.php_ext%'
phpbbstudio.aps.controller.main:
class: phpbbstudio\aps\controller\main_controller
arguments:
- '@auth'
- '@phpbbstudio.aps.blockader'
- '@phpbbstudio.aps.blocks'
- '@dispatcher'
- '@phpbbstudio.aps.functions'
- '@controller.helper'
- '@language'
- '@request'
- '@template'
- '@user'
- '%core.root_path%'
- '%core.php_ext%'

View File

@@ -1,78 +0,0 @@
services:
phpbbstudio.aps.acp:
class: phpbbstudio\aps\core\acp
arguments:
- '@phpbbstudio.aps.functions'
- '@template'
- '@phpbbstudio.aps.actions_collection'
- '@phpbbstudio.aps.valuator'
phpbbstudio.aps.blocks:
class: phpbbstudio\aps\core\blocks
arguments:
- '@auth'
- '@config'
- '@dbal.conn'
- '@phpbbstudio.aps.dbal'
- '@phpbbstudio.aps.functions'
- '@group_helper'
- '@controller.helper'
- '@language'
- '@phpbbstudio.aps.log'
- '@pagination'
- '@request'
- '@template'
- '@user'
- '%core.root_path%'
- '%core.php_ext%'
- '%phpbbstudio.aps.tables.logs%'
phpbbstudio.aps.dbal:
class: phpbbstudio\aps\core\dbal
arguments:
- '@dbal.conn'
phpbbstudio.aps.functions:
class: phpbbstudio\aps\core\functions
arguments:
- '@auth'
- '@config'
- '@dbal.conn'
- '@ext.manager'
- '@language'
- '@path_helper'
- '@request'
- '@user'
- '%core.table_prefix%'
- '%phpbbstudio.aps.constants%'
phpbbstudio.aps.language:
class: phpbbstudio\aps\core\language
arguments:
- '@config'
- '@language'
- '@ext.manager'
- '@user'
- '%core.php_ext%'
phpbbstudio.aps.log:
class: phpbbstudio\aps\core\log
arguments:
- '@auth'
- '@config'
- '@dbal.conn'
- '@phpbbstudio.aps.functions'
- '@language'
- '@phpbbstudio.aps.language'
- '@user'
- '%phpbbstudio.aps.tables.logs%'
- '%core.root_path%'
- '%core.adm_relative_path%'
- '%core.php_ext%'
phpbbstudio.aps.template:
class: phpbbstudio\aps\core\template
arguments:
- '@phpbbstudio.aps.functions'
tags:
- { name: twig.extension }

View File

@@ -1,67 +0,0 @@
services:
phpbbstudio.aps.listener.acp:
class: phpbbstudio\aps\event\acp
arguments:
- '@phpbbstudio.aps.acp'
- '@auth'
- '@config'
- '@phpbbstudio.aps.functions'
- '@controller.helper'
- '@language'
- '@log'
- '@phpbbstudio.aps.log'
- '@request'
- '@template'
- '@user'
tags:
- { name: event.listener }
phpbbstudio.aps.listener.actions:
class: phpbbstudio\aps\event\actions
arguments:
- '@auth'
- '@config'
- '@phpbbstudio.aps.functions'
- '@phpbbstudio.aps.manager'
- '@request'
- '@user'
- '%core.root_path%'
- '%core.php_ext%'
tags:
- { name: event.listener }
phpbbstudio.aps.listener.check:
class: phpbbstudio\aps\event\check
arguments:
- '@config'
- '@phpbbstudio.aps.functions'
- '@language'
- '@template'
- '@user'
- '@phpbbstudio.aps.valuator'
tags:
- { name: event.listener }
phpbbstudio.aps.listener.display:
class: phpbbstudio\aps\event\display
arguments:
- '@phpbbstudio.aps.functions'
- '@controller.helper'
- '@language'
- '@template'
- '%core.php_ext%'
tags:
- { name: event.listener }
phpbbstudio.aps.listener.modules:
class: phpbbstudio\aps\event\modules
arguments:
- '@phpbbstudio.aps.functions'
- '@language'
tags:
- { name: event.listener }
phpbbstudio.aps.listener.permissions:
class: phpbbstudio\aps\event\permissions
tags:
- { name: event.listener }

View File

@@ -1,940 +0,0 @@
<?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\controller;
/**
* phpBB Studio - Advanced Points System ACP controller.
*/
class acp_controller
{
/** @var \phpbbstudio\aps\core\acp */
protected $acp;
/** @var \phpbb\auth\auth */
protected $auth;
/** @var \phpbbstudio\aps\points\blockader */
protected $blockader;
/** @var \phpbb\config\config */
protected $config;
/** @var array Clone of phpBB config */
protected $config_new;
/** @var \phpbbstudio\aps\controller\main_controller */
protected $controller;
/** @var \phpbb\db\driver\driver_interface */
protected $db;
/** @var \phpbb\event\dispatcher */
protected $dispatcher;
/** @var \phpbbstudio\aps\core\functions */
protected $functions;
/** @var \phpbb\language\language */
protected $language;
/** @var \phpbb\log\log */
protected $log_phpbb;
/** @var \phpbbstudio\aps\core\log */
protected $log;
/** @var \phpbb\pagination */
protected $pagination;
/** @var \phpbbstudio\aps\points\reasoner */
protected $reasoner;
/** @var \phpbb\request\request */
protected $request;
/** @var \phpbb\template\template */
protected $template;
/** @var \phpbb\user */
protected $user;
/** @var string Custom form action */
protected $u_action;
/**
* Constructor.
*
* @param \phpbbstudio\aps\core\acp $acp APS ACP functions
* @param \phpbb\auth\auth $auth Authentication object
* @param \phpbbstudio\aps\points\blockader $blockader APS Blockader object
* @param \phpbb\config\config $config Configuration object
* @param \phpbbstudio\aps\controller\main_controller $controller APS Main controller
* @param \phpbb\db\driver\driver_interface $db Database object
* @param \phpbb\event\dispatcher $dispatcher Event dispatcher
* @param \phpbbstudio\aps\core\functions $functions APS Core functions
* @param \phpbb\language\language $language phpBB Language object
* @param \phpbb\log\log $log_phpbb phpBB Log object
* @param \phpbbstudio\aps\core\log $log APS Log object
* @param \phpbb\pagination $pagination Pagination object
* @param \phpbbstudio\aps\points\reasoner $reasoner APS Reasoner object
* @param \phpbb\request\request $request Request object
* @param \phpbb\template\template $template Template object
* @param \phpbb\user $user User object
* @return void
* @access public
*/
public function __construct(
\phpbbstudio\aps\core\acp $acp,
\phpbb\auth\auth $auth,
\phpbbstudio\aps\points\blockader $blockader,
\phpbb\config\config $config,
main_controller $controller,
\phpbb\db\driver\driver_interface $db,
\phpbb\event\dispatcher $dispatcher,
\phpbbstudio\aps\core\functions $functions,
\phpbb\language\language $language,
\phpbb\log\log $log_phpbb,
\phpbbstudio\aps\core\log $log,
\phpbb\pagination $pagination,
\phpbbstudio\aps\points\reasoner $reasoner,
\phpbb\request\request $request,
\phpbb\template\template $template,
\phpbb\user $user
)
{
$this->acp = $acp;
$this->auth = $auth;
$this->blockader = $blockader;
$this->config = $config;
$this->controller = $controller;
$this->db = $db;
$this->dispatcher = $dispatcher;
$this->functions = $functions;
$this->language = $language;
$this->log_phpbb = $log_phpbb;
$this->log = $log;
$this->pagination = $pagination;
$this->reasoner = $reasoner;
$this->request = $request;
$this->template = $template;
$this->user = $user;
}
/**
* Handle ACP settings.
*
* @return void
* @access public
*/
public function settings()
{
$this->log->load_lang();
$this->language->add_lang('aps_acp_common', 'phpbbstudio/aps');
$errors = [];
$submit = $this->request->is_set_post('submit');
$form_key = 'aps_settings';
add_form_key($form_key);
if ($action = $this->request->variable('action', '', true))
{
switch ($action)
{
case 'copy':
$errors = $this->copy_points();
break;
case 'clean':
$this->clean_points();
break;
case 'locations':
$this->link_locations();
break;
}
}
$settings = [
'legend1' => 'GENERAL_OPTIONS',
'aps_points_copy' => ['lang' => 'ACP_APS_POINTS_COPY_TITLE', 'type' => 'custom', 'method' => 'set_action', 'params' => ['copy']],
'aps_points_clean' => ['lang' => 'ACP_APS_POINTS_CLEAN', 'type' => 'custom', 'method' => 'set_action', 'params' => ['clean']],
'aps_points_safe_mode' => ['lang' => 'ACP_APS_POINTS_SAFE_MODE', 'type' => 'radio:enabled_disabled', 'validate' => 'bool', 'explain' => true],
'legend2' => 'ACP_APS_POINTS_NAMES',
// Later inserted
'legend3' => 'ACP_APS_FORMATTING',
'aps_points_icon' => ['lang' => 'ACP_APS_POINTS_ICON', 'type' => 'text:0:100', 'append' => '<i class="icon fa-fw" aria-hidden="true"></i>'],
'aps_points_icon_img' => ['lang' => 'ACP_APS_POINTS_ICON_IMG', 'validate' => 'string:0:255', 'type' => 'custom', 'method' => 'build_icon_image_select', 'explain' => true],
'aps_points_icon_position' => ['lang' => 'ACP_APS_POINTS_ICON_POSITION', 'validate' => 'bool', 'type' => 'custom', 'method' => 'build_position_radio'],
'aps_points_decimals' => ['lang' => 'ACP_APS_POINTS_DECIMALS', 'validate' => 'string', 'type' => 'select', 'method' => 'build_decimal_select'],
'aps_points_separator_dec' => ['lang' => 'ACP_APS_SEPARATOR_DEC', 'validate' => 'string', 'type' => 'select', 'method' => 'build_separator_select', 'params' => ['{CONFIG_VALUE}']],
'aps_points_separator_thou' => ['lang' => 'ACP_APS_SEPARATOR_THOU', 'validate' => 'string', 'type' => 'select', 'method' => 'build_separator_select'],
'legend4' => 'GENERAL_SETTINGS',
'aps_link_locations' => ['lang' => 'ACP_APS_LOCATIONS', 'type' => 'custom', 'method' => 'set_action', 'params' => ['locations', false], 'explain' => true],
'aps_points_display_profile' => ['lang' => 'ACP_APS_POINTS_DISPLAY_PROFILE', 'type' => 'radio:yes_no', 'validate' => 'bool', 'explain' => true],
'aps_points_display_post' => ['lang' => 'ACP_APS_POINTS_DISPLAY_POST', 'type' => 'radio:yes_no', 'validate' => 'bool', 'explain' => true],
'aps_points_display_pm' => ['lang' => 'ACP_APS_POINTS_DISPLAY_PM', 'type' => 'radio:yes_no', 'validate' => 'bool', 'explain' => true],
'aps_points_min' => ['lang' => 'ACP_APS_POINTS_MIN', 'type' => 'number', 'validate' => 'string', 'explain' => true], // Validate as string to make sure it does not default to 0
'aps_points_max' => ['lang' => 'ACP_APS_POINTS_MAX', 'type' => 'number', 'validate' => 'string', 'explain' => true],
'aps_actions_per_page' => ['lang' => 'ACP_APS_POINTS_PER_PAGE', 'type' => 'number:10:100', 'validate' => 'number:10:100', 'explain' => true],
'aps_points_exclude_words' => ['lang' => 'ACP_APS_POINTS_EXCLUDE_WORDS', 'type' => 'number:0:10', 'validate' => 'number:0:10', 'explain' => true, 'append' => '&nbsp;' . $this->language->lang('ACP_APS_CHARACTERS')],
'aps_points_exclude_chars' => ['lang' => 'ACP_APS_POINTS_EXCLUDE_CHARS', 'type' => 'radio:yes_no', 'validate' => 'bool', 'explain' => true],
'legend5' => 'ACP_APS_IGNORE_SETTINGS',
'aps_ignore_criteria' => ['lang' => 'ACP_APS_IGNORE_CRITERIA', 'validate' => 'int:0:4', 'type' => 'custom', 'method' => 'build_ignore_criteria_radio', 'explain' => true],
'aps_ignore_min_words' => ['lang' => 'ACP_APS_IGNORE_MIN_WORDS', 'type' => 'number:0:100', 'validate' => 'number:0:100', 'explain' => true],
'aps_ignore_min_chars' => ['lang' => 'ACP_APS_IGNORE_MIN_CHARS', 'type' => 'number:0:200', 'validate' => 'number:0:200', 'explain' => true],
'aps_ignore_excluded_words' => ['lang' => 'ACP_APS_IGNORE_EXCLUDED_WORDS', 'type' => 'radio:yes_no', 'validate' => 'bool', 'explain' => true],
'aps_ignore_excluded_chars' => ['lang' => 'ACP_APS_IGNORE_EXCLUDED_CHARS', 'type' => 'radio:yes_no', 'validate' => 'bool', 'explain' => true],
'legend6' => 'ACP_APS_CHAIN_SETTINGS',
'aps_chain_merge_delete' => ['lang' => 'ACP_APS_CHAIN_MERGE_DELETE', 'type' => 'radio:enabled_disabled', 'validate' => 'bool', 'explain' => true],
'aps_chain_merge_move' => ['lang' => 'ACP_APS_CHAIN_MERGE_MOVE', 'type' => 'radio:enabled_disabled', 'validate' => 'bool', 'explain' => true],
'aps_chain_warn_pm' => ['lang' => 'ACP_APS_CHAIN_WARN_PM', 'type' => 'radio:enabled_disabled', 'validate' => 'bool', 'explain' => true],
];
$settings = phpbb_insert_config_array($settings, $this->build_point_names(), ['after' => 'legend2']);
/**
* Event to add additional settings to the APS ACP settings page.
*
* @event phpbbstudio.aps.acp_settings
* @var array settings Available settings
* @since 1.0.0
*/
$vars = ['settings'];
extract($this->dispatcher->trigger_event('phpbbstudio.aps.acp_settings', compact($vars)));
$this->config_new = clone $this->config;
$settings_array = $submit ? $this->request->variable('config', ['' => '']) : $this->config_new;
validate_config_vars($settings, $settings_array, $errors);
if ($submit && !check_form_key($form_key))
{
$errors[] = $this->language->lang('FORM_INVALID');
}
if (!empty($errors))
{
$submit = false;
}
foreach ($settings as $config_name => $data)
{
if (!isset($settings_array[$config_name]) || strpos($config_name, 'legend') !== false)
{
continue;
}
$this->config_new[$config_name] = $config_value = $settings_array[$config_name];
if ($submit)
{
$this->config->set($config_name, $config_value);
}
}
if ($submit)
{
// Log the action
$this->log_phpbb->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_ACP_APS_SETTINGS');
// Show success message
trigger_error($this->language->lang('ACP_APS_SETTINGS_SUCCESS') . adm_back_link($this->u_action));
}
foreach ($settings as $config_key => $setting)
{
if (!is_array($setting) && strpos($config_key, 'legend') === false)
{
continue;
}
if (strpos($config_key, 'legend') !== false)
{
$this->template->assign_block_vars('settings', [
'CLASS' => str_replace(['acp_', '_'], ['', '-'], utf8_strtolower($setting)),
'LEGEND' => $setting,
'S_LEGEND' => true,
]);
continue;
}
$type = explode(':', $setting['type']);
$content = build_cfg_template($type, $config_key, $this->config_new, $config_key, $setting);
if (empty($content))
{
continue;
}
$booleans = ['yes_no', 'no_yes', 'enabled_disabled', 'disabled_enabled'];
if ($type[0] === 'radio' && !empty($type[1]) && in_array($type[1], $booleans))
{
$yes = [$this->language->lang('YES'), $this->language->lang('ENABLED')];
$no = [$this->language->lang('NO'), $this->language->lang('DISABLED')];
$content = preg_replace(
['/(' . implode('|', $yes) . ')/', '/(' . implode('|', $no) . ')/', '/class="radio"/'],
['<span class="aps-button-green">$1</span>', '<span class="aps-button-red">$1</span>', 'class="radio aps-bool"'],
$content
);
}
$this->template->assign_block_vars('settings', [
'KEY' => $config_key,
'CONTENT' => $content,
'TITLE' => $setting['lang'],
'S_EXPLAIN' => isset($setting['explain']) ? $setting['explain'] : false,
]);
}
$this->template->assign_vars([
'S_ERROR' => !empty($errors),
'ERROR_MSG' => !empty($errors) ? implode('<br>', $errors) : '',
'U_ACTION' => $this->u_action,
]);
}
/**
* Handle ACP display.
*
* @return void
* @access public
*/
public function display()
{
$this->log->load_lang();
$this->language->add_lang(['aps_acp_common', 'aps_display'], 'phpbbstudio/aps');
$errors = [];
add_form_key('aps_display');
$blocks = $this->controller->get_page_blocks();
$admin_blocks = $this->blockader->row($this->blockader->get_admin_id());
$insert = empty($admin_blocks);
if ($insert)
{
foreach ($blocks as $slug => $data)
{
$admin_blocks[$slug] = array_keys($data['blocks']);
}
}
$admin_pages = array_keys($admin_blocks);
foreach ($admin_pages as $slug)
{
if (empty($blocks[$slug]))
{
continue;
}
$data = $blocks[$slug];
$this->template->assign_block_vars('aps_pages', [
'ID' => $slug,
'TITLE' => $data['title'],
'S_ACTIVE' => in_array($slug, $admin_pages),
]);
foreach ($data['blocks'] as $block_id => $block)
{
$this->template->assign_block_vars('aps_pages.blocks', [
'ID' => $block_id,
'TITLE' => $block['title'],
'S_ACTIVE' => isset($admin_blocks[$slug]) && in_array($block_id, $admin_blocks[$slug]),
]);
}
}
$submit = $this->request->is_set_post('submit');
$settings = [
'aps_display_top_change' => $this->request->variable('aps_display_top_change', (int) $this->config['aps_display_top_change']),
'aps_display_top_count' => $this->request->variable('aps_display_top_count', (int) $this->config['aps_display_top_count']),
'aps_display_adjustments' => $this->request->variable('aps_display_adjustments', (int) $this->config['aps_display_adjustments']),
'aps_display_graph_time' => $this->request->variable('aps_display_graph_time', (int) $this->config['aps_display_graph_time']),
];
/**
* Event to handle additional settings for the APS ACP display page.
*
* @event phpbbstudio.aps.acp_display
* @var array settings Available settings
* @var array errors Any errors that may have occurred
* @var bool submit Whether or not the form was submitted
* @since 1.0.2
*/
$vars = ['settings', 'errors', 'submit'];
extract($this->dispatcher->trigger_event('phpbbstudio.aps.acp_display', compact($vars)));
if ($submit)
{
if (!check_form_key('aps_display'))
{
$errors[] = $this->language->lang('FORM_INVALID');
}
$display_blocks = $this->request->variable('aps_blocks', ['' => ['']]);
if (empty($errors))
{
// Set the settings
foreach ($settings as $name => $value)
{
if ($this->config[$name] != $value)
{
$this->config->set($name, $value);
}
}
foreach ($display_blocks as $key => $array)
{
$display_blocks[$key] = array_filter($array);
}
// Set the blocks
$this->blockader->set_blocks($this->blockader->get_admin_id(), $display_blocks, $insert);
// Log the action
$this->log_phpbb->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_ACP_APS_DISPLAY');
// Show success message
trigger_error($this->language->lang('ACP_APS_DISPLAY_SUCCESS') . adm_back_link($this->u_action));
}
}
foreach ($settings as $name => $value)
{
$this->template->assign_var(utf8_strtoupper($name), $value);
}
$this->template->assign_vars([
'S_ERROR' => !empty($errors),
'ERROR_MSG' => !empty($errors) ? implode('<br>', $errors) : '',
'U_ACTION' => $this->u_action,
]);
}
/**
* Handle ACP points and reasons.
*
* @return void
* @access public
*/
public function points()
{
$this->log->load_lang();
$this->language->add_lang('aps_acp_common', 'phpbbstudio/aps');
$errors = [];
$action = $this->request->variable('action', '');
$submit = $this->request->is_set_post('submit');
$form_name = 'acp_aps_points';
add_form_key($form_name);
if (
(!$this->auth->acl_get('a_aps_points') && !$this->auth->acl_get('a_aps_reasons'))
|| (!empty($action) && !$this->auth->acl_get('a_aps_reasons'))
)
{
trigger_error('NOT_AUTHORISED', E_USER_WARNING);
}
switch ($action)
{
case 'add':
case 'edit':
$reason_id = (int) $this->request->variable('r', 0);
$reason = $this->reasoner->row($reason_id);
$reason = $this->reasoner->fill($reason);
$reason['reason_title'] = $this->request->variable('title', (string) $reason['reason_title'] , true);
$reason['reason_desc'] = $this->request->variable('description', (string) $reason['reason_desc'], true);
$reason['reason_points'] = $this->request->variable('points', (double) $reason['reason_points']);
if ($submit)
{
if (!check_form_key($form_name))
{
$errors[] = $this->language->lang('FORM_INVALID');
}
if (empty($reason['reason_title']) || strlen($reason['reason_title']) > 255)
{
$errors[] = $this->language->lang('ACP_APS_REASON_EMPTY_SUBJECT');
}
$reason_points_to_check = round($reason['reason_points'], 2);
if (empty($reason_points_to_check))
{
$errors[] = $this->language->lang('ACP_APS_REASON_EMPTY_POINTS', $this->functions->get_name());
}
if (empty($errors))
{
if ($action === 'add')
{
$this->reasoner->insert($reason);
}
else
{
$this->reasoner->update($reason, $reason_id);
}
$this->log_phpbb->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_ACP_APS_REASON_' . utf8_strtoupper($action));
trigger_error($this->language->lang('ACP_APS_REASON_SAVED') . adm_back_link($this->u_action));
}
}
$this->template->assign_vars([
'REASON_TITLE' => $reason['reason_title'],
'REASON_DESC' => $reason['reason_desc'],
'REASON_POINTS' => $reason['reason_points'],
]);
break;
case 'delete':
$reason_id = (int) $this->request->variable('r', 0);
if (confirm_box(true))
{
$this->reasoner->delete($reason_id);
$json_response = new \phpbb\json_response;
$json_response->send([
'SUCCESS' => true,
'MESSAGE_TITLE' => $this->language->lang('INFORMATION'),
'MESSAGE_TEXT' => $this->language->lang('ACP_APS_REASON_DELETE_SUCCESS'),
]);
}
else
{
confirm_box(false, 'ACP_APS_REASON_DELETE', build_hidden_fields([
'submit' => $submit,
'action' => $action,
]));
}
break;
case 'move':
$reason_id = $this->request->variable('r', 0);
$dir = $this->request->variable('dir', '');
$this->reasoner->order($reason_id, $dir);
$json_response = new \phpbb\json_response;
$json_response->send([
'success' => true,
]);
break;
default:
if ($this->auth->acl_get('a_aps_points'))
{
$this->acp->build();
if ($submit)
{
if (!check_form_key($form_name))
{
$errors[] = $this->language->lang('FORM_INVALID');
}
if (empty($errors))
{
$values = $this->request->variable('aps_values', ['' => 0.00]);
$this->acp->set_points($values);
$this->log_phpbb->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_ACP_APS_POINTS', time(), [$this->functions->get_name()]);
trigger_error($this->language->lang('ACP_APS_POINTS_SUCCESS', $this->functions->get_name()) . adm_back_link($this->u_action));
}
}
}
if ($this->auth->acl_get('a_aps_points'))
{
$rowset = $this->reasoner->rowset();
foreach ($rowset as $row)
{
$this->template->assign_block_vars('aps_reasons', [
'ID' => (int) $row['reason_id'],
'TITLE' => (string) $row['reason_title'],
'DESC' => (string) $row['reason_desc'],
'POINTS' => (double) $row['reason_points'],
'U_DELETE' => $this->u_action . '&action=delete&r=' . (int) $row['reason_id'],
'U_EDIT' => $this->u_action . '&action=edit&r=' . (int) $row['reason_id'],
'U_MOVE_UP' => $this->u_action . '&action=move&dir=up&r=' . (int) $row['reason_id'],
'U_MOVE_DOWN' => $this->u_action . '&action=move&dir=down&r=' . (int) $row['reason_id'],
]);
}
$this->template->assign_vars([
'U_APS_REASON_ADD' => $this->u_action . '&action=add',
]);
}
break;
}
$s_errors = (bool) count($errors);
$this->template->assign_vars([
'S_ERRORS' => $s_errors,
'ERROR_MSG' => $s_errors ? implode('<br />', $errors) : '',
'APS_TITLE' => $action ? $this->language->lang('ACP_APS_REASON_' . utf8_strtoupper($action)) : $this->functions->get_name(),
'S_APS_ACTION' => $action,
'S_APS_POINTS' => $this->auth->acl_get('a_aps_points'),
'S_APS_REASONS' => $this->auth->acl_get('a_aps_reasons'),
'U_APS_ACTION' => $this->u_action . ($action ? "&amp;action={$action}" : '') . (!empty($reason_id) ? "&amp;r={$reason_id}" : ''),
]);
}
/**
* Handle ACP logs.
*
* @return void
* @access public
*/
public function logs()
{
$this->log->load_lang();
$this->language->add_lang('aps_acp_common', 'phpbbstudio/aps');
// Set up general vars
$start = $this->request->variable('start', 0);
$forum_id = $this->request->variable('f', '');
$topic_id = $this->request->variable('t', 0);
$post_id = $this->request->variable('p', 0);
$user_id = $this->request->variable('u', 0);
$reportee_id = $this->request->variable('r', 0);
$delete_mark = $this->request->variable('del_marked', false, false, \phpbb\request\request_interface::POST);
$delete_all = $this->request->variable('del_all', false, false, \phpbb\request\request_interface::POST);
$marked = $this->request->variable('mark', [0]);
// 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);
$keywords_param = !empty($keywords) ? '&amp;keywords=' . urlencode(htmlspecialchars_decode($keywords)) : '';
if (($delete_mark || $delete_all))
{
if (confirm_box(true))
{
$conditions = [];
if ($delete_mark && count($marked))
{
$conditions['log_id'] = ['IN' => $marked];
}
if ($delete_all)
{
if ($sort_days)
{
$conditions['log_time'] = ['>=', time() - ($sort_days * 86400)];
}
$conditions['keywords'] = $keywords;
}
$this->log->delete($conditions);
$plural = $delete_all ? 2 : count($marked);
$log_action = 'LOG_ACP_APS_LOGS_' . $delete_all ? 'CLEARED' : 'DELETED';
$this->log_phpbb->add('admin', $this->user->data['user_id'], $this->user->ip, $log_action, time(), [$this->functions->get_name()]);
trigger_error($this->language->lang('ACP_APS_LOGS_DELETED', $plural) . adm_back_link($this->u_action));
}
else
{
confirm_box(false, $this->language->lang('CONFIRM_OPERATION'), build_hidden_fields([
'f' => $forum_id,
'start' => $start,
'del_marked' => $delete_mark,
'del_all' => $delete_all,
'mark' => $marked,
'st' => $sort_days,
'sk' => $sort_key,
'sd' => $sort_dir,
]));
}
}
$name = $this->functions->get_name();
$limit = $this->config['aps_actions_per_page'];
// Sorting
$limit_days = [
0 => $this->language->lang('ALL_ENTRIES'),
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('SORT_ACTION'),
'ps' => $name,
'pn' => $this->language->lang('APS_POINTS_NEW', $name),
'po' => $this->language->lang('APS_POINTS_OLD', $name),
'uu' => $this->language->lang('SORT_USERNAME'),
'ru' => ucfirst($this->language->lang('FROM')),
't' => $this->language->lang('SORT_DATE'),
];
$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);
// 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_id, $post_id, $user_id, $reportee_id, $sql_time, $sql_sort, $keywords);
$start = $this->log->get_valid_offset();
$total = $this->log->get_log_count();
$base_url = $this->u_action . "&amp;$u_sort_param$keywords_param";
$this->pagination->generate_template_pagination($base_url, 'pagination', 'start', $total, $limit, $start);
foreach ($rowset as $row)
{
$this->template->assign_block_vars('logs', array_change_key_case($row, CASE_UPPER));
}
$this->template->assign_vars([
'U_ACTION' => $this->u_action . "&amp;$u_sort_param$keywords_param&amp;start=$start",
'S_LIMIT_DAYS' => $s_limit_days,
'S_SORT_KEY' => $s_sort_key,
'S_SORT_DIR' => $s_sort_dir,
'S_KEYWORDS' => $keywords,
]);
}
/**
* Set custom form action.
*
* @param string $u_action Custom form action
* @return acp_controller $this This controller for chaining calls
* @access public
*/
public function set_page_url($u_action)
{
$this->u_action = $u_action;
return $this;
}
/**
* Build a settings array for point names for all installed languages.
*
* @return array $names Array of localised point name settings
* @access protected
*/
protected function build_point_names()
{
$names = [];
$sql = 'SELECT * FROM ' . LANG_TABLE . ' ORDER BY lang_english_name';
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
$name['aps_points_name_' . $row['lang_iso']] = ['lang' =>$row['lang_english_name'], 'validate' => 'string:0:100', 'type' => 'text:0:100'];
$names = $row['lang_iso'] === $this->config['default_lang'] ? $name + $names : array_merge($names, $name);
}
$this->db->sql_freeresult($result);
// Only add the 'expand view' if there are multiple language installed
if (count($names) > 1)
{
// Get the first array key
$key = array_keys($names)[0];
// The 'expand view' HTML string
$expand = '<a class="aps-names-toggle" data-text="' . $this->language->lang('COLLAPSE_VIEW') . '">' . $this->language->lang('EXPAND_VIEW') . '</a>';
$names[$key]['append'] = $expand;
}
return $names;
}
/**
* Handle the copy action from the settings page.
*
* @return array Array filled with errors
* @access protected
*/
protected function copy_points()
{
$json_response = new \phpbb\json_response;
add_form_key('aps_points_copy');
if ($this->request->is_set_post('submit_copy'))
{
$errors = [];
$from = $this->request->variable('aps_forums_from', 0);
$to = $this->request->variable('aps_forums_to', [0]);
if (empty($from) || empty($to))
{
$errors[] = $this->language->lang('ACP_APS_POINTS_COPY_EMPTY');
}
if (!check_form_key('aps_points_copy'))
{
$errors[] = $this->language->lang('FORM_INVALID');
}
if ($errors)
{
if ($this->request->is_ajax())
{
$json_response->send([
'MESSAGE_TITLE' => $this->language->lang('ERROR'),
'MESSAGE_TEXT' => implode('<br />', $errors),
]);
}
else
{
return $errors;
}
}
else
{
$this->acp->copy_multiple($from, $to);
$this->log_phpbb->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_ACP_APS_COPIED', time(), [$this->functions->get_name()]);
$json_response->send([
'MESSAGE_TITLE' => $this->language->lang('INFORMATION'),
'MESSAGE_TEXT' => $this->language->lang('ACP_APS_POINTS_COPY_SUCCESS', $this->functions->get_name()),
]);
trigger_error($this->language->lang('ACP_APS_POINTS_COPY_SUCCESS', $this->functions->get_name()) . adm_back_link($this->u_action));
}
}
$this->template->set_filenames(['copy' => '@phpbbstudio_aps/aps_points_copy.html']);
$this->template->assign_vars([
'S_APS_COPY' => true,
'S_APS_FORUMS' => make_forum_select(),
'U_APS_ACTION_COPY' => $this->u_action . '&action=copy',
]);
if ($this->request->is_ajax())
{
$json_response->send([
'MESSAGE_TITLE' => $this->language->lang('ACP_APS_POINTS_COPY_TITLE', $this->functions->get_name()),
'MESSAGE_TEXT' => $this->template->assign_display('copy'),
]);
}
return [];
}
/**
* Handles the clean action from the settings page.
*
* @return void
* @access protected
*/
protected function clean_points()
{
if (confirm_box(true))
{
$this->acp->clean_points();
$this->log_phpbb->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_ACP_APS_CLEANED', time(), [$this->functions->get_name()]);
$json_response = new \phpbb\json_response;
$json_response->send([
'MESSAGE_TITLE' => $this->language->lang('INFORMATION'),
'MESSAGE_TEXT' => $this->language->lang('ACP_APS_POINTS_CLEAN_SUCCESS', $this->functions->get_name()),
]);
}
else
{
confirm_box(false, $this->language->lang('ACP_APS_POINTS_CLEAN_CONFIRM', $this->functions->get_name()), build_hidden_fields([
'action' => 'clean',
]));
}
}
/**
* Handles the link locations from the settings page.
*
* @return void
* @access protected
*/
protected function link_locations()
{
$locations = $this->functions->get_link_locations();
$variables = ['S_APS_LOCATIONS' => true];
foreach ($locations as $location => $status)
{
$variables[$location] = (bool) $status;
}
$this->template->assign_vars($variables);
if ($this->request->is_set_post('submit_locations'))
{
$links = [];
foreach (array_keys($locations) as $location)
{
$links[$location] = $this->request->variable((string) $location, false);
}
$this->functions->set_link_locations($links);
$this->log_phpbb->add('admin', $this->user->data['user_id'], $this->user->data['user_ip'], 'LOG_ACP_APS_LOCATIONS');
trigger_error($this->language->lang('ACP_APS_LOCATIONS_SUCCESS') . adm_back_link($this->u_action));
}
}
}

View File

@@ -1,578 +0,0 @@
<?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\controller;
use Symfony\Component\HttpFoundation\Response;
/**
* phpBB Studio - Advanced Points System main controller.
*/
class main_controller
{
/** @var \phpbb\auth\auth */
protected $auth;
/** @var \phpbbstudio\aps\points\blockader */
protected $blockader;
/** @var \phpbbstudio\aps\core\blocks */
protected $blocks;
/** @var \phpbb\event\dispatcher */
protected $dispatcher;
/** @var \phpbbstudio\aps\core\functions */
protected $functions;
/** @var \phpbb\controller\helper */
protected $helper;
/** @var \phpbb\language\language */
protected $language;
/** @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 Points name */
protected $name;
/** @var string Current page */
protected $page;
/** @var array Available page blocks */
protected $page_blocks;
/** @var array User desired page blocks */
protected $user_blocks;
/** @var array Admin desired page blocks */
protected $admin_blocks;
/**
* Constructor.
*
* @param \phpbb\auth\auth $auth Authentication object
* @param \phpbbstudio\aps\points\blockader $blockader APS Blockader
* @param \phpbbstudio\aps\core\blocks $blocks APS Blocks functions
* @param \phpbb\event\dispatcher $dispatcher Event dispatcher
* @param \phpbbstudio\aps\core\functions $functions APS Core functions
* @param \phpbb\controller\helper $helper Controller helper object
* @param \phpbb\language\language $language Language 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
* @return void
* @access public
*/
public function __construct(
\phpbb\auth\auth $auth,
\phpbbstudio\aps\points\blockader $blockader,
\phpbbstudio\aps\core\blocks $blocks,
\phpbb\event\dispatcher $dispatcher,
\phpbbstudio\aps\core\functions $functions,
\phpbb\controller\helper $helper,
\phpbb\language\language $language,
\phpbb\request\request $request,
\phpbb\template\template $template,
\phpbb\user $user,
$root_path,
$php_ext
)
{
$this->auth = $auth;
$this->blockader = $blockader;
$this->blocks = $blocks;
$this->dispatcher = $dispatcher;
$this->functions = $functions;
$this->helper = $helper;
$this->language = $language;
$this->request = $request;
$this->template = $template;
$this->user = $user;
$this->root_path = $root_path;
$this->php_ext = $php_ext;
$this->name = $functions->get_name();
}
/**
* Display the points page.
*
* @param string $page The page slug
* @param int $pagination The page number for pagination
* @return Response
* @access public
*/
public function display($page, $pagination)
{
$this->language->add_lang('aps_display', 'phpbbstudio/aps');
$this->page = $page;
// Load page blocks
$this->get_page_blocks($pagination);
// Load admin and user blocks
$this->get_admin_user_blocks();
// Check existance
if ($msg = $this->check_existance())
{
return $msg;
}
// Check authorisation
if ($msg = $this->check_auth())
{
return $msg;
}
// Handle any action
$this->handle_action();
foreach ($this->admin_blocks as $slug => $admin_blocks)
{
if (empty($admin_blocks))
{
continue;
}
$data = $this->page_blocks[$slug];
// Only list pages that the user is authorised to see
if (!isset($data['auth']) || $data['auth'])
{
$this->template->assign_block_vars('aps_navbar', [
'TITLE' => $data['title'],
'S_ACTIVE' => $this->page === $slug,
'U_VIEW' => $this->helper->route('phpbbstudio_aps_display', ['page' => $slug]),
]);
}
}
$called_functions = [];
$blocks = array_keys($this->page_blocks[$this->page]['blocks']);
$blocks = empty($this->user_blocks[$this->page]) ? $blocks : array_unique(array_merge($this->user_blocks[$this->page], $blocks));
foreach ($blocks as $block_id)
{
// If the block is no longer available, remove it from the user blocks
if (empty($this->page_blocks[$this->page]['blocks'][$block_id]))
{
$this->delete_block($block_id);
continue;
}
// If it's disabled by the admin, do not display it
if (!in_array($block_id, $this->admin_blocks[$this->page]))
{
continue;
}
$block = $this->page_blocks[$this->page]['blocks'][$block_id];
// Only show blocks that the user is authorised to see
if (!isset($block['auth']) || $block['auth'])
{
if (empty($this->user_blocks[$this->page]) || in_array($block_id, $this->user_blocks[$this->page]))
{
if (!empty($block['function']) && !in_array($block['function'], $called_functions))
{
$called_functions[] = $this->call_function($block_id, $block);
}
$this->template->assign_block_vars('aps_blocks', $this->build_display($block_id, $block));
}
else
{
$this->template->assign_block_vars('aps_blocks_add', ['item' => $this->build_list($block_id, $block)]);
}
}
}
// Purge temporary variable
unset($called_functions);
// Output template variables for display
$this->template->assign_vars([
'S_APS_DAE_ENABLED' => $this->functions->is_dae_enabled(),
'S_APS_OVERVIEW' => true,
'U_APS_ACTION_SORT' => $this->helper->route('phpbbstudio_aps_display', ['page' => $page, 'aps_action' => 'move']),
'U_MCP' => ($this->auth->acl_get('m_') || $this->auth->acl_getf_global('m_')) ? append_sid("{$this->root_path}mcp.{$this->php_ext}", 'i=-phpbbstudio-aps-mcp-main_module&amp;mode=front', true, $this->user->session_id) : '',
]);
// Breadcrumbs
$this->template->assign_block_vars_array('navlinks', [
[
'FORUM_NAME' => $this->name,
'U_VIEW_FORUM' => $this->helper->route('phpbbstudio_aps_display'),
],
[
'FORUM_NAME' => $this->language->lang('APS_OVERVIEW'),
'U_VIEW_FORUM' => $this->helper->route('phpbbstudio_aps_display'),
],
]);
// Output the page!
return $this->helper->render('@phpbbstudio_aps/aps_display.html', $this->page_blocks[$this->page]['title']);
}
/**
* Build template variables array for a given block.
*
* @param string $block_id The block identifier
* @param array $block The block data
* @return array The block template variables
* @access protected
*/
protected function build_display($block_id, array $block)
{
return [
'ID' => $block_id,
'TITLE' => $block['title'],
'TEMPLATE' => $block['template'],
'S_REQUIRED' => !empty($block['required']),
'U_DELETE' => $this->helper->route('phpbbstudio_aps_display', ['page' => $this->page, 'aps_action' => 'delete', 'id' => $block_id]),
];
}
/**
* Build template list item for a given block.
*
* @param string $block_id The block identifier
* @param array $block The block data
* @return string The block template list item
* @access protected
*/
protected function build_list($block_id, array $block)
{
$u_add = $this->helper->route('phpbbstudio_aps_display', ['page' => $this->page, 'aps_action' => 'add', 'id' => $block_id]);
return '<li><a class="aps-button-green" href="' . $u_add . '" data-ajax="aps_add">' . $block['title'] . '</a></li>';
}
/**
* Call a function defined in the block data.
*
* @param string $block_id The block identifier
* @param array $block The block data
* @return mixed The block function declaration
* @access protected
*/
protected function call_function($block_id, array $block)
{
// Set up function parameters and append the block id
$params = !empty($block['params']) ? $block['params'] : [];
$params = array_merge($params, [
'block_id' => $block_id
]);
// Call the function
call_user_func_array($block['function'], $params);
return $block['function'];
}
/**
* Check if the current user is authorised to see this display page.
*
* @return string|Response
* @access protected
*/
protected function check_auth()
{
if (isset($this->page_blocks[$this->page]['auth']) && !$this->page_blocks[$this->page]['auth'])
{
$message = $this->language->lang('NOT_AUTHORISED');
$back_link = '<a href="' . $this->helper->route('phpbbstudio_aps_display', ['page' => 'overview']) . '">' . $this->language->lang('APS_OVERVIEW') . '</a>';
$back_msg = $this->language->lang('RETURN_TO', $back_link);
return $this->helper->message($message . '<br /><br />' . $back_msg, [], 'INFORMATION', 401);
}
return '';
}
/**
* Check if the current page is available.
*
* @return string|Response
* @access protected
*/
protected function check_existance()
{
if (empty($this->page_blocks[$this->page]))
{
$message = $this->language->lang('PAGE_NOT_FOUND');
$back_link = '<a href="' . $this->helper->route('phpbbstudio_aps_display', ['page' => 'overview']) . '">' . $this->language->lang('APS_OVERVIEW') . '</a>';
$back_msg = $this->language->lang('RETURN_TO', $back_link);;
return $this->helper->message($message . '<br /><br />' . $back_msg, [], 'INFORMATION', 404);
}
return '';
}
/**
* Handle actions for the display blocks.
*
* @return void
* @access protected
*/
protected function handle_action()
{
// Request the action
$action = $this->request->variable('aps_action', '', true);
// Only these actions are available
if (!in_array($action, ['add', 'delete', 'move']))
{
return;
}
// Request the block identifier
$block_id = $this->request->variable('id', '', true);
// Call the action's function
$response = $this->{$action . '_block'}($block_id);
// If the request is AJAX, send a response
if ($this->request->is_ajax())
{
$json_response = new \phpbb\json_response;
$json_response->send([
'success' => $response,
'APS_TITLE' => $this->language->lang('APS_SUCCESS'),
'APS_TEXT' => $this->language->lang('APS_POINTS_BLOCK_' . utf8_strtoupper($action), $this->name),
]);
}
// Otherwise assign a meta refresh
$this->helper->assign_meta_refresh_var(0, $this->helper->route('phpbbstudio_aps_display', ['page' => $this->page]));
}
/**
* Get the admin and user desired page blocks.
*
* @return void
* @access protected
*/
protected function get_admin_user_blocks()
{
$rowset = $this->blockader->rowset($this->user->data['user_id']);
foreach ($rowset as $user_id => $blocks)
{
if ($user_id == $this->blockader->get_admin_id())
{
$this->admin_blocks = $blocks;
}
if ($user_id == $this->user->data['user_id'])
{
$this->user_blocks = $blocks;
}
}
if (empty($this->admin_blocks))
{
foreach ($this->page_blocks as $page => $data)
{
$this->admin_blocks[$page] = array_keys($data['blocks']);
}
}
}
/**
* Get all available display blocks.
*
* @param int $pagination Pagination page number
* @return array The display blocks
* @access public
*/
public function get_page_blocks($pagination = 1)
{
$page_blocks = [
'overview' => [
'title' => $this->language->lang('APS_OVERVIEW'),
'blocks' => [
'points_top' => [
'title' => $this->language->lang('APS_TOP_USERS'),
'function' => [$this->blocks, 'user_top_search'],
'template' => '@phpbbstudio_aps/blocks/points_top.html',
],
'points_search' => [
'title' => $this->language->lang('FIND_USERNAME'),
'function' => [$this->blocks, 'user_top_search'],
'template' => '@phpbbstudio_aps/blocks/points_search.html',
],
'points_settings' => [
'title' => $this->language->lang('SETTINGS'),
'template' => '@phpbbstudio_aps/blocks/points_settings.html',
],
'points_random' => [
'title' => $this->language->lang('APS_RANDOM_USER'),
'function' => [$this->blocks, 'user_random'],
'template' => '@phpbbstudio_aps/blocks/points_random.html',
],
'points_forums' => [
'title' => $this->language->lang('APS_POINTS_PER_FORUM', $this->name),
'function' => [$this->blocks, 'charts_forum'],
'template' => '@phpbbstudio_aps/blocks/points_forums.html',
],
'points_groups' => [
'title' => $this->language->lang('APS_POINTS_PER_GROUP', $this->name),
'function' => [$this->blocks, 'charts_group'],
'template' => '@phpbbstudio_aps/blocks/points_groups.html',
],
'points_growth' => [
'title' => $this->language->lang('APS_POINTS_GROWTH', $this->name),
'function' => [$this->blocks, 'charts_period'],
'template' => '@phpbbstudio_aps/blocks/points_growth.html',
],
'points_trade_off' => [
'title' => $this->language->lang('APS_POINTS_TRADE_OFF', $this->name),
'function' => [$this->blocks, 'charts_period'],
'template' => '@phpbbstudio_aps/blocks/points_trade_off.html',
],
],
],
'actions' => [
'title' => $this->language->lang('APS_POINTS_ACTIONS', $this->name),
'auth' => $this->auth->acl_get('u_aps_view_logs'),
'blocks' => [
'points_actions' => [
'auth' => $this->auth->acl_get('u_aps_view_logs'),
'title' => $this->language->lang('APS_POINTS_ACTIONS', $this->name),
'required' => true,
'function' => [$this->blocks, 'display_actions'],
'params' => ['pagination' => $pagination],
'template' => '@phpbbstudio_aps/blocks/points_actions.html',
],
'points_registration' => [
'auth' => $this->auth->acl_get('u_aps_view_logs'),
'title' => $this->language->lang('APS_RECENT_ADJUSTMENTS'),
'function' => [$this->blocks, 'recent_adjustments'],
'template' => '@phpbbstudio_aps/blocks/points_adjustments.html',
],
],
],
];
/**
* Event to add additional page blocks to the APS display page.
*
* @event phpbbstudio.aps.display_blocks
* @var array page_blocks Available page blocks
* @var int pagination Pagination's page number
* @since 1.0.0
*/
$vars = ['page_blocks', 'pagination'];
extract($this->dispatcher->trigger_event('phpbbstudio.aps.display_blocks', compact($vars)));
$this->page_blocks = $page_blocks;
return $this->page_blocks;
}
/**
* Add a block to the user desired blocks.
*
* @param string $block_id The block identifier
* @return string The rendered block for display
* @access protected
*/
protected function add_block($block_id)
{
$insert = empty($this->user_blocks);
$this->user_blocks[$this->page] = !$insert ? array_merge($this->user_blocks[$this->page], [$block_id]) : [$block_id];
$this->blockader->set_blocks($this->user->data['user_id'], $this->user_blocks, $insert);
$this->template->set_filenames(['block' => '@phpbbstudio_aps/blocks/base.html']);
if (!empty($this->page_blocks[$this->page]['blocks'][$block_id]['function']))
{
$this->call_function($block_id, $this->page_blocks[$this->page]['blocks'][$block_id]);
}
$this->template->assign_vars([
'block' => $this->build_display($block_id, $this->page_blocks[$this->page]['blocks'][$block_id]),
'S_USER_LOGGED_IN' => $this->user->data['user_id'] != ANONYMOUS,
'S_IS_BOT' => $this->user->data['is_bot'],
]);
return $this->template->assign_display('block');
}
/**
* Delete a block from the user desired blocks.
*
* @param string $block_id The block identifier
* @return string HTML list item
* @access protected
*/
protected function delete_block($block_id)
{
$insert = empty($this->user_blocks);
if ($insert)
{
foreach ($this->page_blocks as $page => $data)
{
$this->user_blocks[$page] = array_keys($data['blocks']);
}
}
if (($key = array_search($block_id, $this->user_blocks[$this->page])) !== false) {
unset($this->user_blocks[$this->page][$key]);
}
$this->blockader->set_blocks($this->user->data['user_id'], $this->user_blocks, $insert);
return $this->build_list($block_id, $this->page_blocks[$this->page]['blocks'][$block_id]);
}
/**
* Move (order) the user desired blocks.
*
* @return bool|int Boolean on update or integer on insert.
* @access protected
*/
protected function move_block()
{
$insert = empty($this->user_blocks);
$order = $this->request->variable('order', ['']);
// Filter out empty block identifiers
$this->user_blocks[$this->page] = array_filter($order);
return $this->blockader->set_blocks($this->user->data['user_id'], $this->user_blocks, $insert);
}
}

View File

@@ -1,617 +0,0 @@
<?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\controller;
/**
* phpBB Studio - Advanced Points System MCP controller.
*/
class mcp_controller
{
/** @var \phpbb\auth\auth */
protected $auth;
/** @var \phpbb\config\config */
protected $config;
/** @var \phpbb\db\driver\driver_interface */
protected $db;
/** @var \phpbb\event\dispatcher */
protected $dispatcher;
/** @var \phpbbstudio\aps\points\distributor */
protected $distributor;
/** @var \phpbbstudio\aps\core\functions */
protected $functions;
/** @var \phpbb\group\helper */
protected $group_helper;
/** @var \phpbb\language\language */
protected $language;
/** @var \phpbbstudio\aps\core\log */
protected $log;
/** @var \phpbb\notification\manager */
protected $notification;
/** @var \phpbb\pagination */
protected $pagination;
/** @var \phpbbstudio\aps\points\reasoner */
protected $reasoner;
/** @var \phpbb\request\request */
protected $request;
/** @var \phpbb\template\template */
protected $template;
/** @var \phpbb\user */
protected $user;
/** @var \phpbbstudio\aps\points\valuator */
protected $valuator;
/** @var string phpBB root path */
protected $root_path;
/** @var string PHP file extension */
protected $php_ext;
/** @var string Points name */
protected $name;
/** @var string Custom form action */
protected $u_action;
/**
* 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\event\dispatcher $dispatcher Event dispatcher
* @param \phpbbstudio\aps\points\distributor $distributor APS Distributor object
* @param \phpbbstudio\aps\core\functions $functions APS Core functions
* @param \phpbb\group\helper $group_helper Group helper object
* @param \phpbb\language\language $language Language object
* @param \phpbbstudio\aps\core\log $log APS Log object
* @param \phpbb\notification\manager $notification Notification manager object
* @param \phpbb\pagination $pagination Pagination object
* @param \phpbbstudio\aps\points\reasoner $reasoner APS Reasoner object
* @param \phpbb\request\request $request Request object
* @param \phpbb\template\template $template Template object
* @param \phpbb\user $user User object
* @param \phpbbstudio\aps\points\valuator $valuator APS Valuator object
* @param string $root_path phpBB root 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,
\phpbb\event\dispatcher $dispatcher,
\phpbbstudio\aps\points\distributor $distributor,
\phpbbstudio\aps\core\functions $functions,
\phpbb\group\helper $group_helper,
\phpbb\language\language $language,
\phpbbstudio\aps\core\log $log,
\phpbb\notification\manager $notification,
\phpbb\pagination $pagination,
\phpbbstudio\aps\points\reasoner $reasoner,
\phpbb\request\request $request,
\phpbb\template\template $template,
\phpbb\user $user,
\phpbbstudio\aps\points\valuator $valuator,
$root_path,
$php_ext
)
{
$this->auth = $auth;
$this->config = $config;
$this->db = $db;
$this->dispatcher = $dispatcher;
$this->distributor = $distributor;
$this->functions = $functions;
$this->group_helper = $group_helper;
$this->language = $language;
$this->log = $log;
$this->notification = $notification;
$this->pagination = $pagination;
$this->reasoner = $reasoner;
$this->request = $request;
$this->template = $template;
$this->user = $user;
$this->valuator = $valuator;
$this->root_path = $root_path;
$this->php_ext = $php_ext;
$this->name = $functions->get_name();
}
/**
* Handle MCP front page.
*
* @return void
* @access public
*/
public function front()
{
if ($this->auth->acl_get('u_aps_view_logs'))
{
$this->log->load_lang();
// Latest 5 logs
$logs = $this->log->get(false, 5);
foreach ($logs as $row)
{
$this->template->assign_block_vars('logs', array_change_key_case($row, CASE_UPPER));
}
// Latest 5 adjustments
$moderated = $this->log->get(false, 5, 0, '', 0, 0, 0, 0, 0, 'l.log_time DESC', 'APS_POINTS_USER_ADJUSTED');
foreach ($moderated as $row)
{
$this->template->assign_block_vars('moderated', array_change_key_case($row, CASE_UPPER));
}
}
// Top 5 users
$sql = 'SELECT user_id, username, user_colour, user_points
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, 5);
while ($row = $this->db->sql_fetchrow($result))
{
$this->template->assign_block_vars('aps_users_top', [
'NAME' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']),
'POINTS' => $row['user_points'],
]);
}
$this->db->sql_freeresult($result);
// Bottom 5 user
$sql = 'SELECT user_id, username, user_colour, user_points
FROM ' . $this->functions->table('users') . '
WHERE user_type <> ' . USER_IGNORE . '
ORDER BY user_points ASC, username_clean DESC';
$result = $this->db->sql_query_limit($sql, 5);
while ($row = $this->db->sql_fetchrow($result))
{
$this->template->assign_block_vars('aps_users_bottom', [
'NAME' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']),
'POINTS' => $row['user_points'],
]);
}
$this->db->sql_freeresult($result);
/**
* Event to assign additional variables for the APS MCP front page.
*
* @event phpbbstudio.aps.mcp_front
* @since 1.0.0
*/
$this->dispatcher->dispatch('phpbbstudio.aps.mcp_front');
$this->template->assign_vars([
'S_APS_LOGS' => $this->auth->acl_get('u_aps_view_logs'),
]);
}
/**
* Handle MCP logs.
*
* @return void
* @access public
*/
public function logs()
{
$this->log->load_lang();
// Set up general vars
$start = $this->request->variable('start', 0);
$forum_id = $this->request->variable('f', '');
$topic_id = $this->request->variable('t', 0);
$post_id = $this->request->variable('p', 0);
$user_id = $this->request->variable('u', 0);
$reportee_id = $this->request->variable('r', 0);
// 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);
$keywords_param = !empty($keywords) ? '&amp;keywords=' . urlencode(htmlspecialchars_decode($keywords)) : '';
$name = $this->functions->get_name();
$limit = $this->config['aps_actions_per_page'];
// Sorting
$limit_days = [
0 => $this->language->lang('ALL_ENTRIES'),
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('SORT_ACTION'),
'ps' => $name,
'pn' => $this->language->lang('APS_POINTS_NEW', $name),
'po' => $this->language->lang('APS_POINTS_OLD', $name),
'uu' => $this->language->lang('SORT_USERNAME'),
'ru' => $this->language->lang('FROM'),
't' => $this->language->lang('SORT_DATE'),
];
$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);
// 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_id, $post_id, $user_id, $reportee_id, $sql_time, $sql_sort, $keywords);
$start = $this->log->get_valid_offset();
$total = $this->log->get_log_count();
$base_url = $this->u_action . "&amp;$u_sort_param$keywords_param";
$this->pagination->generate_template_pagination($base_url, 'pagination', 'start', $total, $limit, $start);
foreach ($rowset as $row)
{
$this->template->assign_block_vars('logs', array_change_key_case($row, CASE_UPPER));
}
$this->template->assign_vars([
'U_ACTION' => $this->u_action . "&amp;$u_sort_param$keywords_param&amp;start=$start",
'S_LIMIT_DAYS' => $s_limit_days,
'S_SORT_KEY' => $s_sort_key,
'S_SORT_DIR' => $s_sort_dir,
'S_KEYWORDS' => $keywords,
]);
}
/**
* Handle MCP user adjustment.
*
* @return void
* @access public
*/
public function change()
{
$this->log->load_lang();
$group_id = $this->request->variable('g', 0);
$user_id = $this->request->variable('u', 0);
if (empty($group_id) && empty($user_id))
{
$this->find_user();
return;
}
$this->language->add_lang('acp/common');
$action = $this->request->variable('action', '');
switch ($action)
{
case 'add':
case 'sub':
case 'set':
if (!$this->auth->acl_get('m_aps_adjust_custom'))
{
trigger_error($this->language->lang('NOT_AUTHORISED'), E_USER_WARNING);
}
break;
case '':
// do nothing
break;
default:
if (!$this->auth->acl_get('m_aps_adjust_reason'))
{
trigger_error($this->language->lang('NOT_AUTHORISED'), E_USER_WARNING);
}
break;
}
if (!empty($user_id))
{
$sql = 'SELECT user_id, username, user_colour
FROM ' . $this->functions->table('users') . '
WHERE user_type <> ' . USER_IGNORE . '
AND user_id = ' . (int) $user_id;
$result = $this->db->sql_query_limit($sql, 1);
$user = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
if ($user === false)
{
trigger_error($this->language->lang('NO_USER') . $this->back_link($this->u_action), E_USER_WARNING);
}
$user_ids = [$user_id];
$u_action = '&u=' . (int) $user_id;
}
else
{
$sql = 'SELECT user_id
FROM ' . $this->functions->table('user_group') . '
WHERE group_id = ' . (int) $group_id;
$result = $this->db->sql_query($sql);
$rowset = $this->db->sql_fetchrowset($result);
$this->db->sql_freeresult($result);
if (empty($rowset))
{
$this->language->add_lang('acp/groups');
trigger_error($this->language->lang('GROUPS_NO_MEMBERS') . $this->back_link($this->u_action), E_USER_WARNING);
}
$user_ids = array_column($rowset, 'user_id');
$u_action = '&g=' . (int) $group_id;
}
// Actions
$reasons = $this->reasoner->rowset();
$actions = [
'add' => $this->language->lang('ADD'),
'sub' => $this->language->lang('REMOVE'),
'set' => $this->language->lang('CHANGE'),
];
$users = $this->valuator->users($user_ids);
$submit = $this->request->is_set_post('submit');
$points = $this->request->variable('points', 0.00);
$reason = $this->request->variable('reason', '', true);
if ($submit)
{
if ($action === '')
{
trigger_error($this->language->lang('NO_ACTION'), E_USER_WARNING);
}
if (confirm_box(true))
{
foreach ($users as $uid => $user_points)
{
switch ($action)
{
case 'add':
$sum_points = $points;
break;
case 'sub':
$sum_points = $this->functions->equate_points(0, $points, '-');
break;
case 'set':
$sum_points = $this->functions->equate_points($points, $user_points, '-');
break;
default:
if (empty($reasons[$action]))
{
trigger_error($this->language->lang('NO_ACTION') . $this->back_link($this->u_action), E_USER_WARNING);
}
$sum_points = $reasons[$action]['reason_points'];
$reason = $reasons[$action]['reason_title'] . '<br />' . $reasons[$action]['reason_desc'];
break;
}
$log_entry = [];
$log_entry[] = [
'action' => 'APS_POINTS_USER_ADJUSTED',
'actions' => !empty($reason) ? [$reason => $sum_points] : ['APS_POINTS_USER_ADJUSTED' => $sum_points],
'user_id' => (int) $uid,
'reportee_id' => (int) $this->user->data['user_id'],
'reportee_ip' => (string) $this->user->ip,
'points_old' => $user_points,
'points_sum' => $sum_points,
];
$this->distributor->distribute($uid, $sum_points, $log_entry, $user_points);
}
$this->config->increment('aps_notification_id', 1);
$this->notification->add_notifications('phpbbstudio.aps.notification.type.adjust', [
'name' => $this->functions->get_name(),
'reason' => $reason,
'user_ids' => array_keys($users),
'moderator' => get_username_string('no_profile', $this->user->data['user_id'], $this->user->data['username'], $this->user->data['user_colour']),
'moderator_id' => (int) $this->user->data['user_id'],
'notification_id' => (int) $this->config['aps_notification_id'],
]);
trigger_error($this->language->lang('MCP_APS_POINTS_USER_CHANGE_SUCCESS', $this->name) . $this->back_link($this->u_action));
}
else
{
confirm_box(false, $this->language->lang('MCP_APS_POINTS_USER_CHANGE', $this->name), build_hidden_fields([
'submit' => $submit,
'action' => $action,
'points' => $points,
'reason' => $reason,
]));
redirect($this->u_action);
}
}
if (!empty($user_id) && $this->auth->acl_get('u_aps_view_logs'))
{
$logs = $this->log->get(false, 5, 0, '', 0, 0, (int) $user_id);
foreach ($logs as $row)
{
$this->template->assign_block_vars('logs', array_change_key_case($row, CASE_UPPER));
}
$this->template->assign_var('S_APS_LOGS', true);
}
if (!empty($group_id))
{
$sql = 'SELECT group_id, group_name, group_colour
FROM ' . $this->functions->table('groups') . '
WHERE group_id = ' . (int) $group_id;
$result = $this->db->sql_query_limit($sql, 1);
$group = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
$group_name = $this->group_helper->get_name_string('full', $group['group_id'], $group['group_name'], $group['group_colour']);
}
$this->template->assign_vars([
'APS_ACTIONS' => $actions,
'APS_REASONS' => $reasons,
'APS_POINTS' => $user_id ? $this->functions->display_points($users[$user_id]) : '',
'APS_USERNAME' => !empty($user) ? get_username_string('full', $user['user_id'], $user['username'], $user['user_colour']) : '',
'APS_GROUP' => !empty($group_name) ? $group_name : '',
'S_APS_CUSTOM' => $this->auth->acl_get('m_aps_adjust_custom'),
'S_APS_REASON' => $this->auth->acl_get('m_aps_adjust_reason'),
'S_APS_POINTS' => true,
'U_APS_ACTION' => $this->u_action . $u_action,
]);
}
/**
* Find a user for the MCP adjustment page.
*
* @return void
* @access protected
*/
protected function find_user()
{
$this->language->add_lang('acp/groups');
$form_name = 'mcp_aps_change';
add_form_key($form_name);
$submit_group = $this->request->is_set_post('submit_group');
$submit_user = $this->request->is_set_post('submit_user');
$submit = $submit_group || $submit_user;
$group_id = $this->request->variable('group_id', 0);
if ($submit && !check_form_key($form_name))
{
$error = 'FORM_INVALID';
}
else if ($submit)
{
if ($submit_group)
{
redirect($this->u_action . '&g=' . (int) $group_id);
}
if ($submit_user)
{
if (!function_exists('user_get_id_name'))
{
/** @noinspection PhpIncludeInspection */
include $this->root_path . 'includes/functions_user.' . $this->php_ext;
}
$username[] = $this->request->variable('username', '', true);
$error = user_get_id_name($user_ids, $username);
if (empty($error))
{
$user_id = $user_ids[0];
redirect($this->u_action . '&u=' . (int) $user_id);
}
}
}
if (!function_exists('group_select_options'))
{
/** @noinspection PhpIncludeInspection */
include $this->root_path . 'includes/functions_admin.' . $this->php_ext;
}
$this->template->assign_vars([
'S_ERROR' => !empty($error),
'ERROR_MSG' => !empty($error) ? $this->language->lang($error) : '',
'APS_USERNAME' => !empty($username[0]) ? $username[0] : '',
'APS_GROUPS' => group_select_options($group_id),
'S_APS_SEARCH' => true,
'U_APS_ACTION' => $this->u_action,
'U_APS_SEARCH' => append_sid("{$this->root_path}memberlist.{$this->php_ext}", 'mode=searchuser&amp;form=mcp_aps_change&amp;field=username'),
]);
}
/**
* Generate a back link for this MCP controller.
*
* @param string $action The action to return to
* @return string A HTML formatted URL to the action
* @access protected
*/
protected function back_link($action)
{
return '<br /><br /><a href="' . $action . '">&laquo; ' . $this->language->lang('BACK_TO_PREV') . '</a>';
}
/**
* Set custom form action.
*
* @param string $u_action Custom form action
* @return mcp_controller $this This controller for chaining calls
* @access public
*/
public function set_page_url($u_action)
{
$this->u_action = $u_action;
return $this;
}
}

View File

@@ -1,236 +0,0 @@
<?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);
}
}

View File

@@ -1,647 +0,0 @@
<?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&amp;mode=change&amp;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&amp;mode=change&amp;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('&amp;', $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;
}
}

View File

@@ -1,119 +0,0 @@
<?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;
}
}
}

View File

@@ -1,501 +0,0 @@
<?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 . '&nbsp;' . $this->get_icon()) : ($this->get_icon() . '&nbsp;' . $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);
}
}

View File

@@ -1,106 +0,0 @@
<?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);
}
}
}

View File

@@ -1,560 +0,0 @@
<?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&amp;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;
}
}

View File

@@ -1,104 +0,0 @@
<?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;
}
}
}

View File

@@ -1,122 +0,0 @@
<?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\cron\task;
/**
* phpBB Studio - Advanced Points System birthday cron.
*/
class birthday extends \phpbb\cron\task\base
{
/**
* How often the cron should run (in seconds).
* @var int 86400 One day in seconds
*/
protected $cron_frequency = 86400;
/** @var \phpbb\config\config */
protected $config;
/** @var \phpbb\db\driver\driver_interface */
protected $db;
/** @var \phpbbstudio\aps\core\functions */
protected $functions;
/** @var \phpbbstudio\aps\actions\manager */
protected $manager;
/**
* Constructor.
*
* @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 \phpbbstudio\aps\actions\manager $manager APS Actions manager object
* @return void
* @access public
*/
public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbbstudio\aps\core\functions $functions, \phpbbstudio\aps\actions\manager $manager)
{
$this->config = $config;
$this->db = $db;
$this->functions = $functions;
$this->manager = $manager;
}
/**
* Runs this cron task.
*
* @return void
* @access public
*/
public function run()
{
$user_ids = $data = [];
$data['birthdays'] = [];
// Set the default timezone
date_default_timezone_set($this->config['board_timezone']);
// Get current day and month (no leading zero)
$day = date('j');
$month = date('n');
// Birthdays are stored with a leading space if only one digit: " 8- 6-1990".
$data['day'] = strlen($day) === 1 ? ' ' . $day : $day;
$data['month'] = strlen($month) === 1 ? ' ' . $month : $month;
// Build a SQL like expression: DD-MM-%
$birthday = $data['day'] . '-' . $data['month'] . '-' . $this->db->get_any_char();
// Select all the user identifiers that are celebrating their birthday today
$sql = 'SELECT user_id, user_birthday
FROM ' . $this->functions->table('users') . '
WHERE user_type <> ' . USER_IGNORE . '
AND user_birthday ' . $this->db->sql_like_expression($birthday);
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
$user_ids[] = $row['user_id'];
$data['birthdays'][(int) $row['user_id']] = $row['user_birthday'];
}
$this->db->sql_freeresult($result);
// Calculate the points!
$this->manager->trigger('birthday', $user_ids, $data);
// Update the cron task run time here
$this->config->set('aps_birthday_last_run', time(), false);
}
/**
* Returns whether this cron task can run, given current board configuration.
*
* @return bool
* @access public
*/
public function is_runnable()
{
return true;
}
/**
* Returns whether this cron task should run now, because enough time
* has passed since it was last run.
*
* @return bool
* @access public
*/
public function should_run()
{
return $this->config['aps_birthday_last_run'] < time() - $this->cron_frequency;
}
}

View File

@@ -1,4 +0,0 @@
<Files *>
Order Allow,Deny
Deny from All
</Files>

View File

@@ -1,53 +0,0 @@
# phpBB Studio - Advanced Points System
#### v1.0.6-RC on 11-03-2020
- Fixed template block inclusion
- Fixed approved post points distribution
- Updated permission language strings
- Added phpBB 3.3 compatibility
#### v1.0.5-RC1 on 20-12-2019
- Entered the stage features frozen.
- Fixed a bug where points were displayed on profile despite the setting
- Fixed a bug where excluded points were still receiving points
- Added an option to ignore points which do not meet certain criteria
- Added an option to determine where the Points link shows up
- Enhanced the CSS to be altered more easily for other styles
#### v1.0.4-beta on 01-12-2019
- Major code clean up
- Bumped phpBB version requirement to 3.2.8
- Fixed MCP "Front" missing log language strings
- Fixed ACP "Display" missing language strings
- Fixed ACP setting for "icon position" not taking affect
- Added radio CSS to admin
- Added changing user points for an entire group
- Added the possibility to use an image as icon
- Added to automatically hide display categories without blocks
- Added version checker
#### v1.0.3-beta
- Fixed PHP event DocBlocks versions
- Added PHP event for points distribution
#### v1.0.2-beta
- Improved position of reportee/moderator name in Actions list
- Added public function for points distribution
- Added PHP and Style events
#### v1.0.1-beta
- Updated route requirements
- Fixed pagination issues for blocks
- Fixed top users _cups_ to now show proper colour on same points
- Added top users numbers for users not on the podium
- Added two new permissions
- Can only view own logged actions
- Can only view own logged actions augmentation _(build up)_
- Added support for forum names with special characters, such as emoji
- Added more CSS utility classes
- Fixed CSS to be stylelint compliant
- Fixed a bug where charts were displaying unapproved points
- Fixed a bug where users did not receive unapproved points
#### v1.0.0-beta
- first public release

View File

@@ -1,19 +0,0 @@
/**
* Advanced Points System extension © Copyright phpBB Studio 2019
* https://www.phpbbstudio.com
*
* APS is a free extension for the phpBB Forum Software Package.
* You can redistribute it and/or modify it under the terms of
* the GNU General Public License, version 2 (GPL-2.0) as
* published by the Free Software Foundation.
*
* This extension is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* A copy of the license can be viewed in the license.txt file.
* The same can be viewed at <http://opensource.org/licenses/gpl-2.0.php>
*/
No events required while using at least phpBB 3.2.8

View File

@@ -1,9 +0,0 @@
# phpBB Studio - Advanced Points System
- Fully integrated Points System for phpBB 3.2
- Set up point values on a global or per-forum basis.
- All major native phpBB actions are available.
- User, Moderator and Administrator permissions.
- Notification to user on adjustment by moderator.<br />*(with anonymity)*
- Integrated and fully extendable overview page.<br />*(customisable by user)*
- Fully extendable by other extensions.<br />*(with detailed explanation and examples)*

View File

@@ -1,81 +0,0 @@
<h1 align="center"><img src="./images/aps.png" alt="Advanced Points System" /></h1>
<h4 align="center">An extension for the phpBB Forum Software.</h4>
<p align="center">
<img src="https://img.shields.io/badge/License-GPLv2-gold.svg" alt="GPLv2 License" />
</p>
## Table of Contents
> - [Install](#install)
> - [Uninstall](#uninstall)
> - [Support](#support)
> - [Translations](#translations)
> - [Features](#features)
> - [Other extensions](#other-extensions)
> - [Extending APS](#extending-aps)
> - [You might also like](#you-might-also-like)
> - [License](#license)
## Install
1. Download the latest validated release
2. Unzip the downloaded release and copy it to the `ext` directory of your phpBB board.
3. Navigate in the ***<abbr title="Administration Control Panel">ACP</abbr>*** to `Customise » Extension management » Manage extensions`.
4. Look for `phpBB Studio - Advanced Points System` under the **Disabled Extensions** list, and click its **`Enable`** link.
5. Set up and configure `Advanced Points System` by navigating in the ***<abbr title="Administration Control Panel">ACP</abbr>*** to `Extensions » Advanced Points System`.
> *Read more about [installing phpBB Extensions](https://www.phpbb.com/extensions/installing/#installing).*
## Uninstall
1. Navigate in the ***<abbr title="Administration Control Panel">ACP</abbr>*** to `Customise » Extension management » Manage extensions`.
2. Look for `phpBB Studio - Advanced Points System` under the **Enabled Extensions** list, and click its **`Disable`** link.
3. To permanently uninstall, click **`Delete Data`** and then delete the `/ext/phpbbstudio/aps` directory.
> *Read more about [uninstalling phpBB Extensions](https://www.phpbb.com/extensions/installing/#removing).*
## Support
- **Important: Only official release versions validated by the phpBB Extensions Team should be installed on a live forum. Pre-release (beta, RC) versions downloaded from this repository are only to be used for testing on offline/development forums and are not officially supported.**
- Report bugs and other issues to our **[Issue Tracker](https://github.com/phpBB-Studio/AdvancedPointsSystem/issues)**.
- Support requests can be posted and discussed in the **[Extension support](https://phpbbstudio.com/viewforum.php?f=5)** forum over at the [phpBB Studio](https://www.phpbbstudio.com).
- Support requests can be posted and discussed in the **[Development topic](https://www.phpbb.com/community/viewforum.php?f=456)** over at [phpBB.com](https://www.phpbb.com).
## Translations
- Translations should be posted in the corresponding forum in **[Extension support](https://phpbbstudio.com/viewforum.php?f=5)** over at the [phpBB Studio](https://www.phpbbstudio.com).
- Each translation should be created in a **separate** topic.
- The topic should either contain a **zip archive** as an attachment or a link to your **GitHub repository**.
- Translations should <u>***not***</u> be posted in the Development topic over at [phpBB.com](https://www.phpbb.com).
- Translations should <u>***not***</u> be created as Pull Requests over at the [GitHub](https://github.com/phpBB-Studio/) repository.
## Features
- Fully integrated Points System for phpBB 3.2
- Set up point values on a global or per-forum basis.
- All major native phpBB actions are available.
- User, Moderator and Administrator permissions.
- Notification to user on adjustment by moderator.<br />*(with anonymity)*
- Integrated and fully extendable overview page.<br />*(customisable by user)*
- Fully extendable by other extensions.<br />*(with detailed explanation and examples)*
## Other extensions
- [Advanced Shop System](https://github.com/phpBB-Studio/AdvancedShopSystem)
- [Advanced Points System · Purchases](https://phpbbstudio.com/extensions/advanced-points-system-purchases)
- [Advanced Points System · Auto Groups](https://github.com/phpBB-Studio/AdvancedShopSystemAutoGroups)
- Bank _(To be determined)_
- Lottery _(To be determined)_
## Extending APS
For the extension developers amongst us, we have written a comprehensive Wiki that should describe everything in detail.
You can read about [Extending APS](https://github.com/phpBB-Studio/AdvancedPointsSystem/wiki/Extending-APS) and all [the possibilities](https://github.com/phpBB-Studio/AdvancedPointsSystem/wiki/Extending-possibilities) there are. If there are still any questions, feel free to ask.
## You might also like
- <a href="https://github.com/phpBB-Studio/DiceRolls"><img src="./images/dice_rolls.png" alt="Dice Rolls" /></a>
- <a href="https://github.com/phpBB-Studio/HighlightPosts"><img src="./images/highlight_posts.png" alt="Highlight Posts" /></a>
- <a href="https://github.com/phpBB-Studio/WhoReadWhat"><img src="./images/who_read_what.png" alt="Who Read What" /></a>
- <a href="https://github.com/phpBB-Studio/SubGlobalTopics"><img src="./images/subglobal_topic.png" alt="Sub Global Topic" /></a>
- <a href="https://github.com/phpBB-Studio/TopicCementStyle"><img src="./images/topic_cement.png" alt="Topic Cement Style" /></a>
- <a href="https://github.com/phpBB-Studio/DateTopicStarterTemplate"><img src="./images/topic_events.png" alt="Topic Events" /></a>
## License
GNU General Public License, version 2 ([GPLv2](../license.txt)).
---
> [phpbbstudio.com](https://www.phpbbstudio.com) · GitHub [phpbb-studio](https://github.com/phpbb-studio/) · phpBB [3Di](https://www.phpbb.com/community/memberlist.php?mode=viewprofile&u=177467) / [mrgoldy](https://www.phpbb.com/community/memberlist.php?mode=viewprofile&u=1114105)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 915 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 993 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 787 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 910 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -1,14 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="Author" content="phpbbstudio.com">
<meta name="Keywords" content="extension for phpBB">
<meta name="Description" content="Advanced Points System">
<title></title>
</head>
<body style="background-color: #ffffff; color: #000000;">
</body>
</html>

View File

@@ -1,266 +0,0 @@
<?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\event;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* phpBB Studio - Advanced Points System Event listener: ACP.
*/
class acp implements EventSubscriberInterface
{
/** @var \phpbbstudio\aps\core\acp */
protected $acp;
/** @var \phpbb\auth\auth */
protected $auth;
/** @var \phpbb\config\config */
protected $config;
/** @var \phpbbstudio\aps\core\functions */
protected $functions;
/** @var \phpbb\controller\helper */
protected $helper;
/** @var \phpbb\language\language */
protected $language;
/** @var \phpbb\log\log */
protected $log;
/** @var \phpbbstudio\aps\core\log */
protected $log_aps;
/** @var \phpbb\request\request */
protected $request;
/** @var \phpbb\template\template */
protected $template;
/** @var \phpbb\user */
protected $user;
/**
* Constructor.
*
* @param \phpbbstudio\aps\core\acp $acp APS ACP functions
* @param \phpbb\auth\auth $auth Authentication object
* @param \phpbb\config\config $config Configuration object
* @param \phpbbstudio\aps\core\functions $functions APS Core functions
* @param \phpbb\controller\helper $helper Controller helper object
* @param \phpbb\language\language $language Language object
* @param \phpbb\log\log $log phpBB Log object
* @param \phpbbstudio\aps\core\log $log_aps APS Log object
* @param \phpbb\request\request $request Request object
* @param \phpbb\template\template $template Template object
* @param \phpbb\user $user User object
* @return void
* @access public
*/
public function __construct(
\phpbbstudio\aps\core\acp $acp,
\phpbb\auth\auth $auth,
\phpbb\config\config $config,
\phpbbstudio\aps\core\functions $functions,
\phpbb\controller\helper $helper,
\phpbb\language\language $language,
\phpbb\log\log $log,
\phpbbstudio\aps\core\log $log_aps,
\phpbb\request\request $request,
\phpbb\template\template $template,
\phpbb\user $user
)
{
$this->acp = $acp;
$this->auth = $auth;
$this->config = $config;
$this->functions = $functions;
$this->helper = $helper;
$this->language = $language;
$this->log = $log;
$this->log_aps = $log_aps;
$this->request = $request;
$this->template = $template;
$this->user = $user;
}
/**
* Assign functions defined in this class to event listeners in the core.
*
* @static
* @return array
* @access public
*/
static public function getSubscribedEvents()
{
return [
'core.acp_language_after_delete' => 'delete_name',
'core.acp_users_display_overview' => 'display_user',
'core.acp_manage_forums_display_form' => 'display_data',
'core.acp_manage_forums_update_data_after' => 'request_data',
];
}
/**
* Delete a localised points name upon language deletion.
*
* @event core.acp_language_after_delete
* @param \phpbb\event\data $event The event object
* @return void
* @access public
*/
public function delete_name(\phpbb\event\data $event)
{
$this->config->delete('aps_points_name_' . $event['lang_iso'], true);
}
/**
* Display a user's points when managing a specific user.
*
* @event core.acp_users_display_overview
* @param \phpbb\event\data $event The event object
* @return void
* @access public
*/
public function display_user(\phpbb\event\data $event)
{
$this->template->assign_var('APS_POINTS', $event['user_row']['user_points']);
}
/**
* Display a points list when adding/creating a forum.
*
* @event core.acp_manage_forums_display_form
* @param \phpbb\event\data $event The event object
* @return void
* @access public
*/
public function display_data(\phpbb\event\data $event)
{
$this->log_aps->load_lang();
// Only display a points list if the administrator is authorised to edit the points
if ($s_auth = $this->auth->acl_get('a_aps_points'))
{
// Build a points list for this forum
$this->acp->build((int) $event['forum_id']);
// Request any action (ajax)
$action = $this->request->variable('aps_action', '');
// Ajaxify the copy points action
if (!empty($action) && $this->request->is_ajax())
{
$json_response = new \phpbb\json_response;
$forum_id = $this->request->variable('f', 0);
switch ($action)
{
case 'copy':
$copy = $this->request->variable('aps_points_copy', 0);
if (empty($copy))
{
$json_response->send([
'MESSAGE_TITLE' => $this->language->lang('ERROR'),
'MESSAGE_TEXT' => $this->language->lang('ACP_APS_POINTS_COPY_EMPTY_FROM'),
]);
}
$fields = $this->acp->get_fields();
$fields = array_flip($fields[0]);
$this->acp->copy_points($copy, $forum_id, $fields);
$json_response->send([
'MESSAGE_TITLE' => $this->language->lang('INFORMATION'),
'MESSAGE_TEXT' => $this->language->lang('ACP_APS_POINTS_COPY_SUCCESS', $this->functions->get_name()),
'APS_VALUES' => $this->acp->assign_values($forum_id),
]);
break;
case 'reset':
if (confirm_box(true))
{
$this->acp->delete_points($forum_id);
$json_response->send([
'MESSAGE_TITLE' => $this->language->lang('INFORMATION'),
'MESSAGE_TEXT' => $this->language->lang('ACP_APS_POINTS_RESET_SUCCESS', $this->functions->get_name()),
]);
}
else
{
confirm_box(false, $this->language->lang('ACP_APS_POINTS_RESET_CONFIRM', $this->functions->get_name()), build_hidden_fields([
'aps_action' => $action,
'forum_id' => $forum_id,
]));
}
break;
}
}
}
$this->template->assign_vars([
'S_APS_POINTS' => (bool) $s_auth,
'U_APS_RESET' => $this->helper->get_current_url() . '&amp;aps_action=reset',
]);
}
/**
* Request and set the points when adding/editing a forum.
*
* @event core.acp_manage_forums_update_data_after
* @param \phpbb\event\data $event The event object
* @return void
* @access public
*/
public function request_data(\phpbb\event\data $event)
{
$this->log_aps->load_lang();
// Only set the points when the administrator is authorised to edit the points
if (!$this->auth->acl_get('a_aps_points'))
{
return;
}
$forum_id = !empty($event['forum_data']['forum_id']) ? (int) $event['forum_data']['forum_id'] : 0;
$copy = $this->request->variable('aps_points_copy', 0);
$reset = $this->request->variable('aps_points_reset', 0);
$values = $this->request->variable('aps_values', ['' => 0.00]);
if (!empty($reset) && !empty($forum_id))
{
$this->acp->delete_points($forum_id);
$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_ACP_APS_POINTS_RESET', time(), [$event['forum_data']['forum_name'], $this->functions->get_name()]);
}
else if (!empty($copy) && $copy != $forum_id)
{
$this->acp->copy_points($copy, $forum_id, $values);
$forum_name = $this->functions->forum_name($copy);
$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_ACP_APS_POINTS_COPIED', time(), [$forum_name, $event['forum_data']['forum_name'], $this->functions->get_name()]);
}
else
{
$this->acp->set_points($values, $forum_id);
}
}
}

View File

@@ -1,528 +0,0 @@
<?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\event;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* phpBB Studio - Advanced Points System Event listener: Actions.
*/
class actions implements EventSubscriberInterface
{
/** @var \phpbb\auth\auth */
protected $auth;
/** @var \phpbb\config\config */
protected $config;
/** @var \phpbbstudio\aps\core\functions */
protected $functions;
/** @var \phpbbstudio\aps\actions\manager */
protected $manager;
/** @var \phpbb\request\request */
protected $request;
/** @var \phpbb\user */
protected $user;
/** @var string phpBB root path */
protected $root_path;
/** @var string PHP file extension */
protected $php_ext;
/**
* Constructor.
*
* @param \phpbb\auth\auth $auth Authentication object
* @param \phpbb\config\config $config Configuration object
* @param \phpbbstudio\aps\core\functions $functions APS Core functions
* @param \phpbbstudio\aps\actions\manager $manager APS Manager object
* @param \phpbb\request\request $request Request object
* @param \phpbb\user $user User object
* @param string $root_path phpBB root path
* @param string $php_ext php File extension
* @return void
* @access public
*/
public function __construct(
\phpbb\auth\auth $auth,
\phpbb\config\config $config,
\phpbbstudio\aps\core\functions $functions,
\phpbbstudio\aps\actions\manager $manager,
\phpbb\request\request $request,
\phpbb\user $user,
$root_path,
$php_ext
)
{
$this->auth = $auth;
$this->config = $config;
$this->functions = $functions;
$this->manager = $manager;
$this->request = $request;
$this->user = $user;
$this->root_path = $root_path;
$this->php_ext = $php_ext;
}
/**
* Assign functions defined in this class to event listeners in the core.
*
* @static
* @return array
* @access public
*/
static public function getSubscribedEvents()
{
return [
/* User actions */
'core.modify_posting_auth' => 'bump',
'core.submit_post_end' => 'post',
'core.delete_post_after' => 'post_delete',
'core.viewtopic_modify_poll_ajax_data' => 'vote',
/* Moderator actions */
'core.mcp_main_modify_fork_sql' => 'copy',
'core.mcp_change_poster_after' => 'change',
'core.delete_topics_before_query' => 'delete',
'core.posting_modify_submit_post_before' => 'lock_and_type',
'core.mcp_lock_unlock_after' => 'lock',
'core.move_posts_before' => 'move_posts',
'core.move_topics_before_query' => 'move_topics',
'core.approve_posts_after' => 'queue',
'core.approve_topics_after' => 'queue',
'core.disapprove_posts_after' => 'queue',
'core.mcp_forum_merge_topics_after' => 'merge',
/* Global actions */
'core.ucp_register_register_after' => 'register',
'core.mcp_warn_post_after' => 'warn',
'core.mcp_warn_user_after' => 'warn',
'core.submit_pm_after' => 'pm',
];
}
/**
* Trigger Advanced Points System action: “bump”!
*
* @event core.modify_posting_auth
* @param \phpbb\event\data $event The event object
* @since 1.0.0
* @return void
* @access public
*/
public function bump(\phpbb\event\data $event)
{
if (
($event['mode'] !== 'bump')
||
(!$event['is_authed'] || !empty($event['error']) || $event['post_data']['forum_type'] != FORUM_POST)
||
(($event['post_data']['forum_status'] == ITEM_LOCKED || (isset($event['post_data']['topic_status']) && $event['post_data']['topic_status'] == ITEM_LOCKED)) && !$this->auth->acl_get('m_edit', $event['forum_id']))
)
{
return;
}
if ($bump_time = bump_topic_allowed($event['forum_id'], $event['post_data']['topic_bumped'], $event['post_data']['topic_last_post_time'], $event['post_data']['topic_poster'], $event['post_data']['topic_last_poster_id'])
&& check_link_hash($this->request->variable('hash', ''), "topic_{$event['post_data']['topic_id']}"))
{
$this->manager->trigger('topic', $this->user->data['user_id'], $event, $event['forum_id']);
}
}
/**
* Trigger Advanced Points System action: “post” or “topic”!
*
* @event core.submit_post_end
* @param \phpbb\event\data $event The event object
* @since 1.0.0
* @return void
* @access public
*/
public function post(\phpbb\event\data $event)
{
if ($event['mode'] === 'edit' && $event['data']['poster_id'] != $this->user->data['user_id'])
{
$this->manager->trigger('edit', $event['data']['poster_id'], $event, $event['data']['forum_id']);
return;
}
switch ($event['mode'])
{
case 'edit':
$action = $event['data']['topic_first_post_id'] == $event['data']['post_id'] ? 'topic' : 'post';
break;
case 'post':
$action = 'topic';
break;
case 'reply':
case 'quote':
$action = 'post';
break;
default:
return;
break;
}
$this->manager->trigger($action, $this->user->data['user_id'], $event, $event['data']['forum_id']);
}
/**
* Trigger Advanced Points System action: “delete” or “post”!
*
* @event core.delete_post_after
* @param \phpbb\event\data $event The event object
* @since 1.0.0
* @return void
* @access public
*/
public function post_delete(\phpbb\event\data $event)
{
if ($this->user->data['user_id'] == $event['data']['poster_id'])
{
$data = array_merge($this->manager->clean_event($event), [
'mode' => ($event['is_soft'] ? 'soft_' : '') . 'delete',
'post_data' => ['topic_type' => POST_NORMAL],
]);
$this->manager->trigger('post', $event['data']['poster_id'], $data, $event['forum_id']);
}
else
{
$data = [
'action' => 'post',
'is_soft' => $event['is_soft'],
'posts' => [
0 => [
'forum_id' => $event['forum_id'],
'topic_id' => $event['topic_id'],
'post_id' => $event['post_id'],
'poster_id' => $event['data']['poster_id'],
],
],
];
$this->manager->trigger('delete', $event['data']['poster_id'], $data, $event['forum_id']);
}
}
/**
* Trigger Advanced Points System action: “vote”!
*
* @event core.viewtopic_modify_poll_ajax_data
* @param \phpbb\event\data $event The event object
* @since 1.0.0
* @return void
* @access public
*/
public function vote(\phpbb\event\data $event)
{
$this->manager->trigger('vote', $this->user->data['user_id'], $event, $event['forum_id']);
}
/**
* Trigger Advanced Points System action: “copy”!
*
* @event core.mcp_main_modify_fork_sql
* @param \phpbb\event\data $event The event object
* @since 1.0.0
* @return void
* @access public
*/
public function copy(\phpbb\event\data $event)
{
$this->manager->trigger('copy', $event['topic_row']['topic_poster'], $event, [(int) $event['topic_row']['forum_id'], (int) $event['sql_ary']['forum_id']]);
}
/**
* Trigger Advanced Points System action: “change”!
*
* @event core.mcp_change_poster_after
* @param \phpbb\event\data $event The event object
* @since 1.0.0
* @return void
* @access public
*/
public function change(\phpbb\event\data $event)
{
$this->manager->trigger('change', [$event['userdata']['user_id'], $event['post_info']['poster_id']], $event, $event['post_info']['forum_id']);
}
/**
* Trigger Advanced Points System action: “delete”!
*
* @event core.delete_topics_before_query
* @param \phpbb\event\data $event The event object
* @since 1.0.0
* @return void
* @access public
*/
public function delete(\phpbb\event\data $event)
{
// Check for chain triggering events
if (!$this->config['aps_chain_merge_delete'] && $this->request->variable('action', '', true) === 'merge_topics')
{
return;
}
if (!function_exists('phpbb_get_topic_data'))
{
/** @noinspection PhpIncludeInspection */
include $this->root_path . 'includes/functions_mcp.' . $this->php_ext;
}
$topics = phpbb_get_topic_data($event['topic_ids']);
$forum_ids = $this->manager->get_identifiers($topics, 'forum_id');
$user_ids = $this->manager->get_identifiers($topics, 'topic_poster');
$data = array_merge($this->manager->clean_event($event), [
'action' => 'topic',
'topics' => $topics,
]);
$this->manager->trigger('delete', $user_ids, $data, $forum_ids);
}
/**
* Trigger Advanced Points System action: “lock” and/or “type”!
*
* @event core.posting_modify_submit_post_before
* @param \phpbb\event\data $event The event object
* @since 1.0.0
* @return void
* @access public
*/
public function lock_and_type(\phpbb\event\data $event)
{
if ($event['mode'] === 'edit')
{
if ($this->user->data['user_id'] != $event['data']['poster_id'])
{
$row = $this->functions->topic_post_locked($event['data']['post_id']);
if ($row['post_edit_locked'] != $event['data']['post_edit_locked'])
{
$data = array_merge($this->manager->clean_event($event), [
'action' => $event['data']['post_edit_locked'] ? 'lock_post' : 'unlock_post',
'data' => [$event['data']],
]);
$this->manager->trigger('lock', $event['data']['poster_id'], $data, $event['data']['forum_id']);
}
if ($row['topic_status'] != $event['data']['topic_status'])
{
$data = array_merge($this->manager->clean_event($event), [
'action' => $event['data']['topic_status'] ? 'unlock' : 'lock',
'data' => [$event['data'] + ['topic_poster' => (int) $row['topic_poster']]],
]);
$this->manager->trigger('lock', $row['topic_poster'], $data, $event['data']['forum_id']);
}
}
if ($event['post_data']['orig_topic_type'] != $event['post_data']['topic_type'])
{
$data = array_merge($this->manager->clean_event($event), [
'type_from' => $event['post_data']['orig_topic_type'],
'type_to' => $event['post_data']['topic_type'],
]);
$this->manager->trigger('topic_type', $event['post_data']['topic_poster'], $data, $event['data']['forum_id']);
}
}
}
/**
* Trigger Advanced Points System action: “lock”!
*
* @event core.mcp_lock_unlock_after
* @param \phpbb\event\data $event The event object
* @since 1.0.0
* @return void
* @access public
*/
public function lock(\phpbb\event\data $event)
{
$s_user = in_array($event['action'], ['lock', 'unlock']) ? 'topic_poster' : 'poster_id';
$forum_ids = $this->manager->get_identifiers($event['data'], 'forum_id');
$user_ids = $this->manager->get_identifiers($event['data'] , $s_user);
$this->manager->trigger('lock', $user_ids, $event, $forum_ids);
}
/**
* Trigger Advanced Points System action: “move”!
*
* @event core.move_posts_before
* @param \phpbb\event\data $event The event object
* @since 1.0.0
* @return void
* @access public
*/
public function move_posts(\phpbb\event\data $event)
{
// Check for chain triggering events
if (!$this->config['aps_chain_merge_move'] && $this->request->variable('action', '', true) === 'merge_topics')
{
return;
}
if (!function_exists('phpbb_get_topic_data'))
{
/** @noinspection PhpIncludeInspection */
include $this->root_path . 'includes/functions_mcp.' . $this->php_ext;
}
$posts = phpbb_get_post_data($event['post_ids']);
$forum_ids = $this->manager->get_identifiers($posts, 'forum_id');
$user_ids = $this->manager->get_identifiers($posts, 'poster_id');
$data = array_merge($this->manager->clean_event($event), [
'action' => 'post',
'posts' => $posts,
]);
$this->manager->trigger('move', $user_ids, $data, $forum_ids);
}
/**
* Trigger Advanced Points System action: “move”!
*
* @event core.move_topics_before_query
* @param \phpbb\event\data $event The event object
* @since 1.0.0
* @return void
* @access public
*/
public function move_topics(\phpbb\event\data $event)
{
if (!function_exists('phpbb_get_topic_data'))
{
/** @noinspection PhpIncludeInspection */
include $this->root_path . 'includes/functions_mcp.' . $this->php_ext;
}
$topics = phpbb_get_topic_data($event['topic_ids']);
$forum_ids = $this->manager->get_identifiers($topics, 'forum_id');
$user_ids = $this->manager->get_identifiers($topics, 'topic_poster');
$data = array_merge($this->manager->clean_event($event), [
'action' => 'topic',
'topics' => $topics,
]);
$this->manager->trigger('move', $user_ids, $data, $forum_ids);
}
/**
* Trigger Advanced Points System action: “queue”!
*
* @event core.approve_posts_after
* @event core.approve_topics_after
* @event core.disapprove_posts_after
* @param \phpbb\event\data $event The event object
* @since 1.0.0
* @return void
* @access public
*/
public function queue(\phpbb\event\data $event)
{
$data = array_merge($this->manager->clean_event($event), [
'mode' => isset($event['action']) ? $event['action'] : 'disapprove',
]);
$posts = isset($event['post_info']) ? $event['post_info'] : $event['topic_info'];
$forum_ids = $this->manager->get_identifiers($posts, 'forum_id');
$user_ids = $this->manager->get_identifiers($posts, 'poster_id');
$this->manager->trigger('queue', $user_ids, $data, $forum_ids);
}
/**
* Trigger Advanced Points System action: “merge”!
*
* @event core.mcp_forum_merge_topics_after
* @param \phpbb\event\data $event The event object
* @since 1.0.0
* @return void
* @access public
*/
public function merge(\phpbb\event\data $event)
{
$user_ids = $this->manager->get_identifiers($event['all_topic_data'], 'topic_poster');
$this->manager->trigger('merge', $user_ids, $event, $event['all_topic_data'][$event['to_topic_id']]['forum_id']);
}
/**
* Trigger Advanced Points System action: “register”!
*
* @event core.ucp_register_register_after
* @param \phpbb\event\data $event The event object
* @since 1.0.0
* @return void
* @access public
*/
public function register(\phpbb\event\data $event)
{
$this->manager->trigger('register', $event['user_id'], $event);
}
/**
* Trigger Advanced Points System action: “warn”!
*
* @event core.mcp_warn_post_after
* @event core.mcp_warn_user_after
* @param \phpbb\event\data $event The event object
* @since 1.0.0
* @return void
* @access public
*/
public function warn(\phpbb\event\data $event)
{
$this->manager->trigger('warn', $event['user_row']['user_id'], $event, 0);
}
/**
* Trigger Advanced Points System action: “pm”!
*
* @event core.submit_pm_after
* @param \phpbb\event\data $event The event object
* @since 1.0.0
* @return void
* @access public
*/
public function pm(\phpbb\event\data $event)
{
// Check for chain triggering events
if (!$this->config['aps_chain_warn_pm'] && $this->request->variable('mode', '', true) === 'warn_user')
{
return;
}
$this->manager->trigger('pm', [], $event, 0);
}
}

View File

@@ -1,275 +0,0 @@
<?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\event;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* phpBB Studio - Advanced Points System Event listener: Check.
*/
class check implements EventSubscriberInterface
{
/** @var \phpbbstudio\aps\core\functions */
protected $functions;
/** @var \phpbb\language\language */
protected $language;
/** @var \phpbb\template\template */
protected $template;
/** @var \phpbb\user */
protected $user;
/** @var \phpbbstudio\aps\points\valuator */
protected $valuator;
/** @var double|false The minimum point value */
protected $min;
/**
* Constructor.
*
* @param \phpbb\config\config $config Configuration object
* @param \phpbbstudio\aps\core\functions $functions APS Core functions
* @param \phpbb\language\language $language Language object
* @param \phpbb\template\template $template Template object
* @param \phpbb\user $user User object
* @param \phpbbstudio\aps\points\valuator $valuator APS Valuator object
* @return void
* @access public
*/
public function __construct(
\phpbb\config\config $config,
\phpbbstudio\aps\core\functions $functions,
\phpbb\language\language $language,
\phpbb\template\template $template,
\phpbb\user $user,
\phpbbstudio\aps\points\valuator $valuator
)
{
$this->functions = $functions;
$this->language = $language;
$this->template = $template;
$this->user = $user;
$this->valuator = $valuator;
$this->min = $config['aps_points_min'] !== '' ? (double) $config['aps_points_min'] : false;
}
/**
* Assign functions defined in this class to event listeners in the core.
*
* @static
* @return array
* @access public
*/
static public function getSubscribedEvents()
{
return [
'core.viewtopic_modify_page_title' => 'check_bump',
'core.handle_post_delete_conditions' => 'check_delete',
'core.modify_posting_auth' => 'check_post',
'core.viewtopic_modify_poll_data' => 'check_vote',
];
}
/**
* Check the action: "Bump".
*
* @param \phpbb\event\data $event The event object
* @return void
* @access public
*/
public function check_bump(\phpbb\event\data $event)
{
if ($this->min === false)
{
return;
}
// If there already is no bump link, return
if ($this->template->retrieve_var('U_BUMP_TOPIC') === '')
{
return;
}
// Get the value
$value = $this->get_value('aps_bump', $event['forum_id']);
// Check if the value is negative
if ($value >= 0)
{
return;
}
if ($this->below_min($value))
{
$this->template->assign_var('U_BUMP_TOPIC', '');
}
}
/**
* Check the action: "Delete".
*
* @param \phpbb\event\data $event The event object
* @return void
* @access public
*/
public function check_delete(\phpbb\event\data $event)
{
if ($this->min === false)
{
return;
}
if (confirm_box(true))
{
$data = $this->functions->post_data($event['post_id']);
if ($this->user->data['user_id'] != $data['poster_id'])
{
return;
}
$field = 'aps_post_delete' . ($event['is_soft'] ? '_soft' : '');
if ($value = $this->check_value($field, $event['forum_id']))
{
$event['error'] = array_merge($event['error'], [
$this->language->lang('APS_POINTS_TOO_LOW', $this->functions->get_name()) . '<br>' .
$this->language->lang('APS_POINTS_ACTION_COST', $this->functions->display_points($value))
]);
}
}
}
/**
* Check the action: "Post" and "Topic".
*
* @param \phpbb\event\data $event The event object
* @return void
* @access public
*/
public function check_post(\phpbb\event\data $event)
{
if ($this->min === false)
{
return;
}
switch ($event['mode'])
{
default:
return;
break;
case 'post':
$field = 'aps_topic_base';
break;
case 'reply':
case 'quote':
$field = 'aps_post_base';
break;
case 'edit':
$data = $this->functions->post_data($event['post_id']);
if ($this->user->data['user_id'] != $data['poster_id'])
{
return;
}
$type = $data['topic_first_post_id'] == $event['post_id'] ? 'topic' : 'post';
$field = 'aps_' . $type . '_edit';
break;
}
if ($value = $this->check_value($field, $event['forum_id']))
{
$event['error'] = array_merge($event['error'], [
$this->language->lang('APS_POINTS_TOO_LOW', $this->functions->get_name()) . '<br>' .
$this->language->lang('APS_POINTS_ACTION_COST', $this->functions->display_points($value))
]);
}
}
/**
* Check the action: "Vote".
*
* @param \phpbb\event\data $event The event object
* @return void
* @access public
*/
public function check_vote(\phpbb\event\data $event)
{
if ($this->min === false)
{
return;
}
if ($this->check_value('aps_vote', $event['forum_id']))
{
$event['s_can_vote'] = false;
}
}
/**
* Verify the user has enough points to perform an action.
*
* @param int $field The points field
* @param int $forum_id The forum identifier
* @return double|false The points value
* @access protected
*/
protected function check_value($field, $forum_id)
{
$value = $this->get_value($field, $forum_id);
$check = $value < 0 && $this->below_min($value) ? $value : false;
return $check;
}
/**
* Get the base value for a points action.
*
* @param int $field The points field
* @param int $forum_id The forum identifier
* @return double The points value
* @access protected
*/
protected function get_value($field, $forum_id)
{
$fields = [0 => [$field]];
$values = $this->valuator->get_points($fields, $forum_id, false);
$value = isset($values[$forum_id][$field]) ? $values[$forum_id][$field] : 0.00;
return (double) $value;
}
/**
* Check whether or not the value is below the points minimum.
*
* @param double $value The points value
* @return bool Whether or not the value is below the minimum
* @access protected
*/
protected function below_min($value)
{
$points = $this->functions->equate_points($this->user->data['user_points'], $value);
return (bool) ($points < $this->min);
}
}

View File

@@ -1,200 +0,0 @@
<?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\event;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* phpBB Studio - Advanced Points System Event listener: Display.
*/
class display implements EventSubscriberInterface
{
/** @var \phpbbstudio\aps\core\functions */
protected $functions;
/** @var \phpbb\controller\helper */
protected $helper;
/** @var \phpbb\language\language */
protected $language;
/** @var \phpbb\template\template */
protected $template;
/** @var string php File extension */
protected $php_ext;
/**
* Constructor.
*
* @param \phpbbstudio\aps\core\functions $functions APS Core functions
* @param \phpbb\controller\helper $helper Controller helper object
* @param \phpbb\language\language $language Language object
* @param \phpbb\template\template $template Template object
* @param string $php_ext php File extension
* @return void
* @access public
*/
public function __construct(
\phpbbstudio\aps\core\functions $functions,
\phpbb\controller\helper $helper,
\phpbb\language\language $language,
\phpbb\template\template $template,
$php_ext
)
{
$this->functions = $functions;
$this->helper = $helper;
$this->language = $language;
$this->template = $template;
$this->php_ext = $php_ext;
}
/**
* Assign functions defined in this class to event listeners in the core.
*
* @static
* @return array
* @access public
*/
static public function getSubscribedEvents()
{
return [
'core.user_setup' => 'load_lang',
'core.page_header_after' => 'display_links',
'core.viewonline_overwrite_location' => 'view_online',
'core.ucp_pm_view_message' => 'display_pm',
'core.viewtopic_post_rowset_data' => 'set_post',
'core.viewtopic_cache_user_data' => 'cache_post',
'core.viewtopic_modify_post_row' => 'display_post',
'core.memberlist_prepare_profile_data' => 'display_profile',
];
}
/**
* Load language during user set up.
*
* @event core.user_setup
* @return void
* @access public
*/
public function load_lang()
{
$this->language->add_lang('aps_common', 'phpbbstudio/aps');
}
public function display_links()
{
$locations = array_filter($this->functions->get_link_locations());
if ($locations)
{
$this->template->assign_vars(array_combine(array_map(function($key) {
return 'S_APS_' . strtoupper($key);
}, array_keys($locations)), $locations));
}
}
/**
* Display the points page when viewing the Who is Online page.
*
* @event core.viewonline_overwrite_location
* @param \phpbb\event\data $event The event object
* @return void
* @access public
*/
public function view_online(\phpbb\event\data $event)
{
if ($event['on_page'][1] === 'app' && strrpos($event['row']['session_page'], 'app.' . $this->php_ext . '/points') === 0)
{
$event['location'] = $this->language->lang('APS_VIEWING_POINTS_PAGE', $this->functions->get_name());
$event['location_url'] = $this->helper->route('phpbbstudio_aps_display');
}
}
/**
* Display the user points when viewing a Private Message.
*
* @event core.ucp_pm_view_message
* @param \phpbb\event\data $event The event object
* @return void
* @access public
*/
public function display_pm(\phpbb\event\data $event)
{
$event['msg_data'] = array_merge($event['msg_data'], [
'AUTHOR_POINTS' => $event['user_info']['user_points'],
]);
}
/**
* Set the user points after being retrieved from the database.
*
* @event core.viewtopic_post_rowset_data
* @param \phpbb\event\data $event The event object
* @return void
* @access public
*/
public function set_post(\phpbb\event\data $event)
{
$event['rowset_data'] = array_merge($event['rowset_data'], [
'user_points' => $event['row']['user_points'],
]);
}
/**
* Cache the user points when displaying a post.
*
* @event core.viewtopic_cache_user_data
* @param \phpbb\event\data $event The event object
* @return void
* @access public
*/
public function cache_post(\phpbb\event\data $event)
{
$event['user_cache_data'] = array_merge($event['user_cache_data'], [
'user_points' => $event['row']['user_points'],
]);
}
/**
* Display the user points when displaying a post.
*
* @event core.viewtopic_modify_post_row
* @param \phpbb\event\data $event The event object
* @return void
* @access public
*/
public function display_post(\phpbb\event\data $event)
{
$event['post_row'] = array_merge($event['post_row'], [
'POSTER_POINTS' => $event['user_cache'][$event['poster_id']]['user_points'],
]);
}
/**
* Display the user points when display a profile.
*
* @event core.memberlist_prepare_profile_data
* @param \phpbb\event\data $event The event object
* @return void
* @access public
*/
public function display_profile(\phpbb\event\data $event)
{
$event['template_data'] = array_merge($event['template_data'], [
'USER_POINTS' => $event['data']['user_points'],
]);
}
}

View File

@@ -1,83 +0,0 @@
<?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\event;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* phpBB Studio - Advanced Points System Event listener: Modules.
*/
class modules implements EventSubscriberInterface
{
/** @var \phpbbstudio\aps\core\functions */
protected $functions;
/** @var \phpbb\language\language */
protected $language;
/**
* Constructor.
*
* @param \phpbbstudio\aps\core\functions $functions APS Core functions
* @param \phpbb\language\language $language Language object
* @return void
* @access public
*/
public function __construct(\phpbbstudio\aps\core\functions $functions, \phpbb\language\language $language)
{
$this->functions = $functions;
$this->language = $language;
}
/**
* Assign functions defined in this class to event listeners in the core.
*
* @static
* @return array
* @access public
*/
static public function getSubscribedEvents()
{
return [
'core.modify_module_row' => 'module_names',
];
}
/**
* Localise the APS module titles.
*
* @event core.modify_module_row
* @param \phpbb\event\data $event The event object
* @return void
* @access public
*/
public function module_names(\phpbb\event\data $event)
{
$module = $event['module_row'];
$langname = $module['langname'];
switch ($langname)
{
case 'ACP_APS_MODE_POINTS':
case 'MCP_APS_POINTS':
case 'UCP_APS_POINTS':
$module['lang'] = $this->language->lang($langname, ucfirst($this->functions->get_name()));
break;
default:
return;
break;
}
$event['module_row'] = $module;
}
}

View File

@@ -1,67 +0,0 @@
<?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\event;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* phpBB Studio - Advanced Points System Event listener: Permissions.
*/
class permissions implements EventSubscriberInterface
{
/**
* Assign functions defined in this class to event listeners in the core.
*
* @static
* @return array
* @access public
*/
static public function getSubscribedEvents()
{
return [
'core.permissions' => 'permissions',
];
}
/**
* Add Advanced Points System permissions
*
* @event core.permissions
* @param \phpbb\event\data $event The event object
* @return void
* @access public
*/
public function permissions(\phpbb\event\data $event)
{
$categories = $event['categories'];
$permissions = $event['permissions'];
if (empty($categories['phpbb_studio']))
{
$categories['phpbb_studio'] = 'ACL_CAT_PHPBB_STUDIO';
$event['categories'] = $categories;
}
$perms = [
'a_aps_logs', 'a_aps_points', 'a_aps_reasons', 'a_aps_display', 'a_aps_settings',
'm_aps_adjust_custom', 'm_aps_adjust_reason',
'u_aps_view_build', 'u_aps_view_build_other', 'u_aps_view_logs', 'u_aps_view_logs_other', 'u_aps_view_mod',
];
foreach ($perms as $permission)
{
$permissions[$permission] = ['lang' => 'ACL_' . utf8_strtoupper($permission), 'cat' => 'phpbb_studio'];
}
$event['permissions'] = $permissions;
}
}

View File

@@ -1,159 +0,0 @@
<?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;
/**
* phpBB Studio - Advanced Points System Extension base
*/
class ext extends \phpbb\extension\base
{
public function is_enableable()
{
if (!(phpbb_version_compare(PHPBB_VERSION, '3.2.8', '>=') && phpbb_version_compare(PHPBB_VERSION, '4.0.0@dev', '<')))
{
if (phpbb_version_compare(PHPBB_VERSION, '3.3.0@dev', '<'))
{
$user = $this->container->get('user');
$user->add_lang_ext('phpbbstudio/aps', 'aps_ext');
$lang = $user->lang;
$lang['EXTENSION_NOT_ENABLEABLE'] .= '<br>' . $user->lang('APS_PHPBB_VERSION', '3.2.8', '4.0.0@dev');
$user->lang = $lang;
return false;
}
if (phpbb_version_compare(PHPBB_VERSION, '3.3.0@dev', '>'))
{
$language= $this->container->get('language');
$language->add_lang('aps_ext', 'phpbbstudio/aps');
return $language->lang('APS_PHPBB_VERSION', '3.2.8', '4.0.0@dev');
}
}
/**
* Now if Ultimate Points is enabled already.
*/
$ext_manager = $this->container->get('ext.manager');
$is_ups_enabled = $ext_manager->is_enabled('dmzx/ultimatepoints');
if ($is_ups_enabled)
{
if (phpbb_version_compare(PHPBB_VERSION, '3.3.0@dev', '<'))
{
$user = $this->container->get('user');
$user->add_lang_ext('phpbbstudio/aps', 'aps_ext');
$lang = $user->lang;
$lang['EXTENSION_NOT_ENABLEABLE'] .= '<br>' . $user->lang('APS_UP_INSTALLED');
$user->lang = $lang;
return false;
}
if (phpbb_version_compare(PHPBB_VERSION, '3.3.0@dev', '>'))
{
$language= $this->container->get('language');
$language->add_lang('aps_ext', 'phpbbstudio/aps');
return $language->lang('APS_UP_INSTALLED');
}
}
return true;
}
/**
* Enable notifications for the extension
*
* @param mixed $old_state State returned by previous call of this method
*
* @return mixed Returns false after last step, otherwise temporary state
*/
public function enable_step($old_state)
{
if ($old_state === false)
{
$this->container->get('notification_manager')
->enable_notifications('phpbbstudio.aps.notification.type.adjust');
return 'notification';
}
return parent::enable_step($old_state);
}
/**
* Disable notifications for the extension
*
* @param mixed $old_state State returned by previous call of this method
*
* @return mixed Returns false after last step, otherwise temporary state
*/
public function disable_step($old_state)
{
if ($old_state === false)
{
try
{
if ($this->container->hasParameter('phpbbstudio.aps.extended'))
{
$language = $this->container->get('language');
$language->add_lang('aps_ext', 'phpbbstudio/aps');
$message = $language->lang('APS_DISABLE_EXTENDED', $this->container->getParameter('phpbbstudio.aps.extended'));
// Trigger error for the ACP
@trigger_error($message, E_USER_WARNING);
// Throw an exception for the CLI
throw new \RuntimeException($message);
}
}
catch (\InvalidArgumentException $e)
{
// Continue
}
$this->container->get('notification_manager')
->disable_notifications('phpbbstudio.aps.notification.type.adjust');
return 'notification';
}
return parent::disable_step($old_state);
}
/**
* Purge notifications for the extension
*
* @param mixed $old_state State returned by previous call of this method
*
* @return mixed Returns false after last step, otherwise temporary state
*/
public function purge_step($old_state)
{
if ($old_state === false)
{
$this->container->get('notification_manager')
->purge_notifications('phpbbstudio.aps.notification.type.adjust');
return 'notification';
}
return parent::purge_step($old_state);
}
}

View File

@@ -1,148 +0,0 @@
<?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)
*
*/
if (!defined('IN_PHPBB'))
{
exit;
}
if (empty($lang) || !is_array($lang))
{
$lang = [];
}
/**
* Some characters you may want to copy&paste: » “ ” …
*/
$lang = array_merge($lang, [
// Logs mode
'ACP_APS_LOGS_EXPLAIN' => 'This lists all %s actions across the board. There are various sorting and searching options available.',
'ACP_APS_LOGS_DELETED' => [
1 => 'You have successfully deleted the log entry.',
2 => 'You have successfully deleted the log entries.',
],
// Points mode
'ACP_APS_POINTS_EXPLAIN' => 'Here you can set %1$s values for global actions. You can also manage the preset reasons used in adjusting a users %1$s.',
'ACP_APS_POINTS_SUCCESS' => 'Advanced Points System %s updated successfully.',
'ACP_APS_REASON_ADD' => 'Add reason',
'ACP_APS_REASON_EDIT' => 'Edit reason',
'ACP_APS_REASON_DELETE' => 'Delete reason',
'ACP_APS_REASON_DELETE_CONFIRM' => 'Are you sure you wish to delete this reason?',
'ACP_APS_REASON_DELETE_SUCCESS' => 'You have successfully deleted this reason.',
'ACP_APS_REASON_SAVED' => 'The reason has successfully been saved.',
'ACP_APS_REASON_EMPTY_SUBJECT' => 'The reason subject can not be empty.',
'ACP_APS_REASON_EMPTY_POINTS' => 'The reason %s can not be empty.',
// Display mode
'ACP_APS_DISPLAY_EXPLAIN' => 'Here you can determine the availability of display blocks and define some functionality.',
'ACP_APS_DISPLAY_SUCCESS' => 'Advanced Points System display settings updated successfully.',
'ACP_APS_DISPLAY_TOP_COUNT' => 'Top users count',
'ACP_APS_DISPLAY_TOP_COUNT_DESC' => 'The default amount of users to show for the “Top users” block.',
'ACP_APS_DISPLAY_TOP_CHANGE' => 'Allow changing top user count',
'ACP_APS_DISPLAY_TOP_CHANGE_DESC' => 'Whether users are allowed to increase the “Top users” count.',
'ACP_APS_DISPLAY_ADJUSTMENTS' => 'Adjustments count',
'ACP_APS_DISPLAY_ADJUSTMENTS_DESC' => 'The default amount of adjustments to show for the “Recent adjustments” block.',
'ACP_APS_DISPLAY_GRAPH_TIME' => 'Graph animation time',
'ACP_APS_DISPLAY_GRAPH_TIME_DESC' => 'The default animation time in milliseconds when displaying graph blocks.',
// Settings mode
'ACP_APS_SETTINGS_EXPLAIN' => 'Here you can determine the basic %1$s settings of your board, give it a fitting name and formatting, and among other settings adjust the default values for minimum and maximum %1$s.',
'ACP_APS_SETTINGS_SUCCESS' => 'Advanced Points System settings updated successfully.',
'ACP_APS_POINTS_CLEAN' => 'Clean %s table',
'ACP_APS_POINTS_CLEAN_CONFIRM' => 'Are you sure you wish to clean the %s table?',
'ACP_APS_POINTS_CLEAN_SUCCESS' => 'You have successfully cleaned the %s table.',
'ACP_APS_POINTS_COPY_EMPTY' => 'You need to select at least 1 “from” forum and one “to” forum.',
'ACP_APS_POINTS_COPY_TO' => 'Copy %s to',
'ACP_APS_POINTS_DECIMALS' => 'Decimal amount',
'ACP_APS_POINTS_DISPLAY_PM' => 'Display on view private message page',
'ACP_APS_POINTS_DISPLAY_PM_DESC' => 'Should %s be displayed in the mini-profile on the private message page.',
'ACP_APS_POINTS_DISPLAY_POST' => 'Display on viewtopic page',
'ACP_APS_POINTS_DISPLAY_POST_DESC' => 'Should %s be displayed in the mini-profile on the topic page.',
'ACP_APS_POINTS_DISPLAY_PROFILE' => 'Display on profile page',
'ACP_APS_POINTS_DISPLAY_PROFILE_DESC' => 'Should %s be displayed in a users profile page.',
'ACP_APS_POINTS_EXCLUDE_CHARS' => 'Exclude characters',
'ACP_APS_POINTS_EXCLUDE_CHARS_DESC' => 'This will not count the characters from the excluded words when calculating %s.',
'ACP_APS_POINTS_EXCLUDE_WORDS' => 'Exclude words',
'ACP_APS_POINTS_EXCLUDE_WORDS_DESC' => 'This will not count the words with equal or less than X characters when calculating %s.',
'ACP_APS_POINTS_ICON' => 'Icon',
'ACP_APS_POINTS_ICON_IMG' => 'Icon image',
'ACP_APS_POINTS_ICON_IMG_DESC' => 'Setting an image will override the icon selected above.<br />Images can be selected from the <samp>/images</samp> folder.',
'ACP_APS_POINTS_ICON_IMG_NO' => 'No image',
'ACP_APS_POINTS_ICON_POSITION' => 'Icon position',
'ACP_APS_POINTS_ICON_POSITION_LEFT' => 'Left',
'ACP_APS_POINTS_ICON_POSITION_RIGHT' => 'Right',
'ACP_APS_POINTS_MIN' => 'Minimum user %s',
'ACP_APS_POINTS_MIN_DESC' => 'If set, users %s can not go lower than this amount.',
'ACP_APS_POINTS_MAX' => 'Maximum user %s',
'ACP_APS_POINTS_MAX_DESC' => 'If set, users %s can not go higher than this amount.',
'ACP_APS_POINTS_NAMES' => 'Points names',
'ACP_APS_POINTS_PER_PAGE' => '%s actions per page',
'ACP_APS_POINTS_PER_PAGE_DESC' => 'The amount of %s actions that should be displayed per page.',
'ACP_APS_POINTS_SAFE_MODE' => 'Safe mode',
'ACP_APS_POINTS_SAFE_MODE_DESC' => 'Turning this on will catch and log any errors during point calculations.<br />When testing and developing custom actions this should be turned <strong>off</strong>.',
'ACP_APS_FORMATTING' => 'Formatting',
'ACP_APS_IGNORE_SETTINGS' => 'Ignore settings',
'ACP_APS_IGNORE_CRITERIA' => 'Ignore criteria',
'ACP_APS_IGNORE_CRITERIA_DESC' => 'What criteria should checked to see if a post will not receive points.',
'ACP_APS_IGNORE_MIN_CHARS' => 'Minimum characters',
'ACP_APS_IGNORE_MIN_CHARS_DESC' => 'Posts with less characters than this will not receive points.',
'ACP_APS_IGNORE_MIN_WORDS' => 'Minimum words',
'ACP_APS_IGNORE_MIN_WORDS_DESC' => 'Posts with less words than this will not receive points.',
'ACP_APS_IGNORE_EXCLUDED_CHARS' => 'Ignore excluded characters',
'ACP_APS_IGNORE_EXCLUDED_CHARS_DESC' => 'Do not count the “excluded characters” towards the “minimum characters” criteria.',
'ACP_APS_IGNORE_EXCLUDED_WORDS' => 'Ignore excluded words',
'ACP_APS_IGNORE_EXCLUDED_WORDS_DESC' => 'Do not count the “excluded words” towards the “minimum words” criteria.',
'ACP_APS_IGNORE_BOTH' => 'Both',
'ACP_APS_IGNORE_NONE' => 'None',
'ACP_APS_IGNORE_CHARS' => 'Chars',
'ACP_APS_IGNORE_WORDS' => 'Words',
'ACP_APS_CHAIN_SETTINGS' => 'Chain settings',
'ACP_APS_CHAIN_MERGE_DELETE' => 'When “merging” also trigger “delete”',
'ACP_APS_CHAIN_MERGE_DELETE_DESC' => 'If a topic is merged into an other, the initial topic will be deleted.<br />This determines if %s should be calculated for the delete action.',
'ACP_APS_CHAIN_MERGE_MOVE' => 'When “merging” also trigger “move”',
'ACP_APS_CHAIN_MERGE_MOVE_DESC' => 'If a topic is merged into an other, the initial topics posts will be moved.<br />This determines if %s should be calculated for the move action.',
'ACP_APS_CHAIN_WARN_PM' => 'When “warning” also trigger “pm”',
'ACP_APS_CHAIN_WARN_PM_DESC' => 'If a user is warned and <samp>“Notify user”</samp> is checked, a private message is send.<br />This determines if %s should be calculated for the private message action.',
'ACP_APS_CHARACTERS' => 'character(s)',
'ACP_APS_SEPARATOR_DEC' => 'Decimal separator',
'ACP_APS_SEPARATOR_THOU' => 'Thousands separator',
'ACP_APS_SEPARATOR_COMMA' => 'Comma',
'ACP_APS_SEPARATOR_PERIOD' => 'Period',
'ACP_APS_SEPARATOR_DASH' => 'Dash',
'ACP_APS_SEPARATOR_UNDERSCORE' => 'Underscore',
'ACP_APS_SEPARATOR_SPACE' => 'Space',
'ACP_APS_SEPARATOR_SPACE_NARROW' => 'Narrow space',
// Locations
'ACP_APS_LOCATIONS' => 'Link locations',
'ACP_APS_LOCATIONS_DESC' => 'Determine where the link to the Points page should be displayed.',
'ACP_APS_LOCATIONS_EXPLAIN' => 'This is an example of a board index. In here you can select where you want the link to show up.<br>You can select as many locations as you like, from nowhere to at all places.',
'ACP_APS_LOCATIONS_SUCCESS' => 'You have successfully updated the link locations.',
]);

View File

@@ -1,30 +0,0 @@
<?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)
*
*/
if (!defined('IN_PHPBB'))
{
exit;
}
if (empty($lang) || !is_array($lang))
{
$lang = [];
}
/**
* Some characters you may want to copy&paste: » “ ” …
*/
$lang = array_merge($lang, [
'APS_NOTIFICATION_ADJUSTED' => '<strong>Your %1$s were adjusted</strong>',
'APS_VIEWING_POINTS_PAGE' => 'Viewing the %s page',
'APS_POINTS_TOO_LOW' => 'You do not have enough %s to perform this action.',
'APS_POINTS_ACTION_COST' => 'The cost of this action is %s',
]);

View File

@@ -1,73 +0,0 @@
<?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)
*
*/
if (!defined('IN_PHPBB'))
{
exit;
}
if (empty($lang) || !is_array($lang))
{
$lang = [];
}
/**
* Some characters you may want to copy&paste: » “ ” …
*/
$lang = array_merge($lang, [
'APS_OVERVIEW' => 'Overview',
'APS_SUCCESS' => 'Success',
'APS_TOP_USERS' => 'Top users',
'APS_ADJUST_USER_POINTS' => 'Adjust user %s',
'APS_PURCHASE_POINTS' => 'Purchase %s',
'APS_POINTS_ACTION' => '%s action',
'APS_POINTS_ACTION_SEARCH' => 'Search %s action',
'APS_POINTS_ACTION_TIME' => '%s action time',
'APS_POINTS_ACTIONS' => '%s actions',
'APS_POINTS_ACTIONS_ALL' => 'All %s actions',
'APS_POINTS_ACTIONS_NONE' => 'There are no %s actions yet.',
'APS_POINTS_ACTIONS_PAGE' => 'Actions per page',
'APS_POINTS_ACTIONS_TOTAL' => [
1 => '%2$d %1$s action',
2 => '%2$d %1$s actions',
],
'APS_POINTS_BLOCK_ADD' => '%s block was added!',
'APS_POINTS_BLOCK_DELETE' => '%s block was removed!',
'APS_POINTS_BLOCK_MOVE' => '%s block was moved!',
'APS_POINTS_BLOCK_NO' => 'No blocks',
'APS_POINTS_BLOCK_NONE' => 'It looks like you do not have any blocks added.',
'APS_POINTS_BLOCK_NO_CONTENT' => 'Oops! Looks like something went wrong.<br />This block does not have any content!<br /><br />The required <code>{% block content %}...{% endblock %}</code> is missing!',
'APS_POINTS_FORMAT' => '%s format',
'APS_POINTS_MAX' => 'Maximum %s',
'APS_POINTS_MIN' => 'Minimum %s',
'APS_POINTS_NAME' => 'Name',
'APS_POINTS_DATA_EMPTY' => 'No %s data to display',
'APS_POINTS_GAINED' => '%s gained',
'APS_POINTS_GLOBAL' => 'Global',
'APS_POINTS_GROWTH' => '%s growth',
'APS_POINTS_LOST' => '%s lost',
'APS_POINTS_TRADE_OFF' => '%s trade off',
'APS_POINTS_PER_FORUM' => '%s per forum',
'APS_POINTS_PER_GROUP' => '%s per group',
'APS_RANDOM_USER' => 'Random user',
'APS_RECENT_ADJUSTMENTS' => 'Recent adjustments',
'APS_RECENT_ATTACHMENTS' => 'Recent attachments',
'APS_RECENT_POLL' => 'Recent poll',
]);

View File

@@ -1,28 +0,0 @@
<?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)
*
*/
if (!defined('IN_PHPBB'))
{
exit;
}
if (empty($lang) || !is_array($lang))
{
$lang = [];
}
/**
* Some characters you may want to copy&paste: » “ ” …
*/
$lang = array_merge($lang, [
'APS_DISABLE_EXTENDED' => 'Disabling the <strong>“Advanced Points System”</strong> is not possible as it is still being extended by an other extension. Extension name: <strong>“%s”</strong>',
'APS_PHPBB_VERSION' => 'Minimum phpBB version required is %1$s but less than %2$s',
'APS_UP_INSTALLED' => 'The extension <strong>“dmzx/ultimatepoints”</strong> is not compatible with this one!',
]);

View File

@@ -1,49 +0,0 @@
<?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)
*
*/
if (!defined('IN_PHPBB'))
{
exit;
}
if (empty($lang) || !is_array($lang))
{
$lang = [];
}
/**
* Some characters you may want to copy&paste: » “ ” …
*/
$lang = array_merge($lang, [
// ACP modules and modes
'ACP_APS_POINTS' => 'Advanced Points System',
'ACP_APS_MODE_SETTINGS' => 'Settings',
'ACP_APS_MODE_DISPLAY' => 'Display',
'ACP_APS_MODE_POINTS' => '%s',
'ACP_APS_MODE_LOGS' => 'Logs',
// ACP log
'LOG_ACP_APS_SETTINGS' => '<strong>Altered <abbr title="Advanced Points System">APS</abbr> settings</strong>',
'LOG_ACP_APS_DISPLAY' => '<strong>Altered <abbr title="Advanced Points System">APS</abbr> display settings</strong>',
'LOG_ACP_APS_POINTS' => '<strong>Altered <abbr title="Advanced Points System">APS</abbr> %s</strong>',
'LOG_ACP_APS_POINTS_COPIED' => '<strong>Copied <abbr title="Advanced Points System">APS</abbr> %3$s</strong> for %2$s<br>from %1$s',
'LOG_ACP_APS_POINTS_RESET' => '<strong>Reset <abbr title="Advanced Points System">APS</abbr> %2$s</strong><br>» %1$s',
'LOG_ACP_APS_LOCATIONS' => '<strong>Updated <abbr title="Advanced Points System">APS</abbr> link locations</strong>',
'LOG_ACP_APS_LOGS_CLEARED' => '<strong>Cleared <abbr title="Advanced Points System">APS</abbr> %s actions</strong>',
'LOG_ACP_APS_LOGS_DELETED' => '<strong>Deleted <abbr title="Advanced Points System">APS</abbr> %s actions</strong>',
'LOG_ACP_APS_COPIED' => '<strong>Copied <abbr title="Advanced Points System">APS</abbr> %s to multiple forums</strong>',
'LOG_ACP_APS_CLEANED' => '<strong>Cleaned the <abbr title="Advanced Points System">APS</abbr> %s table</strong>',
'LOG_ACP_APS_REASON_ADD' => '<strong>Added an <abbr title="Advanced Points System">APS</abbr> reason</strong>',
'LOG_ACP_APS_REASON_EDIT' => '<strong>Edited an <abbr title="Advanced Points System">APS</abbr> reason</strong>',
'LOG_ACP_APS_REASON_DELETE' => '<strong>Deleted an <abbr title="Advanced Points System">APS</abbr> reason</strong>',
'LOG_ACP_APS_CALCULATION_ERROR' => '<strong><abbr title="Advanced Points System">APS</abbr> - There was an error calculating the %4$s</strong><br />Error: <samp>%1$s</samp><br />File: <samp>%2$s</samp><br />Line: <samp>%3$s</samp>',
]);

View File

@@ -1,39 +0,0 @@
<?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)
*
*/
if (!defined('IN_PHPBB'))
{
exit;
}
if (empty($lang) || !is_array($lang))
{
$lang = [];
}
/**
* Some characters you may want to copy&paste: » “ ” …
*/
$lang = array_merge($lang, [
'MCP_APS_POINTS' => '%s',
'MCP_APS_CHANGE' => 'Change',
'MCP_APS_FRONT' => 'Front',
'MCP_APS_LOGS' => 'Logs',
'MCP_APS_LATEST_ADJUSTED' => 'Latest %d adjustments',
'MCP_APS_USERS_TOP' => 'Top %d users',
'MCP_APS_USERS_BOTTOM' => 'Bottom %d users',
'MCP_APS_POINTS_CURRENT' => 'Current %s',
'MCP_APS_POINTS_CHANGE' => 'Change %s',
'MCP_APS_POINTS_USER_CHANGE' => 'Are you sure you want to adjust this users %s?',
'MCP_APS_POINTS_USER_CHANGE_SUCCESS' => 'The %s for this user have successfully been adjusted.',
]);

View File

@@ -1,26 +0,0 @@
<?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)
*
*/
if (!defined('IN_PHPBB'))
{
exit;
}
if (empty($lang) || !is_array($lang))
{
$lang = [];
}
/**
* Some characters you may want to copy&paste: » “ ” …
*/
$lang = array_merge($lang, [
'UCP_APS_POINTS' => '%s',
]);

View File

@@ -1,41 +0,0 @@
<?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)
*
*/
if (!defined('IN_PHPBB'))
{
exit;
}
if (empty($lang) || !is_array($lang))
{
$lang = [];
}
/**
* Some characters you may want to copy&paste: » “ ” …
*/
$lang = array_merge($lang, [
'ACL_CAT_PHPBB_STUDIO' => 'phpBB Studio',
'ACL_A_APS_LOGS' => '<strong>Advanced Points System</strong> - Can manage the logs',
'ACL_A_APS_POINTS' => '<strong>Advanced Points System</strong> - Can manage the points',
'ACL_A_APS_REASONS' => '<strong>Advanced Points System</strong> - Can manage the reasons',
'ACL_A_APS_DISPLAY' => '<strong>Advanced Points System</strong> - Can manage the display',
'ACL_A_APS_SETTINGS' => '<strong>Advanced Points System</strong> - Can manage the settings',
'ACL_M_APS_ADJUST_CUSTOM' => '<strong>Advanced Points System</strong> - Can adjust a users points with a custom action',
'ACL_M_APS_ADJUST_REASON' => '<strong>Advanced Points System</strong> - Can adjust a users points with a predefined reason',
'ACL_U_APS_VIEW_BUILD' => '<strong>Advanced Points System</strong> - Can view their augmentation<br /><em>Augmentation is the “build up” of the total points.</em>',
'ACL_U_APS_VIEW_BUILD_OTHER' => '<strong>Advanced Points System</strong> - Can view other users augmentation<br /><em>This requires “Can view their augmentation” to be set to Yes.</em>',
'ACL_U_APS_VIEW_MOD' => '<strong>Advanced Points System</strong> - Can view the moderator',
'ACL_U_APS_VIEW_LOGS' => '<strong>Advanced Points System</strong> - Can view their logs',
'ACL_U_APS_VIEW_LOGS_OTHER' => '<strong>Advanced Points System</strong> - Can view other users logs<br /><em>This requires “Can view their logs” to be set to Yes.</em>',
]);

View File

@@ -1,155 +0,0 @@
<?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)
*
*/
if (!defined('IN_PHPBB'))
{
exit;
}
if (empty($lang) || !is_array($lang))
{
$lang = [];
}
/**
* Some characters you may want to copy&paste: » “ ” …
*/
$lang = array_merge($lang, [
'ACP_APS_POINTS_COPY' => 'Copy %s from',
'ACP_APS_POINTS_COPY_EMPTY_FROM' => 'You have to select a “from” forum',
'ACP_APS_POINTS_COPY_EXPLAIN' => 'If you select to copy %1$s, the forum will have the same %1$s as the one you select here. This will overwrite any %1$s you have previously set for this forum with the %1$s of the forum you select here. If no forum is selected, the current %1$s will be kept.',
'ACP_APS_POINTS_COPY_NOT' => 'Do not copy %s',
'ACP_APS_POINTS_COPY_SUCCESS' => 'You have successfully copied the %s.',
'ACP_APS_POINTS_COPY_TITLE' => 'Copy %s',
'ACP_APS_POINTS_RESET' => 'Reset %s',
'ACP_APS_POINTS_RESET_CONFIRM' => 'Are you sure you wish to to reset the %s for this forum?',
'ACP_APS_POINTS_RESET_EXPLAIN' => 'If you select to reset %1$s, all values for this forum will be set to 0. This will overwrite any %1$s you have previously set for this forum or any forum you selected below to copy %1$s from.',
'ACP_APS_POINTS_RESET_SUCCESS' => 'You have successfully reset the %s.',
'APS_POINTS_DIFF' => '%s difference',
'APS_POINTS_OLD' => 'Old %s',
'APS_POINTS_NEW' => 'New %s',
# Global
'APS_POINTS_REGISTER' => 'Registered',
'APS_POINTS_BIRTHDAY' => 'Celebrated their birthday',
'APS_POINTS_BIRTHDAY_DESC' => 'This action is ran through the system cron once a day. <br /><samp>ACP &raquo; General &raquo; Server settings &raquo; Run periodic tasks from system cron',
'APS_POINTS_MOD_WARN' => 'Warned a user',
'APS_POINTS_USER_WARN' => 'Received a warning',
'APS_POINTS_PM' => 'Created a private message',
'APS_POINTS_PM_PER_RECIPIENT' => 'Per recipient',
# Misc
'ACP_APS_POINTS_MISC' => 'Miscellaneous',
'APS_POINTS_PER_VOTE' => 'Per option voted for',
'APS_POINTS_VOTE_ADDED' => 'Voted in a poll',
'APS_POINTS_VOTE_REMOVED' => 'Removed a vote',
'APS_POINTS_VOTE_AMOUNT' => 'Amount of options voted for',
# Topics / Posts
'APS_POINTS_POST' => 'Created a post',
'APS_POINTS_TOPIC' => 'Created a topic',
'APS_POINTS_STICKY' => 'Created a sticky',
'APS_POINTS_ANNOUNCE' => 'Created an announcement',
'APS_POINTS_GLOBAL' => 'Created a global announcement',
'APS_POINTS_PER_CHAR' => 'Per character',
'APS_POINTS_PER_CHAR_DESC' => 'The text is stripped from BBCodes before counting the characters.',
'APS_POINTS_PER_WORD' => 'Per word',
'APS_POINTS_PER_WORD_DESC' => 'The text is stripped from BBCodes before counting the words.',
'APS_POINTS_ATTACH_HAS' => 'Including attachment(s)',
'APS_POINTS_ATTACH_PER' => 'Per included attachment',
'APS_POINTS_PER_QUOTE' => 'Per quote',
'APS_POINTS_PER_QUOTE_DESC' => 'Only the outer most quotes are counted and only if there is an author provided.',
'APS_POINTS_POLL_HAS' => 'Included a poll',
'APS_POINTS_POLL_OPTION' => 'Per included poll option',
'APS_POINTS_EDIT' => 'Edited their post',
'APS_POINTS_DELETE' => 'Deleted their post',
'APS_POINTS_DELETE_SOFT' => 'Soft deleted their post',
'APS_POINTS_BUMP' => 'Bumped a topic',
# Topic types
'ACP_APS_TOPIC_TYPES' => 'Topic types',
'APS_POINTS_MOD_NORMAL_STICKY' => 'Made a topic a sticky',
'APS_POINTS_MOD_NORMAL_ANNOUNCE' => 'Made a topic an announcement',
'APS_POINTS_MOD_NORMAL_GLOBAL' => 'Made a topic a global announcement',
'APS_POINTS_MOD_STICKY_NORMAL' => 'Made a sticky a normal topic',
'APS_POINTS_MOD_STICKY_ANNOUNCE' => 'Made a sticky an announcement',
'APS_POINTS_MOD_STICKY_GLOBAL' => 'Made a sticky a global announcement',
'APS_POINTS_MOD_ANNOUNCE_NORMAL' => 'Made an announcement a normal topic',
'APS_POINTS_MOD_ANNOUNCE_STICKY' => 'Made an announcement a sticky',
'APS_POINTS_MOD_ANNOUNCE_GLOBAL' => 'Made an announcement a global announcement',
'APS_POINTS_MOD_GLOBAL_NORMAL' => 'Made a global announcement a normal topic',
'APS_POINTS_MOD_GLOBAL_STICKY' => 'Made a global announcement a sticky',
'APS_POINTS_MOD_GLOBAL_ANNOUNCE' => 'Made a global announcement an announcement',
'APS_POINTS_USER_NORMAL_STICKY' => 'Their topic was made a sticky',
'APS_POINTS_USER_NORMAL_ANNOUNCE' => 'Their topic was made an announcement',
'APS_POINTS_USER_NORMAL_GLOBAL' => 'Their topic was made a global announcement',
'APS_POINTS_USER_STICKY_NORMAL' => 'Their sticky was made a normal topic',
'APS_POINTS_USER_STICKY_ANNOUNCE' => 'Their sticky was made an announcement',
'APS_POINTS_USER_STICKY_GLOBAL' => 'Their sticky was made a global announcement',
'APS_POINTS_USER_ANNOUNCE_NORMAL' => 'Their announcement was made a normal topic',
'APS_POINTS_USER_ANNOUNCE_STICKY' => 'Their announcement was made a sticky',
'APS_POINTS_USER_ANNOUNCE_GLOBAL' => 'Their announcement was made a global announcement',
'APS_POINTS_USER_GLOBAL_NORMAL' => 'Their global announcement was made a normal topic',
'APS_POINTS_USER_GLOBAL_STICKY' => 'Their global announcement was made a sticky',
'APS_POINTS_USER_GLOBAL_ANNOUNCE' => 'Their global announcement was made an announcement',
# Moderation
'APS_POINTS_MOD_COPY' => 'Copied a topic from this forum',
'APS_POINTS_USER_COPY' => 'Their topic got copied from this forum',
'APS_POINTS_MOD_CHANGE' => 'Changed a posts author',
'APS_POINTS_USER_CHANGE_FROM' => 'Removed as a posts author',
'APS_POINTS_USER_CHANGE_TO' => 'Became a posts author',
'APS_POINTS_MOD_DELETE_POST' => 'Deleted a post',
'APS_POINTS_USER_DELETE_POST' => 'Their post got deleted',
'APS_POINTS_MOD_DELETE_SOFT_POST' => 'Soft deleted a post',
'APS_POINTS_USER_DELETE_SOFT_POST' => 'Their post got soft deleted',
'APS_POINTS_MOD_DELETE_TOPIC' => 'Deleted a topic',
'APS_POINTS_USER_DELETE_TOPIC' => 'Their topic got deleted',
'APS_POINTS_MOD_DELETE_SOFT_TOPIC' => 'Soft deleted a topic',
'APS_POINTS_USER_DELETE_SOFT_TOPIC' => 'Their topic got soft deleted',
'APS_POINTS_MOD_EDIT' => 'Edited a post',
'APS_POINTS_USER_EDIT' => 'Their post got edited',
'APS_POINTS_MOD_LOCK' => 'Locked a topic',
'APS_POINTS_USER_LOCK' => 'Their topic got locked',
'APS_POINTS_MOD_LOCK_POST' => 'Locked a post',
'APS_POINTS_USER_LOCK_POST' => 'Their post got locked',
'APS_POINTS_MOD_UNLOCK' => 'Unlocked a topic',
'APS_POINTS_USER_UNLOCK' => 'Their topic got unlocked',
'APS_POINTS_MOD_UNLOCK_POST' => 'Unlocked a post',
'APS_POINTS_USER_UNLOCK_POST' => 'Their post got unlocked',
'APS_POINTS_MOD_MERGE' => 'Merged a topic',
'APS_POINTS_MOD_MERGE_DESC' => 'This will also trigger the “delete” action on the topics that are being merged into an other.',
'APS_POINTS_USER_MERGE' => 'Their topic got merged',
'APS_POINTS_USER_MERGE_DESC' => 'This will also trigger the “delete” action on the topics that are being merged into an other.',
'APS_POINTS_MOD_MOVE_POST' => 'Moved a post',
'APS_POINTS_MOD_MOVE_POST_DESC' => 'Moved values are for moving <strong>from</strong> this forum, not <em>to</em>.',
'APS_POINTS_USER_MOVE_POST' => 'Their post got moved',
'APS_POINTS_MOD_MOVE_TOPIC' => 'Moved a topic',
'APS_POINTS_USER_MOVE_TOPIC' => 'Their topic got moved',
'APS_POINTS_MOD_APPROVE' => 'Approved a post',
'APS_POINTS_MOD_DISAPPROVE' => 'Disapproved a post',
'APS_POINTS_MOD_RESTORE' => 'Restored a post',
'APS_POINTS_USER_APPROVE' => 'Their post is approved',
'APS_POINTS_USER_DISAPPROVE' => 'Their post is disapproved',
'APS_POINTS_USER_RESTORE' => 'Their post is restored',
'APS_POINTS_USER_ADJUSTED' => 'Adjusted by moderator',
]);

View File

@@ -1,280 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS

View File

@@ -1,42 +0,0 @@
<?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\mcp;
/**
* phpBB Studio - Advanced Points System MCP module info.
*/
class main_info
{
function module()
{
return [
'filename' => '\phpbbstudio\aps\mcp\main_module',
'title' => 'MCP_APS_POINTS',
'modes' => [
'front' => [
'title' => 'MCP_APS_FRONT',
'auth' => 'ext_phpbbstudio/aps',
'cat' => ['MCP_APS_POINTS']
],
'change' => [
'title' => 'MCP_APS_CHANGE',
'auth' => 'ext_phpbbstudio/aps && (acl_m_aps_adjust_custom || acl_m_aps_adjust_reason)',
'cat' => ['MCP_APS_POINTS']
],
'logs' => [
'title' => 'MCP_APS_LOGS',
'auth' => 'ext_phpbbstudio/aps && acl_u_aps_view_logs',
'cat' => ['MCP_APS_POINTS']
],
],
];
}
}

View File

@@ -1,48 +0,0 @@
<?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\mcp;
/**
* phpBB Studio - Advanced Points System MCP module.
*/
class main_module
{
/** @var string MCP Page title */
var $page_title;
/** @var string MCP Page template */
var $tpl_name;
/** @var string Custom form action */
var $u_action;
function main($id, $mode)
{
/** @var \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container */
global $phpbb_container;
/** @var \phpbbstudio\aps\core\functions $functions */
$functions = $phpbb_container->get('phpbbstudio.aps.functions');
/** @var \phpbb\language\language $language */
$language = $phpbb_container->get('language');
/** @var \phpbbstudio\aps\controller\mcp_controller $mcp_controller */
$mcp_controller = $phpbb_container->get('phpbbstudio.aps.controller.mcp');
// Set page title and template
$this->tpl_name = 'mcp/mcp_aps_' . $mode;
$this->page_title = $language->lang('MCP_APS_POINTS_' . utf8_strtoupper($mode), $functions->get_name());
// Make the custom form action available in the controller and handle the mode
$mcp_controller->set_page_url($this->u_action)->{$mode}();
}
}

View File

@@ -1,78 +0,0 @@
<?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\migrations;
/**
* phpBB Studio - Advanced Points System migrations: ACP Module.
*/
class install_acp_module extends \phpbb\db\migration\migration
{
/**
* Allows you to check if the migration is effectively installed (entirely optional)
*
* This is checked when a migration is installed. If true is returned, the migration will be set as
* installed without performing the database changes.
* This function is intended to help moving to migrations from a previous database updater, where some
* migrations may have been installed already even though they are not yet listed in the migrations table.
*
* @return bool True if this migration is installed, False if this migration is not installed (checked on install)
* @access public
*/
public function effectively_installed()
{
$sql = 'SELECT module_id
FROM ' . $this->table_prefix . "modules
WHERE module_class = 'acp'
AND module_langname = 'ACP_APS_POINTS'";
$result = $this->db->sql_query($sql);
$module_id = $this->db->sql_fetchfield('module_id');
$this->db->sql_freeresult($result);
return $module_id !== false;
}
/**
* Assign migration file dependencies for this migration.
*
* @return array Array of migration files
* @access public
* @static
*/
static public function depends_on()
{
return ['\phpbb\db\migration\data\v32x\v327'];
}
/**
* Add the Advanced Points System ACP module to the database.
*
* @return array Array of module data
* @access public
*/
public function update_data()
{
return [
['module.add', [
'acp',
'ACP_CAT_DOT_MODS',
'ACP_APS_POINTS'
]],
['module.add', [
'acp',
'ACP_APS_POINTS',
[
'module_basename' => '\phpbbstudio\aps\acp\main_module',
'modes' => ['settings', 'display', 'points', 'logs'],
],
]],
];
}
}

View File

@@ -1,84 +0,0 @@
<?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\migrations;
/**
* phpBB Studio - Advanced Points System migrations: Configuration.
*/
class install_configuration extends \phpbb\db\migration\migration
{
/**
* Allows you to check if the migration is effectively installed (entirely optional)
*
* This is checked when a migration is installed. If true is returned, the migration will be set as
* installed without performing the database changes.
* This function is intended to help moving to migrations from a previous database updater, where some
* migrations may have been installed already even though they are not yet listed in the migrations table.
*
* @return bool True if this migration is installed, False if this migration is not installed (checked on install)
* @access public
*/
public function effectively_installed()
{
return $this->config->offsetExists('aps_points_name_en');
}
/**
* Assign migration file dependencies for this migration.
*
* @return array Array of migration files
* @access public
* @static
*/
static public function depends_on()
{
return ['\phpbbstudio\aps\migrations\install_user_schema'];
}
/**
* Add the Advanced Points System configuration to the database.
*
* @return array Array of configuration
* @access public
*/
public function update_data()
{
return [
['config.add', ['aps_points_name_en', 'Points']],
['config.add', ['aps_points_safe_mode', false]], // @todo Change to true upon release
['config.add', ['aps_points_icon', 'fa-money']],
['config.add', ['aps_points_icon_position', 1]],
['config.add', ['aps_points_decimals', 2]],
['config.add', ['aps_points_separator_dec', ',']],
['config.add', ['aps_points_separator_thou', htmlspecialchars('&#8239;')]],
['config.add', ['aps_points_display_pm', true]],
['config.add', ['aps_points_display_post', true]],
['config.add', ['aps_points_display_profile', true]],
['config.add', ['aps_points_min', '']],
['config.add', ['aps_points_max', '']],
['config.add', ['aps_points_exclude_words', 1]],
['config.add', ['aps_points_exclude_chars', 1]],
['config.add', ['aps_birthday_last_run', 0, true]],
['config.add', ['aps_notification_id', 0]],
['config.add', ['aps_actions_per_page', 10]],
['config.add', ['aps_chain_merge_delete', false]],
['config.add', ['aps_chain_merge_move', false]],
['config.add', ['aps_chain_warn_pm', false]],
['config.add', ['aps_display_top_change', true]],
['config.add', ['aps_display_top_count', 3]],
['config.add', ['aps_display_adjustments', 5]],
['config.add', ['aps_display_graph_time', 1500]],
];
}
}

View File

@@ -1,78 +0,0 @@
<?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\migrations;
/**
* phpBB Studio - Advanced Points System migrations: MCP Module.
*/
class install_mcp_module extends \phpbb\db\migration\migration
{
/**
* Allows you to check if the migration is effectively installed (entirely optional)
*
* This is checked when a migration is installed. If true is returned, the migration will be set as
* installed without performing the database changes.
* This function is intended to help moving to migrations from a previous database updater, where some
* migrations may have been installed already even though they are not yet listed in the migrations table.
*
* @return bool True if this migration is installed, False if this migration is not installed (checked on install)
* @access public
*/
public function effectively_installed()
{
$sql = 'SELECT module_id
FROM ' . $this->table_prefix . "modules
WHERE module_class = 'mcp'
AND module_langname = 'MCP_APS_POINTS'";
$result = $this->db->sql_query($sql);
$module_id = $this->db->sql_fetchfield('module_id');
$this->db->sql_freeresult($result);
return $module_id !== false;
}
/**
* Assign migration file dependencies for this migration.
*
* @return array Array of migration files
* @access public
* @static
*/
static public function depends_on()
{
return ['\phpbbstudio\aps\migrations\install_acp_module'];
}
/**
* Add the Advanced Points System MCP module to the database.
*
* @return array Array of module data
* @access public
*/
public function update_data()
{
return [
['module.add', [
'mcp',
0,
'MCP_APS_POINTS'
]],
['module.add', [
'mcp',
'MCP_APS_POINTS',
[
'module_basename' => '\phpbbstudio\aps\mcp\main_module',
'modes' => ['front', 'change', 'logs'],
],
]],
];
}
}

View File

@@ -1,117 +0,0 @@
<?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\migrations;
/**
* phpBB Studio - Advanced Points System migrations: Permissions.
*/
class install_permissions extends \phpbb\db\migration\migration
{
/**
* Assign migration file dependencies for this migration.
*
* @return array Array of migration files
* @access public
* @static
*/
static public function depends_on()
{
return ['\phpbbstudio\aps\migrations\install_user_schema'];
}
/**
* Add the Advanced Points System permissions to the database.
*
* @return array Array of permission
* @access public
*/
public function update_data()
{
$data = [
['permission.add', ['a_aps_logs']],
['permission.add', ['a_aps_points']],
['permission.add', ['a_aps_reasons']],
['permission.add', ['a_aps_display']],
['permission.add', ['a_aps_settings']],
['permission.add', ['m_aps_adjust_custom']],
['permission.add', ['m_aps_adjust_reason']],
['permission.add', ['u_aps_view_build']],
['permission.add', ['u_aps_view_logs']],
['permission.add', ['u_aps_view_mod']],
];
if ($this->role_exists('ROLE_USER_STANDARD'))
{
$data[] = ['permission.permission_set', ['ROLE_USER_STANDARD', 'u_aps_view_build']];
$data[] = ['permission.permission_set', ['ROLE_USER_STANDARD', 'u_aps_view_logs']];
// Can NOT view the moderator's name
}
if ($this->role_exists('ROLE_USER_FULL'))
{
$data[] = ['permission.permission_set', ['ROLE_USER_FULL', 'u_aps_view_build']];
$data[] = ['permission.permission_set', ['ROLE_USER_FULL', 'u_aps_view_logs']];
$data[] = ['permission.permission_set', ['ROLE_USER_FULL', 'u_aps_view_mod']];
}
if ($this->role_exists('ROLE_MOD_STANDARD'))
{
$data[] = ['permission.permission_set', ['ROLE_MOD_STANDARD', 'm_aps_adjust_reason']];
// Can NOT adjust a user's points with a custom action, only admin defined ones
}
if ($this->role_exists('ROLE_MOD_FULL'))
{
$data[] = ['permission.permission_set', ['ROLE_MOD_FULL', 'm_aps_adjust_custom']];
$data[] = ['permission.permission_set', ['ROLE_MOD_FULL', 'm_aps_adjust_reason']];
}
if ($this->role_exists('ROLE_ADMIN_STANDARD'))
{
$data[] = ['permission.permission_set', ['ROLE_ADMIN_STANDARD', 'a_aps_logs']];
$data[] = ['permission.permission_set', ['ROLE_ADMIN_STANDARD', 'a_aps_points']];
$data[] = ['permission.permission_set', ['ROLE_ADMIN_STANDARD', 'a_aps_reasons']];
$data[] = ['permission.permission_set', ['ROLE_ADMIN_STANDARD', 'a_aps_display']];
$data[] = ['permission.permission_set', ['ROLE_ADMIN_STANDARD', 'a_aps_settings']];
}
if ($this->role_exists('ROLE_ADMIN_FULL'))
{
$data[] = ['permission.permission_set', ['ROLE_ADMIN_FULL', 'a_aps_logs']];
$data[] = ['permission.permission_set', ['ROLE_ADMIN_FULL', 'a_aps_points']];
$data[] = ['permission.permission_set', ['ROLE_ADMIN_FULL', 'a_aps_reasons']];
$data[] = ['permission.permission_set', ['ROLE_ADMIN_FULL', 'a_aps_display']];
$data[] = ['permission.permission_set', ['ROLE_ADMIN_FULL', 'a_aps_settings']];
}
return $data;
}
/**
* Checks whether the given role does exist or not.
*
* @param string $role The name of the role
* @return bool True if the role exists, false otherwise
*/
private function role_exists($role)
{
$sql = 'SELECT role_id
FROM ' . ACL_ROLES_TABLE . '
WHERE role_name = "' . $this->db->sql_escape($role) . '"';
$result = $this->db->sql_query_limit($sql, 1);
$role_id = $this->db->sql_fetchfield('role_id');
$this->db->sql_freeresult($result);
return (bool) $role_id;
}
}

View File

@@ -1,79 +0,0 @@
<?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\migrations;
/**
* phpBB Studio - Advanced Points System migrations: UCP Module.
*/
class install_ucp_module extends \phpbb\db\migration\migration
{
/**
* Allows you to check if the migration is effectively installed (entirely optional)
*
* This is checked when a migration is installed. If true is returned, the migration will be set as
* installed without performing the database changes.
* This function is intended to help moving to migrations from a previous database updater, where some
* migrations may have been installed already even though they are not yet listed in the migrations table.
*
* @return bool True if this migration is installed, False if this migration is not installed (checked on install)
* @access public
*/
public function effectively_installed()
{
$sql = 'SELECT module_id
FROM ' . $this->table_prefix . "modules
WHERE module_class = 'ucp'
AND module_langname = 'UCP_APS_POINTS'";
$result = $this->db->sql_query($sql);
$module_id = $this->db->sql_fetchfield('module_id');
$this->db->sql_freeresult($result);
return $module_id !== false;
}
/**
* Assign migration file dependencies for this migration.
*
* @return array Array of migration files
* @access public
* @static
*/
static public function depends_on()
{
return ['\phpbbstudio\aps\migrations\install_acp_module'];
}
/**
* Add the Advanced Points System UCP module to the database.
*
* @return array Array of module data
* @access public
*/
public function update_data()
{
return [
['module.add', [
'ucp',
0,
[
'module_enabled' => 1,
'module_display' => 1,
'module_basename' => '',
'module_class' => 'ucp',
'parent_id' => 0,
'module_langname' => 'UCP_APS_POINTS',
'module_mode' => '',
'module_auth' => 'ext_phpbbstudio/aps',
]
]],
];
}
}

View File

@@ -1,142 +0,0 @@
<?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\migrations;
/**
* phpBB Studio - Advanced Points System migrations: Database changes.
*/
class install_user_schema extends \phpbb\db\migration\migration
{
/**
* Allows you to check if the migration is effectively installed (entirely optional)
*
* This is checked when a migration is installed. If true is returned, the migration will be set as
* installed without performing the database changes.
* This function is intended to help moving to migrations from a previous database updater, where some
* migrations may have been installed already even though they are not yet listed in the migrations table.
*
* @return bool True if this migration is installed, False if this migration is not installed (checked on install)
* @access public
*/
public function effectively_installed()
{
return $this->db_tools->sql_column_exists($this->table_prefix . 'users', 'user_points');
}
/**
* Assign migration file dependencies for this migration.
*
* @return array Array of migration files
* @access public
* @static
*/
static public function depends_on()
{
return ['\phpbbstudio\aps\migrations\install_acp_module'];
}
/**
* Add the Advanced Points System tables and columns to the database.
*
* @return array Array of tables and columns data
* @access public
*/
public function update_schema()
{
return [
'add_columns' => [
$this->table_prefix . 'users' => [
'user_points' => ['DECIMAL:14', 0.00],
],
],
'add_tables' => [
$this->table_prefix . 'aps_display' => [
'COLUMNS' => [
'user_id' => ['ULINT', 0],
'aps_display' => ['MTEXT_UNI', ''],
],
'PRIMARY_KEY' => 'user_id',
],
$this->table_prefix . 'aps_logs' => [
'COLUMNS' => [
'log_id' => ['ULINT', null, 'auto_increment'],
'log_action' => ['TEXT_UNI', ''],
'log_actions' => ['MTEXT_UNI', ''],
'log_time' => ['TIMESTAMP', 0],
'log_approved' => ['BOOL', 1],
'forum_id' => ['ULINT', 0],
'topic_id' => ['ULINT', 0],
'post_id' => ['ULINT', 0],
'user_id' => ['ULINT', 0],
'reportee_id' => ['ULINT', 0],
'reportee_ip' => ['VCHAR:40', ''],
'points_old' => ['DECIMAL:14', 0.00],
'points_sum' => ['DECIMAL:14', 0.00],
'points_new' => ['DECIMAL:14', 0.00],
],
'PRIMARY_KEY' => 'log_id',
'KEYS' => [
'forum_id' => ['INDEX', 'forum_id'],
'topic_id' => ['INDEX', 'topic_id'],
'post_id' => ['INDEX', 'post_id'],
'user_id' => ['INDEX', 'user_id'],
'reportee_id' => ['INDEX', 'reportee_id'],
],
],
$this->table_prefix . 'aps_points' => [
'COLUMNS' => [
'points_name' => ['VCHAR_UNI', ''],
'points_value' => ['DECIMAL:6', 0.00],
'forum_id' => ['ULINT', 0],
],
'PRIMARY_KEY' => ['points_name', 'forum_id'],
'KEYS' => [
'forum_id' => ['INDEX', 'forum_id'],
],
],
$this->table_prefix . 'aps_reasons' => [
'COLUMNS' => [
'reason_id' => ['ULINT', null, 'auto_increment'],
'reason_title' => ['VCHAR_UNI', ''],
'reason_desc' => ['TEXT_UNI', ''],
'reason_points' => ['DECIMAL:14', 0.00],
'reason_order' => ['UINT', 0],
],
'PRIMARY_KEY' => 'reason_id',
],
],
];
}
/**
* Reverts the database schema by providing a set of change instructions
*
* @return array Array of schema changes
* (compatible with db_tools->perform_schema_changes())
* @access public
*/
public function revert_schema()
{
return [
'drop_columns' => [
$this->table_prefix . 'users' => [
'user_points',
],
],
'drop_tables' => [
$this->table_prefix . 'aps_display',
$this->table_prefix . 'aps_logs',
$this->table_prefix . 'aps_points',
$this->table_prefix . 'aps_reasons',
],
];
}
}

View File

@@ -1,58 +0,0 @@
<?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\migrations;
/**
* phpBB Studio - Advanced Points System migrations: Configuration.
*/
class update_configuration extends \phpbb\db\migration\migration
{
/**
* Allows you to check if the migration is effectively installed (entirely optional)
*
* This is checked when a migration is installed. If true is returned, the migration will be set as
* installed without performing the database changes.
* This function is intended to help moving to migrations from a previous database updater, where some
* migrations may have been installed already even though they are not yet listed in the migrations table.
*
* @return bool True if this migration is installed, False if this migration is not installed (checked on install)
* @access public
*/
public function effectively_installed()
{
return $this->config->offsetExists('aps_points_icon_img');
}
/**
* Assign migration file dependencies for this migration.
*
* @return array Array of migration files
* @access public
* @static
*/
static public function depends_on()
{
return ['\phpbbstudio\aps\migrations\install_configuration'];
}
/**
* Add the Advanced Points System configuration to the database.
*
* @return array Array of configuration
* @access public
*/
public function update_data()
{
return [
['config.add', ['aps_points_icon_img', '']],
];
}
}

Some files were not shown because too many files have changed in this diff Show More