function formatValue($name, $value) { $lang = $this->getLanguage(); $row = $this->mCurrentRow; switch ($name) { case 'af_id': return $lang->formatNum(intval($value)); case 'af_public_comments': return $this->getOutput()->parseInline($value); case 'af_actions': $actions = explode(',', $value); $displayActions = array(); foreach ($actions as $action) { $displayActions[] = AbuseFilter::getActionDisplay($action); } return htmlspecialchars($lang->commaList($displayActions)); case 'af_enabled': $statuses = array(); if ($row->af_deleted) { $statuses[] = $this->msg('abusefilter-deleted')->parse(); } elseif ($row->af_enabled) { $statuses[] = $this->msg('abusefilter-enabled')->parse(); } else { $statuses[] = $this->msg('abusefilter-disabled')->parse(); } if ($row->af_global) { $statuses[] = $this->msg('abusefilter-status-global')->parse(); } return $lang->commaList($statuses); case 'af_hidden': $msg = $value ? 'abusefilter-hidden' : 'abusefilter-unhidden'; return $this->msg($msg, 'parseinline')->parse(); case 'af_hit_count': // If the rule is hidden, don't show it, even to priviledged local admins if ($row->af_hidden) { return ''; } return $this->msg('abusefilter-hitcount')->numParams($value)->parse(); case 'af_timestamp': $user = $row->af_user_text; return $this->msg('abusefilter-edit-lastmod-text', $lang->timeanddate($value, true), $user, $lang->date($value, true), $lang->time($value, true), $user)->parse(); case 'af_group': // If this is global, local name probably doesn't exist, but try return AbuseFilter::nameGroup($value); break; default: throw new MWException("Unknown row type {$name}!"); } }
/** * Builds the full form for edit filters. * Loads data either from the database or from the HTTP request. * The request takes precedence over the database * @param $error string An error message to show above the filter box. * @param $filter int The filter ID * @param $history_id int The history ID of the filter, if applicable. Otherwise null * @return bool|string False if there is a failure building the editor, otherwise the HTML text for the editor. */ 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(); // Load from request OR database. list($row, $actions) = $this->loadRequest($filter, $history_id); if (!$row) { $out->addWikiMsg('abusefilter-edit-badfilter'); $out->addHTML(Linker::link($this->getTitle(), $this->msg('abusefilter-return')->text())); return false; } $out->addSubtitle($this->msg($filter === 'new' ? 'abusefilter-edit-subtitle-new' : 'abusefilter-edit-subtitle', $this->getLanguage()->formatNum($filter), $history_id)->text()); // Hide hidden filters. if ((isset($row->af_hidden) && $row->af_hidden || AbuseFilter::filterHidden($filter)) && !$this->canViewPrivate()) { return $this->msg('abusefilter-edit-denied')->text(); } $output = ''; if ($error) { $out->addHTML("<span class=\"error\">{$error}</span>"); } // Read-only attribute $readOnlyAttrib = array(); $cbReadOnlyAttrib = array(); // For checkboxes if (!$this->canEditFilter($row)) { $readOnlyAttrib['readonly'] = 'readonly'; $cbReadOnlyAttrib['disabled'] = 'disabled'; } $fields = array(); $fields['abusefilter-edit-id'] = $this->mFilter == 'new' ? $this->msg('abusefilter-edit-new')->text() : $lang->formatNum($filter); $fields['abusefilter-edit-description'] = Xml::input('wpFilterDescription', 45, isset($row->af_public_comments) ? $row->af_public_comments : '', $readOnlyAttrib); global $wgAbuseFilterValidGroups; if (count($wgAbuseFilterValidGroups) > 1) { $groupSelector = new XmlSelect('wpFilterGroup', 'mw-abusefilter-edit-group-input', 'default'); if (isset($row->af_group) && $row->af_group) { $groupSelector->setDefault($row->af_group); } foreach ($wgAbuseFilterValidGroups as $group) { $groupSelector->addOption(AbuseFilter::nameGroup($group), $group); } $fields['abusefilter-edit-group'] = $groupSelector->getHTML(); } // Hit count display if (!empty($row->af_hit_count)) { $count_display = $this->msg('abusefilter-hitcount')->numParams((int) $row->af_hit_count)->escaped(); $hitCount = Linker::linkKnown(SpecialPage::getTitleFor('AbuseLog'), $count_display, array(), array('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($row->af_group)); if ($total > 0) { $matches_percent = sprintf('%.2f', 100 * $matches_count / $total); list($timeProfile, $condProfile) = AbuseFilter::getFilterProfile($filter); $fields['abusefilter-edit-status-label'] = $this->msg('abusefilter-edit-status')->numParams($total, $matches_count, $matches_percent, $timeProfile, $condProfile)->escaped(); } } $fields['abusefilter-edit-rules'] = AbuseFilter::buildEditBox($row->af_pattern, 'wpFilterRules', true, $this->canEditFilter($row)); $fields['abusefilter-edit-notes'] = Xml::textarea('wpFilterNotes', isset($row->af_comments) ? $row->af_comments . "\n" : "\n", 40, 15, $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; // determine emergency disable value for this action $emergencyDisableThreshold = AbuseFilter::getEmergencyValue($wgAbuseFilterEmergencyDisableThreshold, $row->af_group); $threshold_percent = sprintf('%.2f', $emergencyDisableThreshold * 100); $flags .= $out->parse($this->msg('abusefilter-edit-throttled')->numParams($threshold_percent)->text()); } foreach ($checkboxes as $checkboxId) { // Messages that can be used here: // * abusefilter-edit-enabled // * abusefilter-edit-deleted // * abusefilter-edit-hidden // * abusefilter-edit-global $message = "abusefilter-edit-{$checkboxId}"; $dbField = "af_{$checkboxId}"; $postVar = 'wpFilter' . ucfirst($checkboxId); if ($checkboxId == 'global' && !$this->canEditGlobal()) { $cbReadOnlyAttrib['disabled'] = 'disabled'; } $checkbox = Xml::checkLabel($this->msg($message)->text(), $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, Linker::link($this->getTitle('revert/' . $filter), $this->msg('abusefilter-edit-revert')->text())); } if ($filter != 'new') { // Test link $tools .= Xml::tags('p', null, Linker::link($this->getTitle("test/{$filter}"), $this->msg('abusefilter-edit-test-link')->parse())); // Last modification details $userLink = Linker::userLink($row->af_user, $row->af_user_text) . Linker::userToolLinks($row->af_user, $row->af_user_text); $userName = $row->af_user_text; $fields['abusefilter-edit-lastmod'] = $this->msg('abusefilter-edit-lastmod-text')->rawParams($lang->timeanddate($row->af_timestamp, true), $userLink, $lang->date($row->af_timestamp, true), $lang->time($row->af_timestamp, true), $userName)->parse(); $history_display = $this->msg('abusefilter-edit-viewhistory')->parse(); $fields['abusefilter-edit-history'] = Linker::linkKnown($this->getTitle('history/' . $filter), $history_display); } // Add export $exportText = FormatJson::encode(array('row' => $row, 'actions' => $actions)); $tools .= Xml::tags('a', array('href' => '#', 'id' => 'mw-abusefilter-export-link'), $this->msg('abusefilter-edit-export')->parse()); $tools .= Xml::element('textarea', array('readonly' => 'readonly', 'id' => 'mw-abusefilter-export'), $exportText); $fields['abusefilter-edit-tools'] = $tools; $form = Xml::buildForm($fields); $form = Xml::fieldset($this->msg('abusefilter-edit-main')->text(), $form); $form .= Xml::fieldset($this->msg('abusefilter-edit-consequences')->text(), $this->buildConsequenceEditor($row, $actions)); if ($this->canEditFilter($row)) { $form .= Xml::submitButton($this->msg('abusefilter-edit-save')->text(), 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; }
/** * @return string */ function formatDiff() { $oldVersion = $this->mOldVersion; $newVersion = $this->mNewVersion; // headings $oldLink = $this->formatVersionLink($oldVersion['meta']['modified'], $oldVersion['meta']['history_id']); $newLink = $this->formatVersionLink($newVersion['meta']['modified'], $newVersion['meta']['history_id']); $oldUserLink = Linker::userLink($oldVersion['meta']['modified_by'], $oldVersion['meta']['modified_by_text']); $newUserLink = Linker::userLink($newVersion['meta']['modified_by'], $newVersion['meta']['modified_by_text']); $headings = ''; $headings .= Xml::tags('th', null, $this->msg('abusefilter-diff-item')->parse()); $headings .= Xml::tags('th', null, $this->msg('abusefilter-diff-version')->rawParams($oldLink, $oldUserLink)->params($newVersion['meta']['modified_by_text'])->parse()); $headings .= Xml::tags('th', null, $this->msg('abusefilter-diff-version')->rawParams($newLink, $newUserLink)->params($newVersion['meta']['modified_by_text'])->parse()); $headings = Xml::tags('tr', null, $headings); // Basic info $info = ''; $info .= $this->getHeaderRow('abusefilter-diff-info'); $info .= $this->getDiffRow('abusefilter-edit-description', $oldVersion['info']['description'], $newVersion['info']['description']); global $wgAbuseFilterValidGroups; if (count($wgAbuseFilterValidGroups) > 1 || $oldVersion['info']['group'] != $newVersion['info']['group']) { $info .= $this->getDiffRow('abusefilter-edit-group', AbuseFilter::nameGroup($oldVersion['info']['group']), AbuseFilter::nameGroup($newVersion['info']['group'])); } $info .= $this->getDiffRow('abusefilter-edit-flags', AbuseFilter::formatFlags($oldVersion['info']['flags']), AbuseFilter::formatFlags($newVersion['info']['flags'])); $info .= $this->getDiffRow('abusefilter-edit-notes', $oldVersion['info']['notes'], $newVersion['info']['notes']); // Pattern $info .= $this->getHeaderRow('abusefilter-diff-pattern'); $info .= $this->getDiffRow('abusefilter-edit-rules', $oldVersion['pattern'], $newVersion['pattern'], 'text'); // Actions $oldActions = $this->stringifyActions($oldVersion['actions']); $newActions = $this->stringifyActions($newVersion['actions']); $info .= $this->getHeaderRow('abusefilter-edit-consequences'); $info .= $this->getDiffRow('abusefilter-edit-consequences', $oldActions, $newActions); $html = "<table class='wikitable'>\n\t\t\t<thead>{$headings}</thead>\n\t\t\t<tbody>{$info}</tbody>\n\t\t</table>"; $html = Xml::tags('h2', null, $this->msg('abusefilter-diff-title')->parse()) . $html; return $html; }