diff --git a/e107_admin/sql/extended_timezones.php b/e107_admin/sql/extended_timezones.php
index 822b60cc4..24955ade9 100644
--- a/e107_admin/sql/extended_timezones.php
+++ b/e107_admin/sql/extended_timezones.php
@@ -1,78 +1,134 @@
- text pair
-The text is displayed in a drop-down; the value is returned.
-If function timezones_value() exists, it is called to create the displayed text
-*/
-
-//FIXME - remove globals.
-global $timezones_list;
-if (!is_array($timezones_list))
-{
-$timezones_list = array(
- array('-12', "International DateLine West"),
- array('-11', "Samoa"),
- array('-10', "Hawaii"),
- array( '-9', "Alaska"),
- array( '-8', "Pacific Time (US and Canada)"),
- array( '-7', "Mountain Time (US and Canada)"),
- array( '-6', "Central Time (US and Canada), Central America"),
- array( '-5', "Eastern Time (US and Canada)"),
- array( '-4', "Atlantic Time (Canada)"),
- array( '-3.30', 'Newfoundland'),
- array( '-3', "Greenland, Brasilia, Buenos Aires, Georgetown"),
- array( '-2', "Mid-Atlantic"),
- array( '-1', "Azores, Cape Verde Islands"),
- array( '+0', "UK, Ireland, Lisbon"),
- array( '+1', "West Central Africa, Western Europe"),
- array( '+2', "Greece, Egypt, parts of Africa"),
- array( '+3', "Russia, Baghdad, Kuwait, Nairobi"),
- array( '+3.30', 'Tehran, Iran'),
- array( '+4', "Abu Dhabi, Kabul"),
- array( '+4.30', 'Afghanistan'),
- array( '+5', "Islamabad, Karachi"),
- array( '+5.30', "Mumbai, Delhi, Calcutta"),
- array( '+5.45', 'Kathmandu'),
- array( '+6', "Astana, Dhaka"),
- array( '+7', "Bangkok, Rangoon"),
- array( '+8', "Hong Kong, Singapore, Perth, Beijing"),
- array( '+9', "Tokyo, Seoul"),
- array( '+9.30', 'Darwin, Adelaide'),
- array('+10', "Brisbane, Canberra, Sydney, Melbourne"),
- array('+10.30', 'Lord Howe Island'),
- array('+11', "Soloman Islands"),
- array('+11.30', 'Norfolk Island'),
- array('+12', "New Zealand, Fiji, Marshall Islands"),
- array('+13', "Tonga, Nuku'alofa, Rawaki Islands"),
- array('+13.45', 'Chatham Island'),
- array('+14', 'Kiribati: Line Islands')
- );
-}
-
-if (!function_exists('timezones_value'))
-{
- function timezones_value($key, $value)
- {
- return 'GMT'.$key.' - '.$value;
- }
-}
-
+ text pair
+The text is displayed in a drop-down; the value is returned.
+If function timezones_value() exists, it is called to create the displayed text
+*/
+
+class extended_timezones
+{
+
+ private $timezonesList = array(
+ '-12' => "International DateLine West",
+ '-11' => "Samoa",
+ '-10' => "Hawaii",
+ '-9' => "Alaska",
+ '-8' => "Pacific Time (US and Canada)",
+ '-7' => "Mountain Time (US and Canada)",
+ '-6' => "Central Time (US and Canada), Central America",
+ '-5' => "Eastern Time (US and Canada)",
+ '-4' => "Atlantic Time (Canada)",
+ '-3.30' => 'Newfoundland',
+ '-3' => "Greenland, Brasilia, Buenos Aires, Georgetown",
+ '-2' => "Mid-Atlantic",
+ '-1' => "Azores, Cape Verde Islands",
+ '+0' => "UK, Ireland, Lisbon",
+ '+1' => "West Central Africa, Western Europe",
+ '+2' => "Greece, Egypt, parts of Africa",
+ '+3' => "Russia, Baghdad, Kuwait, Nairobi",
+ '+3.30' => 'Tehran, Iran',
+ '+4' => "Abu Dhabi, Kabul",
+ '+4.30' => 'Afghanistan',
+ '+5' => "Islamabad, Karachi",
+ '+5.30' => "Mumbai, Delhi, Calcutta",
+ '+5.45' => 'Kathmandu',
+ '+6' => "Astana, Dhaka",
+ '+7' => "Bangkok, Rangoon",
+ '+8' => "Hong Kong, Singapore, Perth, Beijing",
+ '+9' => "Tokyo, Seoul",
+ '+9.30' => 'Darwin, Adelaide',
+ '+10' => "Brisbane, Canberra, Sydney, Melbourne",
+ '+10.30' => 'Lord Howe Island',
+ '+11' => "Soloman Islands",
+ '+11.30' => 'Norfolk Island',
+ '+12' => "New Zealand, Fiji, Marshall Islands",
+ '+13' => "Tonga, Nuku'alofa, Rawaki Islands",
+ '+13.45' => 'Chatham Island',
+ '+14' => 'Kiribati: Line Islands'
+ );
+
+
+ private $isEOF = FALSE; // True if at last element of list
+ private $bufferValid = FALSE;
+
+
+ /**
+ * Call before using the 'next' format option, to ensure the array is indexed from the beginning
+ */
+ public function pointerReset()
+ {
+ $this->isEOF = (FALSE === reset($this->timezonesList));
+ $this->bufferValid = TRUE;
+ }
+
+
+ /**
+ * Return a formatted timezone value
+ *
+ * @param mixed $key - the key value to select
+ * @param string $formatSpec - defines format of return value
+ *
+ * @return mixed (according to $formatSpec). FALSE if no value available
+ * 'array' - a single-element array; key as passed, and value to match key
+ * 'next' - as 'array', but ignores the passed $key and moves to next value.
+ * default - a string usable for display
+ */
+ public function getValue($key, $formatSpec = '')
+ {
+ if ($formatSpec == 'next')
+ {
+ if (!$this->bufferValid) $this->pointerReset; // Make sure buffer is defined
+ if ($this->isEOF) return FALSE;
+ $key = key($this->timezonesList);
+ $val = current($this->timezonesList);
+ if (FALSE === $val)
+ {
+ $this->isEOF = TRUE;
+ return FALSE;
+ }
+ $this->isEOF = (FALSE === next($this->timezonesList));
+ return array($key => $val);
+ }
+
+ $exists = isset($this->timezonesList[$key]);
+ if (!$exists) return FALSE;
+
+ $val = $this->timezonesList[$key];
+ if ($formatSpec == 'array')
+ {
+ return array($key => $val);
+ }
+
+ // Default (as per earlier implementations) - can be specified with 'display' format
+ return 'GMT'.$key.' - '.$val;
+ }
+}
+
+
?>
\ No newline at end of file
diff --git a/e107_handlers/user_extended_class.php b/e107_handlers/user_extended_class.php
index 964a8597a..472029e62 100644
--- a/e107_handlers/user_extended_class.php
+++ b/e107_handlers/user_extended_class.php
@@ -1,906 +1,904 @@
-typeArray = array(
- 'text' => 1,
- 'radio' => 2,
- 'dropdown' => 3,
- 'db field' => 4,
- 'textarea' => 5,
- 'integer' => 6,
- 'date' => 7,
- 'language' => 8,
- 'list' => 9,
- 'checkbox' => 10,
- 'predefined' => 11, // DON'T USE IT IN PREDEFINED FIELD XML!!! Used in plugin installation routine.
- );
-
- $this->user_extended_types = array(
- 1 => UE_LAN_1,
- 2 => UE_LAN_2,
- 3 => UE_LAN_3,
- 4 => UE_LAN_4,
- 5 => UE_LAN_5,
- 6 => UE_LAN_6,
- 7 => UE_LAN_7,
- 8 => UE_LAN_8,
- 9 => UE_LAN_9,
- 10=> UE_LAN_10
- );
-
- //load array with field names from main user table, so we can disallow these
- // user_new, user_timezone deleted for 0.8
- $this->reserved_names = array (
- 'id', 'name', 'loginname', 'customtitle', 'password',
- 'sess', 'email', 'signature', 'image', 'hideemail',
- 'join', 'lastvisit', 'currentvisit', 'chats',
- 'comments', 'forums', 'ip', 'ban', 'prefs', 'viewed',
- 'visits', 'admin', 'login', 'class', 'baseclasslist', 'perms', 'pwchange',
- 'xup'
- );
-
- $sql = e107::getDB();
-
- // Read in all the field and category fields
- // At present we load all fields into common array - may want to split system and non-system
- $this ->catDefinitions = array(); // Categories array
- $this->fieldDefinitions = array(); // Field definitions array
- $this->nameIndex = array(); // Index of names => field IDs
- $this->systemCount = 0;
- $this->userCount = 0;
-
- if($sql->db_Select('user_extended_struct', '*', "user_extended_struct_text != '_system_' ORDER BY user_extended_struct_order ASC"))
- {
- while($row = $sql->db_Fetch(MYSQL_ASSOC))
- {
- if ($row['user_extended_struct_type'] == 0)
- { // Its a category
- $this->catDefinitions[$row['user_extended_struct_id']] = $row;
- }
- else
- { // Its a field definition
- $this->fieldDefinitions[$row['user_extended_struct_id']] = $row;
- $this->nameIndex['user_'.$row['user_extended_struct_name']] = $row['user_extended_struct_id']; // Create name to ID index
- if ($row['user_extended_struct_text'] == '_system_')
- {
- $this->systemCount++;
- }
- else
- {
- $this->userCount++;
- }
- }
- }
- }
- }
-
-
-
- /**
- * Check for reserved field names.
- * (Names which clash with the 'normal' user table aren't allowed)
- *
- * @param string $name - name of field bweing checked (no 'user_' prefix)
- *
- * @return boolean TRUE if disallowed name
- */
- public function user_extended_reserved($name)
- {
- return (in_array($name, $this->reserved_names));
- }
-
-
-
- // Adds the _FIELD_TYPES array to the data, ready for saving in the DB.
- function addFieldTypes(&$target)
- {
- $target['_FIELD_TYPES'] = array(); // We should always want to recreate the array, even if it exists
- foreach ($target['data'] as $k => $v)
- {
- if (isset($this->nameIndex[$k]))
- {
- switch ($this->fieldDefinitions[$this->nameIndex[$k]]['user_extended_struct_type'])
- {
- case EUF_TEXT :
- case EUF_DB_FIELD :
- case EUF_TEXTAREA :
- case EUF_DROPDOWN :
- case EUF_DATE :
- case EUF_LANGUAGE :
- case EUF_PREDEFINED :
- case EUF_CHECKBOX :
- case EUF_RADIO :
- $target['_FIELD_TYPES'][$k] = 'todb';
- break;
-
- case EUF_INTEGER :
- $target['_FIELD_TYPES'][$k] = 'int';
- break;
- }
- }
- }
- }
-
-
-
- /**
- * For all UEFs not in the target array, adds the default value
- * Also updates the _FIELD_TYPES array, so call this last thing before writing to the DB
- *
- * @param $target - pointer to data array
- */
- public function addDefaultFields(&$target)
- {
- //$target['_FIELD_TYPES'] = array(); // We should always want to recreate the array, even if it exists
- foreach ($this->fieldDefinitions as $k => $defs)
- {
- $f = 'user_'.$defs['user_extended_struct_name'];
- if (!isset($target['data'][$f]) && $this->fieldDefinitions[$k]['user_extended_struct_default'])
- {
- switch ($this->fieldDefinitions[$k]['user_extended_struct_type'])
- {
- case EUF_TEXT :
- case EUF_DB_FIELD :
- case EUF_TEXTAREA :
- case EUF_DROPDOWN :
- case EUF_DATE :
- case EUF_LANGUAGE :
- case EUF_PREDEFINED :
-
- $target['data'][$f] = $this->fieldDefinitions[$k]['user_extended_struct_default'];
- $target['_FIELD_TYPES'][$f] = 'todb';
- break;
- case EUF_RADIO :
- case EUF_INTEGER :
- $target['data'][$f] = $this->fieldDefinitions[$k]['user_extended_struct_default'];
- $target['_FIELD_TYPES'][$f] = 'int';
- break;
- case EUF_CHECKBOX :
- $target['data'][$f] = $this->fieldDefinitions[$k]['user_extended_struct_default'];
- $target['_FIELD_TYPES'][$f] = 'array';
- break;
- }
- }
- }
- }
-
-
-
- // Validate a single extended user field
- // $val is whatever the user entered.
- // $params is the field definition
- // Return FALSE if acceptable, TRUE if fail , error message on regex fail if the message is defined
- function user_extended_validate_entry($val, $params)
- {
- global $tp;
- $parms = explode('^,^', $params['user_extended_struct_parms']);
- $requiredField = $params['user_extended_struct_required'] == 1;
- $regex = $tp->toText($parms[1]);
- $regexfail = $tp->toText($parms[2]);
- if (defined($regexfail)) { $regexfail = constant($regexfail); }
- if($val == '' && $requiredField) return TRUE;
- switch ($type)
- {
- case EUF_DATE :
- if ($requiredField && ($val == '0000-00-00')) return TRUE;
- break;
- }
- if($regex != "" && $val != "")
- {
- if(!preg_match($regex, $val)) return $regexfail ? $regexfail : TRUE;
- }
- return FALSE; // Pass by default here
- }
-
-
-
- /**
- * Validate all user-modifable extended user fields which are presented.
- * Primarily intended to validate data entered by a user or admin
- *
- * @param array $inArray is the input data (usually from $_POST or $_POST['ue'], although doesn't have to be) - may have 'surplus' values
- * @param array $hideArray is a set of possible 'hide' flags
- * @param boolean $isSignup TRUE causes required fields to be specifically checked, else only data passed is checked
- *
- * @return array with three potential subkeys:
- * 'data' - valid data values (key is field name)
- * ['data']['user_hidden_fields'] is the hidden fields
- * 'errors' - data values in error
- * 'errortext' - error message corresponding to erroneous value
- *
- * @todo - does $hidden_fields need to be merged with values for fields not processed? (Probably not - should only relate to fields current user can see)
- * @todo - make sure admin can edit fields of other users
- */
- public function userExtendedValidateAll($inArray, $hideArray, $isSignup=FALSE)
- {
- global $tp;
- $eufVals = array(); // 'Answer' array
- $hideFlags = array();
-
- foreach ($this->fieldDefinitions as $k => $defs)
- {
- $category = $defs['user_extended_struct_parent'];
- if (($category == 0) || ($isSignup && (int) $this->catDefinitions[$category]['user_extended_struct_applicable'] === (int) e_UC_MEMBER && (int) $this->catDefinitions[$category]['user_extended_struct_write'] === (int) e_UC_MEMBER) || (check_class($this->catDefinitions[$category]['user_extended_struct_applicable']) && check_class($this->catDefinitions[$category]['user_extended_struct_write'])))
- { // Category applicable to user
-
- if (($isSignup && (int) $defs['user_extended_struct_applicable'] === (int) e_UC_MEMBER && (int) $defs['user_extended_struct_write'] === (int) e_UC_MEMBER) || (check_class($defs['user_extended_struct_applicable']) && check_class($defs['user_extended_struct_write'])))
- { // User can also update field
- $f = 'user_'.$defs['user_extended_struct_name'];
- if (isset($inArray[$f]) || ($isSignup && ($defs['user_extended_struct_required'] == 1)))
- { // Only allow valid keys
- $val = varset($inArray[$f], FALSE);
- $err = $this->user_extended_validate_entry($val, $defs);
- if ($err === true)
- { // General error - usually empty field; could be unacceptable value, or regex fail and no error message defined
- $eufVals['errortext'][$f] = str_replace('--SOMETHING--',$tp->toHtml(defset($defs['user_extended_struct_text'], $defs['user_extended_struct_text']),FALSE,'defs'),LAN_USER_75);
- $eufVals['errors'][$f] = ERR_GENERIC;
- }
- elseif ($err)
- { // Specific error message returned - usually regex fail
- $eufVals['errortext'][$f] = $err;
- $eufVals['errors'][$f] = ERR_GENERIC;
- }
- elseif (!$err)
- {
- $eufVals['data'][$f] = $tp->toDB($val);
- }
- if (isset($hideArray[$f]))
- {
- $hideFlags[] = $f;
- }
- }
- }
- }
- }
- $hidden_fields = implode('^', $hideFlags);
- if ($hidden_fields != '')
- {
- $hidden_fields = '^'.$hidden_fields.'^';
- }
- $eufVals['data']['user_hidden_fields'] = $hidden_fields;
-
- return $eufVals;
- }
-
-
-
-
- function user_extended_get_categories($byID = TRUE)
- {
- $ret = array();
- global $sql;
- if($sql->db_Select("user_extended_struct", "*", "user_extended_struct_type = 0 ORDER BY user_extended_struct_order ASC"))
- {
- if($byID == TRUE)
- {
- while($row = $sql->db_Fetch())
- {
- $ret[$row['user_extended_struct_id']][] = $row;
- }
- }
- else
- {
- $ret = $sql->db_getList();
- }
- }
- return $ret;
- }
-
-
- // Get the definition of all fields, or those in a specific category, grouped by category ID
- // Reads non-system fields only
- function user_extended_get_fields($cat = "")
- {
- global $sql;
- $ret = array();
- $more = ($cat) ? " AND user_extended_struct_parent = ".intval($cat)." " : "";
- if($sql->db_Select("user_extended_struct", "*", "user_extended_struct_type > 0 AND user_extended_struct_text != '_system_' {$more} ORDER BY user_extended_struct_order ASC"))
- {
- while($row = $sql->db_Fetch(MYSQL_ASSOC))
- {
- $ret[$row['user_extended_struct_parent']][] = $row;
- }
- }
- return $ret;
- }
-
- // Get the definition of all fields, or those in a specific category, indexed by field ID (or some other field by specifying $indexField)
- function user_extended_get_fieldList($cat = "", $indexField = 'user_extended_struct_id')
- {
- global $sql;
- $more = ($cat != '') ? " AND user_extended_struct_parent = ".intval($cat)." " : "";
- if($sql->db_Select("user_extended_struct", "*", "user_extended_struct_type > 0 AND user_extended_struct_text != '_system_' {$more} ORDER BY user_extended_struct_order ASC"))
- {
- while($row = $sql->db_Fetch(MYSQL_ASSOC))
- {
- $ret[$row[$indexField]] = $row;
- }
- }
- return $ret;
- }
-
-
- // Return the field creation text for a definition
- function user_extended_type_text($type, $default)
- {
- global $tp;
- if(!is_numeric($type))
- {
- return false;
- }
-
- switch ($type)
- {
- case EUF_INTEGER :
- $db_type = 'INT(11)';
- break;
-
- case EUF_DATE :
- $db_type = 'DATE NOT NULL';
- break;
-
- case EUF_TEXTAREA:
- $db_type = 'TEXT';
- break;
-
- case EUF_TEXT :
- case EUF_RADIO :
- case EUF_DROPDOWN :
- case EUF_DB_FIELD :
- case EUF_LANGUAGE :
- case EUF_PREDEFINED :
- case EUF_CHECKBOX :
- $db_type = 'VARCHAR(255)';
- break;
-
- case EUF_CATEGORY:
- return '';
- break;
-
- default:
- e107::getMessage()->addDebug("Unknown type '{$type}' for user extended field.");
- return false;
- break;
-
- }
- if($type != EUF_DB_FIELD && $type != EUF_TEXTAREA && $default != '')
- {
- $default_text = " DEFAULT '".$tp -> toDB($default, true)."'";
- }
- else
- {
- $default_text = '';
- }
- return $db_type.$default_text;
- }
-
-
- function user_extended_field_exist($name)
- {
- global $sql, $tp;
- return $sql->db_Count('user_extended_struct','(*)', "WHERE user_extended_struct_name = '".$tp -> toDB($name, true)."'");
- }
-
- function clear_cache()
- {
- $e107 = e107::getInstance();
- $e107->ecache->clear_sys('nomd5_extended_struct');
- }
-
- // For use by plugins to add extended user fields and won't be visible anywhere else
- function user_extended_add_system($name, $type, $default = '', $source = '_system_')
- {
- return $this->user_extended_add($name, '_system_', $type, $source, '', $default, 0, 255, 255, 255, 0, 0);
- }
-
-
- function user_extended_add($name, $text, $type, $parms, $values, $default, $required, $read, $write, $applicable, $order='', $parent)
- {
- global $sql, $tp;
- $this->clear_cache();
- if(is_array($name))
- {
- extract($name);
- }
- if(!is_numeric($type))
- {
- $type = $this->typeArray[$type];
- }
-
- if (!$this->user_extended_field_exist($name) && !$this->user_extended_reserved($name))
- {
- $field_info = $this->user_extended_type_text($type, $default);
-
- // wrong type
- if(false === $field_info) return false;
-
- if($order === '' && $field_info)
- {
- if($sql->db_Select('user_extended_struct','MAX(user_extended_struct_order) as maxorder','1'))
- {
- $row = $sql->db_Fetch();
- if(is_numeric($row['maxorder']))
- {
- $order = $row['maxorder']+1;
- }
- }
- }
- // field of type category
- if($field_info)
- {
- $sql->db_Select_gen('ALTER TABLE #user_extended ADD user_'.$tp -> toDB($name, true).' '.$field_info);
- }
-
- $sql->db_Insert('user_extended_struct',"null,'".$tp -> toDB($name, true)."','".$tp -> toDB($text, true)."','".intval($type)."','".$tp -> toDB($parms, true)."','".$tp -> toDB($values, true)."', '".$tp -> toDB($default, true)."', '".intval($read)."', '".intval($write)."', '".intval($required)."', '0', '".intval($applicable)."', '".intval($order)."', '".intval($parent)."'");
- if ($this->user_extended_field_exist($name))
- {
- return TRUE;
- }
- }
- return FALSE;
- }
-
-
-
- function user_extended_modify($id, $name, $text, $type, $parms, $values, $default, $required, $read, $write, $applicable, $parent)
- {
- global $sql, $tp;
- if ($this->user_extended_field_exist($name))
- {
- $field_info = $this->user_extended_type_text($type, $default);
- // wrong type
- if(false === $field_info) return false;
-
- // field of type category
- if($field_info)
- {
- $sql->db_Select_gen("ALTER TABLE #user_extended MODIFY user_".$tp -> toDB($name, true)." ".$field_info);
- }
-
- $newfield_info = "
- user_extended_struct_text = '".$tp -> toDB($text, true)."',
- user_extended_struct_type = '".intval($type)."',
- user_extended_struct_parms = '".$tp -> toDB($parms, true)."',
- user_extended_struct_values = '".$tp -> toDB($values, true)."',
- user_extended_struct_default = '".$tp -> toDB($default, true)."',
- user_extended_struct_required = '".intval($required)."',
- user_extended_struct_read = '".intval($read)."',
- user_extended_struct_write = '".intval($write)."',
- user_extended_struct_applicable = '".intval($applicable)."',
- user_extended_struct_parent = '".intval($parent)."'
- WHERE user_extended_struct_id = '".intval($id)."'
- ";
- return $sql->db_Update("user_extended_struct", $newfield_info);
- }
- }
-
- function user_extended_remove($id, $name)
- {
- global $sql, $tp;
- $this->clear_cache();
- if ($this->user_extended_field_exist($name))
- {
- // FIXME - no table structure changes for categories
- // but no good way to detect it right now - ignore the sql error for now, fix it asap
- $sql->db_Select_gen("ALTER TABLE #user_extended DROP user_".$tp -> toDB($name, true));
-
- if(is_numeric($id))
- {
- $sql->db_Delete("user_extended_struct", "user_extended_struct_id = '".intval($id)."' ");
- }
- else
- {
- $sql->db_Delete("user_extended_struct", "user_extended_struct_name = '".$tp -> toDB($id, true)."' ");
- }
- return !($this->user_extended_field_exist($name));
- }
- }
-
- function user_extended_hide($struct, $curval)
- {
- $chk = ($curval) ? " checked='checked' " : "";
- $name = "hide[user_".$struct['user_extended_struct_name']."]";
- return " ".UE_LAN_HIDE;
- }
-
-
-
- function user_extended_edit($struct, $curval)
- {
- global $tp;
- if(trim($curval) == "" && $struct['user_extended_struct_default'] != "")
- {
- $curval = $struct['user_extended_struct_default'];
- }
- $choices = explode(",",$struct['user_extended_struct_values']);
- foreach($choices as $k => $v)
- {
- $choices[$k] = str_replace("[E_COMMA]", ",", $choices[$k]);
- }
- $parms = explode("^,^",$struct['user_extended_struct_parms']);
- $include = preg_replace("/\n/", " ", $tp->toHtml($parms[0]));
- $regex = $tp->toText($parms[1]);
- $regexfail = $tp->toText($parms[2]);
- $fname = "ue[user_".$struct['user_extended_struct_name']."]";
- if(strpos($include, 'class') === FALSE)
- {
- $include .= " class='tbox' ";
- }
-
-
- switch($struct['user_extended_struct_type'])
- {
- case EUF_TEXT : //textbox
- case EUF_INTEGER : //integer
- $ret = "";
- return $ret;
- break;
-
- case EUF_RADIO : //radio
- $ret = '';
- foreach($choices as $choice)
- {
- $choice = trim($choice);
- $choice = deftrue($choice, $choice);
- $chk = ($curval == $choice)? " checked='checked' " : "";
- $ret .= " {$choice}";
- }
- return $ret;
- break;
-
- case EUF_CHECKBOX : //checkboxes
- foreach($choices as $choice)
- {
- $choice = trim($choice);
- if(strpos($choice,"|")!==FALSE)
- {
- list($val,$label) = explode("|",$choice);
- }
- else
- {
- $val = $choice;
- $label = $choice;
- }
- $label = deftrue($label, $label);
- $chk = ($curval == $val)? " checked='checked' " : "";
- $ret .= " {$label}
";
- }
- return $ret;
- break;
-
- case EUF_DROPDOWN : //dropdown
- $ret = "\n";
- return $ret;
- break;
-
- case EUF_PREDEFINED : // predefined list, shown in dropdown
- $filename = e_ADMIN.'sql/extended_'.trim($struct['user_extended_struct_values']).'.php';
- if (!is_readable($filename)) return 'No file: '.$filename;
- require($filename);
- $list_name = $struct['user_extended_struct_values'].'_list';
- $display_func = $struct['user_extended_struct_values'].'_value';
- if (!function_exists($display_func)) $display_func = '';
- $source_data = $$list_name;
- $ret = "\n";
- return $ret;
- break;
-
- case EUF_DB_FIELD : //db_field
- global $sql;
- $order = ($choices[3]) ? "ORDER BY ".$tp -> toDB($choices[3], true) : "";
-
- if($sql->db_Select($tp -> toDB($choices[0], true), $tp -> toDB($choices[1], true).",".$tp -> toDB($choices[2], true), "1 $order")){
- $choiceList = $sql->db_getList('ALL',FALSE);
- $ret = "\n";
- return $ret;
- } else {
- return "";
- }
- break;
-
- case EUF_TEXTAREA : //textarea
- return "";
- break;
-
- case EUF_DATE : //date
- return e107::getForm()->datepicker($fname,$curval,'dateformat=yy-mm-dd');
- break;
-
- case EUF_LANGUAGE : // language
- require_once(e_HANDLER."file_class.php");
- $fl = new e_file;
- $lanlist = $fl->get_dirs(e_LANGUAGEDIR);
- sort($lanlist);
- $ret = "\n";
- break;
-
- }
-
- return $ret;
- }
-
- function user_extended_getStruct($orderby="user_extended_struct_order")
- {
- if($ueStruct = getcachedvars('ue_struct'))
- {
- return $ueStruct;
- }
- global $tp;
- $ret = array();
- $parms = "";
- if($orderby != "")
- {
- $parms = "1 ORDER BY ".$tp -> toDB($orderby, true);
- }
- $sql_ue = new db; // Use our own db to avoid interference with other objects
- if($sql_ue->db_Select('user_extended_struct','*',$parms))
- {
- while($row = $sql_ue->db_Fetch())
- {
- $ret['user_'.$row['user_extended_struct_name']] = $row;
- }
- }
- cachevars('ue_struct',$ret);
- return $ret;
- }
-
-
- function parse_extended_xml($contents, $no_cache = FALSE)
- {
- if($no_cache == FALSE && $this->extended_xml)
- {
- return $this->extended_xml;
- }
-
- $xml = e107::getXml();
- $data = $xml->loadXMLfile(e_CORE."xml/user_extended.xml", true);
- $ret['version'] = $data['@attributes']['version'];
- unset($info);
- foreach($data['item'] as $item)
- {
- if(is_array($item['include_text']) && !count($item['include_text']))
- {
- $item['include_text'] = '';
- }
- $info = array(
- "name" => $item['@attributes']['name'],
- "text" => "UE_LAN_".strtoupper($item['@attributes']['name']),
- "type" => $item['type'],
- "values" => $item['values'],
- "default" => $item['default'],
- "required" => $item['required'],
- "read" => $item['read'],
- "write" => $item['write'],
- "applicable" => $item['applicable'],
- "include_text" => $item['include_text'],
- "parms" => $item['include_text'],
- "regex" => $item['regex']
- );
- if(is_array($item['default']) && $item['default'] == '')
- {
- $info['default'] = 0;
- }
- if($item['regex'])
- {
- $info['parms'] .= $item['include_text']."^,^".$item['regex']."^,^LAN_UE_FAIL_".strtoupper($item['@attributes']['name']);
- }
- $ret[$item['@attributes']['name']] = $info;
- }
- $this->extended_xml = $ret;
- return $this->extended_xml;
- }
-
- /**
- * Proxy Method to retrieve the value of an extended field
- * @param int $uid
- * @param var $field_name
- * @param object $ifnotset [optional]
- * @return mixed
- */
- function get($uid, $field_name, $ifnotset=false)
- {
- return user_extended_getvalue($uid, $field_name, $ifnotset);
- }
-
-
-
- /**
- * Proxy method for setting the value of an extended field
- * (inserts or updates)
- *
- * @param integer $uid
- * @param string $field_name eg. location
- * @param string $newvalue eg. USA
- * @param string $fieldType [optional] default 'todb' |
- * @return boolean;
- */
- function set($uid, $field_name, $newvalue, $fieldType = 'todb')
- {
- return $this->user_extended_setvalue($uid, $field_name, $newvalue, $fieldType);
- }
-
-
- /**
- * Set the value of an extended field
- *
- * $ue = new e107_user_extended;
- * $result = $ue->user_extended_setvalue(1, 'location', 'Pittsburgh');
- *
- *
- */
- function user_extended_setvalue($uid, $field_name, $newvalue, $fieldType = 'todb')
- {
- $sql = e107::getDb();
- $tp = e107::getParser();
-
- $uid = (int)$uid;
- switch($fieldType)
- {
- case 'int':
- $newvalue = (int)$newvalue;
- break;
-
- case 'escape':
- $newvalue = "'".mysql_real_escape_string($newvalue)."'";
- break;
-
- default:
- $newvalue = "'".$tp->toDB($newvalue)."'";
- break;
- }
- if(substr($field_name, 0, 5) != 'user_')
- {
- $field_name = 'user_'.$field_name;
- }
- $qry = "
- INSERT INTO `#user_extended` (user_extended_id, {$field_name})
- VALUES ({$uid}, {$newvalue})
- ON DUPLICATE KEY UPDATE {$field_name} = {$newvalue}
- ";
- return $sql->db_Select_gen($qry);
- }
-
-
- /**
- * Retrieve the value of an extended field
- *
- * $ue = new e107_user_extended;
- * $value = $ue->user_extended_getvalue(2, 'location');
- *
- */
- function user_extended_getvalue($uid, $field_name, $ifnotset=false)
- {
- $uid = intval($uid);
- if(substr($field_name, 0, 5) != 'user_')
- {
- $field_name = 'user_'.$field_name;
- }
- $uinfo = get_user_data($uid);
- if (!isset($uinfo[$field_name])) return $ifnotset;
- return $uinfo[$field_name];
- }
-
- // Given a predefined list field, returns the display text corresponding to the passed value
- function user_extended_display_text($table,$value)
- {
- $filename = e_ADMIN.'sql/extended_'.$table.'.php';
- if (!is_readable($filename)) return 'No file: '.$filename;
- require_once($filename);
- $list_name = $table.'_list';
- $display_func = $table.'_value';
- if (!function_exists($display_func)) $display_func = '';
- $source_data = $$list_name;
- foreach($source_data as $v)
- {
- if ($value == $v[0])
- {
- if ($display_func) return $display_func($v[0],$v[1]);
- return $v[1];
- }
- }
- return '????';
- }
-
-}
+typeArray = array(
+ 'text' => 1,
+ 'radio' => 2,
+ 'dropdown' => 3,
+ 'db field' => 4,
+ 'textarea' => 5,
+ 'integer' => 6,
+ 'date' => 7,
+ 'language' => 8,
+ 'list' => 9,
+ 'checkbox' => 10,
+ 'predefined' => 11, // DON'T USE IT IN PREDEFINED FIELD XML!!! Used in plugin installation routine.
+ );
+
+ $this->user_extended_types = array(
+ 1 => UE_LAN_1,
+ 2 => UE_LAN_2,
+ 3 => UE_LAN_3,
+ 4 => UE_LAN_4,
+ 5 => UE_LAN_5,
+ 6 => UE_LAN_6,
+ 7 => UE_LAN_7,
+ 8 => UE_LAN_8,
+ 9 => UE_LAN_9,
+ 10=> UE_LAN_10
+ );
+
+ //load array with field names from main user table, so we can disallow these
+ // user_new, user_timezone deleted for 0.8
+ $this->reserved_names = array (
+ 'id', 'name', 'loginname', 'customtitle', 'password',
+ 'sess', 'email', 'signature', 'image', 'hideemail',
+ 'join', 'lastvisit', 'currentvisit', 'chats',
+ 'comments', 'forums', 'ip', 'ban', 'prefs', 'viewed',
+ 'visits', 'admin', 'login', 'class', 'baseclasslist', 'perms', 'pwchange',
+ 'xup'
+ );
+
+ $sql = e107::getDB();
+
+ // Read in all the field and category fields
+ // At present we load all fields into common array - may want to split system and non-system
+ $this ->catDefinitions = array(); // Categories array
+ $this->fieldDefinitions = array(); // Field definitions array
+ $this->nameIndex = array(); // Index of names => field IDs
+ $this->systemCount = 0;
+ $this->userCount = 0;
+
+ if($sql->db_Select('user_extended_struct', '*', "user_extended_struct_text != '_system_' ORDER BY user_extended_struct_order ASC"))
+ {
+ while($row = $sql->db_Fetch(MYSQL_ASSOC))
+ {
+ if ($row['user_extended_struct_type'] == 0)
+ { // Its a category
+ $this->catDefinitions[$row['user_extended_struct_id']] = $row;
+ }
+ else
+ { // Its a field definition
+ $this->fieldDefinitions[$row['user_extended_struct_id']] = $row;
+ $this->nameIndex['user_'.$row['user_extended_struct_name']] = $row['user_extended_struct_id']; // Create name to ID index
+ if ($row['user_extended_struct_text'] == '_system_')
+ {
+ $this->systemCount++;
+ }
+ else
+ {
+ $this->userCount++;
+ }
+ }
+ }
+ }
+ }
+
+
+
+ /**
+ * Check for reserved field names.
+ * (Names which clash with the 'normal' user table aren't allowed)
+ *
+ * @param string $name - name of field bweing checked (no 'user_' prefix)
+ *
+ * @return boolean TRUE if disallowed name
+ */
+ public function user_extended_reserved($name)
+ {
+ return (in_array($name, $this->reserved_names));
+ }
+
+
+
+ // Adds the _FIELD_TYPES array to the data, ready for saving in the DB.
+ function addFieldTypes(&$target)
+ {
+ $target['_FIELD_TYPES'] = array(); // We should always want to recreate the array, even if it exists
+ foreach ($target['data'] as $k => $v)
+ {
+ if (isset($this->nameIndex[$k]))
+ {
+ switch ($this->fieldDefinitions[$this->nameIndex[$k]]['user_extended_struct_type'])
+ {
+ case EUF_TEXT :
+ case EUF_DB_FIELD :
+ case EUF_TEXTAREA :
+ case EUF_DROPDOWN :
+ case EUF_DATE :
+ case EUF_LANGUAGE :
+ case EUF_PREDEFINED :
+ case EUF_CHECKBOX :
+ case EUF_RADIO :
+ $target['_FIELD_TYPES'][$k] = 'todb';
+ break;
+
+ case EUF_INTEGER :
+ $target['_FIELD_TYPES'][$k] = 'int';
+ break;
+ }
+ }
+ }
+ }
+
+
+
+ /**
+ * For all UEFs not in the target array, adds the default value
+ * Also updates the _FIELD_TYPES array, so call this last thing before writing to the DB
+ *
+ * @param $target - pointer to data array
+ */
+ public function addDefaultFields(&$target)
+ {
+ //$target['_FIELD_TYPES'] = array(); // We should always want to recreate the array, even if it exists
+ foreach ($this->fieldDefinitions as $k => $defs)
+ {
+ $f = 'user_'.$defs['user_extended_struct_name'];
+ if (!isset($target['data'][$f]) && $this->fieldDefinitions[$k]['user_extended_struct_default'])
+ {
+ switch ($this->fieldDefinitions[$k]['user_extended_struct_type'])
+ {
+ case EUF_TEXT :
+ case EUF_DB_FIELD :
+ case EUF_TEXTAREA :
+ case EUF_DROPDOWN :
+ case EUF_DATE :
+ case EUF_LANGUAGE :
+ case EUF_PREDEFINED :
+
+ $target['data'][$f] = $this->fieldDefinitions[$k]['user_extended_struct_default'];
+ $target['_FIELD_TYPES'][$f] = 'todb';
+ break;
+ case EUF_RADIO :
+ case EUF_INTEGER :
+ $target['data'][$f] = $this->fieldDefinitions[$k]['user_extended_struct_default'];
+ $target['_FIELD_TYPES'][$f] = 'int';
+ break;
+ case EUF_CHECKBOX :
+ $target['data'][$f] = $this->fieldDefinitions[$k]['user_extended_struct_default'];
+ $target['_FIELD_TYPES'][$f] = 'array';
+ break;
+ }
+ }
+ }
+ }
+
+
+
+ // Validate a single extended user field
+ // $val is whatever the user entered.
+ // $params is the field definition
+ // Return FALSE if acceptable, TRUE if fail , error message on regex fail if the message is defined
+ function user_extended_validate_entry($val, $params)
+ {
+ global $tp;
+ $parms = explode('^,^', $params['user_extended_struct_parms']);
+ $requiredField = $params['user_extended_struct_required'] == 1;
+ $regex = $tp->toText($parms[1]);
+ $regexfail = $tp->toText($parms[2]);
+ if (defined($regexfail)) { $regexfail = constant($regexfail); }
+ if($val == '' && $requiredField) return TRUE;
+ switch ($type)
+ {
+ case EUF_DATE :
+ if ($requiredField && ($val == '0000-00-00')) return TRUE;
+ break;
+ }
+ if($regex != "" && $val != "")
+ {
+ if(!preg_match($regex, $val)) return $regexfail ? $regexfail : TRUE;
+ }
+ return FALSE; // Pass by default here
+ }
+
+
+
+ /**
+ * Validate all user-modifable extended user fields which are presented.
+ * Primarily intended to validate data entered by a user or admin
+ *
+ * @param array $inArray is the input data (usually from $_POST or $_POST['ue'], although doesn't have to be) - may have 'surplus' values
+ * @param array $hideArray is a set of possible 'hide' flags
+ * @param boolean $isSignup TRUE causes required fields to be specifically checked, else only data passed is checked
+ *
+ * @return array with three potential subkeys:
+ * 'data' - valid data values (key is field name)
+ * ['data']['user_hidden_fields'] is the hidden fields
+ * 'errors' - data values in error
+ * 'errortext' - error message corresponding to erroneous value
+ *
+ * @todo - does $hidden_fields need to be merged with values for fields not processed? (Probably not - should only relate to fields current user can see)
+ * @todo - make sure admin can edit fields of other users
+ */
+ public function userExtendedValidateAll($inArray, $hideArray, $isSignup=FALSE)
+ {
+ global $tp;
+ $eufVals = array(); // 'Answer' array
+ $hideFlags = array();
+
+ foreach ($this->fieldDefinitions as $k => $defs)
+ {
+ $category = $defs['user_extended_struct_parent'];
+ if (($category == 0) || ($isSignup && (int) $this->catDefinitions[$category]['user_extended_struct_applicable'] === (int) e_UC_MEMBER && (int) $this->catDefinitions[$category]['user_extended_struct_write'] === (int) e_UC_MEMBER) || (check_class($this->catDefinitions[$category]['user_extended_struct_applicable']) && check_class($this->catDefinitions[$category]['user_extended_struct_write'])))
+ { // Category applicable to user
+
+ if (($isSignup && (int) $defs['user_extended_struct_applicable'] === (int) e_UC_MEMBER && (int) $defs['user_extended_struct_write'] === (int) e_UC_MEMBER) || (check_class($defs['user_extended_struct_applicable']) && check_class($defs['user_extended_struct_write'])))
+ { // User can also update field
+ $f = 'user_'.$defs['user_extended_struct_name'];
+ if (isset($inArray[$f]) || ($isSignup && ($defs['user_extended_struct_required'] == 1)))
+ { // Only allow valid keys
+ $val = varset($inArray[$f], FALSE);
+ $err = $this->user_extended_validate_entry($val, $defs);
+ if ($err === true)
+ { // General error - usually empty field; could be unacceptable value, or regex fail and no error message defined
+ $eufVals['errortext'][$f] = str_replace('--SOMETHING--',$tp->toHtml(defset($defs['user_extended_struct_text'], $defs['user_extended_struct_text']),FALSE,'defs'),LAN_USER_75);
+ $eufVals['errors'][$f] = ERR_GENERIC;
+ }
+ elseif ($err)
+ { // Specific error message returned - usually regex fail
+ $eufVals['errortext'][$f] = $err;
+ $eufVals['errors'][$f] = ERR_GENERIC;
+ }
+ elseif (!$err)
+ {
+ $eufVals['data'][$f] = $tp->toDB($val);
+ }
+ if (isset($hideArray[$f]))
+ {
+ $hideFlags[] = $f;
+ }
+ }
+ }
+ }
+ }
+ $hidden_fields = implode('^', $hideFlags);
+ if ($hidden_fields != '')
+ {
+ $hidden_fields = '^'.$hidden_fields.'^';
+ }
+ $eufVals['data']['user_hidden_fields'] = $hidden_fields;
+
+ return $eufVals;
+ }
+
+
+
+
+ function user_extended_get_categories($byID = TRUE)
+ {
+ $ret = array();
+ global $sql;
+ if($sql->db_Select("user_extended_struct", "*", "user_extended_struct_type = 0 ORDER BY user_extended_struct_order ASC"))
+ {
+ if($byID == TRUE)
+ {
+ while($row = $sql->db_Fetch())
+ {
+ $ret[$row['user_extended_struct_id']][] = $row;
+ }
+ }
+ else
+ {
+ $ret = $sql->db_getList();
+ }
+ }
+ return $ret;
+ }
+
+
+ // Get the definition of all fields, or those in a specific category, grouped by category ID
+ // Reads non-system fields only
+ function user_extended_get_fields($cat = "")
+ {
+ global $sql;
+ $ret = array();
+ $more = ($cat) ? " AND user_extended_struct_parent = ".intval($cat)." " : "";
+ if($sql->db_Select("user_extended_struct", "*", "user_extended_struct_type > 0 AND user_extended_struct_text != '_system_' {$more} ORDER BY user_extended_struct_order ASC"))
+ {
+ while($row = $sql->db_Fetch(MYSQL_ASSOC))
+ {
+ $ret[$row['user_extended_struct_parent']][] = $row;
+ }
+ }
+ return $ret;
+ }
+
+ // Get the definition of all fields, or those in a specific category, indexed by field ID (or some other field by specifying $indexField)
+ function user_extended_get_fieldList($cat = "", $indexField = 'user_extended_struct_id')
+ {
+ global $sql;
+ $more = ($cat != '') ? " AND user_extended_struct_parent = ".intval($cat)." " : "";
+ if($sql->db_Select("user_extended_struct", "*", "user_extended_struct_type > 0 AND user_extended_struct_text != '_system_' {$more} ORDER BY user_extended_struct_order ASC"))
+ {
+ while($row = $sql->db_Fetch(MYSQL_ASSOC))
+ {
+ $ret[$row[$indexField]] = $row;
+ }
+ }
+ return $ret;
+ }
+
+
+ // Return the field creation text for a definition
+ function user_extended_type_text($type, $default)
+ {
+ global $tp;
+ if(!is_numeric($type))
+ {
+ return false;
+ }
+
+ switch ($type)
+ {
+ case EUF_INTEGER :
+ $db_type = 'INT(11)';
+ break;
+
+ case EUF_DATE :
+ $db_type = 'DATE NOT NULL';
+ break;
+
+ case EUF_TEXTAREA:
+ $db_type = 'TEXT';
+ break;
+
+ case EUF_TEXT :
+ case EUF_RADIO :
+ case EUF_DROPDOWN :
+ case EUF_DB_FIELD :
+ case EUF_LANGUAGE :
+ case EUF_PREDEFINED :
+ case EUF_CHECKBOX :
+ $db_type = 'VARCHAR(255)';
+ break;
+
+ case EUF_CATEGORY:
+ return '';
+ break;
+
+ default:
+ e107::getMessage()->addDebug("Unknown type '{$type}' for user extended field.");
+ return false;
+ break;
+
+ }
+ if($type != EUF_DB_FIELD && $type != EUF_TEXTAREA && $default != '')
+ {
+ $default_text = " DEFAULT '".$tp -> toDB($default, true)."'";
+ }
+ else
+ {
+ $default_text = '';
+ }
+ return $db_type.$default_text;
+ }
+
+
+ function user_extended_field_exist($name)
+ {
+ global $sql, $tp;
+ return $sql->db_Count('user_extended_struct','(*)', "WHERE user_extended_struct_name = '".$tp -> toDB($name, true)."'");
+ }
+
+ function clear_cache()
+ {
+ $e107 = e107::getInstance();
+ $e107->ecache->clear_sys('nomd5_extended_struct');
+ }
+
+ // For use by plugins to add extended user fields and won't be visible anywhere else
+ function user_extended_add_system($name, $type, $default = '', $source = '_system_')
+ {
+ return $this->user_extended_add($name, '_system_', $type, $source, '', $default, 0, 255, 255, 255, 0, 0);
+ }
+
+
+ function user_extended_add($name, $text, $type, $parms, $values, $default, $required, $read, $write, $applicable, $order='', $parent)
+ {
+ global $sql, $tp;
+ $this->clear_cache();
+ if(is_array($name))
+ {
+ extract($name);
+ }
+ if(!is_numeric($type))
+ {
+ $type = $this->typeArray[$type];
+ }
+
+ if (!$this->user_extended_field_exist($name) && !$this->user_extended_reserved($name))
+ {
+ $field_info = $this->user_extended_type_text($type, $default);
+
+ // wrong type
+ if(false === $field_info) return false;
+
+ if($order === '' && $field_info)
+ {
+ if($sql->db_Select('user_extended_struct','MAX(user_extended_struct_order) as maxorder','1'))
+ {
+ $row = $sql->db_Fetch();
+ if(is_numeric($row['maxorder']))
+ {
+ $order = $row['maxorder']+1;
+ }
+ }
+ }
+ // field of type category
+ if($field_info)
+ {
+ $sql->db_Select_gen('ALTER TABLE #user_extended ADD user_'.$tp -> toDB($name, true).' '.$field_info);
+ }
+
+ $sql->db_Insert('user_extended_struct',"null,'".$tp -> toDB($name, true)."','".$tp -> toDB($text, true)."','".intval($type)."','".$tp -> toDB($parms, true)."','".$tp -> toDB($values, true)."', '".$tp -> toDB($default, true)."', '".intval($read)."', '".intval($write)."', '".intval($required)."', '0', '".intval($applicable)."', '".intval($order)."', '".intval($parent)."'");
+ if ($this->user_extended_field_exist($name))
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+
+
+
+ function user_extended_modify($id, $name, $text, $type, $parms, $values, $default, $required, $read, $write, $applicable, $parent)
+ {
+ global $sql, $tp;
+ if ($this->user_extended_field_exist($name))
+ {
+ $field_info = $this->user_extended_type_text($type, $default);
+ // wrong type
+ if(false === $field_info) return false;
+
+ // field of type category
+ if($field_info)
+ {
+ $sql->db_Select_gen("ALTER TABLE #user_extended MODIFY user_".$tp -> toDB($name, true)." ".$field_info);
+ }
+
+ $newfield_info = "
+ user_extended_struct_text = '".$tp -> toDB($text, true)."',
+ user_extended_struct_type = '".intval($type)."',
+ user_extended_struct_parms = '".$tp -> toDB($parms, true)."',
+ user_extended_struct_values = '".$tp -> toDB($values, true)."',
+ user_extended_struct_default = '".$tp -> toDB($default, true)."',
+ user_extended_struct_required = '".intval($required)."',
+ user_extended_struct_read = '".intval($read)."',
+ user_extended_struct_write = '".intval($write)."',
+ user_extended_struct_applicable = '".intval($applicable)."',
+ user_extended_struct_parent = '".intval($parent)."'
+ WHERE user_extended_struct_id = '".intval($id)."'
+ ";
+ return $sql->db_Update("user_extended_struct", $newfield_info);
+ }
+ }
+
+ function user_extended_remove($id, $name)
+ {
+ global $sql, $tp;
+ $this->clear_cache();
+ if ($this->user_extended_field_exist($name))
+ {
+ // FIXME - no table structure changes for categories
+ // but no good way to detect it right now - ignore the sql error for now, fix it asap
+ $sql->db_Select_gen("ALTER TABLE #user_extended DROP user_".$tp -> toDB($name, true));
+
+ if(is_numeric($id))
+ {
+ $sql->db_Delete("user_extended_struct", "user_extended_struct_id = '".intval($id)."' ");
+ }
+ else
+ {
+ $sql->db_Delete("user_extended_struct", "user_extended_struct_name = '".$tp -> toDB($id, true)."' ");
+ }
+ return !($this->user_extended_field_exist($name));
+ }
+ }
+
+ function user_extended_hide($struct, $curval)
+ {
+ $chk = ($curval) ? " checked='checked' " : "";
+ $name = "hide[user_".$struct['user_extended_struct_name']."]";
+ return " ".UE_LAN_HIDE;
+ }
+
+
+
+ function user_extended_edit($struct, $curval)
+ {
+ global $tp;
+ if(trim($curval) == "" && $struct['user_extended_struct_default'] != "")
+ {
+ $curval = $struct['user_extended_struct_default'];
+ }
+ $choices = explode(",",$struct['user_extended_struct_values']);
+ foreach($choices as $k => $v)
+ {
+ $choices[$k] = str_replace("[E_COMMA]", ",", $choices[$k]);
+ }
+ $parms = explode("^,^",$struct['user_extended_struct_parms']);
+ $include = preg_replace("/\n/", " ", $tp->toHtml($parms[0]));
+ $regex = $tp->toText($parms[1]);
+ $regexfail = $tp->toText($parms[2]);
+ $fname = "ue[user_".$struct['user_extended_struct_name']."]";
+ if(strpos($include, 'class') === FALSE)
+ {
+ $include .= " class='tbox' ";
+ }
+
+
+ switch($struct['user_extended_struct_type'])
+ {
+ case EUF_TEXT : //textbox
+ case EUF_INTEGER : //integer
+ $ret = "";
+ return $ret;
+ break;
+
+ case EUF_RADIO : //radio
+ $ret = '';
+ foreach($choices as $choice)
+ {
+ $choice = trim($choice);
+ $choice = deftrue($choice, $choice);
+ $chk = ($curval == $choice)? " checked='checked' " : "";
+ $ret .= " {$choice}";
+ }
+ return $ret;
+ break;
+
+ case EUF_CHECKBOX : //checkboxes
+ foreach($choices as $choice)
+ {
+ $choice = trim($choice);
+ if(strpos($choice,"|")!==FALSE)
+ {
+ list($val,$label) = explode("|",$choice);
+ }
+ else
+ {
+ $val = $choice;
+ $label = $choice;
+ }
+ $label = deftrue($label, $label);
+ $chk = ($curval == $val)? " checked='checked' " : "";
+ $ret .= " {$label}
";
+ }
+ return $ret;
+ break;
+
+ case EUF_DROPDOWN : //dropdown
+ $ret = "\n";
+ return $ret;
+ break;
+
+ case EUF_PREDEFINED : // predefined list, shown in dropdown
+ $listRoot = trim($struct['user_extended_struct_values']); // Base list name
+ $filename = e_ADMIN.'sql/extended_'.$listRoot.'.php';
+ if (!is_readable($filename)) return 'No file: '.$filename;
+ require_once($filename);
+ $className = 'extended_'.$listRoot;
+ if (!class_exists($className)) return '?????';
+ $temp = new $className();
+ if (!method_exists($className, 'getValue')) return '???-???';
+ $temp->pointerReset();
+
+ $ret = "\n";
+ return $ret;
+
+ case EUF_DB_FIELD : //db_field
+ global $sql;
+ $order = ($choices[3]) ? "ORDER BY ".$tp -> toDB($choices[3], true) : "";
+
+ if($sql->db_Select($tp -> toDB($choices[0], true), $tp -> toDB($choices[1], true).",".$tp -> toDB($choices[2], true), "1 $order")){
+ $choiceList = $sql->db_getList('ALL',FALSE);
+ $ret = "\n";
+ return $ret;
+ } else {
+ return "";
+ }
+ break;
+
+ case EUF_TEXTAREA : //textarea
+ return "";
+ break;
+
+ case EUF_DATE : //date
+ return e107::getForm()->datepicker($fname,$curval,'dateformat=yy-mm-dd');
+ break;
+
+ case EUF_LANGUAGE : // language
+ require_once(e_HANDLER."file_class.php");
+ $fl = new e_file;
+ $lanlist = $fl->get_dirs(e_LANGUAGEDIR);
+ sort($lanlist);
+ $ret = "\n";
+ break;
+
+ }
+
+ return $ret;
+ }
+
+ function user_extended_getStruct($orderby="user_extended_struct_order")
+ {
+ if($ueStruct = getcachedvars('ue_struct'))
+ {
+ return $ueStruct;
+ }
+ global $tp;
+ $ret = array();
+ $parms = "";
+ if($orderby != "")
+ {
+ $parms = "1 ORDER BY ".$tp -> toDB($orderby, true);
+ }
+ $sql_ue = new db; // Use our own db to avoid interference with other objects
+ if($sql_ue->db_Select('user_extended_struct','*',$parms))
+ {
+ while($row = $sql_ue->db_Fetch())
+ {
+ $ret['user_'.$row['user_extended_struct_name']] = $row;
+ }
+ }
+ cachevars('ue_struct',$ret);
+ return $ret;
+ }
+
+
+ function parse_extended_xml($contents, $no_cache = FALSE)
+ {
+ if($no_cache == FALSE && $this->extended_xml)
+ {
+ return $this->extended_xml;
+ }
+
+ $xml = e107::getXml();
+ $data = $xml->loadXMLfile(e_CORE."xml/user_extended.xml", true);
+ $ret['version'] = $data['@attributes']['version'];
+ unset($info);
+ foreach($data['item'] as $item)
+ {
+ if(is_array($item['include_text']) && !count($item['include_text']))
+ {
+ $item['include_text'] = '';
+ }
+ $info = array(
+ "name" => $item['@attributes']['name'],
+ "text" => "UE_LAN_".strtoupper($item['@attributes']['name']),
+ "type" => $item['type'],
+ "values" => $item['values'],
+ "default" => $item['default'],
+ "required" => $item['required'],
+ "read" => $item['read'],
+ "write" => $item['write'],
+ "applicable" => $item['applicable'],
+ "include_text" => $item['include_text'],
+ "parms" => $item['include_text'],
+ "regex" => $item['regex']
+ );
+ if(is_array($item['default']) && $item['default'] == '')
+ {
+ $info['default'] = 0;
+ }
+ if($item['regex'])
+ {
+ $info['parms'] .= $item['include_text']."^,^".$item['regex']."^,^LAN_UE_FAIL_".strtoupper($item['@attributes']['name']);
+ }
+ $ret[$item['@attributes']['name']] = $info;
+ }
+ $this->extended_xml = $ret;
+ return $this->extended_xml;
+ }
+
+ /**
+ * Proxy Method to retrieve the value of an extended field
+ * @param int $uid
+ * @param var $field_name
+ * @param object $ifnotset [optional]
+ * @return mixed
+ */
+ function get($uid, $field_name, $ifnotset=false)
+ {
+ return user_extended_getvalue($uid, $field_name, $ifnotset);
+ }
+
+
+
+ /**
+ * Proxy method for setting the value of an extended field
+ * (inserts or updates)
+ *
+ * @param integer $uid
+ * @param string $field_name eg. location
+ * @param string $newvalue eg. USA
+ * @param string $fieldType [optional] default 'todb' |
+ * @return boolean;
+ */
+ function set($uid, $field_name, $newvalue, $fieldType = 'todb')
+ {
+ return $this->user_extended_setvalue($uid, $field_name, $newvalue, $fieldType);
+ }
+
+
+ /**
+ * Set the value of an extended field
+ *
+ * $ue = new e107_user_extended;
+ * $result = $ue->user_extended_setvalue(1, 'location', 'Pittsburgh');
+ *
+ *
+ */
+ function user_extended_setvalue($uid, $field_name, $newvalue, $fieldType = 'todb')
+ {
+ $sql = e107::getDb();
+ $tp = e107::getParser();
+
+ $uid = (int)$uid;
+ switch($fieldType)
+ {
+ case 'int':
+ $newvalue = (int)$newvalue;
+ break;
+
+ case 'escape':
+ $newvalue = "'".mysql_real_escape_string($newvalue)."'";
+ break;
+
+ default:
+ $newvalue = "'".$tp->toDB($newvalue)."'";
+ break;
+ }
+ if(substr($field_name, 0, 5) != 'user_')
+ {
+ $field_name = 'user_'.$field_name;
+ }
+ $qry = "
+ INSERT INTO `#user_extended` (user_extended_id, {$field_name})
+ VALUES ({$uid}, {$newvalue})
+ ON DUPLICATE KEY UPDATE {$field_name} = {$newvalue}
+ ";
+ return $sql->db_Select_gen($qry);
+ }
+
+
+ /**
+ * Retrieve the value of an extended field
+ *
+ * $ue = new e107_user_extended;
+ * $value = $ue->user_extended_getvalue(2, 'location');
+ *
+ */
+ function user_extended_getvalue($uid, $field_name, $ifnotset=false)
+ {
+ $uid = intval($uid);
+ if(substr($field_name, 0, 5) != 'user_')
+ {
+ $field_name = 'user_'.$field_name;
+ }
+ $uinfo = get_user_data($uid);
+ if (!isset($uinfo[$field_name])) return $ifnotset;
+ return $uinfo[$field_name];
+ }
+
+
+ /**
+ * Given a predefined list field, returns the display text corresponding to the passed value
+ *
+ * @TODO: consider whether to cache the class object
+ */
+ function user_extended_display_text($table, $value)
+ {
+ $filename = e_ADMIN.'sql/extended_'.$table.'.php';
+ if (!is_readable($filename)) return 'No file: '.$filename;
+ require_once($filename);
+ $className = 'extended_'.$table;
+ if (!class_exists($className)) return '?????';
+ $temp = new $className();
+ if (!method_exists($className, 'getValue')) return '???-???';
+ return $temp->getValue($value);
+ }
+
+}
?>
\ No newline at end of file