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