Fix for compatibility with short_open_tag = Off
[lhc/web/wiklou.git] / includes / EditPage.php
1 <?php
2
3 # Splitting edit page/HTML interface from Article...
4 # The actual database and text munging is still in Article,
5 # but it should get easier to call those from alternate
6 # interfaces.
7
8 class EditPage {
9 var $mArticle;
10 var $mTitle;
11
12 function EditPage( $article ) {
13 $this->mArticle =& $article;
14 global $wgTitle;
15 $this->mTitle =& $wgTitle;
16 }
17
18 # This is the function that gets called for "action=edit".
19
20 function edit()
21 {
22 global $wgOut, $wgUser, $wgWhitelistEdit;
23 global $wpTextbox1, $wpSummary, $wpSave, $wpPreview;
24 global $wpMinoredit, $wpEdittime, $wpTextbox2;
25 // this is not an article
26 $wgOut->setArticleFlag(false);
27
28 $fields = array( "wpTextbox1", "wpSummary", "wpTextbox2" );
29 wfCleanFormFields( $fields );
30
31 if ( ! $this->mTitle->userCanEdit() ) {
32 $wgOut->readOnlyPage( $this->mArticle->getContent(), true );
33 return;
34 }
35 if ( $wgUser->isBlocked() ) {
36 $this->blockedIPpage();
37 return;
38 }
39 if ( !$wgUser->getID() && $wgWhitelistEdit ) {
40 $this->userNotLoggedInPage();
41 return;
42 }
43 if ( wfReadOnly() ) {
44 if( isset( $wpSave ) or isset( $wpPreview ) ) {
45 $this->editForm( "preview" );
46 } else {
47 $wgOut->readOnlyPage( $this->mArticle->getContent() );
48 }
49 return;
50 }
51 if ( $_SERVER['REQUEST_METHOD'] != "POST" ) unset( $wpSave );
52 if ( isset( $wpSave ) ) {
53 $this->editForm( "save" );
54 } else if ( isset( $wpPreview ) ) {
55 $this->editForm( "preview" );
56 } else { # First time through
57 $this->editForm( "initial" );
58 }
59 }
60
61 # Since there is only one text field on the edit form,
62 # pressing <enter> will cause the form to be submitted, but
63 # the submit button value won't appear in the query, so we
64 # Fake it here before going back to edit(). This is kind of
65 # ugly, but it helps some old URLs to still work.
66
67 function submit()
68 {
69 global $wpSave, $wpPreview;
70 if ( ! isset( $wpPreview ) ) { $wpSave = 1; }
71
72 $this->edit();
73 }
74
75 # The edit form is self-submitting, so that when things like
76 # preview and edit conflicts occur, we get the same form back
77 # with the extra stuff added. Only when the final submission
78 # is made and all is well do we actually save and redirect to
79 # the newly-edited page.
80
81 function editForm( $formtype )
82 {
83 global $wgOut, $wgUser;
84 global $wpTextbox1, $wpSummary, $wpWatchthis;
85 global $wpSave, $wpPreview;
86 global $wpMinoredit, $wpEdittime, $wpTextbox2, $wpSection;
87 global $oldid, $redirect, $section;
88 global $wgLang;
89 global $wgAllowAnonymousMinor;
90
91 if(isset($wpSection)) { $section=$wpSection; } else { $wpSection=$section; }
92
93 $sk = $wgUser->getSkin();
94 $isConflict = false;
95 $wpTextbox1 = rtrim ( $wpTextbox1 ) ; # To avoid text getting longer on each preview
96
97 if(!$this->mTitle->getArticleID()) { # new article
98
99 $wgOut->addWikiText(wfmsg("newarticletext"));
100
101 }
102
103 # Attempt submission here. This will check for edit conflicts,
104 # and redundantly check for locked database, blocked IPs, etc.
105 # that edit() already checked just in case someone tries to sneak
106 # in the back door with a hand-edited submission URL.
107
108 if ( "save" == $formtype ) {
109 if ( $wgUser->isBlocked() ) {
110 $this->blockedIPpage();
111 return;
112 }
113 if ( !$wgUser->getID() && $wgWhitelistEdit ) {
114 $this->userNotLoggedInPage();
115 return;
116 }
117 if ( wfReadOnly() ) {
118 $wgOut->readOnlyPage();
119 return;
120 }
121 # If article is new, insert it.
122
123 $aid = $this->mTitle->getArticleID();
124 if ( 0 == $aid ) {
125 # we need to strip Windoze linebreaks because some browsers
126 # append them and the string comparison fails
127 if ( ( "" == $wpTextbox1 ) ||
128 ( wfMsg( "newarticletext" ) == rtrim( preg_replace("/\r/","",$wpTextbox1) ) ) ) {
129 $wgOut->redirect( wfLocalUrl(
130 $this->mTitle->getPrefixedURL() ) );
131 return;
132 }
133 $this->mArticle->insertNewArticle( $wpTextbox1, $wpSummary, $wpMinoredit, $wpWatchthis );
134 return;
135 }
136 # Article exists. Check for edit conflict.
137 # Don't check for conflict when appending a comment - this should always work
138
139 $this->mArticle->clear(); # Force reload of dates, etc.
140 if ( $section!="new" && ( $this->mArticle->getTimestamp() != $wpEdittime ) ) {
141 $isConflict = true;
142 }
143 $u = $wgUser->getID();
144
145 # Supress edit conflict with self
146
147 if ( ( 0 != $u ) && ( $this->mArticle->getUser() == $u ) ) {
148 $isConflict = false;
149 } else {
150 # switch from section editing to normal editing in edit conflict
151 if($isConflict) {
152 $section="";$wpSection="";
153 }
154
155 }
156 if ( ! $isConflict ) {
157 # All's well: update the article here
158 if($this->mArticle->updateArticle( $wpTextbox1, $wpSummary, $wpMinoredit, $wpWatchthis, $wpSection ))
159 return;
160 else
161 $isConflict = true;
162 }
163 }
164 # First time through: get contents, set time for conflict
165 # checking, etc.
166
167 if ( "initial" == $formtype ) {
168 $wpEdittime = $this->mArticle->getTimestamp();
169 $wpTextbox1 = $this->mArticle->getContent(true);
170 $wpSummary = "";
171 }
172 $wgOut->setRobotpolicy( "noindex,nofollow" );
173
174 # Enabled article-related sidebar, toplinks, etc.
175 $wgOut->setArticleRelated( true );
176
177 if ( $isConflict ) {
178 $s = wfMsg( "editconflict", $this->mTitle->getPrefixedText() );
179 $wgOut->setPageTitle( $s );
180 $wgOut->addHTML( wfMsg( "explainconflict" ) );
181
182 $wpTextbox2 = $wpTextbox1;
183 $wpTextbox1 = $this->mArticle->getContent(true);
184 $wpEdittime = $this->mArticle->getTimestamp();
185 } else {
186 $s = wfMsg( "editing", $this->mTitle->getPrefixedText() );
187
188 if($section!="") {
189 if($section=="new") {
190 $s.=wfMsg("commentedit");
191 } else {
192 $s.=wfMsg("sectionedit");
193 }
194 }
195 $wgOut->setPageTitle( $s );
196 if ( $oldid ) {
197 $this->mArticle->setOldSubtitle();
198 $wgOut->addHTML( wfMsg( "editingold" ) );
199 }
200 }
201
202 if( wfReadOnly() ) {
203 $wgOut->addHTML( "<strong>" .
204 wfMsg( "readonlywarning" ) .
205 "</strong>" );
206 }
207 if( $this->mTitle->isProtected() ) {
208 $wgOut->addHTML( "<strong>" . wfMsg( "protectedpagewarning" ) .
209 "</strong><br />\n" );
210 }
211
212 $kblength = (int)(strlen( $wpTextbox1 ) / 1024);
213 if( $kblength > 29 ) {
214 $wgOut->addHTML( "<strong>" .
215 wfMsg( "longpagewarning", $kblength )
216 . "</strong>" );
217 }
218
219 $rows = $wgUser->getOption( "rows" );
220 $cols = $wgUser->getOption( "cols" );
221
222 $ew = $wgUser->getOption( "editwidth" );
223 if ( $ew ) $ew = " style=\"width:100%\"";
224 else $ew = "" ;
225
226 $q = "action=submit";
227 if ( "no" == $redirect ) { $q .= "&redirect=no"; }
228 $action = wfEscapeHTML( wfLocalUrl( $this->mTitle->getPrefixedURL(), $q ) );
229
230 $summary = wfMsg( "summary" );
231 $subject = wfMsg("subject");
232 $minor = wfMsg( "minoredit" );
233 $watchthis = wfMsg ("watchthis");
234 $save = wfMsg( "savearticle" );
235 $prev = wfMsg( "showpreview" );
236
237 $cancel = $sk->makeKnownLink( $this->mTitle->getPrefixedURL(),
238 wfMsg( "cancel" ) );
239 $edithelp = $sk->makeKnownLink( wfMsg( "edithelppage" ),
240 wfMsg( "edithelp" ) );
241 $copywarn = wfMsg( "copyrightwarning", $sk->makeKnownLink(
242 wfMsg( "copyrightpage" ) ) );
243
244 $wpTextbox1 = wfEscapeHTML( $wpTextbox1 );
245 $wpTextbox2 = wfEscapeHTML( $wpTextbox2 );
246 $wpSummary = wfEscapeHTML( $wpSummary );
247
248
249 if($wgUser->getOption("showtoolbar")) {
250 // prepare toolbar for edit buttons
251 $toolbar=$sk->getEditToolbar();
252 }
253
254 // activate checkboxes if user wants them to be always active
255 if (!$wpPreview && $wgUser->getOption("watchdefault")) $wpWatchthis=1;
256 if (!$wpPreview && $wgUser->getOption("minordefault")) $wpMinoredit=1;
257
258 // activate checkbox also if user is already watching the page,
259 // require wpWatchthis to be unset so that second condition is not
260 // checked unnecessarily
261 if (!$wpWatchthis && !$wpPreview && $this->mTitle->userIsWatching()) $wpWatchthis=1;
262
263 $minoredithtml = "";
264
265 if ( 0 != $wgUser->getID() || $wgAllowAnonymousMinor ) {
266 $minoredithtml =
267 "<input tabindex=3 type=checkbox value=1 name='wpMinoredit'".($wpMinoredit?" checked":"")." id='wpMinoredit'>".
268 "<label for='wpMinoredit'>{$minor}</label>";
269 }
270
271 $watchhtml = "";
272
273 if ( 0 != $wgUser->getID() ) {
274 $watchhtml = "<input tabindex=4 type=checkbox name='wpWatchthis'".($wpWatchthis?" checked":"")." id='wpWatchthis'>".
275 "<label for='wpWatchthis'>{$watchthis}</label>";
276
277 }
278
279 $checkboxhtml= $minoredithtml . $watchhtml . "<br>";
280
281 if ( "preview" == $formtype) {
282
283 $previewhead="<h2>" . wfMsg( "preview" ) . "</h2>\n<p><large><center><font color=\"#cc0000\">" .
284 wfMsg( "note" ) . wfMsg( "previewnote" ) . "</font></center></large><P>\n";
285 if ( $isConflict ) {
286 $previewhead.="<h2>" . wfMsg( "previewconflict" ) .
287 "</h2>\n";
288 }
289 $previewtext = wfUnescapeHTML( $wpTextbox1 );
290
291 if($wgUser->getOption("previewontop")) {
292 $wgOut->addHTML($previewhead);
293 $wgOut->addWikiText( $this->mArticle->preSaveTransform( $previewtext ) ."\n\n");
294 }
295 $wgOut->addHTML( "<br clear=\"all\" />\n" );
296 }
297
298 # if this is a comment, show a subject line at the top, which is also the edit summary.
299 # Otherwise, show a summary field at the bottom
300 if($section=="new") {
301
302 $commentsubject="{$subject}: <input tabindex=1 type=text value=\"{$wpSummary}\" name=\"wpSummary\" maxlength=200 size=60><br>";
303 } else {
304
305 $editsummary="{$summary}: <input tabindex=3 type=text value=\"{$wpSummary}\" name=\"wpSummary\" maxlength=200 size=60><br>";
306 }
307
308 if( $_GET["action"] == "edit" ) {
309 # Don't select the edit box on preview; this interferes with seeing what's going on.
310 $wgOut->setOnloadHandler( "document.editform.wpTextbox1.focus()" );
311 }
312 $wgOut->addHTML( "
313 {$toolbar}
314 <form id=\"editform\" name=\"editform\" method=\"post\" action=\"$action\"
315 enctype=\"application/x-www-form-urlencoded\">
316 {$commentsubject}
317 <textarea tabindex=2 name=\"wpTextbox1\" rows={$rows}
318 cols={$cols}{$ew} wrap=\"virtual\">" .
319 $wgLang->recodeForEdit( $wpTextbox1 ) .
320 "
321 </textarea>
322 <br>{$editsummary}
323 {$checkboxhtml}
324 <input tabindex=5 type=submit value=\"{$save}\" name=\"wpSave\" accesskey=\"s\">
325 <input tabindex=6 type=submit value=\"{$prev}\" name=\"wpPreview\" accesskey=\"p\">
326 <em>{$cancel}</em> | <em>{$edithelp}</em>
327 <br><br>{$copywarn}
328 <input type=hidden value=\"{$section}\" name=\"wpSection\">
329 <input type=hidden value=\"{$wpEdittime}\" name=\"wpEdittime\">\n" );
330
331 if ( $isConflict ) {
332 $wgOut->addHTML( "<h2>" . wfMsg( "yourdiff" ) . "</h2>\n" );
333 DifferenceEngine::showDiff( $wpTextbox2, $wpTextbox1,
334 wfMsg( "yourtext" ), wfMsg( "storedversion" ) );
335
336 $wgOut->addHTML( "<h2>" . wfMsg( "yourtext" ) . "</h2>
337 <textarea tabindex=6 name=\"wpTextbox2\" rows={$rows} cols={$cols} wrap=virtual>"
338 . $wgLang->recodeForEdit( $wpTextbox2 ) .
339 "
340 </textarea>" );
341 }
342 $wgOut->addHTML( "</form>\n" );
343 if($formtype =="preview" && !$wgUser->getOption("previewontop")) {
344 $wgOut->addHTML($previewhead);
345 $wgOut->addWikiText( $this->mArticle->preSaveTransform( $previewtext ) );
346 }
347
348 }
349
350 function blockedIPpage()
351 {
352 global $wgOut, $wgUser, $wgLang, $wgIP;
353
354 $wgOut->setPageTitle( wfMsg( "blockedtitle" ) );
355 $wgOut->setRobotpolicy( "noindex,nofollow" );
356 $wgOut->setArticleRelated( false );
357
358 $id = $wgUser->blockedBy();
359 $reason = $wgUser->blockedFor();
360 $ip = $wgIP;
361
362 $name = User::whoIs( $id );
363 $link = "[[" . $wgLang->getNsText( Namespace::getUser() ) .
364 ":{$name}|{$name}]]";
365
366 $wgOut->addWikiText( wfMsg( "blockedtext", $link, $reason, $ip ) );
367 $wgOut->returnToMain( false );
368 }
369
370
371
372 function userNotLoggedInPage()
373 {
374 global $wgOut, $wgUser, $wgLang;
375
376 $wgOut->setPageTitle( wfMsg( "whitelistedittitle" ) );
377 $wgOut->setRobotpolicy( "noindex,nofollow" );
378 $wgOut->setArticleRelated( false );
379
380 $wgOut->addWikiText( wfMsg( "whitelistedittext" ) );
381 $wgOut->returnToMain( false );
382 }
383
384
385 }
386
387 ?>