diff options
Diffstat (limited to 'includes/Wiki.php')
-rw-r--r-- | includes/Wiki.php | 157 |
1 files changed, 63 insertions, 94 deletions
diff --git a/includes/Wiki.php b/includes/Wiki.php index dc4467b6..b2cb1eb0 100644 --- a/includes/Wiki.php +++ b/includes/Wiki.php @@ -1,16 +1,14 @@ <?php /** * MediaWiki is the to-be base class for this whole project + * + * @internal documentation reviewed 15 Mar 2010 */ class MediaWiki { - - var $GET; /* Stores the $_GET variables at time of creation, can be changed */ var $params = array(); - /** Constructor. It just save the $_GET variable */ - function __construct() { - $this->GET = $_GET; - } + /** Constructor */ + function __construct() {} /** * Stores key/value pairs to circumvent global variables @@ -29,7 +27,8 @@ class MediaWiki { * Note that keys are case-insensitive! * * @param $key String: key to get - * @param $default Mixed: default value if if the key doesn't exist + * @param $default string default value, defaults to empty string + * @return $default Mixed: default value if if the key doesn't exist */ function getVal( $key, $default = '' ) { $key = strtolower( $key ); @@ -51,12 +50,12 @@ class MediaWiki { */ function performRequestForTitle( &$title, &$article, &$output, &$user, $request ) { wfProfileIn( __METHOD__ ); - + $output->setTitle( $title ); - + wfRunHooks( 'BeforeInitialize', array( &$title, &$article, &$output, &$user, $request, $this ) ); - - if( !$this->preliminaryChecks( $title, $output, $request ) ) { + + if( !$this->preliminaryChecks( $title, $output ) ) { wfProfileOut( __METHOD__ ); return; } @@ -109,9 +108,15 @@ class MediaWiki { if( $wgRequest->getVal( 'printable' ) === 'yes' ) { $wgOut->setPrintable(); } - $ret = null; - if( $curid = $wgRequest->getInt( 'curid' ) ) { - # URLs like this are generated by RC, because rc_title isn't always accurate + + $curid = $wgRequest->getInt( 'curid' ); + if( $wgRequest->getCheck( 'search' ) ) { + // Compatibility with old search URLs which didn't use Special:Search + // Just check for presence here, so blank requests still + // show the search page when using ugly URLs (bug 8054). + $ret = SpecialPage::getTitleFor( 'Search' ); + } elseif( $curid ) { + // URLs like this are generated by RC, because rc_title isn't always accurate $ret = Title::newFromID( $curid ); } elseif( $title == '' && $action != 'delete' ) { $ret = Title::newMainPage(); @@ -122,7 +127,7 @@ class MediaWiki { if( count( $wgContLang->getVariants() ) > 1 && !is_null( $ret ) && $ret->getArticleID() == 0 ) $wgContLang->findVariantLink( $title, $ret ); } - # For non-special titles, check for implicit titles + // For non-special titles, check for implicit titles if( is_null( $ret ) || $ret->getNamespace() != NS_SPECIAL ) { // We can have urls with just ?diff=,?oldid= or even just ?diff= $oldid = $wgRequest->getInt( 'oldid' ); @@ -137,28 +142,19 @@ class MediaWiki { } /** - * Checks for search query and anon-cannot-read case + * Checks for anon-cannot-read case * * @param $title Title * @param $output OutputPage - * @param $request WebRequest + * @return boolean true if successful */ - function preliminaryChecks( &$title, &$output, $request ) { - if( $request->getCheck( 'search' ) ) { - // Compatibility with old search URLs which didn't use Special:Search - // Just check for presence here, so blank requests still - // show the search page when using ugly URLs (bug 8054). - - // Do this above the read whitelist check for security... - $title = SpecialPage::getTitleFor( 'Search' ); - } - # If the user is not logged in, the Namespace:title of the article must be in - # the Read array in order for the user to see it. (We have to check here to - # catch special pages etc. We check again in Article::view()) + function preliminaryChecks( &$title, &$output ) { + // If the user is not logged in, the Namespace:title of the article must be in + // the Read array in order for the user to see it. (We have to check here to + // catch special pages etc. We check again in Article::view()) if( !is_null( $title ) && !$title->userCanRead() ) { - global $wgDeferredUpdateList; $output->loginToUse(); - $this->finalCleanup( $wgDeferredUpdateList, $output ); + $this->finalCleanup( $output ); $output->disable(); return false; } @@ -179,19 +175,20 @@ class MediaWiki { */ function handleSpecialCases( &$title, &$output, $request ) { wfProfileIn( __METHOD__ ); - global $wgContLang, $wgUser; + $action = $this->getVal( 'Action' ); - $perferred = $wgContLang->getPreferredVariant( false ); // Invalid titles. Bug 21776: The interwikis must redirect even if the page name is empty. - if( is_null($title) || ( ($title->getDBkey() == '') && ($title->getInterwiki() == '') ) ) { + if( is_null($title) || ( ( $title->getDBkey() == '' ) && ( $title->getInterwiki() == '' ) ) ) { $title = SpecialPage::getTitleFor( 'Badtitle' ); - # Die now before we mess up $wgArticle and the skin stops working + $output->setTitle( $title ); // bug 21456 + // Die now before we mess up $wgArticle and the skin stops working throw new ErrorPageError( 'badtitle', 'badtitletext' ); // Interwiki redirects } else if( $title->getInterwiki() != '' ) { - if( $rdfrom = $request->getVal( 'rdfrom' ) ) { + $rdfrom = $request->getVal( 'rdfrom' ); + if( $rdfrom ) { $url = $title->getFullURL( 'rdfrom=' . urlencode( $rdfrom ) ); } else { $query = $request->getValues(); @@ -200,26 +197,26 @@ class MediaWiki { } /* Check for a redirect loop */ if( !preg_match( '/^' . preg_quote( $this->getVal('Server'), '/' ) . '/', $url ) && $title->isLocal() ) { - $output->redirect( $url ); + // 301 so google et al report the target as the actual url. + $output->redirect( $url, 301 ); } else { $title = SpecialPage::getTitleFor( 'Badtitle' ); + $output->setTitle( $title ); // bug 21456 wfProfileOut( __METHOD__ ); throw new ErrorPageError( 'badtitle', 'badtitletext' ); } // Redirect loops, no title in URL, $wgUsePathInfo URLs, and URLs with a variant - } else if( $action == 'view' && !$request->wasPosted() && - ( ( !isset($this->GET['title']) || $title->getPrefixedDBKey() != $this->GET['title'] ) || - // No valid variant in URL (if the main-language has multi-variants), to ensure - // anonymous access would always be redirect to a URL with 'variant' parameter - ( !isset($this->GET['variant']) && $wgContLang->hasVariants() && !$wgUser->isLoggedIn() ) ) && - !count( array_diff( array_keys( $this->GET ), array( 'action', 'title' ) ) ) ) + } else if ( $action == 'view' && !$request->wasPosted() + && ( $request->getVal( 'title' ) === null || $title->getPrefixedDBKey() != $request->getVal( 'title' ) ) + && !count( array_diff( array_keys( $request->getValues() ), array( 'action', 'title' ) ) ) ) { - if( !$wgUser->isLoggedIn() ) { - $pref = $wgContLang->getPreferredVariant( false, $fromHeader = true ); - $targetUrl = $title->getFullURL( '', $variant = $pref ); + if ( $title->getNamespace() == NS_SPECIAL ) { + list( $name, $subpage ) = SpecialPage::resolveAliasWithSubpage( $title->getDBkey() ); + if ( $name ) { + $title = SpecialPage::getTitleFor( $name, $subpage ); + } } - else - $targetUrl = $title->getFullURL(); + $targetUrl = $title->getFullURL(); // Redirect to canonical url, make it a 301 to allow caching if( $targetUrl == $request->getFullRequestURL() ) { $message = "Redirect loop detected!\n\n" . @@ -304,8 +301,8 @@ class MediaWiki { $action = $this->getVal( 'action', 'view' ); $article = self::articleFromTitle( $title ); - # NS_MEDIAWIKI has no redirects. - # It is also used for CSS/JS, so performance matters here... + // NS_MEDIAWIKI has no redirects. + // It is also used for CSS/JS, so performance matters here... if( $title->getNamespace() == NS_MEDIAWIKI ) { wfProfileOut( __METHOD__ ); return $article; @@ -315,23 +312,24 @@ class MediaWiki { $file = ($title->getNamespace() == NS_FILE) ? $article->getFile() : null; if( ( $action == 'view' || $action == 'render' ) // ... for actions that show content && !$request->getVal( 'oldid' ) && // ... and are not old revisions + !$request->getVal( 'diff' ) && // ... and not when showing diff $request->getVal( 'redirect' ) != 'no' && // ... unless explicitly told not to // ... and the article is not a non-redirect image page with associated file !( is_object( $file ) && $file->exists() && !$file->getRedirected() ) ) { - # Give extensions a change to ignore/handle redirects as needed + // Give extensions a change to ignore/handle redirects as needed $ignoreRedirect = $target = false; - + $dbr = wfGetDB( DB_SLAVE ); $article->loadPageData( $article->pageDataFromTitle( $dbr, $title ) ); - wfRunHooks( 'InitializeArticleMaybeRedirect', + wfRunHooks( 'InitializeArticleMaybeRedirect', array(&$title,&$request,&$ignoreRedirect,&$target,&$article) ); // Follow redirects only for... redirects. // If $target is set, then a hook wanted to redirect. if( !$ignoreRedirect && ($target || $article->isRedirect()) ) { - # Is the target already set by an extension? + // Is the target already set by an extension? $target = $target ? $target : $article->followRedirect(); if( is_string( $target ) ) { if( !$this->getVal( 'DisableHardRedirects' ) ) { @@ -363,52 +361,23 @@ class MediaWiki { * Cleaning up request by doing: ** deferred updates, DB transaction, and the output * - * @param $deferredUpdates array of updates to do * @param $output OutputPage */ - function finalCleanup( &$deferredUpdates, &$output ) { + function finalCleanup( &$output ) { wfProfileIn( __METHOD__ ); - # Now commit any transactions, so that unreported errors after - # output() don't roll back the whole DB transaction + // Now commit any transactions, so that unreported errors after + // output() don't roll back the whole DB transaction $factory = wfGetLBFactory(); $factory->commitMasterChanges(); - # Output everything! + // Output everything! $output->output(); - # Do any deferred jobs - $this->doUpdates( $deferredUpdates ); + // Do any deferred jobs + wfDoUpdates( true ); $this->doJobs(); wfProfileOut( __METHOD__ ); } /** - * Deferred updates aren't really deferred anymore. It's important to report - * errors to the user, and that means doing this before OutputPage::output(). - * Note that for page saves, the client will wait until the script exits - * anyway before following the redirect. - * - * @param $updates array of objects that hold an update to do - */ - function doUpdates( &$updates ) { - wfProfileIn( __METHOD__ ); - /* No need to get master connections in case of empty updates array */ - if (!$updates) { - wfProfileOut( __METHOD__ ); - return; - } - - $dbw = wfGetDB( DB_MASTER ); - foreach( $updates as $up ) { - $up->doUpdate(); - - # Commit after every update to prevent lock contention - if( $dbw->trxLevel() ) { - $dbw->commit(); - } - } - wfProfileOut( __METHOD__ ); - } - - /** * Do a job from the job queue */ function doJobs() { @@ -447,7 +416,7 @@ class MediaWiki { */ function restInPeace() { wfLogProfilingData(); - # Commit and close up! + // Commit and close up! $factory = wfGetLBFactory(); $factory->commitMasterChanges(); $factory->shutdown(); @@ -477,8 +446,8 @@ class MediaWiki { $action = 'nosuchaction'; } - # Workaround for bug #20966: inability of IE to provide an action dependent - # on which submit button is clicked. + // Workaround for bug #20966: inability of IE to provide an action dependent + // on which submit button is clicked. if ( $action === 'historysubmit' ) { if ( $request->getBool( 'revisiondelete' ) ) { $action = 'revisiondelete'; @@ -566,7 +535,7 @@ class MediaWiki { $history->history(); break; case 'revisiondelete': - # For show/hide submission from history page + // For show/hide submission from history page $special = SpecialPage::getPage( 'Revisiondelete' ); $special->execute( '' ); break; @@ -579,4 +548,4 @@ class MediaWiki { } -}; /* End of class MediaWiki */ +} |