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

functions_display.php

Zuletzt modifiziert: 02.04.2025, 15:01 - Dateigröße: 59.16 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  if (!defined('IN_PHPBB'))
0018  {
0019      exit;
0020  }
0021   
0022  /**
0023  * Display Forums
0024  */
0025  function display_forums($root_data = '', $display_moderators = true, $return_moderators = false)
0026  {
0027      global $db, $auth, $user, $template;
0028      global $phpbb_root_path, $phpEx, $config;
0029      global $request, $phpbb_dispatcher, $phpbb_container;
0030   
0031      $forum_rows = $subforums = $forum_ids = $forum_ids_moderator = $forum_moderators = $active_forum_ary = array();
0032      $parent_id = $visible_forums = 0;
0033      $parent_subforum_limit = false;
0034   
0035      // Mark forums read?
0036      $mark_read = $request->variable('mark', '');
0037   
0038      if ($mark_read == 'all')
0039      {
0040          $mark_read = '';
0041      }
0042   
0043      if (!$root_data)
0044      {
0045          if ($mark_read == 'forums')
0046          {
0047              $mark_read = 'all';
0048          }
0049   
0050          $root_data = array('forum_id' => 0);
0051          $sql_where = '';
0052      }
0053      else
0054      {
0055          $sql_where = 'left_id > ' . $root_data['left_id'] . ' AND left_id < ' . $root_data['right_id'];
0056      }
0057   
0058      // Handle marking everything read
0059      if ($mark_read == 'all')
0060      {
0061          $redirect = build_url(array('mark', 'hash', 'mark_time'));
0062          meta_refresh(3, $redirect);
0063   
0064          if (check_link_hash($request->variable('hash', ''), 'global'))
0065          {
0066              markread('all', false, false, $request->variable('mark_time', 0));
0067   
0068              if ($request->is_ajax())
0069              {
0070                  // Tell the ajax script what language vars and URL need to be replaced
0071                  $data = array(
0072                      'NO_UNREAD_POSTS'    => $user->lang['NO_UNREAD_POSTS'],
0073                      'UNREAD_POSTS'        => $user->lang['UNREAD_POSTS'],
0074                      'U_MARK_FORUMS'        => ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}index.$phpEx", 'hash=' . generate_link_hash('global') . '&mark=forums&mark_time=' . time(), false) : '',
0075                      'MESSAGE_TITLE'        => $user->lang['INFORMATION'],
0076                      'MESSAGE_TEXT'        => $user->lang['FORUMS_MARKED']
0077                  );
0078                  $json_response = new \phpbb\json_response();
0079                  $json_response->send($data);
0080              }
0081   
0082              trigger_error(
0083                  $user->lang['FORUMS_MARKED'] . '<br /><br />' .
0084                  sprintf($user->lang['RETURN_INDEX'], '<a href="' . $redirect . '">', '</a>')
0085              );
0086          }
0087          else
0088          {
0089              trigger_error(sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>'));
0090          }
0091      }
0092   
0093      // Display list of active topics for this category?
0094      $show_active = (isset($root_data['forum_flags']) && ($root_data['forum_flags'] & FORUM_FLAG_ACTIVE_TOPICS)) ? true : false;
0095   
0096      $sql_array = array(
0097          'SELECT'    => 'f.*',
0098          'FROM'        => array(
0099              FORUMS_TABLE        => 'f'
0100          ),
0101          'LEFT_JOIN'    => array(),
0102      );
0103   
0104      if ($config['load_db_lastread'] && $user->data['is_registered'])
0105      {
0106          $sql_array['LEFT_JOIN'][] = array('FROM' => array(FORUMS_TRACK_TABLE => 'ft'), 'ON' => 'ft.user_id = ' . $user->data['user_id'] . ' AND ft.forum_id = f.forum_id');
0107          $sql_array['SELECT'] .= ', ft.mark_time';
0108      }
0109      else if ($config['load_anon_lastread'] || $user->data['is_registered'])
0110      {
0111          $tracking_topics = $request->variable($config['cookie_name'] . '_track', '', true, \phpbb\request\request_interface::COOKIE);
0112          $tracking_topics = ($tracking_topics) ? tracking_unserialize($tracking_topics) : array();
0113   
0114          if (!$user->data['is_registered'])
0115          {
0116              $user->data['user_lastmark'] = (isset($tracking_topics['l'])) ? (int) (base_convert($tracking_topics['l'], 36, 10) + $config['board_startdate']) : 0;
0117          }
0118      }
0119   
0120      if ($show_active)
0121      {
0122          $sql_array['LEFT_JOIN'][] = array(
0123              'FROM'    => array(FORUMS_ACCESS_TABLE => 'fa'),
0124              'ON'    => "fa.forum_id = f.forum_id AND fa.session_id = '" . $db->sql_escape($user->session_id) . "'"
0125          );
0126   
0127          $sql_array['SELECT'] .= ', fa.user_id';
0128      }
0129   
0130      $sql_ary = array(
0131          'SELECT'    => $sql_array['SELECT'],
0132          'FROM'        => $sql_array['FROM'],
0133          'LEFT_JOIN'    => $sql_array['LEFT_JOIN'],
0134   
0135          'WHERE'        => $sql_where,
0136   
0137          'ORDER_BY'    => 'f.left_id',
0138      );
0139   
0140      /**
0141      * Event to modify the SQL query before the forum data is queried
0142      *
0143      * @event core.display_forums_modify_sql
0144      * @var    array    sql_ary        The SQL array to get the data of the forums
0145      * @since 3.1.0-a1
0146      */
0147      $vars = array('sql_ary');
0148      extract($phpbb_dispatcher->trigger_event('core.display_forums_modify_sql', compact($vars)));
0149   
0150      $sql = $db->sql_build_query('SELECT', $sql_ary);
0151      $result = $db->sql_query($sql);
0152   
0153      $forum_tracking_info = $valid_categories = array();
0154      $branch_root_id = $root_data['forum_id'];
0155   
0156      /* @var $phpbb_content_visibility \phpbb\content_visibility */
0157      $phpbb_content_visibility = $phpbb_container->get('content.visibility');
0158   
0159      while ($row = $db->sql_fetchrow($result))
0160      {
0161          /**
0162          * Event to modify the data set of a forum
0163          *
0164          * This event is triggered once per forum
0165          *
0166          * @event core.display_forums_modify_row
0167          * @var    int        branch_root_id    Last top-level forum
0168          * @var    array    row                The data of the forum
0169          * @since 3.1.0-a1
0170          */
0171          $vars = array('branch_root_id', 'row');
0172          extract($phpbb_dispatcher->trigger_event('core.display_forums_modify_row', compact($vars)));
0173   
0174          $forum_id = $row['forum_id'];
0175   
0176          // Mark forums read?
0177          if ($mark_read == 'forums')
0178          {
0179              if ($auth->acl_get('f_list', $forum_id))
0180              {
0181                  $forum_ids[] = $forum_id;
0182              }
0183   
0184              continue;
0185          }
0186   
0187          // Category with no members
0188          if ($row['forum_type'] == FORUM_CAT && ($row['left_id'] + 1 == $row['right_id']))
0189          {
0190              continue;
0191          }
0192   
0193          // Skip branch
0194          if (isset($right_id))
0195          {
0196              if ($row['left_id'] < $right_id)
0197              {
0198                  continue;
0199              }
0200              unset($right_id);
0201          }
0202   
0203          if (!$auth->acl_get('f_list', $forum_id))
0204          {
0205              // if the user does not have permissions to list this forum, skip everything until next branch
0206              $right_id = $row['right_id'];
0207              continue;
0208          }
0209   
0210          if ($config['load_db_lastread'] && $user->data['is_registered'])
0211          {
0212              $forum_tracking_info[$forum_id] = (!empty($row['mark_time'])) ? $row['mark_time'] : $user->data['user_lastmark'];
0213          }
0214          else if ($config['load_anon_lastread'] || $user->data['is_registered'])
0215          {
0216              if (!$user->data['is_registered'])
0217              {
0218                  $user->data['user_lastmark'] = (isset($tracking_topics['l'])) ? (int) (base_convert($tracking_topics['l'], 36, 10) + $config['board_startdate']) : 0;
0219              }
0220              $forum_tracking_info[$forum_id] = (isset($tracking_topics['f'][$forum_id])) ? (int) (base_convert($tracking_topics['f'][$forum_id], 36, 10) + $config['board_startdate']) : $user->data['user_lastmark'];
0221          }
0222   
0223          // Lets check whether there are unapproved topics/posts, so we can display an information to moderators
0224          $row['forum_id_unapproved_topics'] = ($auth->acl_get('m_approve', $forum_id) && $row['forum_topics_unapproved']) ? $forum_id : 0;
0225          $row['forum_id_unapproved_posts'] = ($auth->acl_get('m_approve', $forum_id) && $row['forum_posts_unapproved']) ? $forum_id : 0;
0226          $row['forum_posts'] = $phpbb_content_visibility->get_count('forum_posts', $row, $forum_id);
0227          $row['forum_topics'] = $phpbb_content_visibility->get_count('forum_topics', $row, $forum_id);
0228   
0229          // Display active topics from this forum?
0230          if ($show_active && $row['forum_type'] == FORUM_POST && $auth->acl_get('f_read', $forum_id) && ($row['forum_flags'] & FORUM_FLAG_ACTIVE_TOPICS))
0231          {
0232              if (!isset($active_forum_ary['forum_topics']))
0233              {
0234                  $active_forum_ary['forum_topics'] = 0;
0235              }
0236   
0237              if (!isset($active_forum_ary['forum_posts']))
0238              {
0239                  $active_forum_ary['forum_posts'] = 0;
0240              }
0241   
0242              $active_forum_ary['forum_id'][]        = $forum_id;
0243              $active_forum_ary['enable_icons'][]    = $row['enable_icons'];
0244              $active_forum_ary['forum_topics']    += $row['forum_topics'];
0245              $active_forum_ary['forum_posts']    += $row['forum_posts'];
0246   
0247              // If this is a passworded forum we do not show active topics from it if the user is not authorised to view it...
0248              if ($row['forum_password'] && $row['user_id'] != $user->data['user_id'])
0249              {
0250                  $active_forum_ary['exclude_forum_id'][] = $forum_id;
0251              }
0252          }
0253   
0254          // Fill list of categories with forums
0255          if (isset($forum_rows[$row['parent_id']]))
0256          {
0257              $valid_categories[$row['parent_id']] = true;
0258          }
0259   
0260          //
0261          if ($row['parent_id'] == $root_data['forum_id'] || $row['parent_id'] == $branch_root_id)
0262          {
0263              if ($row['forum_type'] != FORUM_CAT)
0264              {
0265                  $forum_ids_moderator[] = (int) $forum_id;
0266              }
0267   
0268              // Direct child of current branch
0269              $parent_id = $forum_id;
0270              $parent_subforum_limit = $row['display_subforum_limit'] ?? false;
0271              $forum_rows[$forum_id] = $row;
0272   
0273              if ($row['forum_type'] == FORUM_CAT && $row['parent_id'] == $root_data['forum_id'])
0274              {
0275                  $branch_root_id = $forum_id;
0276              }
0277              $forum_rows[$parent_id]['forum_id_last_post'] = $row['forum_id'];
0278              $forum_rows[$parent_id]['forum_password_last_post'] = $row['forum_password'];
0279              $forum_rows[$parent_id]['orig_forum_last_post_time'] = $row['forum_last_post_time'];
0280          }
0281          else if ($row['forum_type'] != FORUM_CAT)
0282          {
0283              $subforums[$parent_id][$forum_id]['display'] = ($row['display_on_index'] && (!$parent_subforum_limit || $parent_id == $row['parent_id']));
0284              $subforums[$parent_id][$forum_id]['name'] = $row['forum_name'];
0285              $subforums[$parent_id][$forum_id]['orig_forum_last_post_time'] = $row['forum_last_post_time'];
0286              $subforums[$parent_id][$forum_id]['children'] = array();
0287              $subforums[$parent_id][$forum_id]['type'] = $row['forum_type'];
0288   
0289              if (isset($subforums[$parent_id][$row['parent_id']]) && !$row['display_on_index'])
0290              {
0291                  $subforums[$parent_id][$row['parent_id']]['children'][] = $forum_id;
0292              }
0293   
0294              if (!$forum_rows[$parent_id]['forum_id_unapproved_topics'] && $row['forum_id_unapproved_topics'])
0295              {
0296                  $forum_rows[$parent_id]['forum_id_unapproved_topics'] = $forum_id;
0297              }
0298   
0299              if (!$forum_rows[$parent_id]['forum_id_unapproved_posts'] && $row['forum_id_unapproved_posts'])
0300              {
0301                  $forum_rows[$parent_id]['forum_id_unapproved_posts'] = $forum_id;
0302              }
0303   
0304              $forum_rows[$parent_id]['forum_topics'] += $row['forum_topics'];
0305   
0306              // Do not list redirects in LINK Forums as Posts.
0307              if ($row['forum_type'] != FORUM_LINK)
0308              {
0309                  $forum_rows[$parent_id]['forum_posts'] += $row['forum_posts'];
0310              }
0311   
0312              if ($row['forum_last_post_time'] > $forum_rows[$parent_id]['forum_last_post_time'])
0313              {
0314                  $forum_rows[$parent_id]['forum_last_post_id'] = $row['forum_last_post_id'];
0315                  $forum_rows[$parent_id]['forum_last_post_subject'] = $row['forum_last_post_subject'];
0316                  $forum_rows[$parent_id]['forum_last_post_time'] = $row['forum_last_post_time'];
0317                  $forum_rows[$parent_id]['forum_last_poster_id'] = $row['forum_last_poster_id'];
0318                  $forum_rows[$parent_id]['forum_last_poster_name'] = $row['forum_last_poster_name'];
0319                  $forum_rows[$parent_id]['forum_last_poster_colour'] = $row['forum_last_poster_colour'];
0320                  $forum_rows[$parent_id]['forum_id_last_post'] = $forum_id;
0321                  $forum_rows[$parent_id]['forum_password_last_post'] = $row['forum_password'];
0322              }
0323          }
0324   
0325          /**
0326          * Event to modify the forum rows data set
0327          *
0328          * This event is triggered once per forum
0329          *
0330          * @event core.display_forums_modify_forum_rows
0331          * @var    array    forum_rows        Data array of all forums we display
0332          * @var    array    subforums        Data array of all subforums we display
0333          * @var    int        branch_root_id    Current top-level forum
0334          * @var    int        parent_id        Current parent forum
0335          * @var    array    row                The data of the forum
0336          * @since 3.1.0-a1
0337          */
0338          $vars = array('forum_rows', 'subforums', 'branch_root_id', 'parent_id', 'row');
0339          extract($phpbb_dispatcher->trigger_event('core.display_forums_modify_forum_rows', compact($vars)));
0340      }
0341      $db->sql_freeresult($result);
0342   
0343      // Handle marking posts
0344      if ($mark_read == 'forums')
0345      {
0346          $redirect = build_url(array('mark', 'hash', 'mark_time'));
0347          $token = $request->variable('hash', '');
0348          if (check_link_hash($token, 'global'))
0349          {
0350              markread('topics', $forum_ids, false, $request->variable('mark_time', 0));
0351              $message = sprintf($user->lang['RETURN_FORUM'], '<a href="' . $redirect . '">', '</a>');
0352              meta_refresh(3, $redirect);
0353   
0354              if ($request->is_ajax())
0355              {
0356                  // Tell the ajax script what language vars and URL need to be replaced
0357                  $data = array(
0358                      'NO_UNREAD_POSTS'    => $user->lang['NO_UNREAD_POSTS'],
0359                      'UNREAD_POSTS'        => $user->lang['UNREAD_POSTS'],
0360                      'U_MARK_FORUMS'        => ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'hash=' . generate_link_hash('global') . '&f=' . $root_data['forum_id'] . '&mark=forums&mark_time=' . time(), false) : '',
0361                      'MESSAGE_TITLE'        => $user->lang['INFORMATION'],
0362                      'MESSAGE_TEXT'        => $user->lang['FORUMS_MARKED']
0363                  );
0364                  $json_response = new \phpbb\json_response();
0365                  $json_response->send($data);
0366              }
0367   
0368              trigger_error($user->lang['FORUMS_MARKED'] . '<br /><br />' . $message);
0369          }
0370          else
0371          {
0372              $message = sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>');
0373              meta_refresh(3, $redirect);
0374              trigger_error($message);
0375          }
0376   
0377      }
0378   
0379      // Grab moderators ... if necessary
0380      if ($display_moderators)
0381      {
0382          if ($return_moderators)
0383          {
0384              $forum_ids_moderator[] = $root_data['forum_id'];
0385          }
0386          get_moderators($forum_moderators, $forum_ids_moderator);
0387      }
0388   
0389      /**
0390      * Event to perform additional actions before the forum list is being generated
0391      *
0392      * @event core.display_forums_before
0393      * @var    array    active_forum_ary    Array with forum data to display active topics
0394      * @var    bool    display_moderators    Flag indicating if we display forum moderators
0395      * @var    array    forum_moderators    Array with forum moderators list
0396      * @var    array    forum_rows            Data array of all forums we display
0397      * @var    bool    return_moderators    Flag indicating if moderators list should be returned
0398      * @var    array    root_data            Array with the root forum data
0399      * @since 3.1.4-RC1
0400      */
0401      $vars = array(
0402          'active_forum_ary',
0403          'display_moderators',
0404          'forum_moderators',
0405          'forum_rows',
0406          'return_moderators',
0407          'root_data',
0408      );
0409      extract($phpbb_dispatcher->trigger_event('core.display_forums_before', compact($vars)));
0410   
0411      // Used to tell whatever we have to create a dummy category or not.
0412      $last_catless = true;
0413      foreach ($forum_rows as $row)
0414      {
0415          // Category
0416          if ($row['parent_id'] == $root_data['forum_id'] && $row['forum_type'] == FORUM_CAT)
0417          {
0418              // Do not display categories without any forums to display
0419              if (!isset($valid_categories[$row['forum_id']]))
0420              {
0421                  continue;
0422              }
0423   
0424              $cat_row = array(
0425                  'S_IS_CAT'                => true,
0426                  'FORUM_ID'                => $row['forum_id'],
0427                  'FORUM_NAME'            => $row['forum_name'],
0428                  'FORUM_DESC'            => generate_text_for_display($row['forum_desc'], $row['forum_desc_uid'], $row['forum_desc_bitfield'], $row['forum_desc_options']),
0429                  'FORUM_FOLDER_IMG'        => '',
0430                  'FORUM_FOLDER_IMG_SRC'    => '',
0431                  'FORUM_IMAGE'            => ($row['forum_image']) ? '<img src="' . $phpbb_root_path . $row['forum_image'] . '" alt="' . $user->lang['FORUM_CAT'] . '" />' : '',
0432                  'FORUM_IMAGE_SRC'        => ($row['forum_image']) ? $phpbb_root_path . $row['forum_image'] : '',
0433                  'U_VIEWFORUM'            => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $row['forum_id']),
0434              );
0435   
0436              /**
0437              * Modify the template data block of the 'category'
0438              *
0439              * This event is triggered once per 'category'
0440              *
0441              * @event core.display_forums_modify_category_template_vars
0442              * @var    array    cat_row            Template data of the 'category'
0443              * @var    bool    last_catless    The flag indicating whether the last forum had a parent category
0444              * @var    array    root_data        Array with the root forum data
0445              * @var    array    row                The data of the 'category'
0446              * @since 3.1.0-RC4
0447              * @changed 3.1.7-RC1 Removed undefined catless variable
0448              */
0449              $vars = array(
0450                  'cat_row',
0451                  'last_catless',
0452                  'root_data',
0453                  'row',
0454              );
0455              extract($phpbb_dispatcher->trigger_event('core.display_forums_modify_category_template_vars', compact($vars)));
0456   
0457              $template->assign_block_vars('forumrow', $cat_row);
0458   
0459              continue;
0460          }
0461   
0462          $visible_forums++;
0463          $forum_id = $row['forum_id'];
0464   
0465          $forum_unread = (isset($forum_tracking_info[$forum_id]) && $row['orig_forum_last_post_time'] > $forum_tracking_info[$forum_id]) ? true : false;
0466   
0467          $folder_image = $folder_alt = $l_subforums = '';
0468          $subforums_list = array();
0469   
0470          // Generate list of subforums if we need to
0471          if (isset($subforums[$forum_id]))
0472          {
0473              foreach ($subforums[$forum_id] as $subforum_id => $subforum_row)
0474              {
0475                  $subforum_unread = (isset($forum_tracking_info[$subforum_id]) && $subforum_row['orig_forum_last_post_time'] > $forum_tracking_info[$subforum_id]) ? true : false;
0476   
0477                  if (!$subforum_unread && !empty($subforum_row['children']))
0478                  {
0479                      foreach ($subforum_row['children'] as $child_id)
0480                      {
0481                          if (isset($forum_tracking_info[$child_id]) && $subforums[$forum_id][$child_id]['orig_forum_last_post_time'] > $forum_tracking_info[$child_id])
0482                          {
0483                              // Once we found an unread child forum, we can drop out of this loop
0484                              $subforum_unread = true;
0485                              break;
0486                          }
0487                      }
0488                  }
0489   
0490                  if ($subforum_row['display'] && $subforum_row['name'])
0491                  {
0492                      $subforums_list[] = array(
0493                          'link'        => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $subforum_id),
0494                          'name'        => $subforum_row['name'],
0495                          'unread'    => $subforum_unread,
0496                          'type'        => $subforum_row['type'],
0497                      );
0498                  }
0499                  else
0500                  {
0501                      unset($subforums[$forum_id][$subforum_id]);
0502                  }
0503   
0504                  // If one subforum is unread the forum gets unread too...
0505                  if ($subforum_unread)
0506                  {
0507                      $forum_unread = true;
0508                  }
0509              }
0510   
0511              $l_subforums = (count($subforums[$forum_id]) == 1) ? $user->lang['SUBFORUM'] : $user->lang['SUBFORUMS'];
0512              $folder_image = ($forum_unread) ? 'forum_unread_subforum' : 'forum_read_subforum';
0513          }
0514          else
0515          {
0516              switch ($row['forum_type'])
0517              {
0518                  case FORUM_POST:
0519                      $folder_image = ($forum_unread) ? 'forum_unread' : 'forum_read';
0520                  break;
0521   
0522                  case FORUM_LINK:
0523                      $folder_image = 'forum_link';
0524                  break;
0525              }
0526          }
0527   
0528          // Which folder should we display?
0529          if ($row['forum_status'] == ITEM_LOCKED)
0530          {
0531              $folder_image = ($forum_unread) ? 'forum_unread_locked' : 'forum_read_locked';
0532              $folder_alt = 'FORUM_LOCKED';
0533          }
0534          else
0535          {
0536              $folder_alt = ($forum_unread) ? 'UNREAD_POSTS' : 'NO_UNREAD_POSTS';
0537          }
0538   
0539          // Create last post link information, if appropriate
0540          if ($row['forum_last_post_id'])
0541          {
0542              if ($row['forum_password_last_post'] === '' && $auth->acl_gets('f_read', 'f_list_topics', $row['forum_id_last_post']))
0543              {
0544                  $last_post_subject = utf8_decode_ncr(censor_text($row['forum_last_post_subject']));
0545   
0546                  $last_post_subject_truncated = truncate_string($last_post_subject, 30, 255, false, $user->lang['ELLIPSIS']);
0547              }
0548              else
0549              {
0550                  $last_post_subject = $last_post_subject_truncated = '';
0551              }
0552              $last_post_time = $user->format_date($row['forum_last_post_time']);
0553              $last_post_time_rfc3339 = gmdate(DATE_RFC3339, $row['forum_last_post_time']);
0554              $last_post_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $row['forum_last_post_id']) . '#p' . $row['forum_last_post_id'];
0555          }
0556          else
0557          {
0558              $last_post_subject = $last_post_time = $last_post_time_rfc3339 = $last_post_url = $last_post_subject_truncated = '';
0559          }
0560   
0561          // Output moderator listing ... if applicable
0562          $l_moderator = $moderators_list = '';
0563          if ($display_moderators && !empty($forum_moderators[$forum_id]))
0564          {
0565              $l_moderator = (count($forum_moderators[$forum_id]) == 1) ? $user->lang['MODERATOR'] : $user->lang['MODERATORS'];
0566              $moderators_list = implode($user->lang['COMMA_SEPARATOR'], $forum_moderators[$forum_id]);
0567          }
0568   
0569          $l_post_click_count = ($row['forum_type'] == FORUM_LINK) ? 'CLICKS' : 'POSTS';
0570          $post_click_count = ($row['forum_type'] != FORUM_LINK || $row['forum_flags'] & FORUM_FLAG_LINK_TRACK) ? $row['forum_posts'] : '';
0571   
0572          $s_subforums_list = $subforums_row = array();
0573          foreach ($subforums_list as $subforum)
0574          {
0575              $s_subforums_list[] = '<a href="' . $subforum['link'] . '" class="subforum ' . (($subforum['unread']) ? 'unread' : 'read') . '" title="' . (($subforum['unread']) ? $user->lang['UNREAD_POSTS'] : $user->lang['NO_UNREAD_POSTS']) . '">' . $subforum['name'] . '</a>';
0576              $subforums_row[] = array(
0577                  'U_SUBFORUM'    => $subforum['link'],
0578                  'SUBFORUM_NAME'    => $subforum['name'],
0579                  'S_UNREAD'        => $subforum['unread'],
0580                  'IS_LINK'        => $subforum['type'] == FORUM_LINK,
0581              );
0582          }
0583          $s_subforums_list = (string) implode($user->lang['COMMA_SEPARATOR'], $s_subforums_list);
0584          $catless = ($row['parent_id'] == $root_data['forum_id']) ? true : false;
0585   
0586          if ($row['forum_type'] != FORUM_LINK)
0587          {
0588              $u_viewforum = append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $row['forum_id']);
0589          }
0590          else
0591          {
0592              // If the forum is a link and we count redirects we need to visit it
0593              // If the forum is having a password or no read access we do not expose the link, but instead handle it in viewforum
0594              if (($row['forum_flags'] & FORUM_FLAG_LINK_TRACK) || $row['forum_password'] || !$auth->acl_get('f_read', $forum_id))
0595              {
0596                  $u_viewforum = append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $row['forum_id']);
0597              }
0598              else
0599              {
0600                  $u_viewforum = $row['forum_link'];
0601              }
0602          }
0603   
0604          $forum_row = array(
0605              'S_IS_CAT'            => false,
0606              'S_NO_CAT'            => $catless && !$last_catless,
0607              'S_IS_LINK'            => ($row['forum_type'] == FORUM_LINK) ? true : false,
0608              'S_UNREAD_FORUM'    => $forum_unread,
0609              'S_AUTH_READ'        => $auth->acl_get('f_read', $row['forum_id']),
0610              'S_LOCKED_FORUM'    => ($row['forum_status'] == ITEM_LOCKED) ? true : false,
0611              'S_LIST_SUBFORUMS'    => ($row['display_subforum_list']) ? true : false,
0612              'S_SUBFORUMS'        => (count($subforums_list)) ? true : false,
0613              'S_DISPLAY_SUBJECT'    =>    ($last_post_subject !== '' && $config['display_last_subject']) ? true : false,
0614              'S_FEED_ENABLED'    => ($config['feed_forum'] && !phpbb_optionget(FORUM_OPTION_FEED_EXCLUDE, $row['forum_options']) && $row['forum_type'] == FORUM_POST) ? true : false,
0615   
0616              'FORUM_ID'                => $row['forum_id'],
0617              'FORUM_NAME'            => $row['forum_name'],
0618              'FORUM_DESC'            => generate_text_for_display($row['forum_desc'], $row['forum_desc_uid'], $row['forum_desc_bitfield'], $row['forum_desc_options']),
0619              'TOPICS'                => $row['forum_topics'],
0620              $l_post_click_count        => $post_click_count,
0621              'FORUM_IMG_STYLE'        => $folder_image,
0622              'FORUM_FOLDER_IMG'        => $user->img($folder_image, $folder_alt),
0623              'FORUM_FOLDER_IMG_ALT'    => isset($user->lang[$folder_alt]) ? $user->lang[$folder_alt] : '',
0624              'FORUM_IMAGE'            => ($row['forum_image']) ? '<img src="' . $phpbb_root_path . $row['forum_image'] . '" alt="' . $user->lang[$folder_alt] . '" />' : '',
0625              'FORUM_IMAGE_SRC'        => ($row['forum_image']) ? $phpbb_root_path . $row['forum_image'] : '',
0626              'LAST_POST_SUBJECT'        => $last_post_subject,
0627              'LAST_POST_SUBJECT_TRUNCATED'    => $last_post_subject_truncated,
0628              'LAST_POST_TIME'        => $last_post_time,
0629              'LAST_POST_TIME_RFC3339'=> $last_post_time_rfc3339,
0630              'LAST_POSTER'            => get_username_string('username', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']),
0631              'LAST_POSTER_COLOUR'    => get_username_string('colour', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']),
0632              'LAST_POSTER_FULL'        => get_username_string('full', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']),
0633              'MODERATORS'            => $moderators_list,
0634              'SUBFORUMS'                => $s_subforums_list,
0635   
0636              'L_SUBFORUM_STR'        => $l_subforums,
0637              'L_MODERATOR_STR'        => $l_moderator,
0638   
0639              'U_UNAPPROVED_TOPICS'    => ($row['forum_id_unapproved_topics']) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&amp;mode=unapproved_topics&amp;f=' . $row['forum_id_unapproved_topics']) : '',
0640              'U_UNAPPROVED_POSTS'    => ($row['forum_id_unapproved_posts']) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&amp;mode=unapproved_posts&amp;f=' . $row['forum_id_unapproved_posts']) : '',
0641              'U_VIEWFORUM'        => $u_viewforum,
0642              'U_LAST_POSTER'        => get_username_string('profile', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']),
0643              'U_LAST_POST'        => $last_post_url,
0644          );
0645   
0646          /**
0647          * Modify the template data block of the forum
0648          *
0649          * This event is triggered once per forum
0650          *
0651          * @event core.display_forums_modify_template_vars
0652          * @var    array    forum_row        Template data of the forum
0653          * @var    array    row                The data of the forum
0654          * @var    array    subforums_row    Template data of subforums
0655          * @since 3.1.0-a1
0656          * @changed 3.1.0-b5 Added var subforums_row
0657          */
0658          $vars = array('forum_row', 'row', 'subforums_row');
0659          extract($phpbb_dispatcher->trigger_event('core.display_forums_modify_template_vars', compact($vars)));
0660   
0661          $template->assign_block_vars('forumrow', $forum_row);
0662   
0663          // Assign subforums loop for style authors
0664          $template->assign_block_vars_array('forumrow.subforum', $subforums_row);
0665   
0666          /**
0667          * Modify and/or assign additional template data for the forum
0668          * after forumrow loop has been assigned. This can be used
0669          * to create additional forumrow subloops in extensions.
0670          *
0671          * This event is triggered once per forum
0672          *
0673          * @event core.display_forums_add_template_data
0674          * @var    array    forum_row        Template data of the forum
0675          * @var    array    row                The data of the forum
0676          * @var    array    subforums_list    The data of subforums
0677          * @var    array    subforums_row    Template data of subforums
0678          * @var    bool    catless            The flag indicating whether a forum has a parent category
0679          * @since 3.1.0-b5
0680          */
0681          $vars = array(
0682              'forum_row',
0683              'row',
0684              'subforums_list',
0685              'subforums_row',
0686              'catless',
0687          );
0688          extract($phpbb_dispatcher->trigger_event('core.display_forums_add_template_data', compact($vars)));
0689   
0690          $last_catless = $catless;
0691      }
0692   
0693      $template->assign_vars(array(
0694          'U_MARK_FORUMS'        => ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'hash=' . generate_link_hash('global') . '&amp;f=' . $root_data['forum_id'] . '&amp;mark=forums&amp;mark_time=' . time()) : '',
0695          'S_HAS_SUBFORUM'    => ($visible_forums) ? true : false,
0696          'L_SUBFORUM'        => ($visible_forums == 1) ? $user->lang['SUBFORUM'] : $user->lang['SUBFORUMS'],
0697          'LAST_POST_IMG'        => $user->img('icon_topic_latest', 'VIEW_LATEST_POST'),
0698          'UNAPPROVED_IMG'    => $user->img('icon_topic_unapproved', 'TOPICS_UNAPPROVED'),
0699          'UNAPPROVED_POST_IMG'    => $user->img('icon_topic_unapproved', 'POSTS_UNAPPROVED_FORUM'),
0700      ));
0701   
0702      /**
0703      * Event to perform additional actions after the forum list has been generated
0704      *
0705      * @event core.display_forums_after
0706      * @var    array    active_forum_ary    Array with forum data to display active topics
0707      * @var    bool    display_moderators    Flag indicating if we display forum moderators
0708      * @var    array    forum_moderators    Array with forum moderators list
0709      * @var    array    forum_rows            Data array of all forums we display
0710      * @var    bool    return_moderators    Flag indicating if moderators list should be returned
0711      * @var    array    root_data            Array with the root forum data
0712      * @since 3.1.0-RC5
0713      */
0714      $vars = array(
0715          'active_forum_ary',
0716          'display_moderators',
0717          'forum_moderators',
0718          'forum_rows',
0719          'return_moderators',
0720          'root_data',
0721      );
0722      extract($phpbb_dispatcher->trigger_event('core.display_forums_after', compact($vars)));
0723   
0724      if ($return_moderators)
0725      {
0726          return array($active_forum_ary, $forum_moderators);
0727      }
0728   
0729      return array($active_forum_ary, array());
0730  }
0731   
0732  /**
0733  * Create forum rules for given forum
0734  */
0735  function generate_forum_rules(&$forum_data)
0736  {
0737      if ($forum_data['forum_rules'])
0738      {
0739          $forum_data['forum_rules'] = generate_text_for_display($forum_data['forum_rules'], $forum_data['forum_rules_uid'], $forum_data['forum_rules_bitfield'], $forum_data['forum_rules_options']);
0740      }
0741   
0742      if (!$forum_data['forum_rules'] && !$forum_data['forum_rules_link'])
0743      {
0744          return;
0745      }
0746   
0747      global $template;
0748   
0749      $template->assign_vars(array(
0750          'S_FORUM_RULES'    => true,
0751          'U_FORUM_RULES'    => $forum_data['forum_rules_link'],
0752          'FORUM_RULES'    => $forum_data['forum_rules'])
0753      );
0754  }
0755   
0756  /**
0757  * Create forum navigation links for given forum, create parent
0758  * list if currently null, assign basic forum info to template
0759  */
0760  function generate_forum_nav(&$forum_data_ary)
0761  {
0762      global $template, $auth, $config;
0763      global $phpEx, $phpbb_root_path, $phpbb_dispatcher;
0764   
0765      if (!$auth->acl_get('f_list', $forum_data_ary['forum_id']))
0766      {
0767          return;
0768      }
0769   
0770      $navlinks_parents = $forum_template_data = array();
0771   
0772      // Get forum parents
0773      $forum_parents = get_forum_parents($forum_data_ary);
0774   
0775      $microdata_attr = 'data-forum-id';
0776   
0777      // Build navigation links
0778      if (!empty($forum_parents))
0779      {
0780          foreach ($forum_parents as $parent_forum_id => $parent_data)
0781          {
0782              list($parent_name, $parent_type) = array_values($parent_data);
0783   
0784              // Skip this parent if the user does not have the permission to view it
0785              if (!$auth->acl_get('f_list', $parent_forum_id))
0786              {
0787                  continue;
0788              }
0789   
0790              $navlinks_parents[] = array(
0791                  'S_IS_CAT'            => ($parent_type == FORUM_CAT) ? true : false,
0792                  'S_IS_LINK'            => ($parent_type == FORUM_LINK) ? true : false,
0793                  'S_IS_POST'            => ($parent_type == FORUM_POST) ? true : false,
0794                  'BREADCRUMB_NAME'    => $parent_name,
0795                  'FORUM_ID'            => $parent_forum_id,
0796                  'MICRODATA'            => $microdata_attr . '="' . $parent_forum_id . '"',
0797                  'U_BREADCRUMB'        => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $parent_forum_id),
0798              );
0799          }
0800      }
0801   
0802      $navlinks = array(
0803          'S_IS_CAT'            => ($forum_data_ary['forum_type'] == FORUM_CAT) ? true : false,
0804          'S_IS_LINK'            => ($forum_data_ary['forum_type'] == FORUM_LINK) ? true : false,
0805          'S_IS_POST'            => ($forum_data_ary['forum_type'] == FORUM_POST) ? true : false,
0806          'BREADCRUMB_NAME'    => $forum_data_ary['forum_name'],
0807          'FORUM_ID'            => $forum_data_ary['forum_id'],
0808          'MICRODATA'            => $microdata_attr . '="' . $forum_data_ary['forum_id'] . '"',
0809          'U_BREADCRUMB'        => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_data_ary['forum_id']),
0810      );
0811   
0812      $forum_template_data = array(
0813          'FORUM_ID'         => $forum_data_ary['forum_id'],
0814          'FORUM_NAME'    => $forum_data_ary['forum_name'],
0815          'FORUM_DESC'    => generate_text_for_display($forum_data_ary['forum_desc'], $forum_data_ary['forum_desc_uid'], $forum_data_ary['forum_desc_bitfield'], $forum_data_ary['forum_desc_options']),
0816   
0817          'S_ENABLE_FEEDS_FORUM'    => ($config['feed_forum'] && $forum_data_ary['forum_type'] == FORUM_POST && !phpbb_optionget(FORUM_OPTION_FEED_EXCLUDE, $forum_data_ary['forum_options'])) ? true : false,
0818      );
0819   
0820      $forum_data = $forum_data_ary;
0821      /**
0822      * Event to modify the navlinks text
0823      *
0824      * @event core.generate_forum_nav
0825      * @var    array    forum_data                Array with the forum data
0826      * @var    array    forum_template_data        Array with generic forum template data
0827      * @var    string    microdata_attr            The microdata attribute
0828      * @var    array    navlinks_parents        Array with the forum parents navlinks data
0829      * @var    array    navlinks                Array with the forum navlinks data
0830      * @since 3.1.5-RC1
0831      */
0832      $vars = array(
0833          'forum_data',
0834          'forum_template_data',
0835          'microdata_attr',
0836          'navlinks_parents',
0837          'navlinks',
0838      );
0839      extract($phpbb_dispatcher->trigger_event('core.generate_forum_nav', compact($vars)));
0840      $forum_data_ary = $forum_data;
0841      unset($forum_data);
0842   
0843      $template->assign_block_vars_array('navlinks', $navlinks_parents);
0844      $template->assign_block_vars('navlinks', $navlinks);
0845      $template->assign_vars($forum_template_data);
0846   
0847      return;
0848  }
0849   
0850  /**
0851  * Returns forum parents as an array. Get them from forum_data if available, or update the database otherwise
0852  */
0853  function get_forum_parents(&$forum_data)
0854  {
0855      global $db;
0856   
0857      $forum_parents = array();
0858   
0859      if ($forum_data['parent_id'] > 0)
0860      {
0861          if ($forum_data['forum_parents'] == '')
0862          {
0863              $sql = 'SELECT forum_id, forum_name, forum_type
0864                  FROM ' . FORUMS_TABLE . '
0865                  WHERE left_id < ' . $forum_data['left_id'] . '
0866                      AND right_id > ' . $forum_data['right_id'] . '
0867                  ORDER BY left_id ASC';
0868              $result = $db->sql_query($sql);
0869   
0870              while ($row = $db->sql_fetchrow($result))
0871              {
0872                  $forum_parents[$row['forum_id']] = array($row['forum_name'], (int) $row['forum_type']);
0873              }
0874              $db->sql_freeresult($result);
0875   
0876              $forum_data['forum_parents'] = serialize($forum_parents);
0877   
0878              $sql = 'UPDATE ' . FORUMS_TABLE . "
0879                  SET forum_parents = '" . $db->sql_escape($forum_data['forum_parents']) . "'
0880                  WHERE parent_id = " . $forum_data['parent_id'];
0881              $db->sql_query($sql);
0882          }
0883          else
0884          {
0885              $forum_parents = unserialize($forum_data['forum_parents']);
0886          }
0887      }
0888   
0889      return $forum_parents;
0890  }
0891   
0892  /**
0893  * Obtain list of moderators of each forum
0894  */
0895  function get_moderators(&$forum_moderators, $forum_id = false)
0896  {
0897      global $db, $phpbb_root_path, $phpEx, $user, $auth;
0898      global $phpbb_container;
0899   
0900      $forum_id_ary = array();
0901   
0902      if ($forum_id !== false)
0903      {
0904          if (!is_array($forum_id))
0905          {
0906              $forum_id = array($forum_id);
0907          }
0908   
0909          // Exchange key/value pair to be able to faster check for the forum id existence
0910          $forum_id_ary = array_flip($forum_id);
0911      }
0912   
0913      $sql_array = array(
0914          'SELECT'    => 'm.*, u.user_colour, g.group_colour, g.group_type',
0915   
0916          'FROM'        => array(
0917              MODERATOR_CACHE_TABLE    => 'm',
0918          ),
0919   
0920          'LEFT_JOIN'    => array(
0921              array(
0922                  'FROM'    => array(USERS_TABLE => 'u'),
0923                  'ON'    => 'm.user_id = u.user_id',
0924              ),
0925              array(
0926                  'FROM'    => array(GROUPS_TABLE => 'g'),
0927                  'ON'    => 'm.group_id = g.group_id',
0928              ),
0929          ),
0930   
0931          'WHERE'        => 'm.display_on_index = 1',
0932      );
0933   
0934      /** @var \phpbb\group\helper $group_helper */
0935      $group_helper = $phpbb_container->get('group_helper');
0936   
0937      // We query every forum here because for caching we should not have any parameter.
0938      $sql = $db->sql_build_query('SELECT', $sql_array);
0939      $result = $db->sql_query($sql, 3600);
0940   
0941      while ($row = $db->sql_fetchrow($result))
0942      {
0943          $f_id = (int) $row['forum_id'];
0944   
0945          if (!isset($forum_id_ary[$f_id]))
0946          {
0947              continue;
0948          }
0949   
0950          if (!empty($row['user_id']))
0951          {
0952              $forum_moderators[$f_id][] = get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']);
0953          }
0954          else
0955          {
0956              $group_name = $group_helper->get_name($row['group_name']);
0957   
0958              if ($user->data['user_id'] != ANONYMOUS && !$auth->acl_get('u_viewprofile'))
0959              {
0960                  $forum_moderators[$f_id][] = '<span' . (($row['group_colour']) ? ' style="color:#' . $row['group_colour'] . ';"' : '') . '>' . $group_name . '</span>';
0961              }
0962              else
0963              {
0964                  $forum_moderators[$f_id][] = '<a' . (($row['group_colour']) ? ' style="color:#' . $row['group_colour'] . ';"' : '') . ' href="' . append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=group&amp;g=' . $row['group_id']) . '">' . $group_name . '</a>';
0965              }
0966          }
0967      }
0968      $db->sql_freeresult($result);
0969   
0970      return;
0971  }
0972   
0973  /**
0974  * User authorisation levels output
0975  *
0976  * @param    string    $mode            Can be forum or topic. Not in use at the moment.
0977  * @param    int        $forum_id        The current forum the user is in.
0978  * @param    int        $forum_status    The forums status bit.
0979  */
0980  function gen_forum_auth_level($mode, $forum_id, $forum_status)
0981  {
0982      global $template, $auth, $user, $config;
0983   
0984      $locked = ($forum_status == ITEM_LOCKED && !$auth->acl_get('m_edit', $forum_id)) ? true : false;
0985   
0986      $rules = array(
0987          ($auth->acl_get('f_post', $forum_id) && !$locked) ? $user->lang['RULES_POST_CAN'] : $user->lang['RULES_POST_CANNOT'],
0988          ($auth->acl_get('f_reply', $forum_id) && !$locked) ? $user->lang['RULES_REPLY_CAN'] : $user->lang['RULES_REPLY_CANNOT'],
0989          ($user->data['is_registered'] && $auth->acl_gets('f_edit', 'm_edit', $forum_id) && !$locked) ? $user->lang['RULES_EDIT_CAN'] : $user->lang['RULES_EDIT_CANNOT'],
0990          ($user->data['is_registered'] && ($auth->acl_gets('f_delete', 'm_delete', $forum_id) || $auth->acl_gets('f_softdelete', 'm_softdelete', $forum_id)) && !$locked) ? $user->lang['RULES_DELETE_CAN'] : $user->lang['RULES_DELETE_CANNOT'],
0991      );
0992   
0993      if ($config['allow_attachments'])
0994      {
0995          $rules[] = ($auth->acl_get('f_attach', $forum_id) && $auth->acl_get('u_attach') && !$locked) ? $user->lang['RULES_ATTACH_CAN'] : $user->lang['RULES_ATTACH_CANNOT'];
0996      }
0997   
0998      foreach ($rules as $rule)
0999      {
1000          $template->assign_block_vars('rules', array('RULE' => $rule));
1001      }
1002   
1003      return;
1004  }
1005   
1006  /**
1007  * Generate topic status
1008  */
1009  function topic_status(&$topic_row, $replies, $unread_topic, &$folder_img, &$folder_alt, &$topic_type)
1010  {
1011      global $user, $config;
1012   
1013      if ($topic_row['topic_status'] == ITEM_MOVED)
1014      {
1015          $topic_type = $user->lang['VIEW_TOPIC_MOVED'];
1016          $folder_img = 'topic_moved';
1017          $folder_alt = 'TOPIC_MOVED';
1018      }
1019      else
1020      {
1021          switch ($topic_row['topic_type'])
1022          {
1023              case POST_GLOBAL:
1024                  $topic_type = $user->lang['VIEW_TOPIC_GLOBAL'];
1025                  $folder = 'global_read';
1026                  $folder_new = 'global_unread';
1027              break;
1028   
1029              case POST_ANNOUNCE:
1030                  $topic_type = $user->lang['VIEW_TOPIC_ANNOUNCEMENT'];
1031                  $folder = 'announce_read';
1032                  $folder_new = 'announce_unread';
1033              break;
1034   
1035              case POST_STICKY:
1036                  $topic_type = $user->lang['VIEW_TOPIC_STICKY'];
1037                  $folder = 'sticky_read';
1038                  $folder_new = 'sticky_unread';
1039              break;
1040   
1041              default:
1042                  $topic_type = '';
1043                  $folder = 'topic_read';
1044                  $folder_new = 'topic_unread';
1045   
1046                  // Hot topic threshold is for posts in a topic, which is replies + the first post. ;)
1047                  if ($config['hot_threshold'] && ($replies + 1) >= $config['hot_threshold'] && $topic_row['topic_status'] != ITEM_LOCKED)
1048                  {
1049                      $folder .= '_hot';
1050                      $folder_new .= '_hot';
1051                  }
1052              break;
1053          }
1054   
1055          if ($topic_row['topic_status'] == ITEM_LOCKED)
1056          {
1057              $topic_type = $user->lang['VIEW_TOPIC_LOCKED'];
1058              $folder .= '_locked';
1059              $folder_new .= '_locked';
1060          }
1061   
1062          $folder_img = ($unread_topic) ? $folder_new : $folder;
1063          $folder_alt = ($unread_topic) ? 'UNREAD_POSTS' : (($topic_row['topic_status'] == ITEM_LOCKED) ? 'TOPIC_LOCKED' : 'NO_UNREAD_POSTS');
1064   
1065          // Posted image?
1066          if (!empty($topic_row['topic_posted']) && $topic_row['topic_posted'])
1067          {
1068              $folder_img .= '_mine';
1069          }
1070      }
1071   
1072      if ($topic_row['poll_start'] && $topic_row['topic_status'] != ITEM_MOVED)
1073      {
1074          $topic_type = $user->lang['VIEW_TOPIC_POLL'];
1075      }
1076  }
1077   
1078  /**
1079  * Assign/Build custom bbcodes for display in screens supporting using of bbcodes
1080  * The custom bbcodes buttons will be placed within the template block 'custom_tags'
1081  */
1082  function display_custom_bbcodes()
1083  {
1084      global $db, $template, $user, $phpbb_dispatcher;
1085   
1086      // Start counting from 22 for the bbcode ids (every bbcode takes two ids - opening/closing)
1087      $num_predefined_bbcodes = NUM_PREDEFINED_BBCODES;
1088   
1089      $sql_ary = [
1090          'SELECT'    => 'b.bbcode_id, b.bbcode_tag, b.bbcode_helpline, b.bbcode_match',
1091          'FROM'        => [BBCODES_TABLE => 'b'],
1092          'WHERE'        => 'b.display_on_posting = 1',
1093          'ORDER_BY'    => 'b.bbcode_tag',
1094      ];
1095   
1096      /**
1097      * Event to modify the SQL query before custom bbcode data is queried
1098      *
1099      * @event core.display_custom_bbcodes_modify_sql
1100      * @var    array    sql_ary                    The SQL array to get the bbcode data
1101      * @var    int        num_predefined_bbcodes    The number of predefined core bbcodes
1102      *                                        (multiplied by factor of 2)
1103      * @since 3.1.0-a3
1104      */
1105      $vars = array('sql_ary', 'num_predefined_bbcodes');
1106      extract($phpbb_dispatcher->trigger_event('core.display_custom_bbcodes_modify_sql', compact($vars)));
1107   
1108      $result = $db->sql_query($db->sql_build_query('SELECT', $sql_ary));
1109   
1110      $i = 0;
1111      while ($row = $db->sql_fetchrow($result))
1112      {
1113          // If the helpline is defined within the language file, we will use the localised version, else just use the database entry...
1114          if (isset($user->lang[strtoupper($row['bbcode_helpline'])]))
1115          {
1116              $row['bbcode_helpline'] = $user->lang[strtoupper($row['bbcode_helpline'])];
1117          }
1118   
1119          // Convert Numeric Character References to UTF-8 chars.
1120          $row['bbcode_helpline'] = utf8_decode_ncr($row['bbcode_helpline']);
1121   
1122          // Does the closing bbcode tag exists? If so display it.
1123          $bbcode_close_tag    = '%\[\/' . utf8_strtolower($row['bbcode_tag']) . '\]%';
1124          $bbcode_match_str    = utf8_strtolower($row['bbcode_match']);
1125          $bbcode_name_clean    = preg_match($bbcode_close_tag, $bbcode_match_str) ? "'[{$row['bbcode_tag']}]', '[/" . str_replace('=', '', $row['bbcode_tag']) . "]'" : "'[{$row['bbcode_tag']}]', ''";
1126   
1127          $custom_tags = [
1128              'BBCODE_NAME'        => $bbcode_name_clean,
1129              'BBCODE_ID'            => $num_predefined_bbcodes + ($i * 2),
1130              'BBCODE_TAG'        => $row['bbcode_tag'],
1131              'BBCODE_TAG_CLEAN'    => str_replace('=', '-', $row['bbcode_tag']),
1132              'BBCODE_HELPLINE'    => $row['bbcode_helpline'],
1133          ];
1134   
1135          /**
1136          * Event to modify the template data block of a custom bbcode
1137          *
1138          * This event is triggered once per bbcode
1139          *
1140          * @event core.display_custom_bbcodes_modify_row
1141          * @var    array    custom_tags        Template data of the bbcode
1142          * @var    array    row                The data of the bbcode
1143          * @since 3.1.0-a1
1144          */
1145          $vars = array('custom_tags', 'row');
1146          extract($phpbb_dispatcher->trigger_event('core.display_custom_bbcodes_modify_row', compact($vars)));
1147   
1148          $template->assign_block_vars('custom_tags', $custom_tags);
1149   
1150          $i++;
1151      }
1152      $db->sql_freeresult($result);
1153   
1154      /**
1155      * Display custom bbcodes
1156      *
1157      * @event core.display_custom_bbcodes
1158      * @since 3.1.0-a1
1159      */
1160      $phpbb_dispatcher->dispatch('core.display_custom_bbcodes');
1161  }
1162   
1163  /**
1164  * Display user activity (action forum/topic)
1165  */
1166  function display_user_activity(&$userdata_ary)
1167  {
1168      global $auth, $template, $db, $user, $config;
1169      global $phpbb_root_path, $phpEx;
1170      global $phpbb_container, $phpbb_dispatcher;
1171   
1172      // Do not display user activity for users having too many posts...
1173      $limit = $config['load_user_activity_limit'];
1174      if ($userdata_ary['user_posts'] > $limit && $limit != 0)
1175      {
1176          return;
1177      }
1178   
1179      $forum_ary = array();
1180   
1181      $forum_read_ary = $auth->acl_getf('f_read');
1182      foreach ($forum_read_ary as $forum_id => $allowed)
1183      {
1184          if ($allowed['f_read'])
1185          {
1186              $forum_ary[] = (int) $forum_id;
1187          }
1188      }
1189   
1190      $forum_ary = array_diff($forum_ary, $user->get_passworded_forums());
1191   
1192      $active_f_row = $active_t_row = array();
1193      if (!empty($forum_ary))
1194      {
1195          /* @var $phpbb_content_visibility \phpbb\content_visibility */
1196          $phpbb_content_visibility = $phpbb_container->get('content.visibility');
1197   
1198          // Obtain active forum
1199          $sql = 'SELECT forum_id, COUNT(post_id) AS num_posts
1200              FROM ' . POSTS_TABLE . '
1201              WHERE poster_id = ' . $userdata_ary['user_id'] . '
1202                  AND post_postcount = 1
1203                  AND ' . $phpbb_content_visibility->get_forums_visibility_sql('post', $forum_ary) . '
1204              GROUP BY forum_id
1205              ORDER BY num_posts DESC';
1206          $result = $db->sql_query_limit($sql, 1);
1207          $active_f_row = $db->sql_fetchrow($result);
1208          $db->sql_freeresult($result);
1209   
1210          if (!empty($active_f_row))
1211          {
1212              $sql = 'SELECT forum_name
1213                  FROM ' . FORUMS_TABLE . '
1214                  WHERE forum_id = ' . $active_f_row['forum_id'];
1215              $result = $db->sql_query($sql, 3600);
1216              $active_f_row['forum_name'] = (string) $db->sql_fetchfield('forum_name');
1217              $db->sql_freeresult($result);
1218          }
1219   
1220          // Obtain active topic
1221          $sql = 'SELECT topic_id, COUNT(post_id) AS num_posts
1222              FROM ' . POSTS_TABLE . '
1223              WHERE poster_id = ' . $userdata_ary['user_id'] . '
1224                  AND post_postcount = 1
1225                  AND ' . $phpbb_content_visibility->get_forums_visibility_sql('post', $forum_ary) . '
1226              GROUP BY topic_id
1227              ORDER BY num_posts DESC';
1228          $result = $db->sql_query_limit($sql, 1);
1229          $active_t_row = $db->sql_fetchrow($result);
1230          $db->sql_freeresult($result);
1231   
1232          if (!empty($active_t_row))
1233          {
1234              $sql = 'SELECT topic_title
1235                  FROM ' . TOPICS_TABLE . '
1236                  WHERE topic_id = ' . $active_t_row['topic_id'];
1237              $result = $db->sql_query($sql);
1238              $active_t_row['topic_title'] = (string) $db->sql_fetchfield('topic_title');
1239              $db->sql_freeresult($result);
1240          }
1241      }
1242   
1243      $userdata = $userdata_ary;
1244      $show_user_activity = true;
1245      /**
1246      * Alter list of forums and topics to display as active
1247      *
1248      * @event core.display_user_activity_modify_actives
1249      * @var    array    userdata                        User's data
1250      * @var    array    active_f_row                    List of active forums
1251      * @var    array    active_t_row                    List of active posts
1252      * @var    bool    show_user_activity                Show user forum and topic activity
1253      * @since 3.1.0-RC3
1254      * @changed 3.2.5-RC1 Added show_user_activity into event
1255      */
1256      $vars = array('userdata', 'active_f_row', 'active_t_row', 'show_user_activity');
1257      extract($phpbb_dispatcher->trigger_event('core.display_user_activity_modify_actives', compact($vars)));
1258      $userdata_ary = $userdata;
1259      unset($userdata);
1260   
1261      $userdata_ary['active_t_row'] = $active_t_row;
1262      $userdata_ary['active_f_row'] = $active_f_row;
1263   
1264      $active_f_name = $active_f_id = $active_f_count = $active_f_pct = '';
1265      if (!empty($active_f_row['num_posts']))
1266      {
1267          $active_f_name = $active_f_row['forum_name'];
1268          $active_f_id = $active_f_row['forum_id'];
1269          $active_f_count = $active_f_row['num_posts'];
1270          $active_f_pct = ($userdata_ary['user_posts']) ? ($active_f_count / $userdata_ary['user_posts']) * 100 : 0;
1271      }
1272   
1273      $active_t_name = $active_t_id = $active_t_count = $active_t_pct = '';
1274      if (!empty($active_t_row['num_posts']))
1275      {
1276          $active_t_name = $active_t_row['topic_title'];
1277          $active_t_id = $active_t_row['topic_id'];
1278          $active_t_count = $active_t_row['num_posts'];
1279          $active_t_pct = ($userdata_ary['user_posts']) ? ($active_t_count / $userdata_ary['user_posts']) * 100 : 0;
1280      }
1281   
1282      $l_active_pct = ($userdata_ary['user_id'] != ANONYMOUS && $userdata_ary['user_id'] == $user->data['user_id']) ? $user->lang['POST_PCT_ACTIVE_OWN'] : $user->lang['POST_PCT_ACTIVE'];
1283   
1284      $template->assign_vars(array(
1285          'ACTIVE_FORUM'            => $active_f_name,
1286          'ACTIVE_FORUM_POSTS'    => $user->lang('USER_POSTS', (int) $active_f_count),
1287          'ACTIVE_FORUM_PCT'        => sprintf($l_active_pct, $active_f_pct),
1288          'ACTIVE_TOPIC'            => censor_text($active_t_name),
1289          'ACTIVE_TOPIC_POSTS'    => $user->lang('USER_POSTS', (int) $active_t_count),
1290          'ACTIVE_TOPIC_PCT'        => sprintf($l_active_pct, $active_t_pct),
1291          'U_ACTIVE_FORUM'        => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $active_f_id),
1292          'U_ACTIVE_TOPIC'        => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 't=' . $active_t_id),
1293          'S_SHOW_ACTIVITY'        => $show_user_activity)
1294      );
1295  }
1296   
1297  /**
1298  * Topic and forum watching common code
1299  */
1300  function watch_topic_forum($mode, &$s_watching, $user_id, $forum_id, $topic_id, $notify_status = 'unset', $start = 0, $item_title = '')
1301  {
1302      global $db, $user, $phpEx, $start, $phpbb_root_path;
1303      global $request;
1304   
1305      $table_sql = ($mode == 'forum') ? FORUMS_WATCH_TABLE : TOPICS_WATCH_TABLE;
1306      $where_sql = ($mode == 'forum') ? 'forum_id' : 'topic_id';
1307      $match_id = ($mode == 'forum') ? $forum_id : $topic_id;
1308      $u_url = "uid={$user->data['user_id']}";
1309      $u_url .= ($mode == 'forum') ? '&amp;f' : '&amp;f=' . $forum_id . '&amp;t';
1310      $is_watching = 0;
1311   
1312      // Is user watching this topic?
1313      if ($user_id != ANONYMOUS)
1314      {
1315          $can_watch = true;
1316   
1317          if ($notify_status == 'unset')
1318          {
1319              $sql = "SELECT notify_status
1320                  FROM $table_sql
1321                  WHERE $where_sql = $match_id
1322                      AND user_id = $user_id";
1323              $result = $db->sql_query($sql);
1324   
1325              $notify_status = ($row = $db->sql_fetchrow($result)) ? $row['notify_status'] : NULL;
1326              $db->sql_freeresult($result);
1327          }
1328   
1329          if (!is_null($notify_status) && $notify_status !== '')
1330          {
1331              if (isset($_GET['unwatch']))
1332              {
1333                  $uid = $request->variable('uid', 0);
1334                  $token = $request->variable('hash', '');
1335   
1336                  if ($token && check_link_hash($token, "{$mode}_$match_id") || confirm_box(true))
1337                  {
1338                      if ($uid != $user_id || $request->variable('unwatch', '', false, \phpbb\request\request_interface::GET) != $mode)
1339                      {
1340                          $redirect_url = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&amp;start=$start");
1341                          $message = $user->lang['ERR_UNWATCHING'];
1342   
1343                          if (!$request->is_ajax())
1344                          {
1345                              $message .= '<br /><br />' . $user->lang('RETURN_' . strtoupper($mode), '<a href="' . $redirect_url . '">', '</a>');
1346                          }
1347                          trigger_error($message);
1348                      }
1349   
1350                      $sql = 'DELETE FROM ' . $table_sql . "
1351                          WHERE $where_sql = $match_id
1352                              AND user_id = $user_id";
1353                      $db->sql_query($sql);
1354   
1355                      $redirect_url = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&amp;start=$start");
1356                      $message = $user->lang['NOT_WATCHING_' . strtoupper($mode)];
1357   
1358                      if (!$request->is_ajax())
1359                      {
1360                          $message .= '<br /><br />' . $user->lang('RETURN_' . strtoupper($mode), '<a href="' . $redirect_url . '">', '</a>');
1361                      }
1362                      meta_refresh(3, $redirect_url);
1363                      trigger_error($message);
1364                  }
1365                  else
1366                  {
1367                      $s_hidden_fields = array(
1368                          'uid'        => $user->data['user_id'],
1369                          'unwatch'    => $mode,
1370                          'start'        => $start,
1371                          'f'            => $forum_id,
1372                      );
1373                      if ($mode != 'forum')
1374                      {
1375                          $s_hidden_fields['t'] = $topic_id;
1376                      }
1377   
1378                      if ($item_title == '')
1379                      {
1380                          $confirm_box_message = 'UNWATCH_' . strtoupper($mode);
1381                      }
1382                      else
1383                      {
1384                          $confirm_box_message = $user->lang('UNWATCH_' . strtoupper($mode) . '_DETAILED', $item_title);
1385                      }
1386                      confirm_box(false, $confirm_box_message, build_hidden_fields($s_hidden_fields));
1387                  }
1388              }
1389              else
1390              {
1391                  $is_watching = true;
1392   
1393                  if ($notify_status != NOTIFY_YES)
1394                  {
1395                      $sql = 'UPDATE ' . $table_sql . "
1396                          SET notify_status = " . NOTIFY_YES . "
1397                          WHERE $where_sql = $match_id
1398                              AND user_id = $user_id";
1399                      $db->sql_query($sql);
1400                  }
1401              }
1402          }
1403          else
1404          {
1405              if (isset($_GET['watch']))
1406              {
1407                  $uid = $request->variable('uid', 0);
1408                  $token = $request->variable('hash', '');
1409   
1410                  if ($token && check_link_hash($token, "{$mode}_$match_id") || confirm_box(true))
1411                  {
1412                      if ($uid != $user_id || $request->variable('watch', '', false, \phpbb\request\request_interface::GET) != $mode)
1413                      {
1414                          $redirect_url = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&amp;start=$start");
1415                          $message = $user->lang['ERR_WATCHING'];
1416   
1417                          if (!$request->is_ajax())
1418                          {
1419                              $message .= '<br /><br />' . $user->lang('RETURN_' . strtoupper($mode), '<a href="' . $redirect_url . '">', '</a>');
1420                          }
1421                          trigger_error($message);
1422                      }
1423   
1424                      $is_watching = true;
1425   
1426                      $sql = 'INSERT INTO ' . $table_sql . " (user_id, $where_sql, notify_status)
1427                          VALUES ($user_id$match_id" . NOTIFY_YES . ')';
1428                      $db->sql_query($sql);
1429   
1430                      $redirect_url = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&amp;start=$start");
1431                      $message = $user->lang['ARE_WATCHING_' . strtoupper($mode)];
1432   
1433                      if (!$request->is_ajax())
1434                      {
1435                          $message .= '<br /><br />' . $user->lang('RETURN_' . strtoupper($mode), '<a href="' . $redirect_url . '">', '</a>');
1436                      }
1437                      meta_refresh(3, $redirect_url);
1438                      trigger_error($message);
1439                  }
1440                  else
1441                  {
1442                      $s_hidden_fields = array(
1443                          'uid'        => $user->data['user_id'],
1444                          'watch'        => $mode,
1445                          'start'        => $start,
1446                          'f'            => $forum_id,
1447                      );
1448                      if ($mode != 'forum')
1449                      {
1450                          $s_hidden_fields['t'] = $topic_id;
1451                      }
1452   
1453                      $confirm_box_message = (($item_title == '') ? 'WATCH_' . strtoupper($mode) : $user->lang('WATCH_' . strtoupper($mode) . '_DETAILED', $item_title));
1454                      confirm_box(false, $confirm_box_message, build_hidden_fields($s_hidden_fields));
1455                  }
1456              }
1457              else
1458              {
1459                  $is_watching = 0;
1460              }
1461          }
1462      }
1463      else
1464      {
1465          if ((isset($_GET['unwatch']) && $request->variable('unwatch', '', false, \phpbb\request\request_interface::GET) == $mode) ||
1466              (isset($_GET['watch']) && $request->variable('watch', '', false, \phpbb\request\request_interface::GET) == $mode))
1467          {
1468              login_box();
1469          }
1470          else
1471          {
1472              $can_watch = 0;
1473              $is_watching = 0;
1474          }
1475      }
1476   
1477      if ($can_watch)
1478      {
1479          $s_watching['link'] = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&amp;" . (($is_watching) ? 'unwatch' : 'watch') . "=$mode&amp;start=$start&amp;hash=" . generate_link_hash("{$mode}_$match_id"));
1480          $s_watching['link_toggle'] = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&amp;" . ((!$is_watching) ? 'unwatch' : 'watch') . "=$mode&amp;start=$start&amp;hash=" . generate_link_hash("{$mode}_$match_id"));
1481          $s_watching['title'] = $user->lang[(($is_watching) ? 'STOP' : 'START') . '_WATCHING_' . strtoupper($mode)];
1482          $s_watching['title_toggle'] = $user->lang[((!$is_watching) ? 'STOP' : 'START') . '_WATCHING_' . strtoupper($mode)];
1483          $s_watching['is_watching'] = $is_watching;
1484      }
1485   
1486      return;
1487  }
1488   
1489  /**
1490  * Get user rank title and image
1491  *
1492  * @param array $user_data the current stored users data
1493  * @param int $user_posts the users number of posts
1494  *
1495  * @return array An associative array containing the rank title (title), the rank image as full img tag (img) and the rank image source (img_src)
1496  *
1497  * Note: since we do not want to break backwards-compatibility, this function will only properly assign ranks to guests if you call it for them with user_posts == false
1498  */
1499  function phpbb_get_user_rank($user_data, $user_posts)
1500  {
1501      global $ranks, $config, $phpbb_root_path, $phpbb_path_helper, $phpbb_dispatcher;
1502   
1503      $user_rank_data = array(
1504          'title'        => null,
1505          'img'        => null,
1506          'img_src'    => null,
1507      );
1508   
1509      /**
1510      * Preparing a user's rank before displaying
1511      *
1512      * @event core.modify_user_rank
1513      * @var    array    user_data        Array with user's data
1514      * @var    int        user_posts        User_posts to change
1515      * @since 3.1.0-RC4
1516      */
1517   
1518      $vars = array('user_data', 'user_posts');
1519      extract($phpbb_dispatcher->trigger_event('core.modify_user_rank', compact($vars)));
1520   
1521      if (empty($ranks))
1522      {
1523          global $cache;
1524          $ranks = $cache->obtain_ranks();
1525      }
1526   
1527      if (!empty($user_data['user_rank']))
1528      {
1529   
1530          $user_rank_data['title'] = (isset($ranks['special'][$user_data['user_rank']]['rank_title'])) ? $ranks['special'][$user_data['user_rank']]['rank_title'] : '';
1531   
1532          $user_rank_data['img_src'] = (!empty($ranks['special'][$user_data['user_rank']]['rank_image'])) ? $phpbb_path_helper->update_web_root_path($phpbb_root_path . $config['ranks_path'] . '/' . $ranks['special'][$user_data['user_rank']]['rank_image']) : '';
1533   
1534          $user_rank_data['img'] = (!empty($ranks['special'][$user_data['user_rank']]['rank_image'])) ? '<img src="' . $user_rank_data['img_src'] . '" alt="' . $ranks['special'][$user_data['user_rank']]['rank_title'] . '" title="' . $ranks['special'][$user_data['user_rank']]['rank_title'] . '" />' : '';
1535      }
1536      else if ($user_posts !== false)
1537      {
1538          if (!empty($ranks['normal']))
1539          {
1540              foreach ($ranks['normal'] as $rank)
1541              {
1542                  if ($user_posts >= $rank['rank_min'])
1543                  {
1544                      $user_rank_data['title'] = $rank['rank_title'];
1545                      $user_rank_data['img_src'] = (!empty($rank['rank_image'])) ? $phpbb_path_helper->update_web_root_path($phpbb_root_path . $config['ranks_path'] . '/' . $rank['rank_image']) : '';
1546                      $user_rank_data['img'] = (!empty($rank['rank_image'])) ? '<img src="' . $user_rank_data['img_src'] . '" alt="' . $rank['rank_title'] . '" title="' . $rank['rank_title'] . '" />' : '';
1547                      break;
1548                  }
1549              }
1550          }
1551      }
1552   
1553      /**
1554      * Modify a user's rank before displaying
1555      *
1556      * @event core.get_user_rank_after
1557      * @var    array    user_data        Array with user's data
1558      * @var    int        user_posts        User_posts to change
1559      * @var    array    user_rank_data    User rank data
1560      * @since 3.1.11-RC1
1561      */
1562   
1563      $vars = array(
1564          'user_data',
1565          'user_posts',
1566          'user_rank_data',
1567      );
1568      extract($phpbb_dispatcher->trigger_event('core.get_user_rank_after', compact($vars)));
1569   
1570      return $user_rank_data;
1571  }
1572   
1573  /**
1574  * Prepare profile data
1575  */
1576  function phpbb_show_profile($data, $user_notes_enabled = false, $warn_user_enabled = false, $check_can_receive_pm = true)
1577  {
1578      global $config, $auth, $user, $phpEx, $phpbb_root_path, $phpbb_dispatcher;
1579   
1580      $username = $data['username'];
1581      $user_id = $data['user_id'];
1582   
1583      $user_rank_data = phpbb_get_user_rank($data, (($user_id == ANONYMOUS) ? false : $data['user_posts']));
1584   
1585      if ((!empty($data['user_allow_viewemail']) && $auth->acl_get('u_sendemail')) || $auth->acl_get('a_user'))
1586      {
1587          $email = ($config['board_email_form'] && $config['email_enable']) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=email&amp;u=' . $user_id) : (($config['board_hide_emails'] && !$auth->acl_get('a_user')) ? '' : 'mailto:' . $data['user_email']);
1588      }
1589      else
1590      {
1591          $email = '';
1592      }
1593   
1594      if ($config['load_onlinetrack'])
1595      {
1596          $update_time = $config['load_online_time'] * 60;
1597          $online = (time() - $update_time < $data['session_time'] && ((isset($data['session_viewonline']) && $data['session_viewonline']) || $auth->acl_get('u_viewonline'))) ? true : false;
1598      }
1599      else
1600      {
1601          $online = false;
1602      }
1603   
1604      if ($data['user_allow_viewonline'] || $auth->acl_get('u_viewonline'))
1605      {
1606          $last_active = $data['user_last_active'] ?: ($data['session_time'] ?? 0);
1607      }
1608      else
1609      {
1610          $last_active = '';
1611      }
1612   
1613      $age = '';
1614   
1615      if ($config['allow_birthdays'] && $data['user_birthday'])
1616      {
1617          list($bday_day, $bday_month, $bday_year) = array_map('intval', explode('-', $data['user_birthday']));
1618   
1619          if ($bday_year)
1620          {
1621              $now = $user->create_datetime();
1622              $now = phpbb_gmgetdate($now->getTimestamp() + $now->getOffset());
1623   
1624              $diff = $now['mon'] - $bday_month;
1625              if ($diff == 0)
1626              {
1627                  $diff = ($now['mday'] - $bday_day < 0) ? 1 : 0;
1628              }
1629              else
1630              {
1631                  $diff = ($diff < 0) ? 1 : 0;
1632              }
1633   
1634              $age = max(0, (int) ($now['year'] - $bday_year - $diff));
1635          }
1636      }
1637   
1638      if (!function_exists('phpbb_get_banned_user_ids'))
1639      {
1640          include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
1641      }
1642   
1643      // Can this user receive a Private Message?
1644      $can_receive_pm = $check_can_receive_pm && (
1645          // They must be a "normal" user
1646          $data['user_type'] != USER_IGNORE &&
1647   
1648          // They must not be deactivated by the administrator
1649          ($data['user_type'] != USER_INACTIVE || $data['user_inactive_reason'] != INACTIVE_MANUAL) &&
1650   
1651          // They must be able to read PMs
1652          count($auth->acl_get_list($user_id, 'u_readpm')) &&
1653   
1654          // They must not be permanently banned
1655          !count(phpbb_get_banned_user_ids($user_id, false)) &&
1656   
1657          // They must allow users to contact via PM
1658          (($auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_')) || $data['user_allow_pm'])
1659      );
1660   
1661      // Dump it out to the template
1662      $template_data = array(
1663          'AGE'            => $age,
1664          'RANK_TITLE'    => $user_rank_data['title'],
1665          'JOINED'        => $user->format_date($data['user_regdate']),
1666          'LAST_ACTIVE'    => (empty($last_active)) ? ' - ' : $user->format_date($last_active),
1667          'POSTS'            => ($data['user_posts']) ? $data['user_posts'] : 0,
1668          'WARNINGS'        => isset($data['user_warnings']) ? $data['user_warnings'] : 0,
1669   
1670          'USERNAME_FULL'        => get_username_string('full', $user_id, $username, $data['user_colour']),
1671          'USERNAME'            => get_username_string('username', $user_id, $username, $data['user_colour']),
1672          'USER_COLOR'        => get_username_string('colour', $user_id, $username, $data['user_colour']),
1673          'U_VIEW_PROFILE'    => get_username_string('profile', $user_id, $username, $data['user_colour']),
1674   
1675          'A_USERNAME'        => addslashes(get_username_string('username', $user_id, $username, $data['user_colour'])),
1676   
1677          'AVATAR_IMG'        => phpbb_get_user_avatar($data),
1678          'ONLINE_IMG'        => (!$config['load_onlinetrack']) ? '' : (($online) ? $user->img('icon_user_online', 'ONLINE') : $user->img('icon_user_offline', 'OFFLINE')),
1679          'S_ONLINE'            => ($config['load_onlinetrack'] && $online) ? true : false,
1680          'RANK_IMG'            => $user_rank_data['img'],
1681          'RANK_IMG_SRC'        => $user_rank_data['img_src'],
1682          'S_JABBER_ENABLED'    => ($config['jab_enable']) ? true : false,
1683   
1684          'S_WARNINGS'    => ($auth->acl_getf_global('m_') || $auth->acl_get('m_warn')) ? true : false,
1685   
1686          'U_SEARCH_USER' => ($auth->acl_get('u_search')) ? append_sid("{$phpbb_root_path}search.$phpEx", "author_id=$user_id&amp;sr=posts") : '',
1687          'U_NOTES'        => ($user_notes_enabled && $auth->acl_getf_global('m_')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=notes&amp;mode=user_notes&amp;u=' . $user_id, true, $user->session_id) : '',
1688          'U_WARN'        => ($warn_user_enabled && $auth->acl_get('m_warn')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=warn&amp;mode=warn_user&amp;u=' . $user_id, true, $user->session_id) : '',
1689          'U_PM'            => ($config['allow_privmsg'] && $auth->acl_get('u_sendpm') && $can_receive_pm) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;mode=compose&amp;u=' . $user_id) : '',
1690          'U_EMAIL'        => $email,
1691          'U_JABBER'        => ($data['user_jabber'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contact&amp;action=jabber&amp;u=' . $user_id) : '',
1692   
1693          'USER_JABBER'        => ($config['jab_enable'] && $auth->acl_get('u_sendim')) ? $data['user_jabber'] : '',
1694          'USER_JABBER_IMG'    => ($config['jab_enable'] && $auth->acl_get('u_sendim') && $data['user_jabber']) ? $user->img('icon_contact_jabber', $data['user_jabber']) : '',
1695   
1696          'L_SEND_EMAIL_USER' => $user->lang('SEND_EMAIL_USER', $username),
1697          'L_CONTACT_USER'    => $user->lang('CONTACT_USER', $username),
1698          'L_VIEWING_PROFILE' => $user->lang('VIEWING_PROFILE', $username),
1699      );
1700   
1701      /**
1702      * Preparing a user's data before displaying it in profile and memberlist
1703      *
1704      * @event core.memberlist_prepare_profile_data
1705      * @var    array    data                Array with user's data
1706      * @var    array    template_data        Template array with user's data
1707      * @since 3.1.0-a1
1708      */
1709      $vars = array('data', 'template_data');
1710      extract($phpbb_dispatcher->trigger_event('core.memberlist_prepare_profile_data', compact($vars)));
1711   
1712      return $template_data;
1713  }
1714   
1715  function phpbb_sort_last_active($first, $second)
1716  {
1717      global $id_cache, $sort_dir;
1718   
1719      $lesser_than = ($sort_dir === 'd') ? -1 : 1;
1720   
1721      if (isset($id_cache[$first]['group_leader']) && $id_cache[$first]['group_leader'] && (!isset($id_cache[$second]['group_leader']) || !$id_cache[$second]['group_leader']))
1722      {
1723          return -1;
1724      }
1725      else if (isset($id_cache[$second]['group_leader']) && (!isset($id_cache[$first]['group_leader']) || !$id_cache[$first]['group_leader']) && $id_cache[$second]['group_leader'])
1726      {
1727          return 1;
1728      }
1729      else
1730      {
1731          return $lesser_than * (int) ($id_cache[$first]['last_visit'] - $id_cache[$second]['last_visit']);
1732      }
1733  }
1734