r14834 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r14833‎ | r14834 | r14835 >
Date:09:50, 20 June 2006
Author:tstarling
Status:old (Comments)
Tags:
Comment:
Did some refactoring in Article.php:

* Introduced doEdit(), a simplified editing API. Rewrote updateArticle() and insertNewArticle() to call doEdit() and marked them deprecated. Callers should be updated to use doEdit() at a later date.
* Replaced $fname with __METHOD__
* Removed some unused member variables
* Fixed cache purging on null edit, hopefully it should work the same as action=purge now.
* Fixed doRedirect() callers, minor bug introduced with HTMLCacheUpdate.
Modified paths:
  • /trunk/phase3/includes/Article.php (modified) (history)
  • /trunk/phase3/includes/Defines.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/Defines.php
@@ -164,5 +164,15 @@
165165 define( 'RC_MOVE_OVER_REDIRECT', 4);
166166 /**#@-*/
167167
 168+/**#@+
 169+ * Article edit flags
 170+ */
 171+define( 'EDIT_NEW', 1 );
 172+define( 'EDIT_UPDATE', 2 );
 173+define( 'EDIT_MINOR', 4 );
 174+define( 'EDIT_SUPPRESS_RC', 8 );
 175+define( 'EDIT_FORCE_BOT', 16 );
 176+define( 'EDIT_DEFER_UPDATES', 32 );
 177+/**#@-*/
168178
169179 ?>
Index: trunk/phase3/includes/Article.php
@@ -26,10 +26,8 @@
2727 var $mContent; //!<
2828 var $mContentLoaded; //!<
2929 var $mCounter; //!<
30 - var $mFileCache; //!<
3130 var $mForUpdate; //!<
3231 var $mGoodAdjustment; //!<
33 - var $mId; //!<
3432 var $mLatest; //!<
3533 var $mMinorEdit; //!<
3634 var $mOldId; //!<
@@ -37,7 +35,6 @@
3836 var $mRedirectUrl; //!<
3937 var $mRevIdFetched; //!<
4038 var $mRevision; //!<
41 - var $mTable; //!<
4239 var $mTimestamp; //!<
4340 var $mTitle; //!<
4441 var $mTotalAdjustment; //!<
@@ -125,7 +122,7 @@
126123 $this->mCurID = $this->mUser = $this->mCounter = -1; # Not loaded
127124 $this->mRedirectedFrom = null; # Title object if set
128125 $this->mUserText =
129 - $this->mTimestamp = $this->mComment = $this->mFileCache = '';
 126+ $this->mTimestamp = $this->mComment = '';
130127 $this->mGoodAdjustment = $this->mTotalAdjustment = 0;
131128 $this->mTouched = '19700101000000';
132129 $this->mForUpdate = false;
@@ -154,12 +151,11 @@
155152 $section = $wgRequest->getText( 'section' );
156153 $preload = $wgRequest->getText( 'preload' );
157154
158 - $fname = 'Article::getContent';
159 - wfProfileIn( $fname );
 155+ wfProfileIn( __METHOD__ );
