plugins/SpecialUserFuncs.php
changeset 1227 bdac73ed481e
parent 1222 d1ded7b4c775
child 1243 db42b7c50e57
equal deleted inserted replaced
1226:de56132c008d 1227:bdac73ed481e
     1 <?php
     1 <?php
     2 /**!info**
     2 /**!info**
     3 {
     3 {
     4   "Plugin Name"  : "plugin_specialuserfuncs_title",
     4 	"Plugin Name"  : "plugin_specialuserfuncs_title",
     5   "Plugin URI"   : "http://enanocms.org/",
     5 	"Plugin URI"   : "http://enanocms.org/",
     6   "Description"  : "plugin_specialuserfuncs_desc",
     6 	"Description"  : "plugin_specialuserfuncs_desc",
     7   "Author"       : "Dan Fuhry",
     7 	"Author"       : "Dan Fuhry",
     8   "Version"      : "1.1.6",
     8 	"Version"      : "1.1.6",
     9   "Author URI"   : "http://enanocms.org/"
     9 	"Author URI"   : "http://enanocms.org/"
    10 }
    10 }
    11 **!*/
    11 **!*/
    12 
    12 
    13 /*
    13 /*
    14  * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
    14  * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
    25 
    25 
    26 // $plugins->attachHook('session_started', 'SpecialUserFuncs_paths_init();');
    26 // $plugins->attachHook('session_started', 'SpecialUserFuncs_paths_init();');
    27 
    27 
    28 function SpecialUserFuncs_paths_init()
    28 function SpecialUserFuncs_paths_init()
    29 {
    29 {
    30   register_special_page('Login', 'specialpage_log_in');
    30 	register_special_page('Login', 'specialpage_log_in');
    31   register_special_page('Logout', 'specialpage_log_out');
    31 	register_special_page('Logout', 'specialpage_log_out');
    32   register_special_page('Register', 'specialpage_register');
    32 	register_special_page('Register', 'specialpage_register');
    33   register_special_page('Preferences', 'specialpage_preferences');
    33 	register_special_page('Preferences', 'specialpage_preferences');
    34   register_special_page('Contributions', 'specialpage_contributions');
    34 	register_special_page('Contributions', 'specialpage_contributions');
    35   register_special_page('ChangeStyle', 'specialpage_change_theme');
    35 	register_special_page('ChangeStyle', 'specialpage_change_theme');
    36   register_special_page('ActivateAccount', 'specialpage_activate_account');
    36 	register_special_page('ActivateAccount', 'specialpage_activate_account');
    37   register_special_page('Captcha', 'specialpage_captcha');
    37 	register_special_page('Captcha', 'specialpage_captcha');
    38   register_special_page('PasswordReset', 'specialpage_password_reset');
    38 	register_special_page('PasswordReset', 'specialpage_password_reset');
    39   register_special_page('Memberlist', 'specialpage_member_list');
    39 	register_special_page('Memberlist', 'specialpage_member_list');
    40   register_special_page('LangExportJSON', 'specialpage_language_export', false);
    40 	register_special_page('LangExportJSON', 'specialpage_language_export', false);
    41   register_special_page('Avatar', 'specialpage_avatar', false);
    41 	register_special_page('Avatar', 'specialpage_avatar', false);
    42 }
    42 }
    43 
    43 
    44 // function names are IMPORTANT!!! The name pattern is: page_<namespace ID>_<page URLname, without namespace>
    44 // function names are IMPORTANT!!! The name pattern is: page_<namespace ID>_<page URLname, without namespace>
    45 
    45 
    46 $__login_status = '';
    46 $__login_status = '';
    47 
    47 
    48 function page_Special_Login()
    48 function page_Special_Login()
    49 {
    49 {
    50   global $db, $session, $paths, $template, $plugins; // Common objects
    50 	global $db, $session, $paths, $template, $plugins; // Common objects
    51   global $login_result;
    51 	global $login_result;
    52   global $lang, $output;
    52 	global $lang, $output;
    53   
    53 	
    54   // Determine which level we're going up to
    54 	// Determine which level we're going up to
    55   $level = ( isset($_GET['level']) && in_array($_GET['level'], array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') ) ) ? intval($_GET['level']) : USER_LEVEL_MEMBER;
    55 	$level = ( isset($_GET['level']) && in_array($_GET['level'], array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') ) ) ? intval($_GET['level']) : USER_LEVEL_MEMBER;
    56   if ( isset($_POST['login']) )
    56 	if ( isset($_POST['login']) )
    57   {
    57 	{
    58     if ( in_array($_POST['level'], array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') ) )
    58 		if ( in_array($_POST['level'], array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') ) )
    59     {
    59 		{
    60       $level = intval($_POST['level']);
    60 			$level = intval($_POST['level']);
    61     }
    61 		}
    62   }
    62 	}
    63   // Don't allow going from guest straight to elevated
    63 	// Don't allow going from guest straight to elevated
    64   // FIXME do we want to allow this with a CSRF check?
    64 	// FIXME do we want to allow this with a CSRF check?
    65   if ( $level > USER_LEVEL_MEMBER && !$session->user_logged_in )
    65 	if ( $level > USER_LEVEL_MEMBER && !$session->user_logged_in )
    66   {
    66 	{
    67     $level = USER_LEVEL_MEMBER;
    67 		$level = USER_LEVEL_MEMBER;
    68   }
    68 	}
    69   
    69 	
    70   // If we're already at or above this level, redirect to the target page or, if no target
    70 	// If we're already at or above this level, redirect to the target page or, if no target
    71   // specified, back to the main page.
    71 	// specified, back to the main page.
    72   if ( $level <= USER_LEVEL_MEMBER && $session->user_logged_in )
    72 	if ( $level <= USER_LEVEL_MEMBER && $session->user_logged_in )
    73   {
    73 	{
    74     if ( $target = $paths->getAllParams() )
    74 		if ( $target = $paths->getAllParams() )
    75     {
    75 		{
    76       redirect(makeUrl($target), '', '', 0);
    76 			redirect(makeUrl($target), '', '', 0);
    77     }
    77 		}
    78     $paths->main_page();
    78 		$paths->main_page();
    79   }
    79 	}
    80   
    80 	
    81   // Lockout aliasing
    81 	// Lockout aliasing
    82   $lockout =& $login_result['lockout'];
    82 	$lockout =& $login_result['lockout'];
    83   
    83 	
    84   $output->header();
    84 	$output->header();
    85   echo '<form action="' . makeUrl($paths->nslist['Special'].'Login') . '" method="post" name="loginform" onsubmit="try { return runEncryption(); } catch(e) { console.error(e); };">';
    85 	echo '<form action="' . makeUrl($paths->nslist['Special'].'Login') . '" method="post" name="loginform" onsubmit="try { return runEncryption(); } catch(e) { console.error(e); };">';
    86   
    86 	
    87   if ( $p = $paths->getAllParams() )
    87 	if ( $p = $paths->getAllParams() )
    88   {
    88 	{
    89     echo '<input type="hidden" name="return_to" value="' . htmlspecialchars($p) . '" />';
    89 		echo '<input type="hidden" name="return_to" value="' . htmlspecialchars($p) . '" />';
    90   }
    90 	}
    91   else if ( isset($_POST['login']) && isset($_POST['return_to']) )
    91 	else if ( isset($_POST['login']) && isset($_POST['return_to']) )
    92   {
    92 	{
    93     echo '<input type="hidden" name="return_to" value="' . htmlspecialchars($_POST['return_to']) . '" />';
    93 		echo '<input type="hidden" name="return_to" value="' . htmlspecialchars($_POST['return_to']) . '" />';
    94   }
    94 	}
    95   
    95 	
    96   // determine what the "remember me" checkbox should say
    96 	// determine what the "remember me" checkbox should say
    97   $session_time = intval(getConfig('session_remember_time', '30'));
    97 	$session_time = intval(getConfig('session_remember_time', '30'));
    98   if ( $session_time === 0 )
    98 	if ( $session_time === 0 )
    99   {
    99 	{
   100     // sessions are infinite
   100 		// sessions are infinite
   101     $text_remember = $lang->get('user_login_check_remember_infinite');
   101 		$text_remember = $lang->get('user_login_check_remember_infinite');
   102   }
   102 	}
   103   else
   103 	else
   104   {
   104 	{
   105     // is the number of days evenly divisible by 7? if so, use weeks
   105 		// is the number of days evenly divisible by 7? if so, use weeks
   106     if ( $session_time % 7 == 0 )
   106 		if ( $session_time % 7 == 0 )
   107     {
   107 		{
   108       $session_time = $session_time / 7;
   108 			$session_time = $session_time / 7;
   109       $unit = 'week';
   109 			$unit = 'week';
   110     }
   110 		}
   111     else
   111 		else
   112     {
   112 		{
   113       $unit = 'day';
   113 			$unit = 'day';
   114     }
   114 		}
   115     // if it's not equal to 1, pluralize it
   115 		// if it's not equal to 1, pluralize it
   116     if ( $session_time != 1 )
   116 		if ( $session_time != 1 )
   117     {
   117 		{
   118       $unit .= $lang->get('meta_plural');
   118 			$unit .= $lang->get('meta_plural');
   119     }
   119 		}
   120     $text_remember = $lang->get('user_login_check_remember', array(
   120 		$text_remember = $lang->get('user_login_check_remember', array(
   121         'session_length' => $session_time,
   121 				'session_length' => $session_time,
   122         'length_units' => $lang->get("etc_unit_$unit")
   122 				'length_units' => $lang->get("etc_unit_$unit")
   123       ));
   123 			));
   124   }
   124 	}
   125   
   125 	
   126   if ( $error_text = login_get_error($login_result) )
   126 	if ( $error_text = login_get_error($login_result) )
   127   {
   127 	{
   128     echo '<div class="error-box-mini">' . htmlspecialchars($error_text) . '</div>';
   128 		echo '<div class="error-box-mini">' . htmlspecialchars($error_text) . '</div>';
   129   }
   129 	}
   130   
   130 	
   131   //
   131 	//
   132   // START FORM
   132 	// START FORM
   133   //
   133 	//
   134   ?>
   134 	?>
   135     <div class="tblholder">
   135 		<div class="tblholder">
   136       <table border="0" style="width: 100%;" cellspacing="1" cellpadding="4">
   136 			<table border="0" style="width: 100%;" cellspacing="1" cellpadding="4">
   137         <tr>
   137 				<tr>
   138           <th colspan="3">
   138 					<th colspan="3">
   139             <!-- Table header: "Please enter..." -->
   139 						<!-- Table header: "Please enter..." -->
   140             <?php echo ( $level > USER_LEVEL_MEMBER ) ? $lang->get('user_login_message_short_elev') : $lang->get('user_login_message_short'); ?>
   140 						<?php echo ( $level > USER_LEVEL_MEMBER ) ? $lang->get('user_login_message_short_elev') : $lang->get('user_login_message_short'); ?>
   141           </th>
   141 					</th>
   142         </tr>
   142 				</tr>
   143         <tr>
   143 				<tr>
   144           <td colspan="3" class="row1">
   144 					<td colspan="3" class="row1">
   145             <!-- Introduction text -->
   145 						<!-- Introduction text -->
   146             <?php
   146 						<?php
   147             if ( $level <= USER_LEVEL_MEMBER )
   147 						if ( $level <= USER_LEVEL_MEMBER )
   148               echo '<p>' . $lang->get('user_login_body', array('reg_link' => makeUrlNS('Special', 'Register'))) . '</p>';
   148 							echo '<p>' . $lang->get('user_login_body', array('reg_link' => makeUrlNS('Special', 'Register'))) . '</p>';
   149             else
   149 						else
   150               echo '<p>' . $lang->get('user_login_body_elev') . '</p>';
   150 							echo '<p>' . $lang->get('user_login_body_elev') . '</p>';
   151             ?>
   151 						?>
   152           </td>
   152 					</td>
   153         </tr>
   153 				</tr>
   154         <tr>
   154 				<tr>
   155           <!-- Username field -->
   155 					<!-- Username field -->
   156           <td class="row2">
   156 					<td class="row2">
   157             <?php echo $lang->get('user_login_field_username'); ?>:
   157 						<?php echo $lang->get('user_login_field_username'); ?>:
   158           </td>
   158 					</td>
   159           <td class="row1">
   159 					<td class="row1">
   160             <input name="username" size="25" type="text" value="<?php echo $session->user_logged_in ? htmlspecialchars($session->username) : ''; ?>" />
   160 						<input name="username" size="25" type="text" value="<?php echo $session->user_logged_in ? htmlspecialchars($session->username) : ''; ?>" />
   161           </td>
   161 					</td>
   162           <?php if ( $level <= USER_LEVEL_MEMBER ): ?>
   162 					<?php if ( $level <= USER_LEVEL_MEMBER ): ?>
   163           <!-- Forgot password / create account links -->
   163 					<!-- Forgot password / create account links -->
   164           <td rowspan="<?php echo ( ( $lockout['active'] && $lockout['policy'] == 'captcha' ) ) ? '4' : '2'; ?>" class="row3">
   164 					<td rowspan="<?php echo ( ( $lockout['active'] && $lockout['policy'] == 'captcha' ) ) ? '4' : '2'; ?>" class="row3">
   165             <small><?php echo $lang->get('user_login_forgotpass_blurb', array('forgotpass_link' => makeUrlNS('Special', 'PasswordReset'))); ?><br />
   165 						<small><?php echo $lang->get('user_login_forgotpass_blurb', array('forgotpass_link' => makeUrlNS('Special', 'PasswordReset'))); ?><br />
   166             <?php echo $lang->get('user_login_createaccount_blurb', array('reg_link' => makeUrlNS('Special', 'Register'))); ?></small>
   166 						<?php echo $lang->get('user_login_createaccount_blurb', array('reg_link' => makeUrlNS('Special', 'Register'))); ?></small>
   167           </td>
   167 					</td>
   168           <?php endif; ?>
   168 					<?php endif; ?>
   169         </tr>
   169 				</tr>
   170         <tr>
   170 				<tr>
   171           <!-- Password field -->
   171 					<!-- Password field -->
   172           <td class="row2">
   172 					<td class="row2">
   173             <?php echo $lang->get('user_login_field_password'); ?>:
   173 						<?php echo $lang->get('user_login_field_password'); ?>:
   174           </td><td class="row1"><input name="password" size="25" type="password" /></td>
   174 					</td><td class="row1"><input name="password" size="25" type="password" /></td>
   175          </tr>
   175  				</tr>
   176          
   176  				
   177          <?php
   177  				<?php
   178          // CAPTCHA?
   178  				// CAPTCHA?
   179          if ( $lockout['active'] && $lockout['policy'] == 'captcha' )
   179  				if ( $lockout['active'] && $lockout['policy'] == 'captcha' )
   180          {
   180  				{
   181            ?>
   181  					?>
   182            <!-- CAPTCHA -->
   182  					<!-- CAPTCHA -->
   183            <tr>
   183  					<tr>
   184              <td class="row2" rowspan="2">
   184  						<td class="row2" rowspan="2">
   185                <?php echo $lang->get('user_login_field_captcha'); ?>:
   185  							<?php echo $lang->get('user_login_field_captcha'); ?>:
   186                <br />
   186  							<br />
   187              </td>
   187  						</td>
   188              <td class="row1">
   188  						<td class="row1">
   189                <input type="hidden" name="captcha_hash" value="<?php echo $lockout['captcha']; ?>" />
   189  							<input type="hidden" name="captcha_hash" value="<?php echo $lockout['captcha']; ?>" />
   190                <input name="captcha_code" size="25" type="text" tabindex="<?php echo ( $level <= USER_LEVEL_MEMBER ) ? '3' : '4'; ?>" />
   190  							<input name="captcha_code" size="25" type="text" tabindex="<?php echo ( $level <= USER_LEVEL_MEMBER ) ? '3' : '4'; ?>" />
   191              </td>
   191  						</td>
   192            </tr>
   192  					</tr>
   193            <tr>
   193  					<tr>
   194              <td class="row3">
   194  						<td class="row3">
   195                <img src="<?php echo makeUrlNS('Special', 'Captcha/' . $lockout['captcha']) ?>" onclick="this.src=this.src+'/a';" style="cursor: pointer;" />
   195  							<img src="<?php echo makeUrlNS('Special', 'Captcha/' . $lockout['captcha']) ?>" onclick="this.src=this.src+'/a';" style="cursor: pointer;" />
   196              </td>
   196  						</td>
   197            </tr>
   197  					</tr>
   198            <?php
   198  					<?php
   199          }
   199  				}
   200          
   200  				
   201          // Run hooks
   201  				// Run hooks
   202          $code = $plugins->setHook('login_form_html');
   202  				$code = $plugins->setHook('login_form_html');
   203          foreach ( $code as $cmd )
   203  				foreach ( $code as $cmd )
   204          {
   204  				{
   205            eval($cmd);
   205  					eval($cmd);
   206          }
   206  				}
   207          
   207  				
   208          // level-2 only: "Remember me" switch
   208  				// level-2 only: "Remember me" switch
   209          if ( $level <= USER_LEVEL_MEMBER )
   209  				if ( $level <= USER_LEVEL_MEMBER )
   210          {
   210  				{
   211            ?>
   211  					?>
   212            <tr>
   212  					<tr>
   213              <td class="row2">
   213  						<td class="row2">
   214                <?php echo $lang->get('user_login_field_remember'); ?>
   214  							<?php echo $lang->get('user_login_field_remember'); ?>
   215              </td>
   215  						</td>
   216              <td class="row1" colspan="2">
   216  						<td class="row1" colspan="2">
   217                <label>
   217  							<label>
   218                  <input type="checkbox" name="remember" tabindex="3" />
   218  								<input type="checkbox" name="remember" tabindex="3" />
   219                  <?php echo $text_remember; ?>
   219  								<?php echo $text_remember; ?>
   220                </label>
   220  							</label>
   221              </td>
   221  						</td>
   222            </tr>
   222  					</tr>
   223            
   223  					
   224          <!-- Crypto notice -->
   224  				<!-- Crypto notice -->
   225            <?php
   225  					<?php
   226          }
   226  				}
   227          
   227  				
   228          // lol DeMorgan'd
   228  				// lol DeMorgan'd
   229          $crypto_disable = ( isset($_GET['use_crypt']) && $_GET['use_crypt'] == '0' );
   229  				$crypto_disable = ( isset($_GET['use_crypt']) && $_GET['use_crypt'] == '0' );
   230          
   230  				
   231          // Crypto disable: crypto on, normal login
   231  				// Crypto disable: crypto on, normal login
   232          if ( $level <= USER_LEVEL_MEMBER && !$crypto_disable )
   232  				if ( $level <= USER_LEVEL_MEMBER && !$crypto_disable )
   233          {
   233  				{
   234            echo '<tr>
   234  					echo '<tr>
   235              <td class="row3" colspan="3">';
   235  						<td class="row3" colspan="3">';
   236              
   236  						
   237            $returnpage_link = ( $return = $paths->getAllParams() ) ? '/' . $return : '';
   237  					$returnpage_link = ( $return = $paths->getAllParams() ) ? '/' . $return : '';
   238            $nocrypt_link = makeUrlNS('Special', "Login$returnpage_link", "level=$level&use_crypt=0", true);
   238  					$nocrypt_link = makeUrlNS('Special', "Login$returnpage_link", "level=$level&use_crypt=0", true);
   239            echo '<p><b>' . $lang->get('user_login_nocrypt_title') . '</b> ' . $lang->get('user_login_nocrypt_body', array('nocrypt_link' => $nocrypt_link)) . '</p>';
   239  					echo '<p><b>' . $lang->get('user_login_nocrypt_title') . '</b> ' . $lang->get('user_login_nocrypt_body', array('nocrypt_link' => $nocrypt_link)) . '</p>';
   240            echo '<p>' . $lang->get('user_login_nocrypt_countrylist') . '</p>';
   240  					echo '<p>' . $lang->get('user_login_nocrypt_countrylist') . '</p>';
   241            
   241  					
   242            echo '  </td>
   242  					echo '  </td>
   243            </tr>';
   243  					</tr>';
   244          }
   244  				}
   245          // Crypto disable: crypto OFF, normal login
   245  				// Crypto disable: crypto OFF, normal login
   246          else if ( $level <= USER_LEVEL_MEMBER && $crypto_disable )
   246  				else if ( $level <= USER_LEVEL_MEMBER && $crypto_disable )
   247          {
   247  				{
   248            echo '<tr>
   248  					echo '<tr>
   249              <td class="row3" colspan="3">';
   249  						<td class="row3" colspan="3">';
   250              
   250  						
   251            $returnpage_link = ( $return = $paths->getAllParams() ) ? '/' . $return : '';
   251  					$returnpage_link = ( $return = $paths->getAllParams() ) ? '/' . $return : '';
   252            $usecrypt_link = makeUrlNS('Special', "Login$returnpage_link", "level=$level&use_crypt=1", true);
   252  					$usecrypt_link = makeUrlNS('Special', "Login$returnpage_link", "level=$level&use_crypt=1", true);
   253            echo '<p><b>' . $lang->get('user_login_usecrypt_title') . '</b> ' . $lang->get('user_login_usecrypt_body', array('usecrypt_link' => $usecrypt_link)) . '</p>';
   253  					echo '<p><b>' . $lang->get('user_login_usecrypt_title') . '</b> ' . $lang->get('user_login_usecrypt_body', array('usecrypt_link' => $usecrypt_link)) . '</p>';
   254            echo '<p>' . $lang->get('user_login_usecrypt_countrylist') . '</p>';
   254  					echo '<p>' . $lang->get('user_login_usecrypt_countrylist') . '</p>';
   255            
   255  					
   256            echo '  </td>
   256  					echo '  </td>
   257            </tr>';
   257  					</tr>';
   258          }
   258  				}
   259          // Crypto disable: crypto on, ELEV login
   259  				// Crypto disable: crypto on, ELEV login
   260          else if ( $level > USER_LEVEL_MEMBER && $GLOBALS['dh_supported'] )
   260  				else if ( $level > USER_LEVEL_MEMBER && $GLOBALS['dh_supported'] )
   261          {
   261  				{
   262            echo '<tr>';
   262  					echo '<tr>';
   263            echo '<td class="row3" colspan="3">';
   263  					echo '<td class="row3" colspan="3">';
   264            echo '<p>' . $lang->get('user_login_dh_notice') . '</p>';
   264  					echo '<p>' . $lang->get('user_login_dh_notice') . '</p>';
   265            echo '</td>';
   265  					echo '</td>';
   266            echo '</tr>';
   266  					echo '</tr>';
   267          }
   267  				}
   268          ?>
   268  				?>
   269          
   269  				
   270          <!-- Submit button -->
   270  				<!-- Submit button -->
   271          <tr>
   271  				<tr>
   272            <th colspan="3" style="text-align: center" class="subhead">
   272  					<th colspan="3" style="text-align: center" class="subhead">
   273              <input type="hidden" name="login" value="true" />
   273  						<input type="hidden" name="login" value="true" />
   274              <input type="submit" value="<?php echo $lang->get('user_login_btn_log_in'); ?>" />
   274  						<input type="submit" value="<?php echo $lang->get('user_login_btn_log_in'); ?>" />
   275            </th>
   275  					</th>
   276          </tr>
   276  				</tr>
   277       </table>
   277 			</table>
   278     </div>
   278 		</div>
   279     
   279 		
   280       <input type="hidden" name="level" value="<?php echo (string)$level; ?>" />
   280 			<input type="hidden" name="level" value="<?php echo (string)$level; ?>" />
   281       <?php if ( $level <= USER_LEVEL_MEMBER ): ?>
   281 			<?php if ( $level <= USER_LEVEL_MEMBER ): ?>
   282       <script type="text/javascript">
   282 			<script type="text/javascript">
   283         document.forms.loginform.username.focus();
   283 				document.forms.loginform.username.focus();
   284       </script>
   284 			</script>
   285       <?php else: ?>
   285 			<?php else: ?>
   286       <script type="text/javascript">
   286 			<script type="text/javascript">
   287         document.forms.loginform.pass.focus();
   287 				document.forms.loginform.pass.focus();
   288       </script>
   288 			</script>
   289       <?php endif; ?>
   289 			<?php endif; ?>
   290       <?php
   290 			<?php
   291       echo $session->generate_aes_form();
   291 			echo $session->generate_aes_form();
   292       
   292 			
   293       // Any additional parameters that need to be passed back?
   293 			// Any additional parameters that need to be passed back?
   294       if ( $p = $paths->getAllParams() )
   294 			if ( $p = $paths->getAllParams() )
   295       {
   295 			{
   296         // ... only if we have a return_to destination.
   296 				// ... only if we have a return_to destination.
   297         $get_fwd = $_GET;
   297 				$get_fwd = $_GET;
   298         unset($get_fwd['do']);
   298 				unset($get_fwd['do']);
   299         if ( isset($get_fwd['target_do']) )
   299 				if ( isset($get_fwd['target_do']) )
   300         {
   300 				{
   301           $get_fwd['do'] = $get_fwd['target_do'];
   301 					$get_fwd['do'] = $get_fwd['target_do'];
   302           unset($get_fwd['target_do']);
   302 					unset($get_fwd['target_do']);
   303         }
   303 				}
   304         if ( isset($get_fwd['level']) )
   304 				if ( isset($get_fwd['level']) )
   305           unset($get_fwd['level']);
   305 					unset($get_fwd['level']);
   306         if ( isset($get_fwd['title']) )
   306 				if ( isset($get_fwd['title']) )
   307           unset($get_fwd['title']);
   307 					unset($get_fwd['title']);
   308         
   308 				
   309         if ( !empty($get_fwd) )
   309 				if ( !empty($get_fwd) )
   310         {
   310 				{
   311           $get_string = htmlspecialchars(enano_json_encode($get_fwd));
   311 					$get_string = htmlspecialchars(enano_json_encode($get_fwd));
   312           echo '<input type="hidden" name="get_fwd" value="' . $get_string . '" />';
   312 					echo '<input type="hidden" name="get_fwd" value="' . $get_string . '" />';
   313         }
   313 				}
   314       }
   314 			}
   315       else if ( isset($_POST['get_fwd']) )
   315 			else if ( isset($_POST['get_fwd']) )
   316       {
   316 			{
   317         echo '<input type="hidden" name="get_fwd" value="' . htmlspecialchars($_POST['get_fwd']) . '" />';
   317 				echo '<input type="hidden" name="get_fwd" value="' . htmlspecialchars($_POST['get_fwd']) . '" />';
   318       }
   318 			}
   319       ?>
   319 			?>
   320     </form>
   320 		</form>
   321     <?php
   321 		<?php
   322       if ( !$crypto_disable )
   322 			if ( !$crypto_disable )
   323         echo $session->aes_javascript('loginform', 'password');
   323 				echo $session->aes_javascript('loginform', 'password');
   324     ?>
   324 		?>
   325   <?php
   325 	<?php
   326   $output->footer();
   326 	$output->footer();
   327 }
   327 }
   328 
   328 
   329 function page_Special_Login_preloader() // adding _preloader to the end of the function name calls the function before $session and $paths setup routines are called
   329 function page_Special_Login_preloader() // adding _preloader to the end of the function name calls the function before $session and $paths setup routines are called
   330 {
   330 {
   331   global $db, $session, $paths, $template, $plugins; // Common objects
   331 	global $db, $session, $paths, $template, $plugins; // Common objects
   332   global $login_result;
   332 	global $login_result;
   333   global $lang;
   333 	global $lang;
   334   
   334 	
   335   // Are we calling the JSON interface?
   335 	// Are we calling the JSON interface?
   336   $paths->fullpage = $GLOBALS['urlname'];
   336 	$paths->fullpage = $GLOBALS['urlname'];
   337   if ( $paths->getParam(0) === 'action.json' )
   337 	if ( $paths->getParam(0) === 'action.json' )
   338   {
   338 	{
   339     if ( !isset($_POST['r']) )
   339 		if ( !isset($_POST['r']) )
   340       die('No request.');
   340 			die('No request.');
   341     
   341 		
   342     $request = $_POST['r'];
   342 		$request = $_POST['r'];
   343     try
   343 		try
   344     {
   344 		{
   345       $request = enano_json_decode($request);
   345 			$request = enano_json_decode($request);
   346     }
   346 		}
   347     catch ( Exception $e )
   347 		catch ( Exception $e )
   348     {
   348 		{
   349       die(enano_json_encode(array(
   349 			die(enano_json_encode(array(
   350           'mode' => 'error',
   350 					'mode' => 'error',
   351           'error' => 'ERR_JSON_PARSE_FAILED'
   351 					'error' => 'ERR_JSON_PARSE_FAILED'
   352         )));
   352 				)));
   353     }
   353 		}
   354     
   354 		
   355     echo enano_json_encode($session->process_login_request($request));
   355 		echo enano_json_encode($session->process_login_request($request));
   356     
   356 		
   357     $db->close();
   357 		$db->close();
   358     exit;
   358 		exit;
   359   }
   359 	}
   360   
   360 	
   361   // No. Process incoming results from the HTML version.
   361 	// No. Process incoming results from the HTML version.
   362   if ( isset($_POST['login']) )
   362 	if ( isset($_POST['login']) )
   363   {
   363 	{
   364     $_POST['password'] = $session->get_aes_post();
   364 		$_POST['password'] = $session->get_aes_post();
   365     
   365 		
   366     $result = $session->process_login_request(array(
   366 		$result = $session->process_login_request(array(
   367         'mode' => 'login_pt',
   367 				'mode' => 'login_pt',
   368         'userinfo' => $_POST,
   368 				'userinfo' => $_POST,
   369         'level' => $_POST['level'],
   369 				'level' => $_POST['level'],
   370         'captcha_hash' => isset($_POST['captcha_hash']) ? $_POST['captcha_hash'] : false,
   370 				'captcha_hash' => isset($_POST['captcha_hash']) ? $_POST['captcha_hash'] : false,
   371         'captcha_code' => isset($_POST['captcha_code']) ? $_POST['captcha_code'] : false
   371 				'captcha_code' => isset($_POST['captcha_code']) ? $_POST['captcha_code'] : false
   372       ));
   372 			));
   373     
   373 		
   374     if ( $result['mode'] === 'login_success' )
   374 		if ( $result['mode'] === 'login_success' )
   375     {
   375 		{
   376       //
   376 			//
   377       // LOGIN SUCCESS.
   377 			// LOGIN SUCCESS.
   378       // Redirect as necessary.
   378 			// Redirect as necessary.
   379       //
   379 			//
   380       
   380 			
   381       // Load our preferences
   381 			// Load our preferences
   382       $session->start();
   382 			$session->start();
   383       
   383 			
   384       // Decode get_add
   384 			// Decode get_add
   385       $get_add = false;
   385 			$get_add = false;
   386       if ( isset($_POST['get_fwd']) )
   386 			if ( isset($_POST['get_fwd']) )
   387       {
   387 			{
   388         try
   388 				try
   389         {
   389 				{
   390           $get_fwd = enano_json_decode($_POST['get_fwd']);
   390 					$get_fwd = enano_json_decode($_POST['get_fwd']);
   391           $get_add = '';
   391 					$get_add = '';
   392           foreach ( $get_fwd as $key => $value )
   392 					foreach ( $get_fwd as $key => $value )
   393           {
   393 					{
   394             $get_add .= "&{$key}=" . urlencode($value);
   394 						$get_add .= "&{$key}=" . urlencode($value);
   395           }
   395 					}
   396           $get_add = ltrim($get_add, '&');
   396 					$get_add = ltrim($get_add, '&');
   397         }
   397 				}
   398         catch ( Exception $e )
   398 				catch ( Exception $e )
   399         {
   399 				{
   400         }
   400 				}
   401       }
   401 			}
   402       
   402 			
   403       // Going to a user-specified page?
   403 			// Going to a user-specified page?
   404       if ( isset($_POST['return_to']) )
   404 			if ( isset($_POST['return_to']) )
   405       {
   405 			{
   406         // yea
   406 				// yea
   407         $name = get_page_title($_POST['return_to']);
   407 				$name = get_page_title($_POST['return_to']);
   408         $subst = array(
   408 				$subst = array(
   409             'username' => $session->username,
   409 						'username' => $session->username,
   410             'redir_target' => $name
   410 						'redir_target' => $name
   411           );
   411 					);
   412         redirect( makeUrl($_POST['return_to'], $get_add), $lang->get('user_login_success_title'), $lang->get('user_login_success_body', $subst) );
   412 				redirect( makeUrl($_POST['return_to'], $get_add), $lang->get('user_login_success_title'), $lang->get('user_login_success_body', $subst) );
   413       }
   413 			}
   414       else
   414 			else
   415       {
   415 			{
   416         // No, redirect them to the main page
   416 				// No, redirect them to the main page
   417         $subst = array(
   417 				$subst = array(
   418             'username' => $session->username,
   418 						'username' => $session->username,
   419             'redir_target' => $lang->get('user_login_success_body_mainpage')
   419 						'redir_target' => $lang->get('user_login_success_body_mainpage')
   420           );
   420 					);
   421         redirect( makeUrl(get_main_page(), $get_add), $lang->get('user_login_success_title'), $lang->get('user_login_success_body', $subst) );
   421 				redirect( makeUrl(get_main_page(), $get_add), $lang->get('user_login_success_title'), $lang->get('user_login_success_body', $subst) );
   422       }
   422 			}
   423     }
   423 		}
   424     else if ( $result['mode'] === 'login_success_reset' )
   424 		else if ( $result['mode'] === 'login_success_reset' )
   425     {
   425 		{
   426       // They logged in with a temporary password; send them to the reset form
   426 			// They logged in with a temporary password; send them to the reset form
   427       redirect($result['redirect_url'], '', '', 0);
   427 			redirect($result['redirect_url'], '', '', 0);
   428     }
   428 		}
   429     // Otherwise, the result is likely an error.
   429 		// Otherwise, the result is likely an error.
   430     $login_result = $result;
   430 		$login_result = $result;
   431   }
   431 	}
   432   else
   432 	else
   433   {
   433 	{
   434     $login_result = $session->process_login_request(array(
   434 		$login_result = $session->process_login_request(array(
   435         'mode' => 'getkey'
   435 				'mode' => 'getkey'
   436       ));
   436 			));
   437   }
   437 	}
   438   
   438 	
   439   // This is a bit of a hack. The login form generates AES and DiffieHellman keys on its
   439 	// This is a bit of a hack. The login form generates AES and DiffieHellman keys on its
   440   // own, so we need to clean up the ones from the login request API.
   440 	// own, so we need to clean up the ones from the login request API.
   441   if ( !empty($login_result['crypto']) )
   441 	if ( !empty($login_result['crypto']) )
   442   {
   442 	{
   443     $session->process_login_request(array(
   443 		$session->process_login_request(array(
   444         'mode' => 'clean_key',
   444 				'mode' => 'clean_key',
   445         'key_aes' => $login_result['crypto']['aes_key'],
   445 				'key_aes' => $login_result['crypto']['aes_key'],
   446         'key_dh' => $login_result['crypto']['dh_public_key'],
   446 				'key_dh' => $login_result['crypto']['dh_public_key'],
   447       ));
   447 			));
   448   }
   448 	}
   449 }
   449 }
   450 
   450 
   451 /**
   451 /**
   452  * Given a Login API response, find the appropriate error text, if any.
   452  * Given a Login API response, find the appropriate error text, if any.
   453  * @param array LoginAPI response
   453  * @param array LoginAPI response
   454  * @return mixed Error string, or bool(false) if no error.
   454  * @return mixed Error string, or bool(false) if no error.
   455  */
   455  */
   456 
   456 
   457 function login_get_error($response)
   457 function login_get_error($response)
   458 {
   458 {
   459   global $lang;
   459 	global $lang;
   460   
   460 	
   461   if ( !empty($response['lockout']) )
   461 	if ( !empty($response['lockout']) )
   462   {
   462 	{
   463     // set this pluralality thing
   463 		// set this pluralality thing
   464     $response['lockout']['plural'] = $response['lockout']['time_rem'] == 1 ? '' : $lang->get('meta_plural');
   464 		$response['lockout']['plural'] = $response['lockout']['time_rem'] == 1 ? '' : $lang->get('meta_plural');
   465   }
   465 	}
   466   
   466 	
   467   if ( $response['mode'] == 'initial' )
   467 	if ( $response['mode'] == 'initial' )
   468   {
   468 	{
   469     // Just showing the box for the first time. If there's an error now, it's based on a preexisting lockout.
   469 		// Just showing the box for the first time. If there's an error now, it's based on a preexisting lockout.
   470     if ( $response['lockout']['active'] )
   470 		if ( $response['lockout']['active'] )
   471     {
   471 		{
   472       return $lang->get('user_err_locked_out_initial_' . $response['lockout']['policy'], $response['lockout']);
   472 			return $lang->get('user_err_locked_out_initial_' . $response['lockout']['policy'], $response['lockout']);
   473     }
   473 		}
   474     return false;
   474 		return false;
   475   }
   475 	}
   476   else
   476 	else
   477   {
   477 	{
   478     // An attempt was made.
   478 		// An attempt was made.
   479     switch($response['mode'])
   479 		switch($response['mode'])
   480     {
   480 		{
   481       case 'login_failure':
   481 			case 'login_failure':
   482         // Generic login user error.
   482 				// Generic login user error.
   483         $error = '';
   483 				$error = '';
   484         if ( ($x = $lang->get($response['error'])) != $response['error'] )
   484 				if ( ($x = $lang->get($response['error'])) != $response['error'] )
   485           $error = $x;
   485 					$error = $x;
   486         else
   486 				else
   487           $error = $lang->get('user_err_' . $response['error']);
   487 					$error = $lang->get('user_err_' . $response['error']);
   488         if ( $response['lockout']['active'] && $response['lockout']['policy'] == 'lockout' )
   488 				if ( $response['lockout']['active'] && $response['lockout']['policy'] == 'lockout' )
   489         {
   489 				{
   490           // Lockout enforcement was just activated.
   490 					// Lockout enforcement was just activated.
   491           return $lang->get('user_err_locked_out_initial_' . $response['lockout']['policy'], $response['lockout']);
   491 					return $lang->get('user_err_locked_out_initial_' . $response['lockout']['policy'], $response['lockout']);
   492         }
   492 				}
   493         else if ( $response['lockout']['policy'] != 'disable' && !$response['lockout']['active'] && $response['lockout']['fails'] > 0 )
   493 				else if ( $response['lockout']['policy'] != 'disable' && !$response['lockout']['active'] && $response['lockout']['fails'] > 0 )
   494         {
   494 				{
   495           // Lockout is in a warning state.
   495 					// Lockout is in a warning state.
   496           $error .= ' ' . $lang->get('user_err_invalid_credentials_' . $response['lockout']['policy'], $response['lockout']);
   496 					$error .= ' ' . $lang->get('user_err_invalid_credentials_' . $response['lockout']['policy'], $response['lockout']);
   497         }
   497 				}
   498         return $error;
   498 				return $error;
   499         break;
   499 				break;
   500       case 'api_error':
   500 			case 'api_error':
   501         // Error in the API.
   501 				// Error in the API.
   502         return $lang->get('user_err_login_generic_title') + ': ' + $lang->get('user_' . strtolower($response['error']));
   502 				return $lang->get('user_err_login_generic_title') + ': ' + $lang->get('user_' . strtolower($response['error']));
   503         break;
   503 				break;
   504     }
   504 		}
   505   }
   505 	}
   506   
   506 	
   507   return is_string($response['error']) ? $response['error'] : false;
   507 	return is_string($response['error']) ? $response['error'] : false;
   508 }
   508 }
   509 
   509 
   510 function page_Special_Logout()
   510 function page_Special_Logout()
   511 {
   511 {
   512   global $db, $session, $paths, $template, $plugins; // Common objects
   512 	global $db, $session, $paths, $template, $plugins; // Common objects
   513   global $lang;
   513 	global $lang;
   514   
   514 	
   515   if ( !$session->user_logged_in )
   515 	if ( !$session->user_logged_in )
   516     $paths->main_page();
   516 		$paths->main_page();
   517   
   517 	
   518   $token = $paths->getParam(0);
   518 	$token = $paths->getParam(0);
   519   if ( $token !== $session->csrf_token )
   519 	if ( $token !== $session->csrf_token )
   520   {
   520 	{
   521     csrf_request_confirm();
   521 		csrf_request_confirm();
   522   }
   522 	}
   523   
   523 	
   524   $l = $session->logout();
   524 	$l = $session->logout();
   525   if ( $l == 'success' )
   525 	if ( $l == 'success' )
   526   {
   526 	{
   527     $url = makeUrl(get_main_page(), false, true);
   527 		$url = makeUrl(get_main_page(), false, true);
   528     if ( $paths->getParam(1) )
   528 		if ( $paths->getParam(1) )
   529     {
   529 		{
   530       $pi = explode('/', $paths->getAllParams());
   530 			$pi = explode('/', $paths->getAllParams());
   531       $pi = implode('/', array_values(array_slice($pi, 1)));
   531 			$pi = implode('/', array_values(array_slice($pi, 1)));
   532       list($pid, $ns) = RenderMan::strToPageID($pi);
   532 			list($pid, $ns) = RenderMan::strToPageID($pi);
   533       $perms = $session->fetch_page_acl($pid, $ns);
   533 			$perms = $session->fetch_page_acl($pid, $ns);
   534       if ( $perms->get_permissions('read') )
   534 			if ( $perms->get_permissions('read') )
   535       {
   535 			{
   536         $url = makeUrl($pi, false, true);
   536 				$url = makeUrl($pi, false, true);
   537       }
   537 			}
   538     }
   538 		}
   539     redirect($url, $lang->get('user_logout_success_title'), $lang->get('user_logout_success_body'), 3);
   539 		redirect($url, $lang->get('user_logout_success_title'), $lang->get('user_logout_success_body'), 3);
   540   }
   540 	}
   541   $template->header();
   541 	$template->header();
   542   echo '<h3>' . $lang->get('user_logout_err_title') . '</h3>';
   542 	echo '<h3>' . $lang->get('user_logout_err_title') . '</h3>';
   543   echo '<p>' . $l . '</p>';
   543 	echo '<p>' . $l . '</p>';
   544   $template->footer();
   544 	$template->footer();
   545 }
   545 }
   546 
   546 
   547 function page_Special_Register()
   547 function page_Special_Register()
   548 {
   548 {
   549   global $db, $session, $paths, $template, $plugins; // Common objects
   549 	global $db, $session, $paths, $template, $plugins; // Common objects
   550   global $lang;
   550 	global $lang;
   551   
   551 	
   552   if ( $session->user_level < USER_LEVEL_ADMIN && $session->user_logged_in )
   552 	if ( $session->user_level < USER_LEVEL_ADMIN && $session->user_logged_in )
   553   {
   553 	{
   554     $paths->main_page();
   554 		$paths->main_page();
   555   }
   555 	}
   556   
   556 	
   557   // form field trackers
   557 	// form field trackers
   558   $username = '';
   558 	$username = '';
   559   $email = '';
   559 	$email = '';
   560   $realname = '';
   560 	$realname = '';
   561   
   561 	
   562   $terms = getConfig('register_tou');
   562 	$terms = getConfig('register_tou');
   563   
   563 	
   564   if(getConfig('account_activation') == 'disable' && ( ( $session->user_level >= USER_LEVEL_ADMIN && !isset($_GET['IWannaPlayToo']) ) || $session->user_level < USER_LEVEL_ADMIN || !$session->user_logged_in ))
   564 	if(getConfig('account_activation') == 'disable' && ( ( $session->user_level >= USER_LEVEL_ADMIN && !isset($_GET['IWannaPlayToo']) ) || $session->user_level < USER_LEVEL_ADMIN || !$session->user_logged_in ))
   565   {
   565 	{
   566     $s = ($session->user_level >= USER_LEVEL_ADMIN) ? '<p>' . $lang->get('user_reg_err_disabled_body_adminblurb', array( 'reg_link' => makeUrl($paths->page, 'IWannaPlayToo&coppa=no', true) )) . '</p>' : '';
   566 		$s = ($session->user_level >= USER_LEVEL_ADMIN) ? '<p>' . $lang->get('user_reg_err_disabled_body_adminblurb', array( 'reg_link' => makeUrl($paths->page, 'IWannaPlayToo&coppa=no', true) )) . '</p>' : '';
   567     die_friendly($lang->get('user_reg_err_disabled_title'), '<p>' . $lang->get('user_reg_err_disabled_body') . '</p>' . $s);
   567 		die_friendly($lang->get('user_reg_err_disabled_title'), '<p>' . $lang->get('user_reg_err_disabled_body') . '</p>' . $s);
   568   }
   568 	}
   569   // are we locked out from logging in? if so, also lock out registration
   569 	// are we locked out from logging in? if so, also lock out registration
   570   if ( getConfig('lockout_policy') === 'lockout' )
   570 	if ( getConfig('lockout_policy') === 'lockout' )
   571   {
   571 	{
   572     $ip = $db->escape($_SERVER['REMOTE_ADDR']);
   572 		$ip = $db->escape($_SERVER['REMOTE_ADDR']);
   573     $threshold = time() - ( 60 * intval(getConfig('lockout_duration')) );
   573 		$threshold = time() - ( 60 * intval(getConfig('lockout_duration')) );
   574     $limit = intval(getConfig('lockout_threshold'));
   574 		$limit = intval(getConfig('lockout_threshold'));
   575     $q = $db->sql_query('SELECT * FROM ' . table_prefix . "lockout WHERE timestamp >= $threshold ORDER BY timestamp DESC;");
   575 		$q = $db->sql_query('SELECT * FROM ' . table_prefix . "lockout WHERE timestamp >= $threshold ORDER BY timestamp DESC;");
   576     if ( !$q )
   576 		if ( !$q )
   577       $db->_die();
   577 			$db->_die();
   578     if ( $db->numrows() >= $limit )
   578 		if ( $db->numrows() >= $limit )
   579     {
   579 		{
   580       $row = $db->fetchrow();
   580 			$row = $db->fetchrow();
   581       $db->free_result();
   581 			$db->free_result();
   582       $time_rem = intval(getConfig('lockout_duration')) - round((time() - $row['timestamp']) / 60);
   582 			$time_rem = intval(getConfig('lockout_duration')) - round((time() - $row['timestamp']) / 60);
   583       die_friendly($lang->get('user_reg_err_disabled_title'), '<p>' . $lang->get('user_reg_err_locked_out', array('time' => $time_rem)) . '</p>');
   583 			die_friendly($lang->get('user_reg_err_disabled_title'), '<p>' . $lang->get('user_reg_err_locked_out', array('time' => $time_rem)) . '</p>');
   584     }
   584 		}
   585     $db->free_result();
   585 		$db->free_result();
   586   }
   586 	}
   587   if(isset($_POST['submit'])) 
   587 	if(isset($_POST['submit'])) 
   588   {
   588 	{
   589     $_GET['coppa'] = ( isset($_POST['coppa']) ) ? $_POST['coppa'] : 'x';
   589 		$_GET['coppa'] = ( isset($_POST['coppa']) ) ? $_POST['coppa'] : 'x';
   590     
   590 		
   591     $captcharesult = $session->get_captcha($_POST['captchahash']);
   591 		$captcharesult = $session->get_captcha($_POST['captchahash']);
   592     $session->kill_captcha();
   592 		$session->kill_captcha();
   593     // bypass captcha if logged in (at this point, if logged in, we're admin)
   593 		// bypass captcha if logged in (at this point, if logged in, we're admin)
   594     if ( !$session->user_logged_in && strtolower($captcharesult) != strtolower($_POST['captchacode']) )
   594 		if ( !$session->user_logged_in && strtolower($captcharesult) != strtolower($_POST['captchacode']) )
   595     {
   595 		{
   596       $s = $lang->get('user_reg_err_captcha');
   596 			$s = $lang->get('user_reg_err_captcha');
   597     }
   597 		}
   598     else
   598 		else
   599     {
   599 		{
   600       if ( getConfig('enable_coppa') == '1' && ( !isset($_POST['coppa']) || ( isset($_POST['coppa']) && !in_array($_POST['coppa'], array('yes', 'no')) ) ) )
   600 			if ( getConfig('enable_coppa') == '1' && ( !isset($_POST['coppa']) || ( isset($_POST['coppa']) && !in_array($_POST['coppa'], array('yes', 'no')) ) ) )
   601       {
   601 			{
   602         $s = 'Invalid COPPA input';
   602 				$s = 'Invalid COPPA input';
   603       }
   603 			}
   604       else if ( !$session->user_logged_in && !empty($terms) && !isset($_POST['tou_agreed']) )
   604 			else if ( !$session->user_logged_in && !empty($terms) && !isset($_POST['tou_agreed']) )
   605       {
   605 			{
   606         $s = $lang->get('user_reg_err_accept_tou');
   606 				$s = $lang->get('user_reg_err_accept_tou');
   607       }
   607 			}
   608       else
   608 			else
   609       {
   609 			{
   610         $coppa = ( isset($_POST['coppa']) && $_POST['coppa'] == 'yes' );
   610 				$coppa = ( isset($_POST['coppa']) && $_POST['coppa'] == 'yes' );
   611         $s = false;
   611 				$s = false;
   612         
   612 				
   613         // decrypt password
   613 				// decrypt password
   614         // as with the change pass form, we aren't going to bother checking the confirmation code because if the passwords didn't match
   614 				// as with the change pass form, we aren't going to bother checking the confirmation code because if the passwords didn't match
   615         // and yet the password got encrypted, that means the user screwed with the code, and if the user screwed with the code and thus
   615 				// and yet the password got encrypted, that means the user screwed with the code, and if the user screwed with the code and thus
   616         // forgot his password, that's his problem.
   616 				// forgot his password, that's his problem.
   617         
   617 				
   618         if ( $_POST['use_crypt'] == 'yes' )
   618 				if ( $_POST['use_crypt'] == 'yes' )
   619         {
   619 				{
   620           $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE);
   620 					$aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE);
   621           $crypt_key = $session->fetch_public_key($_POST['crypt_key']);
   621 					$crypt_key = $session->fetch_public_key($_POST['crypt_key']);
   622           if ( !$crypt_key )
   622 					if ( !$crypt_key )
   623           {
   623 					{
   624             $s = $lang->get('user_reg_err_missing_key');
   624 						$s = $lang->get('user_reg_err_missing_key');
   625           }
   625 					}
   626           else
   626 					else
   627           {
   627 					{
   628             $data = $_POST['crypt_data'];
   628 						$data = $_POST['crypt_data'];
   629             $bin_key = hexdecode($crypt_key);
   629 						$bin_key = hexdecode($crypt_key);
   630             //die("Decrypting with params: key $crypt_key, data $data");
   630 						//die("Decrypting with params: key $crypt_key, data $data");
   631             $password = $aes->decrypt($data, $bin_key, ENC_HEX);
   631 						$password = $aes->decrypt($data, $bin_key, ENC_HEX);
   632           }
   632 					}
   633         }
   633 				}
   634         else
   634 				else
   635         {
   635 				{
   636           $password = $_POST['password'];
   636 					$password = $_POST['password'];
   637         }
   637 				}
   638         
   638 				
   639         $error =& $s;
   639 				$error =& $s;
   640         
   640 				
   641         /**
   641 				/**
   642          * Validation of POST data coming from registration. Put an error message in the variable $error to stop registration.
   642  				* Validation of POST data coming from registration. Put an error message in the variable $error to stop registration.
   643          * @hook ucp_register_validate
   643  				* @hook ucp_register_validate
   644          */
   644  				*/
   645         
   645 				
   646         $code = $plugins->setHook('ucp_register_validate');
   646 				$code = $plugins->setHook('ucp_register_validate');
   647         foreach ( $code as $cmd )
   647 				foreach ( $code as $cmd )
   648         {
   648 				{
   649           eval($cmd);
   649 					eval($cmd);
   650         }
   650 				}
   651         
   651 				
   652         // All things verified, create account
   652 				// All things verified, create account
   653         if ( !$s )
   653 				if ( !$s )
   654           $s = $session->create_user($_POST['username'], $password, $_POST['email'], $_POST['real_name'], $coppa);
   654 					$s = $session->create_user($_POST['username'], $password, $_POST['email'], $_POST['real_name'], $coppa);
   655       }
   655 			}
   656     }
   656 		}
   657     if($s == 'success' && !$coppa)
   657 		if($s == 'success' && !$coppa)
   658     {
   658 		{
   659       switch(getConfig('account_activation'))
   659 			switch(getConfig('account_activation'))
   660       {
   660 			{
   661         case "none":
   661 				case "none":
   662         default:
   662 				default:
   663           $str = $lang->get('user_reg_msg_success_activ_none', array('login_link' => makeUrlNS('Special', 'Login', false, true)));
   663 					$str = $lang->get('user_reg_msg_success_activ_none', array('login_link' => makeUrlNS('Special', 'Login', false, true)));
   664           break;
   664 					break;
   665         case "user":
   665 				case "user":
   666           $str = $lang->get('user_reg_msg_success_activ_user');
   666 					$str = $lang->get('user_reg_msg_success_activ_user');
   667           break;
   667 					break;
   668         case "admin":
   668 				case "admin":
   669           $str = $lang->get('user_reg_msg_success_activ_admin');
   669 					$str = $lang->get('user_reg_msg_success_activ_admin');
   670           break;
   670 					break;
   671       }
   671 			}
   672       die_friendly($lang->get('user_reg_msg_success_title'), '<p>' . $lang->get('user_reg_msg_success_body') . ' ' . $str . '</p>');
   672 			die_friendly($lang->get('user_reg_msg_success_title'), '<p>' . $lang->get('user_reg_msg_success_body') . ' ' . $str . '</p>');
   673     }
   673 		}
   674     else if ( $s == 'success' && $coppa )
   674 		else if ( $s == 'success' && $coppa )
   675     {
   675 		{
   676       $str = $lang->get('user_reg_msg_success_activ_coppa');
   676 			$str = $lang->get('user_reg_msg_success_activ_coppa');
   677       die_friendly($lang->get('user_reg_msg_success_title'), '<p>' . $lang->get('user_reg_msg_success_body') . ' ' . $str . '</p>');
   677 			die_friendly($lang->get('user_reg_msg_success_title'), '<p>' . $lang->get('user_reg_msg_success_body') . ' ' . $str . '</p>');
   678     }
   678 		}
   679     $username = htmlspecialchars($_POST['username']);
   679 		$username = htmlspecialchars($_POST['username']);
   680     $email    = htmlspecialchars($_POST['email']);
   680 		$email    = htmlspecialchars($_POST['email']);
   681     $realname = htmlspecialchars($_POST['real_name']);
   681 		$realname = htmlspecialchars($_POST['real_name']);
   682   }
   682 	}
   683   $template->header();
   683 	$template->header();
   684   echo $lang->get('user_reg_msg_greatercontrol');
   684 	echo $lang->get('user_reg_msg_greatercontrol');
   685   
   685 	
   686   if ( getConfig('enable_coppa') != '1' || ( isset($_GET['coppa']) && in_array($_GET['coppa'], array('yes', 'no')) ) )
   686 	if ( getConfig('enable_coppa') != '1' || ( isset($_GET['coppa']) && in_array($_GET['coppa'], array('yes', 'no')) ) )
   687   {
   687 	{
   688     $coppa = ( isset($_GET['coppa']) && $_GET['coppa'] == 'yes' );
   688 		$coppa = ( isset($_GET['coppa']) && $_GET['coppa'] == 'yes' );
   689     $session->kill_captcha();
   689 		$session->kill_captcha();
   690     $captchacode = $session->make_captcha();
   690 		$captchacode = $session->make_captcha();
   691     
   691 		
   692     $pubkey = $session->rijndael_genkey();
   692 		$pubkey = $session->rijndael_genkey();
   693     $challenge = $session->dss_rand();
   693 		$challenge = $session->dss_rand();
   694     
   694 		
   695     ?>
   695 		?>
   696       <h3><?php echo $lang->get('user_reg_msg_table_title'); ?></h3>
   696 			<h3><?php echo $lang->get('user_reg_msg_table_title'); ?></h3>
   697       <form name="regform" action="<?php echo makeUrl($paths->page); ?>" method="post" onsubmit="return runEncryption();">
   697 			<form name="regform" action="<?php echo makeUrl($paths->page); ?>" method="post" onsubmit="return runEncryption();">
   698         <div class="tblholder">
   698 				<div class="tblholder">
   699           <table border="0" width="100%" cellspacing="1" cellpadding="4">
   699 					<table border="0" width="100%" cellspacing="1" cellpadding="4">
   700             <tr><th colspan="3"><?php echo $lang->get('user_reg_msg_table_subtitle'); ?></th></tr>
   700 						<tr><th colspan="3"><?php echo $lang->get('user_reg_msg_table_subtitle'); ?></th></tr>
   701             
   701 						
   702             <?php if(isset($_POST['submit'])) echo '<tr><td colspan="3" class="row2" style="color: red;">'.$s.'</td></tr>'; ?>
   702 						<?php if(isset($_POST['submit'])) echo '<tr><td colspan="3" class="row2" style="color: red;">'.$s.'</td></tr>'; ?>
   703             
   703 						
   704             <!-- FIELD: Username -->
   704 						<!-- FIELD: Username -->
   705             <tr>
   705 						<tr>
   706               <td class="row1" style="width: 50%;">
   706 							<td class="row1" style="width: 50%;">
   707                 <?php echo $lang->get('user_reg_lbl_field_username'); ?>
   707 								<?php echo $lang->get('user_reg_lbl_field_username'); ?>
   708                 <span id="e_username"></span>
   708 								<span id="e_username"></span>
   709               </td>
   709 							</td>
   710               <td class="row1" style="width: 50%;">
   710 							<td class="row1" style="width: 50%;">
   711                 <input tabindex="1" type="text" name="username" size="30" value="<?php echo $username; ?>" onkeyup="namegood = false; validateForm(this);" onblur="checkUsername();" />
   711 								<input tabindex="1" type="text" name="username" size="30" value="<?php echo $username; ?>" onkeyup="namegood = false; validateForm(this);" onblur="checkUsername();" />
   712               </td>
   712 							</td>
   713               <td class="row1" style="width: 1px;">
   713 							<td class="row1" style="width: 1px;">
   714                 <img alt="Good/bad icon" src="<?php echo scriptPath; ?>/images/checkbad.png" id="s_username" />
   714 								<img alt="Good/bad icon" src="<?php echo scriptPath; ?>/images/checkbad.png" id="s_username" />
   715               </td>
   715 							</td>
   716             </tr>
   716 						</tr>
   717             
   717 						
   718             <!-- FIELD: Password -->
   718 						<!-- FIELD: Password -->
   719             <tr>
   719 						<tr>
   720               <td class="row3" style="width: 50%;" rowspan="<?php echo ( getConfig('pw_strength_enable') == '1' ) ? '3' : '2'; ?>">
   720 							<td class="row3" style="width: 50%;" rowspan="<?php echo ( getConfig('pw_strength_enable') == '1' ) ? '3' : '2'; ?>">
   721                 <?php echo $lang->get('user_reg_lbl_field_password'); ?>
   721 								<?php echo $lang->get('user_reg_lbl_field_password'); ?>
   722                 <span id="e_password"></span>
   722 								<span id="e_password"></span>
   723                 <?php if ( getConfig('pw_strength_enable') == '1' && getConfig('pw_strength_minimum') > -10 ): ?>
   723 								<?php if ( getConfig('pw_strength_enable') == '1' && getConfig('pw_strength_minimum') > -10 ): ?>
   724                 <small><?php echo $lang->get('user_reg_msg_password_score'); ?></small>
   724 								<small><?php echo $lang->get('user_reg_msg_password_score'); ?></small>
   725                 <?php endif; ?>
   725 								<?php endif; ?>
   726               </td>
   726 							</td>
   727               <td class="row3" style="width: 50%;">
   727 							<td class="row3" style="width: 50%;">
   728                 <input tabindex="2" type="password" name="password" size="15" onkeyup="<?php if ( getConfig('pw_strength_enable') == '1' ): ?>password_score_field(this); <?php endif; ?>validateForm(this);" /><?php if ( getConfig('pw_strength_enable') == '1' ): ?><span class="password-checker" style="font-weight: bold; color: #aaaaaa;"> Loading...</span><?php endif; ?>
   728 								<input tabindex="2" type="password" name="password" size="15" onkeyup="<?php if ( getConfig('pw_strength_enable') == '1' ): ?>password_score_field(this); <?php endif; ?>validateForm(this);" /><?php if ( getConfig('pw_strength_enable') == '1' ): ?><span class="password-checker" style="font-weight: bold; color: #aaaaaa;"> Loading...</span><?php endif; ?>
   729               </td>
   729 							</td>
   730               <td rowspan="<?php echo ( getConfig('pw_strength_enable') == '1' ) ? '3' : '2'; ?>" class="row3" style="max-width: 24px;">
   730 							<td rowspan="<?php echo ( getConfig('pw_strength_enable') == '1' ) ? '3' : '2'; ?>" class="row3" style="max-width: 24px;">
   731                 <img alt="Good/bad icon" src="<?php echo scriptPath; ?>/images/checkbad.png" id="s_password" />
   731 								<img alt="Good/bad icon" src="<?php echo scriptPath; ?>/images/checkbad.png" id="s_password" />
   732               </td>
   732 							</td>
   733             </tr>
   733 						</tr>
   734             
   734 						
   735             <!-- FIELD: Password confirmation -->
   735 						<!-- FIELD: Password confirmation -->
   736             <tr>
   736 						<tr>
   737               <td class="row3" style="width: 50%;">
   737 							<td class="row3" style="width: 50%;">
   738                 <input tabindex="3" type="password" name="password_confirm" size="15" onkeyup="validateForm(this);" /> <small><?php echo $lang->get('user_reg_lbl_field_password_confirm'); ?></small>
   738 								<input tabindex="3" type="password" name="password_confirm" size="15" onkeyup="validateForm(this);" /> <small><?php echo $lang->get('user_reg_lbl_field_password_confirm'); ?></small>
   739               </td>
   739 							</td>
   740             </tr>
   740 						</tr>
   741             
   741 						
   742             <!-- FIELD: Password strength meter -->
   742 						<!-- FIELD: Password strength meter -->
   743             
   743 						
   744             <?php if ( getConfig('pw_strength_enable') == '1' ): ?>
   744 						<?php if ( getConfig('pw_strength_enable') == '1' ): ?>
   745             <tr>
   745 						<tr>
   746               <td class="row3" style="width: 50%;">
   746 							<td class="row3" style="width: 50%;">
   747                 <div id="pwmeter"></div>
   747 								<div id="pwmeter"></div>
   748               </td>
   748 							</td>
   749             </tr>
   749 						</tr>
   750             <?php endif; ?>
   750 						<?php endif; ?>
   751             
   751 						
   752             <!-- FIELD: E-mail address -->
   752 						<!-- FIELD: E-mail address -->
   753             <tr>
   753 						<tr>
   754               <td class="row1" style="width: 50%;">
   754 							<td class="row1" style="width: 50%;">
   755                 <?php
   755 								<?php
   756                   if ( $coppa )
   756 									if ( $coppa )
   757                   {
   757 									{
   758                     echo $lang->get('user_reg_lbl_field_email_coppa');
   758 										echo $lang->get('user_reg_lbl_field_email_coppa');
   759                   }
   759 									}
   760                   else
   760 									else
   761                   {
   761 									{
   762                     echo $lang->get('user_reg_lbl_field_email');
   762 										echo $lang->get('user_reg_lbl_field_email');
   763                   }
   763 									}
   764                 ?>
   764 								?>
   765                 <?php
   765 								<?php
   766                   if ( ( $x = getConfig('account_activation') ) == 'user' )
   766 									if ( ( $x = getConfig('account_activation') ) == 'user' )
   767                   {
   767 									{
   768                     echo '<br /><small>' . $lang->get('user_reg_msg_email_activuser') . '</small>';
   768 										echo '<br /><small>' . $lang->get('user_reg_msg_email_activuser') . '</small>';
   769                   }
   769 									}
   770                 ?>
   770 								?>
   771               </td>
   771 							</td>
   772               <td class="row1" style="width: 50%;">
   772 							<td class="row1" style="width: 50%;">
   773                 <input tabindex="4" type="text" name="email" size="30" value="<?php echo $email; ?>" onkeyup="validateForm(this);" />
   773 								<input tabindex="4" type="text" name="email" size="30" value="<?php echo $email; ?>" onkeyup="validateForm(this);" />
   774               </td>
   774 							</td>
   775               <td class="row1" style="max-width: 24px;">
   775 							<td class="row1" style="max-width: 24px;">
   776                 <img alt="Good/bad icon" src="<?php echo scriptPath; ?>/images/checkbad.png" id="s_email" />
   776 								<img alt="Good/bad icon" src="<?php echo scriptPath; ?>/images/checkbad.png" id="s_email" />
   777               </td>
   777 							</td>
   778             </tr>
   778 						</tr>
   779             
   779 						
   780             <!-- FIELD: Real name -->
   780 						<!-- FIELD: Real name -->
   781             <tr>
   781 						<tr>
   782               <td class="row3" style="width: 50%;">
   782 							<td class="row3" style="width: 50%;">
   783                 <?php echo $lang->get('user_reg_lbl_field_realname'); ?><br />
   783 								<?php echo $lang->get('user_reg_lbl_field_realname'); ?><br />
   784                 <small><?php echo $lang->get('user_reg_msg_realname_optional'); ?></small>
   784 								<small><?php echo $lang->get('user_reg_msg_realname_optional'); ?></small>
   785               </td>
   785 							</td>
   786               <td class="row3" style="width: 50%;">
   786 							<td class="row3" style="width: 50%;">
   787                 <input tabindex="5" type="text" name="real_name" size="30" value="<?php echo $realname; ?>" />
   787 								<input tabindex="5" type="text" name="real_name" size="30" value="<?php echo $realname; ?>" />
   788               </td>
   788 							</td>
   789               <td class="row3" style="max-width: 24px;">
   789 							<td class="row3" style="max-width: 24px;">
   790               </td>
   790 							</td>
   791             </tr>
   791 						</tr>
   792             
   792 						
   793             <?php
   793 						<?php
   794             /**
   794 						/**
   795              * Allows adding fields to the user registration form. Form is built with Enano tables, 3 columns. (Rightmost can be left empty or if you're using Javascript validation an image you can update with your own Javascript code)
   795  						* Allows adding fields to the user registration form. Form is built with Enano tables, 3 columns. (Rightmost can be left empty or if you're using Javascript validation an image you can update with your own Javascript code)
   796              * @hook ucp_register_form
   796  						* @hook ucp_register_form
   797              */
   797  						*/
   798             
   798 						
   799             $code = $plugins->setHook('ucp_register_form');
   799 						$code = $plugins->setHook('ucp_register_form');
   800             foreach ( $code as $cmd )
   800 						foreach ( $code as $cmd )
   801             {
   801 						{
   802               eval($cmd);
   802 							eval($cmd);
   803             }
   803 						}
   804             ?>
   804 						?>
   805             
   805 						
   806             <!-- FIELD: CAPTCHA image -->
   806 						<!-- FIELD: CAPTCHA image -->
   807             <?php
   807 						<?php
   808             if ( !$session->user_logged_in ):
   808 						if ( !$session->user_logged_in ):
   809             ?>
   809 						?>
   810             <tr>
   810 						<tr>
   811               <td class="row1" style="width: 50%;" rowspan="2">
   811 							<td class="row1" style="width: 50%;" rowspan="2">
   812                 <?php echo $lang->get('user_reg_lbl_field_captcha'); ?><br />
   812 								<?php echo $lang->get('user_reg_lbl_field_captcha'); ?><br />
   813                 <small>
   813 								<small>
   814                   <?php echo $lang->get('user_reg_msg_captcha_pleaseenter', array('regen_flags' => 'href="#" onclick="regenCaptcha(); return false;"')); ?><br />
   814 									<?php echo $lang->get('user_reg_msg_captcha_pleaseenter', array('regen_flags' => 'href="#" onclick="regenCaptcha(); return false;"')); ?><br />
   815                   <br />
   815 									<br />
   816                   <?php echo $lang->get('user_reg_msg_captcha_blind'); ?>
   816 									<?php echo $lang->get('user_reg_msg_captcha_blind'); ?>
   817                 </small>
   817 								</small>
   818               </td>
   818 							</td>
   819               <td class="row1">
   819 							<td class="row1">
   820                 <img id="captchaimg" alt="CAPTCHA image" src="<?php echo makeUrlNS('Special', 'Captcha/'.$captchacode); ?>" style="cursor: pointer;" onclick="regenCaptcha(); return false;" />
   820 								<img id="captchaimg" alt="CAPTCHA image" src="<?php echo makeUrlNS('Special', 'Captcha/'.$captchacode); ?>" style="cursor: pointer;" onclick="regenCaptcha(); return false;" />
   821               </td>
   821 							</td>
   822               <td class="row1">
   822 							<td class="row1">
   823                 <img alt="Good/bad icon" src="<?php echo scriptPath; ?>/images/checkbad.png" id="s_captcha" />
   823 								<img alt="Good/bad icon" src="<?php echo scriptPath; ?>/images/checkbad.png" id="s_captcha" />
   824               </td>
   824 							</td>
   825             </tr>
   825 						</tr>
   826             
   826 						
   827             <!-- FIELD: CAPTCHA input field -->
   827 						<!-- FIELD: CAPTCHA input field -->
   828             <tr>
   828 						<tr>
   829               <td class="row1" colspan="2">
   829 							<td class="row1" colspan="2">
   830                 <?php echo $lang->get('user_reg_lbl_field_captcha_code'); ?>
   830 								<?php echo $lang->get('user_reg_lbl_field_captcha_code'); ?>
   831                 <input tabindex="6" name="captchacode" type="text" size="10" onkeyup="validateCaptcha(this);" />
   831 								<input tabindex="6" name="captchacode" type="text" size="10" onkeyup="validateCaptcha(this);" />
   832                 <img id="captchaajax" width="16" height="16" src="<?php echo cdnPath; ?>/images/spacer.gif" />
   832 								<img id="captchaajax" width="16" height="16" src="<?php echo cdnPath; ?>/images/spacer.gif" />
   833                 <input type="hidden" name="captchahash" value="<?php echo $captchacode; ?>" />
   833 								<input type="hidden" name="captchahash" value="<?php echo $captchacode; ?>" />
   834               </td>
   834 							</td>
   835             </tr>
   835 						</tr>
   836             
   836 						
   837             <!-- FIELD: TOU -->
   837 						<!-- FIELD: TOU -->
   838             
   838 						
   839             <?php
   839 						<?php
   840             if ( !empty($terms) ):
   840 						if ( !empty($terms) ):
   841             ?>
   841 						?>
   842             
   842 						
   843             <tr>
   843 						<tr>
   844               <td class="row1" colspan="3">
   844 							<td class="row1" colspan="3">
   845                 <?php
   845 								<?php
   846                 echo $lang->get('user_reg_msg_please_read_tou');
   846 								echo $lang->get('user_reg_msg_please_read_tou');
   847                 ?>
   847 								?>
   848               </td>
   848 							</td>
   849             </tr>
   849 						</tr>
   850             
   850 						
   851             <tr>
   851 						<tr>
   852               <td class="row3" colspan="3">
   852 							<td class="row3" colspan="3">
   853                 <div style="border: 1px solid #000000; height: 75px; width: 60%; clip: rect(0px,auto,auto,0px); overflow: auto; background-color: #FFF; margin: 0 auto; padding: 4px;">
   853 								<div style="border: 1px solid #000000; height: 75px; width: 60%; clip: rect(0px,auto,auto,0px); overflow: auto; background-color: #FFF; margin: 0 auto; padding: 4px;">
   854                   <?php
   854 									<?php
   855                   echo RenderMan::render($terms);
   855 									echo RenderMan::render($terms);
   856                   ?>
   856 									?>
   857                 </div>
   857 								</div>
   858                 <p style="text-align: center;">
   858 								<p style="text-align: center;">
   859                   <label>
   859 									<label>
   860                     <input tabindex="7" type="checkbox" name="tou_agreed" />
   860 										<input tabindex="7" type="checkbox" name="tou_agreed" />
   861                     <b><?php echo $lang->get('user_reg_lbl_field_tou'); ?></b>
   861 										<b><?php echo $lang->get('user_reg_lbl_field_tou'); ?></b>
   862                   </label>
   862 									</label>
   863                 </p>
   863 								</p>
   864               </td>
   864 							</td>
   865             </tr>
   865 						</tr>
   866             
   866 						
   867             <?php
   867 						<?php
   868             endif; // !empty($terms)
   868 						endif; // !empty($terms)
   869             endif; // $session->user_logged_in
   869 						endif; // $session->user_logged_in
   870             ?>
   870 						?>
   871             
   871 						
   872             <!-- FIELD: submit button -->
   872 						<!-- FIELD: submit button -->
   873             <tr>
   873 						<tr>
   874               <th class="subhead" colspan="3" style="text-align: center;">
   874 							<th class="subhead" colspan="3" style="text-align: center;">
   875                 <input tabindex="8" type="submit" name="submit" value="<?php echo $lang->get('user_reg_btn_create_account'); ?>" />
   875 								<input tabindex="8" type="submit" name="submit" value="<?php echo $lang->get('user_reg_btn_create_account'); ?>" />
   876               </td>
   876 							</td>
   877             </tr>
   877 						</tr>
   878             
   878 						
   879           </table>
   879 					</table>
   880         </div>
   880 				</div>
   881         <?php
   881 				<?php
   882           $val = ( $coppa ) ? 'yes' : 'no';
   882 					$val = ( $coppa ) ? 'yes' : 'no';
   883           echo '<input type="hidden" name="coppa" value="' . $val . '" />';
   883 					echo '<input type="hidden" name="coppa" value="' . $val . '" />';
   884         ?>
   884 				?>
   885         <input type="hidden" name="challenge_data" value="<?php echo $challenge; ?>" />
   885 				<input type="hidden" name="challenge_data" value="<?php echo $challenge; ?>" />
   886         <input type="hidden" name="use_crypt" value="no" />
   886 				<input type="hidden" name="use_crypt" value="no" />
   887         <input type="hidden" name="crypt_key" value="<?php echo $pubkey; ?>" />
   887 				<input type="hidden" name="crypt_key" value="<?php echo $pubkey; ?>" />
   888         <input type="hidden" name="crypt_data" value="" />
   888 				<input type="hidden" name="crypt_data" value="" />
   889       <script type="text/javascript">
   889 			<script type="text/javascript">
   890         // ENCRYPTION CODE
   890 				// ENCRYPTION CODE
   891         function runEncryption()
   891 				function runEncryption()
   892         {
   892 				{
   893           var frm = document.forms.regform;
   893 					var frm = document.forms.regform;
   894           if ( frm.password.value.length < 1 )
   894 					if ( frm.password.value.length < 1 )
   895             return true;
   895 						return true;
   896           pass1 = frm.password.value;
   896 					pass1 = frm.password.value;
   897           pass2 = frm.password_confirm.value;
   897 					pass2 = frm.password_confirm.value;
   898           if ( pass1 != pass2 )
   898 					if ( pass1 != pass2 )
   899           {
   899 					{
   900             alert($lang.get('user_reg_err_alert_password_nomatch'));
   900 						alert($lang.get('user_reg_err_alert_password_nomatch'));
   901             return false;
   901 						return false;
   902           }
   902 					}
   903           if ( pass1.length < 6 && pass1.length > 0 )
   903 					if ( pass1.length < 6 && pass1.length > 0 )
   904           {
   904 					{
   905             alert($lang.get('user_reg_err_alert_password_tooshort'));
   905 						alert($lang.get('user_reg_err_alert_password_tooshort'));
   906             return false;
   906 						return false;
   907           }
   907 					}
   908           if(aes_self_test())
   908 					if(aes_self_test())
   909           {
   909 					{
   910             frm.use_crypt.value = 'yes';
   910 						frm.use_crypt.value = 'yes';
   911             var cryptkey = frm.crypt_key.value;
   911 						var cryptkey = frm.crypt_key.value;
   912             frm.crypt_key.value = hex_md5(cryptkey);
   912 						frm.crypt_key.value = hex_md5(cryptkey);
   913             cryptkey = hexToByteArray(cryptkey);
   913 						cryptkey = hexToByteArray(cryptkey);
   914             if(!cryptkey || ( ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ) && cryptkey.length != keySizeInBits / 8 )
   914 						if(!cryptkey || ( ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ) && cryptkey.length != keySizeInBits / 8 )
   915             {
   915 						{
   916               frm.submit.disabled = true;
   916 							frm.submit.disabled = true;
   917               len = ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ? '\nLen: '+cryptkey.length : '';
   917 							len = ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ? '\nLen: '+cryptkey.length : '';
   918               alert('The key is messed up\nType: '+typeof(cryptkey)+len);
   918 							alert('The key is messed up\nType: '+typeof(cryptkey)+len);
   919             }
   919 						}
   920             pass = frm.password.value;
   920 						pass = frm.password.value;
   921             pass = stringToByteArray(pass);
   921 						pass = stringToByteArray(pass);
   922             cryptstring = rijndaelEncrypt(pass, cryptkey, 'ECB');
   922 						cryptstring = rijndaelEncrypt(pass, cryptkey, 'ECB');
   923             if(!cryptstring)
   923 						if(!cryptstring)
   924             {
   924 						{
   925               return false;
   925 							return false;
   926             }
   926 						}
   927             cryptstring = byteArrayToHex(cryptstring);
   927 						cryptstring = byteArrayToHex(cryptstring);
   928             frm.crypt_data.value = cryptstring;
   928 						frm.crypt_data.value = cryptstring;
   929             frm.password.value = "";
   929 						frm.password.value = "";
   930             frm.password_confirm.value = "";
   930 						frm.password_confirm.value = "";
   931           }
   931 					}
   932           return true;
   932 					return true;
   933         }
   933 				}
   934         </script>
   934 				</script>
   935       </form>
   935 			</form>
   936       <!-- Don't optimize this script, it fails when compressed -->
   936 			<!-- Don't optimize this script, it fails when compressed -->
   937       <enano:no-opt>
   937 			<enano:no-opt>
   938         <script type="text/javascript">
   938 				<script type="text/javascript">
   939           // <![CDATA[
   939 					// <![CDATA[
   940           var namegood = false;
   940 					var namegood = false;
   941           function validateForm(field)
   941 					function validateForm(field)
   942           {
   942 					{
   943             if ( typeof(field) != 'object' )
   943 						if ( typeof(field) != 'object' )
   944             {
   944 						{
   945               field = {
   945 							field = {
   946                 name: '_nil',
   946 								name: '_nil',
   947                 value: '_nil'
   947 								value: '_nil'
   948               }
   948 							}
   949             }
   949 						}
   950             // wait until $lang is initted
   950 						// wait until $lang is initted
   951             if ( typeof($lang) != 'object' )
   951 						if ( typeof($lang) != 'object' )
   952             {
   952 						{
   953               setTimeout('validateForm();', 200);
   953 							setTimeout('validateForm();', 200);
   954               return false;
   954 							return false;
   955             }
   955 						}
   956             var frm = document.forms.regform;
   956 						var frm = document.forms.regform;
   957             failed = false;
   957 						failed = false;
   958             
   958 						
   959             // Username
   959 						// Username
   960             if(!namegood && ( field.name == 'username' || field.name == '_nil' ) ) 
   960 						if(!namegood && ( field.name == 'username' || field.name == '_nil' ) ) 
   961             {
   961 						{
   962               //if(frm.username.value.match(/^([A-z0-9 \!@\-\(\)]+){2,}$/ig))
   962 							//if(frm.username.value.match(/^([A-z0-9 \!@\-\(\)]+){2,}$/ig))
   963               var regex = new RegExp('^([^<>&\?]+){2,}$', 'ig');
   963 							var regex = new RegExp('^([^<>&\?]+){2,}$', 'ig');
   964               if ( frm.username.value.match(regex) )
   964 							if ( frm.username.value.match(regex) )
   965               {
   965 							{
   966                 document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/checkunk.png';
   966 								document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/checkunk.png';
   967                 document.getElementById('e_username').innerHTML = '&nbsp;';
   967 								document.getElementById('e_username').innerHTML = '&nbsp;';
   968               } else {
   968 							} else {
   969                 failed = true;
   969 								failed = true;
   970                 document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/checkbad.png';
   970 								document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/checkbad.png';
   971                 document.getElementById('e_username').innerHTML = '<br /><small>' + $lang.get('user_reg_err_username_invalid') + '</small>';
   971 								document.getElementById('e_username').innerHTML = '<br /><small>' + $lang.get('user_reg_err_username_invalid') + '</small>';
   972               }
   972 							}
   973             }
   973 						}
   974             if ( document.getElementById('b_username') )
   974 						if ( document.getElementById('b_username') )
   975             {
   975 						{
   976               document.getElementById('b_username').innerHTML = '';
   976 							document.getElementById('b_username').innerHTML = '';
   977               if(hex_md5(frm.real_name.value) == '5a397df72678128cf0e8147a2befd5f1')
   977 							if(hex_md5(frm.real_name.value) == '5a397df72678128cf0e8147a2befd5f1')
   978               {
   978 							{
   979                 document.getElementById('b_username').innerHTML = '<br /><br />Hey...I know you!<br /><img alt="" src="http://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Bill_Gates_2004_cr.jpg/220px-Bill_Gates_2004_cr.jpg" />';
   979 								document.getElementById('b_username').innerHTML = '<br /><br />Hey...I know you!<br /><img alt="" src="http://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Bill_Gates_2004_cr.jpg/220px-Bill_Gates_2004_cr.jpg" />';
   980               }
   980 							}
   981             }
   981 						}
   982             
   982 						
   983             // Password
   983 						// Password
   984             if ( field.name == 'password' || field.name == 'password_confirm' || field.name == '_nil' )
   984 						if ( field.name == 'password' || field.name == 'password_confirm' || field.name == '_nil' )
   985             {
   985 						{
   986               if(frm.password.value.match(/^(.+){6,}$/ig) && frm.password_confirm.value.match(/^(.+){6,}$/ig) && frm.password.value == frm.password_confirm.value )
   986 							if(frm.password.value.match(/^(.+){6,}$/ig) && frm.password_confirm.value.match(/^(.+){6,}$/ig) && frm.password.value == frm.password_confirm.value )
   987               {
   987 							{
   988                 document.getElementById('s_password').src='<?php echo scriptPath; ?>/images/check.png';
   988 								document.getElementById('s_password').src='<?php echo scriptPath; ?>/images/check.png';
   989                 document.getElementById('e_password').innerHTML = '<br /><small>' + $lang.get('user_reg_err_password_good') + '</small>';
   989 								document.getElementById('e_password').innerHTML = '<br /><small>' + $lang.get('user_reg_err_password_good') + '</small>';
   990               } else {
   990 							} else {
   991                 failed = true;
   991 								failed = true;
   992                 if(frm.password.value.length < 6)
   992 								if(frm.password.value.length < 6)
   993                 {
   993 								{
   994                   document.getElementById('e_password').innerHTML = '<br /><small>' + $lang.get('user_reg_msg_password_length') + '</small>';
   994 									document.getElementById('e_password').innerHTML = '<br /><small>' + $lang.get('user_reg_msg_password_length') + '</small>';
   995                 }
   995 								}
   996                 else if(frm.password.value != frm.password_confirm.value)
   996 								else if(frm.password.value != frm.password_confirm.value)
   997                 {
   997 								{
   998                   document.getElementById('e_password').innerHTML = '<br /><small>' + $lang.get('user_reg_msg_password_needmatch') + '</small>';
   998 									document.getElementById('e_password').innerHTML = '<br /><small>' + $lang.get('user_reg_msg_password_needmatch') + '</small>';
   999                 }
   999 								}
  1000                 else
  1000 								else
  1001                 {
  1001 								{
  1002                   document.getElementById('e_password').innerHTML = '';
  1002 									document.getElementById('e_password').innerHTML = '';
  1003                 }
  1003 								}
  1004                 document.getElementById('s_password').src='<?php echo scriptPath; ?>/images/checkbad.png';
  1004 								document.getElementById('s_password').src='<?php echo scriptPath; ?>/images/checkbad.png';
  1005               }
  1005 							}
  1006             }
  1006 						}
  1007             
  1007 						
  1008             // E-mail address
  1008 						// E-mail address
  1009             
  1009 						
  1010             // workaround for idiot jEdit bug
  1010 						// workaround for idiot jEdit bug
  1011             if ( validateEmail(frm.email.value) && ( field.name == 'email' || field.name == '_nil' ) )
  1011 						if ( validateEmail(frm.email.value) && ( field.name == 'email' || field.name == '_nil' ) )
  1012             {
  1012 						{
  1013               document.getElementById('s_email').src='<?php echo scriptPath; ?>/images/check.png';
  1013 							document.getElementById('s_email').src='<?php echo scriptPath; ?>/images/check.png';
  1014             } else {
  1014 						} else {
  1015               failed = true;
  1015 							failed = true;
  1016               document.getElementById('s_email').src='<?php echo scriptPath; ?>/images/checkbad.png';
  1016 							document.getElementById('s_email').src='<?php echo scriptPath; ?>/images/checkbad.png';
  1017             }
  1017 						}
  1018             if(failed)
  1018 						if(failed)
  1019             {
  1019 						{
  1020               frm.submit.disabled = 'disabled';
  1020 							frm.submit.disabled = 'disabled';
  1021             } else {
  1021 						} else {
  1022               frm.submit.disabled = false;
  1022 							frm.submit.disabled = false;
  1023             }
  1023 						}
  1024           }
  1024 					}
  1025           function checkUsername()
  1025 					function checkUsername()
  1026           {
  1026 					{
  1027             var frm = document.forms.regform;
  1027 						var frm = document.forms.regform;
  1028             
  1028 						
  1029             if(!namegood)
  1029 						if(!namegood)
  1030             {
  1030 						{
  1031               var regex = new RegExp('^([^<>&\?]+){2,}$', 'ig');
  1031 							var regex = new RegExp('^([^<>&\?]+){2,}$', 'ig');
  1032               if ( frm.username.value.match(regex) )
  1032 							if ( frm.username.value.match(regex) )
  1033               {
  1033 							{
  1034                 document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/checkunk.png';
  1034 								document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/checkunk.png';
  1035                 document.getElementById('e_username').innerHTML = '&nbsp;';
  1035 								document.getElementById('e_username').innerHTML = '&nbsp;';
  1036               } else {
  1036 							} else {
  1037                 document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/checkbad.png';
  1037 								document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/checkbad.png';
  1038                 document.getElementById('e_username').innerHTML = '<br /><small>' + $lang.get('user_reg_err_username_invalid') + '</small>';
  1038 								document.getElementById('e_username').innerHTML = '<br /><small>' + $lang.get('user_reg_err_username_invalid') + '</small>';
  1039                 return false;
  1039 								return false;
  1040               }
  1040 							}
  1041             }
  1041 						}
  1042             
  1042 						
  1043             document.getElementById('e_username').innerHTML = '<br /><small><b>' + $lang.get('user_reg_msg_username_checking') + '</b></small>';
  1043 						document.getElementById('e_username').innerHTML = '<br /><small><b>' + $lang.get('user_reg_msg_username_checking') + '</b></small>';
  1044             ajaxGet('<?php echo scriptPath; ?>/ajax.php?title=null&_mode=checkusername&name='+escape(frm.username.value), function() {
  1044 						ajaxGet('<?php echo scriptPath; ?>/ajax.php?title=null&_mode=checkusername&name='+escape(frm.username.value), function() {
  1045               if ( ajax.readyState == 4 && ajax.status == 200 )
  1045 							if ( ajax.readyState == 4 && ajax.status == 200 )
  1046                 if(ajax.responseText == 'good')
  1046 								if(ajax.responseText == 'good')
  1047                 {
  1047 								{
  1048                   document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/check.png';
  1048 									document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/check.png';
  1049                   document.getElementById('e_username').innerHTML = '<br /><small><b>' + $lang.get('user_reg_msg_username_available') + '</b></small>';
  1049 									document.getElementById('e_username').innerHTML = '<br /><small><b>' + $lang.get('user_reg_msg_username_available') + '</b></small>';
  1050                   namegood = true;
  1050 									namegood = true;
  1051                 } else if(ajax.responseText == 'bad') {
  1051 								} else if(ajax.responseText == 'bad') {
  1052                   document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/checkbad.png';
  1052 									document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/checkbad.png';
  1053                   document.getElementById('e_username').innerHTML = '<br /><small><b>' + $lang.get('user_reg_msg_username_unavailable') + '</b></small>';
  1053 									document.getElementById('e_username').innerHTML = '<br /><small><b>' + $lang.get('user_reg_msg_username_unavailable') + '</b></small>';
  1054                   namegood = false;
  1054 									namegood = false;
  1055                 } else {
  1055 								} else {
  1056                   document.getElementById('e_username').innerHTML = ajax.responseText;
  1056 									document.getElementById('e_username').innerHTML = ajax.responseText;
  1057                 }
  1057 								}
  1058             });
  1058 						});
  1059           }
  1059 					}
  1060           function regenCaptcha()
  1060 					function regenCaptcha()
  1061           {
  1061 					{
  1062             var frm = document.forms.regform;
  1062 						var frm = document.forms.regform;
  1063             document.getElementById('captchaimg').src = '<?php echo makeUrlNS("Special", "Captcha/$captchacode"); ?>/'+Math.floor(Math.random() * 100000);
  1063 						document.getElementById('captchaimg').src = '<?php echo makeUrlNS("Special", "Captcha/$captchacode"); ?>/'+Math.floor(Math.random() * 100000);
  1064             frm.captchacode.value = '';
  1064 						frm.captchacode.value = '';
  1065             return false;
  1065 						return false;
  1066           }
  1066 					}
  1067           function validateCaptcha(input)
  1067 					function validateCaptcha(input)
  1068           {
  1068 					{
  1069             var frm = document.forms.regform;
  1069 						var frm = document.forms.regform;
  1070             if ( input.value.length < 7 )
  1070 						if ( input.value.length < 7 )
  1071             {
  1071 						{
  1072               return false;
  1072 							return false;
  1073             }
  1073 						}
  1074             var valid_field = document.getElementById('s_captcha');
  1074 						var valid_field = document.getElementById('s_captcha');
  1075             var loader_img = document.getElementById('captchaajax');
  1075 						var loader_img = document.getElementById('captchaajax');
  1076             loader_img.src = cdnPath + '/images/loading.gif';
  1076 						loader_img.src = cdnPath + '/images/loading.gif';
  1077             ajaxGet(makeUrlNS('Special', 'Captcha/' + frm.captchahash.value + '/validate=' + input.value), function(ajax)
  1077 						ajaxGet(makeUrlNS('Special', 'Captcha/' + frm.captchahash.value + '/validate=' + input.value), function(ajax)
  1078               {
  1078 							{
  1079                 if ( ajax.readyState == 4 && ajax.status == 200 )
  1079 								if ( ajax.readyState == 4 && ajax.status == 200 )
  1080                 {
  1080 								{
  1081                   var response = String(ajax.responseText + '');
  1081 									var response = String(ajax.responseText + '');
  1082                   if ( !check_json_response(response) )
  1082 									if ( !check_json_response(response) )
  1083                   {
  1083 									{
  1084                     handle_invalid_json(response);
  1084 										handle_invalid_json(response);
  1085                     return false;
  1085 										return false;
  1086                   }
  1086 									}
  1087                   response = parseJSON(response);
  1087 									response = parseJSON(response);
  1088                   if ( response.valid )
  1088 									if ( response.valid )
  1089                   {
  1089 									{
  1090                     loader_img.src = cdnPath + '/images/spacer.gif';
  1090 										loader_img.src = cdnPath + '/images/spacer.gif';
  1091                     valid_field.src = cdnPath + '/images/check.png';
  1091 										valid_field.src = cdnPath + '/images/check.png';
  1092                   }
  1092 									}
  1093                   else
  1093 									else
  1094                   {
  1094 									{
  1095                     valid_field.src = cdnPath + '/images/checkbad.png';
  1095 										valid_field.src = cdnPath + '/images/checkbad.png';
  1096                     regenCaptcha();
  1096 										regenCaptcha();
  1097                     document.getElementById('captchaimg').onload = function()
  1097 										document.getElementById('captchaimg').onload = function()
  1098                     {
  1098 										{
  1099                       document.getElementById('captchaajax').src = cdnPath + '/images/spacer.gif';
  1099 											document.getElementById('captchaajax').src = cdnPath + '/images/spacer.gif';
  1100                       input.focus();
  1100 											input.focus();
  1101                     };
  1101 										};
  1102                     input.value = '';
  1102 										input.value = '';
  1103                   }
  1103 									}
  1104                 }
  1104 								}
  1105               });
  1105 							});
  1106           }
  1106 					}
  1107           addOnloadHook(function()
  1107 					addOnloadHook(function()
  1108             {
  1108 						{
  1109               <?php if ( getConfig('pw_strength_enable') == '1' ): ?>
  1109 							<?php if ( getConfig('pw_strength_enable') == '1' ): ?>
  1110               var frm = document.forms.regform;
  1110 							var frm = document.forms.regform;
  1111               load_component('pwstrength');
  1111 							load_component('pwstrength');
  1112               password_score_field(frm.password);
  1112 							password_score_field(frm.password);
  1113               <?php endif; ?>
  1113 							<?php endif; ?>
  1114               load_component('crypto');
  1114 							load_component('crypto');
  1115               validateForm();
  1115 							validateForm();
  1116               setTimeout('checkUsername();', 1000);
  1116 							setTimeout('checkUsername();', 1000);
  1117             });
  1117 						});
  1118           // ]]>
  1118 					// ]]>
  1119         </script>
  1119 				</script>
  1120       </enano:no-opt>
  1120 			</enano:no-opt>
  1121     <?php
  1121 		<?php
  1122   }
  1122 	}
  1123   else
  1123 	else
  1124   {
  1124 	{
  1125     $year = intval( enano_date('Y') );
  1125 		$year = intval( enano_date('Y') );
  1126     $year = $year - 13;
  1126 		$year = $year - 13;
  1127     $month = enano_date('F');
  1127 		$month = enano_date('F');
  1128     $day = enano_date('d');
  1128 		$day = enano_date('d');
  1129     
  1129 		
  1130     $yo13_date = "$month $day, $year";
  1130 		$yo13_date = "$month $day, $year";
  1131     $link_coppa_yes = makeUrlNS('Special', 'Register', 'coppa=yes', true);
  1131 		$link_coppa_yes = makeUrlNS('Special', 'Register', 'coppa=yes', true);
  1132     $link_coppa_no  = makeUrlNS('Special', 'Register', 'coppa=no',  true);
  1132 		$link_coppa_no  = makeUrlNS('Special', 'Register', 'coppa=no',  true);
  1133     
  1133 		
  1134     // COPPA enabled, ask age
  1134 		// COPPA enabled, ask age
  1135     echo '<div class="tblholder">';
  1135 		echo '<div class="tblholder">';
  1136     echo '<table border="0" cellspacing="1" cellpadding="4">';
  1136 		echo '<table border="0" cellspacing="1" cellpadding="4">';
  1137     echo '<tr>
  1137 		echo '<tr>
  1138             <td class="row1">
  1138 						<td class="row1">
  1139               ' . $lang->get('user_reg_coppa_title') . '
  1139 							' . $lang->get('user_reg_coppa_title') . '
  1140             </td>
  1140 						</td>
  1141           </tr>
  1141 					</tr>
  1142           <tr>
  1142 					<tr>
  1143             <td class="row3">
  1143 						<td class="row3">
  1144               <a href="' . $link_coppa_no  . '">' . $lang->get('user_reg_coppa_link_atleast13', array( 'yo13_date' => $yo13_date )) . '</a><br />
  1144 							<a href="' . $link_coppa_no  . '">' . $lang->get('user_reg_coppa_link_atleast13', array( 'yo13_date' => $yo13_date )) . '</a><br />
  1145               <a href="' . $link_coppa_yes . '">' . $lang->get('user_reg_coppa_link_not13', array( 'yo13_date' => $yo13_date )) . '</a>
  1145 							<a href="' . $link_coppa_yes . '">' . $lang->get('user_reg_coppa_link_not13', array( 'yo13_date' => $yo13_date )) . '</a>
  1146             </td>
  1146 						</td>
  1147           </tr>';
  1147 					</tr>';
  1148     echo '</table>';
  1148 		echo '</table>';
  1149     echo '</div>';
  1149 		echo '</div>';
  1150   }
  1150 	}
  1151   $template->footer();
  1151 	$template->footer();
  1152 }
  1152 }
  1153 
  1153 
  1154 function page_Special_Contributions()
  1154 function page_Special_Contributions()
  1155 {
  1155 {
  1156   global $db, $session, $paths, $template, $plugins; // Common objects
  1156 	global $db, $session, $paths, $template, $plugins; // Common objects
  1157   global $lang;
  1157 	global $lang;
  1158   
  1158 	
  1159   // This is a vast improvement over the old Special:Contributions in 1.0.x.
  1159 	// This is a vast improvement over the old Special:Contributions in 1.0.x.
  1160   
  1160 	
  1161   $template->header();
  1161 	$template->header();
  1162   $user = $paths->getParam();
  1162 	$user = $paths->getParam();
  1163   if ( !$user && isset($_GET['user']) )
  1163 	if ( !$user && isset($_GET['user']) )
  1164   {
  1164 	{
  1165     $user = $_GET['user'];
  1165 		$user = $_GET['user'];
  1166   }
  1166 	}
  1167   else if ( !$user && !isset($_GET['user']) )
  1167 	else if ( !$user && !isset($_GET['user']) )
  1168   {
  1168 	{
  1169     echo '<p>' . $lang->get('userfuncs_contribs_err_no_user') . '</p>';
  1169 		echo '<p>' . $lang->get('userfuncs_contribs_err_no_user') . '</p>';
  1170     $template->footer();
  1170 		$template->footer();
  1171     return;
  1171 		return;
  1172   }
  1172 	}
  1173   
  1173 	
  1174   $url = makeUrlNS("Special", "Log/user={$user}");
  1174 	$url = makeUrlNS("Special", "Log/user={$user}");
  1175   redirect($url, '', '', 0);
  1175 	redirect($url, '', '', 0);
  1176 }
  1176 }
  1177 
  1177 
  1178 function page_Special_ChangeStyle()
  1178 function page_Special_ChangeStyle()
  1179 {
  1179 {
  1180   global $db, $session, $paths, $template, $plugins; // Common objects
  1180 	global $db, $session, $paths, $template, $plugins; // Common objects
  1181   global $lang;
  1181 	global $lang;
  1182   
  1182 	
  1183   if ( !$session->user_logged_in )
  1183 	if ( !$session->user_logged_in )
  1184   {
  1184 	{
  1185     die_friendly('Access denied', '<p>You must be logged in to change your style. Spoofer.</p>');
  1185 		die_friendly('Access denied', '<p>You must be logged in to change your style. Spoofer.</p>');
  1186   }
  1186 	}
  1187   if(isset($_POST['theme']) && isset($_POST['style']) && isset($_POST['return_to']))
  1187 	if(isset($_POST['theme']) && isset($_POST['style']) && isset($_POST['return_to']))
  1188   {
  1188 	{
  1189     if ( !preg_match('/^([a-z0-9_-]+)$/i', $_POST['theme']) )
  1189 		if ( !preg_match('/^([a-z0-9_-]+)$/i', $_POST['theme']) )
  1190       die('Hacking attempt');
  1190 			die('Hacking attempt');
  1191     if ( !preg_match('/^([a-z0-9_-]+)$/i', $_POST['style']) )
  1191 		if ( !preg_match('/^([a-z0-9_-]+)$/i', $_POST['style']) )
  1192       die('Hacking attempt');
  1192 			die('Hacking attempt');
  1193     $d = ENANO_ROOT . '/themes/' . $_POST['theme'];
  1193 		$d = ENANO_ROOT . '/themes/' . $_POST['theme'];
  1194     $f = ENANO_ROOT . '/themes/' . $_POST['theme'] . '/css/' . $_POST['style'] . '.css';
  1194 		$f = ENANO_ROOT . '/themes/' . $_POST['theme'] . '/css/' . $_POST['style'] . '.css';
  1195     if ( !file_exists($d) || !is_dir($d) )
  1195 		if ( !file_exists($d) || !is_dir($d) )
  1196     {
  1196 		{
  1197       die('The directory "'.$d.'" does not exist.');
  1197 			die('The directory "'.$d.'" does not exist.');
  1198     }
  1198 		}
  1199     if ( !file_exists($f) )
  1199 		if ( !file_exists($f) )
  1200     {
  1200 		{
  1201       die('The file "'.$f.'" does not exist.');
  1201 			die('The file "'.$f.'" does not exist.');
  1202     }
  1202 		}
  1203     $d = $db->escape($_POST['theme']);
  1203 		$d = $db->escape($_POST['theme']);
  1204     $f = $db->escape($_POST['style']);
  1204 		$f = $db->escape($_POST['style']);
  1205     $q = 'UPDATE '.table_prefix.'users SET theme=\''.$d.'\',style=\''.$f.'\' WHERE username=\''.$session->username.'\'';
  1205 		$q = 'UPDATE '.table_prefix.'users SET theme=\''.$d.'\',style=\''.$f.'\' WHERE username=\''.$session->username.'\'';
  1206     if ( !$db->sql_query($q) )
  1206 		if ( !$db->sql_query($q) )
  1207     {
  1207 		{
  1208       $db->_die('Your theme/style preferences were not updated.');
  1208 			$db->_die('Your theme/style preferences were not updated.');
  1209     }
  1209 		}
  1210     else
  1210 		else
  1211     {
  1211 		{
  1212       redirect(makeUrl($_POST['return_to']), $lang->get('userfuncs_changetheme_success_title'), $lang->get('userfuncs_changetheme_success_body'), 3);
  1212 			redirect(makeUrl($_POST['return_to']), $lang->get('userfuncs_changetheme_success_title'), $lang->get('userfuncs_changetheme_success_body'), 3);
  1213     }
  1213 		}
  1214   }
  1214 	}
  1215   else
  1215 	else
  1216   {
  1216 	{
  1217     $template->header();
  1217 		$template->header();
  1218       $ret = ( isset($_POST['return_to']) ) ? $_POST['return_to'] : $paths->getParam(0);
  1218 			$ret = ( isset($_POST['return_to']) ) ? $_POST['return_to'] : $paths->getParam(0);
  1219       if ( !$ret )
  1219 			if ( !$ret )
  1220       {
  1220 			{
  1221         $ret = get_main_page();
  1221 				$ret = get_main_page();
  1222       }
  1222 			}
  1223       ?>
  1223 			?>
  1224         <form action="<?php echo makeUrl($paths->page); ?>" method="post">
  1224 				<form action="<?php echo makeUrl($paths->page); ?>" method="post">
  1225           <?php if ( !isset($_POST['themeselected']) ) { ?>
  1225 					<?php if ( !isset($_POST['themeselected']) ) { ?>
  1226             <h3><?php echo $lang->get('userfuncs_changetheme_heading_theme'); ?></h3>
  1226 						<h3><?php echo $lang->get('userfuncs_changetheme_heading_theme'); ?></h3>
  1227             <p>
  1227 						<p>
  1228               <select name="theme">
  1228 							<select name="theme">
  1229                <?php
  1229  							<?php
  1230                 foreach ( $template->theme_list as $t )
  1230 								foreach ( $template->theme_list as $t )
  1231                 {
  1231 								{
  1232                   if ( $t['enabled'] )
  1232 									if ( $t['enabled'] )
  1233                   {
  1233 									{
  1234                     echo '<option value="'.$t['theme_id'].'"';
  1234 										echo '<option value="'.$t['theme_id'].'"';
  1235                     if ( $t['theme_id'] == $session->theme )
  1235 										if ( $t['theme_id'] == $session->theme )
  1236                     {
  1236 										{
  1237                       echo ' selected="selected"';
  1237 											echo ' selected="selected"';
  1238                     }
  1238 										}
  1239                     echo '>' . $t['theme_name'] . '</option>';
  1239 										echo '>' . $t['theme_name'] . '</option>';
  1240                   }
  1240 									}
  1241                 }
  1241 								}
  1242                ?>
  1242  							?>
  1243               </select>
  1243 							</select>
  1244             </p>
  1244 						</p>
  1245             <p><input type="hidden" name="return_to" value="<?php echo $ret; ?>" />
  1245 						<p><input type="hidden" name="return_to" value="<?php echo $ret; ?>" />
  1246                <input type="submit" name="themeselected" value="<?php echo $lang->get('userfuncs_changetheme_btn_continue'); ?>" /></p>
  1246  							<input type="submit" name="themeselected" value="<?php echo $lang->get('userfuncs_changetheme_btn_continue'); ?>" /></p>
  1247           <?php } else { 
  1247 					<?php } else { 
  1248             $theme = $_POST['theme'];
  1248 						$theme = $_POST['theme'];
  1249             if ( !preg_match('/^([0-9A-z_-]+)$/i', $theme ) )
  1249 						if ( !preg_match('/^([0-9A-z_-]+)$/i', $theme ) )
  1250               die('Hacking attempt');
  1250 							die('Hacking attempt');
  1251             ?>
  1251 						?>
  1252             <h3><?php echo $lang->get('userfuncs_changetheme_heading_style'); ?></h3>
  1252 						<h3><?php echo $lang->get('userfuncs_changetheme_heading_style'); ?></h3>
  1253             <p>
  1253 						<p>
  1254               <select name="style">
  1254 							<select name="style">
  1255                 <?php
  1255 								<?php
  1256                   $dir = './themes/'.$theme.'/css/';
  1256 									$dir = './themes/'.$theme.'/css/';
  1257                   $list = Array();
  1257 									$list = Array();
  1258                   // Open a known directory, and proceed to read its contents
  1258 									// Open a known directory, and proceed to read its contents
  1259                   if (is_dir($dir)) {
  1259 									if (is_dir($dir)) {
  1260                     if ($dh = opendir($dir)) {
  1260 										if ($dh = opendir($dir)) {
  1261                       while (($file = readdir($dh)) !== false) {
  1261 											while (($file = readdir($dh)) !== false) {
  1262                         if(preg_match('#^(.*?)\.css$#is', $file) && $file != '_printable.css') {
  1262 												if(preg_match('#^(.*?)\.css$#is', $file) && $file != '_printable.css') {
  1263                           $list[] = substr($file, 0, strlen($file)-4);
  1263 													$list[] = substr($file, 0, strlen($file)-4);
  1264                         }
  1264 												}
  1265                       }
  1265 											}
  1266                       closedir($dh);
  1266 											closedir($dh);
  1267                     }
  1267 										}
  1268                   } else die($dir.' is not a dir');
  1268 									} else die($dir.' is not a dir');
  1269                   foreach ( $list as $l )
  1269 									foreach ( $list as $l )
  1270                   {
  1270 									{
  1271                     echo '<option value="'.$l.'">'.capitalize_first_letter($l).'</option>';
  1271 										echo '<option value="'.$l.'">'.capitalize_first_letter($l).'</option>';
  1272                   }
  1272 									}
  1273                 ?>
  1273 								?>
  1274               </select>
  1274 							</select>
  1275             </p>
  1275 						</p>
  1276             <p><input type="hidden" name="return_to" value="<?php echo $ret; ?>" />
  1276 						<p><input type="hidden" name="return_to" value="<?php echo $ret; ?>" />
  1277                <input type="hidden" name="theme" value="<?php echo $theme; ?>" />
  1277  							<input type="hidden" name="theme" value="<?php echo $theme; ?>" />
  1278                <input type="submit" name="allclear" value="<?php echo $lang->get('userfuncs_changetheme_btn_allclear'); ?>" /></p>
  1278  							<input type="submit" name="allclear" value="<?php echo $lang->get('userfuncs_changetheme_btn_allclear'); ?>" /></p>
  1279           <?php } ?>
  1279 					<?php } ?>
  1280         </form>
  1280 				</form>
  1281       <?php
  1281 			<?php
  1282     $template->footer();
  1282 		$template->footer();
  1283   }
  1283 	}
  1284 }
  1284 }
  1285 
  1285 
  1286 function page_Special_ActivateAccount()
  1286 function page_Special_ActivateAccount()
  1287 {
  1287 {
  1288   global $db, $session, $paths, $template, $plugins; // Common objects
  1288 	global $db, $session, $paths, $template, $plugins; // Common objects
  1289   global $lang;
  1289 	global $lang;
  1290   
  1290 	
  1291   $user = $paths->getParam(0);
  1291 	$user = $paths->getParam(0);
  1292   if ( !$user )
  1292 	if ( !$user )
  1293   {
  1293 	{
  1294     die_friendly($lang->get('userfuncs_activate_err_badlink_title'), '<p>' . $lang->get('userfuncs_activate_err_badlink_body') . '</p>');
  1294 		die_friendly($lang->get('userfuncs_activate_err_badlink_title'), '<p>' . $lang->get('userfuncs_activate_err_badlink_body') . '</p>');
  1295   }
  1295 	}
  1296   $user = str_replace('_', ' ', dirtify_page_id($user));
  1296 	$user = str_replace('_', ' ', dirtify_page_id($user));
  1297   $key = $paths->getParam(1);
  1297 	$key = $paths->getParam(1);
  1298   if ( !$key )
  1298 	if ( !$key )
  1299   {
  1299 	{
  1300     die_friendly($lang->get('userfuncs_activate_err_badlink_title'), '<p>' . $lang->get('userfuncs_activate_err_badlink_body') . '</p>');
  1300 		die_friendly($lang->get('userfuncs_activate_err_badlink_title'), '<p>' . $lang->get('userfuncs_activate_err_badlink_body') . '</p>');
  1301   }
  1301 	}
  1302   $s = $session->activate_account(str_replace('_', ' ', $user), $key);
  1302 	$s = $session->activate_account(str_replace('_', ' ', $user), $key);
  1303   if ( $s )
  1303 	if ( $s )
  1304   {
  1304 	{
  1305     die_friendly($lang->get('userfuncs_activate_success_title'), '<p>' . $lang->get('userfuncs_activate_success_body') . '</p>');
  1305 		die_friendly($lang->get('userfuncs_activate_success_title'), '<p>' . $lang->get('userfuncs_activate_success_body') . '</p>');
  1306   }
  1306 	}
  1307   else
  1307 	else
  1308   {
  1308 	{
  1309     die_friendly($lang->get('userfuncs_activate_err_badlink_title'), '<p>' . $lang->get('userfuncs_activate_err_bad_key') . '</p>');
  1309 		die_friendly($lang->get('userfuncs_activate_err_badlink_title'), '<p>' . $lang->get('userfuncs_activate_err_bad_key') . '</p>');
  1310   }
  1310 	}
  1311 }
  1311 }
  1312 
  1312 
  1313 function page_Special_Captcha()
  1313 function page_Special_Captcha()
  1314 {
  1314 {
  1315   global $db, $session, $paths, $template, $plugins; // Common objects
  1315 	global $db, $session, $paths, $template, $plugins; // Common objects
  1316   if ( $paths->getParam(0) == 'make' )
  1316 	if ( $paths->getParam(0) == 'make' )
  1317   {
  1317 	{
  1318     $session->kill_captcha();
  1318 		$session->kill_captcha();
  1319     echo $session->make_captcha();
  1319 		echo $session->make_captcha();
  1320     return;
  1320 		return;
  1321   }
  1321 	}
  1322   
  1322 	
  1323   $hash = $paths->getParam(0);
  1323 	$hash = $paths->getParam(0);
  1324   if ( !$hash || !preg_match('#^([0-9a-f]*){32,40}$#i', $hash) )
  1324 	if ( !$hash || !preg_match('#^([0-9a-f]*){32,40}$#i', $hash) )
  1325   {
  1325 	{
  1326     $paths->main_page();
  1326 		$paths->main_page();
  1327   }
  1327 	}
  1328   
  1328 	
  1329   if ( $validate_code = $paths->getParam(1) )
  1329 	if ( $validate_code = $paths->getParam(1) )
  1330   {
  1330 	{
  1331     if ( preg_match('/^validate=(.+)$/', $validate_code, $match) )
  1331 		if ( preg_match('/^validate=(.+)$/', $validate_code, $match) )
  1332     {
  1332 		{
  1333       header('Content-type: text/javascript');
  1333 			header('Content-type: text/javascript');
  1334       $code = $session->get_captcha($hash, true);
  1334 			$code = $session->get_captcha($hash, true);
  1335       $valid = strtolower($code) === strtolower($match[1]);
  1335 			$valid = strtolower($code) === strtolower($match[1]);
  1336       if ( !$valid )
  1336 			if ( !$valid )
  1337       {
  1337 			{
  1338         $session->make_captcha(7, $hash);
  1338 				$session->make_captcha(7, $hash);
  1339       }
  1339 			}
  1340       echo enano_json_encode(array(
  1340 			echo enano_json_encode(array(
  1341         'valid' => $valid
  1341 				'valid' => $valid
  1342         ));
  1342 				));
  1343       exit;
  1343 			exit;
  1344     }
  1344 		}
  1345   }
  1345 	}
  1346 
  1346 
  1347   $session->make_captcha(7, $hash);
  1347 	$session->make_captcha(7, $hash);
  1348   $code = $session->generate_captcha_code();
  1348 	$code = $session->generate_captcha_code();
  1349   // Avoid letting our captchas end up on failblog.org
  1349 	// Avoid letting our captchas end up on failblog.org
  1350   // BTW, the last one was a real-life encounter: http://files.ha.xx0r.info/murder.png
  1350 	// BTW, the last one was a real-life encounter: http://files.ha.xx0r.info/murder.png
  1351   foreach ( array('shit', 'cock', 'fuck', 'nazi', 'cunt', 'clit', 'pussy', 'penis', 'piss', 'tits', 'murder') as $word )
  1351 	foreach ( array('shit', 'cock', 'fuck', 'nazi', 'cunt', 'clit', 'pussy', 'penis', 'piss', 'tits', 'murder') as $word )
  1352   {
  1352 	{
  1353     if ( stristr($code, $word) )
  1353 		if ( stristr($code, $word) )
  1354     {
  1354 		{
  1355       // but don't put too much effort into this (will only correct this once)
  1355 			// but don't put too much effort into this (will only correct this once)
  1356       // I mean, face it. If it generates one of those words twice in a row, either the local root has had
  1356 			// I mean, face it. If it generates one of those words twice in a row, either the local root has had
  1357       // way too much fun with his /dev/random, or this server is just plain gutter-minded.
  1357 			// way too much fun with his /dev/random, or this server is just plain gutter-minded.
  1358       $code = $session->generate_captcha_code();
  1358 			$code = $session->generate_captcha_code();
  1359       break;
  1359 			break;
  1360     }
  1360 		}
  1361   }
  1361 	}
  1362   $q = $db->sql_query('UPDATE ' . table_prefix . "captcha SET code = '$code' WHERE session_id = '$hash';");
  1362 	$q = $db->sql_query('UPDATE ' . table_prefix . "captcha SET code = '$code' WHERE session_id = '$hash';");
  1363   if ( !$q )
  1363 	if ( !$q )
  1364     $db->_die();
  1364 		$db->_die();
  1365   
  1365 	
  1366   require ( ENANO_ROOT.'/includes/captcha.php' );
  1366 	require ( ENANO_ROOT.'/includes/captcha.php' );
  1367   $captcha = captcha_object($hash, 'freecap');
  1367 	$captcha = captcha_object($hash, 'freecap');
  1368   // $captcha->debug = true;
  1368 	// $captcha->debug = true;
  1369   $captcha->make_image();
  1369 	$captcha->make_image();
  1370   
  1370 	
  1371   exit;
  1371 	exit;
  1372 }
  1372 }
  1373 
  1373 
  1374 function page_Special_PasswordReset()
  1374 function page_Special_PasswordReset()
  1375 {
  1375 {
  1376   global $db, $session, $paths, $template, $plugins; // Common objects
  1376 	global $db, $session, $paths, $template, $plugins; // Common objects
  1377   global $lang;
  1377 	global $lang;
  1378   
  1378 	
  1379   $template->header();
  1379 	$template->header();
  1380   if($paths->getParam(0) == 'stage2')
  1380 	if($paths->getParam(0) == 'stage2')
  1381   {
  1381 	{
  1382     require_once(ENANO_ROOT . '/includes/math.php');
  1382 		require_once(ENANO_ROOT . '/includes/math.php');
  1383     require_once(ENANO_ROOT . '/includes/diffiehellman.php');
  1383 		require_once(ENANO_ROOT . '/includes/diffiehellman.php');
  1384     
  1384 		
  1385     $user_id = intval($paths->getParam(1));
  1385 		$user_id = intval($paths->getParam(1));
  1386     $encpass = $paths->getParam(2);
  1386 		$encpass = $paths->getParam(2);
  1387     if ( $user_id < 2 )
  1387 		if ( $user_id < 2 )
  1388     {
  1388 		{
  1389       echo '<p>Hacking attempt</p>';
  1389 			echo '<p>Hacking attempt</p>';
  1390       $template->footer();
  1390 			$template->footer();
  1391       return false;
  1391 			return false;
  1392     }
  1392 		}
  1393     if(!preg_match('#^([a-f0-9]+)$#i', $encpass))
  1393 		if(!preg_match('#^([a-f0-9]+)$#i', $encpass))
  1394     {
  1394 		{
  1395       echo '<p>Hacking attempt</p>';
  1395 			echo '<p>Hacking attempt</p>';
  1396       $template->footer();
  1396 			$template->footer();
  1397       return false;
  1397 			return false;
  1398     }
  1398 		}
  1399     
  1399 		
  1400     $q = $db->sql_query('SELECT username,temp_password_time,temp_password,password_salt FROM '.table_prefix.'users WHERE user_id='.$user_id.';');
  1400 		$q = $db->sql_query('SELECT username,temp_password_time,temp_password,password_salt FROM '.table_prefix.'users WHERE user_id='.$user_id.';');
  1401     if($db->numrows() < 1)
  1401 		if($db->numrows() < 1)
  1402     {
  1402 		{
  1403       echo '<p>Invalid credentials</p>';
  1403 			echo '<p>Invalid credentials</p>';
  1404       $template->footer();
  1404 			$template->footer();
  1405       return false;
  1405 			return false;
  1406     }
  1406 		}
  1407     $row = $db->fetchrow();
  1407 		$row = $db->fetchrow();
  1408     $db->free_result();
  1408 		$db->free_result();
  1409     
  1409 		
  1410     $temp_pass = $session->pk_decrypt($encpass);
  1410 		$temp_pass = $session->pk_decrypt($encpass);
  1411     $temp_hmac = hmac_sha1($temp_pass, $row['password_salt']);
  1411 		$temp_hmac = hmac_sha1($temp_pass, $row['password_salt']);
  1412     
  1412 		
  1413     if ( $temp_hmac !== $row['temp_password'] )
  1413 		if ( $temp_hmac !== $row['temp_password'] )
  1414     {
  1414 		{
  1415       echo '<p>Invalid credentials</p>';
  1415 			echo '<p>Invalid credentials</p>';
  1416       $template->footer();
  1416 			$template->footer();
  1417       return false;
  1417 			return false;
  1418     }
  1418 		}
  1419     
  1419 		
  1420     if ( ( intval($row['temp_password_time']) + ( 3600 * 24 ) ) < time() )
  1420 		if ( ( intval($row['temp_password_time']) + ( 3600 * 24 ) ) < time() )
  1421     {
  1421 		{
  1422       echo '<p>' . $lang->get('userfuncs_passreset_err_pass_expired', array('reset_url' => makeUrlNS('Special', 'PasswordReset'))) . '</p>';
  1422 			echo '<p>' . $lang->get('userfuncs_passreset_err_pass_expired', array('reset_url' => makeUrlNS('Special', 'PasswordReset'))) . '</p>';
  1423       $template->footer();
  1423 			$template->footer();
  1424       return false;
  1424 			return false;
  1425     }
  1425 		}
  1426     
  1426 		
  1427     if ( isset($_POST['do_stage2']) )
  1427 		if ( isset($_POST['do_stage2']) )
  1428     {
  1428 		{
  1429       $data = $session->get_aes_post('pass');
  1429 			$data = $session->get_aes_post('pass');
  1430       
  1430 			
  1431       if(empty($data))
  1431 			if(empty($data))
  1432       {
  1432 			{
  1433         echo 'ERROR: Sanity check failed!';
  1433 				echo 'ERROR: Sanity check failed!';
  1434         $template->footer();
  1434 				$template->footer();
  1435         return false;
  1435 				return false;
  1436       }
  1436 			}
  1437       if ( strlen($data) < 6 )
  1437 			if ( strlen($data) < 6 )
  1438       {
  1438 			{
  1439         echo '<p>' . $lang->get('userfuncs_passreset_err_too_short') . '</p>';
  1439 				echo '<p>' . $lang->get('userfuncs_passreset_err_too_short') . '</p>';
  1440         $template->footer();
  1440 				$template->footer();
  1441         return false;
  1441 				return false;
  1442       }
  1442 			}
  1443       if ( $_POST['use_crypt'] == 'no' )
  1443 			if ( $_POST['use_crypt'] == 'no' )
  1444       {
  1444 			{
  1445         if ( $_POST['pass'] !== $_POST['pass_confirm'] )
  1445 				if ( $_POST['pass'] !== $_POST['pass_confirm'] )
  1446         {
  1446 				{
  1447           echo '<p>' . $lang->get('userfuncs_passreset_err_no_match') . '</p>';
  1447 					echo '<p>' . $lang->get('userfuncs_passreset_err_no_match') . '</p>';
  1448           $template->footer();
  1448 					$template->footer();
  1449           return false;
  1449 					return false;
  1450         }
  1450 				}
  1451       }
  1451 			}
  1452       if ( getConfig('pw_strength_enable') == '1' )
  1452 			if ( getConfig('pw_strength_enable') == '1' )
  1453       {
  1453 			{
  1454         $min_score = intval(getConfig('pw_strength_minimum'));
  1454 				$min_score = intval(getConfig('pw_strength_minimum'));
  1455         $inp_score = password_score($data);
  1455 				$inp_score = password_score($data);
  1456         if ( $inp_score < $min_score )
  1456 				if ( $inp_score < $min_score )
  1457         {
  1457 				{
  1458           $url = makeUrl($paths->fullpage);
  1458 					$url = makeUrl($paths->fullpage);
  1459           echo "<p>" . $lang->get('userfuncs_passreset_err_failed_score', array('inp_score' => $inp_score, 'url' => $url)) . "</p>";
  1459 					echo "<p>" . $lang->get('userfuncs_passreset_err_failed_score', array('inp_score' => $inp_score, 'url' => $url)) . "</p>";
  1460           $template->footer();
  1460 					$template->footer();
  1461           return false;
  1461 					return false;
  1462         }
  1462 				}
  1463       }
  1463 			}
  1464       
  1464 			
  1465       $session->set_password($user_id, $data);
  1465 			$session->set_password($user_id, $data);
  1466       
  1466 			
  1467       $q = $db->sql_query('UPDATE '.table_prefix.'users SET temp_password=\'\',temp_password_time=0 WHERE user_id = '.$user_id.';');
  1467 			$q = $db->sql_query('UPDATE '.table_prefix.'users SET temp_password=\'\',temp_password_time=0 WHERE user_id = '.$user_id.';');
  1468       
  1468 			
  1469       if($q)
  1469 			if($q)
  1470       {
  1470 			{
  1471         $session->login_without_crypto($row['username'], $data);
  1471 				$session->login_without_crypto($row['username'], $data);
  1472         echo '<p>' . $lang->get('userfuncs_passreset_stage2_success', array('url_mainpage' => makeUrl(get_main_page()))) . '</p>';
  1472 				echo '<p>' . $lang->get('userfuncs_passreset_stage2_success', array('url_mainpage' => makeUrl(get_main_page()))) . '</p>';
  1473       }
  1473 			}
  1474       else
  1474 			else
  1475       {
  1475 			{
  1476         echo $db->get_error();
  1476 				echo $db->get_error();
  1477       }
  1477 			}
  1478       
  1478 			
  1479       $template->footer();
  1479 			$template->footer();
  1480       return false;
  1480 			return false;
  1481     }
  1481 		}
  1482     
  1482 		
  1483     // Password reset form
  1483 		// Password reset form
  1484     $evt_get_score = ( getConfig('pw_strength_enable') == '1' ) ? 'onkeyup="password_score_field(this);" ' : '';
  1484 		$evt_get_score = ( getConfig('pw_strength_enable') == '1' ) ? 'onkeyup="password_score_field(this);" ' : '';
  1485     $pw_meter =      ( getConfig('pw_strength_enable') == '1' ) ? '<tr><td class="row1">' . $lang->get('userfuncs_passreset_stage2_lbl_strength') . '</td><td class="row1"><div id="pwmeter"></div></td></tr>' : '';
  1485 		$pw_meter =      ( getConfig('pw_strength_enable') == '1' ) ? '<tr><td class="row1">' . $lang->get('userfuncs_passreset_stage2_lbl_strength') . '</td><td class="row1"><div id="pwmeter"></div></td></tr>' : '';
  1486     $pw_blurb =      ( getConfig('pw_strength_enable') == '1' && intval(getConfig('pw_strength_minimum')) > -10 ) ? '<br /><small>' . $lang->get('userfuncs_passreset_stage2_blurb_strength') . '</small>' : '';
  1486 		$pw_blurb =      ( getConfig('pw_strength_enable') == '1' && intval(getConfig('pw_strength_minimum')) > -10 ) ? '<br /><small>' . $lang->get('userfuncs_passreset_stage2_blurb_strength') . '</small>' : '';
  1487     
  1487 		
  1488     ?>
  1488 		?>
  1489     <form action="<?php echo makeUrl($paths->fullpage); ?>" method="post" name="resetform" onsubmit="return runEncryption();">
  1489 		<form action="<?php echo makeUrl($paths->fullpage); ?>" method="post" name="resetform" onsubmit="return runEncryption();">
  1490       <br />
  1490 			<br />
  1491       <div class="tblholder">
  1491 			<div class="tblholder">
  1492         <table border="0" style="width: 100%;" cellspacing="1" cellpadding="4">
  1492 				<table border="0" style="width: 100%;" cellspacing="1" cellpadding="4">
  1493           <tr><th colspan="2"><?php echo $lang->get('userfuncs_passreset_stage2_th'); ?></th></tr>
  1493 					<tr><th colspan="2"><?php echo $lang->get('userfuncs_passreset_stage2_th'); ?></th></tr>
  1494           <tr><td class="row1"><?php echo $lang->get('userfuncs_passreset_stage2_lbl_password'); ?> <?php echo $pw_blurb; ?></td><td class="row1"><input name="pass" type="password" <?php echo $evt_get_score; ?>/></td></tr>
  1494 					<tr><td class="row1"><?php echo $lang->get('userfuncs_passreset_stage2_lbl_password'); ?> <?php echo $pw_blurb; ?></td><td class="row1"><input name="pass" type="password" <?php echo $evt_get_score; ?>/></td></tr>
  1495           <tr><td class="row2"><?php echo $lang->get('userfuncs_passreset_stage2_lbl_confirm'); ?> </td><td class="row2"><input name="pass_confirm" type="password" /></td></tr>
  1495 					<tr><td class="row2"><?php echo $lang->get('userfuncs_passreset_stage2_lbl_confirm'); ?> </td><td class="row2"><input name="pass_confirm" type="password" /></td></tr>
  1496           <?php echo $pw_meter; ?>
  1496 					<?php echo $pw_meter; ?>
  1497           <tr>
  1497 					<tr>
  1498             <td colspan="2" class="row3" style="text-align: center;">
  1498 						<td colspan="2" class="row3" style="text-align: center;">
  1499               
  1499 							
  1500               <input type="submit" name="do_stage2" value="<?php echo $lang->get('userfuncs_passreset_stage2_btn_submit'); ?>" />
  1500 							<input type="submit" name="do_stage2" value="<?php echo $lang->get('userfuncs_passreset_stage2_btn_submit'); ?>" />
  1501             </td>
  1501 						</td>
  1502           </tr>
  1502 					</tr>
  1503         </table>
  1503 				</table>
  1504       </div>
  1504 			</div>
  1505       <?php echo $session->generate_aes_form(); ?>
  1505 			<?php echo $session->generate_aes_form(); ?>
  1506     </form>
  1506 		</form>
  1507     <script type="text/javascript">
  1507 		<script type="text/javascript">
  1508     addOnloadHook(function()
  1508 		addOnloadHook(function()
  1509       {
  1509 			{
  1510         load_component('pwstrength');
  1510 				load_component('pwstrength');
  1511         password_score_field(document.forms.resetform.pass);
  1511 				password_score_field(document.forms.resetform.pass);
  1512       });
  1512 			});
  1513     </script>
  1513 		</script>
  1514     <?php
  1514 		<?php
  1515     echo $session->aes_javascript('resetform', 'pass', 'use_crypt', 'crypt_key', 'crypt_data', 'challenge_data', 'dh_supported', 'dh_public_key', 'dh_client_public_key');
  1515 		echo $session->aes_javascript('resetform', 'pass', 'use_crypt', 'crypt_key', 'crypt_data', 'challenge_data', 'dh_supported', 'dh_public_key', 'dh_client_public_key');
  1516     $template->footer();
  1516 		$template->footer();
  1517     return true;
  1517 		return true;
  1518   }
  1518 	}
  1519   if ( $session->user_logged_in )
  1519 	if ( $session->user_logged_in )
  1520   {
  1520 	{
  1521     $paths->main_page();
  1521 		$paths->main_page();
  1522   }
  1522 	}
  1523   
  1523 	
  1524   if(isset($_POST['do_reset']))
  1524 	if(isset($_POST['do_reset']))
  1525   {
  1525 	{
  1526     if($session->mail_password_reset($_POST['username']))
  1526 		if($session->mail_password_reset($_POST['username']))
  1527     {
  1527 		{
  1528       echo '<p>' . $lang->get('userfuncs_passreset_stage1_success') . '</p>';
  1528 			echo '<p>' . $lang->get('userfuncs_passreset_stage1_success') . '</p>';
  1529     }
  1529 		}
  1530     else
  1530 		else
  1531     {
  1531 		{
  1532       echo '<p>' . $lang->get('userfuncs_passreset_stage1_error') . '</p>';
  1532 			echo '<p>' . $lang->get('userfuncs_passreset_stage1_error') . '</p>';
  1533     }
  1533 		}
  1534     $template->footer();
  1534 		$template->footer();
  1535     return true;
  1535 		return true;
  1536   }
  1536 	}
  1537   echo '<p>' . $lang->get('userfuncs_passreset_blurb_line1') . '</p>
  1537 	echo '<p>' . $lang->get('userfuncs_passreset_blurb_line1') . '</p>
  1538         <p>' . $lang->get('userfuncs_passreset_blurb_line2') . '</p>
  1538 				<p>' . $lang->get('userfuncs_passreset_blurb_line2') . '</p>
  1539         <form action="'.makeUrl($paths->page).'" method="post" onsubmit="if(!submitAuthorized) return false;">
  1539 				<form action="'.makeUrl($paths->page).'" method="post" onsubmit="if(!submitAuthorized) return false;">
  1540           <p>' . $lang->get('userfuncs_passreset_lbl_username') . '  '.$template->username_field('username').'</p>
  1540 					<p>' . $lang->get('userfuncs_passreset_lbl_username') . '  '.$template->username_field('username').'</p>
  1541           <p><input type="submit" name="do_reset" value="' . $lang->get('userfuncs_passreset_btn_mailpasswd') . '" /></p>
  1541 					<p><input type="submit" name="do_reset" value="' . $lang->get('userfuncs_passreset_btn_mailpasswd') . '" /></p>
  1542         </form>';
  1542 				</form>';
  1543   $template->footer();
  1543 	$template->footer();
  1544 }
  1544 }
  1545 
  1545 
  1546 function page_Special_Memberlist()
  1546 function page_Special_Memberlist()
  1547 {
  1547 {
  1548   global $db, $session, $paths, $template, $plugins; // Common objects
  1548 	global $db, $session, $paths, $template, $plugins; // Common objects
  1549   global $lang;
  1549 	global $lang;
  1550   
  1550 	
  1551   $template->header();
  1551 	$template->header();
  1552   
  1552 	
  1553   $startletters = 'abcdefghijklmnopqrstuvwxyz';
  1553 	$startletters = 'abcdefghijklmnopqrstuvwxyz';
  1554   $startletters = enano_str_split($startletters);
  1554 	$startletters = enano_str_split($startletters);
  1555   $startletter = ( isset($_GET['letter']) ) ? strtolower($_GET['letter']) : '';
  1555 	$startletter = ( isset($_GET['letter']) ) ? strtolower($_GET['letter']) : '';
  1556   if ( !in_array($startletter, $startletters) && $startletter != 'chr' )
  1556 	if ( !in_array($startletter, $startletters) && $startletter != 'chr' )
  1557   {
  1557 	{
  1558     $startletter = '';
  1558 		$startletter = '';
  1559   }
  1559 	}
  1560   
  1560 	
  1561   $startletter_sql = $startletter;
  1561 	$startletter_sql = $startletter;
  1562   if ( $startletter == 'chr' )
  1562 	if ( $startletter == 'chr' )
  1563   {
  1563 	{
  1564     $startletter_sql = '([^a-z])';
  1564 		$startletter_sql = '([^a-z])';
  1565   }
  1565 	}
  1566   
  1566 	
  1567   // offset
  1567 	// offset
  1568   $perpage = 25;
  1568 	$perpage = 25;
  1569   $page = (( isset($_GET['offset']) && strval(intval($_GET['offset'])) === $_GET['offset']) ? intval($_GET['offset']) : 1) - 1;
  1569 	$page = (( isset($_GET['offset']) && strval(intval($_GET['offset'])) === $_GET['offset']) ? intval($_GET['offset']) : 1) - 1;
  1570   $offset = $page * $perpage;
  1570 	$offset = $page * $perpage;
  1571   
  1571 	
  1572   // sort order
  1572 	// sort order
  1573   $sortkeys = array(
  1573 	$sortkeys = array(
  1574       'uid' => 'u.user_id',
  1574 			'uid' => 'u.user_id',
  1575       'username' => 'u.username',
  1575 			'username' => 'u.username',
  1576       'email' => 'u.email',
  1576 			'email' => 'u.email',
  1577       'regist' => 'u.reg_time'
  1577 			'regist' => 'u.reg_time'
  1578     );
  1578 		);
  1579   
  1579 	
  1580   $sortby = ( isset($_GET['sort']) && isset($sortkeys[$_GET['sort']]) ) ? $_GET['sort'] : 'username';
  1580 	$sortby = ( isset($_GET['sort']) && isset($sortkeys[$_GET['sort']]) ) ? $_GET['sort'] : 'username';
  1581   $sort_sqllet = $sortkeys[$sortby];
  1581 	$sort_sqllet = $sortkeys[$sortby];
  1582   
  1582 	
  1583   $target_order = ( isset($_GET['orderby']) && in_array($_GET['orderby'], array('ASC', 'DESC')) )? $_GET['orderby'] : 'ASC';
  1583 	$target_order = ( isset($_GET['orderby']) && in_array($_GET['orderby'], array('ASC', 'DESC')) )? $_GET['orderby'] : 'ASC';
  1584   
  1584 	
  1585   $sortorders = array();
  1585 	$sortorders = array();
  1586   foreach ( $sortkeys as $k => $_unused )
  1586 	foreach ( $sortkeys as $k => $_unused )
  1587   {
  1587 	{
  1588     $sortorders[$k] = ( $sortby == $k ) ? ( $target_order == 'ASC' ? 'DESC' : 'ASC' ) : 'ASC';
  1588 		$sortorders[$k] = ( $sortby == $k ) ? ( $target_order == 'ASC' ? 'DESC' : 'ASC' ) : 'ASC';
  1589   }
  1589 	}
  1590   
  1590 	
  1591   // Why 3.3714%? 100 percent / 28 cells, minus a little (0.2% / cell) to account for cell spacing
  1591 	// Why 3.3714%? 100 percent / 28 cells, minus a little (0.2% / cell) to account for cell spacing
  1592   
  1592 	
  1593   echo '<div class="tblholder">
  1593 	echo '<div class="tblholder">
  1594           <table border="0" cellspacing="1" cellpadding="4" style="text-align: center;">
  1594 					<table border="0" cellspacing="1" cellpadding="4" style="text-align: center;">
  1595             <tr>';
  1595 						<tr>';
  1596   echo '<td class="row1" style="width: 3.3714%;"><a href="' . makeUrlNS('Special', 'Memberlist', 'letter=&sort=' . $sortby . '&orderby=' . $target_order, true) . '">All</a></td>';
  1596 	echo '<td class="row1" style="width: 3.3714%;"><a href="' . makeUrlNS('Special', 'Memberlist', 'letter=&sort=' . $sortby . '&orderby=' . $target_order, true) . '">All</a></td>';
  1597   echo '<td class="row1" style="width: 3.3714%;"><a href="' . makeUrlNS('Special', 'Memberlist', 'letter=chr&sort=' . $sortby . '&orderby=' . $target_order, true) . '">#</a></td>';
  1597 	echo '<td class="row1" style="width: 3.3714%;"><a href="' . makeUrlNS('Special', 'Memberlist', 'letter=chr&sort=' . $sortby . '&orderby=' . $target_order, true) . '">#</a></td>';
  1598   foreach ( $startletters as $letter )
  1598 	foreach ( $startletters as $letter )
  1599   {
  1599 	{
  1600     echo '<td class="row1" style="width: 3.3714%;"><a href="' . makeUrlNS('Special', 'Memberlist', 'letter=' . $letter . '&sort=' . $sortby . '&orderby=' . $target_order, true) . '">' . strtoupper($letter) . '</a></td>';
  1600 		echo '<td class="row1" style="width: 3.3714%;"><a href="' . makeUrlNS('Special', 'Memberlist', 'letter=' . $letter . '&sort=' . $sortby . '&orderby=' . $target_order, true) . '">' . strtoupper($letter) . '</a></td>';
  1601   }
  1601 	}
  1602   echo '    </tr>
  1602 	echo '    </tr>
  1603           </table>
  1603 					</table>
  1604         </div>';
  1604 				</div>';
  1605   
  1605 	
  1606   // User search             
  1606 	// User search             
  1607   if ( isset($_GET['finduser']) )
  1607 	if ( isset($_GET['finduser']) )
  1608   {
  1608 	{
  1609     $finduser = str_replace(array(  '%',   '_'),
  1609 		$finduser = str_replace(array(  '%',   '_'),
  1610                             array('\\%', '\\_'),
  1610 														array('\\%', '\\_'),
  1611                             $_GET['finduser']);
  1611 														$_GET['finduser']);
  1612     $finduser = str_replace(array('*', '?'),
  1612 		$finduser = str_replace(array('*', '?'),
  1613                             array('%', '_'),
  1613 														array('%', '_'),
  1614                             $finduser);
  1614 														$finduser);
  1615     $finduser = $db->escape($finduser);
  1615 		$finduser = $db->escape($finduser);
  1616     $username_where = ENANO_SQLFUNC_LOWERCASE . '(u.username) LIKE \'%' . strtolower($finduser) . '%\'';
  1616 		$username_where = ENANO_SQLFUNC_LOWERCASE . '(u.username) LIKE \'%' . strtolower($finduser) . '%\'';
  1617     $finduser_url = 'finduser=' . rawurlencode($_GET['finduser']) . '&';
  1617 		$finduser_url = 'finduser=' . rawurlencode($_GET['finduser']) . '&';
  1618   }
  1618 	}
  1619   else
  1619 	else
  1620   {
  1620 	{
  1621     if ( ENANO_DBLAYER == 'MYSQL' )
  1621 		if ( ENANO_DBLAYER == 'MYSQL' )
  1622       $username_where = 'lcase(u.username) REGEXP lcase("^' . $startletter_sql . '")';
  1622 			$username_where = 'lcase(u.username) REGEXP lcase("^' . $startletter_sql . '")';
  1623     else if ( ENANO_DBLAYER == 'PGSQL' )
  1623 		else if ( ENANO_DBLAYER == 'PGSQL' )
  1624       $username_where = 'lower(u.username) ~ lower(\'^' . $startletter_sql . '\')';
  1624 			$username_where = 'lower(u.username) ~ lower(\'^' . $startletter_sql . '\')';
  1625     $finduser_url = '';
  1625 		$finduser_url = '';
  1626   }
  1626 	}
  1627   
  1627 	
  1628   // Column markers
  1628 	// Column markers
  1629   $headings = '<tr>
  1629 	$headings = '<tr>
  1630                  <th style="max-width: 50px;">
  1630  								<th style="max-width: 50px;">
  1631                    <a href="' . makeUrlNS('Special', 'Memberlist', $finduser_url . 'letter=' . $startletter . '&sort=uid&orderby=' . $sortorders['uid'], true) . '">#</a>
  1631  									<a href="' . makeUrlNS('Special', 'Memberlist', $finduser_url . 'letter=' . $startletter . '&sort=uid&orderby=' . $sortorders['uid'], true) . '">#</a>
  1632                  </th>
  1632  								</th>
  1633                  <th>
  1633  								<th>
  1634                    <a href="' . makeUrlNS('Special', 'Memberlist', $finduser_url . 'letter=' . $startletter . '&sort=username&orderby=' . $sortorders['username'], true) . '">' . $lang->get('userfuncs_ml_column_username') . '</a>
  1634  									<a href="' . makeUrlNS('Special', 'Memberlist', $finduser_url . 'letter=' . $startletter . '&sort=username&orderby=' . $sortorders['username'], true) . '">' . $lang->get('userfuncs_ml_column_username') . '</a>
  1635                  </th>
  1635  								</th>
  1636                  <th>
  1636  								<th>
  1637                    ' . $lang->get('userfuncs_ml_column_userlevel') . '
  1637  									' . $lang->get('userfuncs_ml_column_userlevel') . '
  1638                  </th>
  1638  								</th>
  1639                  <th>
  1639  								<th>
  1640                    <a href="' . makeUrlNS('Special', 'Memberlist', $finduser_url . 'letter=' . $startletter . '&sort=email&orderby=' . $sortorders['email'], true) . '">' . $lang->get('userfuncs_ml_column_email') . '</a>
  1640  									<a href="' . makeUrlNS('Special', 'Memberlist', $finduser_url . 'letter=' . $startletter . '&sort=email&orderby=' . $sortorders['email'], true) . '">' . $lang->get('userfuncs_ml_column_email') . '</a>
  1641                  </th>
  1641  								</th>
  1642                  <th>
  1642  								<th>
  1643                    <a href="' . makeUrlNS('Special', 'Memberlist', $finduser_url . 'letter=' . $startletter . '&sort=regist&orderby=' . $sortorders['regist'], true) . '">' . $lang->get('userfuncs_ml_column_regtime') . '</a>
  1643  									<a href="' . makeUrlNS('Special', 'Memberlist', $finduser_url . 'letter=' . $startletter . '&sort=regist&orderby=' . $sortorders['regist'], true) . '">' . $lang->get('userfuncs_ml_column_regtime') . '</a>
  1644                  </th>
  1644  								</th>
  1645                </tr>';
  1645  							</tr>';
  1646                
  1646  							
  1647   // determine number of rows
  1647 	// determine number of rows
  1648   $q = $db->sql_query('SELECT COUNT(u.user_id) FROM '.table_prefix.'users AS u WHERE ' . $username_where . ' AND u.username != \'Anonymous\';');
  1648 	$q = $db->sql_query('SELECT COUNT(u.user_id) FROM '.table_prefix.'users AS u WHERE ' . $username_where . ' AND u.username != \'Anonymous\';');
  1649   if ( !$q )
  1649 	if ( !$q )
  1650     $db->_die();
  1650 		$db->_die();
  1651   
  1651 	
  1652   list($num_rows) = $db->fetchrow_num();
  1652 	list($num_rows) = $db->fetchrow_num();
  1653   $db->free_result();
  1653 	$db->free_result();
  1654   
  1654 	
  1655   if ( !empty($finduser_url) )
  1655 	if ( !empty($finduser_url) )
  1656   {
  1656 	{
  1657     switch ( $num_rows )
  1657 		switch ( $num_rows )
  1658     {
  1658 		{
  1659       case 0:
  1659 			case 0:
  1660         $str = ''; /* $lang->get('userfuncs_ml_msg_matches_zero'); */ break;
  1660 				$str = ''; /* $lang->get('userfuncs_ml_msg_matches_zero'); */ break;
  1661       case 1:
  1661 			case 1:
  1662         $str = $lang->get('userfuncs_ml_msg_matches_one'); break;
  1662 				$str = $lang->get('userfuncs_ml_msg_matches_one'); break;
  1663       default:
  1663 			default:
  1664         $str = $lang->get('userfuncs_ml_msg_matches', array('matches' => $num_rows)); break;
  1664 				$str = $lang->get('userfuncs_ml_msg_matches', array('matches' => $num_rows)); break;
  1665     }
  1665 		}
  1666     echo "<h3>$str</h3>";
  1666 		echo "<h3>$str</h3>";
  1667   }
  1667 	}
  1668   
  1668 	
  1669   // main selector
  1669 	// main selector
  1670   $pgsql_additional_group_by = ( ENANO_DBLAYER == 'PGSQL' ) ? ', u.username, u.reg_time, u.email, u.user_level, u.user_has_avatar, u.avatar_type, x.email_public' : '';
  1670 	$pgsql_additional_group_by = ( ENANO_DBLAYER == 'PGSQL' ) ? ', u.username, u.reg_time, u.email, u.user_level, u.user_has_avatar, u.avatar_type, x.email_public' : '';
  1671   $q = $db->sql_query('SELECT \'\' AS infobit, u.user_id, u.username, u.reg_time, u.email, u.user_level, u.user_has_avatar, u.avatar_type, x.email_public, COUNT(c.comment_id) AS num_comments FROM '.table_prefix.'users AS u
  1671 	$q = $db->sql_query('SELECT \'\' AS infobit, u.user_id, u.username, u.reg_time, u.email, u.user_level, u.user_has_avatar, u.avatar_type, x.email_public, COUNT(c.comment_id) AS num_comments FROM '.table_prefix.'users AS u
  1672                                     LEFT JOIN '.table_prefix.'users_extra AS x
  1672 																		LEFT JOIN '.table_prefix.'users_extra AS x
  1673                                       ON ( u.user_id = x.user_id )
  1673 																			ON ( u.user_id = x.user_id )
  1674                                     LEFT JOIN ' . table_prefix . 'comments AS c
  1674 																		LEFT JOIN ' . table_prefix . 'comments AS c
  1675                                       ON ( u.user_id = c.user_id )
  1675 																			ON ( u.user_id = c.user_id )
  1676                                     WHERE ' . $username_where . ' AND u.username != \'Anonymous\'
  1676 																		WHERE ' . $username_where . ' AND u.username != \'Anonymous\'
  1677                                     GROUP BY u.user_id' . $pgsql_additional_group_by . '
  1677 																		GROUP BY u.user_id' . $pgsql_additional_group_by . '
  1678                                     ORDER BY ' . $sort_sqllet . ' ' . $target_order . '
  1678 																		ORDER BY ' . $sort_sqllet . ' ' . $target_order . '
  1679                                     LIMIT ' . $perpage . ' OFFSET ' . $offset . ';');
  1679 																		LIMIT ' . $perpage . ' OFFSET ' . $offset . ';');
  1680   if ( !$q )
  1680 	if ( !$q )
  1681     $db->_die();
  1681 		$db->_die();
  1682   
  1682 	
  1683   // formatter parameters
  1683 	// formatter parameters
  1684   $formatter = new MemberlistFormatter();
  1684 	$formatter = new MemberlistFormatter();
  1685   $formatters = array(
  1685 	$formatters = array(
  1686     'username' => array($formatter, 'username'),
  1686 		'username' => array($formatter, 'username'),
  1687     'user_level' => array($formatter, 'user_level'),
  1687 		'user_level' => array($formatter, 'user_level'),
  1688     'email' => array($formatter, 'email'),
  1688 		'email' => array($formatter, 'email'),
  1689     'reg_time' => array($formatter, 'reg_time'),
  1689 		'reg_time' => array($formatter, 'reg_time'),
  1690     'infobit' => array($formatter, 'infobit')
  1690 		'infobit' => array($formatter, 'infobit')
  1691     );
  1691 		);
  1692   
  1692 	
  1693   $result_url = makeUrlNS('Special', 'Memberlist', ( str_replace('%', '%%', $finduser_url) ) . 'letter=' . $startletter . '&offset=%s&sort=' . $sortby . '&orderby=' . $target_order );
  1693 	$result_url = makeUrlNS('Special', 'Memberlist', ( str_replace('%', '%%', $finduser_url) ) . 'letter=' . $startletter . '&offset=%s&sort=' . $sortby . '&orderby=' . $target_order );
  1694   $paginator = generate_paginator($page, ceil($num_rows / $perpage), $result_url);
  1694 	$paginator = generate_paginator($page, ceil($num_rows / $perpage), $result_url);
  1695   
  1695 	
  1696   if ( $num_rows > 0 )
  1696 	if ( $num_rows > 0 )
  1697   {
  1697 	{
  1698     if ( $num_rows > $perpage )
  1698 		if ( $num_rows > $perpage )
  1699       echo $paginator;
  1699 			echo $paginator;
  1700     
  1700 		
  1701     echo '<div class="tblholder">
  1701 		echo '<div class="tblholder">
  1702                 <table border="0" cellspacing="1" cellpadding="4" style="text-align: center;">
  1702 								<table border="0" cellspacing="1" cellpadding="4" style="text-align: center;">
  1703                   ' . $headings;
  1703 									' . $headings;
  1704                   
  1704 									
  1705     $i = 0;
  1705 		$i = 0;
  1706     while ( $row = $db->fetchrow($q) )
  1706 		while ( $row = $db->fetchrow($q) )
  1707     {
  1707 		{
  1708       $i++;
  1708 			$i++;
  1709       $cls = ( $i % 2 == 0 ) ? 'row2' : 'row1';
  1709 			$cls = ( $i % 2 == 0 ) ? 'row2' : 'row1';
  1710       echo '<tr>';
  1710 			echo '<tr>';
  1711       echo '<td class="' . $cls . '">' . $row['user_id'] . '</td>';
  1711 			echo '<td class="' . $cls . '">' . $row['user_id'] . '</td>';
  1712       echo '<td class="' . $cls . '" style="text-align: left;">' . $formatter->username($row['username'], $row) . '</td>';
  1712 			echo '<td class="' . $cls . '" style="text-align: left;">' . $formatter->username($row['username'], $row) . '</td>';
  1713       echo '<td class="' . $cls . '">' . $formatter->user_level($row['user_level'], $row) . '</td>';
  1713 			echo '<td class="' . $cls . '">' . $formatter->user_level($row['user_level'], $row) . '</td>';
  1714       echo '<td class="' . $cls . '">' . $formatter->email($row['email'], $row) . '</td>';
  1714 			echo '<td class="' . $cls . '">' . $formatter->email($row['email'], $row) . '</td>';
  1715       echo '<td class="' . $cls . '">' . $formatter->reg_time($row['reg_time'], $row) . '</td>';
  1715 			echo '<td class="' . $cls . '">' . $formatter->reg_time($row['reg_time'], $row) . '</td>';
  1716       echo '</tr>';
  1716 			echo '</tr>';
  1717       echo '<tr>';
  1717 			echo '<tr>';
  1718       echo '<td colspan="5" class="row3" style="text-align: left;">
  1718 			echo '<td colspan="5" class="row3" style="text-align: left;">
  1719                  <div id="ml_moreinfo_' . $row['user_id'] . '" style="display: none;">
  1719  								<div id="ml_moreinfo_' . $row['user_id'] . '" style="display: none;">
  1720                    ' . $formatter->infobit(true, $row) . '
  1720  									' . $formatter->infobit(true, $row) . '
  1721                  </div>
  1721  								</div>
  1722                </td>';
  1722  							</td>';
  1723       echo '</tr>';
  1723 			echo '</tr>';
  1724     }
  1724 		}
  1725     
  1725 		
  1726     echo '  ' . $headings . '
  1726 		echo '  ' . $headings . '
  1727                  </table>
  1727  								</table>
  1728               </div>
  1728 							</div>
  1729               ';
  1729 							';
  1730     
  1730 		
  1731     if ( $num_rows > $perpage )
  1731 		if ( $num_rows > $perpage )
  1732       echo $paginator;
  1732 			echo $paginator;
  1733   }
  1733 	}
  1734   else
  1734 	else
  1735   {
  1735 	{
  1736     echo '<h2 class="emptymessage">' . $lang->get('log_msg_no_results') . '</h2>';
  1736 		echo '<h2 class="emptymessage">' . $lang->get('log_msg_no_results') . '</h2>';
  1737   }
  1737 	}
  1738   
  1738 	
  1739   echo '<div style="float: left;">
  1739 	echo '<div style="float: left;">
  1740           <form action="' . makeUrlNS('Special', 'Memberlist') . '" method="get" onsubmit="if ( !submitAuthorized ) return false;">'
  1740 					<form action="' . makeUrlNS('Special', 'Memberlist') . '" method="get" onsubmit="if ( !submitAuthorized ) return false;">'
  1741          . ( urlSeparator == '&' ? '<input type="hidden" name="title" value="' . htmlspecialchars( $paths->page ) . '" />' : '' )
  1741  				. ( urlSeparator == '&' ? '<input type="hidden" name="title" value="' . htmlspecialchars( $paths->page ) . '" />' : '' )
  1742          . ( $session->sid_super ? '<input type="hidden" name="auth"  value="' . $session->sid_super . '" />' : '')
  1742  				. ( $session->sid_super ? '<input type="hidden" name="auth"  value="' . $session->sid_super . '" />' : '')
  1743          . '<p>' . $lang->get('userfuncs_ml_lbl_finduser') . ' ' . $template->username_field('finduser') . ' <input type="submit" value="' . $lang->get('userfuncs_ml_btn_go') . '" /><br />
  1743  				. '<p>' . $lang->get('userfuncs_ml_lbl_finduser') . ' ' . $template->username_field('finduser') . ' <input type="submit" value="' . $lang->get('userfuncs_ml_btn_go') . '" /><br />
  1744             <small>' . $lang->get('userfuncs_ml_tip_wildcard') . '</small></p>'
  1744 						<small>' . $lang->get('userfuncs_ml_tip_wildcard') . '</small></p>'
  1745          . '</form>
  1745  				. '</form>
  1746          </div>';
  1746  				</div>';
  1747   
  1747 	
  1748   $template->footer();
  1748 	$template->footer();
  1749 }
  1749 }
  1750 
  1750 
  1751 /**
  1751 /**
  1752  * Class for formatting results for the memberlist.
  1752  * Class for formatting results for the memberlist.
  1753  * @access private
  1753  * @access private
  1754  */
  1754  */
  1755 
  1755 
  1756 class MemberlistFormatter
  1756 class MemberlistFormatter
  1757 {
  1757 {
  1758   function username($username, $row)
  1758 	function username($username, $row)
  1759   {
  1759 	{
  1760     global $db, $session, $paths, $template, $plugins; // Common objects
  1760 		global $db, $session, $paths, $template, $plugins; // Common objects
  1761     global $lang;
  1761 		global $lang;
  1762     
  1762 		
  1763     $userpage = $paths->nslist['User'] . sanitize_page_id($username);
  1763 		$userpage = $paths->nslist['User'] . sanitize_page_id($username);
  1764     $class = ( isPage($userpage) ) ? '' : ' class="wikilink-nonexistent"';
  1764 		$class = ( isPage($userpage) ) ? '' : ' class="wikilink-nonexistent"';
  1765     $anchor = '<a href="' . makeUrlNS('User', sanitize_page_id($username)) . '"' . $class . ' onclick="load_component(\'jquery\'); load_component(\'jquery-ui\'); var el = document.getElementById(\'ml_moreinfo_' . $row['user_id'] . '\'); $(el).toggle(\'blind\'); return false;">' . htmlspecialchars($username) . '</a>';
  1765 		$anchor = '<a href="' . makeUrlNS('User', sanitize_page_id($username)) . '"' . $class . ' onclick="load_component(\'jquery\'); load_component(\'jquery-ui\'); var el = document.getElementById(\'ml_moreinfo_' . $row['user_id'] . '\'); $(el).toggle(\'blind\'); return false;">' . htmlspecialchars($username) . '</a>';
  1766     if ( $session->user_level >= USER_LEVEL_ADMIN )
  1766 		if ( $session->user_level >= USER_LEVEL_ADMIN )
  1767     {
  1767 		{
  1768       $anchor .= ' <small>- <a href="' . makeUrlNS('Special', 'Administration', 'module=' . $paths->nslist['Admin'] . 'UserManager&src=get&username=' . urlencode($username), true) . '"
  1768 			$anchor .= ' <small>- <a href="' . makeUrlNS('Special', 'Administration', 'module=' . $paths->nslist['Admin'] . 'UserManager&src=get&username=' . urlencode($username), true) . '"
  1769                                onclick="ajaxAdminUser(\'' . addslashes(htmlspecialchars($username)) . '\'); return false;">' . $lang->get('userfuncs_ml_btn_adminuser') . '</a></small>';
  1769  															onclick="ajaxAdminUser(\'' . addslashes(htmlspecialchars($username)) . '\'); return false;">' . $lang->get('userfuncs_ml_btn_adminuser') . '</a></small>';
  1770     }
  1770 		}
  1771     return $anchor;
  1771 		return $anchor;
  1772   }
  1772 	}
  1773   function user_level($level, $row)
  1773 	function user_level($level, $row)
  1774   {
  1774 	{
  1775     global $db, $session, $paths, $template, $plugins; // Common objects
  1775 		global $db, $session, $paths, $template, $plugins; // Common objects
  1776     global $lang;
  1776 		global $lang;
  1777     /*
  1777 		/*
  1778     switch ( $level )
  1778 		switch ( $level )
  1779     {
  1779 		{
  1780       case USER_LEVEL_GUEST:
  1780 			case USER_LEVEL_GUEST:
  1781         $s_level = $lang->get('userfuncs_ml_level_guest'); break;
  1781 				$s_level = $lang->get('userfuncs_ml_level_guest'); break;
  1782       case USER_LEVEL_MEMBER:
  1782 			case USER_LEVEL_MEMBER:
  1783       case USER_LEVEL_CHPREF:
  1783 			case USER_LEVEL_CHPREF:
  1784         $s_level = $lang->get('userfuncs_ml_level_member'); break;
  1784 				$s_level = $lang->get('userfuncs_ml_level_member'); break;
  1785       case USER_LEVEL_MOD:
  1785 			case USER_LEVEL_MOD:
  1786         $s_level = $lang->get('userfuncs_ml_level_mod'); break;
  1786 				$s_level = $lang->get('userfuncs_ml_level_mod'); break;
  1787       case USER_LEVEL_ADMIN:
  1787 			case USER_LEVEL_ADMIN:
  1788         $s_level = $lang->get('userfuncs_ml_level_admin'); break;
  1788 				$s_level = $lang->get('userfuncs_ml_level_admin'); break;
  1789       default:
  1789 			default:
  1790         $s_level = $lang->get('userfuncs_ml_level_unknown', array( 'level' => $level ));
  1790 				$s_level = $lang->get('userfuncs_ml_level_unknown', array( 'level' => $level ));
  1791     }
  1791 		}
  1792     */
  1792 		*/
  1793     
  1793 		
  1794     // TODO: Requested by mm3. Is this too CPU-intensive? Optimize?
  1794 		// TODO: Requested by mm3. Is this too CPU-intensive? Optimize?
  1795     //       Performance yield =/= about the same (but only 4 users under testing conditions)
  1795 		//       Performance yield =/= about the same (but only 4 users under testing conditions)
  1796     $rankdata = $session->get_user_rank($row['user_id']);
  1796 		$rankdata = $session->get_user_rank($row['user_id']);
  1797     $s_level = '<span style="' . $rankdata['rank_style'] . '">' . $lang->get($rankdata['rank_title']) . '</span>';
  1797 		$s_level = '<span style="' . $rankdata['rank_style'] . '">' . $lang->get($rankdata['rank_title']) . '</span>';
  1798     
  1798 		
  1799     return $s_level;
  1799 		return $s_level;
  1800   }
  1800 	}
  1801   function email($addy, $row)
  1801 	function email($addy, $row)
  1802   {
  1802 	{
  1803     global $lang;
  1803 		global $lang;
  1804     if ( $row['email_public'] == '1' )
  1804 		if ( $row['email_public'] == '1' )
  1805     {
  1805 		{
  1806       global $email;
  1806 			global $email;
  1807       $addy = $email->encryptEmail($addy);
  1807 			$addy = $email->encryptEmail($addy);
  1808       return $addy;
  1808 			return $addy;
  1809     }
  1809 		}
  1810     else
  1810 		else
  1811     {
  1811 		{
  1812       return '<small>&lt;' . $lang->get('userfuncs_ml_email_nonpublic') . '&gt;</small>';
  1812 			return '<small>&lt;' . $lang->get('userfuncs_ml_email_nonpublic') . '&gt;</small>';
  1813     }
  1813 		}
  1814   }
  1814 	}
  1815   /**
  1815 	/**
  1816    * Format a time as a reference to a day, with user-friendly "X days ago"/"Today"/"Yesterday" returned when relevant.
  1816  	* Format a time as a reference to a day, with user-friendly "X days ago"/"Today"/"Yesterday" returned when relevant.
  1817    * @param int UNIX timestamp
  1817  	* @param int UNIX timestamp
  1818    * @return string
  1818  	* @return string
  1819    */
  1819  	*/
  1820   
  1820 	
  1821   public static function format_date($time)
  1821 	public static function format_date($time)
  1822   {
  1822 	{
  1823     // merged into enano_date() :)
  1823 		// merged into enano_date() :)
  1824     return enano_date(ED_DATE, $time);
  1824 		return enano_date(ED_DATE, $time);
  1825   }
  1825 	}
  1826   function reg_time($time, $row)
  1826 	function reg_time($time, $row)
  1827   {
  1827 	{
  1828     return $this->format_date($time);
  1828 		return $this->format_date($time);
  1829   }
  1829 	}
  1830   function infobit($_, $row)
  1830 	function infobit($_, $row)
  1831   {
  1831 	{
  1832     global $db, $session, $paths, $template, $plugins; // Common objects
  1832 		global $db, $session, $paths, $template, $plugins; // Common objects
  1833     global $lang;
  1833 		global $lang;
  1834     
  1834 		
  1835     $bit = '';
  1835 		$bit = '';
  1836     if ( $row['user_has_avatar'] == 1 )
  1836 		if ( $row['user_has_avatar'] == 1 )
  1837     {
  1837 		{
  1838       $bit .= '<div style="float: left; margin-right: 10px;">
  1838 			$bit .= '<div style="float: left; margin-right: 10px;">
  1839         <img alt=" " src="' . make_avatar_url(intval($row['user_id']), $row['avatar_type'], $row['email']) . '" />
  1839 				<img alt=" " src="' . make_avatar_url(intval($row['user_id']), $row['avatar_type'], $row['email']) . '" />
  1840       </div>';
  1840 			</div>';
  1841     }
  1841 		}
  1842     $rank_data = $session->get_user_rank(intval($row['user_id']));
  1842 		$rank_data = $session->get_user_rank(intval($row['user_id']));
  1843     $userpage = $paths->nslist['User'] . sanitize_page_id($row['username']);
  1843 		$userpage = $paths->nslist['User'] . sanitize_page_id($row['username']);
  1844     $title = ( isPage($userpage) ) ? ' title="' . $lang->get('userfuncs_ml_tip_userpage') . '"' : ' title="' . $lang->get('userfuncs_ml_tip_nouserpage') . '"';
  1844 		$title = ( isPage($userpage) ) ? ' title="' . $lang->get('userfuncs_ml_tip_userpage') . '"' : ' title="' . $lang->get('userfuncs_ml_tip_nouserpage') . '"';
  1845     $bit .= '<a' . $title . ' href="' . makeUrlNS('User', $row['username'], false, true) . '" style="font-size: x-large; ' . $rank_data['rank_style'] . '">' . htmlspecialchars($row['username']) . '</a><br />';
  1845 		$bit .= '<a' . $title . ' href="' . makeUrlNS('User', $row['username'], false, true) . '" style="font-size: x-large; ' . $rank_data['rank_style'] . '">' . htmlspecialchars($row['username']) . '</a><br />';
  1846     if ( $rank_data['user_title'] )
  1846 		if ( $rank_data['user_title'] )
  1847       $bit .= htmlspecialchars($rank_data['user_title']) . '<br />';
  1847 			$bit .= htmlspecialchars($rank_data['user_title']) . '<br />';
  1848     if ( $rank_data['rank_title'] )
  1848 		if ( $rank_data['rank_title'] )
  1849       $bit .= '<small>' . htmlspecialchars($lang->get($rank_data['rank_title'])) . '</small><br />';
  1849 			$bit .= '<small>' . htmlspecialchars($lang->get($rank_data['rank_title'])) . '</small><br />';
  1850     
  1850 		
  1851     $bit .= '<div style="text-align: right;">
  1851 		$bit .= '<div style="text-align: right;">
  1852                <a href="' . makeUrlNS('Special', "PrivateMessages/Compose/To/{$row['username']}", false, true) . '" class="abutton icon abutton_blue" style="background-image: url(' . cdnPath . '/images/icons/send_pm.png);">' . $lang->get('comment_btn_send_privmsg') . '</a>
  1852  							<a href="' . makeUrlNS('Special', "PrivateMessages/Compose/To/{$row['username']}", false, true) . '" class="abutton icon abutton_blue" style="background-image: url(' . cdnPath . '/images/icons/send_pm.png);">' . $lang->get('comment_btn_send_privmsg') . '</a>
  1853                <a href="' . makeUrlNS('Special', "PrivateMessages/FriendList/Add/{$row['username']}", false, true) . '" class="abutton icon abutton_green" style="background-image: url(' . cdnPath . '/images/icons/add_buddy.png);">' . $lang->get('comment_btn_add_buddy') . '</a>
  1853  							<a href="' . makeUrlNS('Special', "PrivateMessages/FriendList/Add/{$row['username']}", false, true) . '" class="abutton icon abutton_green" style="background-image: url(' . cdnPath . '/images/icons/add_buddy.png);">' . $lang->get('comment_btn_add_buddy') . '</a>
  1854              </div>';
  1854  						</div>';
  1855     
  1855 		
  1856     return $bit;
  1856 		return $bit;
  1857   }
  1857 	}
  1858 }
  1858 }
  1859 
  1859 
  1860 function page_Special_LangExportJSON()
  1860 function page_Special_LangExportJSON()
  1861 {
  1861 {
  1862   global $db, $session, $paths, $template, $plugins; // Common objects
  1862 	global $db, $session, $paths, $template, $plugins; // Common objects
  1863   global $lang;
  1863 	global $lang;
  1864   
  1864 	
  1865   $lang_id = ( $x = $paths->getParam(0) ) ? intval($x) : $lang->lang_id;
  1865 	$lang_id = ( $x = $paths->getParam(0) ) ? intval($x) : $lang->lang_id;
  1866   
  1866 	
  1867   if ( $lang->lang_id == $lang_id )
  1867 	if ( $lang->lang_id == $lang_id )
  1868     $lang_local =& $lang;
  1868 		$lang_local =& $lang;
  1869   else
  1869 	else
  1870     $lang_local = new Language($lang_id);
  1870 		$lang_local = new Language($lang_id);
  1871     
  1871 		
  1872   $lang_local->get('meta_meta');
  1872 	$lang_local->get('meta_meta');
  1873   
  1873 	
  1874   $lang_strings = enano_json_encode($lang_local->strings);
  1874 	$lang_strings = enano_json_encode($lang_local->strings);
  1875   $etag = substr(sha1($lang_strings), 0, 20) . '-' . dechex($lang_local->lang_timestamp);
  1875 	$etag = substr(sha1($lang_strings), 0, 20) . '-' . dechex($lang_local->lang_timestamp);
  1876   
  1876 	
  1877   if ( isset($_SERVER['HTTP_IF_NONE_MATCH']) )
  1877 	if ( isset($_SERVER['HTTP_IF_NONE_MATCH']) )
  1878   {
  1878 	{
  1879     if ( "\"$etag\"" == $_SERVER['HTTP_IF_NONE_MATCH'] )
  1879 		if ( "\"$etag\"" == $_SERVER['HTTP_IF_NONE_MATCH'] )
  1880     {
  1880 		{
  1881       header('HTTP/1.1 304 Not Modified');
  1881 			header('HTTP/1.1 304 Not Modified');
  1882       exit();
  1882 			exit();
  1883     }
  1883 		}
  1884   }
  1884 	}
  1885   
  1885 	
  1886   $timestamp = enano_date('D, j M Y H:i:s T', $lang_local->lang_timestamp);
  1886 	$timestamp = enano_date('D, j M Y H:i:s T', $lang_local->lang_timestamp);
  1887   // generate expires header
  1887 	// generate expires header
  1888   $expires = date('r', mktime(-1, -1, -1, -1, -1, intval(date('y'))+1));
  1888 	$expires = date('r', mktime(-1, -1, -1, -1, -1, intval(date('y'))+1));
  1889 
  1889 
  1890   header("Last-Modified: $timestamp");
  1890 	header("Last-Modified: $timestamp");
  1891   header("Date: $timestamp");
  1891 	header("Date: $timestamp");
  1892   header("ETag: \"$etag\"");
  1892 	header("ETag: \"$etag\"");
  1893   header('Content-type: text/javascript');
  1893 	header('Content-type: text/javascript');
  1894   header("Expires: $expires");
  1894 	header("Expires: $expires");
  1895   
  1895 	
  1896   $lang_local->fetch();
  1896 	$lang_local->fetch();
  1897   echo "if ( typeof(enano_lang) != 'object' )
  1897 	echo "if ( typeof(enano_lang) != 'object' )
  1898   var enano_lang = new Object();
  1898 	var enano_lang = new Object();
  1899 
  1899 
  1900 enano_lang[{$lang_local->lang_id}] = " . $lang_strings . ";";
  1900 enano_lang[{$lang_local->lang_id}] = " . $lang_strings . ";";
  1901 
  1901 
  1902   gzip_output();
  1902 	gzip_output();
  1903   
  1903 	
  1904   exit(0);
  1904 	exit(0);
  1905 }
  1905 }
  1906 
  1906 
  1907 /**
  1907 /**
  1908  * Fetches and displays an avatar from the filesystem. Avatar fetching is abstracted as of 1.1.4.
  1908  * Fetches and displays an avatar from the filesystem. Avatar fetching is abstracted as of 1.1.4.
  1909  */
  1909  */
  1910 
  1910 
  1911 function page_Special_Avatar()
  1911 function page_Special_Avatar()
  1912 {
  1912 {
  1913   global $db, $session, $paths, $template, $plugins; // Common objects
  1913 	global $db, $session, $paths, $template, $plugins; // Common objects
  1914   global $aggressive_optimize_html;
  1914 	global $aggressive_optimize_html;
  1915   $aggressive_optimize_html = false;
  1915 	$aggressive_optimize_html = false;
  1916   
  1916 	
  1917   $img_types = array(
  1917 	$img_types = array(
  1918       IMAGE_TYPE_PNG => 'png',
  1918 			IMAGE_TYPE_PNG => 'png',
  1919       IMAGE_TYPE_GIF => 'gif',
  1919 			IMAGE_TYPE_GIF => 'gif',
  1920       IMAGE_TYPE_JPG => 'jpg',
  1920 			IMAGE_TYPE_JPG => 'jpg',
  1921       IMAGE_TYPE_GRV => 'grv'
  1921 			IMAGE_TYPE_GRV => 'grv'
  1922     );
  1922 		);
  1923   
  1923 	
  1924   $avi_id = $paths->getParam(0);
  1924 	$avi_id = $paths->getParam(0);
  1925   if ( !$avi_id || !@preg_match('/^[a-f0-9]+$/', $avi_id) )
  1925 	if ( !$avi_id || !@preg_match('/^[a-f0-9]+$/', $avi_id) )
  1926   {
  1926 	{
  1927     echo 'Doesn\'t match the regexp';
  1927 		echo 'Doesn\'t match the regexp';
  1928     return true;
  1928 		return true;
  1929   }
  1929 	}
  1930   
  1930 	
  1931   $avi_id_dec = hexdecode($avi_id);
  1931 	$avi_id_dec = hexdecode($avi_id);
  1932   $avi_id_dec = @unpack('Vdate/Vuid/vimg_type', $avi_id_dec);
  1932 	$avi_id_dec = @unpack('Vdate/Vuid/vimg_type', $avi_id_dec);
  1933   if ( !$avi_id_dec )
  1933 	if ( !$avi_id_dec )
  1934   {
  1934 	{
  1935     echo 'Bad unpack';
  1935 		echo 'Bad unpack';
  1936     return true;
  1936 		return true;
  1937   }
  1937 	}
  1938   
  1938 	
  1939   // check parameters
  1939 	// check parameters
  1940   if ( !isset($img_types[$avi_id_dec['img_type']]) )
  1940 	if ( !isset($img_types[$avi_id_dec['img_type']]) )
  1941   {
  1941 	{
  1942     echo 'Invalid image type';
  1942 		echo 'Invalid image type';
  1943     return true;
  1943 		return true;
  1944   }
  1944 	}
  1945   
  1945 	
  1946   // build file path
  1946 	// build file path
  1947   $avi_type = $img_types[$avi_id_dec['img_type']];
  1947 	$avi_type = $img_types[$avi_id_dec['img_type']];
  1948   
  1948 	
  1949   // is this a gravatar?
  1949 	// is this a gravatar?
  1950   if ( $avi_type == 'grv' )
  1950 	if ( $avi_type == 'grv' )
  1951   {
  1951 	{
  1952     // yes, we'll have to redirect
  1952 		// yes, we'll have to redirect
  1953     // sanitize UID
  1953 		// sanitize UID
  1954     $uid = intval($avi_id_dec['uid']);
  1954 		$uid = intval($avi_id_dec['uid']);
  1955     
  1955 		
  1956     // fetch email
  1956 		// fetch email
  1957     $q = $db->sql_query('SELECT email FROM ' . table_prefix . "users WHERE user_id = $uid;");
  1957 		$q = $db->sql_query('SELECT email FROM ' . table_prefix . "users WHERE user_id = $uid;");
  1958     if ( !$q )
  1958 		if ( !$q )
  1959       $db->_die();
  1959 			$db->_die();
  1960     if ( $db->numrows() < 1 )
  1960 		if ( $db->numrows() < 1 )
  1961       return false;
  1961 			return false;
  1962     
  1962 		
  1963     list($email) = $db->fetchrow_num();
  1963 		list($email) = $db->fetchrow_num();
  1964     $db->free_result();
  1964 		$db->free_result();
  1965     
  1965 		
  1966     $url = make_gravatar_url($url);
  1966 		$url = make_gravatar_url($url);
  1967     
  1967 		
  1968     // ship out the redirect
  1968 		// ship out the redirect
  1969     header('HTTP/1.1 302 Permanent Redirect');
  1969 		header('HTTP/1.1 302 Permanent Redirect');
  1970     header("Location: $url");
  1970 		header("Location: $url");
  1971   }
  1971 	}
  1972   
  1972 	
  1973   $avi_path = ENANO_ROOT . '/' . getConfig('avatar_directory') . '/' . $avi_id_dec['uid'] . '.' . $avi_type;
  1973 	$avi_path = ENANO_ROOT . '/' . getConfig('avatar_directory') . '/' . $avi_id_dec['uid'] . '.' . $avi_type;
  1974   if ( file_exists($avi_path) )
  1974 	if ( file_exists($avi_path) )
  1975   {
  1975 	{
  1976     $avi_mod_time = @filemtime($avi_path);
  1976 		$avi_mod_time = @filemtime($avi_path);
  1977     $avi_mod_time = date('r', $avi_mod_time);
  1977 		$avi_mod_time = date('r', $avi_mod_time);
  1978     $avi_size = @filesize($avi_path);
  1978 		$avi_size = @filesize($avi_path);
  1979     header("Last-Modified: $avi_mod_time");
  1979 		header("Last-Modified: $avi_mod_time");
  1980     header("Content-Length: $avi_size");
  1980 		header("Content-Length: $avi_size");
  1981     header("Content-Type: image/$avi_type");
  1981 		header("Content-Type: image/$avi_type");
  1982     // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
  1982 		// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
  1983     header("Cache-Control: public");
  1983 		header("Cache-Control: public");
  1984     // expire it 30 days from now
  1984 		// expire it 30 days from now
  1985     $expiry_time = time() + ( 86400 * 30 );
  1985 		$expiry_time = time() + ( 86400 * 30 );
  1986     header("Expires: " . date('r', $expiry_time));
  1986 		header("Expires: " . date('r', $expiry_time));
  1987     
  1987 		
  1988     $fh = @fopen($avi_path, 'r');
  1988 		$fh = @fopen($avi_path, 'r');
  1989     if ( !$fh )
  1989 		if ( !$fh )
  1990     {
  1990 		{
  1991       echo 'Could not open file';
  1991 			echo 'Could not open file';
  1992       return true;
  1992 			return true;
  1993     }
  1993 		}
  1994     
  1994 		
  1995     while ( $fd = @fread($fh, 1024) )
  1995 		while ( $fd = @fread($fh, 1024) )
  1996     {
  1996 		{
  1997       echo $fd;
  1997 			echo $fd;
  1998     }
  1998 		}
  1999     fclose($fh);
  1999 		fclose($fh);
  2000     
  2000 		
  2001   }
  2001 	}
  2002   return true;
  2002 	return true;
  2003 }
  2003 }
  2004 
  2004 
  2005 ?>
  2005 ?>