Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

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: 09.10.2024, 12:52 - Dateigröße: 27.09 KiB


 001  <?php
 002  /**
 003  *
 004  * This file is part of the phpBB Forum Software package.
 005  *
 006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
 007  * @license GNU General Public License, version 2 (GPL-2.0)
 008  *
 009  * For full copyright and license information, please see
 010  * the docs/CREDITS.txt file.
 011  *
 012  */
 013   
 014  namespace phpbb\log;
 015   
 016  /**
 017  * This class is used to add entries into the log table.
 018  */
 019  class log implements \phpbb\log\log_interface
 020  {
 021      /**
 022      * If set, administrative user profile links will be returned and messages
 023      * will not be censored.
 024      * @var bool
 025      */
 026      protected $is_in_admin;
 027   
 028      /**
 029      * An array with the disabled log types. Logs of such types will not be
 030      * added when add() is called.
 031      * @var array
 032      */
 033      protected $disabled_types;
 034   
 035      /**
 036      * Keeps the total log count of the last call to get_logs()
 037      * @var int
 038      */
 039      protected $entry_count;
 040   
 041      /**
 042      * Keeps the offset of the last valid page of the last call to get_logs()
 043      * @var int
 044      */
 045      protected $last_page_offset;
 046   
 047      /**
 048      * The table we use to store our logs.
 049      * @var string
 050      */
 051      protected $log_table;
 052   
 053      /**
 054      * Database object
 055      * @var \phpbb\db\driver\driver
 056      */
 057      protected $db;
 058   
 059      /**
 060      * User object
 061      * @var \phpbb\user
 062      */
 063      protected $user;
 064   
 065      /**
 066      * Auth object
 067      * @var \phpbb\auth\auth
 068      */
 069      protected $auth;
 070   
 071      /**
 072      * Event dispatcher object
 073      * @var \phpbb\event\dispatcher_interface
 074      */
 075      protected $dispatcher;
 076   
 077      /**
 078      * phpBB root path
 079      * @var string
 080      */
 081      protected $phpbb_root_path;
 082   
 083      /**
 084      * Admin root path
 085      * @var string
 086      */
 087      protected $phpbb_admin_path;
 088   
 089      /**
 090      * PHP Extension
 091      * @var string
 092      */
 093      protected $php_ext;
 094   
 095      /**
 096      * Constructor
 097      *
 098      * @param    \phpbb\db\driver\driver_interface    $db        Database object
 099      * @param    \phpbb\user        $user    User object
 100      * @param    \phpbb\auth\auth        $auth    Auth object
 101      * @param    \phpbb\event\dispatcher_interface    $phpbb_dispatcher    Event dispatcher
 102      * @param    string        $phpbb_root_path        Root path
 103      * @param    string        $relative_admin_path    Relative admin root path
 104      * @param    string        $php_ext            PHP Extension
 105      * @param    string        $log_table        Name of the table we use to store our logs
 106      */
 107      public function __construct($db, $user, $auth, $phpbb_dispatcher, $phpbb_root_path, $relative_admin_path, $php_ext, $log_table)
 108      {
 109          $this->db = $db;
 110          $this->user = $user;
 111          $this->auth = $auth;
 112          $this->dispatcher = $phpbb_dispatcher;
 113          $this->phpbb_root_path = $phpbb_root_path;
 114          $this->phpbb_admin_path = $this->phpbb_root_path . $relative_admin_path;
 115          $this->php_ext = $php_ext;
 116          $this->log_table = $log_table;
 117   
 118          /*
 119          * IN_ADMIN is set after the session is created,
 120          * so we need to take ADMIN_START into account as well, otherwise
 121          * it will not work for the \phpbb\log\log object we create in common.php
 122          */
 123          $this->set_is_admin((defined('ADMIN_START') && ADMIN_START) || (defined('IN_ADMIN') && IN_ADMIN));
 124          $this->enable();
 125      }
 126   
 127      /**
 128      * Set is_in_admin in order to return administrative user profile links
 129      * in get_logs()
 130      *
 131      * @param    bool    $is_in_admin        Are we called from within the acp?
 132      * @return    null
 133      */
 134      public function set_is_admin($is_in_admin)
 135      {
 136          $this->is_in_admin = (bool) $is_in_admin;
 137      }
 138   
 139      /**
 140      * Returns the is_in_admin option
 141      *
 142      * @return    bool
 143      */
 144      public function get_is_admin()
 145      {
 146          return $this->is_in_admin;
 147      }
 148   
 149      /**
 150      * Set table name
 151      *
 152      * @param    string    $log_table        Can overwrite the table to use for the logs
 153      * @return    null
 154      */
 155      public function set_log_table($log_table)
 156      {
 157          $this->log_table = $log_table;
 158      }
 159   
 160      /**
 161      * {@inheritDoc}
 162      */
 163      public function is_enabled($type = '')
 164      {
 165          if ($type == '' || $type == 'all')
 166          {
 167              return !isset($this->disabled_types['all']);
 168          }
 169          return !isset($this->disabled_types[$type]) && !isset($this->disabled_types['all']);
 170      }
 171   
 172      /**
 173      * {@inheritDoc}
 174      */
 175      public function disable($type = '')
 176      {
 177          if (is_array($type))
 178          {
 179              foreach ($type as $disable_type)
 180              {
 181                  $this->disable($disable_type);
 182              }
 183              return;
 184          }
 185   
 186          // Empty string is an equivalent for all types.
 187          if ($type == '')
 188          {
 189              $type = 'all';
 190          }
 191          $this->disabled_types[$type] = true;
 192      }
 193   
 194      /**
 195      * {@inheritDoc}
 196      */
 197      public function enable($type = '')
 198      {
 199          if (is_array($type))
 200          {
 201              foreach ($type as $enable_type)
 202              {
 203                  $this->enable($enable_type);
 204              }
 205              return;
 206          }
 207   
 208          if ($type == '' || $type == 'all')
 209          {
 210              $this->disabled_types = array();
 211              return;
 212          }
 213          unset($this->disabled_types[$type]);
 214      }
 215   
 216      /**
 217      * {@inheritDoc}
 218      */
 219      public function add($mode, $user_id, $log_ip, $log_operation, $log_time = false, $additional_data = array())
 220      {
 221          if (!$this->is_enabled($mode))
 222          {
 223              return false;
 224          }
 225   
 226          if ($log_time === false)
 227          {
 228              $log_time = time();
 229          }
 230   
 231          $sql_ary = array(
 232              'user_id'        => !empty($user_id) ? $user_id : ANONYMOUS,
 233              'log_ip'        => !empty($log_ip) ? $log_ip : '',
 234              'log_time'        => $log_time,
 235              'log_operation'    => $log_operation,
 236          );
 237   
 238          switch ($mode)
 239          {
 240              case 'admin':
 241                  $sql_ary += array(
 242                      'log_type'        => LOG_ADMIN,
 243                      'log_data'        => (!empty($additional_data)) ? serialize($additional_data) : '',
 244                  );
 245              break;
 246   
 247              case 'mod':
 248                  $forum_id = isset($additional_data['forum_id']) ? (int) $additional_data['forum_id'] : 0;
 249                  unset($additional_data['forum_id']);
 250                  $topic_id = isset($additional_data['topic_id']) ? (int) $additional_data['topic_id'] : 0;
 251                  unset($additional_data['topic_id']);
 252                  $post_id = isset($additional_data['post_id']) ? (int) $additional_data['post_id'] : 0;
 253                  unset($additional_data['post_id']);
 254                  $sql_ary += array(
 255                      'log_type'        => LOG_MOD,
 256                      'forum_id'        => $forum_id,
 257                      'topic_id'        => $topic_id,
 258                      'post_id'        => $post_id,
 259                      'log_data'        => (!empty($additional_data)) ? serialize($additional_data) : '',
 260                  );
 261              break;
 262   
 263              case 'user':
 264                  $reportee_id = (int) $additional_data['reportee_id'];
 265                  unset($additional_data['reportee_id']);
 266   
 267                  $sql_ary += array(
 268                      'log_type'        => LOG_USERS,
 269                      'reportee_id'    => $reportee_id,
 270                      'log_data'        => (!empty($additional_data)) ? serialize($additional_data) : '',
 271                  );
 272              break;
 273   
 274              case 'critical':
 275                  $sql_ary += array(
 276                      'log_type'        => LOG_CRITICAL,
 277                      'log_data'        => (!empty($additional_data)) ? serialize($additional_data) : '',
 278                  );
 279              break;
 280          }
 281   
 282          /**
 283          * Allows to modify log data before we add it to the database
 284          *
 285          * NOTE: if sql_ary does not contain a log_type value, the entry will
 286          * not be stored in the database. So ensure to set it, if needed.
 287          *
 288          * @event core.add_log
 289          * @var    string    mode            Mode of the entry we log
 290          * @var    int        user_id            ID of the user who triggered the log
 291          * @var    string    log_ip            IP of the user who triggered the log
 292          * @var    string    log_operation    Language key of the log operation
 293          * @var    int        log_time        Timestamp, when the log was added
 294          * @var    array    additional_data    Array with additional log data
 295          * @var    array    sql_ary            Array with log data we insert into the
 296          *                            database. If sql_ary[log_type] is not set,
 297          *                            we won't add the entry to the database.
 298          * @since 3.1.0-a1
 299          */
 300          $vars = array(
 301              'mode',
 302              'user_id',
 303              'log_ip',
 304              'log_operation',
 305              'log_time',
 306              'additional_data',
 307              'sql_ary',
 308          );
 309          extract($this->dispatcher->trigger_event('core.add_log', compact($vars)));
 310   
 311          // We didn't find a log_type, so we don't save it in the database.
 312          if (!isset($sql_ary['log_type']))
 313          {
 314              return false;
 315          }
 316   
 317          $this->db->sql_query('INSERT INTO ' . $this->log_table . ' ' . $this->db->sql_build_array('INSERT', $sql_ary));
 318   
 319          return $this->db->sql_nextid();
 320      }
 321   
 322      /**
 323      * {@inheritDoc}
 324      */
 325      public function delete($mode, $conditions = array())
 326      {
 327          switch ($mode)
 328          {
 329              case 'admin':
 330                  $log_type = LOG_ADMIN;
 331                  break;
 332   
 333              case 'mod':
 334                  $log_type = LOG_MOD;
 335                  break;
 336   
 337              case 'user':
 338                  $log_type = LOG_USERS;
 339                  break;
 340   
 341              case 'users':
 342                  $log_type = LOG_USERS;
 343                  break;
 344   
 345              case 'critical':
 346                  $log_type = LOG_CRITICAL;
 347                  break;
 348   
 349              default:
 350                  $log_type = false;
 351          }
 352   
 353          /**
 354          * Allows to modify log data before we delete it from the database
 355          *
 356          * NOTE: if sql_ary does not contain a log_type value, the entry will
 357          * not be deleted in the database. So ensure to set it, if needed.
 358          *
 359          * @event core.delete_log
 360          * @var    string    mode            Mode of the entry we log
 361          * @var    string    log_type        Type ID of the log (should be different than false)
 362          * @var    array    conditions        An array of conditions, 3 different  forms are accepted
 363          *                                 1) <key> => <value> transformed into 'AND <key> = <value>' (value should be an integer)
 364          *                                2) <key> => array(<operator>, <value>) transformed into 'AND <key> <operator> <value>' (values can't be an array)
 365          *                                3) <key> => array('IN' => array(<values>)) transformed into 'AND <key> IN <values>'
 366          *                                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.
 367          * @since 3.1.0-b4
 368          */
 369          $vars = array(
 370              'mode',
 371              'log_type',
 372              'conditions',
 373          );
 374          extract($this->dispatcher->trigger_event('core.delete_log', compact($vars)));
 375   
 376          if ($log_type === false)
 377          {
 378              return;
 379          }
 380   
 381          $sql_where = 'WHERE log_type = ' . $log_type;
 382   
 383          if (isset($conditions['keywords']))
 384          {
 385              $sql_where .= $this->generate_sql_keyword($conditions['keywords'], '');
 386   
 387              unset($conditions['keywords']);
 388          }
 389   
 390          foreach ($conditions as $field => $field_value)
 391          {
 392              $sql_where .= ' AND ';
 393   
 394              if (is_array($field_value) && sizeof($field_value) == 2 && !is_array($field_value[1]))
 395              {
 396                  $sql_where .= $field . ' ' . $field_value[0] . ' ' . $field_value[1];
 397              }
 398              else if (is_array($field_value) && isset($field_value['IN']) && is_array($field_value['IN']))
 399              {
 400                  $sql_where .= $this->db->sql_in_set($field, $field_value['IN']);
 401              }
 402              else
 403              {
 404                  $sql_where .= $field . ' = ' . $field_value;
 405              }
 406          }
 407   
 408          $sql = 'DELETE FROM ' . $this->log_table . "
 409                      $sql_where";
 410          $this->db->sql_query($sql);
 411   
 412          $this->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_CLEAR_' . strtoupper($mode));
 413      }
 414   
 415      /**
 416      * {@inheritDoc}
 417      */
 418      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 = '')
 419      {
 420          $this->entry_count = 0;
 421          $this->last_page_offset = $offset;
 422   
 423          $topic_id_list = $reportee_id_list = array();
 424   
 425          $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');
 426   
 427          switch ($mode)
 428          {
 429              case 'admin':
 430                  $log_type = LOG_ADMIN;
 431                  $sql_additional = '';
 432              break;
 433   
 434              case 'mod':
 435                  $log_type = LOG_MOD;
 436                  $sql_additional = '';
 437   
 438                  if ($topic_id)
 439                  {
 440                      $sql_additional = 'AND l.topic_id = ' . (int) $topic_id;
 441                  }
 442                  else if (is_array($forum_id))
 443                  {
 444                      $sql_additional = 'AND ' . $this->db->sql_in_set('l.forum_id', array_map('intval', $forum_id));
 445                  }
 446                  else if ($forum_id)
 447                  {
 448                      $sql_additional = 'AND l.forum_id = ' . (int) $forum_id;
 449                  }
 450              break;
 451   
 452              case 'user':
 453                  $log_type = LOG_USERS;
 454                  $sql_additional = 'AND l.reportee_id = ' . (int) $user_id;
 455              break;
 456   
 457              case 'users':
 458                  $log_type = LOG_USERS;
 459                  $sql_additional = '';
 460              break;
 461   
 462              case 'critical':
 463                  $log_type = LOG_CRITICAL;
 464                  $sql_additional = '';
 465              break;
 466   
 467              default:
 468                  $log_type = false;
 469                  $sql_additional = '';
 470          }
 471   
 472          /**
 473          * Overwrite log type and limitations before we count and get the logs
 474          *
 475          * NOTE: if log_type is false, no entries will be returned.
 476          *
 477          * @event core.get_logs_modify_type
 478          * @var    string    mode        Mode of the entries we display
 479          * @var    bool    count_logs    Do we count all matching entries?
 480          * @var    int        limit        Limit the number of entries
 481          * @var    int        offset        Offset when fetching the entries
 482          * @var    mixed    forum_id    Limit entries to the forum_id,
 483          *                            can also be an array of forum_ids
 484          * @var    int        topic_id    Limit entries to the topic_id
 485          * @var    int        user_id        Limit entries to the user_id
 486          * @var    int        log_time    Limit maximum age of log entries
 487          * @var    string    sort_by        SQL order option
 488          * @var    string    keywords    Will only return entries that have the
 489          *                            keywords in log_operation or log_data
 490          * @var    string    profile_url    URL to the users profile
 491          * @var    int        log_type    Limit logs to a certain type. If log_type
 492          *                            is false, no entries will be returned.
 493          * @var    string    sql_additional    Additional conditions for the entries,
 494          *                                e.g.: 'AND l.forum_id = 1'
 495          * @since 3.1.0-a1
 496          */
 497          $vars = array(
 498              'mode',
 499              'count_logs',
 500              'limit',
 501              'offset',
 502              'forum_id',
 503              'topic_id',
 504              'user_id',
 505              'log_time',
 506              'sort_by',
 507              'keywords',
 508              'profile_url',
 509              'log_type',
 510              'sql_additional',
 511          );
 512          extract($this->dispatcher->trigger_event('core.get_logs_modify_type', compact($vars)));
 513   
 514          if ($log_type === false)
 515          {
 516              $this->last_page_offset = 0;
 517              return array();
 518          }
 519   
 520          $sql_keywords = '';
 521          if (!empty($keywords))
 522          {
 523              // Get the SQL condition for our keywords
 524              $sql_keywords = $this->generate_sql_keyword($keywords);
 525          }
 526   
 527          $get_logs_sql_ary = array(
 528              'SELECT' => 'l.*, u.username, u.username_clean, u.user_colour',
 529              'FROM' => array(
 530                          $this->log_table => 'l',
 531                          USERS_TABLE => 'u',
 532                      ),
 533              'WHERE' => 'l.log_type = ' . (int) $log_type . "
 534                      AND l.user_id = u.user_id
 535                      $sql_keywords
 536                      $sql_additional",
 537   
 538              'ORDER_BY' => $sort_by,
 539          );
 540   
 541          if ($log_time)
 542          {
 543              $get_logs_sql_ary['WHERE'] = 'l.log_time >= ' . (int) $log_time . '
 544                      AND ' . $get_logs_sql_ary['WHERE'];
 545          }
 546   
 547          /**
 548          * Modify the query to obtain the logs data
 549          *
 550          * @event core.get_logs_main_query_before
 551          * @var    array    get_logs_sql_ary    The array in the format of the query builder with the query
 552          *                                    to get the log count and the log list
 553          * @var    string    mode                Mode of the entries we display
 554          * @var    bool    count_logs            Do we count all matching entries?
 555          * @var    int        limit                Limit the number of entries
 556          * @var    int        offset                Offset when fetching the entries
 557          * @var    mixed    forum_id            Limit entries to the forum_id,
 558          *                                    can also be an array of forum_ids
 559          * @var    int        topic_id            Limit entries to the topic_id
 560          * @var    int        user_id                Limit entries to the user_id
 561          * @var    int        log_time            Limit maximum age of log entries
 562          * @var    string    sort_by                SQL order option
 563          * @var    string    keywords            Will only return entries that have the
 564          *                                    keywords in log_operation or log_data
 565          * @var    string    profile_url            URL to the users profile
 566          * @var    int        log_type            Limit logs to a certain type. If log_type
 567          *                                    is false, no entries will be returned.
 568          * @var    string    sql_additional        Additional conditions for the entries,
 569          *                                    e.g.: 'AND l.forum_id = 1'
 570          * @since 3.1.5-RC1
 571          */
 572          $vars = array(
 573              'get_logs_sql_ary',
 574              'mode',
 575              'count_logs',
 576              'limit',
 577              'offset',
 578              'forum_id',
 579              'topic_id',
 580              'user_id',
 581              'log_time',
 582              'sort_by',
 583              'keywords',
 584              'profile_url',
 585              'log_type',
 586              'sql_additional',
 587          );
 588          extract($this->dispatcher->trigger_event('core.get_logs_main_query_before', compact($vars)));
 589   
 590          if ($count_logs)
 591          {
 592              $count_logs_sql_ary = $get_logs_sql_ary;
 593   
 594              $count_logs_sql_ary['SELECT'] = 'COUNT(l.log_id) AS total_entries';
 595              unset($count_logs_sql_ary['ORDER_BY']);
 596   
 597              $sql = $this->db->sql_build_query('SELECT', $count_logs_sql_ary);
 598              $result = $this->db->sql_query($sql);
 599              $this->entry_count = (int) $this->db->sql_fetchfield('total_entries');
 600              $this->db->sql_freeresult($result);
 601   
 602              if ($this->entry_count == 0)
 603              {
 604                  // Save the queries, because there are no logs to display
 605                  $this->last_page_offset = 0;
 606                  return array();
 607              }
 608   
 609              // Return the user to the last page that is valid
 610              while ($this->last_page_offset >= $this->entry_count)
 611              {
 612                  $this->last_page_offset = max(0, $this->last_page_offset - $limit);
 613              }
 614          }
 615   
 616          $sql = $this->db->sql_build_query('SELECT', $get_logs_sql_ary);
 617          $result = $this->db->sql_query_limit($sql, $limit, $this->last_page_offset);
 618   
 619          $i = 0;
 620          $log = array();
 621          while ($row = $this->db->sql_fetchrow($result))
 622          {
 623              $row['forum_id'] = (int) $row['forum_id'];
 624              if ($row['topic_id'])
 625              {
 626                  $topic_id_list[] = (int) $row['topic_id'];
 627              }
 628   
 629              if ($row['reportee_id'])
 630              {
 631                  $reportee_id_list[] = (int) $row['reportee_id'];
 632              }
 633   
 634              $log_entry_data = array(
 635                  'id'                => (int) $row['log_id'],
 636   
 637                  'reportee_id'            => (int) $row['reportee_id'],
 638                  'reportee_username'        => '',
 639                  'reportee_username_full'=> '',
 640   
 641                  'user_id'            => (int) $row['user_id'],
 642                  'username'            => $row['username'],
 643                  'username_full'        => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour'], false, $profile_url),
 644   
 645                  'ip'                => $row['log_ip'],
 646                  'time'                => (int) $row['log_time'],
 647                  'forum_id'            => (int) $row['forum_id'],
 648                  'topic_id'            => (int) $row['topic_id'],
 649                  'post_id'            => (int) $row['post_id'],
 650   
 651                  '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,
 652                  'action'            => (isset($this->user->lang[$row['log_operation']])) ? $row['log_operation'] : '{' . ucfirst(str_replace('_', ' ', $row['log_operation'])) . '}',
 653              );
 654   
 655              /**
 656              * Modify the entry's data before it is returned
 657              *
 658              * @event core.get_logs_modify_entry_data
 659              * @var    array    row            Entry data from the database
 660              * @var    array    log_entry_data    Entry's data which is returned
 661              * @since 3.1.0-a1
 662              */
 663              $vars = array('row', 'log_entry_data');
 664              extract($this->dispatcher->trigger_event('core.get_logs_modify_entry_data', compact($vars)));
 665   
 666              $log[$i] = $log_entry_data;
 667   
 668              if (!empty($row['log_data']))
 669              {
 670                  $log_data_ary = unserialize($row['log_data']);
 671                  $log_data_ary = ($log_data_ary !== false) ? $log_data_ary : array();
 672   
 673                  if (isset($this->user->lang[$row['log_operation']]))
 674                  {
 675                      // Check if there are more occurrences of % than
 676                      // arguments, if there are we fill out the arguments
 677                      // array. It doesn't matter if we add more arguments than
 678                      // placeholders.
 679                      $num_args = 0;
 680                      if (!is_array($this->user->lang[$row['log_operation']]))
 681                      {
 682                          $num_args = substr_count($this->user->lang[$row['log_operation']], '%');
 683                      }
 684                      else
 685                      {
 686                          foreach ($this->user->lang[$row['log_operation']] as $case => $plural_string)
 687                          {
 688                              $num_args = max($num_args, substr_count($plural_string, '%'));
 689                          }
 690                      }
 691   
 692                      if (($num_args - sizeof($log_data_ary)) > 0)
 693                      {
 694                          $log_data_ary = array_merge($log_data_ary, array_fill(0, $num_args - sizeof($log_data_ary), ''));
 695                      }
 696   
 697                      $lang_arguments = array_merge(array($log[$i]['action']), $log_data_ary);
 698                      $log[$i]['action'] = call_user_func_array(array($this->user, 'lang'), $lang_arguments);
 699   
 700                      // If within the admin panel we do not censor text out
 701                      if ($this->get_is_admin())
 702                      {
 703                          $log[$i]['action'] = bbcode_nl2br($log[$i]['action']);
 704                      }
 705                      else
 706                      {
 707                          $log[$i]['action'] = bbcode_nl2br(censor_text($log[$i]['action']));
 708                      }
 709                  }
 710                  else if (!empty($log_data_ary))
 711                  {
 712                      $log[$i]['action'] .= '<br />' . implode('', $log_data_ary);
 713                  }
 714   
 715                  /* Apply make_clickable... has to be seen if it is for good. :/
 716                  // Seems to be not for the moment, reconsider later...
 717                  $log[$i]['action'] = make_clickable($log[$i]['action']);
 718                  */
 719              }
 720              else
 721              {
 722                  $log[$i]['action'] = $this->user->lang($log[$i]['action']);
 723              }
 724   
 725              $i++;
 726          }
 727          $this->db->sql_freeresult($result);
 728   
 729          /**
 730          * Get some additional data after we got all log entries
 731          *
 732          * @event core.get_logs_get_additional_data
 733          * @var    array    log            Array with all our log entries
 734          * @var    array    topic_id_list        Array of topic ids, for which we
 735          *                                    get the permission data
 736          * @var    array    reportee_id_list    Array of additional user IDs we
 737          *                                    get the username strings for
 738          * @since 3.1.0-a1
 739          */
 740          $vars = array('log', 'topic_id_list', 'reportee_id_list');
 741          extract($this->dispatcher->trigger_event('core.get_logs_get_additional_data', compact($vars)));
 742   
 743          if (sizeof($topic_id_list))
 744          {
 745              $topic_auth = $this->get_topic_auth($topic_id_list);
 746   
 747              foreach ($log as $key => $row)
 748              {
 749                  $log[$key]['viewtopic'] = (isset($topic_auth['f_read'][$row['topic_id']])) ? append_sid("{$this->phpbb_root_path}viewtopic.{$this->php_ext}", 'f=' . $topic_auth['f_read'][$row['topic_id']] . '&amp;t=' . $row['topic_id']) : false;
 750                  $log[$key]['viewpost'] = (isset($topic_auth['f_read'][$row['topic_id']]) && $row['post_id']) ? append_sid("{$this->phpbb_root_path}viewtopic.{$this->php_ext}", 'f=' . $topic_auth['f_read'][$row['topic_id']] . '&amp;t=' . $row['topic_id'] . '&amp;p=' . $row['post_id']) : false;
 751                  $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;
 752              }
 753          }
 754   
 755          if (sizeof($reportee_id_list))
 756          {
 757              $reportee_data_list = $this->get_reportee_data($reportee_id_list);
 758   
 759              foreach ($log as $key => $row)
 760              {
 761                  if (!isset($reportee_data_list[$row['reportee_id']]))
 762                  {
 763                      continue;
 764                  }
 765   
 766                  $log[$key]['reportee_username'] = $reportee_data_list[$row['reportee_id']]['username'];
 767                  $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);
 768              }
 769          }
 770   
 771          /**
 772          * Allow modifying or execute extra final filter on log entries
 773          *
 774          * @event core.get_logs_after
 775          * @var    array    log            Array with all our log entries
 776          * @var    array    topic_id_list        Array of topic ids, for which we
 777          *                                    get the permission data
 778          * @var    array    reportee_id_list    Array of additional user IDs we
 779          *                                    get the username strings for
 780          * @var    string    mode        Mode of the entries we display
 781          * @var    bool    count_logs    Do we count all matching entries?
 782          * @var    int        limit        Limit the number of entries
 783          * @var    int        offset        Offset when fetching the entries
 784          * @var    mixed    forum_id    Limit entries to the forum_id,
 785          *                            can also be an array of forum_ids
 786          * @var    int        topic_id    Limit entries to the topic_id
 787          * @var    int        user_id        Limit entries to the user_id
 788          * @var    int        log_time    Limit maximum age of log entries
 789          * @var    string    sort_by        SQL order option
 790          * @var    string    keywords    Will only return entries that have the
 791          *                            keywords in log_operation or log_data
 792          * @var    string    profile_url    URL to the users profile
 793          * @var    int        log_type    The type of logs it was filtered
 794          * @since 3.1.3-RC1
 795          */
 796          $vars = array(
 797              'log',
 798              'topic_id_list',
 799              'reportee_id_list',
 800              'mode',
 801              'count_logs',
 802              'limit',
 803              'offset',
 804              'forum_id',
 805              'topic_id',
 806              'user_id',
 807              'log_time',
 808              'sort_by',
 809              'keywords',
 810              'profile_url',
 811              'log_type',
 812          );
 813          extract($this->dispatcher->trigger_event('core.get_logs_after', compact($vars)));
 814   
 815          return $log;
 816      }
 817   
 818      /**
 819      * Generates a sql condition for the specified keywords
 820      *
 821      * @param    string    $keywords            The keywords the user specified to search for
 822      * @param    string    $table_alias        The alias of the logs' table ('l.' by default)
 823      * @param    string    $statement_operator    The operator used to prefix the statement ('AND' by default)
 824      *
 825      * @return    string        Returns the SQL condition searching for the keywords
 826      */
 827      protected function generate_sql_keyword($keywords, $table_alias = 'l.', $statement_operator = 'AND')
 828      {
 829          // Use no preg_quote for $keywords because this would lead to sole
 830          // backslashes being added. We also use an OR connection here for
 831          // spaces and the | string. Currently, regex is not supported for
 832          // searching (but may come later).
 833          $keywords = preg_split('#[\s|]+#u', utf8_strtolower($keywords), 0, PREG_SPLIT_NO_EMPTY);
 834          $sql_keywords = '';
 835   
 836          if (!empty($keywords))
 837          {
 838              $keywords_pattern = array();
 839   
 840              // Build pattern and keywords...
 841              for ($i = 0, $num_keywords = sizeof($keywords); $i < $num_keywords; $i++)
 842              {
 843                  $keywords_pattern[] = preg_quote($keywords[$i], '#');
 844                  $keywords[$i] = $this->db->sql_like_expression($this->db->get_any_char() . $keywords[$i] . $this->db->get_any_char());
 845              }
 846   
 847              $keywords_pattern = '#' . implode('|', $keywords_pattern) . '#ui';
 848   
 849              $operations = array();
 850              foreach ($this->user->lang as $key => $value)
 851              {
 852                  if (substr($key, 0, 4) == 'LOG_')
 853                  {
 854                      if (is_array($value))
 855                      {
 856                          foreach ($value as $plural_value)
 857                          {
 858                              if (preg_match($keywords_pattern, $plural_value))
 859                              {
 860                                  $operations[] = $key;
 861                                  break;
 862                              }
 863                          }
 864                      }
 865                      else if (preg_match($keywords_pattern, $value))
 866                      {
 867                          $operations[] = $key;
 868                      }
 869                  }
 870              }
 871   
 872              $sql_keywords = ' ' . $statement_operator . ' (';
 873              if (!empty($operations))
 874              {
 875                  $sql_keywords .= $this->db->sql_in_set($table_alias . 'log_operation', $operations) . ' OR ';
 876              }
 877              $sql_lower = $this->db->sql_lower_text($table_alias . 'log_data');
 878              $sql_keywords .= " $sql_lower " . implode(" OR $sql_lower ", $keywords) . ')';
 879          }
 880   
 881          return $sql_keywords;
 882      }
 883   
 884      /**
 885      * Determine whether the user is allowed to read and/or moderate the forum of the topic
 886      *
 887      * @param    array    $topic_ids    Array with the topic ids
 888      *
 889      * @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:
 890      *                        array(
 891      *                            'permission' => array(
 892      *                                topic_id => forum_id
 893      *                            ),
 894      *                        ),
 895      */
 896      protected function get_topic_auth(array $topic_ids)
 897      {
 898          $forum_auth = array('f_read' => array(), 'm_' => array());
 899          $topic_ids = array_unique($topic_ids);
 900   
 901          $sql_ary = array(
 902              'SELECT'    => 'topic_id, forum_id',
 903              'FROM'        => array(
 904                  TOPICS_TABLE    => 't',
 905              ),
 906              'WHERE'        => $this->db->sql_in_set('topic_id', array_map('intval', $topic_ids)),
 907          );
 908   
 909          /**
 910          * Allow modifying SQL query before topic data is retrieved.
 911          *
 912          * @event core.phpbb_log_get_topic_auth_sql_before
 913          * @var    array    topic_ids    Array with unique topic IDs
 914          * @var    array    sql_ary        SQL array
 915          * @since 3.1.11-RC1
 916          */
 917          $vars = array(
 918              'topic_ids',
 919              'sql_ary',
 920          );
 921          extract($this->dispatcher->trigger_event('core.phpbb_log_get_topic_auth_sql_before', compact($vars)));
 922   
 923          $sql = $this->db->sql_build_query('SELECT', $sql_ary);
 924          $result = $this->db->sql_query($sql);
 925   
 926          while ($row = $this->db->sql_fetchrow($result))
 927          {
 928              $row['topic_id'] = (int) $row['topic_id'];
 929              $row['forum_id'] = (int) $row['forum_id'];
 930   
 931              if ($this->auth->acl_get('f_read', $row['forum_id']))
 932              {
 933                  $forum_auth['f_read'][$row['topic_id']] = $row['forum_id'];
 934              }
 935   
 936              if ($this->auth->acl_gets('a_', 'm_', $row['forum_id']))
 937              {
 938                  $forum_auth['m_'][$row['topic_id']] = $row['forum_id'];
 939              }
 940          }
 941          $this->db->sql_freeresult($result);
 942   
 943          return $forum_auth;
 944      }
 945   
 946      /**
 947      * Get the data for all reportee from the database
 948      *
 949      * @param    array    $reportee_ids    Array with the user ids of the reportees
 950      *
 951      * @return    array        Returns an array with the reportee data
 952      */
 953      protected function get_reportee_data(array $reportee_ids)
 954      {
 955          $reportee_ids = array_unique($reportee_ids);
 956          $reportee_data_list = array();
 957   
 958          $sql = 'SELECT user_id, username, user_colour
 959              FROM ' . USERS_TABLE . '
 960              WHERE ' . $this->db->sql_in_set('user_id', $reportee_ids);
 961          $result = $this->db->sql_query($sql);
 962   
 963          while ($row = $this->db->sql_fetchrow($result))
 964          {
 965              $reportee_data_list[$row['user_id']] = $row;
 966          }
 967          $this->db->sql_freeresult($result);
 968   
 969          return $reportee_data_list;
 970      }
 971   
 972      /**
 973      * {@inheritDoc}
 974      */
 975      public function get_log_count()
 976      {
 977          return ($this->entry_count) ? $this->entry_count : 0;
 978      }
 979   
 980      /**
 981      * {@inheritDoc}
 982      */
 983      public function get_valid_offset()
 984      {
 985          return ($this->last_page_offset) ? $this->last_page_offset : 0;
 986      }
 987  }
 988