160156
161157 if ( 0 == $this->getID() ) {
162158 if ( 'edit' == $action ) {
163 - wfProfileOut( $fname );
 159+ wfProfileOut( __METHOD__ );
164160
165161 # If requested, preload some text.
166162 $text=$this->getPreloadedText($preload);
@@ -169,7 +165,7 @@
170166 # This is now shown above the edit box instead.
171167 return $text;
172168 }
173 - wfProfileOut( $fname );
 169+ wfProfileOut( __METHOD__ );
174170 $wgOut->setRobotpolicy( 'noindex,nofollow' );
175171
176172 if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
@@ -184,7 +180,7 @@
185181 if($action=='edit') {
186182 if($section!='') {
187183 if($section=='new') {
188 - wfProfileOut( $fname );
 184+ wfProfileOut( __METHOD__ );
189185 $text=$this->getPreloadedText($preload);
190186 return $text;
191187 }
@@ -192,11 +188,11 @@
193189 # strip NOWIKI etc. to avoid confusion (true-parameter causes HTML
194190 # comments to be stripped as well)
195191 $rv=$this->getSection($this->mContent,$section);
196 - wfProfileOut( $fname );
 192+ wfProfileOut( __METHOD__ );
197193 return $rv;
198194 }
199195 }
200 - wfProfileOut( $fname );
 196+ wfProfileOut( __METHOD__ );
201197 return $this->mContent;
202198 }
203199 }
@@ -400,7 +396,6 @@
401397 }
402398
403399 $dbr =& $this->getDB();
404 - $fname = 'Article::fetchContent';
405400
406401 # Pre-fill content with error message so that if something
407402 # fails we'll have something telling us what we intended.
@@ -413,12 +408,12 @@
414409 if( $oldid ) {
415410 $revision = Revision::newFromId( $oldid );
416411 if( is_null( $revision ) ) {
417 - wfDebug( "$fname failed to retrieve specified revision, id $oldid\n" );
 412+ wfDebug( __METHOD__." failed to retrieve specified revision, id $oldid\n" );
418413 return false;
419414 }
420415 $data = $this->pageDataFromId( $dbr, $revision->getPage() );
421416 if( !$data ) {
422 - wfDebug( "$fname failed to get page data linked to revision id $oldid\n" );
 417+ wfDebug( __METHOD__." failed to get page data linked to revision id $oldid\n" );
423418 return false;
424419 }
425420 $this->mTitle = Title::makeTitle( $data->page_namespace, $data->page_title );
@@ -427,14 +422,14 @@
428423 if( !$this->mDataLoaded ) {
429424 $data = $this->pageDataFromTitle( $dbr, $this->mTitle );
430425 if( !$data ) {
431 - wfDebug( "$fname failed to find page data for title " . $this->mTitle->getPrefixedText() . "\n" );
 426+ wfDebug( __METHOD__." failed to find page data for title " . $this->mTitle->getPrefixedText() . "\n" );
432427 return false;
433428 }
434429 $this->loadPageData( $data );
435430 }
436431 $revision = Revision::newFromId( $this->mLatest );
437432 if( is_null( $revision ) ) {
438 - wfDebug( "$fname failed to retrieve current page, rev_id {$data->page_latest}\n" );
 433+ wfDebug( __METHOD__." failed to retrieve current page, rev_id {$data->page_latest}\n" );
439434 return false;
440435 }
441436 }
@@ -637,8 +632,6 @@
638633 * @param $offset Integer: default 0.
639634 */
640635 function getContributors($limit = 0, $offset = 0) {
641 - $fname = 'Article::getContributors';
642 -
643636 # XXX: this is expensive; cache this info somewhere.
644637
645638 $title = $this->mTitle;
@@ -661,7 +654,7 @@
662655 if ($limit > 0) { $sql .= ' LIMIT '.$limit; }
663656 $sql .= ' '. $this->getSelectOptions();
664657
665 - $res = $dbr->query($sql, $fname);
 658+ $res = $dbr->query($sql, __METHOD__);
666659
667660 while ( $line = $dbr->fetchObject( $res ) ) {
668661 $contribs[] = array($line->rev_user, $line->rev_user_text, $line->user_real_name);
@@ -681,8 +674,7 @@
682675 global $wgUseTrackbacks, $wgNamespaceRobotPolicies;
683676 $sk = $wgUser->getSkin();
684677
685 - $fname = 'Article::view';
686 - wfProfileIn( $fname );
 678+ wfProfileIn( __METHOD__ );
687679
688680 $parserCache =& ParserCache::singleton();
689681 $ns = $this->mTitle->getNamespace(); # shortcut
@@ -693,7 +685,7 @@
694686 # getOldID may want us to redirect somewhere else
695687 if ( $this->mRedirectUrl ) {
696688 $wgOut->redirect( $this->mRedirectUrl );
697 - wfProfileOut( $fname );
 689+ wfProfileOut( __METHOD__ );
698690 return;
699691 }
700692
@@ -725,7 +717,7 @@
726718 # Run view updates for current revision only
727719 $this->viewUpdates();
728720 }
729 - wfProfileOut( $fname );
 721+ wfProfileOut( __METHOD__ );
730722 return;
731723 }
732724
@@ -733,13 +725,13 @@
734726 $wgOut->setETag($parserCache->getETag($this, $wgUser));
735727
736728 if( $wgOut->checkLastModified( $this->mTouched ) ){
737 - wfProfileOut( $fname );
 729+ wfProfileOut( __METHOD__ );
738730 return;
739731 } else if ( $this->tryFileCache() ) {
740732 # tell wgOut that output is taken care of
741733 $wgOut->disable();
742734 $this->viewUpdates();
743 - wfProfileOut( $fname );
 735+ wfProfileOut( __METHOD__ );
744736 return;
745737 }
746738 }
@@ -904,7 +896,7 @@
905897 $this->addTrackbacks();
906898
907899 $this->viewUpdates();
908 - wfProfileOut( $fname );
 900+ wfProfileOut( __METHOD__ );
909901 }
910902
911903 function addTrackbacks() {
@@ -1027,8 +1019,7 @@
10281020 * @private
10291021 */
10301022 function insertOn( &$dbw, $restrictions = '' ) {
1031 - $fname = 'Article::insertOn';
1032 - wfProfileIn( $fname );
 1023+ wfProfileIn( __METHOD__ );
10331024
10341025 $page_id = $dbw->nextSequenceValue( 'page_page_id_seq' );
10351026 $dbw->insert( 'page', array(
@@ -1043,12 +1034,12 @@
10441035 'page_touched' => $dbw->timestamp(),
10451036 'page_latest' => 0, # Fill this in shortly...
10461037 'page_len' => 0, # Fill this in shortly...
1047 - ), $fname );
 1038+ ), __METHOD__ );
10481039 $newid = $dbw->insertId();
10491040
10501041 $this->mTitle->resetArticleId( $newid );
10511042
1052 - wfProfileOut( $fname );
 1043+ wfProfileOut( __METHOD__ );
10531044 return $newid;
10541045 }
10551046
@@ -1066,8 +1057,7 @@
10671058 * @private
10681059 */
10691060 function updateRevisionOn( &$dbw, $revision, $lastRevision = null ) {
1070 - $fname = 'Article::updateToRevision';
1071 - wfProfileIn( $fname );
 1061+ wfProfileIn( __METHOD__ );
10721062
10731063 $conditions = array( 'page_id' => $this->getId() );
10741064 if( !is_null( $lastRevision ) ) {
@@ -1085,9 +1075,9 @@
10861076 'page_len' => strlen( $text ),
10871077 ),
10881078 $conditions,
1089 - $fname );
 1079+ __METHOD__ );
10901080
1091 - wfProfileOut( $fname );
 1081+ wfProfileOut( __METHOD__ );
