Move up devunt's name to Developers
[lhc/web/wiklou.git] / includes / Import.php
index de453b5..c2fae30 100644 (file)
@@ -34,7 +34,7 @@ class WikiImporter {
        private $reader = null;
        private $foreignNamespaces = null;
        private $mLogItemCallback, $mUploadCallback, $mRevisionCallback, $mPageCallback;
-       private $mSiteInfoCallback, $mTargetNamespace, $mPageOutCallback;
+       private $mSiteInfoCallback, $mPageOutCallback;
        private $mNoticeCallback, $mDebug;
        private $mImportUploads, $mImageBasePath;
        private $mNoUpdates = false;
@@ -49,8 +49,13 @@ class WikiImporter {
         * Creates an ImportXMLReader drawing from the source provided
         * @param ImportSource $source
         * @param Config $config
+        * @throws Exception
         */
        function __construct( ImportSource $source, Config $config = null ) {
+               if ( !class_exists( 'XMLReader' ) ) {
+                       throw new Exception( 'Import requires PHP to have been compiled with libxml support' );
+               }
+
                $this->reader = new XMLReader();
                if ( !$config ) {
                        wfDeprecated( __METHOD__ . ' without a Config instance', '1.25' );
@@ -62,11 +67,22 @@ class WikiImporter {
                        stream_wrapper_register( 'uploadsource', 'UploadSourceAdapter' );
                }
                $id = UploadSourceAdapter::registerSource( $source );
+
+               // Enable the entity loader, as it is needed for loading external URLs via
+               // XMLReader::open (T86036)
+               $oldDisable = libxml_disable_entity_loader( false );
                if ( defined( 'LIBXML_PARSEHUGE' ) ) {
-                       $this->reader->open( "uploadsource://$id", null, LIBXML_PARSEHUGE );
+                       $status = $this->reader->open( "uploadsource://$id", null, LIBXML_PARSEHUGE );
                } else {
-                       $this->reader->open( "uploadsource://$id" );
+                       $status = $this->reader->open( "uploadsource://$id" );
+               }
+               if ( !$status ) {
+                       $error = libxml_get_last_error();
+                       libxml_disable_entity_loader( $oldDisable );
+                       throw new MWException( 'Encountered an internal error while initializing WikiImporter object: ' .
+                               $error->message );
                }
+               libxml_disable_entity_loader( $oldDisable );
 
                // Default callbacks
                $this->setPageCallback( array( $this, 'beforeImportPage' ) );
@@ -224,7 +240,6 @@ class WikiImporter {
        public function setTargetNamespace( $namespace ) {
                if ( is_null( $namespace ) ) {
                        // Don't override namespaces
-                       $this->mTargetNamespace = null;
                        $this->setImportTitleFactory( new NaiveImportTitleFactory() );
                        return true;
                } elseif (
@@ -232,7 +247,6 @@ class WikiImporter {
                        MWNamespace::exists( intval( $namespace ) )
                ) {
                        $namespace = intval( $namespace );
-                       $this->mTargetNamespace = $namespace;
                        $this->setImportTitleFactory( new NamespaceImportTitleFactory( $namespace ) );
                        return true;
                } else {
@@ -252,10 +266,7 @@ class WikiImporter {
                        $this->setImportTitleFactory( new NaiveImportTitleFactory() );
                } elseif ( $rootpage !== '' ) {
                        $rootpage = rtrim( $rootpage, '/' ); //avoid double slashes
-                       $title = Title::newFromText( $rootpage, !is_null( $this->mTargetNamespace )
-                               ? $this->mTargetNamespace
-                               : NS_MAIN
-                       );
+                       $title = Title::newFromText( $rootpage );
 
                        if ( !$title || $title->isExternal() ) {
                                $status->fatal( 'import-rootpage-invalid' );
@@ -375,14 +386,19 @@ class WikiImporter {
                $page = WikiPage::factory( $title );
                $page->loadPageData( 'fromdbmaster' );
                $content = $page->getContent();
-               $editInfo = $page->prepareContentForEdit( $content );
-               $countKey = 'title_' . $title->getPrefixedText();
-               $countable = $page->isCountable( $editInfo );
-               if ( array_key_exists( $countKey, $this->countableCache ) &&
-                       $countable != $this->countableCache[ $countKey ] ) {
-                       DeferredUpdates::addUpdate( SiteStatsUpdate::factory( array(
-                               'articles' => ( (int)$countable - (int)$this->countableCache[ $countKey ] )
-                       ) ) );
+               if ( $content === null ) {
+                       wfDebug( __METHOD__ . ': Skipping article count adjustment for ' . $title .
+                               ' because WikiPage::getContent() returned null' );
+               } else {
+                       $editInfo = $page->prepareContentForEdit( $content );
+                       $countKey = 'title_' . $title->getPrefixedText();
+                       $countable = $page->isCountable( $editInfo );
+                       if ( array_key_exists( $countKey, $this->countableCache ) &&
+                               $countable != $this->countableCache[ $countKey ] ) {
+                               DeferredUpdates::addUpdate( SiteStatsUpdate::factory( array(
+                                       'articles' => ( (int)$countable - (int)$this->countableCache[ $countKey ] )
+                               ) ) );
+                       }
                }
 
                $args = func_get_args();
@@ -523,10 +539,10 @@ class WikiImporter {
                $oldDisable = libxml_disable_entity_loader( true );
                $this->reader->read();
 
-               if ( $this->reader->name != 'mediawiki' ) {
+               if ( $this->reader->localName != 'mediawiki' ) {
                        libxml_disable_entity_loader( $oldDisable );
                        throw new MWException( "Expected <mediawiki> tag, got " .
-                               $this->reader->name );
+                               $this->reader->localName );
                }
                $this->debug( "<mediawiki> tag is correct." );
 
@@ -537,7 +553,7 @@ class WikiImporter {
                $rethrow = null;
                try {
                        while ( $keepReading ) {
-                               $tag = $this->reader->name;
+                               $tag = $this->reader->localName;
                                $type = $this->reader->nodeType;
 
                                if ( !Hooks::run( 'ImportHandleToplevelXMLTag', array( $this ) ) ) {
@@ -588,11 +604,11 @@ class WikiImporter {
 
                while ( $this->reader->read() ) {
                        if ( $this->reader->nodeType == XmlReader::END_ELEMENT &&
-                                       $this->reader->name == 'siteinfo' ) {
+                                       $this->reader->localName == 'siteinfo' ) {
                                break;
                        }
 
-                       $tag = $this->reader->name;
+                       $tag = $this->reader->localName;
 
                        if ( $tag == 'namespace' ) {
                                $this->foreignNamespaces[ $this->nodeAttribute( 'key' ) ] =
@@ -616,11 +632,11 @@ class WikiImporter {
 
                while ( $this->reader->read() ) {
                        if ( $this->reader->nodeType == XMLReader::END_ELEMENT &&
-                                       $this->reader->name == 'logitem' ) {
+                                       $this->reader->localName == 'logitem' ) {
                                break;
                        }
 
-                       $tag = $this->reader->name;
+                       $tag = $this->reader->localName;
 
                        if ( !Hooks::run( 'ImportHandleLogItemXMLTag', array(
                                $this, $logInfo
@@ -680,13 +696,13 @@ class WikiImporter {
 
                while ( $skip ? $this->reader->next() : $this->reader->read() ) {
                        if ( $this->reader->nodeType == XMLReader::END_ELEMENT &&
-                                       $this->reader->name == 'page' ) {
+                                       $this->reader->localName == 'page' ) {
                                break;
                        }
 
                        $skip = false;
 
-                       $tag = $this->reader->name;
+                       $tag = $this->reader->localName;
 
                        if ( $badTitle ) {
                                // The title is invalid, bail out of this page
@@ -753,11 +769,11 @@ class WikiImporter {
 
                while ( $skip ? $this->reader->next() : $this->reader->read() ) {
                        if ( $this->reader->nodeType == XMLReader::END_ELEMENT &&
-                                       $this->reader->name == 'revision' ) {
+                                       $this->reader->localName == 'revision' ) {
                                break;
                        }
 
-                       $tag = $this->reader->name;
+                       $tag = $this->reader->localName;
 
                        if ( !Hooks::run( 'ImportHandleRevisionXMLTag', array(
                                $this, $pageInfo, $revisionInfo
@@ -845,11 +861,11 @@ class WikiImporter {
 
                while ( $skip ? $this->reader->next() : $this->reader->read() ) {
                        if ( $this->reader->nodeType == XMLReader::END_ELEMENT &&
-                                       $this->reader->name == 'upload' ) {
+                                       $this->reader->localName == 'upload' ) {
                                break;
                        }
 
-                       $tag = $this->reader->name;
+                       $tag = $this->reader->localName;
 
                        if ( !Hooks::run( 'ImportHandleUploadXMLTag', array(
                                $this, $pageInfo
@@ -943,11 +959,11 @@ class WikiImporter {
 
                while ( $this->reader->read() ) {
                        if ( $this->reader->nodeType == XMLReader::END_ELEMENT &&
-                                       $this->reader->name == 'contributor' ) {
+                                       $this->reader->localName == 'contributor' ) {
                                break;
                        }
 
-                       $tag = $this->reader->name;
+                       $tag = $this->reader->localName;
 
                        if ( in_array( $tag, $fields ) ) {
                                $info[$tag] = $this->nodeContents();