plugins/admin/UserManager.php
changeset 1103 90225c988124
parent 1099 73abd46f5148
child 1141 5a858d6f3634
equal deleted inserted replaced
1102:faef5e62e1e0 1103:90225c988124
     1 <?php
     1 <?php
     2 
     2 
     3 /*
     3 /*
     4  * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
     4  * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
     5  * Version 1.1.6 (Caoineag beta 1)
     5  * Copyright (C) 2006-2009 Dan Fuhry
     6  * Copyright (C) 2006-2008 Dan Fuhry
       
     7  *
     6  *
     8  * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
     7  * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
     9  * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
     8  * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
    10  *
     9  *
    11  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
    10  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
    58         $db->_die();
    57         $db->_die();
    59       $q = $db->sql_query('DELETE FROM '.table_prefix."session_keys WHERE user_id=$user_id;");
    58       $q = $db->sql_query('DELETE FROM '.table_prefix."session_keys WHERE user_id=$user_id;");
    60       if ( !$q )
    59       if ( !$q )
    61         $db->_die();
    60         $db->_die();
    62       echo '<div class="info-box">' . $lang->get('acpum_msg_delete_success') . '</div>';
    61       echo '<div class="info-box">' . $lang->get('acpum_msg_delete_success') . '</div>';
       
    62       
       
    63       // deleting own account?
       
    64       if ( $user_id === $session->user_id )
       
    65       {
       
    66         // cute little hack to boot them out of the admin panel
       
    67         echo '<script type="text/javascript">
       
    68           addOnloadHook(function()
       
    69           {
       
    70             setTimeout(function()
       
    71             {
       
    72               eraseCookie("sid");
       
    73               ENANO_SID = false;
       
    74               auth_level = USER_LEVEL_MEMBER;
       
    75               window.location = makeUrlNS("Special", "Login");
       
    76             }, 3000);
       
    77           });
       
    78         </script>';
       
    79       }
    63     }
    80     }
    64     else
    81     else
    65     {
    82     {
    66       if ( $session->user_id == $user_id )
    83       if ( $session->user_id == $user_id )
    67       {
    84       {
    87           $errors[] = $lang->get('acpum_err_illegal_email');
   104           $errors[] = $lang->get('acpum_err_illegal_email');
    88         
   105         
    89         $real_name = $_POST['real_name'];
   106         $real_name = $_POST['real_name'];
    90       }
   107       }
    91       
   108       
    92       $signature = RenderMan::preprocess_text($_POST['signature'], true, true);
   109       $signature = RenderMan::preprocess_text($_POST['signature'], true, false);
    93       
   110       
    94       $user_level = intval($_POST['user_level']);
   111       $user_level = intval($_POST['user_level']);
    95       if ( $user_level < USER_LEVEL_MEMBER || $user_level > USER_LEVEL_ADMIN )
   112       if ( $user_level < USER_LEVEL_MEMBER || $user_level > USER_LEVEL_ADMIN )
    96         $errors[] = 'Invalid user level';
   113         $errors[] = 'Invalid user level';
    97       
   114       
   127       if ( !preg_match('/^http:\/\/([a-z0-9-.]+)([A-z0-9@#\$%\&:;<>,\.\?=\+\(\)\[\]_\/\\\\]*?)$/i', $homepage) )
   144       if ( !preg_match('/^http:\/\/([a-z0-9-.]+)([A-z0-9@#\$%\&:;<>,\.\?=\+\(\)\[\]_\/\\\\]*?)$/i', $homepage) )
   128       {
   145       {
   129         $homepage = '';
   146         $homepage = '';
   130       }
   147       }
   131       
   148       
   132       if ( count($errors) < 1 )
   149       // true for quiet operation
       
   150       list(, , $avatar_post_fail) = avatar_post($user_id, true);
       
   151       
       
   152       if ( count($errors) < 1 && !$avatar_post_fail )
   133       {
   153       {
   134         $q = $db->sql_query('SELECT u.user_level, u.user_has_avatar, u.avatar_type FROM '.table_prefix.'users AS u WHERE u.user_id = ' . $user_id . ';');
   154         $q = $db->sql_query('SELECT u.user_level, u.user_has_avatar, u.avatar_type FROM '.table_prefix.'users AS u WHERE u.user_id = ' . $user_id . ';');
   135         if ( !$q )
   155         if ( !$q )
   136           $db->_die();
   156           $db->_die();
   137         
   157         
   173         }
   193         }
   174         else
   194         else
   175         {
   195         {
   176           $to_update_users['account_active'] = "0";
   196           $to_update_users['account_active'] = "0";
   177           $to_update_users['activation_key'] = sha1($session->dss_rand());
   197           $to_update_users['activation_key'] = sha1($session->dss_rand());
   178         }
       
   179         
       
   180         // Avatar validation
       
   181         $action = ( isset($_POST['avatar_action']) ) ? $_POST['avatar_action'] : 'keep';
       
   182         $avi_path = ENANO_ROOT . '/' . getConfig('avatar_directory') . '/' . $user_id . '.' . $avi_type;
       
   183         switch($action)
       
   184         {
       
   185           case 'keep':
       
   186           default:
       
   187             break;
       
   188           case 'remove':
       
   189             if ( $has_avi )
       
   190             {
       
   191               // First switch the avatar off
       
   192               $to_update_users['user_has_avatar'] = '0';
       
   193               @unlink($avi_path);
       
   194             }
       
   195             break;
       
   196           case 'set_http':
       
   197           case 'set_file':
       
   198             // Hackish way to preserve the UNIX philosophy of reusing as much code as possible
       
   199             if ( $action == 'set_http' )
       
   200             {
       
   201               // Check if this action is enabled
       
   202               if ( getConfig('avatar_upload_http', 1) !== 1 )
       
   203               {
       
   204                 // non-localized, only appears on hack attempt
       
   205                 $errors[] = 'Uploads over HTTP are disabled.';
       
   206                 break;
       
   207               }
       
   208               // Download the file
       
   209               require_once( ENANO_ROOT . '/includes/http.php' );
       
   210               
       
   211               if ( !preg_match('/^http:\/\/([a-z0-9-\.]+)(:([0-9]+))?\/(.+)$/', $_POST['avatar_http_url'], $match) )
       
   212               {
       
   213                 $errors[] = $lang->get('usercp_avatar_invalid_url');
       
   214                 break;
       
   215               }
       
   216               
       
   217               $hostname = $match[1];
       
   218               $uri = '/' . $match[4];
       
   219               $port = ( $match[3] ) ? intval($match[3]) : 80;
       
   220               $max_size = intval(getConfig('avatar_max_size'));
       
   221               
       
   222               // Get temporary file
       
   223               $tempfile = tempnam(false, "enanoavatar_{$user_id}");
       
   224               if ( !$tempfile )
       
   225                 $errors[] = 'Error getting temp file.';
       
   226               
       
   227               @unlink($tempfile);
       
   228               $request = new Request_HTTP($hostname, $uri, 'GET', $port);
       
   229               $result = $request->write_response_to_file($tempfile, 50, $max_size);
       
   230               if ( !$result || $request->response_code != HTTP_OK )
       
   231               {
       
   232                 @unlink($tempfile);
       
   233                 $errors[] = $lang->get('usercp_avatar_bad_write');
       
   234                 break;
       
   235               }
       
   236               
       
   237               // Response written. Proceed to validation...
       
   238             }
       
   239             else
       
   240             {
       
   241               // Check if this action is enabled
       
   242               if ( getConfig('avatar_upload_file', 1) !== 1 )
       
   243               {
       
   244                 // non-localized, only appears on hack attempt
       
   245                 $errors[] = 'Uploads from the browser are disabled.';
       
   246                 break;
       
   247               }
       
   248               
       
   249               $max_size = intval(getConfig('avatar_max_size'));
       
   250               
       
   251               $file =& $_FILES['avatar_file'];
       
   252               $tempfile =& $file['tmp_name'];
       
   253               if ( filesize($tempfile) > $max_size )
       
   254               {
       
   255                 @unlink($tempfile);
       
   256                 $errors[] = $lang->get('usercp_avatar_file_too_large');
       
   257                 break;
       
   258               }
       
   259             }
       
   260             $file_type = get_image_filetype($tempfile);
       
   261             if ( !$file_type )
       
   262             {
       
   263               unlink($tempfile);
       
   264               $errors[] = $lang->get('usercp_avatar_bad_filetype');
       
   265               break;
       
   266             }
       
   267             
       
   268             $avi_path_new = ENANO_ROOT . '/' . getConfig('avatar_directory') . '/' . $user_id . '.' . $file_type;
       
   269             
       
   270             // The file type is good - validate dimensions and animation
       
   271             switch($file_type)
       
   272             {
       
   273               case 'png':
       
   274                 $is_animated = is_png_animated($tempfile);
       
   275                 $dimensions = png_get_dimensions($tempfile);
       
   276                 break;
       
   277               case 'gif':
       
   278                 $is_animated = is_gif_animated($tempfile);
       
   279                 $dimensions = gif_get_dimensions($tempfile);
       
   280                 break;
       
   281               case 'jpg':
       
   282                 $is_animated = false;
       
   283                 $dimensions = jpg_get_dimensions($tempfile);
       
   284                 break;
       
   285               default:
       
   286                 $errors[] = 'API mismatch';
       
   287                 break 2;
       
   288             }
       
   289             // Did we get invalid size data? If so the image is probably corrupt.
       
   290             if ( !$dimensions )
       
   291             {
       
   292               @unlink($tempfile);
       
   293               $errors[] = $lang->get('usercp_avatar_corrupt_image');
       
   294               break;
       
   295             }
       
   296             // Is the image animated?
       
   297             if ( $is_animated && getConfig('avatar_enable_anim') !== '1' )
       
   298             {
       
   299               @unlink($tempfile);
       
   300               $errors[] = $lang->get('usercp_avatar_disallowed_animation');
       
   301               break;
       
   302             }
       
   303             // Check image dimensions
       
   304             list($image_x, $image_y) = $dimensions;
       
   305             $max_x = intval(getConfig('avatar_max_width'));
       
   306             $max_y = intval(getConfig('avatar_max_height'));
       
   307             if ( $image_x > $max_x || $image_y > $max_y )
       
   308             {
       
   309               @unlink($tempfile);
       
   310               $errors[] = $lang->get('usercp_avatar_too_large');
       
   311               break;
       
   312             }
       
   313             // All good!
       
   314             @unlink($avi_path);
       
   315             if ( rename($tempfile, $avi_path_new) )
       
   316             {
       
   317               $to_update_users['user_has_avatar'] = '1';
       
   318               $to_update_users['avatar_type'] = $file_type;
       
   319             }
       
   320             else
       
   321             {
       
   322               // move failed - turn avatar off
       
   323               $to_update_users['user_has_avatar'] = '0';
       
   324             }
       
   325             break;
       
   326           case 'set_gravatar':
       
   327             // set avatar to use Gravatar
       
   328             // first, remove old image
       
   329             if ( $has_avi )
       
   330             {
       
   331               @unlink($avi_path);
       
   332             }
       
   333             // set to gravatar mode
       
   334             $to_update_users['user_has_avatar'] = '1';
       
   335             $to_update_users['avatar_type'] = 'grv';
       
   336             
       
   337             $has_avi = 1;
       
   338             break;
       
   339         }
   198         }
   340         
   199         
   341         if ( count($errors) < 1 )
   200         if ( count($errors) < 1 )
   342         {
   201         {
   343           $to_update_users_extra = array();
   202           $to_update_users_extra = array();
   421           echo '<div class="info-box">' . $lang->get('acpum_msg_save_success') . '</div>';
   280           echo '<div class="info-box">' . $lang->get('acpum_msg_save_success') . '</div>';
   422         }
   281         }
   423       }
   282       }
   424     }
   283     }
   425     
   284     
   426     if ( count($errors) > 0 )
   285     if ( count($errors) > 0 || @$avatar_post_fail )
   427     {
   286     {
   428       echo '<div class="error-box">
   287       if ( count($errors) > 0 )
   429               <b>' . $lang->get('acpum_err_validation_fail') . '</b>
   288       {
   430               <ul>
   289         echo '<div class="error-box">
   431                 <li>' . implode("</li>\n        <li>", $errors) . '</li>
   290                 <b>' . $lang->get('acpum_err_validation_fail') . '</b>
   432               </ul>
   291                 <ul>
   433             </div>';
   292                   <li>' . implode("</li>\n        <li>", $errors) . '</li>
       
   293                 </ul>
       
   294               </div>';
       
   295       }
   434       $form = new Admin_UserManager_SmartForm();
   296       $form = new Admin_UserManager_SmartForm();
   435       $form->user_id = $user_id;
   297       $form->user_id = $user_id;
   436       $form->username = $username;
   298       $form->username = $username;
   437       $form->email = $email;
   299       $form->email = $email;
   438       $form->real_name = $real_name;
   300       $form->real_name = $real_name;
   464     
   326     
   465     #
   327     #
   466     # END VALIDATION
   328     # END VALIDATION
   467     #
   329     #
   468   }
   330   }
   469   else if ( isset($_POST['action']['go']) || ( isset($_GET['src']) && $_GET['src'] == 'get' ) )
   331   else if ( isset($_POST['action']['go']) || ( isset($_GET['src']) && $_GET['src'] == 'get' ) || ($pathsuser = $paths->getParam(0)) )
   470   {
   332   {
   471     if ( isset($_GET['user']) )
   333     if ( isset($_GET['user']) )
   472     {
   334     {
   473       $username =& $_GET['user'];
   335       $username =& $_GET['user'];
   474     }
   336     }
   477       $username =& $_GET['username'];
   339       $username =& $_GET['username'];
   478     }
   340     }
   479     else if ( isset($_POST['username']) )
   341     else if ( isset($_POST['username']) )
   480     {
   342     {
   481       $username =& $_POST['username'];
   343       $username =& $_POST['username'];
       
   344     }
       
   345     else if ( $pathsuser )
       
   346     {
       
   347       $username = str_replace('_', ' ', dirtify_page_id($pathsuser));
   482     }
   348     }
   483     else
   349     else
   484     {
   350     {
   485       echo 'No username provided';
   351       echo 'No username provided';
   486       return false;
   352       return false;
   678       {
   544       {
   679         if($cls == 'row2') $cls = 'row1';
   545         if($cls == 'row2') $cls = 'row1';
   680         else $cls = 'row2';
   546         else $cls = 'row2';
   681         $coppa = ( $row['user_coppa'] == '1' ) ? '<b>' . $lang->get('acpum_coppauser_yes') . '</b>' : $lang->get('acpum_coppauser_no');
   547         $coppa = ( $row['user_coppa'] == '1' ) ? '<b>' . $lang->get('acpum_coppauser_yes') . '</b>' : $lang->get('acpum_coppauser_no');
   682         echo '<tr>
   548         echo '<tr>
   683                 <td class="'.$cls.'">'.enano_date('F d, Y h:i a', $row['time_id']).'</td>
   549                 <td class="'.$cls.'">'.enano_date(ED_DATE | ED_TIME, $row['time_id']).'</td>
   684                 <td class="'.$cls.'">'.$row['author'].'</td>
   550                 <td class="'.$cls.'">'.$row['author'].'</td>
   685                 <td class="'.$cls.'">'.$row['edit_summary'].'</td>
   551                 <td class="'.$cls.'">'.$row['edit_summary'].'</td>
   686                 <td style="text-align: center;" class="' . $cls . '">' . $coppa . '</td>
   552                 <td style="text-align: center;" class="' . $cls . '">' . $coppa . '</td>
   687                 <td class="'.$cls.'" style="text-align: center;">
   553                 <td class="'.$cls.'" style="text-align: center;">
   688                   <a href="'.makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'UserManager&action=activate&user='.rawurlencode($row['edit_summary']).'&logid='.$row['time_id'], true).'">' . $lang->get('acpum_btn_activate_now') . '</a>
   554                   <a href="'.makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'UserManager&action=activate&user='.rawurlencode($row['edit_summary']).'&logid='.$row['time_id'], true).'">' . $lang->get('acpum_btn_activate_now') . '</a>
  1089                 
   955                 
  1090                 <tr>
   956                 <tr>
  1091                   <td class="row2">
   957                   <td class="row2">
  1092                     {lang:acpum_avatar_lbl_change}
   958                     {lang:acpum_avatar_lbl_change}
  1093                   </td>
   959                   </td>
  1094                   <td class="row1">
   960                   <td class="row1" id="avatar_upload_btns_{UUID}">
  1095                     <script type="text/javascript">
   961                     <script type="text/javascript">
  1096                       function admincp_users_avatar_set_{UUID}(elParent)
   962                       function admincp_users_avatar_set_{UUID}(elParent)
  1097                       {
   963                       {
       
   964                         $('td#avatar_upload_btns_{UUID} > div:visible').hide('blind');
  1098                         switch(elParent.value)
   965                         switch(elParent.value)
  1099                         {
   966                         {
  1100                           case 'keep':
       
  1101                           case 'remove':
       
  1102                             \$dynano('avatar_upload_http_{UUID}').object.style.display = 'none';
       
  1103                             \$dynano('avatar_upload_file_{UUID}').object.style.display = 'none';
       
  1104                             \$dynano('avatar_upload_gravatar_{UUID}').object.style.display = 'none';
       
  1105                             break;
       
  1106                           case 'set_http':
   967                           case 'set_http':
  1107                             \$dynano('avatar_upload_http_{UUID}').object.style.display = 'block';
   968                             $('#avatar_upload_http_{UUID}').show('blind');
  1108                             \$dynano('avatar_upload_file_{UUID}').object.style.display = 'none';
       
  1109                             \$dynano('avatar_upload_gravatar_{UUID}').object.style.display = 'none';
       
  1110                             break;
   969                             break;
  1111                           case 'set_file':
   970                           case 'set_file':
  1112                             \$dynano('avatar_upload_http_{UUID}').object.style.display = 'none';
   971                             $('#avatar_upload_file_{UUID}').show('blind');
  1113                             \$dynano('avatar_upload_file_{UUID}').object.style.display = 'block';
       
  1114                             \$dynano('avatar_upload_gravatar_{UUID}').object.style.display = 'none';
       
  1115                             break;
   972                             break;
  1116                           case 'set_gravatar':
   973                           case 'set_gravatar':
  1117                             \$dynano('avatar_upload_gravatar_{UUID}').object.style.display = 'block';
   974                             $('#avatar_upload_gravatar_{UUID}').show('blind');
  1118                             \$dynano('avatar_upload_http_{UUID}').object.style.display = 'none';
       
  1119                             \$dynano('avatar_upload_file_{UUID}').object.style.display = 'none';
       
  1120                             break;
   975                             break;
  1121                         }
   976                         }
  1122                       }
   977                       }
  1123                     </script>
   978                     </script>
  1124                     <label><input onclick="admincp_users_avatar_set_{UUID}(this);" type="radio" name="avatar_action" value="keep" checked="checked" /> {lang:acpum_avatar_lbl_keep}</label><br />
   979                     <label><input onclick="admincp_users_avatar_set_{UUID}(this);" type="radio" name="avatar_action" value="keep" checked="checked" /> {lang:acpum_avatar_lbl_keep}</label><br />