26use Mediawiki\MediaWikiServices;
37 parent::__construct(
'Export' );
46 $this->curonly =
true;
49 $this->templates =
$request->getCheck(
'templates' );
51 $request->getIntOrNull(
'pagelink-depth' )
56 if (
$request->getCheck(
'addcat' ) ) {
57 $page =
$request->getText(
'pages' );
58 $catname =
$request->getText(
'catname' );
60 if ( $catname !==
'' && $catname !==
null && $catname !==
false ) {
61 $t = Title::makeTitleSafe(
NS_MAIN, $catname );
73 $page .= implode(
"\n", $catpages );
77 } elseif (
$request->getCheck(
'addns' ) && $config->get(
'ExportFromNamespaces' ) ) {
78 $page =
$request->getText(
'pages' );
79 $nsindex =
$request->getText(
'nsindex',
'' );
81 if ( strval( $nsindex ) !==
'' ) {
87 $page .=
"\n" . implode(
"\n", $nspages );
90 } elseif (
$request->getCheck(
'exportall' ) && $config->get(
'ExportAllowAll' ) ) {
100 } elseif (
$request->wasPosted() && $par ==
'' ) {
101 $page =
$request->getText(
'pages' );
102 $this->curonly =
$request->getCheck(
'curonly' );
103 $rawOffset =
$request->getVal(
'offset' );
111 $maxHistory = $config->get(
'ExportMaxHistory' );
112 $limit =
$request->getInt(
'limit' );
117 'limit' => $maxHistory,
119 $historyCheck =
$request->getCheck(
'history' );
121 if ( $this->curonly ) {
123 } elseif ( !$historyCheck ) {
124 if ( $limit > 0 && ( $maxHistory == 0 || $limit < $maxHistory ) ) {
125 $history[
'limit'] = $limit;
128 if ( !is_null( $offset ) ) {
129 $history[
'offset'] = $offset;
132 if ( strtolower(
$dir ) ==
'desc' ) {
133 $history[
'dir'] =
'desc';
142 $page =
$request->getText(
'pages', $par );
143 $historyCheck =
$request->getCheck(
'history' );
145 if ( $historyCheck ) {
156 if ( !$config->get(
'ExportAllowHistory' ) ) {
161 $list_authors =
$request->getCheck(
'listauthors' );
162 if ( !$this->curonly || !$config->get(
'ExportAllowListContributors' ) ) {
163 $list_authors =
false;
172 $request->response()->header(
"Content-type: application/xml; charset=utf-8" );
173 $request->response()->header(
"X-Robots-Tag: noindex,nofollow" );
175 if (
$request->getCheck(
'wpDownload' ) ) {
177 $filename = urlencode( $config->get(
'Sitename' ) .
'-' .
wfTimestampNow() .
'.xml' );
178 $request->response()->header(
"Content-disposition: attachment;filename={$filename}" );
181 $this->
doExport( $page, $history, $list_authors, $exportall );
187 $out->addWikiMsg(
'exporttext' );
190 $categoryName =
$request->getText(
'catname' );
197 'type' =>
'textwithbutton',
199 'horizontal-label' =>
true,
200 'label-message' =>
'export-addcattext',
201 'default' => $categoryName,
203 'buttontype' =>
'submit',
204 'buttonname' =>
'addcat',
205 'buttondefault' => $this->
msg(
'export-addcat' )->text(),
206 'hide-if' => [
'===',
'exportall',
'1' ],
209 if ( $config->get(
'ExportFromNamespaces' ) ) {
212 'type' =>
'namespaceselectwithbutton',
213 'default' => $nsindex,
214 'label-message' =>
'export-addnstext',
215 'horizontal-label' =>
true,
218 'cssclass' =>
'namespaceselector',
219 'buttontype' =>
'submit',
220 'buttonname' =>
'addns',
221 'buttondefault' => $this->
msg(
'export-addns' )->text(),
222 'hide-if' => [
'===',
'exportall',
'1' ],
227 if ( $config->get(
'ExportAllowAll' ) ) {
231 'label-message' =>
'exportall',
232 'name' =>
'exportall',
234 'default' =>
$request->wasPosted() ?
$request->getCheck(
'exportall' ) :
false,
241 'class' =>
'HTMLTextAreaField',
243 'label-message' =>
'export-manual',
247 'hide-if' => [
'===',
'exportall',
'1' ],
251 if ( $config->get(
'ExportAllowHistory' ) ) {
255 'label-message' =>
'exportcuronly',
258 'default' =>
$request->wasPosted() ?
$request->getCheck(
'curonly' ) :
true,
262 $out->addWikiMsg(
'exportnohistory' );
268 'label-message' =>
'export-templates',
269 'name' =>
'templates',
270 'id' =>
'wpExportTemplates',
271 'default' =>
$request->wasPosted() ?
$request->getCheck(
'templates' ) :
false,
275 if ( $config->get(
'ExportMaxLinkDepth' ) || $this->userCanOverrideExportDepth() ) {
277 'pagelink-depth' => [
279 'name' =>
'pagelink-depth',
280 'id' =>
'pagelink-depth',
281 'label-message' =>
'export-pagelinks',
291 'name' =>
'wpDownload',
292 'id' =>
'wpDownload',
293 'default' =>
$request->wasPosted() ?
$request->getCheck(
'wpDownload' ) :
true,
294 'label-message' =>
'export-download',
298 if ( $config->get(
'ExportAllowListContributors' ) ) {
302 'label-message' =>
'exportlistauthors',
303 'default' =>
$request->wasPosted() ?
$request->getCheck(
'listauthors' ) :
false,
304 'name' =>
'listauthors',
305 'id' =>
'listauthors',
311 $htmlForm->setSubmitTextMsg(
'export-submit' );
312 $htmlForm->prepareForm()->displayForm(
false );
320 return $this->
getUser()->isAllowed(
'override-export-depth' );
332 private function doExport( $page, $history, $list_authors, $exportall ) {
340 foreach ( explode(
"\n", $page ) as $pageName ) {
341 $pageName = trim( $pageName );
342 $title = Title::newFromText( $pageName );
343 if ( $title && !$title->isExternal() && $title->getText() !==
'' ) {
345 $pageSet[$title->getPrefixedText()] =
true;
350 $inputPages = array_keys( $pageSet );
353 if ( $this->templates ) {
354 $pageSet = $this->
getTemplates( $inputPages, $pageSet );
358 $pageSet = $this->
getPageLinks( $inputPages, $pageSet, $linkDepth );
361 $pages = array_keys( $pageSet );
364 foreach ( $pages as $k => $v ) {
365 $pages[$k] = str_replace(
" ",
"_", $v );
368 $pages = array_unique( $pages );
378 $lb = MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->newMainLB();
383 MediaWiki\suppressWarnings();
385 MediaWiki\restoreWarnings();
389 $exporter->list_authors = $list_authors;
390 $exporter->openStream();
393 $exporter->allPages();
395 foreach ( $pages as $page ) {
396 # T10824: Only export pages the user can read
397 $title = Title::newFromText( $page );
398 if ( is_null( $title ) ) {
403 if ( !$title->userCan(
'read', $this->getUser() ) ) {
408 $exporter->pageByTitle( $title );
412 $exporter->closeStream();
426 $maxPages = $this->
getConfig()->get(
'ExportPagelistLimit' );
428 $name = $title->getDBkey();
432 [
'page',
'categorylinks' ],
433 [
'page_namespace',
'page_title' ],
434 [
'cl_from=page_id',
'cl_to' => $name ],
436 [
'LIMIT' => $maxPages ]
441 foreach (
$res as $row ) {
442 $n = $row->page_title;
443 if ( $row->page_namespace ) {
444 $ns =
$wgContLang->getNsText( $row->page_namespace );
461 $maxPages = $this->
getConfig()->get(
'ExportPagelistLimit' );
466 [
'page_namespace',
'page_title' ],
467 [
'page_namespace' => $nsindex ],
469 [
'LIMIT' => $maxPages ]
474 foreach (
$res as $row ) {
475 $n = $row->page_title;
477 if ( $row->page_namespace ) {
478 $ns =
$wgContLang->getNsText( $row->page_namespace );
495 return $this->
getLinks( $inputPages, $pageSet,
497 [
'namespace' =>
'tl_namespace',
'title' =>
'tl_title' ],
498 [
'page_id=tl_from' ]
513 $maxLinkDepth = $this->
getConfig()->get(
'ExportMaxLinkDepth' );
514 if ( $depth > $maxLinkDepth ) {
515 return $maxLinkDepth;
525 return intval( min( $depth, 5 ) );
537 for ( ; $depth > 0; --$depth ) {
540 $inputPages, $pageSet,
'pagelinks',
541 [
'namespace' =>
'pl_namespace',
'title' =>
'pl_title' ],
542 [
'page_id=pl_from' ]
544 $inputPages = array_keys( $pageSet );
559 private function getLinks( $inputPages, $pageSet, $table, $fields, $join ) {
562 foreach ( $inputPages as $page ) {
563 $title = Title::newFromText( $page );
566 $pageSet[$title->getPrefixedText()] =
true;
569 $result =
$dbr->select(
575 'page_namespace' => $title->getNamespace(),
576 'page_title' => $title->getDBkey()
582 foreach ( $result as $row ) {
583 $template = Title::makeTitle( $row->namespace, $row->title );
584 $pageSet[
$template->getPrefixedText()] =
true;
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
wfResetOutputBuffers( $resetGzipEncoding=true)
Clear away any user-level output buffers, discarding contents.
A special page that allows users to export pages in a XML file.
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
doExport( $page, $history, $list_authors, $exportall)
Do the actual page exporting.
getPageLinks( $inputPages, $pageSet, $depth)
Expand a list of pages to include pages linked to from that page.
userCanOverrideExportDepth()
getLinks( $inputPages, $pageSet, $table, $fields, $join)
Expand a list of pages to include items used in those pages.
getPagesFromNamespace( $nsindex)
execute( $par)
Default execute method Checks user permissions.
validateLinkDepth( $depth)
Validate link depth setting, if available.
getTemplates( $inputPages, $pageSet)
Expand a list of pages to include templates used in those pages.
getPagesFromCategory( $title)
Parent class for all special pages.
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
getOutput()
Get the OutputPage being used for this instance.
getUser()
Shortcut to get the User executing this instance.
getContext()
Gets the context this SpecialPage is executed in.
msg( $key)
Wrapper around wfMessage that sets the current context.
getConfig()
Shortcut to get main config object.
getRequest()
Get the WebRequest being used for this instance.
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the local content language as $wgContLang
do that in ParserLimitReportFormat instead use this to modify the parameters of the image all existing parser cache entries will be invalid To avoid you ll need to handle that somehow(e.g. with the RejectParserCacheValue hook) because MediaWiki won 't do it for you. & $defaults also a ContextSource after deleting those rows but within the same transaction you ll probably need to make sure the header is varied on $request
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping $template
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output $out