10921082 return ( $dbw->affectedRows() != 0 );
10931083 }
10941084
@@ -1099,8 +1089,7 @@
11001090 * @param Revision $revision
11011091 */
11021092 function updateIfNewerOn( &$dbw, $revision ) {
1103 - $fname = 'Article::updateIfNewerOn';
1104 - wfProfileIn( $fname );
 1093+ wfProfileIn( __METHOD__ );
11051094
11061095 $row = $dbw->selectRow(
11071096 array( 'revision', 'page' ),
@@ -1108,10 +1097,10 @@
11091098 array(
11101099 'page_id' => $this->getId(),
11111100 'page_latest=rev_id' ),
1112 - $fname );
 1101+ __METHOD__ );
11131102 if( $row ) {
11141103 if( wfTimestamp(TS_MW, $row->rev_timestamp) >= $revision->getTimestamp() ) {
1115 - wfProfileOut( $fname );
 1104+ wfProfileOut( __METHOD__ );
11161105 return false;
11171106 }
11181107 $prev = $row->rev_id;
@@ -1121,115 +1110,15 @@
11221111 }
11231112
11241113 $ret = $this->updateRevisionOn( $dbw, $revision, $prev );
1125 - wfProfileOut( $fname );
 1114+ wfProfileOut( __METHOD__ );
11261115 return $ret;
11271116 }
11281117
11291118 /**
1130 - * Insert a new article into the database
1131 - * @private
1132 - */
1133 - function insertNewArticle( $text, $summary, $isminor, $watchthis, $suppressRC=false, $comment=false ) {
1134 - global $wgUser;
1135 -
1136 - $fname = 'Article::insertNewArticle';
1137 - wfProfileIn( $fname );
1138 -
1139 - if( !wfRunHooks( 'ArticleSave', array( &$this, &$wgUser, &$text,
1140 - &$summary, &$isminor, &$watchthis, NULL ) ) ) {
1141 - wfDebug( "$fname: ArticleSave hook aborted save!\n" );
1142 - wfProfileOut( $fname );
1143 - return false;
1144 - }
1145 -
1146 - $ns = $this->mTitle->getNamespace();
1147 - $ttl = $this->mTitle->getDBkey();
1148 -
1149 - # If this is a comment, add the summary as headline
1150 - if($comment && $summary!="") {
1151 - $text="== {$summary} ==\n\n".$text;
1152 - }
1153 - $text = $this->preSaveTransform( $text );
1154 -
1155 -
1156 - # Set statistics members
1157 - # We work out if it's countable after PST to avoid counter drift
1158 - # when articles are created with {{subst:}}
1159 - $this->mGoodAdjustment = (int)$this->isCountable( $text );
1160 - $this->mTotalAdjustment = 1;
1161 -
1162 - /* Silently ignore minoredit if not allowed */
1163 - $isminor = $isminor && $wgUser->isAllowed('minoredit');
1164 - $now = wfTimestampNow();
1165 -
1166 - $dbw =& wfGetDB( DB_MASTER );
1167 -
1168 - # Add the page record; stake our claim on this title!
1169 - $newid = $this->insertOn( $dbw );
1170 -
1171 - # Save the revision text...
1172 - $revision = new Revision( array(
1173 - 'page' => $newid,
1174 - 'comment' => $summary,
1175 - 'minor_edit' => $isminor,
1176 - 'text' => $text
1177 - ) );
1178 - $revisionId = $revision->insertOn( $dbw );
1179 -
1180 - $this->mTitle->resetArticleID( $newid );
1181 -
1182 - # Update the page record with revision data
1183 - $this->updateRevisionOn( $dbw, $revision, 0 );
1184 -
1185 - if(!$suppressRC) {
1186 - $rcid = RecentChange::notifyNew( $now, $this->mTitle, $isminor, $wgUser, $summary, 'default',
1187 - '', strlen( $text ), $revisionId );
1188 - # Mark as patrolled if the user can and has the option set
1189 - if( $wgUser->isAllowed( 'patrol' ) && $wgUser->getOption( 'autopatrol' ) ) {
1190 - RecentChange::markPatrolled( $rcid );
1191 - }
1192 - }
1193 -
1194 - if ($watchthis) {
1195 - if(!$this->mTitle->userIsWatching()) $this->doWatch();
1196 - } else {
1197 - if ( $this->mTitle->userIsWatching() ) {
1198 - $this->doUnwatch();
1199 - }
1200 - }
1201 -
1202 - # The talk page isn't in the regular link tables, so we need to update manually:
1203 - $talkns = $ns ^ 1; # talk -> normal; normal -> talk
1204 - $dbw->update( 'page',
1205 - array( 'page_touched' => $dbw->timestamp($now) ),
1206 - array( 'page_namespace' => $talkns,
1207 - 'page_title' => $ttl ),
1208 - $fname );
1209 -
1210 - # Update links, etc.
1211 - $this->editUpdates( $text, $summary, $isminor, $now, $revisionId );
1212 -
1213 - # Clear caches
1214 - Article::onArticleCreate( $this->mTitle );
1215 -
1216 - # Output a redirect back to the article
1217 - $this->doRedirect( $this->isRedirect( $text ) );
1218 -
1219 - wfRunHooks( 'ArticleInsertComplete', array( &$this, &$wgUser, $text,
1220 - $summary, $isminor,
1221 - $watchthis, NULL ) );
1222 - wfRunHooks( 'ArticleSaveComplete', array( &$this, &$wgUser, $text,
1223 - $summary, $isminor,
1224 - $watchthis, NULL ) );
1225 - wfProfileOut( $fname );
1226 - }
1227 -
1228 - /**
12291119 * @return string Complete article text, or null if error
12301120 */
12311121 function replaceSection($section, $text, $summary = '', $edittime = NULL) {
1232 - $fname = 'Article::replaceSection';
1233 - wfProfileIn( $fname );
 1122+ wfProfileIn( __METHOD__ );
12341123
12351124 if( $section == '' ) {
12361125 // Whole-page edit; let the text through unmolested.
@@ -1256,132 +1145,280 @@
12571146 }
12581147 }
12591148
1260 - wfProfileOut( $fname );
 1149+ wfProfileOut( __METHOD__ );
