Example #1
0
 function showStatus()
 {
     global $wgMemc, $wgAbuseFilterConditionLimit, $wgOut, $wgLang;
     $overflow_count = (int) $wgMemc->get(AbuseFilter::filterLimitReachedKey());
     $match_count = (int) $wgMemc->get(AbuseFilter::filterMatchesKey());
     $total_count = (int) $wgMemc->get(AbuseFilter::filterUsedKey());
     if ($total_count > 0) {
         $overflow_percent = sprintf("%.2f", 100 * $overflow_count / $total_count);
         $match_percent = sprintf("%.2f", 100 * $match_count / $total_count);
         $status = wfMsgExt('abusefilter-status', array('parseinline'), $wgLang->formatNum($total_count), $wgLang->formatNum($overflow_count), $wgLang->formatNum($overflow_percent), $wgLang->formatNum($wgAbuseFilterConditionLimit), $wgLang->formatNum($match_count), $wgLang->formatNum($match_percent));
         $status = Xml::tags('div', array('class' => 'mw-abusefilter-status'), $status);
         $wgOut->addHTML($status);
     }
 }
 function showStatus()
 {
     global $wgMemc, $wgAbuseFilterConditionLimit, $wgAbuseFilterValidGroups;
     $overflow_count = (int) $wgMemc->get(AbuseFilter::filterLimitReachedKey());
     $match_count = (int) $wgMemc->get(AbuseFilter::filterMatchesKey());
     $total_count = 0;
     foreach ($wgAbuseFilterValidGroups as $group) {
         $total_count += (int) $wgMemc->get(AbuseFilter::filterUsedKey($group));
     }
     if ($total_count > 0) {
         $overflow_percent = sprintf("%.2f", 100 * $overflow_count / $total_count);
         $match_percent = sprintf("%.2f", 100 * $match_count / $total_count);
         $status = $this->msg('abusefilter-status')->numParams($total_count, $overflow_count, $overflow_percent, $wgAbuseFilterConditionLimit, $match_count, $match_percent)->parse();
         $status = Xml::tags('div', array('class' => 'mw-abusefilter-status'), $status);
         $this->getOutput()->addHTML($status);
     }
 }
 /**
  * @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__);
 }
 function buildFilterEditor($error, $filter, $history_id = null)
 {
     if ($filter === null) {
         return false;
     }
     // Build the edit form
     $out = $this->getOutput();
     $lang = $this->getLanguage();
     $user = $this->getUser();
     $sk = $this->getSkin();
     // Load from request OR database.
     list($row, $actions) = $this->loadRequest($filter, $history_id);
     if (!$row) {
         $out->addWikiMsg('abusefilter-edit-badfilter');
         $out->addHTML($sk->link($this->getTitle(), wfMsg('abusefilter-return')));
         return;
     }
     $out->setSubtitle(wfMsg('abusefilter-edit-subtitle', $filter, $history_id));
     // Hide hidden filters.
     if ((isset($row->af_hidden) && $row->af_hidden || AbuseFilter::filterHidden($filter)) && !$this->canViewPrivate()) {
         return wfMsg('abusefilter-edit-denied');
     }
     $output = '';
     if ($error) {
         $out->addHTML("<span class=\"error\">{$error}</span>");
     }
     // Read-only attribute
     $readOnlyAttrib = array();
     $cbReadOnlyAttrib = array();
     // For checkboxes
     if (!$this->canEdit()) {
         $readOnlyAttrib['readonly'] = 'readonly';
         $cbReadOnlyAttrib['disabled'] = 'disabled';
     }
     $fields = array();
     $fields['abusefilter-edit-id'] = $this->mFilter == 'new' ? wfMsg('abusefilter-edit-new') : $lang->formatNum($filter);
     $fields['abusefilter-edit-description'] = Xml::input('wpFilterDescription', 45, isset($row->af_public_comments) ? $row->af_public_comments : '', $readOnlyAttrib);
     // Hit count display
     if (!empty($row->af_hit_count)) {
         $count = (int) $row->af_hit_count;
         $count_display = wfMsgExt('abusefilter-hitcount', array('parseinline'), $lang->formatNum($count));
         $hitCount = $sk->makeKnownLinkObj(SpecialPage::getTitleFor('AbuseLog'), $count_display, 'wpSearchFilter=' . $row->af_id);
         $fields['abusefilter-edit-hitcount'] = $hitCount;
     }
     if ($filter !== 'new') {
         // Statistics
         global $wgMemc;
         $matches_count = $wgMemc->get(AbuseFilter::filterMatchesKey($filter));
         $total = $wgMemc->get(AbuseFilter::filterUsedKey());
         if ($total > 0) {
             $matches_percent = sprintf('%.2f', 100 * $matches_count / $total);
             list($timeProfile, $condProfile) = AbuseFilter::getFilterProfile($filter);
             $fields['abusefilter-edit-status-label'] = wfMsgExt('abusefilter-edit-status', array('parsemag', 'escape'), array($lang->formatNum($total), $lang->formatNum($matches_count), $lang->formatNum($matches_percent), $lang->formatNum($timeProfile), $lang->formatNum($condProfile)));
         }
     }
     $fields['abusefilter-edit-rules'] = AbuseFilter::buildEditBox($row->af_pattern, 'wpFilterRules', true, $this->canEdit());
     $fields['abusefilter-edit-notes'] = Xml::textarea('wpFilterNotes', isset($row->af_comments) ? $row->af_comments . "\n" : "\n", 40, 5, $readOnlyAttrib);
     // Build checkboxen
     $checkboxes = array('hidden', 'enabled', 'deleted');
     $flags = '';
     global $wgAbuseFilterIsCentral;
     if ($wgAbuseFilterIsCentral) {
         $checkboxes[] = 'global';
     }
     if (isset($row->af_throttled) && $row->af_throttled) {
         global $wgAbuseFilterEmergencyDisableThreshold;
         $threshold_percent = sprintf('%.2f', $wgAbuseFilterEmergencyDisableThreshold * 100);
         $flags .= $out->parse(wfMsg('abusefilter-edit-throttled', $lang->formatNum($threshold_percent)));
     }
     foreach ($checkboxes as $checkboxId) {
         $message = "abusefilter-edit-{$checkboxId}";
         $dbField = "af_{$checkboxId}";
         $postVar = 'wpFilter' . ucfirst($checkboxId);
         $checkbox = Xml::checkLabel(wfMsg($message), $postVar, $postVar, isset($row->{$dbField}) ? $row->{$dbField} : false, $cbReadOnlyAttrib);
         $checkbox = Xml::tags('p', null, $checkbox);
         $flags .= $checkbox;
     }
     $fields['abusefilter-edit-flags'] = $flags;
     $tools = '';
     if ($filter != 'new' && $user->isAllowed('abusefilter-revert')) {
         $tools .= Xml::tags('p', null, $sk->link($this->getTitle('revert/' . $filter), wfMsg('abusefilter-edit-revert')));
     }
     if ($filter != 'new') {
         // Test link
         $tools .= Xml::tags('p', null, $sk->link($this->getTitle("test/{$filter}"), wfMsgExt('abusefilter-edit-test-link', 'parseinline')));
         // Last modification details
         $userLink = $sk->userLink($row->af_user, $row->af_user_text) . $sk->userToolLinks($row->af_user, $row->af_user_text);
         $userName = $row->af_user_text;
         $fields['abusefilter-edit-lastmod'] = wfMsgExt('abusefilter-edit-lastmod-text', array('parseinline', 'replaceafter'), array($lang->timeanddate($row->af_timestamp, true), $userLink, $lang->date($row->af_timestamp, true), $lang->time($row->af_timestamp, true), $userName));
         $history_display = wfMsgExt('abusefilter-edit-viewhistory', array('parseinline'));
         $fields['abusefilter-edit-history'] = $sk->makeKnownLinkObj($this->getTitle('history/' . $filter), $history_display);
     }
     // Add export
     $exportText = json_encode(array('row' => $row, 'actions' => $actions));
     $tools .= Xml::tags('a', array('href' => '#', 'id' => 'mw-abusefilter-export-link'), wfMsgExt('abusefilter-edit-export', 'parseinline'));
     $tools .= Xml::element('textarea', array('readonly' => 'readonly', 'id' => 'mw-abusefilter-export'), $exportText);
     $fields['abusefilter-edit-tools'] = $tools;
     $form = Xml::buildForm($fields);
     $form = Xml::fieldset(wfMsg('abusefilter-edit-main'), $form);
     $form .= Xml::fieldset(wfMsg('abusefilter-edit-consequences'), $this->buildConsequenceEditor($row, $actions));
     if ($this->canEdit()) {
         $form .= Xml::submitButton(wfMsg('abusefilter-edit-save'), array('accesskey' => 's'));
         $form .= Html::hidden('wpEditToken', $user->getEditToken(array('abusefilter', $filter)));
     }
     $form = Xml::tags('form', array('action' => $this->getTitle($filter)->getFullURL(), 'method' => 'post'), $form);
     $output .= $form;
     return $output;
 }
 public static function addLogEntries($actions_taken, $log_template, $action, $vars)
 {
     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
     foreach ($log_rows as $index => $data) {
         $log_rows[$index]['afl_var_dump'] = $var_dump;
     }
     wfProfileIn(__METHOD__ . '-hitstats');
     global $wgMemc;
     // Increment trigger counter
     $wgMemc->incr(self::filterMatchesKey());
     $dbw->insert('abuse_filter_log', $log_rows, __METHOD__);
     if (count($logged_local_filters)) {
         // Update hit-counter.
         $dbw->update('abuse_filter', array('af_hit_count=af_hit_count+1'), array('af_id' => $logged_local_filters), __METHOD__);
     }
     // Global stuff
     if (count($logged_global_filters)) {
         $vars->computeDBVars();
         $global_var_dump = self::storeVarDump($vars, 'global');
         $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);
         $fdb->insert('abuse_filter_log', $central_log_rows, __METHOD__);
         $fdb->update('abuse_filter', array('af_hit_count=af_hit_count+1'), array('af_id' => $logged_global_filters), __METHOD__);
     }
     // Check for emergency disabling.
     $total = $wgMemc->get(AbuseFilter::filterUsedKey());
     self::checkEmergencyDisable($logged_local_filters, $total);
     wfProfileOut(__METHOD__ . '-hitstats');
     wfProfileOut(__METHOD__);
 }