Index: trunk/phase3/index.php |
— | — | @@ -66,7 +66,7 @@ |
67 | 67 | $mediaWiki = new MediaWiki( $wgRequest, $wgOut ); |
68 | 68 | |
69 | 69 | # Set title from request parameters |
70 | | -$wgTitle = $mediaWiki->checkInitialQueries(); |
| 70 | +$wgTitle = $mediaWiki->getTitle(); |
71 | 71 | $action = $wgRequest->getVal( 'action', 'view' ); |
72 | 72 | |
73 | 73 | wfProfileOut( 'index.php-setup' ); |
— | — | @@ -116,7 +116,7 @@ |
117 | 117 | $mediaWiki->setVal( 'UseExternalEditor', $wgUseExternalEditor ); |
118 | 118 | $mediaWiki->setVal( 'UsePathInfo', $wgUsePathInfo ); |
119 | 119 | |
120 | | -$mediaWiki->performRequestForTitle( $wgTitle, $wgArticle, $wgUser ); |
| 120 | +$mediaWiki->performRequestForTitle( $wgArticle, $wgUser ); |
121 | 121 | $mediaWiki->finalCleanup(); |
122 | 122 | |
123 | 123 | wfProfileOut( 'index.php' ); |
Index: trunk/phase3/includes/SpecialPage.php |
— | — | @@ -519,10 +519,11 @@ |
520 | 520 | * Returns a title object if the page is redirected, false if there was no such special |
521 | 521 | * page, and true if it was successful. |
522 | 522 | * |
523 | | - * @param $title a title object |
524 | | - * @param $including output is being captured for use in {{special:whatever}} |
| 523 | + * @param $title Title object |
| 524 | + * @param $context RequestContext |
| 525 | + * @param $including Bool output is being captured for use in {{special:whatever}} |
525 | 526 | */ |
526 | | - static function executePath( &$title, $including = false ) { |
| 527 | + static function executePath( &$title, RequestContext $context, $including = false ) { |
527 | 528 | global $wgOut, $wgTitle, $wgRequest; |
528 | 529 | wfProfileIn( __METHOD__ ); |
529 | 530 | |
— | — | @@ -546,7 +547,7 @@ |
547 | 548 | } |
548 | 549 | |
549 | 550 | # Page exists, set the context |
550 | | - $page->setContext( $wgOut->getContext() ); |
| 551 | + $page->setContext( $context ); |
551 | 552 | |
552 | 553 | # Check for redirect |
553 | 554 | if ( !$including ) { |
— | — | @@ -624,7 +625,7 @@ |
625 | 626 | $context->setTitle( $title ); |
626 | 627 | $wgOut = $context->getOutput(); |
627 | 628 | |
628 | | - $ret = SpecialPage::executePath( $title, true ); |
| 629 | + $ret = SpecialPage::executePath( $title, $context, true ); |
629 | 630 | if ( $ret === true ) { |
630 | 631 | $ret = $wgOut->getHTML(); |
631 | 632 | } |
Index: trunk/phase3/includes/RequestContext.php |
— | — | @@ -10,7 +10,7 @@ |
11 | 11 | class RequestContext { |
12 | 12 | private $request; /// WebRequest object |
13 | 13 | private $title; /// Title object |
14 | | - private $out; /// OutputPage object |
| 14 | + private $output; /// OutputPage object |
15 | 15 | private $user; /// User object |
16 | 16 | private $lang; /// Language object |
17 | 17 | private $skin; /// Skin object |
— | — | @@ -60,6 +60,15 @@ |
61 | 61 | } |
62 | 62 | |
63 | 63 | /** |
| 64 | + * Set the OutputPage object |
| 65 | + * |
| 66 | + * @param $u OutputPage |
| 67 | + */ |
| 68 | + public function setOutput( OutputPage $u ) { |
| 69 | + $this->output = $u; |
| 70 | + } |
| 71 | + |
| 72 | + /** |
64 | 73 | * Get the OutputPage object |
65 | 74 | * |
66 | 75 | * @return OutputPage object |
— | — | @@ -160,8 +169,8 @@ |
161 | 170 | * @return Message object |
162 | 171 | */ |
163 | 172 | public function msg() { |
164 | | - $args = function_get_args(); |
165 | | - return call_user_func_array( 'wfMessage', $args )->inLanguage( $this->getLang() )->outputPage( $this->getOut() ); |
| 173 | + $args = func_get_args(); |
| 174 | + return call_user_func_array( 'wfMessage', $args )->inLanguage( $this->getLang() ); |
166 | 175 | } |
167 | 176 | |
168 | 177 | /** Static methods **/ |
— | — | @@ -178,6 +187,5 @@ |
179 | 188 | } |
180 | 189 | return $instance; |
181 | 190 | } |
182 | | - |
183 | 191 | } |
184 | 192 | |
Index: trunk/phase3/includes/Wiki.php |
— | — | @@ -29,6 +29,18 @@ |
30 | 30 | private $output; |
31 | 31 | |
32 | 32 | /** |
| 33 | + * The Title we'll be working on |
| 34 | + * @var Title |
| 35 | + */ |
| 36 | + private $title; |
| 37 | + |
| 38 | + /** |
| 39 | + * TODO: fold $output, etc, into this |
| 40 | + * @var RequestContext |
| 41 | + */ |
| 42 | + private $context; |
| 43 | + |
| 44 | + /** |
33 | 45 | * Stores key/value pairs to circumvent global variables |
34 | 46 | * Note that keys are case-insensitive! |
35 | 47 | * |
— | — | @@ -67,26 +79,31 @@ |
68 | 80 | public function __construct( WebRequest &$request, /*OutputPage*/ &$output ){ |
69 | 81 | $this->request =& $request; |
70 | 82 | $this->output =& $output; |
| 83 | + $this->title = $this->parseTitle(); |
| 84 | + |
| 85 | + $this->context = new RequestContext(); |
| 86 | + $this->context->setRequest( $this->request ); |
| 87 | + $this->context->setOutput( $this->output ); |
| 88 | + $this->context->setTitle( $this->title ); |
71 | 89 | } |
72 | 90 | |
73 | 91 | /** |
74 | 92 | * Initialization of ... everything |
75 | 93 | * Performs the request too |
76 | 94 | * |
77 | | - * @param $title Title ($wgTitle) |
78 | 95 | * @param $article Article |
79 | 96 | * @param $user User |
80 | 97 | */ |
81 | | - public function performRequestForTitle( &$title, &$article, &$user ) { |
| 98 | + public function performRequestForTitle( &$article, &$user ) { |
82 | 99 | wfProfileIn( __METHOD__ ); |
83 | 100 | |
84 | | - $this->output->setTitle( $title ); |
| 101 | + $this->output->setTitle( $this->title ); |
85 | 102 | if ( $this->request->getVal( 'printable' ) === 'yes' ) { |
86 | 103 | $this->output->setPrintable(); |
87 | 104 | } |
88 | 105 | |
89 | 106 | wfRunHooks( 'BeforeInitialize', array( |
90 | | - &$title, |
| 107 | + &$this->title, |
91 | 108 | &$article, |
92 | 109 | &$this->output, |
93 | 110 | &$user, |
— | — | @@ -97,7 +114,7 @@ |
98 | 115 | // If the user is not logged in, the Namespace:title of the article must be in |
99 | 116 | // the Read array in order for the user to see it. (We have to check here to |
100 | 117 | // catch special pages etc. We check again in Article::view()) |
101 | | - if ( !is_null( $title ) && !$title->userCanRead() ) { |
| 118 | + if ( !is_null( $this->title ) && !$this->title->userCanRead() ) { |
102 | 119 | $this->output->loginToUse(); |
103 | 120 | $this->finalCleanup(); |
104 | 121 | $this->output->disable(); |
— | — | @@ -106,13 +123,13 @@ |
107 | 124 | } |
108 | 125 | |
109 | 126 | // Call handleSpecialCases() to deal with all special requests... |
110 | | - if ( !$this->handleSpecialCases( $title ) ) { |
| 127 | + if ( !$this->handleSpecialCases() ) { |
111 | 128 | // ...otherwise treat it as an article view. The article |
112 | 129 | // may be a redirect to another article or URL. |
113 | | - $new_article = $this->initializeArticle( $title ); |
| 130 | + $new_article = $this->initializeArticle(); |
114 | 131 | if ( is_object( $new_article ) ) { |
115 | 132 | $article = $new_article; |
116 | | - $this->performAction( $article, $title, $user ); |
| 133 | + $this->performAction( $article, $user ); |
117 | 134 | } elseif ( is_string( $new_article ) ) { |
118 | 135 | $this->output->redirect( $new_article ); |
119 | 136 | } else { |
— | — | @@ -124,12 +141,11 @@ |
125 | 142 | } |
126 | 143 | |
127 | 144 | /** |
128 | | - * Checks some initial queries |
129 | | - * FIXME: rename to parseTitle() ? |
| 145 | + * Parse $request to get the Title object |
130 | 146 | * |
131 | 147 | * @return Title object to be $wgTitle |
132 | 148 | */ |
133 | | - /* private */ function checkInitialQueries() { |
| 149 | + private function parseTitle() { |
134 | 150 | global $wgContLang; |
135 | 151 | |
136 | 152 | $curid = $this->request->getInt( 'curid' ); |
— | — | @@ -167,57 +183,67 @@ |
168 | 184 | } |
169 | 185 | |
170 | 186 | /** |
| 187 | + * Get the Title object that we'll be acting on, as specified in the WebRequest |
| 188 | + * @return Title |
| 189 | + */ |
| 190 | + public function getTitle(){ |
| 191 | + if( $this->title === null ){ |
| 192 | + $this->title = $this->parseTitle(); |
| 193 | + } |
| 194 | + return $this->title; |
| 195 | + } |
| 196 | + |
| 197 | + /** |
171 | 198 | * Initialize some special cases: |
172 | 199 | * - bad titles |
173 | 200 | * - local interwiki redirects |
174 | 201 | * - redirect loop |
175 | 202 | * - special pages |
176 | 203 | * |
177 | | - * @param $title Title |
178 | 204 | * @return bool true if the request is already executed |
179 | 205 | */ |
180 | | - private function handleSpecialCases( &$title ) { |
| 206 | + private function handleSpecialCases() { |
181 | 207 | wfProfileIn( __METHOD__ ); |
182 | 208 | |
183 | 209 | // Invalid titles. Bug 21776: The interwikis must redirect even if the page name is empty. |
184 | | - if ( is_null( $title ) || ( ( $title->getDBkey() == '' ) && ( $title->getInterwiki() == '' ) ) ) { |
185 | | - $title = SpecialPage::getTitleFor( 'Badtitle' ); |
186 | | - $this->output->setTitle( $title ); // bug 21456 |
| 210 | + if ( is_null( $this->title ) || ( ( $this->title->getDBkey() == '' ) && ( $this->title->getInterwiki() == '' ) ) ) { |
| 211 | + $this->title = SpecialPage::getTitleFor( 'Badtitle' ); |
| 212 | + $this->output->setTitle( $this->title ); // bug 21456 |
187 | 213 | // Die now before we mess up $wgArticle and the skin stops working |
188 | 214 | throw new ErrorPageError( 'badtitle', 'badtitletext' ); |
189 | 215 | |
190 | 216 | // Interwiki redirects |
191 | | - } else if ( $title->getInterwiki() != '' ) { |
| 217 | + } else if ( $this->title->getInterwiki() != '' ) { |
192 | 218 | $rdfrom = $this->request->getVal( 'rdfrom' ); |
193 | 219 | if ( $rdfrom ) { |
194 | | - $url = $title->getFullURL( 'rdfrom=' . urlencode( $rdfrom ) ); |
| 220 | + $url = $this->title->getFullURL( 'rdfrom=' . urlencode( $rdfrom ) ); |
195 | 221 | } else { |
196 | 222 | $query = $this->request->getValues(); |
197 | 223 | unset( $query['title'] ); |
198 | | - $url = $title->getFullURL( $query ); |
| 224 | + $url = $this->title->getFullURL( $query ); |
199 | 225 | } |
200 | 226 | /* Check for a redirect loop */ |
201 | | - if ( !preg_match( '/^' . preg_quote( $this->getVal( 'Server' ), '/' ) . '/', $url ) && $title->isLocal() ) { |
| 227 | + if ( !preg_match( '/^' . preg_quote( $this->getVal( 'Server' ), '/' ) . '/', $url ) && $this->title->isLocal() ) { |
202 | 228 | // 301 so google et al report the target as the actual url. |
203 | 229 | $this->output->redirect( $url, 301 ); |
204 | 230 | } else { |
205 | | - $title = SpecialPage::getTitleFor( 'Badtitle' ); |
206 | | - $this->output->setTitle( $title ); // bug 21456 |
| 231 | + $this->title = SpecialPage::getTitleFor( 'Badtitle' ); |
| 232 | + $this->output->setTitle( $this->title ); // bug 21456 |
207 | 233 | wfProfileOut( __METHOD__ ); |
208 | 234 | throw new ErrorPageError( 'badtitle', 'badtitletext' ); |
209 | 235 | } |
210 | 236 | // Redirect loops, no title in URL, $wgUsePathInfo URLs, and URLs with a variant |
211 | 237 | } else if ( $this->request->getVal( 'action', 'view' ) == 'view' && !$this->request->wasPosted() |
212 | | - && ( $this->request->getVal( 'title' ) === null || $title->getPrefixedDBKey() != $this->request->getVal( 'title' ) ) |
| 238 | + && ( $this->request->getVal( 'title' ) === null || $this->title->getPrefixedDBKey() != $this->request->getVal( 'title' ) ) |
213 | 239 | && !count( array_diff( array_keys( $this->request->getValues() ), array( 'action', 'title' ) ) ) ) |
214 | 240 | { |
215 | | - if ( $title->getNamespace() == NS_SPECIAL ) { |
216 | | - list( $name, $subpage ) = SpecialPage::resolveAliasWithSubpage( $title->getDBkey() ); |
| 241 | + if ( $this->title->getNamespace() == NS_SPECIAL ) { |
| 242 | + list( $name, $subpage ) = SpecialPage::resolveAliasWithSubpage( $this->title->getDBkey() ); |
217 | 243 | if ( $name ) { |
218 | | - $title = SpecialPage::getTitleFor( $name, $subpage ); |
| 244 | + $this->title = SpecialPage::getTitleFor( $name, $subpage ); |
219 | 245 | } |
220 | 246 | } |
221 | | - $targetUrl = $title->getFullURL(); |
| 247 | + $targetUrl = $this->title->getFullURL(); |
222 | 248 | // Redirect to canonical url, make it a 301 to allow caching |
223 | 249 | if ( $targetUrl == $this->request->getFullRequestURL() ) { |
224 | 250 | $message = "Redirect loop detected!\n\n" . |
— | — | @@ -247,9 +273,9 @@ |
248 | 274 | $this->output->redirect( $targetUrl, '301' ); |
249 | 275 | } |
250 | 276 | // Special pages |
251 | | - } else if ( NS_SPECIAL == $title->getNamespace() ) { |
| 277 | + } else if ( NS_SPECIAL == $this->title->getNamespace() ) { |
252 | 278 | /* actions that need to be made when we have a special pages */ |
253 | | - SpecialPage::executePath( $title ); |
| 279 | + SpecialPage::executePath( $this->title, $this->context ); |
254 | 280 | } else { |
255 | 281 | /* No match to special cases */ |
256 | 282 | wfProfileOut( __METHOD__ ); |
— | — | @@ -326,23 +352,22 @@ |
327 | 353 | * Initialize the object to be known as $wgArticle for "standard" actions |
328 | 354 | * Create an Article object for the page, following redirects if needed. |
329 | 355 | * |
330 | | - * @param $title Title ($wgTitle) |
331 | 356 | * @return mixed an Article, or a string to redirect to another URL |
332 | 357 | */ |
333 | | - private function initializeArticle( &$title ) { |
| 358 | + private function initializeArticle() { |
334 | 359 | wfProfileIn( __METHOD__ ); |
335 | 360 | |
336 | 361 | $action = $this->request->getVal( 'action', 'view' ); |
337 | | - $article = self::articleFromTitle( $title ); |
| 362 | + $article = self::articleFromTitle( $this->title ); |
338 | 363 | // NS_MEDIAWIKI has no redirects. |
339 | 364 | // It is also used for CSS/JS, so performance matters here... |
340 | | - if ( $title->getNamespace() == NS_MEDIAWIKI ) { |
| 365 | + if ( $this->title->getNamespace() == NS_MEDIAWIKI ) { |
341 | 366 | wfProfileOut( __METHOD__ ); |
342 | 367 | return $article; |
343 | 368 | } |
344 | 369 | // Namespace might change when using redirects |
345 | 370 | // Check for redirects ... |
346 | | - $file = ( $title->getNamespace() == NS_FILE ) ? $article->getFile() : null; |
| 371 | + $file = ( $this->title->getNamespace() == NS_FILE ) ? $article->getFile() : null; |
347 | 372 | if ( ( $action == 'view' || $action == 'render' ) // ... for actions that show content |
348 | 373 | && !$this->request->getVal( 'oldid' ) && // ... and are not old revisions |
349 | 374 | !$this->request->getVal( 'diff' ) && // ... and not when showing diff |
— | — | @@ -354,7 +379,7 @@ |
355 | 380 | $ignoreRedirect = $target = false; |
356 | 381 | |
357 | 382 | wfRunHooks( 'InitializeArticleMaybeRedirect', |
358 | | - array( &$title, &$this->request, &$ignoreRedirect, &$target, &$article ) ); |
| 383 | + array( &$this->title, &$this->request, &$ignoreRedirect, &$target, &$article ) ); |
359 | 384 | |
360 | 385 | // Follow redirects only for... redirects. |
361 | 386 | // If $target is set, then a hook wanted to redirect. |
— | — | @@ -373,14 +398,14 @@ |
374 | 399 | $rarticle = self::articleFromTitle( $target ); |
375 | 400 | $rarticle->loadPageData(); |
376 | 401 | if ( $rarticle->exists() || ( is_object( $file ) && !$file->isLocal() ) ) { |
377 | | - $rarticle->setRedirectedFrom( $title ); |
| 402 | + $rarticle->setRedirectedFrom( $this->title ); |
378 | 403 | $article = $rarticle; |
379 | | - $title = $target; |
380 | | - $this->output->setTitle( $title ); |
| 404 | + $this->title = $target; |
| 405 | + $this->output->setTitle( $this->title ); |
381 | 406 | } |
382 | 407 | } |
383 | 408 | } else { |
384 | | - $title = $article->getTitle(); |
| 409 | + $this->title = $article->getTitle(); |
385 | 410 | } |
386 | 411 | } |
387 | 412 | wfProfileOut( __METHOD__ ); |
— | — | @@ -457,13 +482,15 @@ |
458 | 483 | * Perform one of the "standard" actions |
459 | 484 | * |
460 | 485 | * @param $article Article |
461 | | - * @param $title Title |
462 | 486 | * @param $user User |
463 | 487 | */ |
464 | | - private function performAction( &$article, &$title, &$user ) { |
| 488 | + private function performAction( &$article, &$user ) { |
465 | 489 | wfProfileIn( __METHOD__ ); |
466 | 490 | |
467 | | - if ( !wfRunHooks( 'MediaWikiPerformAction', array( $this->output, $article, $title, $user, $this->request, $this ) ) ) { |
| 491 | + if ( !wfRunHooks( 'MediaWikiPerformAction', array( |
| 492 | + $this->output, $article, $this->title, |
| 493 | + $user, $this->request, $this ) ) ) |
| 494 | + { |
468 | 495 | wfProfileOut( __METHOD__ ); |
469 | 496 | return; |
470 | 497 | } |
— | — | @@ -541,7 +568,7 @@ |
542 | 569 | } |
543 | 570 | break; |
544 | 571 | case 'history': |
545 | | - if ( $this->request->getFullRequestURL() == $title->getInternalURL( 'action=history' ) ) { |
| 572 | + if ( $this->request->getFullRequestURL() == $this->title->getInternalURL( 'action=history' ) ) { |
546 | 573 | $this->output->setSquidMaxage( $this->getVal( 'SquidMaxage' ) ); |
547 | 574 | } |
548 | 575 | $history = new HistoryPage( $article ); |