Eranroz has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/370956 )

Change subject: Adding a new mw.wikibase.getStatements
......................................................................

Adding a new mw.wikibase.getStatements

A new Lua interface to directly access entity statements,
with equivalent output to existing:
* mw.wikibase.getEntity( 'Q3'):getBestStatements('P2') - existing
* mw.wikibase.getStatements( 'Q3', 'P2') - new one

the php code filters the claims hence allowing less serialization
(other claims aren't serialized), and may later on provide better
tracking on the actually used claims.

Bug: T172905
Change-Id: I38a160d4acd6b2e1ab61d3e25b229e2cd0bd7f96
---
M client/includes/DataAccess/Scribunto/EntityAccessor.php
M client/includes/DataAccess/Scribunto/Scribunto_LuaWikibaseLibrary.php
M client/includes/DataAccess/Scribunto/mw.wikibase.lua
M client/includes/Serializer/ClientEntitySerializer.php
M client/includes/WikibaseClient.php
M client/tests/phpunit/includes/DataAccess/Scribunto/EntityAccessorTest.php
6 files changed, 257 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase 
refs/changes/56/370956/1

diff --git a/client/includes/DataAccess/Scribunto/EntityAccessor.php 
b/client/includes/DataAccess/Scribunto/EntityAccessor.php
index b192598..01d3a31 100644
--- a/client/includes/DataAccess/Scribunto/EntityAccessor.php
+++ b/client/includes/DataAccess/Scribunto/EntityAccessor.php
@@ -9,6 +9,8 @@
 use Wikibase\DataModel\Entity\EntityIdParser;
 use Wikibase\DataModel\Services\Lookup\EntityLookup;
 use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup;
+use Wikibase\DataModel\Statement\StatementListProvider;
+use Wikibase\DataModel\Entity\PropertyId;
 use Wikibase\LanguageFallbackChain;
 use Wikibase\Lib\ContentLanguages;
 use Wikibase\Lib\Store\RevisionedUnresolvedRedirectException;
@@ -65,6 +67,7 @@
                EntityLookup $entityLookup,
                UsageAccumulator $usageAccumulator,
                Serializer $entitySerializer,
+               Serializer $statementSerializer,
                PropertyDataTypeLookup $dataTypeLookup,
                LanguageFallbackChain $fallbackChain,
                Language $language,
@@ -74,6 +77,7 @@
                $this->entityLookup = $entityLookup;
                $this->usageAccumulator = $usageAccumulator;
                $this->entitySerializer = $entitySerializer;
+               $this->statementSerializer = $statementSerializer;
                $this->dataTypeLookup = $dataTypeLookup;
                $this->fallbackChain = $fallbackChain;
                $this->language = $language;
@@ -136,6 +140,46 @@
                return $entityArr;
        }
 
+       /**
+        * Get statement list from prefixed ID (e.g. "Q23") and property (e.g 
"P123") and return it as serialized array.
+        *
+        * @param string $prefixedEntityId
+        * @param string $propertyId
+        *
+        * @return array|null
+        */
+       public function getEntityStatement( $prefixedEntityId, $propertyId ) {
+               $prefixedEntityId = trim( $prefixedEntityId );
+               $entityId = $this->entityIdParser->parse( $prefixedEntityId );
+
+               # FIXME: usage only for the specific property not the whole 
entity
+               $this->usageAccumulator->addAllUsage( $entityId );
+
+               try {
+                       $entityObject = $this->entityLookup->getEntity( 
$entityId );
+               } catch ( RevisionedUnresolvedRedirectException $ex ) {
+                       // We probably hit a double redirect
+                       wfLogWarning(
+                               'Encountered a UnresolvedRedirectException when 
trying to load ' . $prefixedEntityId
+                       );
+
+                       return null;
+               }
+
+               if ( $entityObject === null ) {
+                       return null;
+               }
+
+               $statements = $entityObject->getStatements();
+               $propertyIdObj = new PropertyId( $propertyId );
+               $statementsProp = $statements->getByPropertyId( $propertyIdObj 
);
+               $statementsRanked = $statementsProp->getBestStatements();
+               $statementArr = 
$this->newClientStatemnetListSerializer()->serializeStatementList( 
$statementsRanked );
+               $this->renumber( $statementArr );
+
+               return $statementArr;
+       }
+
        private function newClientEntitySerializer() {
                return new ClientEntitySerializer(
                        $this->entitySerializer,
@@ -149,4 +193,16 @@
                );
        }
 
