From 2471b19d73c38359ed70a7c9e3a82a297946c5b8 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 17 Sep 2013 15:17:54 +0200 Subject: [ticket/11201] Make profile field classes autoloadable PHPBB3-11201 --- phpBB/config/profilefields.yml | 23 + phpBB/config/services.yml | 1 + phpBB/includes/acp/acp_profile.php | 5 +- phpBB/includes/acp/acp_users.php | 3 +- phpBB/includes/functions_profile_fields.php | 1187 --------------------------- phpBB/includes/functions_user.php | 9 +- phpBB/includes/ucp/ucp_pm_viewmessage.php | 8 +- phpBB/includes/ucp/ucp_profile.php | 7 +- phpBB/includes/ucp/ucp_register.php | 4 +- phpBB/memberlist.php | 6 +- phpBB/phpbb/profilefields/admin.php | 191 +++++ phpBB/phpbb/profilefields/profilefields.php | 974 ++++++++++++++++++++++ phpBB/viewtopic.php | 6 +- 13 files changed, 1202 insertions(+), 1222 deletions(-) create mode 100644 phpBB/config/profilefields.yml delete mode 100644 phpBB/includes/functions_profile_fields.php create mode 100644 phpBB/phpbb/profilefields/admin.php create mode 100644 phpBB/phpbb/profilefields/profilefields.php (limited to 'phpBB') diff --git a/phpBB/config/profilefields.yml b/phpBB/config/profilefields.yml new file mode 100644 index 0000000000..3b9b1a60a0 --- /dev/null +++ b/phpBB/config/profilefields.yml @@ -0,0 +1,23 @@ +services: + profilefields: + class: \phpbb\profilefields\profilefields + arguments: + - @auth + - @dbal.conn + - @request + - @template + - @user + + profilefields.admin: + class: \phpbb\profilefields\admin + arguments: + - @auth + - @dbal.conn + - @request + - @template + - @user + + #migrator.tool.permission1: + # class: \phpbb\profilefields\profilefields + # tags: + # - { name: ffoobar.tool } diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index c11184d6b6..9c9a0f625c 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -8,6 +8,7 @@ imports: - { resource: auth_providers.yml } - { resource: console.yml } - { resource: mimetype_guessers.yml } + - { resource: profilefields.yml } services: acl.permissions: diff --git a/phpBB/includes/acp/acp_profile.php b/phpBB/includes/acp/acp_profile.php index 6efd778b12..510239a837 100644 --- a/phpBB/includes/acp/acp_profile.php +++ b/phpBB/includes/acp/acp_profile.php @@ -29,11 +29,10 @@ class acp_profile { 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'; @@ -60,7 +59,7 @@ class acp_profile FIELD_DROPDOWN => array('field_length' => 0, 'field_minlen' => 0, 'field_maxlen' => 5, 'field_validation' => '', 'field_novalue' => 0, 'field_default_value' => 0), ); - $cp = new custom_profile_admin(); + $cp = $phpbb_container->get('profilefields.admin'); // Build Language array // Based on this, we decide which elements need to be edited later and which language items are missing diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index b24adfc586..beb6fa1960 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -1343,9 +1343,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'); $cp_data = $cp_error = array(); 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 @@ - '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'] = ''; - for ($i = 1; $i < 32; $i++) - { - $profile_row['s_day_options'] .= '"; - } - - $profile_row['s_month_options'] = ''; - for ($i = 1; $i < 13; $i++) - { - $profile_row['s_month_options'] .= '"; - } - - $profile_row['s_year_options'] = ''; - for ($i = $now['year'] - 100; $i <= $now['year'] + 100; $i++) - { - $profile_row['s_year_options'] .= '"; - } - 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 .= ''; - } - - 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' => ''), - 1 => array('TITLE' => $user->lang['MIN_FIELD_CHARS'], 'FIELD' => ''), - 2 => array('TITLE' => $user->lang['MAX_FIELD_CHARS'], 'FIELD' => ''), - 3 => array('TITLE' => $user->lang['FIELD_VALIDATION'], 'FIELD' => '') - ); - - 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' => ' ' . $user->lang['ROWS'] . '
' . $user->lang['COLUMNS'] . ' '), - 1 => array('TITLE' => $user->lang['MIN_FIELD_CHARS'], 'FIELD' => ''), - 2 => array('TITLE' => $user->lang['MAX_FIELD_CHARS'], 'FIELD' => ''), - 3 => array('TITLE' => $user->lang['FIELD_VALIDATION'], 'FIELD' => '') - ); - - 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' => ''), - 1 => array('TITLE' => $user->lang['MIN_FIELD_NUMBER'], 'FIELD' => ''), - 2 => array('TITLE' => $user->lang['MAX_FIELD_NUMBER'], 'FIELD' => ''), - 3 => array('TITLE' => $user->lang['DEFAULT_VALUE'], 'FIELD' => '') - ); - - 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' => ''), - 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' => ''), - ); - - return $options; - } -} diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index dba6d3d6c2..b2cd911a0d 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'])) { @@ -276,12 +276,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'); $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/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php index cebbadc7c7..78a0e010e6 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'); $profile_fields = $cp->generate_profile_fields_template('grab', $author_id); } diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php index 2252b2ea17..672588c51f 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'); @@ -257,9 +256,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'); $cp_data = $cp_error = array(); diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php index 1641c6eef1..333aa2816f 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'); $error = $cp_data = $cp_error = array(); $s_hidden_fields = array(); diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index 14425ca6e4..84fbb8218a 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -617,8 +617,7 @@ switch ($mode) $profile_fields = array(); if ($config['load_cpf_viewprofile']) { - include_once($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); - $cp = new custom_profile(); + $cp = $phpbb_container->get('profilefields'); $profile_fields = $cp->generate_profile_fields_template('grab', $user_id); $profile_fields = (isset($profile_fields[$user_id])) ? $cp->generate_profile_fields_template('show', false, $profile_fields[$user_id]) : array(); } @@ -1555,8 +1554,7 @@ switch ($mode) // Load custom profile fields if ($config['load_cpf_memberlist']) { - include_once($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); - $cp = new custom_profile(); + $cp = $phpbb_container->get('profilefields'); // Grab all profile fields from users in id cache for later use - similar to the poster cache $profile_fields_cache = $cp->generate_profile_fields_template('grab', $user_list); diff --git a/phpBB/phpbb/profilefields/admin.php b/phpBB/phpbb/profilefields/admin.php new file mode 100644 index 0000000000..b784b91c55 --- /dev/null +++ b/phpBB/phpbb/profilefields/admin.php @@ -0,0 +1,191 @@ + '.*', '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 .= ''; + } + + 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' => ''), + 1 => array('TITLE' => $user->lang['MIN_FIELD_CHARS'], 'FIELD' => ''), + 2 => array('TITLE' => $user->lang['MAX_FIELD_CHARS'], 'FIELD' => ''), + 3 => array('TITLE' => $user->lang['FIELD_VALIDATION'], 'FIELD' => '') + ); + + 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' => ' ' . $user->lang['ROWS'] . '
' . $user->lang['COLUMNS'] . ' '), + 1 => array('TITLE' => $user->lang['MIN_FIELD_CHARS'], 'FIELD' => ''), + 2 => array('TITLE' => $user->lang['MAX_FIELD_CHARS'], 'FIELD' => ''), + 3 => array('TITLE' => $user->lang['FIELD_VALIDATION'], 'FIELD' => '') + ); + + 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' => ''), + 1 => array('TITLE' => $user->lang['MIN_FIELD_NUMBER'], 'FIELD' => ''), + 2 => array('TITLE' => $user->lang['MAX_FIELD_NUMBER'], 'FIELD' => ''), + 3 => array('TITLE' => $user->lang['DEFAULT_VALUE'], 'FIELD' => '') + ); + + 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' => ''), + 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' => ''), + ); + + return $options; + } +} diff --git a/phpBB/phpbb/profilefields/profilefields.php b/phpBB/phpbb/profilefields/profilefields.php new file mode 100644 index 0000000000..3d9339d1d7 --- /dev/null +++ b/phpBB/phpbb/profilefields/profilefields.php @@ -0,0 +1,974 @@ + 'int', FIELD_STRING => 'string', FIELD_TEXT => 'text', FIELD_BOOL => 'bool', FIELD_DROPDOWN => 'dropdown', FIELD_DATE => 'date'); + var $profile_cache = array(); + var $options_lang = array(); + + /** + * + */ + public function __construct($auth, $db, $request, $template, $user) + { + $this->auth = $auth; + $this->db = $db; + $this->request = $request; + $this->template = $template; + $this->user = $user; + } + + /** + * 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) + { + $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 (!$this->auth->acl_gets('a_', 'm_') && !$this->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 = $this->db->sql_query($sql); + + while ($row = $this->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']; + + $this->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) + ); + } + $this->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() + { + $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 = ' . $this->user->get_iso_lang_id() . ' + AND f.field_active = 1 ' . + ((!$this->auth->acl_gets('a_', 'm_') && !$this->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 = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $this->profile_cache[$row['field_ident']] = $row; + } + $this->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) + { + 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 = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $this->options_lang[$field_id][$lang_id][($row['option_id'] + 1)] = $row['lang_value']; + } + $this->db->sql_freeresult($result); + } + } + + /** + * Submit profile field for validation + * @access public + */ + function submit_cp_field($mode, $lang_id, &$cp_data, &$cp_error) + { + $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 (!$this->auth->acl_gets('a_', 'm_') && !$this->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 = $this->db->sql_query($sql); + + while ($row = $this->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 = $this->user->lang($cp_result, $row['lang_name']); + break; + + case 'FIELD_TOO_SHORT': + case 'FIELD_TOO_SMALL': + $error = $this->user->lang($cp_result, (int) $row['field_minlen'], $row['lang_name']); + break; + + case 'FIELD_TOO_LONG': + case 'FIELD_TOO_LARGE': + $error = $this->user->lang($cp_result, (int) $row['field_maxlen'], $row['lang_name']); + break; + + case 'FIELD_INVALID_CHARS': + switch ($row['field_validation']) + { + case '[0-9]+': + $error = $this->user->lang($cp_result . '_NUMBERS_ONLY', $row['lang_name']); + break; + + case '[\w]+': + $error = $this->user->lang($cp_result . '_ALPHA_ONLY', $row['lang_name']); + break; + + case '[\w_\+\. \-\[\]]+': + $error = $this->user->lang($cp_result . '_SPACERS_ONLY', $row['lang_name']); + break; + } + break; + } + + if ($error != '') + { + $cp_error[] = $error; + } + } + } + $this->db->sql_freeresult($result); + } + + /** + * Update profile field data directly + */ + function update_profile_field_data($user_id, &$cp_data) + { + 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 . (($this->db->sql_layer == 'firebird' || $this->db->sql_layer == 'oracle') ? strtoupper($key) : $key) . $right_delim] = $value; + } + + $sql = 'UPDATE ' . PROFILE_FIELDS_DATA_TABLE . ' + SET ' . $this->db->sql_build_array('UPDATE', $cp_data_sql) . " + WHERE user_id = $user_id"; + $this->db->sql_query($sql); + + if (!$this->db->sql_affectedrows()) + { + $cp_data_sql['user_id'] = (int) $user_id; + + $this->db->sql_return_on_error(true); + + $sql = 'INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . ' ' . $this->db->sql_build_array('INSERT', $cp_data_sql); + $this->db->sql_query($sql); + + $this->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) + { + 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 ' . $this->db->sql_in_set('user_id', array_map('intval', $user_id)); + $result = $this->db->sql_query($sql); + + $field_data = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $field_data[$row['user_id']] = $row; + } + $this->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) + { + // Date should display as the same date for every user regardless of timezone + return $this->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) + { + $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($this->user->profile_fields[$user_ident]) || $preview) ? $default_value : $this->user->profile_fields[$user_ident]); + } + else if ($profile_row['field_type'] == FIELD_INT) + { + if (isset($_REQUEST[$profile_row['field_ident']])) + { + $value = ($this->request->variable($profile_row['field_ident'], '') === '') ? NULL : $this->request->variable($profile_row['field_ident'], $default_value); + } + else + { + if (!$preview && array_key_exists($user_ident, $this->user->profile_fields) && is_null($this->user->profile_fields[$user_ident])) + { + $value = NULL; + } + else if (!isset($this->user->profile_fields[$user_ident]) || $preview) + { + $value = $default_value; + } + else + { + $value = $this->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($this->user->profile_fields[$user_ident]) || $preview) ? $default_value : $this->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) + { + $profile_row['field_value'] = $this->get_var('int', $profile_row, $profile_row['field_default_value'], $preview); + $this->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) + { + $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($this->user->profile_fields[$user_ident]) || $preview) ? $profile_row['field_default_value'] : $this->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($this->user->profile_fields[$user_ident]) || $preview) ? $profile_row['field_default_value'] : $this->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'] = ''; + for ($i = 1; $i < 32; $i++) + { + $profile_row['s_day_options'] .= '"; + } + + $profile_row['s_month_options'] = ''; + for ($i = 1; $i < 13; $i++) + { + $profile_row['s_month_options'] .= '"; + } + + $profile_row['s_year_options'] = ''; + for ($i = $now['year'] - 100; $i <= $now['year'] + 100; $i++) + { + $profile_row['s_year_options'] .= '"; + } + unset($now); + + $profile_row['field_value'] = 0; + $this->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) + { + $value = $this->get_var('int', $profile_row, $profile_row['field_default_value'], $preview); + + $profile_row['field_value'] = $value; + $this->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) + { + $this->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) + { + $profile_row['field_value'] = $this->get_var('string', $profile_row, $profile_row['lang_default_value'], $preview); + $this->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) + { + $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); + $this->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) + { + $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; + $this->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) + { + $this->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) + { + $preview = ($mode == 'preview') ? true : false; + + // set template filename + $this->template->set_filenames(array( + 'cp_body' => 'custom_profile_fields.html', + )); + + // empty previously filled blockvars + foreach ($this->profile_types as $field_case => $field_type) + { + $this->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 $this->template->assign_display('cp_body'); + } + + /** + * Build Array for user insertion into custom profile fields table + */ + function build_insert_sql_array($cp_data) + { + $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 = ' . $this->user->get_iso_lang_id() . ' + ' . ((sizeof($sql_not_in)) ? ' AND ' . $this->db->sql_in_set('f.field_ident', $sql_not_in, true) : '') . ' + AND l.field_id = f.field_id'; + $result = $this->db->sql_query($sql); + + while ($row = $this->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']; + } + $this->db->sql_freeresult($result); + + return $cp_data; + } + + /** + * Get profile field value on submit + * @access private + */ + function get_profile_field($profile_row) + { + $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]) && $this->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; + } +} diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index 14040176cb..396de132cb 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -1265,11 +1265,7 @@ $db->sql_freeresult($result); // Load custom profile fields if ($config['load_cpf_viewtopic']) { - if (!class_exists('custom_profile')) - { - include($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); - } - $cp = new custom_profile(); + $cp = $phpbb_container->get('profilefields'); // Grab all profile fields from users in id cache for later use - similar to the poster cache $profile_fields_tmp = $cp->generate_profile_fields_template('grab', $id_cache); -- cgit v1.2.1