00001 <?php
00002
00003
# Splitting edit page/HTML interface from Article...
00004
# The actual database and text munging is still in Article,
00005
# but it should get easier to call those from alternate
00006
# interfaces.
00007
00008
class EditPage {
00009 var $mArticle;
00010 var $mTitle;
00011
00012
# Form values
00013
var $save =
false, $preview =
false;
00014 var $minoredit =
false, $watchthis =
false;
00015 var $textbox1 =
"", $textbox2 =
"", $summary =
"";
00016 var $edittime =
"", $section =
"";
00017 var $oldid = 0;
00018
00019 function EditPage( $article ) {
00020 $this->mArticle =& $article;
00021 global
$wgTitle;
00022 $this->mTitle =&
$wgTitle;
00023 }
00024
00025
# This is the function that gets called for "action=edit".
00026
00027 function edit()
00028 {
00029 global
$wgOut,
$wgUser,
$wgWhitelistEdit,
$wgRequest;
00030
00031
$wgOut->setArticleFlag(
false);
00032
00033 $this->importFormData( $wgRequest );
00034
00035
if ( ! $this->mTitle->userCanEdit() ) {
00036
$wgOut->readOnlyPage( $this->mArticle->getContent(
true ),
true );
00037
return;
00038 }
00039
if (
$wgUser->isBlocked() ) {
00040 $this->blockedIPpage();
00041
return;
00042 }
00043
if ( !
$wgUser->getID() &&
$wgWhitelistEdit ) {
00044 $this->userNotLoggedInPage();
00045
return;
00046 }
00047
if (
wfReadOnly() ) {
00048
if( $this->save || $this->preview ) {
00049 $this->editForm(
"preview" );
00050 }
else {
00051
$wgOut->readOnlyPage( $this->mArticle->getContent(
true ) );
00052 }
00053
return;
00054 }
00055
if ( $this->save ) {
00056 $this->editForm(
"save" );
00057 }
else if ( $this->preview ) {
00058 $this->editForm(
"preview" );
00059 }
else { # First time through
00060 $this->editForm(
"initial" );
00061 }
00062 }
00063
00064 function importFormData( &$request ) {
00065 global
$wgIsMySQL,
$wgIsPg;
00066
# These fields need to be checked for encoding.
00067
# Also remove trailing whitespace, but don't remove _initial_
00068
# whitespace from the text boxes. This may be significant formatting.
00069
$this->textbox1 = rtrim( $request->getText(
"wpTextbox1" ) );
00070 $this->textbox2 = rtrim( $request->getText(
"wpTextbox2" ) );
00071 $this->summary = trim( $request->getText(
"wpSummary" ) );
00072
00073 $this->edittime = $request->getVal( 'wpEdittime' );
00074
if (
$wgIsMySQL)
00075
if( !preg_match( '/^\d{14}$/', $this->edittime )) $this->edittime =
"";
00076
if (
$wgIsPg)
00077
if ( !preg_match( '/^\d{4}-\d\d-\d\d \d\d:\d\d:\d\d$/',
00078 $this->edittime ))
00079 $this->edittime =
"";
00080
00081 $this->preview = $request->getCheck( 'wpPreview' );
00082 $this->save = $request->wasPosted() && !$this->preview;
00083 $this->minoredit = $request->getCheck( 'wpMinoredit' );
00084 $this->watchthis = $request->getCheck( 'wpWatchthis' );
00085
00086 $this->oldid = $request->getInt( 'oldid' );
00087
00088
# Section edit can come from either the form or a link
00089
$this->section = $request->getVal( 'wpSection', $request->getVal( 'section' ) );
00090 }
00091
00092
# Since there is only one text field on the edit form,
00093
# pressing <enter> will cause the form to be submitted, but
00094
# the submit button value won't appear in the query, so we
00095
# Fake it here before going back to edit(). This is kind of
00096
# ugly, but it helps some old URLs to still work.
00097
00098 function submit()
00099 {
00100
if( !$this->preview ) $this->save =
true;
00101
00102 $this->edit();
00103 }
00104
00105
# The edit form is self-submitting, so that when things like
00106
# preview and edit conflicts occur, we get the same form back
00107
# with the extra stuff added. Only when the final submission
00108
# is made and all is well do we actually save and redirect to
00109
# the newly-edited page.
00110
00111 function editForm( $formtype )
00112 {
00113 global
$wgOut,
$wgUser;
00114 global
$wgLang,
$wgParser,
$wgTitle;
00115 global
$wgAllowAnonymousMinor;
00116 global
$wgWhitelistEdit;
00117 global
$wgSpamRegex;
00118
00119 $sk =
$wgUser->getSkin();
00120 $isConflict =
false;
00121
00122 $isCssJsSubpage = (
Namespace::getUser() ==
$wgTitle->getNamespace() and preg_match("/\\.(css|js)$/", $wgTitle->getText() ));
00123
00124 if(!$this->mTitle->getArticleID()) { #
new article
00125
$wgOut->addWikiText(wfmsg(
"newarticletext"));
00126 }
00127
00128
if(
Namespace::isTalk( $this->mTitle->getNamespace() ) ) {
00129
$wgOut->addWikiText(wfmsg(
"talkpagetext"));
00130 }
00131
00132
# Attempt submission here. This will check for edit conflicts,
00133
# and redundantly check for locked database, blocked IPs, etc.
00134
# that edit() already checked just in case someone tries to sneak
00135
# in the back door with a hand-edited submission URL.
00136
00137
if (
"save" == $formtype ) {
00138
# Check for spam
00139
if (
$wgSpamRegex && preg_match( $wgSpamRegex, $this->textbox1 ) ) {
00140
if (
$wgUser->isSysop() ) {
00141 $this->spamPage();
00142 }
else {
00143 sleep(10);
00144
$wgOut->redirect( $this->mTitle->getFullURL() );
00145 }
00146
return;
00147 }
00148
if (
$wgUser->isBlocked() ) {
00149 $this->blockedIPpage();
00150
return;
00151 }
00152
if ( !
$wgUser->getID() &&
$wgWhitelistEdit ) {
00153 $this->userNotLoggedInPage();
00154
return;
00155 }
00156
if (
wfReadOnly() ) {
00157
$wgOut->readOnlyPage();
00158
return;
00159 }
00160
00161
# If article is new, insert it.
00162
$aid = $this->mTitle->getArticleID();
00163
if ( 0 == $aid ) {
00164
# Don't save a new article if it's blank.
00165
if ( (
"" == $this->textbox1 ) ||
00166 (
wfMsg(
"newarticletext" ) == $this->textbox1 ) ) {
00167
$wgOut->redirect( $this->mTitle->getFullURL() );
00168
return;
00169 }
00170 $this->mArticle->insertNewArticle( $this->textbox1, $this->summary, $this->minoredit, $this->watchthis );
00171
return;
00172 }
00173
00174
# Article exists. Check for edit conflict.
00175
00176 $this->mArticle->clear(); # Force reload of dates, etc.
00177
00178
if( ( $this->section !=
"new" ) &&
00179 ($this->mArticle->getTimestamp() != $this->edittime ) ) {
00180 $isConflict =
true;
00181 }
00182 $userid =
$wgUser->getID();
00183
00184 $text = $this->mArticle->getTextOfLastEditWithSectionReplacedOrAdded(
00185 $this->section, $this->textbox1, $this->summary);
00186
# Suppress edit conflict with self
00187
00188
if ( ( 0 != $userid ) && ( $this->mArticle->getUser() == $userid ) ) {
00189 $isConflict =
false;
00190 }
else {
00191
# switch from section editing to normal editing in edit conflict
00192
if($isConflict) {
00193
# Attempt merge
00194
if( $this->mergeChangesInto( $text ) ){
00195
00196 $isConflict =
false;
00197 }
else {
00198 $this->section =
"";
00199 $this->textbox1 = $text;
00200 }
00201 }
00202 }
00203
if ( ! $isConflict ) {
00204
# All's well
00205
$sectionanchor = '';
00206
if( $this->section != '' ) {
00207
# Try to get a section anchor from the section source, redirect to edited section if header found
00208
# XXX: might be better to integrate this into Article::getTextOfLastEditWithSectionReplacedOrAdded
00209
# for duplicate heading checking and maybe parsing
00210
$hasmatch = preg_match(
"/^ *([=]{1,6})(.*?)(\\1) *\\n/i", $this->textbox1, $matches );
00211
# we can't deal with anchors, includes, html etc in the header for now,
00212
# headline would need to be parsed to improve this
00213
#if($hasmatch and strlen($matches[2]) > 0 and !preg_match( "/[\\['{<>]/", $matches[2])) {
00214
if($hasmatch and strlen($matches[2]) > 0) {
00215 global
$wgInputEncoding;
00216 $headline =
do_html_entity_decode( $matches[2], ENT_COMPAT, $wgInputEncoding );
00217
# strip out HTML
00218
$headline = preg_replace(
"/<.*?" .
">/",
"",$headline );
00219 $headline = trim( $headline );
00220 $sectionanchor =
'#'.urlencode( str_replace(
' ',
'_', $headline ) );
00221 $replacearray = array(
00222 '%3A' =>
':',
00223
'%' =>
'.'
00224 );
00225 $sectionanchor = str_replace(array_keys($replacearray),array_values($replacearray),$sectionanchor);
00226 }
00227 }
00228
00229
# update the article here
00230
if($this->mArticle->updateArticle( $text, $this->summary, $this->minoredit, $this->watchthis, '', $sectionanchor ))
00231
return;
00232
else
00233 $isConflict =
true;
00234 }
00235 }
00236
# First time through: get contents, set time for conflict
00237
# checking, etc.
00238
00239
if (
"initial" == $formtype ) {
00240 $this->edittime = $this->mArticle->getTimestamp();
00241 $this->textbox1 = $this->mArticle->getContent(
true );
00242 $this->summary =
"";
00243 $this->proxyCheck();
00244 }
00245
$wgOut->setRobotpolicy(
"noindex,nofollow" );
00246
00247
# Enabled article-related sidebar, toplinks, etc.
00248
$wgOut->setArticleRelated(
true );
00249
00250
if ( $isConflict ) {
00251
$s =
wfMsg(
"editconflict", $this->mTitle->getPrefixedText() );
00252
$wgOut->setPageTitle( $s );
00253
$wgOut->addHTML(
wfMsg(
"explainconflict" ) );
00254
00255 $this->textbox2 = $this->textbox1;
00256 $this->textbox1 = $this->mArticle->getContent(
true );
00257 $this->edittime = $this->mArticle->getTimestamp();
00258 }
else {
00259
$s =
wfMsg(
"editing", $this->mTitle->getPrefixedText() );
00260
00261
if( $this->section !=
"" ) {
00262
if( $this->section ==
"new" ) {
00263
$s.=
wfMsg(
"commentedit");
00264 }
else {
00265
$s.=
wfMsg(
"sectionedit");
00266 }
00267
if(!$this->preview) {
00268 $sectitle=preg_match(
"/^=+(.*?)=+/mi",
00269 $this->textbox1,
00270 $matches);
00271
if( !empty( $matches[1] ) ) {
00272 $this->summary =
"/* ". trim($matches[1]).
" */ ";
00273 }
00274 }
00275 }
00276
$wgOut->setPageTitle( $s );
00277
if ( $this->oldid ) {
00278 $this->mArticle->setOldSubtitle();
00279
$wgOut->addHTML(
wfMsg(
"editingold" ) );
00280 }
00281 }
00282
00283
if(
wfReadOnly() ) {
00284
$wgOut->addHTML(
"<strong>" .
00285
wfMsg(
"readonlywarning" ) .
00286
"</strong>" );
00287 }
else if ( $isCssJsSubpage and
"preview" != $formtype) {
00288
$wgOut->addHTML(
wfMsg(
"usercssjsyoucanpreview" ));
00289 }
00290
if( $this->mTitle->isProtected() ) {
00291
$wgOut->addHTML(
"<strong>" .
wfMsg(
"protectedpagewarning" ) .
00292
"</strong><br />\n" );
00293 }
00294
00295 $kblength = (
int)(strlen( $this->textbox1 ) / 1024);
00296
if( $kblength > 29 ) {
00297
$wgOut->addHTML(
"<strong>" .
00298
wfMsg(
"longpagewarning", $kblength )
00299 .
"</strong>" );
00300 }
00301
00302 $rows =
$wgUser->getOption(
"rows" );
00303 $cols =
$wgUser->getOption(
"cols" );
00304
00305 $ew =
$wgUser->getOption(
"editwidth" );
00306
if ( $ew ) $ew =
" style=\"width:100%\"";
00307
else $ew =
"" ;
00308
00309 $q =
"action=submit";
00310
#if ( "no" == $redirect ) { $q .= "&redirect=no"; }
00311
$action = $this->mTitle->escapeLocalURL( $q );
00312
00313 $summary =
wfMsg(
"summary" );
00314 $subject =
wfMsg(
"subject");
00315 $minor =
wfMsg(
"minoredit" );
00316 $watchthis =
wfMsg (
"watchthis");
00317 $save =
wfMsg(
"savearticle" );
00318 $prev =
wfMsg(
"showpreview" );
00319
00320 $cancel = $sk->makeKnownLink( $this->mTitle->getPrefixedText(),
00321
wfMsg(
"cancel" ) );
00322 $edithelpurl = $sk->makeUrl(
wfMsg( 'edithelppage' ));
00323 $edithelp = '<a target=
"helpwindow" href=
"'.$edithelpurl.'">'.
00324 htmlspecialchars(
wfMsg( 'edithelp' ) ).'</a> '.
00325 htmlspecialchars(
wfMsg( 'newwindow' ) );
00326 $copywarn =
wfMsg(
"copyrightwarning", $sk->makeKnownLink(
00327
wfMsg(
"copyrightpage" ) ) );
00328
00329
if(
$wgUser->getOption(
"showtoolbar") and !$isCssJsSubpage ) {
00330
# prepare toolbar for edit buttons
00331
$toolbar = $sk->getEditToolbar();
00332 }
else {
00333 $toolbar =
"";
00334 }
00335
00336
00337
if( !$this->preview ) {
00338
if(
$wgUser->getOption(
"watchdefault" ) ) $this->watchthis =
true;
00339
if(
$wgUser->getOption(
"minordefault" ) ) $this->minoredit =
true;
00340
00341
00342
00343
00344
if( !$this->watchthis && $this->mTitle->userIsWatching() ) $this->watchthis =
true;
00345 }
00346
00347 $minoredithtml =
"";
00348
00349
if ( 0 !=
$wgUser->getID() ||
$wgAllowAnonymousMinor ) {
00350 $minoredithtml =
00351
"<input tabindex='3' type='checkbox' value='1' name='wpMinoredit'".($this->minoredit?
" checked='checked'":
"").
00352
" accesskey='".wfMsg('accesskey-minoredit').
"' id='wpMinoredit' />".
00353
"<label for='wpMinoredit' title='".wfMsg('tooltip-minoredit').
"'>{$minor}</label>";
00354 }
00355
00356 $watchhtml =
"";
00357
00358
if ( 0 !=
$wgUser->getID() ) {
00359 $watchhtml =
"<input tabindex='4' type='checkbox' name='wpWatchthis'".($this->watchthis?
" checked='checked'":
"").
00360
" accesskey='".wfMsg('accesskey-watch').
"' id='wpWatchthis' />".
00361
"<label for='wpWatchthis' title='".wfMsg('tooltip-watch').
"'>{$watchthis}</label>";
00362 }
00363
00364 $checkboxhtml = $minoredithtml . $watchhtml .
"<br />";
00365
00366
if (
"preview" == $formtype) {
00367 $previewhead=
"<h2>" .
wfMsg(
"preview" ) .
"</h2>\n<p><large><center><font color=\"#cc0000\">" .
00368
wfMsg(
"note" ) .
wfMsg(
"previewnote" ) .
"</font></center></large></p>\n";
00369
if ( $isConflict ) {
00370 $previewhead.=
"<h2>" .
wfMsg(
"previewconflict" ) .
00371
"</h2>\n";
00372 }
00373
00374 $parserOptions = ParserOptions::newFromUser( $wgUser );
00375 $parserOptions->setUseCategoryMagic(
false );
00376 $parserOptions->setEditSection(
false );
00377 $parserOptions->setEditSectionOnRightClick(
false );
00378
# don't parse user css/js, show message about preview
00379
# XXX: stupid php bug won't let us use $wgTitle->isCssJsSubpage() here
00380
if ( $isCssJsSubpage ) {
00381
if(preg_match(
"/\\.css$/", $wgTitle->getText() ) ) {
00382 $previewtext =
wfMsg('usercsspreview');
00383 }
else if(preg_match(
"/\\.js$/", $wgTitle->getText() ) ) {
00384 $previewtext =
wfMsg('userjspreview');
00385 }
00386 $parserOutput =
$wgParser->parse( $previewtext , $wgTitle, $parserOptions );
00387
$wgOut->addHTML( $parserOutput->mText );
00388 }
else {
00389 $parserOutput =
$wgParser->parse( $this->mArticle->preSaveTransform( $this->textbox1 ) .
"\n\n",
00390
$wgTitle, $parserOptions );
00391 $previewHTML = $parserOutput->mText;
00392
00393
if(
$wgUser->getOption(
"previewontop")) {
00394
$wgOut->addHTML($previewhead);
00395
$wgOut->addHTML($previewHTML);
00396 }
00397
$wgOut->addCategoryLinks($parserOutput->getCategoryLinks());
00398
$wgOut->addLanguageLinks($parserOutput->getLanguageLinks());
00399
$wgOut->addHTML(
"<br style=\"clear:both;\" />\n" );
00400 }
00401 }
00402
00403
# if this is a comment, show a subject line at the top, which is also the edit summary.
00404
# Otherwise, show a summary field at the bottom
00405
$summarytext = htmlspecialchars( $wgLang->recodeForEdit( $this->summary ) ); # FIXME
00406
if( $this->section ==
"new" ) {
00407 $commentsubject=
"{$subject}: <input tabindex='1' type='text' value=\"$summarytext\" name=\"wpSummary\" maxlength='200' size='60' /><br />";
00408 $editsummary =
"";
00409 }
else {
00410 $commentsubject =
"";
00411 $editsummary=
"{$summary}: <input tabindex='3' type='text' value=\"$summarytext\" name=\"wpSummary\" maxlength='200' size='60' /><br />";
00412 }
00413
00414
if( !$this->preview ) {
00415
# Don't select the edit box on preview; this interferes with seeing what's going on.
00416
$wgOut->setOnloadHandler(
"document.editform.wpTextbox1.focus()" );
00417 }
00418
$wgOut->addHTML(
"
00419
{$toolbar}
00420
<form id=\"editform\" name=\"editform\" method=\"post\" action=\"$action\"
00421
enctype=\"application/x-www-form-urlencoded\">
00422
{$commentsubject}
00423
<textarea tabindex='1' accesskey=\",\" name=\"wpTextbox1\" rows='{$rows}'
00424
cols='{$cols}'{$ew}>" .
00425 htmlspecialchars( $wgLang->recodeForEdit( $this->textbox1 ) ) .
00426
"
00427
</textarea>
00428
<br />{$editsummary}
00429
{$checkboxhtml}
00430
<input tabindex='5' id='wpSave' type='submit' value=\"{$save}\" name=\"wpSave\" accesskey=\"".
wfMsg('accesskey-save').
"\"".
00431
" title=\"".wfMsg('tooltip-save').
"\"/>
00432
<input tabindex='6' id='wpSave' type='submit' value=\"{$prev}\" name=\"wpPreview\" accesskey=\"".
wfMsg('accesskey-preview').
"\"".
00433
" title=\"".wfMsg('tooltip-preview').
"\"/>
00434
<em>{$cancel}</em> | <em>{$edithelp}</em>
00435
<br /><div id=\"editpage-copywarn\">{$copywarn}</div>
00436
<input type='hidden' value=\"" . htmlspecialchars( $this->section ) .
"\" name=\"wpSection\" />
00437
<input type='hidden' value=\"{$this->edittime}\" name=\"wpEdittime\" />\n" );
00438
00439
if ( $isConflict ) {
00440
$wgOut->addHTML(
"<h2>" .
wfMsg(
"yourdiff" ) .
"</h2>\n" );
00441
DifferenceEngine::showDiff( $this->textbox2, $this->textbox1,
00442
wfMsg(
"yourtext" ),
wfMsg(
"storedversion" ) );
00443
00444
$wgOut->addHTML(
"<h2>" .
wfMsg(
"yourtext" ) .
"</h2>
00445
<textarea tabindex=6 id='wpTextbox2' name=\"wpTextbox2\" rows='{$rows}' cols='{$cols}' wrap='virtual'>"
00446 . htmlspecialchars( $wgLang->recodeForEdit( $this->textbox2 ) ) .
00447
"
00448
</textarea>" );
00449 }
00450
$wgOut->addHTML(
"</form>\n" );
00451
if($formtype ==
"preview" && !
$wgUser->getOption(
"previewontop")) {
00452
$wgOut->addHTML($previewhead);
00453
$wgOut->addHTML($previewHTML);
00454 }
00455
00456 }
00457
00458 function blockedIPpage()
00459 {
00460 global
$wgOut,
$wgUser,
$wgLang,
$wgIP;
00461
00462
$wgOut->setPageTitle(
wfMsg(
"blockedtitle" ) );
00463
$wgOut->setRobotpolicy(
"noindex,nofollow" );
00464
$wgOut->setArticleRelated(
false );
00465
00466 $id =
$wgUser->blockedBy();
00467 $reason =
$wgUser->blockedFor();
00468 $ip =
$wgIP;
00469
00470 $name = User::whoIs( $
id );
00471 $link =
"[[" .
$wgLang->getNsText( Namespace::getUser() ) .
00472
":{$name}|{$name}]]";
00473
00474
$wgOut->addWikiText(
wfMsg(
"blockedtext", $link, $reason, $ip, $name ) );
00475
$wgOut->returnToMain(
false );
00476 }
00477
00478
00479
00480 function userNotLoggedInPage()
00481 {
00482 global
$wgOut,
$wgUser,
$wgLang;
00483
00484
$wgOut->setPageTitle(
wfMsg(
"whitelistedittitle" ) );
00485
$wgOut->setRobotpolicy(
"noindex,nofollow" );
00486
$wgOut->setArticleRelated(
false );
00487
00488
$wgOut->addWikiText(
wfMsg(
"whitelistedittext" ) );
00489
$wgOut->returnToMain(
false );
00490 }
00491
00492 function spamPage()
00493 {
00494 global
$wgOut,
$wgSpamRegex;
00495
$wgOut->setPageTitle(
wfMsg(
"spamprotectiontitle" ) );
00496
$wgOut->setRobotpolicy(
"noindex,nofollow" );
00497
$wgOut->setArticleRelated(
false );
00498
00499
$wgOut->addWikiText(
wfMsg(
"spamprotectiontext" ) );
00500
$wgOut->addWikiText(
"<pre>".$wgSpamRegex.
"</pre>" );
00501
$wgOut->returnToMain(
false );
00502 }
00503
00504
# Forks processes to scan the originating IP for an open proxy server
00505
# MemCached can be used to skip IPs that have already been scanned
00506
function proxyCheck()
00507 {
00508 global
$wgBlockOpenProxies,
$wgProxyPorts,
$wgProxyScriptPath;
00509 global
$wgIP,
$wgUseMemCached,
$wgMemc,
$wgDBname,
$wgProxyMemcExpiry;
00510
00511
if ( !
$wgBlockOpenProxies ) {
00512
return;
00513 }
00514
00515
# Get MemCached key
00516
$skip =
false;
00517
if (
$wgUseMemCached ) {
00518 $mcKey =
"$wgDBname:proxy:ip:$wgIP";
00519 $mcValue =
$wgMemc->get( $mcKey );
00520
if ( $mcValue ) {
00521 $skip =
true;
00522 }
00523 }
00524
00525
# Fork the processes
00526
if ( !$skip ) {
00527
$title = Title::makeTitle( NS_SPECIAL,
"Blockme" );
00528 $iphash = md5( $wgIP . $wgProxyKey );
00529
$url =
$title->getFullURL(
"ip=$iphash" );
00530
00531 foreach ( $wgProxyPorts as $port ) {
00532 $params = implode(
" ", array(
00533 escapeshellarg( $wgProxyScriptPath ),
00534 escapeshellarg( $wgIP ),
00535 escapeshellarg( $port ),
00536 escapeshellarg( $url )
00537 ));
00538 exec(
"php $params &>/dev/null &" );
00539 }
00540
# Set MemCached key
00541
if (
$wgUseMemCached ) {
00542
$wgMemc->set( $mcKey, 1, $wgProxyMemcExpiry );
00543 }
00544 }
00545 }
00546
00547 function mergeChangesInto( &$text ){
00548 global
$wgIsPg;
00549 $oldDate = $this->edittime;
00550
$res =
wfQuery(
"SELECT cur_text FROM cur WHERE cur_id=" .
00551 $this->mTitle->getArticleID() .
" FOR UPDATE",
DB_WRITE);
00552 $obj =
wfFetchObject($res);
00553
00554 $yourtext = $obj->cur_text;
00555 $ns = $this->mTitle->getNamespace();
00556
$title =
wfStrencode( $this->mTitle->getDBkey() );
00557 $oldtable=
$wgIsPg?'
"old"':'old';
00558
$res =
wfQuery(
"SELECT old_text,old_flags FROM $oldtable WHERE old_namespace = $ns AND ".
00559
"old_title = '{$title}' AND old_timestamp = '{$oldDate}'", DB_WRITE);
00560 $obj =
wfFetchObject($res);
00561 $oldText = Article::getRevisionText( $obj );
00562
00563
if(
wfMerge($oldText, $text, $yourtext, $result)){
00564 $text = $result;
00565
return true;
00566 }
else {
00567
return false;
00568 }
00569 }
00570 }
00571
00572 ?>