diff --git a/repo/rest-api/src/Domain/ReadModel/Statement.php b/repo/rest-api/src/Domain/ReadModel/Statement.php index c8fa0afec46..93cd0df3390 100644 --- a/repo/rest-api/src/Domain/ReadModel/Statement.php +++ b/repo/rest-api/src/Domain/ReadModel/Statement.php @@ -3,7 +3,6 @@ namespace Wikibase\Repo\RestApi\Domain\ReadModel; use Wikibase\DataModel\ReferenceList; -use Wikibase\DataModel\Snak\Snak; use Wikibase\DataModel\Snak\SnakList; use Wikibase\DataModel\Statement\StatementGuid; @@ -13,21 +12,24 @@ class Statement { private StatementGuid $guid; + private Property $property; + private Value $value; private Rank $rank; - private Snak $mainSnak; private SnakList $qualifiers; private ReferenceList $references; public function __construct( StatementGuid $guid, + Property $property, + Value $value, Rank $rank, - Snak $mainSnak, SnakList $qualifiers, ReferenceList $references ) { $this->guid = $guid; + $this->property = $property; + $this->value = $value; $this->rank = $rank; - $this->mainSnak = $mainSnak; $this->qualifiers = $qualifiers; $this->references = $references; } @@ -36,12 +38,16 @@ public function getGuid(): StatementGuid { return $this->guid; } - public function getRank(): Rank { - return $this->rank; + public function getProperty(): Property { + return $this->property; + } + + public function getValue(): Value { + return $this->value; } - public function getMainSnak(): Snak { - return $this->mainSnak; + public function getRank(): Rank { + return $this->rank; } public function getQualifiers(): SnakList { diff --git a/repo/rest-api/src/Domain/Services/StatementReadModelConverter.php b/repo/rest-api/src/Domain/Services/StatementReadModelConverter.php index 80ad3ed6441..38e2af0e233 100644 --- a/repo/rest-api/src/Domain/Services/StatementReadModelConverter.php +++ b/repo/rest-api/src/Domain/Services/StatementReadModelConverter.php @@ -2,10 +2,15 @@ namespace Wikibase\Repo\RestApi\Domain\Services; +use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup; +use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookupException; use Wikibase\DataModel\Services\Statement\StatementGuidParser; +use Wikibase\DataModel\Snak\PropertyValueSnak; use Wikibase\DataModel\Statement\Statement as DataModelStatement; +use Wikibase\Repo\RestApi\Domain\ReadModel\Property; use Wikibase\Repo\RestApi\Domain\ReadModel\Rank; use Wikibase\Repo\RestApi\Domain\ReadModel\Statement as ReadModelStatement; +use Wikibase\Repo\RestApi\Domain\ReadModel\Value; /** * @license GPL-2.0-or-later @@ -13,16 +18,27 @@ class StatementReadModelConverter { private StatementGuidParser $statementIdParser; + private PropertyDataTypeLookup $dataTypeLookup; - public function __construct( StatementGuidParser $statementIdParser ) { + public function __construct( StatementGuidParser $statementIdParser, PropertyDataTypeLookup $dataTypeLookup ) { $this->statementIdParser = $statementIdParser; + $this->dataTypeLookup = $dataTypeLookup; } public function convert( DataModelStatement $inputStatement ): ReadModelStatement { + $mainSnak = $inputStatement->getMainSnak(); + + try { + $dataType = $this->dataTypeLookup->getDataTypeIdForProperty( $inputStatement->getPropertyId() ); + } catch ( PropertyDataTypeLookupException $e ) { + $dataType = null; + } + return new ReadModelStatement( $this->statementIdParser->parse( $inputStatement->getGuid() ), + new Property( $inputStatement->getPropertyId(), $dataType ), + new Value( $mainSnak->getType(), $mainSnak instanceof PropertyValueSnak ? $mainSnak->getDataValue() : null ), new Rank( $inputStatement->getRank() ), - $inputStatement->getMainSnak(), $inputStatement->getQualifiers(), $inputStatement->getReferences() ); diff --git a/repo/rest-api/src/Serialization/StatementListSerializer.php b/repo/rest-api/src/Serialization/StatementListSerializer.php index c6054834b89..fc960c81443 100644 --- a/repo/rest-api/src/Serialization/StatementListSerializer.php +++ b/repo/rest-api/src/Serialization/StatementListSerializer.php @@ -20,7 +20,7 @@ public function serialize( StatementList $statementList ): ArrayObject { $serialization = new ArrayObject(); foreach ( $statementList as $statement ) { - $propertyId = $statement->getMainSnak()->getPropertyId()->getSerialization(); + $propertyId = $statement->getProperty()->getId()->getSerialization(); $serialization[$propertyId][] = $this->statementSerializer->serialize( $statement ); } diff --git a/repo/rest-api/src/Serialization/StatementSerializer.php b/repo/rest-api/src/Serialization/StatementSerializer.php index 55dee5b4c62..1ec921b7e5b 100644 --- a/repo/rest-api/src/Serialization/StatementSerializer.php +++ b/repo/rest-api/src/Serialization/StatementSerializer.php @@ -5,6 +5,7 @@ use Wikibase\DataModel\Reference; use Wikibase\DataModel\Snak\Snak; use Wikibase\DataModel\Statement\Statement as DataModelStatement; +use Wikibase\Repo\RestApi\Domain\ReadModel\PropertyValuePair; use Wikibase\Repo\RestApi\Domain\ReadModel\Statement; /** @@ -39,7 +40,7 @@ public function serialize( Statement $statement ): array { iterator_to_array( $statement->getReferences() ) ), ], - $this->propertyValuePairSerializer->serializeSnak( $statement->getMainSnak() ) + $this->propertyValuePairSerializer->serialize( new PropertyValuePair( $statement->getProperty(), $statement->getValue() ) ) ); } diff --git a/repo/rest-api/src/WbRestApi.ServiceWiring.php b/repo/rest-api/src/WbRestApi.ServiceWiring.php index 9bdb0794834..81ad055f9eb 100644 --- a/repo/rest-api/src/WbRestApi.ServiceWiring.php +++ b/repo/rest-api/src/WbRestApi.ServiceWiring.php @@ -217,7 +217,10 @@ 'WbRestApi.ItemDataRetriever' => function( MediaWikiServices $services ): ItemDataRetriever { return new WikibaseEntityLookupItemDataRetriever( WikibaseRepo::getEntityLookup( $services ), - new StatementReadModelConverter( WikibaseRepo::getStatementGuidParser( $services ) ), + new StatementReadModelConverter( + WikibaseRepo::getStatementGuidParser( $services ), + WikibaseRepo::getPropertyDataTypeLookup() + ), new SiteLinksReadModelConverter( $services->getSiteLookup() ) ); }, @@ -229,7 +232,10 @@ WikibaseRepo::getLogger( $services ), new EditSummaryFormatter( WikibaseRepo::getSummaryFormatter( $services ) ), $services->getPermissionManager(), - new StatementReadModelConverter( new StatementGuidParser( new ItemIdParser() ) ) + new StatementReadModelConverter( + WikibaseRepo::getStatementGuidParser( $services ), + WikibaseRepo::getPropertyDataTypeLookup() + ) ); }, diff --git a/repo/rest-api/tests/phpunit/DataAccess/MediaWikiEditEntityFactoryItemUpdaterIntegrationTest.php b/repo/rest-api/tests/phpunit/DataAccess/MediaWikiEditEntityFactoryItemUpdaterIntegrationTest.php index ec71bcc0cb3..98485782ffd 100644 --- a/repo/rest-api/tests/phpunit/DataAccess/MediaWikiEditEntityFactoryItemUpdaterIntegrationTest.php +++ b/repo/rest-api/tests/phpunit/DataAccess/MediaWikiEditEntityFactoryItemUpdaterIntegrationTest.php @@ -9,6 +9,7 @@ use Wikibase\DataModel\Entity\Item; use Wikibase\DataModel\Entity\ItemId; use Wikibase\DataModel\Entity\ItemIdParser; +use Wikibase\DataModel\Services\Lookup\InMemoryDataTypeLookup; use Wikibase\DataModel\Services\Statement\StatementGuidParser; use Wikibase\DataModel\Statement\StatementGuid; use Wikibase\DataModel\Tests\NewItem; @@ -77,7 +78,7 @@ public function testUpdate_replaceStatementOnItem(): void { $statementList = $newRevision->getItem()->getStatements(); $this->assertSame( $newValue, - $statementList->getStatementById( $statementGuid )->getMainSnak()->getDataValue()->getValue() + $statementList->getStatementById( $statementGuid )->getValue()->getContent()->getValue() ); } @@ -100,7 +101,7 @@ private function newItemUpdater(): MediaWikiEditEntityFactoryItemUpdater { new NullLogger(), $this->createStub( EditSummaryFormatter::class ), $permissionManager, - new StatementReadModelConverter( new StatementGuidParser( new ItemIdParser() ) ) + new StatementReadModelConverter( new StatementGuidParser( new ItemIdParser() ), new InMemoryDataTypeLookup() ) ); } diff --git a/repo/rest-api/tests/phpunit/DataAccess/MediaWikiEditEntityFactoryItemUpdaterTest.php b/repo/rest-api/tests/phpunit/DataAccess/MediaWikiEditEntityFactoryItemUpdaterTest.php index 3767d4509ff..45f50ef3306 100644 --- a/repo/rest-api/tests/phpunit/DataAccess/MediaWikiEditEntityFactoryItemUpdaterTest.php +++ b/repo/rest-api/tests/phpunit/DataAccess/MediaWikiEditEntityFactoryItemUpdaterTest.php @@ -13,6 +13,7 @@ use User; use Wikibase\DataModel\Entity\Item; use Wikibase\DataModel\Entity\ItemIdParser; +use Wikibase\DataModel\Services\Lookup\InMemoryDataTypeLookup; use Wikibase\DataModel\Services\Statement\StatementGuidParser; use Wikibase\DataModel\Tests\NewItem; use Wikibase\DataModel\Tests\NewStatement; @@ -229,7 +230,7 @@ private function newItemUpdater(): MediaWikiEditEntityFactoryItemUpdater { $this->logger, $this->summaryFormatter, $this->permissionManager, - new StatementReadModelConverter( new StatementGuidParser( new ItemIdParser() ) ) + new StatementReadModelConverter( new StatementGuidParser( new ItemIdParser() ), new InMemoryDataTypeLookup() ) ); } diff --git a/repo/rest-api/tests/phpunit/DataAccess/WikibaseEntityLookupItemDataRetrieverTest.php b/repo/rest-api/tests/phpunit/DataAccess/WikibaseEntityLookupItemDataRetrieverTest.php index 4202a420fb4..11e44f87507 100644 --- a/repo/rest-api/tests/phpunit/DataAccess/WikibaseEntityLookupItemDataRetrieverTest.php +++ b/repo/rest-api/tests/phpunit/DataAccess/WikibaseEntityLookupItemDataRetrieverTest.php @@ -11,6 +11,7 @@ use Wikibase\DataModel\Entity\ItemId; use Wikibase\DataModel\Entity\NumericPropertyId; use Wikibase\DataModel\Services\Lookup\EntityLookup; +use Wikibase\DataModel\Services\Lookup\InMemoryDataTypeLookup; use Wikibase\DataModel\Statement\StatementGuid; use Wikibase\DataModel\Tests\NewItem; use Wikibase\DataModel\Tests\NewStatement; @@ -271,7 +272,7 @@ private function newEntityLookupForIdWithReturnValue( ItemId $id, ?Item $returnV } private function newStatementReadModelConverter(): StatementReadModelConverter { - return new StatementReadModelConverter( WikibaseRepo::getStatementGuidParser() ); + return new StatementReadModelConverter( WikibaseRepo::getStatementGuidParser(), new InMemoryDataTypeLookup() ); } private function newSiteLinksReadModelConverter(): SiteLinksReadModelConverter { diff --git a/repo/rest-api/tests/phpunit/Domain/ReadModel/NewStatementReadModel.php b/repo/rest-api/tests/phpunit/Domain/ReadModel/NewStatementReadModel.php index 85726d4aa17..46b764dbc28 100644 --- a/repo/rest-api/tests/phpunit/Domain/ReadModel/NewStatementReadModel.php +++ b/repo/rest-api/tests/phpunit/Domain/ReadModel/NewStatementReadModel.php @@ -2,6 +2,7 @@ namespace Wikibase\Repo\Tests\RestApi\Domain\ReadModel; +use Wikibase\DataModel\Services\Lookup\InMemoryDataTypeLookup; use Wikibase\DataModel\Tests\NewStatement; use Wikibase\Repo\RestApi\Domain\ReadModel\Statement; use Wikibase\Repo\RestApi\Domain\Services\StatementReadModelConverter; @@ -13,7 +14,7 @@ class NewStatementReadModel extends NewStatement { public function build(): Statement { - return ( new StatementReadModelConverter( WikibaseRepo::getStatementGuidParser() ) ) + return ( new StatementReadModelConverter( WikibaseRepo::getStatementGuidParser(), new InMemoryDataTypeLookup() ) ) ->convert( parent::build() ); } diff --git a/repo/rest-api/tests/phpunit/Domain/ReadModel/StatementListTest.php b/repo/rest-api/tests/phpunit/Domain/ReadModel/StatementListTest.php index 5f02151c7ec..f41a9b70473 100644 --- a/repo/rest-api/tests/phpunit/Domain/ReadModel/StatementListTest.php +++ b/repo/rest-api/tests/phpunit/Domain/ReadModel/StatementListTest.php @@ -4,13 +4,15 @@ use PHPUnit\Framework\TestCase; use Wikibase\DataModel\Entity\ItemId; +use Wikibase\DataModel\Entity\NumericPropertyId; use Wikibase\DataModel\ReferenceList; -use Wikibase\DataModel\Snak\Snak; use Wikibase\DataModel\Snak\SnakList; use Wikibase\DataModel\Statement\StatementGuid; +use Wikibase\Repo\RestApi\Domain\ReadModel\Property; use Wikibase\Repo\RestApi\Domain\ReadModel\Rank; use Wikibase\Repo\RestApi\Domain\ReadModel\Statement; use Wikibase\Repo\RestApi\Domain\ReadModel\StatementList; +use Wikibase\Repo\RestApi\Domain\ReadModel\Value; /** * @covers \Wikibase\Repo\RestApi\Domain\ReadModel\StatementList @@ -44,8 +46,9 @@ public function testGivenStatementWithIdDoesNotExist_getStatementByIdReturnsNull private function newStatementWithId( StatementGuid $id ): Statement { return new Statement( $id, + new Property( new NumericPropertyId( 'P123' ), 'string' ), + new Value( Value::TYPE_SOME_VALUE ), Rank::normal(), - $this->createStub( Snak::class ), new SnakList(), new ReferenceList() ); diff --git a/repo/rest-api/tests/phpunit/Domain/Services/StatementReadModelConverterTest.php b/repo/rest-api/tests/phpunit/Domain/Services/StatementReadModelConverterTest.php index 969721477f0..224403999d7 100644 --- a/repo/rest-api/tests/phpunit/Domain/Services/StatementReadModelConverterTest.php +++ b/repo/rest-api/tests/phpunit/Domain/Services/StatementReadModelConverterTest.php @@ -4,6 +4,8 @@ use PHPUnit\Framework\TestCase; use Wikibase\DataModel\Entity\ItemId; +use Wikibase\DataModel\Entity\NumericPropertyId; +use Wikibase\DataModel\Services\Lookup\InMemoryDataTypeLookup; use Wikibase\DataModel\Statement\StatementGuid; use Wikibase\DataModel\Tests\NewStatement; use Wikibase\Repo\RestApi\Domain\Services\StatementReadModelConverter; @@ -18,20 +20,34 @@ */ class StatementReadModelConverterTest extends TestCase { + private const STRING_PROPERTY = 'P123'; + public function testConvert(): void { $id = new StatementGuid( new ItemId( 'Q123' ), 'AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE' ); - $dataModelStatement = NewStatement::someValueFor( 'P123' ) + $dataModelStatement = NewStatement::forProperty( 'P123' ) ->withGuid( (string)$id ) + ->withValue( 'potato' ) ->build(); - $readModel = ( new StatementReadModelConverter( WikibaseRepo::getStatementGuidParser() ) ) - ->convert( $dataModelStatement ); + $readModel = $this->newConverter()->convert( $dataModelStatement ); $this->assertEquals( $id, $readModel->getGuid() ); $this->assertSame( $dataModelStatement->getRank(), $readModel->getRank()->asInt() ); - $this->assertSame( $dataModelStatement->getMainSnak(), $readModel->getMainSnak() ); + $this->assertSame( $dataModelStatement->getPropertyId(), $readModel->getProperty()->getId() ); + $this->assertSame( 'string', $readModel->getProperty()->getDataType() ); + $this->assertSame( $dataModelStatement->getMainSnak()->getDataValue(), $readModel->getValue()->getContent() ); $this->assertSame( $dataModelStatement->getQualifiers(), $readModel->getQualifiers() ); $this->assertSame( $dataModelStatement->getReferences(), $readModel->getReferences() ); } + private function newConverter(): StatementReadModelConverter { + $dataTypeLookup = new InMemoryDataTypeLookup(); + $dataTypeLookup->setDataTypeForProperty( new NumericPropertyId( self::STRING_PROPERTY ), 'string' ); + + return new StatementReadModelConverter( + WikibaseRepo::getStatementGuidParser(), + $dataTypeLookup + ); + } + } diff --git a/repo/rest-api/tests/phpunit/Serialization/StatementListSerializerTest.php b/repo/rest-api/tests/phpunit/Serialization/StatementListSerializerTest.php index 8b54ad528f5..e45cdedd31d 100644 --- a/repo/rest-api/tests/phpunit/Serialization/StatementListSerializerTest.php +++ b/repo/rest-api/tests/phpunit/Serialization/StatementListSerializerTest.php @@ -61,7 +61,7 @@ private function newSerializer(): StatementListSerializer { $statementSerializer->method( 'serialize' ) ->willReturnCallback( fn( Statement $statement ) => [ - $statement->getMainSnak()->getPropertyId()->serialize() . ' statement serialization', + $statement->getProperty()->getId()->getSerialization() . ' statement serialization', ] ); return new StatementListSerializer( $statementSerializer ); diff --git a/repo/rest-api/tests/phpunit/Serialization/StatementSerializerTest.php b/repo/rest-api/tests/phpunit/Serialization/StatementSerializerTest.php index 16f7b0f79b3..5e6095a0ba3 100644 --- a/repo/rest-api/tests/phpunit/Serialization/StatementSerializerTest.php +++ b/repo/rest-api/tests/phpunit/Serialization/StatementSerializerTest.php @@ -9,6 +9,7 @@ use Wikibase\DataModel\Snak\PropertyNoValueSnak; use Wikibase\DataModel\Snak\Snak; use Wikibase\DataModel\Statement\Statement as DataModelStatement; +use Wikibase\Repo\RestApi\Domain\ReadModel\PropertyValuePair; use Wikibase\Repo\RestApi\Domain\ReadModel\Statement; use Wikibase\Repo\RestApi\Serialization\PropertyValuePairSerializer; use Wikibase\Repo\RestApi\Serialization\ReferenceSerializer; @@ -121,6 +122,13 @@ private function newSerializer(): StatementSerializer { 'value' => $snak->getPropertyId() . ' value', ] ); + $propertyValuePairSerializer->method( 'serialize' ) + ->willReturnCallback( + fn( PropertyValuePair $propertyValuePair ) => [ + 'property' => $propertyValuePair->getProperty()->getId() . ' property', + 'value' => $propertyValuePair->getProperty()->getId() . ' value', + ] + ); $referenceSerializer = $this->createStub( ReferenceSerializer::class ); $referenceSerializer->method( 'serialize' ) ->willReturnCallback( fn( Reference $ref ) => [ $ref->getHash() ] );