1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-02-24 20:13:22 +01:00
php-phpbb/phpBB/includes/functions_profile_fields.php
Andreas Fischer ec3dac0595 [ticket/9075] CPF Numbers fields: Prevent SQL error on registration page.
When an administrator set a numbers field to default to 'not specified', a SQL
error was caused on the registration page because it was tried to insert an
empty string into an integer column.
Because the column already supports NULL values, empty strings are now
converted to NULL for custom profile fields of the type 'Numbers' before
insertion into the data table.

PHPBB3-9075
2010-10-30 12:42:23 +02:00

1150 lines
34 KiB
PHP

<?php
/**
*
* @package phpBB3
* @version $Id$
* @copyright (c) 2005 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/
/**
* @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;
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_REQUIRED':
$error = sprintf($user->lang[$cp_result], $row['lang_name']);
break;
case 'FIELD_TOO_SHORT':
case 'FIELD_TOO_SMALL':
$error = sprintf($user->lang[$cp_result], $row['lang_name'], $row['field_minlen']);
break;
case 'FIELD_TOO_LONG':
case 'FIELD_TOO_LARGE':
$error = sprintf($user->lang[$cp_result], $row['lang_name'], $row['field_maxlen']);
break;
case 'FIELD_INVALID_CHARS':
switch ($row['field_validation'])
{
case '[0-9]+':
$error = sprintf($user->lang[$cp_result . '_NUMBERS_ONLY'], $row['lang_name']);
break;
case '[\w]+':
$error = sprintf($user->lang[$cp_result . '_ALPHA_ONLY'], $row['lang_name']);
break;
case '[\w_\+\. \-\[\]]+':
$error = sprintf($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();
// 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];
}
}
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 === '')
{
return NULL;
}
return (int) $value;
break;
case 'string':
case 'text':
if (!$value)
{
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)
{
return NULL;
}
else if ($day && $month && $year)
{
global $user;
// Date should display as the same date for every user regardless of timezone, so remove offset
// to compensate for the offset added by user::format_date()
return $user->format_date(gmmktime(0, 0, 0, $month, $day, $year) - ($user->timezone + $user->dst), $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'])
{
return NULL;
}
$value = (int) $value;
// User not having a value assigned
if (!isset($this->options_lang[$field_id][$lang_id][$value]))
{
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 ($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;
$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 - only testing for isset
if ($profile_row['field_type'] == FIELD_BOOL && $profile_row['field_length'] == 2)
{
$value = (isset($_REQUEST[$profile_row['field_ident']])) ? 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[$profile_row['field_ident']] === '') ? NULL : request_var($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;
$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[$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="text" name="field_length" size="5" value="' . $this->vars['field_length'] . '" />'),
1 => array('TITLE' => $user->lang['MIN_FIELD_CHARS'], 'FIELD' => '<input type="text" name="field_minlen" size="5" value="' . $this->vars['field_minlen'] . '" />'),
2 => array('TITLE' => $user->lang['MAX_FIELD_CHARS'], 'FIELD' => '<input type="text" name="field_maxlen" 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 name="rows" size="5" value="' . $this->vars['rows'] . '" /> ' . $user->lang['ROWS'] . '</dd><dd><input 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="text" name="field_minlen" size="10" value="' . $this->vars['field_minlen'] . '" />'),
2 => array('TITLE' => $user->lang['MAX_FIELD_CHARS'], 'FIELD' => '<input type="text" 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="text" name="field_length" size="5" value="' . $this->vars['field_length'] . '" />'),
1 => array('TITLE' => $user->lang['MIN_FIELD_NUMBER'], 'FIELD' => '<input type="text" name="field_minlen" size="5" value="' . $this->vars['field_minlen'] . '" />'),
2 => array('TITLE' => $user->lang['MAX_FIELD_NUMBER'], 'FIELD' => '<input type="text" 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;
}
}
?>