plugins/admin/UserManager.php
changeset 1227 bdac73ed481e
parent 1175 1e2c9819ede3
child 1232 83fd4ed90cc6
--- a/plugins/admin/UserManager.php	Sun Mar 28 21:49:26 2010 -0400
+++ b/plugins/admin/UserManager.php	Sun Mar 28 23:10:46 2010 -0400
@@ -13,589 +13,589 @@
 
 function page_Admin_UserManager()
 {
-  global $db, $session, $paths, $template, $plugins; // Common objects
-  global $lang;
-  if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
-  {
-    $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true);
-    echo '<h3>' . $lang->get('adm_err_not_auth_title') . '</h3>';
-    echo '<p>' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '</p>';
-    return;
-  }
-  
-  require_once(ENANO_ROOT . '/includes/math.php');
-  require_once(ENANO_ROOT . '/includes/diffiehellman.php');
-  
-  $GLOBALS['dh_supported'] = $dh_supported;
-  
-  //die('<pre>' . htmlspecialchars(print_r($_POST, true)) . '</pre>');
-  
-  if ( isset($_POST['action']['save']) )
-  {
-    #
-    # BEGIN VALIDATION
-    #
-    
-    $errors = array();
-    
-    if ( defined('ENANO_DEMO_MODE') )
-    {
-      $errors[] = $lang->get('acpum_err_nosave_demo');
-    }
-    
-    $user_id = intval($_POST['user_id']);
-    if ( empty($user_id) || $user_id == 1 )
-      $errors[] = 'Invalid user ID.';
-    
-    if ( isset($_POST['delete_account']) && count($errors) < 1 )
-    {
-      $q = $db->sql_query('DELETE FROM '.table_prefix."users_extra WHERE user_id=$user_id;");
-      if ( !$q )
-        $db->_die();
-      $q = $db->sql_query('DELETE FROM '.table_prefix."users WHERE user_id=$user_id;");
-      if ( !$q )
-        $db->_die();
-      $q = $db->sql_query('DELETE FROM '.table_prefix."session_keys WHERE user_id=$user_id;");
-      if ( !$q )
-        $db->_die();
-      echo '<div class="info-box">' . $lang->get('acpum_msg_delete_success') . '</div>';
-      
-      // deleting own account?
-      if ( $user_id === $session->user_id )
-      {
-        // cute little hack to boot them out of the admin panel
-        echo '<script type="text/javascript">
-          addOnloadHook(function()
-          {
-            setTimeout(function()
-            {
-              eraseCookie("sid");
-              ENANO_SID = false;
-              auth_level = USER_LEVEL_MEMBER;
-              window.location = makeUrlNS("Special", "Login");
-            }, 3000);
-          });
-        </script>';
-      }
-    }
-    else
-    {
-      if ( $session->user_id == $user_id )
-      {
-        $username = $session->username;
-        $password = false;
-        $email = $session->email;
-        $real_name = $session->real_name;
-      }
-      else
-      {
-        $username = $_POST['username'];
-        if ( !preg_match('#^'.$session->valid_username.'$#', $username) )
-          $errors[] = $lang->get('acpum_err_illegal_username');
-        
-        $password = false;
-        if ( $_POST['changing_pw'] == 'yes' )
-        {
-          $password = $session->get_aes_post('new_password');
-        }
-        
-        $email = $_POST['email'];
-        if ( !preg_match('/^(?:[\w\d]+\.?)+@((?:(?:[\w\d]\-?)+\.)+\w{2,4}|localhost)$/', $email) )
-          $errors[] = $lang->get('acpum_err_illegal_email');
-        
-        $real_name = $_POST['real_name'];
-      }
-      
-      $signature = RenderMan::preprocess_text($_POST['signature'], true, false);
-      
-      $user_level = intval($_POST['user_level']);
-      if ( $user_level < USER_LEVEL_MEMBER || $user_level > USER_LEVEL_ADMIN )
-        $errors[] = 'Invalid user level';
-      
-      $user_rank = $_POST['user_rank'];
-      if ( $user_rank !== 'NULL' )
-      {
-        $user_rank = intval($user_rank);
-        if ( !$user_rank )
-          $errors[] = 'Invalid user rank';
-      }
-      
-      $imaddr_aim = htmlspecialchars($_POST['imaddr_aim']);
-      $imaddr_msn = htmlspecialchars($_POST['imaddr_msn']);
-      $imaddr_yahoo = htmlspecialchars($_POST['imaddr_yahoo']);
-      $imaddr_xmpp = htmlspecialchars($_POST['imaddr_xmpp']);
-      $homepage = htmlspecialchars($_POST['homepage']);
-      $location = htmlspecialchars($_POST['location']);
-      $occupation = htmlspecialchars($_POST['occupation']);
-      $hobbies = htmlspecialchars($_POST['hobbies']);
-      $email_public = ( isset($_POST['email_public']) ) ? '1' : '0';
-      $user_title = htmlspecialchars($_POST['user_title']);
-      
-      if ( !preg_match('/@([a-z0-9-]+)(\.([a-z0-9-\.]+))?/', $imaddr_msn) && !empty($imaddr_msn) )
-      {
-        $imaddr_msn = "$imaddr_msn@hotmail.com";
-      }
-      
-      if ( !preg_match('#^https?://#', $homepage) )
-      {
-        $homepage = "http://$homepage";
-      }
-      
-      if ( !preg_match('/^http:\/\/([a-z0-9-.]+)([A-z0-9@#\$%\&:;<>,\.\?=\+\(\)\[\]_\/\\\\]*?)$/i', $homepage) )
-      {
-        $homepage = '';
-      }
-      
-      // true for quiet operation
-      list(, , $avatar_post_fail) = avatar_post($user_id, true);
-      
-      if ( count($errors) < 1 && !$avatar_post_fail )
-      {
-        $q = $db->sql_query('SELECT u.user_level, u.user_has_avatar, u.avatar_type, u.username FROM '.table_prefix.'users AS u WHERE u.user_id = ' . $user_id . ';');
-        if ( !$q )
-          $db->_die();
-        
-        if ( $db->numrows() < 1 )
-        {
-          echo 'Couldn\'t select user data: no rows returned';
-        }
-        
-        $row = $db->fetchrow();
-        $existing_level =& $row['user_level'];
-        $avi_type =& $row['avatar_type'];
-        $has_avi = ( $row['user_has_avatar'] == 1 );
-        $old_username = $row['username'];
-        $db->free_result();
-        
-        $to_update_users = array();
-        if ( $user_id != $session->user_id )
-        {
-          $to_update_users['username'] = $username;
-          if ( $password )
-          {
-            $session->set_password($user_id, $password);
-          }
-          $to_update_users['email'] = $email;
-          $to_update_users['real_name'] = $real_name;
-        }
-        $to_update_users['signature'] = $signature;
-        $to_update_users['user_level'] = $user_level;
-        $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";
-        }
-        else
-        {
-          $to_update_users['account_active'] = "0";
-          $to_update_users['activation_key'] = sha1($session->dss_rand());
-        }
-        
-        if ( count($errors) < 1 )
-        {
-          $to_update_users_extra = array();
-          $to_update_users_extra['user_aim'] = $imaddr_aim;
-          $to_update_users_extra['user_msn'] = $imaddr_msn;
-          $to_update_users_extra['user_yahoo'] = $imaddr_yahoo;
-          $to_update_users_extra['user_xmpp'] = $imaddr_xmpp;
-          $to_update_users_extra['user_homepage'] = $homepage;
-          $to_update_users_extra['user_location'] = $location;
-          $to_update_users_extra['user_job'] = $occupation;
-          $to_update_users_extra['user_hobbies'] = $hobbies;
-          $to_update_users_extra['email_public'] = ( $email_public ) ? '1' : '0';
-          
-          $update_sql = '';
-          
-          foreach ( $to_update_users as $key => $unused_crap )
-          {
-            $value =& $to_update_users[$key];
-            if ( $value !== 'NULL' )
-              $value = "'" . $db->escape($value) . "'";
+	global $db, $session, $paths, $template, $plugins; // Common objects
+	global $lang;
+	if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
+	{
+		$login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true);
+		echo '<h3>' . $lang->get('adm_err_not_auth_title') . '</h3>';
+		echo '<p>' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '</p>';
+		return;
+	}
+	
+	require_once(ENANO_ROOT . '/includes/math.php');
+	require_once(ENANO_ROOT . '/includes/diffiehellman.php');
+	
+	$GLOBALS['dh_supported'] = $dh_supported;
+	
+	//die('<pre>' . htmlspecialchars(print_r($_POST, true)) . '</pre>');
+	
+	if ( isset($_POST['action']['save']) )
+	{
+		#
+		# BEGIN VALIDATION
+		#
+		
+		$errors = array();
+		
+		if ( defined('ENANO_DEMO_MODE') )
+		{
+			$errors[] = $lang->get('acpum_err_nosave_demo');
+		}
+		
+		$user_id = intval($_POST['user_id']);
+		if ( empty($user_id) || $user_id == 1 )
+			$errors[] = 'Invalid user ID.';
+		
+		if ( isset($_POST['delete_account']) && count($errors) < 1 )
+		{
+			$q = $db->sql_query('DELETE FROM '.table_prefix."users_extra WHERE user_id=$user_id;");
+			if ( !$q )
+				$db->_die();
+			$q = $db->sql_query('DELETE FROM '.table_prefix."users WHERE user_id=$user_id;");
+			if ( !$q )
+				$db->_die();
+			$q = $db->sql_query('DELETE FROM '.table_prefix."session_keys WHERE user_id=$user_id;");
+			if ( !$q )
+				$db->_die();
+			echo '<div class="info-box">' . $lang->get('acpum_msg_delete_success') . '</div>';
+			
+			// deleting own account?
+			if ( $user_id === $session->user_id )
+			{
+				// cute little hack to boot them out of the admin panel
+				echo '<script type="text/javascript">
+					addOnloadHook(function()
+					{
+						setTimeout(function()
+						{
+							eraseCookie("sid");
+							ENANO_SID = false;
+							auth_level = USER_LEVEL_MEMBER;
+							window.location = makeUrlNS("Special", "Login");
+						}, 3000);
+					});
+				</script>';
+			}
+		}
+		else
+		{
+			if ( $session->user_id == $user_id )
+			{
+				$username = $session->username;
+				$password = false;
+				$email = $session->email;
+				$real_name = $session->real_name;
+			}
+			else
+			{
+				$username = $_POST['username'];
+				if ( !preg_match('#^'.$session->valid_username.'$#', $username) )
+					$errors[] = $lang->get('acpum_err_illegal_username');
+				
+				$password = false;
+				if ( $_POST['changing_pw'] == 'yes' )
+				{
+					$password = $session->get_aes_post('new_password');
+				}
+				
+				$email = $_POST['email'];
+				if ( !preg_match('/^(?:[\w\d]+\.?)+@((?:(?:[\w\d]\-?)+\.)+\w{2,4}|localhost)$/', $email) )
+					$errors[] = $lang->get('acpum_err_illegal_email');
+				
+				$real_name = $_POST['real_name'];
+			}
+			
+			$signature = RenderMan::preprocess_text($_POST['signature'], true, false);
+			
+			$user_level = intval($_POST['user_level']);
+			if ( $user_level < USER_LEVEL_MEMBER || $user_level > USER_LEVEL_ADMIN )
+				$errors[] = 'Invalid user level';
+			
+			$user_rank = $_POST['user_rank'];
+			if ( $user_rank !== 'NULL' )
+			{
+				$user_rank = intval($user_rank);
+				if ( !$user_rank )
+					$errors[] = 'Invalid user rank';
+			}
+			
+			$imaddr_aim = htmlspecialchars($_POST['imaddr_aim']);
+			$imaddr_msn = htmlspecialchars($_POST['imaddr_msn']);
+			$imaddr_yahoo = htmlspecialchars($_POST['imaddr_yahoo']);
+			$imaddr_xmpp = htmlspecialchars($_POST['imaddr_xmpp']);
+			$homepage = htmlspecialchars($_POST['homepage']);
+			$location = htmlspecialchars($_POST['location']);
+			$occupation = htmlspecialchars($_POST['occupation']);
+			$hobbies = htmlspecialchars($_POST['hobbies']);
+			$email_public = ( isset($_POST['email_public']) ) ? '1' : '0';
+			$user_title = htmlspecialchars($_POST['user_title']);
+			
+			if ( !preg_match('/@([a-z0-9-]+)(\.([a-z0-9-\.]+))?/', $imaddr_msn) && !empty($imaddr_msn) )
+			{
+				$imaddr_msn = "$imaddr_msn@hotmail.com";
+			}
+			
+			if ( !preg_match('#^https?://#', $homepage) )
+			{
+				$homepage = "http://$homepage";
+			}
+			
+			if ( !preg_match('/^http:\/\/([a-z0-9-.]+)([A-z0-9@#\$%\&:;<>,\.\?=\+\(\)\[\]_\/\\\\]*?)$/i', $homepage) )
+			{
+				$homepage = '';
+			}
+			
+			// true for quiet operation
+			list(, , $avatar_post_fail) = avatar_post($user_id, true);
+			
+			if ( count($errors) < 1 && !$avatar_post_fail )
+			{
+				$q = $db->sql_query('SELECT u.user_level, u.user_has_avatar, u.avatar_type, u.username FROM '.table_prefix.'users AS u WHERE u.user_id = ' . $user_id . ';');
+				if ( !$q )
+					$db->_die();
+				
+				if ( $db->numrows() < 1 )
+				{
+					echo 'Couldn\'t select user data: no rows returned';
+				}
+				
+				$row = $db->fetchrow();
+				$existing_level =& $row['user_level'];
+				$avi_type =& $row['avatar_type'];
+				$has_avi = ( $row['user_has_avatar'] == 1 );
+				$old_username = $row['username'];
+				$db->free_result();
+				
+				$to_update_users = array();
+				if ( $user_id != $session->user_id )
+				{
+					$to_update_users['username'] = $username;
+					if ( $password )
+					{
+						$session->set_password($user_id, $password);
+					}
+					$to_update_users['email'] = $email;
+					$to_update_users['real_name'] = $real_name;
+				}
+				$to_update_users['signature'] = $signature;
+				$to_update_users['user_level'] = $user_level;
+				$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";
+				}
+				else
+				{
+					$to_update_users['account_active'] = "0";
+					$to_update_users['activation_key'] = sha1($session->dss_rand());
+				}
+				
+				if ( count($errors) < 1 )
+				{
+					$to_update_users_extra = array();
+					$to_update_users_extra['user_aim'] = $imaddr_aim;
+					$to_update_users_extra['user_msn'] = $imaddr_msn;
+					$to_update_users_extra['user_yahoo'] = $imaddr_yahoo;
+					$to_update_users_extra['user_xmpp'] = $imaddr_xmpp;
+					$to_update_users_extra['user_homepage'] = $homepage;
+					$to_update_users_extra['user_location'] = $location;
+					$to_update_users_extra['user_job'] = $occupation;
+					$to_update_users_extra['user_hobbies'] = $hobbies;
+					$to_update_users_extra['email_public'] = ( $email_public ) ? '1' : '0';
+					
+					$update_sql = '';
+					
+					foreach ( $to_update_users as $key => $unused_crap )
+					{
+						$value =& $to_update_users[$key];
+						if ( $value !== 'NULL' )
+							$value = "'" . $db->escape($value) . "'";
  
-            $update_sql .= ( empty($update_sql) ? '' : ',' ) . "$key=$value";
-          }
-          
-          $update_sql = 'UPDATE ' . table_prefix . "users SET $update_sql WHERE user_id=$user_id;";
-          
-          $update_sql_extra = '';
-          
-          foreach ( $to_update_users_extra as $key => $unused_crap )
-          {
-            $value =& $to_update_users_extra[$key];
-            $value = $db->escape($value);
-            $update_sql_extra .= ( empty($update_sql_extra) ? '' : ',' ) . "$key='$value'";
-          }
-          
-          $update_sql_extra = 'UPDATE '.table_prefix."users_extra SET $update_sql_extra WHERE user_id=$user_id;";
-          
-          if ( !$db->sql_query($update_sql) )
-            $db->_die();
-          
-          if ( !$db->sql_query($update_sql_extra) )
-            $db->_die();
-          
-          // If the username was changed, we need to update their user page as well
-          if ( $old_username != $username )
-          {
-            $page = new PageProcessor($old_username, 'User');
-            if ( $page->exists() )
-            {
-              // they have a user page, rename it
-              $old_urlname = $db->escape(sanitize_page_id($old_username));
-              $new_urlname = $db->escape(sanitize_page_id($username));
-              $sql = array(
-                      'UPDATE ' . table_prefix . "pages      SET urlname = '$new_urlname' WHERE urlname = '$old_urlname' AND namespace = 'User';",
-                      // Change the page's title ONLY if it exactly matches the old username
-                      'UPDATE ' . table_prefix . "pages      SET name = '" . $db->escape($username) . "' WHERE urlname = '$new_urlname' AND name = '" . $db->escape($old_username) . "' AND namespace = 'User';",
-                      'UPDATE ' . table_prefix . "logs       SET page_id = '$new_urlname' WHERE page_id = '$old_urlname' AND namespace = 'User';",
-                      'UPDATE ' . table_prefix . "tags       SET page_id = '$new_urlname' WHERE page_id = '$old_urlname' AND namespace = 'User';",
-                      'UPDATE ' . table_prefix . "comments   SET page_id = '$new_urlname' WHERE page_id = '$old_urlname' AND namespace = 'User';",
-                      'UPDATE ' . table_prefix . "page_text  SET page_id = '$new_urlname' WHERE page_id = '$old_urlname' AND namespace = 'User';",
-                      'UPDATE ' . table_prefix . "categories SET page_id = '$new_urlname' WHERE page_id = '$old_urlname' AND namespace = 'User';"
-                    );
-              foreach ( $sql as $q )
-              {
-                if ( !$db->sql_query($q) )
-                  $db->_die('UserManager renaming user page post-username change');
-              }
-            }
-          }
-          
-          if ( $existing_level != $user_level )
-          {
-            // We need to update group memberships
-            if ( $existing_level == USER_LEVEL_ADMIN ) 
-            {
-              $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,author_uid,page_text) VALUES(\'security\',\'u_from_admin\',' . time() . ', \'' . $db->escape($_SERVER['REMOTE_ADDR']) . '\', ' . $session->user_id . ', \'' . $db->escape($session->username) . '\', \'' . $db->escape($username) . '\');');
-              if ( !$q )
-                $db->_die();
-              $session->remove_user_from_group($user_id, GROUP_ID_ADMIN);
-            }
-            else if ( $existing_level == USER_LEVEL_MOD ) 
-            {
-              $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,author_uid,page_text) VALUES(\'security\',\'u_from_mod\',' . time() . ', \'' . $db->escape($_SERVER['REMOTE_ADDR']) . '\', ' . $session->user_id . ', \'' . $db->escape($session->username) . '\', \'' . $db->escape($username) . '\');');
-              if ( !$q )
-                $db->_die();
-              $session->remove_user_from_group($user_id, GROUP_ID_MOD);
-            }
-            
-            if ( $user_level == USER_LEVEL_ADMIN )
-            {
-              $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,author_uid,page_text) VALUES(\'security\',\'u_to_admin\',' . time() . ', \'' . $db->escape($_SERVER['REMOTE_ADDR']) . '\', ' . $session->user_id . ', \'' . $db->escape($session->username) . '\', \'' . $db->escape($username) . '\');');
-              if ( !$q )
-                $db->_die();
-              $session->add_user_to_group($user_id, GROUP_ID_ADMIN, false);
-            }
-            else if ( $user_level == USER_LEVEL_MOD )
-            {
-              $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,author_uid,page_text) VALUES(\'security\',\'u_to_mod\',' . time() . ', \'' . $db->escape($_SERVER['REMOTE_ADDR']) . '\', ' . $session->user_id . ', \'' . $db->escape($session->username) . '\', \'' . $db->escape($username) . '\');');
-              if ( !$q )
-                $db->_die();
-              $session->add_user_to_group($user_id, GROUP_ID_MOD, false);
-            }
-          }
-          
-          // user level updated, regenerate the ranks cache
-          generate_cache_userranks();
-          
-          echo '<div class="info-box">' . $lang->get('acpum_msg_save_success') . '</div>';
-        }
-      }
-    }
-    
-    if ( count($errors) > 0 || @$avatar_post_fail )
-    {
-      if ( count($errors) > 0 )
-      {
-        echo '<div class="error-box">
-                <b>' . $lang->get('acpum_err_validation_fail') . '</b>
-                <ul>
-                  <li>' . implode("</li>\n        <li>", $errors) . '</li>
-                </ul>
-              </div>';
-      }
-      $form = new Admin_UserManager_SmartForm();
-      $form->user_id = $user_id;
-      $form->username = $username;
-      $form->email = $email;
-      $form->real_name = $real_name;
-      $form->signature = $signature;
-      $form->user_level = $user_level;
-      $form->user_rank = $user_rank;
-      $form->user_title = $user_title;
-      $form->im = array(
-          'aim' => $imaddr_aim,
-          'yahoo' => $imaddr_yahoo,
-          'msn' => $imaddr_msn,
-          'xmpp' => $imaddr_xmpp
-        );
-      $form->contact = array(
-          'homepage' => $homepage,
-          'location' => $location,
-          'job' => $occupation,
-          'hobbies' => $hobbies
-        );
-      $form->email_public = ( isset($_POST['email_public']) );
-      $form->account_active = ( isset($_POST['account_active']) );
-      // This is SAFE. The smartform calls is_valid_ip() on this value, thus preventing XSS
-      // attempts from making it into the form HTML. Badly coded templates may still be
-      // affected, but if have_reg_ip is checked for, then you're fine.
-      $form->reg_ip_addr = $_POST['user_registration_ip'];
-      echo $form->render();
-      return false;
-    }
-    
-    #
-    # END VALIDATION
-    #
-  }
-  else if ( isset($_POST['action']['go']) || ( isset($_GET['src']) && $_GET['src'] == 'get' ) || ($pathsuser = $paths->getParam(0)) )
-  {
-    if ( isset($_GET['user']) )
-    {
-      $username =& $_GET['user'];
-    }
-    else if ( isset($_GET['username']) )
-    {
-      $username =& $_GET['username'];
-    }
-    else if ( isset($_POST['username']) )
-    {
-      $username =& $_POST['username'];
-    }
-    else if ( $pathsuser )
-    {
-      $username = str_replace('_', ' ', dirtify_page_id($pathsuser));
-    }
-    else
-    {
-      echo 'No username provided';
-      return false;
-    }
-    $q = $db->sql_query('SELECT u.user_id AS authoritative_uid, u.username, u.email, u.real_name, u.signature, u.account_active, u.user_level, u.user_rank, u.user_title, u.user_has_avatar, u.avatar_type, u.user_registration_ip, x.* FROM '.table_prefix.'users AS u
-                           LEFT JOIN '.table_prefix.'users_extra AS x
-                             ON ( u.user_id = x.user_id OR x.user_id IS NULL )
-                           WHERE ( ' . ENANO_SQLFUNC_LOWERCASE . '(u.username) = \'' . $db->escape(strtolower($username)) . '\' OR u.username = \'' . $db->escape($username) . '\' ) AND u.user_id != 1;');
-    if ( !$q )
-      $db->_die();
-    
-    if ( $db->numrows() < 1 )
-    {
-      echo '<div class="error-box">' . $lang->get('acpum_err_bad_username') . '</div>';
-    }
-    else
-    {
-      $row = $db->fetchrow();
-      $row['user_id'] = $row['authoritative_uid'];
-      $form = new Admin_UserManager_SmartForm();
-      $form->user_id   = $row['user_id'];
-      $form->username  = $row['username'];
-      $form->email     = $row['email'];
-      $form->real_name = $row['real_name'];
-      $form->signature = $row['signature'];
-      $form->user_level= $row['user_level'];
-      $form->user_rank = $row['user_rank'];
-      $form->user_title= $row['user_title'];
-      $form->account_active = ( $row['account_active'] == 1 );
-      $form->email_public   = ( $row['email_public'] == 1 );
-      $form->has_avatar     = ( $row['user_has_avatar'] == 1 );
-      $form->avi_type       = $row['avatar_type'];
-      $form->im = array(
-          'aim' => $row['user_aim'],
-          'yahoo' => $row['user_yahoo'],
-          'msn' => $row['user_msn'],
-          'xmpp' => $row['user_xmpp']
-        );
-      $form->contact = array(
-          'homepage' => $row['user_homepage'],
-          'location' => $row['user_location'],
-          'job'      => $row['user_job'],
-          'hobbies'  => $row['user_hobbies'],
-        );
-      $form->email_public = ( $row['email_public'] == 1 );
-      $form->reg_ip_addr = ( $row['user_registration_ip'] ) ? $row['user_registration_ip'] : '';
-      $html = $form->render();
-      if ( !$html )
-      {
-        echo 'Internal error: form processor returned false';
-      }
-      else
-      {
-        echo $html;
-      }
-      return true;
-    }
-  }
-  else if ( isset($_POST['action']['clear_sessions']) )
-  {
-    if ( defined('ENANO_DEMO_MODE') )
-    {
-      echo '<div class="error-box">' . $lang->get('acpum_err_sessionclear_demo') . '</div>';
-    }
-    else
-    {
-      // Get the current session information so the user doesn't get logged out
-      $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE);
-      $sk = md5($session->sid_super);
-      $qb = $db->sql_query('SELECT session_key,salt,auth_level,source_ip,time FROM '.table_prefix.'session_keys WHERE session_key=\''.$sk.'\' AND user_id='.$session->user_id.' AND auth_level='.USER_LEVEL_ADMIN);
-      if ( !$qb )
-      {
-        die('Error selecting session key info block B: '.$db->get_error());
-      }
-      if ( $db->numrows($qb) < 1 )
-      {
-        die('Error: cannot read admin session info block B, aborting table clear process');
-      }
-      $qa = $db->sql_query('SELECT session_key,salt,auth_level,source_ip,time FROM '.table_prefix.'session_keys WHERE session_key=\''.md5($session->sid).'\' AND user_id='.$session->user_id.' AND auth_level='.USER_LEVEL_MEMBER);
-      if ( !$qa )
-      {
-        die('Error selecting session key info block A: '.$db->get_error());
-      }
-      if ( $db->numrows($qa) < 1 )
-      {
-        die('Error: cannot read user session info block A, aborting table clear process');
-      }
-      $ra = $db->fetchrow($qa);
-      $rb = $db->fetchrow($qb);
-      $db->free_result($qa);
-      $db->free_result($qb);
-      
-      $db->sql_query('DELETE FROM '.table_prefix.'session_keys;');
-      $db->sql_query('INSERT INTO '.table_prefix.'session_keys( session_key,salt,user_id,auth_level,source_ip,time ) VALUES( \''.$ra['session_key'].'\', \'' . $db->escape($ra['salt']) . '\', \''.$session->user_id.'\', \''.$ra['auth_level'].'\', \''.$ra['source_ip'].'\', '.$ra['time'].' ),( \''.$rb['session_key'].'\', \'' . $db->escape($rb['salt']) . '\', \''.$session->user_id.'\', \''.$rb['auth_level'].'\', \''.$rb['source_ip'].'\', '.$rb['time'].' )');
-      
-      echo '<div class="info-box">' . $lang->get('acpum_msg_sessionclear_success') . '</div>';
-    }
-  }
-  echo '<form action="' . makeUrlNS('Special', 'Administration', 'module=' . $paths->cpage['module'], true) . '" method="post" enctype="multipart/form-data" onsubmit="if ( !submitAuthorized ) return false;">';
-  echo '<h3>' . $lang->get('acpum_heading_main') . '</h3>';
-  echo '<p>' . $lang->get('acpum_hint_intro') . '</p>';
-  echo '<table border="0">
-          <tr>
-            <td><b>' . $lang->get('acpum_field_search_user') . '</b><br />
-                <small>' . $lang->get('acpum_field_search_user_hint') . '</small>
-                </td>
-            <td style="width: 10px;"></td>
-            <td>' . $template->username_field('username') . '</td>
-            <td>
-              <input type="submit" name="action[go]" value="' . $lang->get('acpum_btn_search_user_go') . ' &raquo;" />
-            </td>
-          </tr>
-        </table>';
-  echo '<h3>' . $lang->get('acpum_heading_clear_sessions') . '</h3>';
-  echo '<p>' . $lang->get('acpum_hint_clear_sessions') . '</p>';
-  echo '<p><input type="submit" name="action[clear_sessions]" value="' . $lang->get('acpum_btn_clear_sessions') . '" /></p>';
-  echo '</form>';
-  
-  if(isset($_GET['action']) && isset($_GET['user']))
-  {
-    switch($_GET['action'])
-    {
-      case "activate":
-        $e = $db->sql_query('SELECT activation_key FROM '.table_prefix.'users WHERE username=\'' . $db->escape($_GET['user']) . '\'');
-        if ( $e )
-        {
-          // attempt to activate the account
-          $row = $db->fetchrow();
-          $db->free_result();
-          if ( $session->activate_account($_GET['user'], $row['activation_key']) )
-          {
-            echo '<div class="info-box">' . $lang->get('acpum_msg_activate_success', array('username' => htmlspecialchars($_GET['user']))) . '</div>';
-            $db->sql_query('DELETE FROM '.table_prefix.'logs WHERE time_id=' . $db->escape($_GET['logid']));
-          }
-          else
-          {
-            echo '<div class="warning-box">' . $lang->get('acpum_err_activate_fail', array('username' => htmlspecialchars($_GET['user']))) . '</div>';
-          }
-        }
-        else
-        {
-          echo '<div class="error-box">Error activating account: '.$db->get_error().'</div>';
-        }
-        break;
-      case "sendemail":
-        if ( $session->send_activation_mail($_GET['user'] ) )
-        {
-          echo '<div class="info-box">' . $lang->get('acpum_msg_activate_email_success', array('username' => htmlspecialchars($_GET['user']))) . '</div>';
-          $db->sql_query('DELETE FROM '.table_prefix.'logs WHERE time_id=' . $db->escape($_GET['logid']));
-        }
-        else
-        {
-          echo '<div class="error-box">' . $lang->get('acpum_err_activate_email_fail', array('username' => htmlspecialchars($_GET['user']))) . '</div>';
-        }
-        break;
-      case "deny":
-        $e = $db->sql_query('DELETE FROM '.table_prefix.'logs WHERE log_type=\'admin\' AND action=\'activ_req\' AND time_id=\'' . $db->escape($_GET['logid']) . '\';');
-        if ( !$e )
-        {
-          echo '<div class="error-box">Error during row deletion: '.$db->get_error().'</div>';
-        }
-        else
-        {
-          echo '<div class="info-box">' . $lang->get('acpum_msg_activate_deny_success', array('username' => htmlspecialchars($_GET['user']))) . '</div>';
-        }
-        break;
-    }
-  }
-  $q = $db->sql_query('SELECT l.log_type, l.action, l.time_id, l.date_string, l.author, l.edit_summary, u.user_coppa FROM '.table_prefix.'logs AS l
-                         LEFT JOIN '.table_prefix.'users AS u
-                           ON ( u.username = l.edit_summary OR u.username IS NULL )
-                         WHERE log_type=\'admin\' AND action=\'activ_req\' ORDER BY time_id DESC;');
-  if($q)
-  {
-    if($db->numrows() > 0)
-    {
-      $n = $db->numrows();
-      $str = ( $n == 1 ) ?
-        $lang->get('acpum_heading_activation_one') :
-        $lang->get('acpum_heading_activation_plural', array('count' => strval($n)));
-        
-      echo '<h3>' . $str . '</h3>';
-        
-      echo '<div class="tblholder">
-              <table border="0" cellspacing="1" cellpadding="4" width="100%">
-                <tr>
-                  <th>' . $lang->get('acpum_col_activate_timestamp') . '</th>
-                  <th>' . $lang->get('acpum_col_activate_requestedby') . '</th>
-                  <th>' . $lang->get('acpum_col_activate_requestedfor') . '</th>
-                  <th>' . $lang->get('acpum_col_activate_coppauser') . '</th>
-                  <th colspan="3">' . $lang->get('acpum_col_activate_actions') . '</th>
-                </tr>';
-      $cls = 'row2';
-      while($row = $db->fetchrow())
-      {
-        if($cls == 'row2') $cls = 'row1';
-        else $cls = 'row2';
-        $coppa = ( $row['user_coppa'] == '1' ) ? '<b>' . $lang->get('acpum_coppauser_yes') . '</b>' : $lang->get('acpum_coppauser_no');
-        echo '<tr>
-                <td class="'.$cls.'">'.enano_date(ED_DATE | ED_TIME, $row['time_id']).'</td>
-                <td class="'.$cls.'">'.$row['author'].'</td>
-                <td class="'.$cls.'">'.$row['edit_summary'].'</td>
-                <td style="text-align: center;" class="' . $cls . '">' . $coppa . '</td>
-                <td class="'.$cls.'" style="text-align: center;">
-                  <a href="'.makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'UserManager&action=activate&user='.rawurlencode($row['edit_summary']).'&logid='.$row['time_id'], true).'">' . $lang->get('acpum_btn_activate_now') . '</a>
-                </td>
-                <td class="'.$cls.'" style="text-align: center;">
-                  <a href="'.makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'UserManager&action=sendemail&user='.rawurlencode($row['edit_summary']).'&logid='.$row['time_id'], true).'">' . $lang->get('acpum_btn_send_email') . '</a>
-                </td>
-                <td class="'.$cls.'" style="text-align: center;">
-                  <a href="'.makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'UserManager&action=deny&user='.rawurlencode($row['edit_summary']).'&logid='.$row['time_id'], true).'">' . $lang->get('acpum_btn_activate_deny') . '</a>
-                </td>
-              </tr>';
-      }
-      echo '</table>';
-      echo '</div>';
-    }
-    $db->free_result();
-  }
-  
-  acp_usermanager_lockouts();
+						$update_sql .= ( empty($update_sql) ? '' : ',' ) . "$key=$value";
+					}
+					
+					$update_sql = 'UPDATE ' . table_prefix . "users SET $update_sql WHERE user_id=$user_id;";
+					
+					$update_sql_extra = '';
+					
+					foreach ( $to_update_users_extra as $key => $unused_crap )
+					{
+						$value =& $to_update_users_extra[$key];
+						$value = $db->escape($value);
+						$update_sql_extra .= ( empty($update_sql_extra) ? '' : ',' ) . "$key='$value'";
+					}
+					
+					$update_sql_extra = 'UPDATE '.table_prefix."users_extra SET $update_sql_extra WHERE user_id=$user_id;";
+					
+					if ( !$db->sql_query($update_sql) )
+						$db->_die();
+					
+					if ( !$db->sql_query($update_sql_extra) )
+						$db->_die();
+					
+					// If the username was changed, we need to update their user page as well
+					if ( $old_username != $username )
+					{
+						$page = new PageProcessor($old_username, 'User');
+						if ( $page->exists() )
+						{
+							// they have a user page, rename it
+							$old_urlname = $db->escape(sanitize_page_id($old_username));
+							$new_urlname = $db->escape(sanitize_page_id($username));
+							$sql = array(
+											'UPDATE ' . table_prefix . "pages      SET urlname = '$new_urlname' WHERE urlname = '$old_urlname' AND namespace = 'User';",
+											// Change the page's title ONLY if it exactly matches the old username
+											'UPDATE ' . table_prefix . "pages      SET name = '" . $db->escape($username) . "' WHERE urlname = '$new_urlname' AND name = '" . $db->escape($old_username) . "' AND namespace = 'User';",
+											'UPDATE ' . table_prefix . "logs       SET page_id = '$new_urlname' WHERE page_id = '$old_urlname' AND namespace = 'User';",
+											'UPDATE ' . table_prefix . "tags       SET page_id = '$new_urlname' WHERE page_id = '$old_urlname' AND namespace = 'User';",
+											'UPDATE ' . table_prefix . "comments   SET page_id = '$new_urlname' WHERE page_id = '$old_urlname' AND namespace = 'User';",
+											'UPDATE ' . table_prefix . "page_text  SET page_id = '$new_urlname' WHERE page_id = '$old_urlname' AND namespace = 'User';",
+											'UPDATE ' . table_prefix . "categories SET page_id = '$new_urlname' WHERE page_id = '$old_urlname' AND namespace = 'User';"
+										);
+							foreach ( $sql as $q )
+							{
+								if ( !$db->sql_query($q) )
+									$db->_die('UserManager renaming user page post-username change');
+							}
+						}
+					}
+					
+					if ( $existing_level != $user_level )
+					{
+						// We need to update group memberships
+						if ( $existing_level == USER_LEVEL_ADMIN ) 
+						{
+							$q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,author_uid,page_text) VALUES(\'security\',\'u_from_admin\',' . time() . ', \'' . $db->escape($_SERVER['REMOTE_ADDR']) . '\', ' . $session->user_id . ', \'' . $db->escape($session->username) . '\', \'' . $db->escape($username) . '\');');
+							if ( !$q )
+								$db->_die();
+							$session->remove_user_from_group($user_id, GROUP_ID_ADMIN);
+						}
+						else if ( $existing_level == USER_LEVEL_MOD ) 
+						{
+							$q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,author_uid,page_text) VALUES(\'security\',\'u_from_mod\',' . time() . ', \'' . $db->escape($_SERVER['REMOTE_ADDR']) . '\', ' . $session->user_id . ', \'' . $db->escape($session->username) . '\', \'' . $db->escape($username) . '\');');
+							if ( !$q )
+								$db->_die();
+							$session->remove_user_from_group($user_id, GROUP_ID_MOD);
+						}
+						
+						if ( $user_level == USER_LEVEL_ADMIN )
+						{
+							$q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,author_uid,page_text) VALUES(\'security\',\'u_to_admin\',' . time() . ', \'' . $db->escape($_SERVER['REMOTE_ADDR']) . '\', ' . $session->user_id . ', \'' . $db->escape($session->username) . '\', \'' . $db->escape($username) . '\');');
+							if ( !$q )
+								$db->_die();
+							$session->add_user_to_group($user_id, GROUP_ID_ADMIN, false);
+						}
+						else if ( $user_level == USER_LEVEL_MOD )
+						{
+							$q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,author_uid,page_text) VALUES(\'security\',\'u_to_mod\',' . time() . ', \'' . $db->escape($_SERVER['REMOTE_ADDR']) . '\', ' . $session->user_id . ', \'' . $db->escape($session->username) . '\', \'' . $db->escape($username) . '\');');
+							if ( !$q )
+								$db->_die();
+							$session->add_user_to_group($user_id, GROUP_ID_MOD, false);
+						}
+					}
+					
+					// user level updated, regenerate the ranks cache
+					generate_cache_userranks();
+					
+					echo '<div class="info-box">' . $lang->get('acpum_msg_save_success') . '</div>';
+				}
+			}
+		}
+		
+		if ( count($errors) > 0 || @$avatar_post_fail )
+		{
+			if ( count($errors) > 0 )
+			{
+				echo '<div class="error-box">
+								<b>' . $lang->get('acpum_err_validation_fail') . '</b>
+								<ul>
+									<li>' . implode("</li>\n        <li>", $errors) . '</li>
+								</ul>
+							</div>';
+			}
+			$form = new Admin_UserManager_SmartForm();
+			$form->user_id = $user_id;
+			$form->username = $username;
+			$form->email = $email;
+			$form->real_name = $real_name;
+			$form->signature = $signature;
+			$form->user_level = $user_level;
+			$form->user_rank = $user_rank;
+			$form->user_title = $user_title;
+			$form->im = array(
+					'aim' => $imaddr_aim,
+					'yahoo' => $imaddr_yahoo,
+					'msn' => $imaddr_msn,
+					'xmpp' => $imaddr_xmpp
+				);
+			$form->contact = array(
+					'homepage' => $homepage,
+					'location' => $location,
+					'job' => $occupation,
+					'hobbies' => $hobbies
+				);
+			$form->email_public = ( isset($_POST['email_public']) );
+			$form->account_active = ( isset($_POST['account_active']) );
+			// This is SAFE. The smartform calls is_valid_ip() on this value, thus preventing XSS
+			// attempts from making it into the form HTML. Badly coded templates may still be
+			// affected, but if have_reg_ip is checked for, then you're fine.
+			$form->reg_ip_addr = $_POST['user_registration_ip'];
+			echo $form->render();
+			return false;
+		}
+		
+		#
+		# END VALIDATION
+		#
+	}
+	else if ( isset($_POST['action']['go']) || ( isset($_GET['src']) && $_GET['src'] == 'get' ) || ($pathsuser = $paths->getParam(0)) )
+	{
+		if ( isset($_GET['user']) )
+		{
+			$username =& $_GET['user'];
+		}
+		else if ( isset($_GET['username']) )
+		{
+			$username =& $_GET['username'];
+		}
+		else if ( isset($_POST['username']) )
+		{
+			$username =& $_POST['username'];
+		}
+		else if ( $pathsuser )
+		{
+			$username = str_replace('_', ' ', dirtify_page_id($pathsuser));
+		}
+		else
+		{
+			echo 'No username provided';
+			return false;
+		}
+		$q = $db->sql_query('SELECT u.user_id AS authoritative_uid, u.username, u.email, u.real_name, u.signature, u.account_active, u.user_level, u.user_rank, u.user_title, u.user_has_avatar, u.avatar_type, u.user_registration_ip, x.* FROM '.table_prefix.'users AS u
+ 													LEFT JOIN '.table_prefix.'users_extra AS x
+ 														ON ( u.user_id = x.user_id OR x.user_id IS NULL )
+ 													WHERE ( ' . ENANO_SQLFUNC_LOWERCASE . '(u.username) = \'' . $db->escape(strtolower($username)) . '\' OR u.username = \'' . $db->escape($username) . '\' ) AND u.user_id != 1;');
+		if ( !$q )
+			$db->_die();
+		
+		if ( $db->numrows() < 1 )
+		{
+			echo '<div class="error-box">' . $lang->get('acpum_err_bad_username') . '</div>';
+		}
+		else
+		{
+			$row = $db->fetchrow();
+			$row['user_id'] = $row['authoritative_uid'];
+			$form = new Admin_UserManager_SmartForm();
+			$form->user_id   = $row['user_id'];
+			$form->username  = $row['username'];
+			$form->email     = $row['email'];
+			$form->real_name = $row['real_name'];
+			$form->signature = $row['signature'];
+			$form->user_level= $row['user_level'];
+			$form->user_rank = $row['user_rank'];
+			$form->user_title= $row['user_title'];
+			$form->account_active = ( $row['account_active'] == 1 );
+			$form->email_public   = ( $row['email_public'] == 1 );
+			$form->has_avatar     = ( $row['user_has_avatar'] == 1 );
+			$form->avi_type       = $row['avatar_type'];
+			$form->im = array(
+					'aim' => $row['user_aim'],
+					'yahoo' => $row['user_yahoo'],
+					'msn' => $row['user_msn'],
+					'xmpp' => $row['user_xmpp']
+				);
+			$form->contact = array(
+					'homepage' => $row['user_homepage'],
+					'location' => $row['user_location'],
+					'job'      => $row['user_job'],
+					'hobbies'  => $row['user_hobbies'],
+				);
+			$form->email_public = ( $row['email_public'] == 1 );
+			$form->reg_ip_addr = ( $row['user_registration_ip'] ) ? $row['user_registration_ip'] : '';
+			$html = $form->render();
+			if ( !$html )
+			{
+				echo 'Internal error: form processor returned false';
+			}
+			else
+			{
+				echo $html;
+			}
+			return true;
+		}
+	}
+	else if ( isset($_POST['action']['clear_sessions']) )
+	{
+		if ( defined('ENANO_DEMO_MODE') )
+		{
+			echo '<div class="error-box">' . $lang->get('acpum_err_sessionclear_demo') . '</div>';
+		}
+		else
+		{
+			// Get the current session information so the user doesn't get logged out
+			$aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE);
+			$sk = md5($session->sid_super);
+			$qb = $db->sql_query('SELECT session_key,salt,auth_level,source_ip,time FROM '.table_prefix.'session_keys WHERE session_key=\''.$sk.'\' AND user_id='.$session->user_id.' AND auth_level='.USER_LEVEL_ADMIN);
+			if ( !$qb )
+			{
+				die('Error selecting session key info block B: '.$db->get_error());
+			}
+			if ( $db->numrows($qb) < 1 )
+			{
+				die('Error: cannot read admin session info block B, aborting table clear process');
+			}
+			$qa = $db->sql_query('SELECT session_key,salt,auth_level,source_ip,time FROM '.table_prefix.'session_keys WHERE session_key=\''.md5($session->sid).'\' AND user_id='.$session->user_id.' AND auth_level='.USER_LEVEL_MEMBER);
+			if ( !$qa )
+			{
+				die('Error selecting session key info block A: '.$db->get_error());
+			}
+			if ( $db->numrows($qa) < 1 )
+			{
+				die('Error: cannot read user session info block A, aborting table clear process');
+			}
+			$ra = $db->fetchrow($qa);
+			$rb = $db->fetchrow($qb);
+			$db->free_result($qa);
+			$db->free_result($qb);
+			
+			$db->sql_query('DELETE FROM '.table_prefix.'session_keys;');
+			$db->sql_query('INSERT INTO '.table_prefix.'session_keys( session_key,salt,user_id,auth_level,source_ip,time ) VALUES( \''.$ra['session_key'].'\', \'' . $db->escape($ra['salt']) . '\', \''.$session->user_id.'\', \''.$ra['auth_level'].'\', \''.$ra['source_ip'].'\', '.$ra['time'].' ),( \''.$rb['session_key'].'\', \'' . $db->escape($rb['salt']) . '\', \''.$session->user_id.'\', \''.$rb['auth_level'].'\', \''.$rb['source_ip'].'\', '.$rb['time'].' )');
+			
+			echo '<div class="info-box">' . $lang->get('acpum_msg_sessionclear_success') . '</div>';
+		}
+	}
+	echo '<form action="' . makeUrlNS('Special', 'Administration', 'module=' . $paths->cpage['module'], true) . '" method="post" enctype="multipart/form-data" onsubmit="if ( !submitAuthorized ) return false;">';
+	echo '<h3>' . $lang->get('acpum_heading_main') . '</h3>';
+	echo '<p>' . $lang->get('acpum_hint_intro') . '</p>';
+	echo '<table border="0">
+					<tr>
+						<td><b>' . $lang->get('acpum_field_search_user') . '</b><br />
+								<small>' . $lang->get('acpum_field_search_user_hint') . '</small>
+								</td>
+						<td style="width: 10px;"></td>
+						<td>' . $template->username_field('username') . '</td>
+						<td>
+							<input type="submit" name="action[go]" value="' . $lang->get('acpum_btn_search_user_go') . ' &raquo;" />
+						</td>
+					</tr>
+				</table>';
+	echo '<h3>' . $lang->get('acpum_heading_clear_sessions') . '</h3>';
+	echo '<p>' . $lang->get('acpum_hint_clear_sessions') . '</p>';
+	echo '<p><input type="submit" name="action[clear_sessions]" value="' . $lang->get('acpum_btn_clear_sessions') . '" /></p>';
+	echo '</form>';
+	
+	if(isset($_GET['action']) && isset($_GET['user']))
+	{
+		switch($_GET['action'])
+		{
+			case "activate":
+				$e = $db->sql_query('SELECT activation_key FROM '.table_prefix.'users WHERE username=\'' . $db->escape($_GET['user']) . '\'');
+				if ( $e )
+				{
+					// attempt to activate the account
+					$row = $db->fetchrow();
+					$db->free_result();
+					if ( $session->activate_account($_GET['user'], $row['activation_key']) )
+					{
+						echo '<div class="info-box">' . $lang->get('acpum_msg_activate_success', array('username' => htmlspecialchars($_GET['user']))) . '</div>';
+						$db->sql_query('DELETE FROM '.table_prefix.'logs WHERE time_id=' . $db->escape($_GET['logid']));
+					}
+					else
+					{
+						echo '<div class="warning-box">' . $lang->get('acpum_err_activate_fail', array('username' => htmlspecialchars($_GET['user']))) . '</div>';
+					}
+				}
+				else
+				{
+					echo '<div class="error-box">Error activating account: '.$db->get_error().'</div>';
+				}
+				break;
+			case "sendemail":
+				if ( $session->send_activation_mail($_GET['user'] ) )
+				{
+					echo '<div class="info-box">' . $lang->get('acpum_msg_activate_email_success', array('username' => htmlspecialchars($_GET['user']))) . '</div>';
+					$db->sql_query('DELETE FROM '.table_prefix.'logs WHERE time_id=' . $db->escape($_GET['logid']));
+				}
+				else
+				{
+					echo '<div class="error-box">' . $lang->get('acpum_err_activate_email_fail', array('username' => htmlspecialchars($_GET['user']))) . '</div>';
+				}
+				break;
+			case "deny":
+				$e = $db->sql_query('DELETE FROM '.table_prefix.'logs WHERE log_type=\'admin\' AND action=\'activ_req\' AND time_id=\'' . $db->escape($_GET['logid']) . '\';');
+				if ( !$e )
+				{
+					echo '<div class="error-box">Error during row deletion: '.$db->get_error().'</div>';
+				}
+				else
+				{
+					echo '<div class="info-box">' . $lang->get('acpum_msg_activate_deny_success', array('username' => htmlspecialchars($_GET['user']))) . '</div>';
+				}
+				break;
+		}
+	}
+	$q = $db->sql_query('SELECT l.log_type, l.action, l.time_id, l.date_string, l.author, l.edit_summary, u.user_coppa FROM '.table_prefix.'logs AS l
+ 												LEFT JOIN '.table_prefix.'users AS u
+ 													ON ( u.username = l.edit_summary OR u.username IS NULL )
+ 												WHERE log_type=\'admin\' AND action=\'activ_req\' ORDER BY time_id DESC;');
+	if($q)
+	{
+		if($db->numrows() > 0)
+		{
+			$n = $db->numrows();
+			$str = ( $n == 1 ) ?
+				$lang->get('acpum_heading_activation_one') :
+				$lang->get('acpum_heading_activation_plural', array('count' => strval($n)));
+				
+			echo '<h3>' . $str . '</h3>';
+				
+			echo '<div class="tblholder">
+							<table border="0" cellspacing="1" cellpadding="4" width="100%">
+								<tr>
+									<th>' . $lang->get('acpum_col_activate_timestamp') . '</th>
+									<th>' . $lang->get('acpum_col_activate_requestedby') . '</th>
+									<th>' . $lang->get('acpum_col_activate_requestedfor') . '</th>
+									<th>' . $lang->get('acpum_col_activate_coppauser') . '</th>
+									<th colspan="3">' . $lang->get('acpum_col_activate_actions') . '</th>
+								</tr>';
+			$cls = 'row2';
+			while($row = $db->fetchrow())
+			{
+				if($cls == 'row2') $cls = 'row1';
+				else $cls = 'row2';
+				$coppa = ( $row['user_coppa'] == '1' ) ? '<b>' . $lang->get('acpum_coppauser_yes') . '</b>' : $lang->get('acpum_coppauser_no');
+				echo '<tr>
+								<td class="'.$cls.'">'.enano_date(ED_DATE | ED_TIME, $row['time_id']).'</td>
+								<td class="'.$cls.'">'.$row['author'].'</td>
+								<td class="'.$cls.'">'.$row['edit_summary'].'</td>
+								<td style="text-align: center;" class="' . $cls . '">' . $coppa . '</td>
+								<td class="'.$cls.'" style="text-align: center;">
+									<a href="'.makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'UserManager&action=activate&user='.rawurlencode($row['edit_summary']).'&logid='.$row['time_id'], true).'">' . $lang->get('acpum_btn_activate_now') . '</a>
+								</td>
+								<td class="'.$cls.'" style="text-align: center;">
+									<a href="'.makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'UserManager&action=sendemail&user='.rawurlencode($row['edit_summary']).'&logid='.$row['time_id'], true).'">' . $lang->get('acpum_btn_send_email') . '</a>
+								</td>
+								<td class="'.$cls.'" style="text-align: center;">
+									<a href="'.makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'UserManager&action=deny&user='.rawurlencode($row['edit_summary']).'&logid='.$row['time_id'], true).'">' . $lang->get('acpum_btn_activate_deny') . '</a>
+								</td>
+							</tr>';
+			}
+			echo '</table>';
+			echo '</div>';
+		}
+		$db->free_result();
+	}
+	
+	acp_usermanager_lockouts();
 }
 
 /**
@@ -606,698 +606,698 @@
 
 class Admin_UserManager_SmartForm
 {
-  
-  /**
-   * Universally Unique Identifier (UUID) for this editor instance. Used to unique-itize Javascript functions and whatnot.
-   * @var string
-   */
-  
-  var $uuid = '';
-  
-  /**
-   * User ID that we're editing.
-   * @var int
-   */
-  
-  var $user_id = 0;
-  
-  /**
-   * Username
-   * @var string
-   */
-  
-  var $username = '';
-  
-  /**
-   * E-mail address
-   * @var string
-   */
-  
-  var $email = '';
-  
-  /**
-   * Real name
-   * @var string
-   */
-  
-  var $real_name = '';
-  
-  /**
-   * Signature
-   * @var string
-   */
-  
-  var $signature = '';
-  
-  /**
-   * IM contact information
-   * @var array
-   */
-   
-  var $im = array();
-  
-  /**
-   * Real-life contact info
-   * @var array
-   */
-  
-  var $contact = array();
-  
-  /**
-   * User level
-   * @var int
-   */
-  
-  var $user_level = USER_LEVEL_MEMBER;
-  
-  /**
-   * User-specific user rank
-   * @var int
-   */
-  
-  var $user_rank = NULL;
-  
-  /**
-   * User's custom title
-   * @var int
-   */
-  
-  var $user_title = '';
-  
-  /**
-   * Account activated
-   * @var bool
-   */
-  
-  var $account_active = true;
-  
-  /**
-   * Email public switch
-   * @var bool
-   */
-  
-  var $email_public = false;
-  
-  /**
-   * Whether the user has an avatar or not.
-   * @var bool
-   */
-  
-  var $has_avatar = false;
-  
-  /**
-   * The type of avatar the user has. One of "jpg", "png", or "gif".
-   * @var string
-   */
-  
-  var $avi_type = 'png';
-  
-  /**
-   * The IP address of the user during registration
-   * @var string
-   */
-  
-  var $reg_ip_addr = '';
-  
-  /**
-   * Constructor.
-   */
-  
-  function Admin_UserManager_SmartForm()
-  {
-    $this->uuid = md5( mt_rand() . microtime() );
-  }
-  
-  /**
-   * Renders and returns the finished form.
-   * @return string
-   */
-  
-  function render()
-  {
-    global $db, $session, $paths, $template, $plugins; // Common objects
-    global $lang;
-    global $dh_supported;
-    if ( file_exists( ENANO_ROOT . "/themes/$template->theme/admin_usermanager_form.tpl" ) )
-    {
-      $parser = $template->makeParser('admin_usermanager_form.tpl');
-    }
-    else
-    {
-      $tpl_code = <<<EOF
-      <!-- Start of user edit form -->
-      
-        <script type="text/javascript">
-          function userform_{UUID}_chpasswd()
-          {
-            var link = document.getElementById('userform_{UUID}_pwlink');
-            var form = document.getElementById('userform_{UUID}_pwform');
-            domOpacity(link, 100, 0, 500);
-            domObjChangeOpac(0, form);
-            setTimeout("var link = document.getElementById('userform_{UUID}_pwlink'); var form = document.getElementById('userform_{UUID}_pwform'); link.style.display = 'none'; form.style.display = 'block'; domOpacity(form, 0, 100, 500);", 550);
-            <!-- BEGINNOT same_user -->document.forms['useredit_{UUID}'].changing_pw.value = 'yes';<!-- END same_user -->
-          }
-          
-          function userform_{UUID}_chpasswd_cancel()
-          {
-            var link = document.getElementById('userform_{UUID}_pwlink');
-            var form = document.getElementById('userform_{UUID}_pwform');
-            domOpacity(form, 100, 0, 500);
-            domObjChangeOpac(0, link);
-            setTimeout("var link = document.getElementById('userform_{UUID}_pwlink'); var form = document.getElementById('userform_{UUID}_pwform'); form.style.display = 'none'; link.style.display = 'block'; domOpacity(link, 0, 100, 500);", 550);
-            <!-- BEGINNOT same_user -->document.forms['useredit_{UUID}'].changing_pw.value = 'no';<!-- END same_user -->
-          }
-          
-          function userform_{UUID}_validate()
-          {
-            var form = document.forms['useredit_{UUID}'];
-            <!-- BEGINNOT same_user -->
-            if ( form.changing_pw.value == 'yes' )
-            {
-              return runEncryption(true);
-            }
-            <!-- END same_user -->
-            return true;
-          }
-        </script>
-      
-        <form action="{FORM_ACTION}" method="post" name="useredit_{UUID}" enctype="multipart/form-data" onsubmit="return userform_{UUID}_validate();">
-        
-          <input name="user_id" value="{USER_ID}" type="hidden" />
-        
-          <div class="tblholder">
-            <table border="0" cellspacing="1" cellpadding="4">
-            
-              <!-- Heading -->
-            
-              <tr>
-                <th colspan="2">
-                  {lang:acpum_heading_editing_user} {USERNAME}
-                </th>
-              </tr>
-              
-              <!-- Basic options (stored in enano_users) -->
-              
-                <tr>
-                  <th colspan="2" class="subhead">
-                    {lang:acpum_heading_basic_options}
-                  </th>
-                </tr>
-                
-                <tr>
-                  <td class="row2" style="width: 25%;">
-                    {lang:acpum_field_username}<br />
-                    <small>{lang:acpum_field_username_hint}</small>
-                  </td>
-                  <td class="row1" style="width: 75%;">
-                    <input type="text" name="username" value="{USERNAME}" size="40" <!-- BEGIN same_user -->disabled="disabled" <!-- END same_user -->/>
-                    <!-- BEGIN same_user --><small>{lang:acpum_msg_same_user_username}</small><!-- END same_user -->
-                  </td>
-                </tr>
-                
-                <tr>
-                  <td class="row2">
-                    {lang:acpum_field_password}
-                    <!-- BEGIN password_meter -->
-                    <br />
-                    <small>{lang:acpum_field_password_hint}</small>
-                    <!-- END password_meter -->
-                  </td>
-                  <td class="row1">
-                    <div id="userform_{UUID}_pwlink">
-                      <b>{lang:acpum_msg_password_unchanged}</b> <a href="#" onclick="userform_{UUID}_chpasswd(); return false;">{lang:acpum_btn_reset_password}</a>
-                    </div>
-                    <div id="userform_{UUID}_pwform" style="display: none;">
-                      <!-- BEGIN same_user -->
-                        {lang:acpum_msg_same_user_password} <a href="#" onclick="userform_{UUID}_chpasswd_cancel(); return false;">{lang:etc_cancel}</a>
-                      <!-- BEGINELSE same_user -->
-                      <input type="hidden" name="changing_pw" value="no" />
-                      {AES_FORM}
-                      <table border="0" style="background-color: transparent;" cellspacing="0" cellpadding="0">
-                        <tr>
-                          <td colspan="2">
-                            <b>{lang:acpum_field_password_title}</b>
-                          </td>
-                        </tr>
-                        <tr>
-                          <td>{lang:acpum_field_newpassword}</td>
-                          <td>
-                          <!-- BEGIN password_meter -->
-                            <input type="password" name="new_password" value="" onkeyup="password_score_field(this);" /><span class="password-checker" style="font-weight: bold; color: #A0A0A0"> Waiting for l10n init</span>
-                          <!-- BEGINELSE password_meter -->
-                            <input type="password" name="new_password" value="" />
-                          <!-- END password_meter -->
-                          <!-- BEGIN password_meter -->
-                            <div id="pwmeter" style="margin: 4px 0; height: 8px;"></div>
-                          <!-- END password_meter -->
-                          </td>
-                        </tr>
-                        <tr>
-                          <td>{lang:acpum_field_newpassword_confirm}</td>
-                          <td><input type="password" name="new_password_confirm" value="" /></td>
-                        </tr>
-                        <tr>
-                          <td colspan="2">
-                            <a href="#" onclick="userform_{UUID}_chpasswd_cancel(); return false;">{lang:etc_cancel}</a>
-                          </td>
-                        </tr>
-                      </table>
-                      <!-- END same_user -->
-                    </div>
-                  </td>
-                </tr>
-                
-                <tr>
-                  <td class="row2" style="width: 25%;">
-                    {lang:acpum_field_email}
-                  </td>
-                  <td class="row1" style="width: 75%;">
-                    <input type="text" name="email" value="{EMAIL}" size="40" <!-- BEGIN same_user -->disabled="disabled" <!-- END same_user -->/>
-                    <!-- BEGIN same_user --><small>{lang:acpum_msg_same_user_email}</small><!-- END same_user -->
-                  </td>
-                </tr>
-                
-                <tr>
-                  <td class="row2" style="width: 25%;">
-                    {lang:acpum_field_realname}
-                  </td>
-                  <td class="row1" style="width: 75%;">
-                    <input type="text" name="real_name" value="{REAL_NAME}" size="40" <!-- BEGIN same_user -->disabled="disabled" <!-- END same_user -->/>
-                    <!-- BEGIN same_user --><small>{lang:acpum_msg_same_user_realname}</small><!-- END same_user -->
-                  </td>
-                </tr>
-                
-                <tr>
-                  <td class="row2" style="width: 25%;">
-                    {lang:acpum_field_signature}
-                  </td>
-                  <td class="row1" style="width: 75%;">
-                    {SIGNATURE_FIELD}
-                  </td>
-                </tr>
-                
-                <tr>
-                  <td class="row2" style="width: 25%;">
-                    {lang:acpum_field_usertitle}<br />
-                    <small>
-                      {lang:acpum_field_usertitle_hint}
-                    </small>
-                  </td>
-                  <td class="row1" style="width: 75%;">
-                    <input type="text" name="user_title" value="{USER_TITLE}" />
-                  </td>
-                </tr>
-                
-                
-                
-              <!-- / Basic options -->
-              
-              <!-- Extended options (anything in enano_users_extra) -->
-              
-                <tr>
-                  <th class="subhead" colspan="2">
-                    {lang:acpum_heading_imcontact}
-                  </th>
-                <tr>
-                  <td class="row2">{lang:acpum_field_aim}</td>
-                  <td class="row1"><input type="text" name="imaddr_aim" value="{IM_AIM}" size="30" /></td>
-                </tr>
-                <tr>
-                  <td class="row2">{lang:acpum_field_wlm}<br /><small>{lang:acpum_field_wlm_hint}</small></td>
-                  <td class="row1"><input type="text" name="imaddr_msn" value="{IM_WLM}" size="30" /></td>
-                </tr>
-                <tr>
-                  <td class="row2">{lang:acpum_field_yim}</td>
-                  <td class="row1"><input type="text" name="imaddr_yahoo" value="{IM_YAHOO}" size="30" /></td>
-                </tr>
-                <tr>
-                  <td class="row2">{lang:acpum_field_xmpp}</td>
-                  <td class="row1"><input type="text" name="imaddr_xmpp" value="{IM_XMPP}" size="30" /></td>
-                </tr>
-                <tr>
-                  <th class="subhead" colspan="2">
-                    {lang:acpum_heading_contact_extra}
-                  </th>
-                </tr>
-                <tr>
-                  <td class="row2">{lang:acpum_field_homepage}<br /><small>{lang:acpum_field_homepage_hint}</small></td>
-                  <td class="row1"><input type="text" name="homepage" value="{HOMEPAGE}" size="30" /></td>
-                </tr>
-                <tr>
-                  <td class="row2">{lang:acpum_field_location}</td>
-                  <td class="row1"><input type="text" name="location" value="{LOCATION}" size="30" /></td>
-                </tr>
-                <tr>
-                  <td class="row2">{lang:acpum_field_job}</td>
-                  <td class="row1"><input type="text" name="occupation" value="{JOB}" size="30" /></td>
-                </tr>
-                <tr>
-                  <td class="row2">{lang:acpum_field_hobbies}</td>
-                  <td class="row1"><input type="text" name="hobbies" value="{HOBBIES}" size="30" /></td>
-                </tr>
-                <tr>
-                  <td class="row2"><label for="chk_email_public_{UUID}">{lang:acpum_field_email_public}</label><br /><small>{lang:acpum_field_email_public_hint}</small></td>
-                  <td class="row1"><input type="checkbox" id="chk_email_public_{UUID}" name="email_public" <!-- BEGIN email_public -->checked="checked" <!-- END email_public -->size="30" /></td>
-                </tr>
-              
-              <!-- / Extended options -->
-              
-              <!-- Avatar settings -->
-              
-                <tr>
-                  <th class="subhead" colspan="2">
-                    {lang:acpum_avatar_heading}
-                  </th>
-                </tr>
-                
-                <tr>
-                  <td class="row2">
-                    {lang:usercp_avatar_label_current}
-                  </td>
-                  <td class="row1">
-                    <!-- BEGIN user_has_avatar -->
-                      <img alt="{AVATAR_ALT}" src="{AVATAR_SRC}" />
-                    <!-- BEGINELSE user_has_avatar -->
-                      {lang:acpum_avatar_image_none}
-                    <!-- END user_has_avatar -->
-                  </td>
-                </tr>
-                
-                <tr>
-                  <td class="row2">
-                    {lang:acpum_avatar_lbl_change}
-                  </td>
-                  <td class="row1" id="avatar_upload_btns_{UUID}">
-                    <script type="text/javascript">
-                      function admincp_users_avatar_set_{UUID}(elParent)
-                      {
-                        $('td#avatar_upload_btns_{UUID} > div:visible').hide('blind');
-                        switch(elParent.value)
-                        {
-                          case 'set_http':
-                            $('#avatar_upload_http_{UUID}').show('blind');
-                            break;
-                          case 'set_file':
-                            $('#avatar_upload_file_{UUID}').show('blind');
-                            break;
-                          case 'set_gravatar':
-                            $('#avatar_upload_gravatar_{UUID}').show('blind');
-                            break;
-                        }
-                      }
-                    </script>
-                    <label><input onclick="admincp_users_avatar_set_{UUID}(this);" type="radio" name="avatar_action" value="keep" checked="checked" /> {lang:acpum_avatar_lbl_keep}</label><br />
-                    <label><input onclick="admincp_users_avatar_set_{UUID}(this);" type="radio" name="avatar_action" value="remove" /> {lang:acpum_avatar_lbl_remove}</label><br />
-                    <label><input onclick="admincp_users_avatar_set_{UUID}(this);" type="radio" name="avatar_action" value="set_http" /> {lang:acpum_avatar_lbl_set_http}</label><br />
-                      <div id="avatar_upload_http_{UUID}" style="display: none; margin: 10px 0 0 2.2em;">
-                        {lang:usercp_avatar_lbl_url} <input type="text" name="avatar_http_url" size="40" value="http://" /><br />
-                        <small>{lang:usercp_avatar_lbl_url_desc} {lang:usercp_avatar_limits}</small>
-                      </div>
-                    <label><input onclick="admincp_users_avatar_set_{UUID}(this);" type="radio" name="avatar_action" value="set_file" /> {lang:acpum_avatar_lbl_set_file}</label><br />
-                      <div id="avatar_upload_file_{UUID}" style="display: none; margin: 10px 0 0 2.2em;">
-                        {lang:usercp_avatar_lbl_file} <input type="file" name="avatar_file" size="40" value="http://" /><br />
-                        <small>{lang:usercp_avatar_lbl_file_desc} {lang:usercp_avatar_limits}</small>
-                      </div>
-                    <label><input onclick="admincp_users_avatar_set_{UUID}(this);" type="radio" name="avatar_action" value="set_gravatar" /> {lang:acpum_avatar_lbl_set_gravatar} <img alt=" " src="{GRAVATAR_URL}" /></label><br />
-                      <div id="avatar_upload_gravatar_{UUID}"></div>
-                  </td>
-                </tr>
-                
-              <!-- / Avatar settings -->
-              
-              <!-- Administrator-only options -->
-              
-                <tr>
-                  <th class="subhead" colspan="2">
-                    {lang:acpum_heading_adminonly}
-                  </th>
-                </tr>
-                
-                <tr>
-                  <td class="row2">{lang:acpum_field_active_title}<br />
-                                   <small>{lang:acpum_field_active_hint}</small>
-                                   </td>
-                  <td class="row1"><label><input type="checkbox" name="account_active" <!-- BEGIN account_active -->checked="checked" <!-- END account_active -->/> {lang:acpum_field_active}</label></td>
-                </tr>
-                
-                <tr>
-                  <td class="row2">
-                    {lang:acpum_field_userlevel}<br />
-                    <small>{lang:acpum_field_userlevel_hint}</small>
-                  </td>
-                  <td class="row1">
-                    <select name="user_level">
-                      <option value="{USER_LEVEL_MEMBER}"<!-- BEGIN ul_member --> selected="selected"<!-- END ul_member -->>{lang:userfuncs_ml_level_member}</option>
-                      <option value="{USER_LEVEL_MOD}"<!-- BEGIN ul_mod --> selected="selected"<!-- END ul_mod -->>{lang:userfuncs_ml_level_mod}</option>
-                      <option value="{USER_LEVEL_ADMIN}"<!-- BEGIN ul_admin --> selected="selected"<!-- END ul_admin -->>{lang:userfuncs_ml_level_admin}</option>
-                    </select>
-                  </td>
-                </tr>
-                
-                <tr>
-                  <td class="row2">
-                    {lang:acpum_field_userrank}<br />
-                    <small>{lang:acpum_field_userrank_hint}</small>
-                  </td>
-                  <td class="row1">
-                    <select name="user_rank">
-                      {RANK_LIST}
-                    </select>
-                  </td>
-                </tr>
-                
-                <!-- BEGIN have_reg_ip -->
-                <tr>
-                  <td class="row2">
-                    {lang:acpum_field_reg_ip}
-                  </td>
-                  <td class="row1">
-                    {REG_IP_ADDR}
-                    <input type="hidden" name="user_registration_ip" value="{REG_IP_ADDR}" />
-                  </td>
-                </tr>
-                <!-- BEGINELSE have_reg_ip -->
-                <input type="hidden" name="user_registration_ip" value="" />
-                <!-- END have_reg_ip -->
-                
-                <tr>
-                  <td class="row2">
-                    {lang:acpum_field_deleteaccount_title}
-                  </td>
-                  <td class="row1">
-                  <label><input type="checkbox" name="delete_account" onclick="var d = (this.checked) ? 'block' : 'none'; document.getElementById('delete_blurb_{UUID}').style.display = d;" /> {lang:acpum_field_deleteaccount}</label>
-                    <div id="delete_blurb_{UUID}" style="display: none;">
-                      <!-- BEGIN same_user -->
-                      <!-- Obnoxious I know, but it's needed. -->
-                      <p><b>{lang:acpum_msg_delete_own_account}</b></p>
-                      <!-- END same_user -->
-                      <p><small>{lang:acpum_field_deleteaccount_hint}</small></p>
-                    </div>
-                  </td>
-                </tr>
-                </tr>
-              
-              <!-- Save button -->
-              <tr>
-                <th colspan="2">
-                  <input type="submit" name="action[save]" value="{lang:acpum_btn_save}" style="font-weight: bold;" />
-                  <input type="submit" name="action[noop]" value="{lang:etc_cancel}" style="font-weight: normal;" />
-                </th>
-              </tr>
-            
-            </table>
-          </div>
-        
-        </form>
-        
-        <!-- BEGINNOT same_user -->
-        <script type="text/javascript">
-        password_score_field(document.forms['useredit_{UUID}'].new_password);
-        </script>
-        <!-- END same_user -->
-        
-        {AES_JAVASCRIPT}
-      <!-- Conclusion of user edit form -->
+	
+	/**
+ 	* Universally Unique Identifier (UUID) for this editor instance. Used to unique-itize Javascript functions and whatnot.
+ 	* @var string
+ 	*/
+	
+	var $uuid = '';
+	
+	/**
+ 	* User ID that we're editing.
+ 	* @var int
+ 	*/
+	
+	var $user_id = 0;
+	
+	/**
+ 	* Username
+ 	* @var string
+ 	*/
+	
+	var $username = '';
+	
+	/**
+ 	* E-mail address
+ 	* @var string
+ 	*/
+	
+	var $email = '';
+	
+	/**
+ 	* Real name
+ 	* @var string
+ 	*/
+	
+	var $real_name = '';
+	
+	/**
+ 	* Signature
+ 	* @var string
+ 	*/
+	
+	var $signature = '';
+	
+	/**
+ 	* IM contact information
+ 	* @var array
+ 	*/
+ 	
+	var $im = array();
+	
+	/**
+ 	* Real-life contact info
+ 	* @var array
+ 	*/
+	
+	var $contact = array();
+	
+	/**
+ 	* User level
+ 	* @var int
+ 	*/
+	
+	var $user_level = USER_LEVEL_MEMBER;
+	
+	/**
+ 	* User-specific user rank
+ 	* @var int
+ 	*/
+	
+	var $user_rank = NULL;
+	
+	/**
+ 	* User's custom title
+ 	* @var int
+ 	*/
+	
+	var $user_title = '';
+	
+	/**
+ 	* Account activated
+ 	* @var bool
+ 	*/
+	
+	var $account_active = true;
+	
+	/**
+ 	* Email public switch
+ 	* @var bool
+ 	*/
+	
+	var $email_public = false;
+	
+	/**
+ 	* Whether the user has an avatar or not.
+ 	* @var bool
+ 	*/
+	
+	var $has_avatar = false;
+	
+	/**
+ 	* The type of avatar the user has. One of "jpg", "png", or "gif".
+ 	* @var string
+ 	*/
+	
+	var $avi_type = 'png';
+	
+	/**
+ 	* The IP address of the user during registration
+ 	* @var string
+ 	*/
+	
+	var $reg_ip_addr = '';
+	
+	/**
+ 	* Constructor.
+ 	*/
+	
+	function Admin_UserManager_SmartForm()
+	{
+		$this->uuid = md5( mt_rand() . microtime() );
+	}
+	
+	/**
+ 	* Renders and returns the finished form.
+ 	* @return string
+ 	*/
+	
+	function render()
+	{
+		global $db, $session, $paths, $template, $plugins; // Common objects
+		global $lang;
+		global $dh_supported;
+		if ( file_exists( ENANO_ROOT . "/themes/$template->theme/admin_usermanager_form.tpl" ) )
+		{
+			$parser = $template->makeParser('admin_usermanager_form.tpl');
+		}
+		else
+		{
+			$tpl_code = <<<EOF
+			<!-- Start of user edit form -->
+			
+				<script type="text/javascript">
+					function userform_{UUID}_chpasswd()
+					{
+						var link = document.getElementById('userform_{UUID}_pwlink');
+						var form = document.getElementById('userform_{UUID}_pwform');
+						domOpacity(link, 100, 0, 500);
+						domObjChangeOpac(0, form);
+						setTimeout("var link = document.getElementById('userform_{UUID}_pwlink'); var form = document.getElementById('userform_{UUID}_pwform'); link.style.display = 'none'; form.style.display = 'block'; domOpacity(form, 0, 100, 500);", 550);
+						<!-- BEGINNOT same_user -->document.forms['useredit_{UUID}'].changing_pw.value = 'yes';<!-- END same_user -->
+					}
+					
+					function userform_{UUID}_chpasswd_cancel()
+					{
+						var link = document.getElementById('userform_{UUID}_pwlink');
+						var form = document.getElementById('userform_{UUID}_pwform');
+						domOpacity(form, 100, 0, 500);
+						domObjChangeOpac(0, link);
+						setTimeout("var link = document.getElementById('userform_{UUID}_pwlink'); var form = document.getElementById('userform_{UUID}_pwform'); form.style.display = 'none'; link.style.display = 'block'; domOpacity(link, 0, 100, 500);", 550);
+						<!-- BEGINNOT same_user -->document.forms['useredit_{UUID}'].changing_pw.value = 'no';<!-- END same_user -->
+					}
+					
+					function userform_{UUID}_validate()
+					{
+						var form = document.forms['useredit_{UUID}'];
+						<!-- BEGINNOT same_user -->
+						if ( form.changing_pw.value == 'yes' )
+						{
+							return runEncryption(true);
+						}
+						<!-- END same_user -->
+						return true;
+					}
+				</script>
+			
+				<form action="{FORM_ACTION}" method="post" name="useredit_{UUID}" enctype="multipart/form-data" onsubmit="return userform_{UUID}_validate();">
+				
+					<input name="user_id" value="{USER_ID}" type="hidden" />
+				
+					<div class="tblholder">
+						<table border="0" cellspacing="1" cellpadding="4">
+						
+							<!-- Heading -->
+						
+							<tr>
+								<th colspan="2">
+									{lang:acpum_heading_editing_user} {USERNAME}
+								</th>
+							</tr>
+							
+							<!-- Basic options (stored in enano_users) -->
+							
+								<tr>
+									<th colspan="2" class="subhead">
+										{lang:acpum_heading_basic_options}
+									</th>
+								</tr>
+								
+								<tr>
+									<td class="row2" style="width: 25%;">
+										{lang:acpum_field_username}<br />
+										<small>{lang:acpum_field_username_hint}</small>
+									</td>
+									<td class="row1" style="width: 75%;">
+										<input type="text" name="username" value="{USERNAME}" size="40" <!-- BEGIN same_user -->disabled="disabled" <!-- END same_user -->/>
+										<!-- BEGIN same_user --><small>{lang:acpum_msg_same_user_username}</small><!-- END same_user -->
+									</td>
+								</tr>
+								
+								<tr>
+									<td class="row2">
+										{lang:acpum_field_password}
+										<!-- BEGIN password_meter -->
+										<br />
+										<small>{lang:acpum_field_password_hint}</small>
+										<!-- END password_meter -->
+									</td>
+									<td class="row1">
+										<div id="userform_{UUID}_pwlink">
+											<b>{lang:acpum_msg_password_unchanged}</b> <a href="#" onclick="userform_{UUID}_chpasswd(); return false;">{lang:acpum_btn_reset_password}</a>
+										</div>
+										<div id="userform_{UUID}_pwform" style="display: none;">
+											<!-- BEGIN same_user -->
+												{lang:acpum_msg_same_user_password} <a href="#" onclick="userform_{UUID}_chpasswd_cancel(); return false;">{lang:etc_cancel}</a>
+											<!-- BEGINELSE same_user -->
+											<input type="hidden" name="changing_pw" value="no" />
+											{AES_FORM}
+											<table border="0" style="background-color: transparent;" cellspacing="0" cellpadding="0">
+												<tr>
+													<td colspan="2">
+														<b>{lang:acpum_field_password_title}</b>
+													</td>
+												</tr>
+												<tr>
+													<td>{lang:acpum_field_newpassword}</td>
+													<td>
+													<!-- BEGIN password_meter -->
+														<input type="password" name="new_password" value="" onkeyup="password_score_field(this);" /><span class="password-checker" style="font-weight: bold; color: #A0A0A0"> Waiting for l10n init</span>
+													<!-- BEGINELSE password_meter -->
+														<input type="password" name="new_password" value="" />
+													<!-- END password_meter -->
+													<!-- BEGIN password_meter -->
+														<div id="pwmeter" style="margin: 4px 0; height: 8px;"></div>
+													<!-- END password_meter -->
+													</td>
+												</tr>
+												<tr>
+													<td>{lang:acpum_field_newpassword_confirm}</td>
+													<td><input type="password" name="new_password_confirm" value="" /></td>
+												</tr>
+												<tr>
+													<td colspan="2">
+														<a href="#" onclick="userform_{UUID}_chpasswd_cancel(); return false;">{lang:etc_cancel}</a>
+													</td>
+												</tr>
+											</table>
+											<!-- END same_user -->
+										</div>
+									</td>
+								</tr>
+								
+								<tr>
+									<td class="row2" style="width: 25%;">
+										{lang:acpum_field_email}
+									</td>
+									<td class="row1" style="width: 75%;">
+										<input type="text" name="email" value="{EMAIL}" size="40" <!-- BEGIN same_user -->disabled="disabled" <!-- END same_user -->/>
+										<!-- BEGIN same_user --><small>{lang:acpum_msg_same_user_email}</small><!-- END same_user -->
+									</td>
+								</tr>
+								
+								<tr>
+									<td class="row2" style="width: 25%;">
+										{lang:acpum_field_realname}
+									</td>
+									<td class="row1" style="width: 75%;">
+										<input type="text" name="real_name" value="{REAL_NAME}" size="40" <!-- BEGIN same_user -->disabled="disabled" <!-- END same_user -->/>
+										<!-- BEGIN same_user --><small>{lang:acpum_msg_same_user_realname}</small><!-- END same_user -->
+									</td>
+								</tr>
+								
+								<tr>
+									<td class="row2" style="width: 25%;">
+										{lang:acpum_field_signature}
+									</td>
+									<td class="row1" style="width: 75%;">
+										{SIGNATURE_FIELD}
+									</td>
+								</tr>
+								
+								<tr>
+									<td class="row2" style="width: 25%;">
+										{lang:acpum_field_usertitle}<br />
+										<small>
+											{lang:acpum_field_usertitle_hint}
+										</small>
+									</td>
+									<td class="row1" style="width: 75%;">
+										<input type="text" name="user_title" value="{USER_TITLE}" />
+									</td>
+								</tr>
+								
+								
+								
+							<!-- / Basic options -->
+							
+							<!-- Extended options (anything in enano_users_extra) -->
+							
+								<tr>
+									<th class="subhead" colspan="2">
+										{lang:acpum_heading_imcontact}
+									</th>
+								<tr>
+									<td class="row2">{lang:acpum_field_aim}</td>
+									<td class="row1"><input type="text" name="imaddr_aim" value="{IM_AIM}" size="30" /></td>
+								</tr>
+								<tr>
+									<td class="row2">{lang:acpum_field_wlm}<br /><small>{lang:acpum_field_wlm_hint}</small></td>
+									<td class="row1"><input type="text" name="imaddr_msn" value="{IM_WLM}" size="30" /></td>
+								</tr>
+								<tr>
+									<td class="row2">{lang:acpum_field_yim}</td>
+									<td class="row1"><input type="text" name="imaddr_yahoo" value="{IM_YAHOO}" size="30" /></td>
+								</tr>
+								<tr>
+									<td class="row2">{lang:acpum_field_xmpp}</td>
+									<td class="row1"><input type="text" name="imaddr_xmpp" value="{IM_XMPP}" size="30" /></td>
+								</tr>
+								<tr>
+									<th class="subhead" colspan="2">
+										{lang:acpum_heading_contact_extra}
+									</th>
+								</tr>
+								<tr>
+									<td class="row2">{lang:acpum_field_homepage}<br /><small>{lang:acpum_field_homepage_hint}</small></td>
+									<td class="row1"><input type="text" name="homepage" value="{HOMEPAGE}" size="30" /></td>
+								</tr>
+								<tr>
+									<td class="row2">{lang:acpum_field_location}</td>
+									<td class="row1"><input type="text" name="location" value="{LOCATION}" size="30" /></td>
+								</tr>
+								<tr>
+									<td class="row2">{lang:acpum_field_job}</td>
+									<td class="row1"><input type="text" name="occupation" value="{JOB}" size="30" /></td>
+								</tr>
+								<tr>
+									<td class="row2">{lang:acpum_field_hobbies}</td>
+									<td class="row1"><input type="text" name="hobbies" value="{HOBBIES}" size="30" /></td>
+								</tr>
+								<tr>
+									<td class="row2"><label for="chk_email_public_{UUID}">{lang:acpum_field_email_public}</label><br /><small>{lang:acpum_field_email_public_hint}</small></td>
+									<td class="row1"><input type="checkbox" id="chk_email_public_{UUID}" name="email_public" <!-- BEGIN email_public -->checked="checked" <!-- END email_public -->size="30" /></td>
+								</tr>
+							
+							<!-- / Extended options -->
+							
+							<!-- Avatar settings -->
+							
+								<tr>
+									<th class="subhead" colspan="2">
+										{lang:acpum_avatar_heading}
+									</th>
+								</tr>
+								
+								<tr>
+									<td class="row2">
+										{lang:usercp_avatar_label_current}
+									</td>
+									<td class="row1">
+										<!-- BEGIN user_has_avatar -->
+											<img alt="{AVATAR_ALT}" src="{AVATAR_SRC}" />
+										<!-- BEGINELSE user_has_avatar -->
+											{lang:acpum_avatar_image_none}
+										<!-- END user_has_avatar -->
+									</td>
+								</tr>
+								
+								<tr>
+									<td class="row2">
+										{lang:acpum_avatar_lbl_change}
+									</td>
+									<td class="row1" id="avatar_upload_btns_{UUID}">
+										<script type="text/javascript">
+											function admincp_users_avatar_set_{UUID}(elParent)
+											{
+												$('td#avatar_upload_btns_{UUID} > div:visible').hide('blind');
+												switch(elParent.value)
+												{
+													case 'set_http':
+														$('#avatar_upload_http_{UUID}').show('blind');
+														break;
+													case 'set_file':
+														$('#avatar_upload_file_{UUID}').show('blind');
+														break;
+													case 'set_gravatar':
+														$('#avatar_upload_gravatar_{UUID}').show('blind');
+														break;
+												}
+											}
+										</script>
+										<label><input onclick="admincp_users_avatar_set_{UUID}(this);" type="radio" name="avatar_action" value="keep" checked="checked" /> {lang:acpum_avatar_lbl_keep}</label><br />
+										<label><input onclick="admincp_users_avatar_set_{UUID}(this);" type="radio" name="avatar_action" value="remove" /> {lang:acpum_avatar_lbl_remove}</label><br />
+										<label><input onclick="admincp_users_avatar_set_{UUID}(this);" type="radio" name="avatar_action" value="set_http" /> {lang:acpum_avatar_lbl_set_http}</label><br />
+											<div id="avatar_upload_http_{UUID}" style="display: none; margin: 10px 0 0 2.2em;">
+												{lang:usercp_avatar_lbl_url} <input type="text" name="avatar_http_url" size="40" value="http://" /><br />
+												<small>{lang:usercp_avatar_lbl_url_desc} {lang:usercp_avatar_limits}</small>
+											</div>
+										<label><input onclick="admincp_users_avatar_set_{UUID}(this);" type="radio" name="avatar_action" value="set_file" /> {lang:acpum_avatar_lbl_set_file}</label><br />
+											<div id="avatar_upload_file_{UUID}" style="display: none; margin: 10px 0 0 2.2em;">
+												{lang:usercp_avatar_lbl_file} <input type="file" name="avatar_file" size="40" value="http://" /><br />
+												<small>{lang:usercp_avatar_lbl_file_desc} {lang:usercp_avatar_limits}</small>
+											</div>
+										<label><input onclick="admincp_users_avatar_set_{UUID}(this);" type="radio" name="avatar_action" value="set_gravatar" /> {lang:acpum_avatar_lbl_set_gravatar} <img alt=" " src="{GRAVATAR_URL}" /></label><br />
+											<div id="avatar_upload_gravatar_{UUID}"></div>
+									</td>
+								</tr>
+								
+							<!-- / Avatar settings -->
+							
+							<!-- Administrator-only options -->
+							
+								<tr>
+									<th class="subhead" colspan="2">
+										{lang:acpum_heading_adminonly}
+									</th>
+								</tr>
+								
+								<tr>
+									<td class="row2">{lang:acpum_field_active_title}<br />
+ 																	<small>{lang:acpum_field_active_hint}</small>
+ 																	</td>
+									<td class="row1"><label><input type="checkbox" name="account_active" <!-- BEGIN account_active -->checked="checked" <!-- END account_active -->/> {lang:acpum_field_active}</label></td>
+								</tr>
+								
+								<tr>
+									<td class="row2">
+										{lang:acpum_field_userlevel}<br />
+										<small>{lang:acpum_field_userlevel_hint}</small>
+									</td>
+									<td class="row1">
+										<select name="user_level">
+											<option value="{USER_LEVEL_MEMBER}"<!-- BEGIN ul_member --> selected="selected"<!-- END ul_member -->>{lang:userfuncs_ml_level_member}</option>
+											<option value="{USER_LEVEL_MOD}"<!-- BEGIN ul_mod --> selected="selected"<!-- END ul_mod -->>{lang:userfuncs_ml_level_mod}</option>
+											<option value="{USER_LEVEL_ADMIN}"<!-- BEGIN ul_admin --> selected="selected"<!-- END ul_admin -->>{lang:userfuncs_ml_level_admin}</option>
+										</select>
+									</td>
+								</tr>
+								
+								<tr>
+									<td class="row2">
+										{lang:acpum_field_userrank}<br />
+										<small>{lang:acpum_field_userrank_hint}</small>
+									</td>
+									<td class="row1">
+										<select name="user_rank">
+											{RANK_LIST}
+										</select>
+									</td>
+								</tr>
+								
+								<!-- BEGIN have_reg_ip -->
+								<tr>
+									<td class="row2">
+										{lang:acpum_field_reg_ip}
+									</td>
+									<td class="row1">
+										{REG_IP_ADDR}
+										<input type="hidden" name="user_registration_ip" value="{REG_IP_ADDR}" />
+									</td>
+								</tr>
+								<!-- BEGINELSE have_reg_ip -->
+								<input type="hidden" name="user_registration_ip" value="" />
+								<!-- END have_reg_ip -->
+								
+								<tr>
+									<td class="row2">
+										{lang:acpum_field_deleteaccount_title}
+									</td>
+									<td class="row1">
+									<label><input type="checkbox" name="delete_account" onclick="var d = (this.checked) ? 'block' : 'none'; document.getElementById('delete_blurb_{UUID}').style.display = d;" /> {lang:acpum_field_deleteaccount}</label>
+										<div id="delete_blurb_{UUID}" style="display: none;">
+											<!-- BEGIN same_user -->
+											<!-- Obnoxious I know, but it's needed. -->
+											<p><b>{lang:acpum_msg_delete_own_account}</b></p>
+											<!-- END same_user -->
+											<p><small>{lang:acpum_field_deleteaccount_hint}</small></p>
+										</div>
+									</td>
+								</tr>
+								</tr>
+							
+							<!-- Save button -->
+							<tr>
+								<th colspan="2">
+									<input type="submit" name="action[save]" value="{lang:acpum_btn_save}" style="font-weight: bold;" />
+									<input type="submit" name="action[noop]" value="{lang:etc_cancel}" style="font-weight: normal;" />
+								</th>
+							</tr>
+						
+						</table>
+					</div>
+				
+				</form>
+				
+				<!-- BEGINNOT same_user -->
+				<script type="text/javascript">
+				password_score_field(document.forms['useredit_{UUID}'].new_password);
+				</script>
+				<!-- END same_user -->
+				
+				{AES_JAVASCRIPT}
+			<!-- Conclusion of user edit form -->
 EOF;
-      $parser = $template->makeParserText($tpl_code);
-    }
-    
-    $this->username = htmlspecialchars($this->username);
-    $this->email = htmlspecialchars($this->email);
-    $this->user_id = intval($this->user_id);
-    $this->real_name = htmlspecialchars($this->real_name);
-    $this->signature = htmlspecialchars($this->signature);
-    $this->user_level = intval($this->user_level);
-    
-    $im_aim   = ( isset($this->im['aim']) )   ? $this->im['aim']   : false;
-    $im_yahoo = ( isset($this->im['yahoo']) ) ? $this->im['yahoo'] : false;
-    $im_msn   = ( isset($this->im['msn']) )   ? $this->im['msn']   : false;
-    $im_xmpp  = ( isset($this->im['xmpp']) )  ? $this->im['xmpp']  : false;
-    
-    $homepage = ( isset($this->contact['homepage']) ) ? $this->contact['homepage'] : false;
-    $location = ( isset($this->contact['location']) ) ? $this->contact['location'] : false;
-    $job = ( isset($this->contact['job']) ) ? $this->contact['job'] : false;
-    $hobbies = ( isset($this->contact['hobbies']) ) ? $this->contact['hobbies'] : false;
-    
-    if ( empty($this->username) )
-    {
-      // @error One or more required parameters not set
-      return 'Admin_UserManager_SmartForm::render: Invalid parameter ($form->username)';
-    }
-    
-    if ( empty($this->user_id) )
-    {
-      // @error One or more required parameters not set
-      return 'Admin_UserManager_SmartForm::render: Invalid parameter ($form->user_id)';
-    }
-    
-    if ( empty($this->email) )
-    {
-      // @error One or more required parameters not set
-      return 'Admin_UserManager_SmartForm::render: Invalid parameter ($form->email)';
-    }
-    
-    $form_action = makeUrlNS('Special', 'Administration', 'module=' . $paths->cpage['module'], true);
-    $aes_javascript = $session->aes_javascript("useredit_$this->uuid", 'new_password');
-    
-    // build rank list
-    $q = $db->sql_query('SELECT rank_id, rank_title FROM ' . table_prefix . 'ranks');
-    if ( !$q )
-      $db->_die();
-    $rank_list = '<option value="NULL"' . ( $this->user_rank === NULL ? ' selected="selected"' : '' ) . '>--</option>' . "\n";
-    while ( $row = $db->fetchrow() )
-    {
-      $rank_list .= '<option value="' . $row['rank_id'] . '"' . ( $row['rank_id'] == $this->user_rank ? ' selected="selected"' : '' ) . '>' . htmlspecialchars($lang->get($row['rank_title'])) . '</option>' . "\n";
-    }
-    
-    $parser->assign_vars(array(
-        'UUID' => $this->uuid,
-        'USERNAME' => $this->username,
-        'EMAIL' => $this->email,
-        'USER_ID' => $this->user_id,
-        'AES_FORM' => $session->generate_aes_form(),
-        'REAL_NAME' => $this->real_name,
-        'SIGNATURE_FIELD' => $template->tinymce_textarea('signature', $this->signature, 10, 50),
-        'USER_TITLE' => $this->user_title,
-        'USER_LEVEL_MEMBER' => USER_LEVEL_CHPREF,
-        'USER_LEVEL_MOD' => USER_LEVEL_MOD,
-        'USER_LEVEL_ADMIN' => USER_LEVEL_ADMIN,
-        'AES_JAVASCRIPT' => $aes_javascript,
-        'IM_AIM' => $im_aim,
-        'IM_YAHOO' => $im_yahoo,
-        'IM_WLM' => $im_msn,
-        'IM_XMPP' => $im_xmpp,
-        'HOMEPAGE' => $homepage,
-        'LOCATION' => $location,
-        'JOB' => $job,
-        'HOBBIES' => $hobbies,
-        'FORM_ACTION' => $form_action,
-        'REG_IP_ADDR' => $this->reg_ip_addr,
-        'RANK_LIST' => $rank_list,
-        'GRAVATAR_URL' => make_gravatar_url($this->email, 16)
-      ));
-    
-    if ( $this->has_avatar )
-    {
-      $parser->assign_vars(array(
-          'AVATAR_SRC' => make_avatar_url($this->user_id, $this->avi_type),
-          'AVATAR_ALT' => $lang->get('usercp_avatar_image_alt', array('username' => $this->username), $this->email)
-        ));
-    }
-    
-    $parser->assign_bool(array(
-        'password_meter' => ( getConfig('pw_strength_enable') == '1' ),
-        'ul_member' => ( $this->user_level == USER_LEVEL_CHPREF ),
-        'ul_mod' => ( $this->user_level == USER_LEVEL_MOD ),
-        'ul_admin' => ( $this->user_level == USER_LEVEL_ADMIN ),
-        'account_active' => ( $this->account_active === true ),
-        'email_public' => ( $this->email_public === true ),
-        'same_user' => ( $this->user_id == $session->user_id ),
-        'user_has_avatar' => ( $this->has_avatar ),
-        'have_reg_ip' => ( intval(@strlen($this->reg_ip_addr)) > 0 && is_valid_ip($this->reg_ip_addr) )
-      ));
-    
-    $parsed = $parser->run();
-    return $parsed;
-  }
-  
+			$parser = $template->makeParserText($tpl_code);
+		}
+		
+		$this->username = htmlspecialchars($this->username);
+		$this->email = htmlspecialchars($this->email);
+		$this->user_id = intval($this->user_id);
+		$this->real_name = htmlspecialchars($this->real_name);
+		$this->signature = htmlspecialchars($this->signature);
+		$this->user_level = intval($this->user_level);
+		
+		$im_aim   = ( isset($this->im['aim']) )   ? $this->im['aim']   : false;
+		$im_yahoo = ( isset($this->im['yahoo']) ) ? $this->im['yahoo'] : false;
+		$im_msn   = ( isset($this->im['msn']) )   ? $this->im['msn']   : false;
+		$im_xmpp  = ( isset($this->im['xmpp']) )  ? $this->im['xmpp']  : false;
+		
+		$homepage = ( isset($this->contact['homepage']) ) ? $this->contact['homepage'] : false;
+		$location = ( isset($this->contact['location']) ) ? $this->contact['location'] : false;
+		$job = ( isset($this->contact['job']) ) ? $this->contact['job'] : false;
+		$hobbies = ( isset($this->contact['hobbies']) ) ? $this->contact['hobbies'] : false;
+		
+		if ( empty($this->username) )
+		{
+			// @error One or more required parameters not set
+			return 'Admin_UserManager_SmartForm::render: Invalid parameter ($form->username)';
+		}
+		
+		if ( empty($this->user_id) )
+		{
+			// @error One or more required parameters not set
+			return 'Admin_UserManager_SmartForm::render: Invalid parameter ($form->user_id)';
+		}
+		
+		if ( empty($this->email) )
+		{
+			// @error One or more required parameters not set
+			return 'Admin_UserManager_SmartForm::render: Invalid parameter ($form->email)';
+		}
+		
+		$form_action = makeUrlNS('Special', 'Administration', 'module=' . $paths->cpage['module'], true);
+		$aes_javascript = $session->aes_javascript("useredit_$this->uuid", 'new_password');
+		
+		// build rank list
+		$q = $db->sql_query('SELECT rank_id, rank_title FROM ' . table_prefix . 'ranks');
+		if ( !$q )
+			$db->_die();
+		$rank_list = '<option value="NULL"' . ( $this->user_rank === NULL ? ' selected="selected"' : '' ) . '>--</option>' . "\n";
+		while ( $row = $db->fetchrow() )
+		{
+			$rank_list .= '<option value="' . $row['rank_id'] . '"' . ( $row['rank_id'] == $this->user_rank ? ' selected="selected"' : '' ) . '>' . htmlspecialchars($lang->get($row['rank_title'])) . '</option>' . "\n";
+		}
+		
+		$parser->assign_vars(array(
+				'UUID' => $this->uuid,
+				'USERNAME' => $this->username,
+				'EMAIL' => $this->email,
+				'USER_ID' => $this->user_id,
+				'AES_FORM' => $session->generate_aes_form(),
+				'REAL_NAME' => $this->real_name,
+				'SIGNATURE_FIELD' => $template->tinymce_textarea('signature', $this->signature, 10, 50),
+				'USER_TITLE' => $this->user_title,
+				'USER_LEVEL_MEMBER' => USER_LEVEL_CHPREF,
+				'USER_LEVEL_MOD' => USER_LEVEL_MOD,
+				'USER_LEVEL_ADMIN' => USER_LEVEL_ADMIN,
+				'AES_JAVASCRIPT' => $aes_javascript,
+				'IM_AIM' => $im_aim,
+				'IM_YAHOO' => $im_yahoo,
+				'IM_WLM' => $im_msn,
+				'IM_XMPP' => $im_xmpp,
+				'HOMEPAGE' => $homepage,
+				'LOCATION' => $location,
+				'JOB' => $job,
+				'HOBBIES' => $hobbies,
+				'FORM_ACTION' => $form_action,
+				'REG_IP_ADDR' => $this->reg_ip_addr,
+				'RANK_LIST' => $rank_list,
+				'GRAVATAR_URL' => make_gravatar_url($this->email, 16)
+			));
+		
+		if ( $this->has_avatar )
+		{
+			$parser->assign_vars(array(
+					'AVATAR_SRC' => make_avatar_url($this->user_id, $this->avi_type),
+					'AVATAR_ALT' => $lang->get('usercp_avatar_image_alt', array('username' => $this->username), $this->email)
+				));
+		}
+		
+		$parser->assign_bool(array(
+				'password_meter' => ( getConfig('pw_strength_enable') == '1' ),
+				'ul_member' => ( $this->user_level == USER_LEVEL_CHPREF ),
+				'ul_mod' => ( $this->user_level == USER_LEVEL_MOD ),
+				'ul_admin' => ( $this->user_level == USER_LEVEL_ADMIN ),
+				'account_active' => ( $this->account_active === true ),
+				'email_public' => ( $this->email_public === true ),
+				'same_user' => ( $this->user_id == $session->user_id ),
+				'user_has_avatar' => ( $this->has_avatar ),
+				'have_reg_ip' => ( intval(@strlen($this->reg_ip_addr)) > 0 && is_valid_ip($this->reg_ip_addr) )
+			));
+		
+		$parsed = $parser->run();
+		return $parsed;
+	}
+	
 }
 
 function acp_usermanager_lockouts($homewrap = false)
 {
-  global $db, $session, $paths, $template, $plugins; // Common objects
-  global $lang;
-  
-  // Locked out users
-  
-  if ( !empty($_GET['clear_lockout']) && is_valid_ip($_GET['clear_lockout']) )
-  {
-    $ip = $db->escape($_GET['clear_lockout']);
-    $q = $db->sql_query('DELETE FROM ' . table_prefix . "lockout WHERE ipaddr = '$ip' AND timestamp > ( " . time() . " - (" . getConfig('lockout_duration', 15) . "*60) );");
-    if ( !$q )
-      $db->_die();
-    
-    echo '<div class="info-box">' . $lang->get('acphome_msg_lockout_clear_success', array('ip' => htmlspecialchars($ip))) . '</div>';
-  }
-  
-  $q = $db->sql_query('SELECT COUNT(id) AS fail_count, ipaddr, username, timestamp FROM ' . table_prefix . "lockout\n"
-                    . "  WHERE timestamp > ( " . time() . " - " . intval(getConfig('lockout_duration', 15)) . "*60 ) GROUP BY ipaddr ORDER BY COUNT(id) DESC, timestamp DESC;");
-  if ( !$q )
-    $db->_die();
-  
-  if ( $db->numrows() > 0 )
-  {
-    if ( $homewrap )
-      echo '<div class="acphome-box notice">';
-    echo '<h3>' . $lang->get('acphome_msg_users_locked_out') . '</h3>';
-    echo '<p>' . $lang->get('acphome_msg_users_locked_out_hint') . '</p>';
-    
-    ?>
-    <div class="tblholder" style="margin-bottom: 10px;">
-    <table width="100%" cellspacing="1" cellpadding="4">
-      <tr>
-        <th><?php echo $lang->get('acphome_th_locked_out_ip'); ?></th>
-        <th><?php echo $lang->get('acphome_th_locked_out_username'); ?></th>
-        <th><?php echo $lang->get('acphome_th_locked_out_status'); ?></th>
-        <th><?php echo $lang->get('acphome_th_locked_out_time'); ?></th>
-        <th></th>
-      </tr>
-    <?php
-    
-    while ( $row = $db->fetchrow() )
-    {
-      echo '<tr>';
-      echo '<td class="row1">' . htmlspecialchars($row['ipaddr']) . '</td>';
-      echo '<td class="row2">' . htmlspecialchars($row['username']) . '</td>';
-      // status
-      echo '<td class="row1" style="text-align: center;">' .
-            ( $row['fail_count'] >= getConfig('lockout_threshold', 5)
-                ? '<b>' . $lang->get('acphome_lbl_locked_out_banned') . '</b>'
-                : $lang->get('acphome_lbl_locked_out_warned', array('fail_count' => $row['fail_count']))
-            )
-            . '</td>';
-      // time left
-      if ( $row['fail_count'] >= getConfig('lockout_threshold', 5) )
-      {
-        $expire_time = $row['timestamp'] + ( getConfig('lockout_duration', 15) * 60 );
-        $time_left = round(($expire_time - time()) / 60);
-        $minutes = $time_left == 1 ? $lang->get('etc_unit_minute') : $lang->get('etc_unit_minutes');
-        echo '<td class="row2" style="text-align: center;">' . "$time_left $minutes" . '</td>';
-      }
-      else
-      {
-        echo '<td class="row2" style="text-align: center;">&ndash;</td>';
-      }
-      // action
-      $btn_text = $row['fail_count'] >= getConfig('lockout_threshold', 5) ? $lang->get('acphome_btn_lockout_unblock') : $lang->get('acphome_btn_lockout_clear');
-      echo '<td class="row1" style="text-align: center;"><a href="#" onclick="ajaxPage(\'' . $paths->nslist['Admin'] . 'UserManager\', \'clear_lockout=' . htmlspecialchars($row['ipaddr']) . '\'); return false;">' . $btn_text . '</a></td>';
-      echo '</tr>';
-    }
-    echo '</table>';
-    echo '</div>';
-    if ( $homewrap )
-      echo '</div>';
-  }
-  
-  $db->free_result();
+	global $db, $session, $paths, $template, $plugins; // Common objects
+	global $lang;
+	
+	// Locked out users
+	
+	if ( !empty($_GET['clear_lockout']) && is_valid_ip($_GET['clear_lockout']) )
+	{
+		$ip = $db->escape($_GET['clear_lockout']);
+		$q = $db->sql_query('DELETE FROM ' . table_prefix . "lockout WHERE ipaddr = '$ip' AND timestamp > ( " . time() . " - (" . getConfig('lockout_duration', 15) . "*60) );");
+		if ( !$q )
+			$db->_die();
+		
+		echo '<div class="info-box">' . $lang->get('acphome_msg_lockout_clear_success', array('ip' => htmlspecialchars($ip))) . '</div>';
+	}
+	
+	$q = $db->sql_query('SELECT COUNT(id) AS fail_count, ipaddr, username, timestamp FROM ' . table_prefix . "lockout\n"
+										. "  WHERE timestamp > ( " . time() . " - " . intval(getConfig('lockout_duration', 15)) . "*60 ) GROUP BY ipaddr ORDER BY COUNT(id) DESC, timestamp DESC;");
+	if ( !$q )
+		$db->_die();
+	
+	if ( $db->numrows() > 0 )
+	{
+		if ( $homewrap )
+			echo '<div class="acphome-box notice">';
+		echo '<h3>' . $lang->get('acphome_msg_users_locked_out') . '</h3>';
+		echo '<p>' . $lang->get('acphome_msg_users_locked_out_hint') . '</p>';
+		
+		?>
+		<div class="tblholder" style="margin-bottom: 10px;">
+		<table width="100%" cellspacing="1" cellpadding="4">
+			<tr>
+				<th><?php echo $lang->get('acphome_th_locked_out_ip'); ?></th>
+				<th><?php echo $lang->get('acphome_th_locked_out_username'); ?></th>
+				<th><?php echo $lang->get('acphome_th_locked_out_status'); ?></th>
+				<th><?php echo $lang->get('acphome_th_locked_out_time'); ?></th>
+				<th></th>
+			</tr>
+		<?php
+		
+		while ( $row = $db->fetchrow() )
+		{
+			echo '<tr>';
+			echo '<td class="row1">' . htmlspecialchars($row['ipaddr']) . '</td>';
+			echo '<td class="row2">' . htmlspecialchars($row['username']) . '</td>';
+			// status
+			echo '<td class="row1" style="text-align: center;">' .
+						( $row['fail_count'] >= getConfig('lockout_threshold', 5)
+								? '<b>' . $lang->get('acphome_lbl_locked_out_banned') . '</b>'
+								: $lang->get('acphome_lbl_locked_out_warned', array('fail_count' => $row['fail_count']))
+						)
+						. '</td>';
+			// time left
+			if ( $row['fail_count'] >= getConfig('lockout_threshold', 5) )
+			{
+				$expire_time = $row['timestamp'] + ( getConfig('lockout_duration', 15) * 60 );
+				$time_left = round(($expire_time - time()) / 60);
+				$minutes = $time_left == 1 ? $lang->get('etc_unit_minute') : $lang->get('etc_unit_minutes');
+				echo '<td class="row2" style="text-align: center;">' . "$time_left $minutes" . '</td>';
+			}
+			else
+			{
+				echo '<td class="row2" style="text-align: center;">&ndash;</td>';
+			}
+			// action
+			$btn_text = $row['fail_count'] >= getConfig('lockout_threshold', 5) ? $lang->get('acphome_btn_lockout_unblock') : $lang->get('acphome_btn_lockout_clear');
+			echo '<td class="row1" style="text-align: center;"><a href="#" onclick="ajaxPage(\'' . $paths->nslist['Admin'] . 'UserManager\', \'clear_lockout=' . htmlspecialchars($row['ipaddr']) . '\'); return false;">' . $btn_text . '</a></td>';
+			echo '</tr>';
+		}
+		echo '</table>';
+		echo '</div>';
+		if ( $homewrap )
+			echo '</div>';
+	}
+	
+	$db->free_result();
 }