New extension

This commit is contained in:
Yaron Koren 2008-04-29 14:43:25 +00:00
commit 9ac439452d
Notes: Yaron Koren 2009-07-20 18:49:29 +00:00
3 changed files with 268 additions and 0 deletions

46
README Normal file
View file

@ -0,0 +1,46 @@
Replace Text Extension
Version 0.1
Yaron Koren
This is free software licenced under the GNU General Public Licence. Please
see http://www.gnu.org/copyleft/gpl.html for further details, including the
full text and terms of the licence.
== Overview ==
Replace Text is an extension to MediaWiki that creates a new special page,
Special:ReplaceText, available to administrators only (defined as anyone
who has 'delete' privileges on pages), that does a text find-and-replace
on all pages in the wiki, except the Talk pages and the ones in the wiki's
own project namespace. Only the contents of pages are affected, not their
titles. The search is case-sensitive.
Since the replacement is not undoable, if the replacement string is
blank or a string that is already contained in the wiki, the 'ReplaceText'
page prompts the user to confirm the replacement before it is performed.
Each replacement shows up as a wiki edit, with the administrator who
performed the replacement appearing as the user and an edit summary
that looks like "Text replace: 'search string' to 'replacement string'".
For more information, see the extension homepage at:
http://www.mediawiki.org/wiki/Extension:Replace_Text
== Requirements ==
This version of the Replace Text extension requires MediaWiki 1.8 or higher.
== Installation ==
To install the extension, place the entire 'ReplaceText' directory
within your MediaWiki 'extensions' directory, then add the following
line to your 'LocalSettings.php' file:
require_once( "$IP/extensions/ReplaceText/ReplaceText.php" );
== Contact ==
Comments, questions, suggestions and bug reports are welcome, and can
be placed on the Talk page for the extension, or sent to Yaron at
yaron57@gmail.com.

29
ReplaceText.i18n.php Normal file
View file

@ -0,0 +1,29 @@
<?php
/**
* Internationalization file for the Replace Text extension
*
* @addtogroup Extensions
*/
$messages = array();
/** English
* @author Yaron Koren
*/
$messages['en'] = array(
// user messages
'replacetext' => 'Replace text',
'replacetext_docu' => 'To replace one text string with another across all data pages on this wiki, you can enter the two pieces of text here and then hit \'Replace\'. Your name will appear in page histories as the user responsible for the changes.',
'replacetext_note' => 'Note: this will not replace text in "Talk" pages and project pages, and it will not replace text in page titles themselves.',
'replacetext_originaltext' => 'Original text',
'replacetext_replacementtext' => 'Replacement text',
'replacetext_replace' => 'Replace',
'replacetext_success' => 'Replaced \'$1\' with \'$2\' in $3 files.',
'replacetext_noreplacement' => 'No replacements were made; no files were found containing the string \'$1\'.',
'replacetext_warning' => 'There are $1 files that already contain the replacement string, \'$2\'; if you make this replacement you will not be able to separate your replacements from these strings. Continue with the replacement?',
'replacetext_blankwarning' => 'Because the replacement string is blank, this operation will not be reversible; continue?',
'replacetext_continue' => 'Continue',
'replacetext_cancel' => '(Hit the "Back" button to cancel the operation.)',
// content messages
'replacetext_editsummary' => 'Text replace - \'$1\' to \'$2\'',
);

193
ReplaceText.php Normal file
View file

