diff options
Diffstat (limited to 'phpBB/includes')
42 files changed, 637 insertions, 2385 deletions
diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php index 2282863746..b0b9fdbd15 100644 --- a/phpBB/includes/acp/acp_attachments.php +++ b/phpBB/includes/acp/acp_attachments.php @@ -25,7 +25,7 @@ class acp_attachments function main($id, $mode) { - global $db, $user, $auth, $template, $cache; + global $db, $user, $auth, $template, $cache, $phpbb_container; global $config, $phpbb_admin_path, $phpbb_root_path, $phpEx; $user->add_lang(array('posting', 'viewtopic', 'acp/attachments')); @@ -1166,10 +1166,9 @@ class acp_attachments } // Make sure $start is set to the last page if it exceeds the amount - if ($start < 0 || $start > $num_files) - { - $start = ($start < 0) ? 0 : floor(($num_files - 1) / $attachments_per_page) * $attachments_per_page; - } + + $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; @@ -1179,15 +1178,11 @@ class acp_attachments { $store_reverse = true; - if ($start + $attachments_per_page > $num_files) - { - $sql_limit = min($attachments_per_page, max(1, $num_files - $start)); - } - // 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_start = max(0, $num_files - $sql_limit - $start); + $sql_limit = $pagination->reverse_limit($start, $sql_limit, $num_files); + $sql_start = $pagination->reverse_start($start, $sql_limit, $num_files); } else { @@ -1195,7 +1190,6 @@ class acp_attachments $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(); @@ -1222,13 +1216,12 @@ class acp_attachments $db->sql_freeresult($result); $base_url = $this->u_action . "&$u_sort_param"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $num_files, $attachments_per_page, $start); + $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_ON_PAGE' => phpbb_on_page($template, $user, $base_url, $num_files, $attachments_per_page, $start), 'S_LIMIT_DAYS' => $s_limit_days, 'S_SORT_KEY' => $s_sort_key, 'S_SORT_DIR' => $s_sort_dir) diff --git a/phpBB/includes/acp/acp_bbcodes.php b/phpBB/includes/acp/acp_bbcodes.php index 575ac84012..84382b6276 100644 --- a/phpBB/includes/acp/acp_bbcodes.php +++ b/phpBB/includes/acp/acp_bbcodes.php @@ -24,7 +24,7 @@ class acp_bbcodes function main($id, $mode) { - global $db, $user, $auth, $template, $cache, $request; + global $db, $user, $auth, $template, $cache, $request, $phpbb_dispatcher; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; $user->add_lang('acp/posting'); @@ -96,7 +96,7 @@ class acp_bbcodes case 'edit': case 'add': - $template->assign_vars(array( + $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" : ''), @@ -105,10 +105,27 @@ class acp_bbcodes 'BBCODE_MATCH' => $bbcode_match, 'BBCODE_TPL' => $bbcode_tpl, 'BBCODE_HELPLINE' => $bbcode_helpline, - 'DISPLAY_ON_POSTING' => $display_on_posting) + '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( @@ -124,6 +141,27 @@ class acp_bbcodes 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)) { @@ -178,7 +216,7 @@ class acp_bbcodes trigger_error($user->lang['BBCODE_HELPLINE_TOO_LONG'] . adm_back_link($this->u_action), E_USER_WARNING); } - $sql_ary = array( + $sql_ary = array_merge($sql_ary, array( 'bbcode_tag' => $data['bbcode_tag'], 'bbcode_match' => $bbcode_match, 'bbcode_tpl' => $bbcode_tpl, @@ -188,7 +226,7 @@ class acp_bbcodes 'first_pass_replace' => $data['first_pass_replace'], 'second_pass_match' => $data['second_pass_match'], 'second_pass_replace' => $data['second_pass_replace'] - ); + )); if ($action == 'create') { @@ -244,14 +282,14 @@ class acp_bbcodes } else { - confirm_box(false, $user->lang['BBCODE_DANGER'], build_hidden_fields(array( + 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'); } @@ -300,22 +338,57 @@ class acp_bbcodes break; } - $template->assign_vars(array( - 'U_ACTION' => $this->u_action . '&action=add') + $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', ); - $sql = 'SELECT * - FROM ' . BBCODES_TABLE . ' - ORDER BY bbcode_tag'; - $result = $db->sql_query($sql); + /** + * 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)) { - $template->assign_block_vars('bbcodes', array( + $bbcodes_array = array( 'BBCODE_TAG' => $row['bbcode_tag'], - 'U_EDIT' => $this->u_action . '&action=edit&bbcode=' . $row['bbcode_id'], - 'U_DELETE' => $this->u_action . '&action=delete&bbcode=' . $row['bbcode_id']) + '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); } diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php index 029f4b23c9..a1af8c489d 100644 --- a/phpBB/includes/acp/acp_forums.php +++ b/phpBB/includes/acp/acp_forums.php @@ -926,7 +926,7 @@ class acp_forums */ function update_forum_data(&$forum_data) { - global $db, $user, $cache, $phpbb_root_path, $phpbb_dispatcher; + global $db, $user, $cache, $phpbb_root_path, $phpbb_container, $phpbb_dispatcher; $errors = array(); @@ -1030,7 +1030,10 @@ class acp_forums } else { - $forum_data_sql['forum_password'] = phpbb_hash($forum_data_sql['forum_password']); + // 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']); diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php index b36ea1a8d8..7ecedcf51e 100644 --- a/phpBB/includes/acp/acp_groups.php +++ b/phpBB/includes/acp/acp_groups.php @@ -676,6 +676,7 @@ class acp_groups } $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 @@ -719,14 +720,13 @@ class acp_groups } $base_url = $this->u_action . "&action=$action&g=$group_id"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total_members, $config['topics_per_page'], $start); + $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, - 'S_ON_PAGE' => phpbb_on_page($template, $user, $base_url, $total_members, $config['topics_per_page'], $start), '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", diff --git a/phpBB/includes/acp/acp_icons.php b/phpBB/includes/acp/acp_icons.php index 658be4cc6b..20b1f56182 100644 --- a/phpBB/includes/acp/acp_icons.php +++ b/phpBB/includes/acp/acp_icons.php @@ -27,7 +27,7 @@ class acp_icons { global $db, $user, $auth, $template, $cache; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; - global $request; + global $request, $phpbb_container; $user->add_lang('acp/posting'); @@ -832,9 +832,10 @@ class acp_icons 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 ($db->sql_affectedrows()) + if ($move_executed) { $sql = "UPDATE $table SET {$fields}_order = $switch_order_id @@ -846,6 +847,14 @@ class acp_icons $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; } @@ -893,6 +902,7 @@ class acp_icons ); $spacer = false; + $pagination = $phpbb_container->get('pagination'); $pagination_start = request_var('start', 0); $item_count = $this->item_count($table); @@ -927,7 +937,7 @@ class acp_icons } $db->sql_freeresult($result); - phpbb_generate_template_pagination($template, $this->u_action, 'pagination', 'start', $item_count, $config['smilies_per_page'], $pagination_start); + $pagination->generate_template_pagination($this->u_action, 'pagination', 'start', $item_count, $config['smilies_per_page'], $pagination_start); } /** diff --git a/phpBB/includes/acp/acp_inactive.php b/phpBB/includes/acp/acp_inactive.php index de4679b58d..140815f06a 100644 --- a/phpBB/includes/acp/acp_inactive.php +++ b/phpBB/includes/acp/acp_inactive.php @@ -30,7 +30,7 @@ class acp_inactive function main($id, $mode) { - global $config, $db, $user, $auth, $template; + 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); @@ -49,6 +49,7 @@ class acp_inactive $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 @@ -285,7 +286,7 @@ class acp_inactive } $base_url = $this->u_action . "&$u_sort_param&users_per_page=$per_page"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $inactive_count, $per_page, $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $inactive_count, $per_page, $start); $template->assign_vars(array( 'S_INACTIVE_USERS' => true, @@ -294,7 +295,6 @@ class acp_inactive 'S_LIMIT_DAYS' => $s_limit_days, 'S_SORT_KEY' => $s_sort_key, 'S_SORT_DIR' => $s_sort_dir, - 'S_ON_PAGE' => phpbb_on_page($template, $user, $base_url, $inactive_count, $per_page, $start), 'USERS_PER_PAGE' => $per_page, 'U_ACTION' => $this->u_action . "&$u_sort_param&users_per_page=$per_page&start=$start", diff --git a/phpBB/includes/acp/acp_logs.php b/phpBB/includes/acp/acp_logs.php index 229bf135ff..10852e3a68 100644 --- a/phpBB/includes/acp/acp_logs.php +++ b/phpBB/includes/acp/acp_logs.php @@ -24,7 +24,7 @@ class acp_logs function main($id, $mode) { - global $db, $user, $auth, $template, $cache; + global $db, $user, $auth, $template, $cache, $phpbb_container; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; global $request; @@ -46,6 +46,7 @@ class acp_logs $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')) @@ -130,15 +131,13 @@ class acp_logs $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"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); + $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_ON_PAGE' => phpbb_on_page($template, $user, $base_url, $log_count, $config['topics_per_page'], $start), - 'S_LIMIT_DAYS' => $s_limit_days, 'S_SORT_KEY' => $s_sort_key, 'S_SORT_DIR' => $s_sort_dir, diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php index eecd8c72dc..f01cba0bcc 100644 --- a/phpBB/includes/acp/acp_main.php +++ b/phpBB/includes/acp/acp_main.php @@ -620,6 +620,22 @@ class acp_main $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); + + 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) diff --git a/phpBB/includes/acp/acp_modules.php b/phpBB/includes/acp/acp_modules.php index 100e33044b..c124377ba9 100644 --- a/phpBB/includes/acp/acp_modules.php +++ b/phpBB/includes/acp/acp_modules.php @@ -170,6 +170,14 @@ class acp_modules $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': diff --git a/phpBB/includes/acp/acp_permission_roles.php b/phpBB/includes/acp/acp_permission_roles.php index 17e48d6576..aca45575d3 100644 --- a/phpBB/includes/acp/acp_permission_roles.php +++ b/phpBB/includes/acp/acp_permission_roles.php @@ -27,6 +27,7 @@ class acp_permission_roles { 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); @@ -46,6 +47,11 @@ class acp_permission_roles $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': @@ -85,11 +91,6 @@ class acp_permission_roles { case 'remove': - if (!$role_id) - { - trigger_error($user->lang['NO_ROLE_SELECTED'] . adm_back_link($this->u_action), E_USER_WARNING); - } - $sql = 'SELECT * FROM ' . ACL_ROLES_TABLE . ' WHERE role_id = ' . $role_id; @@ -123,10 +124,6 @@ class acp_permission_roles break; case 'edit': - if (!$role_id) - { - trigger_error($user->lang['NO_ROLE_SELECTED'] . adm_back_link($this->u_action), E_USER_WARNING); - } // Get role we edit $sql = 'SELECT * @@ -273,12 +270,7 @@ class acp_permission_roles case 'edit': if ($action == 'edit') - { - if (!$role_id) - { - trigger_error($user->lang['NO_ROLE_SELECTED'] . adm_back_link($this->u_action), E_USER_WARNING); - } - + { $sql = 'SELECT * FROM ' . ACL_ROLES_TABLE . ' WHERE role_id = ' . $role_id; @@ -366,7 +358,18 @@ class acp_permission_roles case 'move_up': case 'move_down': - $order = request_var('order', 0); + $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 . ' @@ -375,6 +378,14 @@ class acp_permission_roles 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; } @@ -421,8 +432,8 @@ class acp_permission_roles '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&order=' . $row['role_order'], - 'U_MOVE_DOWN' => $this->u_action . '&action=move_down&order=' . $row['role_order'], + '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') ); diff --git a/phpBB/includes/acp/acp_profile.php b/phpBB/includes/acp/acp_profile.php index 4e8145009f..3a5298fb58 100644 --- a/phpBB/includes/acp/acp_profile.php +++ b/phpBB/includes/acp/acp_profile.php @@ -24,37 +24,34 @@ class acp_profile 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; + global $request, $phpbb_container; include($phpbb_root_path . 'includes/functions_posting.' . $phpEx); include($phpbb_root_path . 'includes/functions_user.' . $phpEx); - include($phpbb_root_path . 'includes/functions_profile_fields.' . $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 = ''; - // Define some default values for each field type - $default_values = array( - FIELD_STRING => array('field_length' => 10, 'field_minlen' => 0, 'field_maxlen' => 20, 'field_validation' => '.*', 'field_novalue' => '', 'field_default_value' => ''), - FIELD_TEXT => array('field_length' => '5|80', 'field_minlen' => 0, 'field_maxlen' => 1000, 'field_validation' => '.*', 'field_novalue' => '', 'field_default_value' => ''), - FIELD_INT => array('field_length' => 5, 'field_minlen' => 0, 'field_maxlen' => 100, 'field_validation' => '', 'field_novalue' => 0, 'field_default_value' => 0), - FIELD_DATE => array('field_length' => 10, 'field_minlen' => 10, 'field_maxlen' => 10, 'field_validation' => '', 'field_novalue' => ' 0- 0- 0', 'field_default_value' => ' 0- 0- 0'), - FIELD_BOOL => array('field_length' => 1, 'field_minlen' => 0, 'field_maxlen' => 0, 'field_validation' => '', 'field_novalue' => 0, 'field_default_value' => 0), - FIELD_DROPDOWN => array('field_length' => 0, 'field_minlen' => 0, 'field_maxlen' => 5, 'field_validation' => '', 'field_novalue' => 0, 'field_default_value' => 0), - ); + 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 = new custom_profile_admin(); + $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 @@ -88,22 +85,16 @@ class acp_profile // Have some fields been defined? if (isset($this->lang_defs['entry'])) { - foreach ($this->lang_defs['entry'] as $field_id => $field_ary) + 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_id] = array_diff(array_values($this->lang_defs['iso']), $field_ary); + $this->lang_defs['diff'][$field_ident] = array_diff(array_values($this->lang_defs['iso']), $field_ary); } } switch ($action) { case 'delete': - $field_id = request_var('field_id', 0); - - if (!$field_id) - { - trigger_error($user->lang['NO_FIELD_ID'] . adm_back_link($this->u_action), E_USER_WARNING); - } if (confirm_box(true)) { @@ -210,12 +201,6 @@ class acp_profile break; case 'activate': - $field_id = request_var('field_id', 0); - - if (!$field_id) - { - trigger_error($user->lang['NO_FIELD_ID'] . adm_back_link($this->u_action), E_USER_WARNING); - } $sql = 'SELECT lang_id FROM ' . LANG_TABLE . " @@ -256,12 +241,6 @@ class acp_profile break; case 'deactivate': - $field_id = request_var('field_id', 0); - - if (!$field_id) - { - trigger_error($user->lang['NO_FIELD_ID'] . adm_back_link($this->u_action), E_USER_WARNING); - } $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . " SET field_active = 0 @@ -291,7 +270,19 @@ class acp_profile case 'move_up': case 'move_down': - $field_order = request_var('order', 0); + + $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 . " @@ -299,12 +290,19 @@ class acp_profile 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': - $field_id = request_var('field_id', 0); $step = request_var('step', 1); $submit = (isset($_REQUEST['next']) || isset($_REQUEST['prev'])) ? true : false; @@ -316,11 +314,6 @@ class acp_profile // We are editing... we need to grab basic things if ($action == 'edit') { - if (!$field_id) - { - trigger_error($user->lang['NO_FIELD_ID'] . adm_back_link($this->u_action), E_USER_WARNING); - } - $sql = 'SELECT l.*, f.* FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f WHERE l.lang_id = ' . $this->edit_lang_id . " @@ -350,6 +343,7 @@ class acp_profile $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 * @@ -373,14 +367,15 @@ class acp_profile // We are adding a new field, define basic params $lang_options = $field_row = array(); - $field_type = request_var('field_type', 0); + $field_type = request_var('field_type', ''); - if (!$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); } - $field_row = array_merge($default_values[$field_type], array( + $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, @@ -390,6 +385,7 @@ class acp_profile 'field_show_on_reg' => 0, 'field_show_on_pm' => 0, 'field_show_on_vt' => 0, + 'field_show_on_ml' => 0, 'lang_name' => utf8_normalize_nfc(request_var('field_ident', '', true)), 'lang_explain' => '', 'lang_default_value'=> '') @@ -400,28 +396,11 @@ class acp_profile // $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_required', 'field_show_novalue', 'field_hide', 'field_show_profile', 'field_no_view'), + 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'), 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') ); - // Text-based fields require the lang_default_value to be excluded - if ($field_type == FIELD_STRING || $field_type == FIELD_TEXT) - { - $exclude[1][] = 'lang_default_value'; - } - - // option-specific fields require lang_options to be excluded - if ($field_type == FIELD_BOOL || $field_type == FIELD_DROPDOWN) - { - $exclude[1][] = 'lang_options'; - } - - $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'] = utf8_normalize_nfc(request_var('lang_name', $field_row['lang_name'], true)); - $cp->vars['lang_explain'] = utf8_normalize_nfc(request_var('lang_explain', $field_row['lang_explain'], true)); - $cp->vars['lang_default_value'] = utf8_normalize_nfc(request_var('lang_default_value', $field_row['lang_default_value'], true)); - // Visibility Options... $visibility_ary = array( 'field_required', @@ -429,10 +408,18 @@ class acp_profile 'field_show_on_reg', 'field_show_on_pm', 'field_show_on_vt', + 'field_show_on_ml', 'field_show_profile', 'field_hide', ); + $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'] = utf8_normalize_nfc(request_var('lang_name', $field_row['lang_name'], true)); + $cp->vars['lang_explain'] = utf8_normalize_nfc(request_var('lang_explain', $field_row['lang_explain'], true)); + $cp->vars['lang_default_value'] = utf8_normalize_nfc(request_var('lang_default_value', $field_row['lang_default_value'], true)); + foreach ($visibility_ary as $val) { $cp->vars[$val] = ($submit || $save) ? request_var($val, 0) : $field_row[$val]; @@ -440,16 +427,6 @@ class acp_profile $cp->vars['field_no_view'] = request_var('field_no_view', (int) $field_row['field_no_view']); - // A boolean field expects an array as the lang options - if ($field_type == FIELD_BOOL) - { - $options = utf8_normalize_nfc(request_var('lang_options', array(''), true)); - } - else - { - $options = utf8_normalize_nfc(request_var('lang_options', '', true)); - } - // If the user has submitted a form with options (i.e. dropdown field) if ($options) { @@ -477,93 +454,9 @@ class acp_profile { $var = utf8_normalize_nfc(request_var($key, $field_row[$key], true)); - // Manipulate the intended variables a little bit if needed - if ($field_type == FIELD_DROPDOWN && $key == 'field_maxlen') - { - // Get the number of options if this key is 'field_maxlen' - $var = sizeof(explode("\n", utf8_normalize_nfc(request_var('lang_options', '', true)))); - } - else if ($field_type == FIELD_TEXT && $key == 'field_length') - { - if (isset($_REQUEST['rows'])) - { - $cp->vars['rows'] = request_var('rows', 0); - $cp->vars['columns'] = request_var('columns', 0); - $var = $cp->vars['rows'] . '|' . $cp->vars['columns']; - } - else - { - $row_col = explode('|', $var); - $cp->vars['rows'] = $row_col[0]; - $cp->vars['columns'] = $row_col[1]; - } - } - else if ($field_type == FIELD_DATE && $key == 'field_default_value') - { - $always_now = request_var('always_now', -1); - - if ($always_now == 1 || ($always_now === -1 && $var == 'now')) - { - $now = getdate(); - - $cp->vars['field_default_value_day'] = $now['mday']; - $cp->vars['field_default_value_month'] = $now['mon']; - $cp->vars['field_default_value_year'] = $now['year']; - $var = 'now'; - $request->overwrite('field_default_value', $var, \phpbb\request\request_interface::POST); - } - else - { - if (isset($_REQUEST['field_default_value_day'])) - { - $cp->vars['field_default_value_day'] = request_var('field_default_value_day', 0); - $cp->vars['field_default_value_month'] = request_var('field_default_value_month', 0); - $cp->vars['field_default_value_year'] = request_var('field_default_value_year', 0); - $var = sprintf('%2d-%2d-%4d', $cp->vars['field_default_value_day'], $cp->vars['field_default_value_month'], $cp->vars['field_default_value_year']); - $request->overwrite('field_default_value', $var, \phpbb\request\request_interface::POST); - } - else - { - list($cp->vars['field_default_value_day'], $cp->vars['field_default_value_month'], $cp->vars['field_default_value_year']) = explode('-', $var); - } - } - } - else if ($field_type == FIELD_BOOL && $key == 'field_default_value') - { - // 'field_length' == 1 defines radio buttons. Possible values are 1 or 2 only. - // 'field_length' == 2 defines checkbox. Possible values are 0 or 1 only. - // If we switch the type on step 2, we have to adjust field value. - // 1 is a common value for the checkbox and radio buttons. - - // Adjust unchecked checkbox value. - // If we return or save settings from 2nd/3rd page - // and the checkbox is unchecked, set the value to 0. - if (isset($_REQUEST['step']) && !isset($_REQUEST[$key])) - { - $var = 0; - } - - // If we switch to the checkbox type but former radio buttons value was 2, - // which is not the case for the checkbox, set it to 0 (unchecked). - if ($cp->vars['field_length'] == 2 && $var == 2) - { - $var = 0; - } - // If we switch to the radio buttons but the former checkbox value was 0, - // which is not the case for the radio buttons, set it to 0. - else if ($cp->vars['field_length'] == 1 && $var == 0) - { - $var = 2; - } - } - else if ($field_type == FIELD_INT && $key == 'field_default_value') - { - // Permit an empty string - if ($action == 'create' && request_var('field_default_value', '') === '') - { - $var = ''; - } - } + $field_data = $cp->vars; + $var = $profile_field->get_excluded_options($key, $action, $var, $field_data, 2); + $cp->vars = $field_data; $cp->vars[$key] = $var; } @@ -612,18 +505,10 @@ class acp_profile { $cp->vars[$key] = $$key; } - else if ($key == 'l_lang_options' && $field_type == FIELD_BOOL) - { - $cp->vars[$key] = utf8_normalize_nfc(request_var($key, array(0 => array('')), true)); - } - else if ($key == 'l_lang_options' && is_array($cp->vars[$key])) - { - foreach ($cp->vars[$key] as $lang_id => $options) - { - $cp->vars[$key][$lang_id] = explode("\n", $options); - } - } + $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 @@ -650,15 +535,7 @@ class acp_profile $error[] = $user->lang['EMPTY_USER_FIELD_NAME']; } - if ($field_type == FIELD_DROPDOWN && !sizeof($cp->vars['lang_options'])) - { - $error[] = $user->lang['NO_FIELD_ENTRIES']; - } - - if ($field_type == FIELD_BOOL && (empty($cp->vars['lang_options'][0]) || empty($cp->vars['lang_options'][1]))) - { - $error[] = $user->lang['NO_FIELD_ENTRIES']; - } + $error = $profile_field->validate_options_on_submit($error, $cp->vars); // Check for already existing field ident if ($action != 'edit') @@ -695,54 +572,16 @@ class acp_profile $_new_key_ary = array(); + $field_data = $cp->vars; foreach ($key_ary as $key) { - if ($field_type == FIELD_TEXT && $key == 'field_length' && isset($_REQUEST['rows'])) - { - $cp->vars['rows'] = request_var('rows', 0); - $cp->vars['columns'] = request_var('columns', 0); - $_new_key_ary[$key] = $cp->vars['rows'] . '|' . $cp->vars['columns']; - } - else if ($field_type == FIELD_DATE && $key == 'field_default_value') - { - $always_now = request_var('always_now', 0); - - if ($always_now) - { - $_new_key_ary[$key] = 'now'; - } - else if (isset($_REQUEST['field_default_value_day'])) - { - $cp->vars['field_default_value_day'] = request_var('field_default_value_day', 0); - $cp->vars['field_default_value_month'] = request_var('field_default_value_month', 0); - $cp->vars['field_default_value_year'] = request_var('field_default_value_year', 0); - $_new_key_ary[$key] = sprintf('%2d-%2d-%4d', $cp->vars['field_default_value_day'], $cp->vars['field_default_value_month'], $cp->vars['field_default_value_year']); - } - } - else if ($field_type == FIELD_BOOL && $key == 'l_lang_options' && isset($_REQUEST['l_lang_options'])) - { - $_new_key_ary[$key] = utf8_normalize_nfc(request_var($key, array(array('')), true)); - } - else if ($field_type == FIELD_BOOL && $key == 'field_default_value') + $var = $profile_field->prepare_hidden_fields($step, $key, $action, $field_data); + if ($var !== null) { - $_new_key_ary[$key] = request_var($key, $cp->vars[$key]); - } - else - { - if (!isset($_REQUEST[$key])) - { - $var = false; - } - else if ($key == 'field_ident' && isset($cp->vars[$key])) - { - $_new_key_ary[$key]= $cp->vars[$key]; - } - else - { - $_new_key_ary[$key] = ($field_type == FIELD_BOOL && $key == 'lang_options') ? utf8_normalize_nfc(request_var($key, array(''), true)) : utf8_normalize_nfc(request_var($key, '', true)); - } + $_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); } @@ -776,67 +615,31 @@ class acp_profile { // Create basic options - only small differences between field types case 1: - - // Build common create options - $template->assign_vars(array( + $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, 'L_LANG_SPECIFIC' => sprintf($user->lang['LANG_SPECIFIC_OPTIONS'], $config['default_lang']), - 'FIELD_TYPE' => $user->lang['FIELD_' . strtoupper($cp->profile_types[$field_type])], + 'FIELD_TYPE' => $profile_field->get_name(), 'FIELD_IDENT' => $cp->vars['field_ident'], 'LANG_NAME' => $cp->vars['lang_name'], - 'LANG_EXPLAIN' => $cp->vars['lang_explain']) + 'LANG_EXPLAIN' => $cp->vars['lang_explain'], ); - // String and Text needs to set default values here... - if ($field_type == FIELD_STRING || $field_type == FIELD_TEXT) - { - $template->assign_vars(array( - 'S_TEXT' => ($field_type == FIELD_TEXT) ? true : false, - 'S_STRING' => ($field_type == FIELD_STRING) ? true : false, - - 'L_DEFAULT_VALUE_EXPLAIN' => $user->lang[strtoupper($cp->profile_types[$field_type]) . '_DEFAULT_VALUE_EXPLAIN'], - 'LANG_DEFAULT_VALUE' => $cp->vars['lang_default_value']) - ); - } - - if ($field_type == FIELD_BOOL || $field_type == FIELD_DROPDOWN) - { - // Initialize these array elements if we are creating a new field - if (!sizeof($cp->vars['lang_options'])) - { - if ($field_type == FIELD_BOOL) - { - // No options have been defined for a boolean field. - $cp->vars['lang_options'][0] = ''; - $cp->vars['lang_options'][1] = ''; - } - else - { - // No options have been defined for the dropdown menu - $cp->vars['lang_options'] = array(); - } - } - - $template->assign_vars(array( - 'S_BOOL' => ($field_type == FIELD_BOOL) ? true : false, - 'S_DROPDOWN' => ($field_type == FIELD_DROPDOWN) ? true : false, - - 'L_LANG_OPTIONS_EXPLAIN' => $user->lang[strtoupper($cp->profile_types[$field_type]) . '_ENTRIES_EXPLAIN'], - 'LANG_OPTIONS' => ($field_type == FIELD_DROPDOWN) ? implode("\n", $cp->vars['lang_options']) : '', - 'FIRST_LANG_OPTION' => ($field_type == FIELD_BOOL) ? $cp->vars['lang_options'][0] : '', - 'SECOND_LANG_OPTION' => ($field_type == FIELD_BOOL) ? $cp->vars['lang_options'][1] : '') - ); - } + $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: @@ -847,8 +650,7 @@ class acp_profile ); // Build options based on profile type - $function = 'get_' . $cp->profile_types[$field_type] . '_options'; - $options = $cp->$function(); + $options = $profile_field->get_options($this->lang_defs['iso'][$config['default_lang']], $cp->vars); foreach ($options as $num => $option_ary) { @@ -910,17 +712,18 @@ class acp_profile $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' => $user->lang['FIELD_' . strtoupper($cp->profile_types[$row['field_type']])], + '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&order={$row['field_order']}", - 'U_MOVE_DOWN' => $this->u_action . "&action=move_down&order={$row['field_order']}", + '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) ); @@ -934,15 +737,15 @@ class acp_profile } $s_select_type = ''; - foreach ($cp->profile_types as $key => $value) + foreach ($this->type_collection as $key => $profile_field) { - $s_select_type .= '<option value="' . $key . '">' . $user->lang['FIELD_' . strtoupper($value)] . '</option>'; + $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) - ); + 'S_TYPE_OPTIONS' => $s_select_type, + )); } /** @@ -950,7 +753,7 @@ class acp_profile */ function build_language_options(&$cp, $field_type, $action = 'create') { - global $user, $config, $db; + 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']]; @@ -967,31 +770,8 @@ class acp_profile } $db->sql_freeresult($result); - $options = array(); - $options['lang_name'] = 'string'; - if ($cp->vars['lang_explain']) - { - $options['lang_explain'] = 'text'; - } - - switch ($field_type) - { - case FIELD_BOOL: - $options['lang_options'] = 'two_options'; - break; - - case FIELD_DROPDOWN: - $options['lang_options'] = 'optionfield'; - break; - - case FIELD_TEXT: - case FIELD_STRING: - if (strlen($cp->vars['lang_default_value'])) - { - $options['lang_default_value'] = ($field_type == FIELD_STRING) ? 'string' : 'text'; - } - break; - } + $profile_field = $this->type_collection[$field_type]; + $options = $profile_field->get_language_options($cp->vars); $lang_options = array(); @@ -1070,7 +850,7 @@ class acp_profile */ function save_profile_field(&$cp, $field_type, $action = 'create') { - global $db, $config, $user; + global $db, $config, $user, $phpbb_container; $field_id = request_var('field_id', 0); @@ -1103,6 +883,7 @@ class acp_profile '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'] @@ -1131,10 +912,16 @@ class acp_profile $db->sql_query($sql); } + $profile_field = $this->type_collection[$field_type]; + if ($action == 'create') { $field_ident = 'pf_' . $field_ident; - $profile_sql[] = $this->add_field_ident($field_ident, $field_type); + + $db_tools = $phpbb_container->get('dbal.tools'); + + list($sql_type, $null) = $db_tools->get_column_type($profile_field->get_database_column_type()); + $profile_sql[] = $this->add_field_ident($field_ident, $sql_type); } $sql_ary = array( @@ -1188,23 +975,7 @@ class acp_profile } } - // These are always arrays because the key is the language id... - $cp->vars['l_lang_name'] = utf8_normalize_nfc(request_var('l_lang_name', array(0 => ''), true)); - $cp->vars['l_lang_explain'] = utf8_normalize_nfc(request_var('l_lang_explain', array(0 => ''), true)); - $cp->vars['l_lang_default_value'] = utf8_normalize_nfc(request_var('l_lang_default_value', array(0 => ''), true)); - - if ($field_type != FIELD_BOOL) - { - $cp->vars['l_lang_options'] = utf8_normalize_nfc(request_var('l_lang_options', array(0 => ''), true)); - } - else - { - /** - * @todo check if this line is correct... - $cp->vars['l_lang_default_value'] = request_var('l_lang_default_value', array(0 => array('')), true); - */ - $cp->vars['l_lang_options'] = utf8_normalize_nfc(request_var('l_lang_options', array(0 => array('')), true)); - } + $cp->vars = $profile_field->get_language_options_input($cp->vars); if ($cp->vars['lang_options']) { @@ -1224,7 +995,7 @@ class acp_profile foreach ($cp->vars['lang_options'] as $option_id => $value) { $sql_ary = array( - 'field_type' => (int) $field_type, + 'field_type' => $field_type, 'lang_value' => $value ); @@ -1279,7 +1050,7 @@ class acp_profile 'field_id' => (int) $field_id, 'lang_id' => (int) $lang_id, 'option_id' => (int) $option_id, - 'field_type' => (int) $field_type, + 'field_type' => $field_type, 'lang_value' => $value ); } @@ -1409,7 +1180,7 @@ class acp_profile /** * Return sql statement for adding a new field ident (profile field) to the profile fields data table */ - function add_field_ident($field_ident, $field_type) + function add_field_ident($field_ident, $sql_type) { global $db; @@ -1418,73 +1189,11 @@ class acp_profile case 'mysql': case 'mysql4': case 'mysqli': - - // We are defining the biggest common value, because of the possibility to edit the min/max values of each field. - $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD `$field_ident` "; - - switch ($field_type) - { - case FIELD_STRING: - $sql .= ' VARCHAR(255) '; - break; - - case FIELD_DATE: - $sql .= 'VARCHAR(10) '; - break; - - case FIELD_TEXT: - $sql .= "TEXT"; - // ADD {$field_ident}_bbcode_uid VARCHAR(5) NOT NULL, - // ADD {$field_ident}_bbcode_bitfield INT(11) UNSIGNED"; - break; - - case FIELD_BOOL: - $sql .= 'TINYINT(2) '; - break; - - case FIELD_DROPDOWN: - $sql .= 'MEDIUMINT(8) '; - break; - - case FIELD_INT: - $sql .= 'BIGINT(20) '; - break; - } + $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD `$field_ident` " . $sql_type; break; case 'sqlite': - - switch ($field_type) - { - case FIELD_STRING: - $type = ' VARCHAR(255) '; - break; - - case FIELD_DATE: - $type = 'VARCHAR(10) '; - break; - - case FIELD_TEXT: - $type = "TEXT(65535)"; - // ADD {$field_ident}_bbcode_uid VARCHAR(5) NOT NULL, - // ADD {$field_ident}_bbcode_bitfield INT(11) UNSIGNED"; - break; - - case FIELD_BOOL: - $type = 'TINYINT(2) '; - break; - - case FIELD_DROPDOWN: - $type = 'MEDIUMINT(8) '; - break; - - case FIELD_INT: - $type = 'BIGINT(20) '; - break; - } - - // We are defining the biggest common value, because of the possibility to edit the min/max values of each field. if (version_compare(sqlite_libversion(), '3.0') == -1) { $sql = "SELECT sql @@ -1519,7 +1228,7 @@ class acp_profile $columns = implode(',', $column_list); - $new_table_cols = $field_ident . ' ' . $type . ',' . $new_table_cols; + $new_table_cols = $field_ident . ' ' . $sql_type . ',' . $new_table_cols; // create a new table and fill it up. destroy the temp one $db->sql_query('CREATE TABLE ' . PROFILE_FIELDS_DATA_TABLE . ' (' . $new_table_cols . ');'); @@ -1528,7 +1237,7 @@ class acp_profile } else { - $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD $field_ident [$type]"; + $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD $field_ident [$sql_type]"; } break; @@ -1536,140 +1245,22 @@ class acp_profile case 'mssql': case 'mssql_odbc': case 'mssqlnative': - - // We are defining the biggest common value, because of the possibility to edit the min/max values of each field. - $sql = 'ALTER TABLE [' . PROFILE_FIELDS_DATA_TABLE . "] ADD [$field_ident] "; - - switch ($field_type) - { - case FIELD_STRING: - $sql .= ' [VARCHAR] (255) '; - break; - - case FIELD_DATE: - $sql .= '[VARCHAR] (10) '; - break; - - case FIELD_TEXT: - $sql .= "[TEXT]"; - // ADD {$field_ident}_bbcode_uid [VARCHAR] (5) NOT NULL, - // ADD {$field_ident}_bbcode_bitfield [INT] UNSIGNED"; - break; - - case FIELD_BOOL: - case FIELD_DROPDOWN: - $sql .= '[INT] '; - break; - - case FIELD_INT: - $sql .= '[FLOAT] '; - break; - } + $sql = 'ALTER TABLE [' . PROFILE_FIELDS_DATA_TABLE . "] ADD [$field_ident] " . $sql_type; break; case 'postgres': - - // We are defining the biggest common value, because of the possibility to edit the min/max values of each field. - $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD COLUMN \"$field_ident\" "; - - switch ($field_type) - { - case FIELD_STRING: - $sql .= ' VARCHAR(255) '; - break; - - case FIELD_DATE: - $sql .= 'VARCHAR(10) '; - break; - - case FIELD_TEXT: - $sql .= "TEXT"; - // ADD {$field_ident}_bbcode_uid VARCHAR(5) NOT NULL, - // ADD {$field_ident}_bbcode_bitfield INT4 UNSIGNED"; - break; - - case FIELD_BOOL: - $sql .= 'INT2 '; - break; - - case FIELD_DROPDOWN: - $sql .= 'INT4 '; - break; - - case FIELD_INT: - $sql .= 'INT8 '; - break; - } + $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD COLUMN \"$field_ident\" " . $sql_type; break; case 'firebird': - - // We are defining the biggest common value, because of the possibility to edit the min/max values of each field. - $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . ' ADD "' . strtoupper($field_ident) . '" '; - - switch ($field_type) - { - case FIELD_STRING: - $sql .= ' VARCHAR(255) '; - break; - - case FIELD_DATE: - $sql .= 'VARCHAR(10) '; - break; - - case FIELD_TEXT: - $sql .= "BLOB SUB_TYPE TEXT"; - // ADD {$field_ident}_bbcode_uid VARCHAR(5) NOT NULL, - // ADD {$field_ident}_bbcode_bitfield INTEGER UNSIGNED"; - break; - - case FIELD_BOOL: - case FIELD_DROPDOWN: - $sql .= 'INTEGER '; - break; - - case FIELD_INT: - $sql .= 'DOUBLE PRECISION '; - break; - } + $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . ' ADD "' . strtoupper($field_ident) . '" ' . $sql_type; break; case 'oracle': - - // We are defining the biggest common value, because of the possibility to edit the min/max values of each field. - $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD $field_ident "; - - switch ($field_type) - { - case FIELD_STRING: - $sql .= ' VARCHAR2(255) '; - break; - - case FIELD_DATE: - $sql .= 'VARCHAR2(10) '; - break; - - case FIELD_TEXT: - $sql .= "CLOB"; - // ADD {$field_ident}_bbcode_uid VARCHAR2(5) NOT NULL, - // ADD {$field_ident}_bbcode_bitfield NUMBER(11) UNSIGNED"; - break; - - case FIELD_BOOL: - $sql .= 'NUMBER(2) '; - break; - - case FIELD_DROPDOWN: - $sql .= 'NUMBER(8) '; - break; - - case FIELD_INT: - $sql .= 'NUMBER(20) '; - break; - } + $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD $field_ident " . $sql_type; break; } diff --git a/phpBB/includes/acp/acp_reasons.php b/phpBB/includes/acp/acp_reasons.php index 71e9108c2c..569bb73ab0 100644 --- a/phpBB/includes/acp/acp_reasons.php +++ b/phpBB/includes/acp/acp_reasons.php @@ -26,6 +26,7 @@ class acp_reasons { global $db, $user, $auth, $template, $cache; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; + global $request; $user->add_lang(array('mcp', 'acp/posting')); @@ -280,7 +281,18 @@ class acp_reasons case 'move_up': case 'move_down': - $order = request_var('order', 0); + $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 . ' @@ -288,6 +300,13 @@ class acp_reasons 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; } @@ -363,8 +382,8 @@ class acp_reasons '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&order=' . $row['reason_order'], - 'U_MOVE_DOWN' => $this->u_action . '&action=move_down&order=' . $row['reason_order']) + '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); diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 1a7bc2d186..87582dcedb 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -824,9 +824,12 @@ class acp_users $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'] && !phpbb_check_hash($data['new_password'], $user_row['user_password'])) ? true : 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)) @@ -910,7 +913,7 @@ class acp_users if ($update_password) { $sql_ary += array( - 'user_password' => phpbb_hash($data['new_password']), + 'user_password' => $passwords_manager->hash($data['new_password']), 'user_passchg' => time(), 'user_pass_convert' => 0, ); @@ -1096,6 +1099,7 @@ class acp_users $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); @@ -1166,11 +1170,10 @@ class acp_users $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"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); $template->assign_vars(array( 'S_FEEDBACK' => true, - 'S_ON_PAGE' => phpbb_on_page($template, $user, $base_url, $log_count, $config['topics_per_page'], $start), 'S_LIMIT_DAYS' => $s_limit_days, 'S_SORT_KEY' => $s_sort_key, @@ -1342,9 +1345,8 @@ class acp_users case 'profile': include($phpbb_root_path . 'includes/functions_user.' . $phpEx); - include($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); - $cp = new custom_profile(); + $cp = $phpbb_container->get('profilefields.manager'); $cp_data = $cp_error = array(); @@ -1364,9 +1366,6 @@ class acp_users 'yim' => request_var('yim', $user_row['user_yim']), 'jabber' => utf8_normalize_nfc(request_var('jabber', $user_row['user_jabber'], true)), 'website' => request_var('website', $user_row['user_website']), - 'location' => utf8_normalize_nfc(request_var('location', $user_row['user_from'], true)), - 'occupation' => utf8_normalize_nfc(request_var('occupation', $user_row['user_occ'], true)), - 'interests' => utf8_normalize_nfc(request_var('interests', $user_row['user_interests'], true)), 'bday_day' => 0, 'bday_month' => 0, 'bday_year' => 0, @@ -1398,9 +1397,6 @@ class acp_users 'website' => array( array('string', true, 12, 255), array('match', true, '#^http[s]?://(.*?\.)*?[a-z0-9\-]+\.[a-z]{2,4}#i')), - 'location' => array('string', true, 2, 100), - 'occupation' => array('string', true, 2, 500), - 'interests' => array('string', true, 2, 500), 'bday_day' => array('num', true, 1, 31), 'bday_month' => array('num', true, 1, 12), 'bday_year' => array('num', true, 1901, gmdate('Y', time())), @@ -1428,9 +1424,6 @@ class acp_users 'user_yim' => $data['yim'], 'user_jabber' => $data['jabber'], 'user_website' => $data['website'], - 'user_from' => $data['location'], - 'user_occ' => $data['occupation'], - 'user_interests'=> $data['interests'], 'user_birthday' => $data['user_birthday'], ); @@ -1480,9 +1473,6 @@ class acp_users 'MSN' => $data['msn'], 'JABBER' => $data['jabber'], 'WEBSITE' => $data['website'], - 'LOCATION' => $data['location'], - 'OCCUPATION' => $data['occupation'], - 'INTERESTS' => $data['interests'], 'S_BIRTHDAY_DAY_OPTIONS' => $s_birthday_day_options, 'S_BIRTHDAY_MONTH_OPTIONS' => $s_birthday_month_options, @@ -1998,6 +1988,7 @@ class acp_users $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'); @@ -2134,11 +2125,10 @@ class acp_users $db->sql_freeresult($result); $base_url = $this->u_action . "&u=$user_id&sk=$sort_key&sd=$sort_dir"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $num_attachments, $config['topics_per_page'], $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $num_attachments, $config['topics_per_page'], $start); $template->assign_vars(array( 'S_ATTACHMENTS' => true, - 'S_ON_PAGE' => phpbb_on_page($template, $user, $base_url, $num_attachments, $config['topics_per_page'], $start), 'S_SORT_KEY' => $s_sort_key, 'S_SORT_DIR' => $s_sort_dir, )); diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php index 855b6ff187..c2c7ca0abd 100644 --- a/phpBB/includes/constants.php +++ b/phpBB/includes/constants.php @@ -24,7 +24,7 @@ if (!defined('IN_PHPBB')) */ // phpBB Version -define('PHPBB_VERSION', '3.1.0-a3-dev'); +define('PHPBB_VERSION', '3.1.0-a4-dev'); // QA-related // define('PHPBB_QA', 1); @@ -289,4 +289,3 @@ define('WORDS_TABLE', $table_prefix . 'words'); define('ZEBRA_TABLE', $table_prefix . 'zebra'); // Additional tables - diff --git a/phpBB/includes/db/schema_data.php b/phpBB/includes/db/schema_data.php index 69d39e0f8c..0447895433 100644 --- a/phpBB/includes/db/schema_data.php +++ b/phpBB/includes/db/schema_data.php @@ -318,7 +318,7 @@ $schema_data['phpbb_forums'] = array( 'forum_desc_options' => array('UINT:11', 7), 'forum_desc_uid' => array('VCHAR:8', ''), 'forum_link' => array('VCHAR_UNI', ''), - 'forum_password' => array('VCHAR_UNI:40', ''), + 'forum_password' => array('VCHAR_UNI', ''), 'forum_style' => array('UINT', 0), 'forum_image' => array('VCHAR', ''), 'forum_rules' => array('TEXT_UNI', ''), @@ -758,7 +758,7 @@ $schema_data['phpbb_profile_fields'] = array( 'COLUMNS' => array( 'field_id' => array('UINT', NULL, 'auto_increment'), 'field_name' => array('VCHAR_UNI', ''), - 'field_type' => array('TINT:4', 0), + 'field_type' => array('VCHAR:100', ''), 'field_ident' => array('VCHAR:20', ''), 'field_length' => array('VCHAR:20', ''), 'field_minlen' => array('VCHAR', ''), @@ -771,6 +771,7 @@ $schema_data['phpbb_profile_fields'] = array( 'field_show_on_reg' => array('BOOL', 0), 'field_show_on_pm' => array('BOOL', 0), 'field_show_on_vt' => array('BOOL', 0), + 'field_show_on_ml' => array('BOOL', 0), 'field_show_profile' => array('BOOL', 0), 'field_hide' => array('BOOL', 0), 'field_no_view' => array('BOOL', 0), @@ -787,6 +788,9 @@ $schema_data['phpbb_profile_fields'] = array( $schema_data['phpbb_profile_fields_data'] = array( 'COLUMNS' => array( 'user_id' => array('UINT', 0), + 'pf_phpbb_location' => array('VCHAR', ''), + 'pf_phpbb_interests' => array('TEXT_UNI', ''), + 'pf_phpbb_occupation' => array('TEXT_UNI', ''), ), 'PRIMARY_KEY' => 'user_id', ); @@ -796,7 +800,7 @@ $schema_data['phpbb_profile_fields_lang'] = array( 'field_id' => array('UINT', 0), 'lang_id' => array('UINT', 0), 'option_id' => array('UINT', 0), - 'field_type' => array('TINT:4', 0), + 'field_type' => array('VCHAR:100', ''), 'lang_value' => array('VCHAR_UNI', ''), ), 'PRIMARY_KEY' => array('field_id', 'lang_id', 'option_id'), @@ -1112,9 +1116,11 @@ $schema_data['phpbb_users'] = array( 'user_regdate' => array('TIMESTAMP', 0), 'username' => array('VCHAR_CI', ''), 'username_clean' => array('VCHAR_CI', ''), - 'user_password' => array('VCHAR_UNI:40', ''), + 'user_password' => array('VCHAR_UNI', ''), 'user_passchg' => array('TIMESTAMP', 0), 'user_pass_convert' => array('BOOL', 0), + 'user_actkey' => array('VCHAR:32', ''), + 'user_newpasswd' => array('VCHAR_UNI', ''), 'user_email' => array('VCHAR_UNI:100', ''), 'user_email_hash' => array('BINT', 0), 'user_birthday' => array('VCHAR:10', ''), @@ -1163,17 +1169,12 @@ $schema_data['phpbb_users'] = array( 'user_sig' => array('MTEXT_UNI', ''), 'user_sig_bbcode_uid' => array('VCHAR:8', ''), 'user_sig_bbcode_bitfield' => array('VCHAR:255', ''), - 'user_from' => array('VCHAR_UNI:100', ''), 'user_icq' => array('VCHAR:15', ''), 'user_aim' => array('VCHAR_UNI', ''), 'user_yim' => array('VCHAR_UNI', ''), 'user_msnm' => array('VCHAR_UNI', ''), 'user_jabber' => array('VCHAR_UNI', ''), 'user_website' => array('VCHAR_UNI:200', ''), - 'user_occ' => array('TEXT_UNI', ''), - 'user_interests' => array('TEXT_UNI', ''), - 'user_actkey' => array('VCHAR:32', ''), - 'user_newpasswd' => array('VCHAR_UNI:40', ''), 'user_form_salt' => array('VCHAR_UNI:32', ''), 'user_new' => array('BOOL', 1), 'user_reminded' => array('TINT:4', 0), diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 3a915de82b..689a682de3 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -368,73 +368,27 @@ function still_on_time($extra_time = 15) } /** +* Hash the password * -* @version Version 0.1 / slightly modified for phpBB 3.1.x (using $H$ as hash type identifier) -* -* Portable PHP password hashing framework. -* -* Written by Solar Designer <solar at openwall.com> in 2004-2006 and placed in -* the public domain. -* -* There's absolutely no warranty. -* -* The homepage URL for this framework is: -* -* http://www.openwall.com/phpass/ -* -* Please be sure to update the Version line if you edit this file in any way. -* It is suggested that you leave the main version number intact, but indicate -* your project name (after the slash) and add your own revision information. -* -* Please do not change the "private" password hashing method implemented in -* here, thereby making your hashes incompatible. However, if you must, please -* change the hash type identifier (the "$P$") to something different. -* -* Obviously, since this code is in the public domain, the above are not -* requirements (there can be none), but merely suggestions. +* @deprecated 3.1.0-a2 (To be removed: 3.3.0) * +* @param string $password Password to be hashed * -* Hash the password +* @return string|bool Password hash or false if something went wrong during hashing */ function phpbb_hash($password) { - $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; + global $phpbb_container; - $random_state = unique_id(); - $random = ''; - $count = 6; - - if (($fh = @fopen('/dev/urandom', 'rb'))) - { - $random = fread($fh, $count); - fclose($fh); - } - - if (strlen($random) < $count) - { - $random = ''; - - for ($i = 0; $i < $count; $i += 16) - { - $random_state = md5(unique_id() . $random_state); - $random .= pack('H*', md5($random_state)); - } - $random = substr($random, 0, $count); - } - - $hash = _hash_crypt_private($password, _hash_gensalt_private($random, $itoa64), $itoa64); - - if (strlen($hash) == 34) - { - return $hash; - } - - return md5($password); + $passwords_manager = $phpbb_container->get('passwords.manager'); + return $passwords_manager->hash($password); } /** * Check for correct password * +* @deprecated 3.1.0-a2 (To be removed: 3.3.0) +* * @param string $password The password in plain text * @param string $hash The stored password hash * @@ -442,130 +396,10 @@ function phpbb_hash($password) */ function phpbb_check_hash($password, $hash) { - if (strlen($password) > 4096) - { - // If the password is too huge, we will simply reject it - // and not let the server try to hash it. - return false; - } - - $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; - if (strlen($hash) == 34) - { - return (_hash_crypt_private($password, $hash, $itoa64) === $hash) ? true : false; - } - - return (md5($password) === $hash) ? true : false; -} - -/** -* Generate salt for hash generation -*/ -function _hash_gensalt_private($input, &$itoa64, $iteration_count_log2 = 6) -{ - if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31) - { - $iteration_count_log2 = 8; - } - - $output = '$H$'; - $output .= $itoa64[min($iteration_count_log2 + 5, 30)]; - $output .= _hash_encode64($input, 6, $itoa64); - - return $output; -} - -/** -* Encode hash -*/ -function _hash_encode64($input, $count, &$itoa64) -{ - $output = ''; - $i = 0; - - do - { - $value = ord($input[$i++]); - $output .= $itoa64[$value & 0x3f]; - - if ($i < $count) - { - $value |= ord($input[$i]) << 8; - } - - $output .= $itoa64[($value >> 6) & 0x3f]; - - if ($i++ >= $count) - { - break; - } - - if ($i < $count) - { - $value |= ord($input[$i]) << 16; - } - - $output .= $itoa64[($value >> 12) & 0x3f]; - - if ($i++ >= $count) - { - break; - } - - $output .= $itoa64[($value >> 18) & 0x3f]; - } - while ($i < $count); - - return $output; -} - -/** -* The crypt function/replacement -*/ -function _hash_crypt_private($password, $setting, &$itoa64) -{ - $output = '*'; - - // Check for correct hash - if (substr($setting, 0, 3) != '$H$' && substr($setting, 0, 3) != '$P$') - { - return $output; - } - - $count_log2 = strpos($itoa64, $setting[3]); - - if ($count_log2 < 7 || $count_log2 > 30) - { - return $output; - } - - $count = 1 << $count_log2; - $salt = substr($setting, 4, 8); + global $phpbb_container; - if (strlen($salt) != 8) - { - return $output; - } - - /** - * We're kind of forced to use MD5 here since it's the only - * cryptographic primitive available in all versions of PHP - * currently in use. To implement our own low-level crypto - * in PHP would result in much worse performance and - * consequently in lower iteration counts and hashes that are - * quicker to crack (by non-PHP code). - */ - $hash = md5($salt . $password, true); - do - { - $hash = md5($hash . $password, true); - } - while (--$count); - - $output = substr($setting, 0, 12); - $output .= _hash_encode64($hash, 16, $itoa64); - - return $output; + $passwords_manager = $phpbb_container->get('passwords.manager'); + return $passwords_manager->check($password, $hash); } /** @@ -2205,225 +2039,6 @@ function tracking_unserialize($string, $max_depth = 3) return $level; } -// Pagination functions -/** -* Generate a pagination link based on the url and the page information -* -* @param string $base_url is url prepended to all links generated within the function -* If you use page numbers inside your controller route, base_url should contains a placeholder (%d) -* for the page. Also be sure to specify the pagination path information into the start_name argument -* @param string $on_page is the page for which we want to generate the link -* @param string $start_name is the name of the parameter containing the first item of the given page (example: start=20) -* If you use page numbers inside your controller route, start name should be the string -* that should be removed for the first page (example: /page/%d) -* @param int $per_page the number of items, posts, etc. to display per page, used to determine the number of pages to produce -* @return URL for the requested page -*/ -function phpbb_generate_page_link($base_url, $on_page, $start_name, $per_page) -{ - - if (strpos($start_name, '%d') !== false) - { - return ($on_page > 1) ? sprintf($base_url, (int) $on_page) : str_replace($start_name, '', $base_url); - } - else - { - $url_delim = (strpos($base_url, '?') === false) ? '?' : ((strpos($base_url, '?') === strlen($base_url) - 1) ? '' : '&'); - return ($on_page > 1) ? $base_url . $url_delim . $start_name . '=' . (($on_page - 1) * $per_page) : $base_url; - } -} - -/** -* Generate template rendered pagination -* Allows full control of rendering of pagination with the template -* -* @param object $template the template object -* @param string $base_url is url prepended to all links generated within the function -* If you use page numbers inside your controller route, base_url should contains a placeholder (%d) -* for the page. Also be sure to specify the pagination path information into the start_name argument -* @param string $block_var_name is the name assigned to the pagination data block within the template (example: <!-- BEGIN pagination -->) -* @param string $start_name is the name of the parameter containing the first item of the given page (example: start=20) -* If you use page numbers inside your controller route, start name should be the string -* that should be removed for the first page (example: /page/%d) -* @param int $num_items the total number of items, posts, etc., used to determine the number of pages to produce -* @param int $per_page the number of items, posts, etc. to display per page, used to determine the number of pages to produce -* @param int $start_item the item which should be considered currently active, used to determine the page we're on -* @param bool $reverse_count determines whether we weight display of the list towards the start (false) or end (true) of the list -* @param bool $ignore_on_page decides whether we enable an active (unlinked) item, used primarily for embedded lists -* @return null -*/ -function phpbb_generate_template_pagination($template, $base_url, $block_var_name, $start_name, $num_items, $per_page, $start_item = 1, $reverse_count = false, $ignore_on_page = false) -{ - // Make sure $per_page is a valid value - $per_page = ($per_page <= 0) ? 1 : $per_page; - $total_pages = ceil($num_items / $per_page); - - if ($total_pages == 1 || !$num_items) - { - return; - } - - $on_page = floor($start_item / $per_page) + 1; - - if ($reverse_count) - { - $start_page = ($total_pages > 5) ? $total_pages - 4 : 1; - $end_page = $total_pages; - } - else - { - // What we're doing here is calculating what the "start" and "end" pages should be. We - // do this by assuming pagination is "centered" around the currently active page with - // the three previous and three next page links displayed. Anything more than that and - // we display the ellipsis, likewise anything less. - // - // $start_page is the page at which we start creating the list. When we have five or less - // pages we start at page 1 since there will be no ellipsis displayed. Anymore than that - // and we calculate the start based on the active page. This is the min/max calculation. - // First (max) would we end up starting on a page less than 1? Next (min) would we end - // up starting so close to the end that we'd not display our minimum number of pages. - // - // $end_page is the last page in the list to display. Like $start_page we use a min/max to - // determine this number. Again at most five pages? Then just display them all. More than - // five and we first (min) determine whether we'd end up listing more pages than exist. - // We then (max) ensure we're displaying the minimum number of pages. - $start_page = ($total_pages > 5) ? min(max(1, $on_page - 3), $total_pages - 4) : 1; - $end_page = ($total_pages > 5) ? max(min($total_pages, $on_page + 3), 5) : $total_pages; - } - - $u_previous_page = $u_next_page = ''; - if ($on_page != 1) - { - $u_previous_page = phpbb_generate_page_link($base_url, $on_page - 1, $start_name, $per_page); - - $template->assign_block_vars($block_var_name, array( - 'PAGE_NUMBER' => '', - 'PAGE_URL' => $u_previous_page, - 'S_IS_CURRENT' => false, - 'S_IS_PREV' => true, - 'S_IS_NEXT' => false, - 'S_IS_ELLIPSIS' => false, - )); - } - - // This do...while exists purely to negate the need for start and end assign_block_vars, i.e. - // to display the first and last page in the list plus any ellipsis. We use this loop to jump - // around a little within the list depending on where we're starting (and ending). - $at_page = 1; - do - { - // We decide whether to display the ellipsis during the loop. The ellipsis is always - // displayed as either the second or penultimate item in the list. So are we at either - // of those points and of course do we even need to display it, i.e. is the list starting - // on at least page 3 and ending three pages before the final item. - $template->assign_block_vars($block_var_name, array( - 'PAGE_NUMBER' => $at_page, - 'PAGE_URL' => phpbb_generate_page_link($base_url, $at_page, $start_name, $per_page), - 'S_IS_CURRENT' => (!$ignore_on_page && $at_page == $on_page), - 'S_IS_NEXT' => false, - 'S_IS_PREV' => false, - 'S_IS_ELLIPSIS' => ($at_page == 2 && $start_page > 2) || ($at_page == $total_pages - 1 && $end_page < $total_pages - 1), - )); - - // We may need to jump around in the list depending on whether we have or need to display - // the ellipsis. Are we on page 2 and are we more than one page away from the start - // of the list? Yes? Then we jump to the start of the list. Likewise are we at the end of - // the list and are there more than two pages left in total? Yes? Then jump to the penultimate - // page (so we can display the ellipsis next pass). Else, increment the counter and keep - // going - if ($at_page == 2 && $at_page < $start_page - 1) - { - $at_page = $start_page; - } - else if ($at_page == $end_page && $end_page < $total_pages - 1) - { - $at_page = $total_pages - 1; - } - else - { - $at_page++; - } - } - while ($at_page <= $total_pages); - - if ($on_page != $total_pages) - { - $u_next_page = phpbb_generate_page_link($base_url, $on_page + 1, $start_name, $per_page); - - $template->assign_block_vars($block_var_name, array( - 'PAGE_NUMBER' => '', - 'PAGE_URL' => $u_next_page, - 'S_IS_CURRENT' => false, - 'S_IS_PREV' => false, - 'S_IS_NEXT' => true, - 'S_IS_ELLIPSIS' => false, - )); - } - - // If the block_var_name is a nested block, we will use the last (most - // inner) block as a prefix for the template variables. If the last block - // name is pagination, the prefix is empty. If the rest of the - // block_var_name is not empty, we will modify the last row of that block - // and add our pagination items. - $tpl_block_name = $tpl_prefix = ''; - if (strrpos($block_var_name, '.') !== false) - { - $tpl_block_name = substr($block_var_name, 0, strrpos($block_var_name, '.')); - $tpl_prefix = strtoupper(substr($block_var_name, strrpos($block_var_name, '.') + 1)); - } - else - { - $tpl_prefix = strtoupper($block_var_name); - } - $tpl_prefix = ($tpl_prefix == 'PAGINATION') ? '' : $tpl_prefix . '_'; - - $template_array = array( - $tpl_prefix . 'BASE_URL' => $base_url, - $tpl_prefix . 'PER_PAGE' => $per_page, - 'U_' . $tpl_prefix . 'PREVIOUS_PAGE' => ($on_page != 1) ? $u_previous_page : '', - 'U_' . $tpl_prefix . 'NEXT_PAGE' => ($on_page != $total_pages) ? $u_next_page : '', - $tpl_prefix . 'TOTAL_PAGES' => $total_pages, - $tpl_prefix . 'CURRENT_PAGE' => $on_page, - ); - - if ($tpl_block_name) - { - $template->alter_block_array($tpl_block_name, $template_array, true, 'change'); - } - else - { - $template->assign_vars($template_array); - } -} - -/** -* Return current page -* This function also sets certain specific template variables -* -* @param object $template the template object -* @param object $user the user object -* @param string $base_url the base url used to call this page, used by Javascript for popup jump to page -* @param int $num_items the total number of items, posts, topics, etc. -* @param int $per_page the number of items, posts, etc. per page -* @param int $start the item which should be considered currently active, used to determine the page we're on -* @return null -*/ -function phpbb_on_page($template, $user, $base_url, $num_items, $per_page, $start) -{ - // Make sure $per_page is a valid value - $per_page = ($per_page <= 0) ? 1 : $per_page; - - $on_page = floor($start / $per_page) + 1; - - $template->assign_vars(array( - 'PER_PAGE' => $per_page, - 'ON_PAGE' => $on_page, - 'BASE_URL' => $base_url, - )); - - return sprintf($user->lang['PAGE_OF'], $on_page, max(ceil($num_items / $per_page), 1)); -} - // Server functions (building urls, redirecting...) /** @@ -2653,7 +2268,7 @@ function generate_board_url($without_script_path = false) */ function redirect($url, $return = false, $disable_cd_check = false) { - global $db, $cache, $config, $user, $phpbb_root_path; + global $db, $cache, $config, $user, $phpbb_root_path, $phpbb_filesystem, $phpbb_path_helper, $phpEx; $failover_flag = false; @@ -2696,78 +2311,34 @@ function redirect($url, $return = false, $disable_cd_check = false) // Relative uri $pathinfo = pathinfo($url); - if (!$disable_cd_check && !file_exists($pathinfo['dirname'] . '/')) + // Is the uri pointing to the current directory? + if ($pathinfo['dirname'] == '.') { - $url = str_replace('../', '', $url); - $pathinfo = pathinfo($url); + $url = str_replace('./', '', $url); - if (!file_exists($pathinfo['dirname'] . '/')) + // Strip / from the beginning + if ($url && substr($url, 0, 1) == '/') { - // fallback to "last known user page" - // at least this way we know the user does not leave the phpBB root - $url = generate_board_url() . '/' . $user->page['page']; - $failover_flag = true; + $url = substr($url, 1); } } - if (!$failover_flag) - { - // Is the uri pointing to the current directory? - if ($pathinfo['dirname'] == '.') - { - $url = str_replace('./', '', $url); - - // Strip / from the beginning - if ($url && substr($url, 0, 1) == '/') - { - $url = substr($url, 1); - } + $url = $phpbb_path_helper->remove_web_root_path($url); - if ($user->page['page_dir']) - { - $url = generate_board_url() . '/' . $user->page['page_dir'] . '/' . $url; - } - else - { - $url = generate_board_url() . '/' . $url; - } - } - else - { - // Used ./ before, but $phpbb_root_path is working better with urls within another root path - $root_dirs = explode('/', str_replace('\\', '/', phpbb_realpath($phpbb_root_path))); - $page_dirs = explode('/', str_replace('\\', '/', phpbb_realpath($pathinfo['dirname']))); - $intersection = array_intersect_assoc($root_dirs, $page_dirs); - - $root_dirs = array_diff_assoc($root_dirs, $intersection); - $page_dirs = array_diff_assoc($page_dirs, $intersection); - - $dir = str_repeat('../', sizeof($root_dirs)) . implode('/', $page_dirs); - - // Strip / from the end - if ($dir && substr($dir, -1, 1) == '/') - { - $dir = substr($dir, 0, -1); - } - - // Strip / from the beginning - if ($dir && substr($dir, 0, 1) == '/') - { - $dir = substr($dir, 1); - } + if ($user->page['page_dir']) + { + $url = $user->page['page_dir'] . '/' . $url; + } - $url = str_replace($pathinfo['dirname'] . '/', '', $url); + $url = generate_board_url() . '/' . $url; + } - // Strip / from the beginning - if (substr($url, 0, 1) == '/') - { - $url = substr($url, 1); - } + // Clean URL and check if we go outside the forum directory + $url = $phpbb_path_helper->clean_url($url); - $url = (!empty($dir) ? $dir . '/' : '') . $url; - $url = generate_board_url() . '/' . $url; - } - } + if (!$disable_cd_check && strpos($url, generate_board_url(true)) === false) + { + trigger_error('INSECURE_REDIRECT', E_USER_ERROR); } // Make sure no linebreaks are there... to prevent http response splitting for PHP < 4.4.2 @@ -3469,9 +3040,9 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa */ function login_forum_box($forum_data) { - global $db, $config, $user, $template, $phpEx; + global $db, $phpbb_container, $request, $template, $user; - $password = request_var('password', '', true); + $password = $request->variable('password', '', true); $sql = 'SELECT forum_id FROM ' . FORUMS_ACCESS_TABLE . ' @@ -3512,7 +3083,9 @@ function login_forum_box($forum_data) } $db->sql_freeresult($result); - if (phpbb_check_hash($password, $forum_data['forum_password'])) + $passwords_manager = $phpbb_container->get('passwords.manager'); + + if ($passwords_manager->check($password, $forum_data['forum_password'])) { $sql_ary = array( 'forum_id' => (int) $forum_data['forum_id'], @@ -5318,7 +4891,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 } $hidden_fields_for_jumpbox = phpbb_build_hidden_fields_for_query_params($request, array('f')); - + $notification_mark_hash = generate_link_hash('mark_all_notifications_read'); // The following assigns all _common_ variables that may be used at any point in a template. $template->assign_vars(array( @@ -5338,6 +4911,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'UNREAD_NOTIFICATIONS_COUNT' => ($notifications !== false) ? $notifications['unread_count'] : '', 'NOTIFICATIONS_COUNT' => ($notifications !== false) ? $notifications['unread_count'] : '', 'U_VIEW_ALL_NOTIFICATIONS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_notifications'), + 'U_MARK_ALL_NOTIFICATIONS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_notifications&mode=notification_list&mark=all&token=' . $notification_mark_hash), 'U_NOTIFICATION_SETTINGS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_notifications&mode=notification_options'), 'S_NOTIFICATIONS_DISPLAY' => $config['load_notifications'], diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 0ff842ea6a..e663ac90c5 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -919,7 +919,7 @@ function topic_status(&$topic_row, $replies, $unread_topic, &$folder_img, &$fold /** * Assign/Build custom bbcodes for display in screens supporting using of bbcodes -* The custom bbcodes buttons will be placed within the template block 'custom_codes' +* The custom bbcodes buttons will be placed within the template block 'custom_tags' */ function display_custom_bbcodes() { @@ -928,11 +928,26 @@ function display_custom_bbcodes() // Start counting from 22 for the bbcode ids (every bbcode takes two ids - opening/closing) $num_predefined_bbcodes = 22; - $sql = 'SELECT bbcode_id, bbcode_tag, bbcode_helpline - FROM ' . BBCODES_TABLE . ' - WHERE display_on_posting = 1 - ORDER BY bbcode_tag'; - $result = $db->sql_query($sql); + $sql_ary = array( + 'SELECT' => 'b.bbcode_id, b.bbcode_tag, b.bbcode_helpline', + 'FROM' => array(BBCODES_TABLE => 'b'), + 'WHERE' => 'b.display_on_posting = 1', + 'ORDER_BY' => 'b.bbcode_tag', + ); + + /** + * Event to modify the SQL query before custom bbcode data is queried + * + * @event core.display_custom_bbcodes_modify_sql + * @var array sql_ary The SQL array to get the bbcode data + * @var int num_predefined_bbcodes The number of predefined core bbcodes + * (multiplied by factor of 2) + * @since 3.1.0-a3 + */ + $vars = array('sql_ary', 'num_predefined_bbcodes'); + extract($phpbb_dispatcher->trigger_event('core.display_custom_bbcodes_modify_sql', compact($vars))); + + $result = $db->sql_query($db->sql_build_query('SELECT', $sql_ary)); $i = 0; while ($row = $db->sql_fetchrow($result)) @@ -952,7 +967,7 @@ function display_custom_bbcodes() ); /** - * Modify the template data block of a bbcode + * Event to modify the template data block of a custom bbcode * * This event is triggered once per bbcode * diff --git a/phpBB/includes/functions_download.php b/phpBB/includes/functions_download.php index e7a1d2bff5..c895f7b54b 100644 --- a/phpBB/includes/functions_download.php +++ b/phpBB/includes/functions_download.php @@ -625,17 +625,29 @@ function phpbb_increment_downloads($db, $ids) */ function phpbb_download_handle_forum_auth($db, $auth, $topic_id) { - $sql = 'SELECT t.forum_id, f.forum_name, f.forum_password, f.parent_id - FROM ' . TOPICS_TABLE . ' t, ' . FORUMS_TABLE . " f - WHERE t.topic_id = " . (int) $topic_id . " - AND t.forum_id = f.forum_id"; + $sql_array = array( + 'SELECT' => 't.topic_visibility, t.forum_id, f.forum_name, f.forum_password, f.parent_id', + 'FROM' => array( + TOPICS_TABLE => 't', + FORUMS_TABLE => 'f', + ), + 'WHERE' => 't.topic_id = ' . (int) $topic_id . ' + AND t.forum_id = f.forum_id', + ); + + $sql = $db->sql_build_query('SELECT', $sql_array); $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); - if ($auth->acl_get('u_download') && $auth->acl_get('f_download', $row['forum_id'])) + if ($row && $row['topic_visibility'] != ITEM_APPROVED && !$auth->acl_get('m_approve', $row['forum_id'])) { - if ($row && $row['forum_password']) + send_status_line(404, 'Not Found'); + trigger_error('ERROR_NO_ATTACHMENT'); + } + else if ($row && $auth->acl_get('u_download') && $auth->acl_get('f_download', $row['forum_id'])) + { + if ($row['forum_password']) { // Do something else ... ? login_forum_box($row); diff --git a/phpBB/includes/functions_module.php b/phpBB/includes/functions_module.php index e1259eba12..53055752f6 100644 --- a/phpBB/includes/functions_module.php +++ b/phpBB/includes/functions_module.php @@ -334,7 +334,7 @@ class p_master static function module_auth($module_auth, $forum_id) { global $auth, $config; - global $request; + global $request, $phpbb_extension_manager, $phpbb_dispatcher; $module_auth = trim($module_auth); @@ -351,6 +351,30 @@ class p_master [(),] | [^\s(),]+)/x', $module_auth, $match); + // Valid tokens for auth and their replacements + $valid_tokens = array( + 'acl_([a-z0-9_]+)(,\$id)?' => '(int) $auth->acl_get(\'\\1\'\\2)', + '\$id' => '(int) $forum_id', + 'aclf_([a-z0-9_]+)' => '(int) $auth->acl_getf_global(\'\\1\')', + 'cfg_([a-z0-9_]+)' => '(int) $config[\'\\1\']', + 'request_([a-zA-Z0-9_]+)' => '$request->variable(\'\\1\', false)', + 'ext_([a-zA-Z0-9_/]+)' => 'array_key_exists(\'\\1\', $phpbb_extension_manager->all_enabled())', + ); + + /** + * Alter tokens for module authorisation check + * + * @event core.module_auth + * @var array valid_tokens Valid tokens and their auth check + * replacements + * @var string module_auth The module_auth of the current + * module + * @var int forum_id The current forum_id + * @since 3.1-A3 + */ + $vars = array('valid_tokens', 'module_auth', 'forum_id'); + extract($phpbb_dispatcher->trigger_event('core.module_auth', compact($vars))); + $tokens = $match[0]; for ($i = 0, $size = sizeof($tokens); $i < $size; $i++) { @@ -366,7 +390,7 @@ class p_master break; default: - if (!preg_match('#(?:acl_([a-z0-9_]+)(,\$id)?)|(?:\$id)|(?:aclf_([a-z0-9_]+))|(?:cfg_([a-z0-9_]+))|(?:request_([a-zA-Z0-9_]+))#', $token)) + if (!preg_match('#(?:' . implode(array_keys($valid_tokens), ')|(?:') . ')#', $token)) { $token = ''; } @@ -379,8 +403,17 @@ class p_master // Make sure $id separation is working fine $module_auth = str_replace(' , ', ',', $module_auth); + $module_auth = preg_replace( + // Array keys with # prepended/appended + array_map(function($value) { + return '#' . $value . '#'; + }, array_keys($valid_tokens)), + array_values($valid_tokens), + $module_auth + ); + $is_auth = false; - eval('$is_auth = (int) (' . preg_replace(array('#acl_([a-z0-9_]+)(,\$id)?#', '#\$id#', '#aclf_([a-z0-9_]+)#', '#cfg_([a-z0-9_]+)#', '#request_([a-zA-Z0-9_]+)#'), array('(int) $auth->acl_get(\'\\1\'\\2)', '(int) $forum_id', '(int) $auth->acl_getf_global(\'\\1\')', '(int) $config[\'\\1\']', '$request->variable(\'\\1\', false)'), $module_auth) . ');'); + eval('$is_auth = (int) (' . $module_auth . ');'); return $is_auth; } diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index 172f4403ac..8e9cc3a950 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -21,8 +21,10 @@ if (!defined('IN_PHPBB')) function generate_smilies($mode, $forum_id) { global $db, $user, $config, $template, $phpbb_dispatcher; - global $phpEx, $phpbb_root_path; + global $phpEx, $phpbb_root_path, $phpbb_container; + $base_url = append_sid("{$phpbb_root_path}posting.$phpEx", 'mode=smilies&f=' . $forum_id); + $pagination = $phpbb_container->get('pagination'); $start = request_var('start', 0); if ($mode == 'window') @@ -61,7 +63,8 @@ function generate_smilies($mode, $forum_id) 'body' => 'posting_smilies.html') ); - generate_pagination(append_sid("{$phpbb_root_path}posting.$phpEx", 'mode=smilies&f=' . $forum_id), $smiley_count, $config['smilies_per_page'], $start); + $start = $pagination->validate_start($start, $config['smilies_per_page'], $smiley_count); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $smiley_count, $config['smilies_per_page'], $start); } $display_link = false; @@ -139,8 +142,8 @@ function generate_smilies($mode, $forum_id) { $template->assign_vars(array( 'S_SHOW_SMILEY_LINK' => true, - 'U_MORE_SMILIES' => append_sid("{$phpbb_root_path}posting.$phpEx", 'mode=smilies&f=' . $forum_id)) - ); + 'U_MORE_SMILIES' => $base_url, + )); } if ($mode == 'window') @@ -862,6 +865,7 @@ function posting_gen_attachment_entry($attachment_data, &$filename_data, $show_a 'ATTACH_ID' => $attach_row['attach_id'], 'S_IS_ORPHAN' => $attach_row['is_orphan'], 'ASSOC_INDEX' => $count, + 'FILESIZE' => get_formatted_filesize($attach_row['filesize']), 'U_VIEW_ATTACHMENT' => $download_link, 'S_HIDDEN' => $hidden) @@ -1475,6 +1479,22 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u { global $db, $auth, $user, $config, $phpEx, $template, $phpbb_root_path, $phpbb_container, $phpbb_dispatcher; + /** + * Modify the data for post submitting + * + * @event core.modify_submit_post_data + * @var string mode Variable containing posting mode value + * @var string subject Variable containing post subject value + * @var string username Variable containing post author name + * @var int topic_type Variable containing topic type value + * @var array poll Array with the poll data for the post + * @var array data Array with the data for the post + * @var bool update_message Flag indicating if the post will be updated + * @var bool update_search_index Flag indicating if the search index will be updated + * @since 3.1.0-a4 + */ + extract($phpbb_dispatcher->trigger_event('core.modify_submit_post_data', compact(array('mode', 'subject', 'username', 'topic_type', 'poll', 'data', 'update_message', 'update_search_index')))); + // We do not handle erasing posts here if ($mode == 'delete') { diff --git a/phpBB/includes/functions_profile_fields.php b/phpBB/includes/functions_profile_fields.php deleted file mode 100644 index 7dd0b0e87d..0000000000 --- a/phpBB/includes/functions_profile_fields.php +++ /dev/null @@ -1,1187 +0,0 @@ -<?php -/** -* -* @package phpBB3 -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** -* Custom Profile Fields -* @package phpBB3 -*/ -class custom_profile -{ - var $profile_types = array(FIELD_INT => 'int', FIELD_STRING => 'string', FIELD_TEXT => 'text', FIELD_BOOL => 'bool', FIELD_DROPDOWN => 'dropdown', FIELD_DATE => 'date'); - var $profile_cache = array(); - var $options_lang = array(); - - /** - * Assign editable fields to template, mode can be profile (for profile change) or register (for registration) - * Called by ucp_profile and ucp_register - * @access public - */ - function generate_profile_fields($mode, $lang_id) - { - global $db, $template, $auth; - - $sql_where = ''; - switch ($mode) - { - case 'register': - // If the field is required we show it on the registration page - $sql_where .= ' AND f.field_show_on_reg = 1'; - break; - - case 'profile': - // Show hidden fields to moderators/admins - if (!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_')) - { - $sql_where .= ' AND f.field_show_profile = 1'; - } - break; - - default: - trigger_error('Wrong profile mode specified', E_USER_ERROR); - break; - } - - $sql = 'SELECT l.*, f.* - FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . " f - WHERE f.field_active = 1 - $sql_where - AND l.lang_id = $lang_id - AND l.field_id = f.field_id - ORDER BY f.field_order"; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - // Return templated field - $tpl_snippet = $this->process_field_row('change', $row); - - // Some types are multivalue, we can't give them a field_id as we would not know which to pick - $type = (int) $row['field_type']; - - $template->assign_block_vars('profile_fields', array( - 'LANG_NAME' => $row['lang_name'], - 'LANG_EXPLAIN' => $row['lang_explain'], - 'FIELD' => $tpl_snippet, - 'FIELD_ID' => ($type == FIELD_DATE || ($type == FIELD_BOOL && $row['field_length'] == '1')) ? '' : 'pf_' . $row['field_ident'], - 'S_REQUIRED' => ($row['field_required']) ? true : false) - ); - } - $db->sql_freeresult($result); - } - - /** - * Validate entered profile field data - * @access public - */ - function validate_profile_field($field_type, &$field_value, $field_data) - { - switch ($field_type) - { - case FIELD_DATE: - $field_validate = explode('-', $field_value); - - $day = (isset($field_validate[0])) ? (int) $field_validate[0] : 0; - $month = (isset($field_validate[1])) ? (int) $field_validate[1] : 0; - $year = (isset($field_validate[2])) ? (int) $field_validate[2] : 0; - - if ((!$day || !$month || !$year) && !$field_data['field_required']) - { - return false; - } - - if ((!$day || !$month || !$year) && $field_data['field_required']) - { - return 'FIELD_REQUIRED'; - } - - if ($day < 0 || $day > 31 || $month < 0 || $month > 12 || ($year < 1901 && $year > 0) || $year > gmdate('Y', time()) + 50) - { - return 'FIELD_INVALID_DATE'; - } - - if (checkdate($month, $day, $year) === false) - { - return 'FIELD_INVALID_DATE'; - } - break; - - case FIELD_BOOL: - $field_value = (bool) $field_value; - - if (!$field_value && $field_data['field_required']) - { - return 'FIELD_REQUIRED'; - } - break; - - case FIELD_INT: - if (trim($field_value) === '' && !$field_data['field_required']) - { - return false; - } - - $field_value = (int) $field_value; - - if ($field_value < $field_data['field_minlen']) - { - return 'FIELD_TOO_SMALL'; - } - else if ($field_value > $field_data['field_maxlen']) - { - return 'FIELD_TOO_LARGE'; - } - break; - - case FIELD_DROPDOWN: - $field_value = (int) $field_value; - - // retrieve option lang data if necessary - if (!isset($this->options_lang[$field_data['field_id']]) || !isset($this->options_lang[$field_data['field_id']][$field_data['lang_id']]) || !sizeof($this->options_lang[$file_data['field_id']][$field_data['lang_id']])) - { - $this->get_option_lang($field_data['field_id'], $field_data['lang_id'], FIELD_DROPDOWN, false); - } - - if (!isset($this->options_lang[$field_data['field_id']][$field_data['lang_id']][$field_value])) - { - return 'FIELD_INVALID_VALUE'; - } - - if ($field_value == $field_data['field_novalue'] && $field_data['field_required']) - { - return 'FIELD_REQUIRED'; - } - break; - - case FIELD_STRING: - case FIELD_TEXT: - if (trim($field_value) === '' && !$field_data['field_required']) - { - return false; - } - else if (trim($field_value) === '' && $field_data['field_required']) - { - return 'FIELD_REQUIRED'; - } - - if ($field_data['field_minlen'] && utf8_strlen($field_value) < $field_data['field_minlen']) - { - return 'FIELD_TOO_SHORT'; - } - else if ($field_data['field_maxlen'] && utf8_strlen($field_value) > $field_data['field_maxlen']) - { - return 'FIELD_TOO_LONG'; - } - - if (!empty($field_data['field_validation']) && $field_data['field_validation'] != '.*') - { - $field_validate = ($field_type == FIELD_STRING) ? $field_value : bbcode_nl2br($field_value); - if (!preg_match('#^' . str_replace('\\\\', '\\', $field_data['field_validation']) . '$#i', $field_validate)) - { - return 'FIELD_INVALID_CHARS'; - } - } - break; - } - - return false; - } - - /** - * Build profile cache, used for display - * @access private - */ - function build_cache() - { - global $db, $user, $auth; - - $this->profile_cache = array(); - - // Display hidden/no_view fields for admin/moderator - $sql = 'SELECT l.*, f.* - FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f - WHERE l.lang_id = ' . $user->get_iso_lang_id() . ' - AND f.field_active = 1 ' . - ((!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_')) ? ' AND f.field_hide = 0 ' : '') . ' - AND f.field_no_view = 0 - AND l.field_id = f.field_id - ORDER BY f.field_order'; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - $this->profile_cache[$row['field_ident']] = $row; - } - $db->sql_freeresult($result); - } - - /** - * Get language entries for options and store them here for later use - */ - function get_option_lang($field_id, $lang_id, $field_type, $preview) - { - global $db; - - if ($preview) - { - $lang_options = (!is_array($this->vars['lang_options'])) ? explode("\n", $this->vars['lang_options']) : $this->vars['lang_options']; - - foreach ($lang_options as $num => $var) - { - $this->options_lang[$field_id][$lang_id][($num + 1)] = $var; - } - } - else - { - $sql = 'SELECT option_id, lang_value - FROM ' . PROFILE_FIELDS_LANG_TABLE . " - WHERE field_id = $field_id - AND lang_id = $lang_id - AND field_type = $field_type - ORDER BY option_id"; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - $this->options_lang[$field_id][$lang_id][($row['option_id'] + 1)] = $row['lang_value']; - } - $db->sql_freeresult($result); - } - } - - /** - * Submit profile field for validation - * @access public - */ - function submit_cp_field($mode, $lang_id, &$cp_data, &$cp_error) - { - global $auth, $db, $user; - - $sql_where = ''; - switch ($mode) - { - case 'register': - // If the field is required we show it on the registration page - $sql_where .= ' AND f.field_show_on_reg = 1'; - break; - - case 'profile': - // Show hidden fields to moderators/admins - if (!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_')) - { - $sql_where .= ' AND f.field_show_profile = 1'; - } - break; - - default: - trigger_error('Wrong profile mode specified', E_USER_ERROR); - break; - } - - $sql = 'SELECT l.*, f.* - FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . " f - WHERE l.lang_id = $lang_id - AND f.field_active = 1 - $sql_where - AND l.field_id = f.field_id - ORDER BY f.field_order"; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - $cp_data['pf_' . $row['field_ident']] = $this->get_profile_field($row); - $check_value = $cp_data['pf_' . $row['field_ident']]; - - if (($cp_result = $this->validate_profile_field($row['field_type'], $check_value, $row)) !== false) - { - // If not and only showing common error messages, use this one - $error = ''; - switch ($cp_result) - { - case 'FIELD_INVALID_DATE': - case 'FIELD_INVALID_VALUE': - case 'FIELD_REQUIRED': - $error = $user->lang($cp_result, $row['lang_name']); - break; - - case 'FIELD_TOO_SHORT': - case 'FIELD_TOO_SMALL': - $error = $user->lang($cp_result, (int) $row['field_minlen'], $row['lang_name']); - break; - - case 'FIELD_TOO_LONG': - case 'FIELD_TOO_LARGE': - $error = $user->lang($cp_result, (int) $row['field_maxlen'], $row['lang_name']); - break; - - case 'FIELD_INVALID_CHARS': - switch ($row['field_validation']) - { - case '[0-9]+': - $error = $user->lang($cp_result . '_NUMBERS_ONLY', $row['lang_name']); - break; - - case '[\w]+': - $error = $user->lang($cp_result . '_ALPHA_ONLY', $row['lang_name']); - break; - - case '[\w_\+\. \-\[\]]+': - $error = $user->lang($cp_result . '_SPACERS_ONLY', $row['lang_name']); - break; - } - break; - } - - if ($error != '') - { - $cp_error[] = $error; - } - } - } - $db->sql_freeresult($result); - } - - /** - * Update profile field data directly - */ - function update_profile_field_data($user_id, &$cp_data) - { - global $db; - - if (!sizeof($cp_data)) - { - return; - } - - switch ($db->sql_layer) - { - case 'oracle': - case 'firebird': - case 'postgres': - $right_delim = $left_delim = '"'; - break; - - case 'sqlite': - case 'mssql': - case 'mssql_odbc': - case 'mssqlnative': - $right_delim = ']'; - $left_delim = '['; - break; - - case 'mysql': - case 'mysql4': - case 'mysqli': - $right_delim = $left_delim = '`'; - break; - } - - // use new array for the UPDATE; changes in the key do not affect the original array - $cp_data_sql = array(); - foreach ($cp_data as $key => $value) - { - // Firebird is case sensitive with delimiter - $cp_data_sql[$left_delim . (($db->sql_layer == 'firebird' || $db->sql_layer == 'oracle') ? strtoupper($key) : $key) . $right_delim] = $value; - } - - $sql = 'UPDATE ' . PROFILE_FIELDS_DATA_TABLE . ' - SET ' . $db->sql_build_array('UPDATE', $cp_data_sql) . " - WHERE user_id = $user_id"; - $db->sql_query($sql); - - if (!$db->sql_affectedrows()) - { - $cp_data_sql['user_id'] = (int) $user_id; - - $db->sql_return_on_error(true); - - $sql = 'INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $cp_data_sql); - $db->sql_query($sql); - - $db->sql_return_on_error(false); - } - } - - /** - * Assign fields to template, used for viewprofile, viewtopic and memberlist (if load setting is enabled) - * This is directly connected to the user -> mode == grab is to grab the user specific fields, mode == show is for assigning the row to the template - * @access public - */ - function generate_profile_fields_template($mode, $user_id = 0, $profile_row = false) - { - global $db; - - if ($mode == 'grab') - { - if (!is_array($user_id)) - { - $user_id = array($user_id); - } - - if (!sizeof($this->profile_cache)) - { - $this->build_cache(); - } - - if (!sizeof($user_id)) - { - return array(); - } - - $sql = 'SELECT * - FROM ' . PROFILE_FIELDS_DATA_TABLE . ' - WHERE ' . $db->sql_in_set('user_id', array_map('intval', $user_id)); - $result = $db->sql_query($sql); - - $field_data = array(); - while ($row = $db->sql_fetchrow($result)) - { - $field_data[$row['user_id']] = $row; - } - $db->sql_freeresult($result); - - $user_fields = array(); - - $user_ids = $user_id; - - // Go through the fields in correct order - foreach (array_keys($this->profile_cache) as $used_ident) - { - foreach ($field_data as $user_id => $row) - { - $user_fields[$user_id][$used_ident]['value'] = $row['pf_' . $used_ident]; - $user_fields[$user_id][$used_ident]['data'] = $this->profile_cache[$used_ident]; - } - - foreach ($user_ids as $user_id) - { - if (!isset($user_fields[$user_id][$used_ident]) && $this->profile_cache[$used_ident]['field_show_novalue']) - { - $user_fields[$user_id][$used_ident]['value'] = ''; - $user_fields[$user_id][$used_ident]['data'] = $this->profile_cache[$used_ident]; - } - } - } - - return $user_fields; - } - else if ($mode == 'show') - { - // $profile_row == $user_fields[$row['user_id']]; - $tpl_fields = array(); - $tpl_fields['row'] = $tpl_fields['blockrow'] = array(); - - foreach ($profile_row as $ident => $ident_ary) - { - $value = $this->get_profile_value($ident_ary); - - if ($value === NULL) - { - continue; - } - - $tpl_fields['row'] += array( - 'PROFILE_' . strtoupper($ident) . '_VALUE' => $value, - 'PROFILE_' . strtoupper($ident) . '_TYPE' => $ident_ary['data']['field_type'], - 'PROFILE_' . strtoupper($ident) . '_NAME' => $ident_ary['data']['lang_name'], - 'PROFILE_' . strtoupper($ident) . '_EXPLAIN'=> $ident_ary['data']['lang_explain'], - - 'S_PROFILE_' . strtoupper($ident) => true - ); - - $tpl_fields['blockrow'][] = array( - 'PROFILE_FIELD_VALUE' => $value, - 'PROFILE_FIELD_TYPE' => $ident_ary['data']['field_type'], - 'PROFILE_FIELD_NAME' => $ident_ary['data']['lang_name'], - 'PROFILE_FIELD_EXPLAIN' => $ident_ary['data']['lang_explain'], - - 'S_PROFILE_' . strtoupper($ident) => true - ); - } - - return $tpl_fields; - } - else - { - trigger_error('Wrong mode for custom profile', E_USER_ERROR); - } - } - - /** - * Get Profile Value for display - */ - function get_profile_value($ident_ary) - { - $value = $ident_ary['value']; - $field_type = $ident_ary['data']['field_type']; - - switch ($this->profile_types[$field_type]) - { - case 'int': - if ($value === '' && !$ident_ary['data']['field_show_novalue']) - { - return NULL; - } - return (int) $value; - break; - - case 'string': - case 'text': - if (!$value && !$ident_ary['data']['field_show_novalue']) - { - return NULL; - } - - $value = make_clickable($value); - $value = censor_text($value); - $value = bbcode_nl2br($value); - return $value; - break; - - // case 'datetime': - case 'date': - $date = explode('-', $value); - $day = (isset($date[0])) ? (int) $date[0] : 0; - $month = (isset($date[1])) ? (int) $date[1] : 0; - $year = (isset($date[2])) ? (int) $date[2] : 0; - - if (!$day && !$month && !$year && !$ident_ary['data']['field_show_novalue']) - { - return NULL; - } - else if ($day && $month && $year) - { - global $user; - // Date should display as the same date for every user regardless of timezone - - return $user->create_datetime() - ->setDate($year, $month, $day) - ->setTime(0, 0, 0) - ->format($user->lang['DATE_FORMAT'], true); - } - - return $value; - break; - - case 'dropdown': - $field_id = $ident_ary['data']['field_id']; - $lang_id = $ident_ary['data']['lang_id']; - if (!isset($this->options_lang[$field_id][$lang_id])) - { - $this->get_option_lang($field_id, $lang_id, FIELD_DROPDOWN, false); - } - - if ($value == $ident_ary['data']['field_novalue'] && !$ident_ary['data']['field_show_novalue']) - { - return NULL; - } - - $value = (int) $value; - - // User not having a value assigned - if (!isset($this->options_lang[$field_id][$lang_id][$value])) - { - if ($ident_ary['data']['field_show_novalue']) - { - $value = $ident_ary['data']['field_novalue']; - } - else - { - return NULL; - } - } - - return $this->options_lang[$field_id][$lang_id][$value]; - break; - - case 'bool': - $field_id = $ident_ary['data']['field_id']; - $lang_id = $ident_ary['data']['lang_id']; - if (!isset($this->options_lang[$field_id][$lang_id])) - { - $this->get_option_lang($field_id, $lang_id, FIELD_BOOL, false); - } - - if (!$value && $ident_ary['data']['field_show_novalue']) - { - $value = $ident_ary['data']['field_default_value']; - } - - if ($ident_ary['data']['field_length'] == 1) - { - return (isset($this->options_lang[$field_id][$lang_id][(int) $value])) ? $this->options_lang[$field_id][$lang_id][(int) $value] : NULL; - } - else if (!$value) - { - return NULL; - } - else - { - return $this->options_lang[$field_id][$lang_id][(int) ($value) + 1]; - } - break; - - default: - trigger_error('Unknown profile type', E_USER_ERROR); - break; - } - } - - /** - * Get field value for registration/profile - * @access private - */ - function get_var($field_validation, &$profile_row, $default_value, $preview) - { - global $user; - global $request; - - $profile_row['field_ident'] = (isset($profile_row['var_name'])) ? $profile_row['var_name'] : 'pf_' . $profile_row['field_ident']; - $user_ident = $profile_row['field_ident']; - // checkbox - set the value to "true" if it has been set to 1 - if ($profile_row['field_type'] == FIELD_BOOL && $profile_row['field_length'] == 2) - { - $value = (isset($_REQUEST[$profile_row['field_ident']]) && request_var($profile_row['field_ident'], $default_value) == 1) ? true : ((!isset($user->profile_fields[$user_ident]) || $preview) ? $default_value : $user->profile_fields[$user_ident]); - } - else if ($profile_row['field_type'] == FIELD_INT) - { - if (isset($_REQUEST[$profile_row['field_ident']])) - { - $value = ($request->variable($profile_row['field_ident'], '') === '') ? NULL : $request->variable($profile_row['field_ident'], $default_value); - } - else - { - if (!$preview && array_key_exists($user_ident, $user->profile_fields) && is_null($user->profile_fields[$user_ident])) - { - $value = NULL; - } - else if (!isset($user->profile_fields[$user_ident]) || $preview) - { - $value = $default_value; - } - else - { - $value = $user->profile_fields[$user_ident]; - } - } - - return (is_null($value) || $value === '') ? '' : (int) $value; - } - else - { - $value = (isset($_REQUEST[$profile_row['field_ident']])) ? request_var($profile_row['field_ident'], $default_value, true) : ((!isset($user->profile_fields[$user_ident]) || $preview) ? $default_value : $user->profile_fields[$user_ident]); - - if (gettype($value) == 'string') - { - $value = utf8_normalize_nfc($value); - } - } - - switch ($field_validation) - { - case 'int': - return (int) $value; - break; - } - - return $value; - } - - /** - * Process int-type - * @access private - */ - function generate_int($profile_row, $preview = false) - { - global $template; - - $profile_row['field_value'] = $this->get_var('int', $profile_row, $profile_row['field_default_value'], $preview); - $template->assign_block_vars($this->profile_types[$profile_row['field_type']], array_change_key_case($profile_row, CASE_UPPER)); - } - - /** - * Process date-type - * @access private - */ - function generate_date($profile_row, $preview = false) - { - global $user, $template; - - $profile_row['field_ident'] = (isset($profile_row['var_name'])) ? $profile_row['var_name'] : 'pf_' . $profile_row['field_ident']; - $user_ident = $profile_row['field_ident']; - - $now = getdate(); - - if (!isset($_REQUEST[$profile_row['field_ident'] . '_day'])) - { - if ($profile_row['field_default_value'] == 'now') - { - $profile_row['field_default_value'] = sprintf('%2d-%2d-%4d', $now['mday'], $now['mon'], $now['year']); - } - list($day, $month, $year) = explode('-', ((!isset($user->profile_fields[$user_ident]) || $preview) ? $profile_row['field_default_value'] : $user->profile_fields[$user_ident])); - } - else - { - if ($preview && $profile_row['field_default_value'] == 'now') - { - $profile_row['field_default_value'] = sprintf('%2d-%2d-%4d', $now['mday'], $now['mon'], $now['year']); - list($day, $month, $year) = explode('-', ((!isset($user->profile_fields[$user_ident]) || $preview) ? $profile_row['field_default_value'] : $user->profile_fields[$user_ident])); - } - else - { - $day = request_var($profile_row['field_ident'] . '_day', 0); - $month = request_var($profile_row['field_ident'] . '_month', 0); - $year = request_var($profile_row['field_ident'] . '_year', 0); - } - } - - $profile_row['s_day_options'] = '<option value="0"' . ((!$day) ? ' selected="selected"' : '') . '>--</option>'; - for ($i = 1; $i < 32; $i++) - { - $profile_row['s_day_options'] .= '<option value="' . $i . '"' . (($i == $day) ? ' selected="selected"' : '') . ">$i</option>"; - } - - $profile_row['s_month_options'] = '<option value="0"' . ((!$month) ? ' selected="selected"' : '') . '>--</option>'; - for ($i = 1; $i < 13; $i++) - { - $profile_row['s_month_options'] .= '<option value="' . $i . '"' . (($i == $month) ? ' selected="selected"' : '') . ">$i</option>"; - } - - $profile_row['s_year_options'] = '<option value="0"' . ((!$year) ? ' selected="selected"' : '') . '>--</option>'; - for ($i = $now['year'] - 100; $i <= $now['year'] + 100; $i++) - { - $profile_row['s_year_options'] .= '<option value="' . $i . '"' . (($i == $year) ? ' selected="selected"' : '') . ">$i</option>"; - } - unset($now); - - $profile_row['field_value'] = 0; - $template->assign_block_vars($this->profile_types[$profile_row['field_type']], array_change_key_case($profile_row, CASE_UPPER)); - } - - /** - * Process bool-type - * @access private - */ - function generate_bool($profile_row, $preview = false) - { - global $template; - - $value = $this->get_var('int', $profile_row, $profile_row['field_default_value'], $preview); - - $profile_row['field_value'] = $value; - $template->assign_block_vars($this->profile_types[$profile_row['field_type']], array_change_key_case($profile_row, CASE_UPPER)); - - if ($profile_row['field_length'] == 1) - { - if (!isset($this->options_lang[$profile_row['field_id']][$profile_row['lang_id']]) || !sizeof($this->options_lang[$profile_row['field_id']][$profile_row['lang_id']])) - { - $this->get_option_lang($profile_row['field_id'], $profile_row['lang_id'], FIELD_BOOL, $preview); - } - - foreach ($this->options_lang[$profile_row['field_id']][$profile_row['lang_id']] as $option_id => $option_value) - { - $template->assign_block_vars('bool.options', array( - 'OPTION_ID' => $option_id, - 'CHECKED' => ($value == $option_id) ? ' checked="checked"' : '', - 'VALUE' => $option_value) - ); - } - } - } - - /** - * Process string-type - * @access private - */ - function generate_string($profile_row, $preview = false) - { - global $template; - - $profile_row['field_value'] = $this->get_var('string', $profile_row, $profile_row['lang_default_value'], $preview); - $template->assign_block_vars($this->profile_types[$profile_row['field_type']], array_change_key_case($profile_row, CASE_UPPER)); - } - - /** - * Process text-type - * @access private - */ - function generate_text($profile_row, $preview = false) - { - global $template; - global $user, $phpEx, $phpbb_root_path; - - $field_length = explode('|', $profile_row['field_length']); - $profile_row['field_rows'] = $field_length[0]; - $profile_row['field_cols'] = $field_length[1]; - - $profile_row['field_value'] = $this->get_var('string', $profile_row, $profile_row['lang_default_value'], $preview); - $template->assign_block_vars($this->profile_types[$profile_row['field_type']], array_change_key_case($profile_row, CASE_UPPER)); - } - - /** - * Process dropdown-type - * @access private - */ - function generate_dropdown($profile_row, $preview = false) - { - global $user, $template; - - $value = $this->get_var('int', $profile_row, $profile_row['field_default_value'], $preview); - - if (!isset($this->options_lang[$profile_row['field_id']]) || !isset($this->options_lang[$profile_row['field_id']][$profile_row['lang_id']]) || !sizeof($this->options_lang[$profile_row['field_id']][$profile_row['lang_id']])) - { - $this->get_option_lang($profile_row['field_id'], $profile_row['lang_id'], FIELD_DROPDOWN, $preview); - } - - $profile_row['field_value'] = $value; - $template->assign_block_vars($this->profile_types[$profile_row['field_type']], array_change_key_case($profile_row, CASE_UPPER)); - - foreach ($this->options_lang[$profile_row['field_id']][$profile_row['lang_id']] as $option_id => $option_value) - { - $template->assign_block_vars('dropdown.options', array( - 'OPTION_ID' => $option_id, - 'SELECTED' => ($value == $option_id) ? ' selected="selected"' : '', - 'VALUE' => $option_value) - ); - } - } - - /** - * Return Templated value/field. Possible values for $mode are: - * change == user is able to set/enter profile values; preview == just show the value - * @access private - */ - function process_field_row($mode, $profile_row) - { - global $template; - - $preview = ($mode == 'preview') ? true : false; - - // set template filename - $template->set_filenames(array( - 'cp_body' => 'custom_profile_fields.html') - ); - - // empty previously filled blockvars - foreach ($this->profile_types as $field_case => $field_type) - { - $template->destroy_block_vars($field_type); - } - - // Assign template variables - $type_func = 'generate_' . $this->profile_types[$profile_row['field_type']]; - $this->$type_func($profile_row, $preview); - - // Return templated data - return $template->assign_display('cp_body'); - } - - /** - * Build Array for user insertion into custom profile fields table - */ - function build_insert_sql_array($cp_data) - { - global $db, $user, $auth; - - $sql_not_in = array(); - foreach ($cp_data as $key => $null) - { - $sql_not_in[] = (strncmp($key, 'pf_', 3) === 0) ? substr($key, 3) : $key; - } - - $sql = 'SELECT f.field_type, f.field_ident, f.field_default_value, l.lang_default_value - FROM ' . PROFILE_LANG_TABLE . ' l, ' . PROFILE_FIELDS_TABLE . ' f - WHERE l.lang_id = ' . $user->get_iso_lang_id() . ' - ' . ((sizeof($sql_not_in)) ? ' AND ' . $db->sql_in_set('f.field_ident', $sql_not_in, true) : '') . ' - AND l.field_id = f.field_id'; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - if ($row['field_default_value'] == 'now' && $row['field_type'] == FIELD_DATE) - { - $now = getdate(); - $row['field_default_value'] = sprintf('%2d-%2d-%4d', $now['mday'], $now['mon'], $now['year']); - } - else if ($row['field_default_value'] === '' && $row['field_type'] == FIELD_INT) - { - // We cannot insert an empty string into an integer column. - $row['field_default_value'] = NULL; - } - - $cp_data['pf_' . $row['field_ident']] = (in_array($row['field_type'], array(FIELD_TEXT, FIELD_STRING))) ? $row['lang_default_value'] : $row['field_default_value']; - } - $db->sql_freeresult($result); - - return $cp_data; - } - - /** - * Get profile field value on submit - * @access private - */ - function get_profile_field($profile_row) - { - global $phpbb_root_path, $phpEx; - global $config; - global $request; - - $var_name = 'pf_' . $profile_row['field_ident']; - - switch ($profile_row['field_type']) - { - case FIELD_DATE: - - if (!isset($_REQUEST[$var_name . '_day'])) - { - if ($profile_row['field_default_value'] == 'now') - { - $now = getdate(); - $profile_row['field_default_value'] = sprintf('%2d-%2d-%4d', $now['mday'], $now['mon'], $now['year']); - } - list($day, $month, $year) = explode('-', $profile_row['field_default_value']); - } - else - { - $day = request_var($var_name . '_day', 0); - $month = request_var($var_name . '_month', 0); - $year = request_var($var_name . '_year', 0); - } - - $var = sprintf('%2d-%2d-%4d', $day, $month, $year); - break; - - case FIELD_BOOL: - // Checkbox - if ($profile_row['field_length'] == 2) - { - $var = (isset($_REQUEST[$var_name])) ? 1 : 0; - } - else - { - $var = request_var($var_name, (int) $profile_row['field_default_value']); - } - break; - - case FIELD_STRING: - case FIELD_TEXT: - $var = utf8_normalize_nfc(request_var($var_name, (string) $profile_row['field_default_value'], true)); - break; - - case FIELD_INT: - if (isset($_REQUEST[$var_name]) && $request->variable($var_name, '') === '') - { - $var = NULL; - } - else - { - $var = request_var($var_name, (int) $profile_row['field_default_value']); - } - break; - - case FIELD_DROPDOWN: - $var = request_var($var_name, (int) $profile_row['field_default_value']); - break; - - default: - $var = request_var($var_name, $profile_row['field_default_value']); - break; - } - - return $var; - } -} - -/** -* Custom Profile Fields ACP -* @package phpBB3 -*/ -class custom_profile_admin extends custom_profile -{ - var $vars = array(); - - /** - * Return possible validation options - */ - function validate_options() - { - global $user; - - $validate_ary = array('CHARS_ANY' => '.*', 'NUMBERS_ONLY' => '[0-9]+', 'ALPHA_ONLY' => '[\w]+', 'ALPHA_SPACERS' => '[\w_\+\. \-\[\]]+'); - - $validate_options = ''; - foreach ($validate_ary as $lang => $value) - { - $selected = ($this->vars['field_validation'] == $value) ? ' selected="selected"' : ''; - $validate_options .= '<option value="' . $value . '"' . $selected . '>' . $user->lang[$lang] . '</option>'; - } - - return $validate_options; - } - - /** - * Get string options for second step in ACP - */ - function get_string_options() - { - global $user; - - $options = array( - 0 => array('TITLE' => $user->lang['FIELD_LENGTH'], 'FIELD' => '<input type="number" min="0" name="field_length" size="5" value="' . $this->vars['field_length'] . '" />'), - 1 => array('TITLE' => $user->lang['MIN_FIELD_CHARS'], 'FIELD' => '<input type="number" min="0" name="field_minlen" size="5" value="' . $this->vars['field_minlen'] . '" />'), - 2 => array('TITLE' => $user->lang['MAX_FIELD_CHARS'], 'FIELD' => '<input type="number" min="0" size="5" value="' . $this->vars['field_maxlen'] . '" />'), - 3 => array('TITLE' => $user->lang['FIELD_VALIDATION'], 'FIELD' => '<select name="field_validation">' . $this->validate_options() . '</select>') - ); - - return $options; - } - - /** - * Get text options for second step in ACP - */ - function get_text_options() - { - global $user; - - $options = array( - 0 => array('TITLE' => $user->lang['FIELD_LENGTH'], 'FIELD' => '<input type="number" min="0" max="99999" name="rows" size="5" value="' . $this->vars['rows'] . '" /> ' . $user->lang['ROWS'] . '</dd><dd><input type="number" min="0" max="99999" name="columns" size="5" value="' . $this->vars['columns'] . '" /> ' . $user->lang['COLUMNS'] . ' <input type="hidden" name="field_length" value="' . $this->vars['field_length'] . '" />'), - 1 => array('TITLE' => $user->lang['MIN_FIELD_CHARS'], 'FIELD' => '<input type="number" min="0" max="9999999999" name="field_minlen" size="10" value="' . $this->vars['field_minlen'] . '" />'), - 2 => array('TITLE' => $user->lang['MAX_FIELD_CHARS'], 'FIELD' => '<input type="number" min="0" max="9999999999" name="field_maxlen" size="10" value="' . $this->vars['field_maxlen'] . '" />'), - 3 => array('TITLE' => $user->lang['FIELD_VALIDATION'], 'FIELD' => '<select name="field_validation">' . $this->validate_options() . '</select>') - ); - - return $options; - } - - /** - * Get int options for second step in ACP - */ - function get_int_options() - { - global $user; - - $options = array( - 0 => array('TITLE' => $user->lang['FIELD_LENGTH'], 'FIELD' => '<input type="number" min="0" max="99999" name="field_length" size="5" value="' . $this->vars['field_length'] . '" />'), - 1 => array('TITLE' => $user->lang['MIN_FIELD_NUMBER'], 'FIELD' => '<input type="number" min="0" max="99999" name="field_minlen" size="5" value="' . $this->vars['field_minlen'] . '" />'), - 2 => array('TITLE' => $user->lang['MAX_FIELD_NUMBER'], 'FIELD' => '<input type="number" min="0" max="99999" name="field_maxlen" size="5" value="' . $this->vars['field_maxlen'] . '" />'), - 3 => array('TITLE' => $user->lang['DEFAULT_VALUE'], 'FIELD' => '<input type="post" name="field_default_value" value="' . $this->vars['field_default_value'] . '" />') - ); - - return $options; - } - - /** - * Get bool options for second step in ACP - */ - function get_bool_options() - { - global $user, $config, $lang_defs; - - $default_lang_id = $lang_defs['iso'][$config['default_lang']]; - - $profile_row = array( - 'var_name' => 'field_default_value', - 'field_id' => 1, - 'lang_name' => $this->vars['lang_name'], - 'lang_explain' => $this->vars['lang_explain'], - 'lang_id' => $default_lang_id, - 'field_default_value' => $this->vars['field_default_value'], - 'field_ident' => 'field_default_value', - 'field_type' => FIELD_BOOL, - 'field_length' => $this->vars['field_length'], - 'lang_options' => $this->vars['lang_options'] - ); - - $options = array( - 0 => array('TITLE' => $user->lang['FIELD_TYPE'], 'EXPLAIN' => $user->lang['BOOL_TYPE_EXPLAIN'], 'FIELD' => '<label><input type="radio" class="radio" name="field_length" value="1"' . (($this->vars['field_length'] == 1) ? ' checked="checked"' : '') . ' onchange="document.getElementById(\'add_profile_field\').submit();" /> ' . $user->lang['RADIO_BUTTONS'] . '</label><label><input type="radio" class="radio" name="field_length" value="2"' . (($this->vars['field_length'] == 2) ? ' checked="checked"' : '') . ' onchange="document.getElementById(\'add_profile_field\').submit();" /> ' . $user->lang['CHECKBOX'] . '</label>'), - 1 => array('TITLE' => $user->lang['DEFAULT_VALUE'], 'FIELD' => $this->process_field_row('preview', $profile_row)) - ); - - return $options; - } - - /** - * Get dropdown options for second step in ACP - */ - function get_dropdown_options() - { - global $user, $config, $lang_defs; - - $default_lang_id = $lang_defs['iso'][$config['default_lang']]; - - $profile_row[0] = array( - 'var_name' => 'field_default_value', - 'field_id' => 1, - 'lang_name' => $this->vars['lang_name'], - 'lang_explain' => $this->vars['lang_explain'], - 'lang_id' => $default_lang_id, - 'field_default_value' => $this->vars['field_default_value'], - 'field_ident' => 'field_default_value', - 'field_type' => FIELD_DROPDOWN, - 'lang_options' => $this->vars['lang_options'] - ); - - $profile_row[1] = $profile_row[0]; - $profile_row[1]['var_name'] = 'field_novalue'; - $profile_row[1]['field_ident'] = 'field_novalue'; - $profile_row[1]['field_default_value'] = $this->vars['field_novalue']; - - $options = array( - 0 => array('TITLE' => $user->lang['DEFAULT_VALUE'], 'FIELD' => $this->process_field_row('preview', $profile_row[0])), - 1 => array('TITLE' => $user->lang['NO_VALUE_OPTION'], 'EXPLAIN' => $user->lang['NO_VALUE_OPTION_EXPLAIN'], 'FIELD' => $this->process_field_row('preview', $profile_row[1])) - ); - - return $options; - } - - /** - * Get date options for second step in ACP - */ - function get_date_options() - { - global $user, $config, $lang_defs; - - $default_lang_id = $lang_defs['iso'][$config['default_lang']]; - - $profile_row = array( - 'var_name' => 'field_default_value', - 'lang_name' => $this->vars['lang_name'], - 'lang_explain' => $this->vars['lang_explain'], - 'lang_id' => $default_lang_id, - 'field_default_value' => $this->vars['field_default_value'], - 'field_ident' => 'field_default_value', - 'field_type' => FIELD_DATE, - 'field_length' => $this->vars['field_length'] - ); - - $always_now = request_var('always_now', -1); - if ($always_now == -1) - { - $s_checked = ($this->vars['field_default_value'] == 'now') ? true : false; - } - else - { - $s_checked = ($always_now) ? true : false; - } - - $options = array( - 0 => array('TITLE' => $user->lang['DEFAULT_VALUE'], 'FIELD' => $this->process_field_row('preview', $profile_row)), - 1 => array('TITLE' => $user->lang['ALWAYS_TODAY'], 'FIELD' => '<label><input type="radio" class="radio" name="always_now" value="1"' . (($s_checked) ? ' checked="checked"' : '') . ' onchange="document.getElementById(\'add_profile_field\').submit();" /> ' . $user->lang['YES'] . '</label><label><input type="radio" class="radio" name="always_now" value="0"' . ((!$s_checked) ? ' checked="checked"' : '') . ' onchange="document.getElementById(\'add_profile_field\').submit();" /> ' . $user->lang['NO'] . '</label>'), - ); - - return $options; - } -} diff --git a/phpBB/includes/functions_transfer.php b/phpBB/includes/functions_transfer.php index 07c9171c60..9bec17ca8f 100644 --- a/phpBB/includes/functions_transfer.php +++ b/phpBB/includes/functions_transfer.php @@ -234,7 +234,7 @@ class transfer /** * Determine methods able to be used */ - function methods() + static public function methods() { $methods = array(); $disabled_functions = explode(',', @ini_get('disable_functions')); @@ -287,7 +287,7 @@ class ftp extends transfer /** * Requests data */ - function data() + static public function data() { global $user; @@ -541,7 +541,7 @@ class ftp_fsock extends transfer /** * Requests data */ - function data() + static public function data() { global $user; diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index dba6d3d6c2..6682622d94 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -162,7 +162,7 @@ function user_update_name($old_name, $new_name) function user_add($user_row, $cp_data = false) { global $db, $user, $auth, $config, $phpbb_root_path, $phpEx; - global $phpbb_dispatcher; + global $phpbb_dispatcher, $phpbb_container; if (empty($user_row['username']) || !isset($user_row['group_id']) || !isset($user_row['user_email']) || !isset($user_row['user_type'])) { @@ -210,8 +210,6 @@ function user_add($user_row, $cp_data = false) 'user_lastpage' => '', 'user_posts' => 0, 'user_colour' => '', - 'user_occ' => '', - 'user_interests' => '', 'user_avatar' => '', 'user_avatar_type' => '', 'user_avatar_width' => 0, @@ -276,12 +274,7 @@ function user_add($user_row, $cp_data = false) { $cp_data['user_id'] = (int) $user_id; - if (!class_exists('custom_profile')) - { - include_once($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); - } - - $cp = new custom_profile(); + $cp = $phpbb_container->get('profilefields.manager'); $sql = 'INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $cp->build_insert_sql_array($cp_data)); $db->sql_query($sql); diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php index d0d13aaf13..7c1c61dae7 100644 --- a/phpBB/includes/mcp/mcp_forum.php +++ b/phpBB/includes/mcp/mcp_forum.php @@ -73,6 +73,8 @@ function mcp_forum_view($id, $mode, $action, $forum_info) break; } + $pagination = $phpbb_container->get('pagination'); + $selected_ids = ''; if (sizeof($post_id_list) && $action != 'merge_topics') { @@ -102,7 +104,7 @@ function mcp_forum_view($id, $mode, $action, $forum_info) $limit_time_sql = ($sort_days) ? 'AND t.topic_last_post_time >= ' . (time() - ($sort_days * 86400)) : ''; $base_url = $url . "&i=$id&action=$action&mode=$mode&sd=$sort_dir&sk=$sort_key&st=$sort_days" . (($merge_select) ? $selected_ids : ''); - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $forum_topics, $topics_per_page, $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $forum_topics, $topics_per_page, $start); $template->assign_vars(array( 'ACTION' => $action, @@ -133,7 +135,6 @@ function mcp_forum_view($id, $mode, $action, $forum_info) 'S_MCP_ACTION' => $url . "&i=$id&forum_action=$action&mode=$mode&start=$start" . (($merge_select) ? $selected_ids : ''), - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $forum_topics, $topics_per_page, $start), 'TOTAL_TOPICS' => $user->lang('VIEW_FORUM_TOPICS', (int) $forum_topics), )); diff --git a/phpBB/includes/mcp/mcp_logs.php b/phpBB/includes/mcp/mcp_logs.php index f706840492..7bcb0fc477 100644 --- a/phpBB/includes/mcp/mcp_logs.php +++ b/phpBB/includes/mcp/mcp_logs.php @@ -33,7 +33,7 @@ class mcp_logs function main($id, $mode) { global $auth, $db, $user, $template; - global $config, $phpbb_root_path, $phpEx; + global $config, $phpbb_root_path, $phpEx, $phpbb_container; $user->add_lang('acp/common'); @@ -62,6 +62,8 @@ class mcp_logs $this->tpl_name = 'mcp_logs'; $this->page_title = 'MCP_LOGS'; + $pagination = $phpbb_container->get('pagination'); + $forum_list = array_values(array_intersect(get_forum_list('f_read'), get_forum_list('m_'))); $forum_list[] = 0; @@ -172,10 +174,9 @@ class mcp_logs $start = view_log('mod', $log_data, $log_count, $config['topics_per_page'], $start, $forum_list, $topic_id, 0, $sql_where, $sql_sort, $keywords); $base_url = $this->u_action . "&$u_sort_param$keywords_param"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); $template->assign_vars(array( - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $log_count, $config['topics_per_page'], $start), 'TOTAL' => $user->lang('TOTAL_LOGS', (int) $log_count), 'L_TITLE' => $user->lang['MCP_LOGS'], diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php index d9197da07e..016094c5d4 100644 --- a/phpBB/includes/mcp/mcp_main.php +++ b/phpBB/includes/mcp/mcp_main.php @@ -34,6 +34,7 @@ class mcp_main { global $auth, $db, $user, $template, $action; global $config, $phpbb_root_path, $phpEx, $request; + global $phpbb_dispatcher; $quickmod = ($mode == 'quickmod') ? true : false; @@ -151,6 +152,16 @@ class mcp_main mcp_restore_topic($topic_ids); break; + + default: + /** + * This event allows you to handle custom quickmod options + * + * @event core.modify_quickmod_actions + * @since 3.1.0-a4 + */ + $phpbb_dispatcher->dispatch('core.modify_quickmod_actions'); + break; } switch ($mode) diff --git a/phpBB/includes/mcp/mcp_notes.php b/phpBB/includes/mcp/mcp_notes.php index 12fcbfe91e..28de8724be 100644 --- a/phpBB/includes/mcp/mcp_notes.php +++ b/phpBB/includes/mcp/mcp_notes.php @@ -72,7 +72,7 @@ class mcp_notes function mcp_notes_user_view($action) { global $phpEx, $phpbb_root_path, $config; - global $template, $db, $user, $auth; + global $template, $db, $user, $auth, $phpbb_container; $user_id = request_var('u', 0); $username = request_var('username', '', true); @@ -80,6 +80,7 @@ class mcp_notes $st = request_var('st', 0); $sk = request_var('sk', 'b'); $sd = request_var('sd', 'd'); + $pagination = $phpbb_container->get('pagination'); add_form_key('mcp_notes'); @@ -216,7 +217,7 @@ class mcp_notes } $base_url = $this->u_action . "&$u_sort_param$keywords_param"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); $template->assign_vars(array( 'U_POST_ACTION' => $this->u_action, @@ -228,7 +229,6 @@ class mcp_notes 'L_TITLE' => $user->lang['MCP_NOTES_USER'], - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $log_count, $config['topics_per_page'], $start), 'TOTAL_REPORTS' => $user->lang('LIST_REPORTS', (int) $log_count), 'RANK_TITLE' => $rank_title, diff --git a/phpBB/includes/mcp/mcp_pm_reports.php b/phpBB/includes/mcp/mcp_pm_reports.php index f0452b37a5..008984b1c3 100644 --- a/phpBB/includes/mcp/mcp_pm_reports.php +++ b/phpBB/includes/mcp/mcp_pm_reports.php @@ -39,6 +39,7 @@ class mcp_pm_reports include_once($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx); $start = request_var('start', 0); + $pagination = $phpbb_container->get('pagination'); $this->page_title = 'MCP_PM_REPORTS'; @@ -297,7 +298,7 @@ class mcp_pm_reports } $base_url = $this->u_action . "&st=$sort_days&sk=$sort_key&sd=$sort_dir"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total, $config['topics_per_page'], $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $total, $config['topics_per_page'], $start); // Now display the page $template->assign_vars(array( @@ -308,7 +309,6 @@ class mcp_pm_reports 'S_MCP_ACTION' => $this->u_action, 'S_CLOSED' => ($mode == 'pm_reports_closed') ? true : false, - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $total, $config['topics_per_page'], $start), 'TOTAL' => $total, 'TOTAL_REPORTS' => $user->lang('LIST_REPORTS', (int) $total), ) diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php index 0318bc5e15..a46c4bd499 100644 --- a/phpBB/includes/mcp/mcp_queue.php +++ b/phpBB/includes/mcp/mcp_queue.php @@ -337,6 +337,7 @@ class mcp_queue $topic_id = $request->variable('t', 0); $forum_info = array(); + $pagination = $phpbb_container->get('pagination'); if ($topic_id) { @@ -532,7 +533,7 @@ class mcp_queue unset($rowset, $forum_names); $base_url = $this->u_action . "&f=$forum_id&st=$sort_days&sk=$sort_key&sd=$sort_dir"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total, $config['topics_per_page'], $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $total, $config['topics_per_page'], $start); // Now display the page $template->assign_vars(array( @@ -546,7 +547,6 @@ class mcp_queue 'S_TOPICS' => $is_topics, 'S_RESTORE' => $is_restore, - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $total, $config['topics_per_page'], $start), 'TOPIC_ID' => $topic_id, 'TOTAL' => $user->lang(((!$is_topics) ? 'VIEW_TOPIC_POSTS' : 'VIEW_FORUM_TOPICS'), (int) $total), )); @@ -653,6 +653,11 @@ class mcp_queue // Handle notifications foreach ($post_info as $post_id => $post_data) { + // A single topic approval may also happen here, so handle deleting the respective notification. + if (!$post_data['topic_posts_approved']) + { + $phpbb_notifications->delete_notifications('topic_in_queue', $post_data['topic_id']); + } $phpbb_notifications->delete_notifications('post_in_queue', $post_id); $phpbb_notifications->add_notifications(array( @@ -772,9 +777,12 @@ class mcp_queue $notify_poster = ($action == 'approve' && isset($_REQUEST['notify_poster'])) ? true : false; $phpbb_content_visibility = $phpbb_container->get('content.visibility'); + $first_post_ids = array(); + foreach ($topic_info as $topic_id => $topic_data) { $phpbb_content_visibility->set_topic_visibility(ITEM_APPROVED, $topic_id, $topic_data['forum_id'], $user->data['user_id'], time(), ''); + $first_post_ids[$topic_id] = (int) $topic_data['topic_first_post_id']; $topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f={$topic_data['forum_id']}&t={$topic_id}"); @@ -798,23 +806,43 @@ class mcp_queue // Only send out the mails, when the posts are being approved if ($action == 'approve') { + // Grab the first post text as it's needed for the quote notification. + $sql = 'SELECT topic_id, post_text + FROM ' . POSTS_TABLE . ' + WHERE ' . $db->sql_in_set('post_id', $first_post_ids); + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + $topic_info[$row['topic_id']]['post_text'] = $row['post_text']; + } + $db->sql_freeresult($result); + // Handle notifications $phpbb_notifications = $phpbb_container->get('notification_manager'); foreach ($topic_info as $topic_id => $topic_data) { - $phpbb_notifications->delete_notifications('topic_in_queue', $post_data['topic_id']); + $topic_data = array_merge($topic_data, array( + 'post_id' => $topic_data['topic_first_post_id'], + 'post_subject' => $topic_data['topic_title'], + 'post_time' => $topic_data['topic_time'], + 'poster_id' => $topic_data['topic_poster'], + 'username' => $topic_data['topic_first_poster_name'], + )); + + $phpbb_notifications->delete_notifications('topic_in_queue', $topic_id); $phpbb_notifications->add_notifications(array( 'quote', 'topic', - ), $post_data); + ), $topic_data); - $phpbb_notifications->mark_notifications_read('quote', $post_data['post_id'], $user->data['user_id']); - $phpbb_notifications->mark_notifications_read('topic', $post_data['topic_id'], $user->data['user_id']); + $phpbb_notifications->mark_notifications_read('quote', $topic_data['post_id'], $user->data['user_id']); + $phpbb_notifications->mark_notifications_read('topic', $topic_id, $user->data['user_id']); if ($notify_poster) { - $phpbb_notifications->add_notifications('approve_topic', $post_data); + $phpbb_notifications->add_notifications('approve_topic', $topic_data); } } } diff --git a/phpBB/includes/mcp/mcp_reports.php b/phpBB/includes/mcp/mcp_reports.php index 8db5bb9727..8026e071cd 100644 --- a/phpBB/includes/mcp/mcp_reports.php +++ b/phpBB/includes/mcp/mcp_reports.php @@ -315,6 +315,7 @@ class mcp_reports $forum_list[] = 0; $forum_data = array(); + $pagination = $phpbb_container->get('pagination'); $forum_options = '<option value="0"' . (($forum_id == 0) ? ' selected="selected"' : '') . '>' . $user->lang['ALL_FORUMS'] . '</option>'; foreach ($forum_list_reports as $row) @@ -410,7 +411,7 @@ class mcp_reports } $base_url = $this->u_action . "&f=$forum_id&t=$topic_id&st=$sort_days&sk=$sort_key&sd=$sort_dir"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total, $config['topics_per_page'], $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $total, $config['topics_per_page'], $start); // Now display the page $template->assign_vars(array( @@ -422,7 +423,6 @@ class mcp_reports 'S_FORUM_OPTIONS' => $forum_options, 'S_CLOSED' => ($mode == 'reports_closed') ? true : false, - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $total, $config['topics_per_page'], $start), 'TOPIC_ID' => $topic_id, 'TOTAL' => $total, 'TOTAL_REPORTS' => $user->lang('LIST_REPORTS', (int) $total), @@ -615,23 +615,25 @@ function close_report($report_id_list, $mode, $action, $pm = false) } unset($close_report_posts, $close_report_topics); + $phpbb_notifications = $phpbb_container->get('notification_manager'); + foreach ($reports as $report) { if ($pm) { add_log('mod', 0, 0, 'LOG_PM_REPORT_' . strtoupper($action) . 'D', $post_info[$report['pm_id']]['message_subject']); + $phpbb_notifications->delete_notifications('report_pm', $report['pm_id']); } else { add_log('mod', $post_info[$report['post_id']]['forum_id'], $post_info[$report['post_id']]['topic_id'], 'LOG_REPORT_' . strtoupper($action) . 'D', $post_info[$report['post_id']]['post_subject']); + $phpbb_notifications->delete_notifications('report_post', $report['post_id']); } } // Notify reporters if (sizeof($notify_reporters)) { - $phpbb_notifications = $phpbb_container->get('notification_manager'); - foreach ($notify_reporters as $report_id => $reporter) { if ($reporter['user_id'] == ANONYMOUS) @@ -648,8 +650,6 @@ function close_report($report_id_list, $mode, $action, $pm = false) 'closer_id' => $user->data['user_id'], 'from_user_id' => $post_info[$post_id]['author_id'], ))); - - $phpbb_notifications->delete_notifications('report_pm', $post_id); } else { @@ -657,8 +657,6 @@ function close_report($report_id_list, $mode, $action, $pm = false) 'reporter' => $reporter['user_id'], 'closer_id' => $user->data['user_id'], ))); - - $phpbb_notifications->delete_notifications('report_post', $post_id); } } } diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php index a2aa03c583..cdb88bf2bf 100644 --- a/phpBB/includes/mcp/mcp_topic.php +++ b/phpBB/includes/mcp/mcp_topic.php @@ -26,6 +26,7 @@ function mcp_topic_view($id, $mode, $action) $url = append_sid("{$phpbb_root_path}mcp.$phpEx?" . extra_url()); $user->add_lang('viewtopic'); + $pagination = $phpbb_container->get('pagination'); $topic_id = request_var('t', 0); $topic_info = get_topic_data(array($topic_id), false, true); @@ -129,12 +130,7 @@ function mcp_topic_view($id, $mode, $action) { $start = 0; } - - // Make sure $start is set to the last page if it exceeds the amount - if ($start < 0 || $start >= $total) - { - $start = ($start < 0) ? 0 : floor(($total - 1) / $posts_per_page) * $posts_per_page; - } + $start = $pagination->validate_start($start, $posts_per_page, $total); $sql = 'SELECT u.username, u.username_clean, u.user_colour, p.* FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u @@ -304,7 +300,7 @@ function mcp_topic_view($id, $mode, $action) $base_url = append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&t={$topic_info['topic_id']}&mode=$mode&action=$action&to_topic_id=$to_topic_id&posts_per_page=$posts_per_page&st=$sort_days&sk=$sort_key&sd=$sort_dir"); if ($posts_per_page) { - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total, $posts_per_page, $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $total, $posts_per_page, $start); } $template->assign_vars(array( @@ -347,7 +343,6 @@ function mcp_topic_view($id, $mode, $action) 'RETURN_TOPIC' => sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f={$topic_info['forum_id']}&t={$topic_info['topic_id']}&start=$start") . '">', '</a>'), 'RETURN_FORUM' => sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", "f={$topic_info['forum_id']}&start=$start") . '">', '</a>'), - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $total, $posts_per_page, $start), 'TOTAL_POSTS' => $user->lang('VIEW_TOPIC_POSTS', (int) $total), )); } diff --git a/phpBB/includes/mcp/mcp_warn.php b/phpBB/includes/mcp/mcp_warn.php index 3ffd75ac78..d396d004dc 100644 --- a/phpBB/includes/mcp/mcp_warn.php +++ b/phpBB/includes/mcp/mcp_warn.php @@ -134,10 +134,11 @@ class mcp_warn */ function mcp_warn_list_view($action) { - global $phpEx, $phpbb_root_path, $config; + global $phpEx, $phpbb_root_path, $config, $phpbb_container; global $template, $db, $user, $auth; $user->add_lang('memberlist'); + $pagination = $phpbb_container->get('pagination'); $start = request_var('start', 0); $st = request_var('st', 0); @@ -176,7 +177,7 @@ class mcp_warn } $base_url = append_sid("{$phpbb_root_path}mcp.$phpEx", "i=warn&mode=list&st=$st&sk=$sk&sd=$sd"); - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $user_count, $config['topics_per_page'], $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $user_count, $config['topics_per_page'], $start); $template->assign_vars(array( 'U_POST_ACTION' => $this->u_action, @@ -185,7 +186,6 @@ class mcp_warn 'S_SELECT_SORT_KEY' => $s_sort_key, 'S_SELECT_SORT_DAYS' => $s_limit_days, - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $user_count, $config['topics_per_page'], $start), 'TOTAL_USERS' => $user->lang('LIST_USERS', (int) $user_count), )); } diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php index acd31fd519..ad6743b3a3 100644 --- a/phpBB/includes/message_parser.php +++ b/phpBB/includes/message_parser.php @@ -103,6 +103,8 @@ class bbcode_firstpass extends bbcode */ function bbcode_init($allow_custom_bbcode = true) { + global $phpbb_dispatcher; + static $rowset; // This array holds all bbcode data. BBCodes will be processed in this @@ -162,6 +164,21 @@ class bbcode_firstpass extends bbcode 'regexp' => array($row['first_pass_match'] => str_replace('$uid', $this->bbcode_uid, $row['first_pass_replace'])) ); } + + $bbcodes = $this->bbcodes; + + /** + * Event to modify the bbcode data for later parsing + * + * @event core.modify_bbcode_init + * @var array bbcodes Array of bbcode data for use in parsing + * @var array rowset Array of bbcode data from the database + * @since 3.1.0-a3 + */ + $vars = array('bbcodes', 'rowset'); + extract($phpbb_dispatcher->trigger_event('core.modify_bbcode_init', compact($vars))); + + $this->bbcodes = $bbcodes; } /** @@ -1198,6 +1215,8 @@ class parse_message extends bbcode_firstpass */ function format_display($allow_bbcode, $allow_magic_url, $allow_smilies, $update_this_message = true) { + global $phpbb_dispatcher; + // If false, then the parsed message get returned but internal message not processed. if (!$update_this_message) { @@ -1226,6 +1245,28 @@ class parse_message extends bbcode_firstpass $this->message = bbcode_nl2br($this->message); $this->message = smiley_text($this->message, !$allow_smilies); + $text = $this->message; + $uid = $this->bbcode_uid; + + /** + * Event to modify the text after it is parsed + * + * @event core.modify_format_display_text_after + * @var string text The message text to parse + * @var string uid The bbcode uid + * @var bool allow_bbcode Do we allow bbcodes + * @var bool allow_magic_url Do we allow magic urls + * @var bool allow_smilies Do we allow smilies + * @var bool update_this_message Do we update the internal message + * with the parsed result + * @since 3.1.0-a3 + */ + $vars = array('text', 'uid', 'allow_bbcode', 'allow_magic_url', 'allow_smilies', 'update_this_message'); + extract($phpbb_dispatcher->trigger_event('core.modify_format_display_text_after', compact($vars))); + + $this->message = $text; + $this->bbcode_uid = $uid; + if (!$update_this_message) { unset($this->message); @@ -1420,6 +1461,7 @@ class parse_message extends bbcode_firstpass 'is_orphan' => 1, 'real_filename' => $filedata['real_filename'], 'attach_comment'=> $this->filename_data['filecomment'], + 'filesize' => $filedata['filesize'], ); $this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data); @@ -1531,6 +1573,7 @@ class parse_message extends bbcode_firstpass 'is_orphan' => 1, 'real_filename' => $filedata['real_filename'], 'attach_comment'=> $this->filename_data['filecomment'], + 'filesize' => $filedata['filesize'], ); $this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data); @@ -1539,8 +1582,10 @@ class parse_message extends bbcode_firstpass if (isset($this->plupload) && $this->plupload->is_active()) { + $download_url = append_sid("{$phpbb_root_path}download/file.{$phpEx}", 'mode=view&id=' . $new_entry['attach_id']); + // Send the client the attachment data to maintain state - $json_response->send($this->attachment_data); + $json_response->send(array('data' => $this->attachment_data, 'download_url' => $download_url)); } } } @@ -1608,7 +1653,7 @@ class parse_message extends bbcode_firstpass if (sizeof($not_orphan)) { // Get the attachment data, based on the poster id... - $sql = 'SELECT attach_id, is_orphan, real_filename, attach_comment + $sql = 'SELECT attach_id, is_orphan, real_filename, attach_comment, filesize FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('attach_id', array_keys($not_orphan)) . ' AND poster_id = ' . $check_user_id; @@ -1633,7 +1678,7 @@ class parse_message extends bbcode_firstpass // Regenerate newly uploaded attachments if (sizeof($orphan)) { - $sql = 'SELECT attach_id, is_orphan, real_filename, attach_comment + $sql = 'SELECT attach_id, is_orphan, real_filename, attach_comment, filesize FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set('attach_id', array_keys($orphan)) . ' AND poster_id = ' . $user->data['user_id'] . ' diff --git a/phpBB/includes/ucp/ucp_attachments.php b/phpBB/includes/ucp/ucp_attachments.php index dc095e7b73..6a5b48a181 100644 --- a/phpBB/includes/ucp/ucp_attachments.php +++ b/phpBB/includes/ucp/ucp_attachments.php @@ -26,7 +26,7 @@ class ucp_attachments function main($id, $mode) { - global $template, $user, $db, $config, $phpEx, $phpbb_root_path; + global $template, $user, $db, $config, $phpEx, $phpbb_root_path, $phpbb_container; $start = request_var('start', 0); $sort_key = request_var('sk', 'a'); @@ -119,6 +119,10 @@ class ucp_attachments $num_attachments = $db->sql_fetchfield('num_attachments'); $db->sql_freeresult($result); + // Ensure start is a valid value + $pagination = $phpbb_container->get('pagination'); + $start = $pagination->validate_start($start, $config['topics_per_page'], $num_attachments); + $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) @@ -171,10 +175,9 @@ class ucp_attachments $db->sql_freeresult($result); $base_url = $this->u_action . "&sk=$sort_key&sd=$sort_dir"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $num_attachments, $config['topics_per_page'], $start); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $num_attachments, $config['topics_per_page'], $start); $template->assign_vars(array( - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $num_attachments, $config['topics_per_page'], $start), 'TOTAL_ATTACHMENTS' => $num_attachments, 'L_TITLE' => $user->lang['UCP_ATTACHMENTS'], diff --git a/phpBB/includes/ucp/ucp_groups.php b/phpBB/includes/ucp/ucp_groups.php index 7c4bc8f617..373d9433b2 100644 --- a/phpBB/includes/ucp/ucp_groups.php +++ b/phpBB/includes/ucp/ucp_groups.php @@ -813,13 +813,14 @@ class ucp_groups $s_action_options .= '<option value="' . $option . '">' . $user->lang['GROUP_' . $lang] . '</option>'; } + $pagination = $phpbb_container->get('pagination'); $base_url = $this->u_action . "&action=$action&g=$group_id"; - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total_members, $config['topics_per_page'], $start); + $start = $pagination->validate_start($start, $config['topics_per_page'], $total_members); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $total_members, $config['topics_per_page'], $start); $template->assign_vars(array( 'S_LIST' => true, 'S_ACTION_OPTIONS' => $s_action_options, - 'S_ON_PAGE' => phpbb_on_page($template, $user, $base_url, $total_members, $config['topics_per_page'], $start), 'U_ACTION' => $this->u_action . "&g=$group_id", 'S_UCP_ACTION' => $this->u_action . "&g=$group_id", diff --git a/phpBB/includes/ucp/ucp_main.php b/phpBB/includes/ucp/ucp_main.php index b859413d92..3ccf3e3545 100644 --- a/phpBB/includes/ucp/ucp_main.php +++ b/phpBB/includes/ucp/ucp_main.php @@ -195,9 +195,6 @@ class ucp_main 'POSTS_DAY' => $user->lang('POST_DAY', $posts_per_day), 'POSTS_PCT' => $user->lang('POST_PCT', $percentage), - 'OCCUPATION' => (!empty($row['user_occ'])) ? $row['user_occ'] : '', - 'INTERESTS' => (!empty($row['user_interests'])) ? $row['user_interests'] : '', - // 'S_GROUP_OPTIONS' => $group_options, 'U_SEARCH_USER' => ($auth->acl_get('u_search')) ? append_sid("{$phpbb_root_path}search.$phpEx", 'author_id=' . $user->data['user_id'] . '&sr=posts') : '', @@ -646,6 +643,7 @@ class ucp_main $table = ($mode == 'subscribed') ? TOPICS_WATCH_TABLE : BOOKMARKS_TABLE; $start = request_var('start', 0); + $pagination = $phpbb_container->get('pagination'); // Grab icons $icons = $cache->obtain_icons(); @@ -669,10 +667,10 @@ class ucp_main if ($topics_count) { - phpbb_generate_template_pagination($template, $this->u_action, 'pagination', 'start', $topics_count, $config['topics_per_page'], $start); + $start = $pagination->validate_start($start, $config['topics_per_page'], $topics_count); + $pagination->generate_template_pagination($this->u_action, 'pagination', 'start', $topics_count, $config['topics_per_page'], $start); $template->assign_vars(array( - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $this->u_action, $topics_count, $config['topics_per_page'], $start), 'TOTAL_TOPICS' => $user->lang('VIEW_FORUM_TOPICS', (int) $topics_count), )); } @@ -839,7 +837,7 @@ class ucp_main 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id), )); - phpbb_generate_template_pagination($template, append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $row['forum_id'] . "&t=$topic_id"), 'topicrow.pagination', 'start', $replies + 1, $config['posts_per_page'], 1, true, true); + $pagination->generate_template_pagination(append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $row['forum_id'] . "&t=$topic_id"), 'topicrow.pagination', 'start', $replies + 1, $config['posts_per_page'], 1, true, true); } } } diff --git a/phpBB/includes/ucp/ucp_notifications.php b/phpBB/includes/ucp/ucp_notifications.php index 63dbe79666..7c487b9073 100644 --- a/phpBB/includes/ucp/ucp_notifications.php +++ b/phpBB/includes/ucp/ucp_notifications.php @@ -31,6 +31,7 @@ class ucp_notifications $form_time = ($form_time <= 0 || $form_time > time()) ? time() : $form_time; $phpbb_notifications = $phpbb_container->get('notification_manager'); + $pagination = $phpbb_container->get('pagination'); switch ($mode) { @@ -97,7 +98,19 @@ class ucp_notifications $phpbb_notifications->mark_notifications_read(false, false, $user->data['user_id'], $form_time); meta_refresh(3, $this->u_action); - $message = $user->lang['NOTIFICATIONS_MARK_ALL_READ_SUCCESS'] . '<br /><br />' . sprintf($user->lang['RETURN_UCP'], '<a href="' . $this->u_action . '">', '</a>'); + $message = $user->lang['NOTIFICATIONS_MARK_ALL_READ_SUCCESS']; + + if ($request->is_ajax()) + { + $json_response = new \phpbb\json_response(); + $json_response->send(array( + 'MESSAGE_TITLE' => $user->lang['INFORMATION'], + 'MESSAGE_TEXT' => $message, + 'success' => true, + )); + } + $message .= '<br /><br />' . $user->lang('RETURN_UCP', '<a href="' . $this->u_action . '">', '</a>'); + trigger_error($message); } else @@ -137,10 +150,10 @@ class ucp_notifications } $base_url = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=ucp_notifications&mode=notification_list"); - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $notifications['total_count'], $config['topics_per_page'], $start); + $start = $pagination->validate_start($start, $config['topics_per_page'], $notifications['total_count']); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $notifications['total_count'], $config['topics_per_page'], $start); $template->assign_vars(array( - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $notifications['total_count'], $config['topics_per_page'], $start), 'TOTAL_COUNT' => $notifications['total_count'], 'U_MARK_ALL' => $base_url . '&mark=all&token=' . generate_link_hash('mark_all_notifications_read'), )); diff --git a/phpBB/includes/ucp/ucp_pm_viewfolder.php b/phpBB/includes/ucp/ucp_pm_viewfolder.php index 9393e65f3c..a567283543 100644 --- a/phpBB/includes/ucp/ucp_pm_viewfolder.php +++ b/phpBB/includes/ucp/ucp_pm_viewfolder.php @@ -393,7 +393,7 @@ function view_folder($id, $mode, $folder_id, $folder) */ function get_pm_from($folder_id, $folder, $user_id) { - global $user, $db, $template, $config, $auth, $phpbb_root_path, $phpEx; + global $user, $db, $template, $config, $auth, $phpbb_container, $phpbb_root_path, $phpEx; $start = request_var('start', 0); @@ -402,6 +402,8 @@ function get_pm_from($folder_id, $folder, $user_id) $sort_key = request_var('sk', 't'); $sort_dir = request_var('sd', 'd'); + $pagination = $phpbb_container->get('pagination'); + // PM ordering options $limit_days = array(0 => $user->lang['ALL_MESSAGES'], 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']); @@ -452,10 +454,10 @@ function get_pm_from($folder_id, $folder, $user_id) } $base_url = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=pm&mode=view&action=view_folder&f=$folder_id&$u_sort_param"); - phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $pm_count, $config['topics_per_page'], $start); + $start = $pagination->validate_start($start, $config['topics_per_page'], $pm_count); + $pagination->generate_template_pagination($base_url, 'pagination', 'start', $pm_count, $config['topics_per_page'], $start); $template->assign_vars(array( - 'PAGE_NUMBER' => phpbb_on_page($template, $user, $base_url, $pm_count, $config['topics_per_page'], $start), 'TOTAL_MESSAGES' => $user->lang('VIEW_PM_MESSAGES', (int) $pm_count), 'POST_IMG' => (!$auth->acl_get('u_sendpm')) ? $user->img('button_topic_locked', 'POST_PM_LOCKED') : $user->img('button_pm_new', 'POST_NEW_PM'), @@ -481,14 +483,10 @@ function get_pm_from($folder_id, $folder, $user_id) { $store_reverse = true; - if ($start + $config['topics_per_page'] > $pm_count) - { - $sql_limit = min($config['topics_per_page'], max(1, $pm_count - $start)); - } - // Select the sort order $direction = ($sort_dir == 'd') ? 'ASC' : 'DESC'; - $sql_start = max(0, $pm_count - $sql_limit - $start); + $sql_limit = $pagination->reverse_limit($start, $sql_limit, $pm_count); + $sql_start = $pagination->reverse_start($start, $sql_limit, $pm_count); } else { diff --git a/phpBB/includes/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php index cebbadc7c7..e513b8ade2 100644 --- a/phpBB/includes/ucp/ucp_pm_viewmessage.php +++ b/phpBB/includes/ucp/ucp_pm_viewmessage.php @@ -20,7 +20,7 @@ if (!defined('IN_PHPBB')) */ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) { - global $user, $template, $auth, $db, $cache; + global $user, $template, $auth, $db, $cache, $phpbb_container; global $phpbb_root_path, $request, $phpEx, $config, $phpbb_dispatcher; $user->add_lang(array('viewtopic', 'memberlist')); @@ -61,11 +61,7 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) // Load the custom profile fields if ($config['load_cpf_pm']) { - if (!class_exists('custom_profile')) - { - include($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); - } - $cp = new custom_profile(); + $cp = $phpbb_container->get('profilefields.manager'); $profile_fields = $cp->generate_profile_fields_template('grab', $author_id); } @@ -192,7 +188,6 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) 'AUTHOR_AVATAR' => (isset($user_info['avatar'])) ? $user_info['avatar'] : '', 'AUTHOR_JOINED' => $user->format_date($user_info['user_regdate']), 'AUTHOR_POSTS' => (int) $user_info['user_posts'], - 'AUTHOR_FROM' => (!empty($user_info['user_from'])) ? $user_info['user_from'] : '', 'ONLINE_IMG' => (!$config['load_onlinetrack']) ? '' : ((isset($user_info['online']) && $user_info['online']) ? $user->img('icon_user_online', $user->lang['ONLINE']) : $user->img('icon_user_offline', $user->lang['OFFLINE'])), 'S_ONLINE' => (!$config['load_onlinetrack']) ? false : ((isset($user_info['online']) && $user_info['online']) ? true : false), @@ -279,7 +274,7 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) // Display not already displayed Attachments for this post, we already parsed them. ;) if (isset($attachments) && sizeof($attachments)) { - $methods = phpbb_gen_download_links('post_msg_id', $msg_id, $phpbb_root_path, $phpEx); + $methods = phpbb_gen_download_links('msg_id', $msg_id, $phpbb_root_path, $phpEx); foreach ($methods as $method) { $template->assign_block_vars('dl_method', $method); diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php index 2252b2ea17..8def48b1b4 100644 --- a/phpBB/includes/ucp/ucp_profile.php +++ b/phpBB/includes/ucp/ucp_profile.php @@ -29,8 +29,7 @@ class ucp_profile function main($id, $mode) { global $cache, $config, $db, $user, $auth, $template, $phpbb_root_path, $phpEx; - global $request; - global $phpbb_container; + global $request, $phpbb_container; $user->add_lang('posting'); @@ -82,13 +81,16 @@ class ucp_profile $error[] = ($data['password_confirm']) ? 'NEW_PASSWORD_ERROR' : 'NEW_PASSWORD_CONFIRM_EMPTY'; } + // Instantiate passwords manager + $passwords_manager = $phpbb_container->get('passwords.manager'); + // Only check the new password against the previous password if there have been no errors - if (!sizeof($error) && $auth->acl_get('u_chgpasswd') && $data['new_password'] && phpbb_check_hash($data['new_password'], $user->data['user_password'])) + if (!sizeof($error) && $auth->acl_get('u_chgpasswd') && $data['new_password'] && $passwords_manager->check($data['new_password'], $user->data['user_password'])) { $error[] = 'SAME_PASSWORD_ERROR'; } - if (!phpbb_check_hash($data['cur_password'], $user->data['user_password'])) + if (!$passwords_manager->check($data['cur_password'], $user->data['user_password'])) { $error[] = ($data['cur_password']) ? 'CUR_PASSWORD_ERROR' : 'CUR_PASSWORD_EMPTY'; } @@ -105,7 +107,7 @@ class ucp_profile 'username_clean' => ($auth->acl_get('u_chgname') && $config['allow_namechange']) ? utf8_clean_string($data['username']) : $user->data['username_clean'], 'user_email' => ($auth->acl_get('u_chgemail')) ? $data['email'] : $user->data['user_email'], 'user_email_hash' => ($auth->acl_get('u_chgemail')) ? phpbb_email_hash($data['email']) : $user->data['user_email_hash'], - 'user_password' => ($auth->acl_get('u_chgpasswd') && $data['new_password']) ? phpbb_hash($data['new_password']) : $user->data['user_password'], + 'user_password' => ($auth->acl_get('u_chgpasswd') && $data['new_password']) ? $passwords_manager->hash($data['new_password']) : $user->data['user_password'], 'user_passchg' => ($auth->acl_get('u_chgpasswd') && $data['new_password']) ? time() : 0, ); @@ -114,7 +116,7 @@ class ucp_profile add_log('user', $user->data['user_id'], 'LOG_USER_UPDATE_NAME', $user->data['username'], $data['username']); } - if ($auth->acl_get('u_chgpasswd') && $data['new_password'] && !phpbb_check_hash($data['new_password'], $user->data['user_password'])) + if ($auth->acl_get('u_chgpasswd') && $data['new_password'] && !$passwords_manager->check($data['new_password'], $user->data['user_password'])) { $user->reset_login_keys(); add_log('user', $user->data['user_id'], 'LOG_USER_NEW_PASSWORD', $data['username']); @@ -257,9 +259,7 @@ class ucp_profile trigger_error('NO_AUTH_PROFILEINFO'); } - include($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); - - $cp = new custom_profile(); + $cp = $phpbb_container->get('profilefields.manager'); $cp_data = $cp_error = array(); @@ -270,9 +270,6 @@ class ucp_profile 'yim' => request_var('yim', $user->data['user_yim']), 'jabber' => utf8_normalize_nfc(request_var('jabber', $user->data['user_jabber'], true)), 'website' => request_var('website', $user->data['user_website']), - 'location' => utf8_normalize_nfc(request_var('location', $user->data['user_from'], true)), - 'occupation' => utf8_normalize_nfc(request_var('occupation', $user->data['user_occ'], true)), - 'interests' => utf8_normalize_nfc(request_var('interests', $user->data['user_interests'], true)), ); if ($config['allow_birthdays']) @@ -307,9 +304,6 @@ class ucp_profile 'website' => array( array('string', true, 12, 255), array('match', true, '#^http[s]?://(.*?\.)*?[a-z0-9\-]+\.[a-z]{2,4}#i')), - 'location' => array('string', true, 2, 100), - 'occupation' => array('string', true, 2, 500), - 'interests' => array('string', true, 2, 500), ); if ($config['allow_birthdays']) @@ -355,9 +349,6 @@ class ucp_profile 'user_yim' => $data['yim'], 'user_jabber' => $data['jabber'], 'user_website' => $data['website'], - 'user_from' => $data['location'], - 'user_occ' => $data['occupation'], - 'user_interests'=> $data['interests'], 'user_notify_type' => $data['notify'], ); @@ -426,9 +417,6 @@ class ucp_profile 'MSN' => $data['msn'], 'JABBER' => $data['jabber'], 'WEBSITE' => $data['website'], - 'LOCATION' => $data['location'], - 'OCCUPATION'=> $data['occupation'], - 'INTERESTS' => $data['interests'], )); // Get additional profile fields and assign them to the template block var 'profile_fields' diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php index 1641c6eef1..ff51ca7b3c 100644 --- a/phpBB/includes/ucp/ucp_register.php +++ b/phpBB/includes/ucp/ucp_register.php @@ -35,8 +35,6 @@ class ucp_register trigger_error('UCP_REGISTER_DISABLE'); } - include($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); - $coppa = $request->is_set('coppa') ? (int) $request->variable('coppa', false) : false; $agreed = $request->variable('agreed', false); $submit = $request->is_set_post('submit'); @@ -78,7 +76,7 @@ class ucp_register } } - $cp = new custom_profile(); + $cp = $phpbb_container->get('profilefields.manager'); $error = $cp_data = $cp_error = array(); $s_hidden_fields = array(); @@ -294,9 +292,12 @@ class ucp_register $user_inactive_time = 0; } + // Instantiate passwords manager + $passwords_manager = $phpbb_container->get('passwords.manager'); + $user_row = array( 'username' => $data['username'], - 'user_password' => phpbb_hash($data['new_password']), + 'user_password' => $passwords_manager->hash($data['new_password']), 'user_email' => $data['email'], 'group_id' => (int) $group_id, 'user_timezone' => $data['tz'], diff --git a/phpBB/includes/ucp/ucp_remind.php b/phpBB/includes/ucp/ucp_remind.php index b3def63896..99e945eeae 100644 --- a/phpBB/includes/ucp/ucp_remind.php +++ b/phpBB/includes/ucp/ucp_remind.php @@ -27,7 +27,7 @@ class ucp_remind function main($id, $mode) { global $config, $phpbb_root_path, $phpEx; - global $db, $user, $auth, $template; + global $db, $user, $auth, $template, $phpbb_container; if (!$config['allow_password_reset']) { @@ -88,8 +88,11 @@ class ucp_remind // For the activation key a random length between 6 and 10 will do. $user_actkey = gen_rand_string(mt_rand(6, 10)); + // Instantiate passwords manager + $passwords_manager = $phpbb_container->get('passwords.manager'); + $sql = 'UPDATE ' . USERS_TABLE . " - SET user_newpasswd = '" . $db->sql_escape(phpbb_hash($user_password)) . "', user_actkey = '" . $db->sql_escape($user_actkey) . "' + SET user_newpasswd = '" . $db->sql_escape($passwords_manager->hash($user_password)) . "', user_actkey = '" . $db->sql_escape($user_actkey) . "' WHERE user_id = " . $user_row['user_id']; $db->sql_query($sql); |