private $countableCache = [];
/** @var bool */
private $disableStatisticsUpdate = false;
+ private $usernamePrefix = 'imported';
+ private $assignKnownUsers = false;
+ private $triedCreations = [];
/**
* Creates an ImportXMLReader drawing from the source provided
$this->mImportUploads = $import;
}
+ /**
+ * @since 1.31
+ * @param string $usernamePrefix Prefix to apply to unknown (and possibly also known) usernames
+ * @param bool $assignKnownUsers Whether to apply the prefix to usernames that exist locally
+ */
+ public function setUsernamePrefix( $usernamePrefix, $assignKnownUsers ) {
+ $this->usernamePrefix = rtrim( (string)$usernamePrefix, ':>' );
+ $this->assignKnownUsers = (bool)$assignKnownUsers;
+ }
+
/**
* Statistics update can cause a lot of time
* @since 1.29
/**
* Primary entry point
+ * @throws Exception
* @throws MWException
* @return bool
*/
}
if ( !isset( $logInfo['contributor']['username'] ) ) {
- $revision->setUsername( 'Unknown user' );
+ $revision->setUsername( $this->usernamePrefix . '>Unknown user' );
} else {
- $revision->setUsername( $logInfo['contributor']['username'] );
+ $revision->setUsername( $this->prefixUsername( $logInfo['contributor']['username'] ) );
}
return $this->logItemCallback( $revision );
/**
* @param array $pageInfo
* @param array $revisionInfo
+ * @throws MWException
* @return bool|mixed
*/
private function processRevision( $pageInfo, $revisionInfo ) {
if ( isset( $revisionInfo['contributor']['ip'] ) ) {
$revision->setUserIP( $revisionInfo['contributor']['ip'] );
} elseif ( isset( $revisionInfo['contributor']['username'] ) ) {
- $revision->setUsername( $revisionInfo['contributor']['username'] );
+ $revision->setUsername( $this->prefixUsername( $revisionInfo['contributor']['username'] ) );
} else {
- $revision->setUsername( 'Unknown user' );
+ $revision->setUsername( $this->usernamePrefix . '>Unknown user' );
}
if ( isset( $revisionInfo['sha1'] ) ) {
$revision->setSha1Base36( $revisionInfo['sha1'] );
$revision->setUserIP( $uploadInfo['contributor']['ip'] );
}
if ( isset( $uploadInfo['contributor']['username'] ) ) {
- $revision->setUsername( $uploadInfo['contributor']['username'] );
+ $revision->setUsername( $this->prefixUsername( $uploadInfo['contributor']['username'] ) );
}
$revision->setNoUpdates( $this->mNoUpdates );
return call_user_func( $this->mUploadCallback, $revision );
}
+ /**
+ * Add an interwiki prefix to the username, if appropriate
+ * @since 1.31
+ * @param string $name Name being imported
+ * @return string Name, possibly with the prefix prepended.
+ */
+ protected function prefixUsername( $name ) {
+ if ( !User::isUsableName( $name ) ) {
+ return $name;
+ }
+
+ if ( $this->assignKnownUsers ) {
+ if ( User::idFromName( $name ) ) {
+ return $name;
+ }
+
+ // See if any extension wants to create it.
+ if ( !isset( $this->triedCreations[$name] ) ) {
+ $this->triedCreations[$name] = true;
+ if ( !Hooks::run( 'ImportHandleUnknownUser', [ $name ] ) &&
+ User::idFromName( $name, User::READ_LATEST )
+ ) {
+ return $name;
+ }
+ }
+ }
+
+ return substr( $this->usernamePrefix . '>' . $name, 0, 255 );
+ }
+
/**
* @return array
*/
);
$this->addOption( 'image-base-path', 'Import files from a specified path', false, true );
$this->addOption( 'skip-to', 'Start from nth page by skipping first n-1 pages', false, true );
+ $this->addOption( 'username-interwiki', 'Use interwiki usernames with this prefix', false, true );
+ $this->addOption( 'no-local-users',
+ 'Treat all usernames as interwiki. ' .
+ 'The default is to assign edits to local users where they exist.',
+ false, false
+ );
$this->addArg( 'file', 'Dump file to import [else use stdin]', false );
}
public function execute() {
if ( wfReadOnly() ) {
- $this->error( "Wiki is in read-only mode; you'll need to disable it for import to work.", true );
+ $this->fatalError( "Wiki is in read-only mode; you'll need to disable it for import to work." );
}
$this->reportingInterval = intval( $this->getOption( 'report', 100 ) );
if ( strval( $ns ) === $namespace && $wgContLang->getNsText( $ns ) !== false ) {
return $ns;
}
- $this->error( "Unknown namespace text / index specified: $namespace", true );
+ $this->fatalError( "Unknown namespace text / index specified: $namespace" );
}
/**
* @param Title|Revision $obj
+ * @throws MWException
* @return bool
*/
private function skippedNamespace( $obj ) {
if ( $this->hasOption( 'no-updates' ) ) {
$importer->setNoUpdates( true );
}
+ if ( $this->hasOption( 'username-prefix' ) ) {
+ $importer->setUsernamePrefix(
+ $this->getOption( 'username-prefix' ),
+ !$this->hasOption( 'no-local-users' )
+ );
+ }
if ( $this->hasOption( 'rootpage' ) ) {
$statusRootPage = $importer->setTargetRootPage( $this->getOption( 'rootpage' ) );
if ( !$statusRootPage->isGood() ) {
// Die here so that it doesn't print "Done!"
- $this->error( $statusRootPage->getMessage()->text(), 1 );
+ $this->fatalError( $statusRootPage->getMessage()->text() );
return false;
}
}