From 750ee375ef721973816dd4083bd28a9f3eedda06 Mon Sep 17 00:00:00 2001 From: Kolja Bailly Date: Wed, 24 Apr 2024 12:52:14 +0200 Subject: [PATCH 01/10] changed PropertyId class to NumericPropertyId to enable compatibility with mediawiki version>1.35 --- composer.json | 2 +- src/SMW/SemanticEntity.php | 18 +++++++++--------- src/SemanticDataUpdate.php | 4 ++-- src/Translation/DataValueTranslator.php | 4 ++-- src/Translation/PropertyTranslator.php | 4 ++-- src/Translation/StatementListTranslator.php | 8 ++++---- src/Translation/StatementTranslator.php | 2 +- src/Translation/UserDefinedProperties.php | 10 +++++----- tests/TestFactory.php | 4 ++-- .../ContainerValueTranslatorTest.php | 12 ++++++------ .../Translation/DataValueTranslatorTest.php | 4 ++-- tests/Unit/Translation/ItemTranslatorTest.php | 18 +++++++++--------- .../Translation/PropertyTranslatorTest.php | 4 ++-- .../Translation/StatementTranslatorTest.php | 6 +++--- 14 files changed, 50 insertions(+), 50 deletions(-) diff --git a/composer.json b/composer.json index 5c936ca..1f76f5f 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "professional-wiki/semantic-wikibase", + "name": "baillyk/semantic-wikibase", "type": "mediawiki-extension", "description": "MediaWiki extension that makes Wikibase data available in Semantic MediaWiki", "keywords": [ diff --git a/src/SMW/SemanticEntity.php b/src/SMW/SemanticEntity.php index 1c0e2ad..d9ca4f4 100644 --- a/src/SMW/SemanticEntity.php +++ b/src/SMW/SemanticEntity.php @@ -13,23 +13,23 @@ class SemanticEntity { private array $dataItemsPerProperty = []; - public function addPropertyValue( string $propertyId, SMWDataItem $dataItem ) { - $this->dataItemsPerProperty[$propertyId][] = $dataItem; + public function addPropertyValue( string $NumericPropertyId, SMWDataItem $dataItem ) { + $this->dataItemsPerProperty[$NumericPropertyId][] = $dataItem; } /** - * @param string $propertyId + * @param string $NumericPropertyId * @return SMWDataItem[] */ - public function getDataItemsForProperty( string $propertyId ): array { - return $this->dataItemsPerProperty[$propertyId] ?? []; + public function getDataItemsForProperty( string $NumericPropertyId ): array { + return $this->dataItemsPerProperty[$NumericPropertyId] ?? []; } public function toSemanticData( DIWikiPage $subject ): SemanticData { $semanticData = new SemanticData( $subject ); - foreach ( $this->dataItemsPerProperty as $propertyId => $dataItems ) { - $property = new DIProperty( $propertyId ); + foreach ( $this->dataItemsPerProperty as $NumericPropertyId => $dataItems ) { + $property = new DIProperty( $NumericPropertyId ); foreach ( $dataItems as $dataItem ) { $semanticData->addPropertyObjectValue( @@ -52,9 +52,9 @@ public function functionalMerge( self $entity ): self { } public function add( self $entity ): void { - foreach ( $entity->dataItemsPerProperty as $propertyId => $dataItems ) { + foreach ( $entity->dataItemsPerProperty as $NumericPropertyId => $dataItems ) { foreach ( $dataItems as $dataItem ) { - $this->addPropertyValue( $propertyId, $dataItem ); + $this->addPropertyValue( $NumericPropertyId, $dataItem ); } } } diff --git a/src/SemanticDataUpdate.php b/src/SemanticDataUpdate.php index 0de6f59..8bdefed 100644 --- a/src/SemanticDataUpdate.php +++ b/src/SemanticDataUpdate.php @@ -12,7 +12,7 @@ use SMW\SemanticData; use Title; use Wikibase\DataModel\Entity\ItemId; -use Wikibase\DataModel\Entity\PropertyId; +use Wikibase\DataModel\Entity\NumericPropertyId; use Wikibase\DataModel\Services\Lookup\ItemLookup; use Wikibase\DataModel\Services\Lookup\PropertyLookup; @@ -64,7 +64,7 @@ private function newItemTranslator( Title $title ): ItemTranslator { private function getSemanticEntityForPropertyTitle( Title $title ): SemanticEntity { return $this->newPropertyTranslator( $title )->translateProperty( - $this->propertyLookup->getPropertyForId( new PropertyId( $title->getText() ) ) + $this->propertyLookup->getPropertyForId( new NumericPropertyId( $title->getText() ) ) ); } diff --git a/src/Translation/DataValueTranslator.php b/src/Translation/DataValueTranslator.php index 23a2a3b..3472fa5 100644 --- a/src/Translation/DataValueTranslator.php +++ b/src/Translation/DataValueTranslator.php @@ -19,7 +19,7 @@ use Wikibase\DataModel\Entity\EntityId; use Wikibase\DataModel\Entity\EntityIdValue; use Wikibase\DataModel\Entity\ItemId; -use Wikibase\DataModel\Entity\PropertyId; +use Wikibase\DataModel\Entity\NumericPropertyId; class DataValueTranslator { @@ -78,7 +78,7 @@ private function entityIdToNamespaceId( EntityId $idValue ): int { return WB_NS_ITEM; } - if ( $idValue instanceof PropertyId ) { + if ( $idValue instanceof NumericPropertyId ) { return WB_NS_PROPERTY; } diff --git a/src/Translation/PropertyTranslator.php b/src/Translation/PropertyTranslator.php index d134b5c..b0dc29d 100644 --- a/src/Translation/PropertyTranslator.php +++ b/src/Translation/PropertyTranslator.php @@ -6,7 +6,7 @@ use MediaWiki\Extension\SemanticWikibase\SMW\SemanticEntity; use Wikibase\DataModel\Entity\Property; -use Wikibase\DataModel\Entity\PropertyId; +use Wikibase\DataModel\Entity\NumericPropertyId; class PropertyTranslator { @@ -32,7 +32,7 @@ public function translateProperty( Property $property ): SemanticEntity { return $semanticEntity; } - private function addId( SemanticEntity $semanticEntity, PropertyId $itemId ): void { + private function addId( SemanticEntity $semanticEntity, NumericPropertyId $itemId ): void { $semanticEntity->addPropertyValue( FixedProperties::ID, new \SMWDIBlob( $itemId->getSerialization() ) diff --git a/src/Translation/StatementListTranslator.php b/src/Translation/StatementListTranslator.php index f45edcc..e6b3074 100644 --- a/src/Translation/StatementListTranslator.php +++ b/src/Translation/StatementListTranslator.php @@ -39,21 +39,21 @@ private function addStatement( SemanticEntity $semanticEntity, Statement $statem $semanticEntity->addPropertyValue( DIProperty::TYPE_SUBOBJECT, $dataItem ); $semanticEntity->addPropertyValue( - $this->propertyIdForStatement( $statement ), + $this->NumericPropertyIdForStatement( $statement ), $dataItem->getSemanticData()->getSubject() ); } else { $semanticEntity->addPropertyValue( - $this->propertyIdForStatement( $statement ), + $this->NumericPropertyIdForStatement( $statement ), $dataItem ); } } } - private function propertyIdForStatement( Statement $statement ): string { - return UserDefinedProperties::idFromWikibaseProperty( $statement->getPropertyId() ); + private function NumericPropertyIdForStatement( Statement $statement ): string { + return UserDefinedProperties::idFromWikibaseProperty( $statement->getNumericPropertyId() ); } } diff --git a/src/Translation/StatementTranslator.php b/src/Translation/StatementTranslator.php index a58ee90..3a0a6fe 100644 --- a/src/Translation/StatementTranslator.php +++ b/src/Translation/StatementTranslator.php @@ -40,7 +40,7 @@ public function statementToDataItem( Statement $statement, DIWikiPage $subject ) private function snakWithSimpleDataValueToDataItem( PropertyValueSnak $snak ): SMWDataItem { return $this->dataValueTranslator->translate( new TypedDataValue( - $this->propertyTypeLookup->getDataTypeIdForProperty( $snak->getPropertyId() ), + $this->propertyTypeLookup->getDataTypeIdForProperty( $snak->getNumericPropertyId() ), $snak->getDataValue() ) ); diff --git a/src/Translation/UserDefinedProperties.php b/src/Translation/UserDefinedProperties.php index 13205b0..d84b525 100644 --- a/src/Translation/UserDefinedProperties.php +++ b/src/Translation/UserDefinedProperties.php @@ -5,7 +5,7 @@ namespace MediaWiki\Extension\SemanticWikibase\Translation; use MediaWiki\Extension\SemanticWikibase\SMW\SemanticProperty; -use Wikibase\DataModel\Entity\PropertyId; +use Wikibase\DataModel\Entity\NumericPropertyId; use Wikibase\DataModel\Services\Lookup\TermLookup; use Wikibase\Lib\Store\PropertyInfoLookup; use Wikibase\Lib\Store\StorageException; @@ -40,7 +40,7 @@ public function getAll(): array { $this->propertyTypeTranslator->translate( $propertyInfo['type'] ), $id, $this->termLookup->getLabel( - new PropertyId( $id ), + new NumericPropertyId( $id ), $this->labelLanguageCode ) ); @@ -59,11 +59,11 @@ public function getAllPropertyInfo(): array { } } - private static function idFromWikibaseString( string $propertyId ): string { - return '___SWB_' . $propertyId; + private static function idFromWikibaseString( string $NumericPropertyId ): string { + return '___SWB_' . $NumericPropertyId; } - public static function idFromWikibaseProperty( PropertyId $id ): string { + public static function idFromWikibaseProperty( NumericPropertyId $id ): string { return self::idFromWikibaseString( $id->getSerialization() ); } diff --git a/tests/TestFactory.php b/tests/TestFactory.php index c09410b..d9acf5d 100644 --- a/tests/TestFactory.php +++ b/tests/TestFactory.php @@ -10,7 +10,7 @@ use MediaWiki\Extension\SemanticWikibase\Translation\MonoTextTranslator; use MediaWiki\Extension\SemanticWikibase\Translation\StatementTranslator; use SMW\DIWikiPage; -use Wikibase\DataModel\Entity\PropertyId; +use Wikibase\DataModel\Entity\NumericPropertyId; use Wikibase\DataModel\Services\Lookup\InMemoryDataTypeLookup; use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup; @@ -36,7 +36,7 @@ private function initialize(): void { private function newPropertyTypeLookup(): InMemoryDataTypeLookup { $lookup = new InMemoryDataTypeLookup(); - $lookup->setDataTypeForProperty( new PropertyId( 'P1' ), 'string' ); + $lookup->setDataTypeForProperty( new NumericPropertyId( 'P1' ), 'string' ); return $lookup; } diff --git a/tests/Unit/Translation/ContainerValueTranslatorTest.php b/tests/Unit/Translation/ContainerValueTranslatorTest.php index 9383020..a5804c4 100644 --- a/tests/Unit/Translation/ContainerValueTranslatorTest.php +++ b/tests/Unit/Translation/ContainerValueTranslatorTest.php @@ -15,7 +15,7 @@ use SMW\DIProperty; use SMW\DIWikiPage; use SMWDIContainer; -use Wikibase\DataModel\Entity\PropertyId; +use Wikibase\DataModel\Entity\NumericPropertyId; use Wikibase\DataModel\Snak\PropertySomeValueSnak; use Wikibase\DataModel\Snak\PropertyValueSnak; use Wikibase\DataModel\Statement\Statement; @@ -32,7 +32,7 @@ public function testTranslateBoundedQuantity() { $container = $this->translate( new Statement( new PropertyValueSnak( - new PropertyId( 'P1' ), + new NumericPropertyId( 'P1' ), new QuantityValue( new DecimalValue( 42 ), 'mega awesome', @@ -70,7 +70,7 @@ public function testTranslateUnboundedQuantity() { $container = $this->translate( new Statement( new PropertyValueSnak( - new PropertyId( 'P1' ), + new NumericPropertyId( 'P1' ), new UnboundedQuantityValue( new DecimalValue( 42 ), 'mega awesome' @@ -111,7 +111,7 @@ public function testSupportsQuantityStatements() { $this->assertTrue( $this->newTranslator()->supportsStatement( new Statement( new PropertyValueSnak( - new PropertyId( 'P1' ), + new NumericPropertyId( 'P1' ), new UnboundedQuantityValue( new DecimalValue( 42 ), 'mega awesome' @@ -125,7 +125,7 @@ public function testDoesNotSupportNonValueStatements() { $this->assertFalse( $this->newTranslator()->supportsStatement( new Statement( new PropertySomeValueSnak( - new PropertyId( 'P1' ) + new NumericPropertyId( 'P1' ) ) ) ) ); @@ -135,7 +135,7 @@ public function testDoesNotSupportBooleanValueStatements() { $this->assertFalse( $this->newTranslator()->supportsStatement( new Statement( new PropertyValueSnak( - new PropertyId( 'P1' ), + new NumericPropertyId( 'P1' ), new BooleanValue( true ) ) ) diff --git a/tests/Unit/Translation/DataValueTranslatorTest.php b/tests/Unit/Translation/DataValueTranslatorTest.php index 35be23e..315dadd 100644 --- a/tests/Unit/Translation/DataValueTranslatorTest.php +++ b/tests/Unit/Translation/DataValueTranslatorTest.php @@ -20,7 +20,7 @@ use SMWDIUri; use Wikibase\DataModel\Entity\EntityIdValue; use Wikibase\DataModel\Entity\ItemId; -use Wikibase\DataModel\Entity\PropertyId; +use Wikibase\DataModel\Entity\NumericPropertyId; /** * @covers \MediaWiki\Extension\SemanticWikibase\Translation\DataValueTranslator @@ -70,7 +70,7 @@ public function testTranslateEntityId() { $this->assertEquals( new DIWikiPage( 'P42', WB_NS_PROPERTY ), - $this->translate( new EntityIdValue( new PropertyId( 'P42' ) ) ) + $this->translate( new EntityIdValue( new NumericPropertyId( 'P42' ) ) ) ); } diff --git a/tests/Unit/Translation/ItemTranslatorTest.php b/tests/Unit/Translation/ItemTranslatorTest.php index 90429e0..8a66007 100644 --- a/tests/Unit/Translation/ItemTranslatorTest.php +++ b/tests/Unit/Translation/ItemTranslatorTest.php @@ -17,7 +17,7 @@ use SMWDIContainer; use Wikibase\DataModel\Entity\Item; use Wikibase\DataModel\Entity\ItemId; -use Wikibase\DataModel\Entity\PropertyId; +use Wikibase\DataModel\Entity\NumericPropertyId; use Wikibase\DataModel\Snak\PropertyNoValueSnak; use Wikibase\DataModel\Snak\PropertySomeValueSnak; use Wikibase\DataModel\Snak\PropertyValueSnak; @@ -54,7 +54,7 @@ public function testItemIdIsTranslated() { public function testStatementMainSnakValueIsTranslated() { $item = new Item( new ItemId( 'Q1' ) ); $item->getStatements()->addNewStatement( new PropertyValueSnak( - new PropertyId( 'P1' ), + new NumericPropertyId( 'P1' ), new StringValue( 'Hello there' ) ) ); @@ -68,12 +68,12 @@ public function testMultipleStatementsForOneProperty() { $item = new Item( new ItemId( 'Q1' ) ); $item->getStatements()->addNewStatement( new PropertyValueSnak( - new PropertyId( 'P1' ), + new NumericPropertyId( 'P1' ), new StringValue( 'Hello there' ) ) ); $item->getStatements()->addNewStatement( new PropertyValueSnak( - new PropertyId( 'P1' ), + new NumericPropertyId( 'P1' ), new StringValue( 'fellow sentient' ) ) ); @@ -89,8 +89,8 @@ public function testMultipleStatementsForOneProperty() { public function testOnlyPropertyValueSnaksGetAdded() { $item = new Item( new ItemId( 'Q1' ) ); - $item->getStatements()->addNewStatement( new PropertyNoValueSnak( new PropertyId( 'P1' ) ) ); - $item->getStatements()->addNewStatement( new PropertySomeValueSnak( new PropertyId( 'P1' ) ) ); + $item->getStatements()->addNewStatement( new PropertyNoValueSnak( new NumericPropertyId( 'P1' ) ) ); + $item->getStatements()->addNewStatement( new PropertySomeValueSnak( new NumericPropertyId( 'P1' ) ) ); $this->assertSame( [], @@ -103,7 +103,7 @@ public function testTranslationToSubobject() { $item->getStatements()->addNewStatement( new PropertyValueSnak( - new PropertyId( 'P1' ), + new NumericPropertyId( 'P1' ), new UnboundedQuantityValue( new DecimalValue( 42 ), 'mega awesome' @@ -135,7 +135,7 @@ public function testTranslationToSubobject() { ); } - private function assertHasSubobjectWithPropertyValue( SemanticEntity $semanticEntity, string $propertyId, \SMWDataItem $expectedDataItem ) { + private function assertHasSubobjectWithPropertyValue( SemanticEntity $semanticEntity, string $NumericPropertyId, \SMWDataItem $expectedDataItem ) { /** * @var SMWDIContainer $container */ @@ -143,7 +143,7 @@ private function assertHasSubobjectWithPropertyValue( SemanticEntity $semanticEn $this->assertEquals( [ $expectedDataItem ], - $container->getSemanticData()->getPropertyValues( new DIProperty( $propertyId ) ) + $container->getSemanticData()->getPropertyValues( new DIProperty( $NumericPropertyId ) ) ); } diff --git a/tests/Unit/Translation/PropertyTranslatorTest.php b/tests/Unit/Translation/PropertyTranslatorTest.php index efa738b..d66a613 100644 --- a/tests/Unit/Translation/PropertyTranslatorTest.php +++ b/tests/Unit/Translation/PropertyTranslatorTest.php @@ -11,7 +11,7 @@ use MediaWiki\Extension\SemanticWikibase\Translation\FixedProperties; use SMW\DIWikiPage; use Wikibase\DataModel\Entity\Property; -use Wikibase\DataModel\Entity\PropertyId; +use Wikibase\DataModel\Entity\NumericPropertyId; /** * @covers \MediaWiki\Extension\SemanticWikibase\Translation\PropertyTranslator @@ -30,7 +30,7 @@ public function testIdIsTranslated() { private function newProperty(): Property { return new Property( - new PropertyId( self::ID ), + new NumericPropertyId( self::ID ), null, self::TYPE ); diff --git a/tests/Unit/Translation/StatementTranslatorTest.php b/tests/Unit/Translation/StatementTranslatorTest.php index 681f293..00c4281 100644 --- a/tests/Unit/Translation/StatementTranslatorTest.php +++ b/tests/Unit/Translation/StatementTranslatorTest.php @@ -13,7 +13,7 @@ use PHPUnit\Framework\TestCase; use SMW\DIProperty; use SMW\DIWikiPage; -use Wikibase\DataModel\Entity\PropertyId; +use Wikibase\DataModel\Entity\NumericPropertyId; use Wikibase\DataModel\Snak\PropertyValueSnak; use Wikibase\DataModel\Statement\Statement; @@ -32,7 +32,7 @@ public function testTranslateSimpleValue() { $this->newTranslator()->statementToDataItem( new Statement( new PropertyValueSnak( - new PropertyId( 'P1' ), + new NumericPropertyId( 'P1' ), new StringValue( 'Kittens' ) ) ), @@ -45,7 +45,7 @@ public function testTranslateContainerValue() { $container = $this->newTranslator()->statementToDataItem( new Statement( new PropertyValueSnak( - new PropertyId( 'P1' ), + new NumericPropertyId( 'P1' ), new UnboundedQuantityValue( new DecimalValue( 42 ), 'mega awesome' From 8b8be889e2580b8a68cc8cf9764e209de53881ce Mon Sep 17 00:00:00 2001 From: baillyk <123638168+baillyk@users.noreply.github.com> Date: Wed, 24 Apr 2024 15:05:29 +0200 Subject: [PATCH 02/10] Update composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 1f76f5f..4412260 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "semantic web", "wikidata" ], - "homepage": "https://github.com/ProfessionalWiki/SemanticWikibase", + "homepage": "https://github.com/baillyk/SemanticWikibase", "license": "GPL-2.0-or-later", "authors": [ { From dadf59507fa2a1b734e72cf5bd57e62b94b96e8d Mon Sep 17 00:00:00 2001 From: Kolja Bailly Date: Wed, 8 May 2024 17:50:29 +0200 Subject: [PATCH 03/10] first working state with MW v1.38 ; need to edit items to activate semanticProperties, props are saved as specialProps --- extension.json | 4 +- src/EntryPoints/HookHandlers.php | 47 ++++++++++++++++++++- src/SemanticDataUpdate.php | 5 +++ src/SemanticWikibase.php | 8 ++-- src/Translation/ItemTranslator.php | 4 +- src/Translation/PropertyTranslator.php | 4 +- src/Translation/StatementListTranslator.php | 2 +- src/Translation/StatementTranslator.php | 2 +- 8 files changed, 65 insertions(+), 11 deletions(-) diff --git a/extension.json b/extension.json index 8296107..8184921 100644 --- a/extension.json +++ b/extension.json @@ -38,9 +38,11 @@ "callback": "MediaWiki\\Extension\\SemanticWikibase\\EntryPoints\\HookHandlers::onExtensionRegistration", "Hooks": { + "ParserFirstCallInit":"MediaWiki\\Extension\\SemanticWikibase\\EntryPoints\\HookHandlers::onParserFirstCallInit", "SMW::Property::initProperties": "MediaWiki\\Extension\\SemanticWikibase\\EntryPoints\\HookHandlers::onSmwInitProperties", "SMW::SQLStore::AddCustomFixedPropertyTables": "MediaWiki\\Extension\\SemanticWikibase\\EntryPoints\\HookHandlers::onSmwAddCustomFixedPropertyTables", - "SMWStore::updateDataBefore": "MediaWiki\\Extension\\SemanticWikibase\\EntryPoints\\HookHandlers::onSmwUpdateDataBefore" + "SMW::SQLStore::BeforeDataUpdateComplete": "MediaWiki\\Extension\\SemanticWikibase\\EntryPoints\\HookHandlers::onSmwUpdateDataBefore", + "MultiContentSave": "MediaWiki\\Extension\\SemanticWikibase\\EntryPoints\\HookHandlers::onMultiContentSave" }, "config": { diff --git a/src/EntryPoints/HookHandlers.php b/src/EntryPoints/HookHandlers.php index 8ab1ec3..508f4a8 100644 --- a/src/EntryPoints/HookHandlers.php +++ b/src/EntryPoints/HookHandlers.php @@ -4,11 +4,22 @@ namespace MediaWiki\Extension\SemanticWikibase\EntryPoints; +use MediaWiki\Revision\RenderedRevision; +use MediaWiki\User\UserIdentity; +use CommentStoreComment; +use Status; +use MediaWiki\MediaWikiServices; +use MediaWiki\TitleFactory; use MediaWiki\Extension\SemanticWikibase\SemanticWikibase; +use SMW\Services\ServicesFactory as ApplicationFactory; use SMW\PropertyRegistry; use SMW\SemanticData; +use SMW\DIWikiPage; +use SMW\StoreFactory; use SMW\Store; +use Parser; + class HookHandlers { public static function onExtensionRegistration(): void { @@ -17,18 +28,52 @@ public static function onExtensionRegistration(): void { $smwgNamespacesWithSemanticLinks[WB_NS_PROPERTY] = true; } + public static function onParserFirstCallInit( Parser $parser ) { + # getInstance() will call initProperties() which aktivates existing hook onSmwInitProperties() + wfDebug( __METHOD__ . "SWB: onParserFirstCallInit" ); + PropertyRegistry::getInstance(); + } + public static function onSmwInitProperties( PropertyRegistry $propertyRegistry ): void { - SemanticWikibase::getGlobalInstance()->registerProperties( $propertyRegistry ); + wfDebug( __METHOD__ . "SWB: onSmwInitProperties..." ); + SemanticWikibase::getGlobalInstance()->registerProperties( $propertyRegistry ); } public static function onSmwAddCustomFixedPropertyTables( array &$customFixedProperties, array &$fixedPropertyTablePrefix ): void { + wfDebug( __METHOD__ . "SWB: onSmwAddCustomFixedPropertyTables" ); SemanticWikibase::getGlobalInstance()->getFixedProperties() ->registerFixedTables( $customFixedProperties, $fixedPropertyTablePrefix ); } public static function onSmwUpdateDataBefore( Store $store, SemanticData $semanticData ): void { + wfDebug( __METHOD__ . "SWB: onSmwUpdateDataBefore" ); SemanticWikibase::getGlobalInstance()->getSemanticDataUpdate() ->run( $semanticData ); + } + public static function onPageSaveComplete( WikiPage $wikiPage, MediaWiki\User\UserIdentity $user, string $summary, int $flags, MediaWiki\Revision\RevisionRecord $revisionRecord, MediaWiki\Storage\EditResult $editResult ) { + wfDebug( __METHOD__ . "SWB: onPageSaveComplete" ); + // Access the semantic data of the page via the Semantic MediaWiki API + $semanticData = \SMW\MediaWiki\Hooks\ParserHooks::getSemanticDataForPage($wikiPage); + + onSmwUpdateDataBefore(null, $semanticData); + } + + public static function onMultiContentSave( RenderedRevision $renderedRevision, UserIdentity $user, CommentStoreComment $summary, $flags, Status $hookStatus ) { + wfDebug( __METHOD__ . "SWB: onMultiContentSave" ); + $revision = $renderedRevision->getRevision(); + + $titleFactory = MediaWikiServices::getInstance()->getTitleFactory(); + $title = $titleFactory->newFromLinkTarget($revision->getPageAsLinkTarget()); + wfDebug( __METHOD__ . "SWB: onMultiContentSave...title:".$title ); + $subject = DIWikiPage::newFromTitle( $title ); + #$new_content = $revision->getContent(SlotRecord::MAIN, RevisionRecord::RAW)->getNativeData(); + $semanticData = StoreFactory::getStore()->getSemanticData( DIWikiPage::newFromTitle( $title ) ); + wfDebug( __METHOD__ . "SWB: onMultiContentSave: ".json_encode($semanticData) ); + SemanticWikibase::getGlobalInstance()->getSemanticDataUpdate()->run( $semanticData ); + + return true; + } + } diff --git a/src/SemanticDataUpdate.php b/src/SemanticDataUpdate.php index 8bdefed..e182b2e 100644 --- a/src/SemanticDataUpdate.php +++ b/src/SemanticDataUpdate.php @@ -63,6 +63,11 @@ private function newItemTranslator( Title $title ): ItemTranslator { } private function getSemanticEntityForPropertyTitle( Title $title ): SemanticEntity { + wfDebug(__METHOD__. "swb: getSemanticEntity:".json_encode($title)); + wfDebug(__METHOD__. "swb: getSemanticEntity:".json_encode($title->getText())); + wfDebug(__METHOD__. "swb: getSemanticEntity:".json_encode(new NumericPropertyId( $title->getText() ))); + wfDebug(__METHOD__. "swb: getSemanticEntity:".json_encode($this->propertyLookup->getPropertyForId( new NumericPropertyId( $title->getText() ) ))); + return $this->newPropertyTranslator( $title )->translateProperty( $this->propertyLookup->getPropertyForId( new NumericPropertyId( $title->getText() ) ) ); diff --git a/src/SemanticWikibase.php b/src/SemanticWikibase.php index 05c728c..038b9b8 100644 --- a/src/SemanticWikibase.php +++ b/src/SemanticWikibase.php @@ -62,15 +62,17 @@ protected function getPropertyTypeLookup(): PropertyDataTypeLookup { } public function registerProperties( PropertyRegistry $propertyRegistry ) { + wfDebug("SWB: register properties ".json_encode($this->getAllProperties())); foreach ( $this->getAllProperties() as $property ) { $propertyRegistry->registerProperty( $property->getId(), $property->getType(), $property->getLabel(), - true, - false + true, #is_visible + true, #is_annotable + false #is_declarative ); - + wfDebug("SWB: register property ".$property->getId()); foreach ( $property->getAliases() as $alias ) { $propertyRegistry->registerPropertyAlias( $property->getId(), $alias ); } diff --git a/src/Translation/ItemTranslator.php b/src/Translation/ItemTranslator.php index ebc877f..4b5d5f7 100644 --- a/src/Translation/ItemTranslator.php +++ b/src/Translation/ItemTranslator.php @@ -18,10 +18,10 @@ public function __construct( FingerprintTranslator $fingerprintTranslator, State $this->statementListTranslator = $statementListTranslator; } - public function translateItem( Item $item ): SemanticEntity { + public function translateItem( ?Item $item ): SemanticEntity { $semanticEntity = new SemanticEntity(); - if ( $item->getId() === null ) { + if ( $item === null || $item->getId() === null ) { return $semanticEntity; } diff --git a/src/Translation/PropertyTranslator.php b/src/Translation/PropertyTranslator.php index b0dc29d..1bc3ac6 100644 --- a/src/Translation/PropertyTranslator.php +++ b/src/Translation/PropertyTranslator.php @@ -18,10 +18,10 @@ public function __construct( FingerprintTranslator $fingerprintTranslator, State $this->statementListTranslator = $statementListTranslator; } - public function translateProperty( Property $property ): SemanticEntity { + public function translateProperty( ?Property $property ): SemanticEntity { $semanticEntity = new SemanticEntity(); - if ( $property->getId() === null ) { + if ( $property === null || $property->getId() === null ) { return $semanticEntity; } diff --git a/src/Translation/StatementListTranslator.php b/src/Translation/StatementListTranslator.php index e6b3074..3564850 100644 --- a/src/Translation/StatementListTranslator.php +++ b/src/Translation/StatementListTranslator.php @@ -53,7 +53,7 @@ private function addStatement( SemanticEntity $semanticEntity, Statement $statem } private function NumericPropertyIdForStatement( Statement $statement ): string { - return UserDefinedProperties::idFromWikibaseProperty( $statement->getNumericPropertyId() ); + return UserDefinedProperties::idFromWikibaseProperty( $statement->getPropertyId() ); } } diff --git a/src/Translation/StatementTranslator.php b/src/Translation/StatementTranslator.php index 3a0a6fe..a58ee90 100644 --- a/src/Translation/StatementTranslator.php +++ b/src/Translation/StatementTranslator.php @@ -40,7 +40,7 @@ public function statementToDataItem( Statement $statement, DIWikiPage $subject ) private function snakWithSimpleDataValueToDataItem( PropertyValueSnak $snak ): SMWDataItem { return $this->dataValueTranslator->translate( new TypedDataValue( - $this->propertyTypeLookup->getDataTypeIdForProperty( $snak->getNumericPropertyId() ), + $this->propertyTypeLookup->getDataTypeIdForProperty( $snak->getPropertyId() ), $snak->getDataValue() ) ); From 04071f85a99a1f3739e45a8ab50508bf0120590a Mon Sep 17 00:00:00 2001 From: Kolja Bailly Date: Wed, 22 May 2024 14:58:21 +0200 Subject: [PATCH 04/10] added basic support of Wikibase qualifiers and prepared support of additional datatypes (edtf, localMedia) --- src/Translation/DataValueTranslator.php | 25 +++++++++++++++++++-- src/Translation/PropertyTypeTranslator.php | 2 ++ src/Translation/StatementListTranslator.php | 19 ++++++++++++++++ src/Translation/StatementTranslator.php | 17 ++++++++++++-- src/Translation/UserDefinedProperties.php | 2 ++ 5 files changed, 61 insertions(+), 4 deletions(-) diff --git a/src/Translation/DataValueTranslator.php b/src/Translation/DataValueTranslator.php index 3472fa5..7347507 100644 --- a/src/Translation/DataValueTranslator.php +++ b/src/Translation/DataValueTranslator.php @@ -20,12 +20,14 @@ use Wikibase\DataModel\Entity\EntityIdValue; use Wikibase\DataModel\Entity\ItemId; use Wikibase\DataModel\Entity\NumericPropertyId; +use EDTF\Services\TimeValueBuilder; +use EDTF\EdtfValue; class DataValueTranslator { public function translate( TypedDataValue $typedValue ): SMWDataItem { $value = $typedValue->getValue(); - + wfDebug("swb: translate". get_class( $value )); if ( $value instanceof StringValue ) { return $this->translateStringValue( $typedValue ); } @@ -47,7 +49,12 @@ public function translate( TypedDataValue $typedValue ): SMWDataItem { if ( $value instanceof TimeValue ) { return $this->translateTimeValue( $value ); } - + if ( $value instanceof EdtfValue ) { + wfDebug("swb: translate edtf"); + $tvb = new TimeValueBuilder( EdtfFactory::newParser() ); + return $tvb->singleValueEdtfToTimeValue($value); + } + throw new \RuntimeException( 'Support for DataValue type "' . get_class( $value ) . '" not implemented' ); } @@ -89,6 +96,20 @@ public function translateDecimalValue( DecimalValue $value ): SMWDataItem { return new \SMWDINumber( $value->getValueFloat() ); } + private function translateEDTF(WikibaseEdtf $value):\SMWDITime { + $components = ( new TimeValueParser() )->parse( $value->getTime() ); + + return new WikibaseEdtf( + $this->wbToSmwCalendarModel( $value->getCalendarModel() ), + $components->get( 'datecomponents' )[0], + $components->get( 'datecomponents' )[2], + $components->get( 'datecomponents' )[4], + $components->get( 'hours' ), + $components->get( 'minutes' ), + $components->get( 'seconds' ), + ); + } + private function translateTimeValue( TimeValue $value ): \SMWDITime { $components = ( new TimeValueParser() )->parse( $value->getTime() ); diff --git a/src/Translation/PropertyTypeTranslator.php b/src/Translation/PropertyTypeTranslator.php index 37676ae..49521f1 100644 --- a/src/Translation/PropertyTypeTranslator.php +++ b/src/Translation/PropertyTypeTranslator.php @@ -38,10 +38,12 @@ private function getMap(): array { 'tabular-data' => null, // TODO 'entity-schema' => null, // TODO 'time' => SMWTimeValue::TYPE_ID, + 'edtf' => SMWTimeValue::TYPE_ID, 'url' => '_uri', 'external-id' => ExternalIdentifierValue::TYPE_ID, 'wikibase-item' => '_wpg', 'wikibase-property' => '_wpg', + 'localMedia' => '_wpg' ]; if ( class_exists( CoordinateValue::class ) ) { diff --git a/src/Translation/StatementListTranslator.php b/src/Translation/StatementListTranslator.php index 3564850..7e71571 100644 --- a/src/Translation/StatementListTranslator.php +++ b/src/Translation/StatementListTranslator.php @@ -9,6 +9,8 @@ use SMW\DIWikiPage; use Wikibase\DataModel\Statement\Statement; use Wikibase\DataModel\Statement\StatementList; +use MWException; +use SMW\PropertyRegistry; class StatementListTranslator { @@ -25,6 +27,7 @@ public function translateStatements( StatementList $statements ): SemanticEntity foreach ( $statements->getBestStatements()->getByRank( [ Statement::RANK_PREFERRED, Statement::RANK_NORMAL ] ) as $statement ) { $this->addStatement( $semanticEntity, $statement ); + } return $semanticEntity; @@ -49,6 +52,22 @@ private function addStatement( SemanticEntity $semanticEntity, Statement $statem $dataItem ); } + + // now process qualifiers + $qualifiers = $statement->getQualifiers(); + $i = 1; + foreach( $qualifiers as $actQualifier) { + $actQualifierDataItem = $this->statementTranslator->snakToDataItem($actQualifier, $statement, $this->subject); + + // TODO: do we need to handle type SMWDIContainer here? + //throw new MWException(json_encode($actQualifier->getDataValue())); + $newPropId = $statement->getPropertyId()->getSerialization()."hasQualifier".$actQualifier->getPropertyId(); + $semanticEntity->addPropertyValue( + $newPropId, + $actQualifierDataItem + ); + $i++; + } } } diff --git a/src/Translation/StatementTranslator.php b/src/Translation/StatementTranslator.php index a58ee90..f4ca83b 100644 --- a/src/Translation/StatementTranslator.php +++ b/src/Translation/StatementTranslator.php @@ -25,8 +25,21 @@ public function __construct( DataValueTranslator $dataValueTranslator, Container public function statementToDataItem( Statement $statement, DIWikiPage $subject ): ?SMWDataItem { $mainSnak = $statement->getMainSnak(); + return $this->snakToDataItem($mainSnak, $statement, $subject); + } + + public function statementToQualifiersDataItemList( Statement $statement, DIWikiPage $subject ): array { + $qualifiers = $statement->getQualifiers(); + $result = []; + foreach( $qualifiers as $actQualifier) { + $result[] = $this->snakToDataItem($actQualifier, $statement, $subject); + } + + return $result; + } - if ( !( $mainSnak instanceof PropertyValueSnak ) ) { + public function snakToDataItem( PropertyValueSnak $snak, Statement $statement, DIWikiPage $subject ): ?SMWDataItem { + if ( !( $snak instanceof PropertyValueSnak ) ) { return null; } @@ -34,7 +47,7 @@ public function statementToDataItem( Statement $statement, DIWikiPage $subject ) return $this->containerValueTranslator->statementToDataItem( $statement, $subject ); } - return $this->snakWithSimpleDataValueToDataItem( $mainSnak ); + return $this->snakWithSimpleDataValueToDataItem( $snak ); } private function snakWithSimpleDataValueToDataItem( PropertyValueSnak $snak ): SMWDataItem { diff --git a/src/Translation/UserDefinedProperties.php b/src/Translation/UserDefinedProperties.php index d84b525..f887a74 100644 --- a/src/Translation/UserDefinedProperties.php +++ b/src/Translation/UserDefinedProperties.php @@ -44,6 +44,8 @@ public function getAll(): array { $this->labelLanguageCode ) ); + }else{ + wfDebug("swb: cannot translate ".$propertyInfo['type']); } } From 9caf3feecc29ee60db26e1d9f3b10adcf13ac226 Mon Sep 17 00:00:00 2001 From: Kolja Bailly Date: Fri, 31 May 2024 10:40:45 +0200 Subject: [PATCH 05/10] added support of wikibase statement qualifiers --- src/Translation/DataValueTranslator.php | 10 +++- src/Translation/StatementListTranslator.php | 35 +++++++++----- src/Translation/StatementTranslator.php | 52 ++++++++++++++++++++- 3 files changed, 82 insertions(+), 15 deletions(-) diff --git a/src/Translation/DataValueTranslator.php b/src/Translation/DataValueTranslator.php index 7347507..89e2dc1 100644 --- a/src/Translation/DataValueTranslator.php +++ b/src/Translation/DataValueTranslator.php @@ -22,12 +22,16 @@ use Wikibase\DataModel\Entity\NumericPropertyId; use EDTF\Services\TimeValueBuilder; use EDTF\EdtfValue; +use MediaWiki\Logger\LoggerFactory; class DataValueTranslator { public function translate( TypedDataValue $typedValue ): SMWDataItem { + + $value = $typedValue->getValue(); - wfDebug("swb: translate". get_class( $value )); + + if ( $value instanceof StringValue ) { return $this->translateStringValue( $typedValue ); } @@ -46,11 +50,13 @@ public function translate( TypedDataValue $typedValue ): SMWDataItem { if ( $value instanceof GlobeCoordinateValue ) { return $this->translateGlobeCoordinateValue( $value ); } + if ( $value instanceof TimeValue ) { + return $this->translateTimeValue( $value ); } if ( $value instanceof EdtfValue ) { - wfDebug("swb: translate edtf"); + $tvb = new TimeValueBuilder( EdtfFactory::newParser() ); return $tvb->singleValueEdtfToTimeValue($value); } diff --git a/src/Translation/StatementListTranslator.php b/src/Translation/StatementListTranslator.php index 7e71571..dcee94f 100644 --- a/src/Translation/StatementListTranslator.php +++ b/src/Translation/StatementListTranslator.php @@ -11,6 +11,9 @@ use Wikibase\DataModel\Statement\StatementList; use MWException; use SMW\PropertyRegistry; +use SMW\Subobject; +use SMW\StoreFactory; +use SMW\Store; class StatementListTranslator { @@ -25,35 +28,45 @@ public function __construct( StatementTranslator $statementTranslator, DIWikiPag public function translateStatements( StatementList $statements ): SemanticEntity { $semanticEntity = new SemanticEntity(); + $i = 1; foreach ( $statements->getBestStatements()->getByRank( [ Statement::RANK_PREFERRED, Statement::RANK_NORMAL ] ) as $statement ) { - $this->addStatement( $semanticEntity, $statement ); - + $this->addStatement( $semanticEntity, $statement, $i ); + $i++; } return $semanticEntity; } - private function addStatement( SemanticEntity $semanticEntity, Statement $statement ): void { - $dataItem = $this->statementTranslator->statementToDataItem( $statement, $this->subject ); + private function addStatement( SemanticEntity $semanticEntity, Statement $statement, $statementNr ): void { + $mainSnakDataItem = $this->statementTranslator->statementToDataItem( $statement, $this->subject ); - if ( $dataItem !== null ) { + if ( $mainSnakDataItem !== null ) { + // first link the statement value directly via property name // TODO: belongs in statement translator - if ( $dataItem instanceof \SMWDIContainer ) { - $semanticEntity->addPropertyValue( DIProperty::TYPE_SUBOBJECT, $dataItem ); + if ( $mainSnakDataItem instanceof \SMWDIContainer ) { + $semanticEntity->addPropertyValue( DIProperty::TYPE_SUBOBJECT, $mainSnakDataItem ); $semanticEntity->addPropertyValue( $this->NumericPropertyIdForStatement( $statement ), - $dataItem->getSemanticData()->getSubject() + $mainSnakDataItem->getSemanticData()->getSubject() ); } else { $semanticEntity->addPropertyValue( $this->NumericPropertyIdForStatement( $statement ), - $dataItem + $mainSnakDataItem ); } + // for complex data e.g. using qualifiers, we add the statement additionally as a subobject + $subObjs = $this->statementTranslator->statementToSubobjects($statement, $this->subject, $statementNr); + foreach($subObjs as $subObject ){ + $semanticEntity->addPropertyValue( DIProperty::TYPE_SUBOBJECT, $subObject->getContainer() ); + } + //$semanticEntity->addPropertyValue( 'STATEMENTS', $subObject->getContainer() ); + // now process qualifiers + /* $qualifiers = $statement->getQualifiers(); $i = 1; foreach( $qualifiers as $actQualifier) { @@ -66,8 +79,8 @@ private function addStatement( SemanticEntity $semanticEntity, Statement $statem $newPropId, $actQualifierDataItem ); - $i++; - } + $i++; + }*/ } } diff --git a/src/Translation/StatementTranslator.php b/src/Translation/StatementTranslator.php index f4ca83b..4ea1407 100644 --- a/src/Translation/StatementTranslator.php +++ b/src/Translation/StatementTranslator.php @@ -5,11 +5,15 @@ namespace MediaWiki\Extension\SemanticWikibase\Translation; use MediaWiki\Extension\SemanticWikibase\Wikibase\TypedDataValue; -use SMW\DIWikiPage; -use SMWDataItem; use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup; use Wikibase\DataModel\Snak\PropertyValueSnak; use Wikibase\DataModel\Statement\Statement; +use SMW\DIWikiPage; +use SMWDataItem; +use SMW\Subobject; +use SMW\DataValueFactory; +use SMW\DIProperty; +use MWNamespace; class StatementTranslator { @@ -59,4 +63,48 @@ private function snakWithSimpleDataValueToDataItem( PropertyValueSnak $snak ): S ); } + public function statementToSubobjects( Statement $statement, DIWikiPage $subject , $statementNr): array { + $result = []; + $mainSnak = $statement->getMainSnak(); + $qualifiers = $statement->getQualifiers(); + // create a smw semantic subobject for the statement + $statementObj = new Subobject($subject->getTitle()); + $statementObj->setEmptyContainerForId("statement"); + $statementObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('subObjectType', 'statement', false, $subject) ); + $statementObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('property', MWNamespace::getCanonicalName(WB_NS_PROPERTY).":".$mainSnak->getPropertyId()->getLocalPart(), false, $subject) ); + + + $mainSnakDI = $this->snakToDataItem($mainSnak, $statement, $subject); + $statementObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('value', StatementTranslator::valueDIToString($mainSnakDI), false, $subject) ); + $result[] = $statementObj; + $qNr = 1; + foreach( $qualifiers as $actQualifier){ + $qualifierId = "statement".$statementNr."-qualifier".$qNr; + $qualifierObj = new Subobject($subject->getTitle()); + $qualifierObj->setEmptyContainerForId($qualifierId); + $qualifierObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('subObjectType', 'qualifier', false, $subject) ); + $qualifierObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('property', MWNamespace::getCanonicalName(WB_NS_PROPERTY).":".$actQualifier->getPropertyId()->getLocalPart(), false, $subject) ); + $qualifierDI = $this->snakToDataItem($actQualifier, $statement, $subject); + $qualifierObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('value', StatementTranslator::valueDIToString($qualifierDI), false, $subject) ); + + // set reference in statement obj + $qualifierPage = $subject->getTitle()."#".$qualifierId; + $statementObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('qualifier', $qualifierPage, false, $subject) ); + $qNr++; + $result[] = $qualifierObj; + } + + return $result; + + } + + private static function valueDIToString($di) : string { + if( $di instanceof DIWikiPage ) { + return $di->getTitle().""; + } + return $di.""; + + } + } + From 7c1856b83ed232834b93005d3c32e8c6f78f09aa Mon Sep 17 00:00:00 2001 From: Kolja Bailly Date: Wed, 5 Jun 2024 13:05:37 +0200 Subject: [PATCH 06/10] added qualifier support --- src/SMW/SemanticEntity.php | 14 +++++ src/SemanticWikibase.php | 1 + src/Translation/DataValueTranslator.php | 80 ++++++++++++++++++------- src/Translation/StatementTranslator.php | 54 +++++++++++++---- 4 files changed, 119 insertions(+), 30 deletions(-) diff --git a/src/SMW/SemanticEntity.php b/src/SMW/SemanticEntity.php index d9ca4f4..7255562 100644 --- a/src/SMW/SemanticEntity.php +++ b/src/SMW/SemanticEntity.php @@ -8,15 +8,21 @@ use SMW\DIWikiPage; use SMW\SemanticData; use SMWDataItem; +use SMW\Subobject; class SemanticEntity { private array $dataItemsPerProperty = []; + private array $subObjectsPerProperty=[]; public function addPropertyValue( string $NumericPropertyId, SMWDataItem $dataItem ) { $this->dataItemsPerProperty[$NumericPropertyId][] = $dataItem; } + public function addSubobject( string $NumericPropertyId, SubObject $subobject ){ + $this->subObjectsPerProperty[$NumericPropertyId][] = $subobject; + } + /** * @param string $NumericPropertyId * @return SMWDataItem[] @@ -39,6 +45,14 @@ public function toSemanticData( DIWikiPage $subject ): SemanticData { } } + foreach ( $this->subObjectsPerProperty as $NumericPropertyId => $subobjects ) { + $property = new DIProperty( $NumericPropertyId ); + + foreach ( $subobjects as $subobject ) { + $semanticData->addSubobject($subobject); + } + } + return $semanticData; } diff --git a/src/SemanticWikibase.php b/src/SemanticWikibase.php index 038b9b8..1cc2a7f 100644 --- a/src/SemanticWikibase.php +++ b/src/SemanticWikibase.php @@ -73,6 +73,7 @@ public function registerProperties( PropertyRegistry $propertyRegistry ) { false #is_declarative ); wfDebug("SWB: register property ".$property->getId()); + wfDebug("SWB: register property ".$property->getType()); foreach ( $property->getAliases() as $alias ) { $propertyRegistry->registerPropertyAlias( $property->getId(), $alias ); } diff --git a/src/Translation/DataValueTranslator.php b/src/Translation/DataValueTranslator.php index 89e2dc1..f58f166 100644 --- a/src/Translation/DataValueTranslator.php +++ b/src/Translation/DataValueTranslator.php @@ -20,9 +20,13 @@ use Wikibase\DataModel\Entity\EntityIdValue; use Wikibase\DataModel\Entity\ItemId; use Wikibase\DataModel\Entity\NumericPropertyId; -use EDTF\Services\TimeValueBuilder; -use EDTF\EdtfValue; +use Wikibase\EDTF\Services\TimeValueBuilder; +use Wikibase\EDTF\EdtfValue; use MediaWiki\Logger\LoggerFactory; +use EDTF\EdtfFactory; +use EDTF\Model\ExtDate; +use EDTF\Model\ExtDateTime; +use EDTF\Model\Interval; class DataValueTranslator { @@ -30,9 +34,16 @@ public function translate( TypedDataValue $typedValue ): SMWDataItem { $value = $typedValue->getValue(); - + $propertyType = $typedValue->getPropertyType(); + if( $value != null) { + wfDebug( 'swb: translate: '.get_class( $value ).' ptype: '.$propertyType ); + } if ( $value instanceof StringValue ) { + wfDebug( 'swb: translate: '. $typedValue->getValue()->getValue() ); + if( $propertyType == 'edtf') { + return $this->translateEDTF("".$value->getValue()); + } return $this->translateStringValue( $typedValue ); } if ( $value instanceof BooleanValue ) { @@ -52,14 +63,10 @@ public function translate( TypedDataValue $typedValue ): SMWDataItem { } if ( $value instanceof TimeValue ) { - + wfDebug( 'swb: translate time: '. $$value.toString() ); return $this->translateTimeValue( $value ); } - if ( $value instanceof EdtfValue ) { - - $tvb = new TimeValueBuilder( EdtfFactory::newParser() ); - return $tvb->singleValueEdtfToTimeValue($value); - } + throw new \RuntimeException( 'Support for DataValue type "' . get_class( $value ) . '" not implemented' ); } @@ -102,18 +109,51 @@ public function translateDecimalValue( DecimalValue $value ): SMWDataItem { return new \SMWDINumber( $value->getValueFloat() ); } - private function translateEDTF(WikibaseEdtf $value):\SMWDITime { - $components = ( new TimeValueParser() )->parse( $value->getTime() ); + private function translateEDTF( String $value ): \SMWDITime { + wfDebug( 'swb: translate edtf' ); + $tvb = new TimeValueBuilder( EdtfFactory::newParser() ); + $tvArr = $tvb->edtfToTimeValues( $value ); + $parser = \EDTF\EdtfFactory::newParser(); + $parsingResult = $parser->parse($value); + wfDebug($parsingResult->isValid()); // true + $edtfValue = $parsingResult->getEdtfValue(); // \EDTF\EdtfValue + $humanizer = \EDTF\EdtfFactory::newHumanizerForLanguage( 'en' ); + wfDebug($humanizer->humanize($edtfValue)); // string + wfDebug(get_class($edtfValue)); // string + $result = null; + + if ( $edtfValue instanceof Interval ) { + if($edtfValue->hasStartDate()){ + $edtfValue = $edtfValue->getStartDate(); + } else if ($edtfValue->hasEndDate()){ + $edtfValue = $edtfValue->getEndDate(); + } else { + wfDebug('ERROR: unable to translate empty edtf interval to smw date'); + return null; + } + } - return new WikibaseEdtf( - $this->wbToSmwCalendarModel( $value->getCalendarModel() ), - $components->get( 'datecomponents' )[0], - $components->get( 'datecomponents' )[2], - $components->get( 'datecomponents' )[4], - $components->get( 'hours' ), - $components->get( 'minutes' ), - $components->get( 'seconds' ), - ); + if( $edtfValue instanceof ExtDate ) { + $result = new \SMWDITime( + SMWDITime::CM_GREGORIAN, + $edtfValue->getYear(), + $edtfValue->getMonth(), + $edtfValue->getDay() + ); + + } else if ( $edtfValue instanceof ExtDateTime ) { + $result = new \SMWDITime( + SMWDITime::CM_GREGORIAN, + $edtfValue->getYear(), + $edtfValue->getMonth(), + $edtfValue->getDay(), + $edtfValue->getHour(), + $edtfValue->getMinute(), + $edtfValue->getSecond() + ); + } + wfDebug($result->getMwTimestamp()); + return $result; } private function translateTimeValue( TimeValue $value ): \SMWDITime { diff --git a/src/Translation/StatementTranslator.php b/src/Translation/StatementTranslator.php index 4ea1407..4669202 100644 --- a/src/Translation/StatementTranslator.php +++ b/src/Translation/StatementTranslator.php @@ -13,7 +13,8 @@ use SMW\Subobject; use SMW\DataValueFactory; use SMW\DIProperty; -use MWNamespace; +use MediaWiki\MediaWikiServices; +use SMWDITime; class StatementTranslator { @@ -65,31 +66,56 @@ private function snakWithSimpleDataValueToDataItem( PropertyValueSnak $snak ): S public function statementToSubobjects( Statement $statement, DIWikiPage $subject , $statementNr): array { $result = []; + $wbPropertyNamespaceName = MediaWikiServices::getInstance()->getNamespaceInfo()->getCanonicalName( WB_NS_PROPERTY ); + $smwPropertyNamespaceName = MediaWikiServices::getInstance()->getNamespaceInfo()->getCanonicalName( SMW_NS_PROPERTY ); + $mainSnak = $statement->getMainSnak(); $qualifiers = $statement->getQualifiers(); + $mainSnakDI = $this->snakToDataItem($mainSnak, $statement, $subject); // create a smw semantic subobject for the statement + $statementProperty = $mainSnak->getPropertyId()->getLocalPart(); + $statementValue = StatementTranslator::valueDIToString($mainSnakDI); + $statementObj = new Subobject($subject->getTitle()); - $statementObj->setEmptyContainerForId("statement"); + $statementObj->setEmptyContainerForId("statement".$statementNr); $statementObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('subObjectType', 'statement', false, $subject) ); - $statementObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('property', MWNamespace::getCanonicalName(WB_NS_PROPERTY).":".$mainSnak->getPropertyId()->getLocalPart(), false, $subject) ); - - - $mainSnakDI = $this->snakToDataItem($mainSnak, $statement, $subject); - $statementObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('value', StatementTranslator::valueDIToString($mainSnakDI), false, $subject) ); + //$statementObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('item', $subject->getTitle(), false, $subject) ); + $statementObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('property_name', $statementProperty, false, $subject) ); + $statementObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('property_wb', $wbPropertyNamespaceName.":".$statementProperty, false, $subject) ); + $statementObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('property_smw', $smwPropertyNamespaceName.":".$statementProperty, false, $subject) ); + $statementObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('value', $statementValue, false, $subject) ); + $statementObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText($statementProperty, $statementValue, false, $subject) ); + #$prop = DIProperty::newFromUserLabel($mainSnak->getPropertyId()->getLocalPart()); + $prop = new DIProperty( 'semanticProperty:value'); + wfDebug('swb: prop: '.$prop); + $propertyDV = DataValueFactory::getInstance()->newPropertyValueByLabel("value"); + $propertyDI = $propertyDV->getDataItem(); + #$statementObj->addDataValue( DataValueFactory::getInstance()->newDataValueByItem($mainSnakDI, $propertyDI)); $result[] = $statementObj; $qNr = 1; + $statementPage = $subject->getTitle()."#statement".$statementNr; foreach( $qualifiers as $actQualifier){ + $qualifierProperty = $actQualifier->getPropertyId()->getLocalPart(); $qualifierId = "statement".$statementNr."-qualifier".$qNr; $qualifierObj = new Subobject($subject->getTitle()); $qualifierObj->setEmptyContainerForId($qualifierId); $qualifierObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('subObjectType', 'qualifier', false, $subject) ); - $qualifierObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('property', MWNamespace::getCanonicalName(WB_NS_PROPERTY).":".$actQualifier->getPropertyId()->getLocalPart(), false, $subject) ); + //$qualifierObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('item', $subject->getTitle(), false, $subject) ); + $qualifierObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('statement', $statementPage, false, $subject) ); + $qualifierObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('property_name', $qualifierProperty, false, $subject) ); + $qualifierObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('property_wb', $wbPropertyNamespaceName.":".$qualifierProperty, false, $subject) ); + $qualifierObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('property_smw', $smwPropertyNamespaceName.":".$qualifierProperty, false, $subject) ); $qualifierDI = $this->snakToDataItem($actQualifier, $statement, $subject); - $qualifierObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('value', StatementTranslator::valueDIToString($qualifierDI), false, $subject) ); + $qualifierValue = StatementTranslator::valueDIToString($qualifierDI); + $qualifierObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('value', $qualifierValue, false, $subject) ); + $qualifierObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText($qualifierProperty, $qualifierValue, false, $subject) ); // set reference in statement obj $qualifierPage = $subject->getTitle()."#".$qualifierId; $statementObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText('qualifier', $qualifierPage, false, $subject) ); + $statementObj->addDataValue( DataValueFactory::getInstance()->newDataValueByText($statementProperty.$statementValue, $qualifierPage, false, $subject) ); + + $qNr++; $result[] = $qualifierObj; } @@ -98,10 +124,18 @@ public function statementToSubobjects( Statement $statement, DIWikiPage $subject } + + private static function valueDIToString($di) : string { + wfDebug('smw: translate DI: '.get_class($di)); if( $di instanceof DIWikiPage ) { - return $di->getTitle().""; + return $di->getTitle()->getText().""; + } else if ( $di instanceof SMWDITime){ + wfDebug('time:'.$di->getSerialization()); + return $di->asDateTime()->format( 'Y-m-d H:i:s' ); + #return "01.01.1700"; } + wfdebug('default'); return $di.""; } From 3740583a09d4d1b2d22a5589969013276639c1ae Mon Sep 17 00:00:00 2001 From: baillyk <123638168+baillyk@users.noreply.github.com> Date: Wed, 18 Sep 2024 18:38:28 +0200 Subject: [PATCH 07/10] Update DataValueTranslator.php removed debug msg to avoid nullpointerexception when running mediawiki maintenance/importDump script --- src/Translation/DataValueTranslator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Translation/DataValueTranslator.php b/src/Translation/DataValueTranslator.php index f58f166..82923c5 100644 --- a/src/Translation/DataValueTranslator.php +++ b/src/Translation/DataValueTranslator.php @@ -152,7 +152,7 @@ private function translateEDTF( String $value ): \SMWDITime { $edtfValue->getSecond() ); } - wfDebug($result->getMwTimestamp()); + return $result; } From c4f259aecc7446885ac3b16d0092f9731a4e2b6c Mon Sep 17 00:00:00 2001 From: baillyk <123638168+baillyk@users.noreply.github.com> Date: Wed, 18 Sep 2024 18:46:49 +0200 Subject: [PATCH 08/10] Update DataValueTranslator.php handle null values --- src/Translation/DataValueTranslator.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Translation/DataValueTranslator.php b/src/Translation/DataValueTranslator.php index 82923c5..59e43e9 100644 --- a/src/Translation/DataValueTranslator.php +++ b/src/Translation/DataValueTranslator.php @@ -151,7 +151,13 @@ private function translateEDTF( String $value ): \SMWDITime { $edtfValue->getMinute(), $edtfValue->getSecond() ); - } + } else { + $result = new \SMWDITime( + SMWDITime::CM_GREGORIAN, + 0 + ); + + } return $result; } From 2523e745f80acc18f185806dec5b54625e5e439a Mon Sep 17 00:00:00 2001 From: baillyk <123638168+baillyk@users.noreply.github.com> Date: Wed, 18 Sep 2024 19:47:29 +0200 Subject: [PATCH 09/10] Update DataValueTranslator.php --- src/Translation/DataValueTranslator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Translation/DataValueTranslator.php b/src/Translation/DataValueTranslator.php index 59e43e9..91e68da 100644 --- a/src/Translation/DataValueTranslator.php +++ b/src/Translation/DataValueTranslator.php @@ -154,7 +154,7 @@ private function translateEDTF( String $value ): \SMWDITime { } else { $result = new \SMWDITime( SMWDITime::CM_GREGORIAN, - 0 + 1970 ); } From 10d40bd1ce4cbcffe4161a35b65d47c08c42364d Mon Sep 17 00:00:00 2001 From: baillyk <123638168+baillyk@users.noreply.github.com> Date: Thu, 7 Aug 2025 22:11:04 +0200 Subject: [PATCH 10/10] added support for dataType WikibaseLocalMedia --- src/Translation/DataValueTranslator.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Translation/DataValueTranslator.php b/src/Translation/DataValueTranslator.php index 91e68da..c82023c 100644 --- a/src/Translation/DataValueTranslator.php +++ b/src/Translation/DataValueTranslator.php @@ -43,7 +43,9 @@ public function translate( TypedDataValue $typedValue ): SMWDataItem { wfDebug( 'swb: translate: '. $typedValue->getValue()->getValue() ); if( $propertyType == 'edtf') { return $this->translateEDTF("".$value->getValue()); - } + }else if ($propertyType == 'localMedia') { + return $this->translateLocalMedia("".$value->getValue()); + } return $this->translateStringValue( $typedValue ); } if ( $value instanceof BooleanValue ) { @@ -86,6 +88,12 @@ private function translateGlobeCoordinateValue( GlobeCoordinateValue $globeValue ); } + private function translateLocalMedia( String $imagePage): SMWDataItem { + return new DIWikiPage( + $imagePage, + NS_FILE + ); + } private function translateEntityIdValue( EntityIdValue $idValue ): SMWDataItem { return new DIWikiPage( $idValue->getEntityId()->getSerialization(),