diff --git a/extension.json b/extension.json index 297741c..c4bce22 100644 --- a/extension.json +++ b/extension.json @@ -22,6 +22,8 @@ }, "config": { "WBImportSourceApi": "https://www.wikidata.org/w/api.php", + "WBImportSourceURL": "https://www.wikidata.org", + "WBImportSourceName": "Wikidata", "WBImportQueryUrl": "https://query.wikidata.org/bigdata/namespace/wdq/sparql", "WBImportQueryPrefixes": { "wikibase": "http://wikiba.se/ontology#", @@ -36,6 +38,7 @@ ] }, "SpecialPages": { + "ImportEntity": "Wikibase\\Import\\Specials\\SpecialImportEntity::newFromGlobalState" }, "manifest_version": 1 } diff --git a/i18n/en.json b/i18n/en.json index 34862c4..48dcee6 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -2,5 +2,14 @@ "@metadata": { "authors": [] }, - "wikibaseimport-desc": "Allows importing data from another Wikibase instance" + "wikibaseimport-desc": "Allows importing data from another Wikibase instance", + "wikibaseimport-importentity-explanation": "This special page imports an entity (item or property) from $1. After the import is completed (which can take several seconds), you will be redirected to the local version of the entity. If the entity was already imported, no new entity is created, and you will be redirected to the existing local entity.", + "wikibaseimport-importentity-desc": "Import an entity", + "wikibaseimport-importentity-form-section": "Import entity", + "wikibaseimport-importentity-form-submit-label": "Import", + "wikibaseimport-importentity-form-entityid-label": "Entity ID on $1", + "wikibaseimport-importentity-form-entityid-placeholder": "Qxx or Pxx", + "wikibaseimport-importentity-form-importstatements-label": "Import statements (not supported yet)", + "wikibaseimport-importentity-error-no-local-id-title": "Redirect failed", + "wikibaseimport-importentity-error-no-local-id-message": "No local entity ID for this remote entity ID found after import; does the remote entity exist?" } diff --git a/i18n/qqq.json b/i18n/qqq.json index d37d794..5a3b6fc 100644 --- a/i18n/qqq.json +++ b/i18n/qqq.json @@ -1,5 +1,14 @@ { "@metadata": { }, - "wikibaseimport-desc": "{{desc|name=WikibaseImport|url=https://www.mediawiki.org/wiki/Extension:WikibaseImport}}" + "wikibaseimport-desc": "{{desc|name=WikibaseImport|url=https://www.mediawiki.org/wiki/Extension:WikibaseImport}}", + "wikibaseimport-importentity-desc": "{{doc-special|ImportEntity}}", + "wikibaseimport-importentity-explanation": "Explanation of what this special page does. This text is displayed on the special page above the entity ID form. Parameters:\n* $1 contains a link to the remote (source) Wikibase installation from which entities are imported.", + "wikibaseimport-importentity-form-section": "Header of the section of the entity ID form.", + "wikibaseimport-importentity-form-submit-label": "Label for the button that starts the import.", + "wikibaseimport-importentity-form-entityid-label": "Label for the entity ID input field.", + "wikibaseimport-importentity-form-entityid-placeholder": "Entity ID placeholder for the input field.", + "wikibaseimport-importentity-form-importstatements-label": "Label for the “import statements” checkbox. This feature is not supported yet, so the checkbox is disabled.", + "wikibaseimport-importentity-error-no-local-id-title": "Page title of the error page for when the local entity ID to redirect to cannot be found.", + "wikibaseimport-importentity-error-no-local-id-message": "Error message for when the local entity ID to redirect to cannot be found." } diff --git a/src/EntityImporterFactory.php b/src/EntityImporterFactory.php index 9394128..0aad8a6 100644 --- a/src/EntityImporterFactory.php +++ b/src/EntityImporterFactory.php @@ -101,7 +101,7 @@ private function newStatementsImporter() { ); } - private function getImportedEntityMappingStore() { + public function getImportedEntityMappingStore() { if ( $this->importedEntityMappingStore === null ) { $wikibaseRepo = WikibaseRepo::getDefaultInstance(); @@ -129,5 +129,5 @@ private function newSerializerFactory() { } } -$maintClass = "Wikibase\Import\Maintenance\ImportEntities"; -require_once RUN_MAINTENANCE_IF_MAIN; +//$maintClass = "Wikibase\Import\Maintenance\ImportEntities"; +//require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/src/Specials/SpecialImportEntity.php b/src/Specials/SpecialImportEntity.php new file mode 100644 index 0000000..b9d5f92 --- /dev/null +++ b/src/Specials/SpecialImportEntity.php @@ -0,0 +1,177 @@ +getStore()->getEntityStore(), + wfGetLB(), + $logger, + MediaWikiServices::getInstance()->getMainConfig()->get( 'WBImportSourceApi' ) + ); + return new self( + $entityImporterFactory->newEntityImporter(), + $entityImporterFactory->getImportedEntityMappingStore(), + $repo->getEntityIdParser(), + $repo->getEntityTitleLookup() + ); + } + + /** + * @param EntityImporter $entityIdImporter + */ + public function __construct( + EntityImporter $entityIdImporter, + ImportedEntityMappingStore $entityMappingStore, + EntityIdParser $idParser, + EntityTitleLookup $entityTitleLookup + ) { + parent::__construct( 'ImportEntity' ); + $this->entityIdImporter = $entityIdImporter; + $this->entityMappingStore = $entityMappingStore; + $this->idParser = $idParser; + $this->entityTitleLookup = $entityTitleLookup; + } + + /** + * @see SpecialPage::getDescription + * + * @return string + */ + public function getDescription() { + return $this->msg( 'wikibaseimport-importentity-desc' )->escaped(); + } + + /** + * @see SpecialPage::execute + * + * @param string|null $subPage + */ + public function execute( $subPage ) { + if ( $this->getContext()->getRequest()->wasPosted() ) { + $this->doImport(); + } else { + $this->showPage( $subPage ); + } + } + + private function doImport() { + $entityId = $this->getContext()->getRequest()->getText( 'wpEntityId' ); + $importStatements = $this->getContext()->getRequest()->getCheck( 'wpImportStatements' ); + if ( $importStatements ) { + // TODO fix bug with importStatements and then remove this if clause and enable the checkbox + throw new \MWException( 'Importing statements is not yet supported!' ); + } + $this->entityIdImporter->importEntities( [ $entityId ], $importStatements ); + // redirect to imported entity + $imported = $this->entityMappingStore->getLocalId( $this->idParser->parse( $entityId ) ); + if ( $imported ) { + $this->getOutput()->redirect( + $this->entityTitleLookup->getTitleForId( $imported )->getLocalUrl() + ); + } else { + throw new ErrorPageError( + "wikibaseimport-importentity-error-no-local-id-title", + "wikibaseimport-importentity-error-no-local-id-message" + ); + } + } + + /** + * Show the special page with explanation and form. + * + * @param string|null $subPage + */ + private function showPage( $subPage ) { + $this->setHeaders(); + // show explanation + $this->getOutput()->addHTML( + Html::rawElement( + 'div', + [ 'class' => 'wikibaseimport-importentity-explanation' ], + $this->msg( 'wikibaseimport-importentity-explanation' )->rawParams( + Html::element( + 'a', + [ 'href' => $this->getConfig()->get( 'WBImportSourceURL' ) ], + $this->getConfig()->get( 'WBImportSourceName' ) + ) + )->escaped() + ) + ); + // show entity ID form + $formDescription = []; + $formDescription['EntityId'] = [ + 'type' => 'text', + 'section' => 'section', + 'label-message' => [ + // message ID + 'wikibaseimport-importentity-form-entityid-label', + // message parameters + $this->getConfig()->get( 'WBImportSourceName' ) + ], + 'placeholder' => $this->msg( 'wikibaseimport-importentity-form-entityid-placeholder' )->escaped(), + ]; + if ( is_string( $subPage ) && preg_match( '/(P|Q)[0-9]+/', $subPage ) ) { + $formDescription['EntityId']['default'] = $subPage; + } + $formDescription['ImportStatements'] = [ + 'type' => 'check', + 'section' => 'section', + 'label-message' => 'wikibaseimport-importentity-form-importstatements-label', + 'disabled' => true, // TODO remove this once importing statements works + ]; + HTMLForm::factory( + 'ooui', + $formDescription, + $this->getContext(), + 'wikibaseimport-importentity-form' + ) + ->setSubmitText( $this->msg( 'wikibaseimport-importentity-form-submit-label' )->escaped() ) + ->setSubmitCallback( + function() { + return false; + } + ) + ->setMethod( 'post' ) + ->prepareForm() + ->displayForm( false ); + } + +}