/** * Do standard deferred updates after page edit. * Update links tables, site stats, search index and message cache. * Purges pages that include this page if the text was changed here. * Every 100th edit, prune the recent changes table. * * @param $revision Revision object * @param $user User object that did the revision * @param array $options of options, following indexes are used: * - changed: boolean, whether the revision changed the content (default true) * - created: boolean, whether the revision created the page (default false) * - oldcountable: boolean or null (default null): * - boolean: whether the page was counted as an article before that * revision, only used in changed is true and created is false * - null: don't change the article count */ public function doEditUpdates( Revision $revision, User $user, array $options = array() ) { global $wgEnableParserCache; wfProfileIn( __METHOD__ ); $options += array( 'changed' => true, 'created' => false, 'oldcountable' => null ); $content = $revision->getContent(); // Parse the text // Be careful not to do pre-save transform twice: $text is usually // already pre-save transformed once. if ( !$this->mPreparedEdit || $this->mPreparedEdit->output->getFlag( 'vary-revision' ) ) { wfDebug( __METHOD__ . ": No prepared edit or vary-revision is set...\n" ); $editInfo = $this->prepareContentForEdit( $content, $revision->getId(), $user ); } else { wfDebug( __METHOD__ . ": No vary-revision, using prepared edit...\n" ); $editInfo = $this->mPreparedEdit; } // Save it to the parser cache if ( $wgEnableParserCache ) { $parserCache = ParserCache::singleton(); $parserCache->save( $editInfo->output, $this, $editInfo->popts ); } // Update the links tables and other secondary data if ( $content ) { $recursive = $options['changed']; // bug 50785 $updates = $content->getSecondaryDataUpdates( $this->getTitle(), null, $recursive, $editInfo->output ); DataUpdate::runUpdates( $updates ); } wfRunHooks( 'ArticleEditUpdates', array( &$this, &$editInfo, $options['changed'] ) ); if ( wfRunHooks( 'ArticleEditUpdatesDeleteFromRecentchanges', array( &$this ) ) ) { if ( 0 == mt_rand( 0, 99 ) ) { // Flush old entries from the `recentchanges` table; we do this on // random requests so as to avoid an increase in writes for no good reason RecentChange::purgeExpiredChanges(); } } if ( !$this->exists() ) { wfProfileOut( __METHOD__ ); return; } $id = $this->getId(); $title = $this->mTitle->getPrefixedDBkey(); $shortTitle = $this->mTitle->getDBkey(); if ( !$options['changed'] ) { $good = 0; $total = 0; } elseif ( $options['created'] ) { $good = (int)$this->isCountable( $editInfo ); $total = 1; } elseif ( $options['oldcountable'] !== null ) { $good = (int)$this->isCountable( $editInfo ) - (int)$options['oldcountable']; $total = 0; } else { $good = 0; $total = 0; } DeferredUpdates::addUpdate( new SiteStatsUpdate( 0, 1, $good, $total ) ); DeferredUpdates::addUpdate( new SearchUpdate( $id, $title, $content ) ); // If this is another user's talk page, update newtalk. // Don't do this if $options['changed'] = false (null-edits) nor if // it's a minor edit and the user doesn't want notifications for those. if ( $options['changed'] && $this->mTitle->getNamespace() == NS_USER_TALK && $shortTitle != $user->getTitleKey() && !( $revision->isMinor() && $user->isAllowed( 'nominornewtalk' ) ) ) { $recipient = User::newFromName( $shortTitle, false ); if ( !$recipient ) { wfDebug( __METHOD__ . ": invalid username\n" ); } else { // Allow extensions to prevent user notification when a new message is added to their talk page if ( wfRunHooks( 'ArticleEditUpdateNewTalk', array( &$this, $recipient ) ) ) { if ( User::isIP( $shortTitle ) ) { // An anonymous user $recipient->setNewtalk( true, $revision ); } elseif ( $recipient->isLoggedIn() ) { $recipient->setNewtalk( true, $revision ); } else { wfDebug( __METHOD__ . ": don't need to notify a nonexistent user\n" ); } } } } if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) { // XXX: could skip pseudo-messages like js/css here, based on content model. $msgtext = $content ? $content->getWikitextForTransclusion() : null; if ( $msgtext === false || $msgtext === null ) { $msgtext = ''; } MessageCache::singleton()->replace( $shortTitle, $msgtext ); } if ( $options['created'] ) { self::onArticleCreate( $this->mTitle ); } else { self::onArticleEdit( $this->mTitle ); } wfProfileOut( __METHOD__ ); }