Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

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: 22.98 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_log() 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'        => $user_id,
 233              '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                  $sql_ary += array(
 253                      'log_type'        => LOG_MOD,
 254                      'forum_id'        => $forum_id,
 255                      'topic_id'        => $topic_id,
 256                      'log_data'        => (!empty($additional_data)) ? serialize($additional_data) : '',
 257                  );
 258              break;
 259   
 260              case 'user':
 261                  $reportee_id = (int) $additional_data['reportee_id'];
 262                  unset($additional_data['reportee_id']);
 263   
 264                  $sql_ary += array(
 265                      'log_type'        => LOG_USERS,
 266                      'reportee_id'    => $reportee_id,
 267                      'log_data'        => (!empty($additional_data)) ? serialize($additional_data) : '',
 268                  );
 269              break;
 270   
 271              case 'critical':
 272                  $sql_ary += array(
 273                      'log_type'        => LOG_CRITICAL,
 274                      'log_data'        => (!empty($additional_data)) ? serialize($additional_data) : '',
 275                  );
 276              break;
 277          }
 278   
 279          /**
 280          * Allows to modify log data before we add it to the database
 281          *
 282          * NOTE: if sql_ary does not contain a log_type value, the entry will
 283          * not be stored in the database. So ensure to set it, if needed.
 284          *
 285          * @event core.add_log
 286          * @var    string    mode            Mode of the entry we log
 287          * @var    int        user_id            ID of the user who triggered the log
 288          * @var    string    log_ip            IP of the user who triggered the log
 289          * @var    string    log_operation    Language key of the log operation
 290          * @var    int        log_time        Timestamp, when the log was added
 291          * @var    array    additional_data    Array with additional log data
 292          * @var    array    sql_ary            Array with log data we insert into the
 293          *                            database. If sql_ary[log_type] is not set,
 294          *                            we won't add the entry to the database.
 295          * @since 3.1.0-a1
 296          */
 297          $vars = array(
 298              'mode',
 299              'user_id',
 300              'log_ip',
 301              'log_operation',
 302              'log_time',
 303              'additional_data',
 304              'sql_ary',
 305          );
 306          extract($this->dispatcher->trigger_event('core.add_log', compact($vars)));
 307   
 308          // We didn't find a log_type, so we don't save it in the database.
 309          if (!isset($sql_ary['log_type']))
 310          {
 311              return false;
 312          }
 313   
 314          $this->db->sql_query('INSERT INTO ' . $this->log_table . ' ' . $this->db->sql_build_array('INSERT', $sql_ary));
 315   
 316          return $this->db->sql_nextid();
 317      }
 318   
 319      /**
 320      * {@inheritDoc}
 321      */
 322      public function delete($mode, $conditions = array())
 323      {
 324          switch ($mode)
 325          {
 326              case 'admin':
 327                  $log_type = LOG_ADMIN;
 328                  break;
 329   
 330              case 'mod':
 331                  $log_type = LOG_MOD;
 332                  break;
 333   
 334              case 'user':
 335                  $log_type = LOG_USERS;
 336                  break;
 337   
 338              case 'users':
 339                  $log_type = LOG_USERS;
 340                  break;
 341   
 342              case 'critical':
 343                  $log_type = LOG_CRITICAL;
 344                  break;
 345   
 346              default:
 347                  $log_type = false;
 348          }
 349   
 350          /**
 351          * Allows to modify log data before we delete it from the database
 352          *
 353          * NOTE: if sql_ary does not contain a log_type value, the entry will
 354          * not be deleted in the database. So ensure to set it, if needed.
 355          *
 356          * @event core.delete_log
 357          * @var    string    mode            Mode of the entry we log
 358          * @var    string    log_type        Type ID of the log (should be different than false)
 359          * @var    array    conditions        An array of conditions, 3 different  forms are accepted
 360          *                                 1) <key> => <value> transformed into 'AND <key> = <value>' (value should be an integer)
 361          *                                2) <key> => array(<operator>, <value>) transformed into 'AND <key> <operator> <value>' (values can't be an array)
 362          *                                3) <key> => array('IN' => array(<values>)) transformed into 'AND <key> IN <values>'
 363          *                                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.
 364          * @since 3.1.0-b4
 365          */
 366          $vars = array(
 367              'mode',
 368              'log_type',
 369              'conditions',
 370          );
 371          extract($this->dispatcher->trigger_event('core.delete_log', compact($vars)));
 372   
 373          if ($log_type === false)
 374          {
 375              return;
 376          }
 377   
 378          $sql_where = 'WHERE log_type = ' . $log_type;
 379   
 380          if (isset($conditions['keywords']))
 381          {
 382              $sql_where .= $this->generate_sql_keyword($conditions['keywords'], '');
 383   
 384              unset($conditions['keywords']);
 385          }
 386   
 387          foreach ($conditions as $field => $field_value)
 388          {
 389              $sql_where .= ' AND ';
 390   
 391              if (is_array($field_value) && sizeof($field_value) == 2 && !is_array($field_value[1]))
 392              {
 393                  $sql_where .= $field . ' ' . $field_value[0] . ' ' . $field_value[1];
 394              }
 395              else if (is_array($field_value) && isset($field_value['IN']) && is_array($field_value['IN']))
 396              {
 397                  $sql_where .= $this->db->sql_in_set($field, $field_value['IN']);
 398              }
 399              else
 400              {
 401                  $sql_where .= $field . ' = ' . $field_value;
 402              }
 403          }
 404   
 405          $sql = 'DELETE FROM ' . LOG_TABLE . "
 406                      $sql_where";
 407          $this->db->sql_query($sql);
 408   
 409          $this->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_CLEAR_' . strtoupper($mode));
 410      }
 411   
 412      /**
 413      * {@inheritDoc}
 414      */
 415      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 = '')
 416      {
 417          $this->entry_count = 0;
 418          $this->last_page_offset = $offset;
 419   
 420          $topic_id_list = $reportee_id_list = array();
 421   
 422          $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');
 423   
 424          switch ($mode)
 425          {
 426              case 'admin':
 427                  $log_type = LOG_ADMIN;
 428                  $sql_additional = '';
 429              break;
 430   
 431              case 'mod':
 432                  $log_type = LOG_MOD;
 433                  $sql_additional = '';
 434   
 435                  if ($topic_id)
 436                  {
 437                      $sql_additional = 'AND l.topic_id = ' . (int) $topic_id;
 438                  }
 439                  else if (is_array($forum_id))
 440                  {
 441                      $sql_additional = 'AND ' . $this->db->sql_in_set('l.forum_id', array_map('intval', $forum_id));
 442                  }
 443                  else if ($forum_id)
 444                  {
 445                      $sql_additional = 'AND l.forum_id = ' . (int) $forum_id;
 446                  }
 447              break;
 448   
 449              case 'user':
 450                  $log_type = LOG_USERS;
 451                  $sql_additional = 'AND l.reportee_id = ' . (int) $user_id;
 452              break;
 453   
 454              case 'users':
 455                  $log_type = LOG_USERS;
 456                  $sql_additional = '';
 457              break;
 458   
 459              case 'critical':
 460                  $log_type = LOG_CRITICAL;
 461                  $sql_additional = '';
 462              break;
 463   
 464              default:
 465                  $log_type = false;
 466                  $sql_additional = '';
 467          }
 468   
 469          /**
 470          * Overwrite log type and limitations before we count and get the logs
 471          *
 472          * NOTE: if log_type is false, no entries will be returned.
 473          *
 474          * @event core.get_logs_modify_type
 475          * @var    string    mode        Mode of the entries we display
 476          * @var    bool    count_logs    Do we count all matching entries?
 477          * @var    int        limit        Limit the number of entries
 478          * @var    int        offset        Offset when fetching the entries
 479          * @var    mixed    forum_id    Limit entries to the forum_id,
 480          *                            can also be an array of forum_ids
 481          * @var    int        topic_id    Limit entries to the topic_id
 482          * @var    int        user_id        Limit entries to the user_id
 483          * @var    int        log_time    Limit maximum age of log entries
 484          * @var    string    sort_by        SQL order option
 485          * @var    string    keywords    Will only return entries that have the
 486          *                            keywords in log_operation or log_data
 487          * @var    string    profile_url    URL to the users profile
 488          * @var    int        log_type    Limit logs to a certain type. If log_type
 489          *                            is false, no entries will be returned.
 490          * @var    string    sql_additional    Additional conditions for the entries,
 491          *                                e.g.: 'AND l.forum_id = 1'
 492          * @since 3.1.0-a1
 493          */
 494          $vars = array(
 495              'mode',
 496              'count_logs',
 497              'limit',
 498              'offset',
 499              'forum_id',
 500              'topic_id',
 501              'user_id',
 502              'log_time',
 503              'sort_by',
 504              'keywords',
 505              'profile_url',
 506              'log_type',
 507              'sql_additional',
 508          );
 509          extract($this->dispatcher->trigger_event('core.get_logs_modify_type', compact($vars)));
 510   
 511          if ($log_type === false)
 512          {
 513              $this->last_page_offset = 0;
 514              return array();
 515          }
 516   
 517          $sql_keywords = '';
 518          if (!empty($keywords))
 519          {
 520              // Get the SQL condition for our keywords
 521              $sql_keywords = $this->generate_sql_keyword($keywords);
 522          }
 523   
 524          if ($count_logs)
 525          {
 526              $sql = 'SELECT COUNT(l.log_id) AS total_entries
 527                  FROM ' . $this->log_table . ' l, ' . USERS_TABLE . ' u
 528                  WHERE l.log_type = ' . (int) $log_type . '
 529                      AND l.user_id = u.user_id
 530                      AND l.log_time >= ' . (int) $log_time . "
 531                      $sql_keywords
 532                      $sql_additional";
 533              $result = $this->db->sql_query($sql);
 534              $this->entry_count = (int) $this->db->sql_fetchfield('total_entries');
 535              $this->db->sql_freeresult($result);
 536   
 537              if ($this->entry_count == 0)
 538              {
 539                  // Save the queries, because there are no logs to display
 540                  $this->last_page_offset = 0;
 541                  return array();
 542              }
 543   
 544              // Return the user to the last page that is valid
 545              while ($this->last_page_offset >= $this->entry_count)
 546              {
 547                  $this->last_page_offset = max(0, $this->last_page_offset - $limit);
 548              }
 549          }
 550   
 551          $sql = 'SELECT l.*, u.username, u.username_clean, u.user_colour
 552              FROM ' . $this->log_table . ' l, ' . USERS_TABLE . ' u
 553              WHERE l.log_type = ' . (int) $log_type . '
 554                  AND u.user_id = l.user_id
 555                  ' . (($log_time) ? 'AND l.log_time >= ' . (int) $log_time : '') . "
 556                  $sql_keywords
 557                  $sql_additional
 558              ORDER BY $sort_by";
 559          $result = $this->db->sql_query_limit($sql, $limit, $this->last_page_offset);
 560   
 561          $i = 0;
 562          $log = array();
 563          while ($row = $this->db->sql_fetchrow($result))
 564          {
 565              $row['forum_id'] = (int) $row['forum_id'];
 566              if ($row['topic_id'])
 567              {
 568                  $topic_id_list[] = (int) $row['topic_id'];
 569              }
 570   
 571              if ($row['reportee_id'])
 572              {
 573                  $reportee_id_list[] = (int) $row['reportee_id'];
 574              }
 575   
 576              $log_entry_data = array(
 577                  'id'                => (int) $row['log_id'],
 578   
 579                  'reportee_id'            => (int) $row['reportee_id'],
 580                  'reportee_username'        => '',
 581                  'reportee_username_full'=> '',
 582   
 583                  'user_id'            => (int) $row['user_id'],
 584                  'username'            => $row['username'],
 585                  'username_full'        => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour'], false, $profile_url),
 586   
 587                  'ip'                => $row['log_ip'],
 588                  'time'                => (int) $row['log_time'],
 589                  'forum_id'            => (int) $row['forum_id'],
 590                  'topic_id'            => (int) $row['topic_id'],
 591   
 592                  '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,
 593                  'action'            => (isset($this->user->lang[$row['log_operation']])) ? $row['log_operation'] : '{' . ucfirst(str_replace('_', ' ', $row['log_operation'])) . '}',
 594              );
 595   
 596              /**
 597              * Modify the entry's data before it is returned
 598              *
 599              * @event core.get_logs_modify_entry_data
 600              * @var    array    row            Entry data from the database
 601              * @var    array    log_entry_data    Entry's data which is returned
 602              * @since 3.1.0-a1
 603              */
 604              $vars = array('row', 'log_entry_data');
 605              extract($this->dispatcher->trigger_event('core.get_logs_modify_entry_data', compact($vars)));
 606   
 607              $log[$i] = $log_entry_data;
 608   
 609              if (!empty($row['log_data']))
 610              {
 611                  $log_data_ary = unserialize($row['log_data']);
 612                  $log_data_ary = ($log_data_ary !== false) ? $log_data_ary : array();
 613   
 614                  if (isset($this->user->lang[$row['log_operation']]))
 615                  {
 616                      // Check if there are more occurrences of % than
 617                      // arguments, if there are we fill out the arguments
 618                      // array. It doesn't matter if we add more arguments than
 619                      // placeholders.
 620                      $num_args = 0;
 621                      if (!is_array($this->user->lang[$row['log_operation']]))
 622                      {
 623                          $num_args = substr_count($this->user->lang[$row['log_operation']], '%');
 624                      }
 625                      else
 626                      {
 627                          foreach ($this->user->lang[$row['log_operation']] as $case => $plural_string)
 628                          {
 629                              $num_args = max($num_args, substr_count($plural_string, '%'));
 630                          }
 631                      }
 632   
 633                      if (($num_args - sizeof($log_data_ary)) > 0)
 634                      {
 635                          $log_data_ary = array_merge($log_data_ary, array_fill(0, $num_args - sizeof($log_data_ary), ''));
 636                      }
 637   
 638                      $lang_arguments = array_merge(array($log[$i]['action']), $log_data_ary);
 639                      $log[$i]['action'] = call_user_func_array(array($this->user, 'lang'), $lang_arguments);
 640   
 641                      // If within the admin panel we do not censor text out
 642                      if ($this->get_is_admin())
 643                      {
 644                          $log[$i]['action'] = bbcode_nl2br($log[$i]['action']);
 645                      }
 646                      else
 647                      {
 648                          $log[$i]['action'] = bbcode_nl2br(censor_text($log[$i]['action']));
 649                      }
 650                  }
 651                  else if (!empty($log_data_ary))
 652                  {
 653                      $log[$i]['action'] .= '<br />' . implode('', $log_data_ary);
 654                  }
 655   
 656                  /* Apply make_clickable... has to be seen if it is for good. :/
 657                  // Seems to be not for the moment, reconsider later...
 658                  $log[$i]['action'] = make_clickable($log[$i]['action']);
 659                  */
 660              }
 661              else
 662              {
 663                  $log[$i]['action'] = $this->user->lang($log[$i]['action']);
 664              }
 665   
 666              $i++;
 667          }
 668          $this->db->sql_freeresult($result);
 669   
 670          /**
 671          * Get some additional data after we got all log entries
 672          *
 673          * @event core.get_logs_get_additional_data
 674          * @var    array    log            Array with all our log entries
 675          * @var    array    topic_id_list        Array of topic ids, for which we
 676          *                                    get the permission data
 677          * @var    array    reportee_id_list    Array of additional user IDs we
 678          *                                    get the username strings for
 679          * @since 3.1.0-a1
 680          */
 681          $vars = array('log', 'topic_id_list', 'reportee_id_list');
 682          extract($this->dispatcher->trigger_event('core.get_logs_get_additional_data', compact($vars)));
 683   
 684          if (sizeof($topic_id_list))
 685          {
 686              $topic_auth = $this->get_topic_auth($topic_id_list);
 687   
 688              foreach ($log as $key => $row)
 689              {
 690                  $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;
 691                  $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;
 692              }
 693          }
 694   
 695          if (sizeof($reportee_id_list))
 696          {
 697              $reportee_data_list = $this->get_reportee_data($reportee_id_list);
 698   
 699              foreach ($log as $key => $row)
 700              {
 701                  if (!isset($reportee_data_list[$row['reportee_id']]))
 702                  {
 703                      continue;
 704                  }
 705   
 706                  $log[$key]['reportee_username'] = $reportee_data_list[$row['reportee_id']]['username'];
 707                  $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);
 708              }
 709          }
 710   
 711          return $log;
 712      }
 713   
 714      /**
 715      * Generates a sql condition for the specified keywords
 716      *
 717      * @param    string    $keywords            The keywords the user specified to search for
 718      * @param    string    $table_alias        The alias of the logs' table ('l.' by default)
 719      * @param    string    $statement_operator    The operator used to prefix the statement ('AND' by default)
 720      *
 721      * @return    string        Returns the SQL condition searching for the keywords
 722      */
 723      protected function generate_sql_keyword($keywords, $table_alias = 'l.', $statement_operator = 'AND')
 724      {
 725          // Use no preg_quote for $keywords because this would lead to sole
 726          // backslashes being added. We also use an OR connection here for
 727          // spaces and the | string. Currently, regex is not supported for
 728          // searching (but may come later).
 729          $keywords = preg_split('#[\s|]+#u', utf8_strtolower($keywords), 0, PREG_SPLIT_NO_EMPTY);
 730          $sql_keywords = '';
 731   
 732          if (!empty($keywords))
 733          {
 734              $keywords_pattern = array();
 735   
 736              // Build pattern and keywords...
 737              for ($i = 0, $num_keywords = sizeof($keywords); $i < $num_keywords; $i++)
 738              {
 739                  $keywords_pattern[] = preg_quote($keywords[$i], '#');
 740                  $keywords[$i] = $this->db->sql_like_expression($this->db->get_any_char() . $keywords[$i] . $this->db->get_any_char());
 741              }
 742   
 743              $keywords_pattern = '#' . implode('|', $keywords_pattern) . '#ui';
 744   
 745              $operations = array();
 746              foreach ($this->user->lang as $key => $value)
 747              {
 748                  if (substr($key, 0, 4) == 'LOG_')
 749                  {
 750                      if (is_array($value))
 751                      {
 752                          foreach ($value as $plural_value)
 753                          {
 754                              if (preg_match($keywords_pattern, $plural_value))
 755                              {
 756                                  $operations[] = $key;
 757                                  break;
 758                              }
 759                          }
 760                      }
 761                      else if (preg_match($keywords_pattern, $value))
 762                      {
 763                          $operations[] = $key;
 764                      }
 765                  }
 766              }
 767   
 768              $sql_keywords = ' ' . $statement_operator . ' (';
 769              if (!empty($operations))
 770              {
 771                  $sql_keywords .= $this->db->sql_in_set($table_alias . 'log_operation', $operations) . ' OR ';
 772              }
 773              $sql_lower = $this->db->sql_lower_text($table_alias . 'log_data');
 774              $sql_keywords .= " $sql_lower " . implode(" OR $sql_lower ", $keywords) . ')';
 775          }
 776   
 777          return $sql_keywords;
 778      }
 779   
 780      /**
 781      * Determine whether the user is allowed to read and/or moderate the forum of the topic
 782      *
 783      * @param    array    $topic_ids    Array with the topic ids
 784      *
 785      * @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:
 786      *                        array(
 787      *                            'permission' => array(
 788      *                                topic_id => forum_id
 789      *                            ),
 790      *                        ),
 791      */
 792      protected function get_topic_auth(array $topic_ids)
 793      {
 794          $forum_auth = array('f_read' => array(), 'm_' => array());
 795          $topic_ids = array_unique($topic_ids);
 796   
 797          $sql = 'SELECT topic_id, forum_id
 798              FROM ' . TOPICS_TABLE . '
 799              WHERE ' . $this->db->sql_in_set('topic_id', array_map('intval', $topic_ids));
 800          $result = $this->db->sql_query($sql);
 801   
 802          while ($row = $this->db->sql_fetchrow($result))
 803          {
 804              $row['topic_id'] = (int) $row['topic_id'];
 805              $row['forum_id'] = (int) $row['forum_id'];
 806   
 807              if ($this->auth->acl_get('f_read', $row['forum_id']))
 808              {
 809                  $forum_auth['f_read'][$row['topic_id']] = $row['forum_id'];
 810              }
 811   
 812              if ($this->auth->acl_gets('a_', 'm_', $row['forum_id']))
 813              {
 814                  $forum_auth['m_'][$row['topic_id']] = $row['forum_id'];
 815              }
 816          }
 817          $this->db->sql_freeresult($result);
 818   
 819          return $forum_auth;
 820      }
 821   
 822      /**
 823      * Get the data for all reportee from the database
 824      *
 825      * @param    array    $reportee_ids    Array with the user ids of the reportees
 826      *
 827      * @return    array        Returns an array with the reportee data
 828      */
 829      protected function get_reportee_data(array $reportee_ids)
 830      {
 831          $reportee_ids = array_unique($reportee_ids);
 832          $reportee_data_list = array();
 833   
 834          $sql = 'SELECT user_id, username, user_colour
 835              FROM ' . USERS_TABLE . '
 836              WHERE ' . $this->db->sql_in_set('user_id', $reportee_ids);
 837          $result = $this->db->sql_query($sql);
 838   
 839          while ($row = $this->db->sql_fetchrow($result))
 840          {
 841              $reportee_data_list[$row['user_id']] = $row;
 842          }
 843          $this->db->sql_freeresult($result);
 844   
 845          return $reportee_data_list;
 846      }
 847   
 848      /**
 849      * {@inheritDoc}
 850      */
 851      public function get_log_count()
 852      {
 853          return ($this->entry_count) ? $this->entry_count : 0;
 854      }
 855   
 856      /**
 857      * {@inheritDoc}
 858      */
 859      public function get_valid_offset()
 860      {
 861          return ($this->last_page_offset) ? $this->last_page_offset : 0;
 862      }
 863  }
 864