Wiki source for ReplaceAction


Show raw source

===== Replace Action =====
>>**See Also**
~- [[http://www.php.net/manual/en/function.preg-replace.php | PHP: preg_replace]]
~- [[http://www.php.net/manual/en/function.preg-match.php | PHP: preg_match]]
**DRAFT**
~- action works, but userinterface needs attention...
>>//DRAFT - NOT Included in any Wikka version yet//{{lastedit}}
==What==
~- A way to find and replace a string in one/multiple/all pages.

==Use==
~- Call the ""{{replace}}"" action in a page (e.g. ""AdminReplace"")

~- In the form enter a pattern under "Find string" (e.g. ##/string/i##) and click the "Replace"-button.
~- As the "Save Changes" checkbox isn't selected, only pagenames matching the pattern are showed
~- You can limit false positives by also giving a pattern for "Page grep" (e.g. ##/^Doc/##, all pages starting with "Doc")
~- Give a "Replace with" string (e.g. ##gnirts##) and click again the "Replace"-button.
~- If this give an expected list of pages to change click for the last time on the "Replace"-button.
~- Please note the uniq timestamp for undo functions (also showed in RecentChanges)

==Examples==
~- /.*/ + /abc123/i + ABC123 + TRUE ---find in all pages 'abc123' (+all case variation) and save in db as uppercase ABC123 e.g. rename a category in all pages
~- -EMPTY- + -EMPTY- + -EMPTY- + -EMPTY- ---no changes, not saved, will just list all pages (no harm)
~- /^wakka/i + /.*/ + -EMPTY- + TRUE ---will clear all pages with a pagename starting with 'Wakka'

==Parameters==
~- UNDER CONSTRUCTION
~""<table cellspacing="0" cellpadding="2" border="1"><thead>
<tr><th scope="col">name</th><th scope="col">type</th><th scope="col">required?</th><th scope="col">default</th><th scope="col">description</th></tr>
</thead><tbody>
<tr><td>aaa</td><td>string</td><td>optional</td><td>empty</td><td>...</td></tr>
</tbody>
</table>""

==Features==
~- Limit the number of pages to change by regex on the pagename/tag.
~- UNDO of one or all pages is possible (via uniq timestamp in 'note').
~- $1, $2,... also works for advanced replacements.
~- Form is pre-filled with last request, so small changes in pattern are easy to make.
~- **W A R N I N G**: removing all content on the whole site is very easy...

==Installation==
~- Save the code below as ##action/replace.php##
~- Give it the same file permissions as the other php files in that directory.

==Code==
~%%(php)<?php
/**
* Find and replace strings in (all) pages.
*
* With some tools you can shoot yourself in the foot,
* aim wrong with this action, and both your legs are gone...
* Extremely powerfull, equaly dangerous !
*
* DRAFT - fully working, but userinterface needs attention
*
* For syntax: see the php-manual for preg_match and preg_replace
*
* UNDO is possible via the normal page revisions / history
* as all saved changes have the same note (with a timestamp)
* it is easy to undo a replacement via e.g. phpMyAdmin - tool
*
* @package Action
* @subpackage AdminModules
* @name Replace
*
* @author {@link http://wikkawiki.org/OnegWR OnegWR}
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @copyright Copyright (c) 2005, OnegWR
* @version 0.1
*
* @input string replace_page - preg_match/grep on pagename/tag
* to limit the number of pages to change (30sec timeout workaround)
* default: / .* / - all pages
* @input string replace_find - pattern to find
* default: // - match any
* @input string replace_by
* default: EMPTY - delete found pattern
* @input boolean replace_save - confirm write to db
* on = save the changes
* default: off - changes not saved
*
* @output (list of changed pages)
*
*
* @todo - Benchmark: what can be done in 30sec
* - i18n
* - GET requests (only POST now)
* - count changes (+preview ?)
*
* @bugs - if you start two replace jobs in the same sec
* no individual 'undo' can be done
*/

$replace = array();

if ( $this->IsAdmin() )
{
if ( isset( $_REQUEST['submit'] ) && $_REQUEST['submit']=='Replace' )
{
$replace['page'] = ($_REQUEST['replace_page']<>'') ? $_REQUEST['replace_page'] : '/.*/';
$replace['find'] = ($_REQUEST['replace_find']<>'') ? $_REQUEST['replace_find'] : '//';
$replace['by'] = $_REQUEST['replace_by'];
$replace['save'] = (isset( $_REQUEST['replace_save'] ) && $_REQUEST['replace_save']=='on') ? TRUE : FALSE;

$replace_arr = $this->LoadAllPages();
foreach ( $replace_arr as $key => $value )
{
if ( preg_match( $replace['page'], $value['tag'] ) )
{
if ( !preg_match( $replace['find'], $value['body'] ) )
{
unset( $replace_arr[$key] ); // hasn't got string to find in body
}

}
else
{
unset( $replace_arr[$key] ); // Not right page/tag name
}
}

// OnegWR: at this point only related pages are left...
if ( $replace_arr == array() )
{
print "\nNo pages found matching both requirements - nothing to replace...<br />\n";
}
else
{
$replace['undo'] = "SnR". date('YmdHis');
foreach ( $replace_arr as $key => $value )
{
if ( $replace['save'] )
{
$replace_arr[$key]['body'] = preg_replace( $replace['find'], $replace['by'], $value['body'] );
$this->SavePage( $value['tag'], $replace_arr[$key]['body'], $replace['undo'] );

print $this->Link( $value['tag'], "", "", 0 ) .
" (". $this->Link( $value['tag'], "revisions", $timeformatted, 0, 1, "View recent revisions list for ".$value['tag']).")" .
" [". $this->Link( $value['tag'], "history", "history", 0, 1, "View edit history of ".$value['tag'])."]" .
"<br />\n";
//print_r( $replace_arr[$key] );
}
else
{
// test only... nothing is saved...
print $this->Link( $value['tag'], "", "", 0 ) ."<br />\n";
}
}
if ( $replace['save'] )
{
print "\n<br /><br />Undo trigger in note: ". $replace['undo'] ."<br />\n\n";
}
}
}


// print form
print $this->FormOpen("","","post");
print <<< EOT
<fieldset>
<legend>Search and replace strings in (all) pages</legend>
{$replace_error}
<label for="replace_page">Page grep: </label><input type="text" name="replace_page" value="{$replace['page']}" size="10" maxlength="50" title="Limit the number of pages"><br />
<label for="replace_find">Find string: </label><input type="text" name="replace_find" value="{$replace['find']}" size="10" maxlength="50"><br />
<label for="replace_by">Replace with: </label><input type="text" name="replace_by" value="{$replace['by']}" size="10" maxlength="50"><br />
<label for="replace_save">Save changes? </label><input type="checkbox" name="replace_save" size="10" maxlength="50"><br />
<label for="replace_submit"> </label><input type="submit" name="submit" value="Replace">
</fieldset>
EOT;
print $this->FormClose();

}
else
{
// no error if not admin...
}
?>%%
==Demo==
~- UNDER CONSTRUCTION

==To Do==
~- a lot...

----
CategoryUserContributions
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki