uawdijnntqw1x1x1
IP : 216.73.216.23
Hostname : web17.us.cloudlogin.co
Kernel : Linux web17.us.cloudlogin.co 5.10.238-xeon-hst #1 SMP Thu Jun 5 12:15:42 UTC 2025 x86_64
Disable Function : None :)
OS : Linux
PATH:
/
home
/
www
/
hallgroupsolutions.com
/
e61a0
/
..
/
d10d3
/
..
/
c9428
/
acp.tar
/
/
acp_send_statistics.php000077700000004054151514745240011325 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_send_statistics { var $u_action; function main($id, $mode) { global $config, $template, $phpbb_admin_path, $phpbb_root_path, $phpEx; include($phpbb_root_path . 'includes/questionnaire/questionnaire.' . $phpEx); $collect_url = "https://www.phpbb.com/stats/receive_stats.php"; $this->tpl_name = 'acp_send_statistics'; $this->page_title = 'ACP_SEND_STATISTICS'; // generate a unique id if necessary if (!isset($config['questionnaire_unique_id'])) { $install_id = unique_id(); set_config('questionnaire_unique_id', $install_id); } else { $install_id = $config['questionnaire_unique_id']; } $collector = new phpbb_questionnaire_data_collector($install_id); // Add data provider $collector->add_data_provider(new phpbb_questionnaire_php_data_provider()); $collector->add_data_provider(new phpbb_questionnaire_system_data_provider()); $collector->add_data_provider(new phpbb_questionnaire_phpbb_data_provider($config)); $template->assign_vars(array( 'U_COLLECT_STATS' => $collect_url, 'RAW_DATA' => $collector->get_data_for_form(), 'U_ACP_MAIN' => append_sid("{$phpbb_admin_path}index.$phpEx"), )); $raw = $collector->get_data_raw(); foreach ($raw as $provider => $data) { if ($provider == 'install_id') { $data = array($provider => $data); } $template->assign_block_vars('providers', array( 'NAME' => htmlspecialchars($provider), )); foreach ($data as $key => $value) { if (is_array($value)) { $value = utf8_wordwrap(serialize($value), 75, "\n", true); } $template->assign_block_vars('providers.values', array( 'KEY' => utf8_htmlspecialchars($key), 'VALUE' => utf8_htmlspecialchars($value), )); } } } } acp_groups.php000077700000121455151514745240007446 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_groups { var $u_action; function main($id, $mode) { global $config, $db, $user, $auth, $template, $cache; global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix, $file_uploads; global $request, $phpbb_container, $phpbb_dispatcher; $user->add_lang('acp/groups'); $this->tpl_name = 'acp_groups'; $this->page_title = 'ACP_GROUPS_MANAGE'; $form_key = 'acp_groups'; add_form_key($form_key); if ($mode == 'position') { $this->manage_position(); return; } include($phpbb_root_path . 'includes/functions_user.' . $phpEx); // Check and set some common vars $action = (isset($_POST['add'])) ? 'add' : ((isset($_POST['addusers'])) ? 'addusers' : request_var('action', '')); $group_id = request_var('g', 0); $mark_ary = request_var('mark', array(0)); $name_ary = request_var('usernames', '', true); $leader = request_var('leader', 0); $default = request_var('default', 0); $start = request_var('start', 0); $update = (isset($_POST['update'])) ? true : false; // Clear some vars $group_row = array(); // Grab basic data for group, if group_id is set and exists if ($group_id) { $sql = 'SELECT g.*, t.teampage_position AS group_teampage FROM ' . GROUPS_TABLE . ' g LEFT JOIN ' . TEAMPAGE_TABLE . ' t ON (t.group_id = g.group_id) WHERE g.group_id = ' . $group_id; $result = $db->sql_query($sql); $group_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$group_row) { trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action), E_USER_WARNING); } // Check if the user is allowed to manage this group if set to founder only. if ($user->data['user_type'] != USER_FOUNDER && $group_row['group_founder_manage']) { trigger_error($user->lang['NOT_ALLOWED_MANAGE_GROUP'] . adm_back_link($this->u_action), E_USER_WARNING); } } // Which page? switch ($action) { case 'approve': case 'demote': case 'promote': if (!check_form_key($form_key)) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } if (!$group_id) { trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action), E_USER_WARNING); } // Approve, demote or promote $group_name = ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name']; $error = group_user_attributes($action, $group_id, $mark_ary, false, $group_name); if (!$error) { switch ($action) { case 'demote': $message = 'GROUP_MODS_DEMOTED'; break; case 'promote': $message = 'GROUP_MODS_PROMOTED'; break; case 'approve': $message = 'USERS_APPROVED'; break; } trigger_error($user->lang[$message] . adm_back_link($this->u_action . '&action=list&g=' . $group_id)); } else { trigger_error($user->lang[$error] . adm_back_link($this->u_action . '&action=list&g=' . $group_id), E_USER_WARNING); } break; case 'default': if (!$group_id) { trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action), E_USER_WARNING); } else if (empty($mark_ary)) { trigger_error($user->lang['NO_USERS'] . adm_back_link($this->u_action . '&action=list&g=' . $group_id), E_USER_WARNING); } if (confirm_box(true)) { $group_name = ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name']; group_user_attributes('default', $group_id, $mark_ary, false, $group_name, $group_row); trigger_error($user->lang['GROUP_DEFS_UPDATED'] . adm_back_link($this->u_action . '&action=list&g=' . $group_id)); } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 'mark' => $mark_ary, 'g' => $group_id, 'i' => $id, 'mode' => $mode, 'action' => $action)) ); } break; case 'set_default_on_all': if (confirm_box(true)) { $group_name = ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name']; $start = 0; do { $sql = 'SELECT user_id FROM ' . USER_GROUP_TABLE . " WHERE group_id = $group_id ORDER BY user_id"; $result = $db->sql_query_limit($sql, 200, $start); $mark_ary = array(); if ($row = $db->sql_fetchrow($result)) { do { $mark_ary[] = $row['user_id']; } while ($row = $db->sql_fetchrow($result)); group_user_attributes('default', $group_id, $mark_ary, false, $group_name, $group_row); $start = (sizeof($mark_ary) < 200) ? 0 : $start + 200; } else { $start = 0; } $db->sql_freeresult($result); } while ($start); trigger_error($user->lang['GROUP_DEFS_UPDATED'] . adm_back_link($this->u_action . '&action=list&g=' . $group_id)); } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 'mark' => $mark_ary, 'g' => $group_id, 'i' => $id, 'mode' => $mode, 'action' => $action)) ); } break; case 'deleteusers': if (empty($mark_ary)) { trigger_error($user->lang['NO_USERS'] . adm_back_link($this->u_action . '&action=list&g=' . $group_id), E_USER_WARNING); } case 'delete': if (!$group_id) { trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action), E_USER_WARNING); } else if ($action === 'delete' && $group_row['group_type'] == GROUP_SPECIAL) { trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } if (confirm_box(true)) { $error = ''; switch ($action) { case 'delete': if (!$auth->acl_get('a_groupdel')) { trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } $error = group_delete($group_id, $group_row['group_name']); break; case 'deleteusers': $group_name = ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name']; $error = group_user_del($group_id, $mark_ary, false, $group_name); break; } $back_link = ($action == 'delete') ? $this->u_action : $this->u_action . '&action=list&g=' . $group_id; if ($error) { trigger_error($user->lang[$error] . adm_back_link($back_link), E_USER_WARNING); } $message = ($action == 'delete') ? 'GROUP_DELETED' : 'GROUP_USERS_REMOVE'; trigger_error($user->lang[$message] . adm_back_link($back_link)); } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 'mark' => $mark_ary, 'g' => $group_id, 'i' => $id, 'mode' => $mode, 'action' => $action)) ); } break; case 'addusers': if (!check_form_key($form_key)) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } if (!$group_id) { trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action), E_USER_WARNING); } if (!$name_ary) { trigger_error($user->lang['NO_USERS'] . adm_back_link($this->u_action . '&action=list&g=' . $group_id), E_USER_WARNING); } $name_ary = array_unique(explode("\n", $name_ary)); $group_name = ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name']; // Add user/s to group if ($error = group_user_add($group_id, false, $name_ary, $group_name, $default, $leader, 0, $group_row)) { trigger_error($user->lang[$error] . adm_back_link($this->u_action . '&action=list&g=' . $group_id), E_USER_WARNING); } $message = ($leader) ? 'GROUP_MODS_ADDED' : 'GROUP_USERS_ADDED'; trigger_error($user->lang[$message] . adm_back_link($this->u_action . '&action=list&g=' . $group_id)); break; case 'edit': case 'add': include($phpbb_root_path . 'includes/functions_display.' . $phpEx); $data = $submit_ary = array(); if ($action == 'edit' && !$group_id) { trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action), E_USER_WARNING); } if ($action == 'add' && !$auth->acl_get('a_groupadd')) { trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } $error = array(); $user->add_lang('ucp'); // Setup avatar data for later $avatars_enabled = false; $avatar_drivers = null; $avatar_data = null; $avatar_error = array(); if ($config['allow_avatar']) { $phpbb_avatar_manager = $phpbb_container->get('avatar.manager'); $avatar_drivers = $phpbb_avatar_manager->get_enabled_drivers(); // This is normalised data, without the group_ prefix $avatar_data = \phpbb\avatar\manager::clean_row($group_row, 'group'); if (!isset($avatar_data['id'])) { $avatar_data['id'] = 'g' . $group_id; } } if ($request->is_set_post('avatar_delete')) { if (confirm_box(true)) { $avatar_data['id'] = substr($avatar_data['id'], 1); $phpbb_avatar_manager->handle_avatar_delete($db, $user, $avatar_data, GROUPS_TABLE, 'group_'); $message = ($action == 'edit') ? 'GROUP_UPDATED' : 'GROUP_CREATED'; trigger_error($user->lang[$message] . adm_back_link($this->u_action)); } else { confirm_box(false, $user->lang('CONFIRM_AVATAR_DELETE'), build_hidden_fields(array( 'avatar_delete' => true, 'i' => $id, 'mode' => $mode, 'g' => $group_id, 'action' => $action)) ); } } // Did we submit? if ($update) { if (!check_form_key($form_key)) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } $group_name = utf8_normalize_nfc(request_var('group_name', '', true)); $group_desc = utf8_normalize_nfc(request_var('group_desc', '', true)); $group_type = request_var('group_type', GROUP_FREE); $allow_desc_bbcode = request_var('desc_parse_bbcode', false); $allow_desc_urls = request_var('desc_parse_urls', false); $allow_desc_smilies = request_var('desc_parse_smilies', false); $submit_ary = array( 'colour' => request_var('group_colour', ''), 'rank' => request_var('group_rank', 0), 'receive_pm' => isset($_REQUEST['group_receive_pm']) ? 1 : 0, 'legend' => isset($_REQUEST['group_legend']) ? 1 : 0, 'teampage' => isset($_REQUEST['group_teampage']) ? 1 : 0, 'message_limit' => request_var('group_message_limit', 0), 'max_recipients' => request_var('group_max_recipients', 0), 'founder_manage' => 0, 'skip_auth' => request_var('group_skip_auth', 0), ); if ($user->data['user_type'] == USER_FOUNDER) { $submit_ary['founder_manage'] = isset($_REQUEST['group_founder_manage']) ? 1 : 0; } if ($config['allow_avatar']) { // Handle avatar $driver_name = $phpbb_avatar_manager->clean_driver_name($request->variable('avatar_driver', '')); if (in_array($driver_name, $avatar_drivers) && !$request->is_set_post('avatar_delete')) { $driver = $phpbb_avatar_manager->get_driver($driver_name); $result = $driver->process_form($request, $template, $user, $avatar_data, $avatar_error); if ($result && empty($avatar_error)) { $result['avatar_type'] = $driver_name; $submit_ary = array_merge($submit_ary, $result); } } else { $driver = $phpbb_avatar_manager->get_driver($avatar_data['avatar_type']); if ($driver) { $driver->delete($avatar_data); } // Removing the avatar $submit_ary['avatar_type'] = ''; $submit_ary['avatar'] = ''; $submit_ary['avatar_width'] = 0; $submit_ary['avatar_height'] = 0; } // Merge any avatar errors into the primary error array $error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error)); } /* * Validate the length of "Maximum number of allowed recipients per * private message" setting. We use 16777215 as a maximum because it matches * MySQL unsigned mediumint maximum value which is the lowest amongst DBMSes * supported by phpBB3. Also validate the submitted colour value. */ $validation_checks = array( 'max_recipients' => array('num', false, 0, 16777215), 'colour' => array('hex_colour', true), ); /** * Request group data and operate on it * * @event core.acp_manage_group_request_data * @var string action Type of the action: add|edit * @var int group_id The group id * @var array group_row Array with new group data * @var array error Array of errors, if you add errors * ensure to update the template variables * S_ERROR and ERROR_MSG to display it * @var string group_name The group name * @var string group_desc The group description * @var int group_type The group type * @var bool allow_desc_bbcode Allow bbcode in group description: true|false * @var bool allow_desc_urls Allow urls in group description: true|false * @var bool allow_desc_smilies Allow smiles in group description: true|false * @var array submit_ary Array with new group data * @var array validation_checks Array with validation data * @since 3.1.0-b5 */ $vars = array( 'action', 'group_id', 'group_row', 'error', 'group_name', 'group_desc', 'group_type', 'allow_desc_bbcode', 'allow_desc_urls', 'allow_desc_smilies', 'submit_ary', 'validation_checks', ); extract($phpbb_dispatcher->trigger_event('core.acp_manage_group_request_data', compact($vars))); if ($validation_error = validate_data($submit_ary, $validation_checks)) { // Replace "error" string with its real, localised form $error = array_merge($error, $validation_error); } if (!sizeof($error)) { // Only set the rank, colour, etc. if it's changed or if we're adding a new // group. This prevents existing group members being updated if no changes // were made. // However there are some attributes that need to be set everytime, // otherwise the group gets removed from the feature. $set_attributes = array('legend', 'teampage'); $group_attributes = array(); $test_variables = array( 'rank' => 'int', 'colour' => 'string', 'avatar' => 'string', 'avatar_type' => 'string', 'avatar_width' => 'int', 'avatar_height' => 'int', 'receive_pm' => 'int', 'legend' => 'int', 'teampage' => 'int', 'message_limit' => 'int', 'max_recipients'=> 'int', 'founder_manage'=> 'int', 'skip_auth' => 'int', ); /** * Initialise data before we display the add/edit form * * @event core.acp_manage_group_initialise_data * @var string action Type of the action: add|edit * @var int group_id The group id * @var array group_row Array with new group data * @var array error Array of errors, if you add errors * ensure to update the template variables * S_ERROR and ERROR_MSG to display it * @var string group_name The group name * @var string group_desc The group description * @var int group_type The group type * @var bool allow_desc_bbcode Allow bbcode in group description: true|false * @var bool allow_desc_urls Allow urls in group description: true|false * @var bool allow_desc_smilies Allow smiles in group description: true|false * @var array submit_ary Array with new group data * @var array test_variables Array with variables for test * @since 3.1.0-b5 */ $vars = array( 'action', 'group_id', 'group_row', 'error', 'group_name', 'group_desc', 'group_type', 'allow_desc_bbcode', 'allow_desc_urls', 'allow_desc_smilies', 'submit_ary', 'test_variables', ); extract($phpbb_dispatcher->trigger_event('core.acp_manage_group_initialise_data', compact($vars))); foreach ($test_variables as $test => $type) { if (isset($submit_ary[$test]) && ($action == 'add' || $group_row['group_' . $test] != $submit_ary[$test] || isset($group_attributes['group_avatar']) && strpos($test, 'avatar') === 0 || in_array($test, $set_attributes))) { settype($submit_ary[$test], $type); $group_attributes['group_' . $test] = $group_row['group_' . $test] = $submit_ary[$test]; } } if (!($error = group_create($group_id, $group_type, $group_name, $group_desc, $group_attributes, $allow_desc_bbcode, $allow_desc_urls, $allow_desc_smilies))) { $group_perm_from = request_var('group_perm_from', 0); // Copy permissions? // If the user has the a_authgroups permission and at least one additional permission ability set the permissions are fully transferred. // We do not limit on one auth category because this can lead to incomplete permissions being tricky to fix for the admin, roles being assigned or added non-default permissions. // Since the user only has the option to copy permissions from non leader managed groups this seems to be a good compromise. if ($group_perm_from && $action == 'add' && $auth->acl_get('a_authgroups') && $auth->acl_gets('a_aauth', 'a_fauth', 'a_mauth', 'a_uauth')) { $sql = 'SELECT group_founder_manage FROM ' . GROUPS_TABLE . ' WHERE group_id = ' . $group_perm_from; $result = $db->sql_query($sql); $check_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); // Check the group if non-founder if ($check_row && ($user->data['user_type'] == USER_FOUNDER || $check_row['group_founder_manage'] == 0)) { // From the mysql documentation: // Prior to MySQL 4.0.14, the target table of the INSERT statement cannot appear in the FROM clause of the SELECT part of the query. This limitation is lifted in 4.0.14. // Due to this we stay on the safe side if we do the insertion "the manual way" // Copy permisisons from/to the acl groups table (only group_id gets changed) $sql = 'SELECT forum_id, auth_option_id, auth_role_id, auth_setting FROM ' . ACL_GROUPS_TABLE . ' WHERE group_id = ' . $group_perm_from; $result = $db->sql_query($sql); $groups_sql_ary = array(); while ($row = $db->sql_fetchrow($result)) { $groups_sql_ary[] = array( 'group_id' => (int) $group_id, 'forum_id' => (int) $row['forum_id'], 'auth_option_id' => (int) $row['auth_option_id'], 'auth_role_id' => (int) $row['auth_role_id'], 'auth_setting' => (int) $row['auth_setting'] ); } $db->sql_freeresult($result); // Now insert the data $db->sql_multi_insert(ACL_GROUPS_TABLE, $groups_sql_ary); $auth->acl_clear_prefetch(); } } $cache->destroy('sql', array(GROUPS_TABLE, TEAMPAGE_TABLE)); $message = ($action == 'edit') ? 'GROUP_UPDATED' : 'GROUP_CREATED'; trigger_error($user->lang[$message] . adm_back_link($this->u_action)); } } if (sizeof($error)) { $error = array_map(array(&$user, 'lang'), $error); $group_rank = $submit_ary['rank']; $group_desc_data = array( 'text' => $group_desc, 'allow_bbcode' => $allow_desc_bbcode, 'allow_smilies' => $allow_desc_smilies, 'allow_urls' => $allow_desc_urls ); } } else if (!$group_id) { $group_name = utf8_normalize_nfc(request_var('group_name', '', true)); $group_desc_data = array( 'text' => '', 'allow_bbcode' => true, 'allow_smilies' => true, 'allow_urls' => true ); $group_rank = 0; $group_type = GROUP_OPEN; } else { $group_name = $group_row['group_name']; $group_desc_data = generate_text_for_edit($group_row['group_desc'], $group_row['group_desc_uid'], $group_row['group_desc_options']); $group_type = $group_row['group_type']; $group_rank = $group_row['group_rank']; } $sql = 'SELECT * FROM ' . RANKS_TABLE . ' WHERE rank_special = 1 ORDER BY rank_title'; $result = $db->sql_query($sql); $rank_options = '<option value="0"' . ((!$group_rank) ? ' selected="selected"' : '') . '>' . $user->lang['USER_DEFAULT'] . '</option>'; while ($row = $db->sql_fetchrow($result)) { $selected = ($group_rank && $row['rank_id'] == $group_rank) ? ' selected="selected"' : ''; $rank_options .= '<option value="' . $row['rank_id'] . '"' . $selected . '>' . $row['rank_title'] . '</option>'; } $db->sql_freeresult($result); $type_free = ($group_type == GROUP_FREE) ? ' checked="checked"' : ''; $type_open = ($group_type == GROUP_OPEN) ? ' checked="checked"' : ''; $type_closed = ($group_type == GROUP_CLOSED) ? ' checked="checked"' : ''; $type_hidden = ($group_type == GROUP_HIDDEN) ? ' checked="checked"' : ''; // Load up stuff for avatars if ($config['allow_avatar']) { $avatars_enabled = false; $selected_driver = $phpbb_avatar_manager->clean_driver_name($request->variable('avatar_driver', $avatar_data['avatar_type'])); foreach ($avatar_drivers as $current_driver) { $driver = $phpbb_avatar_manager->get_driver($current_driver); $avatars_enabled = true; $config_name = $phpbb_avatar_manager->get_driver_config_name($driver); $template->set_filenames(array( 'avatar' => "acp_avatar_options_{$config_name}.html", )); if ($driver->prepare_form($request, $template, $user, $avatar_data, $avatar_error)) { $driver_name = $phpbb_avatar_manager->prepare_driver_name($current_driver); $driver_upper = strtoupper($driver_name); $template->assign_block_vars('avatar_drivers', array( 'L_TITLE' => $user->lang($driver_upper . '_TITLE'), 'L_EXPLAIN' => $user->lang($driver_upper . '_EXPLAIN'), 'DRIVER' => $driver_name, 'SELECTED' => $current_driver == $selected_driver, 'OUTPUT' => $template->assign_display('avatar'), )); } } } $avatar = phpbb_get_group_avatar($group_row, 'GROUP_AVATAR', true); if (isset($phpbb_avatar_manager) && !$update) { // Merge any avatar errors into the primary error array $error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error)); } $back_link = request_var('back_link', ''); switch ($back_link) { case 'acp_users_groups': $u_back = append_sid("{$phpbb_admin_path}index.$phpEx", 'i=users&mode=groups&u=' . request_var('u', 0)); break; default: $u_back = $this->u_action; break; } $template->assign_vars(array( 'S_EDIT' => true, 'S_ADD_GROUP' => ($action == 'add') ? true : false, 'S_GROUP_PERM' => ($action == 'add' && $auth->acl_get('a_authgroups') && $auth->acl_gets('a_aauth', 'a_fauth', 'a_mauth', 'a_uauth')) ? true : false, 'S_INCLUDE_SWATCH' => true, 'S_ERROR' => (sizeof($error)) ? true : false, 'S_SPECIAL_GROUP' => ($group_type == GROUP_SPECIAL) ? true : false, 'S_USER_FOUNDER' => ($user->data['user_type'] == USER_FOUNDER) ? true : false, 'S_AVATARS_ENABLED' => ($config['allow_avatar'] && $avatars_enabled), 'ERROR_MSG' => (sizeof($error)) ? implode('<br />', $error) : '', 'GROUP_NAME' => ($group_type == GROUP_SPECIAL) ? $user->lang['G_' . $group_name] : $group_name, 'GROUP_INTERNAL_NAME' => $group_name, 'GROUP_DESC' => $group_desc_data['text'], 'GROUP_RECEIVE_PM' => (isset($group_row['group_receive_pm']) && $group_row['group_receive_pm']) ? ' checked="checked"' : '', 'GROUP_FOUNDER_MANAGE' => (isset($group_row['group_founder_manage']) && $group_row['group_founder_manage']) ? ' checked="checked"' : '', 'GROUP_LEGEND' => (isset($group_row['group_legend']) && $group_row['group_legend']) ? ' checked="checked"' : '', 'GROUP_TEAMPAGE' => (isset($group_row['group_teampage']) && $group_row['group_teampage']) ? ' checked="checked"' : '', 'GROUP_MESSAGE_LIMIT' => (isset($group_row['group_message_limit'])) ? $group_row['group_message_limit'] : 0, 'GROUP_MAX_RECIPIENTS' => (isset($group_row['group_max_recipients'])) ? $group_row['group_max_recipients'] : 0, 'GROUP_COLOUR' => (isset($group_row['group_colour'])) ? $group_row['group_colour'] : '', 'GROUP_SKIP_AUTH' => (!empty($group_row['group_skip_auth'])) ? ' checked="checked"' : '', 'S_DESC_BBCODE_CHECKED' => $group_desc_data['allow_bbcode'], 'S_DESC_URLS_CHECKED' => $group_desc_data['allow_urls'], 'S_DESC_SMILIES_CHECKED'=> $group_desc_data['allow_smilies'], 'S_RANK_OPTIONS' => $rank_options, 'S_GROUP_OPTIONS' => group_select_options(false, false, (($user->data['user_type'] == USER_FOUNDER) ? false : 0)), 'AVATAR' => empty($avatar) ? '<img src="' . $phpbb_admin_path . 'images/no_avatar.gif" alt="" />' : $avatar, 'AVATAR_MAX_FILESIZE' => $config['avatar_filesize'], 'AVATAR_WIDTH' => (isset($group_row['group_avatar_width'])) ? $group_row['group_avatar_width'] : '', 'AVATAR_HEIGHT' => (isset($group_row['group_avatar_height'])) ? $group_row['group_avatar_height'] : '', 'GROUP_TYPE_FREE' => GROUP_FREE, 'GROUP_TYPE_OPEN' => GROUP_OPEN, 'GROUP_TYPE_CLOSED' => GROUP_CLOSED, 'GROUP_TYPE_HIDDEN' => GROUP_HIDDEN, 'GROUP_TYPE_SPECIAL' => GROUP_SPECIAL, 'GROUP_FREE' => $type_free, 'GROUP_OPEN' => $type_open, 'GROUP_CLOSED' => $type_closed, 'GROUP_HIDDEN' => $type_hidden, 'U_BACK' => $u_back, 'U_ACTION' => "{$this->u_action}&action=$action&g=$group_id", 'L_AVATAR_EXPLAIN' => phpbb_avatar_explanation_string(), )); /** * Modify group template data before we display the form * * @event core.acp_manage_group_display_form * @var string action Type of the action: add|edit * @var bool update Do we display the form only * or did the user press submit * @var int group_id The group id * @var array group_row Array with new group data * @var string group_name The group name * @var int group_type The group type * @var array group_desc_data The group description data * @var string group_rank The group rank * @var string rank_options The rank options * @var array error Array of errors, if you add errors * ensure to update the template variables * S_ERROR and ERROR_MSG to display it * @since 3.1.0-b5 */ $vars = array( 'action', 'update', 'group_id', 'group_row', 'group_desc_data', 'group_name', 'group_type', 'group_rank', 'rank_options', 'error', ); extract($phpbb_dispatcher->trigger_event('core.acp_manage_group_display_form', compact($vars))); return; break; case 'list': if (!$group_id) { trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action), E_USER_WARNING); } $this->page_title = 'GROUP_MEMBERS'; $pagination = $phpbb_container->get('pagination'); // Grab the leaders - always, on every page... $sql = 'SELECT u.user_id, u.username, u.username_clean, u.user_regdate, u.user_colour, u.user_posts, u.group_id, ug.group_leader, ug.user_pending FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . " ug WHERE ug.group_id = $group_id AND u.user_id = ug.user_id AND ug.group_leader = 1 ORDER BY ug.group_leader DESC, ug.user_pending ASC, u.username_clean"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $template->assign_block_vars('leader', array( 'U_USER_EDIT' => append_sid("{$phpbb_admin_path}index.$phpEx", "i=users&action=edit&u={$row['user_id']}"), 'USERNAME' => $row['username'], 'USERNAME_COLOUR' => $row['user_colour'], 'S_GROUP_DEFAULT' => ($row['group_id'] == $group_id) ? true : false, 'JOINED' => ($row['user_regdate']) ? $user->format_date($row['user_regdate']) : ' - ', 'USER_POSTS' => $row['user_posts'], 'USER_ID' => $row['user_id'], )); } $db->sql_freeresult($result); // Total number of group members (non-leaders) $sql = 'SELECT COUNT(user_id) AS total_members FROM ' . USER_GROUP_TABLE . " WHERE group_id = $group_id AND group_leader = 0"; $result = $db->sql_query($sql); $total_members = (int) $db->sql_fetchfield('total_members'); $db->sql_freeresult($result); $s_action_options = ''; $options = array('default' => 'DEFAULT', 'approve' => 'APPROVE', 'demote' => 'DEMOTE', 'promote' => 'PROMOTE', 'deleteusers' => 'DELETE'); foreach ($options as $option => $lang) { $s_action_options .= '<option value="' . $option . '">' . $user->lang['GROUP_' . $lang] . '</option>'; } $base_url = $this->u_action . "&action=$action&g=$group_id"; $pagination->generate_template_pagination($base_url, 'pagination', 'start', $total_members, $config['topics_per_page'], $start); $template->assign_vars(array( 'S_LIST' => true, 'S_GROUP_SPECIAL' => ($group_row['group_type'] == GROUP_SPECIAL) ? true : false, 'S_ACTION_OPTIONS' => $s_action_options, 'GROUP_NAME' => ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name'], 'U_ACTION' => $this->u_action . "&g=$group_id", 'U_BACK' => $this->u_action, 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=list&field=usernames'), 'U_DEFAULT_ALL' => "{$this->u_action}&action=set_default_on_all&g=$group_id", )); // Grab the members $sql = 'SELECT u.user_id, u.username, u.username_clean, u.user_colour, u.user_regdate, u.user_posts, u.group_id, ug.group_leader, ug.user_pending FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . " ug WHERE ug.group_id = $group_id AND u.user_id = ug.user_id AND ug.group_leader = 0 ORDER BY ug.group_leader DESC, ug.user_pending ASC, u.username_clean"; $result = $db->sql_query_limit($sql, $config['topics_per_page'], $start); $pending = false; while ($row = $db->sql_fetchrow($result)) { if ($row['user_pending'] && !$pending) { $template->assign_block_vars('member', array( 'S_PENDING' => true) ); $pending = true; } $template->assign_block_vars('member', array( 'U_USER_EDIT' => append_sid("{$phpbb_admin_path}index.$phpEx", "i=users&action=edit&u={$row['user_id']}"), 'USERNAME' => $row['username'], 'USERNAME_COLOUR' => $row['user_colour'], 'S_GROUP_DEFAULT' => ($row['group_id'] == $group_id) ? true : false, 'JOINED' => ($row['user_regdate']) ? $user->format_date($row['user_regdate']) : ' - ', 'USER_POSTS' => $row['user_posts'], 'USER_ID' => $row['user_id']) ); } $db->sql_freeresult($result); return; break; } $template->assign_vars(array( 'U_ACTION' => $this->u_action, 'S_GROUP_ADD' => ($auth->acl_get('a_groupadd')) ? true : false) ); // Get us all the groups $sql = 'SELECT g.group_id, g.group_name, g.group_type FROM ' . GROUPS_TABLE . ' g ORDER BY g.group_type ASC, g.group_name'; $result = $db->sql_query($sql); $lookup = $cached_group_data = array(); while ($row = $db->sql_fetchrow($result)) { $type = ($row['group_type'] == GROUP_SPECIAL) ? 'special' : 'normal'; // used to determine what type a group is $lookup[$row['group_id']] = $type; // used for easy access to the data within a group $cached_group_data[$type][$row['group_id']] = $row; $cached_group_data[$type][$row['group_id']]['total_members'] = 0; } $db->sql_freeresult($result); // How many people are in which group? $sql = 'SELECT COUNT(ug.user_id) AS total_members, ug.group_id FROM ' . USER_GROUP_TABLE . ' ug WHERE ' . $db->sql_in_set('ug.group_id', array_keys($lookup)) . ' GROUP BY ug.group_id'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $type = $lookup[$row['group_id']]; $cached_group_data[$type][$row['group_id']]['total_members'] = $row['total_members']; } $db->sql_freeresult($result); // The order is... normal, then special ksort($cached_group_data); foreach ($cached_group_data as $type => $row_ary) { if ($type == 'special') { $template->assign_block_vars('groups', array( 'S_SPECIAL' => true) ); } foreach ($row_ary as $group_id => $row) { $group_name = (!empty($user->lang['G_' . $row['group_name']]))? $user->lang['G_' . $row['group_name']] : $row['group_name']; $template->assign_block_vars('groups', array( 'U_LIST' => "{$this->u_action}&action=list&g=$group_id", 'U_EDIT' => "{$this->u_action}&action=edit&g=$group_id", 'U_DELETE' => ($auth->acl_get('a_groupdel')) ? "{$this->u_action}&action=delete&g=$group_id" : '', 'S_GROUP_SPECIAL' => ($row['group_type'] == GROUP_SPECIAL) ? true : false, 'GROUP_NAME' => $group_name, 'TOTAL_MEMBERS' => $row['total_members'], )); } } } public function manage_position() { global $config, $db, $template, $user, $request, $phpbb_container; $this->tpl_name = 'acp_groups_position'; $this->page_title = 'ACP_GROUPS_POSITION'; $field = $request->variable('field', ''); $action = $request->variable('action', ''); $group_id = $request->variable('g', 0); $teampage_id = $request->variable('t', 0); $category_id = $request->variable('c', 0); if ($field && !in_array($field, array('legend', 'teampage'))) { // Invalid mode trigger_error($user->lang['NO_MODE'] . adm_back_link($this->u_action), E_USER_WARNING); } else if ($field && in_array($field, array('legend', 'teampage'))) { $group_position = $phpbb_container->get('groupposition.' . $field); } if ($field == 'teampage') { try { switch ($action) { case 'add': $group_position->add_group_teampage($group_id, $category_id); break; case 'add_category': $group_position->add_category_teampage($request->variable('category_name', '', true)); break; case 'delete': $group_position->delete_teampage($teampage_id); break; case 'move_up': $group_position->move_up_teampage($teampage_id); break; case 'move_down': $group_position->move_down_teampage($teampage_id); break; } } catch (\phpbb\groupposition\exception $exception) { trigger_error($user->lang($exception->getMessage()) . adm_back_link($this->u_action), E_USER_WARNING); } } else if ($field == 'legend') { try { switch ($action) { case 'add': $group_position->add_group($group_id); break; case 'delete': $group_position->delete_group($group_id); break; case 'move_up': $group_position->move_up($group_id); break; case 'move_down': $group_position->move_down($group_id); break; } } catch (\phpbb\groupposition\exception $exception) { trigger_error($user->lang($exception->getMessage()) . adm_back_link($this->u_action), E_USER_WARNING); } } else { switch ($action) { case 'set_config_teampage': $config->set('teampage_forums', $request->variable('teampage_forums', 0)); $config->set('teampage_memberships', $request->variable('teampage_memberships', 0)); trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action)); break; case 'set_config_legend': $config->set('legend_sort_groupname', $request->variable('legend_sort_groupname', 0)); trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action)); break; } } if (($action == 'move_up' || $action == 'move_down') && $request->is_ajax()) { $json_response = new \phpbb\json_response; $json_response->send(array('success' => true)); } $sql = 'SELECT group_id, group_name, group_colour, group_type, group_legend FROM ' . GROUPS_TABLE . ' ORDER BY group_legend ASC, group_type DESC, group_name ASC'; $result = $db->sql_query($sql); $s_group_select_legend = ''; while ($row = $db->sql_fetchrow($result)) { $group_name = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']; if ($row['group_legend']) { $template->assign_block_vars('legend', array( 'GROUP_NAME' => $group_name, 'GROUP_COLOUR' => ($row['group_colour']) ? '#' . $row['group_colour'] : '', 'GROUP_TYPE' => $user->lang[\phpbb\groupposition\legend::group_type_language($row['group_type'])], 'U_MOVE_DOWN' => "{$this->u_action}&field=legend&action=move_down&g=" . $row['group_id'], 'U_MOVE_UP' => "{$this->u_action}&field=legend&action=move_up&g=" . $row['group_id'], 'U_DELETE' => "{$this->u_action}&field=legend&action=delete&g=" . $row['group_id'], )); } else { $template->assign_block_vars('add_legend', array( 'GROUP_ID' => (int) $row['group_id'], 'GROUP_NAME' => $group_name, 'GROUP_SPECIAL' => ($row['group_type'] == GROUP_SPECIAL), )); } } $db->sql_freeresult($result); $category_url_param = (($category_id) ? '&c=' . $category_id : ''); $sql = 'SELECT t.*, g.group_name, g.group_colour, g.group_type FROM ' . TEAMPAGE_TABLE . ' t LEFT JOIN ' . GROUPS_TABLE . ' g ON (t.group_id = g.group_id) WHERE t.teampage_parent = ' . $category_id . ' OR t.teampage_id = ' . $category_id . ' ORDER BY t.teampage_position ASC'; $result = $db->sql_query($sql); $category_data = array(); while ($row = $db->sql_fetchrow($result)) { if ($row['teampage_id'] == $category_id) { $template->assign_vars(array( 'CURRENT_CATEGORY_NAME' => $row['teampage_name'], )); continue; } if ($row['group_id']) { $group_name = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']; $group_type = $user->lang[\phpbb\groupposition\teampage::group_type_language($row['group_type'])]; } else { $group_name = $row['teampage_name']; $group_type = ''; } $template->assign_block_vars('teampage', array( 'GROUP_NAME' => $group_name, 'GROUP_COLOUR' => ($row['group_colour']) ? '#' . $row['group_colour'] : '', 'GROUP_TYPE' => $group_type, 'U_CATEGORY' => (!$row['group_id']) ? "{$this->u_action}&c=" . $row['teampage_id'] : '', 'U_MOVE_DOWN' => "{$this->u_action}&field=teampage&action=move_down{$category_url_param}&t=" . $row['teampage_id'], 'U_MOVE_UP' => "{$this->u_action}&field=teampage&action=move_up{$category_url_param}&t=" . $row['teampage_id'], 'U_DELETE' => "{$this->u_action}&field=teampage&action=delete{$category_url_param}&t=" . $row['teampage_id'], )); } $db->sql_freeresult($result); $sql = 'SELECT g.group_id, g.group_name, g.group_colour, g.group_type FROM ' . GROUPS_TABLE . ' g LEFT JOIN ' . TEAMPAGE_TABLE . ' t ON (t.group_id = g.group_id) WHERE t.teampage_id IS NULL ORDER BY g.group_type DESC, g.group_name ASC'; $result = $db->sql_query($sql); $s_group_select_teampage = ''; while ($row = $db->sql_fetchrow($result)) { $group_name = ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']; $template->assign_block_vars('add_teampage', array( 'GROUP_ID' => (int) $row['group_id'], 'GROUP_NAME' => $group_name, 'GROUP_SPECIAL' => ($row['group_type'] == GROUP_SPECIAL), )); } $db->sql_freeresult($result); $template->assign_vars(array( 'U_ACTION' => $this->u_action, 'U_ACTION_LEGEND' => $this->u_action . '&field=legend', 'U_ACTION_TEAMPAGE' => $this->u_action . '&field=teampage' . $category_url_param, 'U_ACTION_TEAMPAGE_CAT' => $this->u_action . '&field=teampage_cat', 'S_TEAMPAGE_CATEGORY' => $category_id, 'DISPLAY_FORUMS' => ($config['teampage_forums']) ? true : false, 'DISPLAY_MEMBERSHIPS' => $config['teampage_memberships'], 'LEGEND_SORT_GROUPNAME' => ($config['legend_sort_groupname']) ? true : false, )); } } acp_jabber.php000077700000007667151514745240007364 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @todo Check/enter/update transport info */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_jabber { var $u_action; function main($id, $mode) { global $db, $user, $auth, $template; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; $user->add_lang('acp/board'); include_once($phpbb_root_path . 'includes/functions_jabber.' . $phpEx); $action = request_var('action', ''); $submit = (isset($_POST['submit'])) ? true : false; if ($mode != 'settings') { return; } $this->tpl_name = 'acp_jabber'; $this->page_title = 'ACP_JABBER_SETTINGS'; $jab_enable = request_var('jab_enable', (bool) $config['jab_enable']); $jab_host = request_var('jab_host', (string) $config['jab_host']); $jab_port = request_var('jab_port', (int) $config['jab_port']); $jab_username = request_var('jab_username', (string) $config['jab_username']); $jab_password = request_var('jab_password', (string) $config['jab_password']); $jab_package_size = request_var('jab_package_size', (int) $config['jab_package_size']); $jab_use_ssl = request_var('jab_use_ssl', (bool) $config['jab_use_ssl']); $form_name = 'acp_jabber'; add_form_key($form_name); if ($submit) { if (!check_form_key($form_name)) { trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING); } $error = array(); $message = $user->lang['JAB_SETTINGS_CHANGED']; $log = 'JAB_SETTINGS_CHANGED'; // Is this feature enabled? Then try to establish a connection if ($jab_enable) { $jabber = new jabber($jab_host, $jab_port, $jab_username, $jab_password, $jab_use_ssl); if (!$jabber->connect()) { trigger_error($user->lang['ERR_JAB_CONNECT'] . '<br /><br />' . $jabber->get_log() . adm_back_link($this->u_action), E_USER_WARNING); } // We'll try to authorise using this account if (!$jabber->login()) { trigger_error($user->lang['ERR_JAB_AUTH'] . '<br /><br />' . $jabber->get_log() . adm_back_link($this->u_action), E_USER_WARNING); } $jabber->disconnect(); } else { // This feature is disabled. // We update the user table to be sure all users that have IM as notify type are set to both as notify type // We set this to both because users still have their jabber address entered and may want to receive jabber notifications again once it is re-enabled. $sql_ary = array( 'user_notify_type' => NOTIFY_BOTH, ); $sql = 'UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE user_notify_type = ' . NOTIFY_IM; $db->sql_query($sql); } set_config('jab_enable', $jab_enable); set_config('jab_host', $jab_host); set_config('jab_port', $jab_port); set_config('jab_username', $jab_username); if ($jab_password !== '********') { set_config('jab_password', $jab_password); } set_config('jab_package_size', $jab_package_size); set_config('jab_use_ssl', $jab_use_ssl); add_log('admin', 'LOG_' . $log); trigger_error($message . adm_back_link($this->u_action)); } $template->assign_vars(array( 'U_ACTION' => $this->u_action, 'JAB_ENABLE' => $jab_enable, 'L_JAB_SERVER_EXPLAIN' => sprintf($user->lang['JAB_SERVER_EXPLAIN'], '<a href="http://www.jabber.org/">', '</a>'), 'JAB_HOST' => $jab_host, 'JAB_PORT' => ($jab_port) ? $jab_port : '', 'JAB_USERNAME' => $jab_username, 'JAB_PASSWORD' => $jab_password !== '' ? '********' : '', 'JAB_PACKAGE_SIZE' => $jab_package_size, 'JAB_USE_SSL' => $jab_use_ssl, 'S_CAN_USE_SSL' => jabber::can_use_ssl(), 'S_GTALK_NOTE' => (!@function_exists('dns_get_record')) ? true : false, )); } } acp_modules.php000077700000100252151514745240007567 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } /** * - Able to check for new module versions (modes changed/adjusted/added/removed) * Icons for: * - module enabled and displayed (common) * - module enabled and not displayed * - module deactivated * - category (enabled) * - category disabled */ class acp_modules { var $module_class = ''; var $parent_id; var $u_action; function main($id, $mode) { global $db, $user, $auth, $template, $module, $request; global $config, $phpbb_admin_path, $phpbb_root_path, $phpEx; // Set a global define for modules we might include (the author is able to prevent execution of code by checking this constant) define('MODULE_INCLUDE', true); $user->add_lang('acp/modules'); $this->tpl_name = 'acp_modules'; // module class $this->module_class = $mode; if ($this->module_class == 'ucp') { $user->add_lang('ucp'); } else if ($this->module_class == 'mcp') { $user->add_lang('mcp'); } if ($module->p_class != $this->module_class) { $module->add_mod_info($this->module_class); } $this->page_title = strtoupper($this->module_class); $this->parent_id = request_var('parent_id', 0); $module_id = request_var('m', 0); $action = request_var('action', ''); $errors = array(); switch ($action) { case 'delete': if (!$module_id) { trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); } if (confirm_box(true)) { // Make sure we are not directly within a module if ($module_id == $this->parent_id) { $sql = 'SELECT parent_id FROM ' . MODULES_TABLE . ' WHERE module_id = ' . $module_id; $result = $db->sql_query($sql); $this->parent_id = (int) $db->sql_fetchfield('parent_id'); $db->sql_freeresult($result); } $errors = $this->delete_module($module_id); if (!sizeof($errors)) { $this->remove_cache_file(); trigger_error($user->lang['MODULE_DELETED'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id)); } } else { confirm_box(false, 'DELETE_MODULE', build_hidden_fields(array( 'i' => $id, 'mode' => $mode, 'parent_id' => $this->parent_id, 'module_id' => $module_id, 'action' => $action, ))); } break; case 'enable': case 'disable': if (!$module_id) { trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); } $sql = 'SELECT * FROM ' . MODULES_TABLE . " WHERE module_class = '" . $db->sql_escape($this->module_class) . "' AND module_id = $module_id"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$row) { trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); } $sql = 'UPDATE ' . MODULES_TABLE . ' SET module_enabled = ' . (($action == 'enable') ? 1 : 0) . " WHERE module_class = '" . $db->sql_escape($this->module_class) . "' AND module_id = $module_id"; $db->sql_query($sql); add_log('admin', 'LOG_MODULE_' . strtoupper($action), $this->lang_name($row['module_langname'])); $this->remove_cache_file(); break; case 'move_up': case 'move_down': if (!$module_id) { trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); } $sql = 'SELECT * FROM ' . MODULES_TABLE . " WHERE module_class = '" . $db->sql_escape($this->module_class) . "' AND module_id = $module_id"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$row) { trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); } $move_module_name = $this->move_module_by($row, $action, 1); if ($move_module_name !== false) { add_log('admin', 'LOG_MODULE_' . strtoupper($action), $this->lang_name($row['module_langname']), $move_module_name); $this->remove_cache_file(); } if ($request->is_ajax()) { $json_response = new \phpbb\json_response; $json_response->send(array( 'success' => ($move_module_name !== false), )); } break; case 'quickadd': $quick_install = request_var('quick_install', ''); if (confirm_box(true)) { if (!$quick_install || strpos($quick_install, '::') === false) { break; } list($module_basename, $module_mode) = explode('::', $quick_install); // Check if module name and mode exist... $fileinfo = $this->get_module_infos($module_basename); $fileinfo = $fileinfo[$module_basename]; if (isset($fileinfo['modes'][$module_mode])) { $module_data = array( 'module_basename' => $module_basename, 'module_enabled' => 0, 'module_display' => (isset($fileinfo['modes'][$module_mode]['display'])) ? $fileinfo['modes'][$module_mode]['display'] : 1, 'parent_id' => $this->parent_id, 'module_class' => $this->module_class, 'module_langname' => $fileinfo['modes'][$module_mode]['title'], 'module_mode' => $module_mode, 'module_auth' => $fileinfo['modes'][$module_mode]['auth'], ); $errors = $this->update_module_data($module_data); if (!sizeof($errors)) { $this->remove_cache_file(); trigger_error($user->lang['MODULE_ADDED'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id)); } } } else { confirm_box(false, 'ADD_MODULE', build_hidden_fields(array( 'i' => $id, 'mode' => $mode, 'parent_id' => $this->parent_id, 'action' => 'quickadd', 'quick_install' => $quick_install, ))); } break; case 'edit': if (!$module_id) { trigger_error($user->lang['NO_MODULE_ID'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); } $module_row = $this->get_module_row($module_id); // no break case 'add': if ($action == 'add') { $module_row = array( 'module_basename' => '', 'module_enabled' => 0, 'module_display' => 1, 'parent_id' => 0, 'module_langname' => utf8_normalize_nfc(request_var('module_langname', '', true)), 'module_mode' => '', 'module_auth' => '', ); } $module_data = array(); $module_data['module_basename'] = request_var('module_basename', (string) $module_row['module_basename']); $module_data['module_enabled'] = request_var('module_enabled', (int) $module_row['module_enabled']); $module_data['module_display'] = request_var('module_display', (int) $module_row['module_display']); $module_data['parent_id'] = request_var('module_parent_id', (int) $module_row['parent_id']); $module_data['module_class'] = $this->module_class; $module_data['module_langname'] = utf8_normalize_nfc(request_var('module_langname', (string) $module_row['module_langname'], true)); $module_data['module_mode'] = request_var('module_mode', (string) $module_row['module_mode']); $submit = (isset($_POST['submit'])) ? true : false; if ($submit) { if (!$module_data['module_langname']) { trigger_error($user->lang['NO_MODULE_LANGNAME'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); } $module_type = request_var('module_type', 'category'); if ($module_type == 'category') { $module_data['module_basename'] = $module_data['module_mode'] = $module_data['module_auth'] = ''; $module_data['module_display'] = 1; } if ($action == 'edit') { $module_data['module_id'] = $module_id; } // Adjust auth row if ($module_data['module_basename'] && $module_data['module_mode']) { $fileinfo = $this->get_module_infos($module_data['module_basename']); $module_data['module_auth'] = $fileinfo[$module_data['module_basename']]['modes'][$module_data['module_mode']]['auth']; } $errors = $this->update_module_data($module_data); if (!sizeof($errors)) { $this->remove_cache_file(); trigger_error((($action == 'add') ? $user->lang['MODULE_ADDED'] : $user->lang['MODULE_EDITED']) . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id)); } } // Category/not category? $is_cat = (!$module_data['module_basename']) ? true : false; // Get module information $module_infos = $this->get_module_infos(); // Build name options $s_name_options = $s_mode_options = ''; foreach ($module_infos as $option => $values) { if (!$module_data['module_basename']) { $module_data['module_basename'] = $option; } // Name options $s_name_options .= '<option value="' . $option . '"' . (($option == $module_data['module_basename']) ? ' selected="selected"' : '') . '>' . $this->lang_name($values['title']) . ' [' . $option . ']</option>'; $template->assign_block_vars('m_names', array('NAME' => $option, 'A_NAME' => addslashes($option))); // Build module modes foreach ($values['modes'] as $m_mode => $m_values) { if ($option == $module_data['module_basename']) { $s_mode_options .= '<option value="' . $m_mode . '"' . (($m_mode == $module_data['module_mode']) ? ' selected="selected"' : '') . '>' . $this->lang_name($m_values['title']) . '</option>'; } $template->assign_block_vars('m_names.modes', array( 'OPTION' => $m_mode, 'VALUE' => $this->lang_name($m_values['title']), 'A_OPTION' => addslashes($m_mode), 'A_VALUE' => addslashes($this->lang_name($m_values['title']))) ); } } $s_cat_option = '<option value="0"' . (($module_data['parent_id'] == 0) ? ' selected="selected"' : '') . '>' . $user->lang['NO_PARENT'] . '</option>'; $template->assign_vars(array_merge(array( 'S_EDIT_MODULE' => true, 'S_IS_CAT' => $is_cat, 'S_CAT_OPTIONS' => $s_cat_option . $this->make_module_select($module_data['parent_id'], ($action == 'edit') ? $module_row['module_id'] : false, false, false, false, true), 'S_MODULE_NAMES' => $s_name_options, 'S_MODULE_MODES' => $s_mode_options, 'U_BACK' => $this->u_action . '&parent_id=' . $this->parent_id, 'U_EDIT_ACTION' => $this->u_action . '&parent_id=' . $this->parent_id, 'L_TITLE' => $user->lang[strtoupper($action) . '_MODULE'], 'MODULENAME' => $this->lang_name($module_data['module_langname']), 'ACTION' => $action, 'MODULE_ID' => $module_id, ), array_change_key_case($module_data, CASE_UPPER)) ); if (sizeof($errors)) { $template->assign_vars(array( 'S_ERROR' => true, 'ERROR_MSG' => implode('<br />', $errors)) ); } return; break; } // Default management page if (sizeof($errors)) { if ($request->is_ajax()) { $json_response = new \phpbb\json_response; $json_response->send(array( 'MESSAGE_TITLE' => $user->lang('ERROR'), 'MESSAGE_TEXT' => implode('<br />', $errors), 'SUCCESS' => false, )); } $template->assign_vars(array( 'S_ERROR' => true, 'ERROR_MSG' => implode('<br />', $errors)) ); } if (!$this->parent_id) { $navigation = strtoupper($this->module_class); } else { $navigation = '<a href="' . $this->u_action . '">' . strtoupper($this->module_class) . '</a>'; $modules_nav = $this->get_module_branch($this->parent_id, 'parents', 'descending'); foreach ($modules_nav as $row) { $langname = $this->lang_name($row['module_langname']); if ($row['module_id'] == $this->parent_id) { $navigation .= ' -> ' . $langname; } else { $navigation .= ' -> <a href="' . $this->u_action . '&parent_id=' . $row['module_id'] . '">' . $langname . '</a>'; } } } // Jumpbox $module_box = $this->make_module_select($this->parent_id, false, false, false, false); $sql = 'SELECT * FROM ' . MODULES_TABLE . " WHERE parent_id = {$this->parent_id} AND module_class = '" . $db->sql_escape($this->module_class) . "' ORDER BY left_id"; $result = $db->sql_query($sql); if ($row = $db->sql_fetchrow($result)) { do { $langname = $this->lang_name($row['module_langname']); if (!$row['module_enabled']) { $module_image = '<img src="images/icon_folder_lock.gif" alt="' . $user->lang['DEACTIVATED_MODULE'] .'" />'; } else { $module_image = (!$row['module_basename'] || $row['left_id'] + 1 != $row['right_id']) ? '<img src="images/icon_subfolder.gif" alt="' . $user->lang['CATEGORY'] . '" />' : '<img src="images/icon_folder.gif" alt="' . $user->lang['MODULE'] . '" />'; } $url = $this->u_action . '&parent_id=' . $this->parent_id . '&m=' . $row['module_id']; $template->assign_block_vars('modules', array( 'MODULE_IMAGE' => $module_image, 'MODULE_TITLE' => $langname, 'MODULE_ENABLED' => ($row['module_enabled']) ? true : false, 'MODULE_DISPLAYED' => ($row['module_display']) ? true : false, 'S_ACP_CAT_SYSTEM' => ($this->module_class == 'acp' && $row['module_langname'] == 'ACP_CAT_SYSTEM') ? true : false, 'S_ACP_MODULE_MANAGEMENT' => ($this->module_class == 'acp' && ($row['module_basename'] == 'modules' || $row['module_langname'] == 'ACP_MODULE_MANAGEMENT')) ? true : false, 'U_MODULE' => $this->u_action . '&parent_id=' . $row['module_id'], 'U_MOVE_UP' => $url . '&action=move_up', 'U_MOVE_DOWN' => $url . '&action=move_down', 'U_EDIT' => $url . '&action=edit', 'U_DELETE' => $url . '&action=delete', 'U_ENABLE' => $url . '&action=enable', 'U_DISABLE' => $url . '&action=disable') ); } while ($row = $db->sql_fetchrow($result)); } else if ($this->parent_id) { $row = $this->get_module_row($this->parent_id); $url = $this->u_action . '&parent_id=' . $this->parent_id . '&m=' . $row['module_id']; $template->assign_vars(array( 'S_NO_MODULES' => true, 'MODULE_TITLE' => $langname, 'MODULE_ENABLED' => ($row['module_enabled']) ? true : false, 'MODULE_DISPLAYED' => ($row['module_display']) ? true : false, 'U_EDIT' => $url . '&action=edit', 'U_DELETE' => $url . '&action=delete', 'U_ENABLE' => $url . '&action=enable', 'U_DISABLE' => $url . '&action=disable') ); } $db->sql_freeresult($result); // Quick adding module $module_infos = $this->get_module_infos(); // Build quick options $s_install_options = ''; foreach ($module_infos as $option => $values) { // Name options $s_install_options .= '<optgroup label="' . $this->lang_name($values['title']) . ' [' . $option . ']">'; // Build module modes foreach ($values['modes'] as $m_mode => $m_values) { $s_install_options .= '<option value="' . $option . '::' . $m_mode . '"> ' . $this->lang_name($m_values['title']) . '</option>'; } $s_install_options .= '</optgroup>'; } $template->assign_vars(array( 'U_SEL_ACTION' => $this->u_action, 'U_ACTION' => $this->u_action . '&parent_id=' . $this->parent_id, 'NAVIGATION' => $navigation, 'MODULE_BOX' => $module_box, 'PARENT_ID' => $this->parent_id, 'S_INSTALL_OPTIONS' => $s_install_options, ) ); } /** * Get row for specified module */ function get_module_row($module_id) { global $db, $user; $sql = 'SELECT * FROM ' . MODULES_TABLE . " WHERE module_class = '" . $db->sql_escape($this->module_class) . "' AND module_id = $module_id"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$row) { trigger_error($user->lang['NO_MODULE'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); } return $row; } /** * Get available module information from module files * * @param string $module * @param bool|string $module_class * @param bool $use_all_available Use all available instead of just all * enabled extensions * @return array */ function get_module_infos($module = '', $module_class = false, $use_all_available = false) { global $phpbb_extension_manager, $phpbb_root_path, $phpEx; $module_class = ($module_class === false) ? $this->module_class : $module_class; $directory = $phpbb_root_path . 'includes/' . $module_class . '/info/'; $fileinfo = array(); $finder = $phpbb_extension_manager->get_finder($use_all_available); $modules = $finder ->extension_suffix('_module') ->extension_directory("/$module_class") ->core_path("includes/$module_class/info/") ->core_prefix($module_class . '_') ->get_classes(true); foreach ($modules as $cur_module) { // Skip entries we do not need if we know the module we are // looking for if ($module && strpos(str_replace('\\', '_', $cur_module), $module) === false && $module !== $cur_module) { continue; } $info_class = preg_replace('/_module$/', '_info', $cur_module); // If the class does not exist it might be following the old // format. phpbb_acp_info_acp_foo needs to be turned into // acp_foo_info and the respective file has to be included // manually because it does not support auto loading $old_info_class_file = str_replace("phpbb_{$module_class}_info_", '', $cur_module); $old_info_class = $old_info_class_file . '_info'; if (class_exists($old_info_class)) { $info_class = $old_info_class; } else if (!class_exists($info_class)) { $info_class = $old_info_class; // need to check class exists again because previous checks triggered autoloading if (!class_exists($info_class) && file_exists($directory . $old_info_class_file . '.' . $phpEx)) { include($directory . $old_info_class_file . '.' . $phpEx); } } if (class_exists($info_class)) { $info = new $info_class(); $module_info = $info->module(); $main_class = (isset($module_info['filename'])) ? $module_info['filename'] : $cur_module; $fileinfo[$main_class] = $module_info; } } ksort($fileinfo); return $fileinfo; } /** * Simple version of jumpbox, just lists modules */ function make_module_select($select_id = false, $ignore_id = false, $ignore_acl = false, $ignore_nonpost = false, $ignore_emptycat = true, $ignore_noncat = false) { global $db, $user, $auth, $config; $sql = 'SELECT module_id, module_enabled, module_basename, parent_id, module_langname, left_id, right_id, module_auth FROM ' . MODULES_TABLE . " WHERE module_class = '" . $db->sql_escape($this->module_class) . "' ORDER BY left_id ASC"; $result = $db->sql_query($sql); $right = $iteration = 0; $padding_store = array('0' => ''); $module_list = $padding = ''; while ($row = $db->sql_fetchrow($result)) { if ($row['left_id'] < $right) { $padding .= ' '; $padding_store[$row['parent_id']] = $padding; } else if ($row['left_id'] > $right + 1) { $padding = (isset($padding_store[$row['parent_id']])) ? $padding_store[$row['parent_id']] : ''; } $right = $row['right_id']; if (!$ignore_acl && $row['module_auth']) { // We use zero as the forum id to check - global setting. if (!p_master::module_auth($row['module_auth'], 0)) { continue; } } // ignore this module? if ((is_array($ignore_id) && in_array($row['module_id'], $ignore_id)) || $row['module_id'] == $ignore_id) { continue; } // empty category if (!$row['module_basename'] && ($row['left_id'] + 1 == $row['right_id']) && $ignore_emptycat) { continue; } // ignore non-category? if ($row['module_basename'] && $ignore_noncat) { continue; } $selected = (is_array($select_id)) ? ((in_array($row['module_id'], $select_id)) ? ' selected="selected"' : '') : (($row['module_id'] == $select_id) ? ' selected="selected"' : ''); $langname = $this->lang_name($row['module_langname']); $module_list .= '<option value="' . $row['module_id'] . '"' . $selected . ((!$row['module_enabled']) ? ' class="disabled"' : '') . '>' . $padding . $langname . '</option>'; $iteration++; } $db->sql_freeresult($result); unset($padding_store); return $module_list; } /** * Get module branch */ function get_module_branch($module_id, $type = 'all', $order = 'descending', $include_module = true) { global $db; switch ($type) { case 'parents': $condition = 'm1.left_id BETWEEN m2.left_id AND m2.right_id'; break; case 'children': $condition = 'm2.left_id BETWEEN m1.left_id AND m1.right_id'; break; default: $condition = 'm2.left_id BETWEEN m1.left_id AND m1.right_id OR m1.left_id BETWEEN m2.left_id AND m2.right_id'; break; } $rows = array(); $sql = 'SELECT m2.* FROM ' . MODULES_TABLE . ' m1 LEFT JOIN ' . MODULES_TABLE . " m2 ON ($condition) WHERE m1.module_class = '" . $db->sql_escape($this->module_class) . "' AND m2.module_class = '" . $db->sql_escape($this->module_class) . "' AND m1.module_id = $module_id ORDER BY m2.left_id " . (($order == 'descending') ? 'ASC' : 'DESC'); $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { if (!$include_module && $row['module_id'] == $module_id) { continue; } $rows[] = $row; } $db->sql_freeresult($result); return $rows; } /** * Remove modules cache file */ function remove_cache_file() { global $phpbb_container; // Sanitise for future path use, it's escaped as appropriate for queries $p_class = str_replace(array('.', '/', '\\'), '', basename($this->module_class)); $phpbb_container->get('cache.driver')->destroy('_modules_' . $p_class); // Additionally remove sql cache $phpbb_container->get('cache.driver')->destroy('sql', MODULES_TABLE); } /** * Return correct language name */ function lang_name($module_langname) { global $user; return (!empty($user->lang[$module_langname])) ? $user->lang[$module_langname] : $module_langname; } /** * Update/Add module * * @param array &$module_data The module data * @param bool $run_inline if set to true errors will be returned and no logs being written */ function update_module_data(&$module_data, $run_inline = false) { global $db, $user; if (!isset($module_data['module_id'])) { // no module_id means we're creating a new category/module if ($module_data['parent_id']) { $sql = 'SELECT left_id, right_id FROM ' . MODULES_TABLE . " WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "' AND module_id = " . (int) $module_data['parent_id']; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$row) { if ($run_inline) { return 'PARENT_NO_EXIST'; } trigger_error($user->lang['PARENT_NO_EXIST'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); } // Workaround $row['left_id'] = (int) $row['left_id']; $row['right_id'] = (int) $row['right_id']; $sql = 'UPDATE ' . MODULES_TABLE . " SET left_id = left_id + 2, right_id = right_id + 2 WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "' AND left_id > {$row['right_id']}"; $db->sql_query($sql); $sql = 'UPDATE ' . MODULES_TABLE . " SET right_id = right_id + 2 WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "' AND {$row['left_id']} BETWEEN left_id AND right_id"; $db->sql_query($sql); $module_data['left_id'] = (int) $row['right_id']; $module_data['right_id'] = (int) $row['right_id'] + 1; } else { $sql = 'SELECT MAX(right_id) AS right_id FROM ' . MODULES_TABLE . " WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "'"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); $module_data['left_id'] = (int) $row['right_id'] + 1; $module_data['right_id'] = (int) $row['right_id'] + 2; } $sql = 'INSERT INTO ' . MODULES_TABLE . ' ' . $db->sql_build_array('INSERT', $module_data); $db->sql_query($sql); $module_data['module_id'] = $db->sql_nextid(); if (!$run_inline) { add_log('admin', 'LOG_MODULE_ADD', $this->lang_name($module_data['module_langname'])); } } else { $row = $this->get_module_row($module_data['module_id']); if ($module_data['module_basename'] && !$row['module_basename']) { // we're turning a category into a module $branch = $this->get_module_branch($module_data['module_id'], 'children', 'descending', false); if (sizeof($branch)) { return array($user->lang['NO_CATEGORY_TO_MODULE']); } } if ($row['parent_id'] != $module_data['parent_id']) { $this->move_module($module_data['module_id'], $module_data['parent_id']); } $update_ary = $module_data; unset($update_ary['module_id']); $sql = 'UPDATE ' . MODULES_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $update_ary) . " WHERE module_class = '" . $db->sql_escape($module_data['module_class']) . "' AND module_id = " . (int) $module_data['module_id']; $db->sql_query($sql); if (!$run_inline) { add_log('admin', 'LOG_MODULE_EDIT', $this->lang_name($module_data['module_langname'])); } } return array(); } /** * Move module around the tree */ function move_module($from_module_id, $to_parent_id) { global $db; $moved_modules = $this->get_module_branch($from_module_id, 'children', 'descending'); $from_data = $moved_modules[0]; $diff = sizeof($moved_modules) * 2; $moved_ids = array(); for ($i = 0; $i < sizeof($moved_modules); ++$i) { $moved_ids[] = $moved_modules[$i]['module_id']; } // Resync parents $sql = 'UPDATE ' . MODULES_TABLE . " SET right_id = right_id - $diff WHERE module_class = '" . $db->sql_escape($this->module_class) . "' AND left_id < " . (int) $from_data['right_id'] . ' AND right_id > ' . (int) $from_data['right_id']; $db->sql_query($sql); // Resync righthand side of tree $sql = 'UPDATE ' . MODULES_TABLE . " SET left_id = left_id - $diff, right_id = right_id - $diff WHERE module_class = '" . $db->sql_escape($this->module_class) . "' AND left_id > " . (int) $from_data['right_id']; $db->sql_query($sql); if ($to_parent_id > 0) { $to_data = $this->get_module_row($to_parent_id); // Resync new parents $sql = 'UPDATE ' . MODULES_TABLE . " SET right_id = right_id + $diff WHERE module_class = '" . $db->sql_escape($this->module_class) . "' AND " . (int) $to_data['right_id'] . ' BETWEEN left_id AND right_id AND ' . $db->sql_in_set('module_id', $moved_ids, true); $db->sql_query($sql); // Resync the righthand side of the tree $sql = 'UPDATE ' . MODULES_TABLE . " SET left_id = left_id + $diff, right_id = right_id + $diff WHERE module_class = '" . $db->sql_escape($this->module_class) . "' AND left_id > " . (int) $to_data['right_id'] . ' AND ' . $db->sql_in_set('module_id', $moved_ids, true); $db->sql_query($sql); // Resync moved branch $to_data['right_id'] += $diff; if ($to_data['right_id'] > $from_data['right_id']) { $diff = '+ ' . ($to_data['right_id'] - $from_data['right_id'] - 1); } else { $diff = '- ' . abs($to_data['right_id'] - $from_data['right_id'] - 1); } } else { $sql = 'SELECT MAX(right_id) AS right_id FROM ' . MODULES_TABLE . " WHERE module_class = '" . $db->sql_escape($this->module_class) . "' AND " . $db->sql_in_set('module_id', $moved_ids, true); $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); $diff = '+ ' . (int) ($row['right_id'] - $from_data['left_id'] + 1); } $sql = 'UPDATE ' . MODULES_TABLE . " SET left_id = left_id $diff, right_id = right_id $diff WHERE module_class = '" . $db->sql_escape($this->module_class) . "' AND " . $db->sql_in_set('module_id', $moved_ids); $db->sql_query($sql); } /** * Remove module from tree */ function delete_module($module_id) { global $db, $user; $row = $this->get_module_row($module_id); $branch = $this->get_module_branch($module_id, 'children', 'descending', false); if (sizeof($branch)) { return array($user->lang['CANNOT_REMOVE_MODULE']); } // If not move $diff = 2; $sql = 'DELETE FROM ' . MODULES_TABLE . " WHERE module_class = '" . $db->sql_escape($this->module_class) . "' AND module_id = $module_id"; $db->sql_query($sql); $row['right_id'] = (int) $row['right_id']; $row['left_id'] = (int) $row['left_id']; // Resync tree $sql = 'UPDATE ' . MODULES_TABLE . " SET right_id = right_id - $diff WHERE module_class = '" . $db->sql_escape($this->module_class) . "' AND left_id < {$row['right_id']} AND right_id > {$row['right_id']}"; $db->sql_query($sql); $sql = 'UPDATE ' . MODULES_TABLE . " SET left_id = left_id - $diff, right_id = right_id - $diff WHERE module_class = '" . $db->sql_escape($this->module_class) . "' AND left_id > {$row['right_id']}"; $db->sql_query($sql); add_log('admin', 'LOG_MODULE_REMOVED', $this->lang_name($row['module_langname'])); return array(); } /** * Move module position by $steps up/down */ function move_module_by($module_row, $action = 'move_up', $steps = 1) { global $db; /** * Fetch all the siblings between the module's current spot * and where we want to move it to. If there are less than $steps * siblings between the current spot and the target then the * module will move as far as possible */ $sql = 'SELECT module_id, left_id, right_id, module_langname FROM ' . MODULES_TABLE . " WHERE module_class = '" . $db->sql_escape($this->module_class) . "' AND parent_id = " . (int) $module_row['parent_id'] . ' AND ' . (($action == 'move_up') ? 'right_id < ' . (int) $module_row['right_id'] . ' ORDER BY right_id DESC' : 'left_id > ' . (int) $module_row['left_id'] . ' ORDER BY left_id ASC'); $result = $db->sql_query_limit($sql, $steps); $target = array(); while ($row = $db->sql_fetchrow($result)) { $target = $row; } $db->sql_freeresult($result); if (!sizeof($target)) { // The module is already on top or bottom return false; } /** * $left_id and $right_id define the scope of the nodes that are affected by the move. * $diff_up and $diff_down are the values to substract or add to each node's left_id * and right_id in order to move them up or down. * $move_up_left and $move_up_right define the scope of the nodes that are moving * up. Other nodes in the scope of ($left_id, $right_id) are considered to move down. */ if ($action == 'move_up') { $left_id = (int) $target['left_id']; $right_id = (int) $module_row['right_id']; $diff_up = (int) ($module_row['left_id'] - $target['left_id']); $diff_down = (int) ($module_row['right_id'] + 1 - $module_row['left_id']); $move_up_left = (int) $module_row['left_id']; $move_up_right = (int) $module_row['right_id']; } else { $left_id = (int) $module_row['left_id']; $right_id = (int) $target['right_id']; $diff_up = (int) ($module_row['right_id'] + 1 - $module_row['left_id']); $diff_down = (int) ($target['right_id'] - $module_row['right_id']); $move_up_left = (int) ($module_row['right_id'] + 1); $move_up_right = (int) $target['right_id']; } // Now do the dirty job $sql = 'UPDATE ' . MODULES_TABLE . " SET left_id = left_id + CASE WHEN left_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up} ELSE {$diff_down} END, right_id = right_id + CASE WHEN right_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up} ELSE {$diff_down} END WHERE module_class = '" . $db->sql_escape($this->module_class) . "' AND left_id BETWEEN {$left_id} AND {$right_id} AND right_id BETWEEN {$left_id} AND {$right_id}"; $db->sql_query($sql); $this->remove_cache_file(); return $this->lang_name($target['module_langname']); } } acp_ranks.php000077700000017306151514745240007244 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_ranks { var $u_action; function main($id, $mode) { global $db, $user, $auth, $template, $cache, $request, $phpbb_dispatcher; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; $user->add_lang('acp/posting'); // Set up general vars $action = request_var('action', ''); $action = (isset($_POST['add'])) ? 'add' : $action; $action = (isset($_POST['save'])) ? 'save' : $action; $rank_id = request_var('id', 0); $this->tpl_name = 'acp_ranks'; $this->page_title = 'ACP_MANAGE_RANKS'; $form_name = 'acp_ranks'; add_form_key($form_name); switch ($action) { case 'save': if (!check_form_key($form_name)) { trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING); } $rank_title = utf8_normalize_nfc(request_var('title', '', true)); $special_rank = request_var('special_rank', 0); $min_posts = ($special_rank) ? 0 : max(0, request_var('min_posts', 0)); $rank_image = request_var('rank_image', ''); // The rank image has to be a jpg, gif or png if ($rank_image != '' && !preg_match('#(\.gif|\.png|\.jpg|\.jpeg)$#i', $rank_image)) { $rank_image = ''; } if (!$rank_title) { trigger_error($user->lang['NO_RANK_TITLE'] . adm_back_link($this->u_action), E_USER_WARNING); } $sql_ary = array( 'rank_title' => $rank_title, 'rank_special' => $special_rank, 'rank_min' => $min_posts, 'rank_image' => htmlspecialchars_decode($rank_image) ); /** * Modify the SQL array when saving a rank * * @event core.acp_ranks_save_modify_sql_ary * @var int rank_id The ID of the rank (if available) * @var array sql_ary Array with the rank's data * @since 3.1.0-RC3 */ $vars = array('rank_id', 'sql_ary'); extract($phpbb_dispatcher->trigger_event('core.acp_ranks_save_modify_sql_ary', compact($vars))); if ($rank_id) { $sql = 'UPDATE ' . RANKS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " WHERE rank_id = $rank_id"; $message = $user->lang['RANK_UPDATED']; add_log('admin', 'LOG_RANK_UPDATED', $rank_title); } else { $sql = 'INSERT INTO ' . RANKS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); $message = $user->lang['RANK_ADDED']; add_log('admin', 'LOG_RANK_ADDED', $rank_title); } $db->sql_query($sql); $cache->destroy('_ranks'); trigger_error($message . adm_back_link($this->u_action)); break; case 'delete': if (!$rank_id) { trigger_error($user->lang['MUST_SELECT_RANK'] . adm_back_link($this->u_action), E_USER_WARNING); } if (confirm_box(true)) { $sql = 'SELECT rank_title FROM ' . RANKS_TABLE . ' WHERE rank_id = ' . $rank_id; $result = $db->sql_query($sql); $rank_title = (string) $db->sql_fetchfield('rank_title'); $db->sql_freeresult($result); $sql = 'DELETE FROM ' . RANKS_TABLE . " WHERE rank_id = $rank_id"; $db->sql_query($sql); $sql = 'UPDATE ' . USERS_TABLE . " SET user_rank = 0 WHERE user_rank = $rank_id"; $db->sql_query($sql); $cache->destroy('_ranks'); add_log('admin', 'LOG_RANK_REMOVED', $rank_title); if ($request->is_ajax()) { $json_response = new \phpbb\json_response; $json_response->send(array( 'MESSAGE_TITLE' => $user->lang['INFORMATION'], 'MESSAGE_TEXT' => $user->lang['RANK_REMOVED'], 'REFRESH_DATA' => array( 'time' => 3 ) )); } } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 'i' => $id, 'mode' => $mode, 'rank_id' => $rank_id, 'action' => 'delete', ))); } break; case 'edit': case 'add': $data = $ranks = $existing_imgs = array(); $sql = 'SELECT * FROM ' . RANKS_TABLE . ' ORDER BY rank_min ASC, rank_special ASC'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $existing_imgs[] = $row['rank_image']; if ($action == 'edit' && $rank_id == $row['rank_id']) { $ranks = $row; } } $db->sql_freeresult($result); $imglist = filelist($phpbb_root_path . $config['ranks_path'], ''); $edit_img = $filename_list = ''; foreach ($imglist as $path => $img_ary) { sort($img_ary); foreach ($img_ary as $img) { $img = $path . $img; if ($ranks && $img == $ranks['rank_image']) { $selected = ' selected="selected"'; $edit_img = $img; } else { $selected = ''; } if (strlen($img) > 255) { continue; } $filename_list .= '<option value="' . htmlspecialchars($img) . '"' . $selected . '>' . $img . ((in_array($img, $existing_imgs)) ? ' ' . $user->lang['RANK_IMAGE_IN_USE'] : '') . '</option>'; } } $filename_list = '<option value=""' . (($edit_img == '') ? ' selected="selected"' : '') . '>----------</option>' . $filename_list; unset($existing_imgs, $imglist); $tpl_ary = array( 'S_EDIT' => true, 'U_BACK' => $this->u_action, 'RANKS_PATH' => $phpbb_root_path . $config['ranks_path'], 'U_ACTION' => $this->u_action . '&id=' . $rank_id, 'RANK_TITLE' => (isset($ranks['rank_title'])) ? $ranks['rank_title'] : '', 'S_FILENAME_LIST' => $filename_list, 'RANK_IMAGE' => ($edit_img) ? $phpbb_root_path . $config['ranks_path'] . '/' . $edit_img : htmlspecialchars($phpbb_admin_path) . 'images/spacer.gif', 'S_SPECIAL_RANK' => (isset($ranks['rank_special']) && $ranks['rank_special']) ? true : false, 'MIN_POSTS' => (isset($ranks['rank_min']) && !$ranks['rank_special']) ? $ranks['rank_min'] : 0, ); /** * Modify the template output array for editing/adding ranks * * @event core.acp_ranks_edit_modify_tpl_ary * @var array ranks Array with the rank's data * @var array tpl_ary Array with the rank's template data * @since 3.1.0-RC3 */ $vars = array('ranks', 'tpl_ary'); extract($phpbb_dispatcher->trigger_event('core.acp_ranks_edit_modify_tpl_ary', compact($vars))); $template->assign_vars($tpl_ary); return; break; } $template->assign_vars(array( 'U_ACTION' => $this->u_action) ); $sql = 'SELECT * FROM ' . RANKS_TABLE . ' ORDER BY rank_special DESC, rank_min ASC, rank_title ASC'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $rank_row = array( 'S_RANK_IMAGE' => ($row['rank_image']) ? true : false, 'S_SPECIAL_RANK' => ($row['rank_special']) ? true : false, 'RANK_IMAGE' => $phpbb_root_path . $config['ranks_path'] . '/' . $row['rank_image'], 'RANK_TITLE' => $row['rank_title'], 'MIN_POSTS' => $row['rank_min'], 'U_EDIT' => $this->u_action . '&action=edit&id=' . $row['rank_id'], 'U_DELETE' => $this->u_action . '&action=delete&id=' . $row['rank_id'], ); /** * Modify the template output array for each listed rank * * @event core.acp_ranks_list_modify_rank_row * @var array row Array with the rank's data * @var array rank_row Array with the rank's template data * @since 3.1.0-RC3 */ $vars = array('row', 'rank_row'); extract($phpbb_dispatcher->trigger_event('core.acp_ranks_list_modify_rank_row', compact($vars))); $template->assign_block_vars('ranks', $rank_row); } $db->sql_freeresult($result); } } acp_database.php000077700000152430151514745240007670 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_database { var $db_tools; var $u_action; function main($id, $mode) { global $cache, $db, $user, $auth, $template, $table_prefix; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; $this->db_tools = new \phpbb\db\tools($db); $user->add_lang('acp/database'); $this->tpl_name = 'acp_database'; $this->page_title = 'ACP_DATABASE'; $action = request_var('action', ''); $submit = (isset($_POST['submit'])) ? true : false; $template->assign_vars(array( 'MODE' => $mode )); switch ($mode) { case 'backup': $this->page_title = 'ACP_BACKUP'; switch ($action) { case 'download': $type = request_var('type', ''); $table = array_intersect($this->db_tools->sql_list_tables(), request_var('table', array(''))); $format = request_var('method', ''); $where = request_var('where', ''); if (!sizeof($table)) { trigger_error($user->lang['TABLE_SELECT_ERROR'] . adm_back_link($this->u_action), E_USER_WARNING); } $store = $download = $structure = $schema_data = false; if ($where == 'store_and_download' || $where == 'store') { $store = true; } if ($where == 'store_and_download' || $where == 'download') { $download = true; } if ($type == 'full' || $type == 'structure') { $structure = true; } if ($type == 'full' || $type == 'data') { $schema_data = true; } @set_time_limit(1200); @set_time_limit(0); $time = time(); $filename = 'backup_' . $time . '_' . unique_id(); switch ($db->get_sql_layer()) { case 'mysqli': case 'mysql4': case 'mysql': $extractor = new mysql_extractor($format, $filename, $time, $download, $store); break; case 'sqlite': $extractor = new sqlite_extractor($format, $filename, $time, $download, $store); break; case 'sqlite3': $extractor = new sqlite3_extractor($format, $filename, $time, $download, $store); break; case 'postgres': $extractor = new postgres_extractor($format, $filename, $time, $download, $store); break; case 'oracle': $extractor = new oracle_extractor($format, $filename, $time, $download, $store); break; case 'mssql': case 'mssql_odbc': case 'mssqlnative': $extractor = new mssql_extractor($format, $filename, $time, $download, $store); break; } $extractor->write_start($table_prefix); foreach ($table as $table_name) { // Get the table structure if ($structure) { $extractor->write_table($table_name); } else { // We might wanna empty out all that junk :D switch ($db->get_sql_layer()) { case 'sqlite': case 'sqlite3': $extractor->flush('DELETE FROM ' . $table_name . ";\n"); break; case 'mssql': case 'mssql_odbc': case 'mssqlnative': $extractor->flush('TRUNCATE TABLE ' . $table_name . "GO\n"); break; case 'oracle': $extractor->flush('TRUNCATE TABLE ' . $table_name . "/\n"); break; default: $extractor->flush('TRUNCATE TABLE ' . $table_name . ";\n"); break; } } // Data if ($schema_data) { $extractor->write_data($table_name); } } $extractor->write_end(); add_log('admin', 'LOG_DB_BACKUP'); if ($download == true) { exit; } trigger_error($user->lang['BACKUP_SUCCESS'] . adm_back_link($this->u_action)); break; default: $tables = $this->db_tools->sql_list_tables(); asort($tables); foreach ($tables as $table_name) { if (strlen($table_prefix) === 0 || stripos($table_name, $table_prefix) === 0) { $template->assign_block_vars('tables', array( 'TABLE' => $table_name )); } } unset($tables); $template->assign_vars(array( 'U_ACTION' => $this->u_action . '&action=download' )); $available_methods = array('gzip' => 'zlib', 'bzip2' => 'bz2'); foreach ($available_methods as $type => $module) { if (!@extension_loaded($module)) { continue; } $template->assign_block_vars('methods', array( 'TYPE' => $type )); } $template->assign_block_vars('methods', array( 'TYPE' => 'text' )); break; } break; case 'restore': $this->page_title = 'ACP_RESTORE'; switch ($action) { case 'submit': $delete = request_var('delete', ''); $file = request_var('file', ''); $download = request_var('download', ''); if (!preg_match('#^backup_\d{10,}_[a-z\d]{16}\.(sql(?:\.(?:gz|bz2))?)$#', $file, $matches)) { trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } $file_name = $phpbb_root_path . 'store/' . $matches[0]; if (!file_exists($file_name) || !is_readable($file_name)) { trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } if ($delete) { if (confirm_box(true)) { unlink($file_name); add_log('admin', 'LOG_DB_DELETE'); trigger_error($user->lang['BACKUP_DELETE'] . adm_back_link($this->u_action)); } else { confirm_box(false, $user->lang['DELETE_SELECTED_BACKUP'], build_hidden_fields(array('delete' => $delete, 'file' => $file))); } } else if ($download || confirm_box(true)) { if ($download) { $name = $matches[0]; switch ($matches[1]) { case 'sql': $mimetype = 'text/x-sql'; break; case 'sql.bz2': $mimetype = 'application/x-bzip2'; break; case 'sql.gz': $mimetype = 'application/x-gzip'; break; } header('Cache-Control: private, no-cache'); header("Content-Type: $mimetype; name=\"$name\""); header("Content-disposition: attachment; filename=$name"); @set_time_limit(0); $fp = @fopen($file_name, 'rb'); if ($fp !== false) { while (!feof($fp)) { echo fread($fp, 8192); } fclose($fp); } flush(); exit; } switch ($matches[1]) { case 'sql': $fp = fopen($file_name, 'rb'); $read = 'fread'; $seek = 'fseek'; $eof = 'feof'; $close = 'fclose'; $fgetd = 'fgetd'; break; case 'sql.bz2': $fp = bzopen($file_name, 'r'); $read = 'bzread'; $seek = ''; $eof = 'feof'; $close = 'bzclose'; $fgetd = 'fgetd_seekless'; break; case 'sql.gz': $fp = gzopen($file_name, 'rb'); $read = 'gzread'; $seek = 'gzseek'; $eof = 'gzeof'; $close = 'gzclose'; $fgetd = 'fgetd'; break; } switch ($db->get_sql_layer()) { case 'mysql': case 'mysql4': case 'mysqli': case 'sqlite': case 'sqlite3': while (($sql = $fgetd($fp, ";\n", $read, $seek, $eof)) !== false) { $db->sql_query($sql); } break; case 'postgres': $delim = ";\n"; while (($sql = $fgetd($fp, $delim, $read, $seek, $eof)) !== false) { $query = trim($sql); if (substr($query, 0, 13) == 'CREATE DOMAIN') { list(, , $domain) = explode(' ', $query); $sql = "SELECT domain_name FROM information_schema.domains WHERE domain_name = '$domain';"; $result = $db->sql_query($sql); if (!$db->sql_fetchrow($result)) { $db->sql_query($query); } $db->sql_freeresult($result); } else { $db->sql_query($query); } if (substr($query, 0, 4) == 'COPY') { while (($sub = $fgetd($fp, "\n", $read, $seek, $eof)) !== '\.') { if ($sub === false) { trigger_error($user->lang['RESTORE_FAILURE'] . adm_back_link($this->u_action), E_USER_WARNING); } pg_put_line($db->get_db_connect_id(), $sub . "\n"); } pg_put_line($db->get_db_connect_id(), "\\.\n"); pg_end_copy($db->get_db_connect_id()); } } break; case 'oracle': while (($sql = $fgetd($fp, "/\n", $read, $seek, $eof)) !== false) { $db->sql_query($sql); } break; case 'mssql': case 'mssql_odbc': case 'mssqlnative': while (($sql = $fgetd($fp, "GO\n", $read, $seek, $eof)) !== false) { $db->sql_query($sql); } break; } $close($fp); // Purge the cache due to updated data $cache->purge(); add_log('admin', 'LOG_DB_RESTORE'); trigger_error($user->lang['RESTORE_SUCCESS'] . adm_back_link($this->u_action)); break; } else if (!$download) { confirm_box(false, $user->lang['RESTORE_SELECTED_BACKUP'], build_hidden_fields(array('file' => $file))); } default: $methods = array('sql'); $available_methods = array('sql.gz' => 'zlib', 'sql.bz2' => 'bz2'); foreach ($available_methods as $type => $module) { if (!@extension_loaded($module)) { continue; } $methods[] = $type; } $dir = $phpbb_root_path . 'store/'; $dh = @opendir($dir); $backup_files = array(); if ($dh) { while (($file = readdir($dh)) !== false) { if (preg_match('#^backup_(\d{10,})_[a-z\d]{16}\.(sql(?:\.(?:gz|bz2))?)$#', $file, $matches)) { if (in_array($matches[2], $methods)) { $backup_files[(int) $matches[1]] = $file; } } } closedir($dh); } if (!empty($backup_files)) { krsort($backup_files); foreach ($backup_files as $name => $file) { $template->assign_block_vars('files', array( 'FILE' => $file, 'NAME' => $user->format_date($name, 'd-m-Y H:i:s', true), 'SUPPORTED' => true, )); } } $template->assign_vars(array( 'U_ACTION' => $this->u_action . '&action=submit' )); break; } break; } } } class base_extractor { var $fh; var $fp; var $write; var $close; var $store; var $download; var $time; var $format; var $run_comp = false; function base_extractor($format, $filename, $time, $download = false, $store = false) { global $request; $this->download = $download; $this->store = $store; $this->time = $time; $this->format = $format; switch ($format) { case 'text': $ext = '.sql'; $open = 'fopen'; $this->write = 'fwrite'; $this->close = 'fclose'; $mimetype = 'text/x-sql'; break; case 'bzip2': $ext = '.sql.bz2'; $open = 'bzopen'; $this->write = 'bzwrite'; $this->close = 'bzclose'; $mimetype = 'application/x-bzip2'; break; case 'gzip': $ext = '.sql.gz'; $open = 'gzopen'; $this->write = 'gzwrite'; $this->close = 'gzclose'; $mimetype = 'application/x-gzip'; break; } if ($download == true) { $name = $filename . $ext; header('Cache-Control: private, no-cache'); header("Content-Type: $mimetype; name=\"$name\""); header("Content-disposition: attachment; filename=$name"); switch ($format) { case 'bzip2': ob_start(); break; case 'gzip': if (strpos($request->header('Accept-Encoding'), 'gzip') !== false && strpos(strtolower($request->header('User-Agent')), 'msie') === false) { ob_start('ob_gzhandler'); } else { $this->run_comp = true; } break; } } if ($store == true) { global $phpbb_root_path; $file = $phpbb_root_path . 'store/' . $filename . $ext; $this->fp = $open($file, 'w'); if (!$this->fp) { trigger_error('FILE_WRITE_FAIL', E_USER_ERROR); } } } function write_end() { static $close; if ($this->store) { if ($close === null) { $close = $this->close; } $close($this->fp); } // bzip2 must be written all the way at the end if ($this->download && $this->format === 'bzip2') { $c = ob_get_clean(); echo bzcompress($c); } } function flush($data) { static $write; if ($this->store === true) { if ($write === null) { $write = $this->write; } $write($this->fp, $data); } if ($this->download === true) { if ($this->format === 'bzip2' || $this->format === 'text' || ($this->format === 'gzip' && !$this->run_comp)) { echo $data; } // we can write the gzip data as soon as we get it if ($this->format === 'gzip') { if ($this->run_comp) { echo gzencode($data); } else { ob_flush(); flush(); } } } } } class mysql_extractor extends base_extractor { function write_start($table_prefix) { $sql_data = "#\n"; $sql_data .= "# phpBB Backup Script\n"; $sql_data .= "# Dump of tables for $table_prefix\n"; $sql_data .= "# DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n"; $sql_data .= "#\n"; $this->flush($sql_data); } function write_table($table_name) { global $db; static $new_extract; if ($new_extract === null) { if ($db->get_sql_layer() === 'mysqli' || version_compare($db->sql_server_info(true), '3.23.20', '>=')) { $new_extract = true; } else { $new_extract = false; } } if ($new_extract) { $this->new_write_table($table_name); } else { $this->old_write_table($table_name); } } function write_data($table_name) { global $db; if ($db->get_sql_layer() === 'mysqli') { $this->write_data_mysqli($table_name); } else { $this->write_data_mysql($table_name); } } function write_data_mysqli($table_name) { global $db; $sql = "SELECT * FROM $table_name"; $result = mysqli_query($db->get_db_connect_id(), $sql, MYSQLI_USE_RESULT); if ($result != false) { $fields_cnt = mysqli_num_fields($result); // Get field information $field = mysqli_fetch_fields($result); $field_set = array(); for ($j = 0; $j < $fields_cnt; $j++) { $field_set[] = $field[$j]->name; } $search = array("\\", "'", "\x00", "\x0a", "\x0d", "\x1a", '"'); $replace = array("\\\\", "\\'", '\0', '\n', '\r', '\Z', '\\"'); $fields = implode(', ', $field_set); $sql_data = 'INSERT INTO ' . $table_name . ' (' . $fields . ') VALUES '; $first_set = true; $query_len = 0; $max_len = get_usable_memory(); while ($row = mysqli_fetch_row($result)) { $values = array(); if ($first_set) { $query = $sql_data . '('; } else { $query .= ',('; } for ($j = 0; $j < $fields_cnt; $j++) { if (!isset($row[$j]) || is_null($row[$j])) { $values[$j] = 'NULL'; } else if (($field[$j]->flags & 32768) && !($field[$j]->flags & 1024)) { $values[$j] = $row[$j]; } else { $values[$j] = "'" . str_replace($search, $replace, $row[$j]) . "'"; } } $query .= implode(', ', $values) . ')'; $query_len += strlen($query); if ($query_len > $max_len) { $this->flush($query . ";\n\n"); $query = ''; $query_len = 0; $first_set = true; } else { $first_set = false; } } mysqli_free_result($result); // check to make sure we have nothing left to flush if (!$first_set && $query) { $this->flush($query . ";\n\n"); } } } function write_data_mysql($table_name) { global $db; $sql = "SELECT * FROM $table_name"; $result = mysql_unbuffered_query($sql, $db->get_db_connect_id()); if ($result != false) { $fields_cnt = mysql_num_fields($result); // Get field information $field = array(); for ($i = 0; $i < $fields_cnt; $i++) { $field[] = mysql_fetch_field($result, $i); } $field_set = array(); for ($j = 0; $j < $fields_cnt; $j++) { $field_set[] = $field[$j]->name; } $search = array("\\", "'", "\x00", "\x0a", "\x0d", "\x1a", '"'); $replace = array("\\\\", "\\'", '\0', '\n', '\r', '\Z', '\\"'); $fields = implode(', ', $field_set); $sql_data = 'INSERT INTO ' . $table_name . ' (' . $fields . ') VALUES '; $first_set = true; $query_len = 0; $max_len = get_usable_memory(); while ($row = mysql_fetch_row($result)) { $values = array(); if ($first_set) { $query = $sql_data . '('; } else { $query .= ',('; } for ($j = 0; $j < $fields_cnt; $j++) { if (!isset($row[$j]) || is_null($row[$j])) { $values[$j] = 'NULL'; } else if ($field[$j]->numeric && ($field[$j]->type !== 'timestamp')) { $values[$j] = $row[$j]; } else { $values[$j] = "'" . str_replace($search, $replace, $row[$j]) . "'"; } } $query .= implode(', ', $values) . ')'; $query_len += strlen($query); if ($query_len > $max_len) { $this->flush($query . ";\n\n"); $query = ''; $query_len = 0; $first_set = true; } else { $first_set = false; } } mysql_free_result($result); // check to make sure we have nothing left to flush if (!$first_set && $query) { $this->flush($query . ";\n\n"); } } } function new_write_table($table_name) { global $db; $sql = 'SHOW CREATE TABLE ' . $table_name; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $sql_data = '# Table: ' . $table_name . "\n"; $sql_data .= "DROP TABLE IF EXISTS $table_name;\n"; $this->flush($sql_data . $row['Create Table'] . ";\n\n"); $db->sql_freeresult($result); } function old_write_table($table_name) { global $db; $sql_data = '# Table: ' . $table_name . "\n"; $sql_data .= "DROP TABLE IF EXISTS $table_name;\n"; $sql_data .= "CREATE TABLE $table_name(\n"; $rows = array(); $sql = "SHOW FIELDS FROM $table_name"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $line = ' ' . $row['Field'] . ' ' . $row['Type']; if (!is_null($row['Default'])) { $line .= " DEFAULT '{$row['Default']}'"; } if ($row['Null'] != 'YES') { $line .= ' NOT NULL'; } if ($row['Extra'] != '') { $line .= ' ' . $row['Extra']; } $rows[] = $line; } $db->sql_freeresult($result); $sql = "SHOW KEYS FROM $table_name"; $result = $db->sql_query($sql); $index = array(); while ($row = $db->sql_fetchrow($result)) { $kname = $row['Key_name']; if ($kname != 'PRIMARY') { if ($row['Non_unique'] == 0) { $kname = "UNIQUE|$kname"; } } if ($row['Sub_part']) { $row['Column_name'] .= '(' . $row['Sub_part'] . ')'; } $index[$kname][] = $row['Column_name']; } $db->sql_freeresult($result); foreach ($index as $key => $columns) { $line = ' '; if ($key == 'PRIMARY') { $line .= 'PRIMARY KEY (' . implode(', ', $columns) . ')'; } else if (strpos($key, 'UNIQUE') === 0) { $line .= 'UNIQUE ' . substr($key, 7) . ' (' . implode(', ', $columns) . ')'; } else if (strpos($key, 'FULLTEXT') === 0) { $line .= 'FULLTEXT ' . substr($key, 9) . ' (' . implode(', ', $columns) . ')'; } else { $line .= "KEY $key (" . implode(', ', $columns) . ')'; } $rows[] = $line; } $sql_data .= implode(",\n", $rows); $sql_data .= "\n);\n\n"; $this->flush($sql_data); } } class sqlite_extractor extends base_extractor { function write_start($prefix) { $sql_data = "--\n"; $sql_data .= "-- phpBB Backup Script\n"; $sql_data .= "-- Dump of tables for $prefix\n"; $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n"; $sql_data .= "--\n"; $sql_data .= "BEGIN TRANSACTION;\n"; $this->flush($sql_data); } function write_table($table_name) { global $db; $sql_data = '-- Table: ' . $table_name . "\n"; $sql_data .= "DROP TABLE $table_name;\n"; $sql = "SELECT sql FROM sqlite_master WHERE type = 'table' AND name = '" . $db->sql_escape($table_name) . "' ORDER BY type DESC, name;"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); // Create Table $sql_data .= $row['sql'] . ";\n"; $result = $db->sql_query("PRAGMA index_list('" . $db->sql_escape($table_name) . "');"); $ar = array(); while ($row = $db->sql_fetchrow($result)) { $ar[] = $row; } $db->sql_freeresult($result); foreach ($ar as $value) { if (strpos($value['name'], 'autoindex') !== false) { continue; } $result = $db->sql_query("PRAGMA index_info('" . $db->sql_escape($value['name']) . "');"); $fields = array(); while ($row = $db->sql_fetchrow($result)) { $fields[] = $row['name']; } $db->sql_freeresult($result); $sql_data .= 'CREATE ' . ($value['unique'] ? 'UNIQUE ' : '') . 'INDEX ' . $value['name'] . ' on ' . $table_name . ' (' . implode(', ', $fields) . ");\n"; } $this->flush($sql_data . "\n"); } function write_data($table_name) { global $db; $col_types = sqlite_fetch_column_types($db->get_db_connect_id(), $table_name); $sql = "SELECT * FROM $table_name"; $result = sqlite_unbuffered_query($db->get_db_connect_id(), $sql); $rows = sqlite_fetch_all($result, SQLITE_ASSOC); $sql_insert = 'INSERT INTO ' . $table_name . ' (' . implode(', ', array_keys($col_types)) . ') VALUES ('; foreach ($rows as $row) { foreach ($row as $column_name => $column_data) { if (is_null($column_data)) { $row[$column_name] = 'NULL'; } else if ($column_data == '') { $row[$column_name] = "''"; } else if (strpos($col_types[$column_name], 'text') !== false || strpos($col_types[$column_name], 'char') !== false || strpos($col_types[$column_name], 'blob') !== false) { $row[$column_name] = sanitize_data_generic(str_replace("'", "''", $column_data)); } } $this->flush($sql_insert . implode(', ', $row) . ");\n"); } } function write_end() { $this->flush("COMMIT;\n"); parent::write_end(); } } class sqlite3_extractor extends base_extractor { function write_start($prefix) { $sql_data = "--\n"; $sql_data .= "-- phpBB Backup Script\n"; $sql_data .= "-- Dump of tables for $prefix\n"; $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n"; $sql_data .= "--\n"; $sql_data .= "BEGIN TRANSACTION;\n"; $this->flush($sql_data); } function write_table($table_name) { global $db; $sql_data = '-- Table: ' . $table_name . "\n"; $sql_data .= "DROP TABLE $table_name;\n"; $sql = "SELECT sql FROM sqlite_master WHERE type = 'table' AND name = '" . $db->sql_escape($table_name) . "' ORDER BY name ASC;"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); // Create Table $sql_data .= $row['sql'] . ";\n"; $result = $db->sql_query("PRAGMA index_list('" . $db->sql_escape($table_name) . "');"); while ($row = $db->sql_fetchrow($result)) { if (strpos($row['name'], 'autoindex') !== false) { continue; } $result2 = $db->sql_query("PRAGMA index_info('" . $db->sql_escape($row['name']) . "');"); $fields = array(); while ($row2 = $db->sql_fetchrow($result2)) { $fields[] = $row2['name']; } $db->sql_freeresult($result2); $sql_data .= 'CREATE ' . ($row['unique'] ? 'UNIQUE ' : '') . 'INDEX ' . $row['name'] . ' ON ' . $table_name . ' (' . implode(', ', $fields) . ");\n"; } $db->sql_freeresult($result); $this->flush($sql_data . "\n"); } function write_data($table_name) { global $db; $result = $db->sql_query("PRAGMA table_info('" . $db->sql_escape($table_name) . "');"); $col_types = array(); while ($row = $db->sql_fetchrow($result)) { $col_types[$row['name']] = $row['type']; } $db->sql_freeresult($result); $sql_insert = 'INSERT INTO ' . $table_name . ' (' . implode(', ', array_keys($col_types)) . ') VALUES ('; $sql = "SELECT * FROM $table_name"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { foreach ($row as $column_name => $column_data) { if (is_null($column_data)) { $row[$column_name] = 'NULL'; } else if ($column_data === '') { $row[$column_name] = "''"; } else if (stripos($col_types[$column_name], 'text') !== false || stripos($col_types[$column_name], 'char') !== false || stripos($col_types[$column_name], 'blob') !== false) { $row[$column_name] = sanitize_data_generic(str_replace("'", "''", $column_data)); } } $this->flush($sql_insert . implode(', ', $row) . ");\n"); } } function write_end() { $this->flush("COMMIT;\n"); parent::write_end(); } } class postgres_extractor extends base_extractor { function write_start($prefix) { $sql_data = "--\n"; $sql_data .= "-- phpBB Backup Script\n"; $sql_data .= "-- Dump of tables for $prefix\n"; $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n"; $sql_data .= "--\n"; $sql_data .= "BEGIN TRANSACTION;\n"; $this->flush($sql_data); } function write_table($table_name) { global $db; static $domains_created = array(); $sql = "SELECT a.domain_name, a.data_type, a.character_maximum_length, a.domain_default FROM INFORMATION_SCHEMA.domains a, INFORMATION_SCHEMA.column_domain_usage b WHERE a.domain_name = b.domain_name AND b.table_name = '{$table_name}'"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { if (empty($domains_created[$row['domain_name']])) { $domains_created[$row['domain_name']] = true; //$sql_data = "DROP DOMAIN {$row['domain_name']};\n"; $sql_data = "CREATE DOMAIN {$row['domain_name']} as {$row['data_type']}"; if (!empty($row['character_maximum_length'])) { $sql_data .= '(' . $row['character_maximum_length'] . ')'; } $sql_data .= ' NOT NULL'; if (!empty($row['domain_default'])) { $sql_data .= ' DEFAULT ' . $row['domain_default']; } $this->flush($sql_data . ";\n"); } } $db->sql_freeresult($result); $sql_data = '-- Table: ' . $table_name . "\n"; $sql_data .= "DROP TABLE $table_name;\n"; // PGSQL does not "tightly" bind sequences and tables, we must guess... $sql = "SELECT relname FROM pg_class WHERE relkind = 'S' AND relname = '{$table_name}_seq'"; $result = $db->sql_query($sql); // We don't even care about storing the results. We already know the answer if we get rows back. if ($db->sql_fetchrow($result)) { $sql_data .= "DROP SEQUENCE {$table_name}_seq;\n"; $sql_data .= "CREATE SEQUENCE {$table_name}_seq;\n"; } $db->sql_freeresult($result); $field_query = "SELECT a.attnum, a.attname as field, t.typname as type, a.attlen as length, a.atttypmod as lengthvar, a.attnotnull as notnull FROM pg_class c, pg_attribute a, pg_type t WHERE c.relname = '" . $db->sql_escape($table_name) . "' AND a.attnum > 0 AND a.attrelid = c.oid AND a.atttypid = t.oid ORDER BY a.attnum"; $result = $db->sql_query($field_query); $sql_data .= "CREATE TABLE $table_name(\n"; $lines = array(); while ($row = $db->sql_fetchrow($result)) { // Get the data from the table $sql_get_default = "SELECT pg_get_expr(d.adbin, d.adrelid) as rowdefault FROM pg_attrdef d, pg_class c WHERE (c.relname = '" . $db->sql_escape($table_name) . "') AND (c.oid = d.adrelid) AND d.adnum = " . $row['attnum']; $def_res = $db->sql_query($sql_get_default); $def_row = $db->sql_fetchrow($def_res); $db->sql_freeresult($def_res); if (empty($def_row)) { unset($row['rowdefault']); } else { $row['rowdefault'] = $def_row['rowdefault']; } if ($row['type'] == 'bpchar') { // Internally stored as bpchar, but isn't accepted in a CREATE TABLE statement. $row['type'] = 'char'; } $line = ' ' . $row['field'] . ' ' . $row['type']; if (strpos($row['type'], 'char') !== false) { if ($row['lengthvar'] > 0) { $line .= '(' . ($row['lengthvar'] - 4) . ')'; } } if (strpos($row['type'], 'numeric') !== false) { $line .= '('; $line .= sprintf("%s,%s", (($row['lengthvar'] >> 16) & 0xffff), (($row['lengthvar'] - 4) & 0xffff)); $line .= ')'; } if (isset($row['rowdefault'])) { $line .= ' DEFAULT ' . $row['rowdefault']; } if ($row['notnull'] == 't') { $line .= ' NOT NULL'; } $lines[] = $line; } $db->sql_freeresult($result); // Get the listing of primary keys. $sql_pri_keys = "SELECT ic.relname as index_name, bc.relname as tab_name, ta.attname as column_name, i.indisunique as unique_key, i.indisprimary as primary_key FROM pg_class bc, pg_class ic, pg_index i, pg_attribute ta, pg_attribute ia WHERE (bc.oid = i.indrelid) AND (ic.oid = i.indexrelid) AND (ia.attrelid = i.indexrelid) AND (ta.attrelid = bc.oid) AND (bc.relname = '" . $db->sql_escape($table_name) . "') AND (ta.attrelid = i.indrelid) AND (ta.attnum = i.indkey[ia.attnum-1]) ORDER BY index_name, tab_name, column_name"; $result = $db->sql_query($sql_pri_keys); $index_create = $index_rows = $primary_key = array(); // We do this in two steps. It makes placing the comma easier while ($row = $db->sql_fetchrow($result)) { if ($row['primary_key'] == 't') { $primary_key[] = $row['column_name']; $primary_key_name = $row['index_name']; } else { // We have to store this all this info because it is possible to have a multi-column key... // we can loop through it again and build the statement $index_rows[$row['index_name']]['table'] = $table_name; $index_rows[$row['index_name']]['unique'] = ($row['unique_key'] == 't') ? true : false; $index_rows[$row['index_name']]['column_names'][] = $row['column_name']; } } $db->sql_freeresult($result); if (!empty($index_rows)) { foreach ($index_rows as $idx_name => $props) { $index_create[] = 'CREATE ' . ($props['unique'] ? 'UNIQUE ' : '') . "INDEX $idx_name ON $table_name (" . implode(', ', $props['column_names']) . ");"; } } if (!empty($primary_key)) { $lines[] = " CONSTRAINT $primary_key_name PRIMARY KEY (" . implode(', ', $primary_key) . ")"; } // Generate constraint clauses for CHECK constraints $sql_checks = "SELECT conname as index_name, consrc FROM pg_constraint, pg_class bc WHERE conrelid = bc.oid AND bc.relname = '" . $db->sql_escape($table_name) . "' AND NOT EXISTS ( SELECT * FROM pg_constraint as c, pg_inherits as i WHERE i.inhrelid = pg_constraint.conrelid AND c.conname = pg_constraint.conname AND c.consrc = pg_constraint.consrc AND c.conrelid = i.inhparent )"; $result = $db->sql_query($sql_checks); // Add the constraints to the sql file. while ($row = $db->sql_fetchrow($result)) { if (!is_null($row['consrc'])) { $lines[] = ' CONSTRAINT ' . $row['index_name'] . ' CHECK ' . $row['consrc']; } } $db->sql_freeresult($result); $sql_data .= implode(", \n", $lines); $sql_data .= "\n);\n"; if (!empty($index_create)) { $sql_data .= implode("\n", $index_create) . "\n\n"; } $this->flush($sql_data); } function write_data($table_name) { global $db; // Grab all of the data from current table. $sql = "SELECT * FROM $table_name"; $result = $db->sql_query($sql); $i_num_fields = pg_num_fields($result); $seq = ''; for ($i = 0; $i < $i_num_fields; $i++) { $ary_type[] = pg_field_type($result, $i); $ary_name[] = pg_field_name($result, $i); $sql = "SELECT pg_get_expr(d.adbin, d.adrelid) as rowdefault FROM pg_attrdef d, pg_class c WHERE (c.relname = '{$table_name}') AND (c.oid = d.adrelid) AND d.adnum = " . strval($i + 1); $result2 = $db->sql_query($sql); if ($row = $db->sql_fetchrow($result2)) { // Determine if we must reset the sequences if (strpos($row['rowdefault'], "nextval('") === 0) { $seq .= "SELECT SETVAL('{$table_name}_seq',(select case when max({$ary_name[$i]})>0 then max({$ary_name[$i]})+1 else 1 end FROM {$table_name}));\n"; } } } $this->flush("COPY $table_name (" . implode(', ', $ary_name) . ') FROM stdin;' . "\n"); while ($row = $db->sql_fetchrow($result)) { $schema_vals = array(); // Build the SQL statement to recreate the data. for ($i = 0; $i < $i_num_fields; $i++) { $str_val = $row[$ary_name[$i]]; if (preg_match('#char|text|bool|bytea#i', $ary_type[$i])) { $str_val = str_replace(array("\n", "\t", "\r", "\b", "\f", "\v"), array('\n', '\t', '\r', '\b', '\f', '\v'), addslashes($str_val)); $str_empty = ''; } else { $str_empty = '\N'; } if (empty($str_val) && $str_val !== '0') { $str_val = $str_empty; } $schema_vals[] = $str_val; } // Take the ordered fields and their associated data and build it // into a valid sql statement to recreate that field in the data. $this->flush(implode("\t", $schema_vals) . "\n"); } $db->sql_freeresult($result); $this->flush("\\.\n"); // Write out the sequence statements $this->flush($seq); } function write_end() { $this->flush("COMMIT;\n"); parent::write_end(); } } class mssql_extractor extends base_extractor { function write_end() { $this->flush("COMMIT\nGO\n"); parent::write_end(); } function write_start($prefix) { $sql_data = "--\n"; $sql_data .= "-- phpBB Backup Script\n"; $sql_data .= "-- Dump of tables for $prefix\n"; $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n"; $sql_data .= "--\n"; $sql_data .= "BEGIN TRANSACTION\n"; $sql_data .= "GO\n"; $this->flush($sql_data); } function write_table($table_name) { global $db; $sql_data = '-- Table: ' . $table_name . "\n"; $sql_data .= "IF OBJECT_ID(N'$table_name', N'U') IS NOT NULL\n"; $sql_data .= "DROP TABLE $table_name;\n"; $sql_data .= "GO\n"; $sql_data .= "\nCREATE TABLE [$table_name] (\n"; $rows = array(); $text_flag = false; $sql = "SELECT COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') as IS_IDENTITY FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '$table_name'"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $line = "\t[{$row['COLUMN_NAME']}] [{$row['DATA_TYPE']}]"; if ($row['DATA_TYPE'] == 'text') { $text_flag = true; } if ($row['IS_IDENTITY']) { $line .= ' IDENTITY (1 , 1)'; } if ($row['CHARACTER_MAXIMUM_LENGTH'] && $row['DATA_TYPE'] !== 'text') { $line .= ' (' . $row['CHARACTER_MAXIMUM_LENGTH'] . ')'; } if ($row['IS_NULLABLE'] == 'YES') { $line .= ' NULL'; } else { $line .= ' NOT NULL'; } if ($row['COLUMN_DEFAULT']) { $line .= ' DEFAULT ' . $row['COLUMN_DEFAULT']; } $rows[] = $line; } $db->sql_freeresult($result); $sql_data .= implode(",\n", $rows); $sql_data .= "\n) ON [PRIMARY]"; if ($text_flag) { $sql_data .= " TEXTIMAGE_ON [PRIMARY]"; } $sql_data .= "\nGO\n\n"; $rows = array(); $sql = "SELECT CONSTRAINT_NAME, COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME = '$table_name'"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { if (!sizeof($rows)) { $sql_data .= "ALTER TABLE [$table_name] WITH NOCHECK ADD\n"; $sql_data .= "\tCONSTRAINT [{$row['CONSTRAINT_NAME']}] PRIMARY KEY CLUSTERED \n\t(\n"; } $rows[] = "\t\t[{$row['COLUMN_NAME']}]"; } if (sizeof($rows)) { $sql_data .= implode(",\n", $rows); $sql_data .= "\n\t) ON [PRIMARY] \nGO\n"; } $db->sql_freeresult($result); $index = array(); $sql = "EXEC sp_statistics '$table_name'"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { if ($row['TYPE'] == 3) { $index[$row['INDEX_NAME']][] = '[' . $row['COLUMN_NAME'] . ']'; } } $db->sql_freeresult($result); foreach ($index as $index_name => $column_name) { $index[$index_name] = implode(', ', $column_name); } foreach ($index as $index_name => $columns) { $sql_data .= "\nCREATE INDEX [$index_name] ON [$table_name]($columns) ON [PRIMARY]\nGO\n"; } $this->flush($sql_data); } function write_data($table_name) { global $db; if ($db->get_sql_layer() === 'mssql') { $this->write_data_mssql($table_name); } else if($db->get_sql_layer() === 'mssqlnative') { $this->write_data_mssqlnative($table_name); } else { $this->write_data_odbc($table_name); } } function write_data_mssql($table_name) { global $db; $ary_type = $ary_name = array(); $ident_set = false; $sql_data = ''; // Grab all of the data from current table. $sql = "SELECT * FROM $table_name"; $result = $db->sql_query($sql); $retrieved_data = mssql_num_rows($result); $i_num_fields = mssql_num_fields($result); for ($i = 0; $i < $i_num_fields; $i++) { $ary_type[$i] = mssql_field_type($result, $i); $ary_name[$i] = mssql_field_name($result, $i); } if ($retrieved_data) { $sql = "SELECT 1 as has_identity FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1"; $result2 = $db->sql_query($sql); $row2 = $db->sql_fetchrow($result2); if (!empty($row2['has_identity'])) { $sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n"; $ident_set = true; } $db->sql_freeresult($result2); } while ($row = $db->sql_fetchrow($result)) { $schema_vals = $schema_fields = array(); // Build the SQL statement to recreate the data. for ($i = 0; $i < $i_num_fields; $i++) { $str_val = $row[$ary_name[$i]]; if (preg_match('#char|text|bool|varbinary#i', $ary_type[$i])) { $str_quote = ''; $str_empty = "''"; $str_val = sanitize_data_mssql(str_replace("'", "''", $str_val)); } else if (preg_match('#date|timestamp#i', $ary_type[$i])) { if (empty($str_val)) { $str_quote = ''; } else { $str_quote = "'"; } } else { $str_quote = ''; $str_empty = 'NULL'; } if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val))) { $str_val = $str_empty; } $schema_vals[$i] = $str_quote . $str_val . $str_quote; $schema_fields[$i] = $ary_name[$i]; } // Take the ordered fields and their associated data and build it // into a valid sql statement to recreate that field in the data. $sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n"; $this->flush($sql_data); $sql_data = ''; } $db->sql_freeresult($result); if ($retrieved_data && $ident_set) { $sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n"; } $this->flush($sql_data); } function write_data_mssqlnative($table_name) { global $db; $ary_type = $ary_name = array(); $ident_set = false; $sql_data = ''; // Grab all of the data from current table. $sql = "SELECT * FROM $table_name"; $db->mssqlnative_set_query_options(array('Scrollable' => SQLSRV_CURSOR_STATIC)); $result = $db->sql_query($sql); $retrieved_data = $db->mssqlnative_num_rows($result); if (!$retrieved_data) { $db->sql_freeresult($result); return; } $sql = "SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = '" . $db->sql_escape($table_name) . "'"; $result_fields = $db->sql_query($sql); $i_num_fields = 0; while ($row = $db->sql_fetchrow($result_fields)) { $ary_type[$i_num_fields] = $row['DATA_TYPE']; $ary_name[$i_num_fields] = $row['COLUMN_NAME']; $i_num_fields++; } $db->sql_freeresult($result_fields); $sql = "SELECT 1 as has_identity FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1"; $result2 = $db->sql_query($sql); $row2 = $db->sql_fetchrow($result2); if (!empty($row2['has_identity'])) { $sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n"; $ident_set = true; } $db->sql_freeresult($result2); while ($row = $db->sql_fetchrow($result)) { $schema_vals = $schema_fields = array(); // Build the SQL statement to recreate the data. for ($i = 0; $i < $i_num_fields; $i++) { $str_val = $row[$ary_name[$i]]; // defaults to type number - better quote just to be safe, so check for is_int too if (is_int($ary_type[$i]) || preg_match('#char|text|bool|varbinary#i', $ary_type[$i])) { $str_quote = ''; $str_empty = "''"; $str_val = sanitize_data_mssql(str_replace("'", "''", $str_val)); } else if (preg_match('#date|timestamp#i', $ary_type[$i])) { if (empty($str_val)) { $str_quote = ''; } else { $str_quote = "'"; } } else { $str_quote = ''; $str_empty = 'NULL'; } if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val))) { $str_val = $str_empty; } $schema_vals[$i] = $str_quote . $str_val . $str_quote; $schema_fields[$i] = $ary_name[$i]; } // Take the ordered fields and their associated data and build it // into a valid sql statement to recreate that field in the data. $sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n"; $this->flush($sql_data); $sql_data = ''; } $db->sql_freeresult($result); if ($ident_set) { $sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n"; } $this->flush($sql_data); } function write_data_odbc($table_name) { global $db; $ary_type = $ary_name = array(); $ident_set = false; $sql_data = ''; // Grab all of the data from current table. $sql = "SELECT * FROM $table_name"; $result = $db->sql_query($sql); $retrieved_data = odbc_num_rows($result); if ($retrieved_data) { $sql = "SELECT 1 as has_identity FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1"; $result2 = $db->sql_query($sql); $row2 = $db->sql_fetchrow($result2); if (!empty($row2['has_identity'])) { $sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n"; $ident_set = true; } $db->sql_freeresult($result2); } $i_num_fields = odbc_num_fields($result); for ($i = 0; $i < $i_num_fields; $i++) { $ary_type[$i] = odbc_field_type($result, $i + 1); $ary_name[$i] = odbc_field_name($result, $i + 1); } while ($row = $db->sql_fetchrow($result)) { $schema_vals = $schema_fields = array(); // Build the SQL statement to recreate the data. for ($i = 0; $i < $i_num_fields; $i++) { $str_val = $row[$ary_name[$i]]; if (preg_match('#char|text|bool|varbinary#i', $ary_type[$i])) { $str_quote = ''; $str_empty = "''"; $str_val = sanitize_data_mssql(str_replace("'", "''", $str_val)); } else if (preg_match('#date|timestamp#i', $ary_type[$i])) { if (empty($str_val)) { $str_quote = ''; } else { $str_quote = "'"; } } else { $str_quote = ''; $str_empty = 'NULL'; } if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val))) { $str_val = $str_empty; } $schema_vals[$i] = $str_quote . $str_val . $str_quote; $schema_fields[$i] = $ary_name[$i]; } // Take the ordered fields and their associated data and build it // into a valid sql statement to recreate that field in the data. $sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n"; $this->flush($sql_data); $sql_data = ''; } $db->sql_freeresult($result); if ($retrieved_data && $ident_set) { $sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n"; } $this->flush($sql_data); } } class oracle_extractor extends base_extractor { function write_table($table_name) { global $db; $sql_data = '-- Table: ' . $table_name . "\n"; $sql_data .= "DROP TABLE $table_name\n/\n"; $sql_data .= "\nCREATE TABLE $table_name (\n"; $sql = "SELECT COLUMN_NAME, DATA_TYPE, DATA_PRECISION, DATA_LENGTH, NULLABLE, DATA_DEFAULT FROM ALL_TAB_COLS WHERE table_name = '{$table_name}'"; $result = $db->sql_query($sql); $rows = array(); while ($row = $db->sql_fetchrow($result)) { $line = ' "' . $row['column_name'] . '" ' . $row['data_type']; if ($row['data_type'] !== 'CLOB') { if ($row['data_type'] !== 'VARCHAR2' && $row['data_type'] !== 'CHAR') { $line .= '(' . $row['data_precision'] . ')'; } else { $line .= '(' . $row['data_length'] . ')'; } } if (!empty($row['data_default'])) { $line .= ' DEFAULT ' . $row['data_default']; } if ($row['nullable'] == 'N') { $line .= ' NOT NULL'; } $rows[] = $line; } $db->sql_freeresult($result); $sql = "SELECT A.CONSTRAINT_NAME, A.COLUMN_NAME FROM USER_CONS_COLUMNS A, USER_CONSTRAINTS B WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME AND B.CONSTRAINT_TYPE = 'P' AND A.TABLE_NAME = '{$table_name}'"; $result = $db->sql_query($sql); $primary_key = array(); $contraint_name = ''; while ($row = $db->sql_fetchrow($result)) { $constraint_name = '"' . $row['constraint_name'] . '"'; $primary_key[] = '"' . $row['column_name'] . '"'; } $db->sql_freeresult($result); if (sizeof($primary_key)) { $rows[] = " CONSTRAINT {$constraint_name} PRIMARY KEY (" . implode(', ', $primary_key) . ')'; } $sql = "SELECT A.CONSTRAINT_NAME, A.COLUMN_NAME FROM USER_CONS_COLUMNS A, USER_CONSTRAINTS B WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME AND B.CONSTRAINT_TYPE = 'U' AND A.TABLE_NAME = '{$table_name}'"; $result = $db->sql_query($sql); $unique = array(); $contraint_name = ''; while ($row = $db->sql_fetchrow($result)) { $constraint_name = '"' . $row['constraint_name'] . '"'; $unique[] = '"' . $row['column_name'] . '"'; } $db->sql_freeresult($result); if (sizeof($unique)) { $rows[] = " CONSTRAINT {$constraint_name} UNIQUE (" . implode(', ', $unique) . ')'; } $sql_data .= implode(",\n", $rows); $sql_data .= "\n)\n/\n"; $sql = "SELECT A.REFERENCED_NAME, C.* FROM USER_DEPENDENCIES A, USER_TRIGGERS B, USER_SEQUENCES C WHERE A.REFERENCED_TYPE = 'SEQUENCE' AND A.NAME = B.TRIGGER_NAME AND B.TABLE_NAME = '{$table_name}' AND C.SEQUENCE_NAME = A.REFERENCED_NAME"; $result = $db->sql_query($sql); $type = request_var('type', ''); while ($row = $db->sql_fetchrow($result)) { $sql_data .= "\nDROP SEQUENCE \"{$row['referenced_name']}\"\n/\n"; $sql_data .= "\nCREATE SEQUENCE \"{$row['referenced_name']}\""; if ($type == 'full') { $sql_data .= ' START WITH ' . $row['last_number']; } $sql_data .= "\n/\n"; } $db->sql_freeresult($result); $sql = "SELECT DESCRIPTION, WHEN_CLAUSE, TRIGGER_BODY FROM USER_TRIGGERS WHERE TABLE_NAME = '{$table_name}'"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $sql_data .= "\nCREATE OR REPLACE TRIGGER {$row['description']}WHEN ({$row['when_clause']})\n{$row['trigger_body']}\n/\n"; } $db->sql_freeresult($result); $sql = "SELECT A.INDEX_NAME, B.COLUMN_NAME FROM USER_INDEXES A, USER_IND_COLUMNS B WHERE A.UNIQUENESS = 'NONUNIQUE' AND A.INDEX_NAME = B.INDEX_NAME AND B.TABLE_NAME = '{$table_name}'"; $result = $db->sql_query($sql); $index = array(); while ($row = $db->sql_fetchrow($result)) { $index[$row['index_name']][] = $row['column_name']; } foreach ($index as $index_name => $column_names) { $sql_data .= "\nCREATE INDEX $index_name ON $table_name(" . implode(', ', $column_names) . ")\n/\n"; } $db->sql_freeresult($result); $this->flush($sql_data); } function write_data($table_name) { global $db; $ary_type = $ary_name = array(); // Grab all of the data from current table. $sql = "SELECT * FROM $table_name"; $result = $db->sql_query($sql); $i_num_fields = ocinumcols($result); for ($i = 0; $i < $i_num_fields; $i++) { $ary_type[$i] = ocicolumntype($result, $i + 1); $ary_name[$i] = ocicolumnname($result, $i + 1); } $sql_data = ''; while ($row = $db->sql_fetchrow($result)) { $schema_vals = $schema_fields = array(); // Build the SQL statement to recreate the data. for ($i = 0; $i < $i_num_fields; $i++) { // Oracle uses uppercase - we use lowercase $str_val = $row[strtolower($ary_name[$i])]; if (preg_match('#char|text|bool|raw|clob#i', $ary_type[$i])) { $str_quote = ''; $str_empty = "''"; $str_val = sanitize_data_oracle($str_val); } else if (preg_match('#date|timestamp#i', $ary_type[$i])) { if (empty($str_val)) { $str_quote = ''; } else { $str_quote = "'"; } } else { $str_quote = ''; $str_empty = 'NULL'; } if (empty($str_val) && $str_val !== '0') { $str_val = $str_empty; } $schema_vals[$i] = $str_quote . $str_val . $str_quote; $schema_fields[$i] = '"' . $ary_name[$i] . '"'; } // Take the ordered fields and their associated data and build it // into a valid sql statement to recreate that field in the data. $sql_data = "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ")\n/\n"; $this->flush($sql_data); } $db->sql_freeresult($result); } function write_start($prefix) { $sql_data = "--\n"; $sql_data .= "-- phpBB Backup Script\n"; $sql_data .= "-- Dump of tables for $prefix\n"; $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n"; $sql_data .= "--\n"; $this->flush($sql_data); } } // get how much space we allow for a chunk of data, very similar to phpMyAdmin's way of doing things ;-) (hey, we only do this for MySQL anyway :P) function get_usable_memory() { $val = trim(@ini_get('memory_limit')); if (preg_match('/(\\d+)([mkg]?)/i', $val, $regs)) { $memory_limit = (int) $regs[1]; switch ($regs[2]) { case 'k': case 'K': $memory_limit *= 1024; break; case 'm': case 'M': $memory_limit *= 1048576; break; case 'g': case 'G': $memory_limit *= 1073741824; break; } // how much memory PHP requires at the start of export (it is really a little less) if ($memory_limit > 6100000) { $memory_limit -= 6100000; } // allow us to consume half of the total memory available $memory_limit /= 2; } else { // set the buffer to 1M if we have no clue how much memory PHP will give us :P $memory_limit = 1048576; } return $memory_limit; } function sanitize_data_mssql($text) { $data = preg_split('/[\n\t\r\b\f]/', $text); preg_match_all('/[\n\t\r\b\f]/', $text, $matches); $val = array(); foreach ($data as $value) { if (strlen($value)) { $val[] = "'" . $value . "'"; } if (sizeof($matches[0])) { $val[] = 'char(' . ord(array_shift($matches[0])) . ')'; } } return implode('+', $val); } function sanitize_data_oracle($text) { // $data = preg_split('/[\0\n\t\r\b\f\'"\/\\\]/', $text); // preg_match_all('/[\0\n\t\r\b\f\'"\/\\\]/', $text, $matches); $data = preg_split('/[\0\b\f\'\/]/', $text); preg_match_all('/[\0\r\b\f\'\/]/', $text, $matches); $val = array(); foreach ($data as $value) { if (strlen($value)) { $val[] = "'" . $value . "'"; } if (sizeof($matches[0])) { $val[] = 'chr(' . ord(array_shift($matches[0])) . ')'; } } return implode('||', $val); } function sanitize_data_generic($text) { $data = preg_split('/[\n\t\r\b\f]/', $text); preg_match_all('/[\n\t\r\b\f]/', $text, $matches); $val = array(); foreach ($data as $value) { if (strlen($value)) { $val[] = "'" . $value . "'"; } if (sizeof($matches[0])) { $val[] = "'" . array_shift($matches[0]) . "'"; } } return implode('||', $val); } // modified from PHP.net function fgetd(&$fp, $delim, $read, $seek, $eof, $buffer = 8192) { $record = ''; $delim_len = strlen($delim); while (!$eof($fp)) { $pos = strpos($record, $delim); if ($pos === false) { $record .= $read($fp, $buffer); if ($eof($fp) && ($pos = strpos($record, $delim)) !== false) { $seek($fp, $pos + $delim_len - strlen($record), SEEK_CUR); return substr($record, 0, $pos); } } else { $seek($fp, $pos + $delim_len - strlen($record), SEEK_CUR); return substr($record, 0, $pos); } } return false; } function fgetd_seekless(&$fp, $delim, $read, $seek, $eof, $buffer = 8192) { static $array = array(); static $record = ''; if (!sizeof($array)) { while (!$eof($fp)) { if (strpos($record, $delim) !== false) { $array = explode($delim, $record); $record = array_pop($array); break; } else { $record .= $read($fp, $buffer); } } if ($eof($fp) && strpos($record, $delim) !== false) { $array = explode($delim, $record); $record = array_pop($array); } } if (sizeof($array)) { return array_shift($array); } return false; } acp_email.php000077700000024653151514745240007220 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_email { var $u_action; function main($id, $mode) { global $config, $db, $user, $auth, $template, $cache; global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix, $phpbb_dispatcher; $user->add_lang('acp/email'); $this->tpl_name = 'acp_email'; $this->page_title = 'ACP_MASS_EMAIL'; $form_key = 'acp_email'; add_form_key($form_key); // Set some vars $submit = (isset($_POST['submit'])) ? true : false; $error = array(); $usernames = request_var('usernames', '', true); $usernames = (!empty($usernames)) ? explode("\n", $usernames) : array(); $group_id = request_var('g', 0); $subject = utf8_normalize_nfc(request_var('subject', '', true)); $message = utf8_normalize_nfc(request_var('message', '', true)); // Do the job ... if ($submit) { // Error checking needs to go here ... if no subject and/or no message then skip // over the send and return to the form $use_queue = (isset($_POST['send_immediately'])) ? false : true; $priority = request_var('mail_priority_flag', MAIL_NORMAL_PRIORITY); if (!check_form_key($form_key)) { $error[] = $user->lang['FORM_INVALID']; } if (!$subject) { $error[] = $user->lang['NO_EMAIL_SUBJECT']; } if (!$message) { $error[] = $user->lang['NO_EMAIL_MESSAGE']; } if (!sizeof($error)) { if (!empty($usernames)) { // If giving usernames the admin is able to email inactive users too... $sql_ary = array( 'SELECT' => 'username, user_email, user_jabber, user_notify_type, user_lang', 'FROM' => array( USERS_TABLE => '', ), 'WHERE' => $db->sql_in_set('username_clean', array_map('utf8_clean_string', $usernames)) . ' AND user_allow_massemail = 1', 'ORDER_BY' => 'user_lang, user_notify_type', ); } else { if ($group_id) { $sql_ary = array( 'SELECT' => 'u.user_email, u.username, u.username_clean, u.user_lang, u.user_jabber, u.user_notify_type', 'FROM' => array( USERS_TABLE => 'u', USER_GROUP_TABLE => 'ug', ), 'WHERE' => 'ug.group_id = ' . $group_id . ' AND ug.user_pending = 0 AND u.user_id = ug.user_id AND u.user_allow_massemail = 1 AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')', 'ORDER_BY' => 'u.user_lang, u.user_notify_type', ); } else { $sql_ary = array( 'SELECT' => 'u.username, u.username_clean, u.user_email, u.user_jabber, u.user_lang, u.user_notify_type', 'FROM' => array( USERS_TABLE => 'u', ), 'WHERE' => 'u.user_allow_massemail = 1 AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')', 'ORDER_BY' => 'u.user_lang, u.user_notify_type', ); } // Mail banned or not if (!isset($_REQUEST['mail_banned_flag'])) { $sql_ary['WHERE'] .= ' AND (b.ban_id IS NULL OR b.ban_exclude = 1)'; $sql_ary['LEFT_JOIN'] = array( array( 'FROM' => array( BANLIST_TABLE => 'b', ), 'ON' => 'u.user_id = b.ban_userid', ), ); } } /** * Modify sql query to change the list of users the email is sent to * * @event core.acp_email_modify_sql * @var array sql_ary Array which is used to build the sql query * @since 3.1.2-RC1 */ $vars = array('sql_ary'); extract($phpbb_dispatcher->trigger_event('core.acp_email_modify_sql', compact($vars))); $sql = $db->sql_build_query('SELECT', $sql_ary); $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); if (!$row) { $db->sql_freeresult($result); trigger_error($user->lang['NO_USER'] . adm_back_link($this->u_action), E_USER_WARNING); } $i = $j = 0; // Send with BCC // Maximum number of bcc recipients $max_chunk_size = (int) $config['email_max_chunk_size']; $email_list = array(); $old_lang = $row['user_lang']; $old_notify_type = $row['user_notify_type']; do { if (($row['user_notify_type'] == NOTIFY_EMAIL && $row['user_email']) || ($row['user_notify_type'] == NOTIFY_IM && $row['user_jabber']) || ($row['user_notify_type'] == NOTIFY_BOTH && ($row['user_email'] || $row['user_jabber']))) { if ($i == $max_chunk_size || $row['user_lang'] != $old_lang || $row['user_notify_type'] != $old_notify_type) { $i = 0; if (sizeof($email_list)) { $j++; } $old_lang = $row['user_lang']; $old_notify_type = $row['user_notify_type']; } $email_list[$j][$i]['lang'] = $row['user_lang']; $email_list[$j][$i]['method'] = $row['user_notify_type']; $email_list[$j][$i]['email'] = $row['user_email']; $email_list[$j][$i]['name'] = $row['username']; $email_list[$j][$i]['jabber'] = $row['user_jabber']; $i++; } } while ($row = $db->sql_fetchrow($result)); $db->sql_freeresult($result); // Send the messages include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx); $messenger = new messenger($use_queue); $errored = false; $email_template = 'admin_send_email'; $template_data = array( 'CONTACT_EMAIL' => phpbb_get_board_contact($config, $phpEx), 'MESSAGE' => htmlspecialchars_decode($message), ); $generate_log_entry = true; /** * Modify email template data before the emails are sent * * @event core.acp_email_send_before * @var string email_template The template to be used for sending the email * @var string subject The subject of the email * @var array template_data Array with template data assigned to email template * @var bool generate_log_entry If false, no log entry will be created * @var array usernames Usernames which will be displayed in log entry, if it will be created * @var int group_id The group this email will be sent to * @var bool use_queue If true, email queue will be used for sending * @var int priority Priority of sent emails * @since 3.1.3-RC1 */ $vars = array( 'email_template', 'subject', 'template_data', 'generate_log_entry', 'usernames', 'group_id', 'use_queue', 'priority', ); extract($phpbb_dispatcher->trigger_event('core.acp_email_send_before', compact($vars))); for ($i = 0, $size = sizeof($email_list); $i < $size; $i++) { $used_lang = $email_list[$i][0]['lang']; $used_method = $email_list[$i][0]['method']; for ($j = 0, $list_size = sizeof($email_list[$i]); $j < $list_size; $j++) { $email_row = $email_list[$i][$j]; $messenger->{((sizeof($email_list[$i]) == 1) ? 'to' : 'bcc')}($email_row['email'], $email_row['name']); $messenger->im($email_row['jabber'], $email_row['name']); } $messenger->template($email_template, $used_lang); $messenger->anti_abuse_headers($config, $user); $messenger->subject(htmlspecialchars_decode($subject)); $messenger->set_mail_priority($priority); $messenger->assign_vars($template_data); if (!($messenger->send($used_method))) { $errored = true; } } unset($email_list); $messenger->save_queue(); if ($generate_log_entry) { if (!empty($usernames)) { add_log('admin', 'LOG_MASS_EMAIL', implode(', ', utf8_normalize_nfc($usernames))); } else { if ($group_id) { $group_name = get_group_name($group_id); } else { // Not great but the logging routine doesn't cope well with localising on the fly $group_name = $user->lang['ALL_USERS']; } add_log('admin', 'LOG_MASS_EMAIL', $group_name); } } if (!$errored) { $message = ($use_queue) ? $user->lang['EMAIL_SENT_QUEUE'] : $user->lang['EMAIL_SENT']; trigger_error($message . adm_back_link($this->u_action)); } else { $message = sprintf($user->lang['EMAIL_SEND_ERROR'], '<a href="' . append_sid("{$phpbb_admin_path}index.$phpEx", 'i=logs&mode=critical') . '">', '</a>'); trigger_error($message . adm_back_link($this->u_action), E_USER_WARNING); } } } // Exclude bots and guests... $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . " WHERE group_name IN ('BOTS', 'GUESTS')"; $result = $db->sql_query($sql); $exclude = array(); while ($row = $db->sql_fetchrow($result)) { $exclude[] = $row['group_id']; } $db->sql_freeresult($result); $select_list = '<option value="0"' . ((!$group_id) ? ' selected="selected"' : '') . '>' . $user->lang['ALL_USERS'] . '</option>'; $select_list .= group_select_options($group_id, $exclude); $s_priority_options = '<option value="' . MAIL_LOW_PRIORITY . '">' . $user->lang['MAIL_LOW_PRIORITY'] . '</option>'; $s_priority_options .= '<option value="' . MAIL_NORMAL_PRIORITY . '" selected="selected">' . $user->lang['MAIL_NORMAL_PRIORITY'] . '</option>'; $s_priority_options .= '<option value="' . MAIL_HIGH_PRIORITY . '">' . $user->lang['MAIL_HIGH_PRIORITY'] . '</option>'; $template_data = array( 'S_WARNING' => (sizeof($error)) ? true : false, 'WARNING_MSG' => (sizeof($error)) ? implode('<br />', $error) : '', 'U_ACTION' => $this->u_action, 'S_GROUP_OPTIONS' => $select_list, 'USERNAMES' => implode("\n", $usernames), 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=acp_email&field=usernames'), 'SUBJECT' => $subject, 'MESSAGE' => $message, 'S_PRIORITY_OPTIONS' => $s_priority_options, ); /** * Modify custom email template data before we display the form * * @event core.acp_email_display * @var array template_data Array with template data assigned to email template * @var array exclude Array with groups which are excluded from group selection * @var array usernames Usernames which will be displayed in form * * @since 3.1.4-RC1 */ $vars = array('template_data', 'exclude', 'usernames'); extract($phpbb_dispatcher->trigger_event('core.acp_email_display', compact($vars))); $template->assign_vars($template_data); } } acp_board.php000077700000155412151514745240007216 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @todo add cron intervals to server settings? (database_gc, queue_interval, session_gc, search_gc, cache_gc, warnings_gc) */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_board { var $u_action; var $new_config = array(); function main($id, $mode) { global $db, $user, $auth, $template; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; global $cache, $phpbb_container, $phpbb_dispatcher; $user->add_lang('acp/board'); $action = request_var('action', ''); $submit = (isset($_POST['submit']) || isset($_POST['allow_quick_reply_enable'])) ? true : false; $form_key = 'acp_board'; add_form_key($form_key); /** * Validation types are: * string, int, bool, * script_path (absolute path in url - beginning with / and no trailing slash), * rpath (relative), rwpath (realtive, writable), path (relative path, but able to escape the root), wpath (writable) */ switch ($mode) { case 'settings': $display_vars = array( 'title' => 'ACP_BOARD_SETTINGS', 'vars' => array( 'legend1' => 'ACP_BOARD_SETTINGS', 'sitename' => array('lang' => 'SITE_NAME', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => false), 'site_desc' => array('lang' => 'SITE_DESC', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => false), 'site_home_url' => array('lang' => 'SITE_HOME_URL', 'validate' => 'string', 'type' => 'url:40:255', 'explain' => true), 'site_home_text' => array('lang' => 'SITE_HOME_TEXT', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), 'board_index_text' => array('lang' => 'BOARD_INDEX_TEXT', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), 'board_disable' => array('lang' => 'DISABLE_BOARD', 'validate' => 'bool', 'type' => 'custom', 'method' => 'board_disable', 'explain' => true), 'board_disable_msg' => false, 'default_lang' => array('lang' => 'DEFAULT_LANGUAGE', 'validate' => 'lang', 'type' => 'select', 'function' => 'language_select', 'params' => array('{CONFIG_VALUE}'), 'explain' => false), 'default_dateformat' => array('lang' => 'DEFAULT_DATE_FORMAT', 'validate' => 'string', 'type' => 'custom', 'method' => 'dateformat_select', 'explain' => true), 'board_timezone' => array('lang' => 'SYSTEM_TIMEZONE', 'validate' => 'timezone', 'type' => 'custom', 'method' => 'timezone_select', 'explain' => true), 'legend2' => 'BOARD_STYLE', 'default_style' => array('lang' => 'DEFAULT_STYLE', 'validate' => 'int', 'type' => 'select', 'function' => 'style_select', 'params' => array('{CONFIG_VALUE}', false), 'explain' => true), 'guest_style' => array('lang' => 'GUEST_STYLE', 'validate' => 'int', 'type' => 'select', 'function' => 'style_select', 'params' => array($this->guest_style_get(), false), 'explain' => true), 'override_user_style' => array('lang' => 'OVERRIDE_STYLE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'legend3' => 'WARNINGS', 'warnings_expire_days' => array('lang' => 'WARNINGS_EXPIRE', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']), 'legend4' => 'ACP_SUBMIT_CHANGES', ) ); break; case 'features': $display_vars = array( 'title' => 'ACP_BOARD_FEATURES', 'vars' => array( 'legend1' => 'ACP_BOARD_FEATURES', 'allow_privmsg' => array('lang' => 'BOARD_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_topic_notify' => array('lang' => 'ALLOW_TOPIC_NOTIFY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_forum_notify' => array('lang' => 'ALLOW_FORUM_NOTIFY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_namechange' => array('lang' => 'ALLOW_NAME_CHANGE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_attachments' => array('lang' => 'ALLOW_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_pm_attach' => array('lang' => 'ALLOW_PM_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_pm_report' => array('lang' => 'ALLOW_PM_REPORT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_bbcode' => array('lang' => 'ALLOW_BBCODE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_smilies' => array('lang' => 'ALLOW_SMILIES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_sig' => array('lang' => 'ALLOW_SIG', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_nocensors' => array('lang' => 'ALLOW_NO_CENSORS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_bookmarks' => array('lang' => 'ALLOW_BOOKMARKS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_birthdays' => array('lang' => 'ALLOW_BIRTHDAYS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'display_last_subject' => array('lang' => 'DISPLAY_LAST_SUBJECT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_quick_reply' => array('lang' => 'ALLOW_QUICK_REPLY', 'validate' => 'bool', 'type' => 'custom', 'method' => 'quick_reply', 'explain' => true), 'legend2' => 'ACP_LOAD_SETTINGS', 'load_birthdays' => array('lang' => 'YES_BIRTHDAYS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'load_moderators' => array('lang' => 'YES_MODERATORS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_jumpbox' => array('lang' => 'YES_JUMPBOX', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_cpf_memberlist' => array('lang' => 'LOAD_CPF_MEMBERLIST', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_cpf_pm' => array('lang' => 'LOAD_CPF_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_cpf_viewprofile' => array('lang' => 'LOAD_CPF_VIEWPROFILE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_cpf_viewtopic' => array('lang' => 'LOAD_CPF_VIEWTOPIC', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'legend3' => 'ACP_SUBMIT_CHANGES', ) ); break; case 'avatar': $phpbb_avatar_manager = $phpbb_container->get('avatar.manager'); $avatar_drivers = $phpbb_avatar_manager->get_all_drivers(); $avatar_vars = array(); foreach ($avatar_drivers as $current_driver) { $driver = $phpbb_avatar_manager->get_driver($current_driver, false); /* * First grab the settings for enabling/disabling the avatar * driver and afterwards grab additional settings the driver * might have. */ $avatar_vars += $phpbb_avatar_manager->get_avatar_settings($driver); $avatar_vars += $driver->prepare_form_acp($user); } $display_vars = array( 'title' => 'ACP_AVATAR_SETTINGS', 'vars' => array( 'legend1' => 'ACP_AVATAR_SETTINGS', 'avatar_min_width' => array('lang' => 'MIN_AVATAR_SIZE', 'validate' => 'int:0', 'type' => false, 'method' => false, 'explain' => false), 'avatar_min_height' => array('lang' => 'MIN_AVATAR_SIZE', 'validate' => 'int:0', 'type' => false, 'method' => false, 'explain' => false), 'avatar_max_width' => array('lang' => 'MAX_AVATAR_SIZE', 'validate' => 'int:0', 'type' => false, 'method' => false, 'explain' => false), 'avatar_max_height' => array('lang' => 'MAX_AVATAR_SIZE', 'validate' => 'int:0', 'type' => false, 'method' => false, 'explain' => false), 'allow_avatar' => array('lang' => 'ALLOW_AVATARS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'avatar_min' => array('lang' => 'MIN_AVATAR_SIZE', 'validate' => 'int:0', 'type' => 'dimension:0', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'avatar_max' => array('lang' => 'MAX_AVATAR_SIZE', 'validate' => 'int:0', 'type' => 'dimension:0', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), ) ); if (!empty($avatar_vars)) { $display_vars['vars'] += $avatar_vars; } break; case 'message': $display_vars = array( 'title' => 'ACP_MESSAGE_SETTINGS', 'lang' => 'ucp', 'vars' => array( 'legend1' => 'GENERAL_SETTINGS', 'allow_privmsg' => array('lang' => 'BOARD_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'pm_max_boxes' => array('lang' => 'BOXES_MAX', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true), 'pm_max_msgs' => array('lang' => 'BOXES_LIMIT', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true), 'full_folder_action' => array('lang' => 'FULL_FOLDER_ACTION', 'validate' => 'int', 'type' => 'select', 'method' => 'full_folder_select', 'explain' => true), 'pm_edit_time' => array('lang' => 'PM_EDIT_TIME', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']), 'pm_max_recipients' => array('lang' => 'PM_MAX_RECIPIENTS', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true), 'legend2' => 'GENERAL_OPTIONS', 'allow_mass_pm' => array('lang' => 'ALLOW_MASS_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'auth_bbcode_pm' => array('lang' => 'ALLOW_BBCODE_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'auth_smilies_pm' => array('lang' => 'ALLOW_SMILIES_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_pm_attach' => array('lang' => 'ALLOW_PM_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_sig_pm' => array('lang' => 'ALLOW_SIG_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'print_pm' => array('lang' => 'ALLOW_PRINT_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'forward_pm' => array('lang' => 'ALLOW_FORWARD_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'auth_img_pm' => array('lang' => 'ALLOW_IMG_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'auth_flash_pm' => array('lang' => 'ALLOW_FLASH_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'enable_pm_icons' => array('lang' => 'ENABLE_PM_ICONS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'legend3' => 'ACP_SUBMIT_CHANGES', ) ); break; case 'post': $display_vars = array( 'title' => 'ACP_POST_SETTINGS', 'vars' => array( 'legend1' => 'GENERAL_OPTIONS', 'allow_topic_notify' => array('lang' => 'ALLOW_TOPIC_NOTIFY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_forum_notify' => array('lang' => 'ALLOW_FORUM_NOTIFY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_bbcode' => array('lang' => 'ALLOW_BBCODE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_post_flash' => array('lang' => 'ALLOW_POST_FLASH', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_smilies' => array('lang' => 'ALLOW_SMILIES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_post_links' => array('lang' => 'ALLOW_POST_LINKS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_nocensors' => array('lang' => 'ALLOW_NO_CENSORS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_bookmarks' => array('lang' => 'ALLOW_BOOKMARKS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'enable_post_confirm' => array('lang' => 'VISUAL_CONFIRM_POST', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_quick_reply' => array('lang' => 'ALLOW_QUICK_REPLY', 'validate' => 'bool', 'type' => 'custom', 'method' => 'quick_reply', 'explain' => true), 'legend2' => 'POSTING', 'bump_type' => false, 'edit_time' => array('lang' => 'EDIT_TIME', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']), 'delete_time' => array('lang' => 'DELETE_TIME', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']), 'display_last_edited' => array('lang' => 'DISPLAY_LAST_EDITED', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'flood_interval' => array('lang' => 'FLOOD_INTERVAL', 'validate' => 'int:0:9999999999', 'type' => 'number:0:9999999999', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']), 'bump_interval' => array('lang' => 'BUMP_INTERVAL', 'validate' => 'int:0', 'type' => 'custom', 'method' => 'bump_interval', 'explain' => true), 'topics_per_page' => array('lang' => 'TOPICS_PER_PAGE', 'validate' => 'int:1:9999', 'type' => 'number:1:9999', 'explain' => false), 'posts_per_page' => array('lang' => 'POSTS_PER_PAGE', 'validate' => 'int:1:9999', 'type' => 'number:1:9999', 'explain' => false), 'smilies_per_page' => array('lang' => 'SMILIES_PER_PAGE', 'validate' => 'int:1:9999', 'type' => 'number:1:9999', 'explain' => false), 'hot_threshold' => array('lang' => 'HOT_THRESHOLD', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true), 'max_poll_options' => array('lang' => 'MAX_POLL_OPTIONS', 'validate' => 'int:2:127', 'type' => 'number:2:127', 'explain' => false), 'max_post_chars' => array('lang' => 'CHAR_LIMIT', 'validate' => 'int:0:999999', 'type' => 'number:0:999999', 'explain' => true), 'min_post_chars' => array('lang' => 'MIN_CHAR_LIMIT', 'validate' => 'int:1:999999', 'type' => 'number:1:999999', 'explain' => true), 'max_post_smilies' => array('lang' => 'SMILIES_LIMIT', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true), 'max_post_urls' => array('lang' => 'MAX_POST_URLS', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true), 'max_post_font_size' => array('lang' => 'MAX_POST_FONT_SIZE', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' %'), 'max_quote_depth' => array('lang' => 'QUOTE_DEPTH_LIMIT', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true), 'max_post_img_width' => array('lang' => 'MAX_POST_IMG_WIDTH', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'max_post_img_height' => array('lang' => 'MAX_POST_IMG_HEIGHT', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'legend3' => 'ACP_SUBMIT_CHANGES', ) ); break; case 'signature': $display_vars = array( 'title' => 'ACP_SIGNATURE_SETTINGS', 'vars' => array( 'legend1' => 'GENERAL_OPTIONS', 'allow_sig' => array('lang' => 'ALLOW_SIG', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_sig_bbcode' => array('lang' => 'ALLOW_SIG_BBCODE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_sig_img' => array('lang' => 'ALLOW_SIG_IMG', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_sig_flash' => array('lang' => 'ALLOW_SIG_FLASH', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_sig_smilies' => array('lang' => 'ALLOW_SIG_SMILIES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_sig_links' => array('lang' => 'ALLOW_SIG_LINKS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'legend2' => 'GENERAL_SETTINGS', 'max_sig_chars' => array('lang' => 'MAX_SIG_LENGTH', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true), 'max_sig_urls' => array('lang' => 'MAX_SIG_URLS', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true), 'max_sig_font_size' => array('lang' => 'MAX_SIG_FONT_SIZE', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' %'), 'max_sig_smilies' => array('lang' => 'MAX_SIG_SMILIES', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true), 'max_sig_img_width' => array('lang' => 'MAX_SIG_IMG_WIDTH', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'max_sig_img_height' => array('lang' => 'MAX_SIG_IMG_HEIGHT', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'legend3' => 'ACP_SUBMIT_CHANGES', ) ); break; case 'registration': $display_vars = array( 'title' => 'ACP_REGISTER_SETTINGS', 'vars' => array( 'legend1' => 'GENERAL_SETTINGS', 'max_name_chars' => array('lang' => 'USERNAME_LENGTH', 'validate' => 'int:8:180', 'type' => false, 'method' => false, 'explain' => false,), 'max_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:8:255', 'type' => false, 'method' => false, 'explain' => false,), 'require_activation' => array('lang' => 'ACC_ACTIVATION', 'validate' => 'int', 'type' => 'select', 'method' => 'select_acc_activation', 'explain' => true), 'new_member_post_limit' => array('lang' => 'NEW_MEMBER_POST_LIMIT', 'validate' => 'int:0:255', 'type' => 'number:0:255', 'explain' => true, 'append' => ' ' . $user->lang['POSTS']), 'new_member_group_default'=> array('lang' => 'NEW_MEMBER_GROUP_DEFAULT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'min_name_chars' => array('lang' => 'USERNAME_LENGTH', 'validate' => 'int:1', 'type' => 'custom:5:180', 'method' => 'username_length', 'explain' => true), 'min_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:1', 'type' => 'custom', 'method' => 'password_length', 'explain' => true), 'allow_name_chars' => array('lang' => 'USERNAME_CHARS', 'validate' => 'string', 'type' => 'select', 'method' => 'select_username_chars', 'explain' => true), 'pass_complex' => array('lang' => 'PASSWORD_TYPE', 'validate' => 'string', 'type' => 'select', 'method' => 'select_password_chars', 'explain' => true), 'chg_passforce' => array('lang' => 'FORCE_PASS_CHANGE', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']), 'legend2' => 'GENERAL_OPTIONS', 'allow_namechange' => array('lang' => 'ALLOW_NAME_CHANGE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_emailreuse' => array('lang' => 'ALLOW_EMAIL_REUSE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'enable_confirm' => array('lang' => 'VISUAL_CONFIRM_REG', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'max_login_attempts' => array('lang' => 'MAX_LOGIN_ATTEMPTS', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => true), 'max_reg_attempts' => array('lang' => 'REG_LIMIT', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true), 'legend3' => 'COPPA', 'coppa_enable' => array('lang' => 'ENABLE_COPPA', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'coppa_mail' => array('lang' => 'COPPA_MAIL', 'validate' => 'string', 'type' => 'textarea:5:40', 'explain' => true), 'coppa_fax' => array('lang' => 'COPPA_FAX', 'validate' => 'string', 'type' => 'text:25:100', 'explain' => false), 'legend4' => 'ACP_SUBMIT_CHANGES', ) ); break; case 'feed': $display_vars = array( 'title' => 'ACP_FEED_MANAGEMENT', 'vars' => array( 'legend1' => 'ACP_FEED_GENERAL', 'feed_enable' => array('lang' => 'ACP_FEED_ENABLE', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'feed_item_statistics' => array('lang' => 'ACP_FEED_ITEM_STATISTICS', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true), 'feed_http_auth' => array('lang' => 'ACP_FEED_HTTP_AUTH', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true), 'legend2' => 'ACP_FEED_POST_BASED', 'feed_limit_post' => array('lang' => 'ACP_FEED_LIMIT', 'validate' => 'int:5:9999', 'type' => 'number:5:9999', 'explain' => true), 'feed_overall' => array('lang' => 'ACP_FEED_OVERALL', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'feed_forum' => array('lang' => 'ACP_FEED_FORUM', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'feed_topic' => array('lang' => 'ACP_FEED_TOPIC', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'legend3' => 'ACP_FEED_TOPIC_BASED', 'feed_limit_topic' => array('lang' => 'ACP_FEED_LIMIT', 'validate' => 'int:5:9999', 'type' => 'number:5:9999', 'explain' => true), 'feed_topics_new' => array('lang' => 'ACP_FEED_TOPICS_NEW', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'feed_topics_active' => array('lang' => 'ACP_FEED_TOPICS_ACTIVE', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'feed_news_id' => array('lang' => 'ACP_FEED_NEWS', 'validate' => 'string', 'type' => 'custom', 'method' => 'select_news_forums', 'explain' => true), 'legend4' => 'ACP_FEED_SETTINGS_OTHER', 'feed_overall_forums' => array('lang' => 'ACP_FEED_OVERALL_FORUMS', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true ), 'feed_exclude_id' => array('lang' => 'ACP_FEED_EXCLUDE_ID', 'validate' => 'string', 'type' => 'custom', 'method' => 'select_exclude_forums', 'explain' => true), ) ); break; case 'cookie': $display_vars = array( 'title' => 'ACP_COOKIE_SETTINGS', 'vars' => array( 'legend1' => 'ACP_COOKIE_SETTINGS', 'cookie_domain' => array('lang' => 'COOKIE_DOMAIN', 'validate' => 'string', 'type' => 'text::255', 'explain' => false), 'cookie_name' => array('lang' => 'COOKIE_NAME', 'validate' => 'string', 'type' => 'text::16', 'explain' => false), 'cookie_path' => array('lang' => 'COOKIE_PATH', 'validate' => 'string', 'type' => 'text::255', 'explain' => false), 'cookie_secure' => array('lang' => 'COOKIE_SECURE', 'validate' => 'bool', 'type' => 'radio:disabled_enabled', 'explain' => true), ) ); break; case 'load': $display_vars = array( 'title' => 'ACP_LOAD_SETTINGS', 'vars' => array( 'legend1' => 'GENERAL_SETTINGS', 'limit_load' => array('lang' => 'LIMIT_LOAD', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true), 'session_length' => array('lang' => 'SESSION_LENGTH', 'validate' => 'int:60:9999999999', 'type' => 'number:60:9999999999', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']), 'active_sessions' => array('lang' => 'LIMIT_SESSIONS', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true), 'load_online_time' => array('lang' => 'ONLINE_LENGTH', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']), 'read_notification_expire_days' => array('lang' => 'READ_NOTIFICATION_EXPIRE_DAYS', 'validate' => 'int:0', 'type' => 'number:0', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']), 'legend2' => 'GENERAL_OPTIONS', 'load_notifications' => array('lang' => 'LOAD_NOTIFICATIONS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'load_db_track' => array('lang' => 'YES_POST_MARKING', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'load_db_lastread' => array('lang' => 'YES_READ_MARKING', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'load_anon_lastread' => array('lang' => 'YES_ANON_READ_MARKING', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'load_online' => array('lang' => 'YES_ONLINE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'load_online_guests' => array('lang' => 'YES_ONLINE_GUESTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'load_onlinetrack' => array('lang' => 'YES_ONLINE_TRACK', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'load_birthdays' => array('lang' => 'YES_BIRTHDAYS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'load_unreads_search' => array('lang' => 'YES_UNREAD_SEARCH', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_moderators' => array('lang' => 'YES_MODERATORS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_jumpbox' => array('lang' => 'YES_JUMPBOX', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_user_activity' => array('lang' => 'LOAD_USER_ACTIVITY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'load_tplcompile' => array('lang' => 'RECOMPILE_STYLES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_cdn' => array('lang' => 'ALLOW_CDN', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_live_searches' => array('lang' => 'ALLOW_LIVE_SEARCHES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'legend3' => 'CUSTOM_PROFILE_FIELDS', 'load_cpf_memberlist' => array('lang' => 'LOAD_CPF_MEMBERLIST', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_cpf_pm' => array('lang' => 'LOAD_CPF_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_cpf_viewprofile' => array('lang' => 'LOAD_CPF_VIEWPROFILE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_cpf_viewtopic' => array('lang' => 'LOAD_CPF_VIEWTOPIC', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'legend4' => 'ACP_SUBMIT_CHANGES', ) ); break; case 'auth': $display_vars = array( 'title' => 'ACP_AUTH_SETTINGS', 'vars' => array( 'legend1' => 'ACP_AUTH_SETTINGS', 'auth_method' => array('lang' => 'AUTH_METHOD', 'validate' => 'string', 'type' => 'select:1:toggable', 'method' => 'select_auth_method', 'explain' => false), ) ); break; case 'server': $display_vars = array( 'title' => 'ACP_SERVER_SETTINGS', 'vars' => array( 'legend1' => 'ACP_SERVER_SETTINGS', 'gzip_compress' => array('lang' => 'ENABLE_GZIP', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'use_system_cron' => array('lang' => 'USE_SYSTEM_CRON', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'legend2' => 'PATH_SETTINGS', 'enable_mod_rewrite' => array('lang' => 'MOD_REWRITE_ENABLE', 'validate' => 'bool', 'type' => 'custom', 'method' => 'enable_mod_rewrite', 'explain' => true), 'smilies_path' => array('lang' => 'SMILIES_PATH', 'validate' => 'rpath', 'type' => 'text:20:255', 'explain' => true), 'icons_path' => array('lang' => 'ICONS_PATH', 'validate' => 'rpath', 'type' => 'text:20:255', 'explain' => true), 'upload_icons_path' => array('lang' => 'UPLOAD_ICONS_PATH', 'validate' => 'rpath', 'type' => 'text:20:255', 'explain' => true), 'ranks_path' => array('lang' => 'RANKS_PATH', 'validate' => 'rpath', 'type' => 'text:20:255', 'explain' => true), 'legend3' => 'SERVER_URL_SETTINGS', 'force_server_vars' => array('lang' => 'FORCE_SERVER_VARS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'server_protocol' => array('lang' => 'SERVER_PROTOCOL', 'validate' => 'string', 'type' => 'text:10:10', 'explain' => true), 'server_name' => array('lang' => 'SERVER_NAME', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), 'server_port' => array('lang' => 'SERVER_PORT', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true), 'script_path' => array('lang' => 'SCRIPT_PATH', 'validate' => 'script_path', 'type' => 'text::255', 'explain' => true), 'legend4' => 'ACP_SUBMIT_CHANGES', ) ); break; case 'security': $display_vars = array( 'title' => 'ACP_SECURITY_SETTINGS', 'vars' => array( 'legend1' => 'ACP_SECURITY_SETTINGS', 'allow_autologin' => array('lang' => 'ALLOW_AUTOLOGIN', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_password_reset' => array('lang' => 'ALLOW_PASSWORD_RESET', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'max_autologin_time' => array('lang' => 'AUTOLOGIN_LENGTH', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']), 'ip_check' => array('lang' => 'IP_VALID', 'validate' => 'int', 'type' => 'custom', 'method' => 'select_ip_check', 'explain' => true), 'browser_check' => array('lang' => 'BROWSER_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'forwarded_for_check' => array('lang' => 'FORWARDED_FOR_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'referer_validation' => array('lang' => 'REFERRER_VALID', 'validate' => 'int:0:3','type' => 'custom', 'method' => 'select_ref_check', 'explain' => true), 'check_dnsbl' => array('lang' => 'CHECK_DNSBL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'email_check_mx' => array('lang' => 'EMAIL_CHECK_MX', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'max_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:8:255', 'type' => false, 'method' => false, 'explain' => false,), 'min_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:1', 'type' => 'custom', 'method' => 'password_length', 'explain' => true), 'pass_complex' => array('lang' => 'PASSWORD_TYPE', 'validate' => 'string', 'type' => 'select', 'method' => 'select_password_chars', 'explain' => true), 'chg_passforce' => array('lang' => 'FORCE_PASS_CHANGE', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']), 'max_login_attempts' => array('lang' => 'MAX_LOGIN_ATTEMPTS', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => true), 'ip_login_limit_max' => array('lang' => 'IP_LOGIN_LIMIT_MAX', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => true), 'ip_login_limit_time' => array('lang' => 'IP_LOGIN_LIMIT_TIME', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']), 'ip_login_limit_use_forwarded' => array('lang' => 'IP_LOGIN_LIMIT_USE_FORWARDED', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'tpl_allow_php' => array('lang' => 'TPL_ALLOW_PHP', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'form_token_lifetime' => array('lang' => 'FORM_TIME_MAX', 'validate' => 'int:-1:99999', 'type' => 'number:-1:99999', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']), 'form_token_sid_guests' => array('lang' => 'FORM_SID_GUESTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), ) ); break; case 'email': $display_vars = array( 'title' => 'ACP_EMAIL_SETTINGS', 'vars' => array( 'legend1' => 'GENERAL_SETTINGS', 'email_enable' => array('lang' => 'ENABLE_EMAIL', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true), 'board_email_form' => array('lang' => 'BOARD_EMAIL_FORM', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true), 'email_function_name' => array('lang' => 'EMAIL_FUNCTION_NAME', 'validate' => 'string', 'type' => 'text:20:50', 'explain' => true), 'email_package_size' => array('lang' => 'EMAIL_PACKAGE_SIZE', 'validate' => 'int:0', 'type' => 'number:0:99999', 'explain' => true), 'board_contact' => array('lang' => 'CONTACT_EMAIL', 'validate' => 'email', 'type' => 'email:25:100', 'explain' => true), 'board_contact_name' => array('lang' => 'CONTACT_EMAIL_NAME', 'validate' => 'string', 'type' => 'text:25:50', 'explain' => true), 'board_email' => array('lang' => 'ADMIN_EMAIL', 'validate' => 'email', 'type' => 'email:25:100', 'explain' => true), 'board_email_sig' => array('lang' => 'EMAIL_SIG', 'validate' => 'string', 'type' => 'textarea:5:30', 'explain' => true), 'board_hide_emails' => array('lang' => 'BOARD_HIDE_EMAILS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'legend2' => 'SMTP_SETTINGS', 'smtp_delivery' => array('lang' => 'USE_SMTP', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'smtp_host' => array('lang' => 'SMTP_SERVER', 'validate' => 'string', 'type' => 'text:25:50', 'explain' => false), 'smtp_port' => array('lang' => 'SMTP_PORT', 'validate' => 'int:0:99999', 'type' => 'number:0:99999', 'explain' => true), 'smtp_auth_method' => array('lang' => 'SMTP_AUTH_METHOD', 'validate' => 'string', 'type' => 'select', 'method' => 'mail_auth_select', 'explain' => true), 'smtp_username' => array('lang' => 'SMTP_USERNAME', 'validate' => 'string', 'type' => 'text:25:255', 'explain' => true), 'smtp_password' => array('lang' => 'SMTP_PASSWORD', 'validate' => 'string', 'type' => 'password:25:255', 'explain' => true), 'legend3' => 'ACP_SUBMIT_CHANGES', ) ); break; default: trigger_error('NO_MODE', E_USER_ERROR); break; } /** * Event to add and/or modify acp_board configurations * * @event core.acp_board_config_edit_add * @var array display_vars Array of config values to display and process * @var string mode Mode of the config page we are displaying * @var boolean submit Do we display the form or process the submission * @since 3.1.0-a4 */ $vars = array('display_vars', 'mode', 'submit'); extract($phpbb_dispatcher->trigger_event('core.acp_board_config_edit_add', compact($vars))); if (isset($display_vars['lang'])) { $user->add_lang($display_vars['lang']); } $this->new_config = $config; $cfg_array = (isset($_REQUEST['config'])) ? utf8_normalize_nfc(request_var('config', array('' => ''), true)) : $this->new_config; $error = array(); // We validate the complete config if wished validate_config_vars($display_vars['vars'], $cfg_array, $error); if ($submit && !check_form_key($form_key)) { $error[] = $user->lang['FORM_INVALID']; } // Do not write values if there is an error if (sizeof($error)) { $submit = false; } // We go through the display_vars to make sure no one is trying to set variables he/she is not allowed to... foreach ($display_vars['vars'] as $config_name => $data) { if (!isset($cfg_array[$config_name]) || strpos($config_name, 'legend') !== false) { continue; } if ($config_name == 'auth_method' || $config_name == 'feed_news_id' || $config_name == 'feed_exclude_id') { continue; } if ($config_name == 'guest_style') { if (isset($cfg_array[$config_name])) { $this->guest_style_set($cfg_array[$config_name]); } continue; } $this->new_config[$config_name] = $config_value = $cfg_array[$config_name]; if ($config_name == 'email_function_name') { $this->new_config['email_function_name'] = trim(str_replace(array('(', ')'), array('', ''), $this->new_config['email_function_name'])); $this->new_config['email_function_name'] = (empty($this->new_config['email_function_name']) || !function_exists($this->new_config['email_function_name'])) ? 'mail' : $this->new_config['email_function_name']; $config_value = $this->new_config['email_function_name']; } if ($submit) { if (strpos($data['type'], 'password') === 0 && $config_value === '********') { // Do not update password fields if the content is ********, // because that is the password replacement we use to not // send the password to the output continue; } set_config($config_name, $config_value); if ($config_name == 'allow_quick_reply' && isset($_POST['allow_quick_reply_enable'])) { enable_bitfield_column_flag(FORUMS_TABLE, 'forum_flags', log(FORUM_FLAG_QUICK_REPLY, 2)); } } } // Store news and exclude ids if ($mode == 'feed' && $submit) { $cache->destroy('_feed_news_forum_ids'); $cache->destroy('_feed_excluded_forum_ids'); $this->store_feed_forums(FORUM_OPTION_FEED_NEWS, 'feed_news_id'); $this->store_feed_forums(FORUM_OPTION_FEED_EXCLUDE, 'feed_exclude_id'); } if ($mode == 'auth') { // Retrieve a list of auth plugins and check their config values $auth_providers = $phpbb_container->get('auth.provider_collection'); $updated_auth_settings = false; $old_auth_config = array(); foreach ($auth_providers as $provider) { /** @var \phpbb\auth\provider\provider_interface $provider */ if ($fields = $provider->acp()) { // Check if we need to create config fields for this plugin and save config when submit was pressed foreach ($fields as $field) { if (!isset($config[$field])) { set_config($field, ''); } if (!isset($cfg_array[$field]) || strpos($field, 'legend') !== false) { continue; } if (substr($field, -9) === '_password' && $cfg_array[$field] === '********') { // Do not update password fields if the content is ********, // because that is the password replacement we use to not // send the password to the output continue; } $old_auth_config[$field] = $this->new_config[$field]; $config_value = $cfg_array[$field]; $this->new_config[$field] = $config_value; if ($submit) { $updated_auth_settings = true; set_config($field, $config_value); } } } unset($fields); } if ($submit && (($cfg_array['auth_method'] != $this->new_config['auth_method']) || $updated_auth_settings)) { $method = basename($cfg_array['auth_method']); if (array_key_exists('auth.provider.' . $method, $auth_providers)) { $provider = $auth_providers['auth.provider.' . $method]; if ($error = $provider->init()) { foreach ($old_auth_config as $config_name => $config_value) { set_config($config_name, $config_value); } trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING); } set_config('auth_method', basename($cfg_array['auth_method'])); } else { trigger_error('NO_AUTH_PLUGIN', E_USER_ERROR); } } } if ($submit) { add_log('admin', 'LOG_CONFIG_' . strtoupper($mode)); $message = $user->lang('CONFIG_UPDATED'); $message_type = E_USER_NOTICE; if (!$config['email_enable'] && in_array($mode, array('email', 'registration')) && in_array($config['require_activation'], array(USER_ACTIVATION_SELF, USER_ACTIVATION_ADMIN))) { $message .= '<br /><br />' . $user->lang('ACC_ACTIVATION_WARNING'); $message_type = E_USER_WARNING; } trigger_error($message . adm_back_link($this->u_action), $message_type); } $this->tpl_name = 'acp_board'; $this->page_title = $display_vars['title']; $template->assign_vars(array( 'L_TITLE' => $user->lang[$display_vars['title']], 'L_TITLE_EXPLAIN' => $user->lang[$display_vars['title'] . '_EXPLAIN'], 'S_ERROR' => (sizeof($error)) ? true : false, 'ERROR_MSG' => implode('<br />', $error), 'U_ACTION' => $this->u_action) ); // Output relevant page foreach ($display_vars['vars'] as $config_key => $vars) { if (!is_array($vars) && strpos($config_key, 'legend') === false) { continue; } if (strpos($config_key, 'legend') !== false) { $template->assign_block_vars('options', array( 'S_LEGEND' => true, 'LEGEND' => (isset($user->lang[$vars])) ? $user->lang[$vars] : $vars) ); continue; } $type = explode(':', $vars['type']); $l_explain = ''; if ($vars['explain'] && isset($vars['lang_explain'])) { $l_explain = (isset($user->lang[$vars['lang_explain']])) ? $user->lang[$vars['lang_explain']] : $vars['lang_explain']; } else if ($vars['explain']) { $l_explain = (isset($user->lang[$vars['lang'] . '_EXPLAIN'])) ? $user->lang[$vars['lang'] . '_EXPLAIN'] : ''; } $content = build_cfg_template($type, $config_key, $this->new_config, $config_key, $vars); if (empty($content)) { continue; } $template->assign_block_vars('options', array( 'KEY' => $config_key, 'TITLE' => (isset($user->lang[$vars['lang']])) ? $user->lang[$vars['lang']] : $vars['lang'], 'S_EXPLAIN' => $vars['explain'], 'TITLE_EXPLAIN' => $l_explain, 'CONTENT' => $content, ) ); unset($display_vars['vars'][$config_key]); } if ($mode == 'auth') { $template->assign_var('S_AUTH', true); foreach ($auth_providers as $provider) { $auth_tpl = $provider->get_acp_template($this->new_config); if ($auth_tpl) { if (array_key_exists('BLOCK_VAR_NAME', $auth_tpl)) { foreach ($auth_tpl['BLOCK_VARS'] as $block_vars) { $template->assign_block_vars($auth_tpl['BLOCK_VAR_NAME'], $block_vars); } } $template->assign_vars($auth_tpl['TEMPLATE_VARS']); $template->assign_block_vars('auth_tpl', array( 'TEMPLATE_FILE' => $auth_tpl['TEMPLATE_FILE'], )); } } } } /** * Select auth method */ function select_auth_method($selected_method, $key = '') { global $phpbb_root_path, $phpEx, $phpbb_container; $auth_plugins = array(); $auth_providers = $phpbb_container->get('auth.provider_collection'); foreach ($auth_providers as $key => $value) { if (!($value instanceof \phpbb\auth\provider\provider_interface)) { continue; } $auth_plugins[] = str_replace('auth.provider.', '', $key); } sort($auth_plugins); $auth_select = ''; foreach ($auth_plugins as $method) { $selected = ($selected_method == $method) ? ' selected="selected"' : ''; $auth_select .= "<option value=\"$method\"$selected data-toggle-setting=\"#auth_{$method}_settings\">" . ucfirst($method) . '</option>'; } return $auth_select; } /** * Select mail authentication method */ function mail_auth_select($selected_method, $key = '') { global $user; $auth_methods = array('PLAIN', 'LOGIN', 'CRAM-MD5', 'DIGEST-MD5', 'POP-BEFORE-SMTP'); $s_smtp_auth_options = ''; foreach ($auth_methods as $method) { $s_smtp_auth_options .= '<option value="' . $method . '"' . (($selected_method == $method) ? ' selected="selected"' : '') . '>' . $user->lang['SMTP_' . str_replace('-', '_', $method)] . '</option>'; } return $s_smtp_auth_options; } /** * Select full folder action */ function full_folder_select($value, $key = '') { global $user; return '<option value="1"' . (($value == 1) ? ' selected="selected"' : '') . '>' . $user->lang['DELETE_OLDEST_MESSAGES'] . '</option><option value="2"' . (($value == 2) ? ' selected="selected"' : '') . '>' . $user->lang['HOLD_NEW_MESSAGES_SHORT'] . '</option>'; } /** * Select ip validation */ function select_ip_check($value, $key = '') { $radio_ary = array(4 => 'ALL', 3 => 'CLASS_C', 2 => 'CLASS_B', 0 => 'NO_IP_VALIDATION'); return h_radio('config[ip_check]', $radio_ary, $value, $key); } /** * Select referer validation */ function select_ref_check($value, $key = '') { $radio_ary = array(REFERER_VALIDATE_PATH => 'REF_PATH', REFERER_VALIDATE_HOST => 'REF_HOST', REFERER_VALIDATE_NONE => 'NO_REF_VALIDATION'); return h_radio('config[referer_validation]', $radio_ary, $value, $key); } /** * Select account activation method */ function select_acc_activation($selected_value, $value) { global $user, $config; $act_ary = array( 'ACC_DISABLE' => array(true, USER_ACTIVATION_DISABLE), 'ACC_NONE' => array(true, USER_ACTIVATION_NONE), 'ACC_USER' => array($config['email_enable'], USER_ACTIVATION_SELF), 'ACC_ADMIN' => array($config['email_enable'], USER_ACTIVATION_ADMIN), ); $act_options = ''; foreach ($act_ary as $key => $data) { list($available, $value) = $data; $selected = ($selected_value == $value) ? ' selected="selected"' : ''; $class = (!$available) ? ' class="disabled-option"' : ''; $act_options .= '<option value="' . $value . '"' . $selected . $class . '>' . $user->lang($key) . '</option>'; } return $act_options; } /** * Maximum/Minimum username length */ function username_length($value, $key = '') { global $user; return '<input id="' . $key . '" type="number" size="3" maxlength="3" min="1" max="999" name="config[min_name_chars]" value="' . $value . '" /> ' . $user->lang['MIN_CHARS'] . ' <input type="number" size="3" maxlength="3" min="8" max="180" name="config[max_name_chars]" value="' . $this->new_config['max_name_chars'] . '" /> ' . $user->lang['MAX_CHARS']; } /** * Allowed chars in usernames */ function select_username_chars($selected_value, $key) { global $user; $user_char_ary = array('USERNAME_CHARS_ANY', 'USERNAME_ALPHA_ONLY', 'USERNAME_ALPHA_SPACERS', 'USERNAME_LETTER_NUM', 'USERNAME_LETTER_NUM_SPACERS', 'USERNAME_ASCII'); $user_char_options = ''; foreach ($user_char_ary as $user_type) { $selected = ($selected_value == $user_type) ? ' selected="selected"' : ''; $user_char_options .= '<option value="' . $user_type . '"' . $selected . '>' . $user->lang[$user_type] . '</option>'; } return $user_char_options; } /** * Maximum/Minimum password length */ function password_length($value, $key) { global $user; return '<input id="' . $key . '" type="number" size="3" maxlength="3" min="1" max="999" name="config[min_pass_chars]" value="' . $value . '" /> ' . $user->lang['MIN_CHARS'] . ' <input type="number" size="3" maxlength="3" min="8" max="255" name="config[max_pass_chars]" value="' . $this->new_config['max_pass_chars'] . '" /> ' . $user->lang['MAX_CHARS']; } /** * Required chars in passwords */ function select_password_chars($selected_value, $key) { global $user; $pass_type_ary = array('PASS_TYPE_ANY', 'PASS_TYPE_CASE', 'PASS_TYPE_ALPHA', 'PASS_TYPE_SYMBOL'); $pass_char_options = ''; foreach ($pass_type_ary as $pass_type) { $selected = ($selected_value == $pass_type) ? ' selected="selected"' : ''; $pass_char_options .= '<option value="' . $pass_type . '"' . $selected . '>' . $user->lang[$pass_type] . '</option>'; } return $pass_char_options; } /** * Select bump interval */ function bump_interval($value, $key) { global $user; $s_bump_type = ''; $types = array('m' => 'MINUTES', 'h' => 'HOURS', 'd' => 'DAYS'); foreach ($types as $type => $lang) { $selected = ($this->new_config['bump_type'] == $type) ? ' selected="selected"' : ''; $s_bump_type .= '<option value="' . $type . '"' . $selected . '>' . $user->lang[$lang] . '</option>'; } return '<input id="' . $key . '" type="text" size="3" maxlength="4" name="config[bump_interval]" value="' . $value . '" /> <select name="config[bump_type]">' . $s_bump_type . '</select>'; } /** * Board disable option and message */ function board_disable($value, $key) { global $user; $radio_ary = array(1 => 'YES', 0 => 'NO'); return h_radio('config[board_disable]', $radio_ary, $value) . '<br /><input id="' . $key . '" type="text" name="config[board_disable_msg]" maxlength="255" size="40" value="' . $this->new_config['board_disable_msg'] . '" />'; } /** * Global quick reply enable/disable setting and button to enable in all forums */ function quick_reply($value, $key) { global $user; $radio_ary = array(1 => 'YES', 0 => 'NO'); return h_radio('config[allow_quick_reply]', $radio_ary, $value) . '<br /><br /><input class="button2" type="submit" id="' . $key . '_enable" name="' . $key . '_enable" value="' . $user->lang['ALLOW_QUICK_REPLY_BUTTON'] . '" />'; } /** * Select guest timezone */ function timezone_select($value, $key) { global $template, $user; $timezone_select = phpbb_timezone_select($template, $user, $value, true); return '<select name="config[' . $key . ']" id="' . $key . '">' . $timezone_select . '</select>'; } /** * Get guest style */ public function guest_style_get() { global $db; $sql = 'SELECT user_style FROM ' . USERS_TABLE . ' WHERE user_id = ' . ANONYMOUS; $result = $db->sql_query($sql); $style = (int) $db->sql_fetchfield('user_style'); $db->sql_freeresult($result); return $style; } /** * Set guest style * * @param int $style_id The style ID */ public function guest_style_set($style_id) { global $db; $sql = 'UPDATE ' . USERS_TABLE . ' SET user_style = ' . (int) $style_id . ' WHERE user_id = ' . ANONYMOUS; $db->sql_query($sql); } /** * Select default dateformat */ function dateformat_select($value, $key) { global $user, $config; // Let the format_date function operate with the acp values $old_tz = $user->timezone; try { $user->timezone = new DateTimeZone($config['board_timezone']); } catch (\Exception $e) { // If the board timezone is invalid, we just use the users timezone. } $dateformat_options = ''; foreach ($user->lang['dateformats'] as $format => $null) { $dateformat_options .= '<option value="' . $format . '"' . (($format == $value) ? ' selected="selected"' : '') . '>'; $dateformat_options .= $user->format_date(time(), $format, false) . ((strpos($format, '|') !== false) ? $user->lang['VARIANT_DATE_SEPARATOR'] . $user->format_date(time(), $format, true) : ''); $dateformat_options .= '</option>'; } $dateformat_options .= '<option value="custom"'; if (!isset($user->lang['dateformats'][$value])) { $dateformat_options .= ' selected="selected"'; } $dateformat_options .= '>' . $user->lang['CUSTOM_DATEFORMAT'] . '</option>'; // Reset users date options $user->timezone = $old_tz; return "<select name=\"dateoptions\" id=\"dateoptions\" onchange=\"if (this.value == 'custom') { document.getElementById('" . addslashes($key) . "').value = '" . addslashes($value) . "'; } else { document.getElementById('" . addslashes($key) . "').value = this.value; }\">$dateformat_options</select> <input type=\"text\" name=\"config[$key]\" id=\"$key\" value=\"$value\" maxlength=\"30\" />"; } /** * Select multiple forums */ function select_news_forums($value, $key) { global $user, $config; $forum_list = make_forum_select(false, false, true, true, true, false, true); // Build forum options $s_forum_options = '<select id="' . $key . '" name="' . $key . '[]" multiple="multiple">'; foreach ($forum_list as $f_id => $f_row) { $f_row['selected'] = phpbb_optionget(FORUM_OPTION_FEED_NEWS, $f_row['forum_options']); $s_forum_options .= '<option value="' . $f_id . '"' . (($f_row['selected']) ? ' selected="selected"' : '') . (($f_row['disabled']) ? ' disabled="disabled" class="disabled-option"' : '') . '>' . $f_row['padding'] . $f_row['forum_name'] . '</option>'; } $s_forum_options .= '</select>'; return $s_forum_options; } function select_exclude_forums($value, $key) { global $user, $config; $forum_list = make_forum_select(false, false, true, true, true, false, true); // Build forum options $s_forum_options = '<select id="' . $key . '" name="' . $key . '[]" multiple="multiple">'; foreach ($forum_list as $f_id => $f_row) { $f_row['selected'] = phpbb_optionget(FORUM_OPTION_FEED_EXCLUDE, $f_row['forum_options']); $s_forum_options .= '<option value="' . $f_id . '"' . (($f_row['selected']) ? ' selected="selected"' : '') . (($f_row['disabled']) ? ' disabled="disabled" class="disabled-option"' : '') . '>' . $f_row['padding'] . $f_row['forum_name'] . '</option>'; } $s_forum_options .= '</select>'; return $s_forum_options; } function store_feed_forums($option, $key) { global $db, $cache; // Get key $values = request_var($key, array(0 => 0)); // Empty option bit for all forums $sql = 'UPDATE ' . FORUMS_TABLE . ' SET forum_options = forum_options - ' . (1 << $option) . ' WHERE ' . $db->sql_bit_and('forum_options', $option, '<> 0'); $db->sql_query($sql); // Already emptied for all... if (sizeof($values)) { // Set for selected forums $sql = 'UPDATE ' . FORUMS_TABLE . ' SET forum_options = forum_options + ' . (1 << $option) . ' WHERE ' . $db->sql_in_set('forum_id', $values); $db->sql_query($sql); } // Empty sql cache for forums table because options changed $cache->destroy('sql', FORUMS_TABLE); } /** * Option to enable/disable removal of 'app.php' from URLs * * Note that if mod_rewrite is on, URLs without app.php will still work, * but any paths generated by the controller helper url() method will not * contain app.php. * * @param int $value The current config value * @param string $key The config key * @return string The HTML for the form field */ function enable_mod_rewrite($value, $key) { global $user, $config; // Determine whether mod_rewrite is enabled on the server // NOTE: This only works on Apache servers on which PHP is NOT // installed as CGI. In that case, there is no way for PHP to // determine whether or not the Apache module is enabled. // // To be clear on the value of $mod_rewite: // null = Cannot determine whether or not the server has mod_rewrite // enabled // false = Can determine that the server does NOT have mod_rewrite // enabled // true = Can determine that the server DOES have mod_rewrite_enabled $mod_rewrite = null; if (function_exists('apache_get_modules')) { $mod_rewrite = (bool) in_array('mod_rewrite', apache_get_modules()); } // If $message is false, mod_rewrite is enabled. // Otherwise, it is not and we need to: // 1) disable the form field // 2) make sure the config value is set to 0 // 3) append the message to the return $value = ($mod_rewrite === false) ? 0 : $value; $message = $mod_rewrite === null ? 'MOD_REWRITE_INFORMATION_UNAVAILABLE' : ($mod_rewrite === false ? 'MOD_REWRITE_DISABLED' : false); // Let's do some friendly HTML injection if we want to disable the // form field because h_radio() has no pretty way of doing so $field_name = 'config[enable_mod_rewrite]' . ($message === 'MOD_REWRITE_DISABLED' ? '" disabled="disabled' : ''); return h_radio($field_name, array(1 => 'YES', 0 => 'NO'), $value) . ($message !== false ? '<br /><span>' . $user->lang($message) . '</span>' : ''); } } acp_permission_roles.php000077700000041574151514745240011526 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_permission_roles { var $u_action; protected $auth_admin; function main($id, $mode) { global $db, $user, $auth, $template, $cache, $phpbb_container; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; global $request; include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx); include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx); $this->auth_admin = new auth_admin(); $user->add_lang('acp/permissions'); add_permission_language(); $this->tpl_name = 'acp_permission_roles'; $submit = (isset($_POST['submit'])) ? true : false; $role_id = request_var('role_id', 0); $action = request_var('action', ''); $action = (isset($_POST['add'])) ? 'add' : $action; $form_name = 'acp_permissions'; add_form_key($form_name); if (!$role_id && in_array($action, array('remove', 'edit', 'move_up', 'move_down'))) { trigger_error($user->lang['NO_ROLE_SELECTED'] . adm_back_link($this->u_action), E_USER_WARNING); } switch ($mode) { case 'admin_roles': $permission_type = 'a_'; $this->page_title = 'ACP_ADMIN_ROLES'; break; case 'user_roles': $permission_type = 'u_'; $this->page_title = 'ACP_USER_ROLES'; break; case 'mod_roles': $permission_type = 'm_'; $this->page_title = 'ACP_MOD_ROLES'; break; case 'forum_roles': $permission_type = 'f_'; $this->page_title = 'ACP_FORUM_ROLES'; break; default: trigger_error('NO_MODE', E_USER_ERROR); break; } $template->assign_vars(array( 'L_TITLE' => $user->lang[$this->page_title], 'L_EXPLAIN' => $user->lang[$this->page_title . '_EXPLAIN']) ); // Take action... admin submitted something if ($submit || $action == 'remove') { switch ($action) { case 'remove': $sql = 'SELECT * FROM ' . ACL_ROLES_TABLE . ' WHERE role_id = ' . $role_id; $result = $db->sql_query($sql); $role_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$role_row) { trigger_error($user->lang['NO_ROLE_SELECTED'] . adm_back_link($this->u_action), E_USER_WARNING); } if (confirm_box(true)) { $this->remove_role($role_id, $permission_type); $role_name = (!empty($user->lang[$role_row['role_name']])) ? $user->lang[$role_row['role_name']] : $role_row['role_name']; add_log('admin', 'LOG_' . strtoupper($permission_type) . 'ROLE_REMOVED', $role_name); trigger_error($user->lang['ROLE_DELETED'] . adm_back_link($this->u_action)); } else { confirm_box(false, 'DELETE_ROLE', build_hidden_fields(array( 'i' => $id, 'mode' => $mode, 'role_id' => $role_id, 'action' => $action, ))); } break; case 'edit': // Get role we edit $sql = 'SELECT * FROM ' . ACL_ROLES_TABLE . ' WHERE role_id = ' . $role_id; $result = $db->sql_query($sql); $role_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$role_row) { trigger_error($user->lang['NO_ROLE_SELECTED'] . adm_back_link($this->u_action), E_USER_WARNING); } // no break; case 'add': if (!check_form_key($form_name)) { trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING); } $role_name = utf8_normalize_nfc(request_var('role_name', '', true)); $role_description = utf8_normalize_nfc(request_var('role_description', '', true)); $auth_settings = request_var('setting', array('' => 0)); if (!$role_name) { trigger_error($user->lang['NO_ROLE_NAME_SPECIFIED'] . adm_back_link($this->u_action), E_USER_WARNING); } if (utf8_strlen($role_description) > 4000) { trigger_error($user->lang['ROLE_DESCRIPTION_LONG'] . adm_back_link($this->u_action), E_USER_WARNING); } // if we add/edit a role we check the name to be unique among the settings... $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . " WHERE role_type = '" . $db->sql_escape($permission_type) . "' AND role_name = '" . $db->sql_escape($role_name) . "'"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); // Make sure we only print out the error if we add the role or change it's name if ($row && ($mode == 'add' || ($mode == 'edit' && $role_row['role_name'] != $role_name))) { trigger_error(sprintf($user->lang['ROLE_NAME_ALREADY_EXIST'], $role_name) . adm_back_link($this->u_action), E_USER_WARNING); } $sql_ary = array( 'role_name' => (string) $role_name, 'role_description' => (string) $role_description, 'role_type' => (string) $permission_type, ); if ($action == 'edit') { $sql = 'UPDATE ' . ACL_ROLES_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE role_id = ' . $role_id; $db->sql_query($sql); } else { // Get maximum role order for inserting a new role... $sql = 'SELECT MAX(role_order) as max_order FROM ' . ACL_ROLES_TABLE . " WHERE role_type = '" . $db->sql_escape($permission_type) . "'"; $result = $db->sql_query($sql); $max_order = (int) $db->sql_fetchfield('max_order'); $db->sql_freeresult($result); $sql_ary['role_order'] = $max_order + 1; $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); $db->sql_query($sql); $role_id = $db->sql_nextid(); } // Now add the auth settings $this->auth_admin->acl_set_role($role_id, $auth_settings); $role_name = (!empty($user->lang[$role_name])) ? $user->lang[$role_name] : $role_name; add_log('admin', 'LOG_' . strtoupper($permission_type) . 'ROLE_' . strtoupper($action), $role_name); trigger_error($user->lang['ROLE_' . strtoupper($action) . '_SUCCESS'] . adm_back_link($this->u_action)); break; } } // Display screens switch ($action) { case 'add': $options_from = request_var('options_from', 0); $role_row = array( 'role_name' => utf8_normalize_nfc(request_var('role_name', '', true)), 'role_description' => utf8_normalize_nfc(request_var('role_description', '', true)), 'role_type' => $permission_type, ); if ($options_from) { $sql = 'SELECT p.auth_option_id, p.auth_setting, o.auth_option FROM ' . ACL_ROLES_DATA_TABLE . ' p, ' . ACL_OPTIONS_TABLE . ' o WHERE o.auth_option_id = p.auth_option_id AND p.role_id = ' . $options_from . ' ORDER BY p.auth_option_id'; $result = $db->sql_query($sql); $auth_options = array(); while ($row = $db->sql_fetchrow($result)) { $auth_options[$row['auth_option']] = $row['auth_setting']; } $db->sql_freeresult($result); } else { $sql = 'SELECT auth_option_id, auth_option FROM ' . ACL_OPTIONS_TABLE . " WHERE auth_option " . $db->sql_like_expression($permission_type . $db->get_any_char()) . " AND auth_option <> '{$permission_type}' ORDER BY auth_option_id"; $result = $db->sql_query($sql); $auth_options = array(); while ($row = $db->sql_fetchrow($result)) { $auth_options[$row['auth_option']] = ACL_NO; } $db->sql_freeresult($result); } // no break; case 'edit': if ($action == 'edit') { $sql = 'SELECT * FROM ' . ACL_ROLES_TABLE . ' WHERE role_id = ' . $role_id; $result = $db->sql_query($sql); $role_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); $sql = 'SELECT p.auth_option_id, p.auth_setting, o.auth_option FROM ' . ACL_ROLES_DATA_TABLE . ' p, ' . ACL_OPTIONS_TABLE . ' o WHERE o.auth_option_id = p.auth_option_id AND p.role_id = ' . $role_id . ' ORDER BY p.auth_option_id'; $result = $db->sql_query($sql); $auth_options = array(); while ($row = $db->sql_fetchrow($result)) { $auth_options[$row['auth_option']] = $row['auth_setting']; } $db->sql_freeresult($result); } if (!$role_row) { trigger_error($user->lang['NO_ROLE_SELECTED'] . adm_back_link($this->u_action), E_USER_WARNING); } $phpbb_permissions = $phpbb_container->get('acl.permissions'); $template->assign_vars(array( 'S_EDIT' => true, 'U_ACTION' => $this->u_action . "&action={$action}&role_id={$role_id}", 'U_BACK' => $this->u_action, 'ROLE_NAME' => $role_row['role_name'], 'ROLE_DESCRIPTION' => $role_row['role_description'], 'L_ACL_TYPE' => $phpbb_permissions->get_type_lang($permission_type), )); // We need to fill the auth options array with ACL_NO options ;) $sql = 'SELECT auth_option_id, auth_option FROM ' . ACL_OPTIONS_TABLE . " WHERE auth_option " . $db->sql_like_expression($permission_type . $db->get_any_char()) . " AND auth_option <> '{$permission_type}' ORDER BY auth_option_id"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { if (!isset($auth_options[$row['auth_option']])) { $auth_options[$row['auth_option']] = ACL_NO; } } $db->sql_freeresult($result); // Unset global permission option unset($auth_options[$permission_type]); // Display auth options $this->display_auth_options($auth_options); // Get users/groups/forums using this preset... if ($action == 'edit') { $hold_ary = $this->auth_admin->get_role_mask($role_id); if (sizeof($hold_ary)) { $role_name = (!empty($user->lang[$role_row['role_name']])) ? $user->lang[$role_row['role_name']] : $role_row['role_name']; $template->assign_vars(array( 'S_DISPLAY_ROLE_MASK' => true, 'L_ROLE_ASSIGNED_TO' => sprintf($user->lang['ROLE_ASSIGNED_TO'], $role_name)) ); $this->auth_admin->display_role_mask($hold_ary); } } return; break; case 'move_up': case 'move_down': $sql = 'SELECT role_order FROM ' . ACL_ROLES_TABLE . " WHERE role_id = $role_id"; $result = $db->sql_query($sql); $order = $db->sql_fetchfield('role_order'); $db->sql_freeresult($result); if ($order === false || ($order == 0 && $action == 'move_up')) { break; } $order = (int) $order; $order_total = $order * 2 + (($action == 'move_up') ? -1 : 1); $sql = 'UPDATE ' . ACL_ROLES_TABLE . ' SET role_order = ' . $order_total . " - role_order WHERE role_type = '" . $db->sql_escape($permission_type) . "' AND role_order IN ($order, " . (($action == 'move_up') ? $order - 1 : $order + 1) . ')'; $db->sql_query($sql); if ($request->is_ajax()) { $json_response = new \phpbb\json_response; $json_response->send(array( 'success' => (bool) $db->sql_affectedrows(), )); } break; } // By default, check that role_order is valid and fix it if necessary $sql = 'SELECT role_id, role_order FROM ' . ACL_ROLES_TABLE . " WHERE role_type = '" . $db->sql_escape($permission_type) . "' ORDER BY role_order ASC"; $result = $db->sql_query($sql); if ($row = $db->sql_fetchrow($result)) { $order = 0; do { $order++; if ($row['role_order'] != $order) { $db->sql_query('UPDATE ' . ACL_ROLES_TABLE . " SET role_order = $order WHERE role_id = {$row['role_id']}"); } } while ($row = $db->sql_fetchrow($result)); } $db->sql_freeresult($result); // Display assigned items? $display_item = request_var('display_item', 0); // Select existing roles $sql = 'SELECT * FROM ' . ACL_ROLES_TABLE . " WHERE role_type = '" . $db->sql_escape($permission_type) . "' ORDER BY role_order ASC"; $result = $db->sql_query($sql); $s_role_options = ''; while ($row = $db->sql_fetchrow($result)) { $role_name = (!empty($user->lang[$row['role_name']])) ? $user->lang[$row['role_name']] : $row['role_name']; $template->assign_block_vars('roles', array( 'ROLE_NAME' => $role_name, 'ROLE_DESCRIPTION' => (!empty($user->lang[$row['role_description']])) ? $user->lang[$row['role_description']] : nl2br($row['role_description']), 'U_EDIT' => $this->u_action . '&action=edit&role_id=' . $row['role_id'], 'U_REMOVE' => $this->u_action . '&action=remove&role_id=' . $row['role_id'], 'U_MOVE_UP' => $this->u_action . '&action=move_up&role_id=' . $row['role_id'], 'U_MOVE_DOWN' => $this->u_action . '&action=move_down&role_id=' . $row['role_id'], 'U_DISPLAY_ITEMS' => ($row['role_id'] == $display_item) ? '' : $this->u_action . '&display_item=' . $row['role_id'] . '#assigned_to') ); $s_role_options .= '<option value="' . $row['role_id'] . '">' . $role_name . '</option>'; if ($display_item == $row['role_id']) { $template->assign_vars(array( 'L_ROLE_ASSIGNED_TO' => sprintf($user->lang['ROLE_ASSIGNED_TO'], $role_name)) ); } } $db->sql_freeresult($result); $template->assign_vars(array( 'S_ROLE_OPTIONS' => $s_role_options) ); if ($display_item) { $template->assign_vars(array( 'S_DISPLAY_ROLE_MASK' => true) ); $hold_ary = $this->auth_admin->get_role_mask($display_item); $this->auth_admin->display_role_mask($hold_ary); } } /** * Display permission settings able to be set */ function display_auth_options($auth_options) { global $template, $user, $phpbb_container; $phpbb_permissions = $phpbb_container->get('acl.permissions'); $content_array = $categories = array(); $key_sort_array = array(0); $auth_options = array(0 => $auth_options); // Making use of auth_admin method here (we do not really want to change two similar code fragments) $this->auth_admin->build_permission_array($auth_options, $content_array, $categories, $key_sort_array); $content_array = $content_array[0]; $template->assign_var('S_NUM_PERM_COLS', sizeof($categories)); // Assign to template foreach ($content_array as $cat => $cat_array) { $template->assign_block_vars('auth', array( 'CAT_NAME' => $phpbb_permissions->get_category_lang($cat), 'S_YES' => ($cat_array['S_YES'] && !$cat_array['S_NEVER'] && !$cat_array['S_NO']) ? true : false, 'S_NEVER' => ($cat_array['S_NEVER'] && !$cat_array['S_YES'] && !$cat_array['S_NO']) ? true : false, 'S_NO' => ($cat_array['S_NO'] && !$cat_array['S_NEVER'] && !$cat_array['S_YES']) ? true : false) ); foreach ($cat_array['permissions'] as $permission => $allowed) { $template->assign_block_vars('auth.mask', array( 'S_YES' => ($allowed == ACL_YES) ? true : false, 'S_NEVER' => ($allowed == ACL_NEVER) ? true : false, 'S_NO' => ($allowed == ACL_NO) ? true : false, 'FIELD_NAME' => $permission, 'PERMISSION' => $phpbb_permissions->get_permission_lang($permission), )); } } } /** * Remove role */ function remove_role($role_id, $permission_type) { global $db; // Get complete auth array $sql = 'SELECT auth_option, auth_option_id FROM ' . ACL_OPTIONS_TABLE . " WHERE auth_option " . $db->sql_like_expression($permission_type . $db->get_any_char()); $result = $db->sql_query($sql); $auth_settings = array(); while ($row = $db->sql_fetchrow($result)) { $auth_settings[$row['auth_option']] = ACL_NO; } $db->sql_freeresult($result); // Get the role auth settings we need to re-set... $sql = 'SELECT o.auth_option, r.auth_setting FROM ' . ACL_ROLES_DATA_TABLE . ' r, ' . ACL_OPTIONS_TABLE . ' o WHERE o.auth_option_id = r.auth_option_id AND r.role_id = ' . $role_id; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $auth_settings[$row['auth_option']] = $row['auth_setting']; } $db->sql_freeresult($result); // Get role assignments $hold_ary = $this->auth_admin->get_role_mask($role_id); // Re-assign permissions foreach ($hold_ary as $forum_id => $forum_ary) { if (isset($forum_ary['users'])) { $this->auth_admin->acl_set('user', $forum_id, $forum_ary['users'], $auth_settings, 0, false); } if (isset($forum_ary['groups'])) { $this->auth_admin->acl_set('group', $forum_id, $forum_ary['groups'], $auth_settings, 0, false); } } // Remove role from users and groups just to be sure (happens through acl_set) $sql = 'DELETE FROM ' . ACL_USERS_TABLE . ' WHERE auth_role_id = ' . $role_id; $db->sql_query($sql); $sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . ' WHERE auth_role_id = ' . $role_id; $db->sql_query($sql); // Remove role data and role $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' WHERE role_id = ' . $role_id; $db->sql_query($sql); $sql = 'DELETE FROM ' . ACL_ROLES_TABLE . ' WHERE role_id = ' . $role_id; $db->sql_query($sql); $this->auth_admin->acl_clear_prefetch(); } } acp_logs.php000077700000012533151514745240007067 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_logs { var $u_action; function main($id, $mode) { global $db, $user, $auth, $template, $cache, $phpbb_container; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; global $request; $user->add_lang('mcp'); // Set up general vars $action = request_var('action', ''); $forum_id = request_var('f', 0); $topic_id = request_var('t', 0); $start = request_var('start', 0); $deletemark = $request->variable('delmarked', false, false, \phpbb\request\request_interface::POST); $deleteall = $request->variable('delall', false, false, \phpbb\request\request_interface::POST); $marked = request_var('mark', array(0)); // Sort keys $sort_days = request_var('st', 0); $sort_key = request_var('sk', 't'); $sort_dir = request_var('sd', 'd'); $this->tpl_name = 'acp_logs'; $this->log_type = constant('LOG_' . strtoupper($mode)); $pagination = $phpbb_container->get('pagination'); // Delete entries if requested and able if (($deletemark || $deleteall) && $auth->acl_get('a_clearlogs')) { if (confirm_box(true)) { $conditions = array(); if ($deletemark && sizeof($marked)) { $conditions['log_id'] = array('IN' => $marked); } if ($deleteall) { if ($sort_days) { $conditions['log_time'] = array('>=', time() - ($sort_days * 86400)); } $keywords = utf8_normalize_nfc(request_var('keywords', '', true)); $conditions['keywords'] = $keywords; } $phpbb_log = $phpbb_container->get('log'); $phpbb_log->delete($mode, $conditions); } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 'f' => $forum_id, 'start' => $start, 'delmarked' => $deletemark, 'delall' => $deleteall, 'mark' => $marked, 'st' => $sort_days, 'sk' => $sort_key, 'sd' => $sort_dir, 'i' => $id, 'mode' => $mode, 'action' => $action)) ); } } // Sorting $limit_days = array(0 => $user->lang['ALL_ENTRIES'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']); $sort_by_text = array('u' => $user->lang['SORT_USERNAME'], 't' => $user->lang['SORT_DATE'], 'i' => $user->lang['SORT_IP'], 'o' => $user->lang['SORT_ACTION']); $sort_by_sql = array('u' => 'u.username_clean', 't' => 'l.log_time', 'i' => 'l.log_ip', 'o' => 'l.log_operation'); $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_where = ($sort_days) ? (time() - ($sort_days * 86400)) : 0; $sql_sort = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC'); $keywords = utf8_normalize_nfc(request_var('keywords', '', true)); $keywords_param = !empty($keywords) ? '&keywords=' . urlencode(htmlspecialchars_decode($keywords)) : ''; $l_title = $user->lang['ACP_' . strtoupper($mode) . '_LOGS']; $l_title_explain = $user->lang['ACP_' . strtoupper($mode) . '_LOGS_EXPLAIN']; $this->page_title = $l_title; // Define forum list if we're looking @ mod logs if ($mode == 'mod') { $forum_box = '<option value="0">' . $user->lang['ALL_FORUMS'] . '</option>' . make_forum_select($forum_id); $template->assign_vars(array( 'S_SHOW_FORUMS' => true, 'S_FORUM_BOX' => $forum_box) ); } // Grab log data $log_data = array(); $log_count = 0; $start = view_log($mode, $log_data, $log_count, $config['topics_per_page'], $start, $forum_id, 0, 0, $sql_where, $sql_sort, $keywords); $base_url = $this->u_action . "&$u_sort_param$keywords_param"; $pagination->generate_template_pagination($base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); $template->assign_vars(array( 'L_TITLE' => $l_title, 'L_EXPLAIN' => $l_title_explain, 'U_ACTION' => $this->u_action . "&$u_sort_param$keywords_param&start=$start", 'S_LIMIT_DAYS' => $s_limit_days, 'S_SORT_KEY' => $s_sort_key, 'S_SORT_DIR' => $s_sort_dir, 'S_CLEARLOGS' => $auth->acl_get('a_clearlogs'), 'S_KEYWORDS' => $keywords, ) ); foreach ($log_data as $row) { $data = array(); $checks = array('viewtopic', 'viewlogs', 'viewforum'); foreach ($checks as $check) { if (isset($row[$check]) && $row[$check]) { $data[] = '<a href="' . $row[$check] . '">' . $user->lang['LOGVIEW_' . strtoupper($check)] . '</a>'; } } $template->assign_block_vars('log', array( 'USERNAME' => $row['username_full'], 'REPORTEE_USERNAME' => ($row['reportee_username'] && $row['user_id'] != $row['reportee_id']) ? $row['reportee_username_full'] : '', 'IP' => $row['ip'], 'DATE' => $user->format_date($row['time']), 'ACTION' => $row['action'], 'DATA' => (sizeof($data)) ? implode(' | ', $data) : '', 'ID' => $row['id'], ) ); } } } acp_bots.php000077700000030256151514745240007074 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_bots { var $u_action; function main($id, $mode) { global $config, $db, $user, $auth, $template, $cache, $request; global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix; $action = request_var('action', ''); $submit = (isset($_POST['submit'])) ? true : false; $mark = request_var('mark', array(0)); $bot_id = request_var('id', 0); if (isset($_POST['add'])) { $action = 'add'; } $error = array(); $user->add_lang('acp/bots'); $this->tpl_name = 'acp_bots'; $this->page_title = 'ACP_BOTS'; $form_key = 'acp_bots'; add_form_key($form_key); if ($submit && !check_form_key($form_key)) { $error[] = $user->lang['FORM_INVALID']; } // User wants to do something, how inconsiderate of them! switch ($action) { case 'activate': if ($bot_id || sizeof($mark)) { $sql_id = ($bot_id) ? " = $bot_id" : ' IN (' . implode(', ', $mark) . ')'; $sql = 'UPDATE ' . BOTS_TABLE . " SET bot_active = 1 WHERE bot_id $sql_id"; $db->sql_query($sql); } $cache->destroy('_bots'); break; case 'deactivate': if ($bot_id || sizeof($mark)) { $sql_id = ($bot_id) ? " = $bot_id" : ' IN (' . implode(', ', $mark) . ')'; $sql = 'UPDATE ' . BOTS_TABLE . " SET bot_active = 0 WHERE bot_id $sql_id"; $db->sql_query($sql); } $cache->destroy('_bots'); break; case 'delete': if ($bot_id || sizeof($mark)) { if (confirm_box(true)) { // We need to delete the relevant user, usergroup and bot entries ... $sql_id = ($bot_id) ? " = $bot_id" : ' IN (' . implode(', ', $mark) . ')'; $sql = 'SELECT bot_name, user_id FROM ' . BOTS_TABLE . " WHERE bot_id $sql_id"; $result = $db->sql_query($sql); $user_id_ary = $bot_name_ary = array(); while ($row = $db->sql_fetchrow($result)) { $user_id_ary[] = (int) $row['user_id']; $bot_name_ary[] = $row['bot_name']; } $db->sql_freeresult($result); $db->sql_transaction('begin'); $sql = 'DELETE FROM ' . BOTS_TABLE . " WHERE bot_id $sql_id"; $db->sql_query($sql); if (sizeof($user_id_ary)) { $_tables = array(USERS_TABLE, USER_GROUP_TABLE); foreach ($_tables as $table) { $sql = "DELETE FROM $table WHERE " . $db->sql_in_set('user_id', $user_id_ary); $db->sql_query($sql); } } $db->sql_transaction('commit'); $cache->destroy('_bots'); add_log('admin', 'LOG_BOT_DELETE', implode(', ', $bot_name_ary)); trigger_error($user->lang['BOT_DELETED'] . adm_back_link($this->u_action)); } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 'mark' => $mark, 'id' => $bot_id, 'mode' => $mode, 'action' => $action)) ); } } break; case 'edit': case 'add': include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx); $bot_row = array( 'bot_name' => utf8_normalize_nfc(request_var('bot_name', '', true)), 'bot_agent' => request_var('bot_agent', ''), 'bot_ip' => request_var('bot_ip', ''), 'bot_active' => request_var('bot_active', true), 'bot_lang' => request_var('bot_lang', $config['default_lang']), 'bot_style' => request_var('bot_style' , $config['default_style']), ); if ($submit) { if (!$bot_row['bot_agent'] && !$bot_row['bot_ip']) { $error[] = $user->lang['ERR_BOT_NO_MATCHES']; } if ($bot_row['bot_ip'] && !preg_match('#^[\d\.,:]+$#', $bot_row['bot_ip'])) { if (!$ip_list = gethostbynamel($bot_row['bot_ip'])) { $error[] = $user->lang['ERR_BOT_NO_IP']; } else { $bot_row['bot_ip'] = implode(',', $ip_list); } } $bot_row['bot_ip'] = str_replace(' ', '', $bot_row['bot_ip']); // Make sure the admin is not adding a bot with an user agent similar to his one if ($bot_row['bot_agent'] && substr($user->data['session_browser'], 0, 149) === substr($bot_row['bot_agent'], 0, 149)) { $error[] = $user->lang['ERR_BOT_AGENT_MATCHES_UA']; } $bot_name = false; if ($bot_id) { $sql = 'SELECT u.username_clean FROM ' . BOTS_TABLE . ' b, ' . USERS_TABLE . " u WHERE b.bot_id = $bot_id AND u.user_id = b.user_id"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$bot_row) { $error[] = $user->lang['NO_BOT']; } else { $bot_name = $row['username_clean']; } } if (!$this->validate_botname($bot_row['bot_name'], $bot_name)) { $error[] = $user->lang['BOT_NAME_TAKEN']; } if (!sizeof($error)) { // New bot? Create a new user and group entry if ($action == 'add') { $sql = 'SELECT group_id, group_colour FROM ' . GROUPS_TABLE . " WHERE group_name = 'BOTS' AND group_type = " . GROUP_SPECIAL; $result = $db->sql_query($sql); $group_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$group_row) { trigger_error($user->lang['NO_BOT_GROUP'] . adm_back_link($this->u_action . "&id=$bot_id&action=$action"), E_USER_WARNING); } $user_id = user_add(array( 'user_type' => (int) USER_IGNORE, 'group_id' => (int) $group_row['group_id'], 'username' => (string) $bot_row['bot_name'], 'user_regdate' => time(), 'user_password' => '', 'user_colour' => (string) $group_row['group_colour'], 'user_email' => '', 'user_lang' => (string) $bot_row['bot_lang'], 'user_style' => (int) $bot_row['bot_style'], 'user_allow_massemail' => 0, )); $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $db->sql_build_array('INSERT', array( 'user_id' => (int) $user_id, 'bot_name' => (string) $bot_row['bot_name'], 'bot_active' => (int) $bot_row['bot_active'], 'bot_agent' => (string) $bot_row['bot_agent'], 'bot_ip' => (string) $bot_row['bot_ip']) ); $db->sql_query($sql); $log = 'ADDED'; } else if ($bot_id) { $sql = 'SELECT user_id, bot_name FROM ' . BOTS_TABLE . " WHERE bot_id = $bot_id"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$row) { trigger_error($user->lang['NO_BOT'] . adm_back_link($this->u_action . "&id=$bot_id&action=$action"), E_USER_WARNING); } $sql_ary = array( 'user_style' => (int) $bot_row['bot_style'], 'user_lang' => (string) $bot_row['bot_lang'], ); if ($bot_row['bot_name'] !== $row['bot_name']) { $sql_ary['username'] = (string) $bot_row['bot_name']; $sql_ary['username_clean'] = (string) utf8_clean_string($bot_row['bot_name']); } $sql = 'UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " WHERE user_id = {$row['user_id']}"; $db->sql_query($sql); $sql = 'UPDATE ' . BOTS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', array( 'bot_name' => (string) $bot_row['bot_name'], 'bot_active' => (int) $bot_row['bot_active'], 'bot_agent' => (string) $bot_row['bot_agent'], 'bot_ip' => (string) $bot_row['bot_ip']) ) . " WHERE bot_id = $bot_id"; $db->sql_query($sql); // Updated username? if ($bot_row['bot_name'] !== $row['bot_name']) { user_update_name($row['bot_name'], $bot_row['bot_name']); } $log = 'UPDATED'; } $cache->destroy('_bots'); add_log('admin', 'LOG_BOT_' . $log, $bot_row['bot_name']); trigger_error($user->lang['BOT_' . $log] . adm_back_link($this->u_action)); } } else if ($bot_id) { $sql = 'SELECT b.*, u.user_lang, u.user_style FROM ' . BOTS_TABLE . ' b, ' . USERS_TABLE . " u WHERE b.bot_id = $bot_id AND u.user_id = b.user_id"; $result = $db->sql_query($sql); $bot_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$bot_row) { trigger_error($user->lang['NO_BOT'] . adm_back_link($this->u_action . "&id=$bot_id&action=$action"), E_USER_WARNING); } $bot_row['bot_lang'] = $bot_row['user_lang']; $bot_row['bot_style'] = $bot_row['user_style']; unset($bot_row['user_lang'], $bot_row['user_style']); } $s_active_options = ''; $_options = array('0' => 'NO', '1' => 'YES'); foreach ($_options as $value => $lang) { $selected = ($bot_row['bot_active'] == $value) ? ' selected="selected"' : ''; $s_active_options .= '<option value="' . $value . '"' . $selected . '>' . $user->lang[$lang] . '</option>'; } $style_select = style_select($bot_row['bot_style'], true); $lang_select = language_select($bot_row['bot_lang']); $l_title = ($action == 'edit') ? 'EDIT' : 'ADD'; $template->assign_vars(array( 'L_TITLE' => $user->lang['BOT_' . $l_title], 'U_ACTION' => $this->u_action . "&id=$bot_id&action=$action", 'U_BACK' => $this->u_action, 'ERROR_MSG' => (sizeof($error)) ? implode('<br />', $error) : '', 'BOT_NAME' => $bot_row['bot_name'], 'BOT_IP' => $bot_row['bot_ip'], 'BOT_AGENT' => $bot_row['bot_agent'], 'S_EDIT_BOT' => true, 'S_ACTIVE_OPTIONS' => $s_active_options, 'S_STYLE_OPTIONS' => $style_select, 'S_LANG_OPTIONS' => $lang_select, 'S_ERROR' => (sizeof($error)) ? true : false, ) ); return; break; } if ($request->is_ajax() && ($action == 'activate' || $action == 'deactivate')) { $json_response = new \phpbb\json_response; $json_response->send(array( 'text' => $user->lang['BOT_' . (($action == 'activate') ? 'DE' : '') . 'ACTIVATE'], )); } $s_options = ''; $_options = array('activate' => 'BOT_ACTIVATE', 'deactivate' => 'BOT_DEACTIVATE', 'delete' => 'DELETE'); foreach ($_options as $value => $lang) { $s_options .= '<option value="' . $value . '">' . $user->lang[$lang] . '</option>'; } $template->assign_vars(array( 'U_ACTION' => $this->u_action, 'S_BOT_OPTIONS' => $s_options) ); $sql = 'SELECT b.bot_id, b.bot_name, b.bot_active, u.user_lastvisit FROM ' . BOTS_TABLE . ' b, ' . USERS_TABLE . ' u WHERE u.user_id = b.user_id ORDER BY u.user_lastvisit DESC, b.bot_name ASC'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $active_lang = (!$row['bot_active']) ? 'BOT_ACTIVATE' : 'BOT_DEACTIVATE'; $active_value = (!$row['bot_active']) ? 'activate' : 'deactivate'; $template->assign_block_vars('bots', array( 'BOT_NAME' => $row['bot_name'], 'BOT_ID' => $row['bot_id'], 'LAST_VISIT' => ($row['user_lastvisit']) ? $user->format_date($row['user_lastvisit']) : $user->lang['BOT_NEVER'], 'U_ACTIVATE_DEACTIVATE' => $this->u_action . "&id={$row['bot_id']}&action=$active_value", 'L_ACTIVATE_DEACTIVATE' => $user->lang[$active_lang], 'U_EDIT' => $this->u_action . "&id={$row['bot_id']}&action=edit", 'U_DELETE' => $this->u_action . "&id={$row['bot_id']}&action=delete") ); } $db->sql_freeresult($result); } /** * Validate bot name against username table */ function validate_botname($newname, $oldname = false) { global $db; if ($oldname && utf8_clean_string($newname) === $oldname) { return true; } // Admins might want to use names otherwise forbidden, thus we only check for duplicates. $sql = 'SELECT username FROM ' . USERS_TABLE . " WHERE username_clean = '" . $db->sql_escape(utf8_clean_string($newname)) . "'"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); return ($row) ? false : true; } } acp_ban.php000077700000020634151514745240006664 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_ban { var $u_action; function main($id, $mode) { global $user, $template, $request, $phpbb_dispatcher; global $phpbb_root_path, $phpEx; include($phpbb_root_path . 'includes/functions_user.' . $phpEx); $bansubmit = $request->is_set_post('bansubmit'); $unbansubmit = $request->is_set_post('unbansubmit'); $user->add_lang(array('acp/ban', 'acp/users')); $this->tpl_name = 'acp_ban'; $form_key = 'acp_ban'; add_form_key($form_key); if (($bansubmit || $unbansubmit) && !check_form_key($form_key)) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } // Ban submitted? if ($bansubmit) { // Grab the list of entries $ban = $request->variable('ban', '', true); $ban_length = $request->variable('banlength', 0); $ban_length_other = $request->variable('banlengthother', ''); $ban_exclude = $request->variable('banexclude', 0); $ban_reason = $request->variable('banreason', '', true); $ban_give_reason = $request->variable('bangivereason', '', true); if ($ban) { $abort_ban = false; /** * Use this event to modify the ban details before the ban is performed * * @event core.acp_ban_before * @var string mode One of the following: user, ip, email * @var string ban Either string or array with usernames, ips or email addresses * @var int ban_length Ban length in minutes * @var string ban_length_other Ban length as a date (YYYY-MM-DD) * @var bool ban_exclude Are we banning or excluding from another ban * @var string ban_reason Ban reason displayed to moderators * @var string ban_give_reason Ban reason displayed to the banned user * @var mixed abort_ban Either false, or an error message that is displayed to the user. * If a string is given the bans are not issued. * @since 3.1.0-RC5 */ $vars = array( 'mode', 'ban', 'ban_length', 'ban_length_other', 'ban_exclude', 'ban_reason', 'ban_give_reason', 'abort_ban', ); extract($phpbb_dispatcher->trigger_event('core.acp_ban_before', compact($vars))); if ($abort_ban) { trigger_error($abort_ban . adm_back_link($this->u_action)); } user_ban($mode, $ban, $ban_length, $ban_length_other, $ban_exclude, $ban_reason, $ban_give_reason); /** * Use this event to perform actions after the ban has been performed * * @event core.acp_ban_after * @var string mode One of the following: user, ip, email * @var string ban Either string or array with usernames, ips or email addresses * @var int ban_length Ban length in minutes * @var string ban_length_other Ban length as a date (YYYY-MM-DD) * @var bool ban_exclude Are we banning or excluding from another ban * @var string ban_reason Ban reason displayed to moderators * @var string ban_give_reason Ban reason displayed to the banned user * @since 3.1.0-RC5 */ $vars = array( 'mode', 'ban', 'ban_length', 'ban_length_other', 'ban_exclude', 'ban_reason', 'ban_give_reason', ); extract($phpbb_dispatcher->trigger_event('core.acp_ban_after', compact($vars))); trigger_error($user->lang['BAN_UPDATE_SUCCESSFUL'] . adm_back_link($this->u_action)); } } else if ($unbansubmit) { $ban = $request->variable('unban', array('')); if ($ban) { user_unban($mode, $ban); trigger_error($user->lang['BAN_UPDATE_SUCCESSFUL'] . adm_back_link($this->u_action)); } } // Define language vars $this->page_title = $user->lang[strtoupper($mode) . '_BAN']; $l_ban_explain = $user->lang[strtoupper($mode) . '_BAN_EXPLAIN']; $l_ban_exclude_explain = $user->lang[strtoupper($mode) . '_BAN_EXCLUDE_EXPLAIN']; $l_unban_title = $user->lang[strtoupper($mode) . '_UNBAN']; $l_unban_explain = $user->lang[strtoupper($mode) . '_UNBAN_EXPLAIN']; $l_no_ban_cell = $user->lang[strtoupper($mode) . '_NO_BANNED']; switch ($mode) { case 'user': $l_ban_cell = $user->lang['USERNAME']; break; case 'ip': $l_ban_cell = $user->lang['IP_HOSTNAME']; break; case 'email': $l_ban_cell = $user->lang['EMAIL_ADDRESS']; break; } self::display_ban_options($mode); $template->assign_vars(array( 'L_TITLE' => $this->page_title, 'L_EXPLAIN' => $l_ban_explain, 'L_UNBAN_TITLE' => $l_unban_title, 'L_UNBAN_EXPLAIN' => $l_unban_explain, 'L_BAN_CELL' => $l_ban_cell, 'L_BAN_EXCLUDE_EXPLAIN' => $l_ban_exclude_explain, 'L_NO_BAN_CELL' => $l_no_ban_cell, 'S_USERNAME_BAN' => ($mode == 'user') ? true : false, 'U_ACTION' => $this->u_action, 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=acp_ban&field=ban'), )); } /** * Display ban options */ static public function display_ban_options($mode) { global $user, $db, $template; // Ban length options $ban_end_text = array(0 => $user->lang['PERMANENT'], 30 => $user->lang['30_MINS'], 60 => $user->lang['1_HOUR'], 360 => $user->lang['6_HOURS'], 1440 => $user->lang['1_DAY'], 10080 => $user->lang['7_DAYS'], 20160 => $user->lang['2_WEEKS'], 40320 => $user->lang['1_MONTH'], -1 => $user->lang['UNTIL'] . ' -> '); $ban_end_options = ''; foreach ($ban_end_text as $length => $text) { $ban_end_options .= '<option value="' . $length . '">' . $text . '</option>'; } switch ($mode) { case 'user': $field = 'username'; $l_ban_cell = $user->lang['USERNAME']; $sql = 'SELECT b.*, u.user_id, u.username, u.username_clean FROM ' . BANLIST_TABLE . ' b, ' . USERS_TABLE . ' u WHERE (b.ban_end >= ' . time() . ' OR b.ban_end = 0) AND u.user_id = b.ban_userid ORDER BY u.username_clean ASC'; break; case 'ip': $field = 'ban_ip'; $l_ban_cell = $user->lang['IP_HOSTNAME']; $sql = 'SELECT * FROM ' . BANLIST_TABLE . ' WHERE (ban_end >= ' . time() . " OR ban_end = 0) AND ban_ip <> '' ORDER BY ban_ip"; break; case 'email': $field = 'ban_email'; $l_ban_cell = $user->lang['EMAIL_ADDRESS']; $sql = 'SELECT * FROM ' . BANLIST_TABLE . ' WHERE (ban_end >= ' . time() . " OR ban_end = 0) AND ban_email <> '' ORDER BY ban_email"; break; } $result = $db->sql_query($sql); $banned_options = $excluded_options = array(); while ($row = $db->sql_fetchrow($result)) { $option = '<option value="' . $row['ban_id'] . '">' . $row[$field] . '</option>'; if ($row['ban_exclude']) { $excluded_options[] = $option; } else { $banned_options[] = $option; } $time_length = ($row['ban_end']) ? ($row['ban_end'] - $row['ban_start']) / 60 : 0; if ($time_length == 0) { // Banned permanently $ban_length = $user->lang['PERMANENT']; } else if (isset($ban_end_text[$time_length])) { // Banned for a given duration $ban_length = $user->lang('BANNED_UNTIL_DURATION', $ban_end_text[$time_length], $user->format_date($row['ban_end'], false, true)); } else { // Banned until given date $ban_length = $user->lang('BANNED_UNTIL_DATE', $user->format_date($row['ban_end'], false, true)); } $template->assign_block_vars('bans', array( 'BAN_ID' => (int) $row['ban_id'], 'LENGTH' => $ban_length, 'A_LENGTH' => addslashes($ban_length), 'REASON' => $row['ban_reason'], 'A_REASON' => addslashes($row['ban_reason']), 'GIVE_REASON' => $row['ban_give_reason'], 'A_GIVE_REASON' => addslashes($row['ban_give_reason']), )); } $db->sql_freeresult($result); $options = ''; if ($excluded_options) { $options .= '<optgroup label="' . $user->lang['OPTIONS_EXCLUDED'] . '">'; $options .= implode('', $excluded_options); $options .= '</optgroup>'; } if ($banned_options) { $options .= '<optgroup label="' . $user->lang['OPTIONS_BANNED'] . '">'; $options .= implode('', $banned_options); $options .= '</optgroup>'; } $template->assign_vars(array( 'S_BAN_END_OPTIONS' => $ban_end_options, 'S_BANNED_OPTIONS' => ($banned_options || $excluded_options) ? true : false, 'BANNED_OPTIONS' => $options, )); } } acp_permissions.php000077700000116102151514745240010473 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_permissions { var $u_action; var $permission_dropdown; protected $permissions; function main($id, $mode) { global $db, $user, $auth, $template, $cache, $phpbb_container; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx); include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx); $this->permissions = $phpbb_container->get('acl.permissions'); $auth_admin = new auth_admin(); $user->add_lang('acp/permissions'); add_permission_language(); $this->tpl_name = 'acp_permissions'; // Trace has other vars if ($mode == 'trace') { $user_id = request_var('u', 0); $forum_id = request_var('f', 0); $permission = request_var('auth', ''); $this->tpl_name = 'permission_trace'; if ($user_id && isset($auth_admin->acl_options['id'][$permission]) && $auth->acl_get('a_viewauth')) { $this->page_title = sprintf($user->lang['TRACE_PERMISSION'], $this->permissions->get_permission_lang($permission)); $this->permission_trace($user_id, $forum_id, $permission); return; } trigger_error('NO_MODE', E_USER_ERROR); } // Copy forum permissions if ($mode == 'setting_forum_copy') { $this->tpl_name = 'permission_forum_copy'; if ($auth->acl_get('a_fauth') && $auth->acl_get('a_authusers') && $auth->acl_get('a_authgroups') && $auth->acl_get('a_mauth')) { $this->page_title = 'ACP_FORUM_PERMISSIONS_COPY'; $this->copy_forum_permissions(); return; } trigger_error('NO_MODE', E_USER_ERROR); } // Set some vars $action = request_var('action', array('' => 0)); $action = key($action); $action = (isset($_POST['psubmit'])) ? 'apply_permissions' : $action; $all_forums = request_var('all_forums', 0); $subforum_id = request_var('subforum_id', 0); $forum_id = request_var('forum_id', array(0)); $username = request_var('username', array(''), true); $usernames = request_var('usernames', '', true); $user_id = request_var('user_id', array(0)); $group_id = request_var('group_id', array(0)); $select_all_groups = request_var('select_all_groups', 0); $form_name = 'acp_permissions'; add_form_key($form_name); // If select all groups is set, we pre-build the group id array (this option is used for other screens to link to the permission settings screen) if ($select_all_groups) { // Add default groups to selection $sql_and = (!$config['coppa_enable']) ? " AND group_name <> 'REGISTERED_COPPA'" : ''; $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . ' WHERE group_type = ' . GROUP_SPECIAL . " $sql_and"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $group_id[] = $row['group_id']; } $db->sql_freeresult($result); } // Map usernames to ids and vice versa if ($usernames) { $username = explode("\n", $usernames); } unset($usernames); if (sizeof($username) && !sizeof($user_id)) { user_get_id_name($user_id, $username); if (!sizeof($user_id)) { trigger_error($user->lang['SELECTED_USER_NOT_EXIST'] . adm_back_link($this->u_action), E_USER_WARNING); } } unset($username); // Build forum ids (of all forums are checked or subforum listing used) if ($all_forums) { $sql = 'SELECT forum_id FROM ' . FORUMS_TABLE . ' ORDER BY left_id'; $result = $db->sql_query($sql); $forum_id = array(); while ($row = $db->sql_fetchrow($result)) { $forum_id[] = (int) $row['forum_id']; } $db->sql_freeresult($result); } else if ($subforum_id) { $forum_id = array(); foreach (get_forum_branch($subforum_id, 'children') as $row) { $forum_id[] = (int) $row['forum_id']; } } // Define some common variables for every mode $error = array(); $permission_scope = (strpos($mode, '_global') !== false) ? 'global' : 'local'; // Showing introductionary page? if ($mode == 'intro') { $this->page_title = 'ACP_PERMISSIONS'; $template->assign_vars(array( 'S_INTRO' => true) ); return; } switch ($mode) { case 'setting_user_global': case 'setting_group_global': $this->permission_dropdown = array('u_', 'm_', 'a_'); $permission_victim = ($mode == 'setting_user_global') ? array('user') : array('group'); $this->page_title = ($mode == 'setting_user_global') ? 'ACP_USERS_PERMISSIONS' : 'ACP_GROUPS_PERMISSIONS'; break; case 'setting_user_local': case 'setting_group_local': $this->permission_dropdown = array('f_', 'm_'); $permission_victim = ($mode == 'setting_user_local') ? array('user', 'forums') : array('group', 'forums'); $this->page_title = ($mode == 'setting_user_local') ? 'ACP_USERS_FORUM_PERMISSIONS' : 'ACP_GROUPS_FORUM_PERMISSIONS'; break; case 'setting_admin_global': case 'setting_mod_global': $this->permission_dropdown = (strpos($mode, '_admin_') !== false) ? array('a_') : array('m_'); $permission_victim = array('usergroup'); $this->page_title = ($mode == 'setting_admin_global') ? 'ACP_ADMINISTRATORS' : 'ACP_GLOBAL_MODERATORS'; break; case 'setting_mod_local': case 'setting_forum_local': $this->permission_dropdown = ($mode == 'setting_mod_local') ? array('m_') : array('f_'); $permission_victim = array('forums', 'usergroup'); $this->page_title = ($mode == 'setting_mod_local') ? 'ACP_FORUM_MODERATORS' : 'ACP_FORUM_PERMISSIONS'; break; case 'view_admin_global': case 'view_user_global': case 'view_mod_global': $this->permission_dropdown = ($mode == 'view_admin_global') ? array('a_') : (($mode == 'view_user_global') ? array('u_') : array('m_')); $permission_victim = array('usergroup_view'); $this->page_title = ($mode == 'view_admin_global') ? 'ACP_VIEW_ADMIN_PERMISSIONS' : (($mode == 'view_user_global') ? 'ACP_VIEW_USER_PERMISSIONS' : 'ACP_VIEW_GLOBAL_MOD_PERMISSIONS'); break; case 'view_mod_local': case 'view_forum_local': $this->permission_dropdown = ($mode == 'view_mod_local') ? array('m_') : array('f_'); $permission_victim = array('forums', 'usergroup_view'); $this->page_title = ($mode == 'view_mod_local') ? 'ACP_VIEW_FORUM_MOD_PERMISSIONS' : 'ACP_VIEW_FORUM_PERMISSIONS'; break; default: trigger_error('NO_MODE', E_USER_ERROR); break; } $template->assign_vars(array( 'L_TITLE' => $user->lang[$this->page_title], 'L_EXPLAIN' => $user->lang[$this->page_title . '_EXPLAIN']) ); // Get permission type $permission_type = request_var('type', $this->permission_dropdown[0]); if (!in_array($permission_type, $this->permission_dropdown)) { trigger_error($user->lang['WRONG_PERMISSION_TYPE'] . adm_back_link($this->u_action), E_USER_WARNING); } // Handle actions if (strpos($mode, 'setting_') === 0 && $action) { switch ($action) { case 'delete': if (confirm_box(true)) { // All users/groups selected? $all_users = (isset($_POST['all_users'])) ? true : false; $all_groups = (isset($_POST['all_groups'])) ? true : false; if ($all_users || $all_groups) { $items = $this->retrieve_defined_user_groups($permission_scope, $forum_id, $permission_type); if ($all_users && sizeof($items['user_ids'])) { $user_id = $items['user_ids']; } else if ($all_groups && sizeof($items['group_ids'])) { $group_id = $items['group_ids']; } } if (sizeof($user_id) || sizeof($group_id)) { $this->remove_permissions($mode, $permission_type, $auth_admin, $user_id, $group_id, $forum_id); } else { trigger_error($user->lang['NO_USER_GROUP_SELECTED'] . adm_back_link($this->u_action), E_USER_WARNING); } } else { if (isset($_POST['cancel'])) { $u_redirect = $this->u_action . '&type=' . $permission_type; foreach ($forum_id as $fid) { $u_redirect .= '&forum_id[]=' . $fid; } redirect($u_redirect); } $s_hidden_fields = array( 'i' => $id, 'mode' => $mode, 'action' => array($action => 1), 'user_id' => $user_id, 'group_id' => $group_id, 'forum_id' => $forum_id, 'type' => $permission_type, ); if (isset($_POST['all_users'])) { $s_hidden_fields['all_users'] = 1; } if (isset($_POST['all_groups'])) { $s_hidden_fields['all_groups'] = 1; } confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields($s_hidden_fields)); } break; case 'apply_permissions': if (!isset($_POST['setting'])) { trigger_error($user->lang['NO_AUTH_SETTING_FOUND'] . adm_back_link($this->u_action), E_USER_WARNING); } if (!check_form_key($form_name)) { trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING); } $this->set_permissions($mode, $permission_type, $auth_admin, $user_id, $group_id); break; case 'apply_all_permissions': if (!isset($_POST['setting'])) { trigger_error($user->lang['NO_AUTH_SETTING_FOUND'] . adm_back_link($this->u_action), E_USER_WARNING); } if (!check_form_key($form_name)) { trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING); } $this->set_all_permissions($mode, $permission_type, $auth_admin, $user_id, $group_id); break; } } // Go through the screens/options needed and present them in correct order foreach ($permission_victim as $victim) { switch ($victim) { case 'forum_dropdown': if (sizeof($forum_id)) { $this->check_existence('forum', $forum_id); continue 2; } $template->assign_vars(array( 'S_SELECT_FORUM' => true, 'S_FORUM_OPTIONS' => make_forum_select(false, false, true, false, false)) ); break; case 'forums': if (sizeof($forum_id)) { $this->check_existence('forum', $forum_id); continue 2; } $forum_list = make_forum_select(false, false, true, false, false, false, true); // Build forum options $s_forum_options = ''; foreach ($forum_list as $f_id => $f_row) { $s_forum_options .= '<option value="' . $f_id . '"' . (($f_row['selected']) ? ' selected="selected"' : '') . (($f_row['disabled']) ? ' disabled="disabled" class="disabled-option"' : '') . '>' . $f_row['padding'] . $f_row['forum_name'] . '</option>'; } // Build subforum options $s_subforum_options = $this->build_subforum_options($forum_list); $template->assign_vars(array( 'S_SELECT_FORUM' => true, 'S_FORUM_OPTIONS' => $s_forum_options, 'S_SUBFORUM_OPTIONS' => $s_subforum_options, 'S_FORUM_ALL' => true, 'S_FORUM_MULTIPLE' => true) ); break; case 'user': if (sizeof($user_id)) { $this->check_existence('user', $user_id); continue 2; } $template->assign_vars(array( 'S_SELECT_USER' => true, 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=select_victim&field=username&select_single=true'), )); break; case 'group': if (sizeof($group_id)) { $this->check_existence('group', $group_id); continue 2; } $template->assign_vars(array( 'S_SELECT_GROUP' => true, 'S_GROUP_OPTIONS' => group_select_options(false, false, false), // Show all groups )); break; case 'usergroup': case 'usergroup_view': $all_users = (isset($_POST['all_users'])) ? true : false; $all_groups = (isset($_POST['all_groups'])) ? true : false; if ((sizeof($user_id) && !$all_users) || (sizeof($group_id) && !$all_groups)) { if (sizeof($user_id)) { $this->check_existence('user', $user_id); } if (sizeof($group_id)) { $this->check_existence('group', $group_id); } continue 2; } // Now we check the users... because the "all"-selection is different here (all defined users/groups) $items = $this->retrieve_defined_user_groups($permission_scope, $forum_id, $permission_type); if ($all_users && sizeof($items['user_ids'])) { $user_id = $items['user_ids']; continue 2; } if ($all_groups && sizeof($items['group_ids'])) { $group_id = $items['group_ids']; continue 2; } $template->assign_vars(array( 'S_SELECT_USERGROUP' => ($victim == 'usergroup') ? true : false, 'S_SELECT_USERGROUP_VIEW' => ($victim == 'usergroup_view') ? true : false, 'S_DEFINED_USER_OPTIONS' => $items['user_ids_options'], 'S_DEFINED_GROUP_OPTIONS' => $items['group_ids_options'], 'S_ADD_GROUP_OPTIONS' => group_select_options(false, $items['group_ids'], false), // Show all groups 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=add_user&field=username&select_single=true'), )); break; } // The S_ALLOW_SELECT parameter below is a measure to lower memory usage. // If there are more than 5 forums selected the admin is not able to select all users/groups too. // We need to see if the number of forums can be increased or need to be decreased. // Setting permissions screen $s_hidden_fields = build_hidden_fields(array( 'user_id' => $user_id, 'group_id' => $group_id, 'forum_id' => $forum_id, 'type' => $permission_type, )); $template->assign_vars(array( 'U_ACTION' => $this->u_action, 'ANONYMOUS_USER_ID' => ANONYMOUS, 'S_SELECT_VICTIM' => true, 'S_ALLOW_ALL_SELECT' => (sizeof($forum_id) > 5) ? false : true, 'S_CAN_SELECT_USER' => ($auth->acl_get('a_authusers')) ? true : false, 'S_CAN_SELECT_GROUP' => ($auth->acl_get('a_authgroups')) ? true : false, 'S_HIDDEN_FIELDS' => $s_hidden_fields) ); // Let the forum names being displayed if (sizeof($forum_id)) { $sql = 'SELECT forum_name FROM ' . FORUMS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_id) . ' ORDER BY left_id ASC'; $result = $db->sql_query($sql); $forum_names = array(); while ($row = $db->sql_fetchrow($result)) { $forum_names[] = $row['forum_name']; } $db->sql_freeresult($result); $template->assign_vars(array( 'S_FORUM_NAMES' => (sizeof($forum_names)) ? true : false, 'FORUM_NAMES' => implode($user->lang['COMMA_SEPARATOR'], $forum_names)) ); } return; } // Setting permissions screen $s_hidden_fields = build_hidden_fields(array( 'user_id' => $user_id, 'group_id' => $group_id, 'forum_id' => $forum_id, 'type' => $permission_type, )); // Do not allow forum_ids being set and no other setting defined (will bog down the server too much) if (sizeof($forum_id) && !sizeof($user_id) && !sizeof($group_id)) { trigger_error($user->lang['ONLY_FORUM_DEFINED'] . adm_back_link($this->u_action), E_USER_WARNING); } $template->assign_vars(array( 'S_PERMISSION_DROPDOWN' => (sizeof($this->permission_dropdown) > 1) ? $this->build_permission_dropdown($this->permission_dropdown, $permission_type, $permission_scope) : false, 'L_PERMISSION_TYPE' => $this->permissions->get_type_lang($permission_type), 'U_ACTION' => $this->u_action, 'S_HIDDEN_FIELDS' => $s_hidden_fields) ); if (strpos($mode, 'setting_') === 0) { $template->assign_vars(array( 'S_SETTING_PERMISSIONS' => true) ); $hold_ary = $auth_admin->get_mask('set', (sizeof($user_id)) ? $user_id : false, (sizeof($group_id)) ? $group_id : false, (sizeof($forum_id)) ? $forum_id : false, $permission_type, $permission_scope, ACL_NO); $auth_admin->display_mask('set', $permission_type, $hold_ary, ((sizeof($user_id)) ? 'user' : 'group'), (($permission_scope == 'local') ? true : false)); } else { $template->assign_vars(array( 'S_VIEWING_PERMISSIONS' => true) ); $hold_ary = $auth_admin->get_mask('view', (sizeof($user_id)) ? $user_id : false, (sizeof($group_id)) ? $group_id : false, (sizeof($forum_id)) ? $forum_id : false, $permission_type, $permission_scope, ACL_NEVER); $auth_admin->display_mask('view', $permission_type, $hold_ary, ((sizeof($user_id)) ? 'user' : 'group'), (($permission_scope == 'local') ? true : false)); } } /** * Build +subforum options */ function build_subforum_options($forum_list) { global $user; $s_options = ''; $forum_list = array_merge($forum_list); foreach ($forum_list as $key => $row) { if ($row['disabled']) { continue; } $s_options .= '<option value="' . $row['forum_id'] . '"' . (($row['selected']) ? ' selected="selected"' : '') . '>' . $row['padding'] . $row['forum_name']; // We check if a branch is there... $branch_there = false; foreach (array_slice($forum_list, $key + 1) as $temp_row) { if ($temp_row['left_id'] > $row['left_id'] && $temp_row['left_id'] < $row['right_id']) { $branch_there = true; break; } continue; } if ($branch_there) { $s_options .= ' [' . $user->lang['PLUS_SUBFORUMS'] . ']'; } $s_options .= '</option>'; } return $s_options; } /** * Build dropdown field for changing permission types */ function build_permission_dropdown($options, $default_option, $permission_scope) { global $auth; $s_dropdown_options = ''; foreach ($options as $setting) { if (!$auth->acl_get('a_' . str_replace('_', '', $setting) . 'auth')) { continue; } $selected = ($setting == $default_option) ? ' selected="selected"' : ''; $l_setting = $this->permissions->get_type_lang($setting, $permission_scope); $s_dropdown_options .= '<option value="' . $setting . '"' . $selected . '>' . $l_setting . '</option>'; } return $s_dropdown_options; } /** * Check if selected items exist. Remove not found ids and if empty return error. */ function check_existence($mode, &$ids) { global $db, $user; switch ($mode) { case 'user': $table = USERS_TABLE; $sql_id = 'user_id'; break; case 'group': $table = GROUPS_TABLE; $sql_id = 'group_id'; break; case 'forum': $table = FORUMS_TABLE; $sql_id = 'forum_id'; break; } if (sizeof($ids)) { $sql = "SELECT $sql_id FROM $table WHERE " . $db->sql_in_set($sql_id, $ids); $result = $db->sql_query($sql); $ids = array(); while ($row = $db->sql_fetchrow($result)) { $ids[] = (int) $row[$sql_id]; } $db->sql_freeresult($result); } if (!sizeof($ids)) { trigger_error($user->lang['SELECTED_' . strtoupper($mode) . '_NOT_EXIST'] . adm_back_link($this->u_action), E_USER_WARNING); } } /** * Apply permissions */ function set_permissions($mode, $permission_type, &$auth_admin, &$user_id, &$group_id) { global $db, $cache, $user, $auth; global $request; $psubmit = request_var('psubmit', array(0 => array(0 => 0))); // User or group to be set? $ug_type = (sizeof($user_id)) ? 'user' : 'group'; // Check the permission setting again if (!$auth->acl_get('a_' . str_replace('_', '', $permission_type) . 'auth') || !$auth->acl_get('a_auth' . $ug_type . 's')) { trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } $ug_id = $forum_id = 0; // We loop through the auth settings defined in our submit list($ug_id, ) = each($psubmit); list($forum_id, ) = each($psubmit[$ug_id]); $settings = $request->variable('setting', array(0 => array(0 => array('' => 0))), false, \phpbb\request\request_interface::POST); if (empty($settings) || empty($settings[$ug_id]) || empty($settings[$ug_id][$forum_id])) { trigger_error('WRONG_PERMISSION_SETTING_FORMAT', E_USER_WARNING); } $auth_settings = $settings[$ug_id][$forum_id]; // Do we have a role we want to set? $roles = $request->variable('role', array(0 => array(0 => 0)), false, \phpbb\request\request_interface::POST); $assigned_role = (isset($roles[$ug_id][$forum_id])) ? (int) $roles[$ug_id][$forum_id] : 0; // Do the admin want to set these permissions to other items too? $inherit = request_var('inherit', array(0 => array(0))); $ug_id = array($ug_id); $forum_id = array($forum_id); if (sizeof($inherit)) { foreach ($inherit as $_ug_id => $forum_id_ary) { // Inherit users/groups? if (!in_array($_ug_id, $ug_id)) { $ug_id[] = $_ug_id; } // Inherit forums? $forum_id = array_merge($forum_id, array_keys($forum_id_ary)); } } $forum_id = array_unique($forum_id); // If the auth settings differ from the assigned role, then do not set a role... if ($assigned_role) { if (!$this->check_assigned_role($assigned_role, $auth_settings)) { $assigned_role = 0; } } // Update the permission set... $auth_admin->acl_set($ug_type, $forum_id, $ug_id, $auth_settings, $assigned_role); // Do we need to recache the moderator lists? if ($permission_type == 'm_') { phpbb_cache_moderators($db, $cache, $auth); } // Remove users who are now moderators or admins from everyones foes list if ($permission_type == 'm_' || $permission_type == 'a_') { phpbb_update_foes($db, $auth, $group_id, $user_id); } $this->log_action($mode, 'add', $permission_type, $ug_type, $ug_id, $forum_id); trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action)); } /** * Apply all permissions */ function set_all_permissions($mode, $permission_type, &$auth_admin, &$user_id, &$group_id) { global $db, $cache, $user, $auth; global $request; // User or group to be set? $ug_type = (sizeof($user_id)) ? 'user' : 'group'; // Check the permission setting again if (!$auth->acl_get('a_' . str_replace('_', '', $permission_type) . 'auth') || !$auth->acl_get('a_auth' . $ug_type . 's')) { trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } $auth_settings = $request->variable('setting', array(0 => array(0 => array('' => 0))), false, \phpbb\request\request_interface::POST); $auth_roles = $request->variable('role', array(0 => array(0 => 0)), false, \phpbb\request\request_interface::POST); $ug_ids = $forum_ids = array(); // We need to go through the auth settings foreach ($auth_settings as $ug_id => $forum_auth_row) { $ug_id = (int) $ug_id; $ug_ids[] = $ug_id; foreach ($forum_auth_row as $forum_id => $auth_options) { $forum_id = (int) $forum_id; $forum_ids[] = $forum_id; // Check role... $assigned_role = (isset($auth_roles[$ug_id][$forum_id])) ? (int) $auth_roles[$ug_id][$forum_id] : 0; // If the auth settings differ from the assigned role, then do not set a role... if ($assigned_role) { if (!$this->check_assigned_role($assigned_role, $auth_options)) { $assigned_role = 0; } } // Update the permission set... $auth_admin->acl_set($ug_type, $forum_id, $ug_id, $auth_options, $assigned_role, false); } } $auth_admin->acl_clear_prefetch(); // Do we need to recache the moderator lists? if ($permission_type == 'm_') { phpbb_cache_moderators($db, $cache, $auth); } // Remove users who are now moderators or admins from everyones foes list if ($permission_type == 'm_' || $permission_type == 'a_') { phpbb_update_foes($db, $auth, $group_id, $user_id); } $this->log_action($mode, 'add', $permission_type, $ug_type, $ug_ids, $forum_ids); if ($mode == 'setting_forum_local' || $mode == 'setting_mod_local') { trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action . '&forum_id[]=' . implode('&forum_id[]=', $forum_ids))); } else { trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action)); } } /** * Compare auth settings with auth settings from role * returns false if they differ, true if they are equal */ function check_assigned_role($role_id, &$auth_settings) { global $db; $sql = 'SELECT o.auth_option, r.auth_setting FROM ' . ACL_OPTIONS_TABLE . ' o, ' . ACL_ROLES_DATA_TABLE . ' r WHERE o.auth_option_id = r.auth_option_id AND r.role_id = ' . $role_id; $result = $db->sql_query($sql); $test_auth_settings = array(); while ($row = $db->sql_fetchrow($result)) { $test_auth_settings[$row['auth_option']] = $row['auth_setting']; } $db->sql_freeresult($result); // We need to add any ACL_NO setting from auth_settings to compare correctly foreach ($auth_settings as $option => $setting) { if ($setting == ACL_NO) { $test_auth_settings[$option] = $setting; } } if (sizeof(array_diff_assoc($auth_settings, $test_auth_settings))) { return false; } return true; } /** * Remove permissions */ function remove_permissions($mode, $permission_type, &$auth_admin, &$user_id, &$group_id, &$forum_id) { global $user, $db, $cache, $auth; // User or group to be set? $ug_type = (sizeof($user_id)) ? 'user' : 'group'; // Check the permission setting again if (!$auth->acl_get('a_' . str_replace('_', '', $permission_type) . 'auth') || !$auth->acl_get('a_auth' . $ug_type . 's')) { trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } $auth_admin->acl_delete($ug_type, (($ug_type == 'user') ? $user_id : $group_id), (sizeof($forum_id) ? $forum_id : false), $permission_type); // Do we need to recache the moderator lists? if ($permission_type == 'm_') { phpbb_cache_moderators($db, $cache, $auth); } $this->log_action($mode, 'del', $permission_type, $ug_type, (($ug_type == 'user') ? $user_id : $group_id), (sizeof($forum_id) ? $forum_id : array(0 => 0))); if ($mode == 'setting_forum_local' || $mode == 'setting_mod_local') { trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action . '&forum_id[]=' . implode('&forum_id[]=', $forum_id))); } else { trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action)); } } /** * Log permission changes */ function log_action($mode, $action, $permission_type, $ug_type, $ug_id, $forum_id) { global $db, $user; if (!is_array($ug_id)) { $ug_id = array($ug_id); } if (!is_array($forum_id)) { $forum_id = array($forum_id); } // Logging ... first grab user or groupnames ... $sql = ($ug_type == 'group') ? 'SELECT group_name as name, group_type FROM ' . GROUPS_TABLE . ' WHERE ' : 'SELECT username as name FROM ' . USERS_TABLE . ' WHERE '; $sql .= $db->sql_in_set(($ug_type == 'group') ? 'group_id' : 'user_id', array_map('intval', $ug_id)); $result = $db->sql_query($sql); $l_ug_list = ''; while ($row = $db->sql_fetchrow($result)) { $l_ug_list .= (($l_ug_list != '') ? ', ' : '') . ((isset($row['group_type']) && $row['group_type'] == GROUP_SPECIAL) ? '<span class="sep">' . $user->lang['G_' . $row['name']] . '</span>' : $row['name']); } $db->sql_freeresult($result); $mode = str_replace('setting_', '', $mode); if ($forum_id[0] == 0) { add_log('admin', 'LOG_ACL_' . strtoupper($action) . '_' . strtoupper($mode) . '_' . strtoupper($permission_type), $l_ug_list); } else { // Grab the forum details if non-zero forum_id $sql = 'SELECT forum_name FROM ' . FORUMS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_id); $result = $db->sql_query($sql); $l_forum_list = ''; while ($row = $db->sql_fetchrow($result)) { $l_forum_list .= (($l_forum_list != '') ? ', ' : '') . $row['forum_name']; } $db->sql_freeresult($result); add_log('admin', 'LOG_ACL_' . strtoupper($action) . '_' . strtoupper($mode) . '_' . strtoupper($permission_type), $l_forum_list, $l_ug_list); } } /** * Display a complete trace tree for the selected permission to determine where settings are set/unset */ function permission_trace($user_id, $forum_id, $permission) { global $db, $template, $user, $auth; if ($user_id != $user->data['user_id']) { $userdata = $auth->obtain_user_data($user_id); } else { $userdata = $user->data; } if (!$userdata) { trigger_error('NO_USERS', E_USER_ERROR); } $forum_name = false; if ($forum_id) { $sql = 'SELECT forum_name FROM ' . FORUMS_TABLE . " WHERE forum_id = $forum_id"; $result = $db->sql_query($sql, 3600); $forum_name = $db->sql_fetchfield('forum_name'); $db->sql_freeresult($result); } $back = request_var('back', 0); $template->assign_vars(array( 'PERMISSION' => $this->permissions->get_permission_lang($permission), 'PERMISSION_USERNAME' => $userdata['username'], 'FORUM_NAME' => $forum_name, 'S_GLOBAL_TRACE' => ($forum_id) ? false : true, 'U_BACK' => ($back) ? build_url(array('f', 'back')) . "&f=$back" : '') ); $template->assign_block_vars('trace', array( 'WHO' => $user->lang['DEFAULT'], 'INFORMATION' => $user->lang['TRACE_DEFAULT'], 'S_SETTING_NO' => true, 'S_TOTAL_NO' => true) ); $sql = 'SELECT DISTINCT g.group_name, g.group_id, g.group_type FROM ' . GROUPS_TABLE . ' g LEFT JOIN ' . USER_GROUP_TABLE . ' ug ON (ug.group_id = g.group_id) WHERE ug.user_id = ' . $user_id . ' AND ug.user_pending = 0 AND NOT (ug.group_leader = 1 AND g.group_skip_auth = 1) ORDER BY g.group_type DESC, g.group_id DESC'; $result = $db->sql_query($sql); $groups = array(); while ($row = $db->sql_fetchrow($result)) { $groups[$row['group_id']] = array( 'auth_setting' => ACL_NO, 'group_name' => ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'] ); } $db->sql_freeresult($result); $total = ACL_NO; $add_key = (($forum_id) ? '_LOCAL' : ''); if (sizeof($groups)) { // Get group auth settings $hold_ary = $auth->acl_group_raw_data(array_keys($groups), $permission, $forum_id); foreach ($hold_ary as $group_id => $forum_ary) { $groups[$group_id]['auth_setting'] = $hold_ary[$group_id][$forum_id][$permission]; } unset($hold_ary); foreach ($groups as $id => $row) { switch ($row['auth_setting']) { case ACL_NO: $information = $user->lang['TRACE_GROUP_NO' . $add_key]; break; case ACL_YES: $information = ($total == ACL_YES) ? $user->lang['TRACE_GROUP_YES_TOTAL_YES' . $add_key] : (($total == ACL_NEVER) ? $user->lang['TRACE_GROUP_YES_TOTAL_NEVER' . $add_key] : $user->lang['TRACE_GROUP_YES_TOTAL_NO' . $add_key]); $total = ($total == ACL_NO) ? ACL_YES : $total; break; case ACL_NEVER: $information = ($total == ACL_YES) ? $user->lang['TRACE_GROUP_NEVER_TOTAL_YES' . $add_key] : (($total == ACL_NEVER) ? $user->lang['TRACE_GROUP_NEVER_TOTAL_NEVER' . $add_key] : $user->lang['TRACE_GROUP_NEVER_TOTAL_NO' . $add_key]); $total = ACL_NEVER; break; } $template->assign_block_vars('trace', array( 'WHO' => $row['group_name'], 'INFORMATION' => $information, 'S_SETTING_NO' => ($row['auth_setting'] == ACL_NO) ? true : false, 'S_SETTING_YES' => ($row['auth_setting'] == ACL_YES) ? true : false, 'S_SETTING_NEVER' => ($row['auth_setting'] == ACL_NEVER) ? true : false, 'S_TOTAL_NO' => ($total == ACL_NO) ? true : false, 'S_TOTAL_YES' => ($total == ACL_YES) ? true : false, 'S_TOTAL_NEVER' => ($total == ACL_NEVER) ? true : false) ); } } // Get user specific permission... globally or for this forum $hold_ary = $auth->acl_user_raw_data($user_id, $permission, $forum_id); $auth_setting = (!sizeof($hold_ary)) ? ACL_NO : $hold_ary[$user_id][$forum_id][$permission]; switch ($auth_setting) { case ACL_NO: $information = ($total == ACL_NO) ? $user->lang['TRACE_USER_NO_TOTAL_NO' . $add_key] : $user->lang['TRACE_USER_KEPT' . $add_key]; $total = ($total == ACL_NO) ? ACL_NEVER : $total; break; case ACL_YES: $information = ($total == ACL_YES) ? $user->lang['TRACE_USER_YES_TOTAL_YES' . $add_key] : (($total == ACL_NEVER) ? $user->lang['TRACE_USER_YES_TOTAL_NEVER' . $add_key] : $user->lang['TRACE_USER_YES_TOTAL_NO' . $add_key]); $total = ($total == ACL_NO) ? ACL_YES : $total; break; case ACL_NEVER: $information = ($total == ACL_YES) ? $user->lang['TRACE_USER_NEVER_TOTAL_YES' . $add_key] : (($total == ACL_NEVER) ? $user->lang['TRACE_USER_NEVER_TOTAL_NEVER' . $add_key] : $user->lang['TRACE_USER_NEVER_TOTAL_NO' . $add_key]); $total = ACL_NEVER; break; } $template->assign_block_vars('trace', array( 'WHO' => $userdata['username'], 'INFORMATION' => $information, 'S_SETTING_NO' => ($auth_setting == ACL_NO) ? true : false, 'S_SETTING_YES' => ($auth_setting == ACL_YES) ? true : false, 'S_SETTING_NEVER' => ($auth_setting == ACL_NEVER) ? true : false, 'S_TOTAL_NO' => false, 'S_TOTAL_YES' => ($total == ACL_YES) ? true : false, 'S_TOTAL_NEVER' => ($total == ACL_NEVER) ? true : false) ); if ($forum_id != 0 && isset($auth->acl_options['global'][$permission])) { if ($user_id != $user->data['user_id']) { $auth2 = new \phpbb\auth\auth(); $auth2->acl($userdata); $auth_setting = $auth2->acl_get($permission); } else { $auth_setting = $auth->acl_get($permission); } if ($auth_setting) { $information = ($total == ACL_YES) ? $user->lang['TRACE_USER_GLOBAL_YES_TOTAL_YES'] : $user->lang['TRACE_USER_GLOBAL_YES_TOTAL_NEVER']; $total = ACL_YES; } else { $information = $user->lang['TRACE_USER_GLOBAL_NEVER_TOTAL_KEPT']; } // If there is no auth information we do not need to worry the user by showing non-relevant data. if ($auth_setting) { $template->assign_block_vars('trace', array( 'WHO' => sprintf($user->lang['TRACE_GLOBAL_SETTING'], $userdata['username']), 'INFORMATION' => sprintf($information, '<a href="' . $this->u_action . "&u=$user_id&f=0&auth=$permission&back=$forum_id\">", '</a>'), 'S_SETTING_NO' => false, 'S_SETTING_YES' => $auth_setting, 'S_SETTING_NEVER' => !$auth_setting, 'S_TOTAL_NO' => false, 'S_TOTAL_YES' => ($total == ACL_YES) ? true : false, 'S_TOTAL_NEVER' => ($total == ACL_NEVER) ? true : false) ); } } // Take founder status into account, overwriting the default values if ($userdata['user_type'] == USER_FOUNDER && strpos($permission, 'a_') === 0) { $template->assign_block_vars('trace', array( 'WHO' => $userdata['username'], 'INFORMATION' => $user->lang['TRACE_USER_FOUNDER'], 'S_SETTING_NO' => ($auth_setting == ACL_NO) ? true : false, 'S_SETTING_YES' => ($auth_setting == ACL_YES) ? true : false, 'S_SETTING_NEVER' => ($auth_setting == ACL_NEVER) ? true : false, 'S_TOTAL_NO' => false, 'S_TOTAL_YES' => true, 'S_TOTAL_NEVER' => false) ); $total = ACL_YES; } // Total value... $template->assign_vars(array( 'S_RESULT_NO' => ($total == ACL_NO) ? true : false, 'S_RESULT_YES' => ($total == ACL_YES) ? true : false, 'S_RESULT_NEVER' => ($total == ACL_NEVER) ? true : false, )); } /** * Handles copying permissions from one forum to others */ function copy_forum_permissions() { global $db, $auth, $cache, $template, $user; $user->add_lang('acp/forums'); $submit = isset($_POST['submit']) ? true : false; if ($submit) { $src = request_var('src_forum_id', 0); $dest = request_var('dest_forum_ids', array(0)); if (confirm_box(true)) { if (copy_forum_permissions($src, $dest)) { phpbb_cache_moderators($db, $cache, $auth); $auth->acl_clear_prefetch(); $cache->destroy('sql', FORUMS_TABLE); trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action)); } else { trigger_error($user->lang['SELECTED_FORUM_NOT_EXIST'] . adm_back_link($this->u_action), E_USER_WARNING); } } else { $s_hidden_fields = array( 'submit' => $submit, 'src_forum_id' => $src, 'dest_forum_ids' => $dest, ); $s_hidden_fields = build_hidden_fields($s_hidden_fields); confirm_box(false, $user->lang['COPY_PERMISSIONS_CONFIRM'], $s_hidden_fields); } } $template->assign_vars(array( 'S_FORUM_OPTIONS' => make_forum_select(false, false, false, false, false), )); } /** * Get already assigned users/groups */ function retrieve_defined_user_groups($permission_scope, $forum_id, $permission_type) { global $db, $user; $sql_forum_id = ($permission_scope == 'global') ? 'AND a.forum_id = 0' : ((sizeof($forum_id)) ? 'AND ' . $db->sql_in_set('a.forum_id', $forum_id) : 'AND a.forum_id <> 0'); // Permission options are only able to be a permission set... therefore we will pre-fetch the possible options and also the possible roles $option_ids = $role_ids = array(); $sql = 'SELECT auth_option_id FROM ' . ACL_OPTIONS_TABLE . ' WHERE auth_option ' . $db->sql_like_expression($permission_type . $db->get_any_char()); $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $option_ids[] = (int) $row['auth_option_id']; } $db->sql_freeresult($result); if (sizeof($option_ids)) { $sql = 'SELECT DISTINCT role_id FROM ' . ACL_ROLES_DATA_TABLE . ' WHERE ' . $db->sql_in_set('auth_option_id', $option_ids); $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $role_ids[] = (int) $row['role_id']; } $db->sql_freeresult($result); } if (sizeof($option_ids) && sizeof($role_ids)) { $sql_where = 'AND (' . $db->sql_in_set('a.auth_option_id', $option_ids) . ' OR ' . $db->sql_in_set('a.auth_role_id', $role_ids) . ')'; } else if (sizeof($role_ids)) { $sql_where = 'AND ' . $db->sql_in_set('a.auth_role_id', $role_ids); } else if (sizeof($option_ids)) { $sql_where = 'AND ' . $db->sql_in_set('a.auth_option_id', $option_ids); } // Not ideal, due to the filesort, non-use of indexes, etc. $sql = 'SELECT DISTINCT u.user_id, u.username, u.username_clean, u.user_regdate FROM ' . USERS_TABLE . ' u, ' . ACL_USERS_TABLE . " a WHERE u.user_id = a.user_id $sql_forum_id $sql_where ORDER BY u.username_clean, u.user_regdate ASC"; $result = $db->sql_query($sql); $s_defined_user_options = ''; $defined_user_ids = array(); while ($row = $db->sql_fetchrow($result)) { $s_defined_user_options .= '<option value="' . $row['user_id'] . '">' . $row['username'] . '</option>'; $defined_user_ids[] = $row['user_id']; } $db->sql_freeresult($result); $sql = 'SELECT DISTINCT g.group_type, g.group_name, g.group_id FROM ' . GROUPS_TABLE . ' g, ' . ACL_GROUPS_TABLE . " a WHERE g.group_id = a.group_id $sql_forum_id $sql_where ORDER BY g.group_type DESC, g.group_name ASC"; $result = $db->sql_query($sql); $s_defined_group_options = ''; $defined_group_ids = array(); while ($row = $db->sql_fetchrow($result)) { $s_defined_group_options .= '<option' . (($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : '') . ' value="' . $row['group_id'] . '">' . (($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']) . '</option>'; $defined_group_ids[] = $row['group_id']; } $db->sql_freeresult($result); return array( 'group_ids' => $defined_group_ids, 'group_ids_options' => $s_defined_group_options, 'user_ids' => $defined_user_ids, 'user_ids_options' => $s_defined_user_options ); } } acp_main.php000077700000047605151514745240007057 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_main { var $u_action; function main($id, $mode) { global $config, $db, $cache, $user, $auth, $template, $request; global $phpbb_root_path, $phpbb_admin_path, $phpEx, $phpbb_container, $phpbb_dispatcher; // Show restore permissions notice if ($user->data['user_perm_from'] && $auth->acl_get('a_switchperm')) { $this->tpl_name = 'acp_main'; $this->page_title = 'ACP_MAIN'; $sql = 'SELECT user_id, username, user_colour FROM ' . USERS_TABLE . ' WHERE user_id = ' . $user->data['user_perm_from']; $result = $db->sql_query($sql); $user_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); $perm_from = get_username_string('full', $user_row['user_id'], $user_row['username'], $user_row['user_colour']); $template->assign_vars(array( 'S_RESTORE_PERMISSIONS' => true, 'U_RESTORE_PERMISSIONS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=restore_perm'), 'PERM_FROM' => $perm_from, 'L_PERMISSIONS_TRANSFERRED_EXPLAIN' => sprintf($user->lang['PERMISSIONS_TRANSFERRED_EXPLAIN'], $perm_from, append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=restore_perm')), )); return; } $action = request_var('action', ''); if ($action) { if ($action === 'admlogout') { $user->unset_admin(); redirect(append_sid("{$phpbb_root_path}index.$phpEx")); } if (!confirm_box(true)) { switch ($action) { case 'online': $confirm = true; $confirm_lang = 'RESET_ONLINE_CONFIRM'; break; case 'stats': $confirm = true; $confirm_lang = 'RESYNC_STATS_CONFIRM'; break; case 'user': $confirm = true; $confirm_lang = 'RESYNC_POSTCOUNTS_CONFIRM'; break; case 'date': $confirm = true; $confirm_lang = 'RESET_DATE_CONFIRM'; break; case 'db_track': $confirm = true; $confirm_lang = 'RESYNC_POST_MARKING_CONFIRM'; break; case 'purge_cache': $confirm = true; $confirm_lang = 'PURGE_CACHE_CONFIRM'; break; case 'purge_sessions': $confirm = true; $confirm_lang = 'PURGE_SESSIONS_CONFIRM'; break; default: $confirm = true; $confirm_lang = 'CONFIRM_OPERATION'; } if ($confirm) { confirm_box(false, $user->lang[$confirm_lang], build_hidden_fields(array( 'i' => $id, 'mode' => $mode, 'action' => $action, ))); } } else { switch ($action) { case 'online': if (!$auth->acl_get('a_board')) { trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } set_config('record_online_users', 1, true); set_config('record_online_date', time(), true); add_log('admin', 'LOG_RESET_ONLINE'); if ($request->is_ajax()) { trigger_error('RESET_ONLINE_SUCCESS'); } break; case 'stats': if (!$auth->acl_get('a_board')) { trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } $sql = 'SELECT COUNT(post_id) AS stat FROM ' . POSTS_TABLE . ' WHERE post_visibility = ' . ITEM_APPROVED; $result = $db->sql_query($sql); set_config('num_posts', (int) $db->sql_fetchfield('stat'), true); $db->sql_freeresult($result); $sql = 'SELECT COUNT(topic_id) AS stat FROM ' . TOPICS_TABLE . ' WHERE topic_visibility = ' . ITEM_APPROVED; $result = $db->sql_query($sql); set_config('num_topics', (int) $db->sql_fetchfield('stat'), true); $db->sql_freeresult($result); $sql = 'SELECT COUNT(user_id) AS stat FROM ' . USERS_TABLE . ' WHERE user_type IN (' . USER_NORMAL . ',' . USER_FOUNDER . ')'; $result = $db->sql_query($sql); set_config('num_users', (int) $db->sql_fetchfield('stat'), true); $db->sql_freeresult($result); $sql = 'SELECT COUNT(attach_id) as stat FROM ' . ATTACHMENTS_TABLE . ' WHERE is_orphan = 0'; $result = $db->sql_query($sql); set_config('num_files', (int) $db->sql_fetchfield('stat'), true); $db->sql_freeresult($result); $sql = 'SELECT SUM(filesize) as stat FROM ' . ATTACHMENTS_TABLE . ' WHERE is_orphan = 0'; $result = $db->sql_query($sql); set_config('upload_dir_size', (float) $db->sql_fetchfield('stat'), true); $db->sql_freeresult($result); if (!function_exists('update_last_username')) { include($phpbb_root_path . "includes/functions_user.$phpEx"); } update_last_username(); add_log('admin', 'LOG_RESYNC_STATS'); if ($request->is_ajax()) { trigger_error('RESYNC_STATS_SUCCESS'); } break; case 'user': if (!$auth->acl_get('a_board')) { trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } // Resync post counts $start = $max_post_id = 0; // Find the maximum post ID, we can only stop the cycle when we've reached it $sql = 'SELECT MAX(forum_last_post_id) as max_post_id FROM ' . FORUMS_TABLE; $result = $db->sql_query($sql); $max_post_id = (int) $db->sql_fetchfield('max_post_id'); $db->sql_freeresult($result); // No maximum post id? :o if (!$max_post_id) { $sql = 'SELECT MAX(post_id) as max_post_id FROM ' . POSTS_TABLE; $result = $db->sql_query($sql); $max_post_id = (int) $db->sql_fetchfield('max_post_id'); $db->sql_freeresult($result); } // Still no maximum post id? Then we are finished if (!$max_post_id) { add_log('admin', 'LOG_RESYNC_POSTCOUNTS'); break; } $step = ($config['num_posts']) ? (max((int) ($config['num_posts'] / 5), 20000)) : 20000; $db->sql_query('UPDATE ' . USERS_TABLE . ' SET user_posts = 0'); while ($start < $max_post_id) { $sql = 'SELECT COUNT(post_id) AS num_posts, poster_id FROM ' . POSTS_TABLE . ' WHERE post_id BETWEEN ' . ($start + 1) . ' AND ' . ($start + $step) . ' AND post_postcount = 1 AND post_visibility = ' . ITEM_APPROVED . ' GROUP BY poster_id'; $result = $db->sql_query($sql); if ($row = $db->sql_fetchrow($result)) { do { $sql = 'UPDATE ' . USERS_TABLE . " SET user_posts = user_posts + {$row['num_posts']} WHERE user_id = {$row['poster_id']}"; $db->sql_query($sql); } while ($row = $db->sql_fetchrow($result)); } $db->sql_freeresult($result); $start += $step; } add_log('admin', 'LOG_RESYNC_POSTCOUNTS'); if ($request->is_ajax()) { trigger_error('RESYNC_POSTCOUNTS_SUCCESS'); } break; case 'date': if (!$auth->acl_get('a_board')) { trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } set_config('board_startdate', time() - 1); add_log('admin', 'LOG_RESET_DATE'); if ($request->is_ajax()) { trigger_error('RESET_DATE_SUCCESS'); } break; case 'db_track': switch ($db->get_sql_layer()) { case 'sqlite': case 'sqlite3': $db->sql_query('DELETE FROM ' . TOPICS_POSTED_TABLE); break; default: $db->sql_query('TRUNCATE TABLE ' . TOPICS_POSTED_TABLE); break; } // This can get really nasty... therefore we only do the last six months $get_from_time = time() - (6 * 4 * 7 * 24 * 60 * 60); // Select forum ids, do not include categories $sql = 'SELECT forum_id FROM ' . FORUMS_TABLE . ' WHERE forum_type <> ' . FORUM_CAT; $result = $db->sql_query($sql); $forum_ids = array(); while ($row = $db->sql_fetchrow($result)) { $forum_ids[] = $row['forum_id']; } $db->sql_freeresult($result); // Any global announcements? ;) $forum_ids[] = 0; // Now go through the forums and get us some topics... foreach ($forum_ids as $forum_id) { $sql = 'SELECT p.poster_id, p.topic_id FROM ' . POSTS_TABLE . ' p, ' . TOPICS_TABLE . ' t WHERE t.forum_id = ' . $forum_id . ' AND t.topic_moved_id = 0 AND t.topic_last_post_time > ' . $get_from_time . ' AND t.topic_id = p.topic_id AND p.poster_id <> ' . ANONYMOUS . ' GROUP BY p.poster_id, p.topic_id'; $result = $db->sql_query($sql); $posted = array(); while ($row = $db->sql_fetchrow($result)) { $posted[$row['poster_id']][] = $row['topic_id']; } $db->sql_freeresult($result); $sql_ary = array(); foreach ($posted as $user_id => $topic_row) { foreach ($topic_row as $topic_id) { $sql_ary[] = array( 'user_id' => (int) $user_id, 'topic_id' => (int) $topic_id, 'topic_posted' => 1, ); } } unset($posted); if (sizeof($sql_ary)) { $db->sql_multi_insert(TOPICS_POSTED_TABLE, $sql_ary); } } add_log('admin', 'LOG_RESYNC_POST_MARKING'); if ($request->is_ajax()) { trigger_error('RESYNC_POST_MARKING_SUCCESS'); } break; case 'purge_cache': $config->increment('assets_version', 1); $cache->purge(); // Clear permissions $auth->acl_clear_prefetch(); phpbb_cache_moderators($db, $cache, $auth); add_log('admin', 'LOG_PURGE_CACHE'); if ($request->is_ajax()) { trigger_error('PURGE_CACHE_SUCCESS'); } break; case 'purge_sessions': if ((int) $user->data['user_type'] !== USER_FOUNDER) { trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } $tables = array(CONFIRM_TABLE, SESSIONS_TABLE); foreach ($tables as $table) { switch ($db->get_sql_layer()) { case 'sqlite': case 'sqlite3': $db->sql_query("DELETE FROM $table"); break; default: $db->sql_query("TRUNCATE TABLE $table"); break; } } // let's restore the admin session $reinsert_ary = array( 'session_id' => (string) $user->session_id, 'session_page' => (string) substr($user->page['page'], 0, 199), 'session_forum_id' => $user->page['forum'], 'session_user_id' => (int) $user->data['user_id'], 'session_start' => (int) $user->data['session_start'], 'session_last_visit' => (int) $user->data['session_last_visit'], 'session_time' => (int) $user->time_now, 'session_browser' => (string) trim(substr($user->browser, 0, 149)), 'session_forwarded_for' => (string) $user->forwarded_for, 'session_ip' => (string) $user->ip, 'session_autologin' => (int) $user->data['session_autologin'], 'session_admin' => 1, 'session_viewonline' => (int) $user->data['session_viewonline'], ); $sql = 'INSERT INTO ' . SESSIONS_TABLE . ' ' . $db->sql_build_array('INSERT', $reinsert_ary); $db->sql_query($sql); add_log('admin', 'LOG_PURGE_SESSIONS'); if ($request->is_ajax()) { trigger_error('PURGE_SESSIONS_SUCCESS'); } break; } } } // Version check $user->add_lang('install'); if ($auth->acl_get('a_server') && version_compare(PHP_VERSION, '5.3.3', '<')) { $template->assign_vars(array( 'S_PHP_VERSION_OLD' => true, 'L_PHP_VERSION_OLD' => sprintf($user->lang['PHP_VERSION_OLD'], '<a href="https://www.phpbb.com/community/viewtopic.php?f=14&t=2152375">', '</a>'), )); } $version_helper = $phpbb_container->get('version_helper'); try { $recheck = $request->variable('versioncheck_force', false); $updates_available = $version_helper->get_suggested_updates($recheck); $template->assign_var('S_VERSION_UP_TO_DATE', empty($updates_available)); } catch (\RuntimeException $e) { $template->assign_vars(array( 'S_VERSIONCHECK_FAIL' => true, 'VERSIONCHECK_FAIL_REASON' => ($e->getMessage() !== $user->lang('VERSIONCHECK_FAIL')) ? $e->getMessage() : '', )); } /** * Notice admin * * @event core.acp_main_notice * @since 3.1.0-RC3 */ $phpbb_dispatcher->dispatch('core.acp_main_notice'); // Get forum statistics $total_posts = $config['num_posts']; $total_topics = $config['num_topics']; $total_users = $config['num_users']; $total_files = $config['num_files']; $start_date = $user->format_date($config['board_startdate']); $boarddays = (time() - $config['board_startdate']) / 86400; $posts_per_day = sprintf('%.2f', $total_posts / $boarddays); $topics_per_day = sprintf('%.2f', $total_topics / $boarddays); $users_per_day = sprintf('%.2f', $total_users / $boarddays); $files_per_day = sprintf('%.2f', $total_files / $boarddays); $upload_dir_size = get_formatted_filesize($config['upload_dir_size']); $avatar_dir_size = 0; if ($avatar_dir = @opendir($phpbb_root_path . $config['avatar_path'])) { while (($file = readdir($avatar_dir)) !== false) { if ($file[0] != '.' && $file != 'CVS' && strpos($file, 'index.') === false) { $avatar_dir_size += filesize($phpbb_root_path . $config['avatar_path'] . '/' . $file); } } closedir($avatar_dir); $avatar_dir_size = get_formatted_filesize($avatar_dir_size); } else { // Couldn't open Avatar dir. $avatar_dir_size = $user->lang['NOT_AVAILABLE']; } if ($posts_per_day > $total_posts) { $posts_per_day = $total_posts; } if ($topics_per_day > $total_topics) { $topics_per_day = $total_topics; } if ($users_per_day > $total_users) { $users_per_day = $total_users; } if ($files_per_day > $total_files) { $files_per_day = $total_files; } if ($config['allow_attachments'] || $config['allow_pm_attach']) { $sql = 'SELECT COUNT(attach_id) AS total_orphan FROM ' . ATTACHMENTS_TABLE . ' WHERE is_orphan = 1 AND filetime < ' . (time() - 3*60*60); $result = $db->sql_query($sql); $total_orphan = (int) $db->sql_fetchfield('total_orphan'); $db->sql_freeresult($result); } else { $total_orphan = false; } $dbsize = get_database_size(); $template->assign_vars(array( 'TOTAL_POSTS' => $total_posts, 'POSTS_PER_DAY' => $posts_per_day, 'TOTAL_TOPICS' => $total_topics, 'TOPICS_PER_DAY' => $topics_per_day, 'TOTAL_USERS' => $total_users, 'USERS_PER_DAY' => $users_per_day, 'TOTAL_FILES' => $total_files, 'FILES_PER_DAY' => $files_per_day, 'START_DATE' => $start_date, 'AVATAR_DIR_SIZE' => $avatar_dir_size, 'DBSIZE' => $dbsize, 'UPLOAD_DIR_SIZE' => $upload_dir_size, 'TOTAL_ORPHAN' => $total_orphan, 'S_TOTAL_ORPHAN' => ($total_orphan === false) ? false : true, 'GZIP_COMPRESSION' => ($config['gzip_compress'] && @extension_loaded('zlib')) ? $user->lang['ON'] : $user->lang['OFF'], 'DATABASE_INFO' => $db->sql_server_info(), 'BOARD_VERSION' => $config['version'], 'U_ACTION' => $this->u_action, 'U_ADMIN_LOG' => append_sid("{$phpbb_admin_path}index.$phpEx", 'i=logs&mode=admin'), 'U_INACTIVE_USERS' => append_sid("{$phpbb_admin_path}index.$phpEx", 'i=inactive&mode=list'), 'U_VERSIONCHECK' => append_sid("{$phpbb_admin_path}index.$phpEx", 'i=update&mode=version_check'), 'U_VERSIONCHECK_FORCE' => append_sid("{$phpbb_admin_path}index.$phpEx", 'versioncheck_force=1'), 'S_ACTION_OPTIONS' => ($auth->acl_get('a_board')) ? true : false, 'S_FOUNDER' => ($user->data['user_type'] == USER_FOUNDER) ? true : false, ) ); $log_data = array(); $log_count = false; if ($auth->acl_get('a_viewlogs')) { view_log('admin', $log_data, $log_count, 5); foreach ($log_data as $row) { $template->assign_block_vars('log', array( 'USERNAME' => $row['username_full'], 'IP' => $row['ip'], 'DATE' => $user->format_date($row['time']), 'ACTION' => $row['action']) ); } } if ($auth->acl_get('a_user')) { $user->add_lang('memberlist'); $inactive = array(); $inactive_count = 0; view_inactive_users($inactive, $inactive_count, 10); foreach ($inactive as $row) { $template->assign_block_vars('inactive', array( 'INACTIVE_DATE' => $user->format_date($row['user_inactive_time']), 'REMINDED_DATE' => $user->format_date($row['user_reminded_time']), 'JOINED' => $user->format_date($row['user_regdate']), 'LAST_VISIT' => (!$row['user_lastvisit']) ? ' - ' : $user->format_date($row['user_lastvisit']), 'REASON' => $row['inactive_reason'], 'USER_ID' => $row['user_id'], 'POSTS' => ($row['user_posts']) ? $row['user_posts'] : 0, 'REMINDED' => $row['user_reminded'], 'REMINDED_EXPLAIN' => $user->lang('USER_LAST_REMINDED', (int) $row['user_reminded'], $user->format_date($row['user_reminded_time'])), 'USERNAME_FULL' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour'], false, append_sid("{$phpbb_admin_path}index.$phpEx", 'i=users&mode=overview')), 'USERNAME' => get_username_string('username', $row['user_id'], $row['username'], $row['user_colour']), 'USER_COLOR' => get_username_string('colour', $row['user_id'], $row['username'], $row['user_colour']), 'U_USER_ADMIN' => append_sid("{$phpbb_admin_path}index.$phpEx", "i=users&mode=overview&u={$row['user_id']}"), 'U_SEARCH_USER' => ($auth->acl_get('u_search')) ? append_sid("{$phpbb_root_path}search.$phpEx", "author_id={$row['user_id']}&sr=posts") : '', )); } $option_ary = array('activate' => 'ACTIVATE', 'delete' => 'DELETE'); if ($config['email_enable']) { $option_ary += array('remind' => 'REMIND'); } $template->assign_vars(array( 'S_INACTIVE_USERS' => true, 'S_INACTIVE_OPTIONS' => build_select($option_ary)) ); } // Warn if install is still present if (file_exists($phpbb_root_path . 'install') && !is_file($phpbb_root_path . 'install')) { $template->assign_var('S_REMOVE_INSTALL', true); } // Warn if no search index is created if ($config['num_posts'] && class_exists($config['search_type'])) { $error = false; $search_type = $config['search_type']; $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher); if (!$search->index_created()) { $template->assign_vars(array( 'S_SEARCH_INDEX_MISSING' => true, 'L_NO_SEARCH_INDEX' => $user->lang('NO_SEARCH_INDEX', $search->get_name(), '<a href="' . append_sid("{$phpbb_admin_path}index.$phpEx", 'i=acp_search&mode=index') . '">', '</a>'), )); } } if (!defined('PHPBB_DISABLE_CONFIG_CHECK') && file_exists($phpbb_root_path . 'config.' . $phpEx) && phpbb_is_writable($phpbb_root_path . 'config.' . $phpEx)) { // World-Writable? (000x) $template->assign_var('S_WRITABLE_CONFIG', (bool) (@fileperms($phpbb_root_path . 'config.' . $phpEx) & 0x0002)); } if (extension_loaded('mbstring')) { $template->assign_vars(array( 'S_MBSTRING_LOADED' => true, 'S_MBSTRING_FUNC_OVERLOAD_FAIL' => (intval(@ini_get('mbstring.func_overload')) & (MB_OVERLOAD_MAIL | MB_OVERLOAD_STRING)), 'S_MBSTRING_ENCODING_TRANSLATION_FAIL' => (@ini_get('mbstring.encoding_translation') != 0), 'S_MBSTRING_HTTP_INPUT_FAIL' => !in_array(@ini_get('mbstring.http_input'), array('pass', '')), 'S_MBSTRING_HTTP_OUTPUT_FAIL' => !in_array(@ini_get('mbstring.http_output'), array('pass', '')), )); } // Fill dbms version if not yet filled if (empty($config['dbms_version'])) { set_config('dbms_version', $db->sql_server_info(true)); } $this->tpl_name = 'acp_main'; $this->page_title = 'ACP_MAIN'; } } acp_prune.php000077700000041423151514745240007254 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_prune { var $u_action; function main($id, $mode) { global $user, $phpEx, $phpbb_admin_path, $phpbb_root_path; $user->add_lang('acp/prune'); include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx); switch ($mode) { case 'forums': $this->tpl_name = 'acp_prune_forums'; $this->page_title = 'ACP_PRUNE_FORUMS'; $this->prune_forums($id, $mode); break; case 'users': $this->tpl_name = 'acp_prune_users'; $this->page_title = 'ACP_PRUNE_USERS'; $this->prune_users($id, $mode); break; } } /** * Prune forums */ function prune_forums($id, $mode) { global $db, $user, $auth, $template, $cache; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; $all_forums = request_var('all_forums', 0); $forum_id = request_var('f', array(0)); $submit = (isset($_POST['submit'])) ? true : false; if ($all_forums) { $sql = 'SELECT forum_id FROM ' . FORUMS_TABLE . ' ORDER BY left_id'; $result = $db->sql_query($sql); $forum_id = array(); while ($row = $db->sql_fetchrow($result)) { $forum_id[] = $row['forum_id']; } $db->sql_freeresult($result); } if ($submit) { if (confirm_box(true)) { $prune_posted = request_var('prune_days', 0); $prune_viewed = request_var('prune_vieweddays', 0); $prune_all = (!$prune_posted && !$prune_viewed) ? true : false; $prune_flags = 0; $prune_flags += (request_var('prune_old_polls', 0)) ? 2 : 0; $prune_flags += (request_var('prune_announce', 0)) ? 4 : 0; $prune_flags += (request_var('prune_sticky', 0)) ? 8 : 0; // Convert days to seconds for timestamp functions... $prunedate_posted = time() - ($prune_posted * 86400); $prunedate_viewed = time() - ($prune_viewed * 86400); $template->assign_vars(array( 'S_PRUNED' => true) ); $sql_forum = (sizeof($forum_id)) ? ' AND ' . $db->sql_in_set('forum_id', $forum_id) : ''; // Get a list of forum's or the data for the forum that we are pruning. $sql = 'SELECT forum_id, forum_name FROM ' . FORUMS_TABLE . ' WHERE forum_type = ' . FORUM_POST . " $sql_forum ORDER BY left_id ASC"; $result = $db->sql_query($sql); if ($row = $db->sql_fetchrow($result)) { $prune_ids = array(); $p_result['topics'] = 0; $p_result['posts'] = 0; $log_data = ''; do { if (!$auth->acl_get('f_list', $row['forum_id'])) { continue; } if ($prune_all) { $p_result = prune($row['forum_id'], 'posted', time(), $prune_flags, false); } else { if ($prune_posted) { $return = prune($row['forum_id'], 'posted', $prunedate_posted, $prune_flags, false); $p_result['topics'] += $return['topics']; $p_result['posts'] += $return['posts']; } if ($prune_viewed) { $return = prune($row['forum_id'], 'viewed', $prunedate_viewed, $prune_flags, false); $p_result['topics'] += $return['topics']; $p_result['posts'] += $return['posts']; } } $prune_ids[] = $row['forum_id']; $template->assign_block_vars('pruned', array( 'FORUM_NAME' => $row['forum_name'], 'NUM_TOPICS' => $p_result['topics'], 'NUM_POSTS' => $p_result['posts']) ); $log_data .= (($log_data != '') ? ', ' : '') . $row['forum_name']; } while ($row = $db->sql_fetchrow($result)); // Sync all pruned forums at once sync('forum', 'forum_id', $prune_ids, true, true); add_log('admin', 'LOG_PRUNE', $log_data); } $db->sql_freeresult($result); return; } else { confirm_box(false, $user->lang['PRUNE_FORUM_CONFIRM'], build_hidden_fields(array( 'i' => $id, 'mode' => $mode, 'submit' => 1, 'all_forums' => $all_forums, 'f' => $forum_id, 'prune_days' => request_var('prune_days', 0), 'prune_vieweddays' => request_var('prune_vieweddays', 0), 'prune_old_polls' => request_var('prune_old_polls', 0), 'prune_announce' => request_var('prune_announce', 0), 'prune_sticky' => request_var('prune_sticky', 0), ))); } } // If they haven't selected a forum for pruning yet then // display a select box to use for pruning. if (!sizeof($forum_id)) { $template->assign_vars(array( 'U_ACTION' => $this->u_action, 'S_SELECT_FORUM' => true, 'S_FORUM_OPTIONS' => make_forum_select(false, false, false)) ); } else { $sql = 'SELECT forum_id, forum_name FROM ' . FORUMS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_id); $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); if (!$row) { $db->sql_freeresult($result); trigger_error($user->lang['NO_FORUM'] . adm_back_link($this->u_action), E_USER_WARNING); } $forum_list = $s_hidden_fields = ''; do { $forum_list .= (($forum_list != '') ? ', ' : '') . '<b>' . $row['forum_name'] . '</b>'; $s_hidden_fields .= '<input type="hidden" name="f[]" value="' . $row['forum_id'] . '" />'; } while ($row = $db->sql_fetchrow($result)); $db->sql_freeresult($result); $l_selected_forums = (sizeof($forum_id) == 1) ? 'SELECTED_FORUM' : 'SELECTED_FORUMS'; $template->assign_vars(array( 'L_SELECTED_FORUMS' => $user->lang[$l_selected_forums], 'U_ACTION' => $this->u_action, 'U_BACK' => $this->u_action, 'FORUM_LIST' => $forum_list, 'S_HIDDEN_FIELDS' => $s_hidden_fields) ); } } /** * Prune users */ function prune_users($id, $mode) { global $db, $user, $auth, $template, $cache; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; $user->add_lang('memberlist'); $prune = (isset($_POST['prune'])) ? true : false; if ($prune) { $action = request_var('action', 'deactivate'); $deleteposts = request_var('deleteposts', 0); if (confirm_box(true)) { $user_ids = $usernames = array(); $this->get_prune_users($user_ids, $usernames); if (sizeof($user_ids)) { if ($action == 'deactivate') { user_active_flip('deactivate', $user_ids); $l_log = 'LOG_PRUNE_USER_DEAC'; } else if ($action == 'delete') { if ($deleteposts) { user_delete('remove', $user_ids); $l_log = 'LOG_PRUNE_USER_DEL_DEL'; } else { user_delete('retain', $user_ids, true); $l_log = 'LOG_PRUNE_USER_DEL_ANON'; } } add_log('admin', $l_log, implode(', ', $usernames)); $msg = $user->lang['USER_' . strtoupper($action) . '_SUCCESS']; } else { $msg = $user->lang['USER_PRUNE_FAILURE']; } trigger_error($msg . adm_back_link($this->u_action)); } else { // We list the users which will be pruned... $user_ids = $usernames = array(); $this->get_prune_users($user_ids, $usernames); if (!sizeof($user_ids)) { trigger_error($user->lang['USER_PRUNE_FAILURE'] . adm_back_link($this->u_action), E_USER_WARNING); } // Assign to template foreach ($user_ids as $user_id) { $template->assign_block_vars('users', array( 'USERNAME' => $usernames[$user_id], 'USER_ID' => $user_id, 'U_PROFILE' => get_username_string('profile', $user_id, $usernames[$user_id]), 'U_USER_ADMIN' => ($auth->acl_get('a_user')) ? append_sid("{$phpbb_admin_path}index.$phpEx", 'i=users&mode=overview&u=' . $user_id, true, $user->session_id) : '', )); } $template->assign_vars(array( 'S_DEACTIVATE' => ($action == 'deactivate') ? true : false, 'S_DELETE' => ($action == 'delete') ? true : false, )); confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 'i' => $id, 'mode' => $mode, 'prune' => 1, 'deleteposts' => request_var('deleteposts', 0), 'action' => request_var('action', ''), )), 'confirm_body_prune.html'); } } $find_count = array('lt' => $user->lang['LESS_THAN'], 'eq' => $user->lang['EQUAL_TO'], 'gt' => $user->lang['MORE_THAN']); $s_find_count = ''; foreach ($find_count as $key => $value) { $selected = ($key == 'eq') ? ' selected="selected"' : ''; $s_find_count .= '<option value="' . $key . '"' . $selected . '>' . $value . '</option>'; } $find_time = array('lt' => $user->lang['BEFORE'], 'gt' => $user->lang['AFTER']); $s_find_active_time = ''; foreach ($find_time as $key => $value) { $s_find_active_time .= '<option value="' . $key . '">' . $value . '</option>'; } $sql = 'SELECT group_id, group_name FROM ' . GROUPS_TABLE . ' WHERE group_type <> ' . GROUP_SPECIAL . ' ORDER BY group_name ASC'; $result = $db->sql_query($sql); $s_group_list = ''; while ($row = $db->sql_fetchrow($result)) { $s_group_list .= '<option value="' . $row['group_id'] . '">' . $row['group_name'] . '</option>'; } $db->sql_freeresult($result); if ($s_group_list) { // Only prepend the "All groups" option if there are groups, // otherwise we don't want to display this option at all. $s_group_list = '<option value="0">' . $user->lang['PRUNE_USERS_GROUP_NONE'] . '</option>' . $s_group_list; } $template->assign_vars(array( 'U_ACTION' => $this->u_action, 'S_ACTIVE_OPTIONS' => $s_find_active_time, 'S_GROUP_LIST' => $s_group_list, 'S_COUNT_OPTIONS' => $s_find_count, 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=acp_prune&field=users'), )); } /** * Get user_ids/usernames from those being pruned */ function get_prune_users(&$user_ids, &$usernames) { global $user, $db, $request; $users_by_name = request_var('users', '', true); $users_by_id = request_var('user_ids', array(0)); $group_id = request_var('group_id', 0); $posts_on_queue = (trim($request->variable('posts_on_queue', '')) === '') ? false : $request->variable('posts_on_queue', 0); if ($users_by_name) { $users = explode("\n", $users_by_name); $where_sql = ' AND ' . $db->sql_in_set('username_clean', array_map('utf8_clean_string', $users)); } else if (!empty($users_by_id)) { $user_ids = $users_by_id; user_get_id_name($user_ids, $usernames); $where_sql = ' AND ' . $db->sql_in_set('user_id', $user_ids); } else { $username = request_var('username', '', true); $email = request_var('email', ''); $active_select = request_var('active_select', 'lt'); $count_select = request_var('count_select', 'eq'); $queue_select = request_var('queue_select', 'gt'); $joined_before = request_var('joined_before', ''); $joined_after = request_var('joined_after', ''); $active = request_var('active', ''); $count = ($request->variable('count', '') === '') ? false : $request->variable('count', 0); $active = ($active) ? explode('-', $active) : array(); $joined_before = ($joined_before) ? explode('-', $joined_before) : array(); $joined_after = ($joined_after) ? explode('-', $joined_after) : array(); // calculate the conditions required by the join time criteria $joined_sql = ''; if (!empty($joined_before) && !empty($joined_after)) { // if the two entered dates are equal, we need to adjust // so that our time range is a full day instead of 1 second if ($joined_after == $joined_before) { $joined_after[2] += 1; } $joined_sql = ' AND user_regdate BETWEEN ' . gmmktime(0, 0, 0, (int) $joined_after[1], (int) $joined_after[2], (int) $joined_after[0]) . ' AND ' . gmmktime(0, 0, 0, (int) $joined_before[1], (int) $joined_before[2], (int) $joined_before[0]); } else if (empty($joined_before) && !empty($joined_after)) { $joined_sql = ' AND user_regdate > ' . gmmktime(0, 0, 0, (int) $joined_after[1], (int) $joined_after[2], (int) $joined_after[0]); } else if (empty($joined_after) && !empty($joined_before)) { $joined_sql = ' AND user_regdate < ' . gmmktime(0, 0, 0, (int) $joined_before[1], (int) $joined_before[2], (int) $joined_before[0]); } // implicit else when both arrays are empty do nothing if ((sizeof($active) && sizeof($active) != 3) || (sizeof($joined_before) && sizeof($joined_before) != 3) || (sizeof($joined_after) && sizeof($joined_after) != 3)) { trigger_error($user->lang['WRONG_ACTIVE_JOINED_DATE'] . adm_back_link($this->u_action), E_USER_WARNING); } $key_match = array('lt' => '<', 'gt' => '>', 'eq' => '='); $sort_by_types = array('username', 'user_email', 'user_posts', 'user_regdate', 'user_lastvisit'); $where_sql = ''; $where_sql .= ($username) ? ' AND username_clean ' . $db->sql_like_expression(str_replace('*', $db->get_any_char(), utf8_clean_string($username))) : ''; $where_sql .= ($email) ? ' AND user_email ' . $db->sql_like_expression(str_replace('*', $db->get_any_char(), $email)) . ' ' : ''; $where_sql .= $joined_sql; $where_sql .= ($count !== false) ? " AND user_posts " . $key_match[$count_select] . ' ' . (int) $count . ' ' : ''; // First handle pruning of users who never logged in, last active date is 0000-00-00 if (sizeof($active) && (int) $active[0] == 0 && (int) $active[1] == 0 && (int) $active[2] == 0) { $where_sql .= ' AND user_lastvisit = 0'; } else if (sizeof($active) && $active_select != 'lt') { $where_sql .= ' AND user_lastvisit ' . $key_match[$active_select] . ' ' . gmmktime(0, 0, 0, (int) $active[1], (int) $active[2], (int) $active[0]); } else if (sizeof($active)) { $where_sql .= ' AND (user_lastvisit > 0 AND user_lastvisit < ' . gmmktime(0, 0, 0, (int) $active[1], (int) $active[2], (int) $active[0]) . ')'; } } // If no search criteria were provided, go no further. if (!$where_sql && !$group_id && $posts_on_queue === false) { return; } // Get bot ids $sql = 'SELECT user_id FROM ' . BOTS_TABLE; $result = $db->sql_query($sql); $bot_ids = array(); while ($row = $db->sql_fetchrow($result)) { $bot_ids[] = $row['user_id']; } $db->sql_freeresult($result); // Protect the admin, do not prune if no options are given... if ($where_sql) { // Do not prune founder members $sql = 'SELECT user_id, username FROM ' . USERS_TABLE . ' WHERE user_id <> ' . ANONYMOUS . ' AND user_type <> ' . USER_FOUNDER . " $where_sql"; $result = $db->sql_query($sql); $user_ids = $usernames = array(); while ($row = $db->sql_fetchrow($result)) { // Do not prune bots and the user currently pruning. if ($row['user_id'] != $user->data['user_id'] && !in_array($row['user_id'], $bot_ids)) { $user_ids[] = $row['user_id']; $usernames[$row['user_id']] = $row['username']; } } $db->sql_freeresult($result); } if ($group_id) { $sql = 'SELECT u.user_id, u.username FROM ' . USER_GROUP_TABLE . ' ug, ' . USERS_TABLE . ' u WHERE ug.group_id = ' . (int) $group_id . ' AND ug.user_id <> ' . ANONYMOUS . ' AND u.user_type <> ' . USER_FOUNDER . ' AND ug.user_pending = 0 AND u.user_id = ug.user_id ' . (!empty($user_ids) ? ' AND ' . $db->sql_in_set('ug.user_id', $user_ids) : ''); $result = $db->sql_query($sql); // we're performing an intersection operation, so all the relevant users // come from this most recent query (which was limited to the results of the // previous query) $user_ids = $usernames = array(); while ($row = $db->sql_fetchrow($result)) { // Do not prune bots and the user currently pruning. if ($row['user_id'] != $user->data['user_id'] && !in_array($row['user_id'], $bot_ids)) { $user_ids[] = $row['user_id']; $usernames[$row['user_id']] = $row['username']; } } $db->sql_freeresult($result); } if ($posts_on_queue !== false) { $sql = 'SELECT u.user_id, u.username, COUNT(p.post_id) AS queue_posts FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u WHERE u.user_id <> ' . ANONYMOUS . ' AND u.user_type <> ' . USER_FOUNDER . ' AND ' . $db->sql_in_set('p.post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE)) . ' AND u.user_id = p.poster_id ' . (!empty($user_ids) ? ' AND ' . $db->sql_in_set('p.poster_id', $user_ids) : '') . ' GROUP BY p.poster_id HAVING queue_posts ' . $key_match[$queue_select] . ' ' . $posts_on_queue; $result = $db->sql_query($sql); // same intersection logic as the above group ID portion $user_ids = $usernames = array(); while ($row = $db->sql_fetchrow($result)) { // Do not prune bots and the user currently pruning. if ($row['user_id'] != $user->data['user_id'] && !in_array($row['user_id'], $bot_ids)) { $user_ids[] = $row['user_id']; $usernames[$row['user_id']] = $row['username']; } } $db->sql_freeresult($result); } } } acp_styles.php000077700000101774151514745240007454 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_styles { public $u_action; protected $u_base_action; protected $s_hidden_fields; protected $mode; protected $styles_path; protected $styles_path_absolute = 'styles'; protected $default_style = 0; protected $styles_list_cols = 0; protected $reserved_style_names = array('adm', 'admin', 'all'); /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var \phpbb\user */ protected $user; /** @var \phpbb\template\template */ protected $template; /** @var \phpbb\request\request_interface */ protected $request; /** @var \phpbb\cache\driver\driver_interface */ protected $cache; /** @var \phpbb\auth\auth */ protected $auth; /** @var string */ protected $phpbb_root_path; /** @var string */ protected $php_ext; public function main($id, $mode) { global $db, $user, $phpbb_admin_path, $phpbb_root_path, $phpEx, $template, $request, $cache, $auth, $config; $this->db = $db; $this->user = $user; $this->template = $template; $this->request = $request; $this->cache = $cache; $this->auth = $auth; $this->config = $config; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $phpEx; $this->default_style = $config['default_style']; $this->styles_path = $this->phpbb_root_path . $this->styles_path_absolute . '/'; $this->u_base_action = append_sid("{$phpbb_admin_path}index.{$this->php_ext}", "i={$id}"); $this->s_hidden_fields = array( 'mode' => $mode, ); $this->user->add_lang('acp/styles'); $this->tpl_name = 'acp_styles'; $this->page_title = 'ACP_CAT_STYLES'; $this->mode = $mode; $action = $this->request->variable('action', ''); $post_actions = array('install', 'activate', 'deactivate', 'uninstall'); foreach ($post_actions as $key) { if ($this->request->is_set_post($key)) { $action = $key; } } // The uninstall action uses confirm_box() to verify the validity of the request, // so there is no need to check for a valid token here. if (in_array($action, $post_actions) && $action != 'uninstall') { $is_valid_request = check_link_hash($request->variable('hash', ''), $action) || check_form_key('styles_management'); if (!$is_valid_request) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } } if ($action != '') { $this->s_hidden_fields['action'] = $action; } $this->template->assign_vars(array( 'U_ACTION' => $this->u_base_action, 'S_HIDDEN_FIELDS' => build_hidden_fields($this->s_hidden_fields) ) ); // Execute actions switch ($action) { case 'install': $this->action_install(); return; case 'uninstall': $this->action_uninstall(); return; case 'activate': $this->action_activate(); return; case 'deactivate': $this->action_deactivate(); return; case 'details': $this->action_details(); return; default: $this->frontend(); } } /** * Main page */ protected function frontend() { add_form_key('styles_management'); // Check mode switch ($this->mode) { case 'style': $this->welcome_message('ACP_STYLES', 'ACP_STYLES_EXPLAIN'); $this->show_installed(); return; case 'install': $this->welcome_message('INSTALL_STYLES', 'INSTALL_STYLES_EXPLAIN'); $this->show_available(); return; } trigger_error($this->user->lang['NO_MODE'] . adm_back_link($this->u_action), E_USER_WARNING); } /** * Install style(s) */ protected function action_install() { // Get list of styles to install $dirs = $this->request_vars('dir', '', true); // Get list of styles that can be installed $styles = $this->find_available(false); // Install each style $messages = array(); $installed_names = array(); $installed_dirs = array(); $last_installed = false; foreach ($dirs as $dir) { if (in_array($dir, $this->reserved_style_names)) { $messages[] = $this->user->lang('STYLE_NAME_RESERVED', htmlspecialchars($dir)); continue; } $found = false; foreach ($styles as &$style) { // Check if: // 1. Directory matches directory we are looking for // 2. Style is not installed yet // 3. Style with same name or directory hasn't been installed already within this function if ($style['style_path'] == $dir && empty($style['_installed']) && !in_array($style['style_path'], $installed_dirs) && !in_array($style['style_name'], $installed_names)) { // Install style $style['style_active'] = 1; $style['style_id'] = $this->install_style($style); $style['_installed'] = true; $found = true; $last_installed = $style['style_id']; $installed_names[] = $style['style_name']; $installed_dirs[] = $style['style_path']; $messages[] = sprintf($this->user->lang['STYLE_INSTALLED'], htmlspecialchars($style['style_name'])); } } if (!$found) { $messages[] = sprintf($this->user->lang['STYLE_NOT_INSTALLED'], htmlspecialchars($dir)); } } // Show message if (!count($messages)) { trigger_error($this->user->lang['NO_MATCHING_STYLES_FOUND'] . adm_back_link($this->u_action), E_USER_WARNING); } $message = implode('<br />', $messages); $message .= '<br /><br /><a href="' . $this->u_base_action . '&mode=style' . '">« ' . $this->user->lang('STYLE_INSTALLED_RETURN_INSTALLED_STYLES') . '</a>'; $message .= '<br /><br /><a href="' . $this->u_base_action . '&mode=install' . '">» ' . $this->user->lang('STYLE_INSTALLED_RETURN_UNINSTALLED_STYLES') . '</a>'; trigger_error($message, E_USER_NOTICE); } /** * Confirm styles removal */ protected function action_uninstall() { // Get list of styles to uninstall $ids = $this->request_vars('id', 0, true); // Check if confirmation box was submitted if (confirm_box(true)) { // Uninstall $this->action_uninstall_confirmed($ids, $this->request->variable('confirm_delete_files', false)); return; } // Confirm box $s_hidden = build_hidden_fields(array( 'action' => 'uninstall', 'ids' => $ids )); $this->template->assign_var('S_CONFIRM_DELETE', true); confirm_box(false, $this->user->lang['CONFIRM_UNINSTALL_STYLES'], $s_hidden, 'acp_styles.html'); // Canceled - show styles list $this->frontend(); } /** * Uninstall styles(s) * * @param array $ids List of style IDs * @param bool $delete_files If true, script will attempt to remove files for selected styles */ protected function action_uninstall_confirmed($ids, $delete_files) { $default = $this->default_style; $uninstalled = array(); $messages = array(); // Check styles list foreach ($ids as $id) { if (!$id) { trigger_error($this->user->lang['INVALID_STYLE_ID'] . adm_back_link($this->u_action), E_USER_WARNING); } if ($id == $default) { trigger_error($this->user->lang['UNINSTALL_DEFAULT'] . adm_back_link($this->u_action), E_USER_WARNING); } $uninstalled[$id] = false; } // Order by reversed style_id, so parent styles would be removed after child styles // This way parent and child styles can be removed in same function call $sql = 'SELECT * FROM ' . STYLES_TABLE . ' WHERE style_id IN (' . implode(', ', $ids) . ') ORDER BY style_id DESC'; $result = $this->db->sql_query($sql); $rows = $this->db->sql_fetchrowset($result); $this->db->sql_freeresult($result); // Uinstall each style $uninstalled = array(); foreach ($rows as $style) { $result = $this->uninstall_style($style, $delete_files); if (is_string($result)) { $messages[] = $result; continue; } $messages[] = sprintf($this->user->lang['STYLE_UNINSTALLED'], $style['style_name']); $uninstalled[] = $style['style_name']; // Attempt to delete files if ($delete_files) { $messages[] = sprintf($this->user->lang[$this->delete_style_files($style['style_path']) ? 'DELETE_STYLE_FILES_SUCCESS' : 'DELETE_STYLE_FILES_FAILED'], $style['style_name']); } } if (empty($messages)) { // Nothing to uninstall? trigger_error($this->user->lang['NO_MATCHING_STYLES_FOUND'] . adm_back_link($this->u_action), E_USER_WARNING); } // Log action if (count($uninstalled)) { add_log('admin', 'LOG_STYLE_DELETE', implode(', ', $uninstalled)); } // Clear cache $this->cache->purge(); // Show message trigger_error(implode('<br />', $messages) . adm_back_link($this->u_action), E_USER_NOTICE); } /** * Activate styles */ protected function action_activate() { // Get list of styles to activate $ids = $this->request_vars('id', 0, true); // Activate styles $sql = 'UPDATE ' . STYLES_TABLE . ' SET style_active = 1 WHERE style_id IN (' . implode(', ', $ids) . ')'; $this->db->sql_query($sql); // Purge cache $this->cache->destroy('sql', STYLES_TABLE); // Show styles list $this->frontend(); } /** * Deactivate styles */ protected function action_deactivate() { // Get list of styles to deactivate $ids = $this->request_vars('id', 0, true); // Check for default style foreach ($ids as $id) { if ($id == $this->default_style) { trigger_error($this->user->lang['DEACTIVATE_DEFAULT'] . adm_back_link($this->u_action), E_USER_WARNING); } } // Reset default style for users who use selected styles $sql = 'UPDATE ' . USERS_TABLE . ' SET user_style = 0 WHERE user_style IN (' . implode(', ', $ids) . ')'; $this->db->sql_query($sql); // Deactivate styles $sql = 'UPDATE ' . STYLES_TABLE . ' SET style_active = 0 WHERE style_id IN (' . implode(', ', $ids) . ')'; $this->db->sql_query($sql); // Purge cache $this->cache->destroy('sql', STYLES_TABLE); // Show styles list $this->frontend(); } /** * Show style details */ protected function action_details() { $id = $this->request->variable('id', 0); if (!$id) { trigger_error($this->user->lang['NO_MATCHING_STYLES_FOUND'] . adm_back_link($this->u_action), E_USER_WARNING); } // Get all styles $styles = $this->get_styles(); usort($styles, array($this, 'sort_styles')); // Find current style $style = false; foreach ($styles as $row) { if ($row['style_id'] == $id) { $style = $row; break; } } if ($style === false) { trigger_error($this->user->lang['NO_MATCHING_STYLES_FOUND'] . adm_back_link($this->u_action), E_USER_WARNING); } // Find all available parent styles $list = $this->find_possible_parents($styles, $id); // Add form key $form_key = 'acp_styles'; add_form_key($form_key); // Change data if ($this->request->variable('update', false)) { if (!check_form_key($form_key)) { trigger_error($this->user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } $update = array( 'style_name' => trim($this->request->variable('style_name', $style['style_name'])), 'style_parent_id' => $this->request->variable('style_parent', (int) $style['style_parent_id']), 'style_active' => $this->request->variable('style_active', (int) $style['style_active']), ); $update_action = $this->u_action . '&action=details&id=' . $id; // Check style name if ($update['style_name'] != $style['style_name']) { if (!strlen($update['style_name'])) { trigger_error($this->user->lang['STYLE_ERR_STYLE_NAME'] . adm_back_link($update_action), E_USER_WARNING); } foreach ($styles as $row) { if ($row['style_name'] == $update['style_name']) { trigger_error($this->user->lang['STYLE_ERR_NAME_EXIST'] . adm_back_link($update_action), E_USER_WARNING); } } } else { unset($update['style_name']); } // Check parent style id if ($update['style_parent_id'] != $style['style_parent_id']) { if ($update['style_parent_id'] != 0) { $found = false; foreach ($list as $row) { if ($row['style_id'] == $update['style_parent_id']) { $found = true; $update['style_parent_tree'] = ($row['style_parent_tree'] != '' ? $row['style_parent_tree'] . '/' : '') . $row['style_path']; break; } } if (!$found) { trigger_error($this->user->lang['STYLE_ERR_INVALID_PARENT'] . adm_back_link($update_action), E_USER_WARNING); } } else { $update['style_parent_tree'] = ''; } } else { unset($update['style_parent_id']); } // Check style_active if ($update['style_active'] != $style['style_active']) { if (!$update['style_active'] && $this->default_style == $style['style_id']) { trigger_error($this->user->lang['DEACTIVATE_DEFAULT'] . adm_back_link($update_action), E_USER_WARNING); } } else { unset($update['style_active']); } // Update data if (count($update)) { $sql = 'UPDATE ' . STYLES_TABLE . ' SET ' . $this->db->sql_build_array('UPDATE', $update) . " WHERE style_id = $id"; $this->db->sql_query($sql); $style = array_merge($style, $update); if (isset($update['style_parent_id'])) { // Update styles tree $styles = $this->get_styles(); if ($this->update_styles_tree($styles, $style)) { // Something was changed in styles tree, purge all cache $this->cache->purge(); } } add_log('admin', 'LOG_STYLE_EDIT_DETAILS', $style['style_name']); } // Update default style $default = $this->request->variable('style_default', 0); if ($default) { if (!$style['style_active']) { trigger_error($this->user->lang['STYLE_DEFAULT_CHANGE_INACTIVE'] . adm_back_link($update_action), E_USER_WARNING); } set_config('default_style', $id); $this->cache->purge(); } // Show styles list $this->frontend(); return; } // Show page title $this->welcome_message('ACP_STYLES', null); // Show parent styles foreach ($list as $row) { $this->template->assign_block_vars('parent_styles', array( 'STYLE_ID' => $row['style_id'], 'STYLE_NAME' => htmlspecialchars($row['style_name']), 'LEVEL' => $row['level'], 'SPACER' => str_repeat(' ', $row['level']), ) ); } // Show style details $this->template->assign_vars(array( 'S_STYLE_DETAILS' => true, 'STYLE_ID' => $style['style_id'], 'STYLE_NAME' => htmlspecialchars($style['style_name']), 'STYLE_PATH' => htmlspecialchars($style['style_path']), 'STYLE_COPYRIGHT' => strip_tags($style['style_copyright']), 'STYLE_PARENT' => $style['style_parent_id'], 'S_STYLE_ACTIVE' => $style['style_active'], 'S_STYLE_DEFAULT' => ($style['style_id'] == $this->default_style) ) ); } /** * List installed styles */ protected function show_installed() { // Get all installed styles $styles = $this->get_styles(); if (!count($styles)) { trigger_error($this->user->lang['NO_MATCHING_STYLES_FOUND'] . adm_back_link($this->u_action), E_USER_WARNING); } usort($styles, array($this, 'sort_styles')); // Get users $users = $this->get_users(); // Add users counter to rows foreach ($styles as &$style) { $style['_users'] = isset($users[$style['style_id']]) ? $users[$style['style_id']] : 0; } // Set up styles list variables // Addons should increase this number and update template variable $this->styles_list_cols = 4; $this->template->assign_var('STYLES_LIST_COLS', $this->styles_list_cols); // Show styles list $this->show_styles_list($styles, 0, 0); // Show styles with invalid inherits_id foreach ($styles as $style) { if (empty($style['_shown'])) { $style['_note'] = sprintf($this->user->lang['REQUIRES_STYLE'], htmlspecialchars($style['style_parent_tree'])); $this->list_style($style, 0); } } // Add buttons $this->template->assign_block_vars('extra_actions', array( 'ACTION_NAME' => 'activate', 'L_ACTION' => $this->user->lang['STYLE_ACTIVATE'], ) ); $this->template->assign_block_vars('extra_actions', array( 'ACTION_NAME' => 'deactivate', 'L_ACTION' => $this->user->lang['STYLE_DEACTIVATE'], ) ); if (isset($this->style_counters) && $this->style_counters['total'] > 1) { $this->template->assign_block_vars('extra_actions', array( 'ACTION_NAME' => 'uninstall', 'L_ACTION' => $this->user->lang['STYLE_UNINSTALL'], ) ); } } /** * Show list of styles that can be installed */ protected function show_available() { // Get list of styles $styles = $this->find_available(true); // Show styles if (empty($styles)) { trigger_error($this->user->lang['NO_UNINSTALLED_STYLE'] . adm_back_link($this->u_base_action), E_USER_NOTICE); } usort($styles, array($this, 'sort_styles')); $this->styles_list_cols = 3; $this->template->assign_vars(array( 'STYLES_LIST_COLS' => $this->styles_list_cols, 'STYLES_LIST_HIDE_COUNT' => true ) ); // Show styles foreach ($styles as &$style) { // Check if style has a parent style in styles list $has_parent = false; if ($style['_inherit_name'] != '') { foreach ($styles as $parent_style) { if ($parent_style['style_name'] == $style['_inherit_name'] && empty($parent_style['_shown'])) { // Show parent style first $has_parent = true; } } } if (!$has_parent) { $this->list_style($style, 0); $this->show_available_child_styles($styles, $style['style_name'], 1); } } // Show styles that do not have parent style in styles list foreach ($styles as $style) { if (empty($style['_shown'])) { $this->list_style($style, 0); } } // Add button if (isset($this->style_counters) && $this->style_counters['caninstall'] > 0) { $this->template->assign_block_vars('extra_actions', array( 'ACTION_NAME' => 'install', 'L_ACTION' => $this->user->lang['INSTALL_STYLES'], ) ); } } /** * Find styles available for installation * * @param bool $all if true, function will return all installable styles. if false, function will return only styles that can be installed * @return array List of styles */ protected function find_available($all) { // Get list of installed styles $installed = $this->get_styles(); $installed_dirs = array(); $installed_names = array(); foreach ($installed as $style) { $installed_dirs[] = $style['style_path']; $installed_names[$style['style_name']] = array( 'path' => $style['style_path'], 'id' => $style['style_id'], 'parent' => $style['style_parent_id'], 'tree' => (strlen($style['style_parent_tree']) ? $style['style_parent_tree'] . '/' : '') . $style['style_path'], ); } // Get list of directories $dirs = $this->find_style_dirs(); // Find styles that can be installed $styles = array(); foreach ($dirs as $dir) { if (in_array($dir, $installed_dirs)) { // Style is already installed continue; } $cfg = $this->read_style_cfg($dir); if ($cfg === false) { // Invalid style.cfg continue; } // Style should be available for installation $parent = $cfg['parent']; $style = array( 'style_id' => 0, 'style_name' => $cfg['name'], 'style_copyright' => $cfg['copyright'], 'style_active' => 0, 'style_path' => $dir, 'bbcode_bitfield' => $cfg['template_bitfield'], 'style_parent_id' => 0, 'style_parent_tree' => '', // Extra values for styles list // All extra variable start with _ so they won't be confused with data that can be added to styles table '_inherit_name' => $parent, '_available' => true, '_note' => '', ); // Check style inheritance if ($parent != '') { if (isset($installed_names[$parent])) { // Parent style is installed $row = $installed_names[$parent]; $style['style_parent_id'] = $row['id']; $style['style_parent_tree'] = $row['tree']; } else { // Parent style is not installed yet $style['_available'] = false; $style['_note'] = sprintf($this->user->lang['REQUIRES_STYLE'], htmlspecialchars($parent)); } } if ($all || $style['_available']) { $styles[] = $style; } } return $styles; } /** * Show styles list * * @param array $styles styles list * @param int $parent parent style id * @param int $level style inheritance level */ protected function show_styles_list(&$styles, $parent, $level) { foreach ($styles as &$style) { if (empty($style['_shown']) && $style['style_parent_id'] == $parent) { $this->list_style($style, $level); $this->show_styles_list($styles, $style['style_id'], $level + 1); } } } /** * Show available styles tree * * @param array $styles Styles list, passed as reference * @param string $name Name of parent style * @param int $level Styles tree level */ protected function show_available_child_styles(&$styles, $name, $level) { foreach ($styles as &$style) { if (empty($style['_shown']) && $style['_inherit_name'] == $name) { $this->list_style($style, $level); $this->show_available_child_styles($styles, $style['style_name'], $level + 1); } } } /** * Update styles tree * * @param array $styles Styles list, passed as reference * @param array|false $style Current style, false if root * @return bool True if something was updated, false if not */ protected function update_styles_tree(&$styles, $style = false) { $parent_id = ($style === false) ? 0 : $style['style_id']; $parent_tree = ($style === false) ? '' : ($style['style_parent_tree'] == '' ? '' : $style['style_parent_tree']) . $style['style_path']; $update = false; $updated = false; foreach ($styles as &$row) { if ($row['style_parent_id'] == $parent_id) { if ($row['style_parent_tree'] != $parent_tree) { $row['style_parent_tree'] = $parent_tree; $update = true; } $updated |= $this->update_styles_tree($styles, $row); } } if ($update) { $sql = 'UPDATE ' . STYLES_TABLE . " SET style_parent_tree = '" . $this->db->sql_escape($parent_tree) . "' WHERE style_parent_id = {$parent_id}"; $this->db->sql_query($sql); $updated = true; } return $updated; } /** * Find all possible parent styles for style * * @param array $styles list of styles * @param int $id id of style * @param int $parent current parent style id * @param int $level current tree level * @return array Style ids, names and levels */ protected function find_possible_parents($styles, $id = -1, $parent = 0, $level = 0) { $results = array(); foreach ($styles as $style) { if ($style['style_id'] != $id && $style['style_parent_id'] == $parent) { $results[] = array( 'style_id' => $style['style_id'], 'style_name' => $style['style_name'], 'style_path' => $style['style_path'], 'style_parent_id' => $style['style_parent_id'], 'style_parent_tree' => $style['style_parent_tree'], 'level' => $level ); $results = array_merge($results, $this->find_possible_parents($styles, $id, $style['style_id'], $level + 1)); } } return $results; } /** * Show item in styles list * * @param array $style style row * @param int $level style inheritance level */ protected function list_style(&$style, $level) { // Mark row as shown if (!empty($style['_shown'])) { return; } $style['_shown'] = true; // Generate template variables $actions = array(); $row = array( // Style data 'STYLE_ID' => $style['style_id'], 'STYLE_NAME' => htmlspecialchars($style['style_name']), 'STYLE_PATH' => htmlspecialchars($style['style_path']), 'STYLE_COPYRIGHT' => strip_tags($style['style_copyright']), 'STYLE_ACTIVE' => $style['style_active'], // Additional data 'DEFAULT' => ($style['style_id'] && $style['style_id'] == $this->default_style), 'USERS' => (isset($style['_users'])) ? $style['_users'] : '', 'LEVEL' => $level, 'PADDING' => (4 + 16 * $level), 'SHOW_COPYRIGHT' => ($style['style_id']) ? false : true, 'STYLE_PATH_FULL' => htmlspecialchars($this->styles_path_absolute . '/' . $style['style_path']) . '/', // Comment to show below style 'COMMENT' => (isset($style['_note'])) ? $style['_note'] : '', // The following variables should be used by hooks to add custom HTML code 'EXTRA' => '', 'EXTRA_OPTIONS' => '' ); // Status specific data if ($style['style_id']) { // Style is installed // Details $actions[] = array( 'U_ACTION' => $this->u_action . '&action=details&id=' . $style['style_id'], 'L_ACTION' => $this->user->lang['DETAILS'] ); // Activate/Deactive $action_name = ($style['style_active'] ? 'de' : '') . 'activate'; $actions[] = array( 'U_ACTION' => $this->u_action . '&action=' . $action_name . '&hash=' . generate_link_hash($action_name) . '&id=' . $style['style_id'], 'L_ACTION' => $this->user->lang['STYLE_' . ($style['style_active'] ? 'DE' : '') . 'ACTIVATE'] ); /* // Export $actions[] = array( 'U_ACTION' => $this->u_action . '&action=export&hash=' . generate_link_hash('export') . '&id=' . $style['style_id'], 'L_ACTION' => $this->user->lang['EXPORT'] ); */ // Uninstall $actions[] = array( 'U_ACTION' => $this->u_action . '&action=uninstall&hash=' . generate_link_hash('uninstall') . '&id=' . $style['style_id'], 'L_ACTION' => $this->user->lang['STYLE_UNINSTALL'] ); // Preview $actions[] = array( 'U_ACTION' => append_sid($this->phpbb_root_path . 'index.' . $this->php_ext, 'style=' . $style['style_id']), 'L_ACTION' => $this->user->lang['PREVIEW'] ); } else { // Style is not installed if (empty($style['_available'])) { $actions[] = array( 'HTML' => $this->user->lang['CANNOT_BE_INSTALLED'] ); } else { $actions[] = array( 'U_ACTION' => $this->u_action . '&action=install&hash=' . generate_link_hash('install') . '&dir=' . urlencode($style['style_path']), 'L_ACTION' => $this->user->lang['INSTALL_STYLE'] ); } } // todo: add hook // Assign template variables $this->template->assign_block_vars('styles_list', $row); foreach($actions as $action) { $this->template->assign_block_vars('styles_list.actions', $action); } // Increase counters $counter = ($style['style_id']) ? ($style['style_active'] ? 'active' : 'inactive') : (empty($style['_available']) ? 'cannotinstall' : 'caninstall'); if (!isset($this->style_counters)) { $this->style_counters = array( 'total' => 0, 'active' => 0, 'inactive' => 0, 'caninstall' => 0, 'cannotinstall' => 0 ); } $this->style_counters[$counter]++; $this->style_counters['total']++; } /** * Show welcome message * * @param string $title main title * @param string $description page description */ protected function welcome_message($title, $description) { $this->template->assign_vars(array( 'L_TITLE' => $this->user->lang[$title], 'L_EXPLAIN' => (isset($this->user->lang[$description])) ? $this->user->lang[$description] : '' ) ); } /** * Find all directories that have styles * * @return array Directory names */ protected function find_style_dirs() { $styles = array(); $dp = @opendir($this->styles_path); if ($dp) { while (($file = readdir($dp)) !== false) { $dir = $this->styles_path . $file; if ($file[0] == '.' || !is_dir($dir)) { continue; } if (file_exists("{$dir}/style.cfg")) { $styles[] = $file; } } closedir($dp); } return $styles; } /** * Sort styles */ public function sort_styles($style1, $style2) { if ($style1['style_active'] != $style2['style_active']) { return ($style1['style_active']) ? -1 : 1; } if (isset($style1['_available']) && $style1['_available'] != $style2['_available']) { return ($style1['_available']) ? -1 : 1; } return strcasecmp(isset($style1['style_name']) ? $style1['style_name'] : $style1['name'], isset($style2['style_name']) ? $style2['style_name'] : $style2['name']); } /** * Read style configuration file * * @param string $dir style directory * @return array|bool Style data, false on error */ protected function read_style_cfg($dir) { static $required = array('name', 'phpbb_version', 'copyright'); $cfg = parse_cfg_file($this->styles_path . $dir . '/style.cfg'); // Check if it is a valid file foreach ($required as $key) { if (!isset($cfg[$key])) { return false; } } // Check data if (!isset($cfg['parent']) || !is_string($cfg['parent']) || $cfg['parent'] == $cfg['name']) { $cfg['parent'] = ''; } if (!isset($cfg['template_bitfield'])) { $cfg['template_bitfield'] = $this->default_bitfield(); } return $cfg; } /** * Install style * * @param array $style style data * @return int Style id */ protected function install_style($style) { // Generate row $sql_ary = array(); foreach ($style as $key => $value) { if ($key != 'style_id' && substr($key, 0, 1) != '_') { $sql_ary[$key] = $value; } } // Add to database $this->db->sql_transaction('begin'); $sql = 'INSERT INTO ' . STYLES_TABLE . ' ' . $this->db->sql_build_array('INSERT', $sql_ary); $this->db->sql_query($sql); $id = $this->db->sql_nextid(); $this->db->sql_transaction('commit'); add_log('admin', 'LOG_STYLE_ADD', $sql_ary['style_name']); return $id; } /** * Lists all styles * * @return array Rows with styles data */ protected function get_styles() { $sql = 'SELECT * FROM ' . STYLES_TABLE; $result = $this->db->sql_query($sql); $rows = $this->db->sql_fetchrowset($result); $this->db->sql_freeresult($result); return $rows; } /** * Count users for each style * * @return array Styles in following format: [style_id] = number of users */ protected function get_users() { $sql = 'SELECT user_style, COUNT(user_style) AS style_count FROM ' . USERS_TABLE . ' GROUP BY user_style'; $result = $this->db->sql_query($sql); $style_count = array(); while ($row = $this->db->sql_fetchrow($result)) { $style_count[$row['user_style']] = $row['style_count']; } $this->db->sql_freeresult($result); return $style_count; } /** * Uninstall style * * @param array $style Style data * @return bool|string True on success, error message on error */ protected function uninstall_style($style) { $id = $style['style_id']; $path = $style['style_path']; // Check if style has child styles $sql = 'SELECT style_id FROM ' . STYLES_TABLE . ' WHERE style_parent_id = ' . (int) $id . " OR style_parent_tree = '" . $this->db->sql_escape($path) . "'"; $result = $this->db->sql_query($sql); $conflict = $this->db->sql_fetchrow($result); $this->db->sql_freeresult($result); if ($conflict !== false) { return sprintf($this->user->lang['STYLE_UNINSTALL_DEPENDENT'], $style['style_name']); } // Change default style for users $sql = 'UPDATE ' . USERS_TABLE . ' SET user_style = 0 WHERE user_style = ' . $id; $this->db->sql_query($sql); // Uninstall style $sql = 'DELETE FROM ' . STYLES_TABLE . ' WHERE style_id = ' . $id; $this->db->sql_query($sql); return true; } /** * Delete all files in style directory * * @param string $path Style directory * @param string $dir Directory to remove inside style's directory * @return bool True on success, false on error */ protected function delete_style_files($path, $dir = '') { $dirname = $this->styles_path . $path . $dir; $result = true; $dp = @opendir($dirname); if ($dp) { while (($file = readdir($dp)) !== false) { if ($file == '.' || $file == '..') { continue; } $filename = $dirname . '/' . $file; if (is_dir($filename)) { if (!$this->delete_style_files($path, $dir . '/' . $file)) { $result = false; } } else { if (!@unlink($filename)) { $result = false; } } } closedir($dp); } if (!@rmdir($dirname)) { return false; } return $result; } /** * Get list of items from posted data * * @param string $name Variable name * @param string|int $default Default value for array * @param bool $error If true, error will be triggered if list is empty * @return array Items */ protected function request_vars($name, $default, $error = false) { $item = $this->request->variable($name, $default); $items = $this->request->variable($name . 's', array($default)); if (count($items) == 1 && $items[0] == $default) { $items = array(); } if ($item != $default && !count($items)) { $items[] = $item; } if ($error && !count($items)) { trigger_error($this->user->lang['NO_MATCHING_STYLES_FOUND'] . adm_back_link($this->u_action), E_USER_WARNING); } return $items; } /** * Generates default bitfield * * This bitfield decides which bbcodes are defined in a template. * * @return string Bitfield */ protected function default_bitfield() { static $value; if (isset($value)) { return $value; } // Hardcoded template bitfield to add for new templates $bitfield = new bitfield(); $bitfield->set(0); $bitfield->set(1); $bitfield->set(2); $bitfield->set(3); $bitfield->set(4); $bitfield->set(8); $bitfield->set(9); $bitfield->set(11); $bitfield->set(12); $value = $bitfield->get_base64(); return $value; } } info/acp_icons.php000077700000001340151514745240010163 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_icons_info { function module() { return array( 'filename' => 'acp_icons', 'title' => 'ACP_ICONS_SMILIES', 'version' => '1.0.0', 'modes' => array( 'icons' => array('title' => 'ACP_ICONS', 'auth' => 'acl_a_icons', 'cat' => array('ACP_MESSAGES')), 'smilies' => array('title' => 'ACP_SMILIES', 'auth' => 'acl_a_icons', 'cat' => array('ACP_MESSAGES')), ), ); } function install() { } function uninstall() { } } info/acp_reasons.php000077700000001202151514745240010517 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_reasons_info { function module() { return array( 'filename' => 'acp_reasons', 'title' => 'ACP_REASONS', 'version' => '1.0.0', 'modes' => array( 'main' => array('title' => 'ACP_MANAGE_REASONS', 'auth' => 'acl_a_reasons', 'cat' => array('ACP_GENERAL_TASKS')), ), ); } function install() { } function uninstall() { } } info/acp_ban.php000077700000001513151514745240007612 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_ban_info { function module() { return array( 'filename' => 'acp_ban', 'title' => 'ACP_BAN', 'version' => '1.0.0', 'modes' => array( 'email' => array('title' => 'ACP_BAN_EMAILS', 'auth' => 'acl_a_ban', 'cat' => array('ACP_USER_SECURITY')), 'ip' => array('title' => 'ACP_BAN_IPS', 'auth' => 'acl_a_ban', 'cat' => array('ACP_USER_SECURITY')), 'user' => array('title' => 'ACP_BAN_USERNAMES', 'auth' => 'acl_a_ban', 'cat' => array('ACP_USER_SECURITY')), ), ); } function install() { } function uninstall() { } } info/acp_disallow.php000077700000001214151514745240010666 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_disallow_info { function module() { return array( 'filename' => 'acp_disallow', 'title' => 'ACP_DISALLOW', 'version' => '1.0.0', 'modes' => array( 'usernames' => array('title' => 'ACP_DISALLOW_USERNAMES', 'auth' => 'acl_a_names', 'cat' => array('ACP_USER_SECURITY')), ), ); } function install() { } function uninstall() { } } info/acp_users.php000077700000003676151514745240010227 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_users_info { function module() { return array( 'filename' => 'acp_users', 'title' => 'ACP_USER_MANAGEMENT', 'version' => '1.0.0', 'modes' => array( 'overview' => array('title' => 'ACP_MANAGE_USERS', 'auth' => 'acl_a_user', 'cat' => array('ACP_CAT_USERS')), 'feedback' => array('title' => 'ACP_USER_FEEDBACK', 'auth' => 'acl_a_user', 'display' => false, 'cat' => array('ACP_CAT_USERS')), 'warnings' => array('title' => 'ACP_USER_WARNINGS', 'auth' => 'acl_a_user', 'display' => false, 'cat' => array('ACP_CAT_USERS')), 'profile' => array('title' => 'ACP_USER_PROFILE', 'auth' => 'acl_a_user', 'display' => false, 'cat' => array('ACP_CAT_USERS')), 'prefs' => array('title' => 'ACP_USER_PREFS', 'auth' => 'acl_a_user', 'display' => false, 'cat' => array('ACP_CAT_USERS')), 'avatar' => array('title' => 'ACP_USER_AVATAR', 'auth' => 'acl_a_user', 'display' => false, 'cat' => array('ACP_CAT_USERS')), 'rank' => array('title' => 'ACP_USER_RANK', 'auth' => 'acl_a_user', 'display' => false, 'cat' => array('ACP_CAT_USERS')), 'sig' => array('title' => 'ACP_USER_SIG', 'auth' => 'acl_a_user', 'display' => false, 'cat' => array('ACP_CAT_USERS')), 'groups' => array('title' => 'ACP_USER_GROUPS', 'auth' => 'acl_a_user && acl_a_group', 'display' => false, 'cat' => array('ACP_CAT_USERS')), 'perm' => array('title' => 'ACP_USER_PERM', 'auth' => 'acl_a_user && acl_a_viewauth', 'display' => false, 'cat' => array('ACP_CAT_USERS')), 'attach' => array('title' => 'ACP_USER_ATTACH', 'auth' => 'acl_a_user', 'display' => false, 'cat' => array('ACP_CAT_USERS')), ), ); } function install() { } function uninstall() { } } info/acp_contact.php000077700000001172151514745240010506 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @package module_install */ class acp_contact_info { public function module() { return array( 'filename' => 'acp_contact', 'title' => 'ACP_CONTACT', 'version' => '1.0.0', 'modes' => array( 'contact' => array('title' => 'ACP_CONTACT_SETTINGS', 'auth' => 'acl_a_board', 'cat' => array('ACP_BOARD_CONFIGURATION')), ), ); } } info/acp_permissions.php000077700000006362151514745240011434 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_permissions_info { function module() { return array( 'filename' => 'acp_permissions', 'title' => 'ACP_PERMISSIONS', 'version' => '1.0.0', 'modes' => array( 'intro' => array('title' => 'ACP_PERMISSIONS', 'auth' => 'acl_a_authusers || acl_a_authgroups || acl_a_viewauth', 'cat' => array('ACP_CAT_PERMISSIONS')), 'trace' => array('title' => 'ACP_PERMISSION_TRACE', 'auth' => 'acl_a_viewauth', 'display' => false, 'cat' => array('ACP_PERMISSION_MASKS')), 'setting_forum_local' => array('title' => 'ACP_FORUM_PERMISSIONS', 'auth' => 'acl_a_fauth && (acl_a_authusers || acl_a_authgroups)', 'cat' => array('ACP_FORUM_BASED_PERMISSIONS')), 'setting_forum_copy' => array('title' => 'ACP_FORUM_PERMISSIONS_COPY', 'auth' => 'acl_a_fauth && acl_a_authusers && acl_a_authgroups && acl_a_mauth', 'cat' => array('ACP_FORUM_BASED_PERMISSIONS')), 'setting_mod_local' => array('title' => 'ACP_FORUM_MODERATORS', 'auth' => 'acl_a_mauth && (acl_a_authusers || acl_a_authgroups)', 'cat' => array('ACP_FORUM_BASED_PERMISSIONS')), 'setting_user_global' => array('title' => 'ACP_USERS_PERMISSIONS', 'auth' => 'acl_a_authusers && (acl_a_aauth || acl_a_mauth || acl_a_uauth)', 'cat' => array('ACP_GLOBAL_PERMISSIONS', 'ACP_CAT_USERS')), 'setting_user_local' => array('title' => 'ACP_USERS_FORUM_PERMISSIONS', 'auth' => 'acl_a_authusers && (acl_a_mauth || acl_a_fauth)', 'cat' => array('ACP_FORUM_BASED_PERMISSIONS', 'ACP_CAT_USERS')), 'setting_group_global' => array('title' => 'ACP_GROUPS_PERMISSIONS', 'auth' => 'acl_a_authgroups && (acl_a_aauth || acl_a_mauth || acl_a_uauth)', 'cat' => array('ACP_GLOBAL_PERMISSIONS', 'ACP_GROUPS')), 'setting_group_local' => array('title' => 'ACP_GROUPS_FORUM_PERMISSIONS', 'auth' => 'acl_a_authgroups && (acl_a_mauth || acl_a_fauth)', 'cat' => array('ACP_FORUM_BASED_PERMISSIONS', 'ACP_GROUPS')), 'setting_admin_global' => array('title' => 'ACP_ADMINISTRATORS', 'auth' => 'acl_a_aauth && (acl_a_authusers || acl_a_authgroups)', 'cat' => array('ACP_GLOBAL_PERMISSIONS')), 'setting_mod_global' => array('title' => 'ACP_GLOBAL_MODERATORS', 'auth' => 'acl_a_mauth && (acl_a_authusers || acl_a_authgroups)', 'cat' => array('ACP_GLOBAL_PERMISSIONS')), 'view_admin_global' => array('title' => 'ACP_VIEW_ADMIN_PERMISSIONS', 'auth' => 'acl_a_viewauth', 'cat' => array('ACP_PERMISSION_MASKS')), 'view_user_global' => array('title' => 'ACP_VIEW_USER_PERMISSIONS', 'auth' => 'acl_a_viewauth', 'cat' => array('ACP_PERMISSION_MASKS')), 'view_mod_global' => array('title' => 'ACP_VIEW_GLOBAL_MOD_PERMISSIONS', 'auth' => 'acl_a_viewauth', 'cat' => array('ACP_PERMISSION_MASKS')), 'view_mod_local' => array('title' => 'ACP_VIEW_FORUM_MOD_PERMISSIONS', 'auth' => 'acl_a_viewauth', 'cat' => array('ACP_PERMISSION_MASKS')), 'view_forum_local' => array('title' => 'ACP_VIEW_FORUM_PERMISSIONS', 'auth' => 'acl_a_viewauth', 'cat' => array('ACP_PERMISSION_MASKS')), ), ); } function install() { } function uninstall() { } } info/acp_php_info.php000077700000001177151514745240010662 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_php_info_info { function module() { return array( 'filename' => 'acp_php_info', 'title' => 'ACP_PHP_INFO', 'version' => '1.0.0', 'modes' => array( 'info' => array('title' => 'ACP_PHP_INFO', 'auth' => 'acl_a_phpinfo', 'cat' => array('ACP_GENERAL_TASKS')), ), ); } function install() { } function uninstall() { } } info/acp_language.php000077700000001207151514745240010635 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_language_info { function module() { return array( 'filename' => 'acp_language', 'title' => 'ACP_LANGUAGE', 'version' => '1.0.0', 'modes' => array( 'lang_packs' => array('title' => 'ACP_LANGUAGE_PACKS', 'auth' => 'acl_a_language', 'cat' => array('ACP_LANGUAGE')), ), ); } function install() { } function uninstall() { } } info/acp_words.php000077700000001155151514745240010212 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_words_info { function module() { return array( 'filename' => 'acp_words', 'title' => 'ACP_WORDS', 'version' => '1.0.0', 'modes' => array( 'words' => array('title' => 'ACP_WORDS', 'auth' => 'acl_a_words', 'cat' => array('ACP_MESSAGES')), ), ); } function install() { } function uninstall() { } } info/acp_captcha.php000077700000001427151514745240010461 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_captcha_info { function module() { return array( 'filename' => 'acp_captcha', 'title' => 'ACP_CAPTCHA', 'version' => '1.0.0', 'modes' => array( 'visual' => array('title' => 'ACP_VC_SETTINGS', 'auth' => 'acl_a_board', 'cat' => array('ACP_BOARD_CONFIGURATION')), 'img' => array('title' => 'ACP_VC_CAPTCHA_DISPLAY', 'auth' => 'acl_a_board', 'cat' => array('ACP_BOARD_CONFIGURATION'), 'display' => false) ), ); } function install() { } function uninstall() { } } info/acp_send_statistics.php000077700000001254151514745240012257 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_send_statistics_info { function module() { return array( 'filename' => 'acp_send_statistics', 'title' => 'ACP_SEND_STATISTICS', 'version' => '1.0.0', 'modes' => array( 'send_statistics' => array('title' => 'ACP_SEND_STATISTICS', 'auth' => 'acl_a_server', 'cat' => array('ACP_SERVER_CONFIGURATION')), ), ); } function install() { } function uninstall() { } } info/acp_inactive.php000077700000001204151514745240010651 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_inactive_info { function module() { return array( 'filename' => 'acp_inactive', 'title' => 'ACP_INACTIVE_USERS', 'version' => '1.0.0', 'modes' => array( 'list' => array('title' => 'ACP_INACTIVE_USERS', 'auth' => 'acl_a_user', 'cat' => array('ACP_CAT_USERS')), ), ); } function install() { } function uninstall() { } } info/acp_bbcodes.php000077700000001170151514745240010452 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_bbcodes_info { function module() { return array( 'filename' => 'acp_bbcodes', 'title' => 'ACP_BBCODES', 'version' => '1.0.0', 'modes' => array( 'bbcodes' => array('title' => 'ACP_BBCODES', 'auth' => 'acl_a_bbcode', 'cat' => array('ACP_MESSAGES')), ), ); } function install() { } function uninstall() { } } info/acp_profile.php000077700000001225151514745240010512 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_profile_info { function module() { return array( 'filename' => 'acp_profile', 'title' => 'ACP_CUSTOM_PROFILE_FIELDS', 'version' => '1.0.0', 'modes' => array( 'profile' => array('title' => 'ACP_CUSTOM_PROFILE_FIELDS', 'auth' => 'acl_a_profile', 'cat' => array('ACP_CAT_USERS')), ), ); } function install() { } function uninstall() { } } info/acp_jabber.php000077700000001223151514745240010275 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_jabber_info { function module() { return array( 'filename' => 'acp_jabber', 'title' => 'ACP_JABBER_SETTINGS', 'version' => '1.0.0', 'modes' => array( 'settings' => array('title' => 'ACP_JABBER_SETTINGS', 'auth' => 'acl_a_jabber', 'cat' => array('ACP_CLIENT_COMMUNICATION')), ), ); } function install() { } function uninstall() { } } info/acp_groups.php000077700000001365151514745240010376 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_groups_info { function module() { return array( 'filename' => 'acp_groups', 'title' => 'ACP_GROUPS_MANAGEMENT', 'version' => '1.0.0', 'modes' => array( 'manage' => array('title' => 'ACP_GROUPS_MANAGE', 'auth' => 'acl_a_group', 'cat' => array('ACP_GROUPS')), 'position' => array('title' => 'ACP_GROUPS_POSITION', 'auth' => 'acl_a_group', 'cat' => array('ACP_GROUPS')), ), ); } function install() { } function uninstall() { } } info/acp_main.php000077700000001142151514745240007774 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_main_info { function module() { return array( 'filename' => 'acp_main', 'title' => 'ACP_INDEX', 'version' => '1.0.0', 'modes' => array( 'main' => array('title' => 'ACP_INDEX', 'auth' => '', 'cat' => array('ACP_CAT_GENERAL')), ), ); } function install() { } function uninstall() { } } info/acp_modules.php000077700000001526151514745240010526 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_modules_info { function module() { return array( 'filename' => 'acp_modules', 'title' => 'ACP_MODULE_MANAGEMENT', 'version' => '1.0.0', 'modes' => array( 'acp' => array('title' => 'ACP', 'auth' => 'acl_a_modules', 'cat' => array('ACP_MODULE_MANAGEMENT')), 'ucp' => array('title' => 'UCP', 'auth' => 'acl_a_modules', 'cat' => array('ACP_MODULE_MANAGEMENT')), 'mcp' => array('title' => 'MCP', 'auth' => 'acl_a_modules', 'cat' => array('ACP_MODULE_MANAGEMENT')), ), ); } function install() { } function uninstall() { } } info/acp_search.php000077700000001375151514745240010325 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_search_info { function module() { return array( 'filename' => 'acp_search', 'title' => 'ACP_SEARCH', 'version' => '1.0.0', 'modes' => array( 'settings' => array('title' => 'ACP_SEARCH_SETTINGS', 'auth' => 'acl_a_search', 'cat' => array('ACP_SERVER_CONFIGURATION')), 'index' => array('title' => 'ACP_SEARCH_INDEX', 'auth' => 'acl_a_search', 'cat' => array('ACP_CAT_DATABASE')), ), ); } function install() { } function uninstall() { } } info/acp_bots.php000077700000001154151514745240010022 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_bots_info { function module() { return array( 'filename' => 'acp_bots', 'title' => 'ACP_BOTS', 'version' => '1.0.0', 'modes' => array( 'bots' => array('title' => 'ACP_BOTS', 'auth' => 'acl_a_bots', 'cat' => array('ACP_GENERAL_TASKS')), ), ); } function install() { } function uninstall() { } } info/acp_logs.php000077700000001716151514745240010023 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_logs_info { function module() { return array( 'filename' => 'acp_logs', 'title' => 'ACP_LOGGING', 'version' => '1.0.0', 'modes' => array( 'admin' => array('title' => 'ACP_ADMIN_LOGS', 'auth' => 'acl_a_viewlogs', 'cat' => array('ACP_FORUM_LOGS')), 'mod' => array('title' => 'ACP_MOD_LOGS', 'auth' => 'acl_a_viewlogs', 'cat' => array('ACP_FORUM_LOGS')), 'users' => array('title' => 'ACP_USERS_LOGS', 'auth' => 'acl_a_viewlogs', 'cat' => array('ACP_FORUM_LOGS')), 'critical' => array('title' => 'ACP_CRITICAL_LOGS', 'auth' => 'acl_a_viewlogs', 'cat' => array('ACP_FORUM_LOGS')), ), ); } function install() { } function uninstall() { } } info/acp_attachments.php000077700000002230151514745240011362 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_attachments_info { function module() { return array( 'filename' => 'acp_attachments', 'title' => 'ACP_ATTACHMENTS', 'version' => '1.0.0', 'modes' => array( 'attach' => array('title' => 'ACP_ATTACHMENT_SETTINGS', 'auth' => 'acl_a_attach', 'cat' => array('ACP_BOARD_CONFIGURATION', 'ACP_ATTACHMENTS')), 'extensions' => array('title' => 'ACP_MANAGE_EXTENSIONS', 'auth' => 'acl_a_attach', 'cat' => array('ACP_ATTACHMENTS')), 'ext_groups' => array('title' => 'ACP_EXTENSION_GROUPS', 'auth' => 'acl_a_attach', 'cat' => array('ACP_ATTACHMENTS')), 'orphan' => array('title' => 'ACP_ORPHAN_ATTACHMENTS', 'auth' => 'acl_a_attach', 'cat' => array('ACP_ATTACHMENTS')), 'manage' => array('title' => 'ACP_MANAGE_ATTACHMENTS', 'auth' => 'acl_a_attach', 'cat' => array('ACP_ATTACHMENTS')), ), ); } function install() { } function uninstall() { } } info/acp_prune.php000077700000001354151514745240010206 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_prune_info { function module() { return array( 'filename' => 'acp_prune', 'title' => 'ACP_PRUNING', 'version' => '1.0.0', 'modes' => array( 'forums' => array('title' => 'ACP_PRUNE_FORUMS', 'auth' => 'acl_a_prune', 'cat' => array('ACP_MANAGE_FORUMS')), 'users' => array('title' => 'ACP_PRUNE_USERS', 'auth' => 'acl_a_userdel', 'cat' => array('ACP_CAT_USERS')), ), ); } function install() { } function uninstall() { } } info/acp_database.php000077700000001354151514745240010621 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_database_info { function module() { return array( 'filename' => 'acp_database', 'title' => 'ACP_DATABASE', 'version' => '1.0.0', 'modes' => array( 'backup' => array('title' => 'ACP_BACKUP', 'auth' => 'acl_a_backup', 'cat' => array('ACP_CAT_DATABASE')), 'restore' => array('title' => 'ACP_RESTORE', 'auth' => 'acl_a_backup', 'cat' => array('ACP_CAT_DATABASE')), ), ); } function install() { } function uninstall() { } } info/acp_ranks.php000077700000001165151514745240010173 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_ranks_info { function module() { return array( 'filename' => 'acp_ranks', 'title' => 'ACP_RANKS', 'version' => '1.0.0', 'modes' => array( 'ranks' => array('title' => 'ACP_MANAGE_RANKS', 'auth' => 'acl_a_ranks', 'cat' => array('ACP_CAT_USERS')), ), ); } function install() { } function uninstall() { } } info/acp_update.php000077700000001202151514745240010327 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_update_info { function module() { return array( 'filename' => 'acp_update', 'title' => 'ACP_UPDATE', 'version' => '1.0.0', 'modes' => array( 'version_check' => array('title' => 'ACP_VERSION_CHECK', 'auth' => 'acl_a_board', 'cat' => array('ACP_AUTOMATION')), ), ); } function install() { } function uninstall() { } } info/acp_extensions.php000077700000001233151514745240011250 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_extensions_info { function module() { return array( 'filename' => 'acp_extensions', 'title' => 'ACP_EXTENSION_MANAGEMENT', 'version' => '1.0.0', 'modes' => array( 'main' => array('title' => 'ACP_EXTENSIONS', 'auth' => 'acl_a_extensions', 'cat' => array('ACP_EXTENSION_MANAGEMENT')), ), ); } function install() { } function uninstall() { } } info/acp_styles.php000077700000001371151514745240010377 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_styles_info { function module() { return array( 'filename' => 'acp_styles', 'title' => 'ACP_CAT_STYLES', 'version' => '2.0.0', 'modes' => array( 'style' => array('title' => 'ACP_STYLES', 'auth' => 'acl_a_styles', 'cat' => array('ACP_STYLE_MANAGEMENT')), 'install' => array('title' => 'ACP_STYLES_INSTALL', 'auth' => 'acl_a_styles', 'cat' => array('ACP_STYLE_MANAGEMENT')), ), ); } function install() { } function uninstall() { } } info/acp_forums.php000077700000001207151514745240010365 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_forums_info { function module() { return array( 'filename' => 'acp_forums', 'title' => 'ACP_FORUM_MANAGEMENT', 'version' => '1.0.0', 'modes' => array( 'manage' => array('title' => 'ACP_MANAGE_FORUMS', 'auth' => 'acl_a_forum', 'cat' => array('ACP_MANAGE_FORUMS')), ), ); } function install() { } function uninstall() { } } info/acp_email.php000077700000001220151514745240010134 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_email_info { function module() { return array( 'filename' => 'acp_email', 'title' => 'ACP_MASS_EMAIL', 'version' => '1.0.0', 'modes' => array( 'email' => array('title' => 'ACP_MASS_EMAIL', 'auth' => 'acl_a_email && cfg_email_enable', 'cat' => array('ACP_GENERAL_TASKS')), ), ); } function install() { } function uninstall() { } } info/acp_permission_roles.php000077700000002115151514745240012445 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_permission_roles_info { function module() { return array( 'filename' => 'acp_permission_roles', 'title' => 'ACP_PERMISSION_ROLES', 'version' => '1.0.0', 'modes' => array( 'admin_roles' => array('title' => 'ACP_ADMIN_ROLES', 'auth' => 'acl_a_roles && acl_a_aauth', 'cat' => array('ACP_PERMISSION_ROLES')), 'user_roles' => array('title' => 'ACP_USER_ROLES', 'auth' => 'acl_a_roles && acl_a_uauth', 'cat' => array('ACP_PERMISSION_ROLES')), 'mod_roles' => array('title' => 'ACP_MOD_ROLES', 'auth' => 'acl_a_roles && acl_a_mauth', 'cat' => array('ACP_PERMISSION_ROLES')), 'forum_roles' => array('title' => 'ACP_FORUM_ROLES', 'auth' => 'acl_a_roles && acl_a_fauth', 'cat' => array('ACP_PERMISSION_ROLES')), ), ); } function install() { } function uninstall() { } } info/acp_board.php000077700000004444151514745240010147 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ class acp_board_info { function module() { return array( 'filename' => 'acp_board', 'title' => 'ACP_BOARD_MANAGEMENT', 'version' => '1.0.0', 'modes' => array( 'settings' => array('title' => 'ACP_BOARD_SETTINGS', 'auth' => 'acl_a_board', 'cat' => array('ACP_BOARD_CONFIGURATION')), 'features' => array('title' => 'ACP_BOARD_FEATURES', 'auth' => 'acl_a_board', 'cat' => array('ACP_BOARD_CONFIGURATION')), 'avatar' => array('title' => 'ACP_AVATAR_SETTINGS', 'auth' => 'acl_a_board', 'cat' => array('ACP_BOARD_CONFIGURATION')), 'message' => array('title' => 'ACP_MESSAGE_SETTINGS', 'auth' => 'acl_a_board', 'cat' => array('ACP_BOARD_CONFIGURATION', 'ACP_MESSAGES')), 'post' => array('title' => 'ACP_POST_SETTINGS', 'auth' => 'acl_a_board', 'cat' => array('ACP_BOARD_CONFIGURATION', 'ACP_MESSAGES')), 'signature' => array('title' => 'ACP_SIGNATURE_SETTINGS', 'auth' => 'acl_a_board', 'cat' => array('ACP_BOARD_CONFIGURATION')), 'feed' => array('title' => 'ACP_FEED_SETTINGS', 'auth' => 'acl_a_board', 'cat' => array('ACP_BOARD_CONFIGURATION')), 'registration' => array('title' => 'ACP_REGISTER_SETTINGS', 'auth' => 'acl_a_board', 'cat' => array('ACP_BOARD_CONFIGURATION')), 'auth' => array('title' => 'ACP_AUTH_SETTINGS', 'auth' => 'acl_a_server', 'cat' => array('ACP_CLIENT_COMMUNICATION')), 'email' => array('title' => 'ACP_EMAIL_SETTINGS', 'auth' => 'acl_a_server', 'cat' => array('ACP_CLIENT_COMMUNICATION')), 'cookie' => array('title' => 'ACP_COOKIE_SETTINGS', 'auth' => 'acl_a_server', 'cat' => array('ACP_SERVER_CONFIGURATION')), 'server' => array('title' => 'ACP_SERVER_SETTINGS', 'auth' => 'acl_a_server', 'cat' => array('ACP_SERVER_CONFIGURATION')), 'security' => array('title' => 'ACP_SECURITY_SETTINGS', 'auth' => 'acl_a_server', 'cat' => array('ACP_SERVER_CONFIGURATION')), 'load' => array('title' => 'ACP_LOAD_SETTINGS', 'auth' => 'acl_a_server', 'cat' => array('ACP_SERVER_CONFIGURATION')), ), ); } function install() { } function uninstall() { } } acp_words.php000077700000011171151514745240007256 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } /** * @todo [words] check regular expressions for special char replacements (stored specialchared in db) */ class acp_words { var $u_action; function main($id, $mode) { global $db, $user, $auth, $template, $cache; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; $user->add_lang('acp/posting'); // Set up general vars $action = request_var('action', ''); $action = (isset($_POST['add'])) ? 'add' : ((isset($_POST['save'])) ? 'save' : $action); $s_hidden_fields = ''; $word_info = array(); $this->tpl_name = 'acp_words'; $this->page_title = 'ACP_WORDS'; $form_name = 'acp_words'; add_form_key($form_name); switch ($action) { case 'edit': $word_id = request_var('id', 0); if (!$word_id) { trigger_error($user->lang['NO_WORD'] . adm_back_link($this->u_action), E_USER_WARNING); } $sql = 'SELECT * FROM ' . WORDS_TABLE . " WHERE word_id = $word_id"; $result = $db->sql_query($sql); $word_info = $db->sql_fetchrow($result); $db->sql_freeresult($result); $s_hidden_fields .= '<input type="hidden" name="id" value="' . $word_id . '" />'; case 'add': $template->assign_vars(array( 'S_EDIT_WORD' => true, 'U_ACTION' => $this->u_action, 'U_BACK' => $this->u_action, 'WORD' => (isset($word_info['word'])) ? $word_info['word'] : '', 'REPLACEMENT' => (isset($word_info['replacement'])) ? $word_info['replacement'] : '', 'S_HIDDEN_FIELDS' => $s_hidden_fields) ); return; break; case 'save': if (!check_form_key($form_name)) { trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING); } $word_id = request_var('id', 0); $word = utf8_normalize_nfc(request_var('word', '', true)); $replacement = utf8_normalize_nfc(request_var('replacement', '', true)); if ($word === '' || $replacement === '') { trigger_error($user->lang['ENTER_WORD'] . adm_back_link($this->u_action), E_USER_WARNING); } // Replace multiple consecutive asterisks with single one as those are not needed $word = preg_replace('#\*{2,}#', '*', $word); $sql_ary = array( 'word' => $word, 'replacement' => $replacement ); if ($word_id) { $db->sql_query('UPDATE ' . WORDS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE word_id = ' . $word_id); } else { $db->sql_query('INSERT INTO ' . WORDS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); } $cache->destroy('_word_censors'); $log_action = ($word_id) ? 'LOG_WORD_EDIT' : 'LOG_WORD_ADD'; add_log('admin', $log_action, $word); $message = ($word_id) ? $user->lang['WORD_UPDATED'] : $user->lang['WORD_ADDED']; trigger_error($message . adm_back_link($this->u_action)); break; case 'delete': $word_id = request_var('id', 0); if (!$word_id) { trigger_error($user->lang['NO_WORD'] . adm_back_link($this->u_action), E_USER_WARNING); } if (confirm_box(true)) { $sql = 'SELECT word FROM ' . WORDS_TABLE . " WHERE word_id = $word_id"; $result = $db->sql_query($sql); $deleted_word = $db->sql_fetchfield('word'); $db->sql_freeresult($result); $sql = 'DELETE FROM ' . WORDS_TABLE . " WHERE word_id = $word_id"; $db->sql_query($sql); $cache->destroy('_word_censors'); add_log('admin', 'LOG_WORD_DELETE', $deleted_word); trigger_error($user->lang['WORD_REMOVED'] . adm_back_link($this->u_action)); } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 'i' => $id, 'mode' => $mode, 'id' => $word_id, 'action' => 'delete', ))); } break; } $template->assign_vars(array( 'U_ACTION' => $this->u_action, 'S_HIDDEN_FIELDS' => $s_hidden_fields) ); $sql = 'SELECT * FROM ' . WORDS_TABLE . ' ORDER BY word'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $template->assign_block_vars('words', array( 'WORD' => $row['word'], 'REPLACEMENT' => $row['replacement'], 'U_EDIT' => $this->u_action . '&action=edit&id=' . $row['word_id'], 'U_DELETE' => $this->u_action . '&action=delete&id=' . $row['word_id']) ); } $db->sql_freeresult($result); } } auth.php000077700000112767151514745240006253 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } /** * ACP Permission/Auth class */ class auth_admin extends \phpbb\auth\auth { /** * Init auth settings */ function auth_admin() { global $db, $cache; if (($this->acl_options = $cache->get('_acl_options')) === false) { $sql = 'SELECT auth_option_id, auth_option, is_global, is_local FROM ' . ACL_OPTIONS_TABLE . ' ORDER BY auth_option_id'; $result = $db->sql_query($sql); $global = $local = 0; $this->acl_options = array(); while ($row = $db->sql_fetchrow($result)) { if ($row['is_global']) { $this->acl_options['global'][$row['auth_option']] = $global++; } if ($row['is_local']) { $this->acl_options['local'][$row['auth_option']] = $local++; } $this->acl_options['id'][$row['auth_option']] = (int) $row['auth_option_id']; $this->acl_options['option'][(int) $row['auth_option_id']] = $row['auth_option']; } $db->sql_freeresult($result); $cache->put('_acl_options', $this->acl_options); } } /** * Get permission mask * This function only supports getting permissions of one type (for example a_) * * @param set|view $mode defines the permissions we get, view gets effective permissions (checking user AND group permissions), set only gets the user or group permission set alone * @param mixed $user_id user ids to search for (a user_id or a group_id has to be specified at least) * @param mixed $group_id group ids to search for, return group related settings (a user_id or a group_id has to be specified at least) * @param mixed $forum_id forum_ids to search for. Defining a forum id also means getting local settings * @param string $auth_option the auth_option defines the permission setting to look for (a_ for example) * @param local|global $scope the scope defines the permission scope. If local, a forum_id is additionally required * @param ACL_NEVER|ACL_NO|ACL_YES $acl_fill defines the mode those permissions not set are getting filled with */ function get_mask($mode, $user_id = false, $group_id = false, $forum_id = false, $auth_option = false, $scope = false, $acl_fill = ACL_NEVER) { global $db, $user; $hold_ary = array(); $view_user_mask = ($mode == 'view' && $group_id === false) ? true : false; if ($auth_option === false || $scope === false) { return array(); } $acl_user_function = ($mode == 'set') ? 'acl_user_raw_data' : 'acl_raw_data'; if (!$view_user_mask) { if ($forum_id !== false) { $hold_ary = ($group_id !== false) ? $this->acl_group_raw_data($group_id, $auth_option . '%', $forum_id) : $this->$acl_user_function($user_id, $auth_option . '%', $forum_id); } else { $hold_ary = ($group_id !== false) ? $this->acl_group_raw_data($group_id, $auth_option . '%', ($scope == 'global') ? 0 : false) : $this->$acl_user_function($user_id, $auth_option . '%', ($scope == 'global') ? 0 : false); } } // Make sure hold_ary is filled with every setting (prevents missing forums/users/groups) $ug_id = ($group_id !== false) ? ((!is_array($group_id)) ? array($group_id) : $group_id) : ((!is_array($user_id)) ? array($user_id) : $user_id); $forum_ids = ($forum_id !== false) ? ((!is_array($forum_id)) ? array($forum_id) : $forum_id) : (($scope == 'global') ? array(0) : array()); // Only those options we need $compare_options = array_diff(preg_replace('/^((?!' . $auth_option . ').+)|(' . $auth_option . ')$/', '', array_keys($this->acl_options[$scope])), array('')); // If forum_ids is false and the scope is local we actually want to have all forums within the array if ($scope == 'local' && !sizeof($forum_ids)) { $sql = 'SELECT forum_id FROM ' . FORUMS_TABLE; $result = $db->sql_query($sql, 120); while ($row = $db->sql_fetchrow($result)) { $forum_ids[] = (int) $row['forum_id']; } $db->sql_freeresult($result); } if ($view_user_mask) { $auth2 = null; $sql = 'SELECT user_id, user_permissions, user_type FROM ' . USERS_TABLE . ' WHERE ' . $db->sql_in_set('user_id', $ug_id); $result = $db->sql_query($sql); while ($userdata = $db->sql_fetchrow($result)) { if ($user->data['user_id'] != $userdata['user_id']) { $auth2 = new \phpbb\auth\auth(); $auth2->acl($userdata); } else { global $auth; $auth2 = &$auth; } $hold_ary[$userdata['user_id']] = array(); foreach ($forum_ids as $f_id) { $hold_ary[$userdata['user_id']][$f_id] = array(); foreach ($compare_options as $option) { $hold_ary[$userdata['user_id']][$f_id][$option] = $auth2->acl_get($option, $f_id); } } } $db->sql_freeresult($result); unset($userdata); unset($auth2); } foreach ($ug_id as $_id) { if (!isset($hold_ary[$_id])) { $hold_ary[$_id] = array(); } foreach ($forum_ids as $f_id) { if (!isset($hold_ary[$_id][$f_id])) { $hold_ary[$_id][$f_id] = array(); } } } // Now, we need to fill the gaps with $acl_fill. ;) // Now switch back to keys if (sizeof($compare_options)) { $compare_options = array_combine($compare_options, array_fill(1, sizeof($compare_options), $acl_fill)); } // Defining the user-function here to save some memory $return_acl_fill = function () use ($acl_fill) { return $acl_fill; }; // Actually fill the gaps if (sizeof($hold_ary)) { foreach ($hold_ary as $ug_id => $row) { foreach ($row as $id => $options) { // Do not include the global auth_option unset($options[$auth_option]); // Not a "fine" solution, but at all it's a 1-dimensional // array_diff_key function filling the resulting array values with zeros // The differences get merged into $hold_ary (all permissions having $acl_fill set) $hold_ary[$ug_id][$id] = array_merge($options, array_map($return_acl_fill, array_flip( array_diff( array_keys($compare_options), array_keys($options) ) ) ) ); } } } else { $hold_ary[($group_id !== false) ? $group_id : $user_id][(int) $forum_id] = $compare_options; } return $hold_ary; } /** * Get permission mask for roles * This function only supports getting masks for one role */ function get_role_mask($role_id) { global $db; $hold_ary = array(); // Get users having this role set... $sql = 'SELECT user_id, forum_id FROM ' . ACL_USERS_TABLE . ' WHERE auth_role_id = ' . $role_id . ' ORDER BY forum_id'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $hold_ary[$row['forum_id']]['users'][] = $row['user_id']; } $db->sql_freeresult($result); // Now grab groups... $sql = 'SELECT group_id, forum_id FROM ' . ACL_GROUPS_TABLE . ' WHERE auth_role_id = ' . $role_id . ' ORDER BY forum_id'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $hold_ary[$row['forum_id']]['groups'][] = $row['group_id']; } $db->sql_freeresult($result); return $hold_ary; } /** * Display permission mask (assign to template) */ function display_mask($mode, $permission_type, &$hold_ary, $user_mode = 'user', $local = false, $group_display = true) { global $template, $user, $db, $phpbb_root_path, $phpEx, $phpbb_container; $phpbb_permissions = $phpbb_container->get('acl.permissions'); // Define names for template loops, might be able to be set $tpl_pmask = 'p_mask'; $tpl_fmask = 'f_mask'; $tpl_category = 'category'; $tpl_mask = 'mask'; $l_acl_type = $phpbb_permissions->get_type_lang($permission_type, (($local) ? 'local' : 'global')); // Allow trace for viewing permissions and in user mode $show_trace = ($mode == 'view' && $user_mode == 'user') ? true : false; // Get names if ($user_mode == 'user') { $sql = 'SELECT user_id as ug_id, username as ug_name FROM ' . USERS_TABLE . ' WHERE ' . $db->sql_in_set('user_id', array_keys($hold_ary)) . ' ORDER BY username_clean ASC'; } else { $sql = 'SELECT group_id as ug_id, group_name as ug_name, group_type FROM ' . GROUPS_TABLE . ' WHERE ' . $db->sql_in_set('group_id', array_keys($hold_ary)) . ' ORDER BY group_type DESC, group_name ASC'; } $result = $db->sql_query($sql); $ug_names_ary = array(); while ($row = $db->sql_fetchrow($result)) { $ug_names_ary[$row['ug_id']] = ($user_mode == 'user') ? $row['ug_name'] : (($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['ug_name']] : $row['ug_name']); } $db->sql_freeresult($result); // Get used forums $forum_ids = array(); foreach ($hold_ary as $ug_id => $row) { $forum_ids = array_merge($forum_ids, array_keys($row)); } $forum_ids = array_unique($forum_ids); $forum_names_ary = array(); if ($local) { $forum_names_ary = make_forum_select(false, false, true, false, false, false, true); // Remove the disabled ones, since we do not create an option field here... foreach ($forum_names_ary as $key => $value) { if (!$value['disabled']) { continue; } unset($forum_names_ary[$key]); } } else { $forum_names_ary[0] = $l_acl_type; } // Get available roles $sql = 'SELECT * FROM ' . ACL_ROLES_TABLE . " WHERE role_type = '" . $db->sql_escape($permission_type) . "' ORDER BY role_order ASC"; $result = $db->sql_query($sql); $roles = array(); while ($row = $db->sql_fetchrow($result)) { $roles[$row['role_id']] = $row; } $db->sql_freeresult($result); $cur_roles = $this->acl_role_data($user_mode, $permission_type, array_keys($hold_ary)); // Build js roles array (role data assignments) $s_role_js_array = ''; if (sizeof($roles)) { $s_role_js_array = array(); // Make sure every role (even if empty) has its array defined foreach ($roles as $_role_id => $null) { $s_role_js_array[$_role_id] = "\n" . 'role_options[' . $_role_id . '] = new Array();' . "\n"; } $sql = 'SELECT r.role_id, o.auth_option, r.auth_setting FROM ' . ACL_ROLES_DATA_TABLE . ' r, ' . ACL_OPTIONS_TABLE . ' o WHERE o.auth_option_id = r.auth_option_id AND ' . $db->sql_in_set('r.role_id', array_keys($roles)); $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $flag = substr($row['auth_option'], 0, strpos($row['auth_option'], '_') + 1); if ($flag == $row['auth_option']) { continue; } $s_role_js_array[$row['role_id']] .= 'role_options[' . $row['role_id'] . '][\'' . addslashes($row['auth_option']) . '\'] = ' . $row['auth_setting'] . '; '; } $db->sql_freeresult($result); $s_role_js_array = implode('', $s_role_js_array); } $template->assign_var('S_ROLE_JS_ARRAY', $s_role_js_array); unset($s_role_js_array); // Now obtain memberships $user_groups_default = $user_groups_custom = array(); if ($user_mode == 'user' && $group_display) { $sql = 'SELECT group_id, group_name, group_type FROM ' . GROUPS_TABLE . ' ORDER BY group_type DESC, group_name ASC'; $result = $db->sql_query($sql); $groups = array(); while ($row = $db->sql_fetchrow($result)) { $groups[$row['group_id']] = $row; } $db->sql_freeresult($result); $memberships = group_memberships(false, array_keys($hold_ary), false); // User is not a member of any group? Bad admin, bad bad admin... if ($memberships) { foreach ($memberships as $row) { if ($groups[$row['group_id']]['group_type'] == GROUP_SPECIAL) { $user_groups_default[$row['user_id']][] = $user->lang['G_' . $groups[$row['group_id']]['group_name']]; } else { $user_groups_custom[$row['user_id']][] = $groups[$row['group_id']]['group_name']; } } } unset($memberships, $groups); } // If we only have one forum id to display or being in local mode and more than one user/group to display, // we switch the complete interface to group by user/usergroup instead of grouping by forum // To achieve this, we need to switch the array a bit if (sizeof($forum_ids) == 1 || ($local && sizeof($ug_names_ary) > 1)) { $hold_ary_temp = $hold_ary; $hold_ary = array(); foreach ($hold_ary_temp as $ug_id => $row) { foreach ($forum_names_ary as $forum_id => $forum_row) { if (isset($row[$forum_id])) { $hold_ary[$forum_id][$ug_id] = $row[$forum_id]; } } } unset($hold_ary_temp); foreach ($hold_ary as $forum_id => $forum_array) { $content_array = $categories = array(); $this->build_permission_array($hold_ary[$forum_id], $content_array, $categories, array_keys($ug_names_ary)); $template->assign_block_vars($tpl_pmask, array( 'NAME' => ($forum_id == 0) ? $forum_names_ary[0] : $forum_names_ary[$forum_id]['forum_name'], 'PADDING' => ($forum_id == 0) ? '' : $forum_names_ary[$forum_id]['padding'], 'CATEGORIES' => implode('</th><th>', $categories), 'L_ACL_TYPE' => $l_acl_type, 'S_LOCAL' => ($local) ? true : false, 'S_GLOBAL' => (!$local) ? true : false, 'S_NUM_CATS' => sizeof($categories), 'S_VIEW' => ($mode == 'view') ? true : false, 'S_NUM_OBJECTS' => sizeof($content_array), 'S_USER_MODE' => ($user_mode == 'user') ? true : false, 'S_GROUP_MODE' => ($user_mode == 'group') ? true : false) ); @reset($content_array); while (list($ug_id, $ug_array) = each($content_array)) { // Build role dropdown options $current_role_id = (isset($cur_roles[$ug_id][$forum_id])) ? $cur_roles[$ug_id][$forum_id] : 0; $s_role_options = ''; @reset($roles); while (list($role_id, $role_row) = each($roles)) { $role_description = (!empty($user->lang[$role_row['role_description']])) ? $user->lang[$role_row['role_description']] : nl2br($role_row['role_description']); $role_name = (!empty($user->lang[$role_row['role_name']])) ? $user->lang[$role_row['role_name']] : $role_row['role_name']; $title = ($role_description) ? ' title="' . $role_description . '"' : ''; $s_role_options .= '<option value="' . $role_id . '"' . (($role_id == $current_role_id) ? ' selected="selected"' : '') . $title . '>' . $role_name . '</option>'; } if ($s_role_options) { $s_role_options = '<option value="0"' . ((!$current_role_id) ? ' selected="selected"' : '') . ' title="' . htmlspecialchars($user->lang['NO_ROLE_ASSIGNED_EXPLAIN']) . '">' . $user->lang['NO_ROLE_ASSIGNED'] . '</option>' . $s_role_options; } if (!$current_role_id && $mode != 'view') { $s_custom_permissions = false; foreach ($ug_array as $key => $value) { if ($value['S_NEVER'] || $value['S_YES']) { $s_custom_permissions = true; break; } } } else { $s_custom_permissions = false; } $template->assign_block_vars($tpl_pmask . '.' . $tpl_fmask, array( 'NAME' => $ug_names_ary[$ug_id], 'S_ROLE_OPTIONS' => $s_role_options, 'UG_ID' => $ug_id, 'S_CUSTOM' => $s_custom_permissions, 'FORUM_ID' => $forum_id) ); $this->assign_cat_array($ug_array, $tpl_pmask . '.' . $tpl_fmask . '.' . $tpl_category, $tpl_mask, $ug_id, $forum_id, ($mode == 'view'), $show_trace); unset($content_array[$ug_id]); } unset($hold_ary[$forum_id]); } } else { foreach ($ug_names_ary as $ug_id => $ug_name) { if (!isset($hold_ary[$ug_id])) { continue; } $content_array = $categories = array(); $this->build_permission_array($hold_ary[$ug_id], $content_array, $categories, array_keys($forum_names_ary)); $template->assign_block_vars($tpl_pmask, array( 'NAME' => $ug_name, 'CATEGORIES' => implode('</th><th>', $categories), 'USER_GROUPS_DEFAULT' => ($user_mode == 'user' && isset($user_groups_default[$ug_id]) && sizeof($user_groups_default[$ug_id])) ? implode($user->lang['COMMA_SEPARATOR'], $user_groups_default[$ug_id]) : '', 'USER_GROUPS_CUSTOM' => ($user_mode == 'user' && isset($user_groups_custom[$ug_id]) && sizeof($user_groups_custom[$ug_id])) ? implode($user->lang['COMMA_SEPARATOR'], $user_groups_custom[$ug_id]) : '', 'L_ACL_TYPE' => $l_acl_type, 'S_LOCAL' => ($local) ? true : false, 'S_GLOBAL' => (!$local) ? true : false, 'S_NUM_CATS' => sizeof($categories), 'S_VIEW' => ($mode == 'view') ? true : false, 'S_NUM_OBJECTS' => sizeof($content_array), 'S_USER_MODE' => ($user_mode == 'user') ? true : false, 'S_GROUP_MODE' => ($user_mode == 'group') ? true : false) ); @reset($content_array); while (list($forum_id, $forum_array) = each($content_array)) { // Build role dropdown options $current_role_id = (isset($cur_roles[$ug_id][$forum_id])) ? $cur_roles[$ug_id][$forum_id] : 0; $s_role_options = ''; @reset($roles); while (list($role_id, $role_row) = each($roles)) { $role_description = (!empty($user->lang[$role_row['role_description']])) ? $user->lang[$role_row['role_description']] : nl2br($role_row['role_description']); $role_name = (!empty($user->lang[$role_row['role_name']])) ? $user->lang[$role_row['role_name']] : $role_row['role_name']; $title = ($role_description) ? ' title="' . $role_description . '"' : ''; $s_role_options .= '<option value="' . $role_id . '"' . (($role_id == $current_role_id) ? ' selected="selected"' : '') . $title . '>' . $role_name . '</option>'; } if ($s_role_options) { $s_role_options = '<option value="0"' . ((!$current_role_id) ? ' selected="selected"' : '') . ' title="' . htmlspecialchars($user->lang['NO_ROLE_ASSIGNED_EXPLAIN']) . '">' . $user->lang['NO_ROLE_ASSIGNED'] . '</option>' . $s_role_options; } if (!$current_role_id && $mode != 'view') { $s_custom_permissions = false; foreach ($forum_array as $key => $value) { if ($value['S_NEVER'] || $value['S_YES']) { $s_custom_permissions = true; break; } } } else { $s_custom_permissions = false; } $template->assign_block_vars($tpl_pmask . '.' . $tpl_fmask, array( 'NAME' => ($forum_id == 0) ? $forum_names_ary[0] : $forum_names_ary[$forum_id]['forum_name'], 'PADDING' => ($forum_id == 0) ? '' : $forum_names_ary[$forum_id]['padding'], 'S_ROLE_OPTIONS' => $s_role_options, 'S_CUSTOM' => $s_custom_permissions, 'UG_ID' => $ug_id, 'FORUM_ID' => $forum_id) ); $this->assign_cat_array($forum_array, $tpl_pmask . '.' . $tpl_fmask . '.' . $tpl_category, $tpl_mask, $ug_id, $forum_id, ($mode == 'view'), $show_trace); } unset($hold_ary[$ug_id], $ug_names_ary[$ug_id]); } } } /** * Display permission mask for roles */ function display_role_mask(&$hold_ary) { global $db, $template, $user, $phpbb_root_path, $phpbb_admin_path, $phpEx; if (!sizeof($hold_ary)) { return; } // Get forum names $sql = 'SELECT forum_id, forum_name FROM ' . FORUMS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', array_keys($hold_ary)) . ' ORDER BY left_id'; $result = $db->sql_query($sql); // If the role is used globally, then reflect that $forum_names = (isset($hold_ary[0])) ? array(0 => '') : array(); while ($row = $db->sql_fetchrow($result)) { $forum_names[$row['forum_id']] = $row['forum_name']; } $db->sql_freeresult($result); foreach ($forum_names as $forum_id => $forum_name) { $auth_ary = $hold_ary[$forum_id]; $template->assign_block_vars('role_mask', array( 'NAME' => ($forum_id == 0) ? $user->lang['GLOBAL_MASK'] : $forum_name, 'FORUM_ID' => $forum_id) ); if (isset($auth_ary['users']) && sizeof($auth_ary['users'])) { $sql = 'SELECT user_id, username FROM ' . USERS_TABLE . ' WHERE ' . $db->sql_in_set('user_id', $auth_ary['users']) . ' ORDER BY username_clean ASC'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $template->assign_block_vars('role_mask.users', array( 'USER_ID' => $row['user_id'], 'USERNAME' => get_username_string('username', $row['user_id'], $row['username']), 'U_PROFILE' => get_username_string('profile', $row['user_id'], $row['username']), )); } $db->sql_freeresult($result); } if (isset($auth_ary['groups']) && sizeof($auth_ary['groups'])) { $sql = 'SELECT group_id, group_name, group_type FROM ' . GROUPS_TABLE . ' WHERE ' . $db->sql_in_set('group_id', $auth_ary['groups']) . ' ORDER BY group_type ASC, group_name'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $template->assign_block_vars('role_mask.groups', array( 'GROUP_ID' => $row['group_id'], 'GROUP_NAME' => ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'], 'U_PROFILE' => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=group&g={$row['group_id']}")) ); } $db->sql_freeresult($result); } } } /** * NOTE: this function is not in use atm * Add a new option to the list ... $options is a hash of form -> * $options = array( * 'local' => array('option1', 'option2', ...), * 'global' => array('optionA', 'optionB', ...) * ); */ function acl_add_option($options) { global $db, $cache; if (!is_array($options)) { return false; } $cur_options = array(); // Determine current options $sql = 'SELECT auth_option, is_global, is_local FROM ' . ACL_OPTIONS_TABLE . ' ORDER BY auth_option_id'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $cur_options[$row['auth_option']] = ($row['is_global'] && $row['is_local']) ? 'both' : (($row['is_global']) ? 'global' : 'local'); } $db->sql_freeresult($result); // Here we need to insert new options ... this requires discovering whether // an options is global, local or both and whether we need to add an permission // set flag (x_) $new_options = array('local' => array(), 'global' => array()); foreach ($options as $type => $option_ary) { $option_ary = array_unique($option_ary); foreach ($option_ary as $option_value) { $new_options[$type][] = $option_value; $flag = substr($option_value, 0, strpos($option_value, '_') + 1); if (!in_array($flag, $new_options[$type])) { $new_options[$type][] = $flag; } } } unset($options); $options = array(); $options['local'] = array_diff($new_options['local'], $new_options['global']); $options['global'] = array_diff($new_options['global'], $new_options['local']); $options['both'] = array_intersect($new_options['local'], $new_options['global']); // Now check which options to add/update $add_options = $update_options = array(); // First local ones... foreach ($options as $type => $option_ary) { foreach ($option_ary as $option) { if (!isset($cur_options[$option])) { $add_options[] = array( 'auth_option' => (string) $option, 'is_global' => ($type == 'global' || $type == 'both') ? 1 : 0, 'is_local' => ($type == 'local' || $type == 'both') ? 1 : 0 ); continue; } // Else, update existing entry if it is changed... if ($type === $cur_options[$option]) { continue; } // New type is always both: // If is now both, we set both. // If it was global the new one is local and we need to set it to both // If it was local the new one is global and we need to set it to both $update_options[] = $option; } } if (!empty($add_options)) { $db->sql_multi_insert(ACL_OPTIONS_TABLE, $add_options); } if (!empty($update_options)) { $sql = 'UPDATE ' . ACL_OPTIONS_TABLE . ' SET is_global = 1, is_local = 1 WHERE ' . $db->sql_in_set('auth_option', $update_options); $db->sql_query($sql); } $cache->destroy('_acl_options'); $this->acl_clear_prefetch(); // Because we just changed the options and also purged the options cache, we instantly update/regenerate it for later calls to succeed. $this->acl_options = array(); $this->auth_admin(); return true; } /** * Set a user or group ACL record */ function acl_set($ug_type, $forum_id, $ug_id, $auth, $role_id = 0, $clear_prefetch = true) { global $db; // One or more forums if (!is_array($forum_id)) { $forum_id = array($forum_id); } // One or more users if (!is_array($ug_id)) { $ug_id = array($ug_id); } $ug_id_sql = $db->sql_in_set($ug_type . '_id', array_map('intval', $ug_id)); $forum_sql = $db->sql_in_set('forum_id', array_map('intval', $forum_id)); // Instead of updating, inserting, removing we just remove all current settings and re-set everything... $table = ($ug_type == 'user') ? ACL_USERS_TABLE : ACL_GROUPS_TABLE; $id_field = $ug_type . '_id'; // Get any flags as required reset($auth); $flag = key($auth); $flag = substr($flag, 0, strpos($flag, '_') + 1); // This ID (the any-flag) is set if one or more permissions are true... $any_option_id = (int) $this->acl_options['id'][$flag]; // Remove any-flag from auth ary if (isset($auth[$flag])) { unset($auth[$flag]); } // Remove current auth options... $auth_option_ids = array((int) $any_option_id); foreach ($auth as $auth_option => $auth_setting) { $auth_option_ids[] = (int) $this->acl_options['id'][$auth_option]; } $sql = "DELETE FROM $table WHERE $forum_sql AND $ug_id_sql AND " . $db->sql_in_set('auth_option_id', $auth_option_ids); $db->sql_query($sql); // Remove those having a role assigned... the correct type of course... $sql = 'SELECT role_id FROM ' . ACL_ROLES_TABLE . " WHERE role_type = '" . $db->sql_escape($flag) . "'"; $result = $db->sql_query($sql); $role_ids = array(); while ($row = $db->sql_fetchrow($result)) { $role_ids[] = $row['role_id']; } $db->sql_freeresult($result); if (sizeof($role_ids)) { $sql = "DELETE FROM $table WHERE $forum_sql AND $ug_id_sql AND auth_option_id = 0 AND " . $db->sql_in_set('auth_role_id', $role_ids); $db->sql_query($sql); } // Ok, include the any-flag if one or more auth options are set to yes... foreach ($auth as $auth_option => $setting) { if ($setting == ACL_YES && (!isset($auth[$flag]) || $auth[$flag] == ACL_NEVER)) { $auth[$flag] = ACL_YES; } } $sql_ary = array(); foreach ($forum_id as $forum) { $forum = (int) $forum; if ($role_id) { foreach ($ug_id as $id) { $sql_ary[] = array( $id_field => (int) $id, 'forum_id' => (int) $forum, 'auth_option_id' => 0, 'auth_setting' => 0, 'auth_role_id' => (int) $role_id, ); } } else { foreach ($auth as $auth_option => $setting) { $auth_option_id = (int) $this->acl_options['id'][$auth_option]; if ($setting != ACL_NO) { foreach ($ug_id as $id) { $sql_ary[] = array( $id_field => (int) $id, 'forum_id' => (int) $forum, 'auth_option_id' => (int) $auth_option_id, 'auth_setting' => (int) $setting ); } } } } } $db->sql_multi_insert($table, $sql_ary); if ($clear_prefetch) { $this->acl_clear_prefetch(); } } /** * Set a role-specific ACL record */ function acl_set_role($role_id, $auth) { global $db; // Get any-flag as required reset($auth); $flag = key($auth); $flag = substr($flag, 0, strpos($flag, '_') + 1); // Remove any-flag from auth ary if (isset($auth[$flag])) { unset($auth[$flag]); } // Re-set any flag... foreach ($auth as $auth_option => $setting) { if ($setting == ACL_YES && (!isset($auth[$flag]) || $auth[$flag] == ACL_NEVER)) { $auth[$flag] = ACL_YES; } } $sql_ary = array(); foreach ($auth as $auth_option => $setting) { $auth_option_id = (int) $this->acl_options['id'][$auth_option]; if ($setting != ACL_NO) { $sql_ary[] = array( 'role_id' => (int) $role_id, 'auth_option_id' => (int) $auth_option_id, 'auth_setting' => (int) $setting ); } } // If no data is there, we set the any-flag to ACL_NEVER... if (!sizeof($sql_ary)) { $sql_ary[] = array( 'role_id' => (int) $role_id, 'auth_option_id' => (int) $this->acl_options['id'][$flag], 'auth_setting' => ACL_NEVER ); } // Remove current auth options... $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' WHERE role_id = ' . $role_id; $db->sql_query($sql); // Now insert the new values $db->sql_multi_insert(ACL_ROLES_DATA_TABLE, $sql_ary); $this->acl_clear_prefetch(); } /** * Remove local permission */ function acl_delete($mode, $ug_id = false, $forum_id = false, $permission_type = false) { global $db; if ($ug_id === false && $forum_id === false) { return; } $option_id_ary = array(); $table = ($mode == 'user') ? ACL_USERS_TABLE : ACL_GROUPS_TABLE; $id_field = $mode . '_id'; $where_sql = array(); if ($forum_id !== false) { $where_sql[] = (!is_array($forum_id)) ? 'forum_id = ' . (int) $forum_id : $db->sql_in_set('forum_id', array_map('intval', $forum_id)); } if ($ug_id !== false) { $where_sql[] = (!is_array($ug_id)) ? $id_field . ' = ' . (int) $ug_id : $db->sql_in_set($id_field, array_map('intval', $ug_id)); } // There seem to be auth options involved, therefore we need to go through the list and make sure we capture roles correctly if ($permission_type !== false) { // Get permission type $sql = 'SELECT auth_option, auth_option_id FROM ' . ACL_OPTIONS_TABLE . " WHERE auth_option " . $db->sql_like_expression($permission_type . $db->get_any_char()); $result = $db->sql_query($sql); $auth_id_ary = array(); while ($row = $db->sql_fetchrow($result)) { $option_id_ary[] = $row['auth_option_id']; $auth_id_ary[$row['auth_option']] = ACL_NO; } $db->sql_freeresult($result); // First of all, lets grab the items having roles with the specified auth options assigned $sql = "SELECT auth_role_id, $id_field, forum_id FROM $table, " . ACL_ROLES_TABLE . " r WHERE auth_role_id <> 0 AND auth_role_id = r.role_id AND r.role_type = '{$permission_type}' AND " . implode(' AND ', $where_sql) . ' ORDER BY auth_role_id'; $result = $db->sql_query($sql); $cur_role_auth = array(); while ($row = $db->sql_fetchrow($result)) { $cur_role_auth[$row['auth_role_id']][$row['forum_id']][] = $row[$id_field]; } $db->sql_freeresult($result); // Get role data for resetting data if (sizeof($cur_role_auth)) { $sql = 'SELECT ao.auth_option, rd.role_id, rd.auth_setting FROM ' . ACL_OPTIONS_TABLE . ' ao, ' . ACL_ROLES_DATA_TABLE . ' rd WHERE ao.auth_option_id = rd.auth_option_id AND ' . $db->sql_in_set('rd.role_id', array_keys($cur_role_auth)); $result = $db->sql_query($sql); $auth_settings = array(); while ($row = $db->sql_fetchrow($result)) { // We need to fill all auth_options, else setting it will fail... if (!isset($auth_settings[$row['role_id']])) { $auth_settings[$row['role_id']] = $auth_id_ary; } $auth_settings[$row['role_id']][$row['auth_option']] = $row['auth_setting']; } $db->sql_freeresult($result); // Set the options foreach ($cur_role_auth as $role_id => $auth_row) { foreach ($auth_row as $f_id => $ug_row) { $this->acl_set($mode, $f_id, $ug_row, $auth_settings[$role_id], 0, false); } } } } // Now, normally remove permissions... if ($permission_type !== false) { $where_sql[] = $db->sql_in_set('auth_option_id', array_map('intval', $option_id_ary)); } $sql = "DELETE FROM $table WHERE " . implode(' AND ', $where_sql); $db->sql_query($sql); $this->acl_clear_prefetch(); } /** * Assign category to template * used by display_mask() */ function assign_cat_array(&$category_array, $tpl_cat, $tpl_mask, $ug_id, $forum_id, $s_view, $show_trace = false) { global $template, $user, $phpbb_admin_path, $phpEx, $phpbb_container; $phpbb_permissions = $phpbb_container->get('acl.permissions'); @reset($category_array); while (list($cat, $cat_array) = each($category_array)) { $template->assign_block_vars($tpl_cat, array( 'S_YES' => ($cat_array['S_YES'] && !$cat_array['S_NEVER'] && !$cat_array['S_NO']) ? true : false, 'S_NEVER' => ($cat_array['S_NEVER'] && !$cat_array['S_YES'] && !$cat_array['S_NO']) ? true : false, 'S_NO' => ($cat_array['S_NO'] && !$cat_array['S_NEVER'] && !$cat_array['S_YES']) ? true : false, 'CAT_NAME' => $phpbb_permissions->get_category_lang($cat), )); /* Sort permissions by name (more naturaly and user friendly than sorting by a primary key) * Commented out due to it's memory consumption and time needed * $key_array = array_intersect(array_keys($user->lang), array_map(create_function('$a', 'return "acl_" . $a;'), array_keys($cat_array['permissions']))); $values_array = $cat_array['permissions']; $cat_array['permissions'] = array(); foreach ($key_array as $key) { $key = str_replace('acl_', '', $key); $cat_array['permissions'][$key] = $values_array[$key]; } unset($key_array, $values_array); */ @reset($cat_array['permissions']); while (list($permission, $allowed) = each($cat_array['permissions'])) { if ($s_view) { $template->assign_block_vars($tpl_cat . '.' . $tpl_mask, array( 'S_YES' => ($allowed == ACL_YES) ? true : false, 'S_NEVER' => ($allowed == ACL_NEVER) ? true : false, 'UG_ID' => $ug_id, 'FORUM_ID' => $forum_id, 'FIELD_NAME' => $permission, 'S_FIELD_NAME' => 'setting[' . $ug_id . '][' . $forum_id . '][' . $permission . ']', 'U_TRACE' => ($show_trace) ? append_sid("{$phpbb_admin_path}index.$phpEx", "i=permissions&mode=trace&u=$ug_id&f=$forum_id&auth=$permission") : '', 'UA_TRACE' => ($show_trace) ? append_sid("{$phpbb_admin_path}index.$phpEx", "i=permissions&mode=trace&u=$ug_id&f=$forum_id&auth=$permission", false) : '', 'PERMISSION' => $phpbb_permissions->get_permission_lang($permission), )); } else { $template->assign_block_vars($tpl_cat . '.' . $tpl_mask, array( 'S_YES' => ($allowed == ACL_YES) ? true : false, 'S_NEVER' => ($allowed == ACL_NEVER) ? true : false, 'S_NO' => ($allowed == ACL_NO) ? true : false, 'UG_ID' => $ug_id, 'FORUM_ID' => $forum_id, 'FIELD_NAME' => $permission, 'S_FIELD_NAME' => 'setting[' . $ug_id . '][' . $forum_id . '][' . $permission . ']', 'U_TRACE' => ($show_trace) ? append_sid("{$phpbb_admin_path}index.$phpEx", "i=permissions&mode=trace&u=$ug_id&f=$forum_id&auth=$permission") : '', 'UA_TRACE' => ($show_trace) ? append_sid("{$phpbb_admin_path}index.$phpEx", "i=permissions&mode=trace&u=$ug_id&f=$forum_id&auth=$permission", false) : '', 'PERMISSION' => $phpbb_permissions->get_permission_lang($permission), )); } } } } /** * Building content array from permission rows with explicit key ordering * used by display_mask() */ function build_permission_array(&$permission_row, &$content_array, &$categories, $key_sort_array) { global $user, $phpbb_container; $phpbb_permissions = $phpbb_container->get('acl.permissions'); foreach ($key_sort_array as $forum_id) { if (!isset($permission_row[$forum_id])) { continue; } $permissions = $permission_row[$forum_id]; ksort($permissions); @reset($permissions); while (list($permission, $auth_setting) = each($permissions)) { $cat = $phpbb_permissions->get_permission_category($permission); // Build our categories array if (!isset($categories[$cat])) { $categories[$cat] = $phpbb_permissions->get_category_lang($cat); } // Build our content array if (!isset($content_array[$forum_id])) { $content_array[$forum_id] = array(); } if (!isset($content_array[$forum_id][$cat])) { $content_array[$forum_id][$cat] = array( 'S_YES' => false, 'S_NEVER' => false, 'S_NO' => false, 'permissions' => array(), ); } $content_array[$forum_id][$cat]['S_YES'] |= ($auth_setting == ACL_YES) ? true : false; $content_array[$forum_id][$cat]['S_NEVER'] |= ($auth_setting == ACL_NEVER) ? true : false; $content_array[$forum_id][$cat]['S_NO'] |= ($auth_setting == ACL_NO) ? true : false; $content_array[$forum_id][$cat]['permissions'][$permission] = $auth_setting; } } } /** * Use permissions from another user. This transferes a permission set from one user to another. * The other user is always able to revert back to his permission set. * This function does not check for lower/higher permissions, it is possible for the user to gain * "more" permissions by this. * Admin permissions will not be copied. */ function ghost_permissions($from_user_id, $to_user_id) { global $db; if ($to_user_id == ANONYMOUS) { return false; } $hold_ary = $this->acl_raw_data_single_user($from_user_id); // Key 0 in $hold_ary are global options, all others are forum_ids // We disallow copying admin permissions foreach ($this->acl_options['global'] as $opt => $id) { if (strpos($opt, 'a_') === 0) { $hold_ary[0][$this->acl_options['id'][$opt]] = ACL_NEVER; } } // Force a_switchperm to be allowed $hold_ary[0][$this->acl_options['id']['a_switchperm']] = ACL_YES; $user_permissions = $this->build_bitstring($hold_ary); if (!$user_permissions) { return false; } $sql = 'UPDATE ' . USERS_TABLE . " SET user_permissions = '" . $db->sql_escape($user_permissions) . "', user_perm_from = $from_user_id WHERE user_id = " . $to_user_id; $db->sql_query($sql); return true; } } acp_contact.php000077700000007705151514745240007563 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } /** * @package acp */ class acp_contact { public $u_action; public function main($id, $mode) { global $user, $request, $template; global $config, $phpbb_root_path, $phpEx, $phpbb_container; $user->add_lang(array('acp/board', 'posting')); $this->tpl_name = 'acp_contact'; $this->page_title = 'ACP_CONTACT_SETTINGS'; $form_name = 'acp_contact'; add_form_key($form_name); $error = ''; if (!function_exists('display_custom_bbcodes')) { include($phpbb_root_path . 'includes/functions_display.' . $phpEx); } if (!class_exists('parse_message')) { include($phpbb_root_path . 'includes/message_parser.' . $phpEx); } $config_text = $phpbb_container->get('config_text'); $contact_admin_data = $config_text->get_array(array( 'contact_admin_info', 'contact_admin_info_uid', 'contact_admin_info_bitfield', 'contact_admin_info_flags', )); $contact_admin_info = $contact_admin_data['contact_admin_info']; $contact_admin_info_uid = $contact_admin_data['contact_admin_info_uid']; $contact_admin_info_bitfield= $contact_admin_data['contact_admin_info_bitfield']; $contact_admin_info_flags = $contact_admin_data['contact_admin_info_flags']; if ($request->is_set_post('submit') || $request->is_set_post('preview')) { if (!check_form_key($form_name)) { $error = $user->lang('FORM_INVALID'); } $contact_admin_info = $request->variable('contact_admin_info', '', true); generate_text_for_storage( $contact_admin_info, $contact_admin_info_uid, $contact_admin_info_bitfield, $contact_admin_info_flags, !$request->variable('disable_bbcode', false), !$request->variable('disable_magic_url', false), !$request->variable('disable_smilies', false) ); if (empty($error) && $request->is_set_post('submit')) { $config->set('contact_admin_form_enable', $request->variable('contact_admin_form_enable', false)); $config_text->set_array(array( 'contact_admin_info' => $contact_admin_info, 'contact_admin_info_uid' => $contact_admin_info_uid, 'contact_admin_info_bitfield' => $contact_admin_info_bitfield, 'contact_admin_info_flags' => $contact_admin_info_flags, )); trigger_error($user->lang['CONTACT_US_INFO_UPDATED'] . adm_back_link($this->u_action)); } } $contact_admin_info_preview = ''; if ($request->is_set_post('preview')) { $contact_admin_info_preview = generate_text_for_display($contact_admin_info, $contact_admin_info_uid, $contact_admin_info_bitfield, $contact_admin_info_flags); } $contact_admin_edit = generate_text_for_edit($contact_admin_info, $contact_admin_info_uid, $contact_admin_info_flags); $template->assign_vars(array( 'ERRORS' => $error, 'CONTACT_ENABLED' => $config['contact_admin_form_enable'], 'CONTACT_US_INFO' => $contact_admin_edit['text'], 'CONTACT_US_INFO_PREVIEW' => $contact_admin_info_preview, 'S_BBCODE_DISABLE_CHECKED' => !$contact_admin_edit['allow_bbcode'], 'S_SMILIES_DISABLE_CHECKED' => !$contact_admin_edit['allow_smilies'], 'S_MAGIC_URL_DISABLE_CHECKED' => !$contact_admin_edit['allow_urls'], 'BBCODE_STATUS' => $user->lang('BBCODE_IS_ON', '<a href="' . append_sid("{$phpbb_root_path}faq.$phpEx", 'mode=bbcode') . '">', '</a>'), 'SMILIES_STATUS' => $user->lang['SMILIES_ARE_ON'], 'IMG_STATUS' => $user->lang['IMAGES_ARE_ON'], 'FLASH_STATUS' => $user->lang['FLASH_IS_ON'], 'URL_STATUS' => $user->lang['URL_IS_ON'], 'S_BBCODE_ALLOWED' => true, 'S_SMILIES_ALLOWED' => true, 'S_BBCODE_IMG' => true, 'S_BBCODE_FLASH' => true, 'S_LINKS_ALLOWED' => true, )); // Assigning custom bbcodes display_custom_bbcodes(); } } acp_forums.php000077700000207662151514745240007447 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_forums { var $u_action; var $parent_id = 0; function main($id, $mode) { global $db, $user, $auth, $template, $cache, $request, $phpbb_dispatcher; global $config, $phpbb_admin_path, $phpbb_root_path, $phpEx; $user->add_lang('acp/forums'); $this->tpl_name = 'acp_forums'; $this->page_title = 'ACP_MANAGE_FORUMS'; $form_key = 'acp_forums'; add_form_key($form_key); $action = request_var('action', ''); $update = (isset($_POST['update'])) ? true : false; $forum_id = request_var('f', 0); $this->parent_id = request_var('parent_id', 0); $forum_data = $errors = array(); if ($update && !check_form_key($form_key)) { $update = false; $errors[] = $user->lang['FORM_INVALID']; } // Check additional permissions switch ($action) { case 'progress_bar': $start = request_var('start', 0); $total = request_var('total', 0); $this->display_progress_bar($start, $total); break; case 'delete': if (!$auth->acl_get('a_forumdel')) { trigger_error($user->lang['NO_PERMISSION_FORUM_DELETE'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); } break; case 'add': if (!$auth->acl_get('a_forumadd')) { trigger_error($user->lang['NO_PERMISSION_FORUM_ADD'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); } break; } // Major routines if ($update) { switch ($action) { case 'delete': $action_subforums = request_var('action_subforums', ''); $subforums_to_id = request_var('subforums_to_id', 0); $action_posts = request_var('action_posts', ''); $posts_to_id = request_var('posts_to_id', 0); $errors = $this->delete_forum($forum_id, $action_posts, $action_subforums, $posts_to_id, $subforums_to_id); if (sizeof($errors)) { break; } $auth->acl_clear_prefetch(); $cache->destroy('sql', FORUMS_TABLE); trigger_error($user->lang['FORUM_DELETED'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id)); break; case 'edit': $forum_data = array( 'forum_id' => $forum_id ); // No break here case 'add': $forum_data += array( 'parent_id' => request_var('forum_parent_id', $this->parent_id), 'forum_type' => request_var('forum_type', FORUM_POST), 'type_action' => request_var('type_action', ''), 'forum_status' => request_var('forum_status', ITEM_UNLOCKED), 'forum_parents' => '', 'forum_name' => utf8_normalize_nfc(request_var('forum_name', '', true)), 'forum_link' => request_var('forum_link', ''), 'forum_link_track' => request_var('forum_link_track', false), 'forum_desc' => utf8_normalize_nfc(request_var('forum_desc', '', true)), 'forum_desc_uid' => '', 'forum_desc_options' => 7, 'forum_desc_bitfield' => '', 'forum_rules' => utf8_normalize_nfc(request_var('forum_rules', '', true)), 'forum_rules_uid' => '', 'forum_rules_options' => 7, 'forum_rules_bitfield' => '', 'forum_rules_link' => request_var('forum_rules_link', ''), 'forum_image' => request_var('forum_image', ''), 'forum_style' => request_var('forum_style', 0), 'display_subforum_list' => request_var('display_subforum_list', false), 'display_on_index' => request_var('display_on_index', false), 'forum_topics_per_page' => request_var('topics_per_page', 0), 'enable_indexing' => request_var('enable_indexing', true), 'enable_icons' => request_var('enable_icons', false), 'enable_prune' => request_var('enable_prune', false), 'enable_post_review' => request_var('enable_post_review', true), 'enable_quick_reply' => request_var('enable_quick_reply', false), 'enable_shadow_prune' => request_var('enable_shadow_prune', false), 'prune_days' => request_var('prune_days', 7), 'prune_viewed' => request_var('prune_viewed', 7), 'prune_freq' => request_var('prune_freq', 1), 'prune_old_polls' => request_var('prune_old_polls', false), 'prune_announce' => request_var('prune_announce', false), 'prune_sticky' => request_var('prune_sticky', false), 'prune_shadow_days' => request_var('prune_shadow_days', 7), 'prune_shadow_freq' => request_var('prune_shadow_freq', 1), 'forum_password' => request_var('forum_password', '', true), 'forum_password_confirm'=> request_var('forum_password_confirm', '', true), 'forum_password_unset' => request_var('forum_password_unset', false), ); /** * Request forum data and operate on it (parse texts, etc.) * * @event core.acp_manage_forums_request_data * @var string action Type of the action: add|edit * @var array forum_data Array with new forum data * @since 3.1.0-a1 */ $vars = array('action', 'forum_data'); extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_request_data', compact($vars))); // On add, add empty forum_options... else do not consider it (not updating it) if ($action == 'add') { $forum_data['forum_options'] = 0; } // Use link_display_on_index setting if forum type is link if ($forum_data['forum_type'] == FORUM_LINK) { $forum_data['display_on_index'] = request_var('link_display_on_index', false); } // Linked forums and categories are not able to be locked... if ($forum_data['forum_type'] == FORUM_LINK || $forum_data['forum_type'] == FORUM_CAT) { $forum_data['forum_status'] = ITEM_UNLOCKED; } $forum_data['show_active'] = ($forum_data['forum_type'] == FORUM_POST) ? request_var('display_recent', true) : request_var('display_active', false); // Get data for forum rules if specified... if ($forum_data['forum_rules']) { generate_text_for_storage($forum_data['forum_rules'], $forum_data['forum_rules_uid'], $forum_data['forum_rules_bitfield'], $forum_data['forum_rules_options'], request_var('rules_parse_bbcode', false), request_var('rules_parse_urls', false), request_var('rules_parse_smilies', false)); } // Get data for forum description if specified if ($forum_data['forum_desc']) { generate_text_for_storage($forum_data['forum_desc'], $forum_data['forum_desc_uid'], $forum_data['forum_desc_bitfield'], $forum_data['forum_desc_options'], request_var('desc_parse_bbcode', false), request_var('desc_parse_urls', false), request_var('desc_parse_smilies', false)); } $errors = $this->update_forum_data($forum_data); if (!sizeof($errors)) { $forum_perm_from = request_var('forum_perm_from', 0); $cache->destroy('sql', FORUMS_TABLE); $copied_permissions = false; // Copy permissions? if ($forum_perm_from && $forum_perm_from != $forum_data['forum_id'] && ($action != 'edit' || empty($forum_id) || ($auth->acl_get('a_fauth') && $auth->acl_get('a_authusers') && $auth->acl_get('a_authgroups') && $auth->acl_get('a_mauth')))) { copy_forum_permissions($forum_perm_from, $forum_data['forum_id'], ($action == 'edit') ? true : false); phpbb_cache_moderators($db, $cache, $auth); $copied_permissions = true; } /* Commented out because of questionable UI workflow - re-visit for 3.0.7 else if (!$this->parent_id && $action != 'edit' && $auth->acl_get('a_fauth') && $auth->acl_get('a_authusers') && $auth->acl_get('a_authgroups') && $auth->acl_get('a_mauth')) { $this->copy_permission_page($forum_data); return; } */ $auth->acl_clear_prefetch(); $acl_url = '&mode=setting_forum_local&forum_id[]=' . $forum_data['forum_id']; $message = ($action == 'add') ? $user->lang['FORUM_CREATED'] : $user->lang['FORUM_UPDATED']; // redirect directly to permission settings screen if authed if ($action == 'add' && !$copied_permissions && $auth->acl_get('a_fauth')) { $message .= '<br /><br />' . sprintf($user->lang['REDIRECT_ACL'], '<a href="' . append_sid("{$phpbb_admin_path}index.$phpEx", 'i=permissions' . $acl_url) . '">', '</a>'); meta_refresh(4, append_sid("{$phpbb_admin_path}index.$phpEx", 'i=permissions' . $acl_url)); } trigger_error($message . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id)); } break; } } switch ($action) { case 'move_up': case 'move_down': if (!$forum_id) { trigger_error($user->lang['NO_FORUM'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); } $sql = 'SELECT * FROM ' . FORUMS_TABLE . " WHERE forum_id = $forum_id"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$row) { trigger_error($user->lang['NO_FORUM'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); } $move_forum_name = $this->move_forum_by($row, $action, 1); if ($move_forum_name !== false) { add_log('admin', 'LOG_FORUM_' . strtoupper($action), $row['forum_name'], $move_forum_name); $cache->destroy('sql', FORUMS_TABLE); } if ($request->is_ajax()) { $json_response = new \phpbb\json_response; $json_response->send(array('success' => ($move_forum_name !== false))); } break; case 'sync': if (!$forum_id) { trigger_error($user->lang['NO_FORUM'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); } @set_time_limit(0); $sql = 'SELECT forum_name, (forum_topics_approved + forum_topics_unapproved + forum_topics_softdeleted) AS total_topics FROM ' . FORUMS_TABLE . " WHERE forum_id = $forum_id"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$row) { trigger_error($user->lang['NO_FORUM'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); } if ($row['total_topics']) { $sql = 'SELECT MIN(topic_id) as min_topic_id, MAX(topic_id) as max_topic_id FROM ' . TOPICS_TABLE . ' WHERE forum_id = ' . $forum_id; $result = $db->sql_query($sql); $row2 = $db->sql_fetchrow($result); $db->sql_freeresult($result); // Typecast to int if there is no data available $row2['min_topic_id'] = (int) $row2['min_topic_id']; $row2['max_topic_id'] = (int) $row2['max_topic_id']; $start = request_var('start', $row2['min_topic_id']); $batch_size = 2000; $end = $start + $batch_size; // Sync all topics in batch mode... sync('topic', 'range', 'topic_id BETWEEN ' . $start . ' AND ' . $end, true, true); if ($end < $row2['max_topic_id']) { // We really need to find a way of showing statistics... no progress here $sql = 'SELECT COUNT(topic_id) as num_topics FROM ' . TOPICS_TABLE . ' WHERE forum_id = ' . $forum_id . ' AND topic_id BETWEEN ' . $start . ' AND ' . $end; $result = $db->sql_query($sql); $topics_done = request_var('topics_done', 0) + (int) $db->sql_fetchfield('num_topics'); $db->sql_freeresult($result); $start += $batch_size; $url = $this->u_action . "&parent_id={$this->parent_id}&f=$forum_id&action=sync&start=$start&topics_done=$topics_done&total={$row['total_topics']}"; meta_refresh(0, $url); $template->assign_vars(array( 'U_PROGRESS_BAR' => $this->u_action . "&action=progress_bar&start=$topics_done&total={$row['total_topics']}", 'UA_PROGRESS_BAR' => addslashes($this->u_action . "&action=progress_bar&start=$topics_done&total={$row['total_topics']}"), 'S_CONTINUE_SYNC' => true, 'L_PROGRESS_EXPLAIN' => sprintf($user->lang['SYNC_IN_PROGRESS_EXPLAIN'], $topics_done, $row['total_topics'])) ); return; } } $url = $this->u_action . "&parent_id={$this->parent_id}&f=$forum_id&action=sync_forum"; meta_refresh(0, $url); $template->assign_vars(array( 'U_PROGRESS_BAR' => $this->u_action . '&action=progress_bar', 'UA_PROGRESS_BAR' => addslashes($this->u_action . '&action=progress_bar'), 'S_CONTINUE_SYNC' => true, 'L_PROGRESS_EXPLAIN' => sprintf($user->lang['SYNC_IN_PROGRESS_EXPLAIN'], 0, $row['total_topics'])) ); return; break; case 'sync_forum': $sql = 'SELECT forum_name, forum_type FROM ' . FORUMS_TABLE . " WHERE forum_id = $forum_id"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$row) { trigger_error($user->lang['NO_FORUM'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); } sync('forum', 'forum_id', $forum_id, false, true); add_log('admin', 'LOG_FORUM_SYNC', $row['forum_name']); $cache->destroy('sql', FORUMS_TABLE); $template->assign_var('L_FORUM_RESYNCED', sprintf($user->lang['FORUM_RESYNCED'], $row['forum_name'])); break; case 'add': case 'edit': if ($update) { $forum_data['forum_flags'] = 0; $forum_data['forum_flags'] += (request_var('forum_link_track', false)) ? FORUM_FLAG_LINK_TRACK : 0; $forum_data['forum_flags'] += (request_var('prune_old_polls', false)) ? FORUM_FLAG_PRUNE_POLL : 0; $forum_data['forum_flags'] += (request_var('prune_announce', false)) ? FORUM_FLAG_PRUNE_ANNOUNCE : 0; $forum_data['forum_flags'] += (request_var('prune_sticky', false)) ? FORUM_FLAG_PRUNE_STICKY : 0; $forum_data['forum_flags'] += ($forum_data['show_active']) ? FORUM_FLAG_ACTIVE_TOPICS : 0; $forum_data['forum_flags'] += (request_var('enable_post_review', true)) ? FORUM_FLAG_POST_REVIEW : 0; $forum_data['forum_flags'] += (request_var('enable_quick_reply', false)) ? FORUM_FLAG_QUICK_REPLY : 0; } // Initialise $row, so we always have it in the event $row = array(); // Show form to create/modify a forum if ($action == 'edit') { $this->page_title = 'EDIT_FORUM'; $row = $this->get_forum_info($forum_id); $old_forum_type = $row['forum_type']; if (!$update) { $forum_data = $row; } else { $forum_data['left_id'] = $row['left_id']; $forum_data['right_id'] = $row['right_id']; } // Make sure no direct child forums are able to be selected as parents. $exclude_forums = array(); foreach (get_forum_branch($forum_id, 'children') as $row) { $exclude_forums[] = $row['forum_id']; } $parents_list = make_forum_select($forum_data['parent_id'], $exclude_forums, false, false, false); $forum_data['forum_password_confirm'] = $forum_data['forum_password']; } else { $this->page_title = 'CREATE_FORUM'; $forum_id = $this->parent_id; $parents_list = make_forum_select($this->parent_id, false, false, false, false); // Fill forum data with default values if (!$update) { $forum_data = array( 'parent_id' => $this->parent_id, 'forum_type' => FORUM_POST, 'forum_status' => ITEM_UNLOCKED, 'forum_name' => utf8_normalize_nfc(request_var('forum_name', '', true)), 'forum_link' => '', 'forum_link_track' => false, 'forum_desc' => '', 'forum_rules' => '', 'forum_rules_link' => '', 'forum_image' => '', 'forum_style' => 0, 'display_subforum_list' => true, 'display_on_index' => false, 'forum_topics_per_page' => 0, 'enable_indexing' => true, 'enable_icons' => false, 'enable_prune' => false, 'prune_days' => 7, 'prune_viewed' => 7, 'prune_freq' => 1, 'enable_shadow_prune' => false, 'prune_shadow_days' => 7, 'prune_shadow_freq' => 1, 'forum_flags' => FORUM_FLAG_POST_REVIEW + FORUM_FLAG_ACTIVE_TOPICS, 'forum_options' => 0, 'forum_password' => '', 'forum_password_confirm'=> '', ); } } /** * Initialise data before we display the add/edit form * * @event core.acp_manage_forums_initialise_data * @var string action Type of the action: add|edit * @var bool update Do we display the form only * or did the user press submit * @var int forum_id When editing: the forum id, * when creating: the parent forum id * @var array row Array with current forum data * empty when creating new forum * @var array forum_data Array with new forum data * @var string parents_list List of parent options * @since 3.1.0-a1 */ $vars = array('action', 'update', 'forum_id', 'row', 'forum_data', 'parents_list'); extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_initialise_data', compact($vars))); $forum_rules_data = array( 'text' => $forum_data['forum_rules'], 'allow_bbcode' => true, 'allow_smilies' => true, 'allow_urls' => true ); $forum_desc_data = array( 'text' => $forum_data['forum_desc'], 'allow_bbcode' => true, 'allow_smilies' => true, 'allow_urls' => true ); $forum_rules_preview = ''; // Parse rules if specified if ($forum_data['forum_rules']) { if (!isset($forum_data['forum_rules_uid'])) { // Before we are able to display the preview and plane text, we need to parse our request_var()'d value... $forum_data['forum_rules_uid'] = ''; $forum_data['forum_rules_bitfield'] = ''; $forum_data['forum_rules_options'] = 0; generate_text_for_storage($forum_data['forum_rules'], $forum_data['forum_rules_uid'], $forum_data['forum_rules_bitfield'], $forum_data['forum_rules_options'], request_var('rules_allow_bbcode', false), request_var('rules_allow_urls', false), request_var('rules_allow_smilies', false)); } // Generate preview content $forum_rules_preview = generate_text_for_display($forum_data['forum_rules'], $forum_data['forum_rules_uid'], $forum_data['forum_rules_bitfield'], $forum_data['forum_rules_options']); // decode... $forum_rules_data = generate_text_for_edit($forum_data['forum_rules'], $forum_data['forum_rules_uid'], $forum_data['forum_rules_options']); } // Parse desciption if specified if ($forum_data['forum_desc']) { if (!isset($forum_data['forum_desc_uid'])) { // Before we are able to display the preview and plane text, we need to parse our request_var()'d value... $forum_data['forum_desc_uid'] = ''; $forum_data['forum_desc_bitfield'] = ''; $forum_data['forum_desc_options'] = 0; generate_text_for_storage($forum_data['forum_desc'], $forum_data['forum_desc_uid'], $forum_data['forum_desc_bitfield'], $forum_data['forum_desc_options'], request_var('desc_allow_bbcode', false), request_var('desc_allow_urls', false), request_var('desc_allow_smilies', false)); } // decode... $forum_desc_data = generate_text_for_edit($forum_data['forum_desc'], $forum_data['forum_desc_uid'], $forum_data['forum_desc_options']); } $forum_type_options = ''; $forum_type_ary = array(FORUM_CAT => 'CAT', FORUM_POST => 'FORUM', FORUM_LINK => 'LINK'); foreach ($forum_type_ary as $value => $lang) { $forum_type_options .= '<option value="' . $value . '"' . (($value == $forum_data['forum_type']) ? ' selected="selected"' : '') . '>' . $user->lang['TYPE_' . $lang] . '</option>'; } $styles_list = style_select($forum_data['forum_style'], true); $statuslist = '<option value="' . ITEM_UNLOCKED . '"' . (($forum_data['forum_status'] == ITEM_UNLOCKED) ? ' selected="selected"' : '') . '>' . $user->lang['UNLOCKED'] . '</option><option value="' . ITEM_LOCKED . '"' . (($forum_data['forum_status'] == ITEM_LOCKED) ? ' selected="selected"' : '') . '>' . $user->lang['LOCKED'] . '</option>'; $sql = 'SELECT forum_id FROM ' . FORUMS_TABLE . ' WHERE forum_type = ' . FORUM_POST . " AND forum_id <> $forum_id"; $result = $db->sql_query_limit($sql, 1); $postable_forum_exists = false; if ($db->sql_fetchrow($result)) { $postable_forum_exists = true; } $db->sql_freeresult($result); // Subforum move options if ($action == 'edit' && $forum_data['forum_type'] == FORUM_CAT) { $subforums_id = array(); $subforums = get_forum_branch($forum_id, 'children'); foreach ($subforums as $row) { $subforums_id[] = $row['forum_id']; } $forums_list = make_forum_select($forum_data['parent_id'], $subforums_id); if ($postable_forum_exists) { $template->assign_vars(array( 'S_MOVE_FORUM_OPTIONS' => make_forum_select($forum_data['parent_id'], $subforums_id)) // , false, true, false??? ); } $template->assign_vars(array( 'S_HAS_SUBFORUMS' => ($forum_data['right_id'] - $forum_data['left_id'] > 1) ? true : false, 'S_FORUMS_LIST' => $forums_list) ); } else if ($postable_forum_exists) { $template->assign_vars(array( 'S_MOVE_FORUM_OPTIONS' => make_forum_select($forum_data['parent_id'], $forum_id, false, true, false)) ); } $s_show_display_on_index = false; if ($forum_data['parent_id'] > 0) { // if this forum is a subforum put the "display on index" checkbox if ($parent_info = $this->get_forum_info($forum_data['parent_id'])) { if ($parent_info['parent_id'] > 0 || $parent_info['forum_type'] == FORUM_CAT) { $s_show_display_on_index = true; } } } if (strlen($forum_data['forum_password']) == 32) { $errors[] = $user->lang['FORUM_PASSWORD_OLD']; } $template_data = array( 'S_EDIT_FORUM' => true, 'S_ERROR' => (sizeof($errors)) ? true : false, 'S_PARENT_ID' => $this->parent_id, 'S_FORUM_PARENT_ID' => $forum_data['parent_id'], 'S_ADD_ACTION' => ($action == 'add') ? true : false, 'U_BACK' => $this->u_action . '&parent_id=' . $this->parent_id, 'U_EDIT_ACTION' => $this->u_action . "&parent_id={$this->parent_id}&action=$action&f=$forum_id", 'L_COPY_PERMISSIONS_EXPLAIN' => $user->lang['COPY_PERMISSIONS_' . strtoupper($action) . '_EXPLAIN'], 'L_TITLE' => $user->lang[$this->page_title], 'ERROR_MSG' => (sizeof($errors)) ? implode('<br />', $errors) : '', 'FORUM_NAME' => $forum_data['forum_name'], 'FORUM_DATA_LINK' => $forum_data['forum_link'], 'FORUM_IMAGE' => $forum_data['forum_image'], 'FORUM_IMAGE_SRC' => ($forum_data['forum_image']) ? $phpbb_root_path . $forum_data['forum_image'] : '', 'FORUM_POST' => FORUM_POST, 'FORUM_LINK' => FORUM_LINK, 'FORUM_CAT' => FORUM_CAT, 'PRUNE_FREQ' => $forum_data['prune_freq'], 'PRUNE_DAYS' => $forum_data['prune_days'], 'PRUNE_VIEWED' => $forum_data['prune_viewed'], 'PRUNE_SHADOW_FREQ' => $forum_data['prune_shadow_freq'], 'PRUNE_SHADOW_DAYS' => $forum_data['prune_shadow_days'], 'TOPICS_PER_PAGE' => $forum_data['forum_topics_per_page'], 'FORUM_RULES_LINK' => $forum_data['forum_rules_link'], 'FORUM_RULES' => $forum_data['forum_rules'], 'FORUM_RULES_PREVIEW' => $forum_rules_preview, 'FORUM_RULES_PLAIN' => $forum_rules_data['text'], 'S_BBCODE_CHECKED' => ($forum_rules_data['allow_bbcode']) ? true : false, 'S_SMILIES_CHECKED' => ($forum_rules_data['allow_smilies']) ? true : false, 'S_URLS_CHECKED' => ($forum_rules_data['allow_urls']) ? true : false, 'S_FORUM_PASSWORD_SET' => (empty($forum_data['forum_password'])) ? false : true, 'FORUM_DESC' => $forum_desc_data['text'], 'S_DESC_BBCODE_CHECKED' => ($forum_desc_data['allow_bbcode']) ? true : false, 'S_DESC_SMILIES_CHECKED' => ($forum_desc_data['allow_smilies']) ? true : false, 'S_DESC_URLS_CHECKED' => ($forum_desc_data['allow_urls']) ? true : false, 'S_FORUM_TYPE_OPTIONS' => $forum_type_options, 'S_STATUS_OPTIONS' => $statuslist, 'S_PARENT_OPTIONS' => $parents_list, 'S_STYLES_OPTIONS' => $styles_list, 'S_FORUM_OPTIONS' => make_forum_select(($action == 'add') ? $forum_data['parent_id'] : false, ($action == 'edit') ? $forum_data['forum_id'] : false, false, false, false), 'S_SHOW_DISPLAY_ON_INDEX' => $s_show_display_on_index, 'S_FORUM_POST' => ($forum_data['forum_type'] == FORUM_POST) ? true : false, 'S_FORUM_ORIG_POST' => (isset($old_forum_type) && $old_forum_type == FORUM_POST) ? true : false, 'S_FORUM_ORIG_CAT' => (isset($old_forum_type) && $old_forum_type == FORUM_CAT) ? true : false, 'S_FORUM_ORIG_LINK' => (isset($old_forum_type) && $old_forum_type == FORUM_LINK) ? true : false, 'S_FORUM_LINK' => ($forum_data['forum_type'] == FORUM_LINK) ? true : false, 'S_FORUM_CAT' => ($forum_data['forum_type'] == FORUM_CAT) ? true : false, 'S_ENABLE_INDEXING' => ($forum_data['enable_indexing']) ? true : false, 'S_TOPIC_ICONS' => ($forum_data['enable_icons']) ? true : false, 'S_DISPLAY_SUBFORUM_LIST' => ($forum_data['display_subforum_list']) ? true : false, 'S_DISPLAY_ON_INDEX' => ($forum_data['display_on_index']) ? true : false, 'S_PRUNE_ENABLE' => ($forum_data['enable_prune']) ? true : false, 'S_PRUNE_SHADOW_ENABLE' => ($forum_data['enable_shadow_prune']) ? true : false, 'S_FORUM_LINK_TRACK' => ($forum_data['forum_flags'] & FORUM_FLAG_LINK_TRACK) ? true : false, 'S_PRUNE_OLD_POLLS' => ($forum_data['forum_flags'] & FORUM_FLAG_PRUNE_POLL) ? true : false, 'S_PRUNE_ANNOUNCE' => ($forum_data['forum_flags'] & FORUM_FLAG_PRUNE_ANNOUNCE) ? true : false, 'S_PRUNE_STICKY' => ($forum_data['forum_flags'] & FORUM_FLAG_PRUNE_STICKY) ? true : false, 'S_DISPLAY_ACTIVE_TOPICS' => ($forum_data['forum_type'] == FORUM_POST) ? ($forum_data['forum_flags'] & FORUM_FLAG_ACTIVE_TOPICS) : true, 'S_ENABLE_ACTIVE_TOPICS' => ($forum_data['forum_type'] == FORUM_CAT) ? ($forum_data['forum_flags'] & FORUM_FLAG_ACTIVE_TOPICS) : false, 'S_ENABLE_POST_REVIEW' => ($forum_data['forum_flags'] & FORUM_FLAG_POST_REVIEW) ? true : false, 'S_ENABLE_QUICK_REPLY' => ($forum_data['forum_flags'] & FORUM_FLAG_QUICK_REPLY) ? true : false, 'S_CAN_COPY_PERMISSIONS' => ($action != 'edit' || empty($forum_id) || ($auth->acl_get('a_fauth') && $auth->acl_get('a_authusers') && $auth->acl_get('a_authgroups') && $auth->acl_get('a_mauth'))) ? true : false, ); /** * Modify forum template data before we display the form * * @event core.acp_manage_forums_display_form * @var string action Type of the action: add|edit * @var bool update Do we display the form only * or did the user press submit * @var int forum_id When editing: the forum id, * when creating: the parent forum id * @var array row Array with current forum data * empty when creating new forum * @var array forum_data Array with new forum data * @var string parents_list List of parent options * @var array errors Array of errors, if you add errors * ensure to update the template variables * S_ERROR and ERROR_MSG to display it * @var array template_data Array with new forum data * @since 3.1.0-a1 */ $vars = array( 'action', 'update', 'forum_id', 'row', 'forum_data', 'parents_list', 'errors', 'template_data', ); extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_display_form', compact($vars))); $template->assign_vars($template_data); return; break; case 'delete': if (!$forum_id) { trigger_error($user->lang['NO_FORUM'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); } $forum_data = $this->get_forum_info($forum_id); $subforums_id = array(); $subforums = get_forum_branch($forum_id, 'children'); foreach ($subforums as $row) { $subforums_id[] = $row['forum_id']; } $forums_list = make_forum_select($forum_data['parent_id'], $subforums_id); $sql = 'SELECT forum_id FROM ' . FORUMS_TABLE . ' WHERE forum_type = ' . FORUM_POST . " AND forum_id <> $forum_id"; $result = $db->sql_query_limit($sql, 1); if ($db->sql_fetchrow($result)) { $template->assign_vars(array( 'S_MOVE_FORUM_OPTIONS' => make_forum_select($forum_data['parent_id'], $subforums_id, false, true)) // , false, true, false??? ); } $db->sql_freeresult($result); $parent_id = ($this->parent_id == $forum_id) ? 0 : $this->parent_id; $template->assign_vars(array( 'S_DELETE_FORUM' => true, 'U_ACTION' => $this->u_action . "&parent_id={$parent_id}&action=delete&f=$forum_id", 'U_BACK' => $this->u_action . '&parent_id=' . $this->parent_id, 'FORUM_NAME' => $forum_data['forum_name'], 'S_FORUM_POST' => ($forum_data['forum_type'] == FORUM_POST) ? true : false, 'S_FORUM_LINK' => ($forum_data['forum_type'] == FORUM_LINK) ? true : false, 'S_HAS_SUBFORUMS' => ($forum_data['right_id'] - $forum_data['left_id'] > 1) ? true : false, 'S_FORUMS_LIST' => $forums_list, 'S_ERROR' => (sizeof($errors)) ? true : false, 'ERROR_MSG' => (sizeof($errors)) ? implode('<br />', $errors) : '') ); return; break; case 'copy_perm': $forum_perm_from = request_var('forum_perm_from', 0); // Copy permissions? if (!empty($forum_perm_from) && $forum_perm_from != $forum_id) { copy_forum_permissions($forum_perm_from, $forum_id, true); phpbb_cache_moderators($db, $cache, $auth); $auth->acl_clear_prefetch(); $cache->destroy('sql', FORUMS_TABLE); $acl_url = '&mode=setting_forum_local&forum_id[]=' . $forum_id; $message = $user->lang['FORUM_UPDATED']; // Redirect to permissions if ($auth->acl_get('a_fauth')) { $message .= '<br /><br />' . sprintf($user->lang['REDIRECT_ACL'], '<a href="' . append_sid("{$phpbb_admin_path}index.$phpEx", 'i=permissions' . $acl_url) . '">', '</a>'); } trigger_error($message . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id)); } break; } // Default management page if (!$this->parent_id) { $navigation = $user->lang['FORUM_INDEX']; } else { $navigation = '<a href="' . $this->u_action . '">' . $user->lang['FORUM_INDEX'] . '</a>'; $forums_nav = get_forum_branch($this->parent_id, 'parents', 'descending'); foreach ($forums_nav as $row) { if ($row['forum_id'] == $this->parent_id) { $navigation .= ' -> ' . $row['forum_name']; } else { $navigation .= ' -> <a href="' . $this->u_action . '&parent_id=' . $row['forum_id'] . '">' . $row['forum_name'] . '</a>'; } } } // Jumpbox $forum_box = make_forum_select($this->parent_id, false, false, false, false); //make_forum_select($this->parent_id); if ($action == 'sync' || $action == 'sync_forum') { $template->assign_var('S_RESYNCED', true); } $sql = 'SELECT * FROM ' . FORUMS_TABLE . " WHERE parent_id = $this->parent_id ORDER BY left_id"; $result = $db->sql_query($sql); if ($row = $db->sql_fetchrow($result)) { do { $forum_type = $row['forum_type']; if ($row['forum_status'] == ITEM_LOCKED) { $folder_image = '<img src="images/icon_folder_lock.gif" alt="' . $user->lang['LOCKED'] . '" />'; } else { switch ($forum_type) { case FORUM_LINK: $folder_image = '<img src="images/icon_folder_link.gif" alt="' . $user->lang['LINK'] . '" />'; break; default: $folder_image = ($row['left_id'] + 1 != $row['right_id']) ? '<img src="images/icon_subfolder.gif" alt="' . $user->lang['SUBFORUM'] . '" />' : '<img src="images/icon_folder.gif" alt="' . $user->lang['FOLDER'] . '" />'; break; } } $url = $this->u_action . "&parent_id=$this->parent_id&f={$row['forum_id']}"; $template->assign_block_vars('forums', array( 'FOLDER_IMAGE' => $folder_image, 'FORUM_IMAGE' => ($row['forum_image']) ? '<img src="' . $phpbb_root_path . $row['forum_image'] . '" alt="" />' : '', 'FORUM_IMAGE_SRC' => ($row['forum_image']) ? $phpbb_root_path . $row['forum_image'] : '', 'FORUM_NAME' => $row['forum_name'], 'FORUM_DESCRIPTION' => generate_text_for_display($row['forum_desc'], $row['forum_desc_uid'], $row['forum_desc_bitfield'], $row['forum_desc_options']), 'FORUM_TOPICS' => $row['forum_topics_approved'], 'FORUM_POSTS' => $row['forum_posts_approved'], 'S_FORUM_LINK' => ($forum_type == FORUM_LINK) ? true : false, 'S_FORUM_POST' => ($forum_type == FORUM_POST) ? true : false, 'U_FORUM' => $this->u_action . '&parent_id=' . $row['forum_id'], 'U_MOVE_UP' => $url . '&action=move_up', 'U_MOVE_DOWN' => $url . '&action=move_down', 'U_EDIT' => $url . '&action=edit', 'U_DELETE' => $url . '&action=delete', 'U_SYNC' => $url . '&action=sync') ); } while ($row = $db->sql_fetchrow($result)); } else if ($this->parent_id) { $row = $this->get_forum_info($this->parent_id); $url = $this->u_action . '&parent_id=' . $this->parent_id . '&f=' . $row['forum_id']; $template->assign_vars(array( 'S_NO_FORUMS' => true, 'U_EDIT' => $url . '&action=edit', 'U_DELETE' => $url . '&action=delete', 'U_SYNC' => $url . '&action=sync') ); } $db->sql_freeresult($result); $template->assign_vars(array( 'ERROR_MSG' => (sizeof($errors)) ? implode('<br />', $errors) : '', 'NAVIGATION' => $navigation, 'FORUM_BOX' => $forum_box, 'U_SEL_ACTION' => $this->u_action, 'U_ACTION' => $this->u_action . '&parent_id=' . $this->parent_id, 'U_PROGRESS_BAR' => $this->u_action . '&action=progress_bar', 'UA_PROGRESS_BAR' => addslashes($this->u_action . '&action=progress_bar'), )); } /** * Get forum details */ function get_forum_info($forum_id) { global $db; $sql = 'SELECT * FROM ' . FORUMS_TABLE . " WHERE forum_id = $forum_id"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$row) { trigger_error("Forum #$forum_id does not exist", E_USER_ERROR); } return $row; } /** * Update forum data */ function update_forum_data(&$forum_data) { global $db, $user, $cache, $phpbb_root_path, $phpbb_container, $phpbb_dispatcher; $errors = array(); /** * Validate the forum data before we create/update the forum * * @event core.acp_manage_forums_validate_data * @var array forum_data Array with new forum data * @var array errors Array of errors, should be strings and not * language key. * @since 3.1.0-a1 */ $vars = array('forum_data', 'errors'); extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_validate_data', compact($vars))); if ($forum_data['forum_name'] == '') { $errors[] = $user->lang['FORUM_NAME_EMPTY']; } if (utf8_strlen($forum_data['forum_desc']) > 4000) { $errors[] = $user->lang['FORUM_DESC_TOO_LONG']; } if (utf8_strlen($forum_data['forum_rules']) > 4000) { $errors[] = $user->lang['FORUM_RULES_TOO_LONG']; } if ($forum_data['forum_password'] || $forum_data['forum_password_confirm']) { if ($forum_data['forum_password'] != $forum_data['forum_password_confirm']) { $forum_data['forum_password'] = $forum_data['forum_password_confirm'] = ''; $errors[] = $user->lang['FORUM_PASSWORD_MISMATCH']; } } if ($forum_data['prune_days'] < 0 || $forum_data['prune_viewed'] < 0 || $forum_data['prune_freq'] < 0) { $forum_data['prune_days'] = $forum_data['prune_viewed'] = $forum_data['prune_freq'] = 0; $errors[] = $user->lang['FORUM_DATA_NEGATIVE']; } $range_test_ary = array( array('lang' => 'FORUM_TOPICS_PAGE', 'value' => $forum_data['forum_topics_per_page'], 'column_type' => 'TINT:0'), ); if (!empty($forum_data['forum_image']) && !file_exists($phpbb_root_path . $forum_data['forum_image'])) { $errors[] = $user->lang['FORUM_IMAGE_NO_EXIST']; } validate_range($range_test_ary, $errors); // Set forum flags // 1 = link tracking // 2 = prune old polls // 4 = prune announcements // 8 = prune stickies // 16 = show active topics // 32 = enable post review $forum_data['forum_flags'] = 0; $forum_data['forum_flags'] += ($forum_data['forum_link_track']) ? FORUM_FLAG_LINK_TRACK : 0; $forum_data['forum_flags'] += ($forum_data['prune_old_polls']) ? FORUM_FLAG_PRUNE_POLL : 0; $forum_data['forum_flags'] += ($forum_data['prune_announce']) ? FORUM_FLAG_PRUNE_ANNOUNCE : 0; $forum_data['forum_flags'] += ($forum_data['prune_sticky']) ? FORUM_FLAG_PRUNE_STICKY : 0; $forum_data['forum_flags'] += ($forum_data['show_active']) ? FORUM_FLAG_ACTIVE_TOPICS : 0; $forum_data['forum_flags'] += ($forum_data['enable_post_review']) ? FORUM_FLAG_POST_REVIEW : 0; $forum_data['forum_flags'] += ($forum_data['enable_quick_reply']) ? FORUM_FLAG_QUICK_REPLY : 0; // Unset data that are not database fields $forum_data_sql = $forum_data; unset($forum_data_sql['forum_link_track']); unset($forum_data_sql['prune_old_polls']); unset($forum_data_sql['prune_announce']); unset($forum_data_sql['prune_sticky']); unset($forum_data_sql['show_active']); unset($forum_data_sql['enable_post_review']); unset($forum_data_sql['enable_quick_reply']); unset($forum_data_sql['forum_password_confirm']); // What are we going to do tonight Brain? The same thing we do everynight, // try to take over the world ... or decide whether to continue update // and if so, whether it's a new forum/cat/link or an existing one if (sizeof($errors)) { return $errors; } // As we don't know the old password, it's kinda tricky to detect changes if ($forum_data_sql['forum_password_unset']) { $forum_data_sql['forum_password'] = ''; } else if (empty($forum_data_sql['forum_password'])) { unset($forum_data_sql['forum_password']); } else { // Instantiate passwords manager $passwords_manager = $phpbb_container->get('passwords.manager'); $forum_data_sql['forum_password'] = $passwords_manager->hash($forum_data_sql['forum_password']); } unset($forum_data_sql['forum_password_unset']); /** * Remove invalid values from forum_data_sql that should not be updated * * @event core.acp_manage_forums_update_data_before * @var array forum_data Array with forum data * @var array forum_data_sql Array with data we are going to update * If forum_data_sql[forum_id] is set, we update * that forum, otherwise a new one is created. * @since 3.1.0-a1 */ $vars = array('forum_data', 'forum_data_sql'); extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_update_data_before', compact($vars))); $is_new_forum = !isset($forum_data_sql['forum_id']); if ($is_new_forum) { // no forum_id means we're creating a new forum unset($forum_data_sql['type_action']); if ($forum_data_sql['parent_id']) { $sql = 'SELECT left_id, right_id, forum_type FROM ' . FORUMS_TABLE . ' WHERE forum_id = ' . $forum_data_sql['parent_id']; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$row) { trigger_error($user->lang['PARENT_NOT_EXIST'] . adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), E_USER_WARNING); } if ($row['forum_type'] == FORUM_LINK) { $errors[] = $user->lang['PARENT_IS_LINK_FORUM']; return $errors; } $sql = 'UPDATE ' . FORUMS_TABLE . ' SET left_id = left_id + 2, right_id = right_id + 2 WHERE left_id > ' . $row['right_id']; $db->sql_query($sql); $sql = 'UPDATE ' . FORUMS_TABLE . ' SET right_id = right_id + 2 WHERE ' . $row['left_id'] . ' BETWEEN left_id AND right_id'; $db->sql_query($sql); $forum_data_sql['left_id'] = $row['right_id']; $forum_data_sql['right_id'] = $row['right_id'] + 1; } else { $sql = 'SELECT MAX(right_id) AS right_id FROM ' . FORUMS_TABLE; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); $forum_data_sql['left_id'] = $row['right_id'] + 1; $forum_data_sql['right_id'] = $row['right_id'] + 2; } $sql = 'INSERT INTO ' . FORUMS_TABLE . ' ' . $db->sql_build_array('INSERT', $forum_data_sql); $db->sql_query($sql); $forum_data['forum_id'] = $db->sql_nextid(); add_log('admin', 'LOG_FORUM_ADD', $forum_data['forum_name']); } else { $row = $this->get_forum_info($forum_data_sql['forum_id']); if ($row['forum_type'] == FORUM_POST && $row['forum_type'] != $forum_data_sql['forum_type']) { // Has subforums and want to change into a link? if ($row['right_id'] - $row['left_id'] > 1 && $forum_data_sql['forum_type'] == FORUM_LINK) { $errors[] = $user->lang['FORUM_WITH_SUBFORUMS_NOT_TO_LINK']; return $errors; } // we're turning a postable forum into a non-postable forum if ($forum_data_sql['type_action'] == 'move') { $to_forum_id = request_var('to_forum_id', 0); if ($to_forum_id) { $errors = $this->move_forum_content($forum_data_sql['forum_id'], $to_forum_id); } else { return array($user->lang['NO_DESTINATION_FORUM']); } } else if ($forum_data_sql['type_action'] == 'delete') { $errors = $this->delete_forum_content($forum_data_sql['forum_id']); } else { return array($user->lang['NO_FORUM_ACTION']); } $forum_data_sql['forum_posts_approved'] = $forum_data_sql['forum_posts_unapproved'] = $forum_data_sql['forum_posts_softdeleted'] = $forum_data_sql['forum_topics_approved'] = $forum_data_sql['forum_topics_unapproved'] = $forum_data_sql['forum_topics_softdeleted'] = 0; $forum_data_sql['forum_last_post_id'] = $forum_data_sql['forum_last_poster_id'] = $forum_data_sql['forum_last_post_time'] = 0; $forum_data_sql['forum_last_poster_name'] = $forum_data_sql['forum_last_poster_colour'] = ''; } else if ($row['forum_type'] == FORUM_CAT && $forum_data_sql['forum_type'] == FORUM_LINK) { // Has subforums? if ($row['right_id'] - $row['left_id'] > 1) { // We are turning a category into a link - but need to decide what to do with the subforums. $action_subforums = request_var('action_subforums', ''); $subforums_to_id = request_var('subforums_to_id', 0); if ($action_subforums == 'delete') { $rows = get_forum_branch($row['forum_id'], 'children', 'descending', false); foreach ($rows as $_row) { // Do not remove the forum id we are about to change. ;) if ($_row['forum_id'] == $row['forum_id']) { continue; } $forum_ids[] = $_row['forum_id']; $errors = array_merge($errors, $this->delete_forum_content($_row['forum_id'])); } if (sizeof($errors)) { return $errors; } if (sizeof($forum_ids)) { $sql = 'DELETE FROM ' . FORUMS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_ids); $db->sql_query($sql); $sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_ids); $db->sql_query($sql); $sql = 'DELETE FROM ' . ACL_USERS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_ids); $db->sql_query($sql); // Delete forum ids from extension groups table $sql = 'SELECT group_id, allowed_forums FROM ' . EXTENSION_GROUPS_TABLE; $result = $db->sql_query($sql); while ($_row = $db->sql_fetchrow($result)) { if (!$_row['allowed_forums']) { continue; } $allowed_forums = unserialize(trim($_row['allowed_forums'])); $allowed_forums = array_diff($allowed_forums, $forum_ids); $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . " SET allowed_forums = '" . ((sizeof($allowed_forums)) ? serialize($allowed_forums) : '') . "' WHERE group_id = {$_row['group_id']}"; $db->sql_query($sql); } $db->sql_freeresult($result); $cache->destroy('_extensions'); } } else if ($action_subforums == 'move') { if (!$subforums_to_id) { return array($user->lang['NO_DESTINATION_FORUM']); } $sql = 'SELECT forum_name FROM ' . FORUMS_TABLE . ' WHERE forum_id = ' . $subforums_to_id; $result = $db->sql_query($sql); $_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$_row) { return array($user->lang['NO_FORUM']); } $subforums_to_name = $_row['forum_name']; $sql = 'SELECT forum_id FROM ' . FORUMS_TABLE . " WHERE parent_id = {$row['forum_id']}"; $result = $db->sql_query($sql); while ($_row = $db->sql_fetchrow($result)) { $this->move_forum($_row['forum_id'], $subforums_to_id); } $db->sql_freeresult($result); $sql = 'UPDATE ' . FORUMS_TABLE . " SET parent_id = $subforums_to_id WHERE parent_id = {$row['forum_id']}"; $db->sql_query($sql); } // Adjust the left/right id $sql = 'UPDATE ' . FORUMS_TABLE . ' SET right_id = left_id + 1 WHERE forum_id = ' . $row['forum_id']; $db->sql_query($sql); } } else if ($row['forum_type'] == FORUM_CAT && $forum_data_sql['forum_type'] == FORUM_POST) { // Changing a category to a forum? Reset the data (you can't post directly in a cat, you must use a forum) $forum_data_sql['forum_posts_approved'] = 0; $forum_data_sql['forum_posts_unapproved'] = 0; $forum_data_sql['forum_posts_softdeleted'] = 0; $forum_data_sql['forum_topics_approved'] = 0; $forum_data_sql['forum_topics_unapproved'] = 0; $forum_data_sql['forum_topics_softdeleted'] = 0; $forum_data_sql['forum_last_post_id'] = 0; $forum_data_sql['forum_last_post_subject'] = ''; $forum_data_sql['forum_last_post_time'] = 0; $forum_data_sql['forum_last_poster_id'] = 0; $forum_data_sql['forum_last_poster_name'] = ''; $forum_data_sql['forum_last_poster_colour'] = ''; } if (sizeof($errors)) { return $errors; } if ($row['parent_id'] != $forum_data_sql['parent_id']) { if ($row['forum_id'] != $forum_data_sql['parent_id']) { $errors = $this->move_forum($forum_data_sql['forum_id'], $forum_data_sql['parent_id']); } else { $forum_data_sql['parent_id'] = $row['parent_id']; } } if (sizeof($errors)) { return $errors; } unset($forum_data_sql['type_action']); if ($row['forum_name'] != $forum_data_sql['forum_name']) { // the forum name has changed, clear the parents list of all forums (for safety) $sql = 'UPDATE ' . FORUMS_TABLE . " SET forum_parents = ''"; $db->sql_query($sql); } // Setting the forum id to the forum id is not really received well by some dbs. ;) $forum_id = $forum_data_sql['forum_id']; unset($forum_data_sql['forum_id']); $sql = 'UPDATE ' . FORUMS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $forum_data_sql) . ' WHERE forum_id = ' . $forum_id; $db->sql_query($sql); // Add it back $forum_data['forum_id'] = $forum_id; add_log('admin', 'LOG_FORUM_EDIT', $forum_data['forum_name']); } /** * Event after a forum was updated or created * * @event core.acp_manage_forums_update_data_after * @var array forum_data Array with forum data * @var array forum_data_sql Array with data we updated * @var bool is_new_forum Did we create a forum or update one * If you want to overwrite this value, * ensure to set forum_data_sql[forum_id] * @var array errors Array of errors, should be strings and not * language key. * @since 3.1.0-a1 */ $vars = array('forum_data', 'forum_data_sql', 'is_new_forum', 'errors'); extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_update_data_after', compact($vars))); return $errors; } /** * Move forum */ function move_forum($from_id, $to_id) { global $db, $user, $phpbb_dispatcher; $to_data = $moved_ids = $errors = array(); // Check if we want to move to a parent with link type if ($to_id > 0) { $to_data = $this->get_forum_info($to_id); if ($to_data['forum_type'] == FORUM_LINK) { $errors[] = $user->lang['PARENT_IS_LINK_FORUM']; } } /** * Event when we move all children of one forum to another * * This event may be triggered, when a forum is deleted * * @event core.acp_manage_forums_move_children * @var int from_id If of the current parent forum * @var int to_id If of the new parent forum * @var array errors Array of errors, should be strings and not * language key. * @since 3.1.0-a1 */ $vars = array('from_id', 'to_id', 'errors'); extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_move_children', compact($vars))); // Return if there were errors if (!empty($errors)) { return $errors; } $moved_forums = get_forum_branch($from_id, 'children', 'descending'); $from_data = $moved_forums[0]; $diff = sizeof($moved_forums) * 2; $moved_ids = array(); for ($i = 0; $i < sizeof($moved_forums); ++$i) { $moved_ids[] = $moved_forums[$i]['forum_id']; } // Resync parents $sql = 'UPDATE ' . FORUMS_TABLE . " SET right_id = right_id - $diff, forum_parents = '' WHERE left_id < " . $from_data['right_id'] . " AND right_id > " . $from_data['right_id']; $db->sql_query($sql); // Resync righthand side of tree $sql = 'UPDATE ' . FORUMS_TABLE . " SET left_id = left_id - $diff, right_id = right_id - $diff, forum_parents = '' WHERE left_id > " . $from_data['right_id']; $db->sql_query($sql); if ($to_id > 0) { // Retrieve $to_data again, it may have been changed... $to_data = $this->get_forum_info($to_id); // Resync new parents $sql = 'UPDATE ' . FORUMS_TABLE . " SET right_id = right_id + $diff, forum_parents = '' WHERE " . $to_data['right_id'] . ' BETWEEN left_id AND right_id AND ' . $db->sql_in_set('forum_id', $moved_ids, true); $db->sql_query($sql); // Resync the righthand side of the tree $sql = 'UPDATE ' . FORUMS_TABLE . " SET left_id = left_id + $diff, right_id = right_id + $diff, forum_parents = '' WHERE left_id > " . $to_data['right_id'] . ' AND ' . $db->sql_in_set('forum_id', $moved_ids, true); $db->sql_query($sql); // Resync moved branch $to_data['right_id'] += $diff; if ($to_data['right_id'] > $from_data['right_id']) { $diff = '+ ' . ($to_data['right_id'] - $from_data['right_id'] - 1); } else { $diff = '- ' . abs($to_data['right_id'] - $from_data['right_id'] - 1); } } else { $sql = 'SELECT MAX(right_id) AS right_id FROM ' . FORUMS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $moved_ids, true); $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); $diff = '+ ' . ($row['right_id'] - $from_data['left_id'] + 1); } $sql = 'UPDATE ' . FORUMS_TABLE . " SET left_id = left_id $diff, right_id = right_id $diff, forum_parents = '' WHERE " . $db->sql_in_set('forum_id', $moved_ids); $db->sql_query($sql); return $errors; } /** * Move forum content from one to another forum */ function move_forum_content($from_id, $to_id, $sync = true) { global $db, $phpbb_dispatcher; $errors = array(); /** * Event when we move content from one forum to another * * @event core.acp_manage_forums_move_content * @var int from_id If of the current parent forum * @var int to_id If of the new parent forum * @var bool sync Shall we sync the "to"-forum's data * @var array errors Array of errors, should be strings and not * language key. If this array is not empty, * The content will not be moved. * @since 3.1.0-a1 */ $vars = array('from_id', 'to_id', 'sync', 'errors'); extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_move_content', compact($vars))); // Return if there were errors if (!empty($errors)) { return $errors; } $table_ary = array(LOG_TABLE, POSTS_TABLE, TOPICS_TABLE, DRAFTS_TABLE, TOPICS_TRACK_TABLE); foreach ($table_ary as $table) { $sql = "UPDATE $table SET forum_id = $to_id WHERE forum_id = $from_id"; $db->sql_query($sql); } unset($table_ary); $table_ary = array(FORUMS_ACCESS_TABLE, FORUMS_TRACK_TABLE, FORUMS_WATCH_TABLE, MODERATOR_CACHE_TABLE); foreach ($table_ary as $table) { $sql = "DELETE FROM $table WHERE forum_id = $from_id"; $db->sql_query($sql); } if ($sync) { // Delete ghost topics that link back to the same forum then resync counters sync('topic_moved'); sync('forum', 'forum_id', $to_id, false, true); } return array(); } /** * Remove complete forum */ function delete_forum($forum_id, $action_posts = 'delete', $action_subforums = 'delete', $posts_to_id = 0, $subforums_to_id = 0) { global $db, $user, $cache; $forum_data = $this->get_forum_info($forum_id); $errors = array(); $log_action_posts = $log_action_forums = $posts_to_name = $subforums_to_name = ''; $forum_ids = array($forum_id); if ($action_posts == 'delete') { $log_action_posts = 'POSTS'; $errors = array_merge($errors, $this->delete_forum_content($forum_id)); } else if ($action_posts == 'move') { if (!$posts_to_id) { $errors[] = $user->lang['NO_DESTINATION_FORUM']; } else { $log_action_posts = 'MOVE_POSTS'; $sql = 'SELECT forum_name FROM ' . FORUMS_TABLE . ' WHERE forum_id = ' . $posts_to_id; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$row) { $errors[] = $user->lang['NO_FORUM']; } else { $posts_to_name = $row['forum_name']; $errors = array_merge($errors, $this->move_forum_content($forum_id, $posts_to_id)); } } } if (sizeof($errors)) { return $errors; } if ($action_subforums == 'delete') { $log_action_forums = 'FORUMS'; $rows = get_forum_branch($forum_id, 'children', 'descending', false); foreach ($rows as $row) { $forum_ids[] = $row['forum_id']; $errors = array_merge($errors, $this->delete_forum_content($row['forum_id'])); } if (sizeof($errors)) { return $errors; } $diff = sizeof($forum_ids) * 2; $sql = 'DELETE FROM ' . FORUMS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_ids); $db->sql_query($sql); $sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_ids); $db->sql_query($sql); $sql = 'DELETE FROM ' . ACL_USERS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_ids); $db->sql_query($sql); } else if ($action_subforums == 'move') { if (!$subforums_to_id) { $errors[] = $user->lang['NO_DESTINATION_FORUM']; } else { $log_action_forums = 'MOVE_FORUMS'; $sql = 'SELECT forum_name FROM ' . FORUMS_TABLE . ' WHERE forum_id = ' . $subforums_to_id; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$row) { $errors[] = $user->lang['NO_FORUM']; } else { $subforums_to_name = $row['forum_name']; $sql = 'SELECT forum_id FROM ' . FORUMS_TABLE . " WHERE parent_id = $forum_id"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $this->move_forum($row['forum_id'], $subforums_to_id); } $db->sql_freeresult($result); // Grab new forum data for correct tree updating later $forum_data = $this->get_forum_info($forum_id); $sql = 'UPDATE ' . FORUMS_TABLE . " SET parent_id = $subforums_to_id WHERE parent_id = $forum_id"; $db->sql_query($sql); $diff = 2; $sql = 'DELETE FROM ' . FORUMS_TABLE . " WHERE forum_id = $forum_id"; $db->sql_query($sql); $sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . " WHERE forum_id = $forum_id"; $db->sql_query($sql); $sql = 'DELETE FROM ' . ACL_USERS_TABLE . " WHERE forum_id = $forum_id"; $db->sql_query($sql); } } if (sizeof($errors)) { return $errors; } } else { $diff = 2; $sql = 'DELETE FROM ' . FORUMS_TABLE . " WHERE forum_id = $forum_id"; $db->sql_query($sql); $sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . " WHERE forum_id = $forum_id"; $db->sql_query($sql); $sql = 'DELETE FROM ' . ACL_USERS_TABLE . " WHERE forum_id = $forum_id"; $db->sql_query($sql); } // Resync tree $sql = 'UPDATE ' . FORUMS_TABLE . " SET right_id = right_id - $diff WHERE left_id < {$forum_data['right_id']} AND right_id > {$forum_data['right_id']}"; $db->sql_query($sql); $sql = 'UPDATE ' . FORUMS_TABLE . " SET left_id = left_id - $diff, right_id = right_id - $diff WHERE left_id > {$forum_data['right_id']}"; $db->sql_query($sql); // Delete forum ids from extension groups table $sql = 'SELECT group_id, allowed_forums FROM ' . EXTENSION_GROUPS_TABLE; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { if (!$row['allowed_forums']) { continue; } $allowed_forums = unserialize(trim($row['allowed_forums'])); $allowed_forums = array_diff($allowed_forums, $forum_ids); $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . " SET allowed_forums = '" . ((sizeof($allowed_forums)) ? serialize($allowed_forums) : '') . "' WHERE group_id = {$row['group_id']}"; $db->sql_query($sql); } $db->sql_freeresult($result); $cache->destroy('_extensions'); $log_action = implode('_', array($log_action_posts, $log_action_forums)); switch ($log_action) { case 'MOVE_POSTS_MOVE_FORUMS': add_log('admin', 'LOG_FORUM_DEL_MOVE_POSTS_MOVE_FORUMS', $posts_to_name, $subforums_to_name, $forum_data['forum_name']); break; case 'MOVE_POSTS_FORUMS': add_log('admin', 'LOG_FORUM_DEL_MOVE_POSTS_FORUMS', $posts_to_name, $forum_data['forum_name']); break; case 'POSTS_MOVE_FORUMS': add_log('admin', 'LOG_FORUM_DEL_POSTS_MOVE_FORUMS', $subforums_to_name, $forum_data['forum_name']); break; case '_MOVE_FORUMS': add_log('admin', 'LOG_FORUM_DEL_MOVE_FORUMS', $subforums_to_name, $forum_data['forum_name']); break; case 'MOVE_POSTS_': add_log('admin', 'LOG_FORUM_DEL_MOVE_POSTS', $posts_to_name, $forum_data['forum_name']); break; case 'POSTS_FORUMS': add_log('admin', 'LOG_FORUM_DEL_POSTS_FORUMS', $forum_data['forum_name']); break; case '_FORUMS': add_log('admin', 'LOG_FORUM_DEL_FORUMS', $forum_data['forum_name']); break; case 'POSTS_': add_log('admin', 'LOG_FORUM_DEL_POSTS', $forum_data['forum_name']); break; default: add_log('admin', 'LOG_FORUM_DEL_FORUM', $forum_data['forum_name']); break; } return $errors; } /** * Delete forum content */ function delete_forum_content($forum_id) { global $db, $config, $phpbb_root_path, $phpEx; include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx); $db->sql_transaction('begin'); // Select then delete all attachments $sql = 'SELECT a.topic_id FROM ' . POSTS_TABLE . ' p, ' . ATTACHMENTS_TABLE . " a WHERE p.forum_id = $forum_id AND a.in_message = 0 AND a.topic_id = p.topic_id"; $result = $db->sql_query($sql); $topic_ids = array(); while ($row = $db->sql_fetchrow($result)) { $topic_ids[] = $row['topic_id']; } $db->sql_freeresult($result); delete_attachments('topic', $topic_ids, false); // Delete shadow topics pointing to topics in this forum delete_topic_shadows($forum_id); // Before we remove anything we make sure we are able to adjust the post counts later. ;) $sql = 'SELECT poster_id FROM ' . POSTS_TABLE . ' WHERE forum_id = ' . $forum_id . ' AND post_postcount = 1 AND post_visibility = ' . ITEM_APPROVED; $result = $db->sql_query($sql); $post_counts = array(); while ($row = $db->sql_fetchrow($result)) { $post_counts[$row['poster_id']] = (!empty($post_counts[$row['poster_id']])) ? $post_counts[$row['poster_id']] + 1 : 1; } $db->sql_freeresult($result); switch ($db->get_sql_layer()) { case 'mysql4': case 'mysqli': // Delete everything else and thank MySQL for offering multi-table deletion $tables_ary = array( SEARCH_WORDMATCH_TABLE => 'post_id', REPORTS_TABLE => 'post_id', WARNINGS_TABLE => 'post_id', BOOKMARKS_TABLE => 'topic_id', TOPICS_WATCH_TABLE => 'topic_id', TOPICS_POSTED_TABLE => 'topic_id', POLL_OPTIONS_TABLE => 'topic_id', POLL_VOTES_TABLE => 'topic_id', ); $sql = 'DELETE ' . POSTS_TABLE; $sql_using = "\nFROM " . POSTS_TABLE; $sql_where = "\nWHERE " . POSTS_TABLE . ".forum_id = $forum_id\n"; foreach ($tables_ary as $table => $field) { $sql .= ", $table "; $sql_using .= ", $table "; $sql_where .= "\nAND $table.$field = " . POSTS_TABLE . ".$field"; } $db->sql_query($sql . $sql_using . $sql_where); break; default: // Delete everything else and curse your DB for not offering multi-table deletion $tables_ary = array( 'post_id' => array( SEARCH_WORDMATCH_TABLE, REPORTS_TABLE, WARNINGS_TABLE, ), 'topic_id' => array( BOOKMARKS_TABLE, TOPICS_WATCH_TABLE, TOPICS_POSTED_TABLE, POLL_OPTIONS_TABLE, POLL_VOTES_TABLE, ) ); // Amount of rows we select and delete in one iteration. $batch_size = 500; foreach ($tables_ary as $field => $tables) { $start = 0; do { $sql = "SELECT $field FROM " . POSTS_TABLE . ' WHERE forum_id = ' . $forum_id; $result = $db->sql_query_limit($sql, $batch_size, $start); $ids = array(); while ($row = $db->sql_fetchrow($result)) { $ids[] = $row[$field]; } $db->sql_freeresult($result); if (sizeof($ids)) { $start += sizeof($ids); foreach ($tables as $table) { $db->sql_query("DELETE FROM $table WHERE " . $db->sql_in_set($field, $ids)); } } } while (sizeof($ids) == $batch_size); } unset($ids); break; } $table_ary = array(FORUMS_ACCESS_TABLE, FORUMS_TRACK_TABLE, FORUMS_WATCH_TABLE, LOG_TABLE, MODERATOR_CACHE_TABLE, POSTS_TABLE, TOPICS_TABLE, TOPICS_TRACK_TABLE); foreach ($table_ary as $table) { $db->sql_query("DELETE FROM $table WHERE forum_id = $forum_id"); } // Set forum ids to 0 $table_ary = array(DRAFTS_TABLE); foreach ($table_ary as $table) { $db->sql_query("UPDATE $table SET forum_id = 0 WHERE forum_id = $forum_id"); } // Adjust users post counts if (sizeof($post_counts)) { foreach ($post_counts as $poster_id => $substract) { $sql = 'UPDATE ' . USERS_TABLE . ' SET user_posts = 0 WHERE user_id = ' . $poster_id . ' AND user_posts < ' . $substract; $db->sql_query($sql); $sql = 'UPDATE ' . USERS_TABLE . ' SET user_posts = user_posts - ' . $substract . ' WHERE user_id = ' . $poster_id . ' AND user_posts >= ' . $substract; $db->sql_query($sql); } } $db->sql_transaction('commit'); // Make sure the overall post/topic count is correct... $sql = 'SELECT COUNT(post_id) AS stat FROM ' . POSTS_TABLE . ' WHERE post_visibility = ' . ITEM_APPROVED; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); set_config('num_posts', (int) $row['stat'], true); $sql = 'SELECT COUNT(topic_id) AS stat FROM ' . TOPICS_TABLE . ' WHERE topic_visibility = ' . ITEM_APPROVED; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); set_config('num_topics', (int) $row['stat'], true); $sql = 'SELECT COUNT(attach_id) as stat FROM ' . ATTACHMENTS_TABLE; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); set_config('num_files', (int) $row['stat'], true); $sql = 'SELECT SUM(filesize) as stat FROM ' . ATTACHMENTS_TABLE; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); set_config('upload_dir_size', (float) $row['stat'], true); return array(); } /** * Move forum position by $steps up/down */ function move_forum_by($forum_row, $action = 'move_up', $steps = 1) { global $db; /** * Fetch all the siblings between the module's current spot * and where we want to move it to. If there are less than $steps * siblings between the current spot and the target then the * module will move as far as possible */ $sql = 'SELECT forum_id, forum_name, left_id, right_id FROM ' . FORUMS_TABLE . " WHERE parent_id = {$forum_row['parent_id']} AND " . (($action == 'move_up') ? "right_id < {$forum_row['right_id']} ORDER BY right_id DESC" : "left_id > {$forum_row['left_id']} ORDER BY left_id ASC"); $result = $db->sql_query_limit($sql, $steps); $target = array(); while ($row = $db->sql_fetchrow($result)) { $target = $row; } $db->sql_freeresult($result); if (!sizeof($target)) { // The forum is already on top or bottom return false; } /** * $left_id and $right_id define the scope of the nodes that are affected by the move. * $diff_up and $diff_down are the values to substract or add to each node's left_id * and right_id in order to move them up or down. * $move_up_left and $move_up_right define the scope of the nodes that are moving * up. Other nodes in the scope of ($left_id, $right_id) are considered to move down. */ if ($action == 'move_up') { $left_id = $target['left_id']; $right_id = $forum_row['right_id']; $diff_up = $forum_row['left_id'] - $target['left_id']; $diff_down = $forum_row['right_id'] + 1 - $forum_row['left_id']; $move_up_left = $forum_row['left_id']; $move_up_right = $forum_row['right_id']; } else { $left_id = $forum_row['left_id']; $right_id = $target['right_id']; $diff_up = $forum_row['right_id'] + 1 - $forum_row['left_id']; $diff_down = $target['right_id'] - $forum_row['right_id']; $move_up_left = $forum_row['right_id'] + 1; $move_up_right = $target['right_id']; } // Now do the dirty job $sql = 'UPDATE ' . FORUMS_TABLE . " SET left_id = left_id + CASE WHEN left_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up} ELSE {$diff_down} END, right_id = right_id + CASE WHEN right_id BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up} ELSE {$diff_down} END, forum_parents = '' WHERE left_id BETWEEN {$left_id} AND {$right_id} AND right_id BETWEEN {$left_id} AND {$right_id}"; $db->sql_query($sql); return $target['forum_name']; } /** * Display progress bar for syncinc forums */ function display_progress_bar($start, $total) { global $template, $user; adm_page_header($user->lang['SYNC_IN_PROGRESS']); $template->set_filenames(array( 'body' => 'progress_bar.html') ); $template->assign_vars(array( 'L_PROGRESS' => $user->lang['SYNC_IN_PROGRESS'], 'L_PROGRESS_EXPLAIN' => ($start && $total) ? sprintf($user->lang['SYNC_IN_PROGRESS_EXPLAIN'], $start, $total) : $user->lang['SYNC_IN_PROGRESS']) ); adm_page_footer(); } /** * Display copy permission page * Not used at the moment - we will have a look at it for 3.0.7 */ function copy_permission_page($forum_data) { global $phpEx, $phpbb_admin_path, $template, $user; $acl_url = '&mode=setting_forum_local&forum_id[]=' . $forum_data['forum_id']; $action = append_sid($this->u_action . "&parent_id={$this->parent_id}&f={$forum_data['forum_id']}&action=copy_perm"); $l_acl = sprintf($user->lang['COPY_TO_ACL'], '<a href="' . append_sid("{$phpbb_admin_path}index.$phpEx", 'i=permissions' . $acl_url) . '">', '</a>'); $this->tpl_name = 'acp_forums_copy_perm'; $template->assign_vars(array( 'U_ACL' => append_sid("{$phpbb_admin_path}index.$phpEx", 'i=permissions' . $acl_url), 'L_ACL_LINK' => $l_acl, 'L_BACK_LINK' => adm_back_link($this->u_action . '&parent_id=' . $this->parent_id), 'S_COPY_ACTION' => $action, 'S_FORUM_OPTIONS' => make_forum_select($forum_data['parent_id'], $forum_data['forum_id'], false, false, false), )); } } acp_reasons.php000077700000027361151514745240007602 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_reasons { var $u_action; function main($id, $mode) { global $db, $user, $auth, $template, $cache; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; global $request; $user->add_lang(array('mcp', 'acp/posting')); // Set up general vars $action = request_var('action', ''); $submit = (isset($_POST['submit'])) ? true : false; $reason_id = request_var('id', 0); $this->tpl_name = 'acp_reasons'; $this->page_title = 'ACP_REASONS'; $form_name = 'acp_reason'; add_form_key('acp_reason'); $error = array(); switch ($action) { case 'add': case 'edit': $reason_row = array( 'reason_title' => utf8_normalize_nfc(request_var('reason_title', '', true)), 'reason_description' => utf8_normalize_nfc(request_var('reason_description', '', true)), ); if ($submit) { if (!check_form_key($form_name)) { $error[] = $user->lang['FORM_INVALID']; } // Reason specified? if (!$reason_row['reason_title'] || !$reason_row['reason_description']) { $error[] = $user->lang['NO_REASON_INFO']; } $check_double = ($action == 'add') ? true : false; if ($action == 'edit') { $sql = 'SELECT reason_title FROM ' . REPORTS_REASONS_TABLE . " WHERE reason_id = $reason_id"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (strtolower($row['reason_title']) == 'other' || strtolower($reason_row['reason_title']) == 'other') { $reason_row['reason_title'] = 'other'; } if ($row['reason_title'] != $reason_row['reason_title']) { $check_double = true; } } // Check for same reason if adding it... if ($check_double) { $sql = 'SELECT reason_id FROM ' . REPORTS_REASONS_TABLE . " WHERE reason_title = '" . $db->sql_escape($reason_row['reason_title']) . "'"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($row || ($action == 'add' && strtolower($reason_row['reason_title']) == 'other')) { $error[] = $user->lang['REASON_ALREADY_EXIST']; } } if (!sizeof($error)) { // New reason? if ($action == 'add') { // Get new order... $sql = 'SELECT MAX(reason_order) as max_reason_order FROM ' . REPORTS_REASONS_TABLE; $result = $db->sql_query($sql); $max_order = (int) $db->sql_fetchfield('max_reason_order'); $db->sql_freeresult($result); $sql_ary = array( 'reason_title' => (string) $reason_row['reason_title'], 'reason_description' => (string) $reason_row['reason_description'], 'reason_order' => $max_order + 1 ); $db->sql_query('INSERT INTO ' . REPORTS_REASONS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); $log = 'ADDED'; } else if ($reason_id) { $sql_ary = array( 'reason_title' => (string) $reason_row['reason_title'], 'reason_description' => (string) $reason_row['reason_description'], ); $db->sql_query('UPDATE ' . REPORTS_REASONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE reason_id = ' . $reason_id); $log = 'UPDATED'; } add_log('admin', 'LOG_REASON_' . $log, $reason_row['reason_title']); trigger_error($user->lang['REASON_' . $log] . adm_back_link($this->u_action)); } } else if ($reason_id) { $sql = 'SELECT * FROM ' . REPORTS_REASONS_TABLE . ' WHERE reason_id = ' . $reason_id; $result = $db->sql_query($sql); $reason_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$reason_row) { trigger_error($user->lang['NO_REASON'] . adm_back_link($this->u_action), E_USER_WARNING); } } $l_title = ($action == 'edit') ? 'EDIT' : 'ADD'; $translated = false; // If the reason is defined within the language file, we will use the localized version, else just use the database entry... if (isset($user->lang['report_reasons']['TITLE'][strtoupper($reason_row['reason_title'])]) && isset($user->lang['report_reasons']['DESCRIPTION'][strtoupper($reason_row['reason_title'])])) { $translated = true; } $template->assign_vars(array( 'L_TITLE' => $user->lang['REASON_' . $l_title], 'U_ACTION' => $this->u_action . "&id=$reason_id&action=$action", 'U_BACK' => $this->u_action, 'ERROR_MSG' => (sizeof($error)) ? implode('<br />', $error) : '', 'REASON_TITLE' => $reason_row['reason_title'], 'REASON_DESCRIPTION' => $reason_row['reason_description'], 'TRANSLATED_TITLE' => ($translated) ? $user->lang['report_reasons']['TITLE'][strtoupper($reason_row['reason_title'])] : '', 'TRANSLATED_DESCRIPTION'=> ($translated) ? $user->lang['report_reasons']['DESCRIPTION'][strtoupper($reason_row['reason_title'])] : '', 'S_AVAILABLE_TITLES' => implode($user->lang['COMMA_SEPARATOR'], array_map('htmlspecialchars', array_keys($user->lang['report_reasons']['TITLE']))), 'S_EDIT_REASON' => true, 'S_TRANSLATED' => $translated, 'S_ERROR' => (sizeof($error)) ? true : false, ) ); return; break; case 'delete': $sql = 'SELECT * FROM ' . REPORTS_REASONS_TABLE . ' WHERE reason_id = ' . $reason_id; $result = $db->sql_query($sql); $reason_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$reason_row) { trigger_error($user->lang['NO_REASON'] . adm_back_link($this->u_action), E_USER_WARNING); } if (strtolower($reason_row['reason_title']) == 'other') { trigger_error($user->lang['NO_REMOVE_DEFAULT_REASON'] . adm_back_link($this->u_action), E_USER_WARNING); } // Let the deletion be confirmed... if (confirm_box(true)) { $sql = 'SELECT reason_id FROM ' . REPORTS_REASONS_TABLE . " WHERE LOWER(reason_title) = 'other'"; $result = $db->sql_query($sql); $other_reason_id = (int) $db->sql_fetchfield('reason_id'); $db->sql_freeresult($result); switch ($db->get_sql_layer()) { // The ugly one! case 'mysqli': case 'mysql4': case 'mysql': // Change the reports using this reason to 'other' $sql = 'UPDATE ' . REPORTS_TABLE . ' SET reason_id = ' . $other_reason_id . ", report_text = CONCAT('" . $db->sql_escape($reason_row['reason_description']) . "\n\n', report_text) WHERE reason_id = $reason_id"; break; // Standard? What's that? case 'mssql': case 'mssql_odbc': case 'mssqlnative': // Change the reports using this reason to 'other' $sql = "DECLARE @ptrval binary(16) SELECT @ptrval = TEXTPTR(report_text) FROM " . REPORTS_TABLE . " WHERE reason_id = " . $reason_id . " UPDATETEXT " . REPORTS_TABLE . ".report_text @ptrval 0 0 '" . $db->sql_escape($reason_row['reason_description']) . "\n\n' UPDATE " . REPORTS_TABLE . ' SET reason_id = ' . $other_reason_id . " WHERE reason_id = $reason_id"; break; // Teh standard case 'postgres': case 'oracle': case 'sqlite': case 'sqlite3': // Change the reports using this reason to 'other' $sql = 'UPDATE ' . REPORTS_TABLE . ' SET reason_id = ' . $other_reason_id . ", report_text = '" . $db->sql_escape($reason_row['reason_description']) . "\n\n' || report_text WHERE reason_id = $reason_id"; break; } $db->sql_query($sql); $db->sql_query('DELETE FROM ' . REPORTS_REASONS_TABLE . ' WHERE reason_id = ' . $reason_id); add_log('admin', 'LOG_REASON_REMOVED', $reason_row['reason_title']); trigger_error($user->lang['REASON_REMOVED'] . adm_back_link($this->u_action)); } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 'i' => $id, 'mode' => $mode, 'action' => $action, 'id' => $reason_id)) ); } break; case 'move_up': case 'move_down': $sql = 'SELECT reason_order FROM ' . REPORTS_REASONS_TABLE . " WHERE reason_id = $reason_id"; $result = $db->sql_query($sql); $order = $db->sql_fetchfield('reason_order'); $db->sql_freeresult($result); if ($order === false || ($order == 0 && $action == 'move_up')) { break; } $order = (int) $order; $order_total = $order * 2 + (($action == 'move_up') ? -1 : 1); $sql = 'UPDATE ' . REPORTS_REASONS_TABLE . ' SET reason_order = ' . $order_total . ' - reason_order WHERE reason_order IN (' . $order . ', ' . (($action == 'move_up') ? $order - 1 : $order + 1) . ')'; $db->sql_query($sql); if ($request->is_ajax()) { $json_response = new \phpbb\json_response; $json_response->send(array( 'success' => (bool) $db->sql_affectedrows(), )); } break; } // By default, check that order is valid and fix it if necessary $sql = 'SELECT reason_id, reason_order FROM ' . REPORTS_REASONS_TABLE . ' ORDER BY reason_order'; $result = $db->sql_query($sql); if ($row = $db->sql_fetchrow($result)) { $order = 0; do { ++$order; if ($row['reason_order'] != $order) { $sql = 'UPDATE ' . REPORTS_REASONS_TABLE . " SET reason_order = $order WHERE reason_id = {$row['reason_id']}"; $db->sql_query($sql); } } while ($row = $db->sql_fetchrow($result)); } $db->sql_freeresult($result); $template->assign_vars(array( 'U_ACTION' => $this->u_action, ) ); // Reason count $sql = 'SELECT reason_id, COUNT(reason_id) AS reason_count FROM ' . REPORTS_TABLE . ' GROUP BY reason_id'; $result = $db->sql_query($sql); $reason_count = array(); while ($row = $db->sql_fetchrow($result)) { $reason_count[$row['reason_id']] = $row['reason_count']; } $db->sql_freeresult($result); $sql = 'SELECT * FROM ' . REPORTS_REASONS_TABLE . ' ORDER BY reason_order ASC'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $translated = false; $other_reason = ($row['reason_title'] == 'other') ? true : false; // If the reason is defined within the language file, we will use the localized version, else just use the database entry... if (isset($user->lang['report_reasons']['TITLE'][strtoupper($row['reason_title'])]) && isset($user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])])) { $row['reason_description'] = $user->lang['report_reasons']['DESCRIPTION'][strtoupper($row['reason_title'])]; $row['reason_title'] = $user->lang['report_reasons']['TITLE'][strtoupper($row['reason_title'])]; $translated = true; } $template->assign_block_vars('reasons', array( 'REASON_TITLE' => $row['reason_title'], 'REASON_DESCRIPTION' => $row['reason_description'], 'REASON_COUNT' => (isset($reason_count[$row['reason_id']])) ? $reason_count[$row['reason_id']] : 0, 'S_TRANSLATED' => $translated, 'S_OTHER_REASON' => $other_reason, 'U_EDIT' => $this->u_action . '&action=edit&id=' . $row['reason_id'], 'U_DELETE' => (!$other_reason) ? $this->u_action . '&action=delete&id=' . $row['reason_id'] : '', 'U_MOVE_UP' => $this->u_action . '&action=move_up&id=' . $row['reason_id'], 'U_MOVE_DOWN' => $this->u_action . '&action=move_down&id=' . $row['reason_id']) ); } $db->sql_freeresult($result); } } acp_update.php000077700000002772151514745240007411 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_update { var $u_action; function main($id, $mode) { global $config, $user, $template, $request; global $phpbb_root_path, $phpEx, $phpbb_container; $user->add_lang('install'); $this->tpl_name = 'acp_update'; $this->page_title = 'ACP_VERSION_CHECK'; $version_helper = $phpbb_container->get('version_helper'); try { $recheck = $request->variable('versioncheck_force', false); $updates_available = $version_helper->get_suggested_updates($recheck); } catch (\RuntimeException $e) { $template->assign_var('S_VERSIONCHECK_FAIL', true); $updates_available = array(); } foreach ($updates_available as $branch => $version_data) { $template->assign_block_vars('updates_available', $version_data); } $update_link = append_sid($phpbb_root_path . 'install/index.' . $phpEx, 'mode=update'); $template->assign_vars(array( 'S_UP_TO_DATE' => empty($updates_available), 'U_ACTION' => $this->u_action, 'U_VERSIONCHECK_FORCE' => append_sid($this->u_action . '&versioncheck_force=1'), 'CURRENT_VERSION' => $config['version'], 'UPDATE_INSTRUCTIONS' => sprintf($user->lang['UPDATE_INSTRUCTIONS'], $update_link), )); } } acp_inactive.php000077700000025165151514745240007732 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_inactive { var $u_action; var $p_master; function acp_inactive(&$p_master) { $this->p_master = &$p_master; } function main($id, $mode) { global $config, $db, $user, $auth, $template, $phpbb_container; global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix; include($phpbb_root_path . 'includes/functions_user.' . $phpEx); $user->add_lang('memberlist'); $action = request_var('action', ''); $mark = (isset($_REQUEST['mark'])) ? request_var('mark', array(0)) : array(); $start = request_var('start', 0); $submit = isset($_POST['submit']); // Sort keys $sort_days = request_var('st', 0); $sort_key = request_var('sk', 'i'); $sort_dir = request_var('sd', 'd'); $form_key = 'acp_inactive'; add_form_key($form_key); $pagination = $phpbb_container->get('pagination'); // We build the sort key and per page settings here, because they may be needed later // Number of entries to display $per_page = request_var('users_per_page', (int) $config['topics_per_page']); // Sorting $limit_days = array(0 => $user->lang['ALL_ENTRIES'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']); $sort_by_text = array('i' => $user->lang['SORT_INACTIVE'], 'j' => $user->lang['SORT_REG_DATE'], 'l' => $user->lang['SORT_LAST_VISIT'], 'd' => $user->lang['SORT_LAST_REMINDER'], 'r' => $user->lang['SORT_REASON'], 'u' => $user->lang['SORT_USERNAME'], 'p' => $user->lang['SORT_POSTS'], 'e' => $user->lang['SORT_REMINDER']); $sort_by_sql = array('i' => 'user_inactive_time', 'j' => 'user_regdate', 'l' => 'user_lastvisit', 'd' => 'user_reminded_time', 'r' => 'user_inactive_reason', 'u' => 'username_clean', 'p' => 'user_posts', 'e' => 'user_reminded'); $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 ($submit && sizeof($mark)) { if ($action !== 'delete' && !check_form_key($form_key)) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } switch ($action) { case 'activate': case 'delete': $sql = 'SELECT user_id, username FROM ' . USERS_TABLE . ' WHERE ' . $db->sql_in_set('user_id', $mark); $result = $db->sql_query($sql); $user_affected = array(); while ($row = $db->sql_fetchrow($result)) { $user_affected[$row['user_id']] = $row['username']; } $db->sql_freeresult($result); if ($action == 'activate') { // Get those 'being activated'... $sql = 'SELECT user_id, username' . (($config['require_activation'] == USER_ACTIVATION_ADMIN) ? ', user_email, user_lang' : '') . ' FROM ' . USERS_TABLE . ' WHERE ' . $db->sql_in_set('user_id', $mark) . ' AND user_type = ' . USER_INACTIVE; $result = $db->sql_query($sql); $inactive_users = array(); while ($row = $db->sql_fetchrow($result)) { $inactive_users[] = $row; } $db->sql_freeresult($result); user_active_flip('activate', $mark); if ($config['require_activation'] == USER_ACTIVATION_ADMIN && !empty($inactive_users)) { include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); $messenger = new messenger(false); foreach ($inactive_users as $row) { $messenger->template('admin_welcome_activated', $row['user_lang']); $messenger->set_addresses($row); $messenger->anti_abuse_headers($config, $user); $messenger->assign_vars(array( 'USERNAME' => htmlspecialchars_decode($row['username'])) ); $messenger->send(NOTIFY_EMAIL); } $messenger->save_queue(); } if (!empty($inactive_users)) { foreach ($inactive_users as $row) { add_log('admin', 'LOG_USER_ACTIVE', $row['username']); add_log('user', $row['user_id'], 'LOG_USER_ACTIVE_USER'); } trigger_error(sprintf($user->lang['LOG_INACTIVE_ACTIVATE'], implode($user->lang['COMMA_SEPARATOR'], $user_affected) . ' ' . adm_back_link($this->u_action))); } // For activate we really need to redirect, else a refresh can result in users being deactivated again $u_action = $this->u_action . "&$u_sort_param&start=$start"; $u_action .= ($per_page != $config['topics_per_page']) ? "&users_per_page=$per_page" : ''; redirect($u_action); } else if ($action == 'delete') { if (confirm_box(true)) { if (!$auth->acl_get('a_userdel')) { trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } user_delete('retain', $mark, true); add_log('admin', 'LOG_INACTIVE_' . strtoupper($action), implode(', ', $user_affected)); trigger_error(sprintf($user->lang['LOG_INACTIVE_DELETE'], implode($user->lang['COMMA_SEPARATOR'], $user_affected) . ' ' . adm_back_link($this->u_action))); } else { $s_hidden_fields = array( 'mode' => $mode, 'action' => $action, 'mark' => $mark, 'submit' => 1, 'start' => $start, ); confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields($s_hidden_fields)); } } break; case 'remind': if (empty($config['email_enable'])) { trigger_error($user->lang['EMAIL_DISABLED'] . adm_back_link($this->u_action), E_USER_WARNING); } $sql = 'SELECT user_id, username, user_email, user_lang, user_jabber, user_notify_type, user_regdate, user_actkey FROM ' . USERS_TABLE . ' WHERE ' . $db->sql_in_set('user_id', $mark) . ' AND user_inactive_reason'; $sql .= ($config['require_activation'] == USER_ACTIVATION_ADMIN) ? ' = ' . INACTIVE_REMIND : ' <> ' . INACTIVE_MANUAL; $result = $db->sql_query($sql); if ($row = $db->sql_fetchrow($result)) { // Send the messages include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); $messenger = new messenger(); $usernames = $user_ids = array(); do { $messenger->template('user_remind_inactive', $row['user_lang']); $messenger->set_addresses($row); $messenger->anti_abuse_headers($config, $user); $messenger->assign_vars(array( 'USERNAME' => htmlspecialchars_decode($row['username']), 'REGISTER_DATE' => $user->format_date($row['user_regdate'], false, true), 'U_ACTIVATE' => generate_board_url() . "/ucp.$phpEx?mode=activate&u=" . $row['user_id'] . '&k=' . $row['user_actkey']) ); $messenger->send($row['user_notify_type']); $usernames[] = $row['username']; $user_ids[] = (int) $row['user_id']; } while ($row = $db->sql_fetchrow($result)); $messenger->save_queue(); // Add the remind state to the database $sql = 'UPDATE ' . USERS_TABLE . ' SET user_reminded = user_reminded + 1, user_reminded_time = ' . time() . ' WHERE ' . $db->sql_in_set('user_id', $user_ids); $db->sql_query($sql); add_log('admin', 'LOG_INACTIVE_REMIND', implode(', ', $usernames)); trigger_error(sprintf($user->lang['LOG_INACTIVE_REMIND'], implode($user->lang['COMMA_SEPARATOR'], $usernames) . ' ' . adm_back_link($this->u_action))); } $db->sql_freeresult($result); // For remind we really need to redirect, else a refresh can result in more than one reminder $u_action = $this->u_action . "&$u_sort_param&start=$start"; $u_action .= ($per_page != $config['topics_per_page']) ? "&users_per_page=$per_page" : ''; redirect($u_action); break; } } // Define where and sort sql for use in displaying logs $sql_where = ($sort_days) ? (time() - ($sort_days * 86400)) : 0; $sql_sort = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC'); $inactive = array(); $inactive_count = 0; $start = view_inactive_users($inactive, $inactive_count, $per_page, $start, $sql_where, $sql_sort); foreach ($inactive as $row) { $template->assign_block_vars('inactive', array( 'INACTIVE_DATE' => $user->format_date($row['user_inactive_time']), 'REMINDED_DATE' => $user->format_date($row['user_reminded_time']), 'JOINED' => $user->format_date($row['user_regdate']), 'LAST_VISIT' => (!$row['user_lastvisit']) ? ' - ' : $user->format_date($row['user_lastvisit']), 'REASON' => $row['inactive_reason'], 'USER_ID' => $row['user_id'], 'POSTS' => ($row['user_posts']) ? $row['user_posts'] : 0, 'REMINDED' => $row['user_reminded'], 'REMINDED_EXPLAIN' => $user->lang('USER_LAST_REMINDED', (int) $row['user_reminded'], $user->format_date($row['user_reminded_time'])), 'USERNAME_FULL' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour'], false, append_sid("{$phpbb_admin_path}index.$phpEx", 'i=users&mode=overview')), 'USERNAME' => get_username_string('username', $row['user_id'], $row['username'], $row['user_colour']), 'USER_COLOR' => get_username_string('colour', $row['user_id'], $row['username'], $row['user_colour']), 'U_USER_ADMIN' => append_sid("{$phpbb_admin_path}index.$phpEx", "i=users&mode=overview&u={$row['user_id']}"), 'U_SEARCH_USER' => ($auth->acl_get('u_search')) ? append_sid("{$phpbb_root_path}search.$phpEx", "author_id={$row['user_id']}&sr=posts") : '', )); } $option_ary = array('activate' => 'ACTIVATE', 'delete' => 'DELETE'); if ($config['email_enable']) { $option_ary += array('remind' => 'REMIND'); } $base_url = $this->u_action . "&$u_sort_param&users_per_page=$per_page"; $pagination->generate_template_pagination($base_url, 'pagination', 'start', $inactive_count, $per_page, $start); $template->assign_vars(array( 'S_INACTIVE_USERS' => true, 'S_INACTIVE_OPTIONS' => build_select($option_ary), 'S_LIMIT_DAYS' => $s_limit_days, 'S_SORT_KEY' => $s_sort_key, 'S_SORT_DIR' => $s_sort_dir, 'USERS_PER_PAGE' => $per_page, 'U_ACTION' => $this->u_action . "&$u_sort_param&users_per_page=$per_page&start=$start", )); $this->tpl_name = 'acp_inactive'; $this->page_title = 'ACP_INACTIVE_USERS'; } } acp_users.php000077700000261231151514745240007265 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_users { var $u_action; var $p_master; function acp_users(&$p_master) { $this->p_master = &$p_master; } function main($id, $mode) { global $config, $db, $user, $auth, $template, $cache; global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix, $file_uploads; global $phpbb_dispatcher, $request; global $phpbb_container; $user->add_lang(array('posting', 'ucp', 'acp/users')); $this->tpl_name = 'acp_users'; $error = array(); $username = utf8_normalize_nfc(request_var('username', '', true)); $user_id = request_var('u', 0); $action = request_var('action', ''); $submit = (isset($_POST['update']) && !isset($_POST['cancel'])) ? true : false; $form_name = 'acp_users'; add_form_key($form_name); // Whois (special case) if ($action == 'whois') { include($phpbb_root_path . 'includes/functions_user.' . $phpEx); $this->page_title = 'WHOIS'; $this->tpl_name = 'simple_body'; $user_ip = phpbb_ip_normalise(request_var('user_ip', '')); $domain = gethostbyaddr($user_ip); $ipwhois = user_ipwhois($user_ip); $template->assign_vars(array( 'MESSAGE_TITLE' => sprintf($user->lang['IP_WHOIS_FOR'], $domain), 'MESSAGE_TEXT' => nl2br($ipwhois)) ); return; } // Show user selection mask if (!$username && !$user_id) { $this->page_title = 'SELECT_USER'; $template->assign_vars(array( 'U_ACTION' => $this->u_action, 'ANONYMOUS_USER_ID' => ANONYMOUS, 'S_SELECT_USER' => true, 'U_FIND_USERNAME' => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&form=select_user&field=username&select_single=true'), )); return; } if (!$user_id) { $sql = 'SELECT user_id FROM ' . USERS_TABLE . " WHERE username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'"; $result = $db->sql_query($sql); $user_id = (int) $db->sql_fetchfield('user_id'); $db->sql_freeresult($result); if (!$user_id) { trigger_error($user->lang['NO_USER'] . adm_back_link($this->u_action), E_USER_WARNING); } } // Generate content for all modes $sql = 'SELECT u.*, s.* FROM ' . USERS_TABLE . ' u LEFT JOIN ' . SESSIONS_TABLE . ' s ON (s.session_user_id = u.user_id) WHERE u.user_id = ' . $user_id . ' ORDER BY s.session_time DESC'; $result = $db->sql_query_limit($sql, 1); $user_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$user_row) { trigger_error($user->lang['NO_USER'] . adm_back_link($this->u_action), E_USER_WARNING); } // Generate overall "header" for user admin $s_form_options = ''; // Build modes dropdown list $sql = 'SELECT module_mode, module_auth FROM ' . MODULES_TABLE . " WHERE module_basename = 'acp_users' AND module_enabled = 1 AND module_class = 'acp' ORDER BY left_id, module_mode"; $result = $db->sql_query($sql); $dropdown_modes = array(); while ($row = $db->sql_fetchrow($result)) { if (!$this->p_master->module_auth_self($row['module_auth'])) { continue; } $dropdown_modes[$row['module_mode']] = true; } $db->sql_freeresult($result); foreach ($dropdown_modes as $module_mode => $null) { $selected = ($mode == $module_mode) ? ' selected="selected"' : ''; $s_form_options .= '<option value="' . $module_mode . '"' . $selected . '>' . $user->lang['ACP_USER_' . strtoupper($module_mode)] . '</option>'; } $template->assign_vars(array( 'U_BACK' => $this->u_action, 'U_MODE_SELECT' => append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&u=$user_id"), 'U_ACTION' => $this->u_action . '&u=' . $user_id, 'S_FORM_OPTIONS' => $s_form_options, 'MANAGED_USERNAME' => $user_row['username']) ); // Prevent normal users/admins change/view founders if they are not a founder by themselves if ($user->data['user_type'] != USER_FOUNDER && $user_row['user_type'] == USER_FOUNDER) { trigger_error($user->lang['NOT_MANAGE_FOUNDER'] . adm_back_link($this->u_action), E_USER_WARNING); } $this->page_title = $user_row['username'] . ' :: ' . $user->lang('ACP_USER_' . strtoupper($mode)); switch ($mode) { case 'overview': include($phpbb_root_path . 'includes/functions_user.' . $phpEx); $user->add_lang('acp/ban'); $delete = request_var('delete', 0); $delete_type = request_var('delete_type', ''); $ip = request_var('ip', 'ip'); /** * Run code at beginning of ACP users overview * * @event core.acp_users_overview_before * @var array user_row Current user data * @var string mode Active module * @var string action Module that should be run * @var bool submit Do we display the form only * or did the user press submit * @var array error Array holding error messages * @since 3.1.3-RC1 */ $vars = array('user_row', 'mode', 'action', 'submit', 'error'); extract($phpbb_dispatcher->trigger_event('core.acp_users_overview_before', compact($vars))); if ($submit) { if ($delete) { if (!$auth->acl_get('a_userdel')) { trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } // Check if the user wants to remove himself or the guest user account if ($user_id == ANONYMOUS) { trigger_error($user->lang['CANNOT_REMOVE_ANONYMOUS'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } // Founders can not be deleted. if ($user_row['user_type'] == USER_FOUNDER) { trigger_error($user->lang['CANNOT_REMOVE_FOUNDER'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } if ($user_id == $user->data['user_id']) { trigger_error($user->lang['CANNOT_REMOVE_YOURSELF'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } if ($delete_type) { if (confirm_box(true)) { user_delete($delete_type, $user_id, $user_row['username']); add_log('admin', 'LOG_USER_DELETED', $user_row['username']); trigger_error($user->lang['USER_DELETED'] . adm_back_link($this->u_action)); } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 'u' => $user_id, 'i' => $id, 'mode' => $mode, 'action' => $action, 'update' => true, 'delete' => 1, 'delete_type' => $delete_type)) ); } } else { trigger_error($user->lang['NO_MODE'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } } // Handle quicktool actions switch ($action) { case 'banuser': case 'banemail': case 'banip': if ($user_id == $user->data['user_id']) { trigger_error($user->lang['CANNOT_BAN_YOURSELF'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } if ($user_id == ANONYMOUS) { trigger_error($user->lang['CANNOT_BAN_ANONYMOUS'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } if ($user_row['user_type'] == USER_FOUNDER) { trigger_error($user->lang['CANNOT_BAN_FOUNDER'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } if (!check_form_key($form_name)) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } $ban = array(); switch ($action) { case 'banuser': $ban[] = $user_row['username']; $reason = 'USER_ADMIN_BAN_NAME_REASON'; $log = 'LOG_USER_BAN_USER'; break; case 'banemail': $ban[] = $user_row['user_email']; $reason = 'USER_ADMIN_BAN_EMAIL_REASON'; $log = 'LOG_USER_BAN_EMAIL'; break; case 'banip': $ban[] = $user_row['user_ip']; $sql = 'SELECT DISTINCT poster_ip FROM ' . POSTS_TABLE . " WHERE poster_id = $user_id"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $ban[] = $row['poster_ip']; } $db->sql_freeresult($result); $reason = 'USER_ADMIN_BAN_IP_REASON'; $log = 'LOG_USER_BAN_IP'; break; } $ban_reason = utf8_normalize_nfc(request_var('ban_reason', $user->lang[$reason], true)); $ban_give_reason = utf8_normalize_nfc(request_var('ban_give_reason', '', true)); // Log not used at the moment, we simply utilize the ban function. $result = user_ban(substr($action, 3), $ban, 0, 0, 0, $ban_reason, $ban_give_reason); trigger_error((($result === false) ? $user->lang['BAN_ALREADY_ENTERED'] : $user->lang['BAN_SUCCESSFUL']) . adm_back_link($this->u_action . '&u=' . $user_id)); break; case 'reactivate': if ($user_id == $user->data['user_id']) { trigger_error($user->lang['CANNOT_FORCE_REACT_YOURSELF'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } if (!check_form_key($form_name)) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } if ($user_row['user_type'] == USER_FOUNDER) { trigger_error($user->lang['CANNOT_FORCE_REACT_FOUNDER'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } if ($user_row['user_type'] == USER_IGNORE) { trigger_error($user->lang['CANNOT_FORCE_REACT_BOT'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } if ($config['email_enable']) { include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); $server_url = generate_board_url(); $user_actkey = gen_rand_string(mt_rand(6, 10)); $email_template = ($user_row['user_type'] == USER_NORMAL) ? 'user_reactivate_account' : 'user_resend_inactive'; if ($user_row['user_type'] == USER_NORMAL) { user_active_flip('deactivate', $user_id, INACTIVE_REMIND); $sql = 'UPDATE ' . USERS_TABLE . " SET user_actkey = '" . $db->sql_escape($user_actkey) . "' WHERE user_id = $user_id"; $db->sql_query($sql); } else { // Grabbing the last confirm key - we only send a reminder $sql = 'SELECT user_actkey FROM ' . USERS_TABLE . ' WHERE user_id = ' . $user_id; $result = $db->sql_query($sql); $user_actkey = (string) $db->sql_fetchfield('user_actkey'); $db->sql_freeresult($result); } $messenger = new messenger(false); $messenger->template($email_template, $user_row['user_lang']); $messenger->set_addresses($user_row); $messenger->anti_abuse_headers($config, $user); $messenger->assign_vars(array( 'WELCOME_MSG' => htmlspecialchars_decode(sprintf($user->lang['WELCOME_SUBJECT'], $config['sitename'])), 'USERNAME' => htmlspecialchars_decode($user_row['username']), 'U_ACTIVATE' => "$server_url/ucp.$phpEx?mode=activate&u={$user_row['user_id']}&k=$user_actkey") ); $messenger->send(NOTIFY_EMAIL); add_log('admin', 'LOG_USER_REACTIVATE', $user_row['username']); add_log('user', $user_id, 'LOG_USER_REACTIVATE_USER'); trigger_error($user->lang['FORCE_REACTIVATION_SUCCESS'] . adm_back_link($this->u_action . '&u=' . $user_id)); } break; case 'active': if ($user_id == $user->data['user_id']) { // It is only deactivation since the user is already activated (else he would not have reached this page) trigger_error($user->lang['CANNOT_DEACTIVATE_YOURSELF'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } if (!check_form_key($form_name)) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } if ($user_row['user_type'] == USER_FOUNDER) { trigger_error($user->lang['CANNOT_DEACTIVATE_FOUNDER'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } if ($user_row['user_type'] == USER_IGNORE) { trigger_error($user->lang['CANNOT_DEACTIVATE_BOT'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } user_active_flip('flip', $user_id); if ($user_row['user_type'] == USER_INACTIVE) { if ($config['require_activation'] == USER_ACTIVATION_ADMIN) { $phpbb_notifications = $phpbb_container->get('notification_manager'); $phpbb_notifications->delete_notifications('notification.type.admin_activate_user', $user_row['user_id']); include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); $messenger = new messenger(false); $messenger->template('admin_welcome_activated', $user_row['user_lang']); $messenger->set_addresses($user_row); $messenger->anti_abuse_headers($config, $user); $messenger->assign_vars(array( 'USERNAME' => htmlspecialchars_decode($user_row['username'])) ); $messenger->send(NOTIFY_EMAIL); } } $message = ($user_row['user_type'] == USER_INACTIVE) ? 'USER_ADMIN_ACTIVATED' : 'USER_ADMIN_DEACTIVED'; $log = ($user_row['user_type'] == USER_INACTIVE) ? 'LOG_USER_ACTIVE' : 'LOG_USER_INACTIVE'; add_log('admin', $log, $user_row['username']); add_log('user', $user_id, $log . '_USER'); trigger_error($user->lang[$message] . adm_back_link($this->u_action . '&u=' . $user_id)); break; case 'delsig': if (!check_form_key($form_name)) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } $sql_ary = array( 'user_sig' => '', 'user_sig_bbcode_uid' => '', 'user_sig_bbcode_bitfield' => '' ); $sql = 'UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " WHERE user_id = $user_id"; $db->sql_query($sql); add_log('admin', 'LOG_USER_DEL_SIG', $user_row['username']); add_log('user', $user_id, 'LOG_USER_DEL_SIG_USER'); trigger_error($user->lang['USER_ADMIN_SIG_REMOVED'] . adm_back_link($this->u_action . '&u=' . $user_id)); break; case 'delavatar': if (!check_form_key($form_name)) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } // Delete old avatar if present $phpbb_avatar_manager = $phpbb_container->get('avatar.manager'); $phpbb_avatar_manager->handle_avatar_delete($db, $user, $phpbb_avatar_manager->clean_row($user_row, 'user'), USERS_TABLE, 'user_'); add_log('admin', 'LOG_USER_DEL_AVATAR', $user_row['username']); add_log('user', $user_id, 'LOG_USER_DEL_AVATAR_USER'); trigger_error($user->lang['USER_ADMIN_AVATAR_REMOVED'] . adm_back_link($this->u_action . '&u=' . $user_id)); break; case 'delposts': if (confirm_box(true)) { // Delete posts, attachments, etc. delete_posts('poster_id', $user_id); add_log('admin', 'LOG_USER_DEL_POSTS', $user_row['username']); trigger_error($user->lang['USER_POSTS_DELETED'] . adm_back_link($this->u_action . '&u=' . $user_id)); } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 'u' => $user_id, 'i' => $id, 'mode' => $mode, 'action' => $action, 'update' => true)) ); } break; case 'delattach': if (confirm_box(true)) { delete_attachments('user', $user_id); add_log('admin', 'LOG_USER_DEL_ATTACH', $user_row['username']); trigger_error($user->lang['USER_ATTACHMENTS_REMOVED'] . adm_back_link($this->u_action . '&u=' . $user_id)); } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 'u' => $user_id, 'i' => $id, 'mode' => $mode, 'action' => $action, 'update' => true)) ); } break; case 'deloutbox': if (confirm_box(true)) { $msg_ids = array(); $lang = 'EMPTY'; $sql = 'SELECT msg_id FROM ' . PRIVMSGS_TO_TABLE . " WHERE author_id = $user_id AND folder_id = " . PRIVMSGS_OUTBOX; $result = $db->sql_query($sql); if ($row = $db->sql_fetchrow($result)) { if (!function_exists('delete_pm')) { include($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx); } do { $msg_ids[] = (int) $row['msg_id']; } while ($row = $db->sql_fetchrow($result)); $db->sql_freeresult($result); delete_pm($user_id, $msg_ids, PRIVMSGS_OUTBOX); add_log('admin', 'LOG_USER_DEL_OUTBOX', $user_row['username']); $lang = 'EMPTIED'; } $db->sql_freeresult($result); trigger_error($user->lang['USER_OUTBOX_' . $lang] . adm_back_link($this->u_action . '&u=' . $user_id)); } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 'u' => $user_id, 'i' => $id, 'mode' => $mode, 'action' => $action, 'update' => true)) ); } break; case 'moveposts': if (!check_form_key($form_name)) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } $user->add_lang('acp/forums'); $new_forum_id = request_var('new_f', 0); if (!$new_forum_id) { $this->page_title = 'USER_ADMIN_MOVE_POSTS'; $template->assign_vars(array( 'S_SELECT_FORUM' => true, 'U_ACTION' => $this->u_action . "&action=$action&u=$user_id", 'U_BACK' => $this->u_action . "&u=$user_id", 'S_FORUM_OPTIONS' => make_forum_select(false, false, false, true)) ); return; } // Is the new forum postable to? $sql = 'SELECT forum_name, forum_type FROM ' . FORUMS_TABLE . " WHERE forum_id = $new_forum_id"; $result = $db->sql_query($sql); $forum_info = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$forum_info) { trigger_error($user->lang['NO_FORUM'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } if ($forum_info['forum_type'] != FORUM_POST) { trigger_error($user->lang['MOVE_POSTS_NO_POSTABLE_FORUM'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } // Two stage? // Move topics comprising only posts from this user $topic_id_ary = $move_topic_ary = $move_post_ary = $new_topic_id_ary = array(); $forum_id_ary = array($new_forum_id); $sql = 'SELECT topic_id, post_visibility, COUNT(post_id) AS total_posts FROM ' . POSTS_TABLE . " WHERE poster_id = $user_id AND forum_id <> $new_forum_id GROUP BY topic_id, post_visibility"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $topic_id_ary[$row['topic_id']][$row['post_visibility']] = $row['total_posts']; } $db->sql_freeresult($result); if (sizeof($topic_id_ary)) { $sql = 'SELECT topic_id, forum_id, topic_title, topic_posts_approved, topic_posts_unapproved, topic_posts_softdeleted, topic_attachment FROM ' . TOPICS_TABLE . ' WHERE ' . $db->sql_in_set('topic_id', array_keys($topic_id_ary)); $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { if ($topic_id_ary[$row['topic_id']][ITEM_APPROVED] == $row['topic_posts_approved'] && $topic_id_ary[$row['topic_id']][ITEM_UNAPPROVED] == $row['topic_posts_unapproved'] && $topic_id_ary[$row['topic_id']][ITEM_REAPPROVE] == $row['topic_posts_unapproved'] && $topic_id_ary[$row['topic_id']][ITEM_DELETED] == $row['topic_posts_softdeleted']) { $move_topic_ary[] = $row['topic_id']; } else { $move_post_ary[$row['topic_id']]['title'] = $row['topic_title']; $move_post_ary[$row['topic_id']]['attach'] = ($row['topic_attachment']) ? 1 : 0; } $forum_id_ary[] = $row['forum_id']; } $db->sql_freeresult($result); } // Entire topic comprises posts by this user, move these topics if (sizeof($move_topic_ary)) { move_topics($move_topic_ary, $new_forum_id, false); } if (sizeof($move_post_ary)) { // Create new topic // Update post_ids, report_ids, attachment_ids foreach ($move_post_ary as $topic_id => $post_ary) { // Create new topic $sql = 'INSERT INTO ' . TOPICS_TABLE . ' ' . $db->sql_build_array('INSERT', array( 'topic_poster' => $user_id, 'topic_time' => time(), 'forum_id' => $new_forum_id, 'icon_id' => 0, 'topic_visibility' => ITEM_APPROVED, 'topic_title' => $post_ary['title'], 'topic_first_poster_name' => $user_row['username'], 'topic_type' => POST_NORMAL, 'topic_time_limit' => 0, 'topic_attachment' => $post_ary['attach']) ); $db->sql_query($sql); $new_topic_id = $db->sql_nextid(); // Move posts $sql = 'UPDATE ' . POSTS_TABLE . " SET forum_id = $new_forum_id, topic_id = $new_topic_id WHERE topic_id = $topic_id AND poster_id = $user_id"; $db->sql_query($sql); if ($post_ary['attach']) { $sql = 'UPDATE ' . ATTACHMENTS_TABLE . " SET topic_id = $new_topic_id WHERE topic_id = $topic_id AND poster_id = $user_id"; $db->sql_query($sql); } $new_topic_id_ary[] = $new_topic_id; } } $forum_id_ary = array_unique($forum_id_ary); $topic_id_ary = array_unique(array_merge(array_keys($topic_id_ary), $new_topic_id_ary)); if (sizeof($topic_id_ary)) { sync('topic_reported', 'topic_id', $topic_id_ary); sync('topic', 'topic_id', $topic_id_ary); } if (sizeof($forum_id_ary)) { sync('forum', 'forum_id', $forum_id_ary, false, true); } add_log('admin', 'LOG_USER_MOVE_POSTS', $user_row['username'], $forum_info['forum_name']); add_log('user', $user_id, 'LOG_USER_MOVE_POSTS_USER', $forum_info['forum_name']); trigger_error($user->lang['USER_POSTS_MOVED'] . adm_back_link($this->u_action . '&u=' . $user_id)); break; case 'leave_nr': if (confirm_box(true)) { remove_newly_registered($user_id, $user_row); add_log('admin', 'LOG_USER_REMOVED_NR', $user_row['username']); trigger_error($user->lang['USER_LIFTED_NR'] . adm_back_link($this->u_action . '&u=' . $user_id)); } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 'u' => $user_id, 'i' => $id, 'mode' => $mode, 'action' => $action, 'update' => true)) ); } break; default: /** * Run custom quicktool code * * @event core.acp_users_overview_run_quicktool * @var array user_row Current user data * @var string action Quick tool that should be run * @since 3.1.0-a1 */ $vars = array('action', 'user_row'); extract($phpbb_dispatcher->trigger_event('core.acp_users_overview_run_quicktool', compact($vars))); break; } // Handle registration info updates $data = array( 'username' => utf8_normalize_nfc(request_var('user', $user_row['username'], true)), 'user_founder' => request_var('user_founder', ($user_row['user_type'] == USER_FOUNDER) ? 1 : 0), 'email' => strtolower(request_var('user_email', $user_row['user_email'])), 'new_password' => $request->variable('new_password', '', true), 'password_confirm' => $request->variable('password_confirm', '', true), ); // Validation data - we do not check the password complexity setting here $check_ary = array( 'new_password' => array( array('string', true, $config['min_pass_chars'], $config['max_pass_chars']), array('password')), 'password_confirm' => array('string', true, $config['min_pass_chars'], $config['max_pass_chars']), ); // Check username if altered if ($data['username'] != $user_row['username']) { $check_ary += array( 'username' => array( array('string', false, $config['min_name_chars'], $config['max_name_chars']), array('username', $user_row['username']) ), ); } // Check email if altered if ($data['email'] != $user_row['user_email']) { $check_ary += array( 'email' => array( array('string', false, 6, 60), array('user_email', $user_row['user_email']), ), ); } $error = validate_data($data, $check_ary); if ($data['new_password'] && $data['password_confirm'] != $data['new_password']) { $error[] = 'NEW_PASSWORD_ERROR'; } if (!check_form_key($form_name)) { $error[] = 'FORM_INVALID'; } // Instantiate passwords manager $passwords_manager = $phpbb_container->get('passwords.manager'); // Which updates do we need to do? $update_username = ($user_row['username'] != $data['username']) ? $data['username'] : false; $update_password = $data['new_password'] && !$passwords_manager->check($data['new_password'], $user_row['user_password']); $update_email = ($data['email'] != $user_row['user_email']) ? $data['email'] : false; if (!sizeof($error)) { $sql_ary = array(); if ($user_row['user_type'] != USER_FOUNDER || $user->data['user_type'] == USER_FOUNDER) { // Only allow founders updating the founder status... if ($user->data['user_type'] == USER_FOUNDER) { // Setting a normal member to be a founder if ($data['user_founder'] && $user_row['user_type'] != USER_FOUNDER) { // Make sure the user is not setting an Inactive or ignored user to be a founder if ($user_row['user_type'] == USER_IGNORE) { trigger_error($user->lang['CANNOT_SET_FOUNDER_IGNORED'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } if ($user_row['user_type'] == USER_INACTIVE) { trigger_error($user->lang['CANNOT_SET_FOUNDER_INACTIVE'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } $sql_ary['user_type'] = USER_FOUNDER; } else if (!$data['user_founder'] && $user_row['user_type'] == USER_FOUNDER) { // Check if at least one founder is present $sql = 'SELECT user_id FROM ' . USERS_TABLE . ' WHERE user_type = ' . USER_FOUNDER . ' AND user_id <> ' . $user_id; $result = $db->sql_query_limit($sql, 1); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($row) { $sql_ary['user_type'] = USER_NORMAL; } else { trigger_error($user->lang['AT_LEAST_ONE_FOUNDER'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } } } } /** * Modify user data before we update it * * @event core.acp_users_overview_modify_data * @var array user_row Current user data * @var array data Submitted user data * @var array sql_ary User data we udpate * @since 3.1.0-a1 */ $vars = array('user_row', 'data', 'sql_ary'); extract($phpbb_dispatcher->trigger_event('core.acp_users_overview_modify_data', compact($vars))); if ($update_username !== false) { $sql_ary['username'] = $update_username; $sql_ary['username_clean'] = utf8_clean_string($update_username); add_log('user', $user_id, 'LOG_USER_UPDATE_NAME', $user_row['username'], $update_username); } if ($update_email !== false) { $sql_ary += array( 'user_email' => $update_email, 'user_email_hash' => phpbb_email_hash($update_email), ); add_log('user', $user_id, 'LOG_USER_UPDATE_EMAIL', $user_row['username'], $user_row['user_email'], $update_email); } if ($update_password) { $sql_ary += array( 'user_password' => $passwords_manager->hash($data['new_password']), 'user_passchg' => time(), ); $user->reset_login_keys($user_id); add_log('user', $user_id, 'LOG_USER_NEW_PASSWORD', $user_row['username']); } if (sizeof($sql_ary)) { $sql = 'UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE user_id = ' . $user_id; $db->sql_query($sql); } if ($update_username) { user_update_name($user_row['username'], $update_username); } // Let the users permissions being updated $auth->acl_clear_prefetch($user_id); add_log('admin', 'LOG_USER_USER_UPDATE', $data['username']); trigger_error($user->lang['USER_OVERVIEW_UPDATED'] . adm_back_link($this->u_action . '&u=' . $user_id)); } // Replace "error" strings with their real, localised form $error = array_map(array($user, 'lang'), $error); } if ($user_id == $user->data['user_id']) { $quick_tool_ary = array('delsig' => 'DEL_SIG', 'delavatar' => 'DEL_AVATAR', 'moveposts' => 'MOVE_POSTS', 'delposts' => 'DEL_POSTS', 'delattach' => 'DEL_ATTACH', 'deloutbox' => 'DEL_OUTBOX'); if ($user_row['user_new']) { $quick_tool_ary['leave_nr'] = 'LEAVE_NR'; } } else { $quick_tool_ary = array(); if ($user_row['user_type'] != USER_FOUNDER) { $quick_tool_ary += array('banuser' => 'BAN_USER', 'banemail' => 'BAN_EMAIL', 'banip' => 'BAN_IP'); } if ($user_row['user_type'] != USER_FOUNDER && $user_row['user_type'] != USER_IGNORE) { $quick_tool_ary += array('active' => (($user_row['user_type'] == USER_INACTIVE) ? 'ACTIVATE' : 'DEACTIVATE')); } $quick_tool_ary += array('delsig' => 'DEL_SIG', 'delavatar' => 'DEL_AVATAR', 'moveposts' => 'MOVE_POSTS', 'delposts' => 'DEL_POSTS', 'delattach' => 'DEL_ATTACH', 'deloutbox' => 'DEL_OUTBOX'); if ($config['email_enable'] && ($user_row['user_type'] == USER_NORMAL || $user_row['user_type'] == USER_INACTIVE)) { $quick_tool_ary['reactivate'] = 'FORCE'; } if ($user_row['user_new']) { $quick_tool_ary['leave_nr'] = 'LEAVE_NR'; } } if ($config['load_onlinetrack']) { $sql = 'SELECT MAX(session_time) AS session_time, MIN(session_viewonline) AS session_viewonline FROM ' . SESSIONS_TABLE . " WHERE session_user_id = $user_id"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); $user_row['session_time'] = (isset($row['session_time'])) ? $row['session_time'] : 0; $user_row['session_viewonline'] = (isset($row['session_viewonline'])) ? $row['session_viewonline'] : 0; unset($row); } /** * Add additional quick tool options and overwrite user data * * @event core.acp_users_display_overview * @var array user_row Array with user data * @var array quick_tool_ary Ouick tool options * @since 3.1.0-a1 */ $vars = array('user_row', 'quick_tool_ary'); extract($phpbb_dispatcher->trigger_event('core.acp_users_display_overview', compact($vars))); $s_action_options = '<option class="sep" value="">' . $user->lang['SELECT_OPTION'] . '</option>'; foreach ($quick_tool_ary as $value => $lang) { $s_action_options .= '<option value="' . $value . '">' . $user->lang['USER_ADMIN_' . $lang] . '</option>'; } $last_active = (!empty($user_row['session_time'])) ? $user_row['session_time'] : $user_row['user_lastvisit']; $inactive_reason = ''; if ($user_row['user_type'] == USER_INACTIVE) { $inactive_reason = $user->lang['INACTIVE_REASON_UNKNOWN']; switch ($user_row['user_inactive_reason']) { case INACTIVE_REGISTER: $inactive_reason = $user->lang['INACTIVE_REASON_REGISTER']; break; case INACTIVE_PROFILE: $inactive_reason = $user->lang['INACTIVE_REASON_PROFILE']; break; case INACTIVE_MANUAL: $inactive_reason = $user->lang['INACTIVE_REASON_MANUAL']; break; case INACTIVE_REMIND: $inactive_reason = $user->lang['INACTIVE_REASON_REMIND']; break; } } // Posts in Queue $sql = 'SELECT COUNT(post_id) as posts_in_queue FROM ' . POSTS_TABLE . ' WHERE poster_id = ' . $user_id . ' AND ' . $db->sql_in_set('post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE)); $result = $db->sql_query($sql); $user_row['posts_in_queue'] = (int) $db->sql_fetchfield('posts_in_queue'); $db->sql_freeresult($result); $sql = 'SELECT post_id FROM ' . POSTS_TABLE . ' WHERE poster_id = '. $user_id; $result = $db->sql_query_limit($sql, 1); $user_row['user_has_posts'] = (bool) $db->sql_fetchfield('post_id'); $db->sql_freeresult($result); $template->assign_vars(array( 'L_NAME_CHARS_EXPLAIN' => $user->lang($config['allow_name_chars'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_name_chars']), $user->lang('CHARACTERS', (int) $config['max_name_chars'])), 'L_CHANGE_PASSWORD_EXPLAIN' => $user->lang($config['pass_complex'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_pass_chars']), $user->lang('CHARACTERS', (int) $config['max_pass_chars'])), 'L_POSTS_IN_QUEUE' => $user->lang('NUM_POSTS_IN_QUEUE', $user_row['posts_in_queue']), 'S_FOUNDER' => ($user->data['user_type'] == USER_FOUNDER) ? true : false, 'S_OVERVIEW' => true, 'S_USER_IP' => ($user_row['user_ip']) ? true : false, 'S_USER_FOUNDER' => ($user_row['user_type'] == USER_FOUNDER) ? true : false, 'S_ACTION_OPTIONS' => $s_action_options, 'S_OWN_ACCOUNT' => ($user_id == $user->data['user_id']) ? true : false, 'S_USER_INACTIVE' => ($user_row['user_type'] == USER_INACTIVE) ? true : false, 'U_SHOW_IP' => $this->u_action . "&u=$user_id&ip=" . (($ip == 'ip') ? 'hostname' : 'ip'), 'U_WHOIS' => $this->u_action . "&action=whois&user_ip={$user_row['user_ip']}", 'U_MCP_QUEUE' => ($auth->acl_getf_global('m_approve')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue', true, $user->session_id) : '', 'U_SEARCH_USER' => ($config['load_search'] && $auth->acl_get('u_search')) ? append_sid("{$phpbb_root_path}search.$phpEx", "author_id={$user_row['user_id']}&sr=posts") : '', 'U_SWITCH_PERMISSIONS' => ($auth->acl_get('a_switchperm') && $user->data['user_id'] != $user_row['user_id']) ? append_sid("{$phpbb_root_path}ucp.$phpEx", "mode=switch_perm&u={$user_row['user_id']}&hash=" . generate_link_hash('switchperm')) : '', 'POSTS_IN_QUEUE' => $user_row['posts_in_queue'], 'USER' => $user_row['username'], 'USER_REGISTERED' => $user->format_date($user_row['user_regdate']), 'REGISTERED_IP' => ($ip == 'hostname') ? gethostbyaddr($user_row['user_ip']) : $user_row['user_ip'], 'USER_LASTACTIVE' => ($last_active) ? $user->format_date($last_active) : ' - ', 'USER_EMAIL' => $user_row['user_email'], 'USER_WARNINGS' => $user_row['user_warnings'], 'USER_POSTS' => $user_row['user_posts'], 'USER_HAS_POSTS' => $user_row['user_has_posts'], 'USER_INACTIVE_REASON' => $inactive_reason, )); break; case 'feedback': $user->add_lang('mcp'); // Set up general vars $start = request_var('start', 0); $deletemark = (isset($_POST['delmarked'])) ? true : false; $deleteall = (isset($_POST['delall'])) ? true : false; $marked = request_var('mark', array(0)); $message = utf8_normalize_nfc(request_var('message', '', true)); $pagination = $phpbb_container->get('pagination'); // Sort keys $sort_days = request_var('st', 0); $sort_key = request_var('sk', 't'); $sort_dir = request_var('sd', 'd'); // Delete entries if requested and able if (($deletemark || $deleteall) && $auth->acl_get('a_clearlogs')) { if (!check_form_key($form_name)) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } $where_sql = ''; if ($deletemark && $marked) { $sql_in = array(); foreach ($marked as $mark) { $sql_in[] = $mark; } $where_sql = ' AND ' . $db->sql_in_set('log_id', $sql_in); unset($sql_in); } if ($where_sql || $deleteall) { $sql = 'DELETE FROM ' . LOG_TABLE . ' WHERE log_type = ' . LOG_USERS . " AND reportee_id = $user_id $where_sql"; $db->sql_query($sql); add_log('admin', 'LOG_CLEAR_USER', $user_row['username']); } } if ($submit && $message) { if (!check_form_key($form_name)) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } add_log('admin', 'LOG_USER_FEEDBACK', $user_row['username']); add_log('mod', 0, 0, 'LOG_USER_FEEDBACK', $user_row['username']); add_log('user', $user_id, 'LOG_USER_GENERAL', $message); trigger_error($user->lang['USER_FEEDBACK_ADDED'] . adm_back_link($this->u_action . '&u=' . $user_id)); } // Sorting $limit_days = array(0 => $user->lang['ALL_ENTRIES'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']); $sort_by_text = array('u' => $user->lang['SORT_USERNAME'], 't' => $user->lang['SORT_DATE'], 'i' => $user->lang['SORT_IP'], 'o' => $user->lang['SORT_ACTION']); $sort_by_sql = array('u' => 'u.username_clean', 't' => 'l.log_time', 'i' => 'l.log_ip', 'o' => 'l.log_operation'); $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_where = ($sort_days) ? (time() - ($sort_days * 86400)) : 0; $sql_sort = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC'); // Grab log data $log_data = array(); $log_count = 0; $start = view_log('user', $log_data, $log_count, $config['topics_per_page'], $start, 0, 0, $user_id, $sql_where, $sql_sort); $base_url = $this->u_action . "&u=$user_id&$u_sort_param"; $pagination->generate_template_pagination($base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); $template->assign_vars(array( 'S_FEEDBACK' => true, 'S_LIMIT_DAYS' => $s_limit_days, 'S_SORT_KEY' => $s_sort_key, 'S_SORT_DIR' => $s_sort_dir, 'S_CLEARLOGS' => $auth->acl_get('a_clearlogs')) ); foreach ($log_data as $row) { $template->assign_block_vars('log', array( 'USERNAME' => $row['username_full'], 'IP' => $row['ip'], 'DATE' => $user->format_date($row['time']), 'ACTION' => nl2br($row['action']), 'ID' => $row['id']) ); } break; case 'warnings': $user->add_lang('mcp'); // Set up general vars $start = request_var('start', 0); $deletemark = (isset($_POST['delmarked'])) ? true : false; $deleteall = (isset($_POST['delall'])) ? true : false; $confirm = (isset($_POST['confirm'])) ? true : false; $marked = request_var('mark', array(0)); $message = utf8_normalize_nfc(request_var('message', '', true)); // Sort keys $sort_days = request_var('st', 0); $sort_key = request_var('sk', 't'); $sort_dir = request_var('sd', 'd'); // Delete entries if requested and able if ($deletemark || $deleteall || $confirm) { if (confirm_box(true)) { $where_sql = ''; $deletemark = request_var('delmarked', 0); $deleteall = request_var('delall', 0); if ($deletemark && $marked) { $where_sql = ' AND ' . $db->sql_in_set('warning_id', array_values($marked)); } if ($where_sql || $deleteall) { $sql = 'DELETE FROM ' . WARNINGS_TABLE . " WHERE user_id = $user_id $where_sql"; $db->sql_query($sql); if ($deleteall) { $log_warnings = $deleted_warnings = 0; } else { $num_warnings = (int) $db->sql_affectedrows(); $deleted_warnings = ' user_warnings - ' . $num_warnings; $log_warnings = ($num_warnings > 2) ? 2 : $num_warnings; } $sql = 'UPDATE ' . USERS_TABLE . " SET user_warnings = $deleted_warnings WHERE user_id = $user_id"; $db->sql_query($sql); if ($log_warnings) { add_log('admin', 'LOG_WARNINGS_DELETED', $user_row['username'], $num_warnings); } else { add_log('admin', 'LOG_WARNINGS_DELETED_ALL', $user_row['username']); } } } else { $s_hidden_fields = array( 'i' => $id, 'mode' => $mode, 'u' => $user_id, 'mark' => $marked, ); if (isset($_POST['delmarked'])) { $s_hidden_fields['delmarked'] = 1; } if (isset($_POST['delall'])) { $s_hidden_fields['delall'] = 1; } if (isset($_POST['delall']) || (isset($_POST['delmarked']) && sizeof($marked))) { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields($s_hidden_fields)); } } } $sql = 'SELECT w.warning_id, w.warning_time, w.post_id, l.log_operation, l.log_data, l.user_id AS mod_user_id, m.username AS mod_username, m.user_colour AS mod_user_colour FROM ' . WARNINGS_TABLE . ' w LEFT JOIN ' . LOG_TABLE . ' l ON (w.log_id = l.log_id) LEFT JOIN ' . USERS_TABLE . ' m ON (l.user_id = m.user_id) WHERE w.user_id = ' . $user_id . ' ORDER BY w.warning_time DESC'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { if (!$row['log_operation']) { // We do not have a log-entry anymore, so there is no data available $row['action'] = $user->lang['USER_WARNING_LOG_DELETED']; } else { $row['action'] = (isset($user->lang[$row['log_operation']])) ? $user->lang[$row['log_operation']] : '{' . ucfirst(str_replace('_', ' ', $row['log_operation'])) . '}'; if (!empty($row['log_data'])) { $log_data_ary = @unserialize($row['log_data']); $log_data_ary = ($log_data_ary === false) ? array() : $log_data_ary; if (isset($user->lang[$row['log_operation']])) { // Check if there are more occurrences of % than arguments, if there are we fill out the arguments array // It doesn't matter if we add more arguments than placeholders if ((substr_count($row['action'], '%') - sizeof($log_data_ary)) > 0) { $log_data_ary = array_merge($log_data_ary, array_fill(0, substr_count($row['action'], '%') - sizeof($log_data_ary), '')); } $row['action'] = vsprintf($row['action'], $log_data_ary); $row['action'] = bbcode_nl2br(censor_text($row['action'])); } else if (!empty($log_data_ary)) { $row['action'] .= '<br />' . implode('', $log_data_ary); } } } $template->assign_block_vars('warn', array( 'ID' => $row['warning_id'], 'USERNAME' => ($row['log_operation']) ? get_username_string('full', $row['mod_user_id'], $row['mod_username'], $row['mod_user_colour']) : '-', 'ACTION' => make_clickable($row['action']), 'DATE' => $user->format_date($row['warning_time']), )); } $db->sql_freeresult($result); $template->assign_vars(array( 'S_WARNINGS' => true, )); break; case 'profile': include($phpbb_root_path . 'includes/functions_user.' . $phpEx); $cp = $phpbb_container->get('profilefields.manager'); $cp_data = $cp_error = array(); $sql = 'SELECT lang_id FROM ' . LANG_TABLE . " WHERE lang_iso = '" . $db->sql_escape($user->data['user_lang']) . "'"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); $user_row['iso_lang_id'] = $row['lang_id']; $data = array( 'jabber' => utf8_normalize_nfc(request_var('jabber', $user_row['user_jabber'], true)), 'bday_day' => 0, 'bday_month' => 0, 'bday_year' => 0, ); if ($user_row['user_birthday']) { list($data['bday_day'], $data['bday_month'], $data['bday_year']) = explode('-', $user_row['user_birthday']); } $data['bday_day'] = request_var('bday_day', $data['bday_day']); $data['bday_month'] = request_var('bday_month', $data['bday_month']); $data['bday_year'] = request_var('bday_year', $data['bday_year']); $data['user_birthday'] = sprintf('%2d-%2d-%4d', $data['bday_day'], $data['bday_month'], $data['bday_year']); /** * Modify user data on editing profile in ACP * * @event core.acp_users_modify_profile * @var array data Array with user profile data * @var bool submit Flag indicating if submit button has been pressed * @var int user_id The user id * @var array user_row Array with the full user data * @since 3.1.4-RC1 */ $vars = array('data', 'submit', 'user_id', 'user_row'); extract($phpbb_dispatcher->trigger_event('core.acp_users_modify_profile', compact($vars))); if ($submit) { $error = validate_data($data, array( 'jabber' => array( array('string', true, 5, 255), array('jabber')), 'bday_day' => array('num', true, 1, 31), 'bday_month' => array('num', true, 1, 12), 'bday_year' => array('num', true, 1901, gmdate('Y', time())), 'user_birthday' => array('date', true), )); // validate custom profile fields $cp->submit_cp_field('profile', $user_row['iso_lang_id'], $cp_data, $cp_error); if (sizeof($cp_error)) { $error = array_merge($error, $cp_error); } if (!check_form_key($form_name)) { $error[] = 'FORM_INVALID'; } /** * Validate profile data in ACP before submitting to the database * * @event core.acp_users_profile_validate * @var bool submit Flag indicating if submit button has been pressed * @var array data Array with user profile data * @var array error Array with the form errors * @since 3.1.4-RC1 */ $vars = array('submit', 'data', 'error'); extract($phpbb_dispatcher->trigger_event('core.acp_users_profile_validate', compact($vars))); if (!sizeof($error)) { $sql_ary = array( 'user_jabber' => $data['jabber'], 'user_birthday' => $data['user_birthday'], ); /** * Modify profile data in ACP before submitting to the database * * @event core.acp_users_profile_modify_sql_ary * @var array cp_data Array with the user custom profile fields data * @var array data Array with user profile data * @var int user_id The user id * @var array user_row Array with the full user data * @var array sql_ary Array with sql data * @since 3.1.4-RC1 */ $vars = array('cp_data', 'data', 'user_id', 'user_row', 'sql_ary'); extract($phpbb_dispatcher->trigger_event('core.acp_users_profile_modify_sql_ary', compact($vars))); $sql = 'UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " WHERE user_id = $user_id"; $db->sql_query($sql); // Update Custom Fields $cp->update_profile_field_data($user_id, $cp_data); trigger_error($user->lang['USER_PROFILE_UPDATED'] . adm_back_link($this->u_action . '&u=' . $user_id)); } // Replace "error" strings with their real, localised form $error = array_map(array($user, 'lang'), $error); } $s_birthday_day_options = '<option value="0"' . ((!$data['bday_day']) ? ' selected="selected"' : '') . '>--</option>'; for ($i = 1; $i < 32; $i++) { $selected = ($i == $data['bday_day']) ? ' selected="selected"' : ''; $s_birthday_day_options .= "<option value=\"$i\"$selected>$i</option>"; } $s_birthday_month_options = '<option value="0"' . ((!$data['bday_month']) ? ' selected="selected"' : '') . '>--</option>'; for ($i = 1; $i < 13; $i++) { $selected = ($i == $data['bday_month']) ? ' selected="selected"' : ''; $s_birthday_month_options .= "<option value=\"$i\"$selected>$i</option>"; } $s_birthday_year_options = ''; $now = getdate(); $s_birthday_year_options = '<option value="0"' . ((!$data['bday_year']) ? ' selected="selected"' : '') . '>--</option>'; for ($i = $now['year'] - 100; $i <= $now['year']; $i++) { $selected = ($i == $data['bday_year']) ? ' selected="selected"' : ''; $s_birthday_year_options .= "<option value=\"$i\"$selected>$i</option>"; } unset($now); $template->assign_vars(array( 'JABBER' => $data['jabber'], 'S_BIRTHDAY_DAY_OPTIONS' => $s_birthday_day_options, 'S_BIRTHDAY_MONTH_OPTIONS' => $s_birthday_month_options, 'S_BIRTHDAY_YEAR_OPTIONS' => $s_birthday_year_options, 'S_PROFILE' => true) ); // Get additional profile fields and assign them to the template block var 'profile_fields' $user->get_profile_fields($user_id); $cp->generate_profile_fields('profile', $user_row['iso_lang_id']); break; case 'prefs': include($phpbb_root_path . 'includes/functions_user.' . $phpEx); $data = array( 'dateformat' => utf8_normalize_nfc(request_var('dateformat', $user_row['user_dateformat'], true)), 'lang' => basename(request_var('lang', $user_row['user_lang'])), 'tz' => request_var('tz', $user_row['user_timezone']), 'style' => request_var('style', $user_row['user_style']), 'viewemail' => request_var('viewemail', $user_row['user_allow_viewemail']), 'massemail' => request_var('massemail', $user_row['user_allow_massemail']), 'hideonline' => request_var('hideonline', !$user_row['user_allow_viewonline']), 'notifymethod' => request_var('notifymethod', $user_row['user_notify_type']), 'notifypm' => request_var('notifypm', $user_row['user_notify_pm']), 'allowpm' => request_var('allowpm', $user_row['user_allow_pm']), 'topic_sk' => request_var('topic_sk', ($user_row['user_topic_sortby_type']) ? $user_row['user_topic_sortby_type'] : 't'), 'topic_sd' => request_var('topic_sd', ($user_row['user_topic_sortby_dir']) ? $user_row['user_topic_sortby_dir'] : 'd'), 'topic_st' => request_var('topic_st', ($user_row['user_topic_show_days']) ? $user_row['user_topic_show_days'] : 0), 'post_sk' => request_var('post_sk', ($user_row['user_post_sortby_type']) ? $user_row['user_post_sortby_type'] : 't'), 'post_sd' => request_var('post_sd', ($user_row['user_post_sortby_dir']) ? $user_row['user_post_sortby_dir'] : 'a'), 'post_st' => request_var('post_st', ($user_row['user_post_show_days']) ? $user_row['user_post_show_days'] : 0), 'view_images' => request_var('view_images', $this->optionget($user_row, 'viewimg')), 'view_flash' => request_var('view_flash', $this->optionget($user_row, 'viewflash')), 'view_smilies' => request_var('view_smilies', $this->optionget($user_row, 'viewsmilies')), 'view_sigs' => request_var('view_sigs', $this->optionget($user_row, 'viewsigs')), 'view_avatars' => request_var('view_avatars', $this->optionget($user_row, 'viewavatars')), 'view_wordcensor' => request_var('view_wordcensor', $this->optionget($user_row, 'viewcensors')), 'bbcode' => request_var('bbcode', $this->optionget($user_row, 'bbcode')), 'smilies' => request_var('smilies', $this->optionget($user_row, 'smilies')), 'sig' => request_var('sig', $this->optionget($user_row, 'attachsig')), 'notify' => request_var('notify', $user_row['user_notify']), ); /** * Modify users preferences data * * @event core.acp_users_prefs_modify_data * @var array data Array with users preferences data * @var array user_row Array with user data * @since 3.1.0-b3 */ $vars = array('data', 'user_row'); extract($phpbb_dispatcher->trigger_event('core.acp_users_prefs_modify_data', compact($vars))); if ($submit) { $error = validate_data($data, array( 'dateformat' => array('string', false, 1, 30), 'lang' => array('match', false, '#^[a-z_\-]{2,}$#i'), 'tz' => array('timezone'), 'topic_sk' => array('string', false, 1, 1), 'topic_sd' => array('string', false, 1, 1), 'post_sk' => array('string', false, 1, 1), 'post_sd' => array('string', false, 1, 1), )); if (!check_form_key($form_name)) { $error[] = 'FORM_INVALID'; } if (!sizeof($error)) { $this->optionset($user_row, 'viewimg', $data['view_images']); $this->optionset($user_row, 'viewflash', $data['view_flash']); $this->optionset($user_row, 'viewsmilies', $data['view_smilies']); $this->optionset($user_row, 'viewsigs', $data['view_sigs']); $this->optionset($user_row, 'viewavatars', $data['view_avatars']); $this->optionset($user_row, 'viewcensors', $data['view_wordcensor']); $this->optionset($user_row, 'bbcode', $data['bbcode']); $this->optionset($user_row, 'smilies', $data['smilies']); $this->optionset($user_row, 'attachsig', $data['sig']); $sql_ary = array( 'user_options' => $user_row['user_options'], 'user_allow_pm' => $data['allowpm'], 'user_allow_viewemail' => $data['viewemail'], 'user_allow_massemail' => $data['massemail'], 'user_allow_viewonline' => !$data['hideonline'], 'user_notify_type' => $data['notifymethod'], 'user_notify_pm' => $data['notifypm'], 'user_dateformat' => $data['dateformat'], 'user_lang' => $data['lang'], 'user_timezone' => $data['tz'], 'user_style' => $data['style'], 'user_topic_sortby_type' => $data['topic_sk'], 'user_post_sortby_type' => $data['post_sk'], 'user_topic_sortby_dir' => $data['topic_sd'], 'user_post_sortby_dir' => $data['post_sd'], 'user_topic_show_days' => $data['topic_st'], 'user_post_show_days' => $data['post_st'], 'user_notify' => $data['notify'], ); /** * Modify SQL query before users preferences are updated * * @event core.acp_users_prefs_modify_sql * @var array data Array with users preferences data * @var array user_row Array with user data * @var array sql_ary SQL array with users preferences data to update * @var array error Array with errors data * @since 3.1.0-b3 */ $vars = array('data', 'user_row', 'sql_ary', 'error'); extract($phpbb_dispatcher->trigger_event('core.acp_users_prefs_modify_sql', compact($vars))); if (!sizeof($error)) { $sql = 'UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " WHERE user_id = $user_id"; $db->sql_query($sql); // Check if user has an active session if ($user_row['session_id']) { // We'll update the session if user_allow_viewonline has changed and the user is a bot // Or if it's a regular user and the admin set it to hide the session if ($user_row['user_allow_viewonline'] != $sql_ary['user_allow_viewonline'] && $user_row['user_type'] == USER_IGNORE || $user_row['user_allow_viewonline'] && !$sql_ary['user_allow_viewonline']) { // We also need to check if the user has the permission to cloak. $user_auth = new \phpbb\auth\auth(); $user_auth->acl($user_row); $session_sql_ary = array( 'session_viewonline' => ($user_auth->acl_get('u_hideonline')) ? $sql_ary['user_allow_viewonline'] : true, ); $sql = 'UPDATE ' . SESSIONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $session_sql_ary) . " WHERE session_user_id = $user_id"; $db->sql_query($sql); unset($user_auth); } } trigger_error($user->lang['USER_PREFS_UPDATED'] . adm_back_link($this->u_action . '&u=' . $user_id)); } } // Replace "error" strings with their real, localised form $error = array_map(array($user, 'lang'), $error); } $dateformat_options = ''; foreach ($user->lang['dateformats'] as $format => $null) { $dateformat_options .= '<option value="' . $format . '"' . (($format == $data['dateformat']) ? ' selected="selected"' : '') . '>'; $dateformat_options .= $user->format_date(time(), $format, false) . ((strpos($format, '|') !== false) ? $user->lang['VARIANT_DATE_SEPARATOR'] . $user->format_date(time(), $format, true) : ''); $dateformat_options .= '</option>'; } $s_custom = false; $dateformat_options .= '<option value="custom"'; if (!isset($user->lang['dateformats'][$data['dateformat']])) { $dateformat_options .= ' selected="selected"'; $s_custom = true; } $dateformat_options .= '>' . $user->lang['CUSTOM_DATEFORMAT'] . '</option>'; $sort_dir_text = array('a' => $user->lang['ASCENDING'], 'd' => $user->lang['DESCENDING']); // Topic ordering options $limit_topic_days = array(0 => $user->lang['ALL_TOPICS'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']); $sort_by_topic_text = array('a' => $user->lang['AUTHOR'], 't' => $user->lang['POST_TIME'], 'r' => $user->lang['REPLIES'], 's' => $user->lang['SUBJECT'], 'v' => $user->lang['VIEWS']); // Post ordering options $limit_post_days = array(0 => $user->lang['ALL_POSTS'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']); $sort_by_post_text = array('a' => $user->lang['AUTHOR'], 't' => $user->lang['POST_TIME'], 's' => $user->lang['SUBJECT']); $_options = array('topic', 'post'); foreach ($_options as $sort_option) { ${'s_limit_' . $sort_option . '_days'} = '<select name="' . $sort_option . '_st">'; foreach (${'limit_' . $sort_option . '_days'} as $day => $text) { $selected = ($data[$sort_option . '_st'] == $day) ? ' selected="selected"' : ''; ${'s_limit_' . $sort_option . '_days'} .= '<option value="' . $day . '"' . $selected . '>' . $text . '</option>'; } ${'s_limit_' . $sort_option . '_days'} .= '</select>'; ${'s_sort_' . $sort_option . '_key'} = '<select name="' . $sort_option . '_sk">'; foreach (${'sort_by_' . $sort_option . '_text'} as $key => $text) { $selected = ($data[$sort_option . '_sk'] == $key) ? ' selected="selected"' : ''; ${'s_sort_' . $sort_option . '_key'} .= '<option value="' . $key . '"' . $selected . '>' . $text . '</option>'; } ${'s_sort_' . $sort_option . '_key'} .= '</select>'; ${'s_sort_' . $sort_option . '_dir'} = '<select name="' . $sort_option . '_sd">'; foreach ($sort_dir_text as $key => $value) { $selected = ($data[$sort_option . '_sd'] == $key) ? ' selected="selected"' : ''; ${'s_sort_' . $sort_option . '_dir'} .= '<option value="' . $key . '"' . $selected . '>' . $value . '</option>'; } ${'s_sort_' . $sort_option . '_dir'} .= '</select>'; } phpbb_timezone_select($template, $user, $data['tz'], true); $user_prefs_data = array( 'S_PREFS' => true, 'S_JABBER_DISABLED' => ($config['jab_enable'] && $user_row['user_jabber'] && @extension_loaded('xml')) ? false : true, 'VIEW_EMAIL' => $data['viewemail'], 'MASS_EMAIL' => $data['massemail'], 'ALLOW_PM' => $data['allowpm'], 'HIDE_ONLINE' => $data['hideonline'], 'NOTIFY_EMAIL' => ($data['notifymethod'] == NOTIFY_EMAIL) ? true : false, 'NOTIFY_IM' => ($data['notifymethod'] == NOTIFY_IM) ? true : false, 'NOTIFY_BOTH' => ($data['notifymethod'] == NOTIFY_BOTH) ? true : false, 'NOTIFY_PM' => $data['notifypm'], 'BBCODE' => $data['bbcode'], 'SMILIES' => $data['smilies'], 'ATTACH_SIG' => $data['sig'], 'NOTIFY' => $data['notify'], 'VIEW_IMAGES' => $data['view_images'], 'VIEW_FLASH' => $data['view_flash'], 'VIEW_SMILIES' => $data['view_smilies'], 'VIEW_SIGS' => $data['view_sigs'], 'VIEW_AVATARS' => $data['view_avatars'], 'VIEW_WORDCENSOR' => $data['view_wordcensor'], 'S_TOPIC_SORT_DAYS' => $s_limit_topic_days, 'S_TOPIC_SORT_KEY' => $s_sort_topic_key, 'S_TOPIC_SORT_DIR' => $s_sort_topic_dir, 'S_POST_SORT_DAYS' => $s_limit_post_days, 'S_POST_SORT_KEY' => $s_sort_post_key, 'S_POST_SORT_DIR' => $s_sort_post_dir, 'DATE_FORMAT' => $data['dateformat'], 'S_DATEFORMAT_OPTIONS' => $dateformat_options, 'S_CUSTOM_DATEFORMAT' => $s_custom, 'DEFAULT_DATEFORMAT' => $config['default_dateformat'], 'A_DEFAULT_DATEFORMAT' => addslashes($config['default_dateformat']), 'S_LANG_OPTIONS' => language_select($data['lang']), 'S_STYLE_OPTIONS' => style_select($data['style']), ); /** * Modify users preferences data before assigning it to the template * * @event core.acp_users_prefs_modify_template_data * @var array data Array with users preferences data * @var array user_row Array with user data * @var array user_prefs_data Array with users preferences data to be assigned to the template * @since 3.1.0-b3 */ $vars = array('data', 'user_row', 'user_prefs_data'); extract($phpbb_dispatcher->trigger_event('core.acp_users_prefs_modify_template_data', compact($vars))); $template->assign_vars($user_prefs_data); break; case 'avatar': include($phpbb_root_path . 'includes/functions_display.' . $phpEx); $avatars_enabled = false; if ($config['allow_avatar']) { $phpbb_avatar_manager = $phpbb_container->get('avatar.manager'); $avatar_drivers = $phpbb_avatar_manager->get_enabled_drivers(); // This is normalised data, without the user_ prefix $avatar_data = \phpbb\avatar\manager::clean_row($user_row, 'user'); if ($submit) { if (check_form_key($form_name)) { $driver_name = $phpbb_avatar_manager->clean_driver_name($request->variable('avatar_driver', '')); if (in_array($driver_name, $avatar_drivers) && !$request->is_set_post('avatar_delete')) { $driver = $phpbb_avatar_manager->get_driver($driver_name); $result = $driver->process_form($request, $template, $user, $avatar_data, $error); if ($result && empty($error)) { // Success! Lets save the result in the database $result = array( 'user_avatar_type' => $driver_name, 'user_avatar' => $result['avatar'], 'user_avatar_width' => $result['avatar_width'], 'user_avatar_height' => $result['avatar_height'], ); $sql = 'UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $result) . ' WHERE user_id = ' . (int) $user_id; $db->sql_query($sql); trigger_error($user->lang['USER_AVATAR_UPDATED'] . adm_back_link($this->u_action . '&u=' . $user_id)); } } } else { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } } // Handle deletion of avatars if ($request->is_set_post('avatar_delete')) { if (!confirm_box(true)) { confirm_box(false, $user->lang('CONFIRM_AVATAR_DELETE'), build_hidden_fields(array( 'avatar_delete' => true)) ); } else { $phpbb_avatar_manager->handle_avatar_delete($db, $user, $avatar_data, USERS_TABLE, 'user_'); trigger_error($user->lang['USER_AVATAR_UPDATED'] . adm_back_link($this->u_action . '&u=' . $user_id)); } } $selected_driver = $phpbb_avatar_manager->clean_driver_name($request->variable('avatar_driver', $user_row['user_avatar_type'])); foreach ($avatar_drivers as $current_driver) { $driver = $phpbb_avatar_manager->get_driver($current_driver); $avatars_enabled = true; $config_name = $phpbb_avatar_manager->get_driver_config_name($driver); $template->set_filenames(array( 'avatar' => "acp_avatar_options_{$config_name}.html", )); if ($driver->prepare_form($request, $template, $user, $avatar_data, $error)) { $driver_name = $phpbb_avatar_manager->prepare_driver_name($current_driver); $driver_upper = strtoupper($driver_name); $template->assign_block_vars('avatar_drivers', array( 'L_TITLE' => $user->lang($driver_upper . '_TITLE'), 'L_EXPLAIN' => $user->lang($driver_upper . '_EXPLAIN'), 'DRIVER' => $driver_name, 'SELECTED' => $current_driver == $selected_driver, 'OUTPUT' => $template->assign_display('avatar'), )); } } } // Replace "error" strings with their real, localised form $error = $phpbb_avatar_manager->localize_errors($user, $error); $avatar = phpbb_get_user_avatar($user_row, 'USER_AVATAR', true); $template->assign_vars(array( 'S_AVATAR' => true, 'ERROR' => (!empty($error)) ? implode('<br />', $error) : '', 'AVATAR' => (empty($avatar) ? '<img src="' . $phpbb_admin_path . 'images/no_avatar.gif" alt="" />' : $avatar), 'S_FORM_ENCTYPE' => ' enctype="multipart/form-data"', 'L_AVATAR_EXPLAIN' => sprintf($user->lang['AVATAR_EXPLAIN'], $config['avatar_max_width'], $config['avatar_max_height'], $config['avatar_filesize'] / 1024), 'S_AVATARS_ENABLED' => ($config['allow_avatar'] && $avatars_enabled), )); break; case 'rank': if ($submit) { if (!check_form_key($form_name)) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } $rank_id = request_var('user_rank', 0); $sql = 'UPDATE ' . USERS_TABLE . " SET user_rank = $rank_id WHERE user_id = $user_id"; $db->sql_query($sql); trigger_error($user->lang['USER_RANK_UPDATED'] . adm_back_link($this->u_action . '&u=' . $user_id)); } $sql = 'SELECT * FROM ' . RANKS_TABLE . ' WHERE rank_special = 1 ORDER BY rank_title'; $result = $db->sql_query($sql); $s_rank_options = '<option value="0"' . ((!$user_row['user_rank']) ? ' selected="selected"' : '') . '>' . $user->lang['NO_SPECIAL_RANK'] . '</option>'; while ($row = $db->sql_fetchrow($result)) { $selected = ($user_row['user_rank'] && $row['rank_id'] == $user_row['user_rank']) ? ' selected="selected"' : ''; $s_rank_options .= '<option value="' . $row['rank_id'] . '"' . $selected . '>' . $row['rank_title'] . '</option>'; } $db->sql_freeresult($result); $template->assign_vars(array( 'S_RANK' => true, 'S_RANK_OPTIONS' => $s_rank_options) ); break; case 'sig': include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx); include_once($phpbb_root_path . 'includes/functions_display.' . $phpEx); $enable_bbcode = ($config['allow_sig_bbcode']) ? (bool) $this->optionget($user_row, 'sig_bbcode') : false; $enable_smilies = ($config['allow_sig_smilies']) ? (bool) $this->optionget($user_row, 'sig_smilies') : false; $enable_urls = ($config['allow_sig_links']) ? (bool) $this->optionget($user_row, 'sig_links') : false; $signature = utf8_normalize_nfc(request_var('signature', (string) $user_row['user_sig'], true)); $preview = (isset($_POST['preview'])) ? true : false; if ($submit || $preview) { include_once($phpbb_root_path . 'includes/message_parser.' . $phpEx); $enable_bbcode = ($config['allow_sig_bbcode']) ? ((request_var('disable_bbcode', false)) ? false : true) : false; $enable_smilies = ($config['allow_sig_smilies']) ? ((request_var('disable_smilies', false)) ? false : true) : false; $enable_urls = ($config['allow_sig_links']) ? ((request_var('disable_magic_url', false)) ? false : true) : false; $message_parser = new parse_message($signature); // Allowing Quote BBCode $message_parser->parse($enable_bbcode, $enable_urls, $enable_smilies, $config['allow_sig_img'], $config['allow_sig_flash'], true, $config['allow_sig_links'], true, 'sig'); if (sizeof($message_parser->warn_msg)) { $error[] = implode('<br />', $message_parser->warn_msg); } if (!check_form_key($form_name)) { $error = 'FORM_INVALID'; } if (!sizeof($error) && $submit) { $this->optionset($user_row, 'sig_bbcode', $enable_bbcode); $this->optionset($user_row, 'sig_smilies', $enable_smilies); $this->optionset($user_row, 'sig_links', $enable_urls); $sql_ary = array( 'user_sig' => (string) $message_parser->message, 'user_options' => $user_row['user_options'], 'user_sig_bbcode_uid' => (string) $message_parser->bbcode_uid, 'user_sig_bbcode_bitfield' => (string) $message_parser->bbcode_bitfield ); $sql = 'UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE user_id = ' . $user_id; $db->sql_query($sql); trigger_error($user->lang['USER_SIG_UPDATED'] . adm_back_link($this->u_action . '&u=' . $user_id)); } // Replace "error" strings with their real, localised form $error = array_map(array($user, 'lang'), $error); } $signature_preview = ''; if ($preview) { // Now parse it for displaying $signature_preview = $message_parser->format_display($enable_bbcode, $enable_urls, $enable_smilies, false); unset($message_parser); } decode_message($signature, $user_row['user_sig_bbcode_uid']); $template->assign_vars(array( 'S_SIGNATURE' => true, 'SIGNATURE' => $signature, 'SIGNATURE_PREVIEW' => $signature_preview, 'S_BBCODE_CHECKED' => (!$enable_bbcode) ? ' checked="checked"' : '', 'S_SMILIES_CHECKED' => (!$enable_smilies) ? ' checked="checked"' : '', 'S_MAGIC_URL_CHECKED' => (!$enable_urls) ? ' checked="checked"' : '', 'BBCODE_STATUS' => ($config['allow_sig_bbcode']) ? sprintf($user->lang['BBCODE_IS_ON'], '<a href="' . append_sid("{$phpbb_root_path}faq.$phpEx", 'mode=bbcode') . '">', '</a>') : sprintf($user->lang['BBCODE_IS_OFF'], '<a href="' . append_sid("{$phpbb_root_path}faq.$phpEx", 'mode=bbcode') . '">', '</a>'), 'SMILIES_STATUS' => ($config['allow_sig_smilies']) ? $user->lang['SMILIES_ARE_ON'] : $user->lang['SMILIES_ARE_OFF'], 'IMG_STATUS' => ($config['allow_sig_img']) ? $user->lang['IMAGES_ARE_ON'] : $user->lang['IMAGES_ARE_OFF'], 'FLASH_STATUS' => ($config['allow_sig_flash']) ? $user->lang['FLASH_IS_ON'] : $user->lang['FLASH_IS_OFF'], 'URL_STATUS' => ($config['allow_sig_links']) ? $user->lang['URL_IS_ON'] : $user->lang['URL_IS_OFF'], 'L_SIGNATURE_EXPLAIN' => $user->lang('SIGNATURE_EXPLAIN', (int) $config['max_sig_chars']), 'S_BBCODE_ALLOWED' => $config['allow_sig_bbcode'], 'S_SMILIES_ALLOWED' => $config['allow_sig_smilies'], 'S_BBCODE_IMG' => ($config['allow_sig_img']) ? true : false, 'S_BBCODE_FLASH' => ($config['allow_sig_flash']) ? true : false, 'S_LINKS_ALLOWED' => ($config['allow_sig_links']) ? true : false) ); // Assigning custom bbcodes display_custom_bbcodes(); break; case 'attach': $start = request_var('start', 0); $deletemark = (isset($_POST['delmarked'])) ? true : false; $marked = request_var('mark', array(0)); $pagination = $phpbb_container->get('pagination'); // Sort keys $sort_key = request_var('sk', 'a'); $sort_dir = request_var('sd', 'd'); if ($deletemark && sizeof($marked)) { $sql = 'SELECT attach_id FROM ' . ATTACHMENTS_TABLE . ' WHERE poster_id = ' . $user_id . ' AND is_orphan = 0 AND ' . $db->sql_in_set('attach_id', $marked); $result = $db->sql_query($sql); $marked = array(); while ($row = $db->sql_fetchrow($result)) { $marked[] = $row['attach_id']; } $db->sql_freeresult($result); } if ($deletemark && sizeof($marked)) { if (confirm_box(true)) { $sql = 'SELECT real_filename FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('attach_id', $marked); $result = $db->sql_query($sql); $log_attachments = array(); while ($row = $db->sql_fetchrow($result)) { $log_attachments[] = $row['real_filename']; } $db->sql_freeresult($result); delete_attachments('attach', $marked); $message = (sizeof($log_attachments) == 1) ? $user->lang['ATTACHMENT_DELETED'] : $user->lang['ATTACHMENTS_DELETED']; add_log('admin', 'LOG_ATTACHMENTS_DELETED', implode($user->lang['COMMA_SEPARATOR'], $log_attachments)); trigger_error($message . adm_back_link($this->u_action . '&u=' . $user_id)); } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 'u' => $user_id, 'i' => $id, 'mode' => $mode, 'action' => $action, 'delmarked' => true, 'mark' => $marked)) ); } } $sk_text = array('a' => $user->lang['SORT_FILENAME'], 'c' => $user->lang['SORT_EXTENSION'], 'd' => $user->lang['SORT_SIZE'], 'e' => $user->lang['SORT_DOWNLOADS'], 'f' => $user->lang['SORT_POST_TIME'], 'g' => $user->lang['SORT_TOPIC_TITLE']); $sk_sql = array('a' => 'a.real_filename', 'c' => 'a.extension', 'd' => 'a.filesize', 'e' => 'a.download_count', 'f' => 'a.filetime', 'g' => 't.topic_title'); $sd_text = array('a' => $user->lang['ASCENDING'], 'd' => $user->lang['DESCENDING']); $s_sort_key = ''; foreach ($sk_text as $key => $value) { $selected = ($sort_key == $key) ? ' selected="selected"' : ''; $s_sort_key .= '<option value="' . $key . '"' . $selected . '>' . $value . '</option>'; } $s_sort_dir = ''; foreach ($sd_text as $key => $value) { $selected = ($sort_dir == $key) ? ' selected="selected"' : ''; $s_sort_dir .= '<option value="' . $key . '"' . $selected . '>' . $value . '</option>'; } if (!isset($sk_sql[$sort_key])) { $sort_key = 'a'; } $order_by = $sk_sql[$sort_key] . ' ' . (($sort_dir == 'a') ? 'ASC' : 'DESC'); $sql = 'SELECT COUNT(attach_id) as num_attachments FROM ' . ATTACHMENTS_TABLE . " WHERE poster_id = $user_id AND is_orphan = 0"; $result = $db->sql_query_limit($sql, 1); $num_attachments = (int) $db->sql_fetchfield('num_attachments'); $db->sql_freeresult($result); $sql = 'SELECT a.*, t.topic_title, p.message_subject as message_title FROM ' . ATTACHMENTS_TABLE . ' a LEFT JOIN ' . TOPICS_TABLE . ' t ON (a.topic_id = t.topic_id AND a.in_message = 0) LEFT JOIN ' . PRIVMSGS_TABLE . ' p ON (a.post_msg_id = p.msg_id AND a.in_message = 1) WHERE a.poster_id = ' . $user_id . " AND a.is_orphan = 0 ORDER BY $order_by"; $result = $db->sql_query_limit($sql, $config['topics_per_page'], $start); while ($row = $db->sql_fetchrow($result)) { if ($row['in_message']) { $view_topic = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=pm&p={$row['post_msg_id']}"); } else { $view_topic = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "t={$row['topic_id']}&p={$row['post_msg_id']}") . '#p' . $row['post_msg_id']; } $template->assign_block_vars('attach', array( 'REAL_FILENAME' => $row['real_filename'], 'COMMENT' => nl2br($row['attach_comment']), 'EXTENSION' => $row['extension'], 'SIZE' => get_formatted_filesize($row['filesize']), 'DOWNLOAD_COUNT' => $row['download_count'], 'POST_TIME' => $user->format_date($row['filetime']), 'TOPIC_TITLE' => ($row['in_message']) ? $row['message_title'] : $row['topic_title'], 'ATTACH_ID' => $row['attach_id'], 'POST_ID' => $row['post_msg_id'], 'TOPIC_ID' => $row['topic_id'], 'S_IN_MESSAGE' => $row['in_message'], 'U_DOWNLOAD' => append_sid("{$phpbb_root_path}download/file.$phpEx", 'mode=view&id=' . $row['attach_id']), 'U_VIEW_TOPIC' => $view_topic) ); } $db->sql_freeresult($result); $base_url = $this->u_action . "&u=$user_id&sk=$sort_key&sd=$sort_dir"; $pagination->generate_template_pagination($base_url, 'pagination', 'start', $num_attachments, $config['topics_per_page'], $start); $template->assign_vars(array( 'S_ATTACHMENTS' => true, 'S_SORT_KEY' => $s_sort_key, 'S_SORT_DIR' => $s_sort_dir, )); break; case 'groups': include($phpbb_root_path . 'includes/functions_user.' . $phpEx); $user->add_lang(array('groups', 'acp/groups')); $group_id = request_var('g', 0); if ($group_id) { // Check the founder only entry for this group to make sure everything is well $sql = 'SELECT group_founder_manage FROM ' . GROUPS_TABLE . ' WHERE group_id = ' . $group_id; $result = $db->sql_query($sql); $founder_manage = (int) $db->sql_fetchfield('group_founder_manage'); $db->sql_freeresult($result); if ($user->data['user_type'] != USER_FOUNDER && $founder_manage) { trigger_error($user->lang['NOT_ALLOWED_MANAGE_GROUP'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } } else { $founder_manage = 0; } switch ($action) { case 'demote': case 'promote': case 'default': if (!$group_id) { trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } group_user_attributes($action, $group_id, $user_id); if ($action == 'default') { $user_row['group_id'] = $group_id; } break; case 'delete': if (confirm_box(true)) { if (!$group_id) { trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } if ($error = group_user_del($group_id, $user_id)) { trigger_error($user->lang[$error] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } $error = array(); // The delete action was successful - therefore update the user row... $sql = 'SELECT u.*, s.* FROM ' . USERS_TABLE . ' u LEFT JOIN ' . SESSIONS_TABLE . ' s ON (s.session_user_id = u.user_id) WHERE u.user_id = ' . $user_id . ' ORDER BY s.session_time DESC'; $result = $db->sql_query_limit($sql, 1); $user_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 'u' => $user_id, 'i' => $id, 'mode' => $mode, 'action' => $action, 'g' => $group_id)) ); } break; case 'approve': if (confirm_box(true)) { if (!$group_id) { trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } group_user_attributes($action, $group_id, $user_id); } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 'u' => $user_id, 'i' => $id, 'mode' => $mode, 'action' => $action, 'g' => $group_id)) ); } break; } // Add user to group? if ($submit) { if (!check_form_key($form_name)) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } if (!$group_id) { trigger_error($user->lang['NO_GROUP'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } // Add user/s to group if ($error = group_user_add($group_id, $user_id)) { trigger_error($user->lang[$error] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } $error = array(); } $sql = 'SELECT ug.*, g.* FROM ' . GROUPS_TABLE . ' g, ' . USER_GROUP_TABLE . " ug WHERE ug.user_id = $user_id AND g.group_id = ug.group_id ORDER BY g.group_type DESC, ug.user_pending ASC, g.group_name"; $result = $db->sql_query($sql); $i = 0; $group_data = $id_ary = array(); while ($row = $db->sql_fetchrow($result)) { $type = ($row['group_type'] == GROUP_SPECIAL) ? 'special' : (($row['user_pending']) ? 'pending' : 'normal'); $group_data[$type][$i]['group_id'] = $row['group_id']; $group_data[$type][$i]['group_name'] = $row['group_name']; $group_data[$type][$i]['group_leader'] = ($row['group_leader']) ? 1 : 0; $id_ary[] = $row['group_id']; $i++; } $db->sql_freeresult($result); // Select box for other groups $sql = 'SELECT group_id, group_name, group_type, group_founder_manage FROM ' . GROUPS_TABLE . ' ' . ((sizeof($id_ary)) ? 'WHERE ' . $db->sql_in_set('group_id', $id_ary, true) : '') . ' ORDER BY group_type DESC, group_name ASC'; $result = $db->sql_query($sql); $s_group_options = ''; while ($row = $db->sql_fetchrow($result)) { if (!$config['coppa_enable'] && $row['group_name'] == 'REGISTERED_COPPA') { continue; } // Do not display those groups not allowed to be managed if ($user->data['user_type'] != USER_FOUNDER && $row['group_founder_manage']) { continue; } $s_group_options .= '<option' . (($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : '') . ' value="' . $row['group_id'] . '">' . (($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']) . '</option>'; } $db->sql_freeresult($result); $current_type = ''; foreach ($group_data as $group_type => $data_ary) { if ($current_type != $group_type) { $template->assign_block_vars('group', array( 'S_NEW_GROUP_TYPE' => true, 'GROUP_TYPE' => $user->lang['USER_GROUP_' . strtoupper($group_type)]) ); } foreach ($data_ary as $data) { $template->assign_block_vars('group', array( 'U_EDIT_GROUP' => append_sid("{$phpbb_admin_path}index.$phpEx", "i=groups&mode=manage&action=edit&u=$user_id&g={$data['group_id']}&back_link=acp_users_groups"), 'U_DEFAULT' => $this->u_action . "&action=default&u=$user_id&g=" . $data['group_id'], 'U_DEMOTE_PROMOTE' => $this->u_action . '&action=' . (($data['group_leader']) ? 'demote' : 'promote') . "&u=$user_id&g=" . $data['group_id'], 'U_DELETE' => $this->u_action . "&action=delete&u=$user_id&g=" . $data['group_id'], 'U_APPROVE' => ($group_type == 'pending') ? $this->u_action . "&action=approve&u=$user_id&g=" . $data['group_id'] : '', 'GROUP_NAME' => ($group_type == 'special') ? $user->lang['G_' . $data['group_name']] : $data['group_name'], 'L_DEMOTE_PROMOTE' => ($data['group_leader']) ? $user->lang['GROUP_DEMOTE'] : $user->lang['GROUP_PROMOTE'], 'S_IS_MEMBER' => ($group_type != 'pending') ? true : false, 'S_NO_DEFAULT' => ($user_row['group_id'] != $data['group_id']) ? true : false, 'S_SPECIAL_GROUP' => ($group_type == 'special') ? true : false, ) ); } } $template->assign_vars(array( 'S_GROUPS' => true, 'S_GROUP_OPTIONS' => $s_group_options) ); break; case 'perm': include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx); $auth_admin = new auth_admin(); $user->add_lang('acp/permissions'); add_permission_language(); $forum_id = request_var('f', 0); // Global Permissions if (!$forum_id) { // Select auth options $sql = 'SELECT auth_option, is_local, is_global FROM ' . ACL_OPTIONS_TABLE . ' WHERE auth_option ' . $db->sql_like_expression($db->get_any_char() . '_') . ' AND is_global = 1 ORDER BY auth_option'; $result = $db->sql_query($sql); $hold_ary = array(); while ($row = $db->sql_fetchrow($result)) { $hold_ary = $auth_admin->get_mask('view', $user_id, false, false, $row['auth_option'], 'global', ACL_NEVER); $auth_admin->display_mask('view', $row['auth_option'], $hold_ary, 'user', false, false); } $db->sql_freeresult($result); unset($hold_ary); } else { $sql = 'SELECT auth_option, is_local, is_global FROM ' . ACL_OPTIONS_TABLE . " WHERE auth_option " . $db->sql_like_expression($db->get_any_char() . '_') . " AND is_local = 1 ORDER BY is_global DESC, auth_option"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $hold_ary = $auth_admin->get_mask('view', $user_id, false, $forum_id, $row['auth_option'], 'local', ACL_NEVER); $auth_admin->display_mask('view', $row['auth_option'], $hold_ary, 'user', true, false); } $db->sql_freeresult($result); } $s_forum_options = '<option value="0"' . ((!$forum_id) ? ' selected="selected"' : '') . '>' . $user->lang['VIEW_GLOBAL_PERMS'] . '</option>'; $s_forum_options .= make_forum_select($forum_id, false, true, false, false, false); $template->assign_vars(array( 'S_PERMISSIONS' => true, 'S_GLOBAL' => (!$forum_id) ? true : false, 'S_FORUM_OPTIONS' => $s_forum_options, 'U_ACTION' => $this->u_action . '&u=' . $user_id, 'U_USER_PERMISSIONS' => append_sid("{$phpbb_admin_path}index.$phpEx" ,'i=permissions&mode=setting_user_global&user_id[]=' . $user_id), 'U_USER_FORUM_PERMISSIONS' => append_sid("{$phpbb_admin_path}index.$phpEx", 'i=permissions&mode=setting_user_local&user_id[]=' . $user_id)) ); break; } // Assign general variables $template->assign_vars(array( 'S_ERROR' => (sizeof($error)) ? true : false, 'ERROR_MSG' => (sizeof($error)) ? implode('<br />', $error) : '') ); } /** * Set option bit field for user options in a user row array. * * Optionset replacement for this module based on $user->optionset. * * @param array $user_row Row from the users table. * @param int $key Option key, as defined in $user->keyoptions property. * @param bool $value True to set the option, false to clear the option. * @param int $data Current bit field value, or false to use $user_row['user_options'] * @return int|bool If $data is false, the bit field is modified and * written back to $user_row['user_options'], and * return value is true if the bit field changed and * false otherwise. If $data is not false, the new * bitfield value is returned. */ function optionset(&$user_row, $key, $value, $data = false) { global $user; $var = ($data !== false) ? $data : $user_row['user_options']; $new_var = phpbb_optionset($user->keyoptions[$key], $value, $var); if ($data === false) { if ($new_var != $var) { $user_row['user_options'] = $new_var; return true; } else { return false; } } else { return $new_var; } } /** * Get option bit field from user options in a user row array. * * Optionget replacement for this module based on $user->optionget. * * @param array $user_row Row from the users table. * @param int $key option key, as defined in $user->keyoptions property. * @param int $data bit field value to use, or false to use $user_row['user_options'] * @return bool true if the option is set in the bit field, false otherwise */ function optionget(&$user_row, $key, $data = false) { global $user; $var = ($data !== false) ? $data : $user_row['user_options']; return phpbb_optionget($user->keyoptions[$key], $var); } } acp_search.php000077700000040652151514745240007373 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_search { var $u_action; var $state; var $search; var $max_post_id; var $batch_size = 100; function main($id, $mode) { global $user; $user->add_lang('acp/search'); // For some this may be of help... @ini_set('memory_limit', '128M'); switch ($mode) { case 'settings': $this->settings($id, $mode); break; case 'index': $this->index($id, $mode); break; } } function settings($id, $mode) { global $db, $user, $auth, $template, $cache; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; $submit = (isset($_POST['submit'])) ? true : false; $search_types = $this->get_search_types(); $settings = array( 'search_interval' => 'float', 'search_anonymous_interval' => 'float', 'load_search' => 'bool', 'limit_search_load' => 'float', 'min_search_author_chars' => 'integer', 'max_num_search_keywords' => 'integer', 'search_store_results' => 'integer', ); $search = null; $error = false; $search_options = ''; foreach ($search_types as $type) { if ($this->init_search($type, $search, $error)) { continue; } $name = $search->get_name(); $selected = ($config['search_type'] == $type) ? ' selected="selected"' : ''; $identifier = substr($type, strrpos($type, '\\') + 1); $search_options .= "<option value=\"$type\"$selected data-toggle-setting=\"#search_{$identifier}_settings\">$name</option>"; if (method_exists($search, 'acp')) { $vars = $search->acp(); if (!$submit) { $template->assign_block_vars('backend', array( 'NAME' => $name, 'SETTINGS' => $vars['tpl'], 'IDENTIFIER' => $identifier, )); } else if (is_array($vars['config'])) { $settings = array_merge($settings, $vars['config']); } } } unset($search); unset($error); $cfg_array = (isset($_REQUEST['config'])) ? request_var('config', array('' => ''), true) : array(); $updated = request_var('updated', false); foreach ($settings as $config_name => $var_type) { if (!isset($cfg_array[$config_name])) { continue; } // e.g. integer:4:12 (min 4, max 12) $var_type = explode(':', $var_type); $config_value = $cfg_array[$config_name]; settype($config_value, $var_type[0]); if (isset($var_type[1])) { $config_value = max($var_type[1], $config_value); } if (isset($var_type[2])) { $config_value = min($var_type[2], $config_value); } // only change config if anything was actually changed if ($submit && ($config[$config_name] != $config_value)) { set_config($config_name, $config_value); $updated = true; } } if ($submit) { $extra_message = ''; if ($updated) { add_log('admin', 'LOG_CONFIG_SEARCH'); } if (isset($cfg_array['search_type']) && in_array($cfg_array['search_type'], $search_types, true) && ($cfg_array['search_type'] != $config['search_type'])) { $search = null; $error = false; if (!$this->init_search($cfg_array['search_type'], $search, $error)) { if (confirm_box(true)) { if (!method_exists($search, 'init') || !($error = $search->init())) { set_config('search_type', $cfg_array['search_type']); if (!$updated) { add_log('admin', 'LOG_CONFIG_SEARCH'); } $extra_message = '<br />' . $user->lang['SWITCHED_SEARCH_BACKEND'] . '<br /><a href="' . append_sid("{$phpbb_admin_path}index.$phpEx", 'i=search&mode=index') . '">» ' . $user->lang['GO_TO_SEARCH_INDEX'] . '</a>'; } else { trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING); } } else { confirm_box(false, $user->lang['CONFIRM_SEARCH_BACKEND'], build_hidden_fields(array( 'i' => $id, 'mode' => $mode, 'submit' => true, 'updated' => $updated, 'config' => array('search_type' => $cfg_array['search_type']), ))); } } else { trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING); } } $search = null; $error = false; if (!$this->init_search($config['search_type'], $search, $error)) { if ($updated) { if (method_exists($search, 'config_updated')) { if ($search->config_updated()) { trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING); } } } } else { trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING); } trigger_error($user->lang['CONFIG_UPDATED'] . $extra_message . adm_back_link($this->u_action)); } unset($cfg_array); $this->tpl_name = 'acp_search'; $this->page_title = 'ACP_SEARCH_SETTINGS'; $template->assign_vars(array( 'LIMIT_SEARCH_LOAD' => (float) $config['limit_search_load'], 'MIN_SEARCH_AUTHOR_CHARS' => (int) $config['min_search_author_chars'], 'SEARCH_INTERVAL' => (float) $config['search_interval'], 'SEARCH_GUEST_INTERVAL' => (float) $config['search_anonymous_interval'], 'SEARCH_STORE_RESULTS' => (int) $config['search_store_results'], 'MAX_NUM_SEARCH_KEYWORDS' => (int) $config['max_num_search_keywords'], 'S_SEARCH_TYPES' => $search_options, 'S_YES_SEARCH' => (bool) $config['load_search'], 'S_SETTINGS' => true, 'U_ACTION' => $this->u_action) ); } function index($id, $mode) { global $db, $user, $auth, $template, $cache; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; $action = request_var('action', ''); $this->state = explode(',', $config['search_indexing_state']); if (isset($_POST['cancel'])) { $action = ''; $this->state = array(); $this->save_state(); } if ($action) { switch ($action) { case 'progress_bar': $type = request_var('type', ''); $this->display_progress_bar($type); break; case 'delete': $this->state[1] = 'delete'; break; case 'create': $this->state[1] = 'create'; break; default: trigger_error('NO_ACTION', E_USER_ERROR); break; } if (empty($this->state[0])) { $this->state[0] = request_var('search_type', ''); } $this->search = null; $error = false; if ($this->init_search($this->state[0], $this->search, $error)) { trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING); } $name = $this->search->get_name(); $action = &$this->state[1]; $this->max_post_id = $this->get_max_post_id(); $post_counter = (isset($this->state[2])) ? $this->state[2] : 0; $this->state[2] = &$post_counter; $this->save_state(); switch ($action) { case 'delete': if (method_exists($this->search, 'delete_index')) { // pass a reference to myself so the $search object can make use of save_state() and attributes if ($error = $this->search->delete_index($this, append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&mode=$mode&action=delete", false))) { $this->state = array(''); $this->save_state(); trigger_error($error . adm_back_link($this->u_action) . $this->close_popup_js(), E_USER_WARNING); } } else { $starttime = explode(' ', microtime()); $starttime = $starttime[1] + $starttime[0]; $row_count = 0; while (still_on_time() && $post_counter <= $this->max_post_id) { $sql = 'SELECT post_id, poster_id, forum_id FROM ' . POSTS_TABLE . ' WHERE post_id >= ' . (int) ($post_counter + 1) . ' AND post_id <= ' . (int) ($post_counter + $this->batch_size); $result = $db->sql_query($sql); $ids = $posters = $forum_ids = array(); while ($row = $db->sql_fetchrow($result)) { $ids[] = $row['post_id']; $posters[] = $row['poster_id']; $forum_ids[] = $row['forum_id']; } $db->sql_freeresult($result); $row_count += sizeof($ids); if (sizeof($ids)) { $this->search->index_remove($ids, $posters, $forum_ids); } $post_counter += $this->batch_size; } // save the current state $this->save_state(); if ($post_counter <= $this->max_post_id) { $mtime = explode(' ', microtime()); $totaltime = $mtime[0] + $mtime[1] - $starttime; $rows_per_second = $row_count / $totaltime; meta_refresh(1, append_sid($this->u_action . '&action=delete&skip_rows=' . $post_counter)); trigger_error($user->lang('SEARCH_INDEX_DELETE_REDIRECT', (int) $row_count, $post_counter, $rows_per_second)); } } $this->search->tidy(); $this->state = array(''); $this->save_state(); add_log('admin', 'LOG_SEARCH_INDEX_REMOVED', $name); trigger_error($user->lang['SEARCH_INDEX_REMOVED'] . adm_back_link($this->u_action) . $this->close_popup_js()); break; case 'create': if (method_exists($this->search, 'create_index')) { // pass a reference to acp_search so the $search object can make use of save_state() and attributes if ($error = $this->search->create_index($this, append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&mode=$mode&action=create", false))) { $this->state = array(''); $this->save_state(); trigger_error($error . adm_back_link($this->u_action) . $this->close_popup_js(), E_USER_WARNING); } } else { $sql = 'SELECT forum_id, enable_indexing FROM ' . FORUMS_TABLE; $result = $db->sql_query($sql, 3600); while ($row = $db->sql_fetchrow($result)) { $forums[$row['forum_id']] = (bool) $row['enable_indexing']; } $db->sql_freeresult($result); $starttime = explode(' ', microtime()); $starttime = $starttime[1] + $starttime[0]; $row_count = 0; while (still_on_time() && $post_counter <= $this->max_post_id) { $sql = 'SELECT post_id, post_subject, post_text, poster_id, forum_id FROM ' . POSTS_TABLE . ' WHERE post_id >= ' . (int) ($post_counter + 1) . ' AND post_id <= ' . (int) ($post_counter + $this->batch_size); $result = $db->sql_query($sql); $buffer = $db->sql_buffer_nested_transactions(); if ($buffer) { $rows = $db->sql_fetchrowset($result); $rows[] = false; // indicate end of array for while loop below $db->sql_freeresult($result); } $i = 0; while ($row = ($buffer ? $rows[$i++] : $db->sql_fetchrow($result))) { // Indexing enabled for this forum if (isset($forums[$row['forum_id']]) && $forums[$row['forum_id']]) { $this->search->index('post', $row['post_id'], $row['post_text'], $row['post_subject'], $row['poster_id'], $row['forum_id']); } $row_count++; } if (!$buffer) { $db->sql_freeresult($result); } $post_counter += $this->batch_size; } // save the current state $this->save_state(); // pretend the number of posts was as big as the number of ids we indexed so far // just an estimation as it includes deleted posts $num_posts = $config['num_posts']; $config['num_posts'] = min($config['num_posts'], $post_counter); $this->search->tidy(); $config['num_posts'] = $num_posts; if ($post_counter <= $this->max_post_id) { $mtime = explode(' ', microtime()); $totaltime = $mtime[0] + $mtime[1] - $starttime; $rows_per_second = $row_count / $totaltime; meta_refresh(1, append_sid($this->u_action . '&action=create&skip_rows=' . $post_counter)); trigger_error($user->lang('SEARCH_INDEX_CREATE_REDIRECT', (int) $row_count, $post_counter) . $user->lang('SEARCH_INDEX_CREATE_REDIRECT_RATE', $rows_per_second)); } } $this->search->tidy(); $this->state = array(''); $this->save_state(); add_log('admin', 'LOG_SEARCH_INDEX_CREATED', $name); trigger_error($user->lang['SEARCH_INDEX_CREATED'] . adm_back_link($this->u_action) . $this->close_popup_js()); break; } } $search_types = $this->get_search_types(); $search = null; $error = false; foreach ($search_types as $type) { if ($this->init_search($type, $search, $error) || !method_exists($search, 'index_created')) { continue; } $name = $search->get_name(); $data = array(); if (method_exists($search, 'index_stats')) { $data = $search->index_stats(); } $statistics = array(); foreach ($data as $statistic => $value) { $n = sizeof($statistics); if ($n && sizeof($statistics[$n - 1]) < 3) { $statistics[$n - 1] += array('statistic_2' => $statistic, 'value_2' => $value); } else { $statistics[] = array('statistic_1' => $statistic, 'value_1' => $value); } } $template->assign_block_vars('backend', array( 'L_NAME' => $name, 'NAME' => $type, 'S_ACTIVE' => ($type == $config['search_type']) ? true : false, 'S_HIDDEN_FIELDS' => build_hidden_fields(array('search_type' => $type)), 'S_INDEXED' => (bool) $search->index_created(), 'S_STATS' => (bool) sizeof($statistics)) ); foreach ($statistics as $statistic) { $template->assign_block_vars('backend.data', array( 'STATISTIC_1' => $statistic['statistic_1'], 'VALUE_1' => $statistic['value_1'], 'STATISTIC_2' => (isset($statistic['statistic_2'])) ? $statistic['statistic_2'] : '', 'VALUE_2' => (isset($statistic['value_2'])) ? $statistic['value_2'] : '') ); } } unset($search); unset($error); unset($statistics); unset($data); $this->tpl_name = 'acp_search'; $this->page_title = 'ACP_SEARCH_INDEX'; $template->assign_vars(array( 'S_INDEX' => true, 'U_ACTION' => $this->u_action, 'U_PROGRESS_BAR' => append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&mode=$mode&action=progress_bar"), 'UA_PROGRESS_BAR' => addslashes(append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&mode=$mode&action=progress_bar")), )); if (isset($this->state[1])) { $template->assign_vars(array( 'S_CONTINUE_INDEXING' => $this->state[1], 'U_CONTINUE_INDEXING' => $this->u_action . '&action=' . $this->state[1], 'L_CONTINUE' => ($this->state[1] == 'create') ? $user->lang['CONTINUE_INDEXING'] : $user->lang['CONTINUE_DELETING_INDEX'], 'L_CONTINUE_EXPLAIN' => ($this->state[1] == 'create') ? $user->lang['CONTINUE_INDEXING_EXPLAIN'] : $user->lang['CONTINUE_DELETING_INDEX_EXPLAIN']) ); } } function display_progress_bar($type) { global $template, $user; $l_type = ($type == 'create') ? 'INDEXING_IN_PROGRESS' : 'DELETING_INDEX_IN_PROGRESS'; adm_page_header($user->lang[$l_type]); $template->set_filenames(array( 'body' => 'progress_bar.html') ); $template->assign_vars(array( 'L_PROGRESS' => $user->lang[$l_type], 'L_PROGRESS_EXPLAIN' => $user->lang[$l_type . '_EXPLAIN']) ); adm_page_footer(); } function close_popup_js() { return "<script type=\"text/javascript\">\n" . "// <![CDATA[\n" . " close_waitscreen = 1;\n" . "// ]]>\n" . "</script>\n"; } function get_search_types() { global $phpbb_root_path, $phpEx, $phpbb_extension_manager; $finder = $phpbb_extension_manager->get_finder(); return $finder ->extension_suffix('_backend') ->extension_directory('/search') ->core_path('phpbb/search/') ->get_classes(); } function get_max_post_id() { global $db; $sql = 'SELECT MAX(post_id) as max_post_id FROM '. POSTS_TABLE; $result = $db->sql_query($sql); $max_post_id = (int) $db->sql_fetchfield('max_post_id'); $db->sql_freeresult($result); return $max_post_id; } function save_state($state = false) { if ($state) { $this->state = $state; } ksort($this->state); set_config('search_indexing_state', implode(',', $this->state), true); } /** * Initialises a search backend object * * @return false if no error occurred else an error message */ function init_search($type, &$search, &$error) { global $phpbb_root_path, $phpEx, $user, $auth, $config, $db, $phpbb_dispatcher; if (!class_exists($type) || !method_exists($type, 'keyword_search')) { $error = $user->lang['NO_SUCH_SEARCH_MODULE']; return $error; } $error = false; $search = new $type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher); return $error; } } acp_captcha.php000077700000010264151514745240007525 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_captcha { var $u_action; function main($id, $mode) { global $db, $user, $auth, $template; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx, $phpbb_container; $user->add_lang('acp/board'); $factory = $phpbb_container->get('captcha.factory'); $captchas = $factory->get_captcha_types(); $selected = request_var('select_captcha', $config['captcha_plugin']); $selected = (isset($captchas['available'][$selected]) || isset($captchas['unavailable'][$selected])) ? $selected : $config['captcha_plugin']; $configure = request_var('configure', false); // Oh, they are just here for the view if (isset($_GET['captcha_demo'])) { $this->deliver_demo($selected); } // Delegate if ($configure) { $config_captcha = $factory->get_instance($selected); $config_captcha->acp_page($id, $this); } else { $config_vars = array( 'enable_confirm' => array('tpl' => 'REG_ENABLE', 'default' => false), 'enable_post_confirm' => array('tpl' => 'POST_ENABLE', 'default' => false), 'confirm_refresh' => array('tpl' => 'CONFIRM_REFRESH', 'default' => false), 'max_reg_attempts' => array('tpl' => 'REG_LIMIT', 'default' => 0), 'max_login_attempts' => array('tpl' => 'MAX_LOGIN_ATTEMPTS', 'default' => 0), ); $this->tpl_name = 'acp_captcha'; $this->page_title = 'ACP_VC_SETTINGS'; $form_key = 'acp_captcha'; add_form_key($form_key); $submit = request_var('main_submit', false); if ($submit && check_form_key($form_key)) { foreach ($config_vars as $config_var => $options) { set_config($config_var, request_var($config_var, $options['default'])); } if ($selected !== $config['captcha_plugin']) { // sanity check if (isset($captchas['available'][$selected])) { $old_captcha = $factory->get_instance($config['captcha_plugin']); $old_captcha->uninstall(); set_config('captcha_plugin', $selected); $new_captcha = $factory->get_instance($config['captcha_plugin']); $new_captcha->install(); add_log('admin', 'LOG_CONFIG_VISUAL'); } else { trigger_error($user->lang['CAPTCHA_UNAVAILABLE'] . adm_back_link($this->u_action), E_USER_WARNING); } } trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action)); } else if ($submit) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } else { $captcha_select = ''; foreach ($captchas['available'] as $value => $title) { $current = ($selected !== false && $value == $selected) ? ' selected="selected"' : ''; $captcha_select .= '<option value="' . $value . '"' . $current . '>' . $user->lang($title) . '</option>'; } foreach ($captchas['unavailable'] as $value => $title) { $current = ($selected !== false && $value == $selected) ? ' selected="selected"' : ''; $captcha_select .= '<option value="' . $value . '"' . $current . ' class="disabled-option">' . $user->lang($title) . '</option>'; } $demo_captcha = $factory->get_instance($selected); foreach ($config_vars as $config_var => $options) { $template->assign_var($options['tpl'], (isset($_POST[$config_var])) ? request_var($config_var, $options['default']) : $config[$config_var]) ; } $template->assign_vars(array( 'CAPTCHA_PREVIEW_TPL' => $demo_captcha->get_demo_template($id), 'S_CAPTCHA_HAS_CONFIG' => $demo_captcha->has_config(), 'CAPTCHA_SELECT' => $captcha_select, 'U_ACTION' => $this->u_action, )); } } } /** * Entry point for delivering image CAPTCHAs in the ACP. */ function deliver_demo($selected) { global $db, $user, $config, $phpbb_container; $captcha = $phpbb_container->get('captcha.factory')->get_instance($selected); $captcha->init(CONFIRM_REG); $captcha->execute_demo(); garbage_collection(); exit_handler(); } } acp_icons.php000077700000066676151514745240007257 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } /** * @todo [smilies] check regular expressions for special char replacements (stored specialchared in db) */ class acp_icons { var $u_action; function main($id, $mode) { global $db, $user, $auth, $template, $cache; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; global $request, $phpbb_container; $user->add_lang('acp/posting'); // Set up general vars $action = request_var('action', ''); $action = (isset($_POST['add'])) ? 'add' : $action; $action = (isset($_POST['edit'])) ? 'edit' : $action; $action = (isset($_POST['import'])) ? 'import' : $action; $icon_id = request_var('id', 0); $mode = ($mode == 'smilies') ? 'smilies' : 'icons'; $this->tpl_name = 'acp_icons'; // What are we working on? switch ($mode) { case 'smilies': $table = SMILIES_TABLE; $lang = 'SMILIES'; $fields = 'smiley'; $img_path = $config['smilies_path']; break; case 'icons': $table = ICONS_TABLE; $lang = 'ICONS'; $fields = 'icons'; $img_path = $config['icons_path']; break; } $this->page_title = 'ACP_' . $lang; // Clear some arrays $_images = $_paks = array(); $notice = ''; // Grab file list of paks and images if ($action == 'edit' || $action == 'add' || $action == 'import') { $imglist = filelist($phpbb_root_path . $img_path, ''); foreach ($imglist as $path => $img_ary) { if (empty($img_ary)) { continue; } asort($img_ary, SORT_STRING); foreach ($img_ary as $img) { $img_size = getimagesize($phpbb_root_path . $img_path . '/' . $path . $img); if (!$img_size[0] || !$img_size[1] || strlen($img) > 255) { continue; } // adjust the width and height to be lower than 128px while perserving the aspect ratio (for icons) if ($mode == 'icons') { if ($img_size[0] > 127 && $img_size[0] > $img_size[1]) { $img_size[1] = (int) ($img_size[1] * (127 / $img_size[0])); $img_size[0] = 127; } else if ($img_size[1] > 127) { $img_size[0] = (int) ($img_size[0] * (127 / $img_size[1])); $img_size[1] = 127; } } $_images[$path . $img]['file'] = $path . $img; $_images[$path . $img]['width'] = $img_size[0]; $_images[$path . $img]['height'] = $img_size[1]; } } unset($imglist); if ($dir = @opendir($phpbb_root_path . $img_path)) { while (($file = readdir($dir)) !== false) { if (is_file($phpbb_root_path . $img_path . '/' . $file) && preg_match('#\.pak$#i', $file)) { $_paks[] = $file; } } closedir($dir); if (!empty($_paks)) { asort($_paks, SORT_STRING); } } } // What shall we do today? Oops, I believe that's trademarked ... switch ($action) { case 'edit': unset($_images); $_images = array(); // no break; case 'add': $smilies = $default_row = array(); $smiley_options = $order_list = $add_order_list = ''; if ($action == 'add' && $mode == 'smilies') { $sql = 'SELECT * FROM ' . SMILIES_TABLE . ' ORDER BY smiley_order'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { if (empty($smilies[$row['smiley_url']])) { $smilies[$row['smiley_url']] = $row; } } $db->sql_freeresult($result); if (sizeof($smilies)) { foreach ($smilies as $row) { $selected = false; if (!$smiley_options) { $selected = true; $default_row = $row; } $smiley_options .= '<option value="' . $row['smiley_url'] . '"' . (($selected) ? ' selected="selected"' : '') . '>' . $row['smiley_url'] . '</option>'; $template->assign_block_vars('smile', array( 'SMILEY_URL' => addslashes($row['smiley_url']), 'CODE' => addslashes($row['code']), 'EMOTION' => addslashes($row['emotion']), 'WIDTH' => $row['smiley_width'], 'HEIGHT' => $row['smiley_height'], 'ORDER' => $row['smiley_order'] + 1, )); } } } $sql = "SELECT * FROM $table ORDER BY {$fields}_order " . (($icon_id || $action == 'add') ? 'DESC' : 'ASC'); $result = $db->sql_query($sql); $data = array(); $after = false; $display = 0; $order_lists = array('', ''); $add_order_lists = array('', ''); $display_count = 0; while ($row = $db->sql_fetchrow($result)) { if ($action == 'add') { unset($_images[$row[$fields . '_url']]); } if ($row[$fields . '_id'] == $icon_id) { $after = true; $display = $row['display_on_posting']; $data[$row[$fields . '_url']] = $row; } else { if ($action == 'edit' && !$icon_id) { $data[$row[$fields . '_url']] = $row; } $selected = ''; if (!empty($after)) { $selected = ' selected="selected"'; $after = false; } if ($row['display_on_posting']) { $display_count++; } $after_txt = ($mode == 'smilies') ? $row['code'] : $row['icons_url']; $order_lists[$row['display_on_posting']] = '<option value="' . ($row[$fields . '_order'] + 1) . '"' . $selected . '>' . sprintf($user->lang['AFTER_' . $lang], ' -> ' . $after_txt) . '</option>' . $order_lists[$row['display_on_posting']]; if (!empty($default_row)) { $add_order_lists[$row['display_on_posting']] = '<option value="' . ($row[$fields . '_order'] + 1) . '"' . (($row[$fields . '_id'] == $default_row['smiley_id']) ? ' selected="selected"' : '') . '>' . sprintf($user->lang['AFTER_' . $lang], ' -> ' . $after_txt) . '</option>' . $add_order_lists[$row['display_on_posting']]; } } } $db->sql_freeresult($result); $order_list = '<option value="1"' . ((!isset($after)) ? ' selected="selected"' : '') . '>' . $user->lang['FIRST'] . '</option>'; $add_order_list = '<option value="1">' . $user->lang['FIRST'] . '</option>'; if ($action == 'add') { $data = $_images; } $colspan = (($mode == 'smilies') ? 7 : 5); $colspan += ($icon_id) ? 1 : 0; $colspan += ($action == 'add') ? 2 : 0; $template->assign_vars(array( 'S_EDIT' => true, 'S_SMILIES' => ($mode == 'smilies') ? true : false, 'S_ADD' => ($action == 'add') ? true : false, 'S_ORDER_LIST_DISPLAY' => $order_list . $order_lists[1], 'S_ORDER_LIST_UNDISPLAY' => $order_list . $order_lists[0], 'S_ORDER_LIST_DISPLAY_COUNT' => $display_count + 1, 'L_TITLE' => $user->lang['ACP_' . $lang], 'L_EXPLAIN' => $user->lang['ACP_' . $lang . '_EXPLAIN'], 'L_CONFIG' => $user->lang[$lang . '_CONFIG'], 'L_URL' => $user->lang[$lang . '_URL'], 'L_LOCATION' => $user->lang[$lang . '_LOCATION'], 'L_WIDTH' => $user->lang[$lang . '_WIDTH'], 'L_HEIGHT' => $user->lang[$lang . '_HEIGHT'], 'L_ORDER' => $user->lang[$lang . '_ORDER'], 'L_NO_ICONS' => $user->lang['NO_' . $lang . '_' . strtoupper($action)], 'COLSPAN' => $colspan, 'ID' => $icon_id, 'U_BACK' => $this->u_action, 'U_ACTION' => $this->u_action . '&action=' . (($action == 'add') ? 'create' : 'modify'), )); foreach ($data as $img => $img_row) { $template->assign_block_vars('items', array( 'IMG' => $img, 'A_IMG' => addslashes($img), 'IMG_SRC' => $phpbb_root_path . $img_path . '/' . $img, 'CODE' => ($mode == 'smilies' && isset($img_row['code'])) ? $img_row['code'] : '', 'EMOTION' => ($mode == 'smilies' && isset($img_row['emotion'])) ? $img_row['emotion'] : '', 'S_ID' => (isset($img_row[$fields . '_id'])) ? true : false, 'ID' => (isset($img_row[$fields . '_id'])) ? $img_row[$fields . '_id'] : 0, 'WIDTH' => (!empty($img_row[$fields .'_width'])) ? $img_row[$fields .'_width'] : $img_row['width'], 'HEIGHT' => (!empty($img_row[$fields .'_height'])) ? $img_row[$fields .'_height'] : $img_row['height'], 'POSTING_CHECKED' => (!empty($img_row['display_on_posting']) || $action == 'add') ? ' checked="checked"' : '', )); } // Ok, another row for adding an addition code for a pre-existing image... if ($action == 'add' && $mode == 'smilies' && sizeof($smilies)) { $template->assign_vars(array( 'S_ADD_CODE' => true, 'S_IMG_OPTIONS' => $smiley_options, 'S_ADD_ORDER_LIST_DISPLAY' => $add_order_list . $add_order_lists[1], 'S_ADD_ORDER_LIST_UNDISPLAY' => $add_order_list . $add_order_lists[0], 'IMG_SRC' => $phpbb_root_path . $img_path . '/' . $default_row['smiley_url'], 'IMG_PATH' => $img_path, 'CODE' => $default_row['code'], 'EMOTION' => $default_row['emotion'], 'WIDTH' => $default_row['smiley_width'], 'HEIGHT' => $default_row['smiley_height'], )); } return; break; case 'create': case 'modify': // Get items to create/modify $images = (isset($_POST['image'])) ? array_keys(request_var('image', array('' => 0))) : array(); // Now really get the items $image_id = (isset($_POST['id'])) ? request_var('id', array('' => 0)) : array(); $image_order = (isset($_POST['order'])) ? request_var('order', array('' => 0)) : array(); $image_width = (isset($_POST['width'])) ? request_var('width', array('' => 0)) : array(); $image_height = (isset($_POST['height'])) ? request_var('height', array('' => 0)) : array(); $image_add = (isset($_POST['add_img'])) ? request_var('add_img', array('' => 0)) : array(); $image_emotion = utf8_normalize_nfc(request_var('emotion', array('' => ''), true)); $image_code = utf8_normalize_nfc(request_var('code', array('' => ''), true)); $image_display_on_posting = (isset($_POST['display_on_posting'])) ? request_var('display_on_posting', array('' => 0)) : array(); // Ok, add the relevant bits if we are adding new codes to existing emoticons... if ($request->variable('add_additional_code', false, false, \phpbb\request\request_interface::POST)) { $add_image = request_var('add_image', ''); $add_code = utf8_normalize_nfc(request_var('add_code', '', true)); $add_emotion = utf8_normalize_nfc(request_var('add_emotion', '', true)); if ($add_image && $add_emotion && $add_code) { $images[] = $add_image; $image_add[$add_image] = true; $image_code[$add_image] = $add_code; $image_emotion[$add_image] = $add_emotion; $image_width[$add_image] = request_var('add_width', 0); $image_height[$add_image] = request_var('add_height', 0); if ($request->variable('add_display_on_posting', false, false, \phpbb\request\request_interface::POST)) { $image_display_on_posting[$add_image] = 1; } $image_order[$add_image] = request_var('add_order', 0); } } if ($mode == 'smilies' && $action == 'create') { $smiley_count = $this->item_count($table); $addable_smileys_count = sizeof($images); foreach ($images as $image) { if (!isset($image_add[$image])) { --$addable_smileys_count; } } if ($smiley_count + $addable_smileys_count > SMILEY_LIMIT) { trigger_error($user->lang('TOO_MANY_SMILIES', SMILEY_LIMIT) . adm_back_link($this->u_action), E_USER_WARNING); } } $icons_updated = 0; $errors = array(); foreach ($images as $image) { if ($mode == 'smilies' && ($image_emotion[$image] == '' || $image_code[$image] == '')) { $errors[$image] = 'SMILIE_NO_' . (($image_emotion[$image] == '') ? 'EMOTION' : 'CODE'); } else if ($action == 'create' && !isset($image_add[$image])) { // skip images where add wasn't checked } else if (!file_exists($phpbb_root_path . $img_path . '/' . $image)) { $errors[$image] = 'SMILIE_NO_FILE'; } else { if ($image_width[$image] == 0 || $image_height[$image] == 0) { $img_size = getimagesize($phpbb_root_path . $img_path . '/' . $image); $image_width[$image] = $img_size[0]; $image_height[$image] = $img_size[1]; } // Adjust image width/height for icons if ($mode == 'icons') { if ($image_width[$image] > 127 && $image_width[$image] > $image_height[$image]) { $image_height[$image] = (int) ($image_height[$image] * (127 / $image_width[$image])); $image_width[$image] = 127; } else if ($image_height[$image] > 127) { $image_width[$image] = (int) ($image_width[$image] * (127 / $image_height[$image])); $image_height[$image] = 127; } } $img_sql = array( $fields . '_url' => $image, $fields . '_width' => $image_width[$image], $fields . '_height' => $image_height[$image], 'display_on_posting' => (isset($image_display_on_posting[$image])) ? 1 : 0, ); if ($mode == 'smilies') { $img_sql = array_merge($img_sql, array( 'emotion' => $image_emotion[$image], 'code' => $image_code[$image]) ); } // Image_order holds the 'new' order value if (!empty($image_order[$image])) { $img_sql = array_merge($img_sql, array( $fields . '_order' => $image_order[$image]) ); // Since we always add 'after' an item, we just need to increase all following + the current by one $sql = "UPDATE $table SET {$fields}_order = {$fields}_order + 1 WHERE {$fields}_order >= {$image_order[$image]}"; $db->sql_query($sql); // If we adjust the order, we need to adjust all other orders too - they became inaccurate... foreach ($image_order as $_image => $_order) { if ($_image == $image) { continue; } if ($_order >= $image_order[$image]) { $image_order[$_image]++; } } } if ($action == 'modify' && !empty($image_id[$image])) { $sql = "UPDATE $table SET " . $db->sql_build_array('UPDATE', $img_sql) . " WHERE {$fields}_id = " . $image_id[$image]; $db->sql_query($sql); $icons_updated++; } else if ($action !== 'modify') { $sql = "INSERT INTO $table " . $db->sql_build_array('INSERT', $img_sql); $db->sql_query($sql); $icons_updated++; } } } $cache->destroy('_icons'); $cache->destroy('sql', $table); $level = ($icons_updated) ? E_USER_NOTICE : E_USER_WARNING; $errormsgs = ''; foreach ($errors as $img => $error) { $errormsgs .= '<br />' . sprintf($user->lang[$error], $img); } if ($action == 'modify') { trigger_error($user->lang($lang . '_EDITED', $icons_updated) . $errormsgs . adm_back_link($this->u_action), $level); } else { trigger_error($user->lang($lang . '_ADDED', $icons_updated) . $errormsgs . adm_back_link($this->u_action), $level); } break; case 'import': $pak = request_var('pak', ''); $current = request_var('current', ''); if ($pak != '') { $order = 0; if (!($pak_ary = @file($phpbb_root_path . $img_path . '/' . $pak))) { trigger_error($user->lang['PAK_FILE_NOT_READABLE'] . adm_back_link($this->u_action), E_USER_WARNING); } // Make sure the pak_ary is valid foreach ($pak_ary as $pak_entry) { if (preg_match_all("#'(.*?)', ?#", $pak_entry, $data)) { if ((sizeof($data[1]) != 4 && $mode == 'icons') || ((sizeof($data[1]) != 6 || (empty($data[1][4]) || empty($data[1][5]))) && $mode == 'smilies' )) { trigger_error($user->lang['WRONG_PAK_TYPE'] . adm_back_link($this->u_action), E_USER_WARNING); } } else { trigger_error($user->lang['WRONG_PAK_TYPE'] . adm_back_link($this->u_action), E_USER_WARNING); } } // The user has already selected a smilies_pak file if ($current == 'delete') { switch ($db->get_sql_layer()) { case 'sqlite': case 'sqlite3': $db->sql_query('DELETE FROM ' . $table); break; default: $db->sql_query('TRUNCATE TABLE ' . $table); break; } switch ($mode) { case 'smilies': break; case 'icons': // Reset all icon_ids $db->sql_query('UPDATE ' . TOPICS_TABLE . ' SET icon_id = 0'); $db->sql_query('UPDATE ' . POSTS_TABLE . ' SET icon_id = 0'); break; } } else { $cur_img = array(); $field_sql = ($mode == 'smilies') ? 'code' : 'icons_url'; $sql = "SELECT $field_sql FROM $table"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { ++$order; $cur_img[$row[$field_sql]] = 1; } $db->sql_freeresult($result); } if ($mode == 'smilies') { $smiley_count = $this->item_count($table); if ($smiley_count + sizeof($pak_ary) > SMILEY_LIMIT) { trigger_error($user->lang('TOO_MANY_SMILIES', SMILEY_LIMIT) . adm_back_link($this->u_action), E_USER_WARNING); } } foreach ($pak_ary as $pak_entry) { $data = array(); if (preg_match_all("#'(.*?)', ?#", $pak_entry, $data)) { if ((sizeof($data[1]) != 4 && $mode == 'icons') || (sizeof($data[1]) != 6 && $mode == 'smilies')) { trigger_error($user->lang['WRONG_PAK_TYPE'] . adm_back_link($this->u_action), E_USER_WARNING); } // Stripslash here because it got addslashed before... (on export) $img = stripslashes($data[1][0]); $width = stripslashes($data[1][1]); $height = stripslashes($data[1][2]); $display_on_posting = stripslashes($data[1][3]); if (isset($data[1][4]) && isset($data[1][5])) { $emotion = stripslashes($data[1][4]); $code = stripslashes($data[1][5]); } if ($current == 'replace' && (($mode == 'smilies' && !empty($cur_img[$code])) || ($mode == 'icons' && !empty($cur_img[$img])))) { $replace_sql = ($mode == 'smilies') ? $code : $img; $sql = array( $fields . '_url' => $img, $fields . '_height' => (int) $height, $fields . '_width' => (int) $width, 'display_on_posting' => (int) $display_on_posting, ); if ($mode == 'smilies') { $sql = array_merge($sql, array( 'emotion' => $emotion, )); } $sql = "UPDATE $table SET " . $db->sql_build_array('UPDATE', $sql) . " WHERE $field_sql = '" . $db->sql_escape($replace_sql) . "'"; $db->sql_query($sql); } else { ++$order; $sql = array( $fields . '_url' => $img, $fields . '_height' => (int) $height, $fields . '_width' => (int) $width, $fields . '_order' => (int) $order, 'display_on_posting'=> (int) $display_on_posting, ); if ($mode == 'smilies') { $sql = array_merge($sql, array( 'code' => $code, 'emotion' => $emotion, )); } $db->sql_query("INSERT INTO $table " . $db->sql_build_array('INSERT', $sql)); } } } $cache->destroy('_icons'); $cache->destroy('sql', $table); trigger_error($user->lang[$lang . '_IMPORT_SUCCESS'] . adm_back_link($this->u_action)); } else { $pak_options = ''; foreach ($_paks as $pak) { $pak_options .= '<option value="' . $pak . '">' . htmlspecialchars($pak) . '</option>'; } $template->assign_vars(array( 'S_CHOOSE_PAK' => true, 'S_PAK_OPTIONS' => $pak_options, 'L_TITLE' => $user->lang['ACP_' . $lang], 'L_EXPLAIN' => $user->lang['ACP_' . $lang . '_EXPLAIN'], 'L_NO_PAK_OPTIONS' => $user->lang['NO_' . $lang . '_PAK'], 'L_CURRENT' => $user->lang['CURRENT_' . $lang], 'L_CURRENT_EXPLAIN' => $user->lang['CURRENT_' . $lang . '_EXPLAIN'], 'L_IMPORT_SUBMIT' => $user->lang['IMPORT_' . $lang], 'U_BACK' => $this->u_action, 'U_ACTION' => $this->u_action . '&action=import', ) ); } break; case 'export': $this->page_title = 'EXPORT_' . $lang; $this->tpl_name = 'message_body'; $template->assign_vars(array( 'MESSAGE_TITLE' => $user->lang['EXPORT_' . $lang], 'MESSAGE_TEXT' => sprintf($user->lang['EXPORT_' . $lang . '_EXPLAIN'], '<a href="' . $this->u_action . '&action=send">', '</a>'), 'S_USER_NOTICE' => true, ) ); return; break; case 'send': $sql = "SELECT * FROM $table ORDER BY {$fields}_order"; $result = $db->sql_query($sql); $pak = ''; while ($row = $db->sql_fetchrow($result)) { $pak .= "'" . addslashes($row[$fields . '_url']) . "', "; $pak .= "'" . addslashes($row[$fields . '_width']) . "', "; $pak .= "'" . addslashes($row[$fields . '_height']) . "', "; $pak .= "'" . addslashes($row['display_on_posting']) . "', "; if ($mode == 'smilies') { $pak .= "'" . addslashes($row['emotion']) . "', "; $pak .= "'" . addslashes($row['code']) . "', "; } $pak .= "\n"; } $db->sql_freeresult($result); if ($pak != '') { garbage_collection(); header('Cache-Control: public'); // Send out the Headers header('Content-Type: text/x-delimtext; name="' . $mode . '.pak"'); header('Content-Disposition: inline; filename="' . $mode . '.pak"'); echo $pak; flush(); exit; } else { trigger_error($user->lang['NO_' . strtoupper($fields) . '_EXPORT'] . adm_back_link($this->u_action), E_USER_WARNING); } break; case 'delete': if (confirm_box(true)) { $sql = "DELETE FROM $table WHERE {$fields}_id = $icon_id"; $db->sql_query($sql); switch ($mode) { case 'smilies': break; case 'icons': // Reset appropriate icon_ids $db->sql_query('UPDATE ' . TOPICS_TABLE . " SET icon_id = 0 WHERE icon_id = $icon_id"); $db->sql_query('UPDATE ' . POSTS_TABLE . " SET icon_id = 0 WHERE icon_id = $icon_id"); break; } $notice = $user->lang[$lang . '_DELETED']; $cache->destroy('_icons'); $cache->destroy('sql', $table); if ($request->is_ajax()) { $json_response = new \phpbb\json_response; $json_response->send(array( 'MESSAGE_TITLE' => $user->lang['INFORMATION'], 'MESSAGE_TEXT' => $notice, 'REFRESH_DATA' => array( 'time' => 3 ) )); } } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 'i' => $id, 'mode' => $mode, 'id' => $icon_id, 'action' => 'delete', ))); } break; case 'move_up': case 'move_down': // Get current order id... $sql = "SELECT {$fields}_order as current_order FROM $table WHERE {$fields}_id = $icon_id"; $result = $db->sql_query($sql); $current_order = (int) $db->sql_fetchfield('current_order'); $db->sql_freeresult($result); if ($current_order == 0 && $action == 'move_up') { break; } // on move_down, switch position with next order_id... // on move_up, switch position with previous order_id... $switch_order_id = ($action == 'move_down') ? $current_order + 1 : $current_order - 1; // $sql = "UPDATE $table SET {$fields}_order = $current_order WHERE {$fields}_order = $switch_order_id AND {$fields}_id <> $icon_id"; $db->sql_query($sql); $move_executed = (bool) $db->sql_affectedrows(); // Only update the other entry too if the previous entry got updated if ($move_executed) { $sql = "UPDATE $table SET {$fields}_order = $switch_order_id WHERE {$fields}_order = $current_order AND {$fields}_id = $icon_id"; $db->sql_query($sql); } $cache->destroy('_icons'); $cache->destroy('sql', $table); if ($request->is_ajax()) { $json_response = new \phpbb\json_response; $json_response->send(array( 'success' => $move_executed, )); } break; } // By default, check that image_order is valid and fix it if necessary $sql = "SELECT {$fields}_id AS order_id, {$fields}_order AS fields_order FROM $table ORDER BY display_on_posting DESC, {$fields}_order"; $result = $db->sql_query($sql); if ($row = $db->sql_fetchrow($result)) { $order = 0; do { ++$order; if ($row['fields_order'] != $order) { $db->sql_query("UPDATE $table SET {$fields}_order = $order WHERE {$fields}_id = " . $row['order_id']); } } while ($row = $db->sql_fetchrow($result)); } $db->sql_freeresult($result); $template->assign_vars(array( 'L_TITLE' => $user->lang['ACP_' . $lang], 'L_EXPLAIN' => $user->lang['ACP_' . $lang . '_EXPLAIN'], 'L_IMPORT' => $user->lang['IMPORT_' . $lang], 'L_EXPORT' => $user->lang['EXPORT_' . $lang], 'L_NOT_DISPLAYED' => $user->lang[$lang . '_NOT_DISPLAYED'], 'L_ICON_ADD' => $user->lang['ADD_' . $lang], 'L_ICON_EDIT' => $user->lang['EDIT_' . $lang], 'NOTICE' => $notice, 'COLSPAN' => ($mode == 'smilies') ? 5 : 3, 'S_SMILIES' => ($mode == 'smilies') ? true : false, 'U_ACTION' => $this->u_action, 'U_IMPORT' => $this->u_action . '&action=import', 'U_EXPORT' => $this->u_action . '&action=export', ) ); $spacer = false; $pagination = $phpbb_container->get('pagination'); $pagination_start = request_var('start', 0); $item_count = $this->item_count($table); $sql = "SELECT * FROM $table ORDER BY {$fields}_order ASC"; $result = $db->sql_query_limit($sql, $config['smilies_per_page'], $pagination_start); while ($row = $db->sql_fetchrow($result)) { $alt_text = ($mode == 'smilies') ? $row['code'] : ''; $template->assign_block_vars('items', array( 'S_SPACER' => (!$spacer && !$row['display_on_posting']) ? true : false, 'ALT_TEXT' => $alt_text, 'IMG_SRC' => $phpbb_root_path . $img_path . '/' . $row[$fields . '_url'], 'WIDTH' => $row[$fields . '_width'], 'HEIGHT' => $row[$fields . '_height'], 'CODE' => (isset($row['code'])) ? $row['code'] : '', 'EMOTION' => (isset($row['emotion'])) ? $row['emotion'] : '', 'U_EDIT' => $this->u_action . '&action=edit&id=' . $row[$fields . '_id'], 'U_DELETE' => $this->u_action . '&action=delete&id=' . $row[$fields . '_id'], 'U_MOVE_UP' => $this->u_action . '&action=move_up&id=' . $row[$fields . '_id'] . '&start=' . $pagination_start, 'U_MOVE_DOWN' => $this->u_action . '&action=move_down&id=' . $row[$fields . '_id'] . '&start=' . $pagination_start, )); if (!$spacer && !$row['display_on_posting']) { $spacer = true; } } $db->sql_freeresult($result); $pagination->generate_template_pagination($this->u_action, 'pagination', 'start', $item_count, $config['smilies_per_page'], $pagination_start); } /** * Returns the count of smilies or icons in the database * * @param string $table The table of items to count. * @return int number of items */ /* private */ function item_count($table) { global $db; $sql = "SELECT COUNT(*) AS item_count FROM $table"; $result = $db->sql_query($sql); $item_count = (int) $db->sql_fetchfield('item_count'); $db->sql_freeresult($result); return $item_count; } } acp_extensions.php000077700000043400151514745240010317 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_extensions { var $u_action; private $db; private $config; private $template; private $user; private $cache; private $log; private $request; function main() { // Start the page global $config, $user, $template, $request, $phpbb_extension_manager, $db, $phpbb_root_path, $phpEx, $phpbb_log, $cache; $this->db = $db; $this->config = $config; $this->template = $template; $this->user = $user; $this->cache = $cache; $this->request = $request; $this->log = $phpbb_log; $user->add_lang(array('install', 'acp/extensions', 'migrator')); $this->page_title = 'ACP_EXTENSIONS'; $action = $request->variable('action', 'list'); $ext_name = $request->variable('ext_name', ''); // What is a safe limit of execution time? Half the max execution time should be safe. $safe_time_limit = (ini_get('max_execution_time') / 2); $start_time = time(); // Cancel action if ($request->is_set_post('cancel')) { $action = 'list'; $ext_name = ''; } if (in_array($action, array('enable', 'disable', 'delete_data')) && !check_link_hash($request->variable('hash', ''), $action . '.' . $ext_name)) { trigger_error('FORM_INVALID', E_USER_WARNING); } // If they've specified an extension, let's load the metadata manager and validate it. if ($ext_name) { $md_manager = new \phpbb\extension\metadata_manager($ext_name, $config, $phpbb_extension_manager, $template, $user, $phpbb_root_path); try { $md_manager->get_metadata('all'); } catch(\phpbb\extension\exception $e) { trigger_error($e, E_USER_WARNING); } } // What are we doing? switch ($action) { case 'set_config_version_check_force_unstable': $force_unstable = $this->request->variable('force_unstable', false); if ($force_unstable) { $s_hidden_fields = build_hidden_fields(array( 'force_unstable' => $force_unstable, )); confirm_box(false, $user->lang('EXTENSION_FORCE_UNSTABLE_CONFIRM'), $s_hidden_fields); } else { $config->set('extension_force_unstable', false); trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action)); } break; case 'list': default: if (confirm_box(true)) { $config->set('extension_force_unstable', true); trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action)); } $this->list_enabled_exts($phpbb_extension_manager); $this->list_disabled_exts($phpbb_extension_manager); $this->list_available_exts($phpbb_extension_manager); $this->template->assign_vars(array( 'U_VERSIONCHECK_FORCE' => $this->u_action . '&action=list&versioncheck_force=1', 'FORCE_UNSTABLE' => $config['extension_force_unstable'], 'U_ACTION' => $this->u_action, )); add_form_key('version_check_settings'); $this->tpl_name = 'acp_ext_list'; break; case 'enable_pre': if (!$md_manager->validate_dir()) { trigger_error($user->lang['EXTENSION_DIR_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } if (!$md_manager->validate_enable()) { trigger_error($user->lang['EXTENSION_NOT_AVAILABLE'] . adm_back_link($this->u_action), E_USER_WARNING); } $extension = $phpbb_extension_manager->get_extension($ext_name); if (!$extension->is_enableable()) { trigger_error($user->lang['EXTENSION_NOT_ENABLEABLE'] . adm_back_link($this->u_action), E_USER_WARNING); } if ($phpbb_extension_manager->is_enabled($ext_name)) { redirect($this->u_action); } $this->tpl_name = 'acp_ext_enable'; $template->assign_vars(array( 'PRE' => true, 'L_CONFIRM_MESSAGE' => $this->user->lang('EXTENSION_ENABLE_CONFIRM', $md_manager->get_metadata('display-name')), 'U_ENABLE' => $this->u_action . '&action=enable&ext_name=' . urlencode($ext_name) . '&hash=' . generate_link_hash('enable.' . $ext_name), )); break; case 'enable': if (!$md_manager->validate_dir()) { trigger_error($user->lang['EXTENSION_DIR_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } if (!$md_manager->validate_enable()) { trigger_error($user->lang['EXTENSION_NOT_AVAILABLE'] . adm_back_link($this->u_action), E_USER_WARNING); } $extension = $phpbb_extension_manager->get_extension($ext_name); if (!$extension->is_enableable()) { trigger_error($user->lang['EXTENSION_NOT_ENABLEABLE'] . adm_back_link($this->u_action), E_USER_WARNING); } try { while ($phpbb_extension_manager->enable_step($ext_name)) { // Are we approaching the time limit? If so we want to pause the update and continue after refreshing if ((time() - $start_time) >= $safe_time_limit) { $template->assign_var('S_NEXT_STEP', true); meta_refresh(0, $this->u_action . '&action=enable&ext_name=' . urlencode($ext_name) . '&hash=' . generate_link_hash('enable.' . $ext_name)); } } $this->log->add('admin', $user->data['user_id'], $user->ip, 'LOG_EXT_ENABLE', time(), array($ext_name)); } catch (\phpbb\db\migration\exception $e) { $template->assign_var('MIGRATOR_ERROR', $e->getLocalisedMessage($user)); } $this->tpl_name = 'acp_ext_enable'; $template->assign_vars(array( 'U_RETURN' => $this->u_action . '&action=list', )); break; case 'disable_pre': if (!$phpbb_extension_manager->is_enabled($ext_name)) { redirect($this->u_action); } $this->tpl_name = 'acp_ext_disable'; $template->assign_vars(array( 'PRE' => true, 'L_CONFIRM_MESSAGE' => $this->user->lang('EXTENSION_DISABLE_CONFIRM', $md_manager->get_metadata('display-name')), 'U_DISABLE' => $this->u_action . '&action=disable&ext_name=' . urlencode($ext_name) . '&hash=' . generate_link_hash('disable.' . $ext_name), )); break; case 'disable': if (!$phpbb_extension_manager->is_enabled($ext_name)) { redirect($this->u_action); } while ($phpbb_extension_manager->disable_step($ext_name)) { // Are we approaching the time limit? If so we want to pause the update and continue after refreshing if ((time() - $start_time) >= $safe_time_limit) { $template->assign_var('S_NEXT_STEP', true); meta_refresh(0, $this->u_action . '&action=disable&ext_name=' . urlencode($ext_name) . '&hash=' . generate_link_hash('disable.' . $ext_name)); } } $this->log->add('admin', $user->data['user_id'], $user->ip, 'LOG_EXT_DISABLE', time(), array($ext_name)); $this->tpl_name = 'acp_ext_disable'; $template->assign_vars(array( 'U_RETURN' => $this->u_action . '&action=list', )); break; case 'delete_data_pre': if ($phpbb_extension_manager->is_enabled($ext_name)) { redirect($this->u_action); } $this->tpl_name = 'acp_ext_delete_data'; $template->assign_vars(array( 'PRE' => true, 'L_CONFIRM_MESSAGE' => $this->user->lang('EXTENSION_DELETE_DATA_CONFIRM', $md_manager->get_metadata('display-name')), 'U_PURGE' => $this->u_action . '&action=delete_data&ext_name=' . urlencode($ext_name) . '&hash=' . generate_link_hash('delete_data.' . $ext_name), )); break; case 'delete_data': if ($phpbb_extension_manager->is_enabled($ext_name)) { redirect($this->u_action); } try { while ($phpbb_extension_manager->purge_step($ext_name)) { // Are we approaching the time limit? If so we want to pause the update and continue after refreshing if ((time() - $start_time) >= $safe_time_limit) { $template->assign_var('S_NEXT_STEP', true); meta_refresh(0, $this->u_action . '&action=delete_data&ext_name=' . urlencode($ext_name) . '&hash=' . generate_link_hash('delete_data.' . $ext_name)); } } $this->log->add('admin', $user->data['user_id'], $user->ip, 'LOG_EXT_PURGE', time(), array($ext_name)); } catch (\phpbb\db\migration\exception $e) { $template->assign_var('MIGRATOR_ERROR', $e->getLocalisedMessage($user)); } $this->tpl_name = 'acp_ext_delete_data'; $template->assign_vars(array( 'U_RETURN' => $this->u_action . '&action=list', )); break; case 'details': // Output it to the template $md_manager->output_template_data(); try { $updates_available = $this->version_check($md_manager, $request->variable('versioncheck_force', false)); $template->assign_vars(array( 'S_UP_TO_DATE' => empty($updates_available), 'S_VERSIONCHECK' => true, 'UP_TO_DATE_MSG' => $this->user->lang(empty($updates_available) ? 'UP_TO_DATE' : 'NOT_UP_TO_DATE', $md_manager->get_metadata('display-name')), )); foreach ($updates_available as $branch => $version_data) { $template->assign_block_vars('updates_available', $version_data); } } catch (\RuntimeException $e) { $template->assign_vars(array( 'S_VERSIONCHECK_STATUS' => $e->getCode(), 'VERSIONCHECK_FAIL_REASON' => ($e->getMessage() !== $user->lang('VERSIONCHECK_FAIL')) ? $e->getMessage() : '', )); } $template->assign_vars(array( 'U_BACK' => $this->u_action . '&action=list', 'U_VERSIONCHECK_FORCE' => $this->u_action . '&action=details&versioncheck_force=1&ext_name=' . urlencode($md_manager->get_metadata('name')), )); $this->tpl_name = 'acp_ext_details'; break; } } /** * Lists all the enabled extensions and dumps to the template * * @param $phpbb_extension_manager An instance of the extension manager * @return null */ public function list_enabled_exts(\phpbb\extension\manager $phpbb_extension_manager) { $enabled_extension_meta_data = array(); foreach ($phpbb_extension_manager->all_enabled() as $name => $location) { $md_manager = $phpbb_extension_manager->create_extension_metadata_manager($name, $this->template); try { $meta = $md_manager->get_metadata('all'); $enabled_extension_meta_data[$name] = array( 'META_DISPLAY_NAME' => $md_manager->get_metadata('display-name'), 'META_VERSION' => $meta['version'], ); $force_update = $this->request->variable('versioncheck_force', false); $updates = $this->version_check($md_manager, $force_update, !$force_update); $enabled_extension_meta_data[$name]['S_UP_TO_DATE'] = empty($updates); $enabled_extension_meta_data[$name]['S_VERSIONCHECK'] = true; $enabled_extension_meta_data[$name]['U_VERSIONCHECK_FORCE'] = $this->u_action . '&action=details&versioncheck_force=1&ext_name=' . urlencode($md_manager->get_metadata('name')); } catch(\phpbb\extension\exception $e) { $this->template->assign_block_vars('disabled', array( 'META_DISPLAY_NAME' => $this->user->lang('EXTENSION_INVALID_LIST', $name, $e), 'S_VERSIONCHECK' => false, )); } catch (\RuntimeException $e) { $enabled_extension_meta_data[$name]['S_VERSIONCHECK'] = false; } } uasort($enabled_extension_meta_data, array($this, 'sort_extension_meta_data_table')); foreach ($enabled_extension_meta_data as $name => $block_vars) { $block_vars['U_DETAILS'] = $this->u_action . '&action=details&ext_name=' . urlencode($name); $this->template->assign_block_vars('enabled', $block_vars); $this->output_actions('enabled', array( 'DISABLE' => $this->u_action . '&action=disable_pre&ext_name=' . urlencode($name), )); } } /** * Lists all the disabled extensions and dumps to the template * * @param $phpbb_extension_manager An instance of the extension manager * @return null */ public function list_disabled_exts(\phpbb\extension\manager $phpbb_extension_manager) { $disabled_extension_meta_data = array(); foreach ($phpbb_extension_manager->all_disabled() as $name => $location) { $md_manager = $phpbb_extension_manager->create_extension_metadata_manager($name, $this->template); try { $meta = $md_manager->get_metadata('all'); $disabled_extension_meta_data[$name] = array( 'META_DISPLAY_NAME' => $md_manager->get_metadata('display-name'), 'META_VERSION' => $meta['version'], ); $force_update = $this->request->variable('versioncheck_force', false); $updates = $this->version_check($md_manager, $force_update, !$force_update); $disabled_extension_meta_data[$name]['S_UP_TO_DATE'] = empty($updates); $disabled_extension_meta_data[$name]['S_VERSIONCHECK'] = true; $disabled_extension_meta_data[$name]['U_VERSIONCHECK_FORCE'] = $this->u_action . '&action=details&versioncheck_force=1&ext_name=' . urlencode($md_manager->get_metadata('name')); } catch(\phpbb\extension\exception $e) { $this->template->assign_block_vars('disabled', array( 'META_DISPLAY_NAME' => $this->user->lang('EXTENSION_INVALID_LIST', $name, $e), 'S_VERSIONCHECK' => false, )); } catch (\RuntimeException $e) { $disabeld_extension_meta_data[$name]['S_VERSIONCHECK'] = false; } } uasort($disabled_extension_meta_data, array($this, 'sort_extension_meta_data_table')); foreach ($disabled_extension_meta_data as $name => $block_vars) { $block_vars['U_DETAILS'] = $this->u_action . '&action=details&ext_name=' . urlencode($name); $this->template->assign_block_vars('disabled', $block_vars); $this->output_actions('disabled', array( 'ENABLE' => $this->u_action . '&action=enable_pre&ext_name=' . urlencode($name), 'DELETE_DATA' => $this->u_action . '&action=delete_data_pre&ext_name=' . urlencode($name), )); } } /** * Lists all the available extensions and dumps to the template * * @param $phpbb_extension_manager An instance of the extension manager * @return null */ public function list_available_exts(\phpbb\extension\manager $phpbb_extension_manager) { $uninstalled = array_diff_key($phpbb_extension_manager->all_available(), $phpbb_extension_manager->all_configured()); $available_extension_meta_data = array(); foreach ($uninstalled as $name => $location) { $md_manager = $phpbb_extension_manager->create_extension_metadata_manager($name, $this->template); try { $meta = $md_manager->get_metadata('all'); $available_extension_meta_data[$name] = array( 'META_DISPLAY_NAME' => $md_manager->get_metadata('display-name'), 'META_VERSION' => $meta['version'], ); $force_update = $this->request->variable('versioncheck_force', false); $updates = $this->version_check($md_manager, $force_update, !$force_update); $available_extension_meta_data[$name]['S_UP_TO_DATE'] = empty($updates); $available_extension_meta_data[$name]['S_VERSIONCHECK'] = true; $available_extension_meta_data[$name]['U_VERSIONCHECK_FORCE'] = $this->u_action . '&action=details&versioncheck_force=1&ext_name=' . urlencode($md_manager->get_metadata('name')); } catch(\phpbb\extension\exception $e) { $this->template->assign_block_vars('disabled', array( 'META_DISPLAY_NAME' => $this->user->lang('EXTENSION_INVALID_LIST', $name, $e), 'S_VERSIONCHECK' => false, )); } catch (\RuntimeException $e) { $available_extension_meta_data[$name]['S_VERSIONCHECK'] = false; } } uasort($available_extension_meta_data, array($this, 'sort_extension_meta_data_table')); foreach ($available_extension_meta_data as $name => $block_vars) { $block_vars['U_DETAILS'] = $this->u_action . '&action=details&ext_name=' . urlencode($name); $this->template->assign_block_vars('disabled', $block_vars); $this->output_actions('disabled', array( 'ENABLE' => $this->u_action . '&action=enable_pre&ext_name=' . urlencode($name), )); } } /** * Output actions to a block * * @param string $block * @param array $actions */ private function output_actions($block, $actions) { foreach ($actions as $lang => $url) { $this->template->assign_block_vars($block . '.actions', array( 'L_ACTION' => $this->user->lang('EXTENSION_' . $lang), 'L_ACTION_EXPLAIN' => (isset($this->user->lang['EXTENSION_' . $lang . '_EXPLAIN'])) ? $this->user->lang('EXTENSION_' . $lang . '_EXPLAIN') : '', 'U_ACTION' => $url, )); } } /** * Check the version and return the available updates. * * @param \phpbb\extension\metadata_manager $md_manager The metadata manager for the version to check. * @param bool $force_update Ignores cached data. Defaults to false. * @param bool $force_cache Force the use of the cache. Override $force_update. * @return string * @throws RuntimeException */ protected function version_check(\phpbb\extension\metadata_manager $md_manager, $force_update = false, $force_cache = false) { $meta = $md_manager->get_metadata('all'); if (!isset($meta['extra']['version-check'])) { throw new \RuntimeException($this->user->lang('NO_VERSIONCHECK'), 1); } $version_check = $meta['extra']['version-check']; $version_helper = new \phpbb\version_helper($this->cache, $this->config, new \phpbb\file_downloader(), $this->user); $version_helper->set_current_version($meta['version']); $version_helper->set_file_location($version_check['host'], $version_check['directory'], $version_check['filename']); $version_helper->force_stability($this->config['extension_force_unstable'] ? 'unstable' : null); return $updates = $version_helper->get_suggested_updates($force_update, $force_cache); } /** * Sort helper for the table containing the metadata about the extensions. */ protected function sort_extension_meta_data_table($val1, $val2) { return strnatcasecmp($val1['META_DISPLAY_NAME'], $val2['META_DISPLAY_NAME']); } } acp_language.php000077700000033243151514745240007707 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_language { var $u_action; var $main_files; var $language_header = ''; var $lang_header = ''; var $language_file = ''; var $language_directory = ''; function main($id, $mode) { global $config, $db, $user, $template; global $phpbb_root_path, $phpEx, $request; include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx); // Check and set some common vars $action = (isset($_POST['update_details'])) ? 'update_details' : ''; $action = (isset($_POST['remove_store'])) ? 'details' : $action; $submit = (empty($action) && !isset($_POST['update']) && !isset($_POST['test_connection'])) ? false : true; $action = (empty($action)) ? request_var('action', '') : $action; $form_name = 'acp_lang'; add_form_key('acp_lang'); $lang_id = request_var('id', 0); $selected_lang_file = request_var('language_file', '|common.' . $phpEx); list($this->language_directory, $this->language_file) = explode('|', $selected_lang_file); $this->language_directory = basename($this->language_directory); $this->language_file = basename($this->language_file); $user->add_lang('acp/language'); $this->tpl_name = 'acp_language'; $this->page_title = 'ACP_LANGUAGE_PACKS'; switch ($action) { case 'update_details': if (!$submit || !check_form_key($form_name)) { trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING); } if (!$lang_id) { trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING); } $sql = 'SELECT * FROM ' . LANG_TABLE . " WHERE lang_id = $lang_id"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); $sql_ary = array( 'lang_english_name' => request_var('lang_english_name', $row['lang_english_name']), 'lang_local_name' => utf8_normalize_nfc(request_var('lang_local_name', $row['lang_local_name'], true)), 'lang_author' => utf8_normalize_nfc(request_var('lang_author', $row['lang_author'], true)), ); $db->sql_query('UPDATE ' . LANG_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE lang_id = ' . $lang_id); add_log('admin', 'LOG_LANGUAGE_PACK_UPDATED', $sql_ary['lang_english_name']); trigger_error($user->lang['LANGUAGE_DETAILS_UPDATED'] . adm_back_link($this->u_action)); break; case 'details': if (!$lang_id) { trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING); } $this->page_title = 'LANGUAGE_PACK_DETAILS'; $sql = 'SELECT * FROM ' . LANG_TABLE . ' WHERE lang_id = ' . $lang_id; $result = $db->sql_query($sql); $lang_entries = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$lang_entries) { trigger_error($user->lang['LANGUAGE_PACK_NOT_EXIST'] . adm_back_link($this->u_action), E_USER_WARNING); } $lang_iso = $lang_entries['lang_iso']; $template->assign_vars(array( 'S_DETAILS' => true, 'U_ACTION' => $this->u_action . "&action=details&id=$lang_id", 'U_BACK' => $this->u_action, 'LANG_LOCAL_NAME' => $lang_entries['lang_local_name'], 'LANG_ENGLISH_NAME' => $lang_entries['lang_english_name'], 'LANG_ISO' => $lang_iso, 'LANG_AUTHOR' => $lang_entries['lang_author'], 'L_MISSING_FILES' => $user->lang('THOSE_MISSING_LANG_FILES', $lang_entries['lang_local_name']), 'L_MISSING_VARS_EXPLAIN' => $user->lang('THOSE_MISSING_LANG_VARIABLES', $lang_entries['lang_local_name']), )); // If current lang is different from the default lang, then highlight missing files and variables if ($lang_iso != $config['default_lang']) { try { $iterator = new \RecursiveIteratorIterator( new \phpbb\recursive_dot_prefix_filter_iterator( new \RecursiveDirectoryIterator( $phpbb_root_path . 'language/' . $config['default_lang'] . '/', \FilesystemIterator::SKIP_DOTS ) ), \RecursiveIteratorIterator::LEAVES_ONLY ); } catch (\Exception $e) { return array(); } foreach ($iterator as $file_info) { /** @var \RecursiveDirectoryIterator $file_info */ $relative_path = $iterator->getInnerIterator()->getSubPathname(); $relative_path = str_replace(DIRECTORY_SEPARATOR, '/', $relative_path); if (file_exists($phpbb_root_path . 'language/' . $lang_iso . '/' . $relative_path)) { if (substr($relative_path, 0 - strlen($phpEx)) === $phpEx) { $missing_vars = $this->compare_language_files($config['default_lang'], $lang_iso, $relative_path); if (!empty($missing_vars)) { $template->assign_block_vars('missing_varfile', array( 'FILE_NAME' => $relative_path, )); foreach ($missing_vars as $var) { $template->assign_block_vars('missing_varfile.variable', array( 'VAR_NAME' => $var, )); } } } } else { $template->assign_block_vars('missing_files', array( 'FILE_NAME' => $relative_path, )); } } } return; break; case 'delete': if (!$lang_id) { trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING); } $sql = 'SELECT * FROM ' . LANG_TABLE . ' WHERE lang_id = ' . $lang_id; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($row['lang_iso'] == $config['default_lang']) { trigger_error($user->lang['NO_REMOVE_DEFAULT_LANG'] . adm_back_link($this->u_action), E_USER_WARNING); } if (confirm_box(true)) { $db->sql_query('DELETE FROM ' . LANG_TABLE . ' WHERE lang_id = ' . $lang_id); $sql = 'UPDATE ' . USERS_TABLE . " SET user_lang = '" . $db->sql_escape($config['default_lang']) . "' WHERE user_lang = '" . $db->sql_escape($row['lang_iso']) . "'"; $db->sql_query($sql); // We also need to remove the translated entries for custom profile fields - we want clean tables, don't we? $sql = 'DELETE FROM ' . PROFILE_LANG_TABLE . ' WHERE lang_id = ' . $lang_id; $db->sql_query($sql); $sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . ' WHERE lang_id = ' . $lang_id; $db->sql_query($sql); add_log('admin', 'LOG_LANGUAGE_PACK_DELETED', $row['lang_english_name']); trigger_error(sprintf($user->lang['LANGUAGE_PACK_DELETED'], $row['lang_english_name']) . adm_back_link($this->u_action)); } else { $s_hidden_fields = array( 'i' => $id, 'mode' => $mode, 'action' => $action, 'id' => $lang_id, ); confirm_box(false, $user->lang('DELETE_LANGUAGE_CONFIRM', $row['lang_english_name']), build_hidden_fields($s_hidden_fields)); } break; case 'install': $lang_iso = request_var('iso', ''); $lang_iso = basename($lang_iso); if (!$lang_iso || !file_exists("{$phpbb_root_path}language/$lang_iso/iso.txt")) { trigger_error($user->lang['LANGUAGE_PACK_NOT_EXIST'] . adm_back_link($this->u_action), E_USER_WARNING); } $file = file("{$phpbb_root_path}language/$lang_iso/iso.txt"); $lang_pack = array( 'iso' => $lang_iso, 'name' => trim(htmlspecialchars($file[0])), 'local_name'=> trim(htmlspecialchars($file[1], ENT_COMPAT, 'UTF-8')), 'author' => trim(htmlspecialchars($file[2], ENT_COMPAT, 'UTF-8')) ); unset($file); $sql = 'SELECT lang_iso FROM ' . LANG_TABLE . " WHERE lang_iso = '" . $db->sql_escape($lang_iso) . "'"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($row) { trigger_error($user->lang['LANGUAGE_PACK_ALREADY_INSTALLED'] . adm_back_link($this->u_action), E_USER_WARNING); } if (!$lang_pack['name'] || !$lang_pack['local_name']) { trigger_error($user->lang['INVALID_LANGUAGE_PACK'] . adm_back_link($this->u_action), E_USER_WARNING); } // Add language pack $sql_ary = array( 'lang_iso' => $lang_pack['iso'], 'lang_dir' => $lang_pack['iso'], 'lang_english_name' => $lang_pack['name'], 'lang_local_name' => $lang_pack['local_name'], 'lang_author' => $lang_pack['author'] ); $db->sql_query('INSERT INTO ' . LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); $lang_id = $db->sql_nextid(); // Now let's copy the default language entries for custom profile fields for this new language - makes admin's life easier. $sql = 'SELECT lang_id FROM ' . LANG_TABLE . " WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'"; $result = $db->sql_query($sql); $default_lang_id = (int) $db->sql_fetchfield('lang_id'); $db->sql_freeresult($result); // We want to notify the admin that custom profile fields need to be updated for the new language. $notify_cpf_update = false; // From the mysql documentation: // Prior to MySQL 4.0.14, the target table of the INSERT statement cannot appear in the FROM clause of the SELECT part of the query. This limitation is lifted in 4.0.14. // Due to this we stay on the safe side if we do the insertion "the manual way" $sql = 'SELECT field_id, lang_name, lang_explain, lang_default_value FROM ' . PROFILE_LANG_TABLE . ' WHERE lang_id = ' . $default_lang_id; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $row['lang_id'] = $lang_id; $db->sql_query('INSERT INTO ' . PROFILE_LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $row)); $notify_cpf_update = true; } $db->sql_freeresult($result); $sql = 'SELECT field_id, option_id, field_type, lang_value FROM ' . PROFILE_FIELDS_LANG_TABLE . ' WHERE lang_id = ' . $default_lang_id; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $row['lang_id'] = $lang_id; $db->sql_query('INSERT INTO ' . PROFILE_FIELDS_LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $row)); $notify_cpf_update = true; } $db->sql_freeresult($result); add_log('admin', 'LOG_LANGUAGE_PACK_INSTALLED', $lang_pack['name']); $message = sprintf($user->lang['LANGUAGE_PACK_INSTALLED'], $lang_pack['name']); $message .= ($notify_cpf_update) ? '<br /><br />' . $user->lang['LANGUAGE_PACK_CPF_UPDATE'] : ''; trigger_error($message . adm_back_link($this->u_action)); break; } $sql = 'SELECT user_lang, COUNT(user_lang) AS lang_count FROM ' . USERS_TABLE . ' GROUP BY user_lang'; $result = $db->sql_query($sql); $lang_count = array(); while ($row = $db->sql_fetchrow($result)) { $lang_count[$row['user_lang']] = $row['lang_count']; } $db->sql_freeresult($result); $sql = 'SELECT * FROM ' . LANG_TABLE . ' ORDER BY lang_english_name'; $result = $db->sql_query($sql); $installed = array(); while ($row = $db->sql_fetchrow($result)) { $installed[] = $row['lang_iso']; $tagstyle = ($row['lang_iso'] == $config['default_lang']) ? '*' : ''; $template->assign_block_vars('lang', array( 'U_DETAILS' => $this->u_action . "&action=details&id={$row['lang_id']}", 'U_DOWNLOAD' => $this->u_action . "&action=download&id={$row['lang_id']}", 'U_DELETE' => $this->u_action . "&action=delete&id={$row['lang_id']}", 'ENGLISH_NAME' => $row['lang_english_name'], 'TAG' => $tagstyle, 'LOCAL_NAME' => $row['lang_local_name'], 'ISO' => $row['lang_iso'], 'USED_BY' => (isset($lang_count[$row['lang_iso']])) ? $lang_count[$row['lang_iso']] : 0, )); } $db->sql_freeresult($result); $new_ary = $iso = array(); $dp = @opendir("{$phpbb_root_path}language"); if ($dp) { while (($file = readdir($dp)) !== false) { if ($file[0] == '.' || !is_dir($phpbb_root_path . 'language/' . $file)) { continue; } if (file_exists("{$phpbb_root_path}language/$file/iso.txt")) { if (!in_array($file, $installed)) { if ($iso = file("{$phpbb_root_path}language/$file/iso.txt")) { if (sizeof($iso) == 3) { $new_ary[$file] = array( 'iso' => $file, 'name' => trim($iso[0]), 'local_name'=> trim($iso[1]), 'author' => trim($iso[2]) ); } } } } } closedir($dp); } unset($installed); if (sizeof($new_ary)) { foreach ($new_ary as $iso => $lang_ary) { $template->assign_block_vars('notinst', array( 'ISO' => htmlspecialchars($lang_ary['iso']), 'LOCAL_NAME' => htmlspecialchars($lang_ary['local_name'], ENT_COMPAT, 'UTF-8'), 'NAME' => htmlspecialchars($lang_ary['name'], ENT_COMPAT, 'UTF-8'), 'U_INSTALL' => $this->u_action . '&action=install&iso=' . urlencode($lang_ary['iso'])) ); } } unset($new_ary); } /** * Compare two language files */ function compare_language_files($source_lang, $dest_lang, $file) { global $phpbb_root_path; $source_file = $phpbb_root_path . 'language/' . $source_lang . '/' . $file; $dest_file = $phpbb_root_path . 'language/' . $dest_lang . '/' . $file; if (!file_exists($dest_file)) { return array(); } $lang = array(); include($source_file); $lang_entry_src = $lang; $lang = array(); include($dest_file); $lang_entry_dst = $lang; unset($lang); return array_diff(array_keys($lang_entry_src), array_keys($lang_entry_dst)); } } acp_php_info.php000077700000005037151514745240007726 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_php_info { var $u_action; function main($id, $mode) { global $db, $user, $auth, $template; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; if ($mode != 'info') { trigger_error('NO_MODE', E_USER_ERROR); } $this->tpl_name = 'acp_php_info'; $this->page_title = 'ACP_PHP_INFO'; ob_start(); phpinfo(INFO_GENERAL | INFO_CONFIGURATION | INFO_MODULES | INFO_VARIABLES); $phpinfo = ob_get_clean(); $phpinfo = trim($phpinfo); // Here we play around a little with the PHP Info HTML to try and stylise // it along phpBB's lines ... hopefully without breaking anything. The idea // for this was nabbed from the PHP annotated manual preg_match_all('#<body[^>]*>(.*)</body>#si', $phpinfo, $output); if (empty($phpinfo) || empty($output[1][0])) { trigger_error('NO_PHPINFO_AVAILABLE', E_USER_WARNING); } $output = $output[1][0]; // expose_php can make the image not exist if (preg_match('#<a[^>]*><img[^>]*></a>#', $output)) { $output = preg_replace('#<tr class="v"><td>(.*?<a[^>]*><img[^>]*></a>)(.*?)</td></tr>#s', '<tr class="row1"><td><table class="type2"><tr><td>\2</td><td>\1</td></tr></table></td></tr>', $output); } else { $output = preg_replace('#<tr class="v"><td>(.*?)</td></tr>#s', '<tr class="row1"><td><table class="type2"><tr><td>\1</td></tr></table></td></tr>', $output); } $output = preg_replace('#<table[^>]+>#i', '<table>', $output); $output = preg_replace('#<img border="0"#i', '<img', $output); $output = str_replace(array('class="e"', 'class="v"', 'class="h"', '<hr />', '<font', '</font>'), array('class="row1"', 'class="row2"', '', '', '<span', '</span>'), $output); // Fix invalid anchor names (eg "module_Zend Optimizer") $output = preg_replace_callback('#<a name="([^"]+)">#', array($this, 'remove_spaces'), $output); if (empty($output)) { trigger_error('NO_PHPINFO_AVAILABLE', E_USER_WARNING); } $orig_output = $output; preg_match_all('#<div class="center">(.*)</div>#siU', $output, $output); $output = (!empty($output[1][0])) ? $output[1][0] : $orig_output; $template->assign_var('PHPINFO', $output); } function remove_spaces($matches) { return '<a name="' . str_replace(' ', '_', $matches[1]) . '">'; } } acp_attachments.php000077700000156701151514745240010444 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_attachments { /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var \phpbb\config\config */ protected $config; /** @var ContainerBuilder */ protected $phpbb_container; /** @var \phpbb\template\template */ protected $template; /** @var \phpbb\user */ protected $user; public $id; public $u_action; protected $new_config; function main($id, $mode) { global $db, $user, $auth, $template, $cache, $phpbb_container; global $config, $phpbb_admin_path, $phpbb_root_path, $phpEx; $this->id = $id; $this->db = $db; $this->config = $config; $this->template = $template; $this->user = $user; $this->phpbb_container = $phpbb_container; $user->add_lang(array('posting', 'viewtopic', 'acp/attachments')); $error = $notify = array(); $submit = (isset($_POST['submit'])) ? true : false; $action = request_var('action', ''); $form_key = 'acp_attach'; add_form_key($form_key); if ($submit && !check_form_key($form_key)) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } switch ($mode) { case 'attach': $l_title = 'ACP_ATTACHMENT_SETTINGS'; break; case 'extensions': $l_title = 'ACP_MANAGE_EXTENSIONS'; break; case 'ext_groups': $l_title = 'ACP_EXTENSION_GROUPS'; break; case 'orphan': $l_title = 'ACP_ORPHAN_ATTACHMENTS'; break; case 'manage': $l_title = 'ACP_MANAGE_ATTACHMENTS'; break; default: trigger_error('NO_MODE', E_USER_ERROR); break; } $this->tpl_name = 'acp_attachments'; $this->page_title = $l_title; $template->assign_vars(array( 'L_TITLE' => $user->lang[$l_title], 'L_TITLE_EXPLAIN' => $user->lang[$l_title . '_EXPLAIN'], 'U_ACTION' => $this->u_action) ); switch ($mode) { case 'attach': include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx); $sql = 'SELECT group_name, cat_id FROM ' . EXTENSION_GROUPS_TABLE . ' WHERE cat_id > 0 ORDER BY cat_id'; $result = $db->sql_query($sql); $s_assigned_groups = array(); while ($row = $db->sql_fetchrow($result)) { $row['group_name'] = (isset($user->lang['EXT_GROUP_' . $row['group_name']])) ? $user->lang['EXT_GROUP_' . $row['group_name']] : $row['group_name']; $s_assigned_groups[$row['cat_id']][] = $row['group_name']; } $db->sql_freeresult($result); $l_legend_cat_images = $user->lang['SETTINGS_CAT_IMAGES'] . ' [' . $user->lang['ASSIGNED_GROUP'] . ': ' . ((!empty($s_assigned_groups[ATTACHMENT_CATEGORY_IMAGE])) ? implode($user->lang['COMMA_SEPARATOR'], $s_assigned_groups[ATTACHMENT_CATEGORY_IMAGE]) : $user->lang['NO_EXT_GROUP']) . ']'; $display_vars = array( 'title' => 'ACP_ATTACHMENT_SETTINGS', 'vars' => array( 'legend1' => 'ACP_ATTACHMENT_SETTINGS', 'img_max_width' => array('lang' => 'MAX_IMAGE_SIZE', 'validate' => 'int:0', 'type' => false, 'method' => false, 'explain' => false,), 'img_max_height' => array('lang' => 'MAX_IMAGE_SIZE', 'validate' => 'int:0', 'type' => false, 'method' => false, 'explain' => false,), 'img_link_width' => array('lang' => 'IMAGE_LINK_SIZE', 'validate' => 'int:0', 'type' => false, 'method' => false, 'explain' => false,), 'img_link_height' => array('lang' => 'IMAGE_LINK_SIZE', 'validate' => 'int:0', 'type' => false, 'method' => false, 'explain' => false,), 'allow_attachments' => array('lang' => 'ALLOW_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_pm_attach' => array('lang' => 'ALLOW_PM_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'upload_path' => array('lang' => 'UPLOAD_DIR', 'validate' => 'wpath', 'type' => 'text:25:100', 'explain' => true), 'display_order' => array('lang' => 'DISPLAY_ORDER', 'validate' => 'bool', 'type' => 'custom', 'method' => 'display_order', 'explain' => true), 'attachment_quota' => array('lang' => 'ATTACH_QUOTA', 'validate' => 'string', 'type' => 'custom', 'method' => 'max_filesize', 'explain' => true), 'max_filesize' => array('lang' => 'ATTACH_MAX_FILESIZE', 'validate' => 'string', 'type' => 'custom', 'method' => 'max_filesize', 'explain' => true), 'max_filesize_pm' => array('lang' => 'ATTACH_MAX_PM_FILESIZE','validate' => 'string', 'type' => 'custom', 'method' => 'max_filesize', 'explain' => true), 'max_attachments' => array('lang' => 'MAX_ATTACHMENTS', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => false), 'max_attachments_pm' => array('lang' => 'MAX_ATTACHMENTS_PM', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => false), 'secure_downloads' => array('lang' => 'SECURE_DOWNLOADS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'secure_allow_deny' => array('lang' => 'SECURE_ALLOW_DENY', 'validate' => 'int', 'type' => 'custom', 'method' => 'select_allow_deny', 'explain' => true), 'secure_allow_empty_referer' => array('lang' => 'SECURE_EMPTY_REFERRER', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'check_attachment_content' => array('lang' => 'CHECK_CONTENT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'legend2' => $l_legend_cat_images, 'img_display_inlined' => array('lang' => 'DISPLAY_INLINED', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'img_create_thumbnail' => array('lang' => 'CREATE_THUMBNAIL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'img_max_thumb_width' => array('lang' => 'MAX_THUMB_WIDTH', 'validate' => 'int:0:999999999999999', 'type' => 'number:0:999999999999999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'img_min_thumb_filesize' => array('lang' => 'MIN_THUMB_FILESIZE', 'validate' => 'int:0:999999999999999', 'type' => 'number:0:999999999999999', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']), 'img_imagick' => array('lang' => 'IMAGICK_PATH', 'validate' => 'absolute_path', 'type' => 'text:20:200', 'explain' => true, 'append' => ' <span>[ <a href="' . $this->u_action . '&action=imgmagick">' . $user->lang['SEARCH_IMAGICK'] . '</a> ]</span>'), 'img_max' => array('lang' => 'MAX_IMAGE_SIZE', 'validate' => 'int:0:9999', 'type' => 'dimension:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), 'img_link' => array('lang' => 'IMAGE_LINK_SIZE', 'validate' => 'int:0:9999', 'type' => 'dimension:0:9999', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']), ) ); $this->new_config = $config; $cfg_array = (isset($_REQUEST['config'])) ? request_var('config', array('' => '')) : $this->new_config; $error = array(); // We validate the complete config if whished validate_config_vars($display_vars['vars'], $cfg_array, $error); // Do not write values if there is an error if (sizeof($error)) { $submit = false; } // We go through the display_vars to make sure no one is trying to set variables he/she is not allowed to... foreach ($display_vars['vars'] as $config_name => $null) { if (!isset($cfg_array[$config_name]) || strpos($config_name, 'legend') !== false) { continue; } $this->new_config[$config_name] = $config_value = $cfg_array[$config_name]; if (in_array($config_name, array('attachment_quota', 'max_filesize', 'max_filesize_pm'))) { $size_var = request_var($config_name, ''); $this->new_config[$config_name] = $config_value = ($size_var == 'kb') ? round($config_value * 1024) : (($size_var == 'mb') ? round($config_value * 1048576) : $config_value); } if ($submit) { set_config($config_name, $config_value); } } $this->perform_site_list(); if ($submit) { add_log('admin', 'LOG_CONFIG_ATTACH'); // Check Settings $this->test_upload($error, $this->new_config['upload_path'], false); if (!sizeof($error)) { trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action)); } } $template->assign_var('S_ATTACHMENT_SETTINGS', true); if ($action == 'imgmagick') { $this->new_config['img_imagick'] = $this->search_imagemagick(); } // We strip eventually manual added convert program, we only want the patch if ($this->new_config['img_imagick']) { // Change path separator $this->new_config['img_imagick'] = str_replace('\\', '/', $this->new_config['img_imagick']); $this->new_config['img_imagick'] = str_replace(array('convert', '.exe'), array('', ''), $this->new_config['img_imagick']); // Check for trailing slash if (substr($this->new_config['img_imagick'], -1) !== '/') { $this->new_config['img_imagick'] .= '/'; } } $supported_types = get_supported_image_types(); // Check Thumbnail Support if (!$this->new_config['img_imagick'] && (!isset($supported_types['format']) || !sizeof($supported_types['format']))) { $this->new_config['img_create_thumbnail'] = 0; } $template->assign_vars(array( 'U_SEARCH_IMAGICK' => $this->u_action . '&action=imgmagick', 'S_THUMBNAIL_SUPPORT' => (!$this->new_config['img_imagick'] && (!isset($supported_types['format']) || !sizeof($supported_types['format']))) ? false : true) ); // Secure Download Options - Same procedure as with banning $allow_deny = ($this->new_config['secure_allow_deny']) ? 'ALLOWED' : 'DISALLOWED'; $sql = 'SELECT * FROM ' . SITELIST_TABLE; $result = $db->sql_query($sql); $defined_ips = ''; $ips = array(); while ($row = $db->sql_fetchrow($result)) { $value = ($row['site_ip']) ? $row['site_ip'] : $row['site_hostname']; if ($value) { $defined_ips .= '<option' . (($row['ip_exclude']) ? ' class="sep"' : '') . ' value="' . $row['site_id'] . '">' . $value . '</option>'; $ips[$row['site_id']] = $value; } } $db->sql_freeresult($result); $template->assign_vars(array( 'S_SECURE_DOWNLOADS' => $this->new_config['secure_downloads'], 'S_DEFINED_IPS' => ($defined_ips != '') ? true : false, 'S_WARNING' => (sizeof($error)) ? true : false, 'WARNING_MSG' => implode('<br />', $error), 'DEFINED_IPS' => $defined_ips, 'L_SECURE_TITLE' => $user->lang['DEFINE_' . $allow_deny . '_IPS'], 'L_IP_EXCLUDE' => $user->lang['EXCLUDE_FROM_' . $allow_deny . '_IP'], 'L_REMOVE_IPS' => $user->lang['REMOVE_' . $allow_deny . '_IPS']) ); // Output relevant options foreach ($display_vars['vars'] as $config_key => $vars) { if (!is_array($vars) && strpos($config_key, 'legend') === false) { continue; } if (strpos($config_key, 'legend') !== false) { $template->assign_block_vars('options', array( 'S_LEGEND' => true, 'LEGEND' => (isset($user->lang[$vars])) ? $user->lang[$vars] : $vars) ); continue; } $type = explode(':', $vars['type']); $l_explain = ''; if ($vars['explain'] && isset($vars['lang_explain'])) { $l_explain = (isset($user->lang[$vars['lang_explain']])) ? $user->lang[$vars['lang_explain']] : $vars['lang_explain']; } else if ($vars['explain']) { $l_explain = (isset($user->lang[$vars['lang'] . '_EXPLAIN'])) ? $user->lang[$vars['lang'] . '_EXPLAIN'] : ''; } $content = build_cfg_template($type, $config_key, $this->new_config, $config_key, $vars); if (empty($content)) { continue; } $template->assign_block_vars('options', array( 'KEY' => $config_key, 'TITLE' => $user->lang[$vars['lang']], 'S_EXPLAIN' => $vars['explain'], 'TITLE_EXPLAIN' => $l_explain, 'CONTENT' => $content, ) ); unset($display_vars['vars'][$config_key]); } break; case 'extensions': if ($submit || isset($_POST['add_extension_check'])) { if ($submit) { // Change Extensions ? $extension_change_list = request_var('extension_change_list', array(0)); $group_select_list = request_var('group_select', array(0)); // Generate correct Change List $extensions = array(); for ($i = 0, $size = sizeof($extension_change_list); $i < $size; $i++) { $extensions[$extension_change_list[$i]]['group_id'] = $group_select_list[$i]; } $sql = 'SELECT * FROM ' . EXTENSIONS_TABLE . ' ORDER BY extension_id'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { if ($row['group_id'] != $extensions[$row['extension_id']]['group_id']) { $sql = 'UPDATE ' . EXTENSIONS_TABLE . ' SET group_id = ' . (int) $extensions[$row['extension_id']]['group_id'] . ' WHERE extension_id = ' . $row['extension_id']; $db->sql_query($sql); add_log('admin', 'LOG_ATTACH_EXT_UPDATE', $row['extension']); } } $db->sql_freeresult($result); // Delete Extension? $extension_id_list = request_var('extension_id_list', array(0)); if (sizeof($extension_id_list)) { $sql = 'SELECT extension FROM ' . EXTENSIONS_TABLE . ' WHERE ' . $db->sql_in_set('extension_id', $extension_id_list); $result = $db->sql_query($sql); $extension_list = ''; while ($row = $db->sql_fetchrow($result)) { $extension_list .= ($extension_list == '') ? $row['extension'] : ', ' . $row['extension']; } $db->sql_freeresult($result); $sql = 'DELETE FROM ' . EXTENSIONS_TABLE . ' WHERE ' . $db->sql_in_set('extension_id', $extension_id_list); $db->sql_query($sql); add_log('admin', 'LOG_ATTACH_EXT_DEL', $extension_list); } } // Add Extension? $add_extension = strtolower(request_var('add_extension', '')); $add_extension_group = request_var('add_group_select', 0); $add = (isset($_POST['add_extension_check'])) ? true : false; if ($add_extension && $add) { if (!sizeof($error)) { $sql = 'SELECT extension_id FROM ' . EXTENSIONS_TABLE . " WHERE extension = '" . $db->sql_escape($add_extension) . "'"; $result = $db->sql_query($sql); if ($row = $db->sql_fetchrow($result)) { $error[] = sprintf($user->lang['EXTENSION_EXIST'], $add_extension); } $db->sql_freeresult($result); if (!sizeof($error)) { $sql_ary = array( 'group_id' => $add_extension_group, 'extension' => $add_extension ); $db->sql_query('INSERT INTO ' . EXTENSIONS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); add_log('admin', 'LOG_ATTACH_EXT_ADD', $add_extension); } } } if (!sizeof($error)) { $notify[] = $user->lang['EXTENSIONS_UPDATED']; } $cache->destroy('_extensions'); } $template->assign_vars(array( 'S_EXTENSIONS' => true, 'ADD_EXTENSION' => (isset($add_extension)) ? $add_extension : '', 'GROUP_SELECT_OPTIONS' => (isset($_POST['add_extension_check'])) ? $this->group_select('add_group_select', $add_extension_group, 'extension_group') : $this->group_select('add_group_select', false, 'extension_group')) ); $sql = 'SELECT * FROM ' . EXTENSIONS_TABLE . ' ORDER BY group_id, extension'; $result = $db->sql_query($sql); if ($row = $db->sql_fetchrow($result)) { $old_group_id = $row['group_id']; do { $s_spacer = false; $current_group_id = $row['group_id']; if ($old_group_id != $current_group_id) { $s_spacer = true; $old_group_id = $current_group_id; } $template->assign_block_vars('extensions', array( 'S_SPACER' => $s_spacer, 'EXTENSION_ID' => $row['extension_id'], 'EXTENSION' => $row['extension'], 'GROUP_OPTIONS' => $this->group_select('group_select[]', $row['group_id'])) ); } while ($row = $db->sql_fetchrow($result)); } $db->sql_freeresult($result); break; case 'ext_groups': $template->assign_var('S_EXTENSION_GROUPS', true); if ($submit) { $action = request_var('action', ''); $group_id = request_var('g', 0); if ($action != 'add' && $action != 'edit') { trigger_error('NO_MODE', E_USER_ERROR); } if (!$group_id && $action == 'edit') { trigger_error($user->lang['NO_EXT_GROUP_SPECIFIED'] . adm_back_link($this->u_action), E_USER_WARNING); } if ($group_id) { $sql = 'SELECT * FROM ' . EXTENSION_GROUPS_TABLE . " WHERE group_id = $group_id"; $result = $db->sql_query($sql); $ext_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$ext_row) { trigger_error($user->lang['NO_EXT_GROUP_SPECIFIED'] . adm_back_link($this->u_action), E_USER_WARNING); } } else { $ext_row = array(); } $group_name = utf8_normalize_nfc(request_var('group_name', '', true)); $new_group_name = ($action == 'add') ? $group_name : (($ext_row['group_name'] != $group_name) ? $group_name : ''); if (!$group_name) { $error[] = $user->lang['NO_EXT_GROUP_NAME']; } // Check New Group Name if ($new_group_name) { $sql = 'SELECT group_id FROM ' . EXTENSION_GROUPS_TABLE . " WHERE LOWER(group_name) = '" . $db->sql_escape(utf8_strtolower($new_group_name)) . "'"; if ($group_id) { $sql .= ' AND group_id <> ' . $group_id; } $result = $db->sql_query($sql); if ($db->sql_fetchrow($result)) { $error[] = sprintf($user->lang['EXTENSION_GROUP_EXIST'], $new_group_name); } $db->sql_freeresult($result); } if (!sizeof($error)) { // Ok, build the update/insert array $upload_icon = request_var('upload_icon', 'no_image'); $size_select = request_var('size_select', 'b'); $forum_select = request_var('forum_select', false); $allowed_forums = request_var('allowed_forums', array(0)); $allow_in_pm = (isset($_POST['allow_in_pm'])) ? true : false; $max_filesize = request_var('max_filesize', 0); $max_filesize = ($size_select == 'kb') ? round($max_filesize * 1024) : (($size_select == 'mb') ? round($max_filesize * 1048576) : $max_filesize); $allow_group = (isset($_POST['allow_group'])) ? true : false; if ($max_filesize == $config['max_filesize']) { $max_filesize = 0; } if (!sizeof($allowed_forums)) { $forum_select = false; } $group_ary = array( 'group_name' => $group_name, 'cat_id' => request_var('special_category', ATTACHMENT_CATEGORY_NONE), 'allow_group' => ($allow_group) ? 1 : 0, 'upload_icon' => ($upload_icon == 'no_image') ? '' : $upload_icon, 'max_filesize' => $max_filesize, 'allowed_forums'=> ($forum_select) ? serialize($allowed_forums) : '', 'allow_in_pm' => ($allow_in_pm) ? 1 : 0, ); if ($action == 'add') { $group_ary['download_mode'] = INLINE_LINK; } $sql = ($action == 'add') ? 'INSERT INTO ' . EXTENSION_GROUPS_TABLE . ' ' : 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' SET '; $sql .= $db->sql_build_array((($action == 'add') ? 'INSERT' : 'UPDATE'), $group_ary); $sql .= ($action == 'edit') ? " WHERE group_id = $group_id" : ''; $db->sql_query($sql); if ($action == 'add') { $group_id = $db->sql_nextid(); } $group_name = (isset($user->lang['EXT_GROUP_' . $group_name])) ? $user->lang['EXT_GROUP_' . $group_name] : $group_name; add_log('admin', 'LOG_ATTACH_EXTGROUP_' . strtoupper($action), $group_name); } $extension_list = request_var('extensions', array(0)); if ($action == 'edit' && sizeof($extension_list)) { $sql = 'UPDATE ' . EXTENSIONS_TABLE . " SET group_id = 0 WHERE group_id = $group_id"; $db->sql_query($sql); } if (sizeof($extension_list)) { $sql = 'UPDATE ' . EXTENSIONS_TABLE . " SET group_id = $group_id WHERE " . $db->sql_in_set('extension_id', $extension_list); $db->sql_query($sql); } $cache->destroy('_extensions'); if (!sizeof($error)) { $notify[] = $user->lang['SUCCESS_EXTENSION_GROUP_' . strtoupper($action)]; } } $cat_lang = array( ATTACHMENT_CATEGORY_NONE => $user->lang['NO_FILE_CAT'], ATTACHMENT_CATEGORY_IMAGE => $user->lang['CAT_IMAGES'], ATTACHMENT_CATEGORY_WM => $user->lang['CAT_WM_FILES'], ATTACHMENT_CATEGORY_RM => $user->lang['CAT_RM_FILES'], ATTACHMENT_CATEGORY_FLASH => $user->lang['CAT_FLASH_FILES'], ATTACHMENT_CATEGORY_QUICKTIME => $user->lang['CAT_QUICKTIME_FILES'], ); $group_id = request_var('g', 0); $action = (isset($_POST['add'])) ? 'add' : $action; switch ($action) { case 'delete': if (confirm_box(true)) { $sql = 'SELECT group_name FROM ' . EXTENSION_GROUPS_TABLE . " WHERE group_id = $group_id"; $result = $db->sql_query($sql); $group_name = (string) $db->sql_fetchfield('group_name'); $db->sql_freeresult($result); $sql = 'DELETE FROM ' . EXTENSION_GROUPS_TABLE . " WHERE group_id = $group_id"; $db->sql_query($sql); // Set corresponding Extensions to a pending Group $sql = 'UPDATE ' . EXTENSIONS_TABLE . " SET group_id = 0 WHERE group_id = $group_id"; $db->sql_query($sql); add_log('admin', 'LOG_ATTACH_EXTGROUP_DEL', $group_name); $cache->destroy('_extensions'); trigger_error($user->lang['EXTENSION_GROUP_DELETED'] . adm_back_link($this->u_action)); } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 'i' => $id, 'mode' => $mode, 'group_id' => $group_id, 'action' => 'delete', ))); } break; case 'edit': if (!$group_id) { trigger_error($user->lang['NO_EXT_GROUP_SPECIFIED'] . adm_back_link($this->u_action), E_USER_WARNING); } $sql = 'SELECT * FROM ' . EXTENSION_GROUPS_TABLE . " WHERE group_id = $group_id"; $result = $db->sql_query($sql); $ext_group_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); $forum_ids = (!$ext_group_row['allowed_forums']) ? array() : unserialize(trim($ext_group_row['allowed_forums'])); // no break; case 'add': if ($action == 'add') { $ext_group_row = array( 'group_name' => utf8_normalize_nfc(request_var('group_name', '', true)), 'cat_id' => 0, 'allow_group' => 1, 'allow_in_pm' => 1, 'upload_icon' => '', 'max_filesize' => 0, ); $forum_ids = array(); } $extensions = array(); $sql = 'SELECT * FROM ' . EXTENSIONS_TABLE . " WHERE group_id = $group_id OR group_id = 0 ORDER BY extension"; $result = $db->sql_query($sql); $extensions = $db->sql_fetchrowset($result); $db->sql_freeresult($result); if ($ext_group_row['max_filesize'] == 0) { $ext_group_row['max_filesize'] = (int) $config['max_filesize']; } $max_filesize = get_formatted_filesize($ext_group_row['max_filesize'], false, array('mb', 'kb', 'b')); $size_format = $max_filesize['si_identifier']; $ext_group_row['max_filesize'] = $max_filesize['value']; $img_path = $config['upload_icons_path']; $filename_list = ''; $no_image_select = false; $imglist = filelist($phpbb_root_path . $img_path); if (!empty($imglist[''])) { $imglist = array_values($imglist); $imglist = $imglist[0]; foreach ($imglist as $key => $img) { if (!$ext_group_row['upload_icon']) { $no_image_select = true; $selected = ''; } else { $selected = ($ext_group_row['upload_icon'] == $img) ? ' selected="selected"' : ''; } if (strlen($img) > 255) { continue; } $filename_list .= '<option value="' . htmlspecialchars($img) . '"' . $selected . '>' . htmlspecialchars($img) . '</option>'; } } $i = 0; $assigned_extensions = ''; foreach ($extensions as $num => $row) { if ($row['group_id'] == $group_id && $group_id) { $assigned_extensions .= ($i) ? ', ' . $row['extension'] : $row['extension']; $i++; } } $s_extension_options = ''; foreach ($extensions as $row) { $s_extension_options .= '<option' . ((!$row['group_id']) ? ' class="disabled"' : '') . ' value="' . $row['extension_id'] . '"' . (($row['group_id'] == $group_id && $group_id) ? ' selected="selected"' : '') . '>' . $row['extension'] . '</option>'; } $template->assign_vars(array( 'IMG_PATH' => $img_path, 'ACTION' => $action, 'GROUP_ID' => $group_id, 'GROUP_NAME' => $ext_group_row['group_name'], 'ALLOW_GROUP' => $ext_group_row['allow_group'], 'ALLOW_IN_PM' => $ext_group_row['allow_in_pm'], 'UPLOAD_ICON_SRC' => $phpbb_root_path . $img_path . '/' . $ext_group_row['upload_icon'], 'EXTGROUP_FILESIZE' => $ext_group_row['max_filesize'], 'ASSIGNED_EXTENSIONS' => $assigned_extensions, 'S_CATEGORY_SELECT' => $this->category_select('special_category', $group_id, 'category'), 'S_EXT_GROUP_SIZE_OPTIONS' => size_select_options($size_format), 'S_EXTENSION_OPTIONS' => $s_extension_options, 'S_FILENAME_LIST' => $filename_list, 'S_EDIT_GROUP' => true, 'S_NO_IMAGE' => $no_image_select, 'S_FORUM_IDS' => (sizeof($forum_ids)) ? true : false, 'U_EXTENSIONS' => append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&mode=extensions"), 'U_BACK' => $this->u_action, 'L_LEGEND' => $user->lang[strtoupper($action) . '_EXTENSION_GROUP']) ); $s_forum_id_options = ''; /** @todo use in-built function **/ $sql = 'SELECT forum_id, forum_name, parent_id, forum_type, left_id, right_id FROM ' . FORUMS_TABLE . ' ORDER BY left_id ASC'; $result = $db->sql_query($sql, 600); $right = $cat_right = $padding_inc = 0; $padding = $forum_list = $holding = ''; $padding_store = array('0' => ''); while ($row = $db->sql_fetchrow($result)) { if ($row['forum_type'] == FORUM_CAT && ($row['left_id'] + 1 == $row['right_id'])) { // Non-postable forum with no subforums, don't display continue; } if (!$auth->acl_get('f_list', $row['forum_id'])) { // if the user does not have permissions to list this forum skip continue; } if ($row['left_id'] < $right) { $padding .= ' '; $padding_store[$row['parent_id']] = $padding; } else if ($row['left_id'] > $right + 1) { $padding = empty($padding_store[$row['parent_id']]) ? '' : $padding_store[$row['parent_id']]; } $right = $row['right_id']; $selected = (in_array($row['forum_id'], $forum_ids)) ? ' selected="selected"' : ''; if ($row['left_id'] > $cat_right) { // make sure we don't forget anything $s_forum_id_options .= $holding; $holding = ''; } if ($row['right_id'] - $row['left_id'] > 1) { $cat_right = max($cat_right, $row['right_id']); $holding .= '<option value="' . $row['forum_id'] . '"' . (($row['forum_type'] == FORUM_POST) ? ' class="sep"' : '') . $selected . '>' . $padding . $row['forum_name'] . '</option>'; } else { $s_forum_id_options .= $holding . '<option value="' . $row['forum_id'] . '"' . (($row['forum_type'] == FORUM_POST) ? ' class="sep"' : '') . $selected . '>' . $padding . $row['forum_name'] . '</option>'; $holding = ''; } } if ($holding) { $s_forum_id_options .= $holding; } $db->sql_freeresult($result); unset($padding_store); $template->assign_vars(array( 'S_FORUM_ID_OPTIONS' => $s_forum_id_options) ); break; } $sql = 'SELECT * FROM ' . EXTENSION_GROUPS_TABLE . ' ORDER BY allow_group DESC, allow_in_pm DESC, group_name'; $result = $db->sql_query($sql); $old_allow_group = $old_allow_pm = 1; while ($row = $db->sql_fetchrow($result)) { $s_add_spacer = ($old_allow_group != $row['allow_group'] || $old_allow_pm != $row['allow_in_pm']) ? true : false; $template->assign_block_vars('groups', array( 'S_ADD_SPACER' => $s_add_spacer, 'S_ALLOWED_IN_PM' => ($row['allow_in_pm']) ? true : false, 'S_GROUP_ALLOWED' => ($row['allow_group']) ? true : false, 'U_EDIT' => $this->u_action . "&action=edit&g={$row['group_id']}", 'U_DELETE' => $this->u_action . "&action=delete&g={$row['group_id']}", 'GROUP_NAME' => (isset($user->lang['EXT_GROUP_' . $row['group_name']])) ? $user->lang['EXT_GROUP_' . $row['group_name']] : $row['group_name'], 'CATEGORY' => $cat_lang[$row['cat_id']], ) ); $old_allow_group = $row['allow_group']; $old_allow_pm = $row['allow_in_pm']; } $db->sql_freeresult($result); break; case 'orphan': if ($submit) { $delete_files = (isset($_POST['delete'])) ? array_keys(request_var('delete', array('' => 0))) : array(); $add_files = (isset($_POST['add'])) ? array_keys(request_var('add', array('' => 0))) : array(); $post_ids = request_var('post_id', array('' => 0)); if (sizeof($delete_files)) { $sql = 'SELECT * FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('attach_id', $delete_files) . ' AND is_orphan = 1'; $result = $db->sql_query($sql); $delete_files = array(); while ($row = $db->sql_fetchrow($result)) { phpbb_unlink($row['physical_filename'], 'file'); if ($row['thumbnail']) { phpbb_unlink($row['physical_filename'], 'thumbnail'); } $delete_files[$row['attach_id']] = $row['real_filename']; } $db->sql_freeresult($result); } if (sizeof($delete_files)) { $sql = 'DELETE FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('attach_id', array_keys($delete_files)); $db->sql_query($sql); add_log('admin', 'LOG_ATTACH_ORPHAN_DEL', implode(', ', $delete_files)); $notify[] = sprintf($user->lang['LOG_ATTACH_ORPHAN_DEL'], implode($user->lang['COMMA_SEPARATOR'], $delete_files)); } $upload_list = array(); foreach ($add_files as $attach_id) { if (!isset($delete_files[$attach_id]) && !empty($post_ids[$attach_id])) { $upload_list[$attach_id] = $post_ids[$attach_id]; } } unset($add_files); if (sizeof($upload_list)) { $template->assign_var('S_UPLOADING_FILES', true); $sql = 'SELECT forum_id, forum_name FROM ' . FORUMS_TABLE; $result = $db->sql_query($sql); $forum_names = array(); while ($row = $db->sql_fetchrow($result)) { $forum_names[$row['forum_id']] = $row['forum_name']; } $db->sql_freeresult($result); $sql = 'SELECT forum_id, topic_id, post_id, poster_id FROM ' . POSTS_TABLE . ' WHERE ' . $db->sql_in_set('post_id', $upload_list); $result = $db->sql_query($sql); $post_info = array(); while ($row = $db->sql_fetchrow($result)) { $post_info[$row['post_id']] = $row; } $db->sql_freeresult($result); // Select those attachments we want to change... $sql = 'SELECT * FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('attach_id', array_keys($upload_list)) . ' AND is_orphan = 1'; $result = $db->sql_query($sql); $files_added = $space_taken = 0; while ($row = $db->sql_fetchrow($result)) { $post_row = $post_info[$upload_list[$row['attach_id']]]; $template->assign_block_vars('upload', array( 'FILE_INFO' => sprintf($user->lang['UPLOADING_FILE_TO'], $row['real_filename'], $post_row['post_id']), 'S_DENIED' => (!$auth->acl_get('f_attach', $post_row['forum_id'])) ? true : false, 'L_DENIED' => (!$auth->acl_get('f_attach', $post_row['forum_id'])) ? sprintf($user->lang['UPLOAD_DENIED_FORUM'], $forum_names[$row['forum_id']]) : '') ); if (!$auth->acl_get('f_attach', $post_row['forum_id'])) { continue; } // Adjust attachment entry $sql_ary = array( 'in_message' => 0, 'is_orphan' => 0, 'poster_id' => $post_row['poster_id'], 'post_msg_id' => $post_row['post_id'], 'topic_id' => $post_row['topic_id'], ); $sql = 'UPDATE ' . ATTACHMENTS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE attach_id = ' . $row['attach_id']; $db->sql_query($sql); $sql = 'UPDATE ' . POSTS_TABLE . ' SET post_attachment = 1 WHERE post_id = ' . $post_row['post_id']; $db->sql_query($sql); $sql = 'UPDATE ' . TOPICS_TABLE . ' SET topic_attachment = 1 WHERE topic_id = ' . $post_row['topic_id']; $db->sql_query($sql); $space_taken += $row['filesize']; $files_added++; add_log('admin', 'LOG_ATTACH_FILEUPLOAD', $post_row['post_id'], $row['real_filename']); } $db->sql_freeresult($result); if ($files_added) { set_config_count('upload_dir_size', $space_taken, true); set_config_count('num_files', $files_added, true); } } } $template->assign_vars(array( 'S_ORPHAN' => true) ); // Just get the files with is_orphan set and older than 3 hours $sql = 'SELECT * FROM ' . ATTACHMENTS_TABLE . ' WHERE is_orphan = 1 AND filetime < ' . (time() - 3*60*60) . ' ORDER BY filetime DESC'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $template->assign_block_vars('orphan', array( 'FILESIZE' => get_formatted_filesize($row['filesize']), 'FILETIME' => $user->format_date($row['filetime']), 'REAL_FILENAME' => utf8_basename($row['real_filename']), 'PHYSICAL_FILENAME' => utf8_basename($row['physical_filename']), 'ATTACH_ID' => $row['attach_id'], 'POST_IDS' => (!empty($post_ids[$row['attach_id']])) ? $post_ids[$row['attach_id']] : '', 'U_FILE' => append_sid($phpbb_root_path . 'download/file.' . $phpEx, 'mode=view&id=' . $row['attach_id'])) ); } $db->sql_freeresult($result); break; case 'manage': if ($submit) { $delete_files = (isset($_POST['delete'])) ? array_keys(request_var('delete', array('' => 0))) : array(); if (sizeof($delete_files)) { // Select those attachments we want to delete... $sql = 'SELECT real_filename FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('attach_id', $delete_files) . ' AND is_orphan = 0'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $deleted_filenames[] = $row['real_filename']; } $db->sql_freeresult($result); if ($num_deleted = delete_attachments('attach', $delete_files)) { if (sizeof($delete_files) != $num_deleted) { $error[] = $user->lang['FILES_GONE']; } add_log('admin', 'LOG_ATTACHMENTS_DELETED', implode(', ', $deleted_filenames)); $notify[] = sprintf($user->lang['LOG_ATTACHMENTS_DELETED'], implode($user->lang['COMMA_SEPARATOR'], $deleted_filenames)); } else { $error[] = $user->lang['NO_FILES_TO_DELETE']; } } } if ($action == 'stats') { $this->handle_stats_resync(); } $stats_error = $this->check_stats_accuracy(); if ($stats_error) { $error[] = $stats_error; } $template->assign_vars(array( 'S_MANAGE' => true, )); $start = request_var('start', 0); // Sort keys $sort_days = request_var('st', 0); $sort_key = request_var('sk', 't'); $sort_dir = request_var('sd', 'd'); // Sorting $limit_days = array(0 => $user->lang['ALL_ENTRIES'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']); $sort_by_text = array('f' => $user->lang['FILENAME'], 't' => $user->lang['FILEDATE'], 's' => $user->lang['FILESIZE'], 'x' => $user->lang['EXTENSION'], 'd' => $user->lang['DOWNLOADS'],'p' => $user->lang['ATTACH_POST_TYPE'], 'u' => $user->lang['AUTHOR']); $sort_by_sql = array('f' => 'a.real_filename', 't' => 'a.filetime', 's' => 'a.filesize', 'x' => 'a.extension', 'd' => 'a.download_count', 'p' => 'a.in_message', 'u' => 'u.username'); $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); $min_filetime = ($sort_days) ? (time() - ($sort_days * 86400)) : ''; $limit_filetime = ($min_filetime) ? " AND a.filetime >= $min_filetime " : ''; $start = ($sort_days && isset($_POST['sort'])) ? 0 : $start; $attachments_per_page = (int) $config['topics_per_page']; $stats = $this->get_attachment_stats($limit_filetime); $num_files = $stats['num_files']; $total_size = $stats['upload_dir_size']; // Make sure $start is set to the last page if it exceeds the amount $pagination = $phpbb_container->get('pagination'); $start = $pagination->validate_start($start, $attachments_per_page, $num_files); // If the user is trying to reach the second half of the attachments list, fetch it starting from the end $store_reverse = false; $sql_limit = $attachments_per_page; if ($start > $num_files / 2) { $store_reverse = true; // Select the sort order. Add time sort anchor for non-time sorting cases $sql_sort_anchor = ($sort_key != 't') ? ', a.filetime ' . (($sort_dir == 'd') ? 'ASC' : 'DESC') : ''; $sql_sort_order = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'ASC' : 'DESC') . $sql_sort_anchor; $sql_limit = $pagination->reverse_limit($start, $sql_limit, $num_files); $sql_start = $pagination->reverse_start($start, $sql_limit, $num_files); } else { // Select the sort order. Add time sort anchor for non-time sorting cases $sql_sort_anchor = ($sort_key != 't') ? ', a.filetime ' . (($sort_dir == 'd') ? 'DESC' : 'ASC') : ''; $sql_sort_order = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC') . $sql_sort_anchor; $sql_start = $start; } $attachments_list = array(); // Just get the files $sql = 'SELECT a.*, u.username, u.user_colour, t.topic_title FROM ' . ATTACHMENTS_TABLE . ' a LEFT JOIN ' . USERS_TABLE . ' u ON (u.user_id = a.poster_id) LEFT JOIN ' . TOPICS_TABLE . " t ON (a.topic_id = t.topic_id) WHERE a.is_orphan = 0 $limit_filetime ORDER BY $sql_sort_order"; $result = $db->sql_query_limit($sql, $sql_limit, $sql_start); $i = ($store_reverse) ? $sql_limit - 1 : 0; // Store increment value in a variable to save some conditional calls $i_increment = ($store_reverse) ? -1 : 1; while ($attachment_row = $db->sql_fetchrow($result)) { $attachments_list[$i] = $attachment_row; $i = $i + $i_increment; } $db->sql_freeresult($result); $base_url = $this->u_action . "&$u_sort_param"; $pagination->generate_template_pagination($base_url, 'pagination', 'start', $num_files, $attachments_per_page, $start); $template->assign_vars(array( 'TOTAL_FILES' => $num_files, 'TOTAL_SIZE' => get_formatted_filesize($total_size), 'S_LIMIT_DAYS' => $s_limit_days, 'S_SORT_KEY' => $s_sort_key, 'S_SORT_DIR' => $s_sort_dir) ); // Grab extensions $extensions = $cache->obtain_attach_extensions(true); for ($i = 0, $end = sizeof($attachments_list); $i < $end; ++$i) { $row = $attachments_list[$i]; $row['extension'] = strtolower(trim((string) $row['extension'])); $comment = ($row['attach_comment'] && !$row['in_message']) ? str_replace(array("\n", "\r"), array('<br />', "\n"), $row['attach_comment']) : ''; $display_cat = $extensions[$row['extension']]['display_cat']; $l_downloaded_viewed = ($display_cat == ATTACHMENT_CATEGORY_NONE) ? 'DOWNLOAD_COUNTS' : 'VIEWED_COUNTS'; $template->assign_block_vars('attachments', array( 'ATTACHMENT_POSTER' => get_username_string('full', (int) $row['poster_id'], (string) $row['username'], (string) $row['user_colour'], (string) $row['username']), 'FILESIZE' => get_formatted_filesize((int) $row['filesize']), 'FILETIME' => $user->format_date((int) $row['filetime']), 'REAL_FILENAME' => (!$row['in_message']) ? utf8_basename((string) $row['real_filename']) : '', 'PHYSICAL_FILENAME' => utf8_basename((string) $row['physical_filename']), 'EXT_GROUP_NAME' => (!empty($extensions[$row['extension']]['group_name'])) ? $user->lang['EXT_GROUP_' . $extensions[$row['extension']]['group_name']] : '', 'COMMENT' => $comment, 'TOPIC_TITLE' => (!$row['in_message']) ? (string) $row['topic_title'] : '', 'ATTACH_ID' => (int) $row['attach_id'], 'POST_ID' => (int) $row['post_msg_id'], 'TOPIC_ID' => (int) $row['topic_id'], 'POST_IDS' => (!empty($post_ids[$row['attach_id']])) ? (int) $post_ids[$row['attach_id']] : '', 'L_DOWNLOAD_COUNT' => $user->lang($l_downloaded_viewed, (int) $row['download_count']), 'S_IN_MESSAGE' => (bool) $row['in_message'], 'U_VIEW_TOPIC' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", "t={$row['topic_id']}&p={$row['post_msg_id']}") . "#p{$row['post_msg_id']}", 'U_FILE' => append_sid($phpbb_root_path . 'download/file.' . $phpEx, 'mode=view&id=' . $row['attach_id'])) ); } break; } if (sizeof($error)) { $template->assign_vars(array( 'S_WARNING' => true, 'WARNING_MSG' => implode('<br />', $error)) ); } if (sizeof($notify)) { $template->assign_vars(array( 'S_NOTIFY' => true, 'NOTIFY_MSG' => implode('<br />', $notify)) ); } } /** * Get attachment file count and size of upload directory * * @param $limit string Additional limit for WHERE clause to filter stats by. * @return array Returns array with stats: num_files and upload_dir_size */ public function get_attachment_stats($limit = '') { $sql = 'SELECT COUNT(a.attach_id) AS num_files, SUM(a.filesize) AS upload_dir_size FROM ' . ATTACHMENTS_TABLE . " a WHERE a.is_orphan = 0 $limit"; $result = $this->db->sql_query($sql); $row = $this->db->sql_fetchrow($result); $this->db->sql_freeresult($result); return array( 'num_files' => (int) $row['num_files'], 'upload_dir_size' => (float) $row['upload_dir_size'], ); } /** * Set config attachment stat values * * @param $stats array Array of config key => value pairs to set. * @return null */ public function set_attachment_stats($stats) { foreach ($stats as $key => $value) { $this->config->set($key, $value, true); } } /** * Check accuracy of attachment statistics. * * @return bool|string Returns false if stats are correct or error message * otherwise. */ public function check_stats_accuracy() { // Get fresh stats. $stats = $this->get_attachment_stats(); // Get current files stats $num_files = (int) $this->config['num_files']; $total_size = (float) $this->config['upload_dir_size']; if (($num_files != $stats['num_files']) || ($total_size != $stats['upload_dir_size'])) { $u_resync = $this->u_action . '&action=stats'; return $this->user->lang( 'FILES_STATS_WRONG', (int) $stats['num_files'], get_formatted_filesize($stats['upload_dir_size']), '<a href="' . $u_resync . '">', '</a>' ); } return false; } /** * Handle stats resync. * * @return null */ public function handle_stats_resync() { if (!confirm_box(true)) { confirm_box(false, $this->user->lang['RESYNC_FILES_STATS_CONFIRM'], build_hidden_fields(array( 'i' => $this->id, 'mode' => 'manage', 'action' => 'stats', ))); } else { $this->set_attachment_stats($this->get_attachment_stats()); $log = $this->phpbb_container->get('log'); $log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_RESYNC_FILES_STATS'); } } /** * Build Select for category items */ function category_select($select_name, $group_id = false, $key = '') { global $db, $user; $types = array( ATTACHMENT_CATEGORY_NONE => $user->lang['NO_FILE_CAT'], ATTACHMENT_CATEGORY_IMAGE => $user->lang['CAT_IMAGES'], ATTACHMENT_CATEGORY_WM => $user->lang['CAT_WM_FILES'], ATTACHMENT_CATEGORY_RM => $user->lang['CAT_RM_FILES'], ATTACHMENT_CATEGORY_FLASH => $user->lang['CAT_FLASH_FILES'], ATTACHMENT_CATEGORY_QUICKTIME => $user->lang['CAT_QUICKTIME_FILES'], ); if ($group_id) { $sql = 'SELECT cat_id FROM ' . EXTENSION_GROUPS_TABLE . ' WHERE group_id = ' . (int) $group_id; $result = $db->sql_query($sql); $cat_type = (!($row = $db->sql_fetchrow($result))) ? ATTACHMENT_CATEGORY_NONE : $row['cat_id']; $db->sql_freeresult($result); } else { $cat_type = ATTACHMENT_CATEGORY_NONE; } $group_select = '<select name="' . $select_name . '"' . (($key) ? ' id="' . $key . '"' : '') . '>'; foreach ($types as $type => $mode) { $selected = ($type == $cat_type) ? ' selected="selected"' : ''; $group_select .= '<option value="' . $type . '"' . $selected . '>' . $mode . '</option>'; } $group_select .= '</select>'; return $group_select; } /** * Extension group select */ function group_select($select_name, $default_group = false, $key = '') { global $db, $user; $group_select = '<select name="' . $select_name . '"' . (($key) ? ' id="' . $key . '"' : '') . '>'; $sql = 'SELECT group_id, group_name FROM ' . EXTENSION_GROUPS_TABLE . ' ORDER BY group_name'; $result = $db->sql_query($sql); $group_name = array(); while ($row = $db->sql_fetchrow($result)) { $row['group_name'] = (isset($user->lang['EXT_GROUP_' . $row['group_name']])) ? $user->lang['EXT_GROUP_' . $row['group_name']] : $row['group_name']; $group_name[] = $row; } $db->sql_freeresult($result); $row['group_id'] = 0; $row['group_name'] = $user->lang['NOT_ASSIGNED']; $group_name[] = $row; for ($i = 0; $i < sizeof($group_name); $i++) { if ($default_group === false) { $selected = ($i == 0) ? ' selected="selected"' : ''; } else { $selected = ($group_name[$i]['group_id'] == $default_group) ? ' selected="selected"' : ''; } $group_select .= '<option value="' . $group_name[$i]['group_id'] . '"' . $selected . '>' . $group_name[$i]['group_name'] . '</option>'; } $group_select .= '</select>'; return $group_select; } /** * Search Imagick */ function search_imagemagick() { $imagick = ''; $exe = ((defined('PHP_OS')) && (preg_match('#^win#i', PHP_OS))) ? '.exe' : ''; $magic_home = getenv('MAGICK_HOME'); if (empty($magic_home)) { $locations = array('C:/WINDOWS/', 'C:/WINNT/', 'C:/WINDOWS/SYSTEM/', 'C:/WINNT/SYSTEM/', 'C:/WINDOWS/SYSTEM32/', 'C:/WINNT/SYSTEM32/', '/usr/bin/', '/usr/sbin/', '/usr/local/bin/', '/usr/local/sbin/', '/opt/', '/usr/imagemagick/', '/usr/bin/imagemagick/'); $path_locations = str_replace('\\', '/', (explode(($exe) ? ';' : ':', getenv('PATH')))); $locations = array_merge($path_locations, $locations); foreach ($locations as $location) { // The path might not end properly, fudge it if (substr($location, -1) !== '/') { $location .= '/'; } if (@file_exists($location) && @is_readable($location . 'mogrify' . $exe) && @filesize($location . 'mogrify' . $exe) > 3000) { $imagick = str_replace('\\', '/', $location); continue; } } } else { $imagick = str_replace('\\', '/', $magic_home); } return $imagick; } /** * Test Settings */ function test_upload(&$error, $upload_dir, $create_directory = false) { global $user, $phpbb_root_path; // Does the target directory exist, is it a directory and writable. if ($create_directory) { if (!file_exists($phpbb_root_path . $upload_dir)) { @mkdir($phpbb_root_path . $upload_dir, 0777); phpbb_chmod($phpbb_root_path . $upload_dir, CHMOD_READ | CHMOD_WRITE); } } if (!file_exists($phpbb_root_path . $upload_dir)) { $error[] = sprintf($user->lang['NO_UPLOAD_DIR'], $upload_dir); return; } if (!is_dir($phpbb_root_path . $upload_dir)) { $error[] = sprintf($user->lang['UPLOAD_NOT_DIR'], $upload_dir); return; } if (!phpbb_is_writable($phpbb_root_path . $upload_dir)) { $error[] = sprintf($user->lang['NO_WRITE_UPLOAD'], $upload_dir); return; } } /** * Perform operations on sites for external linking */ function perform_site_list() { global $db, $user; global $request; if (isset($_REQUEST['securesubmit'])) { // Grab the list of entries $ips = request_var('ips', ''); $ip_list = array_unique(explode("\n", $ips)); $ip_list_log = implode(', ', $ip_list); $ip_exclude = (int) $request->variable('ipexclude', false, false, \phpbb\request\request_interface::POST); $iplist = array(); $hostlist = array(); foreach ($ip_list as $item) { if (preg_match('#^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})[ ]*\-[ ]*([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$#', trim($item), $ip_range_explode)) { // Don't ask about all this, just don't ask ... ! $ip_1_counter = $ip_range_explode[1]; $ip_1_end = $ip_range_explode[5]; while ($ip_1_counter <= $ip_1_end) { $ip_2_counter = ($ip_1_counter == $ip_range_explode[1]) ? $ip_range_explode[2] : 0; $ip_2_end = ($ip_1_counter < $ip_1_end) ? 254 : $ip_range_explode[6]; if ($ip_2_counter == 0 && $ip_2_end == 254) { $ip_2_counter = 256; $ip_2_fragment = 256; $iplist[] = "'$ip_1_counter.*'"; } while ($ip_2_counter <= $ip_2_end) { $ip_3_counter = ($ip_2_counter == $ip_range_explode[2] && $ip_1_counter == $ip_range_explode[1]) ? $ip_range_explode[3] : 0; $ip_3_end = ($ip_2_counter < $ip_2_end || $ip_1_counter < $ip_1_end) ? 254 : $ip_range_explode[7]; if ($ip_3_counter == 0 && $ip_3_end == 254) { $ip_3_counter = 256; $ip_3_fragment = 256; $iplist[] = "'$ip_1_counter.$ip_2_counter.*'"; } while ($ip_3_counter <= $ip_3_end) { $ip_4_counter = ($ip_3_counter == $ip_range_explode[3] && $ip_2_counter == $ip_range_explode[2] && $ip_1_counter == $ip_range_explode[1]) ? $ip_range_explode[4] : 0; $ip_4_end = ($ip_3_counter < $ip_3_end || $ip_2_counter < $ip_2_end) ? 254 : $ip_range_explode[8]; if ($ip_4_counter == 0 && $ip_4_end == 254) { $ip_4_counter = 256; $ip_4_fragment = 256; $iplist[] = "'$ip_1_counter.$ip_2_counter.$ip_3_counter.*'"; } while ($ip_4_counter <= $ip_4_end) { $iplist[] = "'$ip_1_counter.$ip_2_counter.$ip_3_counter.$ip_4_counter'"; $ip_4_counter++; } $ip_3_counter++; } $ip_2_counter++; } $ip_1_counter++; } } else if (preg_match('#^([0-9]{1,3})\.([0-9\*]{1,3})\.([0-9\*]{1,3})\.([0-9\*]{1,3})$#', trim($item)) || preg_match('#^[a-f0-9:]+\*?$#i', trim($item))) { $iplist[] = "'" . trim($item) . "'"; } else if (preg_match('#^([\w\-_]\.?){2,}$#is', trim($item))) { $hostlist[] = "'" . trim($item) . "'"; } else if (preg_match("#^([a-z0-9\-\*\._/]+?)$#is", trim($item))) { $hostlist[] = "'" . trim($item) . "'"; } } $sql = 'SELECT site_ip, site_hostname FROM ' . SITELIST_TABLE . " WHERE ip_exclude = $ip_exclude"; $result = $db->sql_query($sql); if ($row = $db->sql_fetchrow($result)) { $iplist_tmp = array(); $hostlist_tmp = array(); do { if ($row['site_ip']) { if (strlen($row['site_ip']) > 40) { continue; } $iplist_tmp[] = "'" . $row['site_ip'] . "'"; } else if ($row['site_hostname']) { if (strlen($row['site_hostname']) > 255) { continue; } $hostlist_tmp[] = "'" . $row['site_hostname'] . "'"; } // break; } while ($row = $db->sql_fetchrow($result)); $iplist = array_unique(array_diff($iplist, $iplist_tmp)); $hostlist = array_unique(array_diff($hostlist, $hostlist_tmp)); unset($iplist_tmp); unset($hostlist_tmp); } $db->sql_freeresult($result); if (sizeof($iplist)) { foreach ($iplist as $ip_entry) { $sql = 'INSERT INTO ' . SITELIST_TABLE . " (site_ip, ip_exclude) VALUES ($ip_entry, $ip_exclude)"; $db->sql_query($sql); } } if (sizeof($hostlist)) { foreach ($hostlist as $host_entry) { $sql = 'INSERT INTO ' . SITELIST_TABLE . " (site_hostname, ip_exclude) VALUES ($host_entry, $ip_exclude)"; $db->sql_query($sql); } } if (!empty($ip_list_log)) { // Update log $log_entry = ($ip_exclude) ? 'LOG_DOWNLOAD_EXCLUDE_IP' : 'LOG_DOWNLOAD_IP'; add_log('admin', $log_entry, $ip_list_log); } trigger_error($user->lang['SECURE_DOWNLOAD_UPDATE_SUCCESS'] . adm_back_link($this->u_action)); } else if (isset($_POST['unsecuresubmit'])) { $unip_sql = request_var('unip', array(0)); if (sizeof($unip_sql)) { $l_unip_list = ''; // Grab details of ips for logging information later $sql = 'SELECT site_ip, site_hostname FROM ' . SITELIST_TABLE . ' WHERE ' . $db->sql_in_set('site_id', $unip_sql); $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $l_unip_list .= (($l_unip_list != '') ? ', ' : '') . (($row['site_ip']) ? $row['site_ip'] : $row['site_hostname']); } $db->sql_freeresult($result); $sql = 'DELETE FROM ' . SITELIST_TABLE . ' WHERE ' . $db->sql_in_set('site_id', $unip_sql); $db->sql_query($sql); add_log('admin', 'LOG_DOWNLOAD_REMOVE_IP', $l_unip_list); } trigger_error($user->lang['SECURE_DOWNLOAD_UPDATE_SUCCESS'] . adm_back_link($this->u_action)); } } /** * Write display_order config field */ function display_order($value, $key = '') { $radio_ary = array(0 => 'DESCENDING', 1 => 'ASCENDING'); return h_radio('config[display_order]', $radio_ary, $value, $key); } /** * Adjust all three max_filesize config vars for display */ function max_filesize($value, $key = '') { // Determine size var and adjust the value accordingly $filesize = get_formatted_filesize($value, false, array('mb', 'kb', 'b')); $size_var = $filesize['si_identifier']; $value = $filesize['value']; // size="8" and maxlength="15" attributes as a fallback for browsers that do not support type="number" yet. return '<input type="number" id="' . $key . '" size="8" maxlength="15" min="0" name="config[' . $key . ']" value="' . $value . '" /> <select name="' . $key . '">' . size_select_options($size_var) . '</select>'; } /** * Write secure_allow_deny config field */ function select_allow_deny($value, $key = '') { $radio_ary = array(1 => 'ORDER_ALLOW_DENY', 0 => 'ORDER_DENY_ALLOW'); return h_radio('config[' . $key . ']', $radio_ary, $value, $key); } } acp_disallow.php000077700000006065151514745240007744 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_disallow { var $u_action; function main($id, $mode) { global $db, $user, $auth, $template, $cache; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; include($phpbb_root_path . 'includes/functions_user.' . $phpEx); $user->add_lang('acp/posting'); // Set up general vars $this->tpl_name = 'acp_disallow'; $this->page_title = 'ACP_DISALLOW_USERNAMES'; $form_key = 'acp_disallow'; add_form_key($form_key); $disallow = (isset($_POST['disallow'])) ? true : false; $allow = (isset($_POST['allow'])) ? true : false; if (($allow || $disallow) && !check_form_key($form_key)) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } if ($disallow) { $disallowed_user = str_replace('*', '%', utf8_normalize_nfc(request_var('disallowed_user', '', true))); if (!$disallowed_user) { trigger_error($user->lang['NO_USERNAME_SPECIFIED'] . adm_back_link($this->u_action), E_USER_WARNING); } $sql = 'SELECT disallow_id FROM ' . DISALLOW_TABLE . " WHERE disallow_username = '" . $db->sql_escape($disallowed_user) . "'"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($row) { trigger_error($user->lang['DISALLOWED_ALREADY'] . adm_back_link($this->u_action), E_USER_WARNING); } $sql = 'INSERT INTO ' . DISALLOW_TABLE . ' ' . $db->sql_build_array('INSERT', array('disallow_username' => $disallowed_user)); $db->sql_query($sql); $cache->destroy('_disallowed_usernames'); $message = $user->lang['DISALLOW_SUCCESSFUL']; add_log('admin', 'LOG_DISALLOW_ADD', str_replace('%', '*', $disallowed_user)); trigger_error($message . adm_back_link($this->u_action)); } else if ($allow) { $disallowed_id = request_var('disallowed_id', 0); if (!$disallowed_id) { trigger_error($user->lang['NO_USERNAME_SPECIFIED'] . adm_back_link($this->u_action), E_USER_WARNING); } $sql = 'DELETE FROM ' . DISALLOW_TABLE . ' WHERE disallow_id = ' . $disallowed_id; $db->sql_query($sql); $cache->destroy('_disallowed_usernames'); add_log('admin', 'LOG_DISALLOW_DELETE'); trigger_error($user->lang['DISALLOWED_DELETED'] . adm_back_link($this->u_action)); } // Grab the current list of disallowed usernames... $sql = 'SELECT * FROM ' . DISALLOW_TABLE; $result = $db->sql_query($sql); $disallow_select = ''; while ($row = $db->sql_fetchrow($result)) { $disallow_select .= '<option value="' . $row['disallow_id'] . '">' . str_replace('%', '*', $row['disallow_username']) . '</option>'; } $db->sql_freeresult($result); $template->assign_vars(array( 'U_ACTION' => $this->u_action, 'S_DISALLOWED_NAMES' => $disallow_select) ); } } acp_bbcodes.php000077700000044433151514745240007530 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_bbcodes { var $u_action; function main($id, $mode) { global $db, $user, $auth, $template, $cache, $request, $phpbb_dispatcher; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; $user->add_lang('acp/posting'); // Set up general vars $action = request_var('action', ''); $bbcode_id = request_var('bbcode', 0); $this->tpl_name = 'acp_bbcodes'; $this->page_title = 'ACP_BBCODES'; $form_key = 'acp_bbcodes'; add_form_key($form_key); // Set up mode-specific vars switch ($action) { case 'add': $bbcode_match = $bbcode_tpl = $bbcode_helpline = ''; $display_on_posting = 0; break; case 'edit': $sql = 'SELECT bbcode_match, bbcode_tpl, display_on_posting, bbcode_helpline FROM ' . BBCODES_TABLE . ' WHERE bbcode_id = ' . $bbcode_id; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$row) { trigger_error($user->lang['BBCODE_NOT_EXIST'] . adm_back_link($this->u_action), E_USER_WARNING); } $bbcode_match = $row['bbcode_match']; $bbcode_tpl = htmlspecialchars($row['bbcode_tpl']); $display_on_posting = $row['display_on_posting']; $bbcode_helpline = $row['bbcode_helpline']; break; case 'modify': $sql = 'SELECT bbcode_id, bbcode_tag FROM ' . BBCODES_TABLE . ' WHERE bbcode_id = ' . $bbcode_id; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$row) { trigger_error($user->lang['BBCODE_NOT_EXIST'] . adm_back_link($this->u_action), E_USER_WARNING); } // No break here case 'create': $display_on_posting = request_var('display_on_posting', 0); $bbcode_match = request_var('bbcode_match', ''); $bbcode_tpl = htmlspecialchars_decode(utf8_normalize_nfc(request_var('bbcode_tpl', '', true))); $bbcode_helpline = utf8_normalize_nfc(request_var('bbcode_helpline', '', true)); break; } // Do major work switch ($action) { case 'edit': case 'add': $tpl_ary = array( 'S_EDIT_BBCODE' => true, 'U_BACK' => $this->u_action, 'U_ACTION' => $this->u_action . '&action=' . (($action == 'add') ? 'create' : 'modify') . (($bbcode_id) ? "&bbcode=$bbcode_id" : ''), 'L_BBCODE_USAGE_EXPLAIN'=> sprintf($user->lang['BBCODE_USAGE_EXPLAIN'], '<a href="#down">', '</a>'), 'BBCODE_MATCH' => $bbcode_match, 'BBCODE_TPL' => $bbcode_tpl, 'BBCODE_HELPLINE' => $bbcode_helpline, 'DISPLAY_ON_POSTING' => $display_on_posting, ); $bbcode_tokens = array('TEXT', 'SIMPLETEXT', 'INTTEXT', 'IDENTIFIER', 'NUMBER', 'EMAIL', 'URL', 'LOCAL_URL', 'RELATIVE_URL', 'COLOR'); /** * Modify custom bbcode template data before we display the add/edit form * * @event core.acp_bbcodes_edit_add * @var string action Type of the action: add|edit * @var array tpl_ary Array with custom bbcode add/edit data * @var int bbcode_id When editing: the bbcode id, * when creating: 0 * @var array bbcode_tokens Array of bbcode tokens * @since 3.1.0-a3 */ $vars = array('action', 'tpl_ary', 'bbcode_id', 'bbcode_tokens'); extract($phpbb_dispatcher->trigger_event('core.acp_bbcodes_edit_add', compact($vars))); $template->assign_vars($tpl_ary); foreach ($bbcode_tokens as $token) { $template->assign_block_vars('token', array( 'TOKEN' => '{' . $token . '}', 'EXPLAIN' => ($token === 'LOCAL_URL') ? $user->lang(array('tokens', $token), generate_board_url() . '/') : $user->lang(array('tokens', $token)), )); } return; break; case 'modify': case 'create': $sql_ary = $hidden_fields = array(); /** * Modify custom bbcode data before the modify/create action * * @event core.acp_bbcodes_modify_create * @var string action Type of the action: modify|create * @var array sql_ary Array with new bbcode data * @var int bbcode_id When editing: the bbcode id, * when creating: 0 * @var bool display_on_posting Display bbcode on posting form * @var string bbcode_match The bbcode usage string to match * @var string bbcode_tpl The bbcode HTML replacement string * @var string bbcode_helpline The bbcode help line string * @var array hidden_fields Array of hidden fields for use when * submitting form when $warn_text is true * @since 3.1.0-a3 */ $vars = array( 'action', 'sql_ary', 'bbcode_id', 'display_on_posting', 'bbcode_match', 'bbcode_tpl', 'bbcode_helpline', 'hidden_fields', ); extract($phpbb_dispatcher->trigger_event('core.acp_bbcodes_modify_create', compact($vars))); $warn_text = preg_match('%<[^>]*\{text[\d]*\}[^>]*>%i', $bbcode_tpl); if (!$warn_text || confirm_box(true)) { $data = $this->build_regexp($bbcode_match, $bbcode_tpl); // Make sure the user didn't pick a "bad" name for the BBCode tag. $hard_coded = array('code', 'quote', 'quote=', 'attachment', 'attachment=', 'b', 'i', 'url', 'url=', 'img', 'size', 'size=', 'color', 'color=', 'u', 'list', 'list=', 'email', 'email=', 'flash', 'flash='); if (($action == 'modify' && strtolower($data['bbcode_tag']) !== strtolower($row['bbcode_tag'])) || ($action == 'create')) { $sql = 'SELECT 1 as test FROM ' . BBCODES_TABLE . " WHERE LOWER(bbcode_tag) = '" . $db->sql_escape(strtolower($data['bbcode_tag'])) . "'"; $result = $db->sql_query($sql); $info = $db->sql_fetchrow($result); $db->sql_freeresult($result); // Grab the end, interrogate the last closing tag if ($info['test'] === '1' || in_array(strtolower($data['bbcode_tag']), $hard_coded) || (preg_match('#\[/([^[]*)]$#', $bbcode_match, $regs) && in_array(strtolower($regs[1]), $hard_coded))) { trigger_error($user->lang['BBCODE_INVALID_TAG_NAME'] . adm_back_link($this->u_action), E_USER_WARNING); } } if (substr($data['bbcode_tag'], -1) === '=') { $test = substr($data['bbcode_tag'], 0, -1); } else { $test = $data['bbcode_tag']; } if (!preg_match('%\\[' . $test . '[^]]*].*?\\[/' . $test . ']%s', $bbcode_match)) { trigger_error($user->lang['BBCODE_OPEN_ENDED_TAG'] . adm_back_link($this->u_action), E_USER_WARNING); } if (strlen($data['bbcode_tag']) > 16) { trigger_error($user->lang['BBCODE_TAG_TOO_LONG'] . adm_back_link($this->u_action), E_USER_WARNING); } if (strlen($bbcode_match) > 4000) { trigger_error($user->lang['BBCODE_TAG_DEF_TOO_LONG'] . adm_back_link($this->u_action), E_USER_WARNING); } if (strlen($bbcode_helpline) > 255) { trigger_error($user->lang['BBCODE_HELPLINE_TOO_LONG'] . adm_back_link($this->u_action), E_USER_WARNING); } $sql_ary = array_merge($sql_ary, array( 'bbcode_tag' => $data['bbcode_tag'], 'bbcode_match' => $bbcode_match, 'bbcode_tpl' => $bbcode_tpl, 'display_on_posting' => $display_on_posting, 'bbcode_helpline' => $bbcode_helpline, 'first_pass_match' => $data['first_pass_match'], 'first_pass_replace' => $data['first_pass_replace'], 'second_pass_match' => $data['second_pass_match'], 'second_pass_replace' => $data['second_pass_replace'] )); if ($action == 'create') { $sql = 'SELECT MAX(bbcode_id) as max_bbcode_id FROM ' . BBCODES_TABLE; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($row) { $bbcode_id = $row['max_bbcode_id'] + 1; // Make sure it is greater than the core bbcode ids... if ($bbcode_id <= NUM_CORE_BBCODES) { $bbcode_id = NUM_CORE_BBCODES + 1; } } else { $bbcode_id = NUM_CORE_BBCODES + 1; } if ($bbcode_id > BBCODE_LIMIT) { trigger_error($user->lang['TOO_MANY_BBCODES'] . adm_back_link($this->u_action), E_USER_WARNING); } $sql_ary['bbcode_id'] = (int) $bbcode_id; $db->sql_query('INSERT INTO ' . BBCODES_TABLE . $db->sql_build_array('INSERT', $sql_ary)); $cache->destroy('sql', BBCODES_TABLE); $lang = 'BBCODE_ADDED'; $log_action = 'LOG_BBCODE_ADD'; } else { $sql = 'UPDATE ' . BBCODES_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE bbcode_id = ' . $bbcode_id; $db->sql_query($sql); $cache->destroy('sql', BBCODES_TABLE); $lang = 'BBCODE_EDITED'; $log_action = 'LOG_BBCODE_EDIT'; } add_log('admin', $log_action, $data['bbcode_tag']); trigger_error($user->lang[$lang] . adm_back_link($this->u_action)); } else { confirm_box(false, $user->lang['BBCODE_DANGER'], build_hidden_fields(array_merge($hidden_fields, array( 'action' => $action, 'bbcode' => $bbcode_id, 'bbcode_match' => $bbcode_match, 'bbcode_tpl' => htmlspecialchars($bbcode_tpl), 'bbcode_helpline' => $bbcode_helpline, 'display_on_posting' => $display_on_posting, ))) , 'confirm_bbcode.html'); } break; case 'delete': $sql = 'SELECT bbcode_tag FROM ' . BBCODES_TABLE . " WHERE bbcode_id = $bbcode_id"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($row) { if (confirm_box(true)) { $db->sql_query('DELETE FROM ' . BBCODES_TABLE . " WHERE bbcode_id = $bbcode_id"); $cache->destroy('sql', BBCODES_TABLE); add_log('admin', 'LOG_BBCODE_DELETE', $row['bbcode_tag']); if ($request->is_ajax()) { $json_response = new \phpbb\json_response; $json_response->send(array( 'MESSAGE_TITLE' => $user->lang['INFORMATION'], 'MESSAGE_TEXT' => $user->lang['BBCODE_DELETED'], 'REFRESH_DATA' => array( 'time' => 3 ) )); } } else { confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( 'bbcode' => $bbcode_id, 'i' => $id, 'mode' => $mode, 'action' => $action)) ); } } break; } $u_action = $this->u_action; $template_data = array( 'U_ACTION' => $this->u_action . '&action=add', ); $sql_ary = array( 'SELECT' => 'b.*', 'FROM' => array(BBCODES_TABLE => 'b'), 'ORDER_BY' => 'b.bbcode_tag', ); /** * Modify custom bbcode template data before we display the form * * @event core.acp_bbcodes_display_form * @var string action Type of the action: modify|create * @var string sql_ary The SQL array to get custom bbcode data * @var array template_data Array with form template data * @var string u_action The u_action link * @since 3.1.0-a3 */ $vars = array('action', 'sql_ary', 'template_data', 'u_action'); extract($phpbb_dispatcher->trigger_event('core.acp_bbcodes_display_form', compact($vars))); $result = $db->sql_query($db->sql_build_query('SELECT', $sql_ary)); $template->assign_vars($template_data); while ($row = $db->sql_fetchrow($result)) { $bbcodes_array = array( 'BBCODE_TAG' => $row['bbcode_tag'], 'U_EDIT' => $u_action . '&action=edit&bbcode=' . $row['bbcode_id'], 'U_DELETE' => $u_action . '&action=delete&bbcode=' . $row['bbcode_id'], ); /** * Modify display of custom bbcodes in the form * * @event core.acp_bbcodes_display_bbcodes * @var array row Array with current bbcode data * @var array bbcodes_array Array of bbcodes template data * @var string u_action The u_action link * @since 3.1.0-a3 */ $vars = array('bbcodes_array', 'row', 'u_action'); extract($phpbb_dispatcher->trigger_event('core.acp_bbcodes_display_bbcodes', compact($vars))); $template->assign_block_vars('bbcodes', $bbcodes_array); } $db->sql_freeresult($result); } /* * Build regular expression for custom bbcode */ function build_regexp(&$bbcode_match, &$bbcode_tpl) { $bbcode_match = trim($bbcode_match); $bbcode_tpl = trim($bbcode_tpl); // Allow unicode characters for URL|LOCAL_URL|RELATIVE_URL|INTTEXT tokens $utf8 = preg_match('/(URL|LOCAL_URL|RELATIVE_URL|INTTEXT)/', $bbcode_match); $utf8_pcre_properties = phpbb_pcre_utf8_support(); $fp_match = preg_quote($bbcode_match, '!'); $fp_replace = preg_replace('#^\[(.*?)\]#', '[$1:$uid]', $bbcode_match); $fp_replace = preg_replace('#\[/(.*?)\]$#', '[/$1:$uid]', $fp_replace); $sp_match = preg_quote($bbcode_match, '!'); $sp_match = preg_replace('#^\\\\\[(.*?)\\\\\]#', '\[$1:$uid\]', $sp_match); $sp_match = preg_replace('#\\\\\[/(.*?)\\\\\]$#', '\[/$1:$uid\]', $sp_match); $sp_replace = $bbcode_tpl; // @todo Make sure to change this too if something changed in message parsing $tokens = array( 'URL' => array( '!(?:(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('url')) . ')|(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('www_url')) . '))!ie' => "\$this->bbcode_specialchars(('\$1') ? '\$1' : 'http://\$2')" ), 'LOCAL_URL' => array( '!(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('relative_url')) . ')!e' => "\$this->bbcode_specialchars('$1')" ), 'RELATIVE_URL' => array( '!(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('relative_url')) . ')!e' => "\$this->bbcode_specialchars('$1')" ), 'EMAIL' => array( '!(' . get_preg_expression('email') . ')!ie' => "\$this->bbcode_specialchars('$1')" ), 'TEXT' => array( '!(.*?)!es' => "str_replace(array(\"\\r\\n\", '\\\"', '\\'', '(', ')'), array(\"\\n\", '\"', ''', '(', ')'), trim('\$1'))" ), 'SIMPLETEXT' => array( '!([a-zA-Z0-9-+.,_ ]+)!' => "$1" ), 'INTTEXT' => array( ($utf8_pcre_properties) ? '!([\p{L}\p{N}\-+,_. ]+)!u' : '!([a-zA-Z0-9\-+,_. ]+)!u' => "$1" ), 'IDENTIFIER' => array( '!([a-zA-Z0-9-_]+)!' => "$1" ), 'COLOR' => array( '!([a-z]+|#[0-9abcdef]+)!i' => '$1' ), 'NUMBER' => array( '!([0-9]+)!' => '$1' ) ); $sp_tokens = array( 'URL' => '(?i)((?:' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('url')) . ')|(?:' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('www_url')) . '))(?-i)', 'LOCAL_URL' => '(?i)(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('relative_url')) . ')(?-i)', 'RELATIVE_URL' => '(?i)(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('relative_url')) . ')(?-i)', 'EMAIL' => '(' . get_preg_expression('email') . ')', 'TEXT' => '(.*?)', 'SIMPLETEXT' => '([a-zA-Z0-9-+.,_ ]+)', 'INTTEXT' => ($utf8_pcre_properties) ? '([\p{L}\p{N}\-+,_. ]+)' : '([a-zA-Z0-9\-+,_. ]+)', 'IDENTIFIER' => '([a-zA-Z0-9-_]+)', 'COLOR' => '([a-zA-Z]+|#[0-9abcdefABCDEF]+)', 'NUMBER' => '([0-9]+)', ); $pad = 0; $modifiers = 'i'; $modifiers .= ($utf8 && $utf8_pcre_properties) ? 'u' : ''; if (preg_match_all('/\{(' . implode('|', array_keys($tokens)) . ')[0-9]*\}/i', $bbcode_match, $m)) { foreach ($m[0] as $n => $token) { $token_type = $m[1][$n]; reset($tokens[strtoupper($token_type)]); list($match, $replace) = each($tokens[strtoupper($token_type)]); // Pad backreference numbers from tokens if (preg_match_all('/(?<!\\\\)\$([0-9]+)/', $replace, $repad)) { $repad = $pad + sizeof(array_unique($repad[0])); $replace = preg_replace('/(?<!\\\\)\$([0-9]+)/e', "'\${' . (\$1 + \$pad) . '}'", $replace); $pad = $repad; } // Obtain pattern modifiers to use and alter the regex accordingly $regex = preg_replace('/!(.*)!([a-z]*)/', '$1', $match); $regex_modifiers = preg_replace('/!(.*)!([a-z]*)/', '$2', $match); for ($i = 0, $size = strlen($regex_modifiers); $i < $size; ++$i) { if (strpos($modifiers, $regex_modifiers[$i]) === false) { $modifiers .= $regex_modifiers[$i]; if ($regex_modifiers[$i] == 'e') { $fp_replace = "'" . str_replace("'", "\\'", $fp_replace) . "'"; } } if ($regex_modifiers[$i] == 'e') { $replace = "'.$replace.'"; } } $fp_match = str_replace(preg_quote($token, '!'), $regex, $fp_match); $fp_replace = str_replace($token, $replace, $fp_replace); $sp_match = str_replace(preg_quote($token, '!'), $sp_tokens[$token_type], $sp_match); // Prepend the board url to local relative links $replace_prepend = ($token_type === 'LOCAL_URL') ? generate_board_url() . '/' : ''; $sp_replace = str_replace($token, $replace_prepend . '${' . ($n + 1) . '}', $sp_replace); } $fp_match = '!' . $fp_match . '!' . $modifiers; $sp_match = '!' . $sp_match . '!s' . (($utf8) ? 'u' : ''); if (strpos($fp_match, 'e') !== false) { $fp_replace = str_replace("'.'", '', $fp_replace); $fp_replace = str_replace(".''.", '.', $fp_replace); } } else { // No replacement is present, no need for a second-pass pattern replacement // A simple str_replace will suffice $fp_match = '!' . $fp_match . '!' . $modifiers; $sp_match = $fp_replace; $sp_replace = ''; } // Lowercase tags $bbcode_tag = preg_replace('/.*?\[([a-z0-9_-]+=?).*/i', '$1', $bbcode_match); $bbcode_search = preg_replace('/.*?\[([a-z0-9_-]+)=?.*/i', '$1', $bbcode_match); if (!preg_match('/^[a-zA-Z0-9_-]+=?$/', $bbcode_tag)) { global $user; trigger_error($user->lang['BBCODE_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } $fp_match = preg_replace('#\[/?' . $bbcode_search . '#ie', "strtolower('\$0')", $fp_match); $fp_replace = preg_replace('#\[/?' . $bbcode_search . '#ie', "strtolower('\$0')", $fp_replace); $sp_match = preg_replace('#\[/?' . $bbcode_search . '#ie', "strtolower('\$0')", $sp_match); $sp_replace = preg_replace('#\[/?' . $bbcode_search . '#ie', "strtolower('\$0')", $sp_replace); return array( 'bbcode_tag' => $bbcode_tag, 'first_pass_match' => $fp_match, 'first_pass_replace' => $fp_replace, 'second_pass_match' => $sp_match, 'second_pass_replace' => $sp_replace ); } } acp_profile.php000077700000106041151514745240007561 0ustar00<?php /** * * This file is part of the phpBB Forum Software package. * * @copyright (c) phpBB Limited <https://www.phpbb.com> * @license GNU General Public License, version 2 (GPL-2.0) * * For full copyright and license information, please see * the docs/CREDITS.txt file. * */ /** * @ignore */ if (!defined('IN_PHPBB')) { exit; } class acp_profile { var $u_action; var $edit_lang_id; var $lang_defs; protected $type_collection; function main($id, $mode) { global $config, $db, $user, $auth, $template, $cache; global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix; global $request, $phpbb_container; include($phpbb_root_path . 'includes/functions_posting.' . $phpEx); include($phpbb_root_path . 'includes/functions_user.' . $phpEx); $user->add_lang(array('ucp', 'acp/profile')); $this->tpl_name = 'acp_profile'; $this->page_title = 'ACP_CUSTOM_PROFILE_FIELDS'; $field_id = $request->variable('field_id', 0); $action = (isset($_POST['create'])) ? 'create' : request_var('action', ''); $error = array(); $s_hidden_fields = ''; if (!$field_id && in_array($action, array('delete','activate', 'deactivate', 'move_up', 'move_down', 'edit'))) { trigger_error($user->lang['NO_FIELD_ID'] . adm_back_link($this->u_action), E_USER_WARNING); } $cp = $phpbb_container->get('profilefields.manager'); $this->type_collection = $phpbb_container->get('profilefields.type_collection'); // Build Language array // Based on this, we decide which elements need to be edited later and which language items are missing $this->lang_defs = array(); $sql = 'SELECT lang_id, lang_iso FROM ' . LANG_TABLE . ' ORDER BY lang_english_name'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { // Make some arrays with all available languages $this->lang_defs['id'][$row['lang_id']] = $row['lang_iso']; $this->lang_defs['iso'][$row['lang_iso']] = $row['lang_id']; } $db->sql_freeresult($result); $sql = 'SELECT field_id, lang_id FROM ' . PROFILE_LANG_TABLE . ' ORDER BY lang_id'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { // Which languages are available for each item $this->lang_defs['entry'][$row['field_id']][] = $row['lang_id']; } $db->sql_freeresult($result); // Have some fields been defined? if (isset($this->lang_defs['entry'])) { foreach ($this->lang_defs['entry'] as $field_ident => $field_ary) { // Fill an array with the languages that are missing for each field $this->lang_defs['diff'][$field_ident] = array_diff(array_values($this->lang_defs['iso']), $field_ary); } } switch ($action) { case 'delete': if (confirm_box(true)) { $sql = 'SELECT field_ident FROM ' . PROFILE_FIELDS_TABLE . " WHERE field_id = $field_id"; $result = $db->sql_query($sql); $field_ident = (string) $db->sql_fetchfield('field_ident'); $db->sql_freeresult($result); $db->sql_transaction('begin'); $db->sql_query('DELETE FROM ' . PROFILE_FIELDS_TABLE . " WHERE field_id = $field_id"); $db->sql_query('DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . " WHERE field_id = $field_id"); $db->sql_query('DELETE FROM ' . PROFILE_LANG_TABLE . " WHERE field_id = $field_id"); $db_tools = $phpbb_container->get('dbal.tools'); $db_tools->sql_column_remove(PROFILE_FIELDS_DATA_TABLE, 'pf_' . $field_ident); $order = 0; $sql = 'SELECT * FROM ' . PROFILE_FIELDS_TABLE . ' ORDER BY field_order'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $order++; if ($row['field_order'] != $order) { $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . " SET field_order = $order WHERE field_id = {$row['field_id']}"; $db->sql_query($sql); } } $db->sql_freeresult($result); $db->sql_transaction('commit'); add_log('admin', 'LOG_PROFILE_FIELD_REMOVED', $field_ident); trigger_error($user->lang['REMOVED_PROFILE_FIELD'] . adm_back_link($this->u_action)); } else { confirm_box(false, 'DELETE_PROFILE_FIELD', build_hidden_fields(array( 'i' => $id, 'mode' => $mode, 'action' => $action, 'field_id' => $field_id, ))); } break; case 'activate': $sql = 'SELECT lang_id FROM ' . LANG_TABLE . " WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'"; $result = $db->sql_query($sql); $default_lang_id = (int) $db->sql_fetchfield('lang_id'); $db->sql_freeresult($result); if (!in_array($default_lang_id, $this->lang_defs['entry'][$field_id])) { trigger_error($user->lang['DEFAULT_LANGUAGE_NOT_FILLED'] . adm_back_link($this->u_action), E_USER_WARNING); } $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . " SET field_active = 1 WHERE field_id = $field_id"; $db->sql_query($sql); $sql = 'SELECT field_ident FROM ' . PROFILE_FIELDS_TABLE . " WHERE field_id = $field_id"; $result = $db->sql_query($sql); $field_ident = (string) $db->sql_fetchfield('field_ident'); $db->sql_freeresult($result); add_log('admin', 'LOG_PROFILE_FIELD_ACTIVATE', $field_ident); if ($request->is_ajax()) { $json_response = new \phpbb\json_response(); $json_response->send(array( 'text' => $user->lang('DEACTIVATE'), )); } trigger_error($user->lang['PROFILE_FIELD_ACTIVATED'] . adm_back_link($this->u_action)); break; case 'deactivate': $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . " SET field_active = 0 WHERE field_id = $field_id"; $db->sql_query($sql); $sql = 'SELECT field_ident FROM ' . PROFILE_FIELDS_TABLE . " WHERE field_id = $field_id"; $result = $db->sql_query($sql); $field_ident = (string) $db->sql_fetchfield('field_ident'); $db->sql_freeresult($result); if ($request->is_ajax()) { $json_response = new \phpbb\json_response(); $json_response->send(array( 'text' => $user->lang('ACTIVATE'), )); } add_log('admin', 'LOG_PROFILE_FIELD_DEACTIVATE', $field_ident); trigger_error($user->lang['PROFILE_FIELD_DEACTIVATED'] . adm_back_link($this->u_action)); break; case 'move_up': case 'move_down': $sql = 'SELECT field_order FROM ' . PROFILE_FIELDS_TABLE . " WHERE field_id = $field_id"; $result = $db->sql_query($sql); $field_order = $db->sql_fetchfield('field_order'); $db->sql_freeresult($result); if ($field_order === false || ($field_order == 0 && $action == 'move_up')) { break; } $field_order = (int) $field_order; $order_total = $field_order * 2 + (($action == 'move_up') ? -1 : 1); $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . " SET field_order = $order_total - field_order WHERE field_order IN ($field_order, " . (($action == 'move_up') ? $field_order - 1 : $field_order + 1) . ')'; $db->sql_query($sql); if ($request->is_ajax()) { $json_response = new \phpbb\json_response; $json_response->send(array( 'success' => (bool) $db->sql_affectedrows(), )); } break; case 'create': case 'edit': $step = request_var('step', 1); $submit = (isset($_REQUEST['next']) || isset($_REQUEST['prev'])) ? true : false; $save = (isset($_REQUEST['save'])) ? true : false; // The language id of default language $this->edit_lang_id = $this->lang_defs['iso'][$config['default_lang']]; // We are editing... we need to grab basic things if ($action == 'edit') { $sql = 'SELECT l.*, f.* FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f WHERE l.lang_id = ' . $this->edit_lang_id . " AND f.field_id = $field_id AND l.field_id = f.field_id"; $result = $db->sql_query($sql); $field_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$field_row) { // Some admin changed the default language? $sql = 'SELECT l.*, f.* FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f WHERE l.lang_id <> ' . $this->edit_lang_id . " AND f.field_id = $field_id AND l.field_id = f.field_id"; $result = $db->sql_query($sql); $field_row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$field_row) { trigger_error($user->lang['FIELD_NOT_FOUND'] . adm_back_link($this->u_action), E_USER_WARNING); } $this->edit_lang_id = $field_row['lang_id']; } $field_type = $field_row['field_type']; $profile_field = $this->type_collection[$field_type]; // Get language entries $sql = 'SELECT * FROM ' . PROFILE_FIELDS_LANG_TABLE . ' WHERE lang_id = ' . $this->edit_lang_id . " AND field_id = $field_id ORDER BY option_id ASC"; $result = $db->sql_query($sql); $lang_options = array(); while ($row = $db->sql_fetchrow($result)) { $lang_options[$row['option_id']] = $row['lang_value']; } $db->sql_freeresult($result); $s_hidden_fields = '<input type="hidden" name="field_id" value="' . $field_id . '" />'; } else { // We are adding a new field, define basic params $lang_options = $field_row = array(); $field_type = request_var('field_type', ''); if (!isset($this->type_collection[$field_type])) { trigger_error($user->lang['NO_FIELD_TYPE'] . adm_back_link($this->u_action), E_USER_WARNING); } $profile_field = $this->type_collection[$field_type]; $field_row = array_merge($profile_field->get_default_option_values(), array( 'field_ident' => str_replace(' ', '_', utf8_clean_string(request_var('field_ident', '', true))), 'field_required' => 0, 'field_show_novalue'=> 0, 'field_hide' => 0, 'field_show_profile'=> 0, 'field_no_view' => 0, 'field_show_on_reg' => 0, 'field_show_on_pm' => 0, 'field_show_on_vt' => 0, 'field_show_on_ml' => 0, 'field_is_contact' => 0, 'field_contact_desc'=> '', 'field_contact_url' => '', 'lang_name' => utf8_normalize_nfc(request_var('field_ident', '', true)), 'lang_explain' => '', 'lang_default_value'=> '') ); $s_hidden_fields = '<input type="hidden" name="field_type" value="' . $field_type . '" />'; } // $exclude contains the data we gather in each step $exclude = array( 1 => array('field_ident', 'lang_name', 'lang_explain', 'field_option_none', 'field_show_on_reg', 'field_show_on_pm', 'field_show_on_vt', 'field_show_on_ml', 'field_required', 'field_show_novalue', 'field_hide', 'field_show_profile', 'field_no_view', 'field_is_contact', 'field_contact_desc', 'field_contact_url'), 2 => array('field_length', 'field_maxlen', 'field_minlen', 'field_validation', 'field_novalue', 'field_default_value'), 3 => array('l_lang_name', 'l_lang_explain', 'l_lang_default_value', 'l_lang_options') ); // Visibility Options... $visibility_ary = array( 'field_required', 'field_show_novalue', 'field_show_on_reg', 'field_show_on_pm', 'field_show_on_vt', 'field_show_on_ml', 'field_show_profile', 'field_hide', 'field_is_contact', ); $options = $profile_field->prepare_options_form($exclude, $visibility_ary); $cp->vars['field_ident'] = ($action == 'create' && $step == 1) ? utf8_clean_string(request_var('field_ident', $field_row['field_ident'], true)) : request_var('field_ident', $field_row['field_ident']); $cp->vars['lang_name'] = $request->variable('lang_name', $field_row['lang_name'], true); $cp->vars['lang_explain'] = $request->variable('lang_explain', $field_row['lang_explain'], true); $cp->vars['lang_default_value'] = $request->variable('lang_default_value', $field_row['lang_default_value'], true); $cp->vars['field_contact_desc'] = $request->variable('field_contact_desc', $field_row['field_contact_desc'], true); $cp->vars['field_contact_url'] = $request->variable('field_contact_url', $field_row['field_contact_url'], true); foreach ($visibility_ary as $val) { $cp->vars[$val] = ($submit || $save) ? $request->variable($val, 0) : $field_row[$val]; } $cp->vars['field_no_view'] = $request->variable('field_no_view', (int) $field_row['field_no_view']); // If the user has submitted a form with options (i.e. dropdown field) if ($options) { $exploded_options = (is_array($options)) ? $options : explode("\n", $options); if (sizeof($exploded_options) == sizeof($lang_options) || $action == 'create') { // The number of options in the field is equal to the number of options already in the database // Or we are creating a new dropdown list. $cp->vars['lang_options'] = $exploded_options; } else if ($action == 'edit') { // Changing the number of options? (We remove and re-create the option fields) $cp->vars['lang_options'] = $exploded_options; } } else { $cp->vars['lang_options'] = $lang_options; } // step 2 foreach ($exclude[2] as $key) { $var = utf8_normalize_nfc(request_var($key, $field_row[$key], true)); $field_data = $cp->vars; $var = $profile_field->get_excluded_options($key, $action, $var, $field_data, 2); $cp->vars = $field_data; $cp->vars[$key] = $var; } // step 3 - all arrays if ($action == 'edit') { // Get language entries $sql = 'SELECT * FROM ' . PROFILE_FIELDS_LANG_TABLE . ' WHERE lang_id <> ' . $this->edit_lang_id . " AND field_id = $field_id ORDER BY option_id ASC"; $result = $db->sql_query($sql); $l_lang_options = array(); while ($row = $db->sql_fetchrow($result)) { $l_lang_options[$row['lang_id']][$row['option_id']] = $row['lang_value']; } $db->sql_freeresult($result); $sql = 'SELECT lang_id, lang_name, lang_explain, lang_default_value FROM ' . PROFILE_LANG_TABLE . ' WHERE lang_id <> ' . $this->edit_lang_id . " AND field_id = $field_id ORDER BY lang_id ASC"; $result = $db->sql_query($sql); $l_lang_name = $l_lang_explain = $l_lang_default_value = array(); while ($row = $db->sql_fetchrow($result)) { $l_lang_name[$row['lang_id']] = $row['lang_name']; $l_lang_explain[$row['lang_id']] = $row['lang_explain']; $l_lang_default_value[$row['lang_id']] = $row['lang_default_value']; } $db->sql_freeresult($result); } foreach ($exclude[3] as $key) { $cp->vars[$key] = utf8_normalize_nfc(request_var($key, array(0 => ''), true)); if (!$cp->vars[$key] && $action == 'edit') { $cp->vars[$key] = ${$key}; } $field_data = $cp->vars; $var = $profile_field->get_excluded_options($key, $action, $var, $field_data, 3); $cp->vars = $field_data; } // Check for general issues in every step if ($submit) // && $step == 1 { // Check values for step 1 if ($cp->vars['field_ident'] == '') { $error[] = $user->lang['EMPTY_FIELD_IDENT']; } if (!preg_match('/^[a-z_]+$/', $cp->vars['field_ident'])) { $error[] = $user->lang['INVALID_CHARS_FIELD_IDENT']; } if (strlen($cp->vars['field_ident']) > 17) { $error[] = $user->lang['INVALID_FIELD_IDENT_LEN']; } if ($cp->vars['lang_name'] == '') { $error[] = $user->lang['EMPTY_USER_FIELD_NAME']; } $error = $profile_field->validate_options_on_submit($error, $cp->vars); // Check for already existing field ident if ($action != 'edit') { $sql = 'SELECT field_ident FROM ' . PROFILE_FIELDS_TABLE . " WHERE field_ident = '" . $db->sql_escape($cp->vars['field_ident']) . "'"; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if ($row) { $error[] = $user->lang['FIELD_IDENT_ALREADY_EXIST']; } } } $step = (isset($_REQUEST['next'])) ? $step + 1 : ((isset($_REQUEST['prev'])) ? $step - 1 : $step); if (sizeof($error)) { $step--; $submit = false; } // Build up the specific hidden fields foreach ($exclude as $num => $key_ary) { if ($num == $step) { continue; } $_new_key_ary = array(); $field_data = $cp->vars; foreach ($key_ary as $key) { $var = $profile_field->prepare_hidden_fields($step, $key, $action, $field_data); if ($var !== null) { $_new_key_ary[$key] = $profile_field->prepare_hidden_fields($step, $key, $action, $field_data); } } $cp->vars = $field_data; $s_hidden_fields .= build_hidden_fields($_new_key_ary); } if (!sizeof($error)) { if ($step == 3 && (sizeof($this->lang_defs['iso']) == 1 || $save)) { $this->save_profile_field($cp, $field_type, $action); } else if ($action == 'edit' && $save) { $this->save_profile_field($cp, $field_type, $action); } } $template->assign_vars(array( 'S_EDIT' => true, 'S_EDIT_MODE' => ($action == 'edit') ? true : false, 'ERROR_MSG' => (sizeof($error)) ? implode('<br />', $error) : '', 'L_TITLE' => $user->lang['STEP_' . $step . '_TITLE_' . strtoupper($action)], 'L_EXPLAIN' => $user->lang['STEP_' . $step . '_EXPLAIN_' . strtoupper($action)], 'U_ACTION' => $this->u_action . "&action=$action&step=$step", 'U_BACK' => $this->u_action) ); // Now go through the steps switch ($step) { // Create basic options - only small differences between field types case 1: $template_vars = array( 'S_STEP_ONE' => true, 'S_FIELD_REQUIRED' => ($cp->vars['field_required']) ? true : false, 'S_FIELD_SHOW_NOVALUE'=> ($cp->vars['field_show_novalue']) ? true : false, 'S_SHOW_ON_REG' => ($cp->vars['field_show_on_reg']) ? true : false, 'S_SHOW_ON_PM' => ($cp->vars['field_show_on_pm']) ? true : false, 'S_SHOW_ON_VT' => ($cp->vars['field_show_on_vt']) ? true : false, 'S_SHOW_ON_MEMBERLIST'=> ($cp->vars['field_show_on_ml']) ? true : false, 'S_FIELD_HIDE' => ($cp->vars['field_hide']) ? true : false, 'S_SHOW_PROFILE' => ($cp->vars['field_show_profile']) ? true : false, 'S_FIELD_NO_VIEW' => ($cp->vars['field_no_view']) ? true : false, 'S_FIELD_CONTACT' => $cp->vars['field_is_contact'], 'FIELD_CONTACT_DESC'=> $cp->vars['field_contact_desc'], 'FIELD_CONTACT_URL' => $cp->vars['field_contact_url'], 'L_LANG_SPECIFIC' => sprintf($user->lang['LANG_SPECIFIC_OPTIONS'], $config['default_lang']), 'FIELD_TYPE' => $profile_field->get_name(), 'FIELD_IDENT' => $cp->vars['field_ident'], 'LANG_NAME' => $cp->vars['lang_name'], 'LANG_EXPLAIN' => $cp->vars['lang_explain'], ); $field_data = $cp->vars; $profile_field->display_options($template_vars, $field_data); $cp->vars = $field_data; // Build common create options $template->assign_vars($template_vars); break; case 2: $template->assign_vars(array( 'S_STEP_TWO' => true, 'L_NEXT_STEP' => (sizeof($this->lang_defs['iso']) == 1) ? $user->lang['SAVE'] : $user->lang['PROFILE_LANG_OPTIONS']) ); // Build options based on profile type $options = $profile_field->get_options($this->lang_defs['iso'][$config['default_lang']], $cp->vars); foreach ($options as $num => $option_ary) { $template->assign_block_vars('option', $option_ary); } break; // Define remaining language variables case 3: $template->assign_var('S_STEP_THREE', true); $options = $this->build_language_options($cp, $field_type, $action); foreach ($options as $lang_id => $lang_ary) { $template->assign_block_vars('options', array( 'LANGUAGE' => sprintf($user->lang[(($lang_id == $this->edit_lang_id) ? 'DEFAULT_' : '') . 'ISO_LANGUAGE'], $lang_ary['lang_iso'])) ); foreach ($lang_ary['fields'] as $field_ident => $field_ary) { $template->assign_block_vars('options.field', array( 'L_TITLE' => $field_ary['TITLE'], 'L_EXPLAIN' => (isset($field_ary['EXPLAIN'])) ? $field_ary['EXPLAIN'] : '', 'FIELD' => $field_ary['FIELD']) ); } } break; } $template->assign_vars(array( 'S_HIDDEN_FIELDS' => $s_hidden_fields) ); return; break; } $sql = 'SELECT * FROM ' . PROFILE_FIELDS_TABLE . ' ORDER BY field_order'; $result = $db->sql_query($sql); $s_one_need_edit = false; while ($row = $db->sql_fetchrow($result)) { $active_lang = (!$row['field_active']) ? 'ACTIVATE' : 'DEACTIVATE'; $active_value = (!$row['field_active']) ? 'activate' : 'deactivate'; $id = $row['field_id']; $s_need_edit = (sizeof($this->lang_defs['diff'][$row['field_id']])) ? true : false; if ($s_need_edit) { $s_one_need_edit = true; } $profile_field = $this->type_collection[$row['field_type']]; $template->assign_block_vars('fields', array( 'FIELD_IDENT' => $row['field_ident'], 'FIELD_TYPE' => $profile_field->get_name(), 'L_ACTIVATE_DEACTIVATE' => $user->lang[$active_lang], 'U_ACTIVATE_DEACTIVATE' => $this->u_action . "&action=$active_value&field_id=$id", 'U_EDIT' => $this->u_action . "&action=edit&field_id=$id", 'U_TRANSLATE' => $this->u_action . "&action=edit&field_id=$id&step=3", 'U_DELETE' => $this->u_action . "&action=delete&field_id=$id", 'U_MOVE_UP' => $this->u_action . "&action=move_up&field_id=$id", 'U_MOVE_DOWN' => $this->u_action . "&action=move_down&field_id=$id", 'S_NEED_EDIT' => $s_need_edit) ); } $db->sql_freeresult($result); // At least one option field needs editing? if ($s_one_need_edit) { $template->assign_var('S_NEED_EDIT', true); } $s_select_type = ''; foreach ($this->type_collection as $key => $profile_field) { $s_select_type .= '<option value="' . $key . '">' . $profile_field->get_name() . '</option>'; } $template->assign_vars(array( 'U_ACTION' => $this->u_action, 'S_TYPE_OPTIONS' => $s_select_type, )); } /** * Build all Language specific options */ function build_language_options(&$cp, $field_type, $action = 'create') { global $user, $config, $db, $phpbb_container; $default_lang_id = (!empty($this->edit_lang_id)) ? $this->edit_lang_id : $this->lang_defs['iso'][$config['default_lang']]; $sql = 'SELECT lang_id, lang_iso FROM ' . LANG_TABLE . ' WHERE lang_id <> ' . (int) $default_lang_id . ' ORDER BY lang_english_name'; $result = $db->sql_query($sql); $languages = array(); while ($row = $db->sql_fetchrow($result)) { $languages[$row['lang_id']] = $row['lang_iso']; } $db->sql_freeresult($result); $profile_field = $this->type_collection[$field_type]; $options = $profile_field->get_language_options($cp->vars); $lang_options = array(); foreach ($options as $field => $field_type) { $lang_options[1]['lang_iso'] = $this->lang_defs['id'][$default_lang_id]; $lang_options[1]['fields'][$field] = array( 'TITLE' => $user->lang['CP_' . strtoupper($field)], 'FIELD' => '<dd>' . ((is_array($cp->vars[$field])) ? implode('<br />', $cp->vars[$field]) : bbcode_nl2br($cp->vars[$field])) . '</dd>' ); if (isset($user->lang['CP_' . strtoupper($field) . '_EXPLAIN'])) { $lang_options[1]['fields'][$field]['EXPLAIN'] = $user->lang['CP_' . strtoupper($field) . '_EXPLAIN']; } } foreach ($languages as $lang_id => $lang_iso) { $lang_options[$lang_id]['lang_iso'] = $lang_iso; foreach ($options as $field => $field_type) { $value = ($action == 'create') ? utf8_normalize_nfc(request_var('l_' . $field, array(0 => ''), true)) : $cp->vars['l_' . $field]; if ($field == 'lang_options') { $var = (!isset($cp->vars['l_lang_options'][$lang_id]) || !is_array($cp->vars['l_lang_options'][$lang_id])) ? $cp->vars['lang_options'] : $cp->vars['l_lang_options'][$lang_id]; switch ($field_type) { case 'two_options': $lang_options[$lang_id]['fields'][$field] = array( 'TITLE' => $user->lang['CP_' . strtoupper($field)], 'FIELD' => ' <dd><input class="medium" name="l_' . $field . '[' . $lang_id . '][]" value="' . ((isset($value[$lang_id][0])) ? $value[$lang_id][0] : $var[0]) . '" /> ' . $user->lang['FIRST_OPTION'] . '</dd> <dd><input class="medium" name="l_' . $field . '[' . $lang_id . '][]" value="' . ((isset($value[$lang_id][1])) ? $value[$lang_id][1] : $var[1]) . '" /> ' . $user->lang['SECOND_OPTION'] . '</dd>' ); break; case 'optionfield': $value = ((isset($value[$lang_id])) ? ((is_array($value[$lang_id])) ? implode("\n", $value[$lang_id]) : $value[$lang_id]) : implode("\n", $var)); $lang_options[$lang_id]['fields'][$field] = array( 'TITLE' => $user->lang['CP_' . strtoupper($field)], 'FIELD' => '<dd><textarea name="l_' . $field . '[' . $lang_id . ']" rows="7" cols="80">' . $value . '</textarea></dd>' ); break; } if (isset($user->lang['CP_' . strtoupper($field) . '_EXPLAIN'])) { $lang_options[$lang_id]['fields'][$field]['EXPLAIN'] = $user->lang['CP_' . strtoupper($field) . '_EXPLAIN']; } } else { $var = ($action == 'create' || !is_array($cp->vars[$field])) ? $cp->vars[$field] : $cp->vars[$field][$lang_id]; $lang_options[$lang_id]['fields'][$field] = array( 'TITLE' => $user->lang['CP_' . strtoupper($field)], 'FIELD' => ($field_type == 'string') ? '<dd><input class="medium" type="text" name="l_' . $field . '[' . $lang_id . ']" value="' . ((isset($value[$lang_id])) ? $value[$lang_id] : $var) . '" /></dd>' : '<dd><textarea name="l_' . $field . '[' . $lang_id . ']" rows="3" cols="80">' . ((isset($value[$lang_id])) ? $value[$lang_id] : $var) . '</textarea></dd>' ); if (isset($user->lang['CP_' . strtoupper($field) . '_EXPLAIN'])) { $lang_options[$lang_id]['fields'][$field]['EXPLAIN'] = $user->lang['CP_' . strtoupper($field) . '_EXPLAIN']; } } } } return $lang_options; } /** * Save Profile Field */ function save_profile_field(&$cp, $field_type, $action = 'create') { global $db, $config, $user, $phpbb_container; $field_id = request_var('field_id', 0); // Collect all information, if something is going wrong, abort the operation $profile_sql = $profile_lang = $empty_lang = $profile_lang_fields = array(); $default_lang_id = (!empty($this->edit_lang_id)) ? $this->edit_lang_id : $this->lang_defs['iso'][$config['default_lang']]; if ($action == 'create') { $sql = 'SELECT MAX(field_order) as max_field_order FROM ' . PROFILE_FIELDS_TABLE; $result = $db->sql_query($sql); $new_field_order = (int) $db->sql_fetchfield('max_field_order'); $db->sql_freeresult($result); $field_ident = $cp->vars['field_ident']; } // Save the field $profile_fields = array( 'field_length' => $cp->vars['field_length'], 'field_minlen' => $cp->vars['field_minlen'], 'field_maxlen' => $cp->vars['field_maxlen'], 'field_novalue' => $cp->vars['field_novalue'], 'field_default_value' => $cp->vars['field_default_value'], 'field_validation' => $cp->vars['field_validation'], 'field_required' => $cp->vars['field_required'], 'field_show_novalue' => $cp->vars['field_show_novalue'], 'field_show_on_reg' => $cp->vars['field_show_on_reg'], 'field_show_on_pm' => $cp->vars['field_show_on_pm'], 'field_show_on_vt' => $cp->vars['field_show_on_vt'], 'field_show_on_ml' => $cp->vars['field_show_on_ml'], 'field_hide' => $cp->vars['field_hide'], 'field_show_profile' => $cp->vars['field_show_profile'], 'field_no_view' => $cp->vars['field_no_view'], 'field_is_contact' => $cp->vars['field_is_contact'], 'field_contact_desc' => $cp->vars['field_contact_desc'], 'field_contact_url' => $cp->vars['field_contact_url'], ); if ($action == 'create') { $profile_fields += array( 'field_type' => $field_type, 'field_ident' => $field_ident, 'field_name' => $field_ident, 'field_order' => $new_field_order + 1, 'field_active' => 1 ); $sql = 'INSERT INTO ' . PROFILE_FIELDS_TABLE . ' ' . $db->sql_build_array('INSERT', $profile_fields); $db->sql_query($sql); $field_id = $db->sql_nextid(); } else { $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $profile_fields) . " WHERE field_id = $field_id"; $db->sql_query($sql); } $profile_field = $this->type_collection[$field_type]; if ($action == 'create') { $field_ident = 'pf_' . $field_ident; $db_tools = $phpbb_container->get('dbal.tools'); $db_tools->sql_column_add(PROFILE_FIELDS_DATA_TABLE, $field_ident, array($profile_field->get_database_column_type(), null)); } $sql_ary = array( 'lang_name' => $cp->vars['lang_name'], 'lang_explain' => $cp->vars['lang_explain'], 'lang_default_value' => $cp->vars['lang_default_value'] ); if ($action == 'create') { $sql_ary['field_id'] = $field_id; $sql_ary['lang_id'] = $default_lang_id; $profile_sql[] = 'INSERT INTO ' . PROFILE_LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); } else { $this->update_insert(PROFILE_LANG_TABLE, $sql_ary, array('field_id' => $field_id, 'lang_id' => $default_lang_id)); } if (is_array($cp->vars['l_lang_name']) && sizeof($cp->vars['l_lang_name'])) { foreach ($cp->vars['l_lang_name'] as $lang_id => $data) { if (($cp->vars['lang_name'] != '' && $cp->vars['l_lang_name'][$lang_id] == '') || ($cp->vars['lang_explain'] != '' && $cp->vars['l_lang_explain'][$lang_id] == '') || ($cp->vars['lang_default_value'] != '' && $cp->vars['l_lang_default_value'][$lang_id] == '')) { $empty_lang[$lang_id] = true; break; } if (!isset($empty_lang[$lang_id])) { $profile_lang[] = array( 'field_id' => $field_id, 'lang_id' => $lang_id, 'lang_name' => $cp->vars['l_lang_name'][$lang_id], 'lang_explain' => (isset($cp->vars['l_lang_explain'][$lang_id])) ? $cp->vars['l_lang_explain'][$lang_id] : '', 'lang_default_value' => (isset($cp->vars['l_lang_default_value'][$lang_id])) ? $cp->vars['l_lang_default_value'][$lang_id] : '' ); } } foreach ($empty_lang as $lang_id => $NULL) { $sql = 'DELETE FROM ' . PROFILE_LANG_TABLE . " WHERE field_id = $field_id AND lang_id = " . (int) $lang_id; $db->sql_query($sql); } } $cp->vars = $profile_field->get_language_options_input($cp->vars); if ($cp->vars['lang_options']) { if (!is_array($cp->vars['lang_options'])) { $cp->vars['lang_options'] = explode("\n", $cp->vars['lang_options']); } if ($action != 'create') { $sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . " WHERE field_id = $field_id AND lang_id = " . (int) $default_lang_id; $db->sql_query($sql); } foreach ($cp->vars['lang_options'] as $option_id => $value) { $sql_ary = array( 'field_type' => $field_type, 'lang_value' => $value ); if ($action == 'create') { $sql_ary['field_id'] = $field_id; $sql_ary['lang_id'] = $default_lang_id; $sql_ary['option_id'] = (int) $option_id; $profile_sql[] = 'INSERT INTO ' . PROFILE_FIELDS_LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); } else { $this->update_insert(PROFILE_FIELDS_LANG_TABLE, $sql_ary, array( 'field_id' => $field_id, 'lang_id' => (int) $default_lang_id, 'option_id' => (int) $option_id) ); } } } if (is_array($cp->vars['l_lang_options']) && sizeof($cp->vars['l_lang_options'])) { $empty_lang = array(); foreach ($cp->vars['l_lang_options'] as $lang_id => $lang_ary) { if (!is_array($lang_ary)) { $lang_ary = explode("\n", $lang_ary); } if (sizeof($lang_ary) != sizeof($cp->vars['lang_options'])) { $empty_lang[$lang_id] = true; } if (!isset($empty_lang[$lang_id])) { if ($action != 'create') { $sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . " WHERE field_id = $field_id AND lang_id = " . (int) $lang_id; $db->sql_query($sql); } foreach ($lang_ary as $option_id => $value) { $profile_lang_fields[] = array( 'field_id' => (int) $field_id, 'lang_id' => (int) $lang_id, 'option_id' => (int) $option_id, 'field_type' => $field_type, 'lang_value' => $value ); } } } foreach ($empty_lang as $lang_id => $NULL) { $sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . " WHERE field_id = $field_id AND lang_id = " . (int) $lang_id; $db->sql_query($sql); } } foreach ($profile_lang as $sql) { if ($action == 'create') { $profile_sql[] = 'INSERT INTO ' . PROFILE_LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $sql); } else { $lang_id = $sql['lang_id']; unset($sql['lang_id'], $sql['field_id']); $this->update_insert(PROFILE_LANG_TABLE, $sql, array('lang_id' => (int) $lang_id, 'field_id' => $field_id)); } } if (sizeof($profile_lang_fields)) { foreach ($profile_lang_fields as $sql) { if ($action == 'create') { $profile_sql[] = 'INSERT INTO ' . PROFILE_FIELDS_LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $sql); } else { $lang_id = $sql['lang_id']; $option_id = $sql['option_id']; unset($sql['lang_id'], $sql['field_id'], $sql['option_id']); $this->update_insert(PROFILE_FIELDS_LANG_TABLE, $sql, array( 'lang_id' => $lang_id, 'field_id' => $field_id, 'option_id' => $option_id) ); } } } $db->sql_transaction('begin'); if ($action == 'create') { foreach ($profile_sql as $sql) { $db->sql_query($sql); } } $db->sql_transaction('commit'); if ($action == 'edit') { add_log('admin', 'LOG_PROFILE_FIELD_EDIT', $cp->vars['field_ident'] . ':' . $cp->vars['lang_name']); trigger_error($user->lang['CHANGED_PROFILE_FIELD'] . adm_back_link($this->u_action)); } else { add_log('admin', 'LOG_PROFILE_FIELD_CREATE', substr($field_ident, 3) . ':' . $cp->vars['lang_name']); trigger_error($user->lang['ADDED_PROFILE_FIELD'] . adm_back_link($this->u_action)); } } /** * Update, then insert if not successfull */ function update_insert($table, $sql_ary, $where_fields) { global $db; $where_sql = array(); $check_key = ''; foreach ($where_fields as $key => $value) { $check_key = (!$check_key) ? $key : $check_key; $where_sql[] = $key . ' = ' . ((is_string($value)) ? "'" . $db->sql_escape($value) . "'" : (int) $value); } if (!sizeof($where_sql)) { return; } $sql = "SELECT $check_key FROM $table WHERE " . implode(' AND ', $where_sql); $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); if (!$row) { $sql_ary = array_merge($where_fields, $sql_ary); if (sizeof($sql_ary)) { $db->sql_query("INSERT INTO $table " . $db->sql_build_array('INSERT', $sql_ary)); } } else { if (sizeof($sql_ary)) { $sql = "UPDATE $table SET " . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE ' . implode(' AND ', $where_sql); $db->sql_query($sql); } } } }
/home/www/hallgroupsolutions.com/e61a0/../d10d3/../c9428/acp.tar