12611150 return $text;
12621151 }
12631152
12641153 /**
1265 - * Change an existing article. Puts the previous version back into the old table, updates RC
1266 - * and all necessary caches, mostly via the deferred update array.
 1154+ * @deprecated use Article::doEdit()
 1155+ */
 1156+ function insertNewArticle( $text, $summary, $isminor, $watchthis, $suppressRC=false, $comment=false ) {
 1157+ $flags = EDIT_NEW | EDIT_DEFER_UPDATES |
 1158+ ( $isminor ? EDIT_MINOR : 0 ) |
 1159+ ( $suppressRC ? EDIT_SUPPRESS_RC : 0 );
 1160+
 1161+ # If this is a comment, add the summary as headline
 1162+ if ( $comment && $summary != "" ) {
 1163+ $text = "== {$summary} ==\n\n".$text;
 1164+ }
 1165+
 1166+ $this->doEdit( $text, $summary, $flags );
 1167+
 1168+ $dbw =& wfGetDB( DB_MASTER );
 1169+ if ($watchthis) {
 1170+ if (!$this->mTitle->userIsWatching()) {
 1171+ $dbw->begin();
 1172+ $this->doWatch();
 1173+ $dbw->commit();
 1174+ }
 1175+ } else {
 1176+ if ( $this->mTitle->userIsWatching() ) {
 1177+ $dbw->begin();
 1178+ $this->doUnwatch();
 1179+ $dbw->commit();
 1180+ }
 1181+ }
 1182+ $this->doRedirect( $this->isRedirect( $text ) );
 1183+ }
 1184+
 1185+ /**
 1186+ * @deprecated use Article::doEdit()
 1187+ */
 1188+ function updateArticle( $text, $summary, $minor, $watchthis, $forceBot = false, $sectionanchor = '' ) {
 1189+ $flags = EDIT_UPDATE | EDIT_DEFER_UPDATES |
 1190+ ( $minor ? EDIT_MINOR : 0 ) |
 1191+ ( $forceBot ? EDIT_FORCE_BOT : 0 );
 1192+
 1193+ $good = $this->doEdit( $text, $summary, $flags );
 1194+ if ( $good ) {
 1195+ $dbw =& wfGetDB( DB_MASTER );
 1196+ if ($watchthis) {
 1197+ if (!$this->mTitle->userIsWatching()) {
 1198+ $dbw->begin();
 1199+ $this->doWatch();
 1200+ $dbw->commit();
 1201+ }
 1202+ } else {
 1203+ if ( $this->mTitle->userIsWatching() ) {
 1204+ $dbw->begin();
 1205+ $this->doUnwatch();
 1206+ $dbw->commit();
 1207+ }
 1208+ }
 1209+
 1210+ $this->doRedirect( $this->isRedirect( $text ), $sectionanchor );
 1211+ }
 1212+ return $good;
 1213+ }
 1214+
 1215+ /**
 1216+ * Article::doEdit()
12671217 *
 1218+ * Change an existing article or create a new article. Updates RC and all necessary caches,
 1219+ * optionally via the deferred update array.
 1220+ *
12681221 * It is possible to call this function from a command-line script, but note that you should
12691222 * first set $wgUser, and clean up $wgDeferredUpdates after each edit.
 1223+ *
 1224+ * $wgUser must be set before calling this function.
 1225+ *
 1226+ * @param string $text New text
 1227+ * @param string $summary Edit summary
 1228+ * @param integer $flags bitfield:
 1229+ * EDIT_NEW
 1230+ * Article is known or assumed to be non-existent, create a new one
 1231+ * EDIT_UPDATE
 1232+ * Article is known or assumed to be pre-existing, update it
 1233+ * EDIT_MINOR
 1234+ * Mark this edit minor, if the user is allowed to do so
 1235+ * EDIT_SUPPRESS_RC
 1236+ * Do not log the change in recentchanges
 1237+ * EDIT_FORCE_BOT
 1238+ * Mark the edit a "bot" edit regardless of user rights
 1239+ * EDIT_DEFER_UPDATES
 1240+ * Defer some of the updates until the end of index.php
 1241+ *
 1242+ * If neither EDIT_NEW nor EDIT_UPDATE is specified, the status of the article will be detected.
 1243+ * If EDIT_UPDATE is specified and the article doesn't exist, the function will return false. If
 1244+ * EDIT_NEW is specified and the article does exist, a duplicate key error will cause an exception
 1245+ * to be thrown from the Database. These two conditions are also possible with auto-detection due
 1246+ * to MediaWiki's performance-optimised locking strategy.
 1247+ *
 1248+ * @return bool success
12701249 */
1271 - function updateArticle( $text, $summary, $minor, $watchthis, $forceBot = false, $sectionanchor = '' ) {
1272 - global $wgUser, $wgDBtransactions, $wgUseSquid;
1273 - global $wgPostCommitUpdateList, $wgUseFileCache;
 1250+ function doEdit( $text, $summary, $flags = 0 ) {
 1251+ global $wgUser, $wgDBtransactions;
12741252
1275 - $fname = 'Article::updateArticle';
1276 - wfProfileIn( $fname );
 1253+ wfProfileIn( __METHOD__ );
12771254 $good = true;
12781255
 1256+ if ( !($flags & EDIT_NEW) && !($flags & EDIT_UPDATE) ) {
 1257+ $aid = $this->mTitle->getArticleID( GAID_FOR_UPDATE );
 1258+ if ( $aid ) {
 1259+ $flags |= EDIT_UPDATE;
 1260+ } else {
 1261+ $flags |= EDIT_NEW;
 1262+ }
 1263+ }
 1264+
12791265 if( !wfRunHooks( 'ArticleSave', array( &$this, &$wgUser, &$text,
1280 - &$summary, &$minor,
1281 - &$watchthis, &$sectionanchor ) ) ) {
1282 - wfDebug( "$fname: ArticleSave hook aborted save!\n" );
1283 - wfProfileOut( $fname );
 1266+ &$summary, $flags & EDIT_MINOR,
 1267+ null, null, &$flags ) ) )
 1268+ {
 1269+ wfDebug( __METHOD__ . ": ArticleSave hook aborted save!\n" );
 1270+ wfProfileOut( __METHOD__ );
12841271 return false;
12851272 }
12861273
1287 - $isminor = $minor && $wgUser->isAllowed('minoredit');
 1274+ # Silently ignore EDIT_MINOR if not allowed
 1275+ $isminor = ( $flags & EDIT_MINOR ) && $wgUser->isAllowed('minoredit');
 1276+ $bot = $wgUser->isBot() || ( $flags & EDIT_FORCE_BOT );
