Пример #1
0
	/**
	 * 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__ );
	}