X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FSpecialExport.php;h=2a0d13fda41889935ad766fdb1b87f34ae0d5e63;hb=960ed6ad88bc05c53961099a281c0feab2768264;hp=1f9a7f3a0e432d5ef8b5c996d2abe33c63ca8f0d;hpb=7a9219be74758313796d2c17684ae2c6e95cf728;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/SpecialExport.php b/includes/SpecialExport.php index 1f9a7f3a0e..2a0d13fda4 100644 --- a/includes/SpecialExport.php +++ b/includes/SpecialExport.php @@ -18,64 +18,260 @@ # http://www.gnu.org/copyleft/gpl.html /** * - * @package MediaWiki - * @subpackage SpecialPage + * @addtogroup SpecialPage */ -/** */ -require_once( 'Export.php' ); +function wfExportGetPagesFromCategory( $title ) { + global $wgContLang; + + $name = $title->getDBkey(); + + $dbr = wfGetDB( DB_SLAVE ); + + list( $page, $categorylinks ) = $dbr->tableNamesN( 'page', 'categorylinks' ); + $sql = "SELECT page_namespace, page_title FROM $page " . + "JOIN $categorylinks ON cl_from = page_id " . + "WHERE cl_to = " . $dbr->addQuotes( $name ); + + $pages = array(); + $res = $dbr->query( $sql, 'wfExportGetPagesFromCategory' ); + while ( $row = $dbr->fetchObject( $res ) ) { + $n = $row->page_title; + if ($row->page_namespace) { + $ns = $wgContLang->getNsText( $row->page_namespace ); + $n = $ns . ':' . $n; + } + + $pages[] = $n; + } + $dbr->freeResult($res); + + return $pages; +} + +/** + * Expand a list of pages to include templates used in those pages. + * @param $inputPages array, list of titles to look up + * @param $pageSet array, associative array indexed by titles for output + * @return array associative array index by titles + */ +function wfExportGetTemplates( $inputPages, $pageSet ) { + return wfExportGetLinks( $inputPages, $pageSet, + 'templatelinks', + array( 'tl_namespace AS namespace', 'tl_title AS title' ), + array( 'page_id=tl_from' ) ); +} + +/** + * Expand a list of pages to include images used in those pages. + * @param $inputPages array, list of titles to look up + * @param $pageSet array, associative array indexed by titles for output + * @return array associative array index by titles + */ +function wfExportGetImages( $inputPages, $pageSet ) { + return wfExportGetLinks( $inputPages, $pageSet, + 'imagelinks', + array( NS_IMAGE . ' AS namespace', 'il_to AS title' ), + array( 'page_id=il_from' ) ); +} + +/** + * Expand a list of pages to include items used in those pages. + * @private + */ +function wfExportGetLinks( $inputPages, $pageSet, $table, $fields, $join ) { + $dbr = wfGetDB( DB_SLAVE ); + foreach( $inputPages as $page ) { + $title = Title::newFromText( $page ); + $pageSet[$title->getPrefixedText()] = true; + if( $title ) { + /// @fixme May or may not be more efficient to batch these + /// by namespace when given multiple input pages. + $result = $dbr->select( + array( 'page', $table ), + $fields, + array_merge( $join, + array( + 'page_namespace' => $title->getNamespace(), + 'page_title' => $title->getDbKey() ) ), + __METHOD__ ); + foreach( $result as $row ) { + $template = Title::makeTitle( $row->namespace, $row->title ); + $pageSet[$template->getPrefixedText()] = true; + } + } + } + return $pageSet; +} /** * */ function wfSpecialExport( $page = '' ) { - global $wgOut, $wgRequest, $wgExportAllowListContributors; - global $wgExportAllowHistory; + global $wgOut, $wgRequest, $wgSitename, $wgExportAllowListContributors; + global $wgExportAllowHistory, $wgExportMaxHistory; + + $curonly = true; + $doexport = false; - if( $wgRequest->getVal( 'action' ) == 'submit') { + if ( $wgRequest->getCheck( 'addcat' ) ) { $page = $wgRequest->getText( 'pages' ); - if( $wgExportAllowHistory ) { - $curonly = $wgRequest->getCheck( 'curonly' ); + $catname = $wgRequest->getText( 'catname' ); + + if ( $catname !== '' && $catname !== NULL && $catname !== false ) { + $t = Title::makeTitleSafe( NS_CATEGORY, $catname ); + if ( $t ) { + /** + * @fixme This can lead to hitting memory limit for very large + * categories. Ideally we would do the lookup synchronously + * during the export in a single query. + */ + $catpages = wfExportGetPagesFromCategory( $t ); + if ( $catpages ) $page .= "\n" . implode( "\n", $catpages ); + } + } + } + else if( $wgRequest->wasPosted() && $page == '' ) { + $page = $wgRequest->getText( 'pages' ); + $curonly = $wgRequest->getCheck( 'curonly' ); + $rawOffset = $wgRequest->getVal( 'offset' ); + if( $rawOffset ) { + $offset = wfTimestamp( TS_MW, $rawOffset ); } else { - $curonly = true; + $offset = null; } + $limit = $wgRequest->getInt( 'limit' ); + $dir = $wgRequest->getVal( 'dir' ); + $history = array( + 'dir' => 'asc', + 'offset' => false, + 'limit' => $wgExportMaxHistory, + ); + $historyCheck = $wgRequest->getCheck( 'history' ); + if ( $curonly ) { + $history = WikiExporter::CURRENT; + } elseif ( !$historyCheck ) { + if ( $limit > 0 && $limit < $wgExportMaxHistory ) { + $history['limit'] = $limit; + } + if ( !is_null( $offset ) ) { + $history['offset'] = $offset; + } + if ( strtolower( $dir ) == 'desc' ) { + $history['dir'] = 'desc'; + } + } + + if( $page != '' ) $doexport = true; } else { - # Pre-check the 'current version only' box in the UI - $curonly = true; + // Default to current-only for GET requests + $page = $wgRequest->getText( 'pages', $page ); + $historyCheck = $wgRequest->getCheck( 'history' ); + if( $historyCheck ) { + $history = WikiExporter::FULL; + } else { + $history = WikiExporter::CURRENT; + } + + if( $page != '' ) $doexport = true; + } + + if( !$wgExportAllowHistory ) { + // Override + $history = WikiExporter::CURRENT; } $list_authors = $wgRequest->getCheck( 'listauthors' ); if ( !$curonly || !$wgExportAllowListContributors ) $list_authors = false ; - - if( $page != '' ) { + + if ( $doexport ) { $wgOut->disable(); + + // Cancel output buffering and gzipping if set + // This should provide safer streaming for pages with history + wfResetOutputBuffers(); header( "Content-type: application/xml; charset=utf-8" ); - $pages = explode( "\n", $page ); + if( $wgRequest->getCheck( 'wpDownload' ) ) { + // Provide a sane filename suggestion + $filename = urlencode( $wgSitename . '-' . wfTimestampNow() . '.xml' ); + $wgRequest->response()->header( "Content-disposition: attachment;filename={$filename}" ); + } + + /* Split up the input and look up linked pages */ + $inputPages = array_filter( explode( "\n", $page ) ); + $pageSet = array_flip( $inputPages ); + + if( $wgRequest->getCheck( 'templates' ) ) { + $pageSet = wfExportGetTemplates( $inputPages, $pageSet ); + } + + /* + // Enable this when we can do something useful exporting/importing image information. :) + if( $wgRequest->getCheck( 'images' ) ) { + $pageSet = wfExportGetImages( $inputPages, $pageSet ); + } + */ + + $pages = array_keys( $pageSet ); + + /* Ok, let's get to it... */ - $db =& wfGetDB( DB_SLAVE ); - $history = $curonly ? MW_EXPORT_CURRENT : MW_EXPORT_FULL; + $db = wfGetDB( DB_SLAVE ); $exporter = new WikiExporter( $db, $history ); $exporter->list_authors = $list_authors ; $exporter->openStream(); - $exporter->pagesByName( $pages ); + + foreach( $pages as $page ) { + /* + if( $wgExportMaxHistory && !$curonly ) { + $title = Title::newFromText( $page ); + if( $title ) { + $count = Revision::countByTitle( $db, $title ); + if( $count > $wgExportMaxHistory ) { + wfDebug( __FUNCTION__ . + ": Skipped $page, $count revisions too big\n" ); + continue; + } + } + }*/ + + #Bug 8824: Only export pages the user can read + $title = Title::newFromText( $page ); + if( is_null( $title ) ) continue; #TODO: perhaps output an tag or something. + if( !$title->userCan( 'read' ) ) continue; #TODO: perhaps output an tag or something. + + $exporter->pageByTitle( $title ); + } + $exporter->closeStream(); return; } - $wgOut->addWikiText( wfMsg( "exporttext" ) ); - $titleObj = Title::makeTitle( NS_SPECIAL, "Export" ); + $self = SpecialPage::getTitleFor( 'Export' ); + $wgOut->addHtml( wfMsgExt( 'exporttext', 'parse' ) ); + + $form = Xml::openElement( 'form', array( 'method' => 'post', + 'action' => $self->getLocalUrl( 'action=submit' ) ) ); + + $form .= Xml::inputLabel( wfMsg( 'export-addcattext' ) , 'catname', 'catname', 40 ) . ' '; + $form .= Xml::submitButton( wfMsg( 'export-addcat' ), array( 'name' => 'addcat' ) ) . '
'; + + $form .= Xml::openElement( 'textarea', array( 'name' => 'pages', 'cols' => 40, 'rows' => 10 ) ); + $form .= htmlspecialchars( $page ); + $form .= Xml::closeElement( 'textarea' ); + $form .= '
'; - $form = wfOpenElement( 'form', array( 'method' => 'post', 'action' => $titleObj->getLocalUrl() ) ); - $form .= wfOpenElement( 'textarea', array( 'name' => 'pages', 'cols' => 40, 'rows' => 10 ) ) . '
'; if( $wgExportAllowHistory ) { - $form .= wfCheck( 'curonly', true, array( 'value' => 'true', 'id' => 'curonly' ) ); - $form .= wfLabel( wfMsg( 'exportcuronly' ), 'curonly' ) . '
'; + $form .= Xml::checkLabel( wfMsg( 'exportcuronly' ), 'curonly', 'curonly', true ) . '
'; } else { - $wgOut->addWikiText( wfMsg( 'exportnohistory' ) ); + $wgOut->addHtml( wfMsgExt( 'exportnohistory', 'parse' ) ); } - $form .= wfHidden( 'action', 'submit' ); - $form .= wfSubmitButton( wfMsg( 'export-submit' ) ) . ''; + $form .= Xml::checkLabel( wfMsg( 'export-templates' ), 'templates', 'wpExportTemplates', false ) . '
'; + // Enable this when we can do something useful exporting/importing image information. :) + //$form .= Xml::checkLabel( wfMsg( 'export-images' ), 'images', 'wpExportImages', false ) . '
'; + $form .= Xml::checkLabel( wfMsg( 'export-download' ), 'wpDownload', 'wpDownload', true ) . '
'; + + $form .= Xml::submitButton( wfMsg( 'export-submit' ) ); + $form .= Xml::closeElement( 'form' ); $wgOut->addHtml( $form ); -} - -?> +} \ No newline at end of file