Page move undo feature
[lhc/web/wiklou.git] / includes / SpecialMovepage.php
1 <?php
2 /**
3 *
4 * @package MediaWiki
5 * @subpackage SpecialPage
6 */
7
8 /**
9 *
10 */
11 require_once( "LinksUpdate.php" );
12
13 /**
14 * Constructor
15 */
16 function wfSpecialMovepage() {
17 global $wgUser, $wgOut, $wgRequest, $action, $wgOnlySysopMayMove;
18
19 # check rights. We don't want newbies to move pages to prevents possible attack
20 if ( $wgUser->isAnon() or $wgUser->isBlocked() or ($wgOnlySysopMayMove and $wgUser->isNewbie())) {
21 $wgOut->errorpage( "movenologin", "movenologintext" );
22 return;
23 }
24 # We don't move protected pages
25 if ( wfReadOnly() ) {
26 $wgOut->readOnlyPage();
27 return;
28 }
29
30 $f = new MovePageForm();
31
32 if ( 'success' == $action ) {
33 $f->showSuccess();
34 } else if ( 'submit' == $action && $wgRequest->wasPosted()
35 && $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) ) ) {
36 $f->doSubmit();
37 } else {
38 $f->showForm( '' );
39 }
40 }
41
42 /**
43 *
44 * @package MediaWiki
45 * @subpackage SpecialPage
46 */
47 class MovePageForm {
48 var $oldTitle, $newTitle, $reason; # Text input
49 var $moveTalk;
50
51 function MovePageForm() {
52 global $wgRequest;
53 $this->oldTitle = $wgRequest->getText( 'wpOldTitle', $wgRequest->getVal( 'target' ) );
54 $this->newTitle = $wgRequest->getText( 'wpNewTitle' );
55 $this->reason = $wgRequest->getText( 'wpReason' );
56 $this->moveTalk = $wgRequest->getBool( 'wpMovetalk', true );
57 }
58
59 function showForm( $err ) {
60 global $wgOut, $wgUser, $wgLang;
61
62 $wgOut->setPagetitle( wfMsg( 'movepage' ) );
63
64 if ( $this->oldTitle == '' ) {
65 $wgOut->errorpage( 'notargettitle', 'notargettext' );
66 return;
67 }
68
69 $ot = Title::newFromURL( $this->oldTitle );
70 $oldTitle = $ot->getPrefixedText();
71
72 $encOldTitle = htmlspecialchars( $this->oldTitle );
73 if( $this->newTitle == '' ) {
74 # Show the current title as a default
75 # when the form is first opened.
76 $encNewTitle = $oldTitle;
77 } else {
78 $encNewTitle = htmlspecialchars( $this->newTitle );
79 }
80 $encReason = htmlspecialchars( $this->reason );
81
82 $wgOut->addWikiText( wfMsg( 'movepagetext' ) );
83 if ( !$ot->isTalkPage() ) {
84 $wgOut->addWikiText( wfMsg( 'movepagetalktext' ) );
85 }
86
87 $movearticle = wfMsg( 'movearticle' );
88 $newtitle = wfMsg( 'newtitle' );
89 $movepagebtn = wfMsg( 'movepagebtn' );
90 $movetalk = wfMsg( 'movetalk' );
91 $movereason = wfMsg( 'movereason' );
92
93 $titleObj = Title::makeTitle( NS_SPECIAL, 'Movepage' );
94 $action = $titleObj->escapeLocalURL( 'action=submit' );
95 $token = htmlspecialchars( $wgUser->editToken() );
96
97 if ( $err != '' ) {
98 $wgOut->setSubtitle( wfMsg( 'formerror' ) );
99 $wgOut->addHTML( '<p class="error">'.$err."</p>\n" );
100 }
101
102 if ( $this->moveTalk ) {
103 $moveTalkChecked = " checked='checked'";
104 } else {
105 $moveTalkChecked = '';
106 }
107
108 $wgOut->addHTML( "
109 <form id=\"movepage\" method=\"post\" action=\"{$action}\">
110 <table border='0'>
111 <tr>
112 <td align='right'>{$movearticle}:</td>
113 <td align='left'><strong>{$oldTitle}</strong></td>
114 </tr>
115 <tr>
116 <td align='right'>{$newtitle}:</td>
117 <td align='left'>
118 <input type='text' size='40' name=\"wpNewTitle\" value=\"{$encNewTitle}\" />
119 <input type='hidden' name=\"wpOldTitle\" value=\"{$encOldTitle}\" />
120 </td>
121 </tr>
122 <tr>
123 <td align='right'>{$movereason}:</td>
124 <td align='left'>
125 <input type='text' size=40 name=\"wpReason\" value=\"{$encReason}\" />
126 </td>
127 </tr>" );
128
129 if ( ! $ot->isTalkPage() ) {
130 $wgOut->addHTML( "
131 <tr>
132 <td align='right'>
133 <input type='checkbox' name=\"wpMovetalk\"{$moveTalkChecked} value=\"1\" />
134 </td>
135 <td>{$movetalk}</td>
136 </tr>" );
137 }
138 $wgOut->addHTML( "
139 <tr>
140 <td>&nbsp;</td>
141 <td align='left'>
142 <input type='submit' name=\"wpMove\" value=\"{$movepagebtn}\" />
143 </td>
144 </tr>
145 </table>
146 <input type='hidden' name='wpEditToken' value=\"{$token}\" />
147 </form>\n" );
148
149 }
150
151 function doSubmit() {
152 global $wgOut, $wgUser, $wgLang;
153 global $wgDeferredUpdateList, $wgMessageCache;
154 global $wgUseSquid, $wgRequest;
155 $fname = "MovePageForm::doSubmit";
156
157 # Variables beginning with 'o' for old article 'n' for new article
158
159 # Attempt to move the article
160 $ot = Title::newFromText( $this->oldTitle );
161 $nt = Title::newFromText( $this->newTitle );
162
163 # don't allow moving to pages with # in
164 if ( !$nt || $nt->getFragment() != '' ) {
165 $this->showForm( wfMsg( "badtitletext" ) );
166 return;
167 }
168
169 $error = $ot->moveTo( $nt, true, $this->reason );
170 if ( $error !== true ) {
171 $this->showForm( wfMsg( $error ) );
172 return;
173 }
174
175 # Update counters if the article got moved into or out of NS_MAIN namespace
176 $ons = $ot->getNamespace();
177 $nns = $nt->getNamespace();
178
179 # moved out of article namespace?
180 if ( $ons == NS_MAIN and $nns != NS_MAIN ) {
181 $u = new SiteStatsUpdate( 0, 1, -1); # not viewed, edited, removing
182 }
183 # moved into article namespace?
184 elseif ( $ons != NS_MAIN and $nns == NS_MAIN ) {
185 $u = new SiteStatsUpdate( 0, 1, +1 ); # not viewed, edited, adding
186 } else {
187 $u = false;
188 }
189 if ( $u !== false ) {
190 # save it for later update
191 array_push( $wgDeferredUpdateList, $u );
192 unset($u);
193 }
194
195 # Move talk page if
196 # (1) the checkbox says to,
197 # (2) the namespaces are not themselves talk namespaces, and of course
198 # (3) it exists.
199 if ( ( $wgRequest->getVal('wpMovetalk') == 1 ) &&
200 ( ! Namespace::isTalk( $ons ) ) &&
201 ( ! Namespace::isTalk( $nns ) ) ) {
202
203 # get old talk page namespace
204 $ons = Namespace::getTalk( $ons );
205 # get new talk page namespace
206 $nns = Namespace::getTalk( $nns );
207
208 # make talk page title objects
209 $ott = Title::makeTitle( $ons, $ot->getDBkey() );
210 $ntt = Title::makeTitle( $nns, $nt->getDBkey() );
211
212 # Attempt the move
213 $error = $ott->moveTo( $ntt, true, $this->reason );
214 if ( $error === true ) {
215 $talkmoved = 1;
216 } else {
217 $talkmoved = $error;
218 }
219 }
220
221 # Give back result to user.
222 $titleObj = Title::makeTitle( NS_SPECIAL, 'Movepage' );
223 $success = $titleObj->getFullURL(
224 'action=success&oldtitle=' . wfUrlencode( $ot->getPrefixedText() ) .
225 '&newtitle=' . wfUrlencode( $nt->getPrefixedText() ) .
226 '&talkmoved='.$talkmoved );
227
228 $wgOut->redirect( $success );
229 }
230
231 function showSuccess() {
232 global $wgOut, $wgRequest, $wgRawHtml;
233
234 $wgOut->setPagetitle( wfMsg( 'movepage' ) );
235 $wgOut->setSubtitle( wfMsg( 'pagemovedsub' ) );
236 $oldtitle = $wgRequest->getVal('oldtitle');
237 $newtitle = $wgRequest->getVal('newtitle');
238 $talkmoved = $wgRequest->getVal('talkmoved');
239
240 $text = wfMsg( 'pagemovedtext', $oldtitle, $newtitle );
241
242 # Temporarily disable raw html wikitext option out of XSS paranoia
243 $marchingantofdoom = $wgRawHtml;
244 $wgRawHtml = false;
245 $wgOut->addWikiText( $text );
246 $wgRawHtml = $marchingantofdoom;
247
248 if ( $talkmoved == 1 ) {
249 $wgOut->addHTML( "\n<p>" . wfMsg( 'talkpagemoved' ) . "</p>\n" );
250 } elseif( 'articleexists' == $talkmoved ) {
251 $wgOut->addHTML( "\n<p><strong>" . wfMsg( 'talkexists' ) . "</strong></p>\n" );
252 } else {
253 $ot = Title::newFromURL( $oldtitle );
254 if ( ! $ot->isTalkPage() ) {
255 $wgOut->addHTML( "\n<p>" . wfMsg( 'talkpagenotmoved', wfMsg( $talkmoved ) ) . "</p>\n" );
256 }
257 }
258 }
259 }
260 ?>