Index: trunk/phase3/includes/specials/SpecialExport.php |
— | — | @@ -46,7 +46,8 @@ |
47 | 47 | $this->templates = $wgRequest->getCheck( 'templates' ); |
48 | 48 | $this->images = $wgRequest->getCheck( 'images' ); // Doesn't do anything yet |
49 | 49 | $this->pageLinkDepth = $this->validateLinkDepth( |
50 | | - $wgRequest->getIntOrNull( 'pagelink-depth' ) ); |
| 50 | + $wgRequest->getIntOrNull( 'pagelink-depth' ) |
| 51 | + ); |
51 | 52 | $nsindex = ''; |
52 | 53 | |
53 | 54 | if ( $wgRequest->getCheck( 'addcat' ) ) { |
— | — | @@ -82,11 +83,13 @@ |
83 | 84 | $page = $wgRequest->getText( 'pages' ); |
84 | 85 | $this->curonly = $wgRequest->getCheck( 'curonly' ); |
85 | 86 | $rawOffset = $wgRequest->getVal( 'offset' ); |
| 87 | + |
86 | 88 | if( $rawOffset ) { |
87 | 89 | $offset = wfTimestamp( TS_MW, $rawOffset ); |
88 | 90 | } else { |
89 | 91 | $offset = null; |
90 | 92 | } |
| 93 | + |
91 | 94 | $limit = $wgRequest->getInt( 'limit' ); |
92 | 95 | $dir = $wgRequest->getVal( 'dir' ); |
93 | 96 | $history = array( |
— | — | @@ -95,6 +98,7 @@ |
96 | 99 | 'limit' => $wgExportMaxHistory, |
97 | 100 | ); |
98 | 101 | $historyCheck = $wgRequest->getCheck( 'history' ); |
| 102 | + |
99 | 103 | if ( $this->curonly ) { |
100 | 104 | $history = WikiExporter::CURRENT; |
101 | 105 | } elseif ( !$historyCheck ) { |
— | — | @@ -111,9 +115,10 @@ |
112 | 116 | |
113 | 117 | if( $page != '' ) $this->doExport = true; |
114 | 118 | } else { |
115 | | - // Default to current-only for GET requests |
| 119 | + // Default to current-only for GET requests. |
116 | 120 | $page = $wgRequest->getText( 'pages', $par ); |
117 | 121 | $historyCheck = $wgRequest->getCheck( 'history' ); |
| 122 | + |
118 | 123 | if( $historyCheck ) { |
119 | 124 | $history = WikiExporter::FULL; |
120 | 125 | } else { |
— | — | @@ -133,16 +138,20 @@ |
134 | 139 | |
135 | 140 | if ( $this->doExport ) { |
136 | 141 | $wgOut->disable(); |
| 142 | + |
137 | 143 | // Cancel output buffering and gzipping if set |
138 | 144 | // This should provide safer streaming for pages with history |
139 | 145 | wfResetOutputBuffers(); |
140 | 146 | $wgRequest->response()->header( "Content-type: application/xml; charset=utf-8" ); |
| 147 | + |
141 | 148 | if( $wgRequest->getCheck( 'wpDownload' ) ) { |
142 | 149 | // Provide a sane filename suggestion |
143 | 150 | $filename = urlencode( $wgSitename . '-' . wfTimestampNow() . '.xml' ); |
144 | 151 | $wgRequest->response()->header( "Content-disposition: attachment;filename={$filename}" ); |
145 | 152 | } |
| 153 | + |
146 | 154 | $this->doExport( $page, $history, $list_authors ); |
| 155 | + |
147 | 156 | return; |
148 | 157 | } |
149 | 158 | |
— | — | @@ -166,7 +175,9 @@ |
167 | 176 | } else { |
168 | 177 | $wgOut->addHTML( wfMsgExt( 'exportnohistory', 'parse' ) ); |
169 | 178 | } |
| 179 | + |
170 | 180 | $form .= Xml::checkLabel( wfMsg( 'export-templates' ), 'templates', 'wpExportTemplates', false ) . '<br />'; |
| 181 | + |
171 | 182 | if( $wgExportMaxLinkDepth || $this->userCanOverrideExportDepth() ) { |
172 | 183 | $form .= Xml::inputLabel( wfMsg( 'export-pagelinks' ), 'pagelink-depth', 'pagelink-depth', 20, 0 ) . '<br />'; |
173 | 184 | } |
— | — | @@ -176,12 +187,12 @@ |
177 | 188 | |
178 | 189 | $form .= Xml::submitButton( wfMsg( 'export-submit' ), $wgUser->getSkin()->tooltipAndAccessKeyAttribs( 'export' ) ); |
179 | 190 | $form .= Xml::closeElement( 'form' ); |
| 191 | + |
180 | 192 | $wgOut->addHTML( $form ); |
181 | 193 | } |
182 | 194 | |
183 | 195 | private function userCanOverrideExportDepth() { |
184 | 196 | global $wgUser; |
185 | | - |
186 | 197 | return $wgUser->isAllowed( 'override-export-depth' ); |
187 | 198 | } |
188 | 199 | |
— | — | @@ -231,6 +242,7 @@ |
232 | 243 | foreach( $pages as $k => $v ) { |
233 | 244 | $pages[$k] = str_replace( " ", "_", $v ); |
234 | 245 | } |
| 246 | + |
235 | 247 | $pages = array_unique( $pages ); |
236 | 248 | |
237 | 249 | /* Ok, let's get to it... */ |
— | — | @@ -249,9 +261,11 @@ |
250 | 262 | set_time_limit(0); |
251 | 263 | wfRestoreWarnings(); |
252 | 264 | } |
| 265 | + |
253 | 266 | $exporter = new WikiExporter( $db, $history, $buffer ); |
254 | 267 | $exporter->list_authors = $list_authors; |
255 | 268 | $exporter->openStream(); |
| 269 | + |
256 | 270 | foreach( $pages as $page ) { |
257 | 271 | /* |
258 | 272 | if( $wgExportMaxHistory && !$this->curonly ) { |
— | — | @@ -274,6 +288,7 @@ |
275 | 289 | } |
276 | 290 | |
277 | 291 | $exporter->closeStream(); |
| 292 | + |
278 | 293 | if( $lb ) { |
279 | 294 | $lb->closeAll(); |
280 | 295 | } |
— | — | @@ -285,12 +300,16 @@ |
286 | 301 | $name = $title->getDBkey(); |
287 | 302 | |
288 | 303 | $dbr = wfGetDB( DB_SLAVE ); |
289 | | - $res = $dbr->select( array('page', 'categorylinks' ), |
290 | | - array( 'page_namespace', 'page_title' ), |
291 | | - array('cl_from=page_id', 'cl_to' => $name ), |
292 | | - __METHOD__, array('LIMIT' => '5000')); |
| 304 | + $res = $dbr->select( |
| 305 | + array( 'page', 'categorylinks' ), |
| 306 | + array( 'page_namespace', 'page_title' ), |
| 307 | + array( 'cl_from=page_id', 'cl_to' => $name ), |
| 308 | + __METHOD__, |
| 309 | + array( 'LIMIT' => '5000' ) |
| 310 | + ); |
293 | 311 | |
294 | 312 | $pages = array(); |
| 313 | + |
295 | 314 | while ( $row = $dbr->fetchObject( $res ) ) { |
296 | 315 | $n = $row->page_title; |
297 | 316 | if ($row->page_namespace) { |
— | — | @@ -300,6 +319,7 @@ |
301 | 320 | |
302 | 321 | $pages[] = $n; |
303 | 322 | } |
| 323 | + |
304 | 324 | $dbr->freeResult($res); |
305 | 325 | |
306 | 326 | return $pages; |
— | — | @@ -309,21 +329,28 @@ |
310 | 330 | global $wgContLang; |
311 | 331 | |
312 | 332 | $dbr = wfGetDB( DB_SLAVE ); |
313 | | - $res = $dbr->select( 'page', array('page_namespace', 'page_title'), |
314 | | - array('page_namespace' => $nsindex), |
315 | | - __METHOD__, array('LIMIT' => '5000') ); |
| 333 | + $res = $dbr->select( |
| 334 | + 'page', |
| 335 | + array( 'page_namespace', 'page_title' ), |
| 336 | + array( 'page_namespace' => $nsindex ), |
| 337 | + __METHOD__, |
| 338 | + array( 'LIMIT' => '5000' ) |
| 339 | + ); |
316 | 340 | |
317 | 341 | $pages = array(); |
| 342 | + |
318 | 343 | while ( $row = $dbr->fetchObject( $res ) ) { |
319 | 344 | $n = $row->page_title; |
320 | | - if ($row->page_namespace) { |
| 345 | + |
| 346 | + if ( $row->page_namespace ) { |
321 | 347 | $ns = $wgContLang->getNsText( $row->page_namespace ); |
322 | 348 | $n = $ns . ':' . $n; |
323 | 349 | } |
324 | 350 | |
325 | 351 | $pages[] = $n; |
326 | 352 | } |
327 | | - $dbr->freeResult($res); |
| 353 | + |
| 354 | + $dbr->freeResult( $res ); |
328 | 355 | |
329 | 356 | return $pages; |
330 | 357 | } |
— | — | @@ -336,9 +363,10 @@ |
337 | 364 | */ |
338 | 365 | private function getTemplates( $inputPages, $pageSet ) { |
339 | 366 | return $this->getLinks( $inputPages, $pageSet, |
340 | | - 'templatelinks', |
341 | | - array( 'tl_namespace AS namespace', 'tl_title AS title' ), |
342 | | - array( 'page_id=tl_from' ) ); |
| 367 | + 'templatelinks', |
| 368 | + array( 'tl_namespace AS namespace', 'tl_title AS title' ), |
| 369 | + array( 'page_id=tl_from' ) |
| 370 | + ); |
343 | 371 | } |
344 | 372 | |
345 | 373 | /** |
— | — | @@ -346,14 +374,17 @@ |
347 | 375 | */ |
348 | 376 | private function validateLinkDepth( $depth ) { |
349 | 377 | global $wgExportMaxLinkDepth; |
| 378 | + |
350 | 379 | if( $depth < 0 ) { |
351 | 380 | return 0; |
352 | 381 | } |
| 382 | + |
353 | 383 | if ( !$this->userCanOverrideExportDepth() ) { |
354 | 384 | if( $depth > $wgExportMaxLinkDepth ) { |
355 | 385 | return $wgExportMaxLinkDepth; |
356 | 386 | } |
357 | 387 | } |
| 388 | + |
358 | 389 | /* |
359 | 390 | * There's a HARD CODED limit of 5 levels of recursion here to prevent a |
360 | 391 | * crazy-big export from being done by someone setting the depth |
— | — | @@ -364,55 +395,70 @@ |
365 | 396 | |
366 | 397 | /** Expand a list of pages to include pages linked to from that page. */ |
367 | 398 | private function getPageLinks( $inputPages, $pageSet, $depth ) { |
368 | | - for( $depth=$depth; $depth>0; --$depth ) { |
369 | | - $pageSet = $this->getLinks( $inputPages, $pageSet, 'pagelinks', |
370 | | - array( 'pl_namespace AS namespace', 'pl_title AS title' ), |
371 | | - array( 'page_id=pl_from' ) ); |
| 399 | + for(; $depth > 0; --$depth ) { |
| 400 | + $pageSet = $this->getLinks( |
| 401 | + $inputPages, $pageSet, 'pagelinks', |
| 402 | + array( 'pl_namespace AS namespace', 'pl_title AS title' ), |
| 403 | + array( 'page_id=pl_from' ) |
| 404 | + ); |
372 | 405 | $inputPages = array_keys( $pageSet ); |
373 | 406 | } |
| 407 | + |
374 | 408 | return $pageSet; |
375 | 409 | } |
376 | 410 | |
377 | 411 | /** |
378 | 412 | * Expand a list of pages to include images used in those pages. |
| 413 | + * |
379 | 414 | * @param $inputPages array, list of titles to look up |
380 | 415 | * @param $pageSet array, associative array indexed by titles for output |
| 416 | + * |
381 | 417 | * @return array associative array index by titles |
382 | 418 | */ |
383 | 419 | private function getImages( $inputPages, $pageSet ) { |
384 | | - return $this->getLinks( $inputPages, $pageSet, |
385 | | - 'imagelinks', |
386 | | - array( NS_FILE . ' AS namespace', 'il_to AS title' ), |
387 | | - array( 'page_id=il_from' ) ); |
| 420 | + return $this->getLinks( |
| 421 | + $inputPages, |
| 422 | + $pageSet, |
| 423 | + 'imagelinks', |
| 424 | + array( NS_FILE . ' AS namespace', 'il_to AS title' ), |
| 425 | + array( 'page_id=il_from' ) |
| 426 | + ); |
388 | 427 | } |
389 | 428 | |
390 | 429 | /** |
391 | 430 | * Expand a list of pages to include items used in those pages. |
392 | | - * @private |
393 | 431 | */ |
394 | 432 | private function getLinks( $inputPages, $pageSet, $table, $fields, $join ) { |
395 | 433 | $dbr = wfGetDB( DB_SLAVE ); |
| 434 | + |
396 | 435 | foreach( $inputPages as $page ) { |
397 | 436 | $title = Title::newFromText( $page ); |
| 437 | + |
398 | 438 | if( $title ) { |
399 | 439 | $pageSet[$title->getPrefixedText()] = true; |
400 | 440 | /// @todo Fixme: May or may not be more efficient to batch these |
401 | 441 | /// by namespace when given multiple input pages. |
402 | 442 | $result = $dbr->select( |
403 | | - array( 'page', $table ), |
404 | | - $fields, |
405 | | - array_merge( $join, |
406 | | - array( |
407 | | - 'page_namespace' => $title->getNamespace(), |
408 | | - 'page_title' => $title->getDBkey() ) ), |
409 | | - __METHOD__ ); |
| 443 | + array( 'page', $table ), |
| 444 | + $fields, |
| 445 | + array_merge( |
| 446 | + $join, |
| 447 | + array( |
| 448 | + 'page_namespace' => $title->getNamespace(), |
| 449 | + 'page_title' => $title->getDBkey() |
| 450 | + ) |
| 451 | + ), |
| 452 | + __METHOD__ |
| 453 | + ); |
| 454 | + |
410 | 455 | foreach( $result as $row ) { |
411 | 456 | $template = Title::makeTitle( $row->namespace, $row->title ); |
412 | 457 | $pageSet[$template->getPrefixedText()] = true; |
413 | 458 | } |
414 | 459 | } |
415 | 460 | } |
| 461 | + |
416 | 462 | return $pageSet; |
417 | 463 | } |
418 | | -} |
419 | | - |
| 464 | + |
| 465 | +} |
\ No newline at end of file |