db = $db;
$this->group_helper = $group_helper;
$this->language = $language;
$this->log = $log;
$this->notification = $notification;
$this->operator_cat = $operator_cat;
$this->operator_item = $operator_item;
$this->request = $request;
$this->template = $template;
$this->user = $user;
$this->groups_table = $groups_table;
$this->users_table = $users_table;
$this->user_group_table = $user_group_table;
$this->inventory_table = $inventory_table;
$this->root_path = $root_path;
$this->php_ext = $php_ext;
}
/**
* Handle and display the "Inventory" ACP mode.
*
* @return void
* @access public
*/
public function inventory()
{
$this->language->add_lang(['ass_acp_common', 'ass_common'], 'phpbbstudio/ass');
$type = $this->request->variable('type', '', true);
$submit = $this->request->is_set_post('submit');
$errors = [];
$form_key = 'ass_inventory';
add_form_key($form_key);
switch ($type)
{
case 'global';
$action = $this->request->variable('action', 'add', true);
$item_ids = $this->request->variable('items', [0]);
$group_ids = $this->request->variable('groups', [0]);
$usernames = $this->request->variable('usernames', '', true);
$items = [];
/** @var category $category */
foreach ($this->operator_cat->get_categories() as $category)
{
$this->template->assign_block_vars('categories', array_merge([
'S_INACTIVE' => !$category->get_active(),
], $this->operator_cat->get_variables($category)));
$items += $category_items = $this->operator_item->get_items($category->get_id());
/** @var item $item */
foreach ($category_items as $item)
{
$this->template->assign_block_vars('categories.items', array_merge([
'S_INACTIVE' => !$item->get_active(),
'S_SELECTED' => in_array($item->get_id(), $item_ids),
], $this->operator_item->get_variables($item)));
}
}
if ($submit)
{
if (!check_form_key($form_key))
{
$errors[] = 'FORM_INVALID';
}
if (!in_array($action, ['add', 'delete']))
{
$errors[] = 'NO_ACTION';
}
if (empty($item_ids))
{
$errors[] = 'ACP_ASS_NO_ITEMS_SELECTED';
}
$user_ids = [];
$usernames_array = array_filter(explode("\n", $usernames));
if (empty($usernames_array) && empty($group_ids))
{
$this->language->add_lang('acp/permissions');
$errors[] = 'NO_USER_GROUP_SELECTED';
}
if (!empty($usernames_array))
{
$this->get_ids_from_usernames($usernames_array, $user_ids, $errors);
}
if (!empty($group_ids))
{
$this->get_ids_from_groups($group_ids, $user_ids);
}
if (empty($errors) && empty($user_ids))
{
$errors[] = 'NO_GROUP_MEMBERS';
}
if (empty($errors))
{
$user_ids = array_unique($user_ids);
$this->update_inventory($action, $user_ids, $item_ids);
$count_items = count($item_ids);
$count_users = count($user_ids);
$item_names = [];
foreach ($item_ids as $item_id)
{
$item_names[] = $items[$item_id]->get_title();
}
$l_action = 'ACP_ASS_INVENTORY_' . utf8_strtoupper($action);
$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, "LOG_{$l_action}", time(), [$count_items, implode(', ', $item_names), $count_users, implode(', ', $usernames_array)]);
$message = $this->language->lang("{$l_action}_SUCCESS", $count_items);
$message .= '
» ' . $this->language->lang('ACP_ASS_AMOUNT_ITEMS') . $this->language->lang('COLON') . ' ' . $count_items;
$message .= '
» ' . $this->language->lang('ACP_ASS_AMOUNT_USERS') . $this->language->lang('COLON') . ' ' . $count_users;
$message .= adm_back_link($this->u_action);
trigger_error($message);
}
}
$sql = 'SELECT group_id, group_name, group_type
FROM ' . $this->groups_table . "
WHERE group_name <> 'BOTS'
AND group_name <> 'GUESTS'
ORDER BY group_type DESC, group_name ASC";
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
$this->template->assign_block_vars('groups', [
'ID' => (int) $row['group_id'],
'NAME' => $this->group_helper->get_name($row['group_name']),
'S_SELECTED' => in_array((int) $row['group_id'], $group_ids),
'S_SPECIAL' => GROUP_SPECIAL === (int) $row['group_type'],
]);
}
$this->db->sql_freeresult($result);
$this->template->assign_vars([
'USERNAMES' => $usernames,
'S_ADD' => $action === 'add',
'U_FIND_USER' => append_sid("{$this->root_path}memberlist.{$this->php_ext}", [
'mode' => 'searchuser',
'form' => 'ass_inventory',
'field' => 'usernames',
]),
]);
break;
case 'manage':
$action = $this->request->variable('action', '', true);
$username = $this->request->variable('username', '', true);
$user_id = $this->request->variable('u', 0);
$item_ids = $this->request->variable('items', [0]);
if (empty($username) && empty($user_id))
{
$this->template->assign_var('U_FIND_USER', append_sid("{$this->root_path}memberlist.{$this->php_ext}", [
'mode' => 'searchuser',
'form' => 'ass_inventory',
'field' => 'username',
'select_single' => true,
]));
}
else
{
if (empty($user_id))
{
$user_ids = [];
$this->get_ids_from_usernames([$username], $user_ids, $errors);
if (empty($user_ids))
{
trigger_error($this->language->lang('NO_USER') . adm_back_link($this->u_action . "&type={$type}"), E_USER_WARNING);
}
$user_id = (int) reset($user_ids);
}
$rowset = [];
$sql = 'SELECT i.*, u.username as gifter_name, u.user_colour as gifter_colour
FROM ' . $this->inventory_table . ' i
LEFT JOIN ' . $this->users_table . ' u
ON i.gifter_id = u.user_id
WHERE i.user_id = ' . (int) $user_id;
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
$rowset[(int) $row['item_id']] = $row;
}
$this->db->sql_freeresult($result);
$inventory = [
'categories' => array_column($rowset, 'category_id'),
'items' => array_keys($rowset),
];
$items = [];
$categories = $this->operator_cat->get_categories();
/** @var category $category */
foreach ($categories as $category)
{
$this->template->assign_block_vars('categories', array_merge([
'S_INACTIVE' => !$category->get_active(),
'S_INVENTORY' => in_array($category->get_id(), $inventory['categories']),
], $this->operator_cat->get_variables($category)));
$items += $category_items = $this->operator_item->get_items($category->get_id());
/** @var item $item */
foreach ($category_items as $item)
{
$variables = array_merge([
'S_INACTIVE' => !$item->get_active(),
'S_INVENTORY' => in_array($item->get_id(), $inventory['items']),
'S_SELECTED' => in_array($item->get_id(), $item_ids),
], $this->operator_item->get_variables($item));
if ($variables['S_INVENTORY'])
{
$row = $rowset[$item->get_id()];
$variables = array_merge($variables, [
'GIFTER' => $row['gifter_id'] ? get_username_string('full', $row['gifter_id'], $row['gifter_name'], $row['gifter_colour']) : '',
'PURCHASE_TIME' => $this->user->format_date($row['purchase_time']),
'USE_TIME' => $row['use_time'] ? $this->user->format_date($row['use_time']) : $this->language->lang('NEVER'),
'USE_COUNT' => (int) $row['use_count'],
]);
}
$this->template->assign_block_vars('categories.items', $variables);
}
}
$u_back = $this->u_action . "&type={$type}&u={$user_id}";
if ($action === 'delete')
{
$item_id = $this->request->variable('iid', 0);
if (confirm_box(true))
{
$this->update_inventory($action, [$user_id], [$item_id]);
if (empty($username))
{
$username = $this->get_username($user_id);
}
$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_ACP_ASS_INVENTORY_DELETE_USER', time(), [$items[$item_id]->get_title(), $username]);
trigger_error($this->language->lang('ASS_DELETE_SUCCESS') . adm_back_link($u_back));
}
else
{
confirm_box(false, 'ASS_DELETE', '');
redirect($u_back);
}
}
if ($submit)
{
if (!check_form_key($form_key))
{
$errors[] = 'FORM_INVALID';
}
if (empty($item_ids))
{
$errors[] = 'ACP_ASS_NO_ITEMS_SELECTED';
}
if (empty($errors))
{
$this->update_inventory('add', [$user_id], $item_ids);
if (empty($username))
{
$username = $this->get_username($user_id);
}
$count_items = count($item_ids);
$item_names = [];
foreach ($item_ids as $item_id)
{
$item_names[] = $items[$item_id]->get_title();
}
$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_ACP_ASS_INVENTORY_ADD_USER', time(), [$count_items, implode(', ', $item_names), $username]);
trigger_error($this->language->lang('ACP_ASS_INVENTORY_ADD_SUCCESS', $count_items) . adm_back_link($u_back));
}
}
$this->template->assign_vars([
'ASS_USERNAME' => $username,
'U_DELETE' => $this->u_action . "&type={$type}&u={$user_id}&action=delete&iid=",
]);
}
break;
default:
$this->template->assign_vars([
'U_GLOBAL' => $this->u_action . '&type=global',
'U_MANAGE' => $this->u_action . '&type=manage',
]);
break;
}
$this->template->assign_vars([
'ERRORS' => $errors,
'S_TYPE' => $type,
'U_ACTION' => $this->u_action . ($type ? "&type={$type}" : ''),
'U_BACK' => $this->u_action,
]);
}
/**
* Update users' inventories.
*
* @param string $action The action to perform (add|delete)
* @param array $user_ids The user identifiers
* @param array $item_ids The item identifiers
* @return void
* @access protected
*/
protected function update_inventory($action, array $user_ids, array $item_ids)
{
switch ($action)
{
case 'add':
$owned = [];
$stack = [];
$sql = 'SELECT item_id, user_id
FROM ' . $this->inventory_table . '
WHERE ' . $this->db->sql_in_set('item_id', $item_ids) . '
AND ' . $this->db->sql_in_set('user_id', $user_ids);
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
$item_id = (int) $row['item_id'];
$user_id = (int) $row['user_id'];
$owned[$item_id][] = $user_id;
$stack[$user_id][$item_id][] = $item_id;
}
$this->db->sql_freeresult($result);
$items = $this->operator_item->get_items_by_id($item_ids);
foreach ($item_ids as $item_id)
{
/** @var item $item */
$item = $items[$item_id];
$users = !empty($owned[$item_id]) && !$item->get_stack() ? array_diff($user_ids, $owned[$item_id]) : $user_ids;
foreach ($users as $user_id)
{
$sql = 'INSERT INTO ' . $this->inventory_table . ' ' . $this->db->sql_build_array('INSERT', [
'category_id' => $item->get_category(),
'item_id' => $item->get_id(),
'user_id' => $user_id,
'gifter_id' => (int) $this->user->data['user_id'],
'purchase_time' => time(),
'purchase_price' => 0.00,
]);
$this->db->sql_query($sql);
$index = !empty($stack[$user_id][$item_id]) ? count($stack[$user_id][$item_id]) : 0;
$index = $index + 1;
$this->notification->gift($item, $user_id, $this->db->sql_nextid(), $index);
}
}
break;
case 'delete':
$sql = 'DELETE FROM ' . $this->inventory_table . '
WHERE ' . $this->db->sql_in_set('item_id', $item_ids) . '
AND ' . $this->db->sql_in_set('user_id', $user_ids);
$this->db->sql_query($sql);
break;
}
}
/**
* Get user identifiers from usernames.
*
* @param array $usernames The usernames
* @param array $user_ids The user identifiers
* @param array $errors The errors
* @return void
* @access protected
*/
protected function get_ids_from_usernames(array $usernames, array &$user_ids, array &$errors)
{
$usernames_clean = [];
$usernames_found = [];
foreach ($usernames as $username)
{
$usernames_clean[$username] = utf8_clean_string($username);
}
$sql = 'SELECT user_id, username_clean
FROM ' . $this->users_table . '
WHERE ' . $this->db->sql_in_set('username_clean', $usernames_clean);
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
$usernames_found[] = $row['username_clean'];
$user_ids[] = (int) $row['user_id'];
}
$this->db->sql_freeresult($result);
$usernames_not_found = array_diff($usernames_clean, $usernames_found);
if (!empty($usernames_not_found))
{
$errors[] = count($usernames_not_found) > 1 ? 'NO_USERS' : 'NO_USER';
$not_found = array_intersect($usernames_clean, $usernames_not_found);
$not_found = array_flip($not_found);
foreach ($not_found as $username)
{
$errors[] = '» ' . $username;
}
}
}
/**
* Get user identifiers from group identifiers.
*
* @param array $group_ids The group identifiers
* @param array $user_ids The user identifiers
* @return void
* @access protected
*/
protected function get_ids_from_groups(array $group_ids, array &$user_ids)
{
$sql = 'SELECT user_id
FROM ' . $this->user_group_table . '
WHERE user_pending <> 1
AND ' . $this->db->sql_in_set('group_id', $group_ids);
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
$user_ids[] = (int) $row['user_id'];
}
$this->db->sql_freeresult($result);
}
/**
* Get a username from user identifier.
*
* @param int $user_id The user identifier
* @return string The username
* @access protected
*/
protected function get_username($user_id)
{
$sql = 'SELECT username
FROM ' . $this->users_table . '
WHERE user_id = ' . (int) $user_id;
$result = $this->db->sql_query_limit($sql, 1);
$username = $this->db->sql_fetchfield('username');
$this->db->sql_freeresult($result);
return (string) $username;
}
/**
* Set custom form action.
*
* @param string $u_action Custom form action
* @return self $this This controller for chaining calls
* @access public
*/
public function set_page_url($u_action)
{
$this->u_action = $u_action;
return $this;
}
}