12881277
12891278 $text = $this->preSaveTransform( $text );
 1279+
12901280 $dbw =& wfGetDB( DB_MASTER );
12911281 $now = wfTimestampNow();
 1282+
 1283+ if ( $flags & EDIT_UPDATE ) {
 1284+ # Update article, but only if changed.
12921285
1293 - # Update article, but only if changed.
 1286+ # Make sure the revision is either completely inserted or not inserted at all
 1287+ if( !$wgDBtransactions ) {
 1288+ $userAbort = ignore_user_abort( true );
 1289+ }
12941290
1295 - # It's important that we either rollback or complete, otherwise an attacker could
1296 - # overwrite cur entries by sending precisely timed user aborts. Random bored users
1297 - # could conceivably have the same effect, especially if cur is locked for long periods.
1298 - if( !$wgDBtransactions ) {
1299 - $userAbort = ignore_user_abort( true );
1300 - }
 1291+ $oldtext = $this->getContent();
 1292+ $oldsize = strlen( $oldtext );
 1293+ $newsize = strlen( $text );
 1294+ $lastRevision = 0;
 1295+ $revisionId = 0;
13011296
1302 - $oldtext = $this->getContent();
1303 - $oldsize = strlen( $oldtext );
1304 - $newsize = strlen( $text );
1305 - $lastRevision = 0;
1306 - $revisionId = 0;
 1297+ if ( 0 != strcmp( $text, $oldtext ) ) {
 1298+ $this->mGoodAdjustment = (int)$this->isCountable( $text )
 1299+ - (int)$this->isCountable( $oldtext );
 1300+ $this->mTotalAdjustment = 0;
13071301
1308 - if ( 0 != strcmp( $text, $oldtext ) ) {
1309 - $this->mGoodAdjustment = (int)$this->isCountable( $text )
1310 - - (int)$this->isCountable( $oldtext );
1311 - $this->mTotalAdjustment = 0;
1312 - $now = wfTimestampNow();
 1302+ $lastRevision = $dbw->selectField(
 1303+ 'page', 'page_latest', array( 'page_id' => $this->getId() ) );
13131304
1314 - $lastRevision = $dbw->selectField(
1315 - 'page', 'page_latest', array( 'page_id' => $this->getId() ) );
 1305+ if ( !$lastRevision ) {
 1306+ # Article gone missing
 1307+ wfDebug( __METHOD__.": EDIT_UPDATE specified but article doesn't exist\n" );
 1308+ wfProfileOut( __METHOD__ );
 1309+ return false;
 1310+ }
 1311+
 1312+ $revision = new Revision( array(
 1313+ 'page' => $this->getId(),
 1314+ 'comment' => $summary,
 1315+ 'minor_edit' => $isminor,
 1316+ 'text' => $text
 1317+ ) );
13161318
 1319+ $dbw->begin();
 1320+ $revisionId = $revision->insertOn( $dbw );
 1321+
 1322+ # Update page
 1323+ $ok = $this->updateRevisionOn( $dbw, $revision, $lastRevision );
 1324+
 1325+ if( !$ok ) {
 1326+ /* Belated edit conflict! Run away!! */
 1327+ $good = false;
 1328+ $dbw->rollback();
 1329+ } else {
 1330+ # Update recentchanges
 1331+ if( !( $flags & EDIT_SUPPRESS_RC ) ) {
 1332+ $rcid = RecentChange::notifyEdit( $now, $this->mTitle, $isminor, $wgUser, $summary,
 1333+ $lastRevision, $this->getTimestamp(), $bot, '', $oldsize, $newsize,
 1334+ $revisionId );
 1335+
 1336+ # Mark as patrolled if the user can do so and has it set in their options
 1337+ if( $wgUser->isAllowed( 'patrol' ) && $wgUser->getOption( 'autopatrol' ) ) {
 1338+ RecentChange::markPatrolled( $rcid );
 1339+ }
 1340+ }
 1341+ $dbw->commit();
 1342+ }
 1343+ } else {
 1344+ // Keep the same revision ID, but do some updates on it
 1345+ $revisionId = $this->getRevIdFetched();
 1346+ // Update page_touched, this is usually implicit in the page update
 1347+ // Other cache updates are done in onArticleEdit()
 1348+ $this->mTitle->invalidateCache();
 1349+ }
 1350+
 1351+ if( !$wgDBtransactions ) {
 1352+ ignore_user_abort( $userAbort );
 1353+ }
 1354+
 1355+ if ( $good ) {
 1356+ # Invalidate cache of this article and all pages using this article
 1357+ # as a template. Partly deferred.
 1358+ Article::onArticleEdit( $this->mTitle );
 1359+
 1360+ # Update links tables, site stats, etc.
 1361+ $this->editUpdates( $text, $summary, $isminor, $now, $revisionId );
 1362+ }
 1363+ } else {
 1364+ # Create new article
 1365+
 1366+ # Set statistics members
 1367+ # We work out if it's countable after PST to avoid counter drift
 1368+ # when articles are created with {{subst:}}
 1369+ $this->mGoodAdjustment = (int)$this->isCountable( $text );
 1370+ $this->mTotalAdjustment = 1;
 1371+
 1372+ $dbw->begin();
 1373+
 1374+ # Add the page record; stake our claim on this title!
 1375+ # This will fail with a database query exception if the article already exists
 1376+ $newid = $this->insertOn( $dbw );
 1377+
 1378+ # Save the revision text...
13171379 $revision = new Revision( array(
1318 - 'page' => $this->getId(),
 1380+ 'page' => $newid,
13191381 'comment' => $summary,
13201382 'minor_edit' => $isminor,
13211383 'text' => $text
13221384 ) );
1323 -
1324 - $dbw->begin();
13251385 $revisionId = $revision->insertOn( $dbw );
13261386
1327 - # Update page
1328 - $ok = $this->updateRevisionOn( $dbw, $revision, $lastRevision );
 1387+ $this->mTitle->resetArticleID( $newid );
13291388
1330 - if( !$ok ) {
1331 - /* Belated edit conflict! Run away!! */
1332 - $good = false;
1333 - $dbw->rollback();
1334 - } else {
1335 - # Update recentchanges
1336 - $bot = (int)($wgUser->isBot() || $forceBot);
1337 - $rcid = RecentChange::notifyEdit( $now, $this->mTitle, $isminor, $wgUser, $summary,
1338 - $lastRevision, $this->getTimestamp(), $bot, '', $oldsize, $newsize,
1339 - $revisionId );
1340 -
1341 - # Mark as patrolled if the user can do so and has it set in their options
 1389+ # Update the page record with revision data
 1390+ $this->updateRevisionOn( $dbw, $revision, 0 );
 1391+
 1392+ if( !( $flags & EDIT_SUPPRESS_RC ) ) {
 1393+ $rcid = RecentChange::notifyNew( $now, $this->mTitle, $isminor, $wgUser, $summary, $bot,
 1394+ '', strlen( $text ), $revisionId );
 1395+ # Mark as patrolled if the user can and has the option set
13421396 if( $wgUser->isAllowed( 'patrol' ) && $wgUser->getOption( 'autopatrol' ) ) {
13431397 RecentChange::markPatrolled( $rcid );
13441398 }
1345 -
1346 - $dbw->commit();
13471399 }
1348 - } else {
1349 - // Keep the same revision ID, but do some updates on it
1350 - $revisionId = $this->getRevIdFetched();
 1400+ $dbw->commit();
 1401+
 1402+ # Update links, etc.
 1403+ $this->editUpdates( $text, $summary, $isminor, $now, $revisionId );
 1404+
 1405+ # Clear caches
 1406+ Article::onArticleCreate( $this->mTitle );
 1407+
 1408+ wfRunHooks( 'ArticleInsertComplete', array( &$this, &$wgUser, $text,
 1409+ $summary, $flags & EDIT_MINOR,
 1410+ null, null, &$flags ) );
13511411 }
13521412
1353 - if( !$wgDBtransactions ) {
1354 - ignore_user_abort( $userAbort );
 1413+ if ( $good && !( $flags & EDIT_DEFER_UPDATES ) ) {
 1414+ wfDoUpdates();
13551415 }
13561416
1357 - if ( $good ) {
1358 - # Invalidate cache of this article and all pages using this article
1359 - # as a template. Partly deferred.
1360 - Article::onArticleEdit( $this->mTitle );
1361 -
1362 - if ($watchthis) {
1363 - if (!$this->mTitle->userIsWatching()) {
1364 - $dbw->begin();
1365 - $this->doWatch();
1366 - $dbw->commit();
1367 - }
1368 - } else {
1369 - if ( $this->mTitle->userIsWatching() ) {
1370 - $dbw->begin();
1371 - $this->doUnwatch();
1372 - $dbw->commit();
1373 - }
1374 - }
1375 - # Update links tables, site stats, etc.
1376 - $this->editUpdates( $text, $summary, $minor, $now, $revisionId );
1377 -
1378 - # Output a redirect back to the article
1379 - $this->doRedirect( $this->isRedirect( $text ), $sectionanchor );
1380 - }
13811417 wfRunHooks( 'ArticleSaveComplete',
13821418 array( &$this, &$wgUser, $text,
1383 - $summary, $minor,
1384 - $watchthis, $sectionanchor ) );
1385 - wfProfileOut( $fname );
 1419+ $summary, $flags & EDIT_MINOR,
 1420+ null, null, &$flags ) );
 1421+
 1422+ wfProfileOut( __METHOD__ );
13861423 return $good;
13871424 }
13881425
@@ -1651,7 +1688,6 @@
16521689 */
16531690 function delete() {
16541691 global $wgUser, $wgOut, $wgRequest;
1655 - $fname = 'Article::delete';
16561692 $confirm = $wgRequest->wasPosted() &&
16571693 $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) );
16581694 $reason = $wgRequest->getText( 'wpReason' );
@@ -1679,7 +1715,7 @@
16801716 # Better double-check that it hasn't been deleted yet!
16811717 $dbw =& wfGetDB( DB_MASTER );
16821718 $conds = $this->mTitle->pageCond();
1683 - $latest = $dbw->selectField( 'page', 'page_latest', $conds, $fname );
 1719+ $latest = $dbw->selectField( 'page', 'page_latest', $conds, __METHOD__ );
