# HG changeset patch # User Dan # Date 1229851616 18000 # Node ID 62fed244fa1c8718e191ccb96e1bd44c3d4c943c # Parent 1946d845bb25256e0da150fc12b402c80f181444 Fixed timezone preference setting not fully implemented; added ability for users to select their own rank from a list of possible ranks based on group membership and user level diff -r 1946d845bb25 -r 62fed244fa1c includes/dbal.php --- a/includes/dbal.php Sun Dec 21 04:24:52 2008 -0500 +++ b/includes/dbal.php Sun Dec 21 04:26:56 2008 -0500 @@ -421,7 +421,7 @@ if(!$r) $this->_die('$db->fetchrow(): an invalid MySQL resource was passed.'); $row = mysql_fetch_assoc($r); $this->disable_errorhandler(); - return $row; + return integerize_array($row); } function fetchrow_num($r = false) { @@ -430,7 +430,7 @@ if(!$r) $this->_die('$db->fetchrow(): an invalid MySQL resource was passed.'); $row = mysql_fetch_row($r); $this->disable_errorhandler(); - return $row; + return integerize_array($row); } function numrows($r = false) { @@ -1165,7 +1165,7 @@ if(!$r) $this->_die('$db->fetchrow(): an invalid MySQL resource was passed.'); $row = pg_fetch_assoc($r); $this->disable_errorhandler(); - return $row; + return integerize_array($row); } function fetchrow_num($r = false) { @@ -1174,7 +1174,7 @@ if(!$r) $this->_die('$db->fetchrow(): an invalid MySQL resource was passed.'); $row = pg_fetch_row($r); $this->disable_errorhandler(); - return $row; + return integerize_array($row); } function numrows($r = false) { diff -r 1946d845bb25 -r 62fed244fa1c includes/functions.php --- a/includes/functions.php Sun Dec 21 04:24:52 2008 -0500 +++ b/includes/functions.php Sun Dec 21 04:26:56 2008 -0500 @@ -719,6 +719,31 @@ return $arr3; } +/** + * Looks at all values in an array and casts them to integers if they are strings with digits. Recursive. + * @param array Array to process + * @return array + */ + +function integerize_array($arr) +{ + if ( !is_array($arr) ) + return $arr; + + foreach ( $arr as &$val ) + { + if ( is_string($val) && ctype_digit($val) && strlen($val) < 10 ) + { + $val = intval($val); + } + else if ( is_array($val) ) + { + $val = integerize_array($val); + } + } + return $arr; +} + // Convert IP address to hex string // Input: 127.0.0.1 (string) // Output: 0x7f000001 (string) @@ -2876,7 +2901,8 @@ $page_id = str_replace(' ', '_', $page_id); // Exception for userpages for IP addresses - if ( is_valid_ip($page_id) ) + $pid_ip_check = ( is_object($paths) ) ? preg_replace('+^' . preg_quote($paths->nslist['User']) . '+', '', $page_id) : $page_id; + if ( is_valid_ip($pid_ip_check) ) { return $page_id; } diff -r 1946d845bb25 -r 62fed244fa1c includes/paths.php --- a/includes/paths.php Sun Dec 21 04:24:52 2008 -0500 +++ b/includes/paths.php Sun Dec 21 04:26:56 2008 -0500 @@ -619,7 +619,13 @@ global $cache; // store data (TTL 20 minutes) - $cache->store('page_meta', $md_array, 20); + try + { + $cache->store('page_meta', $md_array, 20); + } + catch ( Exception $e ) + { + } return true; } diff -r 1946d845bb25 -r 62fed244fa1c includes/sessions.php --- a/includes/sessions.php Sun Dec 21 04:24:52 2008 -0500 +++ b/includes/sessions.php Sun Dec 21 04:26:56 2008 -0500 @@ -2349,9 +2349,11 @@ . " COALESCE(ru.rank_id, rg.rank_id, rl.rank_id, rd.rank_id ) AS rank_id,\n" . " COALESCE(ru.rank_title, rg.rank_title, rl.rank_title, rd.rank_title) AS rank_title,\n" . " COALESCE(ru.rank_style, rg.rank_style, rl.rank_style, rd.rank_style) AS rank_style,\n" - . " rg.rank_id AS group_rank_id," - . " ( ru.rank_id IS NULL AND rg.rank_id IS NULL ) AS using_default," - . " ( ru.rank_id IS NULL AND rg.rank_id IS NOT NULL ) AS using_group," + . " rg.rank_id AS group_rank_id,\n" + . " ( ru.rank_id IS NULL AND rg.rank_id IS NULL ) AS using_default,\n" + . " ( ru.rank_id IS NULL AND rg.rank_id IS NOT NULL ) AS using_group,\n" + . " ( ru.rank_id IS NOT NULL ) AS using_user,\n" + . " u.user_rank_userset,\n" . " $gid_col\n" . " FROM " . table_prefix . "users AS u\n" . " LEFT JOIN " . table_prefix . "groups AS g\n" @@ -2393,7 +2395,7 @@ global $db, $session, $paths, $template, $plugins; // Common objects global $lang; global $user_ranks; - // cache info if possible + // cache info in RAM if possible static $_cache = array(); if ( is_int($id) && $id == 0 ) @@ -2407,7 +2409,7 @@ // invalid parameter return false; - // check the cache + // check the RAM cache if ( isset($_cache[$id]) ) return $_cache[$id]; @@ -2557,6 +2559,109 @@ return $row; } + /** + * Get the list of ranks that a user is allowed to use. Returns false if they cannot change it. + * @param string|int User ID or username + * @return array Associative by rank ID + */ + + function get_user_possible_ranks($id) + { + global $db, $session, $paths, $template, $plugins; // Common objects + + // cache info in RAM if possible + static $_cache = array(); + + if ( is_int($id) && $id == 0 ) + $id = 1; + + if ( is_int($id) ) + $col = "u.user_id = $id"; + else if ( is_string($id) ) + $col = ENANO_SQLFUNC_LOWERCASE . "(username) = " . ENANO_SQLFUNC_LOWERCASE . "('" . $db->escape($id) . "')"; + else + // invalid parameter + return false; + + // check the RAM cache + if ( isset($_cache[$id]) ) + return $_cache[$id]; + + $sql = $this->generate_rank_sql("\n WHERE $col"); + + $q = $this->sql($sql); + // any results? + if ( $db->numrows() < 1 ) + { + // nuttin'. + $db->free_result(); + $_cache[$id] = false; + return false; + } + + // Found something. + $row = $db->fetchrow(); + $db->free_result(); + + if ( $row['using_user'] && !$row['user_rank_userset'] ) + { + // The user's rank was set manually by an admin. + $result = array( + array( + 'rank_id' => $row['rank_id'], + 'rank_title' => $row['rank_title'], + 'rank_style' => $row['rank_style'], + 'rank_type' => 'user' + ) + ); + $_cache[$id] = $result; + return $result; + } + + // copy the result to a more permanent array so we can reference this later + $current_settings = $row; + unset($row); + + $result = array(); + + // first rank available to us will be the one set by the user's user level + if ( isset($this->level_rank_table[$current_settings['user_level']]) ) + { + $q = $this->sql('SELECT rank_id, rank_title, rank_style FROM ' . table_prefix . "ranks WHERE rank_id = {$this->level_rank_table[$this->user_level]};"); + if ( $db->numrows() > 0 ) + { + $row = $db->fetchrow(); + $row['rank_type'] = 'ulevel'; + + $result[] = $row; + } + $db->free_result(); + } + + // for each group the user is in, figure out if it has a rank associated with it + $group_list = explode(',', $current_settings['group_list']); + foreach ( $group_list as $group_id ) + { + $group_id = intval($group_id); + $q = $this->sql('SELECT r.rank_id, r.rank_title, r.rank_style FROM ' . table_prefix . "groups AS g\n" + . " LEFT JOIN " . table_prefix . "ranks AS r\n" + . " ON ( g.group_rank = r.rank_id )\n" + . " WHERE g.group_id = $group_id\n" + . " AND r.rank_id IS NOT NULL;"); + if ( $db->numrows() > 0 ) + { + $row = $db->fetchrow(); + $row['rank_type'] = 'group'; + + $result[] = $row; + } + $db->free_result(); + } + + $_cache[$id] = $result; + return $result; + } + # # Access Control Lists # @@ -3571,7 +3676,7 @@ { return array( 'mode' => 'error', - 'error' => 'ERR_DH_HASH_NO_MATCH' + 'error' => 'ERR_DH_HASH_NO_MATCH', ); } diff -r 1946d845bb25 -r 62fed244fa1c install/schemas/mysql_stage2.sql --- a/install/schemas/mysql_stage2.sql Sun Dec 21 04:24:52 2008 -0500 +++ b/install/schemas/mysql_stage2.sql Sun Dec 21 04:26:56 2008 -0500 @@ -112,6 +112,7 @@ avatar_type ENUM('jpg', 'png', 'gif', 'grv') NOT NULL DEFAULT 'png', user_registration_ip varchar(39), user_rank int(12) UNSIGNED DEFAULT NULL, + user_rank_userset tinyint(1) NOT NULL DEFAULT 0, user_timezone int(12) UNSIGNED NOT NULL DEFAULT 0, user_title varchar(64) DEFAULT NULL, user_group mediumint(5) NOT NULL DEFAULT 1, diff -r 1946d845bb25 -r 62fed244fa1c install/schemas/postgresql_stage2.sql --- a/install/schemas/postgresql_stage2.sql Sun Dec 21 04:24:52 2008 -0500 +++ b/install/schemas/postgresql_stage2.sql Sun Dec 21 04:26:56 2008 -0500 @@ -112,6 +112,7 @@ avatar_type varchar(3) NOT NULL, user_registration_ip varchar(39), user_rank int DEFAULT NULL, + user_rank_userset smallint NOT NULL DEFAULT 0, user_timezone int NOT NULL DEFAULT 0, user_title varchar(64) DEFAULT NULL, user_group int NOT NULL DEFAULT 1, diff -r 1946d845bb25 -r 62fed244fa1c install/schemas/upgrade/1.1.4-1.1.5-mysql.sql --- a/install/schemas/upgrade/1.1.4-1.1.5-mysql.sql Sun Dec 21 04:24:52 2008 -0500 +++ b/install/schemas/upgrade/1.1.4-1.1.5-mysql.sql Sun Dec 21 04:26:56 2008 -0500 @@ -1,3 +1,4 @@ ALTER TABLE {{TABLE_PREFIX}}session_keys ADD COLUMN key_type tinyint(1) NOT NULL DEFAULT 0; UPDATE {{TABLE_PREFIX}}session_keys SET key_type = 2 WHERE auth_level > 2; ALTER TABLE {{TABLE_PREFIX}}users ADD COLUMN user_dst varchar(11) NOT NULL DEFAULT '0;0;0;0;60'; +ALTER TABLE {{TABLE_PREFIX}}users ADD COLUMN user_rank_userset tinyint(1) NOT NULL DEFAULT 0; diff -r 1946d845bb25 -r 62fed244fa1c install/schemas/upgrade/1.1.4-1.1.5-postgresql.sql --- a/install/schemas/upgrade/1.1.4-1.1.5-postgresql.sql Sun Dec 21 04:24:52 2008 -0500 +++ b/install/schemas/upgrade/1.1.4-1.1.5-postgresql.sql Sun Dec 21 04:26:56 2008 -0500 @@ -1,4 +1,4 @@ ALTER TABLE {{TABLE_PREFIX}}session_keys ADD COLUMN key_type smallint NOT NULL DEFAULT 0; UPDATE {{TABLE_PREFIX}}session_keys SET key_type = 2 WHERE auth_level > 2; ALTER TABLE {{TABLE_PREFIX}}users ADD COLUMN user_dst varchar(11) NOT NULL DEFAULT '0;0;0;0;60'; - +ALTER TABLE {{TABLE_PREFIX}}users ADD COLUMN user_rank_userset smallint NOT NULL DEFAULT 0; diff -r 1946d845bb25 -r 62fed244fa1c language/english/core.json --- a/language/english/core.json Sun Dec 21 04:24:52 2008 -0500 +++ b/language/english/core.json Sun Dec 21 04:26:56 2008 -0500 @@ -695,7 +695,7 @@ list: '{"n12":-12,"n11":-11,"n10":-10,"n9p5":-9.5,"n9":-9,"n8":-8,"n7":-7,"n6":-6,"n5":-5,"n4":-4,"n3p5":-3.5,"n3":-3,"n2":-2,"n1":-1,"0":0,"1":1,"2":2,"3":3,"3p5":3.5,"4":4,"4p5":4.5,"5":5,"5p5":5.5,"5p75":5.75,"6":6,"6p5":6.5,"7":7,"8":8,"8p75":8.75,"9":9,"9p5":9.5,"10":10,"10p5":10.5,"11":11,"11p5":11.5,"12":12,"12p75":12.75,"13":13,"14":14}', // DST profiles - dst_off: 'My region doesn\'t use DST', + dst_off: 'My region doesn\'t observe DST', dst_usa: 'United States: second Sunday of March to first Sunday of November', dst_europe: 'Europe: last Sunday of March to last Sunday of October', dst_australia: 'Australia (except Tasmania): last Sunday of October to last Sunday of March', diff -r 1946d845bb25 -r 62fed244fa1c language/english/user.json --- a/language/english/user.json Sun Dec 21 04:24:52 2008 -0500 +++ b/language/english/user.json Sun Dec 21 04:26:56 2008 -0500 @@ -315,6 +315,8 @@ publicinfo_field_dst: 'Daylight saving time:', publicinfo_field_usertitle_title: 'User title:', publicinfo_field_usertitle_hint: 'This can be some text that will be displayed underneath your username.', + publicinfo_field_rank_title: 'Display rank:', + publicinfo_field_rank_hint: 'Select the rank you want to be shown with your username.', publicinfo_th_im: 'Instant messenger contact information', publicinfo_field_aim: 'AIM handle:', publicinfo_field_wlm: 'WLM handle:
If you don\'t specify the domain (@whatever.com), "@hotmail.com" will be assumed.', diff -r 1946d845bb25 -r 62fed244fa1c plugins/SpecialUserPrefs.php --- a/plugins/SpecialUserPrefs.php Sun Dec 21 04:24:52 2008 -0500 +++ b/plugins/SpecialUserPrefs.php Sun Dec 21 04:26:56 2008 -0500 @@ -155,6 +155,7 @@ global $db, $session, $paths, $template, $plugins; // Common objects global $lang; global $timezone; + global $cache; // We need a login to continue if ( !$session->user_logged_in ) @@ -468,6 +469,9 @@ echo ''; break; case "Profile": + $available_ranks = $session->get_user_possible_ranks($session->user_id); + $current_rank = $session->get_user_rank($session->user_id); + if ( isset($_POST['submit']) ) { $real_name = htmlspecialchars($_POST['real_name']); @@ -476,6 +480,12 @@ $timezone = intval($_POST['timezone']); $tz_local = $timezone + 1440; + $dst = $db->escape($_POST['dst']); + if ( !preg_match('/^[0-9]+;[0-9]+;[0-9]+;[0-9]+;[0-9]+$/', $dst) ) + $dst = '0;0;0;0;60'; + + $GLOBALS['dst_params'] = explode(';', $dst); + $imaddr_aim = htmlspecialchars($_POST['imaddr_aim']); $imaddr_aim = $db->escape($imaddr_aim); @@ -547,8 +557,36 @@ } $user_title_col = ", user_title = $colval"; } + $user_rank_col = ''; + if ( intval($_POST['user_rank']) != $current_rank['rank_id'] && count($available_ranks) > 1 ) + { + if ( $_POST['user_rank'] == 'NULL' ) + { + $user_rank_col = ", user_rank = NULL, user_rank_userset = 0"; + } + else + { + $new_rank = intval($_POST['user_rank']); + $rank_allowed = false; + foreach ( $available_ranks as $rank ) + { + if ( $rank['rank_id'] == $new_rank ) + { + $rank_allowed = true; + break; + } + } + if ( $rank_allowed ) + { + $user_rank_col = ", user_rank = $new_rank, user_rank_userset = 1"; + // hack + $current_rank['rank_id'] = $new_rank; + $cache->purge('ranks'); + } + } + } - $q = $db->sql_query('UPDATE '.table_prefix."users SET real_name='$real_name', user_timezone = $tz_local{$user_title_col} WHERE user_id=$session->user_id;"); + $q = $db->sql_query('UPDATE '.table_prefix."users SET real_name='$real_name', user_timezone = {$tz_local}, user_dst = '$dst'{$user_title_col}{$user_rank_col} WHERE user_id=$session->user_id;"); if ( !$q ) $db->_die(); @@ -571,6 +609,7 @@ $db->free_result(); // unload / reload $lang, this verifies that the selected language works + // enano should die a violent death if the language fails to load unset($GLOBALS['lang']); unset($lang); $lang_id = intval($lang_id); @@ -682,6 +721,29 @@ 1 ): + ?> + + + get('usercp_publicinfo_field_rank_title'); ?>
+ get('usercp_publicinfo_field_rank_hint'); ?> + + + + + + diff -r 1946d845bb25 -r 62fed244fa1c plugins/admin/UserManager.php --- a/plugins/admin/UserManager.php Sun Dec 21 04:24:52 2008 -0500 +++ b/plugins/admin/UserManager.php Sun Dec 21 04:26:56 2008 -0500 @@ -225,6 +225,11 @@ $to_update_users['user_rank'] = $user_rank; $to_update_users['user_title'] = $user_title; + if ( $user_rank > 0 ) + { + $to_update_users['user_rank_userset'] = '0'; + } + if ( isset($_POST['account_active']) ) { $to_update_users['account_active'] = "1";