@ -0,0 +1,193 @@
<?php
/**
* Replace Text - a MediaWiki extension that provides a special page to
* allow administrators to do a global string find-and-replace on all the
* content pages of a wiki.
*
* http://www.mediawiki.org/wiki/Extension:Text_Replace
*
* The special page created is 'Special:ReplaceText', and it provides
* a form to do a global search-and-replace, with the changes to every
* page showing up as a wiki edit, with the administrator who performed
* the replacement as the user, and an edit summary that looks like
* "Text replace: 'search string' * to 'replacement string'".
*
* If the replacement string is blank, or is already found in the wiki,
* the page provides a warning prompt to the user before doing the
* replacement, since it is not easily reversible.
*
* @version 0.1
* @author Yaron Koren
*/
if (!defined('MEDIAWIKI')) die();
global $IP;
require_once( "$IP/includes/SpecialPage.php" );
$grIP = $IP . '/extensions/ReplaceText';
$wgExtensionFunctions[] = 'grSetupExtension';
if (version_compare($wgVersion, '1.11', '>=')) {
$wgExtensionMessagesFiles['ReplaceText'] = $grIP . '/ReplaceText.i18n.php';
} else {
$wgExtensionFunctions[] = 'grfLoadMessagesManually';
}
function grSetupExtension() {
global $wgVersion, $wgExtensionCredits;
if (version_compare($wgVersion, '1.11', '>='))
wfLoadExtensionMessages( 'ReplaceText' );
// credits
$wgExtensionCredits['specialpage'][] = array(
'name' => 'Replace Text',
'version' => '0.1',
'author' => 'Yaron Koren',
'url' => 'http://www.mediawiki.org/wiki/Extension:Text_Replace',
'description' => 'A special page that lets administrators run a global search-and-replace',
);
// the 'delete' specifies that only users who can delete pages
// (usually, sysops) can access this page
SpecialPage::addPage(new SpecialPage('ReplaceText', 'delete', true, 'doReplaceText', false));
}
/**
* Initialize messages - these settings must be applied later on, since
* the MessageCache does not exist yet when the settings are loaded in
* LocalSettings.php.
* Function based on version in ContributionScores extension
*/
function grfInitMessages() {
global $wgVersion, $wgExtensionFunctions;
}
/**
* Setting of message cache for versions of MediaWiki that do not support
* wgExtensionFunctions - based on ceContributionScores() in
* ContributionScores extension
*/
function grfLoadMessagesManually() {
global $grIP, $wgMessageCache;
# add messages
require($grIP . '/ReplaceText.i18n.php');
foreach($messages as $key => $value) {
$wgMessageCache->addMessages($messages[$key], $key);
}
}
function displayConfirmForm($message) {
global $wgRequest;
$target_str = $wgRequest->getVal('target_str');
$replacement_str = $wgRequest->getVal('replacement_str');
$continue_label = wfMsg('replacetext_continue');
$cancel_label = wfMsg('replacetext_cancel');
$replace_label = wfMsg('replacetext_replace');
$text =<<<END
<form method="post" action="">
<input type="hidden" name="target_str" value="$target_str">
<input type="hidden" name="replacement_str" value="$replacement_str">
<input type="hidden" name="replace" value="$replace_label">
<p>$message</p>
<p><input type="Submit" name="confirm" value="$continue_label"></p>
<p>$cancel_label</p>
</form>
END;
return $text;
}
function doReplaceText() {
global $wgUser, $wgOut, $wgRequest;
if ($wgRequest->getCheck('replace')) {
$dbr =& wfGetDB( DB_SLAVE );
$fname = 'doReplaceText';
$target_str = $wgRequest->getVal('target_str');
$replacement_str = $wgRequest->getVal('replacement_str');
// create an array of all the page titles for the wiki
$res = $dbr->select( 'page',
array( 'page_title', 'page_namespace' ),
array( 'page_is_redirect' => false ),
$fname
);
$titles = array();
while( $s = $dbr->fetchObject( $res ) ) {
// ignore pages in Talk and MediaWiki namespaces
if (($s->page_namespace != NS_TALK) && ($s->page_namespace != NS_MEDIAWIKI)) {
$title = Title::newFromText($s->page_title, $s->page_namespace);
$titles[] = $title;
}
}
if (! $wgRequest->getCheck('confirm')) {
// display a page to make the user confirm the replacement, if the
// replacement string is either blank or found elsewhere on the wiki
// (since undoing the replacement would be difficult in either case)
if ($replacement_str == '') {
$text = wfMsg('replacetext_blankwarning');
$wgOut->addHTML(displayConfirmForm($text));
return;
} else {
$num_files_with_replacement_str = 0;
foreach ($titles as $title) {
$article = new Article($title);
$article_text = $article->fetchContent();
if (strpos($article_text, $replacement_str)) {
$num_files_with_replacement_str++;
}
}
if ($num_files_with_replacement_str > 0) {
$text = wfMsg('replacetext_warning', $num_files_with_replacement_str, $replacement_str);
$wgOut->addHTML(displayConfirmForm($text));
return;
}
}
}
$num_modified_files = 0;
foreach ($titles as $title) {
$article = new Article($title);
$article_text = $article->fetchContent();
$num_matches;
$new_text = str_replace($target_str, $replacement_str, $article_text, $num_matches);
// if there's at least one replacement, modify the page, using an edit
// summary in the language of the wiki
if ($num_matches > 0) {
$edit_summary = wfMsgForContent('replacetext_editsummary', $target_str, $replacement_str);
$article->doEdit($new_text, $edit_summary);
$num_modified_files++;
}
}
if ($num_modified_files == 0)
$wgOut->addHTML(wfMsg('replacetext_noreplacement', $target_str));
else
$wgOut->addHTML(wfMsg('replacetext_success', $target_str, $replacement_str, $num_modified_files));
} else {
$replacement_label = wfMsg('replacetext_docu');
$replacement_note = wfMsg('replacetext_note');
$original_text_label = wfMsg('replacetext_originaltext');
$replacement_text_label = wfMsg('replacetext_replacementtext');
$replace_label = wfMsg('replacetext_replace');
$text =<<<END
<form method="post" action="">
<p>$replacement_label</p>
<p>$replacement_note</p>
<br />
<p>$original_text_label: <input type="text" length="10" name="target_str">
&nbsp;
$replacement_text_label: <input type="text" length="10" name="replacement_str"></p>
<p><input type="Submit" name="replace" value="$replace_label"></p>
</form>
END;
}
$wgOut->addHTML($text);
}