r38720 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r38719‎ | r38720 | r38721 >
Date:16:09, 6 August 2008
Author:yaron
Status:old
Tags:
Comment:
New class for handling 'ReplaceText' special page; contains most of the
extension's functionality
Modified paths:
  • /trunk/extensions/ReplaceText/SpecialReplaceText.php (added) (history)

Diff [purge]

Index: trunk/extensions/ReplaceText/SpecialReplaceText.php
@@ -0,0 +1,217 @@
 2+<?php
 3+
 4+if (!defined('MEDIAWIKI')) die();
 5+
 6+class ReplaceText extends SpecialPage {
 7+
 8+ /**
 9+ * Constructor
 10+ */
 11+ function ReplaceText() {
 12+ SpecialPage::SpecialPage('ReplaceText');
 13+ wfLoadExtensionMessages('ReplaceText');
 14+ }
 15+
 16+ function execute() {
 17+ $this->setHeaders();
 18+ doSpecialReplaceText();
 19+ }
 20+
 21+ function displayConfirmForm($message) {
 22+ global $wgRequest;
 23+ $target_str = $wgRequest->getVal('target_str');
 24+ $replacement_str = $wgRequest->getVal('replacement_str');
 25+ // escape quotes for inclusion in HTML
 26+ $target_str = str_replace('"', '&quot;', $target_str);
 27+ $replacement_str = str_replace('"', '&quot;', $replacement_str);
 28+ $continue_label = wfMsg('replacetext_continue');
 29+ $cancel_label = wfMsg('replacetext_cancel');
 30+ $text =<<<END
 31+ <form method="post" action="">
 32+ <input type="hidden" name="target_str" value="$target_str">
 33+ <input type="hidden" name="replacement_str" value="$replacement_str">
 34+ <p>$message</p>
 35+ <p><input type="Submit" name="confirm" value="$continue_label"></p>
 36+ <p>$cancel_label</p>
 37+ </form>
 38+
 39+END;
 40+ return $text;
 41+ }
 42+}
 43+
 44+function doSpecialReplaceText() {
 45+ global $wgUser, $wgOut, $wgRequest, $wgContLang;
 46+
 47+ if ($wgRequest->getCheck('replace')) {
 48+ $target_str = $wgRequest->getVal('target_str');
 49+ $replacement_str = $wgRequest->getVal('replacement_str');
 50+ $replacement_params = array();
 51+ $replacement_params['user_id'] = $wgUser->getId();
 52+ $replacement_params['target_str'] = $target_str;
 53+ $replacement_params['replacement_str'] = $replacement_str;
 54+ $replacement_params['edit_summary'] = wfMsgForContent('replacetext_editsummary', $target_str, $replacement_str);
 55+ foreach ($wgRequest->getValues() as $key => $value) {
 56+ if ($value == 'on') {
 57+ $title = Title::newFromId($key);
 58+ $jobs[] = new ReplaceTextJob( $title, $replacement_params );
 59+ }
 60+ }
 61+ Job::batchInsert( $jobs );
 62+ $num_modified_pages = count($jobs);
 63+ $wgOut->addHTML(wfMsg('replacetext_success', $target_str, $replacement_str, $num_modified_pages));
 64+ } elseif ($wgRequest->getCheck('target_str')) {
 65+ $dbr =& wfGetDB( DB_SLAVE );
 66+ $fname = 'doSpecialReplaceText';
 67+ $target_str = $wgRequest->getVal('target_str');
 68+ $replacement_str = $wgRequest->getVal('replacement_str');
 69+
 70+ if (! $wgRequest->getCheck('confirm')) {
 71+ // display a page to make the user confirm the replacement, if the
 72+ // replacement string is either blank or found elsewhere on the wiki
 73+ // (since undoing the replacement would be difficult in either case)
 74+ if ($replacement_str == '') {
 75+ $text = wfMsg('replacetext_blankwarning');
 76+ $wgOut->addHTML(displayConfirmForm($text));
 77+ return;
 78+ } else {
 79+ // get the number of pages in which the replacement string appears
 80+ $page_table = $dbr->tableName('page');
 81+ $revision_table = $dbr->tableName('revision');
 82+ $text_table = $dbr->tableName('text');
 83+ $talk_ns = NS_TALK;
 84+ $usertalk_ns = NS_USER_TALK;
 85+ $mediawiki_ns = NS_MEDIAWIKI;
 86+ $sql_replacement_str = str_replace("'", "\'", $replacement_str);
 87+ $sql = "SELECT count(*)
 88+ FROM $page_table p
 89+ JOIN $revision_table r ON p.page_latest = r.rev_id
 90+ JOIN $text_table t ON r.rev_text_id = t.old_id
 91+ WHERE t.old_text LIKE '%$sql_replacement_str%'
 92+ AND p.page_namespace != $talk_ns
 93+ AND p.page_namespace != $usertalk_ns
 94+ AND p.page_namespace != $mediawiki_ns";
 95+ $res = $dbr->query($sql);
 96+ $row = $dbr->fetchRow($res);
 97+ $num_pages_with_replacement_str = $row[0];
 98+ // if there are any, the user most confirm the replacement
 99+ if ($num_pages_with_replacement_str > 0) {
 100+ $text = wfMsg('replacetext_warning', $num_pages_with_replacement_str, $replacement_str);
 101+ $wgOut->addHTML(ReplaceText::displayConfirmForm($text));
 102+ return;
 103+ }
 104+ }
 105+ }
 106+
 107+ $jobs = array();
 108+ $num_modified_pages = 0;
 109+ $found_titles = array();
 110+ $angle_brackets = array('<', '>');
 111+ $escaped_angle_brackets = array('&lt;', '&gt;');
 112+
 113+ // get the set of pages that contain the target string, and display
 114+ // the name and "context" (the text around the string) of each
 115+ $page_table = $dbr->tableName('page');
 116+ $revision_table = $dbr->tableName('revision');
 117+ $text_table = $dbr->tableName('text');
 118+ $talk_ns = NS_TALK;
 119+ $usertalk_ns = NS_USER_TALK;
 120+ $mediawiki_ns = NS_MEDIAWIKI;
 121+ $sql_target_str = str_replace("'", "\'", $target_str);
 122+ $sql = "SELECT p.page_title AS title, p.page_namespace AS namespace, t.old_text AS text
 123+ FROM $page_table p
 124+ JOIN $revision_table r ON p.page_latest = r.rev_id
 125+ JOIN $text_table t ON r.rev_text_id = t.old_id
 126+ WHERE t.old_text LIKE '%$sql_target_str%'
 127+ AND p.page_namespace != $talk_ns
 128+ AND p.page_namespace != $usertalk_ns
 129+ AND p.page_namespace != $mediawiki_ns
 130+ ORDER BY p.page_namespace, p.page_title";
 131+ $res = $dbr->query($sql);
 132+ $contextchars = $wgUser->getOption( 'contextchars', 40 );
 133+ while( $row = $dbr->fetchObject( $res ) ) {
 134+ $title = Title::newFromText($row->title, $row->namespace);
 135+ $article_text = $row->text;
 136+ $target_pos = strpos($article_text, $target_str);
 137+ $context_str = str_replace($angle_brackets, $escaped_angle_brackets, $wgContLang->truncate(substr($article_text, 0, $target_pos), -$contextchars, '...' ));
 138+ $context_str .= "<span class=\"searchmatch\">" . str_replace($angle_brackets, $escaped_angle_brackets, substr($article_text, $target_pos, strlen($target_str))) . "</span>";
 139+ $context_str .= str_replace($angle_brackets, $escaped_angle_brackets, $wgContLang->truncate(substr($article_text, $target_pos + strlen($target_str)), $contextchars, '...' ));
 140+ $found_titles[] = array($title, $context_str);
 141+ $num_modified_pages++;
 142+ }
 143+
 144+ if ($num_modified_pages == 0)
 145+ $wgOut->addHTML(wfMsg('replacetext_noreplacement', $target_str));
 146+ else {
 147+ $javascript_text =<<<END
 148+<script type="text/javascript">
 149+function invertSelections() {
 150+ form = document.getElementById('choose_pages');
 151+ num_elements = form.elements.length;
 152+ for (i = 0; i < num_elements; i++) {
 153+ if (form.elements[i].type == "checkbox") {
 154+ if (form.elements[i].checked == true)
 155+ form.elements[i].checked = false;
 156+ else
 157+ form.elements[i].checked = true;
 158+ }
 159+ }
 160+}
 161+ </script>
 162+
 163+END;
 164+ $wgOut->addScript($javascript_text);
 165+ $replace_label = wfMsg('replacetext_replace');
 166+ $choose_pages_label = wfMsg('replacetext_choosepages', $target_str, $replacement_str);
 167+ $skin = $wgUser->getSkin();
 168+ // escape quotes for inclusion in HTML
 169+ $target_str = str_replace('"', '&quot;', $target_str);
 170+ $replacement_str = str_replace('"', '&quot;', $replacement_str);
 171+ $text =<<<END
 172+ <p>$choose_pages_label</p>
 173+ <form id="choose_pages" method="post">
 174+ <input type="hidden" name="target_str" value="$target_str">
 175+ <input type="hidden" name="replacement_str" value="$replacement_str">
 176+
 177+END;
 178+ foreach ($found_titles as $value_pair) {
 179+ list($title, $context_str) = $value_pair;
 180+ $text .= "<input type=\"checkbox\" name=\"{$title->getArticleID()}\" checked /> {$skin->makeLinkObj( $title, $title->prefix($title->getText()) )} - <small>$context_str</small><br />\n";
 181+ }
 182+ $invert_selections_label = wfMsg('replacetext_invertselections');
 183+ $text .=<<<END
 184+ <p><input type="Submit" name="replace" value="$replace_label"></p>
 185+ <p><strong><a href="javascript:;" onclick="invertSelections(); return false;">$invert_selections_label</a></strong></p>
 186+ </form>
 187+
 188+END;
 189+ $wgOut->addHTML($text);
 190+ }
 191+ } else {
 192+ $replacement_label = wfMsg('replacetext_docu');
 193+ $replacement_note = wfMsg('replacetext_note');
 194+ $original_text_label = wfMsg('replacetext_originaltext');
 195+ $replacement_text_label = wfMsg('replacetext_replacementtext');
 196+ $continue_label = wfMsg('replacetext_continue');
 197+ $text =<<<END
 198+ <form method="get" action="">
 199+ <p>$replacement_label</p>
 200+ <p>$replacement_note</p>
 201+ <table>
 202+ <tr>
 203+ <td>$original_text_label:</td>
 204+ <td><input type="text" length="10" name="target_str"></td>
 205+ </tr>
 206+ <tr>
 207+ <td>$replacement_text_label:</td>
 208+ <td><input type="text" length="10" name="replacement_str"></td>
 209+ </tr>
 210+ </table>
 211+ <p><input type="Submit" value="$continue_label"></p>
 212+ </form>
 213+
 214+END;
 215+ $wgOut->addHTML($text);
 216+ }
 217+
 218+}

Status & tagging log