setHeaders(); if ( ! $this->getUser()->isAllowed( 'datatransferimport' ) ) { throw new PermissionsError( 'datatransferimport' ); } if ( $this->getRequest()->getCheck( 'import_file' ) ) { $text = $this->importFromUploadAndModifyPages(); } else { $text = $this->printForm(); } $this->getOutput()->addModuleStyles( 'ext.datatransfer'); $this->getOutput()->addHTML( $text ); } protected function importFromUploadAndModifyPages () { $text = DTUtils::printImportingMessage(); $uploadResult = ImportStreamSource::newFromUpload( "file_name" ); if ( !$uploadResult->isOK() ) { $uploadError = $this->getOutput()->parse( $uploadResult->getWikiText() ); $text .= $uploadError; return $text; } $source = $uploadResult->value; $encoding = $this->getRequest()->getVal( 'encoding' ); $pages = array(); $error_msg = $this->importFromFile( $source->mHandle, $encoding, $pages ); if ( ! is_null( $error_msg ) ) { $text .= $error_msg; return $text; } $importSummary = $this->getRequest()->getVal( 'import_summary' ); $forPagesThatExist = $this->getRequest()->getVal( 'pagesThatExist' ); $text .= self::modifyPages( $pages, $importSummary, $forPagesThatExist ); return $text; } protected function printForm() { $formText = DTUtils::printFileSelector( $this->getFiletype() ); $utf8OptionText = "\t" . Xml::element( 'option', array( 'selected' => 'selected', 'value' => 'utf8' ), 'UTF-8' ) . "\n"; $utf16OptionText = "\t" . Xml::element( 'option', array( 'value' => 'utf16' ), 'UTF-16' ) . "\n"; $encodingSelectText = Xml::tags( 'select', array( 'name' => 'encoding' ), "\n" . $utf8OptionText . $utf16OptionText. "\t" ) . "\n\t"; $formText .= "\t" . Xml::tags( 'p', null, $this->msg( 'dt_import_encodingtype', 'CSV' )->text() . " " . $encodingSelectText ) . "\n"; $formText .= "\t" . '
' . "\n"; $formText .= DTUtils::printExistingPagesHandling(); $formText .= DTUtils::printImportSummaryInput( $this->getFiletype() ); $formText .= DTUtils::printSubmitButton(); $text = "\t" . Xml::tags( 'form', array( 'enctype' => 'multipart/form-data', 'action' => '', 'method' => 'post' ), $formText ) . "\n"; return $text; } protected function importFromFile( $csv_file, $encoding, &$pages ) { if ( is_null( $csv_file ) ) { return wfMessage( 'emptyfile' )->text(); } $table = array(); if ( $encoding == 'utf16' ) { // Change encoding to UTF-8. // Starting with PHP 5.3 we could use str_getcsv(), // which would save the tempfile hassle. $tempfile = tmpfile(); $csv_string = ''; while ( !feof( $csv_file ) ) { $csv_string .= fgets( $csv_file, 65535 ); } fwrite( $tempfile, iconv( 'UTF-16', 'UTF-8', $csv_string ) ); fseek( $tempfile, 0 ); while ( $line = fgetcsv( $tempfile ) ) { array_push( $table, $line ); } fclose( $tempfile ); } else { while ( $line = fgetcsv( $csv_file ) ) { // Convert from UTF-8 to ASCII - htmlentities() // fails for UTF-8 if there are non-ASCII // characters. // $convertedLine = array(); // foreach ( $line as $value ) { // $convertedLine[] = mb_convert_encoding( $value, 'UTF-8', 'ASCII' ); // } array_push( $table, $line ); } } fclose( $csv_file ); // Get rid of the "byte order mark", if it's there - this is // a three-character string sometimes put at the beginning // of files to indicate its encoding. // Code copied from: // http://www.dotvoid.com/2010/04/detecting-utf-bom-byte-order-mark/ $byteOrderMark = pack( "CCC", 0xef, 0xbb, 0xbf ); if ( 0 == strncmp( $table[0][0], $byteOrderMark, 3 ) ) { $table[0][0] = substr( $table[0][0], 3 ); // If there were quotation marks around this value, // they didn't get removed, so remove them now. $table[0][0] = trim( $table[0][0], '"' ); } return $this->importFromArray( $table, $pages ); } protected function importFromArray( $table, &$pages ) { // Check header line to make sure every term is in the // correct format. $titleLabels = array( wfMessage( 'dt_xml_title' )->inContentLanguage()->text() ); $freeTextLabels = array( wfMessage( 'dt_xml_freetext' )->inContentLanguage()->text() ); // Add the English-language values as well, if this isn't an // English-language wiki. if ( $this->getLanguage()->getCode() !== 'en' ) { $titleLabels[] = wfMessage( 'dt_xml_title' )->inLanguage( 'en' )->text(); $freeTextLabels[] = wfMessage( 'dt_xml_freetext' )->inLanguage( 'en' )->text(); } foreach ( $table[0] as $i => $headerVal ) { if ( !in_array( $headerVal, $titleLabels ) && !in_array( $headerVal, $freeTextLabels ) && $headerVal !== '' && !preg_match( '/^[^\[\]]+\[[^\[\]]+]$/', $headerVal ) ) { $errorMsg = wfMessage( 'dt_importcsv_badheader', $i, $headerVal, $titleLabels[0], $freeTextLabels[0] )->text(); return $errorMsg; } } foreach ( $table as $i => $line ) { if ( $i == 0 ) continue; $page = new DTPage(); foreach ( $line as $j => $val ) { if ( $table[0][$j] === '' ) { continue; } if ( in_array( $table[0][$j], $titleLabels ) ) { $page->setName( $val ); } elseif ( in_array( $table[0][$j], $freeTextLabels ) ) { $page->setFreeText( $val ); } else { list( $templateName, $fieldName ) = explode( '[', str_replace( ']', '', $table[0][$j] ) ); $page->addTemplateField( $templateName, $fieldName, $val ); } } $pages[] = $page; } return null; } protected function modifyPages( $pages, $editSummary, $forPagesThatExist ) { $text = ""; $jobs = array(); $jobParams = array(); $jobParams['user_id'] = $this->getUser()->getId(); $jobParams['edit_summary'] = $editSummary; $jobParams['for_pages_that_exist'] = $forPagesThatExist; foreach ( $pages as $page ) { $title = Title::newFromText( $page->getName() ); if ( is_null( $title ) ) { $text .= '

' . $this->msg( 'img-auth-badtitle', $page->getName() )->text() . "

\n"; continue; } $jobParams['text'] = $page->createText(); $jobs[] = new DTImportJob( $title, $jobParams ); } JobQueueGroup::singleton()->push( $jobs ); $text .= $this->msg( 'dt_import_success' )->numParams( count( $jobs ) )->params( $this->getFiletype() )->parseAsBlock(); return $text; } protected function getFiletype() { return wfMessage( 'dt_filetype_csv' )->text(); } }