[ Index ]

PHP Cross Reference of phpBB 3.0 Beta 3

title

Body

[close]

/includes/ -> functions_user.php (source)

   1  <?php
   2  /**
   3  *
   4  * @package phpBB3
   5  * @version $Id: functions_user.php,v 1.146 2006/11/12 15:35:43 acydburn Exp $
   6  * @copyright (c) 2005 phpBB Group
   7  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
   8  *
   9  */
  10  
  11  /**
  12  * Obtain user_ids from usernames or vice versa. Returns false on
  13  * success else the error string
  14  */
  15  function user_get_id_name(&$user_id_ary, &$username_ary, $only_active = false)
  16  {
  17      global $db;
  18  
  19      // Are both arrays already filled? Yep, return else
  20      // are neither array filled?
  21      if ($user_id_ary && $username_ary)
  22      {
  23          return false;
  24      }
  25      else if (!$user_id_ary && !$username_ary)
  26      {
  27          return 'NO_USERS';
  28      }
  29  
  30      $which_ary = ($user_id_ary) ? 'user_id_ary' : 'username_ary';
  31  
  32      if ($$which_ary && !is_array($$which_ary))
  33      {
  34          $$which_ary = array($$which_ary);
  35      }
  36  
  37      $sql_in = ($which_ary == 'user_id_ary') ? array_map('intval', $$which_ary) : array_map('utf8_clean_string', $$which_ary);
  38      unset($$which_ary);
  39  
  40      $user_id_ary = $username_ary = array();
  41  
  42      // Grab the user id/username records
  43      $sql_where = ($which_ary == 'user_id_ary') ? 'user_id' : 'username_clean';
  44      $sql = 'SELECT user_id, username
  45          FROM ' . USERS_TABLE . '
  46          WHERE ' . $db->sql_in_set($sql_where, $sql_in);
  47  
  48      if ($only_active)
  49      {
  50          $sql .= ' AND user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')';
  51      }
  52  
  53      $result = $db->sql_query($sql);
  54  
  55      if (!($row = $db->sql_fetchrow($result)))
  56      {
  57          $db->sql_freeresult($result);
  58          return 'NO_USERS';
  59      }
  60  
  61      do
  62      {
  63          $username_ary[$row['user_id']] = $row['username'];
  64          $user_id_ary[] = $row['user_id'];
  65      }
  66      while ($row = $db->sql_fetchrow($result));
  67      $db->sql_freeresult($result);
  68  
  69      return false;
  70  }
  71  
  72  /**
  73  * Get latest registered username and update database to reflect it
  74  */
  75  function update_last_username()
  76  {
  77      global $db;
  78  
  79      // Get latest username
  80      $sql = 'SELECT user_id, username
  81          FROM ' . USERS_TABLE . '
  82          WHERE user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')
  83          ORDER BY user_id DESC';
  84      $result = $db->sql_query_limit($sql, 1);
  85      $row = $db->sql_fetchrow($result);
  86      $db->sql_freeresult($result);
  87  
  88      if ($row)
  89      {
  90          set_config('newest_user_id', $row['user_id'], true);
  91          set_config('newest_username', $row['username'], true);
  92      }
  93  }
  94  
  95  /**
  96  * Updates a username across all relevant tables/fields
  97  *
  98  * @param string $old_name the old/current username
  99  * @param string $new_name the new username
 100  */
 101  function user_update_name($old_name, $new_name)
 102  {
 103      global $config, $db, $cache;
 104  
 105      $update_ary = array(
 106          FORUMS_TABLE            => array('forum_last_poster_name'),
 107          MODERATOR_CACHE_TABLE    => array('username'),
 108          POSTS_TABLE                => array('post_username'),
 109          TOPICS_TABLE            => array('topic_first_poster_name', 'topic_last_poster_name'),
 110      );
 111  
 112      foreach ($update_ary as $table => $field_ary)
 113      {
 114          foreach ($field_ary as $field)
 115          {
 116              $sql = "UPDATE $table
 117                  SET $field = '" . $db->sql_escape($new_name) . "'
 118                  WHERE $field = '" . $db->sql_escape($old_name) . "'";
 119              $db->sql_query($sql);
 120          }
 121      }
 122  
 123      if ($config['newest_username'] == $old_name)
 124      {
 125          set_config('newest_username', $new_name, true);
 126      }
 127  }
 128  
 129  /**
 130  * Add User
 131  */
 132  function user_add($user_row, $cp_data = false)
 133  {
 134      global $db, $user, $auth, $config, $phpbb_root_path, $phpEx;
 135  
 136      if (empty($user_row['username']) || !isset($user_row['group_id']) || !isset($user_row['user_email']) || !isset($user_row['user_type']))
 137      {
 138          return false;
 139      }
 140  
 141      $sql_ary = array(
 142          'username'            => $user_row['username'],
 143          'username_clean'    => utf8_clean_string($user_row['username']),
 144          'user_password'        => (isset($user_row['user_password'])) ? $user_row['user_password'] : '',
 145          'user_email'        => $user_row['user_email'],
 146          'user_email_hash'    => (int) crc32(strtolower($user_row['user_email'])) . strlen($user_row['user_email']),
 147          'group_id'            => $user_row['group_id'],
 148          'user_type'            => $user_row['user_type'],
 149      );
 150  
 151      // These are the additional vars able to be specified
 152      $additional_vars = array(
 153          'user_permissions'    => '',
 154          'user_timezone'        => $config['board_timezone'],
 155          'user_dateformat'    => $config['default_dateformat'],
 156          'user_lang'            => $config['default_lang'],
 157          'user_style'        => $config['default_style'],
 158          'user_allow_pm'        => 1,
 159          'user_actkey'        => '',
 160          'user_ip'            => '',
 161          'user_regdate'        => time(),
 162          'user_passchg'        => time(),
 163  
 164          'user_inactive_reason'    => 0,
 165          'user_inactive_time'    => 0,
 166          'user_lastmark'            => time(),
 167          'user_lastvisit'        => 0,
 168          'user_lastpost_time'    => 0,
 169          'user_lastpage'            => '',
 170          'user_posts'            => 0,
 171          'user_dst'                => 0,
 172          'user_colour'            => '',
 173          'user_interests'        => '',
 174          'user_avatar'            => '',
 175          'user_avatar_type'        => 0,
 176          'user_avatar_width'        => 0,
 177          'user_avatar_height'    => 0,
 178          'user_new_privmsg'        => 0,
 179          'user_unread_privmsg'    => 0,
 180          'user_last_privmsg'        => 0,
 181          'user_message_rules'    => 0,
 182          'user_full_folder'        => PRIVMSGS_NO_BOX,
 183          'user_emailtime'        => 0,
 184  
 185          'user_notify'            => 0,
 186          'user_notify_pm'        => 1,
 187          'user_notify_type'        => NOTIFY_EMAIL,
 188          'user_allow_pm'            => 1,
 189          'user_allow_viewonline'    => 1,
 190          'user_allow_viewemail'    => 1,
 191          'user_allow_massemail'    => 1,
 192  
 193          'user_sig'                    => '',
 194          'user_sig_bbcode_uid'        => '',
 195          'user_sig_bbcode_bitfield'    => '',
 196      );
 197  
 198      // Now fill the sql array with not required variables
 199      foreach ($additional_vars as $key => $default_value)
 200      {
 201          $sql_ary[$key] = (isset($user_row[$key])) ? $user_row[$key] : $default_value;
 202      }
 203  
 204      // Any additional variables in $user_row not covered above?
 205      $remaining_vars = array_diff(array_keys($user_row), array_keys($sql_ary));
 206  
 207      // Now fill our sql array with the remaining vars
 208      if (sizeof($remaining_vars))
 209      {
 210          foreach ($remaining_vars as $key)
 211          {
 212              $sql_ary[$key] = $user_row[$key];
 213          }
 214      }
 215  
 216      $sql = 'INSERT INTO ' . USERS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
 217      $db->sql_query($sql);
 218  
 219      $user_id = $db->sql_nextid();
 220  
 221      // Insert Custom Profile Fields
 222      if ($cp_data !== false && sizeof($cp_data))
 223      {
 224          $cp_data['user_id'] = (int) $user_id;
 225  
 226          if (!class_exists('custom_profile'))
 227          {
 228              include_once($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx);
 229          }
 230  
 231          $sql = 'INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . ' ' . 
 232              $db->sql_build_array('INSERT', custom_profile::build_insert_sql_array($cp_data));
 233          $db->sql_query($sql);
 234      }
 235  
 236      // Place into appropriate group...
 237      $sql = 'INSERT INTO ' . USER_GROUP_TABLE . ' ' . $db->sql_build_array('INSERT', array(
 238          'user_id'        => (int) $user_id,
 239          'group_id'        => (int) $user_row['group_id'],
 240          'user_pending'    => 0)
 241      );
 242      $db->sql_query($sql);
 243  
 244      // Now make it the users default group...
 245      group_set_user_default($user_row['group_id'], array($user_id));
 246  
 247      // set the newest user and adjust the user count if the user is a normal user and no activation mail is sent
 248      if ($user_row['user_type'] == USER_NORMAL)
 249      {
 250          set_config('newest_user_id', $user_id, true);
 251          set_config('newest_username', $user_row['username'], true);
 252          set_config('num_users', $config['num_users'] + 1, true);
 253      }
 254  
 255      return $user_id;
 256  }
 257  
 258  /**
 259  * Remove User
 260  */
 261  function user_delete($mode, $user_id, $post_username = false)
 262  {
 263      global $cache, $config, $db, $user, $auth;
 264      global $phpbb_root_path, $phpEx;
 265  
 266      $db->sql_transaction('begin');
 267  
 268      switch ($mode)
 269      {
 270          case 'retain':
 271  
 272              if ($post_username === false)
 273              {
 274                  $post_username = $user->lang['GUEST'];
 275              }
 276  
 277              $sql = 'UPDATE ' . FORUMS_TABLE . '
 278                  SET forum_last_poster_id = ' . ANONYMOUS . ", forum_last_poster_name = '" . $db->sql_escape($post_username) . "', forum_last_poster_colour = ''
 279                  WHERE forum_last_poster_id = $user_id";
 280              $db->sql_query($sql);
 281  
 282              $sql = 'UPDATE ' . POSTS_TABLE . '
 283                  SET poster_id = ' . ANONYMOUS . ", post_username = '" . $db->sql_escape($post_username) . "'
 284                  WHERE poster_id = $user_id";
 285              $db->sql_query($sql);
 286  
 287              $sql = 'UPDATE ' . POSTS_TABLE . '
 288                  SET post_edit_user = ' . ANONYMOUS . "
 289                  WHERE post_edit_user = $user_id";
 290              $db->sql_query($sql);
 291  
 292              $sql = 'UPDATE ' . TOPICS_TABLE . '
 293                  SET topic_poster = ' . ANONYMOUS . ", topic_first_poster_name = '" . $db->sql_escape($post_username) . "', topic_first_poster_colour = ''
 294                  WHERE topic_poster = $user_id";
 295              $db->sql_query($sql);
 296  
 297              $sql = 'UPDATE ' . TOPICS_TABLE . '
 298                  SET topic_last_poster_id = ' . ANONYMOUS . ", topic_last_poster_name = '" . $db->sql_escape($post_username) . "', topic_last_poster_colour = ''
 299                  WHERE topic_last_poster_id = $user_id";
 300              $db->sql_query($sql);
 301  
 302              // Since we change every post by this author, we need to count this amount towards the anonymous user
 303              $sql = 'SELECT user_posts
 304                  FROM ' . USERS_TABLE . '
 305                  WHERE user_id = ' . $user_id;
 306              $result = $db->sql_query($sql);
 307              $num_posts = (int) $db->sql_fetchfield('user_posts');
 308              $db->sql_freeresult($result);
 309  
 310              // Update the post count for the anonymous user
 311              if ($num_posts)
 312              {
 313                  $sql = 'UPDATE ' . USERS_TABLE . '
 314                      SET user_posts = user_posts + ' . $num_posts . '
 315                      WHERE user_id = ' . ANONYMOUS;
 316                  $db->sql_query($sql);
 317              }
 318          break;
 319  
 320          case 'remove':
 321  
 322              if (!function_exists('delete_posts'))
 323              {
 324                  include_once($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
 325              }
 326  
 327              $sql = 'SELECT topic_id, COUNT(post_id) AS total_posts
 328                  FROM ' . POSTS_TABLE . "
 329                  WHERE poster_id = $user_id
 330                  GROUP BY topic_id";
 331              $result = $db->sql_query($sql);
 332  
 333              $topic_id_ary = array();
 334              while ($row = $db->sql_fetchrow($result))
 335              {
 336                  $topic_id_ary[$row['topic_id']] = $row['total_posts'];
 337              }
 338              $db->sql_freeresult($result);
 339  
 340              if (sizeof($topic_id_ary))
 341              {
 342                  $sql = 'SELECT topic_id, topic_replies, topic_replies_real
 343                      FROM ' . TOPICS_TABLE . '
 344                      WHERE ' . $db->sql_in_set('topic_id', array_keys($topic_id_ary));
 345                  $result = $db->sql_query($sql);
 346  
 347                  $del_topic_ary = array();
 348                  while ($row = $db->sql_fetchrow($result))
 349                  {
 350                      if (max($row['topic_replies'], $row['topic_replies_real']) + 1 == $topic_id_ary[$row['topic_id']])
 351                      {
 352                          $del_topic_ary[] = $row['topic_id'];
 353                      }
 354                  }
 355                  $db->sql_freeresult($result);
 356  
 357                  if (sizeof($del_topic_ary))
 358                  {
 359                      $sql = 'DELETE FROM ' . TOPICS_TABLE . '
 360                          WHERE ' . $db->sql_in_set('topic_id', $del_topic_ary);
 361                      $db->sql_query($sql);
 362                  }
 363              }
 364  
 365              // Delete posts, attachments, etc.
 366              delete_posts('poster_id', $user_id);
 367  
 368          break;
 369      }
 370  
 371      $table_ary = array(USERS_TABLE, USER_GROUP_TABLE, TOPICS_WATCH_TABLE, FORUMS_WATCH_TABLE, ACL_USERS_TABLE, TOPICS_TRACK_TABLE, TOPICS_POSTED_TABLE, FORUMS_TRACK_TABLE, PROFILE_FIELDS_DATA_TABLE, MODERATOR_CACHE_TABLE);
 372  
 373      foreach ($table_ary as $table)
 374      {
 375          $sql = "DELETE FROM $table
 376              WHERE user_id = $user_id";
 377          $db->sql_query($sql);
 378      }
 379  
 380      $cache->destroy('sql', MODERATOR_CACHE_TABLE);
 381  
 382      include_once($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx);
 383  
 384      // Remove any undelivered mails...
 385      $sql = 'SELECT msg_id, user_id
 386          FROM ' . PRIVMSGS_TO_TABLE . '
 387          WHERE author_id = ' . $user_id . '
 388              AND folder_id = ' . PRIVMSGS_NO_BOX;
 389      $result = $db->sql_query($sql);
 390  
 391      $undelivered_msg = $undelivered_user = array();
 392      while ($row = $db->sql_fetchrow($result))
 393      {
 394          $undelivered_msg[] = $row['msg_id'];
 395          $undelivered_user[$row['user_id']][] = true;
 396      }
 397      $db->sql_freeresult($result);
 398  
 399      if (sizeof($undelivered_msg))
 400      {
 401          $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . '
 402              WHERE ' . $db->sql_in_set('msg_id', $undelivered_msg);
 403          $db->sql_query($sql);
 404      }
 405  
 406      $sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . '
 407          WHERE author_id = ' . $user_id . '
 408              AND folder_id = ' . PRIVMSGS_NO_BOX;
 409      $db->sql_query($sql);
 410  
 411      // Delete all to-informations
 412      $sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . '
 413          WHERE user_id = ' . $user_id;
 414      $db->sql_query($sql);
 415  
 416      // Set the remaining author id to anonymous - this way users are still able to read messages from users being removed
 417      $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . '
 418          SET author_id = ' . ANONYMOUS . '
 419          WHERE author_id = ' . $user_id;
 420      $db->sql_query($sql);
 421  
 422      $sql = 'UPDATE ' . PRIVMSGS_TABLE . '
 423          SET author_id = ' . ANONYMOUS . '
 424          WHERE author_id = ' . $user_id;
 425      $db->sql_query($sql);
 426  
 427      foreach ($undelivered_user as $_user_id => $ary)
 428      {
 429          if ($_user_id == $user_id)
 430          {
 431              continue;
 432          }
 433  
 434          $sql = 'UPDATE ' . USERS_TABLE . ' 
 435              SET user_new_privmsg = user_new_privmsg - ' . sizeof($ary) . ',
 436                  user_unread_privmsg = user_unread_privmsg - ' . sizeof($ary) . '
 437              WHERE user_id = ' . $_user_id;
 438          $db->sql_query($sql);
 439      }
 440  
 441      // Reset newest user info if appropriate
 442      if ($config['newest_user_id'] == $user_id)
 443      {
 444          update_last_username();
 445      }
 446  
 447      set_config('num_users', $config['num_users'] - 1, true);
 448  
 449      $db->sql_transaction('commit');
 450  
 451      return false;
 452  }
 453  
 454  /**
 455  * Flips user_type from active to inactive and vice versa, handles group membership updates
 456  * 
 457  * @param string $mode can be flip for flipping from active/inactive, activate or deactivate
 458  */
 459  function user_active_flip($mode, $user_id_ary, $reason = INACTIVE_MANUAL)
 460  {
 461      global $config, $db, $user, $auth;
 462  
 463      $deactivated = $activated = 0;
 464      $sql_statements = array();
 465  
 466      if (!is_array($user_id_ary))
 467      {
 468          $user_id_ary = array($user_id_ary);
 469      }
 470  
 471      if (!sizeof($user_id_ary))
 472      {
 473          return;
 474      }
 475  
 476      $sql = 'SELECT user_id, group_id, user_type, user_inactive_reason
 477          FROM ' . USERS_TABLE . '
 478          WHERE ' . $db->sql_in_set('user_id', $user_id_ary);
 479      $result = $db->sql_query($sql);
 480  
 481      while ($row = $db->sql_fetchrow($result))
 482      {
 483          $sql_ary = array();
 484  
 485          if ($row['user_type'] == USER_IGNORE || $row['user_type'] == USER_FOUNDER || 
 486              ($mode == 'activate' && $row['user_type'] != USER_INACTIVE) || 
 487              ($mode == 'deactivate' && $row['user_type'] == USER_INACTIVE))
 488          {
 489              continue;
 490          }
 491  
 492          if ($row['user_type'] == USER_INACTIVE)
 493          {
 494              $activated++;
 495          }
 496          else
 497          {
 498              $deactivated++;
 499  
 500              // Remove the users session key...
 501              $user->reset_login_keys($row['user_id']);
 502          }
 503  
 504          $sql_ary += array(
 505              'user_type'                => ($row['user_type'] == USER_NORMAL) ? USER_INACTIVE : USER_NORMAL,
 506              'user_inactive_time'    => ($row['user_type'] == USER_NORMAL) ? time() : 0,
 507              'user_inactive_reason'    => ($row['user_type'] == USER_NORMAL) ? $reason : 0,
 508          );
 509  
 510          $sql_statements[$row['user_id']] = $sql_ary;
 511      }
 512      $db->sql_freeresult($result);
 513  
 514      if (sizeof($sql_statements))
 515      {
 516          foreach ($sql_statements as $user_id => $sql_ary)
 517          {
 518              $sql = 'UPDATE ' . USERS_TABLE . '
 519                  SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
 520                  WHERE user_id = ' . $user_id;
 521              $db->sql_query($sql);
 522          }
 523  
 524          $auth->acl_clear_prefetch(array_keys($sql_statements));
 525      }
 526  
 527      if ($deactivated)
 528      {
 529          set_config('num_users', $config['num_users'] - $deactivated, true);
 530      }
 531  
 532      if ($activated)
 533      {
 534          set_config('num_users', $config['num_users'] + $activated, true);
 535      }
 536  
 537      // Update latest username
 538      update_last_username();
 539  }
 540  
 541  /**
 542  * Add a ban or ban exclusion to the banlist. Bans either a user, an IP or an email address
 543  *
 544  * @param string $mode Type of ban. One of the following: user, ip, email
 545  * @param mixed $ban Banned entity. Either string or array with usernames, ips or email addresses
 546  * @param int $ban_len Ban length in minutes
 547  * @param string $ban_len_other Ban length as a date (YYYY-MM-DD)
 548  * @param boolean $ban_exclude Exclude these entities from banning?
 549  * @param string $ban_reason String describing the reason for this ban
 550  * @return boolean
 551  */
 552  function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reason, $ban_give_reason = '')
 553  {
 554      global $db, $user, $auth;
 555  
 556      // Delete stale bans
 557      $sql = 'DELETE FROM ' . BANLIST_TABLE . '
 558          WHERE ban_end < ' . time() . '
 559              AND ban_end <> 0';
 560      $db->sql_query($sql);
 561  
 562      $ban_list = (!is_array($ban)) ? array_unique(explode("\n", $ban)) : $ban;
 563      $ban_list_log = implode(', ', $ban_list);
 564  
 565      $current_time = time();
 566  
 567      // Set $ban_end to the unix time when the ban should end. 0 is a permanent ban.
 568      if ($ban_len)
 569      {
 570          if ($ban_len != -1 || !$ban_len_other)
 571          {
 572              $ban_end = max($current_time, $current_time + ($ban_len) * 60);
 573          }
 574          else
 575          {
 576              $ban_other = explode('-', $ban_len_other);
 577              $ban_end = max($current_time, gmmktime(0, 0, 0, $ban_other[1], $ban_other[2], $ban_other[0]));
 578          }
 579      }
 580      else
 581      {
 582          $ban_end = 0;
 583      }
 584  
 585      $founder = array();
 586  
 587      if (!$ban_exclude)
 588      {
 589          // Create a list of founder...
 590          $sql = 'SELECT user_id, user_email
 591              FROM ' . USERS_TABLE . '
 592              WHERE user_type = ' . USER_FOUNDER;
 593          $result = $db->sql_query($sql);
 594  
 595          while ($row = $db->sql_fetchrow($result))
 596          {
 597              $founder[$row['user_id']] = $row['user_email'];
 598          }
 599          $db->sql_freeresult($result);
 600      }
 601  
 602      $banlist_ary = array();
 603  
 604      switch ($mode)
 605      {
 606          case 'user':
 607              $type = 'ban_userid';
 608  
 609              if (in_array('*', $ban_list))
 610              {
 611                  // Ban all users (it's a good thing that you can exclude people)
 612                  $banlist_ary[] = '*';
 613              }
 614              else
 615              {
 616                  // Select the relevant user_ids.
 617                  $sql_usernames = array();
 618  
 619                  foreach ($ban_list as $username)
 620                  {
 621                      $username = trim($username);
 622                      if ($username != '')
 623                      {
 624                          $sql_usernames[] = utf8_clean_string($username);
 625                      }
 626                  }
 627  
 628                  // Make sure we have been given someone to ban
 629                  if (!sizeof($sql_usernames))
 630                  {
 631                      trigger_error($user->lang['NO_USER_SPECIFIED']);
 632                  }
 633  
 634                  $sql = 'SELECT user_id
 635                      FROM ' . USERS_TABLE . '
 636                      WHERE ' . $db->sql_in_set('username_clean', $sql_usernames);
 637  
 638                  // Do not allow banning yourself
 639                  if (sizeof($founder))
 640                  {
 641                      $sql .= ' AND ' . $db->sql_in_set('user_id', array_merge(array_keys($founder), array($user->data['user_id'])), true);
 642                  }
 643                  else
 644                  {
 645                      $sql .= ' AND user_id <> ' . $user->data['user_id'];
 646                  }
 647  
 648                  $result = $db->sql_query($sql);
 649  
 650                  if ($row = $db->sql_fetchrow($result))
 651                  {
 652                      do
 653                      {
 654                          $banlist_ary[] = $row['user_id'];
 655                      }
 656                      while ($row = $db->sql_fetchrow($result));
 657                  }
 658                  else
 659                  {
 660                      trigger_error($user->lang['NO_USERS']);
 661                  }
 662                  $db->sql_freeresult($result);
 663              }
 664          break;
 665  
 666          case 'ip':
 667              $type = 'ban_ip';
 668  
 669              foreach ($ban_list as $ban_item)
 670              {
 671                  if (preg_match('#^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})[ ]*\-[ ]*([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$#', trim($ban_item), $ip_range_explode))
 672                  {
 673                      // This is an IP range
 674                      // Don't ask about all this, just don't ask ... !
 675                      $ip_1_counter = $ip_range_explode[1];
 676                      $ip_1_end = $ip_range_explode[5];
 677  
 678                      while ($ip_1_counter <= $ip_1_end)
 679                      {
 680                          $ip_2_counter = ($ip_1_counter == $ip_range_explode[1]) ? $ip_range_explode[2] : 0;
 681                          $ip_2_end = ($ip_1_counter < $ip_1_end) ? 254 : $ip_range_explode[6];
 682  
 683                          if ($ip_2_counter == 0 && $ip_2_end == 254)
 684                          {
 685                              $ip_2_counter = 256;
 686                              $ip_2_fragment = 256;
 687  
 688                              $banlist_ary[] = "$ip_1_counter.*";
 689                          }
 690  
 691                          while ($ip_2_counter <= $ip_2_end)
 692                          {
 693                              $ip_3_counter = ($ip_2_counter == $ip_range_explode[2] && $ip_1_counter == $ip_range_explode[1]) ? $ip_range_explode[3] : 0;
 694                              $ip_3_end = ($ip_2_counter < $ip_2_end || $ip_1_counter < $ip_1_end) ? 254 : $ip_range_explode[7];
 695  
 696                              if ($ip_3_counter == 0 && $ip_3_end == 254)
 697                              {
 698                                  $ip_3_counter = 256;
 699                                  $ip_3_fragment = 256;
 700  
 701                                  $banlist_ary[] = "$ip_1_counter.$ip_2_counter.*";
 702                              }
 703  
 704                              while ($ip_3_counter <= $ip_3_end)
 705                              {
 706                                  $ip_4_counter = ($ip_3_counter == $ip_range_explode[3] && $ip_2_counter == $ip_range_explode[2] && $ip_1_counter == $ip_range_explode[1]) ? $ip_range_explode[4] : 0;
 707                                  $ip_4_end = ($ip_3_counter < $ip_3_end || $ip_2_counter < $ip_2_end) ? 254 : $ip_range_explode[8];
 708  
 709                                  if ($ip_4_counter == 0 && $ip_4_end == 254)
 710                                  {
 711                                      $ip_4_counter = 256;
 712                                      $ip_4_fragment = 256;
 713  
 714                                      $banlist_ary[] = "$ip_1_counter.$ip_2_counter.$ip_3_counter.*";
 715                                  }
 716  
 717                                  while ($ip_4_counter <= $ip_4_end)
 718                                  {
 719                                      $banlist_ary[] = "$ip_1_counter.$ip_2_counter.$ip_3_counter.$ip_4_counter";
 720                                      $ip_4_counter++;
 721                                  }
 722                                  $ip_3_counter++;
 723                              }
 724                              $ip_2_counter++;
 725                          }
 726                          $ip_1_counter++;
 727                      }
 728                  }
 729                  else if (preg_match('#^([\w\-_]\.?){2,}$#is', trim($ban_item)))
 730                  {
 731                      // hostname
 732                      $ip_ary = gethostbynamel(trim($ban_item));
 733  
 734                      foreach ($ip_ary as $ip)
 735                      {
 736                          if ($ip)
 737                          {
 738                              $banlist_ary[] = $ip;
 739                          }
 740                      }
 741                  }
 742                  else if (preg_match('#^([0-9]{1,3})\.([0-9\*]{1,3})\.([0-9\*]{1,3})\.([0-9\*]{1,3})$#', trim($ban_item)) || preg_match('#^[a-f0-9:]+\*?$#i', trim($ban_item)))
 743                  {
 744                      // Normal IP address
 745                      $banlist_ary[] = trim($ban_item);
 746                  }
 747                  else if (preg_match('#^\*$#', trim($ban_item)))
 748                  {
 749                      // Ban all IPs
 750                      $banlist_ary[] = "*";
 751                  }
 752                  else
 753                  {
 754                      trigger_error('NO_IPS_DEFINED');
 755                  }
 756              }
 757          break;
 758  
 759          case 'email':
 760              $type = 'ban_email';
 761  
 762              foreach ($ban_list as $ban_item)
 763              {
 764                  $ban_item = trim($ban_item);
 765  
 766                  if (preg_match('#^.*?@*|(([a-z0-9\-]+\.)+([a-z]{2,3}))$#i', $ban_item))
 767                  {
 768                      if (!sizeof($founder) || !in_array($ban_item, $founder))
 769                      {
 770                          $banlist_ary[] = $ban_item;
 771                      }
 772                  }
 773              }
 774  
 775              if (sizeof($ban_list) == 0)
 776              {
 777                  trigger_error('NO_EMAILS_DEFINED');
 778              }
 779          break;
 780  
 781          default:
 782              trigger_error('NO_MODE');
 783          break;
 784      }
 785  
 786      // Fetch currently set bans of the specified type and exclude state. Prevent duplicate bans.
 787      $sql = "SELECT $type
 788          FROM " . BANLIST_TABLE . "
 789          WHERE $type <> ''
 790              AND ban_exclude = $ban_exclude";
 791      $result = $db->sql_query($sql);
 792  
 793      if ($row = $db->sql_fetchrow($result))
 794      {
 795          $banlist_ary_tmp = array();
 796          do
 797          {
 798              switch ($mode)
 799              {
 800                  case 'user':
 801                      $banlist_ary_tmp[] = $row['ban_userid'];
 802                  break;
 803  
 804                  case 'ip':
 805                      $banlist_ary_tmp[] = $row['ban_ip'];
 806                  break;
 807  
 808                  case 'email':
 809                      $banlist_ary_tmp[] = $row['ban_email'];
 810                  break;
 811              }
 812          }
 813          while ($row = $db->sql_fetchrow($result));
 814  
 815          $banlist_ary = array_unique(array_diff($banlist_ary, $banlist_ary_tmp));
 816          unset($banlist_ary_tmp);
 817      }
 818      $db->sql_freeresult($result);
 819  
 820      // We have some entities to ban
 821      if (sizeof($banlist_ary))
 822      {
 823          $sql_ary = array();
 824  
 825          foreach ($banlist_ary as $ban_entry)
 826          {
 827              $sql_ary[] = array(
 828                  $type                => $ban_entry,
 829                  'ban_start'            => $current_time,
 830                  'ban_end'            => $ban_end,
 831                  'ban_exclude'        => $ban_exclude,
 832                  'ban_reason'        => $ban_reason,
 833                  'ban_give_reason'    => $ban_give_reason,
 834              );
 835          }
 836          
 837          $db->sql_multi_insert(BANLIST_TABLE, $sql_ary);
 838  
 839          // If we are banning we want to logout anyone matching the ban
 840          if (!$ban_exclude)
 841          {
 842              switch ($mode)
 843              {
 844                  case 'user':
 845                      $sql_where = (in_array('*', $banlist_ary)) ? '' : 'WHERE ' . $db->sql_in_set('session_user_id', $banlist_ary);
 846                  break;
 847  
 848                  case 'ip':
 849                      $sql_where = 'WHERE ' . $db->sql_in_set('session_ip', $banlist_ary);
 850                  break;
 851  
 852                  case 'email':
 853                      $banlist_ary_sql = array();
 854  
 855                      foreach ($banlist_ary as $ban_entry)
 856                      {
 857                          $banlist_ary_sql[] = (string) str_replace('*', '%', $ban_entry);
 858                      }
 859  
 860                      $sql = 'SELECT user_id
 861                          FROM ' . USERS_TABLE . '
 862                          WHERE ' . $db->sql_in_set('user_email', $banlist_ary_sql);
 863                      $result = $db->sql_query($sql);
 864  
 865                      $sql_in = array();
 866  
 867                      if ($row = $db->sql_fetchrow($result))
 868                      {
 869                          do
 870                          {
 871                              $sql_in[] = $row['user_id'];
 872                          }
 873                          while ($row = $db->sql_fetchrow($result));
 874  
 875                          $sql_where = 'WHERE ' . $db->sql_in_set('session_user_id', $sql_in);
 876                      }
 877                      $db->sql_freeresult($result);
 878                  break;
 879              }
 880  
 881              if (isset($sql_where) && $sql_where)
 882              {
 883                  $sql = 'DELETE FROM ' . SESSIONS_TABLE . "
 884                      $sql_where";
 885                  $db->sql_query($sql);
 886  
 887                  if ($mode == 'user')
 888                  {
 889                      $sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . ' ' . ((in_array('*', $banlist_ary)) ? '' : 'WHERE ' . $db->sql_in_set('user_id', $banlist_ary));
 890                      $db->sql_query($sql);
 891                  }
 892              }
 893          }
 894  
 895          // Update log
 896          $log_entry = ($ban_exclude) ? 'LOG_BAN_EXCLUDE_' : 'LOG_BAN_';
 897          add_log('admin', $log_entry . strtoupper($mode), $ban_reason, $ban_list_log);
 898  
 899          return true;
 900      }
 901  
 902      // There was nothing to ban/exclude
 903      return false;
 904  }
 905  
 906  /**
 907  * Unban User
 908  */
 909  function user_unban($mode, $ban)
 910  {
 911      global $db, $user, $auth;
 912  
 913      // Delete stale bans
 914      $sql = 'DELETE FROM ' . BANLIST_TABLE . '
 915          WHERE ban_end < ' . time() . '
 916              AND ban_end <> 0';
 917      $db->sql_query($sql);
 918  
 919      if (!is_array($ban))
 920      {
 921          $ban = array($ban);
 922      }
 923  
 924      $unban_sql = array_map('intval', $ban);
 925  
 926      if (sizeof($unban_sql))
 927      {
 928          // Grab details of bans for logging information later
 929          switch ($mode)
 930          {
 931              case 'user':
 932                  $sql = 'SELECT u.username AS unban_info
 933                      FROM ' . USERS_TABLE . ' u, ' . BANLIST_TABLE . ' b
 934                      WHERE ' . $db->sql_in_set('b.ban_id', $unban_sql) . '
 935                          AND u.user_id = b.ban_userid';
 936              break;
 937  
 938              case 'email':
 939                  $sql = 'SELECT ban_email AS unban_info
 940                      FROM ' . BANLIST_TABLE . '
 941                      WHERE ' . $db->sql_in_set('ban_id', $unban_sql);
 942              break;
 943  
 944              case 'ip':
 945                  $sql = 'SELECT ban_ip AS unban_info
 946                      FROM ' . BANLIST_TABLE . '
 947                      WHERE ' . $db->sql_in_set('ban_id', $unban_sql);
 948              break;
 949          }
 950          $result = $db->sql_query($sql);
 951  
 952          $l_unban_list = '';
 953          while ($row = $db->sql_fetchrow($result))
 954          {
 955              $l_unban_list .= (($l_unban_list != '') ? ', ' : '') . $row['unban_info'];
 956          }
 957          $db->sql_freeresult($result);
 958  
 959          $sql = 'DELETE FROM ' . BANLIST_TABLE . '
 960              WHERE ' . $db->sql_in_set('ban_id', $unban_sql);
 961          $db->sql_query($sql);
 962  
 963          add_log('admin', 'LOG_UNBAN_' . strtoupper($mode), $l_unban_list);
 964      }
 965  
 966      return false;
 967  }
 968  
 969  /**
 970  * Whois facility
 971  */
 972  function user_ipwhois($ip)
 973  {
 974      $ipwhois = '';
 975  
 976      $match = array(
 977          '#RIPE\.NET#is'                => 'whois.ripe.net',
 978          '#whois\.apnic\.net#is'        => 'whois.apnic.net',
 979          '#nic\.ad\.jp#is'            => 'whois.nic.ad.jp',
 980          '#whois\.registro\.br#is'    => 'whois.registro.br'
 981      );
 982  
 983      if (($fsk = @fsockopen('whois.arin.net', 43)))
 984      {
 985          fputs($fsk, "$ip\n");
 986          while (!feof($fsk))
 987          {
 988              $ipwhois .= fgets($fsk, 1024);
 989          }
 990          @fclose($fsk);
 991      }
 992  
 993      foreach (array_keys($match) as $server)
 994      {
 995          if (preg_match($server, $ipwhois))
 996          {
 997              $ipwhois = '';
 998              if (($fsk = @fsockopen($match[$server], 43)))
 999              {
1000                  fputs($fsk, "$ip\n");
1001                  while (!feof($fsk))
1002                  {
1003                      $ipwhois .= fgets($fsk, 1024);
1004                  }
1005                  @fclose($fsk);
1006              }
1007              break;
1008          }
1009      }
1010  
1011      return $ipwhois;
1012  }
1013  
1014  /**
1015  * Data validation ... used primarily but not exclusively by ucp modules
1016  *
1017  * "Master" function for validating a range of data types
1018  */
1019  function validate_data($data, $val_ary)
1020  {
1021      $error = array();
1022  
1023      foreach ($val_ary as $var => $val_seq)
1024      {
1025          if (!is_array($val_seq[0]))
1026          {
1027              $val_seq = array($val_seq);
1028          }
1029  
1030          foreach ($val_seq as $validate)
1031          {
1032              $function = array_shift($validate);
1033              array_unshift($validate, $data[$var]);
1034  
1035              if ($result = call_user_func_array('validate_' . $function, $validate))
1036              {
1037                  $error[] = $result . '_' . strtoupper($var);
1038              }
1039          }
1040      }
1041  
1042      return $error;
1043  }
1044  
1045  /**
1046  * Validate String
1047  *
1048  * @return    boolean|string    Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
1049  */
1050  function validate_string($string, $optional = false, $min = 0, $max = 0)
1051  {
1052      if (empty($string) && $optional)
1053      {
1054          return false;
1055      }
1056  
1057      if ($min && utf8_strlen(htmlspecialchars_decode($string)) < $min)
1058      {
1059          return 'TOO_SHORT';
1060      }
1061      else if ($max && utf8_strlen(htmlspecialchars_decode($string)) > $max)
1062      {
1063          return 'TOO_LONG';
1064      }
1065  
1066      return false;
1067  }
1068  
1069  /**
1070  * Validate Number
1071  *
1072  * @return    boolean|string    Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
1073  */
1074  function validate_num($num, $optional = false, $min = 0, $max = 1E99)
1075  {
1076      if (empty($num) && $optional)
1077      {
1078          return false;
1079      }
1080  
1081      if ($num < $min)
1082      {
1083          return 'TOO_SMALL';
1084      }
1085      else if ($num > $max)
1086      {
1087          return 'TOO_LARGE';
1088      }
1089  
1090      return false;
1091  }
1092  
1093  /**
1094  * Validate Match
1095  *
1096  * @return    boolean|string    Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
1097  */
1098  function validate_match($string, $optional = false, $match)
1099  {
1100      if (empty($string) && $optional)
1101      {
1102          return false;
1103      }
1104  
1105      if (!preg_match($match, $string))
1106      {
1107          return 'WRONG_DATA';
1108      }
1109  
1110      return false;
1111  }
1112  
1113  /**
1114  * Check to see if the username has been taken, or if it is disallowed.
1115  * Also checks if it includes the " character, which we don't allow in usernames.
1116  * Used for registering, changing names, and posting anonymously with a username
1117  *
1118  * @todo do we really check and disallow the " character in usernames as written above. Has it only be forgotten to include the check?
1119  * @return    boolean|string    Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
1120  */
1121  function validate_username($username)
1122  {
1123      global $config, $db, $user, $cache;
1124  
1125      $clean_username = utf8_clean_string($username);
1126  
1127      if (utf8_clean_string($user->data['username']) == $clean_username)
1128      {
1129          return false;
1130      }
1131  
1132      if (!preg_match('#^' . str_replace('\\\\', '\\', $config['allow_name_chars']) . '$#i', $username) || strpos($username, '&quot;') !== false || strpos($username, '"') !== false)
1133      {
1134          return 'INVALID_CHARS';
1135      }
1136  
1137      $sql = 'SELECT username
1138          FROM ' . USERS_TABLE . "
1139          WHERE username_clean = '" . $db->sql_escape($clean_username) . "'";
1140      $result = $db->sql_query($sql);
1141      $row = $db->sql_fetchrow($result);
1142      $db->sql_freeresult($result);
1143  
1144      if ($row)
1145      {
1146          return 'USERNAME_TAKEN';
1147      }
1148  
1149      $sql = 'SELECT group_name
1150          FROM ' . GROUPS_TABLE . "
1151          WHERE LOWER(group_name) = '" . $db->sql_escape(utf8_strtolower($username)) . "'";
1152      $result = $db->sql_query($sql);
1153      $row = $db->sql_fetchrow($result);
1154      $db->sql_freeresult($result);
1155  
1156      if ($row)
1157      {
1158          return 'USERNAME_TAKEN';
1159      }
1160  
1161  
1162      $bad_usernames = $cache->obtain_disallowed_usernames();
1163  
1164      foreach ($bad_usernames as $bad_username)
1165      {
1166          if (preg_match('#^' . $bad_username . '#', $clean_username))
1167          {
1168              return 'USERNAME_DISALLOWED';
1169          }
1170      }
1171  
1172      $sql = 'SELECT word
1173          FROM  ' . WORDS_TABLE;
1174      $result = $db->sql_query($sql);
1175  
1176      while ($row = $db->sql_fetchrow($result))
1177      {
1178          if (preg_match('#(' . str_replace('\*', '.*?', preg_quote($row['word'], '#')) . ')#i', $username))
1179          {
1180              $db->sql_freeresult($result);
1181              return 'USERNAME_DISALLOWED';
1182          }
1183      }
1184      $db->sql_freeresult($result);
1185  
1186      return false;
1187  }
1188  
1189  /**
1190  * Check to see if the password meets the complexity settings
1191  *
1192  * @return    boolean|string    Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
1193  */
1194  function validate_password($password)
1195  {
1196      global $config, $db, $user;
1197  
1198      if (!$password)
1199      {
1200          return false;
1201      }
1202  
1203      // We only check for existance of characters
1204      if (!preg_match('#' . str_replace('\\\\', '\\', $config['pass_complex']) . '#i', $password))
1205      {
1206          return 'INVALID_CHARS';
1207      }
1208  
1209      return false;
1210  }
1211  
1212  /**
1213  * Check to see if email address is banned or already present in the DB
1214  *
1215  * @return    boolean|string    Either false if validation succeeded or a string which will be used as the error message (with the variable name appended)
1216  */
1217  function validate_email($email)
1218  {
1219      global $config, $db, $user;
1220  
1221      if (strtolower($user->data['user_email']) == strtolower($email))
1222      {
1223          return false;
1224      }
1225  
1226      if (!preg_match('/^' . get_preg_expression('email') . '$/i', $email))
1227      {
1228          return 'EMAIL_INVALID';
1229      }
1230  
1231      // Check MX record.
1232      // The idea for this is from reading the UseBB blog/announcement. :)
1233      if ($config['email_check_mx'])
1234      {
1235          list(, $domain) = explode('@', $email);
1236  
1237          if (phpbb_checkdnsrr($domain, 'MX') === false)
1238          {
1239              return 'DOMAIN_NO_MX_RECORD';
1240          }
1241      }
1242  
1243      if ($user->check_ban(false, false, $email, true) == true)
1244      {
1245          return 'EMAIL_BANNED';
1246      }
1247  
1248      if (!$config['allow_emailreuse'])
1249      {
1250          $sql = 'SELECT user_email_hash
1251              FROM ' . USERS_TABLE . "
1252              WHERE user_email_hash = " . crc32(strtolower($email)) . strlen($email);
1253          $result = $db->sql_query($sql);
1254          $row = $db->sql_fetchrow($result);
1255          $db->sql_freeresult($result);
1256  
1257          if ($row)
1258          {
1259              return 'EMAIL_TAKEN';
1260          }
1261      }
1262  
1263      return false;
1264  }
1265  
1266  /**
1267  * Remove avatar
1268  */
1269  function avatar_delete($mode, $row)
1270  {
1271      global $phpbb_root_path, $config, $db, $user;
1272  
1273      // Check if the users avatar is actually *not* a group avatar
1274      if ($mode == 'user')
1275      {
1276          if (strpos($row['user_avatar'], 'g' . $row['group_id'] . '_') === 0 || strpos($row['user_avatar'], $row['user_id'] . '_') !== 0)
1277          {
1278              return false;
1279          }
1280      }
1281  
1282      if (file_exists($phpbb_root_path . $config['avatar_path'] . '/' . basename($row[$mode . '_avatar'])))
1283      {
1284          @unlink($phpbb_root_path . $config['avatar_path'] . '/' . basename($row[$mode . '_avatar']));
1285          return true;
1286      }
1287  
1288      return false;
1289  }
1290  
1291  /**
1292  * Remote avatar linkage
1293  */
1294  function avatar_remote($data, &$error)
1295  {
1296      global $config, $db, $user, $phpbb_root_path, $phpEx;
1297  
1298      if (!preg_match('#^(http|https|ftp)://#i', $data['remotelink']))
1299      {
1300          $data['remotelink'] = 'http://' . $data['remotelink'];
1301      }
1302  
1303      if (!preg_match('#^(http|https|ftp)://(.*?\.)*?[a-z0-9\-]+?\.[a-z]{2,4}:?([0-9]*?).*?\.(gif|jpg|jpeg|png)$#i', $data['remotelink']))
1304      {
1305          $error[] = $user->lang['AVATAR_URL_INVALID'];
1306          return false;
1307      }
1308  
1309      // Make sure getimagesize works...
1310      if (($image_data = @getimagesize($data['remotelink'])) === false)
1311      {
1312          $error[] = $user->lang['UNABLE_GET_IMAGE_SIZE'];
1313          return false;
1314      }
1315  
1316      $width = ($data['width'] && $data['height']) ? $data['width'] : $image_data[0];
1317      $height = ($data['width'] && $data['height']) ? $data['height'] : $image_data[1];
1318  
1319      if (!$width || !$height)
1320      {
1321          $error[] = $user->lang['AVATAR_NO_SIZE'];
1322          return false;
1323      }
1324  
1325      // Check image type
1326      include_once($phpbb_root_path . 'includes/functions_upload.' . $phpEx);
1327      $types = fileupload::image_types();
1328      $extension = strtolower(filespec::get_extension($data['remotelink']));
1329  
1330      if (!isset($types[$image_data[2]]) || !in_array($extension, $types[$image_data[2]]))
1331      {
1332          if (!isset($types[$image_data[2]]))
1333          {
1334              $error[] = $user->lang['UNABLE_GET_IMAGE_SIZE'];
1335          }
1336          else
1337          {
1338              $error[] = sprintf($user->lang['IMAGE_FILETYPE_MISMATCH'], $types[$image_data[2]][0], $extension);
1339          }
1340          return false;
1341      }
1342  
1343      if ($config['avatar_max_width'] || $config['avatar_max_height'])
1344      {
1345          if ($width > $config['avatar_max_width'] || $height > $config['avatar_max_height'])
1346          {
1347              $error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $width, $height);
1348              return false;
1349          }
1350      }
1351  
1352      if ($config['avatar_min_width'] || $config['avatar_min_height'])
1353      {
1354          if ($width < $config['avatar_min_width'] || $height < $config['avatar_min_height'])
1355          {
1356              $error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $width, $height);
1357              return false;
1358          }
1359      }
1360  
1361      return array(AVATAR_REMOTE, $data['remotelink'], $width, $height);
1362  }
1363  
1364  /**
1365  * Avatar upload using the upload class
1366  */
1367  function avatar_upload($data, &$error)
1368  {
1369      global $phpbb_root_path, $config, $db, $user, $phpEx;
1370  
1371      // Init upload class
1372      include_once($phpbb_root_path . 'includes/functions_upload.' . $phpEx);
1373      $upload = new fileupload('AVATAR_', array('jpg', 'jpeg', 'gif', 'png'), $config['avatar_filesize'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height']);
1374  
1375      if (!empty($_FILES['uploadfile']['name']))
1376      {
1377          $file = $upload->form_upload('uploadfile');
1378      }
1379      else
1380      {
1381          $file = $upload->remote_upload($data['uploadurl']);
1382      }
1383  
1384      $file->clean_filename('real', $data['user_id'] . '_');
1385  
1386      $destination = $config['avatar_path'];
1387  
1388      if ($destination{(sizeof($destination)-1)} == '/' || $destination{(sizeof($destination)-1)} == '\\')
1389      {
1390          $destination = substr($destination, 0, sizeof($destination)-2);
1391      }
1392  
1393      $destination = str_replace(array('../', '..\\', './', '.\\'), '', $destination);
1394      if ($destination && ($destination[0] == '/' || $destination[0] == "\\"))
1395      {
1396          $destination = '';
1397      }
1398  
1399      $file->move_file($destination);
1400  
1401      if (sizeof($file->error))
1402      {
1403          $file->remove();
1404          $error = array_merge($error, $file->error);
1405      }
1406  
1407      return array(AVATAR_UPLOAD, $file->get('realname'), $file->get('width'), $file->get('height'));
1408  }
1409  
1410  /**
1411  * Avatar Gallery
1412  */
1413  function avatar_gallery($category, $avatar_select, $items_per_column, $block_var = 'avatar_row')
1414  {
1415      global $user, $cache, $template;
1416      global $config, $phpbb_root_path;
1417  
1418      $avatar_list = array();
1419  
1420      $path = $phpbb_root_path . $config['avatar_gallery_path'];
1421  
1422      if (!file_exists($path) || !is_dir($path))
1423      {
1424          $avatar_list = array($user->lang['NO_AVATAR_CATEGORY'] => array());
1425      }
1426      else
1427      {
1428          // Collect images
1429          $dp = @opendir($path);
1430  
1431          while (($file = readdir($dp)) !== false)
1432          {
1433              if ($file[0] != '.' && is_dir("$path/$file"))
1434              {
1435                  $avatar_row_count = $avatar_col_count = 0;
1436      
1437                  $dp2 = @opendir("$path/$file");
1438                  while (($sub_file = readdir($dp2)) !== false)
1439                  {
1440                      if (preg_match('#\.(?:gif|png|jpe?g)$#i', $sub_file))
1441                      {
1442                          $avatar_list[$file][$avatar_row_count][$avatar_col_count] = array(
1443                              'file'        => "$file/$sub_file",
1444                              'filename'    => $sub_file,
1445                              'name'        => ucfirst(str_replace('_', ' ', preg_replace('#^(.*)\..*$#', '\1', $sub_file))),
1446                          );
1447  
1448                          $avatar_col_count++;
1449                          if ($avatar_col_count == $items_per_column)
1450                          {
1451                              $avatar_row_count++;
1452                              $avatar_col_count = 0;
1453                          }
1454                      }
1455                  }
1456                  closedir($dp2);
1457              }
1458          }
1459          closedir($dp);
1460      }
1461  
1462      if (!sizeof($avatar_list))
1463      {
1464          $avatar_list = array($user->lang['NO_AVATAR_CATEGORY'] => array());
1465      }
1466  
1467      @ksort($avatar_list);
1468  
1469      $category = (!$category) ? key($avatar_list) : $category;
1470      $avatar_categories = array_keys($avatar_list);
1471  
1472      $s_category_options = '';
1473      foreach ($avatar_categories as $cat)
1474      {
1475          $s_category_options .= '<option value="' . $cat . '"' . (($cat == $category) ? ' selected="selected"' : '') . '>' . $cat . '</option>';
1476      }
1477  
1478      $template->assign_vars(array(
1479          'S_IN_AVATAR_GALLERY'    => true,
1480          'S_CAT_OPTIONS'            => $s_category_options)
1481      );
1482  
1483      $avatar_list = $avatar_list[$category];
1484  
1485      foreach ($avatar_list as $avatar_row_ary)
1486      {
1487          $template->assign_block_vars($block_var, array());
1488  
1489          foreach ($avatar_row_ary as $avatar_col_ary)
1490          {
1491              $template->assign_block_vars($block_var . '.avatar_column', array(
1492                  'AVATAR_IMAGE'    => $phpbb_root_path . $config['avatar_gallery_path'] . '/' . $avatar_col_ary['file'],
1493                  'AVATAR_NAME'    => $avatar_col_ary['name'],
1494                  'AVATAR_FILE'    => $avatar_col_ary['filename'])
1495              );
1496  
1497              $template->assign_block_vars($block_var . '.avatar_option_column', array(
1498                  'AVATAR_IMAGE'    => $phpbb_root_path . $config['avatar_gallery_path'] . '/' . $avatar_col_ary['file'],
1499                  'S_OPTIONS_AVATAR'    => $avatar_col_ary['filename'])
1500              );
1501          }
1502      }
1503  
1504      return $avatar_list;
1505  }
1506  
1507  //
1508  // Usergroup functions
1509  //
1510  
1511  /**
1512  * Add or edit a group. If we're editing a group we only update user
1513  * parameters such as rank, etc. if they are changed
1514  */
1515  function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow_desc_bbcode = false, $allow_desc_urls = false, $allow_desc_smilies = false)
1516  {
1517      global $phpbb_root_path, $config, $db, $user, $file_upload;
1518  
1519      $error = array();
1520      $attribute_ary = array(
1521          'group_colour'            => 'string',
1522          'group_rank'            => 'int',
1523          'group_avatar'            => 'string',
1524          'group_avatar_type'        => 'int',
1525          'group_avatar_width'    => 'int',
1526          'group_avatar_height'    => 'int',
1527  
1528          'group_receive_pm'        => 'int',
1529          'group_legend'            => 'int',
1530          'group_message_limit'    => 'int',
1531      );
1532  
1533      // Those are group-only attributes
1534      $group_only_ary = array('group_receive_pm', 'group_legend', 'group_message_limit');
1535  
1536      // Check data
1537      if (!utf8_strlen($name) || utf8_strlen($name) > 40)
1538      {
1539          $error[] = (!utf8_strlen($name)) ? $user->lang['GROUP_ERR_USERNAME'] : $user->lang['GROUP_ERR_USER_LONG'];
1540      }
1541  
1542      if (utf8_strlen($desc) > 255)
1543      {
1544          $error[] = $user->lang['GROUP_ERR_DESC_LONG'];
1545      }
1546  
1547      if (!in_array($type, array(GROUP_OPEN, GROUP_CLOSED, GROUP_HIDDEN, GROUP_SPECIAL, GROUP_FREE)))
1548      {
1549          $error[] = $user->lang['GROUP_ERR_TYPE'];
1550      }
1551  
1552      if (!sizeof($error))
1553      {
1554          $sql_ary = array(
1555              'group_name'            => (string) $name,
1556              'group_desc'            => (string) $desc,
1557              'group_desc_uid'        => '',
1558              'group_desc_bitfield'    => '',
1559              'group_type'            => (int) $type,
1560          );
1561  
1562          // Parse description
1563          if ($desc)
1564          {
1565              generate_text_for_storage($sql_ary['group_desc'], $sql_ary['group_desc_uid'], $sql_ary['group_desc_bitfield'], $sql_ary['group_desc_options'], $allow_desc_bbcode, $allow_desc_urls, $allow_desc_smilies);
1566          }
1567  
1568          if (sizeof($group_attributes))
1569          {
1570              foreach ($attribute_ary as $attribute => $_type)
1571              {
1572                  if (isset($group_attributes[$attribute]))
1573                  {
1574                      settype($group_attributes[$attribute], $_type);
1575                      $sql_ary[$attribute] = $group_attributes[$attribute];
1576                  }
1577              }
1578          }
1579  
1580          // Setting the log message before we set the group id (if group gets added)
1581          $log = ($group_id) ? 'LOG_GROUP_UPDATED' : 'LOG_GROUP_CREATED';
1582  
1583          $query = '';
1584  
1585          if ($group_id)
1586          {
1587              $sql = 'UPDATE ' . GROUPS_TABLE . '
1588                  SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
1589                  WHERE group_id = $group_id";
1590          }
1591          else
1592          {
1593              $sql = 'INSERT INTO ' . GROUPS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
1594          }
1595          $db->sql_query($sql);
1596  
1597          if (!$group_id)
1598          {
1599              $group_id = $db->sql_nextid();
1600          }
1601  
1602          // Set user attributes
1603          $sql_ary = array();
1604          if (sizeof($group_attributes))
1605          {
1606              foreach ($attribute_ary as $attribute => $_type)
1607              {
1608                  if (isset($group_attributes[$attribute]) && !in_array($attribute, $group_only_ary))
1609                  {
1610                      // If we are about to set an avatar, we will not overwrite user avatars if no group avatar is set...
1611                      if (strpos($attribute, 'group_avatar') === 0 && !$group_attributes[$attribute])
1612                      {
1613                          continue;
1614                      }
1615  
1616                      $sql_ary[$attribute] = $group_attributes[$attribute];
1617                  }
1618              }
1619          }
1620  
1621          if (sizeof($sql_ary))
1622          {
1623              $sql = 'SELECT user_id
1624                  FROM ' . USERS_TABLE . '
1625                  WHERE group_id = ' . $group_id;
1626              $result = $db->sql_query($sql);
1627  
1628              $user_ary = array();
1629              while ($row = $db->sql_fetchrow($result))
1630              {
1631                  $user_ary[] = $row['user_id'];
1632              }
1633  
1634              $db->sql_freeresult($result);
1635  
1636              if (sizeof($user_ary))
1637              {
1638                  group_set_user_default($group_id, $user_ary, $sql_ary);
1639              }
1640          }
1641  
1642          $name = ($type == GROUP_SPECIAL) ? $user->lang['G_' . $name] : $name;
1643          add_log('admin', $log, $name);
1644      }
1645  
1646      return (sizeof($error)) ? $error : false;
1647  }
1648  
1649  /**
1650  * Group Delete
1651  */
1652  function group_delete($group_id, $group_name = false)
1653  {
1654      global $db, $phpbb_root_path, $phpEx;
1655  
1656      if (!$group_name)
1657      {
1658          $group_name = get_group_name($group_id);
1659      }
1660  
1661      $start = 0;
1662  
1663      do
1664      {
1665          $user_id_ary = $username_ary = array();
1666  
1667          // Batch query for group members, call group_user_del
1668          $sql = 'SELECT u.user_id, u.username
1669              FROM ' . USER_GROUP_TABLE . ' ug, ' . USERS_TABLE . " u
1670              WHERE ug.group_id = $group_id
1671                  AND u.user_id = ug.user_id";
1672          $result = $db->sql_query_limit($sql, 200, $start);
1673  
1674          if ($row = $db->sql_fetchrow($result))
1675          {
1676              do
1677              {
1678                  $user_id_ary[] = $row['user_id'];
1679                  $username_ary[] = $row['username'];
1680  
1681                  $start++;
1682              }
1683              while ($row = $db->sql_fetchrow($result));
1684  
1685              group_user_del($group_id, $user_id_ary, $username_ary, $group_name);
1686          }
1687          else
1688          {
1689              $start = 0;
1690          }
1691          $db->sql_freeresult($result);
1692      }
1693      while ($start);
1694  
1695      // Delete group
1696      $sql = 'DELETE FROM ' . GROUPS_TABLE . "
1697          WHERE group_id = $group_id";
1698      $db->sql_query($sql);
1699  
1700      // Delete auth entries from the groups table
1701      $sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . "
1702          WHERE group_id = $group_id";
1703      $db->sql_query($sql);
1704  
1705      // Re-cache moderators
1706      if (!function_exists('cache_moderators'))
1707      {
1708          include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
1709      }
1710  
1711      cache_moderators();
1712  
1713      add_log('admin', 'LOG_GROUP_DELETE', $group_name);
1714  
1715      return 'GROUP_DELETED';
1716  }
1717  
1718  /**
1719  * Add user(s) to group
1720  *
1721  * @return false if no errors occurred, else the user lang string for the relevant error, for example 'NO_USER'
1722  */
1723  function group_user_add($group_id, $user_id_ary = false, $username_ary = false, $group_name = false, $default = false, $leader = 0, $pending = 0, $group_attributes = false)
1724  {
1725      global $db, $auth;
1726  
1727      // We need both username and user_id info
1728      $result = user_get_id_name($user_id_ary, $username_ary);
1729  
1730      if (!sizeof($user_id_ary) || $result !== false)
1731      {
1732          return 'NO_USER';
1733      }
1734  
1735      // Remove users who are already members of this group
1736      $sql = 'SELECT user_id, group_leader
1737          FROM ' . USER_GROUP_TABLE . '
1738          WHERE ' . $db->sql_in_set('user_id', $user_id_ary) . "
1739              AND group_id = $group_id";
1740      $result = $db->sql_query($sql);
1741  
1742      $add_id_ary = $update_id_ary = array();
1743      while ($row = $db->sql_fetchrow($result))
1744      {
1745          $add_id_ary[] = (int) $row['user_id'];
1746  
1747          if ($leader && !$row['group_leader'])
1748          {
1749              $update_id_ary[] = (int) $row['user_id'];
1750          }
1751      }
1752      $db->sql_freeresult($result);
1753  
1754      // Do all the users exist in this group?
1755      $add_id_ary = array_diff($user_id_ary, $add_id_ary);
1756  
1757      // If we have no users
1758      if (!sizeof($add_id_ary) && !sizeof($update_id_ary))
1759      {
1760          return 'GROUP_USERS_EXIST';
1761      }
1762  
1763      $db->sql_transaction('begin');
1764  
1765      // Insert the new users
1766      if (sizeof($add_id_ary))
1767      {
1768          $sql_ary = array();
1769  
1770          foreach ($add_id_ary as $user_id)
1771          {
1772              $sql_ary[] = array(
1773                  'user_id'        => $user_id,
1774                  'group_id'        => $group_id,
1775                  'group_leader'    => $leader,
1776                  'user_pending'    => $pending,
1777              );
1778          }
1779  
1780          $db->sql_multi_insert(USER_GROUP_TABLE, $sql_ary);
1781      }
1782  
1783      if (sizeof($update_id_ary))
1784      {
1785          $sql = 'UPDATE ' . USER_GROUP_TABLE . '
1786              SET group_leader = 1
1787              WHERE ' . $db->sql_in_set('user_id', $update_id_ary) . "
1788                  AND group_id = $group_id";
1789          $db->sql_query($sql);
1790      }
1791  
1792      if ($default)
1793      {
1794          group_set_user_default($group_id, $user_id_ary, $group_attributes);
1795      }
1796  
1797      $db->sql_transaction('commit');
1798  
1799      // Clear permissions cache of relevant users
1800      $auth->acl_clear_prefetch($user_id_ary);
1801  
1802      if (!$group_name)
1803      {
1804          $group_name = get_group_name($group_id);
1805      }
1806  
1807      $log = ($leader) ? 'LOG_MODS_ADDED' : 'LOG_USERS_ADDED';
1808  
1809      add_log('admin', $log, $group_name, implode(', ', $username_ary));
1810  
1811      group_update_listings($group_id);
1812  
1813      // Return false - no error
1814      return false;
1815  }
1816  
1817  /**
1818  * Remove a user/s from a given group. When we remove users we update their
1819  * default group_id. We do this by examining which "special" groups they belong
1820  * to. The selection is made based on a reasonable priority system
1821  *
1822  * @return false if no errors occurred, else the user lang string for the relevant error, for example 'NO_USER'
1823  */
1824  function group_user_del($group_id, $user_id_ary = false, $username_ary = false, $group_name = false)
1825  {
1826      global $db, $auth;
1827  
1828      $group_order = array('ADMINISTRATORS', 'GLOBAL_MODERATORS', 'REGISTERED_COPPA', 'REGISTERED', 'BOTS', 'GUESTS');
1829  
1830      // We need both username and user_id info
1831      $result = user_get_id_name($user_id_ary, $username_ary);
1832  
1833      if (!sizeof($user_id_ary) || $result !== false)
1834      {
1835          return 'NO_USER';
1836      }
1837  
1838      $sql = 'SELECT *
1839          FROM ' . GROUPS_TABLE . '
1840          WHERE ' . $db->sql_in_set('group_name', $group_order);
1841      $result = $db->sql_query($sql);
1842  
1843      $group_order_id = $special_group_data = array();
1844      while ($row = $db->sql_fetchrow($result))
1845      {
1846          $group_order_id[$row['group_name']] = $row['group_id'];
1847  
1848          $special_group_data[$row['group_id']] = array(
1849              'group_colour'            => $row['group_colour'],
1850              'group_rank'                => $row['group_rank'],
1851          );
1852  
1853          // Only set the group avatar if one is defined...
1854          if ($row['group_avatar'])
1855          {
1856              $special_group_data[$row['group_id']] = array_merge($special_group_data[$row['group_id']], array(
1857                  'group_avatar'            => $row['group_avatar'],
1858                  'group_avatar_type'        => $row['group_avatar_type'],
1859                  'group_avatar_width'        => $row['group_avatar_width'],
1860                  'group_avatar_height'    => $row['group_avatar_height'])
1861              );
1862          }
1863      }
1864      $db->sql_freeresult($result);
1865  
1866      // Get users default groups - we only need to reset default group membership if the group from which the user gets removed is set as default
1867      $sql = 'SELECT user_id, group_id
1868          FROM ' . USERS_TABLE . '
1869          WHERE ' . $db->sql_in_set('user_id', $user_id_ary);
1870      $result = $db->sql_query($sql);
1871  
1872      $default_groups = array();
1873      while ($row = $db->sql_fetchrow($result))
1874      {
1875          $default_groups[$row['user_id']] = $row['group_id'];
1876      }
1877      $db->sql_freeresult($result);
1878  
1879      // What special group memberships exist for these users?
1880      $sql = 'SELECT g.group_id, g.group_name, ug.user_id
1881          FROM ' . USER_GROUP_TABLE . ' ug, ' . GROUPS_TABLE . ' g
1882          WHERE ' . $db->sql_in_set('ug.user_id', $user_id_ary) . "
1883              AND g.group_id = ug.group_id
1884              AND g.group_id <> $group_id
1885              AND g.group_type = " . GROUP_SPECIAL . '
1886          ORDER BY ug.user_id, g.group_id';
1887      $result = $db->sql_query($sql);
1888  
1889      $temp_ary = array();
1890      while ($row = $db->sql_fetchrow($result))
1891      {
1892          if ($default_groups[$row['user_id']] == $group_id && (!isset($temp_ary[$row['user_id']]) || array_search($row['group_name'], $group_order) < $temp_ary[$row['user_id']]))
1893          {
1894              $temp_ary[$row['user_id']] = $row['group_id'];
1895          }
1896      }
1897      $db->sql_freeresult($result);
1898  
1899      $sql_where_ary = array();
1900      foreach ($temp_ary as $uid => $gid)
1901      {
1902          $sql_where_ary[$gid][] = $uid;
1903      }
1904      unset($temp_ary);
1905  
1906      foreach ($special_group_data as $gid => $default_data_ary)
1907      {
1908          if (isset($sql_where_ary[$gid]) && sizeof($sql_where_ary[$gid]))
1909          {
1910              group_set_user_default($gid, $sql_where_ary[$gid], $special_group_data[$gid]);
1911          }
1912      }
1913      unset($special_group_data);
1914  
1915      $sql = 'DELETE FROM ' . USER_GROUP_TABLE . "
1916          WHERE group_id = $group_id
1917              AND " . $db->sql_in_set('user_id', $user_id_ary);
1918      $db->sql_query($sql);
1919  
1920      // Clear permissions cache of relevant users
1921      $auth->acl_clear_prefetch($user_id_ary);
1922  
1923      if (!$group_name)
1924      {
1925          $group_name = get_group_name($group_id);
1926      }
1927  
1928      $log = 'LOG_GROUP_REMOVE';
1929  
1930      add_log('admin', $log, $group_name, implode(', ', $username_ary));
1931  
1932      // Return false - no error
1933      return false;
1934  }
1935  
1936  /**
1937  * This is used to promote (to leader), demote or set as default a member/s
1938  */
1939  function group_user_attributes($action, $group_id, $user_id_ary = false, $username_ary = false, $group_name = false, $group_attributes = false)
1940  {
1941      global $db, $auth, $phpbb_root_path, $phpEx, $config;
1942  
1943      // We need both username and user_id info
1944      $result = user_get_id_name($user_id_ary, $username_ary);
1945  
1946      if (!sizeof($user_id_ary) || $result !== false)
1947      {
1948          return false;
1949      }
1950  
1951      if (!$group_name)
1952      {
1953          $group_name = get_group_name($group_id);
1954      }
1955  
1956      switch ($action)
1957      {
1958          case 'demote':
1959          case 'promote':
1960              $sql = 'UPDATE ' . USER_GROUP_TABLE . '
1961                  SET group_leader = ' . (($action == 'promote') ? 1 : 0) . "
1962                  WHERE group_id = $group_id
1963                      AND " . $db->sql_in_set('user_id', $user_id_ary);
1964              $db->sql_query($sql);
1965  
1966              $log = ($action == 'promote') ? 'LOG_GROUP_PROMOTED' : 'LOG_GROUP_DEMOTED';
1967          break;
1968  
1969          case 'approve':
1970              // Make sure we only approve those which are pending ;)
1971              $sql = 'SELECT u.user_id, u.user_email, u.username, u.user_notify_type, u.user_jabber, u.user_lang
1972                  FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . ' ug
1973                  WHERE ug.group_id = ' . $group_id . '
1974                      AND ug.user_pending = 1
1975                      AND ug.user_id = u.user_id
1976                      AND ' . $db->sql_in_set('ug.user_id', $user_id_ary);
1977              $result = $db->sql_query($sql);
1978  
1979              $user_id_ary = $email_users = array();
1980              while ($row = $db->sql_fetchrow($result))
1981              {
1982                  $user_id_ary[] = $row['user_id'];
1983                  $email_users[] = $row;
1984              }
1985              $db->sql_freeresult($result);
1986  
1987              if (!sizeof($user_id_ary))
1988              {
1989                  return false;
1990              }
1991  
1992              $sql = 'UPDATE ' . USER_GROUP_TABLE . "
1993                  SET user_pending = 0
1994                  WHERE group_id = $group_id
1995                      AND " . $db->sql_in_set('user_id', $user_id_ary);
1996              $db->sql_query($sql);
1997  
1998              // Send approved email to users...
1999              include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
2000              $messenger = new messenger();
2001  
2002              foreach ($email_users as $row)
2003              {
2004                  $messenger->template('group_approved', $row['user_lang']);
2005  
2006                  $messenger->replyto($config['board_email']);
2007                  $messenger->to($row['user_email'], $row['username']);
2008                  $messenger->im($row['user_jabber'], $row['username']);
2009  
2010                  $messenger->assign_vars(array(
2011                      'USERNAME'        => htmlspecialchars_decode($row['username']),
2012                      'GROUP_NAME'    => htmlspecialchars_decode($group_name),
2013                      'U_GROUP'        => generate_board_url() . "/ucp.$phpEx?i=groups&mode=membership")
2014                  );
2015  
2016                  $messenger->send($row['user_notify_type']);
2017                  $messenger->reset();
2018              }
2019  
2020              $messenger->save_queue();
2021  
2022              $log = 'LOG_USERS_APPROVED';
2023          break;
2024  
2025          case 'default':
2026              group_set_user_default($group_id, $user_id_ary, $group_attributes);
2027              $log = 'LOG_GROUP_DEFAULTS';
2028          break;
2029      }
2030  
2031      // Clear permissions cache of relevant users
2032      $auth->acl_clear_prefetch($user_id_ary);
2033  
2034      add_log('admin', $log, $group_name, implode(', ', $username_ary));
2035  
2036      return true;
2037  }
2038  
2039  /**
2040  * Set users default group
2041  */
2042  function group_set_user_default($group_id, $user_id_ary, $group_attributes = false)
2043  {
2044      global $db;
2045  
2046      if (empty($user_id_ary))
2047      {
2048          return;
2049      }
2050  
2051      $attribute_ary = array(
2052          'group_colour'            => 'string',
2053          'group_rank'            => 'int',
2054          'group_avatar'            => 'string',
2055          'group_avatar_type'        => 'int',
2056          'group_avatar_width'    => 'int',
2057          'group_avatar_height'    => 'int',
2058      );
2059  
2060      $sql_ary = array(
2061          'group_id'        => $group_id
2062      );
2063  
2064      // Were group attributes passed to the function? If not we need to obtain them
2065      if ($group_attributes === false)
2066      {
2067          $sql = 'SELECT ' . implode(', ', array_keys($attribute_ary)) . '
2068              FROM ' . GROUPS_TABLE . "
2069              WHERE group_id = $group_id";
2070          $result = $db->sql_query($sql);
2071          $group_attributes = $db->sql_fetchrow($result);
2072          $db->sql_freeresult($result);
2073      }
2074  
2075      foreach ($attribute_ary as $attribute => $type)
2076      {
2077          if (isset($group_attributes[$attribute]))
2078          {
2079              // If we are about to set an avatar, we will not overwrite user avatars if no group avatar is set...
2080              if (strpos($attribute, 'group_avatar') === 0 && !$group_attributes[$attribute])
2081              {
2082                  continue;
2083              }
2084  
2085              settype($group_attributes[$attribute], $type);
2086              $sql_ary[str_replace('group_', 'user_', $attribute)] = $group_attributes[$attribute];
2087          }
2088      }
2089  
2090      // Before we update the user attributes, we will make a list of those having now the group avatar assigned
2091      if (in_array('user_avatar', array_keys($sql_ary)))
2092      {
2093          // Ok, get the original avatar data from users having an uploaded one (we need to remove these from the filesystem)
2094          $sql = 'SELECT user_id, group_id, user_avatar
2095              FROM ' . USERS_TABLE . '
2096              WHERE ' . $db->sql_in_set('user_id', $user_id_ary) . '
2097                  AND user_avatar_type = ' . AVATAR_UPLOAD;
2098          $result = $db->sql_query($sql);
2099  
2100          while ($row = $db->sql_fetchrow($result))
2101          {
2102              avatar_delete('user', $row);
2103          }
2104          $db->sql_freeresult($result);
2105      }
2106  
2107      $sql = 'UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
2108          WHERE ' . $db->sql_in_set('user_id', $user_id_ary);
2109      $db->sql_query($sql);
2110  
2111      if (in_array('user_colour', array_keys($sql_ary)))
2112      {
2113          // Update any cached colour information for these users
2114          $sql = 'UPDATE ' . FORUMS_TABLE . " SET forum_last_poster_colour = '" . $db->sql_escape($sql_ary['user_colour']) . "'
2115              WHERE " . $db->sql_in_set('forum_last_poster_id', $user_id_ary);
2116          $db->sql_query($sql);
2117  
2118          $sql = 'UPDATE ' . TOPICS_TABLE . " SET topic_first_poster_colour = '" . $db->sql_escape($sql_ary['user_colour']) . "'
2119              WHERE " . $db->sql_in_set('topic_poster', $user_id_ary);
2120          $db->sql_query($sql);
2121  
2122          $sql = 'UPDATE ' . TOPICS_TABLE . " SET topic_last_poster_colour = '" . $db->sql_escape($sql_ary['user_colour']) . "'
2123              WHERE " . $db->sql_in_set('topic_last_poster_id', $user_id_ary);
2124          $db->sql_query($sql);
2125      }
2126  }
2127  
2128  /**
2129  * Get group name
2130  */
2131  function get_group_name($group_id)
2132  {
2133      global $db, $user;
2134  
2135      $sql = 'SELECT group_name, group_type
2136          FROM ' . GROUPS_TABLE . '
2137          WHERE group_id = ' . (int) $group_id;
2138      $result = $db->sql_query($sql);
2139      $row = $db->sql_fetchrow($result);
2140      $db->sql_freeresult($result);
2141  
2142      if (!$row)
2143      {
2144          return '';
2145      }
2146  
2147      return ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'];
2148  }
2149  
2150  /**
2151  * Obtain either the members of a specified group, the groups the specified user is subscribed to
2152  * or checking if a specified user is in a specified group
2153  *
2154  * Note: Never use this more than once... first group your users/groups
2155  */
2156  function group_memberships($group_id_ary = false, $user_id_ary = false, $return_bool = false)
2157  {
2158      global $db;
2159  
2160      if (!$group_id_ary && !$user_id_ary)
2161      {
2162          return true;
2163      }
2164  
2165      if ($user_id_ary)
2166      {
2167          $user_id_ary = (!is_array($user_id_ary)) ? array($user_id_ary) : $user_id_ary;
2168      }
2169  
2170      if ($group_id_ary)
2171      {
2172          $group_id_ary = (!is_array($group_id_ary)) ? array($group_id_ary) : $group_id_ary;
2173      }
2174  
2175      $sql = 'SELECT ug.*, u.username, u.user_email
2176          FROM ' . USER_GROUP_TABLE . ' ug, ' . USERS_TABLE . ' u
2177          WHERE ug.user_id = u.user_id AND ';
2178  
2179      if ($group_id_ary)
2180      {
2181          $sql .= ' ' . $db->sql_in_set('ug.group_id', $group_id_ary);
2182      }
2183  
2184      if ($user_id_ary)
2185      {
2186          $sql .= ($group_id_ary) ? ' AND ' : ' ';
2187          $sql .= $db->sql_in_set('ug.user_id', $user_id_ary);
2188      }
2189  
2190      $result = ($return_bool) ? $db->sql_query_limit($sql, 1) : $db->sql_query($sql);
2191  
2192      $row = $db->sql_fetchrow($result);
2193  
2194      if ($return_bool)
2195      {
2196          $db->sql_freeresult($result);
2197          return ($row) ? true : false;
2198      }
2199  
2200      if (!$row)
2201      {
2202          return false;
2203      }
2204  
2205      $return = array();
2206  
2207      do
2208      {
2209          $return[] = $row;
2210      }
2211      while ($row = $db->sql_fetchrow($result));
2212  
2213      $db->sql_freeresult($result);
2214  
2215      return $return;
2216  }
2217  
2218  /**
2219  * Re-cache moderators and foes if group has a_ or m_ permissions
2220  */
2221  function group_update_listings($group_id)
2222  {
2223      global $auth;
2224  
2225      $hold_ary = $auth->acl_group_raw_data($group_id, array('a_', 'm_'));
2226  
2227      if (!sizeof($hold_ary))
2228      {
2229          return;
2230      }
2231  
2232      $mod_permissions = $admin_permissions = false;
2233  
2234      foreach ($hold_ary as $g_id => $forum_ary)
2235      {
2236          foreach ($forum_ary as $forum_id => $auth_ary)
2237          {
2238              foreach ($auth_ary as $auth_option => $setting)
2239              {
2240                  if ($mod_permissions && $admin_permissions)
2241                  {
2242                      break 3;
2243                  }
2244  
2245                  if ($setting != ACL_YES)
2246                  {
2247                      continue;
2248                  }
2249  
2250                  if ($auth_option == 'm_')
2251                  {
2252                      $mod_permissions = true;
2253                  }
2254  
2255                  if ($auth_option == 'a_')
2256                  {
2257                      $admin_permissions = true;
2258                  }
2259              }
2260          }
2261      }
2262  
2263      if ($mod_permissions)
2264      {
2265          if (!function_exists('cache_moderators'))
2266          {
2267              include($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
2268          }
2269          cache_moderators();
2270      }
2271  
2272      if ($mod_permissions || $admin_permissions)
2273      {
2274          update_foes();
2275      }
2276  }
2277  
2278  ?>


Generated: Wed Nov 22 00:35:05 2006 Cross-referenced by PHPXref 0.6