16841720 if ( $latest === false ) {
16851721 $wgOut->showFatalError( wfMsg( 'cannotdelete' ) );
16861722 return;
@@ -1769,8 +1805,7 @@
17701806 * @return array Array of authors, duplicates not removed
17711807 */
17721808 function getLastNAuthors( $num, $revLatest = 0 ) {
1773 - $fname = 'Article::getLastNAuthors';
1774 - wfProfileIn( $fname );
 1809+ wfProfileIn( __METHOD__ );
17751810
17761811 // First try the slave
17771812 // If that doesn't have the latest revision, try the master
@@ -1783,13 +1818,13 @@
17841819 'page_namespace' => $this->mTitle->getNamespace(),
17851820 'page_title' => $this->mTitle->getDBkey(),
17861821 'rev_page = page_id'
1787 - ), $fname, $this->getSelectOptions( array(
 1822+ ), __METHOD__, $this->getSelectOptions( array(
17881823 'ORDER BY' => 'rev_timestamp DESC',
17891824 'LIMIT' => $num
17901825 ) )
17911826 );
17921827 if ( !$res ) {
1793 - wfProfileOut( $fname );
 1828+ wfProfileOut( __METHOD__ );
17941829 return array();
17951830 }
17961831 $row = $db->fetchObject( $res );
@@ -1805,7 +1840,7 @@
18061841 while ( $row = $db->fetchObject( $res ) ) {
18071842 $authors[] = $row->rev_user_text;
18081843 }
1809 - wfProfileOut( $fname );
 1844+ wfProfileOut( __METHOD__ );
18101845 return $authors;
18111846 }
18121847
@@ -1858,8 +1893,7 @@
18591894 */
18601895 function doDelete( $reason ) {
18611896 global $wgOut, $wgUser;
1862 - $fname = 'Article::doDelete';
1863 - wfDebug( $fname."\n" );
 1897+ wfDebug( __METHOD__."\n" );
18641898
18651899 if (wfRunHooks('ArticleDelete', array(&$this, &$wgUser, &$reason))) {
18661900 if ( $this->doDeleteArticle( $reason ) ) {
@@ -1889,8 +1923,7 @@
18901924 global $wgUseSquid, $wgDeferredUpdateList;
18911925 global $wgPostCommitUpdateList, $wgUseTrackbacks;
18921926
1893 - $fname = 'Article::doDeleteArticle';
1894 - wfDebug( $fname."\n" );
 1927+ wfDebug( __METHOD__."\n" );
18951928
18961929 $dbw =& wfGetDB( DB_MASTER );
18971930 $ns = $this->mTitle->getNamespace();
@@ -1928,18 +1961,18 @@
19291962 ), array(
19301963 'page_id' => $id,
19311964 'page_id = rev_page'
1932 - ), $fname
 1965+ ), __METHOD__
19331966 );
19341967
19351968 # Now that it's safely backed up, delete it
1936 - $dbw->delete( 'revision', array( 'rev_page' => $id ), $fname );
1937 - $dbw->delete( 'page', array( 'page_id' => $id ), $fname);
 1969+ $dbw->delete( 'revision', array( 'rev_page' => $id ), __METHOD__ );
 1970+ $dbw->delete( 'page', array( 'page_id' => $id ), __METHOD__);
