38 parent::__construct(
'Export' );
47 $this->curonly =
true;
50 $this->templates = $request->getCheck(
'templates' );
52 $request->getIntOrNull(
'pagelink-depth' )
57 if ( $request->getCheck(
'addcat' ) ) {
58 $page = $request->getText(
'pages' );
59 $catname = $request->getText(
'catname' );
61 if ( $catname !==
'' && $catname !==
null && $catname !==
false ) {
74 $page .= implode(
"\n", $catpages );
78 } elseif ( $request->getCheck(
'addns' ) && $config->get(
'ExportFromNamespaces' ) ) {
79 $page = $request->getText(
'pages' );
80 $nsindex = $request->getText(
'nsindex',
'' );
82 if ( strval( $nsindex ) !==
'' ) {
88 $page .=
"\n" . implode(
"\n", $nspages );
91 } elseif ( $request->getCheck(
'exportall' ) && $config->get(
'ExportAllowAll' ) ) {
101 } elseif ( $request->wasPosted() && $par ==
'' ) {
104 LoggerFactory::getInstance(
'export' )->debug(
105 'Special:Export POST, dir: [{dir}], offset: [{offset}], limit: [{limit}]', [
106 'dir' => $request->getRawVal(
'dir' ),
107 'offset' => $request->getRawVal(
'offset' ),
108 'limit' => $request->getRawVal(
'limit' ),
111 $page = $request->getText(
'pages' );
112 $this->curonly = $request->getCheck(
'curonly' );
113 $rawOffset = $request->getVal(
'offset' );
121 $maxHistory = $config->get(
'ExportMaxHistory' );
122 $limit = $request->getInt(
'limit' );
123 $dir = $request->getVal(
'dir' );
127 'limit' => $maxHistory,
129 $historyCheck = $request->getCheck(
'history' );
131 if ( $this->curonly ) {
133 } elseif ( !$historyCheck ) {
134 if ( $limit > 0 && ( $maxHistory == 0 || $limit < $maxHistory ) ) {
135 $history[
'limit'] = $limit;
138 if ( !is_null( $offset ) ) {
139 $history[
'offset'] = $offset;
142 if ( strtolower( $dir ) ==
'desc' ) {
143 $history[
'dir'] =
'desc';
152 $page = $request->getText(
'pages', $par );
153 $historyCheck = $request->getCheck(
'history' );
155 if ( $historyCheck ) {
166 if ( !$config->get(
'ExportAllowHistory' ) ) {
171 $list_authors = $request->getCheck(
'listauthors' );
172 if ( !$this->curonly || !$config->get(
'ExportAllowListContributors' ) ) {
173 $list_authors =
false;
182 $request->response()->header(
"Content-type: application/xml; charset=utf-8" );
183 $request->response()->header(
"X-Robots-Tag: noindex,nofollow" );
185 if ( $request->getCheck(
'wpDownload' ) ) {
187 $filename = urlencode( $config->get(
'Sitename' ) .
'-' .
wfTimestampNow() .
'.xml' );
188 $request->response()->header(
"Content-disposition: attachment;filename={$filename}" );
191 $this->
doExport( $page, $history, $list_authors, $exportall );
197 $out->addWikiMsg(
'exporttext' );
200 $categoryName = $request->getText(
'catname' );
207 'type' =>
'textwithbutton',
209 'horizontal-label' =>
true,
210 'label-message' =>
'export-addcattext',
211 'default' => $categoryName,
213 'buttontype' =>
'submit',
214 'buttonname' =>
'addcat',
215 'buttondefault' => $this->
msg(
'export-addcat' )->text(),
216 'hide-if' => [
'===',
'exportall',
'1' ],
219 if ( $config->get(
'ExportFromNamespaces' ) ) {
222 'type' =>
'namespaceselectwithbutton',
223 'default' => $nsindex,
224 'label-message' =>
'export-addnstext',
225 'horizontal-label' =>
true,
228 'cssclass' =>
'namespaceselector',
229 'buttontype' =>
'submit',
230 'buttonname' =>
'addns',
231 'buttondefault' => $this->
msg(
'export-addns' )->text(),
232 'hide-if' => [
'===',
'exportall',
'1' ],
237 if ( $config->get(
'ExportAllowAll' ) ) {
241 'label-message' =>
'exportall',
242 'name' =>
'exportall',
244 'default' => $request->wasPosted() ? $request->getCheck(
'exportall' ) :
false,
251 'class' => HTMLTextAreaField::class,
253 'label-message' =>
'export-manual',
257 'hide-if' => [
'===',
'exportall',
'1' ],
261 if ( $config->get(
'ExportAllowHistory' ) ) {
265 'label-message' =>
'exportcuronly',
268 'default' => $request->wasPosted() ? $request->getCheck(
'curonly' ) :
true,
272 $out->addWikiMsg(
'exportnohistory' );
278 'label-message' =>
'export-templates',
279 'name' =>
'templates',
280 'id' =>
'wpExportTemplates',
281 'default' => $request->wasPosted() ? $request->getCheck(
'templates' ) :
false,
287 'pagelink-depth' => [
289 'name' =>
'pagelink-depth',
290 'id' =>
'pagelink-depth',
291 'label-message' =>
'export-pagelinks',
301 'name' =>
'wpDownload',
302 'id' =>
'wpDownload',
303 'default' => $request->wasPosted() ? $request->getCheck(
'wpDownload' ) :
true,
304 'label-message' =>
'export-download',
308 if ( $config->get(
'ExportAllowListContributors' ) ) {
312 'label-message' =>
'exportlistauthors',
313 'default' => $request->wasPosted() ? $request->getCheck(
'listauthors' ) :
false,
314 'name' =>
'listauthors',
315 'id' =>
'listauthors',
321 $htmlForm->setSubmitTextMsg(
'export-submit' );
322 $htmlForm->prepareForm()->displayForm(
false );
330 return MediaWikiServices::getInstance()
331 ->getPermissionManager()
332 ->userHasRight( $this->
getUser(),
'override-export-depth' );
344 private function doExport( $page, $history, $list_authors, $exportall ) {
352 foreach ( explode(
"\n", $page ) as $pageName ) {
353 $pageName = trim( $pageName );
357 $pageSet[
$title->getPrefixedText()] =
true;
362 $inputPages = array_keys( $pageSet );
365 if ( $this->templates ) {
366 $pageSet = $this->
getTemplates( $inputPages, $pageSet );
370 $pageSet = $this->
getPageLinks( $inputPages, $pageSet, $linkDepth );
373 $pages = array_keys( $pageSet );
376 foreach ( $pages as $k => $v ) {
377 $pages[$k] = str_replace(
" ",
"_", $v );
380 $pages = array_unique( $pages );
387 $exporter->list_authors = $list_authors;
388 $exporter->openStream();
391 $exporter->allPages();
393 $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
395 foreach ( $pages as $page ) {
396 # T10824: Only export pages the user can read
398 if ( is_null(
$title ) ) {
403 if ( !$permissionManager->userCan(
'read', $this->getUser(),
$title ) ) {
408 $exporter->pageByTitle(
$title );
412 $exporter->closeStream();
420 $maxPages = $this->
getConfig()->get(
'ExportPagelistLimit' );
422 $name =
$title->getDBkey();
426 [
'page',
'categorylinks' ],
427 [
'page_namespace',
'page_title' ],
428 [
'cl_from=page_id',
'cl_to' => $name ],
430 [
'LIMIT' => $maxPages ]
435 foreach (
$res as $row ) {
447 $maxPages = $this->
getConfig()->get(
'ExportPagelistLimit' );
452 [
'page_namespace',
'page_title' ],
453 [
'page_namespace' => $nsindex ],
455 [
'LIMIT' => $maxPages ]
460 foreach (
$res as $row ) {
474 return $this->
getLinks( $inputPages, $pageSet,
476 [
'namespace' =>
'tl_namespace',
'title' =>
'tl_title' ],
477 [
'page_id=tl_from' ]
492 $maxLinkDepth = $this->
getConfig()->get(
'ExportMaxLinkDepth' );
493 if ( $depth > $maxLinkDepth ) {
494 return $maxLinkDepth;
504 return intval( min( $depth, 5 ) );
515 for ( ; $depth > 0; --$depth ) {
517 $inputPages, $pageSet,
'pagelinks',
518 [
'namespace' =>
'pl_namespace',
'title' =>
'pl_title' ],
519 [
'page_id=pl_from' ]
521 $inputPages = array_keys( $pageSet );
536 private function getLinks( $inputPages, $pageSet, $table, $fields, $join ) {
539 foreach ( $inputPages as $page ) {
543 $pageSet[
$title->getPrefixedText()] =
true;
546 $result =
$dbr->select(
552 'page_namespace' =>
$title->getNamespace(),
553 'page_title' =>
$title->getDBkey()
559 foreach ( $result as $row ) {
561 $pageSet[$template->getPrefixedText()] =
true;