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

log.php

Zuletzt modifiziert: 02.04.2025, 15:02 - Dateigröße: 27.41 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  namespace phpbb\log;
0015   
0016  /**
0017  * This class is used to add entries into the log table.
0018  */
0019  class log implements \phpbb\log\log_interface
0020  {
0021      /**
0022      * If set, administrative user profile links will be returned and messages
0023      * will not be censored.
0024      * @var bool
0025      */
0026      protected $is_in_admin;
0027   
0028      /**
0029      * An array with the disabled log types. Logs of such types will not be
0030      * added when add() is called.
0031      * @var array
0032      */
0033      protected $disabled_types;
0034   
0035      /**
0036      * Keeps the total log count of the last call to get_logs()
0037      * @var int
0038      */
0039      protected $entry_count;
0040   
0041      /**
0042      * Keeps the offset of the last valid page of the last call to get_logs()
0043      * @var int
0044      */
0045      protected $last_page_offset;
0046   
0047      /**
0048      * The table we use to store our logs.
0049      * @var string
0050      */
0051      protected $log_table;
0052   
0053      /**
0054      * Database object
0055      * @var \phpbb\db\driver\driver
0056      */
0057      protected $db;
0058   
0059      /**
0060      * User object
0061      * @var \phpbb\user
0062      */
0063      protected $user;
0064   
0065      /**
0066      * Auth object
0067      * @var \phpbb\auth\auth
0068      */
0069      protected $auth;
0070   
0071      /**
0072      * Event dispatcher object
0073      * @var \phpbb\event\dispatcher_interface
0074      */
0075      protected $dispatcher;
0076   
0077      /**
0078      * phpBB root path
0079      * @var string
0080      */
0081      protected $phpbb_root_path;
0082   
0083      /**
0084      * Admin root path
0085      * @var string
0086      */
0087      protected $phpbb_admin_path;
0088   
0089      /**
0090      * PHP Extension
0091      * @var string
0092      */
0093      protected $php_ext;
0094   
0095      /**
0096      * Constructor
0097      *
0098      * @param    \phpbb\db\driver\driver_interface    $db        Database object
0099      * @param    \phpbb\user        $user    User object
0100      * @param    \phpbb\auth\auth        $auth    Auth object
0101      * @param    \phpbb\event\dispatcher_interface    $phpbb_dispatcher    Event dispatcher
0102      * @param    string        $phpbb_root_path        Root path
0103      * @param    string        $relative_admin_path    Relative admin root path
0104      * @param    string        $php_ext            PHP Extension
0105      * @param    string        $log_table        Name of the table we use to store our logs
0106      */
0107      public function __construct($db, $user, $auth, $phpbb_dispatcher, $phpbb_root_path, $relative_admin_path, $php_ext, $log_table)
0108      {
0109          $this->db = $db;
0110          $this->user = $user;
0111          $this->auth = $auth;
0112          $this->dispatcher = $phpbb_dispatcher;
0113          $this->phpbb_root_path = $phpbb_root_path;
0114          $this->phpbb_admin_path = $this->phpbb_root_path . $relative_admin_path;
0115          $this->php_ext = $php_ext;
0116          $this->log_table = $log_table;
0117   
0118          /*
0119          * IN_ADMIN is set after the session is created,
0120          * so we need to take ADMIN_START into account as well, otherwise
0121          * it will not work for the \phpbb\log\log object we create in common.php
0122          */
0123          $this->set_is_admin((defined('ADMIN_START') && ADMIN_START) || (defined('IN_ADMIN') && IN_ADMIN));
0124          $this->enable();
0125      }
0126   
0127      /**
0128      * Set is_in_admin in order to return administrative user profile links
0129      * in get_logs()
0130      *
0131      * @param    bool    $is_in_admin        Are we called from within the acp?
0132      * @return    null
0133      */
0134      public function set_is_admin($is_in_admin)
0135      {
0136          $this->is_in_admin = (bool) $is_in_admin;
0137      }
0138   
0139      /**
0140      * Returns the is_in_admin option
0141      *
0142      * @return    bool
0143      */
0144      public function get_is_admin()
0145      {
0146          return $this->is_in_admin;
0147      }
0148   
0149      /**
0150      * Set table name
0151      *
0152      * @param    string    $log_table        Can overwrite the table to use for the logs
0153      * @return    null
0154      */
0155      public function set_log_table($log_table)
0156      {
0157          $this->log_table = $log_table;
0158      }
0159   
0160      /**
0161      * {@inheritDoc}
0162      */
0163      public function is_enabled($type = '')
0164      {
0165          if ($type == '' || $type == 'all')
0166          {
0167              return !isset($this->disabled_types['all']);
0168          }
0169          return !isset($this->disabled_types[$type]) && !isset($this->disabled_types['all']);
0170      }
0171   
0172      /**
0173      * {@inheritDoc}
0174      */
0175      public function disable($type = '')
0176      {
0177          if (is_array($type))
0178          {
0179              foreach ($type as $disable_type)
0180              {
0181                  $this->disable($disable_type);
0182              }
0183              return;
0184          }
0185   
0186          // Empty string is an equivalent for all types.
0187          if ($type == '')
0188          {
0189              $type = 'all';
0190          }
0191          $this->disabled_types[$type] = true;
0192      }
0193   
0194      /**
0195      * {@inheritDoc}
0196      */
0197      public function enable($type = '')
0198      {
0199          if (is_array($type))
0200          {
0201              foreach ($type as $enable_type)
0202              {
0203                  $this->enable($enable_type);
0204              }
0205              return;
0206          }
0207   
0208          if ($type == '' || $type == 'all')
0209          {
0210              $this->disabled_types = array();
0211              return;
0212          }
0213          unset($this->disabled_types[$type]);
0214      }
0215   
0216      /**
0217      * {@inheritDoc}
0218      */
0219      public function add($mode, $user_id, $log_ip, $log_operation, $log_time = false, $additional_data = array())
0220      {
0221          if (!$this->is_enabled($mode))
0222          {
0223              return false;
0224          }
0225   
0226          if ($log_time === false)
0227          {
0228              $log_time = time();
0229          }
0230   
0231          $sql_ary = array(
0232              'user_id'        => !empty($user_id) ? $user_id : ANONYMOUS,
0233              'log_ip'        => !empty($log_ip) ? $log_ip : '',
0234              'log_time'        => $log_time,
0235              'log_operation'    => $log_operation,
0236          );
0237   
0238          switch ($mode)
0239          {
0240              case 'admin':
0241                  $sql_ary += array(
0242                      'log_type'        => LOG_ADMIN,
0243                      'log_data'        => (!empty($additional_data)) ? serialize($additional_data) : '',
0244                  );
0245              break;
0246   
0247              case 'mod':
0248                  $forum_id = isset($additional_data['forum_id']) ? (int) $additional_data['forum_id'] : 0;
0249                  unset($additional_data['forum_id']);
0250                  $topic_id = isset($additional_data['topic_id']) ? (int) $additional_data['topic_id'] : 0;
0251                  unset($additional_data['topic_id']);
0252                  $post_id = isset($additional_data['post_id']) ? (int) $additional_data['post_id'] : 0;
0253                  unset($additional_data['post_id']);
0254                  $sql_ary += array(
0255                      'log_type'        => LOG_MOD,
0256                      'forum_id'        => $forum_id,
0257                      'topic_id'        => $topic_id,
0258                      'post_id'        => $post_id,
0259                      'log_data'        => (!empty($additional_data)) ? serialize($additional_data) : '',
0260                  );
0261              break;
0262   
0263              case 'user':
0264                  $reportee_id = (int) $additional_data['reportee_id'];
0265                  unset($additional_data['reportee_id']);
0266   
0267                  $sql_ary += array(
0268                      'log_type'        => LOG_USERS,
0269                      'reportee_id'    => $reportee_id,
0270                      'log_data'        => (!empty($additional_data)) ? serialize($additional_data) : '',
0271                  );
0272              break;
0273   
0274              case 'critical':
0275                  $sql_ary += array(
0276                      'log_type'        => LOG_CRITICAL,
0277                      'log_data'        => (!empty($additional_data)) ? serialize($additional_data) : '',
0278                  );
0279              break;
0280          }
0281   
0282          /**
0283          * Allows to modify log data before we add it to the database
0284          *
0285          * NOTE: if sql_ary does not contain a log_type value, the entry will
0286          * not be stored in the database. So ensure to set it, if needed.
0287          *
0288          * @event core.add_log
0289          * @var    string    mode            Mode of the entry we log
0290          * @var    int        user_id            ID of the user who triggered the log
0291          * @var    string    log_ip            IP of the user who triggered the log
0292          * @var    string    log_operation    Language key of the log operation
0293          * @var    int        log_time        Timestamp, when the log was added
0294          * @var    array    additional_data    Array with additional log data
0295          * @var    array    sql_ary            Array with log data we insert into the
0296          *                            database. If sql_ary[log_type] is not set,
0297          *                            we won't add the entry to the database.
0298          * @since 3.1.0-a1
0299          */
0300          $vars = array(
0301              'mode',
0302              'user_id',
0303              'log_ip',
0304              'log_operation',
0305              'log_time',
0306              'additional_data',
0307              'sql_ary',
0308          );
0309          extract($this->dispatcher->trigger_event('core.add_log', compact($vars)));
0310   
0311          // We didn't find a log_type, so we don't save it in the database.
0312          if (!isset($sql_ary['log_type']))
0313          {
0314              return false;
0315          }
0316   
0317          $this->db->sql_query('INSERT INTO ' . $this->log_table . ' ' . $this->db->sql_build_array('INSERT', $sql_ary));
0318   
0319          return $this->db->sql_nextid();
0320      }
0321   
0322      /**
0323      * {@inheritDoc}
0324      */
0325      public function delete($mode, $conditions = array())
0326      {
0327          switch ($mode)
0328          {
0329              case 'admin':
0330                  $log_type = LOG_ADMIN;
0331                  break;
0332   
0333              case 'mod':
0334                  $log_type = LOG_MOD;
0335                  break;
0336   
0337              case 'user':
0338                  $log_type = LOG_USERS;
0339                  break;
0340   
0341              case 'users':
0342                  $log_type = LOG_USERS;
0343                  break;
0344   
0345              case 'critical':
0346                  $log_type = LOG_CRITICAL;
0347                  break;
0348   
0349              default:
0350                  $log_type = false;
0351          }
0352   
0353          /**
0354          * Allows to modify log data before we delete it from the database
0355          *
0356          * NOTE: if sql_ary does not contain a log_type value, the entry will
0357          * not be deleted in the database. So ensure to set it, if needed.
0358          *
0359          * @event core.delete_log
0360          * @var    string    mode            Mode of the entry we log
0361          * @var    string    log_type        Type ID of the log (should be different than false)
0362          * @var    array    conditions        An array of conditions, 3 different  forms are accepted
0363          *                                 1) <key> => <value> transformed into 'AND <key> = <value>' (value should be an integer)
0364          *                                2) <key> => array(<operator>, <value>) transformed into 'AND <key> <operator> <value>' (values can't be an array)
0365          *                                3) <key> => array('IN' => array(<values>)) transformed into 'AND <key> IN <values>'
0366          *                                A special field, keywords, can also be defined. In this case only the log entries that have the keywords in log_operation or log_data will be deleted.
0367          * @since 3.1.0-b4
0368          */
0369          $vars = array(
0370              'mode',
0371              'log_type',
0372              'conditions',
0373          );
0374          extract($this->dispatcher->trigger_event('core.delete_log', compact($vars)));
0375   
0376          if ($log_type === false)
0377          {
0378              return;
0379          }
0380   
0381          $sql_where = 'WHERE log_type = ' . $log_type;
0382   
0383          if (isset($conditions['keywords']))
0384          {
0385              $sql_where .= $this->generate_sql_keyword($conditions['keywords'], '');
0386   
0387              unset($conditions['keywords']);
0388          }
0389   
0390          foreach ($conditions as $field => $field_value)
0391          {
0392              $sql_where .= ' AND ';
0393   
0394              if (is_array($field_value) && count($field_value) == 2 && !is_array($field_value[1]))
0395              {
0396                  $sql_where .= $field . ' ' . $field_value[0] . ' ' . $field_value[1];
0397              }
0398              else if (is_array($field_value) && isset($field_value['IN']) && is_array($field_value['IN']))
0399              {
0400                  $sql_where .= $this->db->sql_in_set($field, $field_value['IN']);
0401              }
0402              else
0403              {
0404                  $sql_where .= $field . ' = ' . $field_value;
0405              }
0406          }
0407   
0408          $sql = 'DELETE FROM ' . $this->log_table . "
0409                      $sql_where";
0410          $this->db->sql_query($sql);
0411   
0412          $this->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_CLEAR_' . strtoupper($mode));
0413      }
0414   
0415      /**
0416      * {@inheritDoc}
0417      */
0418      public function get_logs($mode, $count_logs = true, $limit = 0, $offset = 0, $forum_id = 0, $topic_id = 0, $user_id = 0, $log_time = 0, $sort_by = 'l.log_time DESC', $keywords = '')
0419      {
0420          $this->entry_count = 0;
0421          $this->last_page_offset = $offset;
0422   
0423          $topic_id_list = $reportee_id_list = array();
0424   
0425          $profile_url = ($this->get_is_admin() && $this->phpbb_admin_path) ? append_sid("{$this->phpbb_admin_path}index.{$this->php_ext}", 'i=users&amp;mode=overview') : append_sid("{$this->phpbb_root_path}memberlist.{$this->php_ext}", 'mode=viewprofile');
0426   
0427          switch ($mode)
0428          {
0429              case 'admin':
0430                  $log_type = LOG_ADMIN;
0431                  $sql_additional = '';
0432              break;
0433   
0434              case 'mod':
0435                  $log_type = LOG_MOD;
0436                  $sql_additional = '';
0437   
0438                  if ($topic_id)
0439                  {
0440                      $sql_additional = 'AND l.topic_id = ' . (int) $topic_id;
0441                  }
0442                  else if (is_array($forum_id))
0443                  {
0444                      $sql_additional = 'AND ' . $this->db->sql_in_set('l.forum_id', array_map('intval', $forum_id));
0445                  }
0446                  else if ($forum_id)
0447                  {
0448                      $sql_additional = 'AND l.forum_id = ' . (int) $forum_id;
0449                  }
0450              break;
0451   
0452              case 'user':
0453                  $log_type = LOG_USERS;
0454                  $sql_additional = 'AND l.reportee_id = ' . (int) $user_id;
0455              break;
0456   
0457              case 'users':
0458                  $log_type = LOG_USERS;
0459                  $sql_additional = '';
0460              break;
0461   
0462              case 'critical':
0463                  $log_type = LOG_CRITICAL;
0464                  $sql_additional = '';
0465              break;
0466   
0467              default:
0468                  $log_type = false;
0469                  $sql_additional = '';
0470          }
0471   
0472          /**
0473          * Overwrite log type and limitations before we count and get the logs
0474          *
0475          * NOTE: if log_type is false, no entries will be returned.
0476          *
0477          * @event core.get_logs_modify_type
0478          * @var    string    mode        Mode of the entries we display
0479          * @var    bool    count_logs    Do we count all matching entries?
0480          * @var    int        limit        Limit the number of entries
0481          * @var    int        offset        Offset when fetching the entries
0482          * @var    mixed    forum_id    Limit entries to the forum_id,
0483          *                            can also be an array of forum_ids
0484          * @var    int        topic_id    Limit entries to the topic_id
0485          * @var    int        user_id        Limit entries to the user_id
0486          * @var    int        log_time    Limit maximum age of log entries
0487          * @var    string    sort_by        SQL order option
0488          * @var    string    keywords    Will only return entries that have the
0489          *                            keywords in log_operation or log_data
0490          * @var    string    profile_url    URL to the users profile
0491          * @var    int        log_type    Limit logs to a certain type. If log_type
0492          *                            is false, no entries will be returned.
0493          * @var    string    sql_additional    Additional conditions for the entries,
0494          *                                e.g.: 'AND l.forum_id = 1'
0495          * @since 3.1.0-a1
0496          */
0497          $vars = array(
0498              'mode',
0499              'count_logs',
0500              'limit',
0501              'offset',
0502              'forum_id',
0503              'topic_id',
0504              'user_id',
0505              'log_time',
0506              'sort_by',
0507              'keywords',
0508              'profile_url',
0509              'log_type',
0510              'sql_additional',
0511          );
0512          extract($this->dispatcher->trigger_event('core.get_logs_modify_type', compact($vars)));
0513   
0514          if ($log_type === false)
0515          {
0516              $this->last_page_offset = 0;
0517              return array();
0518          }
0519   
0520          $sql_keywords = '';
0521          if (!empty($keywords))
0522          {
0523              // Get the SQL condition for our keywords
0524              $sql_keywords = $this->generate_sql_keyword($keywords);
0525          }
0526   
0527          $get_logs_sql_ary = array(
0528              'SELECT' => 'l.*, u.username, u.username_clean, u.user_colour',
0529              'FROM' => array(
0530                          $this->log_table => 'l',
0531                          USERS_TABLE => 'u',
0532                      ),
0533              'WHERE' => 'l.log_type = ' . (int) $log_type . "
0534                      AND l.user_id = u.user_id
0535                      $sql_keywords
0536                      $sql_additional",
0537   
0538              'ORDER_BY' => $sort_by,
0539          );
0540   
0541          if ($log_time)
0542          {
0543              $get_logs_sql_ary['WHERE'] = 'l.log_time >= ' . (int) $log_time . '
0544                      AND ' . $get_logs_sql_ary['WHERE'];
0545          }
0546   
0547          /**
0548          * Modify the query to obtain the logs data
0549          *
0550          * @event core.get_logs_main_query_before
0551          * @var    array    get_logs_sql_ary    The array in the format of the query builder with the query
0552          *                                    to get the log count and the log list
0553          * @var    string    mode                Mode of the entries we display
0554          * @var    bool    count_logs            Do we count all matching entries?
0555          * @var    int        limit                Limit the number of entries
0556          * @var    int        offset                Offset when fetching the entries
0557          * @var    mixed    forum_id            Limit entries to the forum_id,
0558          *                                    can also be an array of forum_ids
0559          * @var    int        topic_id            Limit entries to the topic_id
0560          * @var    int        user_id                Limit entries to the user_id
0561          * @var    int        log_time            Limit maximum age of log entries
0562          * @var    string    sort_by                SQL order option
0563          * @var    string    keywords            Will only return entries that have the
0564          *                                    keywords in log_operation or log_data
0565          * @var    string    profile_url            URL to the users profile
0566          * @var    int        log_type            Limit logs to a certain type. If log_type
0567          *                                    is false, no entries will be returned.
0568          * @var    string    sql_additional        Additional conditions for the entries,
0569          *                                    e.g.: 'AND l.forum_id = 1'
0570          * @since 3.1.5-RC1
0571          */
0572          $vars = array(
0573              'get_logs_sql_ary',
0574              'mode',
0575              'count_logs',
0576              'limit',
0577              'offset',
0578              'forum_id',
0579              'topic_id',
0580              'user_id',
0581              'log_time',
0582              'sort_by',
0583              'keywords',
0584              'profile_url',
0585              'log_type',
0586              'sql_additional',
0587          );
0588          extract($this->dispatcher->trigger_event('core.get_logs_main_query_before', compact($vars)));
0589   
0590          if ($count_logs)
0591          {
0592              $count_logs_sql_ary = $get_logs_sql_ary;
0593   
0594              $count_logs_sql_ary['SELECT'] = 'COUNT(l.log_id) AS total_entries';
0595              unset($count_logs_sql_ary['ORDER_BY']);
0596   
0597              $sql = $this->db->sql_build_query('SELECT', $count_logs_sql_ary);
0598              $result = $this->db->sql_query($sql);
0599              $this->entry_count = (int) $this->db->sql_fetchfield('total_entries');
0600              $this->db->sql_freeresult($result);
0601   
0602              if ($this->entry_count == 0)
0603              {
0604                  // Save the queries, because there are no logs to display
0605                  $this->last_page_offset = 0;
0606                  return array();
0607              }
0608   
0609              // Return the user to the last page that is valid
0610              while ($this->last_page_offset >= $this->entry_count)
0611              {
0612                  $this->last_page_offset = max(0, $this->last_page_offset - $limit);
0613              }
0614          }
0615   
0616          $sql = $this->db->sql_build_query('SELECT', $get_logs_sql_ary);
0617          $result = $this->db->sql_query_limit($sql, $limit, $this->last_page_offset);
0618   
0619          $i = 0;
0620          $log = array();
0621          while ($row = $this->db->sql_fetchrow($result))
0622          {
0623              $row['forum_id'] = (int) $row['forum_id'];
0624              if ($row['topic_id'])
0625              {
0626                  $topic_id_list[] = (int) $row['topic_id'];
0627              }
0628   
0629              if ($row['reportee_id'])
0630              {
0631                  $reportee_id_list[] = (int) $row['reportee_id'];
0632              }
0633   
0634              $log_entry_data = array(
0635                  'id'                => (int) $row['log_id'],
0636   
0637                  'reportee_id'            => (int) $row['reportee_id'],
0638                  'reportee_username'        => '',
0639                  'reportee_username_full'=> '',
0640   
0641                  'user_id'            => (int) $row['user_id'],
0642                  'username'            => $row['username'],
0643                  'username_full'        => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour'], false, $profile_url),
0644   
0645                  'ip'                => $row['log_ip'],
0646                  'time'                => (int) $row['log_time'],
0647                  'forum_id'            => (int) $row['forum_id'],
0648                  'topic_id'            => (int) $row['topic_id'],
0649                  'post_id'            => (int) $row['post_id'],
0650   
0651                  'viewforum'            => ($row['forum_id'] && $this->auth->acl_get('f_read', $row['forum_id'])) ? append_sid("{$this->phpbb_root_path}viewforum.{$this->php_ext}", 'f=' . $row['forum_id']) : false,
0652                  'action'            => (isset($this->user->lang[$row['log_operation']])) ? $row['log_operation'] : '{' . ucfirst(str_replace('_', ' ', $row['log_operation'])) . '}',
0653              );
0654   
0655              /**
0656              * Modify the entry's data before it is returned
0657              *
0658              * @event core.get_logs_modify_entry_data
0659              * @var    array    row            Entry data from the database
0660              * @var    array    log_entry_data    Entry's data which is returned
0661              * @since 3.1.0-a1
0662              */
0663              $vars = array('row', 'log_entry_data');
0664              extract($this->dispatcher->trigger_event('core.get_logs_modify_entry_data', compact($vars)));
0665   
0666              $log[$i] = $log_entry_data;
0667   
0668              if (!empty($row['log_data']))
0669              {
0670                  $log_data_ary = unserialize($row['log_data']);
0671                  $log_data_ary = ($log_data_ary !== false) ? $log_data_ary : array();
0672   
0673                  if (isset($this->user->lang[$row['log_operation']]))
0674                  {
0675                      // Check if there are more occurrences of % than
0676                      // arguments, if there are we fill out the arguments
0677                      // array. It doesn't matter if we add more arguments than
0678                      // placeholders.
0679                      $num_args = 0;
0680                      if (!is_array($this->user->lang[$row['log_operation']]))
0681                      {
0682                          $num_args = substr_count($this->user->lang[$row['log_operation']], '%');
0683                      }
0684                      else
0685                      {
0686                          foreach ($this->user->lang[$row['log_operation']] as $case => $plural_string)
0687                          {
0688                              $num_args = max($num_args, substr_count($plural_string, '%'));
0689                          }
0690                      }
0691   
0692                      if (($num_args - count($log_data_ary)) > 0)
0693                      {
0694                          $log_data_ary = array_merge($log_data_ary, array_fill(0, $num_args - count($log_data_ary), ''));
0695                      }
0696   
0697                      $lang_arguments = array_merge(array($log[$i]['action']), $log_data_ary);
0698                      $log[$i]['action'] = call_user_func_array(array($this->user, 'lang'), array_values($lang_arguments));
0699   
0700                      // If within the admin panel we do not censor text out
0701                      if ($this->get_is_admin())
0702                      {
0703                          $log[$i]['action'] = bbcode_nl2br($log[$i]['action']);
0704                      }
0705                      else
0706                      {
0707                          $log[$i]['action'] = bbcode_nl2br(censor_text($log[$i]['action']));
0708                      }
0709                  }
0710                  else if (!empty($log_data_ary))
0711                  {
0712                      $log[$i]['action'] .= '<br />' . implode('', $log_data_ary);
0713                  }
0714   
0715                  /* Apply make_clickable... has to be seen if it is for good. :/
0716                  // Seems to be not for the moment, reconsider later...
0717                  $log[$i]['action'] = make_clickable($log[$i]['action']);
0718                  */
0719              }
0720              else
0721              {
0722                  $log[$i]['action'] = $this->user->lang($log[$i]['action']);
0723              }
0724   
0725              $i++;
0726          }
0727          $this->db->sql_freeresult($result);
0728   
0729          /**
0730          * Get some additional data after we got all log entries
0731          *
0732          * @event core.get_logs_get_additional_data
0733          * @var    array    log            Array with all our log entries
0734          * @var    array    topic_id_list        Array of topic ids, for which we
0735          *                                    get the permission data
0736          * @var    array    reportee_id_list    Array of additional user IDs we
0737          *                                    get the username strings for
0738          * @since 3.1.0-a1
0739          */
0740          $vars = array('log', 'topic_id_list', 'reportee_id_list');
0741          extract($this->dispatcher->trigger_event('core.get_logs_get_additional_data', compact($vars)));
0742   
0743          if (count($topic_id_list))
0744          {
0745              $topic_auth = $this->get_topic_auth($topic_id_list);
0746   
0747              foreach ($log as $key => $row)
0748              {
0749                  $log[$key]['viewtopic'] = (isset($topic_auth['f_read'][$row['topic_id']])) ? append_sid("{$this->phpbb_root_path}viewtopic.{$this->php_ext}", 't=' . $row['topic_id']) : false;
0750                  $log[$key]['viewpost'] = (isset($topic_auth['f_read'][$row['topic_id']]) && $row['post_id']) ? append_sid("{$this->phpbb_root_path}viewtopic.{$this->php_ext}", 'p=' . $row['post_id'] . '#p' . $row['post_id']) : false;
0751                  $log[$key]['viewlogs'] = (isset($topic_auth['m_'][$row['topic_id']])) ? append_sid("{$this->phpbb_root_path}mcp.{$this->php_ext}", 'i=logs&amp;mode=topic_logs&amp;t=' . $row['topic_id'], true, $this->user->session_id) : false;
0752              }
0753          }
0754   
0755          if (count($reportee_id_list))
0756          {
0757              $reportee_data_list = $this->get_reportee_data($reportee_id_list);
0758   
0759              foreach ($log as $key => $row)
0760              {
0761                  if (!isset($reportee_data_list[$row['reportee_id']]))
0762                  {
0763                      continue;
0764                  }
0765   
0766                  $log[$key]['reportee_username'] = $reportee_data_list[$row['reportee_id']]['username'];
0767                  $log[$key]['reportee_username_full'] = get_username_string('full', $row['reportee_id'], $reportee_data_list[$row['reportee_id']]['username'], $reportee_data_list[$row['reportee_id']]['user_colour'], false, $profile_url);
0768              }
0769          }
0770   
0771          /**
0772          * Allow modifying or execute extra final filter on log entries
0773          *
0774          * @event core.get_logs_after
0775          * @var    array    log            Array with all our log entries
0776          * @var    array    topic_id_list        Array of topic ids, for which we
0777          *                                    get the permission data
0778          * @var    array    reportee_id_list    Array of additional user IDs we
0779          *                                    get the username strings for
0780          * @var    string    mode        Mode of the entries we display
0781          * @var    bool    count_logs    Do we count all matching entries?
0782          * @var    int        limit        Limit the number of entries
0783          * @var    int        offset        Offset when fetching the entries
0784          * @var    mixed    forum_id    Limit entries to the forum_id,
0785          *                            can also be an array of forum_ids
0786          * @var    int        topic_id    Limit entries to the topic_id
0787          * @var    int        user_id        Limit entries to the user_id
0788          * @var    int        log_time    Limit maximum age of log entries
0789          * @var    string    sort_by        SQL order option
0790          * @var    string    keywords    Will only return entries that have the
0791          *                            keywords in log_operation or log_data
0792          * @var    string    profile_url    URL to the users profile
0793          * @var    int        log_type    The type of logs it was filtered
0794          * @since 3.1.3-RC1
0795          */
0796          $vars = array(
0797              'log',
0798              'topic_id_list',
0799              'reportee_id_list',
0800              'mode',
0801              'count_logs',
0802              'limit',
0803              'offset',
0804              'forum_id',
0805              'topic_id',
0806              'user_id',
0807              'log_time',
0808              'sort_by',
0809              'keywords',
0810              'profile_url',
0811              'log_type',
0812          );
0813          extract($this->dispatcher->trigger_event('core.get_logs_after', compact($vars)));
0814   
0815          return $log;
0816      }
0817   
0818      /**
0819      * Generates a sql condition for the specified keywords
0820      *
0821      * @param    string    $keywords            The keywords the user specified to search for
0822      * @param    string    $table_alias        The alias of the logs' table ('l.' by default)
0823      * @param    string    $statement_operator    The operator used to prefix the statement ('AND' by default)
0824      *
0825      * @return    string        Returns the SQL condition searching for the keywords
0826      */
0827      protected function generate_sql_keyword($keywords, $table_alias = 'l.', $statement_operator = 'AND')
0828      {
0829          // Use no preg_quote for $keywords because this would lead to sole
0830          // backslashes being added. We also use an OR connection here for
0831          // spaces and the | string. Currently, regex is not supported for
0832          // searching (but may come later).
0833          $keywords = preg_split('#[\s|]+#u', utf8_strtolower($keywords), 0, PREG_SPLIT_NO_EMPTY);
0834          $sql_keywords = '';
0835   
0836          if (!empty($keywords))
0837          {
0838              $keywords_pattern = array();
0839   
0840              // Build pattern and keywords...
0841              for ($i = 0, $num_keywords = count($keywords); $i < $num_keywords; $i++)
0842              {
0843                  $keywords_pattern[] = preg_quote($keywords[$i], '#');
0844                  $keywords[$i] = $this->db->sql_like_expression($this->db->get_any_char() . $keywords[$i] . $this->db->get_any_char());
0845              }
0846   
0847              $keywords_pattern = '#' . implode('|', $keywords_pattern) . '#ui';
0848   
0849              $operations = array();
0850              foreach ($this->user->lang as $key => $value)
0851              {
0852                  if (substr($key, 0, 4) == 'LOG_')
0853                  {
0854                      if (is_array($value))
0855                      {
0856                          foreach ($value as $plural_value)
0857                          {
0858                              if (preg_match($keywords_pattern, $plural_value))
0859                              {
0860                                  $operations[] = $key;
0861                                  break;
0862                              }
0863                          }
0864                      }
0865                      else if (preg_match($keywords_pattern, $value))
0866                      {
0867                          $operations[] = $key;
0868                      }
0869                  }
0870              }
0871   
0872              $sql_keywords = ' ' . $statement_operator . ' (';
0873              if (!empty($operations))
0874              {
0875                  $sql_keywords .= $this->db->sql_in_set($table_alias . 'log_operation', $operations) . ' OR ';
0876              }
0877              $sql_lower = $this->db->sql_lower_text($table_alias . 'log_data');
0878              $sql_keywords .= " $sql_lower " . implode(" OR $sql_lower ", $keywords) . ')';
0879          }
0880   
0881          return $sql_keywords;
0882      }
0883   
0884      /**
0885      * Determine whether the user is allowed to read and/or moderate the forum of the topic
0886      *
0887      * @param    array    $topic_ids    Array with the topic ids
0888      *
0889      * @return    array        Returns an array with two keys 'm_' and 'read_f' which are also an array of topic_id => forum_id sets when the permissions are given. Sample:
0890      *                        array(
0891      *                            'permission' => array(
0892      *                                topic_id => forum_id
0893      *                            ),
0894      *                        ),
0895      */
0896      protected function get_topic_auth(array $topic_ids)
0897      {
0898          $forum_auth = array('f_read' => array(), 'm_' => array());
0899          $topic_ids = array_unique($topic_ids);
0900   
0901          $sql_ary = array(
0902              'SELECT'    => 'topic_id, forum_id',
0903              'FROM'        => array(
0904                  TOPICS_TABLE    => 't',
0905              ),
0906              'WHERE'        => $this->db->sql_in_set('topic_id', array_map('intval', $topic_ids)),
0907          );
0908   
0909          /**
0910          * Allow modifying SQL query before topic data is retrieved.
0911          *
0912          * @event core.phpbb_log_get_topic_auth_sql_before
0913          * @var    array    topic_ids    Array with unique topic IDs
0914          * @var    array    sql_ary        SQL array
0915          * @since 3.1.11-RC1
0916          */
0917          $vars = array(
0918              'topic_ids',
0919              'sql_ary',
0920          );
0921          extract($this->dispatcher->trigger_event('core.phpbb_log_get_topic_auth_sql_before', compact($vars)));
0922   
0923          $sql = $this->db->sql_build_query('SELECT', $sql_ary);
0924          $result = $this->db->sql_query($sql);
0925   
0926          while ($row = $this->db->sql_fetchrow($result))
0927          {
0928              $row['topic_id'] = (int) $row['topic_id'];
0929              $row['forum_id'] = (int) $row['forum_id'];
0930   
0931              if ($this->auth->acl_get('f_read', $row['forum_id']))
0932              {
0933                  $forum_auth['f_read'][$row['topic_id']] = $row['forum_id'];
0934              }
0935   
0936              /**
0937               * Allow modifying SQL query after topic data is retrieved (inside loop).
0938               *
0939               * @event core.phpbb_log_get_topic_auth_sql_after
0940               * @var    array    forum_auth    Forum permissions
0941               * @var    array    row            One row of data from SQL query
0942               * @since 3.2.2-RC1
0943               */
0944              $vars = array(
0945                  'forum_auth',
0946                  'row',
0947              );
0948              extract($this->dispatcher->trigger_event('core.phpbb_log_get_topic_auth_sql_after', compact($vars)));
0949   
0950              if ($this->auth->acl_gets('a_', 'm_', $row['forum_id']))
0951              {
0952                  $forum_auth['m_'][$row['topic_id']] = $row['forum_id'];
0953              }
0954          }
0955          $this->db->sql_freeresult($result);
0956   
0957          return $forum_auth;
0958      }
0959   
0960      /**
0961      * Get the data for all reportee from the database
0962      *
0963      * @param    array    $reportee_ids    Array with the user ids of the reportees
0964      *
0965      * @return    array        Returns an array with the reportee data
0966      */
0967      protected function get_reportee_data(array $reportee_ids)
0968      {
0969          $reportee_ids = array_unique($reportee_ids);
0970          $reportee_data_list = array();
0971   
0972          $sql = 'SELECT user_id, username, user_colour
0973              FROM ' . USERS_TABLE . '
0974              WHERE ' . $this->db->sql_in_set('user_id', $reportee_ids);
0975          $result = $this->db->sql_query($sql);
0976   
0977          while ($row = $this->db->sql_fetchrow($result))
0978          {
0979              $reportee_data_list[$row['user_id']] = $row;
0980          }
0981          $this->db->sql_freeresult($result);
0982   
0983          return $reportee_data_list;
0984      }
0985   
0986      /**
0987      * {@inheritDoc}
0988      */
0989      public function get_log_count()
0990      {
0991          return ($this->entry_count) ? $this->entry_count : 0;
0992      }
0993   
0994      /**
0995      * {@inheritDoc}
0996      */
0997      public function get_valid_offset()
0998      {
0999          return ($this->last_page_offset) ? $this->last_page_offset : 0;
1000      }
1001  }
1002