19381971
19391972 if ($wgUseTrackbacks)
1940 - $dbw->delete( 'trackbacks', array( 'tb_page' => $id ), $fname );
 1973+ $dbw->delete( 'trackbacks', array( 'tb_page' => $id ), __METHOD__ );
19411974
19421975 # Clean up recentchanges entries...
1943 - $dbw->delete( 'recentchanges', array( 'rc_namespace' => $ns, 'rc_title' => $t ), $fname );
 1976+ $dbw->delete( 'recentchanges', array( 'rc_namespace' => $ns, 'rc_title' => $t ), __METHOD__ );
19441977
19451978 # Finally, clean up the link tables
19461979 $t = $this->mTitle->getPrefixedDBkey();
@@ -1970,7 +2003,6 @@
19712004 */
19722005 function rollback() {
19732006 global $wgUser, $wgOut, $wgRequest, $wgUseRCPatrol;
1974 - $fname = 'Article::rollback';
19752007
19762008 if( $wgUser->isAllowed( 'rollback' ) ) {
19772009 if( $wgUser->isBlocked() ) {
@@ -2033,7 +2065,7 @@
20342066 array(
20352067 'rev_page' => $current->getPage(),
20362068 "rev_user <> {$user} OR rev_user_text <> {$user_text}"
2037 - ), $fname,
 2069+ ), __METHOD__,
20382070 array(
20392071 'USE INDEX' => 'page_timestamp',
20402072 'ORDER BY' => 'rev_timestamp DESC' )
@@ -2061,7 +2093,7 @@
20622094 'rc_cur_id' => $current->getPage(),
20632095 'rc_user_text' => $current->getUserText(),
20642096 "rc_timestamp > '{$s->rev_timestamp}'",
2065 - ), $fname
 2097+ ), __METHOD__
