Index: trunk/phase3/includes/api/ApiQueryAllLinks.php |
— | — | @@ -43,6 +43,10 @@ |
44 | 44 | $this->run(); |
45 | 45 | } |
46 | 46 | |
| 47 | + public function getCacheMode( $params ) { |
| 48 | + return 'public'; |
| 49 | + } |
| 50 | + |
47 | 51 | public function executeGenerator( $resultPageSet ) { |
48 | 52 | $this->run( $resultPageSet ); |
49 | 53 | } |
— | — | @@ -221,4 +225,4 @@ |
222 | 226 | public function getVersion() { |
223 | 227 | return __CLASS__ . ': $Id$'; |
224 | 228 | } |
225 | | -} |
\ No newline at end of file |
| 229 | +} |
Index: trunk/phase3/includes/api/ApiQueryRecentChanges.php |
— | — | @@ -143,7 +143,6 @@ |
144 | 144 | // Check permissions |
145 | 145 | global $wgUser; |
146 | 146 | if ( isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ) { |
147 | | - $this->getMain()->setVaryCookie(); |
148 | 147 | if ( !$wgUser->useRCPatrol() && !$wgUser->useNPPatrol() ) { |
149 | 148 | $this->dieUsage( 'You need the patrol right to request the patrolled flag', 'permissiondenied' ); |
150 | 149 | } |
— | — | @@ -376,7 +375,6 @@ |
377 | 376 | |
378 | 377 | if ( $this->fld_parsedcomment && isset( $row->rc_comment ) ) { |
379 | 378 | global $wgUser; |
380 | | - $this->getMain()->setVaryCookie(); |
381 | 379 | $vals['parsedcomment'] = $wgUser->getSkin()->formatComment( $row->rc_comment, $title ); |
382 | 380 | } |
383 | 381 | |
— | — | @@ -413,9 +411,6 @@ |
414 | 412 | } |
415 | 413 | |
416 | 414 | if ( !is_null( $this->token ) ) { |
417 | | - // Don't cache tokens |
418 | | - $this->getMain()->setCachePrivate(); |
419 | | - |
420 | 415 | $tokenFunctions = $this->getTokenFunctions(); |
421 | 416 | foreach ( $this->token as $t ) { |
422 | 417 | $val = call_user_func( $tokenFunctions[$t], $row->rc_cur_id, |
— | — | @@ -449,6 +444,24 @@ |
450 | 445 | } |
451 | 446 | } |
452 | 447 | |
| 448 | + public function getCacheMode( $params ) { |
| 449 | + if ( isset( $params['show'] ) ) { |
| 450 | + foreach ( $params['show'] as $show ) { |
| 451 | + if ( $show === 'patrolled' || $show === '!patrolled' ) { |
| 452 | + return 'private'; |
| 453 | + } |
| 454 | + } |
| 455 | + } |
| 456 | + if ( isset( $params['token'] ) ) { |
| 457 | + return 'private'; |
| 458 | + } |
| 459 | + if ( !is_null( $params['prop'] ) && in_array( 'parsedcomment', $params['prop'] ) ) { |
| 460 | + // formatComment() calls wfMsg() among other things |
| 461 | + return 'anon-public-user-private'; |
| 462 | + } |
| 463 | + return 'public'; |
| 464 | + } |
| 465 | + |
453 | 466 | public function getAllowedParams() { |
454 | 467 | return array( |
455 | 468 | 'start' => array( |
Index: trunk/phase3/includes/api/ApiQueryAllCategories.php |
— | — | @@ -44,6 +44,10 @@ |
45 | 45 | $this->run(); |
46 | 46 | } |
47 | 47 | |
| 48 | + public function getCacheMode( $params ) { |
| 49 | + return 'public'; |
| 50 | + } |
| 51 | + |
48 | 52 | public function executeGenerator( $resultPageSet ) { |
49 | 53 | $this->run( $resultPageSet ); |
50 | 54 | } |
— | — | @@ -179,4 +183,4 @@ |
180 | 184 | public function getVersion() { |
181 | 185 | return __CLASS__ . ': $Id$'; |
182 | 186 | } |
183 | | -} |
\ No newline at end of file |
| 187 | +} |
Index: trunk/phase3/includes/api/ApiWatch.php |
— | — | @@ -41,7 +41,6 @@ |
42 | 42 | |
43 | 43 | public function execute() { |
44 | 44 | global $wgUser; |
45 | | - $this->getMain()->setCachePrivate(); |
46 | 45 | if ( !$wgUser->isLoggedIn() ) { |
47 | 46 | $this->dieUsage( 'You must be logged-in to have a watchlist', 'notloggedin' ); |
48 | 47 | } |
Index: trunk/phase3/includes/api/ApiQueryLinks.php |
— | — | @@ -65,6 +65,10 @@ |
66 | 66 | $this->run(); |
67 | 67 | } |
68 | 68 | |
| 69 | + public function getCacheMode( $params ) { |
| 70 | + return 'public'; |
| 71 | + } |
| 72 | + |
69 | 73 | public function executeGenerator( $resultPageSet ) { |
70 | 74 | $this->run( $resultPageSet ); |
71 | 75 | } |
— | — | @@ -232,4 +236,4 @@ |
233 | 237 | public function getVersion() { |
234 | 238 | return __CLASS__ . ': $Id$'; |
235 | 239 | } |
236 | | -} |
\ No newline at end of file |
| 240 | +} |
Index: trunk/phase3/includes/api/ApiQueryRandom.php |
— | — | @@ -119,6 +119,10 @@ |
120 | 120 | return $vals; |
121 | 121 | } |
122 | 122 | |
| 123 | + public function getCacheMode( $params ) { |
| 124 | + return 'public'; |
| 125 | + } |
| 126 | + |
123 | 127 | public function getAllowedParams() { |
124 | 128 | return array( |
125 | 129 | 'namespace' => array( |
— | — | @@ -160,4 +164,4 @@ |
161 | 165 | public function getVersion() { |
162 | 166 | return __CLASS__ . ': $Id: ApiQueryRandom.php overlordq$'; |
163 | 167 | } |
164 | | -} |
\ No newline at end of file |
| 168 | +} |
Index: trunk/phase3/includes/api/ApiQuerySiteinfo.php |
— | — | @@ -427,6 +427,10 @@ |
428 | 428 | return $this->getResult()->addValue( 'query', $property, $data ); |
429 | 429 | } |
430 | 430 | |
| 431 | + public function getCacheMode( $params ) { |
| 432 | + return 'public'; |
| 433 | + } |
| 434 | + |
431 | 435 | public function getAllowedParams() { |
432 | 436 | return array( |
433 | 437 | 'prop' => array( |
Index: trunk/phase3/includes/api/ApiLogout.php |
— | — | @@ -42,7 +42,6 @@ |
43 | 43 | |
44 | 44 | public function execute() { |
45 | 45 | global $wgUser; |
46 | | - $this->getMain()->setCachePrivate(); |
47 | 46 | $oldName = $wgUser->getName(); |
48 | 47 | $wgUser->logout(); |
49 | 48 | |
Index: trunk/phase3/includes/api/ApiParse.php |
— | — | @@ -38,6 +38,9 @@ |
39 | 39 | } |
40 | 40 | |
41 | 41 | public function execute() { |
| 42 | + // The data is hot but user-dependent, like page views, so we set vary cookies |
| 43 | + $this->getMain()->setCacheMode( 'anon-public-user-private' ); |
| 44 | + |
42 | 45 | // Get parameters |
43 | 46 | $params = $this->extractRequestParams(); |
44 | 47 | $text = $params['text']; |
— | — | @@ -161,7 +164,6 @@ |
162 | 165 | |
163 | 166 | if ( $params['pst'] || $params['onlypst'] ) { |
164 | 167 | $text = $wgParser->preSaveTransform( $text, $titleObj, $wgUser, $popts ); |
165 | | - $this->getMain()->setVaryCookie(); |
166 | 168 | } |
167 | 169 | if ( $params['onlypst'] ) { |
168 | 170 | // Build a result and bail out |
— | — | @@ -187,7 +189,6 @@ |
188 | 190 | |
189 | 191 | if ( !is_null( $params['summary'] ) ) { |
190 | 192 | $result_array['parsedsummary'] = array(); |
191 | | - $this->getMain()->setVaryCookie(); |
192 | 193 | $result->setContent( $result_array['parsedsummary'], $wgUser->getSkin()->formatComment( $params['summary'], $titleObj ) ); |
193 | 194 | } |
194 | 195 | |
— | — | @@ -222,7 +223,6 @@ |
223 | 224 | if ( isset( $prop['headitems'] ) || isset( $prop['headhtml'] ) ) { |
224 | 225 | $out = new OutputPage; |
225 | 226 | $out->addParserOutputNoText( $p_result ); |
226 | | - $this->getMain()->setVaryCookie(); |
227 | 227 | $userSkin = $wgUser->getSkin(); |
228 | 228 | } |
229 | 229 | |
— | — | @@ -468,4 +468,4 @@ |
469 | 469 | public function getVersion() { |
470 | 470 | return __CLASS__ . ': $Id$'; |
471 | 471 | } |
472 | | -} |
\ No newline at end of file |
| 472 | +} |
Index: trunk/phase3/includes/api/ApiQueryExtLinksUsage.php |
— | — | @@ -41,6 +41,10 @@ |
42 | 42 | $this->run(); |
43 | 43 | } |
44 | 44 | |
| 45 | + public function getCacheMode( $params ) { |
| 46 | + return 'public'; |
| 47 | + } |
| 48 | + |
45 | 49 | public function executeGenerator( $resultPageSet ) { |
46 | 50 | $this->run( $resultPageSet ); |
47 | 51 | } |
— | — | @@ -226,4 +230,4 @@ |
227 | 231 | public function getVersion() { |
228 | 232 | return __CLASS__ . ': $Id$'; |
229 | 233 | } |
230 | | -} |
\ No newline at end of file |
| 234 | +} |
Index: trunk/phase3/includes/api/ApiQueryAllpages.php |
— | — | @@ -43,6 +43,10 @@ |
44 | 44 | $this->run(); |
45 | 45 | } |
46 | 46 | |
| 47 | + public function getCacheMode( $params ) { |
| 48 | + return 'public'; |
| 49 | + } |
| 50 | + |
47 | 51 | public function executeGenerator( $resultPageSet ) { |
48 | 52 | if ( $resultPageSet->isResolvingRedirects() ) { |
49 | 53 | $this->dieUsage( 'Use "gapfilterredir=nonredirects" option instead of "redirects" when using allpages as a generator', 'params' ); |
Index: trunk/phase3/includes/api/ApiPurge.php |
— | — | @@ -42,7 +42,6 @@ |
43 | 43 | */ |
44 | 44 | public function execute() { |
45 | 45 | global $wgUser; |
46 | | - $this->getMain()->setCachePrivate(); |
47 | 46 | $params = $this->extractRequestParams(); |
48 | 47 | if ( !$wgUser->isAllowed( 'purge' ) ) { |
49 | 48 | $this->dieUsageMsg( array( 'cantpurge' ) ); |
Index: trunk/phase3/includes/api/ApiQueryBacklinks.php |
— | — | @@ -92,6 +92,10 @@ |
93 | 93 | $this->run(); |
94 | 94 | } |
95 | 95 | |
| 96 | + public function getCacheMode( $params ) { |
| 97 | + return 'public'; |
| 98 | + } |
| 99 | + |
96 | 100 | public function executeGenerator( $resultPageSet ) { |
97 | 101 | $this->run( $resultPageSet ); |
98 | 102 | } |
Index: trunk/phase3/includes/api/ApiQueryDeletedrevs.php |
— | — | @@ -41,7 +41,6 @@ |
42 | 42 | |
43 | 43 | public function execute() { |
44 | 44 | global $wgUser; |
45 | | - $this->getMain()->setVaryCookie(); |
46 | 45 | // Before doing anything at all, let's check permissions |
47 | 46 | if ( !$wgUser->isAllowed( 'deletedhistory' ) ) { |
48 | 47 | $this->dieUsage( 'You don\'t have permission to view deleted revision information', 'permissiondenied' ); |
— | — | @@ -210,7 +209,6 @@ |
211 | 210 | |
212 | 211 | if ( $fld_parsedcomment ) { |
213 | 212 | global $wgUser; |
214 | | - $this->getMain()->setVaryCookie(); |
215 | 213 | $rev['parsedcomment'] = $wgUser->getSkin()->formatComment( $row->ar_comment, $title ); |
216 | 214 | } |
217 | 215 | if ( $fld_minor && $row->ar_minor_edit == 1 ) { |
— | — | @@ -367,4 +365,4 @@ |
368 | 366 | public function getVersion() { |
369 | 367 | return __CLASS__ . ': $Id$'; |
370 | 368 | } |
371 | | -} |
\ No newline at end of file |
| 369 | +} |
Index: trunk/phase3/includes/api/ApiExpandTemplates.php |
— | — | @@ -42,6 +42,9 @@ |
43 | 43 | } |
44 | 44 | |
45 | 45 | public function execute() { |
| 46 | + // Cache may vary on $wgUser because ParserOptions gets data from it |
| 47 | + $this->getMain()->setCacheMode( 'anon-public-user-private' ); |
| 48 | + |
46 | 49 | // Get parameters |
47 | 50 | $params = $this->extractRequestParams(); |
48 | 51 | |
Index: trunk/phase3/includes/api/ApiQueryBase.php |
— | — | @@ -47,6 +47,17 @@ |
48 | 48 | } |
49 | 49 | |
50 | 50 | /** |
| 51 | + * Get the cache mode for the data generated by this module. Override this |
| 52 | + * in the module subclass. |
| 53 | + * |
| 54 | + * Public caching will only be allowed if *all* the modules that supply |
| 55 | + * data for a given request return a cache mode of public. |
| 56 | + */ |
| 57 | + public function getCacheMode( $params ) { |
| 58 | + return 'private'; |
| 59 | + } |
| 60 | + |
| 61 | + /** |
51 | 62 | * Blank the internal arrays with query parameters |
52 | 63 | */ |
53 | 64 | protected function resetQueryParams() { |
Index: trunk/phase3/includes/api/ApiQueryBlocks.php |
— | — | @@ -125,8 +125,6 @@ |
126 | 126 | ) ); |
127 | 127 | } |
128 | 128 | |
129 | | - // Make sure private data (deleted blocks) isn't cached |
130 | | - $this->getMain()->setVaryCookie(); |
131 | 129 | if ( !$wgUser->isAllowed( 'hideuser' ) ) { |
132 | 130 | $this->addWhereFld( 'ipb_deleted', 0 ); |
133 | 131 | } |
— | — | @@ -308,4 +306,4 @@ |
309 | 307 | public function getVersion() { |
310 | 308 | return __CLASS__ . ': $Id$'; |
311 | 309 | } |
312 | | -} |
\ No newline at end of file |
| 310 | +} |
Index: trunk/phase3/includes/api/ApiQueryFilearchive.php |
— | — | @@ -43,7 +43,6 @@ |
44 | 44 | |
45 | 45 | public function execute() { |
46 | 46 | global $wgUser; |
47 | | - $this->getMain()->setVaryCookie(); |
48 | 47 | // Before doing anything at all, let's check permissions |
49 | 48 | if ( !$wgUser->isAllowed( 'deletedhistory' ) ) { |
50 | 49 | $this->dieUsage( 'You don\'t have permission to view deleted file information', 'permissiondenied' ); |
Index: trunk/phase3/includes/api/ApiQueryCategoryMembers.php |
— | — | @@ -43,6 +43,10 @@ |
44 | 44 | $this->run(); |
45 | 45 | } |
46 | 46 | |
| 47 | + public function getCacheMode( $params ) { |
| 48 | + return 'public'; |
| 49 | + } |
| 50 | + |
47 | 51 | public function executeGenerator( $resultPageSet ) { |
48 | 52 | $this->run( $resultPageSet ); |
49 | 53 | } |
Index: trunk/phase3/includes/api/ApiQueryCategoryInfo.php |
— | — | @@ -94,6 +94,10 @@ |
95 | 95 | } |
96 | 96 | } |
97 | 97 | |
| 98 | + public function getCacheMode( $params ) { |
| 99 | + return 'public'; |
| 100 | + } |
| 101 | + |
98 | 102 | public function getAllowedParams() { |
99 | 103 | return array( |
100 | 104 | 'continue' => null, |
— | — | @@ -117,4 +121,4 @@ |
118 | 122 | public function getVersion() { |
119 | 123 | return __CLASS__ . ': $Id$'; |
120 | 124 | } |
121 | | -} |
\ No newline at end of file |
| 125 | +} |
Index: trunk/phase3/includes/api/ApiQueryAllimages.php |
— | — | @@ -55,6 +55,10 @@ |
56 | 56 | $this->run(); |
57 | 57 | } |
58 | 58 | |
| 59 | + public function getCacheMode( $params ) { |
| 60 | + return 'public'; |
| 61 | + } |
| 62 | + |
59 | 63 | public function executeGenerator( $resultPageSet ) { |
60 | 64 | if ( $resultPageSet->isResolvingRedirects() ) { |
61 | 65 | $this->dieUsage( 'Use "gaifilterredir=nonredirects" option instead of "redirects" when using allimages as a generator', 'params' ); |
Index: trunk/phase3/includes/api/ApiQueryAllmessages.php |
— | — | @@ -45,12 +45,9 @@ |
46 | 46 | global $wgLang; |
47 | 47 | |
48 | 48 | $oldLang = null; |
49 | | - if ( !is_null( $params['lang'] ) && $params['lang'] != $wgLang->getCode() ) { |
| 49 | + if ( !is_null( $params['lang'] ) ) { |
50 | 50 | $oldLang = $wgLang; // Keep $wgLang for restore later |
51 | 51 | $wgLang = Language::factory( $params['lang'] ); |
52 | | - } else if ( is_null( $params['lang'] ) ) { |
53 | | - // Language not determined by URL but by user preferences, so don't cache |
54 | | - $this->getMain()->setVaryCookie(); |
55 | 52 | } |
56 | 53 | |
57 | 54 | $prop = array_flip( (array)$params['prop'] ); |
— | — | @@ -131,6 +128,19 @@ |
132 | 129 | } |
133 | 130 | } |
134 | 131 | |
| 132 | + public function getCacheMode( $params ) { |
| 133 | + if ( is_null( $params['lang'] ) ) { |
| 134 | + // Language not specified, will be fetched from preferences |
| 135 | + return 'anon-public-user-private'; |
| 136 | + } elseif ( $params['enableparser'] ) { |
| 137 | + // User-specific parser options will be used |
| 138 | + return 'anon-public-user-private'; |
| 139 | + } else { |
| 140 | + // OK to cache |
| 141 | + return 'public'; |
| 142 | + } |
| 143 | + } |
| 144 | + |
135 | 145 | public function getAllowedParams() { |
136 | 146 | return array( |
137 | 147 | 'messages' => array( |
Index: trunk/phase3/includes/api/ApiQuerySearch.php |
— | — | @@ -164,6 +164,10 @@ |
165 | 165 | } |
166 | 166 | } |
167 | 167 | |
| 168 | + public function getCacheMode( $params ) { |
| 169 | + return 'public'; |
| 170 | + } |
| 171 | + |
168 | 172 | public function getAllowedParams() { |
169 | 173 | return array( |
170 | 174 | 'search' => null, |
Index: trunk/phase3/includes/api/ApiQueryLogEvents.php |
— | — | @@ -282,7 +282,6 @@ |
283 | 283 | |
284 | 284 | if ( $this->fld_parsedcomment ) { |
285 | 285 | global $wgUser; |
286 | | - $this->getMain()->setVaryCookie(); |
287 | 286 | $vals['parsedcomment'] = $wgUser->getSkin()->formatComment( $row->log_comment, $title ); |
288 | 287 | } |
289 | 288 | } |
— | — | @@ -301,6 +300,15 @@ |
302 | 301 | return $vals; |
303 | 302 | } |
304 | 303 | |
| 304 | + public function getCacheMode( $params ) { |
| 305 | + if ( !is_null( $params['prop'] ) && in_array( 'parsedcomment', $params['prop'] ) ) { |
| 306 | + // formatComment() calls wfMsg() among other things |
| 307 | + return 'anon-public-user-private'; |
| 308 | + } else { |
| 309 | + return 'public'; |
| 310 | + } |
| 311 | + } |
| 312 | + |
305 | 313 | public function getAllowedParams() { |
306 | 314 | global $wgLogTypes, $wgLogActions; |
307 | 315 | return array( |
Index: trunk/phase3/includes/api/ApiQueryProtectedTitles.php |
— | — | @@ -101,7 +101,6 @@ |
102 | 102 | |
103 | 103 | if ( isset( $prop['parsedcomment'] ) ) { |
104 | 104 | global $wgUser; |
105 | | - $this->getMain()->setVaryCookie(); |
106 | 105 | $vals['parsedcomment'] = $wgUser->getSkin()->formatComment( $row->pt_reason, $title ); |
107 | 106 | } |
108 | 107 | |
— | — | @@ -131,6 +130,15 @@ |
132 | 131 | } |
133 | 132 | } |
134 | 133 | |
| 134 | + public function getCacheMode( $params ) { |
| 135 | + if ( !is_null( $params['prop'] ) && in_array( 'parsedcomment', $params['prop'] ) ) { |
| 136 | + // formatComment() calls wfMsg() among other things |
| 137 | + return 'anon-public-user-private'; |
| 138 | + } else { |
| 139 | + return 'public'; |
| 140 | + } |
| 141 | + } |
| 142 | + |
135 | 143 | public function getAllowedParams() { |
136 | 144 | global $wgRestrictionLevels; |
137 | 145 | return array( |
— | — | @@ -210,4 +218,4 @@ |
211 | 219 | public function getVersion() { |
212 | 220 | return __CLASS__ . ': $Id$'; |
213 | 221 | } |
214 | | -} |
\ No newline at end of file |
| 222 | +} |
Index: trunk/phase3/includes/api/ApiQuery.php |
— | — | @@ -232,9 +232,15 @@ |
233 | 233 | $this->instantiateModules( $modules, 'list', $this->mQueryListModules ); |
234 | 234 | $this->instantiateModules( $modules, 'meta', $this->mQueryMetaModules ); |
235 | 235 | |
| 236 | + $cacheMode = 'public'; |
| 237 | + |
236 | 238 | // If given, execute generator to substitute user supplied data with generated data. |
237 | 239 | if ( isset( $this->params['generator'] ) ) { |
238 | | - $this->executeGeneratorModule( $this->params['generator'], $modules ); |
| 240 | + $generator = $this->newGenerator( $this->params['generator'] ); |
| 241 | + $params = $generator->extractRequestParams(); |
| 242 | + $cacheMode = $this->mergeCacheMode( $cacheMode, |
| 243 | + $generator->getCacheMode( $params ) ); |
| 244 | + $this->executeGeneratorModule( $generator, $modules ); |
239 | 245 | } else { |
240 | 246 | // Append custom fields and populate page/revision information |
241 | 247 | $this->addCustomFldsToPageSet( $modules, $this->mPageSet ); |
— | — | @@ -246,14 +252,38 @@ |
247 | 253 | |
248 | 254 | // Execute all requested modules. |
249 | 255 | foreach ( $modules as $module ) { |
| 256 | + $params = $module->extractRequestParams(); |
| 257 | + $cacheMode = $this->mergeCacheMode( |
| 258 | + $cacheMode, $module->getCacheMode( $params ) ); |
250 | 259 | $module->profileIn(); |
251 | 260 | $module->execute(); |
252 | 261 | wfRunHooks( 'APIQueryAfterExecute', array( &$module ) ); |
253 | 262 | $module->profileOut(); |
254 | 263 | } |
| 264 | + |
| 265 | + // Set the cache mode |
| 266 | + $this->getMain()->setCacheMode( $cacheMode ); |
255 | 267 | } |
256 | 268 | |
257 | 269 | /** |
| 270 | + * Update a cache mode string, applying the cache mode of a new module to it. |
| 271 | + * The cache mode may increase in the level of privacy, but public modules |
| 272 | + * added to private data do not decrease the level of privacy. |
| 273 | + */ |
| 274 | + protected function mergeCacheMode( $cacheMode, $modCacheMode ) { |
| 275 | + if ( $modCacheMode === 'anon-public-user-private' ) { |
| 276 | + if ( $cacheMode !== 'private' ) { |
| 277 | + $cacheMode = 'anon-public-user-private'; |
| 278 | + } |
| 279 | + } elseif ( $modCacheMode === 'public' ) { |
| 280 | + // do nothing, if it's public already it will stay public |
| 281 | + } else { // private |
| 282 | + $cacheMode = 'private'; |
| 283 | + } |
| 284 | + return $cacheMode; |
| 285 | + } |
| 286 | + |
| 287 | + /** |
258 | 288 | * Query modules may optimize data requests through the $this->getPageSet() object |
259 | 289 | * by adding extra fields from the page table. |
260 | 290 | * This function will gather all the extra request fields from the modules. |
— | — | @@ -458,12 +488,9 @@ |
459 | 489 | } |
460 | 490 | |
461 | 491 | /** |
462 | | - * For generator mode, execute generator, and use its output as new |
463 | | - * ApiPageSet |
464 | | - * @param $generatorName string Module name |
465 | | - * @param $modules array of module objects |
| 492 | + * Create a generator object of the given type and return it |
466 | 493 | */ |
467 | | - protected function executeGeneratorModule( $generatorName, $modules ) { |
| 494 | + public function newGenerator( $generatorName ) { |
468 | 495 | // Find class that implements requested generator |
469 | 496 | if ( isset( $this->mQueryListModules[$generatorName] ) ) { |
470 | 497 | $className = $this->mQueryListModules[$generatorName]; |
— | — | @@ -472,18 +499,24 @@ |
473 | 500 | } else { |
474 | 501 | ApiBase::dieDebug( __METHOD__, "Unknown generator=$generatorName" ); |
475 | 502 | } |
476 | | - |
477 | | - // Generator results |
478 | | - $resultPageSet = new ApiPageSet( $this, $this->redirects, $this->convertTitles ); |
479 | | - |
480 | | - // Create and execute the generator |
481 | 503 | $generator = new $className ( $this, $generatorName ); |
482 | 504 | if ( !$generator instanceof ApiQueryGeneratorBase ) { |
483 | 505 | $this->dieUsage( "Module $generatorName cannot be used as a generator", 'badgenerator' ); |
484 | 506 | } |
485 | | - |
486 | 507 | $generator->setGeneratorMode(); |
| 508 | + return $generator; |
| 509 | + } |
487 | 510 | |
| 511 | + /** |
| 512 | + * For generator mode, execute generator, and use its output as new |
| 513 | + * ApiPageSet |
| 514 | + * @param $generatorName string Module name |
| 515 | + * @param $modules array of module objects |
| 516 | + */ |
| 517 | + protected function executeGeneratorModule( $generator, $modules ) { |
| 518 | + // Generator results |
| 519 | + $resultPageSet = new ApiPageSet( $this, $this->redirects, $this->convertTitles ); |
| 520 | + |
488 | 521 | // Add any additional fields modules may need |
489 | 522 | $generator->requestExtraData( $this->mPageSet ); |
490 | 523 | $this->addCustomFldsToPageSet( $modules, $resultPageSet ); |
Index: trunk/phase3/includes/api/ApiQueryIWLinks.php |
— | — | @@ -108,6 +108,10 @@ |
109 | 109 | } |
110 | 110 | } |
111 | 111 | |
| 112 | + public function getCacheMode( $params ) { |
| 113 | + return 'public'; |
| 114 | + } |
| 115 | + |
112 | 116 | public function getAllowedParams() { |
113 | 117 | return array( |
114 | 118 | 'url' => null, |
— | — | @@ -150,4 +154,4 @@ |
151 | 155 | public function getVersion() { |
152 | 156 | return __CLASS__ . ': $Id$'; |
153 | 157 | } |
154 | | -} |
\ No newline at end of file |
| 158 | +} |
Index: trunk/phase3/includes/api/ApiQueryLangLinks.php |
— | — | @@ -95,6 +95,10 @@ |
96 | 96 | } |
97 | 97 | } |
98 | 98 | |
| 99 | + public function getCacheMode( $params ) { |
| 100 | + return 'public'; |
| 101 | + } |
| 102 | + |
99 | 103 | public function getAllowedParams() { |
100 | 104 | return array( |
101 | 105 | 'limit' => array( |
— | — | @@ -135,4 +139,4 @@ |
136 | 140 | public function getVersion() { |
137 | 141 | return __CLASS__ . ': $Id$'; |
138 | 142 | } |
139 | | -} |
\ No newline at end of file |
| 143 | +} |
Index: trunk/phase3/includes/api/ApiQueryUserInfo.php |
— | — | @@ -40,7 +40,6 @@ |
41 | 41 | } |
42 | 42 | |
43 | 43 | public function execute() { |
44 | | - $this->getMain()->setCachePrivate(); |
45 | 44 | $params = $this->extractRequestParams(); |
46 | 45 | $result = $this->getResult(); |
47 | 46 | $r = array(); |
Index: trunk/phase3/includes/api/ApiMain.php |
— | — | @@ -126,7 +126,8 @@ |
127 | 127 | private $mResult, $mAction, $mShowVersions, $mEnableWrite, $mRequest; |
128 | 128 | private $mInternalMode, $mSquidMaxage, $mModule, $mVaryCookie; |
129 | 129 | |
130 | | - private $mCacheControl = array( 'must-revalidate' => true ); |
| 130 | + private $mCacheMode = 'private'; |
| 131 | + private $mCacheControl = array(); |
131 | 132 | |
132 | 133 | /** |
133 | 134 | * Constructs an instance of ApiMain that utilizes the module and format specified by $request. |
— | — | @@ -216,19 +217,67 @@ |
217 | 218 | 's-maxage' => $maxage |
218 | 219 | ) ); |
219 | 220 | } |
| 221 | + |
| 222 | + /** |
| 223 | + * Set the type of caching headers which will be sent. |
| 224 | + * |
| 225 | + * @param $mode One of: |
| 226 | + * - 'public': Cache this object in public caches, if the maxage or smaxage |
| 227 | + * parameter is set, or if setCacheMaxAge() was called. If a maximum age is |
| 228 | + * not provided by any of these means, the object will be private. |
| 229 | + * - 'private': Cache this object only in private client-side caches. |
| 230 | + * - 'anon-public-user-private': Make this object cacheable for logged-out |
| 231 | + * users, but private for logged-in users. IMPORTANT: If this is set, it must be |
| 232 | + * set consistently for a given URL, it cannot be set differently depending on |
| 233 | + * things like the contents of the database, or whether the user is logged in. |
| 234 | + * |
| 235 | + * If the wiki does not allow anonymous users to read it, the mode set here |
| 236 | + * will be ignored, and private caching headers will always be sent. In other words, |
| 237 | + * the "public" mode is equivalent to saying that the data sent is as public as a page |
| 238 | + * view. |
| 239 | + * |
| 240 | + * For user-dependent data, the private mode should generally be used. The |
| 241 | + * anon-public-user-private mode should only be used where there is a particularly |
| 242 | + * good performance reason for caching the anonymous response, but where the |
| 243 | + * response to logged-in users may differ, or may contain private data. |
| 244 | + * |
| 245 | + * If this function is never called, then the default will be the private mode. |
| 246 | + */ |
| 247 | + public function setCacheMode( $mode ) { |
| 248 | + if ( !in_array( $mode, array( 'private', 'public', 'anon-public-user-private' ) ) ) { |
| 249 | + wfDebug( __METHOD__.": unrecognised cache mode \"$mode\"\n" ); |
| 250 | + // Ignore for forwards-compatibility |
| 251 | + return; |
| 252 | + } |
| 253 | + |
| 254 | + if ( !in_array( 'read', User::getGroupPermissions( array( '*' ) ), true ) ) { |
| 255 | + // Private wiki, only private headers |
| 256 | + if ( $mode !== 'private' ) { |
| 257 | + wfDebug( __METHOD__.": ignoring request for $mode cache mode, private wiki\n" ); |
| 258 | + return; |
| 259 | + } |
| 260 | + } |
| 261 | + |
| 262 | + wfDebug( __METHOD__.": setting cache mode $mode\n" ); |
| 263 | + $this->mCacheMode = $mode; |
| 264 | + } |
220 | 265 | |
221 | 266 | /** |
222 | | - * Make sure Cache-Control: private is set. Use this when the output of a request |
223 | | - * is for the current recipient only and should not be cached in any shared cache. |
| 267 | + * @deprecated Private caching is now the default, so there is usually no |
| 268 | + * need to call this function. If there is a need, you can use |
| 269 | + * $this->setCacheMode('private') |
224 | 270 | */ |
225 | 271 | public function setCachePrivate() { |
226 | | - $this->setCacheControl( array( 'private' => true ) ); |
| 272 | + $this->setCacheMode( 'private' ); |
227 | 273 | } |
228 | 274 | |
229 | 275 | /** |
230 | 276 | * Set directives (key/value pairs) for the Cache-Control header. |
231 | 277 | * Boolean values will be formatted as such, by including or omitting |
232 | 278 | * without an equals sign. |
| 279 | + * |
| 280 | + * Cache control values set here will only be used if the cache mode is not |
| 281 | + * private, see setCacheMode(). |
233 | 282 | */ |
234 | 283 | public function setCacheControl( $directives ) { |
235 | 284 | $this->mCacheControl = $directives + $this->mCacheControl; |
— | — | @@ -241,27 +290,12 @@ |
242 | 291 | * WARNING: This function must be called CONSISTENTLY for a given URL. This means that a |
243 | 292 | * given URL must either always or never call this function; if it sometimes does and |
244 | 293 | * sometimes doesn't, stuff will break. |
| 294 | + * |
| 295 | + * @deprecated Use setCacheMode( 'anon-public-user-private' ) |
245 | 296 | */ |
246 | 297 | public function setVaryCookie() { |
247 | | - $this->mVaryCookie = true; |
| 298 | + $this->setCacheMode( 'anon-public-user-private' ); |
248 | 299 | } |
249 | | - |
250 | | - /** |
251 | | - * Actually output the Vary: Cookie header and its friends, if flagged with setVaryCookie(). |
252 | | - * Outputs the appropriate X-Vary-Options header and Cache-Control: private if needed. |
253 | | - */ |
254 | | - private function outputVaryCookieHeader() { |
255 | | - global $wgUseXVO, $wgOut; |
256 | | - if ( $this->mVaryCookie ) { |
257 | | - header( 'Vary: Cookie' ); |
258 | | - if ( $wgUseXVO ) { |
259 | | - header( $wgOut->getXVO() ); |
260 | | - if ( $wgOut->haveCacheVaryCookies() ) { |
261 | | - $this->setCacheControl( array( 'private' => true ) ); |
262 | | - } |
263 | | - } |
264 | | - } |
265 | | - } |
266 | 300 | |
267 | 301 | /** |
268 | 302 | * Create an instance of an output formatter by its name |
— | — | @@ -313,8 +347,7 @@ |
314 | 348 | $errCode = $this->substituteResultWithError( $e ); |
315 | 349 | |
316 | 350 | // Error results should not be cached |
317 | | - $this->setCacheMaxAge( 0 ); |
318 | | - $this->setCachePrivate(); |
| 351 | + $this->setCacheMode( 'private' ); |
319 | 352 | |
320 | 353 | $headerStr = 'MediaWiki-API-Error: ' . $errCode; |
321 | 354 | if ( $e->getCode() === 0 ) { |
— | — | @@ -330,12 +363,49 @@ |
331 | 364 | $this->mPrinter->safeProfileOut(); |
332 | 365 | $this->printResult( true ); |
333 | 366 | } |
334 | | - |
335 | | - // If this wiki is private, don't cache anything ever |
336 | | - if ( ! in_array( 'read', User::getGroupPermissions( array( '*' ) ), true ) ) { |
337 | | - $this->setCachePrivate(); |
| 367 | + |
| 368 | + // Send cache headers after any code which might generate an error, to |
| 369 | + // avoid sending public cache headers for errors. |
| 370 | + $this->sendCacheHeaders(); |
| 371 | + |
| 372 | + if ( $this->mPrinter->getIsHtml() && !$this->mPrinter->isDisabled() ) { |
| 373 | + echo wfReportTime(); |
338 | 374 | } |
339 | 375 | |
| 376 | + ob_end_flush(); |
| 377 | + } |
| 378 | + |
| 379 | + protected function sendCacheHeaders() { |
| 380 | + if ( $this->mCacheMode == 'private' ) { |
| 381 | + header( 'Cache-Control: private' ); |
| 382 | + return; |
| 383 | + } |
| 384 | + |
| 385 | + if ( $this->mCacheMode == 'anon-public-user-private' ) { |
| 386 | + global $wgUseXVO, $wgOut; |
| 387 | + header( 'Vary: Accept-Encoding, Cookie' ); |
| 388 | + if ( $wgUseXVO ) { |
| 389 | + header( $wgOut->getXVO() ); |
| 390 | + if ( $wgOut->haveCacheVaryCookies() ) { |
| 391 | + // Logged in, mark this request private |
| 392 | + header( 'Cache-Control: private' ); |
| 393 | + return; |
| 394 | + } |
| 395 | + // Logged out, send normal public headers below |
| 396 | + } elseif ( session_id() != '' ) { |
| 397 | + // Logged in or otherwise has session (e.g. anonymous users who have edited) |
| 398 | + // Mark request private |
| 399 | + header( 'Cache-Control: private' ); |
| 400 | + return; |
| 401 | + } // else no XVO and anonymous, send public headers below |
| 402 | + } else /* if public */ { |
| 403 | + // Give a debugging message if the user object is unstubbed on a public request |
| 404 | + global $wgUser; |
| 405 | + if ( !( $wgUser instanceof StubUser ) ) { |
| 406 | + wfDebug( __METHOD__." \$wgUser is unstubbed on a public request!\n" ); |
| 407 | + } |
| 408 | + } |
| 409 | + |
340 | 410 | // If nobody called setCacheMaxAge(), use the (s)maxage parameters |
341 | 411 | if ( !isset( $this->mCacheControl['s-maxage'] ) ) { |
342 | 412 | $this->mCacheControl['s-maxage'] = $this->getParameter( 'smaxage' ); |
— | — | @@ -344,12 +414,21 @@ |
345 | 415 | $this->mCacheControl['max-age'] = $this->getParameter( 'maxage' ); |
346 | 416 | } |
347 | 417 | |
348 | | - // Set the cache expiration at the last moment, as any errors may change the expiration. |
349 | | - // if $this->mSquidMaxage == 0, the expiry time is set to the first second of unix epoch |
350 | | - $exp = min( $this->mCacheControl['s-maxage'], $this->mCacheControl['max-age'] ); |
351 | | - $expires = ( $exp == 0 ? 1 : time() + $exp ); |
352 | | - header( 'Expires: ' . wfTimestamp( TS_RFC2822, $expires ) ); |
| 418 | + if ( !$this->mCacheControl['s-maxage'] && !$this->mCacheControl['max-age'] ) { |
| 419 | + // Public cache not requested |
| 420 | + // Sending a Vary header in this case is harmless, and protects us |
| 421 | + // against conditional calls of setCacheMaxAge(). |
| 422 | + header( 'Cache-Control: private' ); |
| 423 | + return; |
| 424 | + } |
353 | 425 | |
| 426 | + $this->mCacheControl['public'] = true; |
| 427 | + |
| 428 | + // Send an Expires header |
| 429 | + $maxAge = min( $this->mCacheControl['s-maxage'], $this->mCacheControl['max-age'] ); |
| 430 | + $expiryUnixTime = ( $maxAge == 0 ? 1 : time() + $maxAge ); |
| 431 | + header( 'Expires: ' . wfTimestamp( TS_RFC2822, $expiryUnixTime ) ); |
| 432 | + |
354 | 433 | // Construct the Cache-Control header |
355 | 434 | $ccHeader = ''; |
356 | 435 | $separator = ''; |
— | — | @@ -366,13 +445,6 @@ |
367 | 446 | } |
368 | 447 | |
369 | 448 | header( "Cache-Control: $ccHeader" ); |
370 | | - $this->outputVaryCookieHeader(); |
371 | | - |
372 | | - if ( $this->mPrinter->getIsHtml() && !$this->mPrinter->isDisabled() ) { |
373 | | - echo wfReportTime(); |
374 | | - } |
375 | | - |
376 | | - ob_end_flush(); |
377 | 449 | } |
378 | 450 | |
379 | 451 | /** |
Index: trunk/phase3/includes/api/ApiQueryImageInfo.php |
— | — | @@ -274,6 +274,10 @@ |
275 | 275 | return $retval; |
276 | 276 | } |
277 | 277 | |
| 278 | + public function getCacheMode( $params ) { |
| 279 | + return 'public'; |
| 280 | + } |
| 281 | + |
278 | 282 | private function getContinueStr( $img ) { |
279 | 283 | return $img->getOriginalTitle()->getText() . |
280 | 284 | '|' . $img->getTimestamp(); |
Index: trunk/phase3/includes/api/ApiOpenSearch.php |
— | — | @@ -56,7 +56,7 @@ |
57 | 57 | // Open search results may be stored for a very long |
58 | 58 | // time |
59 | 59 | $this->getMain()->setCacheMaxAge( $wgSearchSuggestCacheExpiry ); |
60 | | - $this->getMain()->setCacheControl( array( 'must-revalidate' => false ) ); |
| 60 | + $this->getMain()->setCacheMode( 'public' ); |
61 | 61 | |
62 | 62 | $srchres = PrefixSearch::titleSearch( $search, $limit, |
63 | 63 | $namespaces ); |
Index: trunk/phase3/includes/api/ApiQueryIWBacklinks.php |
— | — | @@ -147,6 +147,10 @@ |
148 | 148 | } |
149 | 149 | } |
150 | 150 | |
| 151 | + public function getCacheMode( $params ) { |
| 152 | + return 'public'; |
| 153 | + } |
| 154 | + |
151 | 155 | public function getAllowedParams() { |
152 | 156 | return array( |
153 | 157 | 'prefix' => null, |
Index: trunk/phase3/includes/api/ApiQueryWatchlist.php |
— | — | @@ -74,7 +74,6 @@ |
75 | 75 | $this->fld_notificationtimestamp = isset( $prop['notificationtimestamp'] ); |
76 | 76 | |
77 | 77 | if ( $this->fld_patrol ) { |
78 | | - $this->getMain()->setVaryCookie(); |
79 | 78 | if ( !$user->useRCPatrol() && !$user->useNPPatrol() ) { |
80 | 79 | $this->dieUsage( 'patrol property is not available', 'patrol' ); |
81 | 80 | } |
— | — | @@ -141,9 +140,8 @@ |
142 | 141 | $this->dieUsageMsg( array( 'show' ) ); |
143 | 142 | } |
144 | 143 | |
145 | | - // Check permissions. FIXME: should this check $user instead of $wgUser? |
| 144 | + // Check permissions. |
146 | 145 | if ( isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ) { |
147 | | - $this->getMain()->setVaryCookie(); |
148 | 146 | if ( !$wgUser->useRCPatrol() && !$wgUser->useNPPatrol() ) { |
149 | 147 | $this->dieUsage( 'You need the patrol right to request the patrolled flag', 'permissiondenied' ); |
150 | 148 | } |
— | — | @@ -272,7 +270,6 @@ |
273 | 271 | |
274 | 272 | if ( $this->fld_parsedcomment && isset( $row->rc_comment ) ) { |
275 | 273 | global $wgUser; |
276 | | - $this->getMain()->setVaryCookie(); |
277 | 274 | $vals['parsedcomment'] = $wgUser->getSkin()->formatComment( $row->rc_comment, $title ); |
278 | 275 | } |
279 | 276 | |
Index: trunk/phase3/includes/api/ApiPatrol.php |
— | — | @@ -41,7 +41,6 @@ |
42 | 42 | * Patrols the article or provides the reason the patrol failed. |
43 | 43 | */ |
44 | 44 | public function execute() { |
45 | | - $this->getMain()->setCachePrivate(); |
46 | 45 | $params = $this->extractRequestParams(); |
47 | 46 | |
48 | 47 | if ( !isset( $params['rcid'] ) ) { |
— | — | @@ -107,4 +106,4 @@ |
108 | 107 | public function getVersion() { |
109 | 108 | return __CLASS__ . ': $Id$'; |
110 | 109 | } |
111 | | -} |
\ No newline at end of file |
| 110 | +} |
Index: trunk/phase3/includes/api/ApiQueryRevisions.php |
— | — | @@ -394,7 +394,6 @@ |
395 | 395 | |
396 | 396 | if ( $this->fld_parsedcomment ) { |
397 | 397 | global $wgUser; |
398 | | - $this->getMain()->setVaryCookie(); |
399 | 398 | $vals['parsedcomment'] = $wgUser->getSkin()->formatComment( $comment, $title ); |
400 | 399 | } |
401 | 400 | } |
— | — | @@ -411,9 +410,6 @@ |
412 | 411 | } |
413 | 412 | |
414 | 413 | if ( !is_null( $this->token ) ) { |
415 | | - // Don't cache tokens |
416 | | - $this->getMain()->setCachePrivate(); |
417 | | - |
418 | 414 | $tokenFunctions = $this->getTokenFunctions(); |
419 | 415 | foreach ( $this->token as $t ) { |
420 | 416 | $val = call_user_func( $tokenFunctions[$t], $title->getArticleID(), $title, $revision ); |
— | — | @@ -487,6 +483,17 @@ |
488 | 484 | return $vals; |
489 | 485 | } |
490 | 486 | |
| 487 | + public function getCacheMode( $params ) { |
| 488 | + if ( isset( $params['token'] ) ) { |
| 489 | + return 'private'; |
| 490 | + } |
| 491 | + if ( !is_null( $params['prop'] ) && in_array( 'parsedcomment', $params['prop'] ) ) { |
| 492 | + // formatComment() calls wfMsg() among other things |
| 493 | + return 'anon-public-user-private'; |
| 494 | + } |
| 495 | + return 'public'; |
| 496 | + } |
| 497 | + |
491 | 498 | public function getAllowedParams() { |
492 | 499 | return array( |
493 | 500 | 'prop' => array( |
Index: trunk/phase3/includes/api/ApiQueryExternalLinks.php |
— | — | @@ -83,6 +83,10 @@ |
84 | 84 | } |
85 | 85 | } |
86 | 86 | |
| 87 | + public function getCacheMode( $params ) { |
| 88 | + return 'public'; |
| 89 | + } |
| 90 | + |
87 | 91 | public function getAllowedParams() { |
88 | 92 | return array( |
89 | 93 | 'limit' => array( |
— | — | @@ -117,4 +121,4 @@ |
118 | 122 | public function getVersion() { |
119 | 123 | return __CLASS__ . ': $Id$'; |
120 | 124 | } |
121 | | -} |
\ No newline at end of file |
| 125 | +} |
Index: trunk/phase3/includes/api/ApiBase.php |
— | — | @@ -1105,8 +1105,6 @@ |
1106 | 1106 | $this->dieUsage( 'Incorrect watchlist token provided -- please set a correct token in Special:Preferences', 'bad_wltoken' ); |
1107 | 1107 | } |
1108 | 1108 | } else { |
1109 | | - // User not determined by URL, so don't cache |
1110 | | - $this->getMain()->setVaryCookie(); |
1111 | 1109 | if ( !$wgUser->isLoggedIn() ) { |
1112 | 1110 | $this->dieUsage( 'You must be logged-in to have a watchlist', 'notloggedin' ); |
1113 | 1111 | } |
Index: trunk/phase3/includes/api/ApiQueryCategories.php |
— | — | @@ -43,6 +43,10 @@ |
44 | 44 | $this->run(); |
45 | 45 | } |
46 | 46 | |
| 47 | + public function getCacheMode( $params ) { |
| 48 | + return 'public'; |
| 49 | + } |
| 50 | + |
47 | 51 | public function executeGenerator( $resultPageSet ) { |
48 | 52 | $this->run( $resultPageSet ); |
49 | 53 | } |
Index: trunk/phase3/includes/api/ApiQueryAllUsers.php |
— | — | @@ -184,6 +184,10 @@ |
185 | 185 | $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'u' ); |
186 | 186 | } |
187 | 187 | |
| 188 | + public function getCacheMode( $params ) { |
| 189 | + return 'public'; |
| 190 | + } |
| 191 | + |
188 | 192 | public function getAllowedParams() { |
189 | 193 | return array( |
190 | 194 | 'from' => null, |
— | — | @@ -241,4 +245,4 @@ |
242 | 246 | public function getVersion() { |
243 | 247 | return __CLASS__ . ': $Id$'; |
244 | 248 | } |
245 | | -} |
\ No newline at end of file |
| 249 | +} |
Index: trunk/phase3/includes/api/ApiQueryInfo.php |
— | — | @@ -253,7 +253,6 @@ |
254 | 254 | } |
255 | 255 | |
256 | 256 | if ( $this->fld_watched ) { |
257 | | - $this->getMain()->setVaryCookie(); |
258 | 257 | $this->getWatchedInfo(); |
259 | 258 | } |
260 | 259 | |
— | — | @@ -304,9 +303,6 @@ |
305 | 304 | } |
306 | 305 | |
307 | 306 | if ( !is_null( $this->params['token'] ) ) { |
308 | | - // Don't cache tokens |
309 | | - $this->getMain()->setCachePrivate(); |
310 | | - |
311 | 307 | $tokenFunctions = $this->getTokenFunctions(); |
312 | 308 | $pageInfo['starttimestamp'] = wfTimestamp( TS_ISO_8601, time() ); |
313 | 309 | foreach ( $this->params['token'] as $t ) { |
— | — | @@ -607,6 +603,28 @@ |
608 | 604 | } |
609 | 605 | } |
610 | 606 | |
| 607 | + public function getCacheMode( $params ) { |
| 608 | + $publicProps = array( |
| 609 | + 'protection', |
| 610 | + 'talkid', |
| 611 | + 'subjectid', |
| 612 | + 'url', |
| 613 | + 'preload', |
| 614 | + 'displaytitle', |
| 615 | + ); |
| 616 | + if ( !is_null( $params['prop'] ) ) { |
| 617 | + foreach ( $params['prop'] as $prop ) { |
| 618 | + if ( !in_array( $prop, $publicProps ) ) { |
| 619 | + return 'private'; |
| 620 | + } |
| 621 | + } |
| 622 | + } |
| 623 | + if ( !is_null( $params['token'] ) ) { |
| 624 | + return 'private'; |
| 625 | + } |
| 626 | + return 'public'; |
| 627 | + } |
| 628 | + |
611 | 629 | public function getAllowedParams() { |
612 | 630 | return array( |
613 | 631 | 'prop' => array( |
— | — | @@ -615,12 +633,14 @@ |
616 | 634 | ApiBase::PARAM_TYPE => array( |
617 | 635 | 'protection', |
618 | 636 | 'talkid', |
619 | | - 'watched', |
| 637 | + 'watched', # private |
620 | 638 | 'subjectid', |
621 | 639 | 'url', |
622 | | - 'readable', |
| 640 | + 'readable', # private |
623 | 641 | 'preload', |
624 | 642 | 'displaytitle', |
| 643 | + // If you add more properties here, please consider whether they |
| 644 | + // need to be added to getCacheMode() |
625 | 645 | ) ), |
626 | 646 | 'token' => array( |
627 | 647 | ApiBase::PARAM_DFLT => null, |
Index: trunk/phase3/includes/api/ApiQueryDuplicateFiles.php |
— | — | @@ -43,6 +43,10 @@ |
44 | 44 | $this->run(); |
45 | 45 | } |
46 | 46 | |
| 47 | + public function getCacheMode( $params ) { |
| 48 | + return 'public'; |
| 49 | + } |
| 50 | + |
47 | 51 | public function executeGenerator( $resultPageSet ) { |
48 | 52 | $this->run( $resultPageSet ); |
49 | 53 | } |
Index: trunk/phase3/includes/api/ApiQueryTags.php |
— | — | @@ -129,6 +129,10 @@ |
130 | 130 | return true; |
131 | 131 | } |
132 | 132 | |
| 133 | + public function getCacheMode( $params ) { |
| 134 | + return 'public'; |
| 135 | + } |
| 136 | + |
133 | 137 | public function getAllowedParams() { |
134 | 138 | return array( |
135 | 139 | 'continue' => array( |
Index: trunk/phase3/includes/api/ApiQueryUserContributions.php |
— | — | @@ -163,8 +163,6 @@ |
164 | 164 | ); |
165 | 165 | } |
166 | 166 | |
167 | | - // Make sure private data (deleted revisions) isn't cached |
168 | | - $this->getMain()->setVaryCookie(); |
169 | 167 | if ( !$wgUser->isAllowed( 'hideuser' ) ) { |
170 | 168 | $this->addWhere( $this->getDB()->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0' ); |
171 | 169 | } |
— | — | @@ -216,8 +214,6 @@ |
217 | 215 | $this->fld_patrolled ) |
218 | 216 | { |
219 | 217 | global $wgUser; |
220 | | - // Don't cache private data |
221 | | - $this->getMain()->setVaryCookie(); |
222 | 218 | if ( !$wgUser->useRCPatrol() && !$wgUser->useNPPatrol() ) { |
223 | 219 | $this->dieUsage( 'You need the patrol right to request the patrolled flag', 'permissiondenied' ); |
224 | 220 | } |
— | — | @@ -320,7 +316,6 @@ |
321 | 317 | |
322 | 318 | if ( $this->fld_parsedcomment ) { |
323 | 319 | global $wgUser; |
324 | | - $this->getMain()->setVaryCookie(); |
325 | 320 | $vals['parsedcomment'] = $wgUser->getSkin()->formatComment( $row->rev_comment, $title ); |
326 | 321 | } |
327 | 322 | } |
— | — | @@ -352,6 +347,12 @@ |
353 | 348 | wfTimestamp( TS_ISO_8601, $row->rev_timestamp ); |
354 | 349 | } |
355 | 350 | |
| 351 | + public function getCacheMode( $params ) { |
| 352 | + // This module provides access to deleted revisions and patrol flags if |
| 353 | + // the requester is logged in |
| 354 | + return 'anon-public-user-private'; |
| 355 | + } |
| 356 | + |
356 | 357 | public function getAllowedParams() { |
357 | 358 | return array( |
358 | 359 | 'limit' => array( |
Index: trunk/phase3/includes/api/ApiQueryUsers.php |
— | — | @@ -160,9 +160,6 @@ |
161 | 161 | } |
162 | 162 | |
163 | 163 | if ( !is_null( $params['token'] ) ) { |
164 | | - // Don't cache tokens |
165 | | - $this->getMain()->setCachePrivate(); |
166 | | - |
167 | 164 | $tokenFunctions = $this->getTokenFunctions(); |
168 | 165 | foreach ( $params['token'] as $t ) { |
169 | 166 | $val = call_user_func( $tokenFunctions[$t], $user ); |
— | — | @@ -235,6 +232,14 @@ |
236 | 233 | return array_merge( $groups, Autopromote::getAutopromoteGroups( $user ) ); |
237 | 234 | } |
238 | 235 | |
| 236 | + public function getCacheMode( $params ) { |
| 237 | + if ( isset( $params['token'] ) ) { |
| 238 | + return 'private'; |
| 239 | + } else { |
| 240 | + return 'public'; |
| 241 | + } |
| 242 | + } |
| 243 | + |
239 | 244 | public function getAllowedParams() { |
240 | 245 | return array( |
241 | 246 | 'prop' => array( |
Index: trunk/phase3/includes/api/ApiQueryImages.php |
— | — | @@ -121,6 +121,10 @@ |
122 | 122 | } |
123 | 123 | } |
124 | 124 | |
| 125 | + public function getCacheMode( $params ) { |
| 126 | + return 'public'; |
| 127 | + } |
| 128 | + |
125 | 129 | public function getAllowedParams() { |
126 | 130 | return array( |
127 | 131 | 'limit' => array( |
— | — | @@ -163,4 +167,4 @@ |
164 | 168 | public function getVersion() { |
165 | 169 | return __CLASS__ . ': $Id$'; |
166 | 170 | } |
167 | | -} |
\ No newline at end of file |
| 171 | +} |