Index: trunk/extensions/ReplaceText/ReplaceText.php |
— | — | @@ -16,7 +16,7 @@ |
17 | 17 | * the page provides a warning prompt to the user before doing the |
18 | 18 | * replacement, since it is not easily reversible. |
19 | 19 | * |
20 | | - * @version 0.1.1 |
| 20 | + * @version 0.2 |
21 | 21 | * @author Yaron Koren |
22 | 22 | */ |
23 | 23 | |
— | — | @@ -34,6 +34,11 @@ |
35 | 35 | $wgExtensionFunctions[] = 'grfLoadMessagesManually'; |
36 | 36 | } |
37 | 37 | |
| 38 | +$wgJobClasses['replaceText'] = 'ReplaceTextJob'; |
| 39 | + |
| 40 | +require_once( "$IP/includes/JobQueue.php" ); |
| 41 | +require_once($grIP . '/ReplaceTextJob.php'); |
| 42 | + |
38 | 43 | function grSetupExtension() { |
39 | 44 | global $wgVersion, $wgExtensionCredits; |
40 | 45 | |
— | — | @@ -43,7 +48,7 @@ |
44 | 49 | // credits |
45 | 50 | $wgExtensionCredits['specialpage'][] = array( |
46 | 51 | 'name' => 'Replace Text', |
47 | | - 'version' => '0.1.1', |
| 52 | + 'version' => '0.2', |
48 | 53 | 'author' => 'Yaron Koren', |
49 | 54 | 'url' => 'http://www.mediawiki.org/wiki/Extension:Text_Replace', |
50 | 55 | 'description' => 'A special page that lets administrators run a global search-and-replace', |
— | — | @@ -86,12 +91,10 @@ |
87 | 92 | $replacement_str = $wgRequest->getVal('replacement_str'); |
88 | 93 | $continue_label = wfMsg('replacetext_continue'); |
89 | 94 | $cancel_label = wfMsg('replacetext_cancel'); |
90 | | - $replace_label = wfMsg('replacetext_replace'); |
91 | 95 | $text =<<<END |
92 | 96 | <form method="post" action=""> |
93 | 97 | <input type="hidden" name="target_str" value="$target_str"> |
94 | 98 | <input type="hidden" name="replacement_str" value="$replacement_str"> |
95 | | - <input type="hidden" name="replace" value="$replace_label"> |
96 | 99 | <p>$message</p> |
97 | 100 | <p><input type="Submit" name="confirm" value="$continue_label"></p> |
98 | 101 | <p>$cancel_label</p> |
— | — | @@ -105,6 +108,33 @@ |
106 | 109 | global $wgUser, $wgOut, $wgRequest; |
107 | 110 | |
108 | 111 | if ($wgRequest->getCheck('replace')) { |
| 112 | + $target_str = $wgRequest->getVal('target_str'); |
| 113 | + $replacement_str = $wgRequest->getVal('replacement_str'); |
| 114 | + $replacement_params = array(); |
| 115 | + $replacement_params['user_id'] = $wgUser->getId(); |
| 116 | + $replacement_params['target_str'] = $target_str; |
| 117 | + $replacement_params['replacement_str'] = $replacement_str; |
| 118 | + $replacement_params['edit_summary'] = wfMsgForContent('replacetext_editsummary', $target_str, $replacement_str); |
| 119 | + foreach ($wgRequest->getValues() as $key => $value) { |
| 120 | + if ($value == 'on') { |
| 121 | + $title = Title::newFromId($key); |
| 122 | +/* |
| 123 | + $num_matches; |
| 124 | + $new_text = str_replace($target_str, $replacement_str, $article_text, $num_matches); |
| 125 | + // if there's at least one replacement, modify the page, using an edit |
| 126 | + // summary in the language of the wiki |
| 127 | + if ($num_matches > 0) { |
| 128 | + $edit_summary = wfMsgForContent('replacetext_editsummary', $target_str, $replacement_str); |
| 129 | + $article->doEdit($new_text, $edit_summary); |
| 130 | + } |
| 131 | +*/ |
| 132 | + $jobs[] = new ReplaceTextJob( $title, $replacement_params ); |
| 133 | + } |
| 134 | + } |
| 135 | + Job::batchInsert( $jobs ); |
| 136 | + $num_modified_pages = count($jobs); |
| 137 | + $wgOut->addHTML(wfMsg('replacetext_success', $target_str, $replacement_str, $num_modified_pages)); |
| 138 | + } elseif ($wgRequest->getCheck('target_str')) { |
109 | 139 | $dbr =& wfGetDB( DB_SLAVE ); |
110 | 140 | $fname = 'doReplaceText'; |
111 | 141 | $target_str = $wgRequest->getVal('target_str'); |
— | — | @@ -135,60 +165,88 @@ |
136 | 166 | $wgOut->addHTML(displayConfirmForm($text)); |
137 | 167 | return; |
138 | 168 | } else { |
139 | | - $num_files_with_replacement_str = 0; |
| 169 | + $num_pages_with_replacement_str = 0; |
140 | 170 | foreach ($titles as $title) { |
141 | 171 | $article = new Article($title); |
142 | 172 | $article_text = $article->fetchContent(); |
143 | 173 | if (strpos($article_text, $replacement_str)) { |
144 | | - $num_files_with_replacement_str++; |
| 174 | + $num_pages_with_replacement_str++; |
145 | 175 | } |
146 | 176 | } |
147 | | - if ($num_files_with_replacement_str > 0) { |
148 | | - $text = wfMsg('replacetext_warning', $num_files_with_replacement_str, $replacement_str); |
| 177 | + if ($num_pages_with_replacement_str > 0) { |
| 178 | + $text = wfMsg('replacetext_warning', $num_pages_with_replacement_str, $replacement_str); |
149 | 179 | $wgOut->addHTML(displayConfirmForm($text)); |
150 | 180 | return; |
151 | 181 | } |
152 | 182 | } |
153 | 183 | } |
154 | 184 | |
155 | | - $num_modified_files = 0; |
| 185 | + $jobs = array(); |
| 186 | + $num_modified_pages = 0; |
| 187 | + $found_titles = array(); |
| 188 | + $angle_brackets = array('<', '>'); |
| 189 | + $escaped_angle_brackets = array('<', '>'); |
156 | 190 | foreach ($titles as $title) { |
157 | 191 | $article = new Article($title); |
158 | 192 | $article_text = $article->fetchContent(); |
159 | | - $num_matches; |
160 | | - $new_text = str_replace($target_str, $replacement_str, $article_text, $num_matches); |
161 | | - // if there's at least one replacement, modify the page, using an edit |
162 | | - // summary in the language of the wiki |
163 | | - if ($num_matches > 0) { |
164 | | - $edit_summary = wfMsgForContent('replacetext_editsummary', $target_str, $replacement_str); |
165 | | - $article->doEdit($new_text, $edit_summary); |
166 | | - $num_modified_files++; |
| 193 | + if ($target_pos = strpos($article_text, $target_str)) { |
| 194 | + $left_padding = min($target_pos, 30); |
| 195 | + $right_padding = min(strlen($article_text) - $target_pos, 30); |
| 196 | + $len = strlen($article_text); |
| 197 | + $context_str = ""; |
| 198 | + if ($left_padding == 30) |
| 199 | + $context_str .= "... "; |
| 200 | + $context_str .= str_replace($angle_brackets, $escaped_angle_brackets, substr($article_text, $target_pos - $left_padding, $left_padding)) . "<span class=\"searchmatch\">" . str_replace($angle_brackets, $escaped_angle_brackets, substr($article_text, $target_pos, strlen($target_str))) . "</span>" . str_replace($angle_brackets, $escaped_angle_brackets, substr($article_text, $target_pos + strlen($target_str), $right_padding)); |
| 201 | + if ($right_padding == 30) |
| 202 | + $context_str .= " ..."; |
| 203 | + $found_titles[] = array($title, $context_str); |
| 204 | + $num_modified_pages++; |
167 | 205 | } |
168 | 206 | } |
169 | 207 | |
170 | | - if ($num_modified_files == 0) |
| 208 | + if ($num_modified_pages == 0) |
171 | 209 | $wgOut->addHTML(wfMsg('replacetext_noreplacement', $target_str)); |
172 | | - else |
173 | | - $wgOut->addHTML(wfMsg('replacetext_success', $target_str, $replacement_str, $num_modified_files)); |
| 210 | + else { |
| 211 | + $replace_label = wfMsg('replacetext_replace'); |
| 212 | + $choose_pages_label = wfMsg('replacetext_choosepages', $target_str, $replacement_str); |
| 213 | + $skin = $wgUser->getSkin(); |
| 214 | + $text =<<<END |
| 215 | + <p>$choose_pages_label</p> |
| 216 | + <form method="post"> |
| 217 | + <input type="hidden" name="target_str" value="$target_str"> |
| 218 | + <input type="hidden" name="replacement_str" value="$replacement_str"> |
| 219 | + |
| 220 | +END; |
| 221 | + foreach ($found_titles as $value_pair) { |
| 222 | + list($title, $context_str) = $value_pair; |
| 223 | + $text .= "<input type=\"checkbox\" name=\"{$title->getArticleID()}\" checked /> {$skin->makeLinkObj( $title, $title->prefix($title->getText()) )} - <small>$context_str</small><br />\n"; |
| 224 | + } |
| 225 | + $text .=<<<END |
| 226 | + <p><input type="Submit" name="replace" value="$replace_label"></p> |
| 227 | + </form> |
| 228 | + |
| 229 | +END; |
| 230 | + $wgOut->addHTML($text); |
| 231 | + } |
174 | 232 | } else { |
175 | 233 | $replacement_label = wfMsg('replacetext_docu'); |
176 | 234 | $replacement_note = wfMsg('replacetext_note'); |
177 | 235 | $original_text_label = wfMsg('replacetext_originaltext'); |
178 | 236 | $replacement_text_label = wfMsg('replacetext_replacementtext'); |
179 | | - $replace_label = wfMsg('replacetext_replace'); |
| 237 | + $continue_label = wfMsg('replacetext_continue'); |
180 | 238 | $text =<<<END |
181 | | - <form method="post" action=""> |
| 239 | + <form method="get" action=""> |
182 | 240 | <p>$replacement_label</p> |
183 | 241 | <p>$replacement_note</p> |
184 | 242 | <br /> |
185 | 243 | <p>$original_text_label: <input type="text" length="10" name="target_str"> |
186 | 244 | |
187 | 245 | $replacement_text_label: <input type="text" length="10" name="replacement_str"></p> |
188 | | - <p><input type="Submit" name="replace" value="$replace_label"></p> |
| 246 | + <p><input type="Submit" value="$continue_label"></p> |
189 | 247 | </form> |
190 | 248 | |
191 | 249 | END; |
| 250 | + $wgOut->addHTML($text); |
192 | 251 | } |
193 | 252 | |
194 | | - $wgOut->addHTML($text); |
195 | 253 | } |