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. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
log.php
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&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']] . '&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&mode=topic_logs&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