'ForeignDBFile' => __DIR__ . '/includes/filerepo/file/ForeignDBFile.php',
'ForeignDBRepo' => __DIR__ . '/includes/filerepo/ForeignDBRepo.php',
'ForeignDBViaLBRepo' => __DIR__ . '/includes/filerepo/ForeignDBViaLBRepo.php',
+ 'ForeignTitle' => __DIR__ . '/includes/title/ForeignTitle.php',
+ 'ForeignTitleFactory' => __DIR__ . '/includes/title/ForeignTitleFactory.php',
'ForkController' => __DIR__ . '/includes/ForkController.php',
'FormAction' => __DIR__ . '/includes/actions/FormAction.php',
'FormOptions' => __DIR__ . '/includes/FormOptions.php',
'ImportSiteScripts' => __DIR__ . '/maintenance/importSiteScripts.php',
'ImportStreamSource' => __DIR__ . '/includes/Import.php',
'ImportStringSource' => __DIR__ . '/includes/Import.php',
+ 'ImportTitleFactory' => __DIR__ . '/includes/title/ImportTitleFactory.php',
'IncludableSpecialPage' => __DIR__ . '/includes/specialpage/IncludableSpecialPage.php',
'IndexPager' => __DIR__ . '/includes/pager/IndexPager.php',
'InfoAction' => __DIR__ . '/includes/actions/InfoAction.php',
'MySqlLockManager' => __DIR__ . '/includes/filebackend/lockmanager/DBLockManager.php',
'MysqlInstaller' => __DIR__ . '/includes/installer/MysqlInstaller.php',
'MysqlUpdater' => __DIR__ . '/includes/installer/MysqlUpdater.php',
+ 'NaiveForeignTitleFactory' => __DIR__ . '/includes/title/NaiveForeignTitleFactory.php',
+ 'NaiveImportTitleFactory' => __DIR__ . '/includes/title/NaiveImportTitleFactory.php',
+ 'NamespaceAwareForeignTitleFactory' => __DIR__ . '/includes/title/NamespaceAwareForeignTitleFactory.php',
'NamespaceConflictChecker' => __DIR__ . '/maintenance/namespaceDupes.php',
+ 'NamespaceImportTitleFactory' => __DIR__ . '/includes/title/NamespaceImportTitleFactory.php',
'NewFilesPager' => __DIR__ . '/includes/specials/SpecialNewimages.php',
'NewPagesPager' => __DIR__ . '/includes/specials/SpecialNewpages.php',
'NewUsersLogFormatter' => __DIR__ . '/includes/logging/NewUsersLogFormatter.php',
'StubObject' => __DIR__ . '/includes/StubObject.php',
'StubUserLang' => __DIR__ . '/includes/StubObject.php',
'SubmitAction' => __DIR__ . '/includes/actions/SubmitAction.php',
+ 'SubpageImportTitleFactory' => __DIR__ . '/includes/title/SubpageImportTitleFactory.php',
'SvgHandler' => __DIR__ . '/includes/media/SVG.php',
'SwiftFileBackend' => __DIR__ . '/includes/filebackend/SwiftFileBackend.php',
'SwiftFileBackendDirList' => __DIR__ . '/includes/filebackend/SwiftFileBackend.php',
'AfterImportPage': When a page import is completed.
$title: Title under which the revisions were imported
-$origTitle: Title provided by the XML file
+$foreignTitle: ForeignTitle object based on data provided by the XML file
$revCount: Number of revisions in the XML file
$sRevCount: Number of successfully imported revisions
$pageInfo: associative array of page information
*/
class WikiImporter {
private $reader = null;
+ private $foreignNamespaces = null;
private $mLogItemCallback, $mUploadCallback, $mRevisionCallback, $mPageCallback;
- private $mSiteInfoCallback, $mTargetNamespace, $mTargetRootPage, $mPageOutCallback;
+ private $mSiteInfoCallback, $mTargetNamespace, $mPageOutCallback;
private $mNoticeCallback, $mDebug;
private $mImportUploads, $mImageBasePath;
private $mNoUpdates = false;
/** @var Config */
private $config;
+ /** @var ImportTitleFactory */
+ private $importTitleFactory;
/**
* Creates an ImportXMLReader drawing from the source provided
$this->setUploadCallback( array( $this, 'importUpload' ) );
$this->setLogItemCallback( array( $this, 'importLogItem' ) );
$this->setPageOutCallback( array( $this, 'finishImportPage' ) );
+
+ $this->importTitleFactory = new NaiveImportTitleFactory();
}
/**
return $previous;
}
+ /**
+ * Sets the factory object to use to convert ForeignTitle objects into local
+ * Title objects
+ * @param ImportTitleFactory $factory
+ */
+ public function setImportTitleFactory( $factory ) {
+ $this->importTitleFactory = $factory;
+ }
+
/**
* Set a target namespace to override the defaults
* @param null|int $namespace
if ( is_null( $namespace ) ) {
// Don't override namespaces
$this->mTargetNamespace = null;
- } elseif ( $namespace >= 0 ) {
- // @todo FIXME: Check for validity
- $this->mTargetNamespace = intval( $namespace );
+ $this->setImportTitleFactory( new NaiveImportTitleFactory() );
+ return true;
+ } elseif (
+ $namespace >= 0 &&
+ MWNamespace::exists( intval( $namespace ) )
+ ) {
+ $namespace = intval( $namespace );
+ $this->mTargetNamespace = $namespace;
+ $this->setImportTitleFactory( new NamespaceImportTitleFactory( $namespace ) );
+ return true;
} else {
return false;
}
$status = Status::newGood();
if ( is_null( $rootpage ) ) {
// No rootpage
- $this->mTargetRootPage = null;
+ $this->setImportTitleFactory( new NaiveImportTitleFactory() );
} elseif ( $rootpage !== '' ) {
$rootpage = rtrim( $rootpage, '/' ); //avoid double slashes
$title = Title::newFromText( $rootpage, !is_null( $this->mTargetNamespace )
: $wgContLang->getNsText( $title->getNamespace() );
$status->fatal( 'import-rootpage-nosubpage', $displayNSText );
} else {
- // set namespace to 'all', so the namespace check in processTitle() can passed
+ // set namespace to 'all', so the namespace check in processTitle() can pass
$this->setTargetNamespace( null );
- $this->mTargetRootPage = $title->getPrefixedDBkey();
+ $this->setImportTitleFactory( new SubpageImportTitleFactory( $title ) );
}
}
}
/**
* Mostly for hook use
* @param Title $title
- * @param string $origTitle
+ * @param ForeignTitle $foreignTitle
* @param int $revCount
* @param int $sRevCount
* @param array $pageInfo
* @return bool
*/
- public function finishImportPage( $title, $origTitle, $revCount, $sRevCount, $pageInfo ) {
+ public function finishImportPage( $title, $foreignTitle, $revCount,
+ $sRevCount, $pageInfo ) {
$args = func_get_args();
return wfRunHooks( 'AfterImportPage', $args );
}
$this->debug( "-- Text: " . $revision->text );
}
+ /**
+ * Notify the callback function of site info
+ * @param array $siteInfo
+ * @return bool|mixed
+ */
+ private function siteInfoCallback( $siteInfo ) {
+ if ( isset( $this->mSiteInfoCallback ) ) {
+ return call_user_func_array( $this->mSiteInfoCallback,
+ array( $siteInfo, $this ) );
+ } else {
+ return false;
+ }
+ }
+
/**
* Notify the callback function when a new "<page>" is reached.
* @param Title $title
/**
* Notify the callback function when a "</page>" is closed.
* @param Title $title
- * @param Title $origTitle
+ * @param ForeignTitle $foreignTitle
* @param int $revCount
* @param int $sucCount Number of revisions for which callback returned true
* @param array $pageInfo Associative array of page information
*/
- private function pageOutCallback( $title, $origTitle, $revCount, $sucCount, $pageInfo ) {
+ private function pageOutCallback( $title, $foreignTitle, $revCount,
+ $sucCount, $pageInfo ) {
if ( isset( $this->mPageOutCallback ) ) {
$args = func_get_args();
call_user_func_array( $this->mPageOutCallback, $args );
return true;
}
- /**
- * @return bool
- * @throws MWException
- */
private function handleSiteInfo() {
- // Site info is useful, but not actually used for dump imports.
- // Includes a quick short-circuit to save performance.
- if ( !$this->mSiteInfoCallback ) {
- $this->reader->next();
- return true;
+ $this->debug( "Enter site info handler." );
+ $siteInfo = array();
+
+ // Fields that can just be stuffed in the siteInfo object
+ $normalFields = array( 'sitename', 'base', 'generator', 'case' );
+
+ while ( $this->reader->read() ) {
+ if ( $this->reader->nodeType == XmlReader::END_ELEMENT &&
+ $this->reader->name == 'siteinfo' ) {
+ break;
+ }
+
+ $tag = $this->reader->name;
+
+ if ( $tag == 'namespace' ) {
+ $this->foreignNamespaces[ $this->nodeAttribute( 'key' ) ] =
+ $this->nodeContents();
+ } elseif ( in_array( $tag, $normalFields ) ) {
+ $siteInfo[$tag] = $this->nodeContents();
+ }
}
- throw new MWException( "SiteInfo tag is not yet handled, do not set mSiteInfoCallback" );
+
+ $siteInfo['_namespaces'] = $this->foreignNamespaces;
+ $this->siteInfoCallback( $siteInfo );
}
private function handleLogItem() {
$pageInfo = array( 'revisionCount' => 0, 'successfulRevisionCount' => 0 );
// Fields that can just be stuffed in the pageInfo object
- $normalFields = array( 'title', 'id', 'redirect', 'restrictions' );
+ $normalFields = array( 'title', 'ns', 'id', 'redirect', 'restrictions' );
$skip = false;
$badTitle = false;
break;
}
+ $skip = false;
+
$tag = $this->reader->name;
if ( $badTitle ) {
$pageInfo[$tag] = $this->nodeAttribute( 'title' );
} else {
$pageInfo[$tag] = $this->nodeContents();
- if ( $tag == 'title' ) {
- $title = $this->processTitle( $pageInfo['title'] );
+ }
+ } elseif ( $tag == 'revision' || $tag == 'upload' ) {
+ if ( !isset( $title ) ) {
+ $title = $this->processTitle( $pageInfo['title'],
+ isset( $pageInfo['ns'] ) ? $pageInfo['ns'] : null );
+
+ if ( !$title ) {
+ $badTitle = true;
+ $skip = true;
+ }
- if ( !$title ) {
- $badTitle = true;
- $skip = true;
- }
+ $this->pageCallback( $title );
+ list( $pageInfo['_title'], $foreignTitle ) = $title;
+ }
- $this->pageCallback( $title );
- list( $pageInfo['_title'], $origTitle ) = $title;
+ if ( $title ) {
+ if ( $tag == 'revision' ) {
+ $this->handleRevision( $pageInfo );
+ } else {
+ $this->handleUpload( $pageInfo );
}
}
- } elseif ( $tag == 'revision' ) {
- $this->handleRevision( $pageInfo );
- } elseif ( $tag == 'upload' ) {
- $this->handleUpload( $pageInfo );
} elseif ( $tag != '#text' ) {
$this->warn( "Unhandled page XML tag $tag" );
$skip = true;
}
}
- $this->pageOutCallback( $pageInfo['_title'], $origTitle,
+ $this->pageOutCallback( $pageInfo['_title'], $foreignTitle,
$pageInfo['revisionCount'],
$pageInfo['successfulRevisionCount'],
$pageInfo );
/**
* @param string $text
+ * @param string|null $ns
* @return array|bool
*/
- private function processTitle( $text ) {
- $workTitle = $text;
- $origTitle = Title::newFromText( $workTitle );
-
- if ( !is_null( $this->mTargetNamespace ) && !is_null( $origTitle ) ) {
- # makeTitleSafe, because $origTitle can have a interwiki (different setting of interwiki map)
- # and than dbKey can begin with a lowercase char
- $title = Title::makeTitleSafe( $this->mTargetNamespace,
- $origTitle->getDBkey() );
+ private function processTitle( $text, $ns = null ) {
+ if ( is_null( $this->foreignNamespaces ) ) {
+ $foreignTitleFactory = new NaiveForeignTitleFactory();
} else {
- if ( !is_null( $this->mTargetRootPage ) ) {
- $workTitle = $this->mTargetRootPage . '/' . $workTitle;
- }
- $title = Title::newFromText( $workTitle );
+ $foreignTitleFactory = new NamespaceAwareForeignTitleFactory(
+ $this->foreignNamespaces );
}
+ $foreignTitle = $foreignTitleFactory->createForeignTitle( $text,
+ intval( $ns ) );
+
+ $title = $this->importTitleFactory->createTitleFromForeignTitle(
+ $foreignTitle );
+
$commandLineMode = $this->config->get( 'CommandLineMode' );
if ( is_null( $title ) ) {
# Invalid page title? Ignore the page
- $this->notice( 'import-error-invalid', $workTitle );
+ $this->notice( 'import-error-invalid', $foreignTitle->getFullText() );
return false;
} elseif ( $title->isExternal() ) {
$this->notice( 'import-error-interwiki', $title->getPrefixedText() );
return false;
}
- return array( $title, $origTitle );
+ return array( $title, $foreignTitle );
}
}
/**
* @param Title $title
- * @param Title $origTitle
+ * @param ForeignTitle $foreignTitle
* @param int $revisionCount
* @param int $successCount
* @param array $pageInfo
* @return void
*/
- function reportPage( $title, $origTitle, $revisionCount, $successCount, $pageInfo ) {
+ function reportPage( $title, $foreignTitle, $revisionCount,
+ $successCount, $pageInfo ) {
$args = func_get_args();
call_user_func_array( $this->mOriginalPageOutCallback, $args );
$log->addEntry( 'upload', $title, $detail, array(), $this->getUser() );
} else {
$interwiki = '[[:' . $this->mInterwiki . ':' .
- $origTitle->getPrefixedText() . ']]';
+ $foreignTitle->getFullText() . ']]';
$detail = $this->msg( 'import-logentry-interwiki-detail' )->numParams(
$successCount )->params( $interwiki )->inContentLanguage()->text();
if ( $this->reason ) {
--- /dev/null
+<?php
+/**
+ * A structure to hold the title of a page on a foreign MediaWiki installation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @author This, that and the other
+ */
+
+/**
+ * A simple, immutable structure to hold the title of a page on a foreign
+ * MediaWiki installation.
+ */
+class ForeignTitle {
+ /**
+ * @var int|null
+ * Null if we don't know the namespace ID (e.g. interwiki links)
+ */
+ protected $namespaceId;
+ /** @var string */
+ protected $namespaceName;
+ /** @var string */
+ protected $pageName;
+
+ /**
+ * Creates a new ForeignTitle object.
+ *
+ * @param int|null $namespaceId Null if the namespace ID is unknown (e.g.
+ * interwiki links)
+ * @param string $namespaceName
+ * @param string $pageName
+ */
+ public function __construct( $namespaceId, $namespaceName, $pageName ) {
+ if ( is_null( $namespaceId ) ) {
+ $this->namespaceId = null;
+ } else {
+ $this->namespaceId = intval( $namespaceId );
+ }
+ $this->namespaceName = str_replace( ' ', '_', $namespaceName );
+ $this->pageName = str_replace( ' ', '_', $pageName );
+ }
+
+ /**
+ * Do we know the namespace ID of the page on the foreign wiki?
+ * @return bool
+ */
+ public function isNamespaceIdKnown() {
+ return !is_null( $this->namespaceId );
+ }
+
+ /**
+ * @return int
+ * @throws MWException If isNamespaceIdKnown() is false, it does not make
+ * sense to call this function.
+ */
+ public function getNamespaceId() {
+ if ( is_null( $this->namespaceId ) ) {
+ throw new MWException(
+ "Attempted to call getNamespaceId when the namespace ID is not known" );
+ }
+ return $this->namespaceId;
+ }
+
+ /** @return string */
+ public function getNamespaceName() {
+ return $this->namespaceName;
+ }
+
+ /** @return string */
+ public function getText() {
+ return $this->pageName;
+ }
+
+ /** @return string */
+ public function getFullText() {
+ $result = '';
+ if ( $this->namespaceName ) {
+ $result .= $this->namespaceName . ':';
+ }
+ $result .= $this->pageName;
+ return $result;
+ }
+
+ /**
+ * Returns a string representation of the title, for logging. This is purely
+ * informative and must not be used programmatically. Use the appropriate
+ * ImportTitleFactory to generate the correct string representation for a
+ * given use.
+ *
+ * @return string
+ */
+ public function __toString() {
+ $name = '';
+ if ( $this->isNamespaceIdKnown() ) {
+ $name .= '{ns' . $this->namespaceId . '}';
+ } else {
+ $name .= '{ns??}';
+ }
+ $name .= $this->namespaceName . ':' . $this->pageName;
+
+ return $name;
+ }
+}
--- /dev/null
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @license GPL 2+
+ */
+
+/**
+ * A parser that translates page titles into ForeignTitle objects.
+ */
+interface ForeignTitleFactory {
+ /**
+ * Creates a ForeignTitle object based on the page title, and optionally the
+ * namespace ID, of a page on a foreign wiki. These values could be, for
+ * example, the <title> and <ns> attributes found in an XML dump.
+ *
+ * @param string $title The page title
+ * @param int|null $ns The namespace ID, or null if this data is not available
+ * @return ForeignTitle
+ */
+ public function createForeignTitle( $title, $ns = null );
+}
--- /dev/null
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @license GPL 2+
+ */
+
+/**
+ * Represents an object that can convert page titles on a foreign wiki
+ * (ForeignTitle objects) into page titles on the local wiki (Title objects).
+ */
+interface ImportTitleFactory {
+ /**
+ * Determines which local title best corresponds to the given foreign title.
+ * If such a title can't be found or would be locally invalid, null is
+ * returned.
+ *
+ * @param ForeignTitle $foreignTitle The ForeignTitle to convert
+ * @return Title|null
+ */
+ public function createTitleFromForeignTitle( ForeignTitle $foreignTitle );
+}
--- /dev/null
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @license GPL 2+
+ */
+
+/**
+ * A parser that translates page titles on a foreign wiki into ForeignTitle
+ * objects, with no knowledge of the namespace setup on the foreign site.
+ */
+class NaiveForeignTitleFactory implements ForeignTitleFactory {
+ /**
+ * Creates a ForeignTitle object based on the page title, and optionally the
+ * namespace ID, of a page on a foreign wiki. These values could be, for
+ * example, the <title> and <ns> attributes found in an XML dump.
+ *
+ * Although exported XML dumps have contained a map of namespace IDs to names
+ * since MW 1.5, the importer used to completely ignore the <siteinfo> tag
+ * before MW 1.25. It is therefore possible that custom XML dumps (i.e. not
+ * generated by Special:Export) have been created without this metadata.
+ * As a result, this code falls back to using namespace data for the local
+ * wiki (similar to buggy pre-1.25 behaviour) if $ns is not supplied.
+ *
+ * @param string $title The page title
+ * @param int|null $ns The namespace ID, or null if this data is not available
+ * @return ForeignTitle
+ */
+ public function createForeignTitle( $title, $ns = null ) {
+ $pieces = explode( ':', $title, 2 );
+
+ global $wgContLang;
+
+ // Can we assume that the part of the page title before the colon is a
+ // namespace name?
+ //
+ // XML export schema version 0.5 and earlier (MW 1.18 and earlier) does not
+ // contain a <ns> tag, so we need to be able to handle that case.
+ //
+ // If we know the namespace ID, we assume a non-zero namespace ID means
+ // the ':' sets off a valid namespace name. If we don't know the namespace
+ // ID, we fall back to using the local wiki's namespace names to resolve
+ // this -- better than nothing, and mimics the old crappy behavior
+ $isNamespacePartValid = is_null( $ns ) ?
+ ( $wgContLang->getNsIndex( $pieces[0] ) !== false ) :
+ $ns != 0;
+
+ if ( count( $pieces ) === 2 && $isNamespacePartValid ) {
+ list( $namespaceName, $pageName ) = $pieces;
+ } else {
+ $namespaceName = '';
+ $pageName = $title;
+ }
+
+ return new ForeignTitle( $ns, $namespaceName, $pageName );
+ }
+}
--- /dev/null
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @license GPL 2+
+ */
+
+/**
+ * A class to convert page titles on a foreign wiki (ForeignTitle objects) into
+ * page titles on the local wiki (Title objects), using a default namespace
+ * mapping.
+ *
+ * For built-in namespaces (0 <= ID < 100), we try to find a local namespace
+ * with the same namespace ID as the foreign page. If no such namespace exists,
+ * or the namespace ID is unknown or > 100, we look for a local namespace with
+ * a matching namespace name. If that can't be found, we dump the page in the
+ * main namespace as a last resort.
+ */
+class NaiveImportTitleFactory implements ImportTitleFactory {
+ /**
+ * Determines which local title best corresponds to the given foreign title.
+ * If such a title can't be found or would be locally invalid, null is
+ * returned.
+ *
+ * @param ForeignTitle $foreignTitle The ForeignTitle to convert
+ * @return Title|null
+ */
+ public function createTitleFromForeignTitle( ForeignTitle $foreignTitle ) {
+ global $wgContLang;
+
+ if ( $foreignTitle->isNamespaceIdKnown() ) {
+ $foreignNs = $foreignTitle->getNamespaceId();
+
+ // For built-in namespaces (0 <= ID < 100), we try to find a local NS with
+ // the same namespace ID
+ if ( $foreignNs < 100 && MWNamespace::exists( $foreignNs ) ) {
+ return Title::makeTitleSafe( $foreignNs, $foreignTitle->getText() );
+ }
+ }
+
+ // Do we have a local namespace by the same name as the foreign
+ // namespace?
+ $targetNs = $wgContLang->getNsIndex( $foreignTitle->getNamespaceName() );
+ if ( $targetNs !== false ) {
+ return Title::makeTitleSafe( $targetNs, $foreignTitle->getText() );
+ }
+
+ // Otherwise, just fall back to main namespace
+ return Title::makeTitleSafe( 0, $foreignTitle->getFullText() );
+ }
+}
--- /dev/null
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @license GPL 2+
+ */
+
+/**
+ * A parser that translates page titles on a foreign wiki into ForeignTitle
+ * objects, using information about the namespace setup on the foreign site.
+ */
+class NamespaceAwareForeignTitleFactory implements ForeignTitleFactory {
+ /**
+ * @var array
+ */
+ protected $foreignNamespaces;
+ /**
+ * @var array
+ */
+ private $foreignNamespacesFlipped;
+
+ /**
+ * Normalizes an array name for $foreignNamespacesFlipped.
+ * @param string $name
+ * @return string
+ */
+ private function normalizeNamespaceName( $name ) {
+ return strtolower( str_replace( ' ', '_', $name ) );
+ }
+
+ /**
+ * @param array|null $foreignNamespaces An array 'id' => 'name' which contains
+ * the complete namespace setup of the foreign wiki. Such data could be
+ * obtained from siteinfo/namespaces in an XML dump file, or by an action API
+ * query such as api.php?action=query&meta=siteinfo&siprop=namespaces. If
+ * this data is unavailable, use NaiveForeignTitleFactory instead.
+ */
+ public function __construct( $foreignNamespaces ) {
+ $this->foreignNamespaces = $foreignNamespaces;
+ if ( !is_null( $foreignNamespaces ) ) {
+ $this->foreignNamespacesFlipped = array();
+ foreach ( $foreignNamespaces as $id => $name ) {
+ $newKey = self::normalizeNamespaceName( $name );
+ $this->foreignNamespacesFlipped[$newKey] = $id;
+ }
+ }
+ }
+
+ /**
+ * Creates a ForeignTitle object based on the page title, and optionally the
+ * namespace ID, of a page on a foreign wiki. These values could be, for
+ * example, the <title> and <ns> attributes found in an XML dump.
+ *
+ * @param string $title The page title
+ * @param int|null $ns The namespace ID, or null if this data is not available
+ * @return ForeignTitle
+ */
+ public function createForeignTitle( $title, $ns = null ) {
+ // Export schema version 0.5 and earlier (MW 1.18 and earlier) does not
+ // contain a <ns> tag, so we need to be able to handle that case.
+ if ( is_null( $ns ) ) {
+ return self::parseTitleNoNs( $title );
+ } else {
+ return self::parseTitleWithNs( $title, $ns );
+ }
+ }
+
+ /**
+ * Helper function to parse the title when the namespace ID is not specified.
+ *
+ * @param string $title
+ * @return ForeignTitle
+ */
+ protected function parseTitleNoNs( $title ) {
+ $pieces = explode( ':', $title, 2 );
+ $key = self::normalizeNamespaceName( $pieces[0] );
+
+ // Does the part before the colon match a known namespace? Check the
+ // foreign namespaces
+ $isNamespacePartValid = isset( $this->foreignNamespacesFlipped[$key] );
+
+ if ( count( $pieces ) === 2 && $isNamespacePartValid ) {
+ list( $namespaceName, $pageName ) = $pieces;
+ $ns = $this->foreignNamespacesFlipped[$key];
+ } else {
+ $namespaceName = '';
+ $pageName = $title;
+ $ns = 0;
+ }
+
+ return new ForeignTitle( $ns, $namespaceName, $pageName );
+ }
+
+ /**
+ * Helper function to parse the title when the namespace value is known.
+ *
+ * @param string $title
+ * @param int $ns
+ * @return ForeignTitle
+ */
+ protected function parseTitleWithNs( $title, $ns ) {
+ $pieces = explode( ':', $title, 2 );
+
+ if ( isset( $this->foreignNamespaces[$ns] ) ) {
+ $namespaceName = $this->foreignNamespaces[$ns];
+ } else {
+ $namespaceName = $ns == '0' ? '' : $pieces[0];
+ }
+
+ // We assume that the portion of the page title before the colon is the
+ // namespace name, except in the case of namespace 0
+ if ( $ns != '0' ) {
+ $pageName = $pieces[1];
+ } else {
+ $pageName = $title;
+ }
+
+ return new ForeignTitle( $ns, $namespaceName, $pageName );
+ }
+}
--- /dev/null
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @license GPL 2+
+ */
+
+/**
+ * A class to convert page titles on a foreign wiki (ForeignTitle objects) into
+ * page titles on the local wiki (Title objects), placing all pages in a fixed
+ * local namespace.
+ */
+class NamespaceImportTitleFactory implements ImportTitleFactory {
+ /** @var int */
+ protected $ns;
+
+ /**
+ * @param int $ns The namespace to use for all pages
+ */
+ public function __construct( $ns ) {
+ if ( !MWNamespace::exists( $ns ) ) {
+ throw new MWException( "Namespace $ns doesn't exist on this wiki" );
+ }
+ $this->ns = $ns;
+ }
+
+ /**
+ * Determines which local title best corresponds to the given foreign title.
+ * If such a title can't be found or would be locally invalid, null is
+ * returned.
+ *
+ * @param ForeignTitle $foreignTitle The ForeignTitle to convert
+ * @return Title|null
+ */
+ public function createTitleFromForeignTitle( ForeignTitle $foreignTitle ) {
+ return Title::makeTitleSafe( $this->ns, $foreignTitle->getText() );
+ }
+}
--- /dev/null
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @license GPL 2+
+ */
+
+/**
+ * A class to convert page titles on a foreign wiki (ForeignTitle objects) into
+ * page titles on the local wiki (Title objects), placing all pages as subpages
+ * of a given root page.
+ */
+class SubpageImportTitleFactory implements ImportTitleFactory {
+ /** @var Title */
+ protected $rootPage;
+
+ /**
+ * @param Title $rootPage The root page under which all pages should be
+ * created
+ */
+ public function __construct( Title $rootPage ) {
+ if ( !MWNamespace::hasSubpages( $rootPage->getNamespace() ) ) {
+ throw new MWException( "The root page you specified, $rootPage, is in a " .
+ "namespace where subpages are not allowed" );
+ }
+ $this->rootPage = $rootPage;
+ }
+
+ /**
+ * Determines which local title best corresponds to the given foreign title.
+ * If such a title can't be found or would be locally invalid, null is
+ * returned.
+ *
+ * @param ForeignTitle $foreignTitle The ForeignTitle to convert
+ * @return Title|null
+ */
+ public function createTitleFromForeignTitle( ForeignTitle $foreignTitle ) {
+ return Title::newFromText( $this->rootPage->getPrefixedDBkey() . '/' .
+ $foreignTitle->getFullText() );
+ }
+}
$source = $this->getInputStreamSource( $xml );
$redirect = null;
- $callback = function ( $title, $origTitle, $revCount, $sRevCount, $pageInfo ) use ( &$redirect ) {
+ $callback = function ( Title $title, ForeignTitle $foreignTitle, $revCount,
+ $sRevCount, $pageInfo ) use ( &$redirect ) {
if ( array_key_exists( 'redirect', $pageInfo ) ) {
$redirect = $pageInfo['redirect'];
}
);
}
+ /**
+ * @covers WikiImporter::handleSiteInfo
+ * @dataProvider getSiteInfoXML
+ * @param string $xml
+ * @param array|null $namespaces
+ */
+ public function testSiteInfoContainsNamespaces( $xml, $namespaces ) {
+ $source = $this->getInputStreamSource( $xml );
+
+ $importNamespaces = null;
+ $callback = function ( array $siteinfo, $innerImporter ) use ( &$importNamespaces ) {
+ $importNamespaces = $siteinfo['_namespaces'];
+ };
+
+ $importer = new WikiImporter( $source, ConfigFactory::getDefaultInstance()->makeConfig( 'main' ) );
+ $importer->setSiteInfoCallback( $callback );
+ $importer->doImport();
+
+ $this->assertEquals( $importNamespaces, $namespaces );
+ }
+
+ public function getSiteInfoXML() {
+ return array(
+ array(
+ <<< EOF
+<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.10/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.10/ http://www.mediawiki.org/xml/export-0.10.xsd" version="0.10" xml:lang="en">
+ <siteinfo>
+ <namespaces>
+ <namespace key="-2" case="first-letter">Media</namespace>
+ <namespace key="-1" case="first-letter">Special</namespace>
+ <namespace key="0" case="first-letter" />
+ <namespace key="1" case="first-letter">Talk</namespace>
+ <namespace key="2" case="first-letter">User</namespace>
+ <namespace key="3" case="first-letter">User talk</namespace>
+ <namespace key="100" case="first-letter">Portal</namespace>
+ <namespace key="101" case="first-letter">Portal talk</namespace>
+ </namespaces>
+ </siteinfo>
+</mediawiki>
+EOF
+ ,
+ array(
+ '-2' => 'Media',
+ '-1' => 'Special',
+ '0' => '',
+ '1' => 'Talk',
+ '2' => 'User',
+ '3' => 'User talk',
+ '100' => 'Portal',
+ '101' => 'Portal talk',
+ )
+ ),
+ );
+ }
+
}
--- /dev/null
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @license GPL 2+
+ * @author This, that and the other
+ */
+
+/**
+ * @covers ForeignTitle
+ *
+ * @group Title
+ */
+class ForeignTitleTest extends MediaWikiTestCase {
+
+ public function basicProvider() {
+ return array(
+ array(
+ new ForeignTitle( 20, 'Contributor', 'JohnDoe' ),
+ 20, 'Contributor', 'JohnDoe'
+ ),
+ array(
+ new ForeignTitle( '1', 'Discussion', 'Capital' ),
+ 1, 'Discussion', 'Capital'
+ ),
+ array(
+ new ForeignTitle( 0, '', 'MainNamespace' ),
+ 0, '', 'MainNamespace'
+ ),
+ array(
+ new ForeignTitle( 4, 'Some ns', 'Article title with spaces' ),
+ 4, 'Some_ns', 'Article_title_with_spaces'
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider basicProvider
+ */
+ public function testBasic( ForeignTitle $title, $expectedId, $expectedName,
+ $expectedText ) {
+
+ $this->assertEquals( true, $title->isNamespaceIdKnown() );
+ $this->assertEquals( $expectedId, $title->getNamespaceId() );
+ $this->assertEquals( $expectedName, $title->getNamespaceName() );
+ $this->assertEquals( $expectedText, $title->getText() );
+ }
+
+ public function testUnknownNamespaceCheck( ) {
+ $title = new ForeignTitle( null, 'this', 'that' );
+
+ $this->assertEquals( false, $title->isNamespaceIdKnown() );
+ $this->assertEquals( 'this', $title->getNamespaceName() );
+ $this->assertEquals( 'that', $title->getText() );
+ }
+
+ public function testUnknownNamespaceError( ) {
+ $this->setExpectedException( 'MWException' );
+ $title = new ForeignTitle( null, 'this', 'that' );
+ $title->getNamespaceId();
+ }
+
+ public function fullTextProvider() {
+ return array(
+ array(
+ new ForeignTitle( 20, 'Contributor', 'JohnDoe' ),
+ 'Contributor:JohnDoe'
+ ),
+ array(
+ new ForeignTitle( '1', 'Discussion', 'Capital' ),
+ 'Discussion:Capital'
+ ),
+ array(
+ new ForeignTitle( 0, '', 'MainNamespace' ),
+ 'MainNamespace'
+ ),
+ array(
+ new ForeignTitle( 4, 'Some ns', 'Article title with spaces' ),
+ 'Some_ns:Article_title_with_spaces'
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider fullTextProvider
+ */
+ public function testFullText( ForeignTitle $title, $fullText ) {
+ $this->assertEquals( $fullText, $title->getFullText() );
+ }
+}
--- /dev/null
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @license GPL 2+
+ * @author This, that and the other
+ */
+
+/**
+ * @covers NaiveForeignTitleFactory
+ *
+ * @group Title
+ */
+class NaiveForeignTitleFactoryTest extends MediaWikiTestCase {
+
+ public function basicProvider() {
+ return array(
+ array(
+ 'MainNamespaceArticle', 0,
+ new ForeignTitle( 0, '', 'MainNamespaceArticle' ),
+ ),
+ array(
+ 'MainNamespaceArticle', null,
+ new ForeignTitle( null, '', 'MainNamespaceArticle' ),
+ ),
+ array(
+ 'Talk:Nice_talk', 1,
+ new ForeignTitle( 1, 'Talk', 'Nice_talk' ),
+ ),
+ array(
+ 'Bogus:Nice_talk', 0,
+ new ForeignTitle( 0, '', 'Bogus:Nice_talk' ),
+ ),
+ array(
+ 'Bogus:Nice_talk', 9000, // non-existent local namespace ID
+ new ForeignTitle( 9000, 'Bogus', 'Nice_talk' ),
+ ),
+ array(
+ 'Bogus:Nice_talk', 4, // existing local namespace ID
+ new ForeignTitle( 4, 'Bogus', 'Nice_talk' ),
+ ),
+ array(
+ 'Talk:Extra:Nice_talk', 1,
+ new ForeignTitle( 1, 'Talk', 'Extra:Nice_talk' ),
+ ),
+ array(
+ 'Talk:Extra:Nice_talk', null,
+ new ForeignTitle( null, 'Talk', 'Extra:Nice_talk' ),
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider basicProvider
+ */
+ public function testBasic( $title, $ns, ForeignTitle $foreignTitle ) {
+ $factory = new NaiveForeignTitleFactory();
+ $testTitle = $factory->createForeignTitle( $title, $ns );
+
+ $this->assertEquals( $testTitle->isNamespaceIdKnown(),
+ $foreignTitle->isNamespaceIdKnown() );
+
+ if (
+ $testTitle->isNamespaceIdKnown() &&
+ $foreignTitle->isNamespaceIdKnown()
+ ) {
+ $this->assertEquals( $testTitle->getNamespaceId(),
+ $foreignTitle->getNamespaceId() );
+ }
+
+ $this->assertEquals( $testTitle->getNamespaceName(),
+ $foreignTitle->getNamespaceName() );
+ $this->assertEquals( $testTitle->getText(), $foreignTitle->getText() );
+
+ $this->assertEquals( str_replace( ' ', '_', $title ),
+ $foreignTitle->getFullText() );
+ }
+}
--- /dev/null
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @license GPL 2+
+ * @author This, that and the other
+ */
+
+/**
+ * @covers NaiveImportTitleFactory
+ *
+ * @group Title
+ */
+class NaiveImportTitleFactoryTest extends MediaWikiTestCase {
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->setMwGlobals( array(
+ 'wgLanguageCode' => 'en',
+ 'wgContLang' => Language::factory( 'en' ),
+ 'wgExtraNamespaces' => array( 100 => 'Portal' ),
+ ) );
+ }
+
+ public function basicProvider() {
+ return array(
+ array(
+ new ForeignTitle( 0, '', 'MainNamespaceArticle' ),
+ Title::newFromText( 'MainNamespaceArticle' )
+ ),
+ array(
+ new ForeignTitle( null, '', 'MainNamespaceArticle' ),
+ Title::newFromText( 'MainNamespaceArticle' )
+ ),
+ array(
+ new ForeignTitle( 1, 'Discussion', 'Nice_talk' ),
+ Title::newFromText( 'Talk:Nice_talk' )
+ ),
+ array(
+ new ForeignTitle( 0, '', 'Bogus:Nice_talk' ),
+ Title::newFromText( 'Bogus:Nice_talk' )
+ ),
+ array(
+ new ForeignTitle( 100, 'Bogus', 'Nice_talk' ),
+ Title::newFromText( 'Bogus:Nice_talk' ) // not Portal:Nice_talk
+ ),
+ array(
+ new ForeignTitle( 1, 'Bogus', 'Nice_talk' ),
+ Title::newFromText( 'Talk:Nice_talk' ) // not Bogus:Nice_talk
+ ),
+ array(
+ new ForeignTitle( 100, 'Portal', 'Nice_talk' ),
+ Title::newFromText( 'Portal:Nice_talk' )
+ ),
+ array(
+ new ForeignTitle( 724, 'Portal', 'Nice_talk' ),
+ Title::newFromText( 'Portal:Nice_talk' )
+ ),
+ array(
+ new ForeignTitle( 2, 'Portal', 'Nice_talk' ),
+ Title::newFromText( 'User:Nice_talk' )
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider basicProvider
+ */
+ public function testBasic( ForeignTitle $foreignTitle, Title $title ) {
+ $factory = new NaiveImportTitleFactory();
+ $testTitle = $factory->createTitleFromForeignTitle( $foreignTitle );
+
+ $this->assertTrue( $title->equals( $testTitle ) );
+ }
+}
--- /dev/null
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @license GPL 2+
+ * @author This, that and the other
+ */
+
+/**
+ * @covers NamespaceAwareForeignTitleFactory
+ *
+ * @group Title
+ */
+class NamespaceAwareForeignTitleFactoryTest extends MediaWikiTestCase {
+
+ public function basicProvider() {
+ return array(
+ array(
+ 'MainNamespaceArticle', 0,
+ new ForeignTitle( 0, '', 'MainNamespaceArticle' ),
+ ),
+ array(
+ 'MainNamespaceArticle', null,
+ new ForeignTitle( 0, '', 'MainNamespaceArticle' ),
+ ),
+ array(
+ 'Talk:Nice_talk', 1,
+ new ForeignTitle( 1, 'Talk', 'Nice_talk' ),
+ ),
+ array(
+ 'Bogus:Nice_talk', 0,
+ new ForeignTitle( 0, '', 'Bogus:Nice_talk' ),
+ ),
+ array(
+ 'Bogus:Nice_talk', null,
+ new ForeignTitle( 9000, 'Bogus', 'Nice_talk' ),
+ ),
+ array(
+ 'Bogus:Nice_talk', 4,
+ new ForeignTitle( 4, 'Bogus', 'Nice_talk' ),
+ ),
+ array(
+ 'Bogus:Nice_talk', 1,
+ new ForeignTitle( 1, 'Talk', 'Nice_talk' ),
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider basicProvider
+ */
+ public function testBasic( $title, $ns, ForeignTitle $foreignTitle ) {
+
+ $foreignNamespaces = array(
+ 0 => '', 1 => 'Talk', 100 => 'Portal', 9000 => 'Bogus'
+ );
+
+ $factory = new NamespaceAwareForeignTitleFactory( $foreignNamespaces );
+ $testTitle = $factory->createForeignTitle( $title, $ns );
+
+ $this->assertEquals( $testTitle->isNamespaceIdKnown(),
+ $foreignTitle->isNamespaceIdKnown() );
+
+ if (
+ $testTitle->isNamespaceIdKnown() &&
+ $foreignTitle->isNamespaceIdKnown()
+ ) {
+ $this->assertEquals( $testTitle->getNamespaceId(),
+ $foreignTitle->getNamespaceId() );
+ }
+
+ $this->assertEquals( $testTitle->getNamespaceName(),
+ $foreignTitle->getNamespaceName() );
+ $this->assertEquals( $testTitle->getText(), $foreignTitle->getText() );
+ }
+}
--- /dev/null
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @license GPL 2+
+ * @author This, that and the other
+ */
+
+/**
+ * @covers NamespaceImportTitleFactory
+ *
+ * @group Title
+ */
+class NamespaceImportTitleFactoryTest extends MediaWikiTestCase {
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->setMwGlobals( array(
+ 'wgLanguageCode' => 'en',
+ 'wgContLang' => Language::factory( 'en' ),
+ ) );
+ }
+
+ public function basicProvider() {
+ return array(
+ array(
+ new ForeignTitle( 0, '', 'MainNamespaceArticle' ),
+ 0,
+ Title::newFromText( 'MainNamespaceArticle' )
+ ),
+ array(
+ new ForeignTitle( 0, '', 'MainNamespaceArticle' ),
+ 2,
+ Title::newFromText( 'User:MainNamespaceArticle' )
+ ),
+ array(
+ new ForeignTitle( 1, 'Discussion', 'Nice_talk' ),
+ 0,
+ Title::newFromText( 'Nice_talk' )
+ ),
+ array(
+ new ForeignTitle( 0, '', 'Bogus:Nice_talk' ),
+ 0,
+ Title::newFromText( 'Bogus:Nice_talk' )
+ ),
+ array(
+ new ForeignTitle( 0, '', 'Bogus:Nice_talk' ),
+ 2,
+ Title::newFromText( 'User:Bogus:Nice_talk' )
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider basicProvider
+ */
+ public function testBasic( ForeignTitle $foreignTitle, $ns, Title $title ) {
+ $factory = new NamespaceImportTitleFactory( $ns );
+ $testTitle = $factory->createTitleFromForeignTitle( $foreignTitle );
+
+ $this->assertTrue( $title->equals( $testTitle ) );
+ }
+}
--- /dev/null
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @license GPL 2+
+ * @author This, that and the other
+ */
+
+/**
+ * @covers SubpageImportTitleFactory
+ *
+ * @group Title
+ */
+class SubpageImportTitleFactoryTest extends MediaWikiTestCase {
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->setMwGlobals( array(
+ 'wgLanguageCode' => 'en',
+ 'wgContLang' => Language::factory( 'en' ),
+ 'wgNamespacesWithSubpages' => array( 0 => false, 2 => true ),
+ ) );
+ }
+
+ public function basicProvider() {
+ return array(
+ array(
+ new ForeignTitle( 0, '', 'MainNamespaceArticle' ),
+ Title::newFromText( 'User:Graham' ),
+ Title::newFromText( 'User:Graham/MainNamespaceArticle' )
+ ),
+ array(
+ new ForeignTitle( 1, 'Discussion', 'Nice_talk' ),
+ Title::newFromText( 'User:Graham' ),
+ Title::newFromText( 'User:Graham/Discussion:Nice_talk' )
+ ),
+ array(
+ new ForeignTitle( 0, '', 'Bogus:Nice_talk' ),
+ Title::newFromText( 'User:Graham' ),
+ Title::newFromText( 'User:Graham/Bogus:Nice_talk' )
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider basicProvider
+ */
+ public function testBasic( ForeignTitle $foreignTitle, Title $rootPage,
+ Title $title ) {
+
+ $factory = new SubpageImportTitleFactory( $rootPage );
+ $testTitle = $factory->createTitleFromForeignTitle( $foreignTitle );
+
+ $this->assertTrue( $testTitle->equals( $title ) );
+ }
+
+ public function failureProvider() {
+ return array(
+ array(
+ Title::newFromText( 'Graham' ),
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider failureProvider
+ */
+ public function testFailures( Title $rootPage ) {
+ $this->setExpectedException( 'MWException' );
+ new SubpageImportTitleFactory( $rootPage );
+ }
+}