+       private function newClientStatemnetListSerializer() {
+               return new ClientEntitySerializer(
+                       $this->statementSerializer,
+                       $this->dataTypeLookup,
+                       array_unique( array_merge(
+                               $this->termsLanguages->getLanguages(),
+                               $this->fallbackChain->getFetchLanguageCodes(),
+                               [ $this->language->getCode() ]
+                       ) ),
+                       [ ]
+               );
+       }
 }
diff --git 
a/client/includes/DataAccess/Scribunto/Scribunto_LuaWikibaseLibrary.php 
b/client/includes/DataAccess/Scribunto/Scribunto_LuaWikibaseLibrary.php
index f74fbaa..71f6735 100644
--- a/client/includes/DataAccess/Scribunto/Scribunto_LuaWikibaseLibrary.php
+++ b/client/includes/DataAccess/Scribunto/Scribunto_LuaWikibaseLibrary.php
@@ -210,6 +210,10 @@
                                
SerializerFactory::OPTION_SERIALIZE_MAIN_SNAKS_WITHOUT_HASH +
                                
SerializerFactory::OPTION_SERIALIZE_REFERENCE_SNAKS_WITHOUT_HASH
                        ),
+                       $wikibaseClient->getSerializerFactory(
+                               
SerializerFactory::OPTION_SERIALIZE_MAIN_SNAKS_WITHOUT_HASH +
+                               
SerializerFactory::OPTION_SERIALIZE_REFERENCE_SNAKS_WITHOUT_HASH
+                       )->newStatementListSerializer(),
                        $wikibaseClient->getPropertyDataTypeLookup(),
                        $this->getLanguageFallbackChain(),
                        $this->getLanguage(),
