• 追加された行はこの色です。
  • 削除された行はこの色です。
RIGHT:&tag(解析);

*目次 [#jc4c1b63]
#contents
----
#lsx(new=true);
-[[その他>WikiEngine/MediaWiki#misc]]

*関連 [#p963a4d4]
#lsx(tag=解析,new=true,except=^WikiEngine/MediaWiki(/.*)?$)

[[検索:MediaWiki]]


*参考 [#k91a73dd]
[[Google:MediaWiki]]

:design.txt|docs/design.txt
:MediaWiki Documentation|http://svn.wikimedia.org/doc/
:The MediaWiki codebase|http://www.mediawiki.org/wiki/How_to_become_a_MediaWiki_hacker#The_MediaWiki_codebase


*WikiEngine/MediaWiki/1.10 [#ya91fe21]


**主処理への入り口 [#f5dc3ecc]
-index.phpがエントリーポイント。
-なぜかMediaWiki::initializeの中に主処理がある。
index.php > MediaWiki::initialize > MediaWiki::performAction > (URLクエリーの'action'次第で分岐、それぞれの処理へ)
index.php > MediaWiki::initialize > MediaWiki::performAction > (リクエストの'action'次第で分岐、それぞれの処理へ)
-initialize直後にCleanup。


**MediaWikiひとめぐり [#cb2127c6]
起動から終了までの主な処理を処理順に。

MediaWiki::performActionが処理の中心。
ここで何をするかはMediaWikiの外から与えられるクエリー次第。
ここで何をするかはMediaWikiの外から与えられるリクエスト。

+index.php
+includes/Wiki.php(41)
MediaWiki::initialize
+includes/Wiki.php(365)
MediaWiki::performAction
&color(#f00){※};クエリー'action'次第でいろいろ処理。またはOutputPage::redirectを呼び出すことでリダイレクトすることにする(実際の出力は後のOutputPage::outputで)。
+includes/Wiki.php(289)
MediaWiki::finalCleanup
+includes/Wiki.php(305)
MediaWiki::doUpdates
$wgDeferredUpdateListに溜め込んだオブジェクト全て->doUpdates
こうして処理タイミングを遅らせているのは、処理間の依存関係を解決するため?
+includes/OutputPage.php(553)
OutputPage::output
&color(#f00){※};スキン適用、HTTPヘッダー・HTMLヘッダー生成、レスポンス出力


**action [#h4078d05]
'action'はほとんどMediaWiki(includes/Wiki.php)とArticle(includes/Article.php)で処理される。
それ以外には3つ程度のクラスしか関与しない。
処理の中心になっているのはこれらの数少ないクラスらしい。

'view'というactionは複数のクラスを通して処理される。
'view'はactionのデフォルト値。


***MediaWikiが処理する'action' [#fbde7197]
-dublincore
-creativecommons
-credits


***Articleが処理する'action' [#r99ec491]
-view *
-watch
-unwatch
-delete
-revert
-rollback
-protect
-unprotect
-info
-markpatrolled
-render
-deletetrackback
-purge
-print


***その他 [#feb68484]
-submit *(editを含む)
-edit *
-history *
-raw ?


**action 'view' [#u4b9390e]
Articleが処理する。

includes/Article.php:
actionのデフォルト。
クエリーで指示されたページを表示する。
	$sk = $wgUser->getSkin();
	
	wfProfileIn( __METHOD__ );
	
	$parserCache =& ParserCache::singleton();
	$ns = $this->mTitle->getNamespace(); # shortcut
	
	# Get variables from query string
	$oldid = $this->getOldID();
	
	# getOldID may want us to redirect somewhere else
	if ( $this->mRedirectUrl ) {
		$wgOut->redirect( $this->mRedirectUrl );
		wfProfileOut( __METHOD__ );
		return;
	}
	
	$diff = $wgRequest->getVal( 'diff' );
	$rcid = $wgRequest->getVal( 'rcid' );
	$rdfrom = $wgRequest->getVal( 'rdfrom' );
	$diffOnly = $wgRequest->getBool( 'diffonly', $wgUser->getOption( 'diffonly' ) );
	
	$wgOut->setArticleFlag( true );
	
	# Discourage indexing of printable versions, but encourage following
	if( $wgOut->isPrintable() ) {
		$policy = 'noindex,follow';
	} elseif( isset( $wgNamespaceRobotPolicies[$ns] ) ) {
		# Honour customised robot policies for this namespace
		$policy = $wgNamespaceRobotPolicies[$ns];
	} else {
		# Default to encourage indexing and following links
		$policy = 'index,follow';
	}
	$wgOut->setRobotPolicy( $policy );
	
	# If we got diff and oldid in the query, we want to see a
	# diff page instead of the article.
	
	if ( !is_null( $diff ) ) {
		$wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
	
		$de = new DifferenceEngine( $this->mTitle, $oldid, $diff, $rcid );
		// DifferenceEngine directly fetched the revision:
		$this->mRevIdFetched = $de->mNewid;
		$de->showDiffPage( $diffOnly );
	
		// Needed to get the page's current revision
		$this->loadPageData();
		if( $diff == 0 || $diff == $this->mLatest ) {
			# Run view updates for current revision only
			$this->viewUpdates();
		}
		wfProfileOut( __METHOD__ );
		return;
	}
	
	if ( empty( $oldid ) && $this->checkTouched() ) {
		$wgOut->setETag($parserCache->getETag($this, $wgUser));
	
		if( $wgOut->checkLastModified( $this->mTouched ) ){
			wfProfileOut( __METHOD__ );
			return;
		} else if ( $this->tryFileCache() ) {
			# tell wgOut that output is taken care of
			$wgOut->disable();
			$this->viewUpdates();
			wfProfileOut( __METHOD__ );
			return;
		}
	}
	
	# Should the parser cache be used?
	$pcache = $wgEnableParserCache &&
		intval( $wgUser->getOption( 'stubthreshold' ) ) == 0 &&
		$this->exists() &&
		empty( $oldid );
リクエストで指示されたページを表示する。

スキン参照。
プロセス名変更。
名前空間取得。

リクエストからOldIDを得て、不正なものならリダイレクト。
OldID…履歴のID、Wikipediaでの「特定版」?

-diff
-rcid
-rdfrom
-diffonly(利用者の設定と関連)

ArticleFlagをtrueに。
検索エンジンのロボット向けヘッダーの用意。

'diff'やOldIDを与えられたら差分ページを用意。
差分はDifferenceEngineに任せる。
それでも最新版を表示することもある。

$this->mIsRedirect でなく、OldIDも与えられていなければ…$this->viewUpdates()
HTTPヘッダーにETagも設定。
	wfDebug( 'Article::view using parser cache: ' . ($pcache ? 'yes' : 'no' ) . "\n" );
	if ( $wgUser->getOption( 'stubthreshold' ) ) {
		wfIncrStats( 'pcache_miss_stub' );
	}
	
	$wasRedirected = false;
	if ( isset( $this->mRedirectedFrom ) ) {
		// This is an internally redirected page view.
		// We'll need a backlink to the source page for navigation.
		if ( wfRunHooks( 'ArticleViewRedirect', array( &$this ) ) ) {
			$sk = $wgUser->getSkin();
			$redir = $sk->makeKnownLinkObj( $this->mRedirectedFrom, '', 'redirect=no' );
			$s = wfMsg( 'redirectedfrom', $redir );
			$wgOut->setSubtitle( $s );
	
			// Set the fragment if one was specified in the redirect
			if ( strval( $this->mTitle->getFragment() ) != '' ) {
				$fragment = Xml::escapeJsString( $this->mTitle->getFragmentForURL() );
				$wgOut->addInlineScript( "redirectToFragment(\"$fragment\");" );
			}
			$wasRedirected = true;
		}
	} elseif ( !empty( $rdfrom ) ) {
		// This is an externally redirected view, from some other wiki.
		// If it was reported from a trusted site, supply a backlink.
		global $wgRedirectSources;
		if( $wgRedirectSources && preg_match( $wgRedirectSources, $rdfrom ) ) {
			$sk = $wgUser->getSkin();
			$redir = $sk->makeExternalLink( $rdfrom, $rdfrom );
			$s = wfMsg( 'redirectedfrom', $redir );
			$wgOut->setSubtitle( $s );
			$wasRedirected = true;
		}
	}
	
	$outputDone = false;
	wfRunHooks( 'ArticleViewHeader', array( &$this ) );
	if ( $pcache ) {
		if ( $wgOut->tryParserCache( $this, $wgUser ) ) {
			$outputDone = true;
		}
	}
	if ( !$outputDone ) {
		$text = $this->getContent();
		if ( $text === false ) {
			# Failed to load, replace text with error message
			$t = $this->mTitle->getPrefixedText();
			if( $oldid ) {
				$t .= ',oldid='.$oldid;
				$text = wfMsg( 'missingarticle', $t );
			} else {
				$text = wfMsg( 'noarticletext', $t );
			}
		}
	
		# Another whitelist check in case oldid is altering the title
		if ( !$this->mTitle->userCanRead() ) {
			$wgOut->loginToUse();
			$wgOut->output();
			exit;
		}
	
		# We're looking at an old revision
	
		if ( !empty( $oldid ) ) {
			$wgOut->setRobotpolicy( 'noindex,nofollow' );
			if( is_null( $this->mRevision ) ) {
				// FIXME: This would be a nice place to load the 'no such page' text.
			} else {
				$this->setOldSubtitle( isset($this->mOldId) ? $this->mOldId : $oldid );
				if( $this->mRevision->isDeleted( Revision::DELETED_TEXT ) ) {
					if( !$this->mRevision->userCan( Revision::DELETED_TEXT ) ) {
						$wgOut->addWikiText( wfMsg( 'rev-deleted-text-permission' ) );
						$wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
						return;
					} else {
						$wgOut->addWikiText( wfMsg( 'rev-deleted-text-view' ) );
						// and we are allowed to see...
					}
				}
			}
	
		}
	}
	if( !$outputDone ) {
		$wgOut->setRevisionId( $this->getRevIdFetched() );
		# wrap user css and user js in pre and don't parse
		# XXX: use $this->mTitle->usCssJsSubpage() when php is fixed/ a workaround is found
		if (
			$ns == NS_USER &&
			preg_match('/\\/[\\w]+\\.(?:css|js)$/', $this->mTitle->getDBkey())
		) {
			$wgOut->addWikiText( wfMsg('clearyourcache'));
			$wgOut->addHTML( '<pre>'.htmlspecialchars($this->mContent)."\n</pre>" );
		} else if ( $rt = Title::newFromRedirect( $text ) ) {
			# Display redirect
			$imageDir = $wgContLang->isRTL() ? 'rtl' : 'ltr';
			$imageUrl = $wgStylePath.'/common/images/redirect' . $imageDir . '.png';
			# Don't overwrite the subtitle if this was an old revision
			if( !$wasRedirected && $this->isCurrent() ) {
				$wgOut->setSubtitle( wfMsgHtml( 'redirectpagesub' ) );
			}
			$link = $sk->makeLinkObj( $rt, $rt->getFullText() );
	
			$wgOut->addHTML( '<img src="'.$imageUrl.'" alt="#REDIRECT " />' .
			  '<span class="redirectText">'.$link.'</span>' );
	
			$parseout = $wgParser->parse($text, $this->mTitle, ParserOptions::newFromUser($wgUser));
			$wgOut->addParserOutputNoText( $parseout );
		} else if ( $pcache ) {
			# Display content and save to parser cache
			$this->outputWikiText( $text );
		} else {
			# Display content, don't attempt to save to parser cache
			# Don't show section-edit links on old revisions... this way lies madness.
			if( !$this->isCurrent() ) {
				$oldEditSectionSetting = $wgOut->parserOptions()->setEditSection( false );
			}
			# Display content and don't save to parser cache
			# With timing hack -- TS 2006-07-26
			$time = -wfTime();
			$this->outputWikiText( $text, false );
			$time += wfTime();
	
			# Timing hack
			if ( $time > 3 ) {
				wfDebugLog( 'slow-parse', sprintf( "%-5.2f %s", $time,
					$this->mTitle->getPrefixedDBkey()));
			}
	
			if( !$this->isCurrent() ) {
				$wgOut->parserOptions()->setEditSection( $oldEditSectionSetting );
			}
	
		}
	}
	/* title may have been set from the cache */
	$t = $wgOut->getPageTitle();
	if( empty( $t ) ) {
		$wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
	}
	
	# check if we're displaying a [[User talk:x.x.x.x]] anonymous talk page
	if( $ns == NS_USER_TALK &&
		User::isIP( $this->mTitle->getText() ) ) {
		$wgOut->addWikiText( wfMsg('anontalkpagetext') );
	}
	
	# If we have been passed an &rcid= parameter, we want to give the user a
	# chance to mark this new article as patrolled.
	if ( $wgUseRCPatrol && !is_null( $rcid ) && $rcid != 0 && $wgUser->isAllowed( 'patrol' ) ) {
		$wgOut->addHTML(
			"<div class='patrollink'>" .
				wfMsgHtml( 'markaspatrolledlink',
				$sk->makeKnownLinkObj( $this->mTitle, wfMsgHtml('markaspatrolledtext'),
					"action=markpatrolled&rcid=$rcid" )
		 		) .
			'</div>'
		 );
	}
	
	# Trackbacks
	if ($wgUseTrackbacks)
		$this->addTrackbacks();
	
	$this->viewUpdates();
	wfProfileOut( __METHOD__ );

リダイレクトページ。「~より転送」

リダイレクトページではなくrdfromがあれば…
外部からのリダイレクト。

要ログインページ。

履歴。

さらに追加。
<pre>…</pre>追加。
<span class="redirectText">…</span>追加。
MediaWikiでのページキャッシュ。
履歴ではページキャッシュを無効に。

ページタイトル取得。

名無しさん用会話ページの場合の追加分。

パトロール機能のためのUI追加。
<div class='patrollink'>…</div>追加。

トラックバック表示の追加。

ページ出力。