Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

memberlist.php

Zuletzt modifiziert: 02.04.2025, 15:01 - Dateigröße: 61.63 KiB


0001  <?php
0002  /**
0003  *
0004  * This file is part of the phpBB Forum Software package.
0005  *
0006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
0007  * @license GNU General Public License, version 2 (GPL-2.0)
0008  *
0009  * For full copyright and license information, please see
0010  * the docs/CREDITS.txt file.
0011  *
0012  */
0013   
0014  /**
0015  * @ignore
0016  */
0017  define('IN_PHPBB', true);
0018  $phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
0019  $phpEx = substr(strrchr(__FILE__, '.'), 1);
0020  include($phpbb_root_path . 'common.' . $phpEx);
0021  include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
0022   
0023  $mode = $request->variable('mode', '');
0024   
0025  if ($mode === 'contactadmin')
0026  {
0027      define('SKIP_CHECK_BAN', true);
0028      define('SKIP_CHECK_DISABLED', true);
0029  }
0030   
0031  // Start session management
0032  $user->session_begin();
0033  $auth->acl($user->data);
0034  $user->setup(array('memberlist', 'groups'));
0035   
0036  // Setting a variable to let the style designer know where he is...
0037  $template->assign_var('S_IN_MEMBERLIST', true);
0038   
0039  // Grab data
0040  $action        = $request->variable('action', '');
0041  $user_id    = $request->variable('u', ANONYMOUS);
0042  $username    = $request->variable('un', '', true);
0043  $group_id    = $request->variable('g', 0);
0044  $topic_id    = $request->variable('t', 0);
0045   
0046  // Redirect when old mode is used
0047  if ($mode == 'leaders')
0048  {
0049      send_status_line(301, 'Moved Permanently');
0050      redirect(append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=team'));
0051  }
0052   
0053  // Check our mode...
0054  if (!in_array($mode, array('', 'group', 'viewprofile', 'email', 'contact', 'contactadmin', 'searchuser', 'team', 'livesearch')))
0055  {
0056      trigger_error('NO_MODE');
0057  }
0058   
0059  switch ($mode)
0060  {
0061      case 'email':
0062      case 'contactadmin':
0063      break;
0064   
0065      case 'livesearch':
0066          if (!$config['allow_live_searches'])
0067          {
0068              trigger_error('LIVE_SEARCHES_NOT_ALLOWED');
0069          }
0070          // No break
0071   
0072      default:
0073          // Can this user view profiles/memberlist?
0074          if (!$auth->acl_gets('u_viewprofile', 'a_user', 'a_useradd', 'a_userdel'))
0075          {
0076              if ($user->data['user_id'] != ANONYMOUS)
0077              {
0078                  send_status_line(403, 'Forbidden');
0079                  trigger_error('NO_VIEW_USERS');
0080              }
0081   
0082              login_box('', ((isset($user->lang['LOGIN_EXPLAIN_' . strtoupper($mode)])) ? $user->lang['LOGIN_EXPLAIN_' . strtoupper($mode)] : $user->lang['LOGIN_EXPLAIN_MEMBERLIST']));
0083          }
0084      break;
0085  }
0086   
0087  /** @var \phpbb\group\helper $group_helper */
0088  $group_helper = $phpbb_container->get('group_helper');
0089   
0090  $start    = $request->variable('start', 0);
0091  $submit = (isset($_POST['submit'])) ? true : false;
0092   
0093  $default_key = 'c';
0094  $sort_key = $request->variable('sk', $default_key);
0095  $sort_dir = $request->variable('sd', 'a');
0096   
0097  $user_types = array(USER_NORMAL, USER_FOUNDER);
0098  if ($auth->acl_get('a_user'))
0099  {
0100      $user_types[] = USER_INACTIVE;
0101  }
0102   
0103  // What do you want to do today? ... oops, I think that line is taken ...
0104  switch ($mode)
0105  {
0106      case 'team':
0107          // Display a listing of board admins, moderators
0108          if (!function_exists('user_get_id_name'))
0109          {
0110              include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
0111          }
0112   
0113          $page_title = $user->lang['THE_TEAM'];
0114          $template_html = 'memberlist_team.html';
0115   
0116          $sql = 'SELECT *
0117              FROM ' . TEAMPAGE_TABLE . '
0118              ORDER BY teampage_position ASC';
0119          $result = $db->sql_query($sql, 3600);
0120          $teampage_data = $db->sql_fetchrowset($result);
0121          $db->sql_freeresult($result);
0122   
0123          $sql_ary = array(
0124              'SELECT'    => 'g.group_id, g.group_name, g.group_colour, g.group_type, ug.user_id as ug_user_id, t.teampage_id',
0125   
0126              'FROM'        => array(GROUPS_TABLE => 'g'),
0127   
0128              'LEFT_JOIN'    => array(
0129                  array(
0130                      'FROM'    => array(TEAMPAGE_TABLE => 't'),
0131                      'ON'    => 't.group_id = g.group_id',
0132                  ),
0133                  array(
0134                      'FROM'    => array(USER_GROUP_TABLE => 'ug'),
0135                      'ON'    => 'ug.group_id = g.group_id AND ug.user_pending = 0 AND ug.user_id = ' . (int) $user->data['user_id'],
0136                  ),
0137              ),
0138          );
0139   
0140          $result = $db->sql_query($db->sql_build_query('SELECT', $sql_ary));
0141   
0142          $group_ids = $groups_ary = array();
0143          while ($row = $db->sql_fetchrow($result))
0144          {
0145              if ($row['group_type'] == GROUP_HIDDEN && !$auth->acl_gets('a_group', 'a_groupadd', 'a_groupdel') && $row['ug_user_id'] != $user->data['user_id'])
0146              {
0147                  $row['group_name'] = $user->lang['GROUP_UNDISCLOSED'];
0148                  $row['u_group'] = '';
0149              }
0150              else
0151              {
0152                  $row['group_name'] = $group_helper->get_name($row['group_name']);
0153                  $row['u_group'] = append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=group&amp;g=' . $row['group_id']);
0154              }
0155   
0156              if ($row['teampage_id'])
0157              {
0158                  // Only put groups into the array we want to display.
0159                  // We are fetching all groups, to ensure we got all data for default groups.
0160                  $group_ids[] = (int) $row['group_id'];
0161              }
0162              $groups_ary[(int) $row['group_id']] = $row;
0163          }
0164          $db->sql_freeresult($result);
0165   
0166          $sql_ary = array(
0167              'SELECT'    => 'u.user_id, u.group_id as default_group, u.username, u.username_clean, u.user_colour, u.user_type, u.user_rank, u.user_posts, u.user_allow_pm, g.group_id',
0168   
0169              'FROM'        => array(
0170                  USER_GROUP_TABLE => 'ug',
0171              ),
0172   
0173              'LEFT_JOIN'    => array(
0174                  array(
0175                      'FROM'    => array(USERS_TABLE => 'u'),
0176                      'ON'    => 'ug.user_id = u.user_id',
0177                  ),
0178                  array(
0179                      'FROM'    => array(GROUPS_TABLE => 'g'),
0180                      'ON'    => 'ug.group_id = g.group_id',
0181                  ),
0182              ),
0183   
0184              'WHERE'        => $db->sql_in_set('g.group_id', $group_ids, false, true) . ' AND ug.user_pending = 0',
0185   
0186              'ORDER_BY'    => 'u.username_clean ASC',
0187          );
0188   
0189          /**
0190           * Modify the query used to get the users for the team page
0191           *
0192           * @event core.memberlist_team_modify_query
0193           * @var array    sql_ary            Array containing the query
0194           * @var array    group_ids        Array of group ids
0195           * @var array    teampage_data    The teampage data
0196           * @since 3.1.3-RC1
0197           */
0198          $vars = array(
0199              'sql_ary',
0200              'group_ids',
0201              'teampage_data',
0202          );
0203          extract($phpbb_dispatcher->trigger_event('core.memberlist_team_modify_query', compact($vars)));
0204   
0205          $result = $db->sql_query($db->sql_build_query('SELECT', $sql_ary));
0206   
0207          $user_ary = $user_ids = $group_users = array();
0208          while ($row = $db->sql_fetchrow($result))
0209          {
0210              $row['forums'] = '';
0211              $row['forums_ary'] = array();
0212              $user_ary[(int) $row['user_id']] = $row;
0213              $user_ids[] = (int) $row['user_id'];
0214              $group_users[(int) $row['group_id']][] = (int) $row['user_id'];
0215          }
0216          $db->sql_freeresult($result);
0217   
0218          $user_ids = array_unique($user_ids);
0219   
0220          if (!empty($user_ids) && $config['teampage_forums'])
0221          {
0222              $template->assign_var('S_DISPLAY_MODERATOR_FORUMS', true);
0223              // Get all moderators
0224              $perm_ary = $auth->acl_get_list($user_ids, array('m_'), false);
0225   
0226              foreach ($perm_ary as $forum_id => $forum_ary)
0227              {
0228                  foreach ($forum_ary as $auth_option => $id_ary)
0229                  {
0230                      foreach ($id_ary as $id)
0231                      {
0232                          if (!$forum_id)
0233                          {
0234                              $user_ary[$id]['forums'] = $user->lang['ALL_FORUMS'];
0235                          }
0236                          else
0237                          {
0238                              $user_ary[$id]['forums_ary'][] = $forum_id;
0239                          }
0240                      }
0241                  }
0242              }
0243   
0244              $sql = 'SELECT forum_id, forum_name
0245                  FROM ' . FORUMS_TABLE;
0246              $result = $db->sql_query($sql);
0247   
0248              $forums = array();
0249              while ($row = $db->sql_fetchrow($result))
0250              {
0251                  $forums[$row['forum_id']] = $row['forum_name'];
0252              }
0253              $db->sql_freeresult($result);
0254   
0255              foreach ($user_ary as $user_id => $user_data)
0256              {
0257                  if (!$user_data['forums'])
0258                  {
0259                      foreach ($user_data['forums_ary'] as $forum_id)
0260                      {
0261                          $user_ary[$user_id]['forums_options'] = true;
0262                          if (isset($forums[$forum_id]))
0263                          {
0264                              if ($auth->acl_get('f_list', $forum_id))
0265                              {
0266                                  $user_ary[$user_id]['forums'] .= '<option value="">' . $forums[$forum_id] . '</option>';
0267                              }
0268                          }
0269                      }
0270                  }
0271              }
0272          }
0273   
0274          $parent_team = 0;
0275          foreach ($teampage_data as $team_data)
0276          {
0277              // If this team entry has no group, it's a category
0278              if (!$team_data['group_id'])
0279              {
0280                  $template->assign_block_vars('group', array(
0281                      'GROUP_NAME'  => $team_data['teampage_name'],
0282                  ));
0283   
0284                  $parent_team = (int) $team_data['teampage_id'];
0285                  continue;
0286              }
0287   
0288              $group_data = $groups_ary[(int) $team_data['group_id']];
0289              $group_id = (int) $team_data['group_id'];
0290   
0291              if (!$team_data['teampage_parent'])
0292              {
0293                  // If the group does not have a parent category, we display the groupname as category
0294                  $template->assign_block_vars('group', array(
0295                      'GROUP_NAME'    => $group_data['group_name'],
0296                      'GROUP_COLOR'    => $group_data['group_colour'],
0297                      'U_GROUP'        => $group_data['u_group'],
0298                  ));
0299              }
0300   
0301              // Display group members.
0302              if (!empty($group_users[$group_id]))
0303              {
0304                  foreach ($group_users[$group_id] as $user_id)
0305                  {
0306                      if (isset($user_ary[$user_id]))
0307                      {
0308                          $row = $user_ary[$user_id];
0309                          if ($config['teampage_memberships'] == 1 && ($group_id != $groups_ary[$row['default_group']]['group_id']) && $groups_ary[$row['default_group']]['teampage_id'])
0310                          {
0311                              // Display users in their primary group, instead of the first group, when it is displayed on the teampage.
0312                              continue;
0313                          }
0314   
0315                          $user_rank_data = phpbb_get_user_rank($row, (($row['user_id'] == ANONYMOUS) ? false : $row['user_posts']));
0316   
0317                          $template_vars = array(
0318                              'USER_ID'        => $row['user_id'],
0319                              'FORUMS'        => $row['forums'],
0320                              'FORUM_OPTIONS'    => (isset($row['forums_options'])) ? true : false,
0321                              'RANK_TITLE'    => $user_rank_data['title'],
0322   
0323                              'GROUP_NAME'    => $groups_ary[$row['default_group']]['group_name'],
0324                              'GROUP_COLOR'    => $groups_ary[$row['default_group']]['group_colour'],
0325                              'U_GROUP'        => $groups_ary[$row['default_group']]['u_group'],
0326   
0327                              'RANK_IMG'        => $user_rank_data['img'],
0328                              'RANK_IMG_SRC'    => $user_rank_data['img_src'],
0329   
0330                              'S_INACTIVE'    => $row['user_type'] == USER_INACTIVE,
0331   
0332                              'U_PM'            => ($config['allow_privmsg'] && $auth->acl_get('u_sendpm') && ($row['user_allow_pm'] || $auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_'))) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;mode=compose&amp;u=' . $row['user_id']) : '',
0333   
0334                              'USERNAME_FULL'        => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']),
0335                              'USERNAME'            => get_username_string('username', $row['user_id'], $row['username'], $row['user_colour']),
0336                              'USER_COLOR'        => get_username_string('colour', $row['user_id'], $row['username'], $row['user_colour']),
0337                              'U_VIEW_PROFILE'    => get_username_string('profile', $row['user_id'], $row['username'], $row['user_colour']),
0338                          );
0339   
0340                          /**
0341                           * Modify the template vars for displaying the user in the groups on the teampage
0342                           *
0343                           * @event core.memberlist_team_modify_template_vars
0344                           * @var array    template_vars        Array containing the query
0345                           * @var array    row                    Array containing the action user row
0346                           * @var array    groups_ary            Array of groups with all users that should be displayed
0347                           * @since 3.1.3-RC1
0348                           */
0349                          $vars = array(
0350                              'template_vars',
0351                              'row',
0352                              'groups_ary',
0353                          );
0354                          extract($phpbb_dispatcher->trigger_event('core.memberlist_team_modify_template_vars', compact($vars)));
0355   
0356                          $template->assign_block_vars('group.user', $template_vars);
0357   
0358                          if ($config['teampage_memberships'] != 2)
0359                          {
0360                              unset($user_ary[$user_id]);
0361                          }
0362                      }
0363                  }
0364              }
0365          }
0366   
0367          $template->assign_block_vars('navlinks', array(
0368              'BREADCRUMB_NAME'    => $page_title,
0369              'U_BREADCRUMB'        => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=team"),
0370          ));
0371   
0372          $template->assign_vars(array(
0373              'PM_IMG'        => $user->img('icon_contact_pm', $user->lang['SEND_PRIVATE_MESSAGE']))
0374          );
0375      break;
0376   
0377      case 'contact':
0378   
0379          $page_title = $user->lang['IM_USER'];
0380          $template_html = 'memberlist_im.html';
0381   
0382          if (!$auth->acl_get('u_sendim'))
0383          {
0384              send_status_line(403, 'Forbidden');
0385              trigger_error('NOT_AUTHORISED');
0386          }
0387   
0388          $presence_img = '';
0389          switch ($action)
0390          {
0391              case 'jabber':
0392                  $lang = 'JABBER';
0393                  $sql_field = 'user_jabber';
0394                  $s_select = (@extension_loaded('xml') && $config['jab_enable']) ? 'S_SEND_JABBER' : 'S_NO_SEND_JABBER';
0395                  $s_action = append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=contact&amp;action=$action&amp;u=$user_id");
0396              break;
0397   
0398              default:
0399                  trigger_error('NO_MODE', E_USER_ERROR);
0400              break;
0401          }
0402   
0403          // Grab relevant data
0404          $sql = "SELECT user_id, username, user_email, user_lang, $sql_field
0405              FROM " . USERS_TABLE . "
0406              WHERE user_id = $user_id
0407                  AND user_type IN (" . USER_NORMAL . ', ' . USER_FOUNDER . ')';
0408          $result = $db->sql_query($sql);
0409          $row = $db->sql_fetchrow($result);
0410          $db->sql_freeresult($result);
0411   
0412          if (!$row)
0413          {
0414              trigger_error('NO_USER');
0415          }
0416          else if (empty($row[$sql_field]))
0417          {
0418              trigger_error('IM_NO_DATA');
0419          }
0420   
0421          // Post data grab actions
0422          switch ($action)
0423          {
0424              case 'jabber':
0425                  add_form_key('memberlist_messaging');
0426   
0427                  if ($submit && @extension_loaded('xml') && $config['jab_enable'])
0428                  {
0429                      if (check_form_key('memberlist_messaging'))
0430                      {
0431   
0432                          include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
0433   
0434                          $subject = sprintf($user->lang['IM_JABBER_SUBJECT'], $user->data['username'], $config['server_name']);
0435                          $message = $request->variable('message', '', true);
0436   
0437                          if (empty($message))
0438                          {
0439                              trigger_error('EMPTY_MESSAGE_IM');
0440                          }
0441   
0442                          $messenger = new messenger(false);
0443   
0444                          $messenger->template('profile_send_im', $row['user_lang']);
0445                          $messenger->subject(html_entity_decode($subject, ENT_COMPAT));
0446   
0447                          $messenger->replyto($user->data['user_email']);
0448                          $messenger->set_addresses($row);
0449   
0450                          $messenger->assign_vars(array(
0451                              'BOARD_CONTACT'    => phpbb_get_board_contact($config, $phpEx),
0452                              'FROM_USERNAME'    => html_entity_decode($user->data['username'], ENT_COMPAT),
0453                              'TO_USERNAME'    => html_entity_decode($row['username'], ENT_COMPAT),
0454                              'MESSAGE'        => html_entity_decode($message, ENT_COMPAT))
0455                          );
0456   
0457                          $messenger->send(NOTIFY_IM);
0458   
0459                          $s_select = 'S_SENT_JABBER';
0460                      }
0461                      else
0462                      {
0463                          trigger_error('FORM_INVALID');
0464                      }
0465                  }
0466              break;
0467          }
0468   
0469          $template->assign_block_vars('navlinks', array(
0470              'BREADCRUMB_NAME'    => $page_title,
0471              'U_BREADCRUMB'        => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=contact&amp;action=$action&amp;u=$user_id"),
0472          ));
0473   
0474          // Send vars to the template
0475          $template->assign_vars(array(
0476              'IM_CONTACT'    => $row[$sql_field],
0477              'A_IM_CONTACT'    => addslashes($row[$sql_field]),
0478   
0479              'USERNAME'        => $row['username'],
0480              'CONTACT_NAME'    => $row[$sql_field],
0481              'SITENAME'        => $config['sitename'],
0482   
0483              'PRESENCE_IMG'        => $presence_img,
0484   
0485              'L_SEND_IM_EXPLAIN'    => $user->lang['IM_' . $lang],
0486              'L_IM_SENT_JABBER'    => sprintf($user->lang['IM_SENT_JABBER'], $row['username']),
0487   
0488              $s_select            => true,
0489              'S_IM_ACTION'        => $s_action)
0490          );
0491   
0492      break;
0493   
0494      case 'viewprofile':
0495          // Display a profile
0496          if ($user_id == ANONYMOUS && !$username)
0497          {
0498              trigger_error('NO_USER');
0499          }
0500   
0501          // Get user...
0502          $sql_array = array(
0503              'SELECT'    => 'u.*',
0504              'FROM'        => array(
0505                  USERS_TABLE        => 'u'
0506              ),
0507              'WHERE'        => (($username) ? "u.username_clean = '" . $db->sql_escape(utf8_clean_string($username)) . "'" : "u.user_id = $user_id"),
0508          );
0509   
0510          /**
0511           * Modify user data SQL before member profile row is created
0512           *
0513           * @event core.memberlist_modify_viewprofile_sql
0514           * @var int        user_id                The user ID
0515           * @var string    username            The username
0516           * @var array    sql_array            Array containing the main query
0517           * @since 3.2.6-RC1
0518           */
0519          $vars = array(
0520              'user_id',
0521              'username',
0522              'sql_array',
0523          );
0524          extract($phpbb_dispatcher->trigger_event('core.memberlist_modify_viewprofile_sql', compact($vars)));
0525   
0526          $sql = $db->sql_build_query('SELECT', $sql_array);
0527          $result = $db->sql_query($sql);
0528          $member = $db->sql_fetchrow($result);
0529          $db->sql_freeresult($result);
0530   
0531          if (!$member)
0532          {
0533              trigger_error('NO_USER');
0534          }
0535   
0536          // a_user admins and founder are able to view inactive users and bots to be able to manage them more easily
0537          // Normal users are able to see at least users having only changed their profile settings but not yet reactivated.
0538          if (!$auth->acl_get('a_user') && $user->data['user_type'] != USER_FOUNDER)
0539          {
0540              if ($member['user_type'] == USER_IGNORE)
0541              {
0542                  trigger_error('NO_USER');
0543              }
0544              else if ($member['user_type'] == USER_INACTIVE && $member['user_inactive_reason'] != INACTIVE_PROFILE)
0545              {
0546                  trigger_error('NO_USER');
0547              }
0548          }
0549   
0550          $user_id = (int) $member['user_id'];
0551   
0552          // Get group memberships
0553          // Also get visiting user's groups to determine hidden group memberships if necessary.
0554          $auth_hidden_groups = ($user_id === (int) $user->data['user_id'] || $auth->acl_gets('a_group', 'a_groupadd', 'a_groupdel')) ? true : false;
0555          $sql_uid_ary = ($auth_hidden_groups) ? array($user_id) : array($user_id, (int) $user->data['user_id']);
0556   
0557          // Do the SQL thang
0558          $sql_ary = [
0559              'SELECT'    => 'g.group_id, g.group_name, g.group_type, ug.user_id',
0560   
0561              'FROM'        => [
0562                  GROUPS_TABLE => 'g',
0563              ],
0564   
0565              'LEFT_JOIN' => [
0566                  [
0567                      'FROM' => [USER_GROUP_TABLE => 'ug'],
0568                      'ON'   => 'g.group_id = ug.group_id',
0569                  ],
0570              ],
0571   
0572              'WHERE'        => $db->sql_in_set('ug.user_id', $sql_uid_ary) . '
0573                  AND ug.user_pending = 0',
0574          ];
0575   
0576          /**
0577          * Modify the query used to get the group data
0578          *
0579          * @event core.modify_memberlist_viewprofile_group_sql
0580          * @var array    sql_ary            Array containing the query
0581          * @since 3.2.6-RC1
0582          */
0583          $vars = array(
0584              'sql_ary',
0585          );
0586          extract($phpbb_dispatcher->trigger_event('core.modify_memberlist_viewprofile_group_sql', compact($vars)));
0587   
0588          $result = $db->sql_query($db->sql_build_query('SELECT', $sql_ary));
0589   
0590          // Divide data into profile data and current user data
0591          $profile_groups = $user_groups = array();
0592          while ($row = $db->sql_fetchrow($result))
0593          {
0594              $row['user_id'] = (int) $row['user_id'];
0595              $row['group_id'] = (int) $row['group_id'];
0596   
0597              if ($row['user_id'] == $user_id)
0598              {
0599                  $profile_groups[] = $row;
0600              }
0601              else
0602              {
0603                  $user_groups[$row['group_id']] = $row['group_id'];
0604              }
0605          }
0606          $db->sql_freeresult($result);
0607   
0608          // Filter out hidden groups and sort groups by name
0609          $group_data = $group_sort = array();
0610          foreach ($profile_groups as $row)
0611          {
0612              if (!$auth_hidden_groups && $row['group_type'] == GROUP_HIDDEN && !isset($user_groups[$row['group_id']]))
0613              {
0614                  // Skip over hidden groups the user cannot see
0615                  continue;
0616              }
0617   
0618              $row['group_name'] = $group_helper->get_name($row['group_name']);
0619   
0620              $group_sort[$row['group_id']] = utf8_clean_string($row['group_name']);
0621              $group_data[$row['group_id']] = $row;
0622          }
0623          unset($profile_groups);
0624          unset($user_groups);
0625          asort($group_sort);
0626   
0627          /**
0628          * Modify group data before options is created and data is unset
0629          *
0630          * @event core.modify_memberlist_viewprofile_group_data
0631          * @var array    group_data            Array containing the group data
0632          * @var array    group_sort            Array containing the sorted group data
0633          * @since 3.2.6-RC1
0634          */
0635          $vars = array(
0636              'group_data',
0637              'group_sort',
0638          );
0639          extract($phpbb_dispatcher->trigger_event('core.modify_memberlist_viewprofile_group_data', compact($vars)));
0640   
0641          $group_options = '';
0642          foreach ($group_sort as $group_id => $null)
0643          {
0644              $row = $group_data[$group_id];
0645   
0646              $group_options .= '<option value="' . $row['group_id'] . '"' . (($row['group_id'] == $member['group_id']) ? ' selected="selected"' : '') . '>' . $row['group_name'] . '</option>';
0647          }
0648          unset($group_data);
0649          unset($group_sort);
0650   
0651          // What colour is the zebra
0652          $sql = 'SELECT friend, foe
0653              FROM ' . ZEBRA_TABLE . "
0654              WHERE zebra_id = $user_id
0655                  AND user_id = {$user->data['user_id']}";
0656          $result = $db->sql_query($sql);
0657          $row = $db->sql_fetchrow($result);
0658   
0659          $foe = $row ? (bool) $row['foe'] : false;
0660          $friend = $row ? (bool) $row['friend'] : false;
0661   
0662          $db->sql_freeresult($result);
0663   
0664          if ($config['load_onlinetrack'])
0665          {
0666              $sql = 'SELECT MAX(session_time) AS session_time, MIN(session_viewonline) AS session_viewonline
0667                  FROM ' . SESSIONS_TABLE . "
0668                  WHERE session_user_id = $user_id";
0669              $result = $db->sql_query($sql);
0670              $row = $db->sql_fetchrow($result);
0671              $db->sql_freeresult($result);
0672   
0673              $member['session_time'] = (isset($row['session_time'])) ? $row['session_time'] : 0;
0674              $member['session_viewonline'] = (isset($row['session_viewonline'])) ? $row['session_viewonline'] : 0;
0675              unset($row);
0676          }
0677   
0678          if ($config['load_user_activity'])
0679          {
0680              display_user_activity($member);
0681          }
0682   
0683          // Do the relevant calculations
0684          $memberdays = max(1, round((time() - $member['user_regdate']) / 86400));
0685          $posts_per_day = $member['user_posts'] / $memberdays;
0686          $percentage = ($config['num_posts']) ? min(100, ($member['user_posts'] / $config['num_posts']) * 100) : 0;
0687   
0688   
0689          if ($member['user_sig'])
0690          {
0691              $parse_flags = ($member['user_sig_bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0) | OPTION_FLAG_SMILIES;
0692              $member['user_sig'] = generate_text_for_display($member['user_sig'], $member['user_sig_bbcode_uid'], $member['user_sig_bbcode_bitfield'], $parse_flags, true);
0693          }
0694   
0695          // We need to check if the modules 'zebra' ('friends' & 'foes' mode),  'notes' ('user_notes' mode) and  'warn' ('warn_user' mode) are accessible to decide if we can display appropriate links
0696          $zebra_enabled = $friends_enabled = $foes_enabled = $user_notes_enabled = $warn_user_enabled = false;
0697   
0698          // Only check if the user is logged in
0699          if ($user->data['is_registered'])
0700          {
0701              if (!class_exists('p_master'))
0702              {
0703                  include($phpbb_root_path . 'includes/functions_module.' . $phpEx);
0704              }
0705              $module = new p_master();
0706   
0707              $module->list_modules('ucp');
0708              $module->list_modules('mcp');
0709   
0710              $user_notes_enabled = ($module->loaded('mcp_notes', 'user_notes')) ? true : false;
0711              $warn_user_enabled = ($module->loaded('mcp_warn', 'warn_user')) ? true : false;
0712              $zebra_enabled = ($module->loaded('ucp_zebra')) ? true : false;
0713              $friends_enabled = ($module->loaded('ucp_zebra', 'friends')) ? true : false;
0714              $foes_enabled = ($module->loaded('ucp_zebra', 'foes')) ? true : false;
0715   
0716              unset($module);
0717          }
0718   
0719          // Custom Profile Fields
0720          $profile_fields = array();
0721          if ($config['load_cpf_viewprofile'])
0722          {
0723              /* @var $cp \phpbb\profilefields\manager */
0724              $cp = $phpbb_container->get('profilefields.manager');
0725              $profile_fields = $cp->grab_profile_fields_data($user_id);
0726              $profile_fields = (isset($profile_fields[$user_id])) ? $cp->generate_profile_fields_template_data($profile_fields[$user_id]) : array();
0727          }
0728   
0729          /**
0730          * Modify user data before we display the profile
0731          *
0732          * @event core.memberlist_view_profile
0733          * @var    array    member                    Array with user's data
0734          * @var    bool    user_notes_enabled        Is the mcp user notes module enabled?
0735          * @var    bool    warn_user_enabled        Is the mcp warnings module enabled?
0736          * @var    bool    zebra_enabled            Is the ucp zebra module enabled?
0737          * @var    bool    friends_enabled            Is the ucp friends module enabled?
0738          * @var    bool    foes_enabled            Is the ucp foes module enabled?
0739          * @var    bool    friend                    Is the user friend?
0740          * @var    bool    foe                        Is the user foe?
0741          * @var    array    profile_fields            Array with user's profile field data
0742          * @since 3.1.0-a1
0743          * @changed 3.1.0-b2 Added friend and foe status
0744          * @changed 3.1.0-b3 Added profile fields data
0745          */
0746          $vars = array(
0747              'member',
0748              'user_notes_enabled',
0749              'warn_user_enabled',
0750              'zebra_enabled',
0751              'friends_enabled',
0752              'foes_enabled',
0753              'friend',
0754              'foe',
0755              'profile_fields',
0756          );
0757          extract($phpbb_dispatcher->trigger_event('core.memberlist_view_profile', compact($vars)));
0758   
0759          $template->assign_vars(phpbb_show_profile($member, $user_notes_enabled, $warn_user_enabled));
0760   
0761          // If the user has m_approve permission or a_user permission, then list then display unapproved posts
0762          if ($auth->acl_getf_global('m_approve') || $auth->acl_get('a_user'))
0763          {
0764              $sql = 'SELECT COUNT(post_id) as posts_in_queue
0765                  FROM ' . POSTS_TABLE . '
0766                  WHERE poster_id = ' . $user_id . '
0767                      AND ' . $db->sql_in_set('post_visibility', array(ITEM_UNAPPROVED, ITEM_REAPPROVE));
0768              $result = $db->sql_query($sql);
0769              $member['posts_in_queue'] = (int) $db->sql_fetchfield('posts_in_queue');
0770              $db->sql_freeresult($result);
0771          }
0772          else
0773          {
0774              $member['posts_in_queue'] = 0;
0775          }
0776   
0777          // Define the main array of vars to assign to memberlist_view.html
0778          $template_ary = array(
0779              'L_POSTS_IN_QUEUE'            => $user->lang('NUM_POSTS_IN_QUEUE', $member['posts_in_queue']),
0780   
0781              'POSTS_DAY'                    => $user->lang('POST_DAY', $posts_per_day),
0782              'POSTS_PCT'                    => $user->lang('POST_PCT', $percentage),
0783   
0784              'SIGNATURE'                    => $member['user_sig'],
0785              'POSTS_IN_QUEUE'            => $member['posts_in_queue'],
0786   
0787              'PM_IMG'                    => $user->img('icon_contact_pm', $user->lang['SEND_PRIVATE_MESSAGE']),
0788              'L_SEND_EMAIL_USER'            => $user->lang('SEND_EMAIL_USER', $member['username']),
0789              'EMAIL_IMG'                    => $user->img('icon_contact_email', $user->lang['EMAIL']),
0790              'JABBER_IMG'                => $user->img('icon_contact_jabber', $user->lang['JABBER']),
0791              'SEARCH_IMG'                => $user->img('icon_user_search', $user->lang['SEARCH']),
0792   
0793              'S_PROFILE_ACTION'            => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=group'),
0794              'S_GROUP_OPTIONS'            => $group_options,
0795              'S_CUSTOM_FIELDS'            => (isset($profile_fields['row']) && count($profile_fields['row'])) ? true : false,
0796   
0797              'U_USER_ADMIN'                => ($auth->acl_get('a_user')) ? append_sid("{$phpbb_admin_path}index.$phpEx", 'i=users&amp;mode=overview&amp;u=' . $user_id, true, $user->session_id) : '',
0798              'U_USER_BAN'                => ($auth->acl_get('m_ban') && $user_id != $user->data['user_id']) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=ban&amp;mode=user&amp;u=' . $user_id, true, $user->session_id) : '',
0799              'U_MCP_QUEUE'                => ($auth->acl_getf_global('m_approve')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue', true, $user->session_id) : '',
0800   
0801              'U_SWITCH_PERMISSIONS'        => ($auth->acl_get('a_switchperm') && $user->data['user_id'] != $user_id) ? append_sid("{$phpbb_root_path}ucp.$phpEx", "mode=switch_perm&amp;u={$user_id}&amp;hash=" . generate_link_hash('switchperm')) : '',
0802              'U_EDIT_SELF'                => ($user_id == $user->data['user_id'] && $auth->acl_get('u_chgprofileinfo')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_profile&amp;mode=profile_info') : '',
0803   
0804              'S_USER_NOTES'                => ($user_notes_enabled) ? true : false,
0805              'S_WARN_USER'                => ($warn_user_enabled) ? true : false,
0806              'S_ZEBRA'                    => ($user->data['user_id'] != $user_id && $user->data['is_registered'] && $zebra_enabled) ? true : false,
0807              'U_ADD_FRIEND'                => (!$friend && !$foe && $friends_enabled) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=zebra&amp;add=' . urlencode(html_entity_decode($member['username'], ENT_COMPAT))) : '',
0808              'U_ADD_FOE'                    => (!$friend && !$foe && $foes_enabled) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=zebra&amp;mode=foes&amp;add=' . urlencode(html_entity_decode($member['username'], ENT_COMPAT))) : '',
0809              'U_REMOVE_FRIEND'            => ($friend && $friends_enabled) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=zebra&amp;remove=1&amp;usernames[]=' . $user_id) : '',
0810              'U_REMOVE_FOE'                => ($foe && $foes_enabled) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=zebra&amp;remove=1&amp;mode=foes&amp;usernames[]=' . $user_id) : '',
0811   
0812              'U_CANONICAL'                => generate_board_url() . '/' . append_sid("memberlist.$phpEx", 'mode=viewprofile&amp;u=' . $user_id, true, ''),
0813          );
0814   
0815          /**
0816          * Modify user's template vars before we display the profile
0817          *
0818          * @event core.memberlist_modify_view_profile_template_vars
0819          * @var    array    template_ary            Array with user's template vars
0820          * @var    int        user_id                    The user ID
0821          * @var    bool    user_notes_enabled        Is the mcp user notes module enabled?
0822          * @var    bool    warn_user_enabled        Is the mcp warnings module enabled?
0823          * @var    bool    friends_enabled            Is the ucp friends module enabled?
0824          * @var    bool    foes_enabled            Is the ucp foes module enabled?
0825          * @var    bool    friend                    Is the user friend?
0826          * @var    bool    foe                        Is the user foe?
0827          * @since 3.2.6-RC1
0828          * @changed 3.3.15-RC1 Added vars user_id, user_notes_enabled, warn_user_enabled, friend, friends_enabled, foe, foes_enabled
0829          */
0830          $vars = array(
0831              'template_ary',
0832              'user_id',
0833              'user_notes_enabled',
0834              'warn_user_enabled',
0835              'friend',
0836              'friends_enabled',
0837              'foe',
0838              'foes_enabled',
0839          );
0840          extract($phpbb_dispatcher->trigger_event('core.memberlist_modify_view_profile_template_vars', compact($vars)));
0841   
0842          // Assign vars to memberlist_view.html
0843          $template->assign_vars($template_ary);
0844   
0845          if (!empty($profile_fields['row']))
0846          {
0847              $template->assign_vars($profile_fields['row']);
0848          }
0849   
0850          if (!empty($profile_fields['blockrow']))
0851          {
0852              foreach ($profile_fields['blockrow'] as $field_data)
0853              {
0854                  $template->assign_block_vars('custom_fields', $field_data);
0855              }
0856          }
0857   
0858          // Inactive reason/account?
0859          if ($member['user_type'] == USER_INACTIVE)
0860          {
0861              $user->add_lang('acp/common');
0862   
0863              $inactive_reason = $user->lang['INACTIVE_REASON_UNKNOWN'];
0864   
0865              switch ($member['user_inactive_reason'])
0866              {
0867                  case INACTIVE_REGISTER:
0868                      $inactive_reason = $user->lang['INACTIVE_REASON_REGISTER'];
0869                  break;
0870   
0871                  case INACTIVE_PROFILE:
0872                      $inactive_reason = $user->lang['INACTIVE_REASON_PROFILE'];
0873                  break;
0874   
0875                  case INACTIVE_MANUAL:
0876                      $inactive_reason = $user->lang['INACTIVE_REASON_MANUAL'];
0877                  break;
0878   
0879                  case INACTIVE_REMIND:
0880                      $inactive_reason = $user->lang['INACTIVE_REASON_REMIND'];
0881                  break;
0882              }
0883   
0884              $template->assign_vars(array(
0885                  'S_USER_INACTIVE'        => true,
0886                  'USER_INACTIVE_REASON'    => $inactive_reason)
0887              );
0888          }
0889   
0890          // Now generate page title
0891          $page_title = sprintf($user->lang['VIEWING_PROFILE'], $member['username']);
0892          $template_html = 'memberlist_view.html';
0893   
0894          $template->assign_block_vars('navlinks', array(
0895              'BREADCRUMB_NAME'    => $user->lang('MEMBERLIST'),
0896              'U_BREADCRUMB'        => append_sid("{$phpbb_root_path}memberlist.$phpEx"),
0897          ));
0898          $template->assign_block_vars('navlinks', array(
0899              'BREADCRUMB_NAME'    => $member['username'],
0900              'U_BREADCRUMB'        => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=viewprofile&u=$user_id"),
0901          ));
0902   
0903      break;
0904   
0905      case 'contactadmin':
0906      case 'email':
0907          if (!class_exists('messenger'))
0908          {
0909              include($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
0910          }
0911   
0912          $user_id    = $request->variable('u', 0);
0913          $topic_id    = $request->variable('t', 0);
0914   
0915          if ($user_id)
0916          {
0917              $form_name = 'user';
0918          }
0919          else if ($topic_id)
0920          {
0921              $form_name = 'topic';
0922          }
0923          else if ($mode === 'contactadmin')
0924          {
0925              $form_name = 'admin';
0926          }
0927          else
0928          {
0929              trigger_error('NO_EMAIL');
0930          }
0931   
0932          /** @var $form \phpbb\message\form */
0933          $form = $phpbb_container->get('message.form.' . $form_name);
0934   
0935          $form->bind($request);
0936          $error = $form->check_allow();
0937          if ($error)
0938          {
0939              trigger_error($error);
0940          }
0941   
0942          if ($request->is_set_post('submit'))
0943          {
0944              $messenger = new messenger(false);
0945              $form->submit($messenger);
0946          }
0947   
0948          $page_title = $form->get_page_title();
0949          $template_html = $form->get_template_file();
0950          $form->render($template);
0951   
0952          if ($user_id)
0953          {
0954              $navlink_name = $user->lang('SEND_EMAIL');
0955              $navlink_url = append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=email&u=$user_id");
0956          }
0957          else if ($topic_id)
0958          {
0959              // Generate the navlinks based on the selected topic
0960              $navlinks_sql_array = [
0961                  'SELECT'    => 'f.parent_id, f.forum_parents, f.left_id, f.right_id, f.forum_type, f.forum_name, 
0962                      f.forum_id, f.forum_desc, f.forum_desc_uid, f.forum_desc_bitfield, f.forum_desc_options, 
0963                      f.forum_options, t.topic_title',
0964                  'FROM'      => [
0965                      FORUMS_TABLE  => 'f',
0966                      TOPICS_TABLE  => 't',
0967                  ],
0968                  'WHERE'     => 't.forum_id = f.forum_id AND t.topic_id = ' . (int) $topic_id,
0969              ];
0970   
0971              $sql = $db->sql_build_query('SELECT', $navlinks_sql_array);
0972              $result = $db->sql_query($sql);
0973              $topic_data = $db->sql_fetchrow($result);
0974              $db->sql_freeresult($result);
0975   
0976              generate_forum_nav($topic_data);
0977              $template->assign_block_vars('navlinks', array(
0978                  'BREADCRUMB_NAME'    => $topic_data['topic_title'],
0979                  'U_BREADCRUMB'        => append_sid("{$phpbb_root_path}viewtopic.$phpEx", "t=$topic_id"),
0980              ));
0981   
0982              $navlink_name = $user->lang('EMAIL_TOPIC');
0983              $navlink_url = append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=email&t=$topic_id");
0984          }
0985          else if ($mode === 'contactadmin')
0986          {
0987              $navlink_name = $user->lang('CONTACT_ADMIN');
0988              $navlink_url = append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=contactadmin");
0989          }
0990   
0991          $template->assign_block_vars('navlinks', array(
0992              'BREADCRUMB_NAME'    => $navlink_name,
0993              'U_BREADCRUMB'        => $navlink_url,
0994          ));
0995   
0996      break;
0997   
0998      case 'livesearch':
0999   
1000          $username_chars = $request->variable('username', '', true);
1001   
1002          $sql = 'SELECT username, user_id, user_colour
1003              FROM ' . USERS_TABLE . '
1004              WHERE ' . $db->sql_in_set('user_type', $user_types) . '
1005                  AND username_clean ' . $db->sql_like_expression(utf8_clean_string($username_chars) . $db->get_any_char());
1006          $result = $db->sql_query_limit($sql, 10);
1007   
1008          $user_list = [];
1009   
1010          while ($row = $db->sql_fetchrow($result))
1011          {
1012              $user_list[] = [
1013                  'user_id'        => (int) $row['user_id'],
1014                  'result'        => html_entity_decode($row['username']),
1015                  'username_full'    => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']),
1016                  'display'        => get_username_string('no_profile', $row['user_id'], $row['username'], $row['user_colour']),
1017              ];
1018          }
1019          $db->sql_freeresult($result);
1020   
1021          $json_response = new \phpbb\json_response();
1022   
1023          $json_response->send([
1024              'keyword' => $username_chars,
1025              'results' => $user_list,
1026          ]);
1027   
1028      break;
1029   
1030      case 'group':
1031      default:
1032          // The basic memberlist
1033          $page_title = $user->lang['MEMBERLIST'];
1034          $template_html = 'memberlist_body.html';
1035   
1036          $template->assign_block_vars('navlinks', array(
1037              'BREADCRUMB_NAME'    => $page_title,
1038              'U_BREADCRUMB'        => append_sid("{$phpbb_root_path}memberlist.$phpEx"),
1039          ));
1040   
1041          /* @var $pagination \phpbb\pagination */
1042          $pagination = $phpbb_container->get('pagination');
1043   
1044          // Sorting
1045          $sort_key_text = array('a' => $user->lang['SORT_USERNAME'], 'c' => $user->lang['SORT_JOINED'], 'd' => $user->lang['SORT_POST_COUNT']);
1046          $sort_key_sql = array('a' => 'u.username_clean', 'c' => 'u.user_regdate', 'd' => 'u.user_posts');
1047   
1048          if ($config['jab_enable'] && $auth->acl_get('u_sendim'))
1049          {
1050              $sort_key_text['k'] = $user->lang['JABBER'];
1051              $sort_key_sql['k'] = 'u.user_jabber';
1052          }
1053   
1054          if ($auth->acl_get('a_user'))
1055          {
1056              $sort_key_text['e'] = $user->lang['SORT_EMAIL'];
1057              $sort_key_sql['e'] = 'u.user_email';
1058          }
1059   
1060          if ($auth->acl_get('u_viewonline'))
1061          {
1062              $sort_key_text['l'] = $user->lang['SORT_LAST_ACTIVE'];
1063              $sort_key_sql['l'] = 'u.user_last_active';
1064          }
1065   
1066          $sort_key_text['m'] = $user->lang['SORT_RANK'];
1067          $sort_key_sql['m'] = 'u.user_rank';
1068   
1069          $sort_dir_text = array('a' => $user->lang['ASCENDING'], 'd' => $user->lang['DESCENDING']);
1070   
1071          $s_sort_key = '';
1072          foreach ($sort_key_text as $key => $value)
1073          {
1074              $selected = ($sort_key == $key) ? ' selected="selected"' : '';
1075              $s_sort_key .= '<option value="' . $key . '"' . $selected . '>' . $value . '</option>';
1076          }
1077   
1078          $s_sort_dir = '';
1079          foreach ($sort_dir_text as $key => $value)
1080          {
1081              $selected = ($sort_dir == $key) ? ' selected="selected"' : '';
1082              $s_sort_dir .= '<option value="' . $key . '"' . $selected . '>' . $value . '</option>';
1083          }
1084   
1085          // Additional sorting options for user search ... if search is enabled, if not
1086          // then only admins can make use of this (for ACP functionality)
1087          $sql_select = $sql_where_data = $sql_from = $sql_where = $order_by = '';
1088   
1089   
1090          $form            = $request->variable('form', '');
1091          $field            = $request->variable('field', '');
1092          $select_single     = $request->variable('select_single', false);
1093   
1094          // Search URL parameters, if any of these are in the URL we do a search
1095          $search_params = array('username', 'email', 'jabber', 'search_group_id', 'joined_select', 'active_select', 'count_select', 'joined', 'active', 'count', 'ip');
1096   
1097          // We validate form and field here, only id/class allowed
1098          $form = (!preg_match('/^[a-z0-9_-]+$/i', $form)) ? '' : $form;
1099          $field = (!preg_match('/^[a-z0-9_-]+$/i', $field)) ? '' : $field;
1100          if ((($mode == '' || $mode == 'searchuser') || count(array_intersect($request->variable_names(\phpbb\request\request_interface::GET), $search_params)) > 0) && ($config['load_search'] || $auth->acl_get('a_')))
1101          {
1102              $username    = $request->variable('username', '', true);
1103              $email        = strtolower($request->variable('email', ''));
1104              $jabber        = $request->variable('jabber', '');
1105              $search_group_id    = $request->variable('search_group_id', 0);
1106   
1107              // when using these, make sure that we actually have values defined in $find_key_match
1108              $joined_select    = $request->variable('joined_select', 'lt');
1109              $active_select    = $request->variable('active_select', 'lt');
1110              $count_select    = $request->variable('count_select', 'eq');
1111   
1112              $joined            = explode('-', $request->variable('joined', ''));
1113              $active            = explode('-', $request->variable('active', ''));
1114              $count            = ($request->variable('count', '') !== '') ? $request->variable('count', 0) : '';
1115              $ipdomain        = $request->variable('ip', '');
1116   
1117              $find_key_match = array('lt' => '<', 'gt' => '>', 'eq' => '=');
1118   
1119              $find_count = array('lt' => $user->lang['LESS_THAN'], 'eq' => $user->lang['EQUAL_TO'], 'gt' => $user->lang['MORE_THAN']);
1120              $s_find_count = '';
1121              foreach ($find_count as $key => $value)
1122              {
1123                  $selected = ($count_select == $key) ? ' selected="selected"' : '';
1124                  $s_find_count .= '<option value="' . $key . '"' . $selected . '>' . $value . '</option>';
1125              }
1126   
1127              $find_time = array('lt' => $user->lang['BEFORE'], 'gt' => $user->lang['AFTER']);
1128              $s_find_join_time = '';
1129              foreach ($find_time as $key => $value)
1130              {
1131                  $selected = ($joined_select == $key) ? ' selected="selected"' : '';
1132                  $s_find_join_time .= '<option value="' . $key . '"' . $selected . '>' . $value . '</option>';
1133              }
1134   
1135              $s_find_active_time = '';
1136              foreach ($find_time as $key => $value)
1137              {
1138                  $selected = ($active_select == $key) ? ' selected="selected"' : '';
1139                  $s_find_active_time .= '<option value="' . $key . '"' . $selected . '>' . $value . '</option>';
1140              }
1141   
1142              $sql_where .= ($username) ? ' AND u.username_clean ' . $db->sql_like_expression(str_replace('*', $db->get_any_char(), utf8_clean_string($username))) : '';
1143              $sql_where .= ($auth->acl_get('a_user') && $email) ? ' AND u.user_email ' . $db->sql_like_expression(str_replace('*', $db->get_any_char(), $email)) . ' ' : '';
1144              $sql_where .= ($jabber) ? ' AND u.user_jabber ' . $db->sql_like_expression(str_replace('*', $db->get_any_char(), $jabber)) . ' ' : '';
1145              $sql_where .= (is_numeric($count) && isset($find_key_match[$count_select])) ? ' AND u.user_posts ' . $find_key_match[$count_select] . ' ' . (int) $count . ' ' : '';
1146   
1147              if (isset($find_key_match[$joined_select]) && count($joined) == 3)
1148              {
1149                  $joined_time = gmmktime(0, 0, 0, (int) $joined[1], (int) $joined[2], (int) $joined[0]);
1150   
1151                  if ($joined_time !== false)
1152                  {
1153                      $sql_where .= " AND u.user_regdate " . $find_key_match[$joined_select] . ' ' . $joined_time;
1154                  }
1155              }
1156   
1157              if (isset($find_key_match[$active_select]) && count($active) == 3 && $auth->acl_get('u_viewonline'))
1158              {
1159                  $active_time = gmmktime(0, 0, 0, (int) $active[1], (int) $active[2], (int) $active[0]);
1160   
1161                  if ($active_time !== false)
1162                  {
1163                      if ($active_select === 'lt' && (int) $active[0] == 0 && (int) $active[1] == 0 && (int) $active[2] == 0)
1164                      {
1165                          $sql_where .= ' AND u.user_last_active = 0';
1166                      }
1167                      else if ($active_select === 'gt')
1168                      {
1169                          $sql_where .= ' AND u.user_last_active ' . $find_key_match[$active_select] . ' ' . $active_time;
1170                      }
1171                      else
1172                      {
1173                          $sql_where .= ' AND (u.user_last_active > 0 AND u.user_last_active < ' . $active_time . ')';
1174                      }
1175                  }
1176              }
1177   
1178              $sql_where .= ($search_group_id) ? " AND u.user_id = ug.user_id AND ug.group_id = $search_group_id AND ug.user_pending = 0 " : '';
1179   
1180              if ($search_group_id)
1181              {
1182                  $sql_from = ', ' . USER_GROUP_TABLE . ' ug ';
1183              }
1184   
1185              if ($ipdomain && $auth->acl_getf_global('m_info'))
1186              {
1187                  if (strspn($ipdomain, 'abcdefghijklmnopqrstuvwxyz'))
1188                  {
1189                      $hostnames = gethostbynamel($ipdomain);
1190   
1191                      if ($hostnames !== false)
1192                      {
1193                          $ips = "'" . implode('\', \'', array_map(array($db, 'sql_escape'), preg_replace('#([0-9]{1,3}\.[0-9]{1,3}[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})#', "\\1", gethostbynamel($ipdomain)))) . "'";
1194                      }
1195                      else
1196                      {
1197                          $ips = false;
1198                      }
1199                  }
1200                  else
1201                  {
1202                      $ips = "'" . str_replace('*', '%', $db->sql_escape($ipdomain)) . "'";
1203                  }
1204   
1205                  if ($ips === false)
1206                  {
1207                      // A minor fudge but it does the job :D
1208                      $sql_where .= " AND u.user_id = 0";
1209                  }
1210                  else
1211                  {
1212                      $ip_forums = array_keys($auth->acl_getf('m_info', true));
1213   
1214                      $sql = 'SELECT DISTINCT poster_id
1215                          FROM ' . POSTS_TABLE . '
1216                          WHERE poster_ip ' . ((strpos($ips, '%') !== false) ? 'LIKE' : 'IN') . " ($ips)
1217                              AND " . $db->sql_in_set('forum_id', $ip_forums);
1218   
1219                      /**
1220                      * Modify sql query for members search by ip address / hostname
1221                      *
1222                      * @event core.memberlist_modify_ip_search_sql_query
1223                      * @var    string    ipdomain    The host name
1224                      * @var    string    ips            IP address list for the given host name
1225                      * @var    string    sql            The SQL query for searching members by IP address
1226                      * @since 3.1.7-RC1
1227                      */
1228                      $vars = array(
1229                          'ipdomain',
1230                          'ips',
1231                          'sql',
1232                      );
1233                      extract($phpbb_dispatcher->trigger_event('core.memberlist_modify_ip_search_sql_query', compact($vars)));
1234   
1235                      $result = $db->sql_query($sql);
1236   
1237                      if ($row = $db->sql_fetchrow($result))
1238                      {
1239                          $ip_sql = array();
1240                          do
1241                          {
1242                              $ip_sql[] = $row['poster_id'];
1243                          }
1244                          while ($row = $db->sql_fetchrow($result));
1245   
1246                          $sql_where .= ' AND ' . $db->sql_in_set('u.user_id', $ip_sql);
1247                      }
1248                      else
1249                      {
1250                          // A minor fudge but it does the job :D
1251                          $sql_where .= " AND u.user_id = 0";
1252                      }
1253                      unset($ip_forums);
1254   
1255                      $db->sql_freeresult($result);
1256                  }
1257              }
1258          }
1259   
1260          $first_char = $request->variable('first_char', '');
1261   
1262          if ($first_char == 'other')
1263          {
1264              for ($i = 97; $i < 123; $i++)
1265              {
1266                  $sql_where .= ' AND u.username_clean NOT ' . $db->sql_like_expression(chr($i) . $db->get_any_char());
1267              }
1268          }
1269          else if ($first_char)
1270          {
1271              $sql_where .= ' AND u.username_clean ' . $db->sql_like_expression(substr($first_char, 0, 1) . $db->get_any_char());
1272          }
1273   
1274          // Are we looking at a usergroup? If so, fetch additional info
1275          // and further restrict the user info query
1276          if ($mode == 'group')
1277          {
1278              // We JOIN here to save a query for determining membership for hidden groups. ;)
1279              $sql = 'SELECT g.*, ug.user_id, ug.group_leader
1280                  FROM ' . GROUPS_TABLE . ' g
1281                  LEFT JOIN ' . USER_GROUP_TABLE . ' ug ON (ug.user_pending = 0 AND ug.user_id = ' . $user->data['user_id'] . " AND ug.group_id = $group_id)
1282                  WHERE g.group_id = $group_id";
1283              $result = $db->sql_query($sql);
1284              $group_row = $db->sql_fetchrow($result);
1285              $db->sql_freeresult($result);
1286   
1287              if (!$group_row)
1288              {
1289                  trigger_error('NO_GROUP');
1290              }
1291   
1292              switch ($group_row['group_type'])
1293              {
1294                  case GROUP_OPEN:
1295                      $group_row['l_group_type'] = 'OPEN';
1296                  break;
1297   
1298                  case GROUP_CLOSED:
1299                      $group_row['l_group_type'] = 'CLOSED';
1300                  break;
1301   
1302                  case GROUP_HIDDEN:
1303                      $group_row['l_group_type'] = 'HIDDEN';
1304   
1305                      // Check for membership or special permissions
1306                      if (!$auth->acl_gets('a_group', 'a_groupadd', 'a_groupdel') && $group_row['user_id'] != $user->data['user_id'])
1307                      {
1308                          trigger_error('NO_GROUP');
1309                      }
1310                  break;
1311   
1312                  case GROUP_SPECIAL:
1313                      $group_row['l_group_type'] = 'SPECIAL';
1314                  break;
1315   
1316                  case GROUP_FREE:
1317                      $group_row['l_group_type'] = 'FREE';
1318                  break;
1319              }
1320   
1321              $avatar_img = phpbb_get_group_avatar($group_row);
1322   
1323              // ... same for group rank
1324              $group_rank_data = array(
1325                  'title'        => null,
1326                  'img'        => null,
1327                  'img_src'    => null,
1328              );
1329              if ($group_row['group_rank'])
1330              {
1331                  $group_rank_data = $group_helper->get_rank($group_row);
1332   
1333                  if ($group_rank_data['img'])
1334                  {
1335                      $group_rank_data['img'] .= '<br />';
1336                  }
1337              }
1338              // include modules for manage groups link display or not
1339              // need to ensure the module is active
1340              $can_manage_group = false;
1341              if ($user->data['is_registered'] && $group_row['group_leader'])
1342              {
1343                  if (!class_exists('p_master'))
1344                  {
1345                      include($phpbb_root_path . 'includes/functions_module.' . $phpEx);
1346                  }
1347                  $module = new p_master;
1348                  $module->list_modules('ucp');
1349   
1350                  if ($module->is_active('ucp_groups', 'manage'))
1351                  {
1352                      $can_manage_group = true;
1353                  }
1354                  unset($module);
1355              }
1356   
1357              $template->assign_block_vars('navlinks', array(
1358                  'BREADCRUMB_NAME'    => $group_helper->get_name($group_row['group_name']),
1359                  'U_BREADCRUMB'        => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=group&amp;g=$group_id"),
1360              ));
1361   
1362              $template->assign_vars(array(
1363                  'GROUP_DESC'    => generate_text_for_display($group_row['group_desc'], $group_row['group_desc_uid'], $group_row['group_desc_bitfield'], $group_row['group_desc_options']),
1364                  'GROUP_NAME'    => $group_helper->get_name($group_row['group_name']),
1365                  'GROUP_COLOR'    => $group_row['group_colour'],
1366                  'GROUP_TYPE'    => $user->lang['GROUP_IS_' . $group_row['l_group_type']],
1367                  'GROUP_RANK'    => $group_rank_data['title'],
1368   
1369                  'AVATAR_IMG'    => $avatar_img,
1370                  'RANK_IMG'        => $group_rank_data['img'],
1371                  'RANK_IMG_SRC'    => $group_rank_data['img_src'],
1372   
1373                  'U_PM'            => ($auth->acl_get('u_sendpm') && $auth->acl_get('u_masspm_group') && $group_row['group_receive_pm'] && $config['allow_privmsg'] && $config['allow_mass_pm']) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;mode=compose&amp;g=' . $group_id) : '',
1374                  'U_MANAGE'        => ($can_manage_group) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_groups&amp;mode=manage') : false,)
1375              );
1376   
1377              $sql_select = ', ug.group_leader';
1378              $sql_from = ', ' . USER_GROUP_TABLE . ' ug ';
1379              $order_by = 'ug.group_leader DESC, ';
1380   
1381              $sql_where .= " AND ug.user_pending = 0 AND u.user_id = ug.user_id AND ug.group_id = $group_id";
1382              $sql_where_data = " AND u.user_id = ug.user_id AND ug.group_id = $group_id";
1383          }
1384   
1385          // Sorting and order
1386          if (!isset($sort_key_sql[$sort_key]))
1387          {
1388              $sort_key = $default_key;
1389          }
1390   
1391          $order_by .= $sort_key_sql[$sort_key] . ' ' . (($sort_dir == 'a') ? 'ASC' : 'DESC');
1392   
1393          // For sorting by non-unique columns (rank, posts) add unique sort key to avoid duplicated rows in results
1394          if ($sort_key == 'm' || $sort_key == 'd')
1395          {
1396              $order_by .= ', u.user_id ASC';
1397          }
1398   
1399          /**
1400          * Modify sql query data for members search
1401          *
1402          * @event core.memberlist_modify_sql_query_data
1403          * @var    string    order_by        SQL ORDER BY clause condition
1404          * @var    string    sort_dir        The sorting direction
1405          * @var    string    sort_key        The sorting key
1406          * @var    array    sort_key_sql    Arraty with the sorting conditions data
1407          * @var    string    sql_from        SQL FROM clause condition
1408          * @var    string    sql_select        SQL SELECT fields list
1409          * @var    string    sql_where        SQL WHERE clause condition
1410          * @var    string    sql_where_data    SQL WHERE clause additional conditions data
1411          * @since 3.1.7-RC1
1412          */
1413          $vars = array(
1414              'order_by',
1415              'sort_dir',
1416              'sort_key',
1417              'sort_key_sql',
1418              'sql_from',
1419              'sql_select',
1420              'sql_where',
1421              'sql_where_data',
1422          );
1423          extract($phpbb_dispatcher->trigger_event('core.memberlist_modify_sql_query_data', compact($vars)));
1424   
1425          // Count the users ...
1426          $sql = 'SELECT COUNT(u.user_id) AS total_users
1427              FROM ' . USERS_TABLE . " u$sql_from
1428              WHERE " . $db->sql_in_set('u.user_type', $user_types) . "
1429              $sql_where";
1430          $result = $db->sql_query($sql);
1431          $total_users = (int) $db->sql_fetchfield('total_users');
1432          $db->sql_freeresult($result);
1433   
1434          // Build a relevant pagination_url
1435          $params = $sort_params = array();
1436   
1437          // We do not use $request->variable() here directly to save some calls (not all variables are set)
1438          $check_params = array(
1439              'g'                => array('g', 0),
1440              'sk'            => array('sk', $default_key),
1441              'sd'            => array('sd', 'a'),
1442              'form'            => array('form', ''),
1443              'field'            => array('field', ''),
1444              'select_single'    => array('select_single', $select_single),
1445              'username'        => array('username', '', true),
1446              'email'            => array('email', ''),
1447              'jabber'        => array('jabber', ''),
1448              'search_group_id'    => array('search_group_id', 0),
1449              'joined_select'    => array('joined_select', 'lt'),
1450              'active_select'    => array('active_select', 'lt'),
1451              'count_select'    => array('count_select', 'eq'),
1452              'joined'        => array('joined', ''),
1453              'active'        => array('active', ''),
1454              'count'            => ($request->variable('count', '') !== '') ? array('count', 0) : array('count', ''),
1455              'ip'            => array('ip', ''),
1456              'first_char'    => array('first_char', ''),
1457          );
1458   
1459          $u_first_char_params = array();
1460          foreach ($check_params as $key => $call)
1461          {
1462              if (!isset($_REQUEST[$key]))
1463              {
1464                  continue;
1465              }
1466   
1467              $param = call_user_func_array(array($request, 'variable'), $call);
1468              // Encode strings, convert everything else to int in order to prevent empty parameters.
1469              $param = urlencode($key) . '=' . ((is_string($param)) ? urlencode($param) : (int) $param);
1470              $params[] = $param;
1471   
1472              if ($key != 'first_char')
1473              {
1474                  $u_first_char_params[] = $param;
1475              }
1476              if ($key != 'sk' && $key != 'sd')
1477              {
1478                  $sort_params[] = $param;
1479              }
1480          }
1481   
1482          $u_hide_find_member = append_sid("{$phpbb_root_path}memberlist.$phpEx", "start=$start" . (!empty($params) ? '&amp;' . implode('&amp;', $params) : ''));
1483   
1484          if ($mode)
1485          {
1486              $params[] = "mode=$mode";
1487              $u_first_char_params[] = "mode=$mode";
1488          }
1489          $sort_params[] = "mode=$mode";
1490   
1491          $u_first_char_params = implode('&amp;', $u_first_char_params);
1492          $u_first_char_params .= ($u_first_char_params) ? '&amp;' : '';
1493   
1494          $first_characters = array();
1495          $first_characters[''] = $user->lang['ALL'];
1496          for ($i = 97; $i < 123; $i++)
1497          {
1498              $first_characters[chr($i)] = chr($i - 32);
1499          }
1500          $first_characters['other'] = $user->lang['OTHER'];
1501   
1502          $first_char_block_vars = [];
1503   
1504          foreach ($first_characters as $char => $desc)
1505          {
1506              $first_char_block_vars[] = [
1507                  'DESC'            => $desc,
1508                  'VALUE'            => $char,
1509                  'S_SELECTED'    => ($first_char == $char) ? true : false,
1510                  'U_SORT'        => append_sid("{$phpbb_root_path}memberlist.$phpEx", $u_first_char_params . 'first_char=' . $char) . '#memberlist',
1511              ];
1512          }
1513   
1514          /**
1515           * Modify memberlist sort and pagination parameters
1516           *
1517           * @event core.memberlist_modify_sort_pagination_params
1518           * @var array    sort_params                Array with URL parameters for sorting
1519           * @var array    params                    Array with URL parameters for pagination
1520           * @var array    first_characters        Array that maps each letter in a-z, 'other' and the empty string to their display representation
1521           * @var string    u_first_char_params        Concatenated URL parameters for first character search links
1522           * @var array    first_char_block_vars    Template block variables for each first character
1523           * @var int        total_users                Total number of users found in this search
1524           * @since 3.2.6-RC1
1525           */
1526          $vars = [
1527              'sort_params',
1528              'params',
1529              'first_characters',
1530              'u_first_char_params',
1531              'first_char_block_vars',
1532              'total_users',
1533          ];
1534          extract($phpbb_dispatcher->trigger_event('core.memberlist_modify_sort_pagination_params', compact($vars)));
1535   
1536          $template->assign_block_vars_array('first_char', $first_char_block_vars);
1537   
1538          $pagination_url = append_sid("{$phpbb_root_path}memberlist.$phpEx", implode('&amp;', $params));
1539          $sort_url = append_sid("{$phpbb_root_path}memberlist.$phpEx", implode('&amp;', $sort_params));
1540   
1541          unset($search_params, $sort_params);
1542   
1543          // Some search user specific data
1544          if (($mode == '' || $mode == 'searchuser') && ($config['load_search'] || $auth->acl_get('a_')))
1545          {
1546              $group_selected = $request->variable('search_group_id', 0);
1547              $s_group_select = '<option value="0"' . ((!$group_selected) ? ' selected="selected"' : '') . '>&nbsp;</option>';
1548              $group_ids = array();
1549   
1550              /**
1551              * @todo add this to a separate function (function is responsible for returning the groups the user is able to see based on the users group membership)
1552              */
1553   
1554              if ($auth->acl_gets('a_group', 'a_groupadd', 'a_groupdel'))
1555              {
1556                  $sql = 'SELECT group_id, group_name, group_type
1557                      FROM ' . GROUPS_TABLE;
1558   
1559                  if (!$config['coppa_enable'])
1560                  {
1561                      $sql .= " WHERE group_name <> 'REGISTERED_COPPA'";
1562                  }
1563   
1564                  $sql .= ' ORDER BY group_name ASC';
1565              }
1566              else
1567              {
1568                  $sql = 'SELECT g.group_id, g.group_name, g.group_type
1569                      FROM ' . GROUPS_TABLE . ' g
1570                      LEFT JOIN ' . USER_GROUP_TABLE . ' ug
1571                          ON (
1572                              g.group_id = ug.group_id
1573                              AND ug.user_id = ' . $user->data['user_id'] . '
1574                              AND ug.user_pending = 0
1575                          )
1576                      WHERE (g.group_type <> ' . GROUP_HIDDEN . ' OR ug.user_id = ' . $user->data['user_id'] . ')';
1577   
1578                  if (!$config['coppa_enable'])
1579                  {
1580                      $sql .= " AND g.group_name <> 'REGISTERED_COPPA'";
1581                  }
1582   
1583                  $sql .= ' ORDER BY g.group_name ASC';
1584              }
1585              $result = $db->sql_query($sql);
1586   
1587              while ($row = $db->sql_fetchrow($result))
1588              {
1589                  $group_ids[] = $row['group_id'];
1590                  $s_group_select .= '<option value="' . $row['group_id'] . '"' . (($group_selected == $row['group_id']) ? ' selected="selected"' : '') . '>' . $group_helper->get_name($row['group_name']) . '</option>';
1591              }
1592              $db->sql_freeresult($result);
1593   
1594              if ($group_selected !== 0 && !in_array($group_selected, $group_ids))
1595              {
1596                  trigger_error('NO_GROUP');
1597              }
1598   
1599              $template->assign_vars(array(
1600                  'USERNAME'    => $username,
1601                  'EMAIL'        => $email,
1602                  'JABBER'    => $jabber,
1603                  'JOINED'    => implode('-', $joined),
1604                  'ACTIVE'    => implode('-', $active),
1605                  'COUNT'        => $count,
1606                  'IP'        => $ipdomain,
1607   
1608                  'S_IP_SEARCH_ALLOWED'    => ($auth->acl_getf_global('m_info')) ? true : false,
1609                  'S_EMAIL_SEARCH_ALLOWED'=> ($auth->acl_get('a_user')) ? true : false,
1610                  'S_JABBER_ENABLED'        => $config['jab_enable'],
1611                  'S_IN_SEARCH_POPUP'        => ($form && $field) ? true : false,
1612                  'S_SEARCH_USER'            => ($mode == 'searchuser' || ($mode == '' && $submit)),
1613                  'S_FORM_NAME'            => $form,
1614                  'S_FIELD_NAME'            => $field,
1615                  'S_SELECT_SINGLE'        => $select_single,
1616                  'S_COUNT_OPTIONS'        => $s_find_count,
1617                  'S_SORT_OPTIONS'        => $s_sort_key,
1618                  'S_JOINED_TIME_OPTIONS'    => $s_find_join_time,
1619                  'S_ACTIVE_TIME_OPTIONS'    => $s_find_active_time,
1620                  'S_GROUP_SELECT'        => $s_group_select,
1621                  'S_USER_SEARCH_ACTION'    => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=searchuser&amp;form=$form&amp;field=$field"))
1622              );
1623          }
1624   
1625          $start = $pagination->validate_start($start, $config['topics_per_page'], $total_users);
1626   
1627          // Get us some users :D
1628          $sql = "SELECT u.user_id
1629              FROM " . USERS_TABLE . " u
1630                  $sql_from
1631              WHERE " . $db->sql_in_set('u.user_type', $user_types) . "
1632                  $sql_where
1633              ORDER BY $order_by";
1634          $result = $db->sql_query_limit($sql, $config['topics_per_page'], $start);
1635   
1636          $user_list = array();
1637          while ($row = $db->sql_fetchrow($result))
1638          {
1639              $user_list[] = (int) $row['user_id'];
1640          }
1641          $db->sql_freeresult($result);
1642   
1643          // Load custom profile fields
1644          if ($config['load_cpf_memberlist'])
1645          {
1646              /* @var $cp \phpbb\profilefields\manager */
1647              $cp = $phpbb_container->get('profilefields.manager');
1648   
1649              $cp_row = $cp->generate_profile_fields_template_headlines('field_show_on_ml');
1650              foreach ($cp_row as $profile_field)
1651              {
1652                  $template->assign_block_vars('custom_fields', $profile_field);
1653              }
1654          }
1655   
1656          $leaders_set = false;
1657          // So, did we get any users?
1658          if (count($user_list))
1659          {
1660              // Session time?! Session time...
1661              $sql = 'SELECT session_user_id, MAX(session_time) AS session_time, MIN(session_viewonline) AS session_viewonline
1662                  FROM ' . SESSIONS_TABLE . '
1663                  WHERE session_time >= ' . (time() - $config['session_length']) . '
1664                      AND ' . $db->sql_in_set('session_user_id', $user_list) . '
1665                  GROUP BY session_user_id';
1666              $result = $db->sql_query($sql);
1667   
1668              $session_ary = [];
1669              while ($row = $db->sql_fetchrow($result))
1670              {
1671                  $session_ary[$row['session_user_id']] = [
1672                      'session_time' => $row['session_time'],
1673                      'session_viewonline' => $row['session_viewonline'],
1674                  ];
1675              }
1676              $db->sql_freeresult($result);
1677   
1678              // Do the SQL thang
1679              if ($mode == 'group')
1680              {
1681                  $sql_from_ary = explode(',', $sql_from);
1682                  $extra_tables = [];
1683                  foreach ($sql_from_ary as $entry)
1684                  {
1685                      $table_data = explode(' ', trim($entry));
1686   
1687                      if (empty($table_data[0]) || empty($table_data[1]))
1688                      {
1689                          continue;
1690                      }
1691   
1692                      $extra_tables[$table_data[0]] = $table_data[1];
1693                  }
1694   
1695                  $sql_array = array(
1696                      'SELECT'    => 'u.*' . $sql_select,
1697                      'FROM'        => array_merge([USERS_TABLE => 'u'], $extra_tables),
1698                      'WHERE'        => $db->sql_in_set('u.user_id', $user_list) . $sql_where_data . '',
1699                  );
1700              }
1701              else
1702              {
1703                  $sql_array = array(
1704                      'SELECT'    => 'u.*',
1705                      'FROM'        => array(
1706                          USERS_TABLE        => 'u'
1707                      ),
1708                      'WHERE'        => $db->sql_in_set('u.user_id', $user_list),
1709                  );
1710              }
1711   
1712              /**
1713               * Modify user data SQL before member row is created
1714               *
1715               * @event core.memberlist_modify_memberrow_sql
1716               * @var string    mode                Memberlist mode
1717               * @var string    sql_select            Additional select statement
1718               * @var string    sql_from            Additional from statement
1719               * @var array    sql_array            Array containing the main query
1720               * @var array    user_list            Array containing list of users
1721               * @since 3.2.6-RC1
1722               */
1723              $vars = array(
1724                  'mode',
1725                  'sql_select',
1726                  'sql_from',
1727                  'sql_array',
1728                  'user_list',
1729              );
1730              extract($phpbb_dispatcher->trigger_event('core.memberlist_modify_memberrow_sql', compact($vars)));
1731   
1732              $sql = $db->sql_build_query('SELECT', $sql_array);
1733              $result = $db->sql_query($sql);
1734   
1735              $id_cache = array();
1736              while ($row = $db->sql_fetchrow($result))
1737              {
1738                  $row['session_time'] = $session_ary[$row['user_id']]['session_time'] ?? 0;
1739                  $row['session_viewonline'] = $session_ary[$row['user_id']]['session_viewonline'] ?? 0;
1740                  $row['last_visit'] = $row['user_last_active'] ?: $row['session_time'];
1741   
1742                  $id_cache[$row['user_id']] = $row;
1743              }
1744   
1745              $db->sql_freeresult($result);
1746   
1747              // Load custom profile fields if required
1748              if ($config['load_cpf_memberlist'])
1749              {
1750                  // Grab all profile fields from users in id cache for later use - similar to the poster cache
1751                  $profile_fields_cache = $cp->grab_profile_fields_data($user_list);
1752   
1753                  // Filter the fields we don't want to show
1754                  foreach ($profile_fields_cache as $user_id => $user_profile_fields)
1755                  {
1756                      foreach ($user_profile_fields as $field_ident => $profile_field)
1757                      {
1758                          if (!$profile_field['data']['field_show_on_ml'])
1759                          {
1760                              unset($profile_fields_cache[$user_id][$field_ident]);
1761                          }
1762                      }
1763                  }
1764              }
1765   
1766              // If we sort by last active date we need to adjust the id cache due to user_lastvisit not being the last active date...
1767              if ($sort_key == 'l')
1768              {
1769  //                uasort($id_cache, create_function('$first, $second', "return (\$first['last_visit'] == \$second['last_visit']) ? 0 : ((\$first['last_visit'] < \$second['last_visit']) ? $lesser_than : ($lesser_than * -1));"));
1770                  usort($user_list,  'phpbb_sort_last_active');
1771              }
1772   
1773              // do we need to display contact fields as such
1774              $use_contact_fields = true;
1775   
1776              /**
1777               * Modify list of users before member row is created
1778               *
1779               * @event core.memberlist_memberrow_before
1780               * @var array    user_list            Array containing list of users
1781               * @var bool    use_contact_fields    Should we display contact fields as such?
1782               * @since 3.1.7-RC1
1783               */
1784              $vars = array('user_list', 'use_contact_fields');
1785              extract($phpbb_dispatcher->trigger_event('core.memberlist_memberrow_before', compact($vars)));
1786   
1787              for ($i = 0, $end = count($user_list); $i < $end; ++$i)
1788              {
1789                  $user_id = $user_list[$i];
1790                  $row = $id_cache[$user_id];
1791                  $is_leader = (isset($row['group_leader']) && $row['group_leader']) ? true : false;
1792                  $leaders_set = ($leaders_set || $is_leader);
1793   
1794                  $cp_row = array();
1795                  if ($config['load_cpf_memberlist'])
1796                  {
1797                      $cp_row = (isset($profile_fields_cache[$user_id])) ? $cp->generate_profile_fields_template_data($profile_fields_cache[$user_id], $use_contact_fields) : array();
1798                  }
1799   
1800                  $memberrow = array_merge(phpbb_show_profile($row, false, false, false), array(
1801                      'ROW_NUMBER'        => $i + ($start + 1),
1802   
1803                      'S_CUSTOM_PROFILE'    => (isset($cp_row['row']) && count($cp_row['row'])) ? true : false,
1804                      'S_GROUP_LEADER'    => $is_leader,
1805                      'S_INACTIVE'        => $row['user_type'] == USER_INACTIVE,
1806   
1807                      'U_VIEW_PROFILE'    => get_username_string('profile', $user_id, $row['username']),
1808                  ));
1809   
1810                  if (isset($cp_row['row']) && count($cp_row['row']))
1811                  {
1812                      $memberrow = array_merge($memberrow, $cp_row['row']);
1813                  }
1814   
1815                  $template->assign_block_vars('memberrow', $memberrow);
1816   
1817                  if (isset($cp_row['blockrow']) && count($cp_row['blockrow']))
1818                  {
1819                      foreach ($cp_row['blockrow'] as $field_data)
1820                      {
1821                          $template->assign_block_vars('memberrow.custom_fields', $field_data);
1822                      }
1823                  }
1824   
1825                  unset($id_cache[$user_id]);
1826              }
1827          }
1828   
1829          $pagination->generate_template_pagination($pagination_url, 'pagination', 'start', $total_users, $config['topics_per_page'], $start);
1830   
1831          // Generate page
1832          $template_vars = array(
1833              'TOTAL_USERS'    => $user->lang('LIST_USERS', (int) $total_users),
1834   
1835              'PROFILE_IMG'    => $user->img('icon_user_profile', $user->lang['PROFILE']),
1836              'PM_IMG'        => $user->img('icon_contact_pm', $user->lang['SEND_PRIVATE_MESSAGE']),
1837              'EMAIL_IMG'        => $user->img('icon_contact_email', $user->lang['EMAIL']),
1838              'JABBER_IMG'    => $user->img('icon_contact_jabber', $user->lang['JABBER']),
1839              'SEARCH_IMG'    => $user->img('icon_user_search', $user->lang['SEARCH']),
1840   
1841              'U_FIND_MEMBER'            => ($config['load_search'] || $auth->acl_get('a_')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser' . (($start) ? "&amp;start=$start" : '') . (!empty($params) ? '&amp;' . implode('&amp;', $params) : '')) : '',
1842              'U_HIDE_FIND_MEMBER'    => ($mode == 'searchuser' || ($mode == '' && $submit)) ? $u_hide_find_member : '',
1843              'U_LIVE_SEARCH'            => ($config['allow_live_searches']) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=livesearch') : false,
1844              'U_SORT_USERNAME'        => $sort_url . '&amp;sk=a&amp;sd=' . (($sort_key == 'a' && $sort_dir == 'a') ? 'd' : 'a'),
1845              'U_SORT_JOINED'            => $sort_url . '&amp;sk=c&amp;sd=' . (($sort_key == 'c' && $sort_dir == 'd') ? 'a' : 'd'),
1846              'U_SORT_POSTS'            => $sort_url . '&amp;sk=d&amp;sd=' . (($sort_key == 'd' && $sort_dir == 'd') ? 'a' : 'd'),
1847              'U_SORT_EMAIL'            => $sort_url . '&amp;sk=e&amp;sd=' . (($sort_key == 'e' && $sort_dir == 'd') ? 'a' : 'd'),
1848              'U_SORT_ACTIVE'            => ($auth->acl_get('u_viewonline')) ? $sort_url . '&amp;sk=l&amp;sd=' . (($sort_key == 'l' && $sort_dir == 'd') ? 'a' : 'd') : '',
1849              'U_SORT_RANK'            => $sort_url . '&amp;sk=m&amp;sd=' . (($sort_key == 'm' && $sort_dir == 'd') ? 'a' : 'd'),
1850              'U_LIST_CHAR'            => $sort_url . '&amp;sk=a&amp;sd=' . (($sort_key == 'l' && $sort_dir == 'd') ? 'a' : 'd'),
1851   
1852              'S_SHOW_GROUP'        => ($mode == 'group') ? true : false,
1853              'S_VIEWONLINE'        => $auth->acl_get('u_viewonline'),
1854              'S_LEADERS_SET'        => $leaders_set,
1855              'S_MODE_SELECT'        => $s_sort_key,
1856              'S_ORDER_SELECT'    => $s_sort_dir,
1857              'S_MODE_ACTION'        => $pagination_url,
1858          );
1859   
1860          /**
1861           * Modify memberlist page template vars
1862           *
1863           * @event core.memberlist_modify_template_vars
1864           * @var array    params                Array containing URL parameters
1865           * @var string    sort_url            Sorting URL base
1866           * @var array    template_vars        Array containing template vars
1867           * @since 3.2.2-RC1
1868           */
1869          $vars = array('params', 'sort_url', 'template_vars');
1870          extract($phpbb_dispatcher->trigger_event('core.memberlist_modify_template_vars', compact($vars)));
1871   
1872          $template->assign_vars($template_vars);
1873  }
1874   
1875  // Output the page
1876  page_header($page_title);
1877   
1878  $template->set_filenames(array(
1879      'body' => $template_html)
1880  );
1881  make_jumpbox(append_sid("{$phpbb_root_path}viewforum.$phpEx"));
1882   
1883  page_footer();
1884