@@ -299,6 +303,7 @@
                $lib = [
                        'getLabel' => [ $this, 'getLabel' ],
                        'getEntity' => [ $this, 'getEntity' ],
+                       'getEntityStatement' => [$this, 'getEntityStatement'],
                        'getSetting' => [ $this, 'getSetting' ],
                        'getEntityUrl' => [ $this, 'getEntityUrl' ],
                        'renderSnak' => [ $this, 'renderSnak' ],
@@ -347,6 +352,22 @@
        }
 
        /**
+        * Wrapper for getEntityStatement in EntityAccessor
+        *
+        * @param string $prefixedEntityId
+        * @param string $propertyId
+        *
+        * @throws ScribuntoException
+        * @return array
+        */
+       public function getEntityStatement( $prefixedEntityId, $propertyId ) {
+               $this->checkType( 'getEntityStatement', 1, $prefixedEntityId, 
'string' );
+               $this->checkType( 'getEntityStatement', 2, $propertyId, 
'string' );
+               $statements = $this->getEntityAccessor()->getEntityStatement( 
$prefixedEntityId, $propertyId );
+               return [ $statements ];
+       }
+
+       /**
         * Wrapper for getEntityId in WikibaseLuaBindings
         *
         * @param string|null $pageTitle
diff --git a/client/includes/DataAccess/Scribunto/mw.wikibase.lua 
b/client/includes/DataAccess/Scribunto/mw.wikibase.lua
index 8fb16ee..3bd7212 100644
--- a/client/includes/DataAccess/Scribunto/mw.wikibase.lua
+++ b/client/includes/DataAccess/Scribunto/mw.wikibase.lua
@@ -135,6 +135,33 @@
        -- getEntityObject is an alias for getEntity as these used to be 
different.
        wikibase.getEntityObject = wikibase.getEntity
 
+       -- Get the statement list array for the specified id.
+       --
+       -- @param {string} [id]
+       -- @param {string} [propertyId]
+       wikibase.getStatements = function( id, propertyId )
+               if not php.getSetting( 'allowArbitraryDataAccess' ) and id ~= 
wikibase.getEntityIdForCurrentPage() then
+                       error( 'Access to arbitrary items has been disabled.', 
2 )
+               end
+
+               if id == nil then
+                       error( 'entity id must be provided.', 2 )
+               end
+
+               if propertyId == nil then
+                       error( 'propertyId must be provided.', 2 )
+               end
+
+               statements = php.getEntityStatement( id, propertyId )
+               if statements == nil or statements[propertyId] == nil then
+                       statements = {}
+               elseif statements ~= nil then
+                       statements = statements[propertyId]
+               end
+
+               return statements
+       end
+
        -- Get the URL for the given entity id, if specified, or of the
        -- connected entity, if exists.
        --
diff --git a/client/includes/Serializer/ClientEntitySerializer.php 
b/client/includes/Serializer/ClientEntitySerializer.php
index e539e1c..563c442 100644
--- a/client/includes/Serializer/ClientEntitySerializer.php
+++ b/client/includes/Serializer/ClientEntitySerializer.php
@@ -88,6 +88,23 @@
                return $this->omitEmptyArrays( $serialization );
        }
 
+       /**
+        * Adds data types to serialization
+        *
+        * @param StatementList $statementList
+        *
+        * @throws SerializationException
+        * @return array
+        */
+       public function serializeStatementList( $statementList ) {
+               $serialization = $this->entitySerializer->serialize( 
$statementList );
+
+               $serialization = 
$this->injectStatementListSerializationWithDataTypes( $serialization );
+               $serialization = 
$this->filterEntitySerializationUsingLangCodes( $serialization );
+
+               return $this->omitEmptyArrays( $serialization );
+       }
+
        private function omitEmptyArrays( array $serialization ) {
                return array_filter(
                        $serialization,
@@ -139,6 +156,30 @@
        }
 
        /**
+        * @param array $serialization
+        *
+        * @TODO FIXME very similar functions with the above and the Repo 
ResultBuilder
+        *
+        * @return array
+        */
+       private function injectStatementListSerializationWithDataTypes( array 
$serialization ) {
+               $serialization = $this->modifier->modifyUsingCallback(
+                       $serialization,
+                       '*/*/mainsnak',
+                       $this->callbackFactory->getCallbackToAddDataTypeToSnak( 
$this->dataTypeLookup )
+               );
+               $serialization = 
$this->getArrayWithDataTypesInGroupedSnakListAtPath(
+                       $serialization,
+                       '*/*/qualifiers'
+               );
+               $serialization = 
$this->getArrayWithDataTypesInGroupedSnakListAtPath(
+                       $serialization,
+                       '*/*/references/*/snaks'
+               );
+               return $serialization;
+       }
+
+       /**
         * @param array $array
         * @param string $path
         *
diff --git a/client/includes/WikibaseClient.php 
b/client/includes/WikibaseClient.php
index 164f09f..1a48a00 100644
--- a/client/includes/WikibaseClient.php
+++ b/client/includes/WikibaseClient.php
@@ -1019,6 +1019,16 @@
        /**
         * @param int $options bitwise combination of the 
SerializerFactory::OPTION_ flags
         *
+        * @return SerializerFactory
+        */
+       public function getSerializerFactory( $options = 
SerializerFactory::OPTION_DEFAULT ) {
+               $baseSerializerFactory = new SerializerFactory( new 
DataValueSerializer(), $options );
+               return $baseSerializerFactory;
+       }
+
+       /**
+        * @param int $options bitwise combination of the 
SerializerFactory::OPTION_ flags
+        *
         * @return Serializer
         */
        public function getAllTypesEntitySerializer( $options = 
SerializerFactory::OPTION_DEFAULT ) {
diff --git 
a/client/tests/phpunit/includes/DataAccess/Scribunto/EntityAccessorTest.php 
b/client/tests/phpunit/includes/DataAccess/Scribunto/EntityAccessorTest.php
index a0d3a6d..5b9c656 100644
--- a/client/tests/phpunit/includes/DataAccess/Scribunto/EntityAccessorTest.php
+++ b/client/tests/phpunit/includes/DataAccess/Scribunto/EntityAccessorTest.php
@@ -49,13 +49,13 @@
                $langCode = 'en'
        ) {
                $language = new Language( $langCode );
-
                $serializerFactory = new SerializerFactory(
                        new DataValueSerializer(),
                        
SerializerFactory::OPTION_SERIALIZE_MAIN_SNAKS_WITHOUT_HASH +
                        
SerializerFactory::OPTION_SERIALIZE_REFERENCE_SNAKS_WITHOUT_HASH
                );
                $entitySerializer = $serializerFactory->newItemSerializer();
+               $statementSerializer = 
$serializerFactory->newStatementListSerializer();
 
                $propertyDataTypeLookup = $this->getMock( 
PropertyDataTypeLookup::class );
                $propertyDataTypeLookup->expects( $this->any() )
@@ -72,6 +72,7 @@
                        $entityLookup ?: new MockRepository(),
                        $usageAccumulator ?: new HashUsageAccumulator(),
                        $entitySerializer,
+                       $statementSerializer,
                        $propertyDataTypeLookup,
                        $fallbackChain,
                        $language,
@@ -323,4 +324,104 @@
                $this->assertEquals( $expected, $entityAccessor->getEntity( 
'Q123098' ) );
        }
 
+
+       /**
+        * @dataProvider getEntityProvider
+        */
+       public function testGetEntityStatement( ) {
+               $qid = 'Q123099';
+               $pid = 65;
+               $item = new Item( new ItemId( $qid ) );
+               $snak = new PropertyValueSnak( $pid, new StringValue( 
'snakStringValue' ) );
+
+               $qualifiers = new SnakList();
+               $qualifiers->addSnak( new PropertyValueSnak( $pid, new 
StringValue( 'string!' ) ) );
+               $qualifiers->addSnak( new PropertySomeValueSnak( $pid ) );
+
+               $references = new ReferenceList();
+               $references->addNewReference( [
+                       new PropertySomeValueSnak( 65 ),
+                       new PropertySomeValueSnak( 68 )
+               ] );
+
+               $guid = 'imaguid';
+               $item->getStatements()->addNewStatement( $snak, $qualifiers, 
$references, $guid );
+
+               $entityLookup = new MockRepository();
+               $entityLookup->putEntity( $item );
+
+               $entityAccessor = $this->getEntityAccessor( $entityLookup );
+               $entityArr = $entityAccessor->getEntityStatement( "Q123099", 
"P65" );
+               $actual = is_array( $entityArr ) ? $entityArr : [];
+
+               $expected = [
+                       'P65' => [
+                               1 => [
+                                       'id' => 'imaguid',
+                                       'type' => 'statement',
+                                       'mainsnak' => [
+                                               'snaktype' => 'value',
+                                               'property' => 'P65',
+                                               'datatype' => 'structured-cat',
+                                               'datavalue' => [
+                                                       'value' => 
'snakStringValue',
+                                                       'type' => 'string',
+                                               ],
+                                       ],
+                                       'qualifiers' => [
+                                               'P65' => [
+                                                       1 => [
+                                                               'hash' => 
'3ea0f5404dd4e631780b3386d17a15a583e499a6',
+                                                               'snaktype' => 
'value',
+                                                               'property' => 
'P65',
+                                                               'datavalue' => [
+                                                                       'value' 
=> 'string!',
+                                                                       'type' 
=> 'string',
+                                                               ],
+                                                               'datatype' => 
'structured-cat',
+                                                       ],
+                                                       2 => [
+                                                               'hash' => 
'aa9a5f05e20d7fa5cda7d98371e44c0bdd5de35e',
+                                                               'snaktype' => 
'somevalue',
+                                                               'property' => 
'P65',
+                                                               'datatype' => 
'structured-cat',
+                                                       ],
+                                               ],
+                                       ],
+                                       'rank' => 'normal',
+                                       'qualifiers-order' => [
+                                               1 => 'P65'
+                                       ],
+                                       'references' => [
+                                               1 => [
+                                                       'hash' => 
'8445204eb74e636cb53687e2f947c268d5186075',
+                                                       'snaks' => [
+                                                               'P65' => [
+                                                                       1 => [
+                                                                               
'snaktype' => 'somevalue',
+                                                                               
'property' => 'P65',
+                                                                               
'datatype' => 'structured-cat',
+                                                                       ]
+                                                               ],
+                                                               'P68' => [
+                                                                       1 => [
+                                                                               
'snaktype' => 'somevalue',
+                                                                               
'property' => 'P68',
+                                                                               
'datatype' => 'structured-cat',
+                                                                       ]
+                                                               ],
+                                                       ],
+                                                       'snaks-order' => [
+                                                               1 => 'P65',
+                                                               2 => 'P68'
+                                                       ],
+                                               ],
+                                       ],
+                               ],
+                       ]
+               ];
+               $this->assertSameSize( $expected, $actual );
+               $this->assertEquals( $expected, $actual );
+       }
+
 }

-- 
To view, visit https://gerrit.wikimedia.org/r/370956
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I38a160d4acd6b2e1ab61d3e25b229e2cd0bd7f96
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Eranroz <eranro...@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to