public function onCheckUserInsertForRecentChange($rc, &$fields)
 {
     $fields['cuc_ip'] = IP::sanitizeIP($this->ip);
     $fields['cuc_ip_hex'] = $this->ip ? IP::toHex($this->ip) : null;
     $fields['cuc_agent'] = $this->ua;
     if (method_exists('CheckUserHooks', 'getClientIPfromXFF')) {
         list($xff_ip, $isSquidOnly) = CheckUserHooks::getClientIPfromXFF($this->xff);
         $fields['cuc_xff'] = !$isSquidOnly ? $this->xff : '';
         $fields['cuc_xff_hex'] = $xff_ip && !$isSquidOnly ? IP::toHex($xff_ip) : null;
     } else {
         $fields['cuc_xff'] = '';
         $fields['cuc_xff_hex'] = null;
     }
 }
 /**
  * @param $actions_taken
  * @param $log_template
  * @param $action
  * @param $vars AbuseFilterVariableHolder
  * @param string $group
  * @return mixed
  */
 public static function addLogEntries($actions_taken, $log_template, $action, $vars, $group = 'default')
 {
     wfProfileIn(__METHOD__);
     $dbw = wfGetDB(DB_MASTER);
     $central_log_template = array('afl_wiki' => wfWikiID());
     $log_rows = array();
     $central_log_rows = array();
     $logged_local_filters = array();
     $logged_global_filters = array();
     foreach ($actions_taken as $filter => $actions) {
         $globalIndex = self::decodeGlobalName($filter);
         $thisLog = $log_template;
         $thisLog['afl_filter'] = $filter;
         $thisLog['afl_action'] = $action;
         $thisLog['afl_actions'] = implode(',', $actions);
         // Don't log if we were only throttling.
         if ($thisLog['afl_actions'] != 'throttle') {
             $log_rows[] = $thisLog;
             if (!$globalIndex) {
                 $logged_local_filters[] = $filter;
             }
             // Global logging
             if ($globalIndex) {
                 $title = Title::makeTitle($thisLog['afl_namespace'], $thisLog['afl_title']);
                 $centralLog = $thisLog + $central_log_template;
                 $centralLog['afl_filter'] = $globalIndex;
                 $centralLog['afl_title'] = $title->getPrefixedText();
                 $centralLog['afl_namespace'] = 0;
                 $central_log_rows[] = $centralLog;
                 $logged_global_filters[] = $globalIndex;
             }
         }
     }
     if (!count($log_rows)) {
         wfProfileOut(__METHOD__);
         return;
     }
     // Only store the var dump if we're actually going to add log rows.
     $var_dump = self::storeVarDump($vars);
     $var_dump = "stored-text:{$var_dump}";
     // To distinguish from stuff stored directly
     wfProfileIn(__METHOD__ . '-hitstats');
     global $wgMemc;
     // Increment trigger counter
     $wgMemc->incr(self::filterMatchesKey());
     $local_log_ids = array();
     global $wgAbuseFilterNotifications, $wgAbuseFilterNotificationsPrivate;
     foreach ($log_rows as $data) {
         $data['afl_var_dump'] = $var_dump;
         $data['afl_id'] = $dbw->nextSequenceValue('abuse_filter_log_afl_id_seq');
         $dbw->insert('abuse_filter_log', $data, __METHOD__);
         $local_log_ids[] = $dbw->insertId();
         if ($data['afl_id'] === null) {
             $data['afl_id'] = $dbw->insertId();
         }
         $entry = new ManualLogEntry('abusefilter', 'hit');
         // Construct a user object
         $user = User::newFromId($data['afl_user']);
         $user->setName($data['afl_user_text']);
         $entry->setPerformer($user);
         // Set action target
         $entry->setTarget(Title::makeTitle($data['afl_namespace'], $data['afl_title']));
         // Additional info
         $entry->setParameters(array('action' => $data['afl_action'], 'filter' => $data['afl_filter'], 'actions' => $data['afl_actions'], 'log' => $data['afl_id']));
         // Send data to CheckUser if installed and we
         // aren't already sending a notification to recentchanges
         // Requires MW 1.23+
         if (is_callable('CheckUserHooks::updateCheckUserData') && is_callable('ManualLogEntry::getRecentChange') && strpos($wgAbuseFilterNotifications, 'rc') === false) {
             $rc = $entry->getRecentChange();
             CheckUserHooks::updateCheckUserData($rc);
         }
         if ($wgAbuseFilterNotifications !== false) {
             if (self::filterHidden($data['afl_filter']) && !$wgAbuseFilterNotificationsPrivate) {
                 continue;
             }
             $entry->publish(0, $wgAbuseFilterNotifications);
         }
     }
     $method = __METHOD__;
     if (count($logged_local_filters)) {
         // Update hit-counter.
         $dbw->onTransactionPreCommitOrIdle(function () use($dbw, $logged_local_filters, $method) {
             $dbw->update('abuse_filter', array('af_hit_count=af_hit_count+1'), array('af_id' => $logged_local_filters), $method);
         });
     }
     $global_log_ids = array();
     // Global stuff
     if (count($logged_global_filters)) {
         $vars->computeDBVars();
         $global_var_dump = self::storeVarDump($vars, true);
         $global_var_dump = "stored-text:{$global_var_dump}";
         foreach ($central_log_rows as $index => $data) {
             $central_log_rows[$index]['afl_var_dump'] = $global_var_dump;
         }
         global $wgAbuseFilterCentralDB;
         $fdb = wfGetDB(DB_MASTER, array(), $wgAbuseFilterCentralDB);
         foreach ($central_log_rows as $row) {
             $fdb->insert('abuse_filter_log', $row, __METHOD__);
             $global_log_ids[] = $dbw->insertId();
         }
         $fdb->onTransactionPreCommitOrIdle(function () use($fdb, $logged_global_filters, $method) {
             $fdb->update('abuse_filter', array('af_hit_count=af_hit_count+1'), array('af_id' => $logged_global_filters), $method);
         });
     }
     $vars->setVar('global_log_ids', $global_log_ids);
     $vars->setVar('local_log_ids', $local_log_ids);
     // Check for emergency disabling.
     $total = $wgMemc->get(AbuseFilter::filterUsedKey($group));
     self::checkEmergencyDisable($group, $logged_local_filters, $total);
     wfProfileOut(__METHOD__ . '-hitstats');
     wfProfileOut(__METHOD__);
 }
 /**
  * @param Row $row
  * @param string $reason
  * @return a streamlined recent changes line with IP data
  */
 protected function CUChangesLine($row, $reason)
 {
     global $wgLang;
     static $cuTitle, $flagCache;
     $cuTitle = SpecialPage::getTitleFor('CheckUser');
     # Add date headers as needed
     $date = $wgLang->date(wfTimestamp(TS_MW, $row->cuc_timestamp), true, true);
     if (!isset($this->lastdate)) {
         $this->lastdate = $date;
         $line = "\n<h4>{$date}</h4>\n<ul class=\"special\">";
     } elseif ($date != $this->lastdate) {
         $line = "</ul>\n<h4>{$date}</h4>\n<ul class=\"special\">";
         $this->lastdate = $date;
     } else {
         $line = '';
     }
     $line .= '<li>';
     # Create diff/hist/page links
     $line .= $this->getLinksFromRow($row);
     # Show date
     $line .= ' . . ' . $wgLang->time(wfTimestamp(TS_MW, $row->cuc_timestamp), true, true) . ' . . ';
     # Userlinks
     $line .= $this->sk->userLink($row->cuc_user, $row->cuc_user_text);
     $line .= $this->sk->userToolLinks($row->cuc_user, $row->cuc_user_text);
     # Get block info
     if (isset($flagCache[$row->cuc_user_text])) {
         $flags = $flagCache[$row->cuc_user_text];
     } else {
         $user = User::newFromName($row->cuc_user_text, false);
         $ip = IP::isIPAddress($row->cuc_user_text) ? $row->cuc_user_text : '';
         $flags = $this->userBlockFlags($ip, $row->cuc_user, $user);
         $flagCache[$row->cuc_user_text] = $flags;
     }
     # Add any block information
     if (count($flags)) {
         $line .= ' ' . implode(' ', $flags);
     }
     # Action text, hackish ...
     if ($row->cuc_actiontext) {
         $line .= ' ' . $this->sk->formatComment($row->cuc_actiontext) . ' ';
     }
     # Comment
     $line .= $this->sk->commentBlock($row->cuc_comment);
     $line .= '<br />&#160; &#160; &#160; &#160; <small>';
     # IP
     $line .= ' <strong>IP</strong>: ' . $this->sk->makeKnownLinkObj($cuTitle, htmlspecialchars($row->cuc_ip), 'user='******'&reason=' . urlencode($reason));
     # XFF
     if ($row->cuc_xff != null) {
         # Flag our trusted proxies
         list($client, $trusted) = CheckUserHooks::getClientIPfromXFF($row->cuc_xff, $row->cuc_ip);
         $c = $trusted ? '#F0FFF0' : '#FFFFCC';
         $line .= '&#160;&#160;&#160;<span class="mw-checkuser-xff" style="background-color: ' . $c . '">' . '<strong>XFF</strong>: ';
         $line .= $this->sk->makeKnownLinkObj($cuTitle, htmlspecialchars($row->cuc_xff), 'user='******'/xff&reason=' . urlencode($reason)) . '</span>';
     }
     # User agent
     $line .= '&#160;&#160;&#160;<span class="mw-checkuser-agent" style="color:#888;">' . htmlspecialchars($row->cuc_agent) . '</span>';
     $line .= "</small></li>\n";
     return $line;
 }
 /**
  * When CheckUser extension is installed log events.
  * @param string $action that occurred
  * @param integer $id of the collection that was operated on.
  * @throws MWException
  */
 private function logEntry($action, $id)
 {
     // If CheckUser installed, give it a heads up
     $user = $this->getUser();
     $target = SpecialPage::getTitleFor('Gather')->getSubPage('id')->getSubPage($id);
     $entry = new ManualLogEntry('gather', 'action');
     $entry->setPerformer($user);
     $entry->setTarget($target);
     $params = array('action' => $action);
     $entry->setParameters($params);
     $rc = $entry->getRecentChange();
     if (is_callable('\\CheckUserHooks::updateCheckUserData')) {
         \CheckUserHooks::updateCheckUserData($rc);
     }
     // Surface hide, unhide and approve actions in Special:Log
     if ($action === 'hidelist' || $action === 'showlist' || $action === 'approve') {
         $logId = $entry->insert();
         $entry->publish($logId, 'udp');
     }
 }