20662098 );
20672099 }
20682100
@@ -2113,8 +2145,7 @@
21142146 function editUpdates( $text, $summary, $minoredit, $timestamp_of_pagechange, $newid) {
21152147 global $wgDeferredUpdateList, $wgMessageCache, $wgUser, $wgParser;
21162148
2117 - $fname = 'Article::editUpdates';
2118 - wfProfileIn( $fname );
 2149+ wfProfileIn( __METHOD__ );
21192150
21202151 # Parse the text
21212152 $options = new ParserOptions;
@@ -2148,7 +2179,7 @@
21492180 $shortTitle = $this->mTitle->getDBkey();
21502181
21512182 if ( 0 == $id ) {
2152 - wfProfileOut( $fname );
 2183+ wfProfileOut( __METHOD__ );
21532184 return;
21542185 }
21552186
@@ -2177,7 +2208,7 @@
21782209 $wgMessageCache->replace( $shortTitle, $text );
21792210 }
21802211
2181 - wfProfileOut( $fname );
 2212+ wfProfileOut( __METHOD__ );
21822213 }
21832214
21842215 /**
@@ -2277,7 +2308,6 @@
22782309 *
22792310 */
22802311 function checkTouched() {
2281 - $fname = 'Article::checkTouched';
22822312 if( !$this->mDataLoaded ) {
22832313 $this->loadPageData();
22842314 }
@@ -2315,8 +2345,7 @@
23162346 * @param bool $minor whereas it's a minor modification
23172347 */
23182348 function quickEdit( $text, $comment = '', $minor = 0 ) {
2319 - $fname = 'Article::quickEdit';
2320 - wfProfileIn( $fname );
 2349+ wfProfileIn( __METHOD__ );
23212350
23222351 $dbw =& wfGetDB( DB_MASTER );
23232352 $dbw->begin();
@@ -2331,7 +2360,7 @@
23322361 $this->updateRevisionOn( $dbw, $revision );
23332362 $dbw->commit();
23342363
2335 - wfProfileOut( $fname );
 2364+ wfProfileOut( __METHOD__ );
23362365 }
23372366
23382367 /**
@@ -2405,6 +2434,15 @@
24062435 */
24072436
24082437 static function onArticleCreate($title) {
 2438+ # The talk page isn't in the regular link tables, so we need to update manually:
 2439+ if ( $title->isTalkPage() ) {
 2440+ $other = $title->getSubjectPage();
 2441+ } else {
 2442+ $other = $title->getTalkPage();
 2443+ }
 2444+ $other->invalidateCache();
 2445+ $other->purgeSquid();
 2446+
24092447 $title->touchLinks();
24102448 $title->purgeSquid();
24112449 }
@@ -2458,7 +2496,6 @@
24592497 */
24602498 function info() {
24612499 global $wgLang, $wgOut, $wgAllowPageInfo, $wgUser;
2462 - $fname = 'Article::info';
24632500
24642501 if ( !$wgAllowPageInfo ) {
24652502 $wgOut->showErrorPage( 'nosuchaction', 'nosuchactiontext' );
@@ -2487,7 +2524,7 @@
24882525 'watchlist',
24892526 'COUNT(*)',
24902527 $wl_clause,
2491 - $fname,
 2528+ __METHOD__,
24922529 $this->getSelectOptions() );
24932530
24942531 $pageInfo = $this->pageCountInfo( $page );
@@ -2524,20 +2561,19 @@
25252562 $dbr =& wfGetDB( DB_SLAVE );
25262563
25272564 $rev_clause = array( 'rev_page' => $id );
2528 - $fname = 'Article::pageCountInfo';
25292565
25302566 $edits = $dbr->selectField(
25312567 'revision',
25322568 'COUNT(rev_page)',
25332569 $rev_clause,
2534 - $fname,
 2570+ __METHOD__,
25352571 $this->getSelectOptions() );
25362572
25372573 $authors = $dbr->selectField(
25382574 'revision',
25392575 'COUNT(DISTINCT rev_user_text)',
25402576 $rev_clause,
2541 - $fname,
 2577+ __METHOD__,
25422578 $this->getSelectOptions() );
25432579
25442580 return array( 'edits' => $edits, 'authors' => $authors );

Follow-up revisions

RevisionCommit summaryAuthorDate
r66878(bug 23641) refactor code around Article::doEdit(), and restored access to wa...happy-melon16:40, 25 May 2010
r70760* Revert r66878, completely misses the point of factoring out doEdit() in the...tstarling08:33, 9 August 2010

Comments

#Comment by Platonides (talk | contribs)   20:59, 30 August 2010

Why do $this->doWatch(); and $this->doUnwatch(); need to be surrounded by a transaction?

Status & tagging log