Daniel Kinzler has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/216745

Change subject: Track quantity units as referenced entities.
......................................................................

Track quantity units as referenced entities.

NOTE: requires a new release of data-value/number,
see https://github.com/DataValues/Number/pull/31

Change-Id: Id86dba7dfa2a46c9c7b4a94457b4f8a04f58984e
---
M client/includes/WikibaseClient.php
M lib/includes/ReferencedEntitiesFinder.php
A lib/includes/parsers/ExtractingEntityIdParser.php
M lib/tests/phpunit/ReferencedEntitiesFinderTest.php
A lib/tests/phpunit/parsers/ExtractingEntityIdParserTest.php
M repo/includes/EntityParserOutputGenerator.php
M repo/includes/EntityParserOutputGeneratorFactory.php
M repo/includes/WikibaseRepo.php
M repo/tests/phpunit/includes/EntityParserOutputGeneratorTest.php
9 files changed, 236 insertions(+), 10 deletions(-)


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

diff --git a/client/includes/WikibaseClient.php 
b/client/includes/WikibaseClient.php
index d9609d1..7ddbf8e 100644
--- a/client/includes/WikibaseClient.php
+++ b/client/includes/WikibaseClient.php
@@ -46,6 +46,7 @@
 use Wikibase\Lib\LanguageNameLookup;
 use Wikibase\Lib\OutputFormatSnakFormatterFactory;
 use Wikibase\Lib\OutputFormatValueFormatterFactory;
+use Wikibase\Lib\Parsers\ExtractingEntityIdParser;
 use Wikibase\Lib\PropertyInfoDataTypeLookup;
 use Wikibase\Lib\Serializers\ForbiddenSerializer;
 use Wikibase\Lib\Store\EntityContentDataCodec;
@@ -519,7 +520,18 @@
                return new WikibaseValueFormatterBuilders(
                        $this->contentLanguage,
                        new FormatterLabelDescriptionLookupFactory( 
$this->getTermLookup() ),
-                       new LanguageNameLookup()
+                       new LanguageNameLookup(),
+                       $this->getRepoEntityUriParser()
+               );
+       }
+
+       /**
+        * @return ExtractingEntityIdParser
+        */
+       private function getRepoEntityUriParser() {
+               return ExtractingEntityIdParser::newFrombaseUri(
+                       $this->getSettings()->getSetting( 'conceptBaseUri' ),
+                       $this->getEntityIdParser()
                );
        }
 
diff --git a/lib/includes/ReferencedEntitiesFinder.php 
b/lib/includes/ReferencedEntitiesFinder.php
index b748abd..8a9f89c 100644
--- a/lib/includes/ReferencedEntitiesFinder.php
+++ b/lib/includes/ReferencedEntitiesFinder.php
@@ -2,7 +2,11 @@
 
 namespace Wikibase;
 
+use DataValues\DataValue;
+use DataValues\QuantityValue;
 use Wikibase\DataModel\Entity\EntityId;
+use Wikibase\DataModel\Entity\EntityIdParser;
+use Wikibase\DataModel\Entity\EntityIdParsingException;
 use Wikibase\DataModel\Entity\EntityIdValue;
 use Wikibase\DataModel\Snak\PropertyValueSnak;
 use Wikibase\DataModel\Snak\Snak;
@@ -22,6 +26,18 @@
 class ReferencedEntitiesFinder {
 
        /**
+        * @var EntityIdParser
+        */
+       private $entityUriParser;
+
+       /**
+        * @param EntityIdParser $entityUriParser
+        */
+       public function __construct( EntityIdParser $entityUriParser ) {
+               $this->entityUriParser = $entityUriParser;
+       }
+
+       /**
         * Finds linked entities within a set of snaks.
         *
         * @since 0.4
@@ -39,15 +55,42 @@
 
                        if ( $snak instanceof PropertyValueSnak ) {
                                $dataValue = $snak->getDataValue();
-
-                               if ( $dataValue instanceof EntityIdValue ) {
-                                       $entityId = $dataValue->getEntityId();
-                                       
$entityIds[$entityId->getSerialization()] = $entityId;
-                               }
+                               $this->addEntityIdsFromValue( $dataValue, 
$entityIds );
                        }
                }
 
                return $entityIds;
        }
 
+       /**
+        * @param DataValue $dataValue
+        * @param EntityId[] $entityIds
+        */
+       private function addEntityIdsFromValue( DataValue $dataValue, array 
&$entityIds ) {
+               if ( $dataValue instanceof EntityIdValue ) {
+                       $entityId = $dataValue->getEntityId();
+                       $entityIds[$entityId->getSerialization()] = $entityId;
+               } elseif ( $dataValue instanceof QuantityValue ) {
+                       $unitUri = $dataValue->getUnit();
+                       $this->addEntityIdsFromURI( $unitUri, $entityIds );
+               }
+
+               //TODO: EntityIds from GlobeCoordinateValue's globe URI 
(Wikidata, not local item URI!)
+               //TODO: EntityIds from TimeValue's calendar URI (Wikidata, not 
local item URI!)
+       }
+
+       /**
+        * @param string $uri
+        * @param EntityId[] $entityIds
+        */
+       private function addEntityIdsFromURI( $uri, array &$entityIds ) {
+               try {
+                       $entityId = $this->entityUriParser->parse( $uri );
+                       $entityIds[$entityId->getSerialization()] = $entityId;
+               } catch ( EntityIdParsingException $ex ) {
+                       // noop
+               }
+       }
+
+
 }
diff --git a/lib/includes/parsers/ExtractingEntityIdParser.php 
b/lib/includes/parsers/ExtractingEntityIdParser.php
new file mode 100644
index 0000000..80f09c8
--- /dev/null
+++ b/lib/includes/parsers/ExtractingEntityIdParser.php
@@ -0,0 +1,65 @@
+<?php
+
+namespace Wikibase\Lib\Parsers;
+
+use Wikibase\DataModel\Entity\EntityId;
+use Wikibase\DataModel\Entity\EntityIdParser;
+use Wikibase\DataModel\Entity\EntityIdParsingException;
+
+/**
+ * EntityIdParser that parses full entity URIs into EntityIds.
+ *
+ * @since 0.5
+ *
+ * @license GPL 2+
+ * @author Daniel Kinzler
+ */
+class ExtractingEntityIdParser implements EntityIdParser {
+
+       public static function newFromBaseUri( $baseUri, EntityIdParser 
$idParser ) {
+               $escapedUri = preg_quote( $baseUri, '!' );
+               $uriRegexp =  '!^' . $escapedUri . '(.+)$!';
+
+               return new ExtractingEntityIdParser( $uriRegexp, $idParser );
+       }
+
+       /**
+        * @var string
+        */
+       private $uriRegexp;
+
+       /**
+        * @var EntityIdParser
+        */
+       private $idParser;
+
+       /**
+        * @param string $uriRegexp Regular expression matching the entity ID 
as the first capture group.
+        * @param EntityIdParser $idParser
+        */
+       public function __construct( $uriRegexp,  EntityIdParser $idParser ) {
+               $this->idParser = $idParser;
+               $this->uriRegexp = $uriRegexp;
+       }
+
+       /**
+        * @since 0.5
+        *
+        * @param string $entityUri
+        *
+        * @return EntityId
+        * @throws EntityIdParsingException
+        */
+       public function parse( $entityUri ) {
+               if ( preg_match ( $this->uriRegexp, $entityUri, $m ) ) {
+                       if ( !isset( $m[1] ) ) {
+                               throw new EntityIdParsingException( 'Bad entity 
URI (incomplete match): ' . $entityUri );
+                       }
+
+                       return $this->idParser->parse( $m[1] );
+               }
+
+               throw new EntityIdParsingException( 'Bad entity URI: ' . 
$entityUri );
+       }
+
+}
diff --git a/lib/tests/phpunit/ReferencedEntitiesFinderTest.php 
b/lib/tests/phpunit/ReferencedEntitiesFinderTest.php
index 7313185..844df26 100644
--- a/lib/tests/phpunit/ReferencedEntitiesFinderTest.php
+++ b/lib/tests/phpunit/ReferencedEntitiesFinderTest.php
@@ -2,7 +2,9 @@
 
 namespace Wikibase\Lib\Test;
 
+use DataValues\QuantityValue;
 use DataValues\StringValue;
+use Wikibase\DataModel\Entity\BasicEntityIdParser;
 use Wikibase\DataModel\Entity\EntityId;
 use Wikibase\DataModel\Entity\EntityIdValue;
 use Wikibase\DataModel\Entity\ItemId;
@@ -11,6 +13,7 @@
 use Wikibase\DataModel\Snak\PropertySomeValueSnak;
 use Wikibase\DataModel\Snak\PropertyValueSnak;
 use Wikibase\DataModel\Snak\Snak;
+use Wikibase\Lib\Parsers\ExtractingEntityIdParser;
 use Wikibase\ReferencedEntitiesFinder;
 
 /**
@@ -32,9 +35,11 @@
                $p11 = new PropertyId( 'p11' );
                $p27 = new PropertyId( 'p27' );
                $p44 = new PropertyId( 'p44' );
+               $q800 = new ItemId( 'Q800' );
 
                $q23Value = new EntityIdValue( new ItemId( 'q23' ) );
                $q24Value = new EntityIdValue( new ItemId( 'q24' ) );
+               $quantityValueUnitQ800 = QuantityValue::newFromNumber( 3, 
'http://acme.test/entity/Q800' );
 
                $argLists[] = array(
                        array(),
@@ -63,7 +68,13 @@
                $argLists[] = array(
                        array( new PropertyValueSnak( $p27, $q23Value ) ),
                        array( $p27, $q23Value->getEntityId() ),
-                       "PropertyValueSnak with EntityId"
+                       "PropertyValueSnak with EntityIdValue"
+               );
+
+               $argLists[] = array(
+                       array( new PropertyValueSnak( $p27, 
$quantityValueUnitQ800 ) ),
+                       array( $p27, $q800 ),
+                       "PropertyValueSnak with unit URI in a QuantityValue"
                );
 
                $argLists[] = array(
@@ -89,7 +100,11 @@
         * @param string $message
         */
        public function testFindSnakLinks( array $snaks, array $expected, 
$message ) {
-               $linkFinder = new ReferencedEntitiesFinder();
+               $linkFinder = new ReferencedEntitiesFinder(
+                       ExtractingEntityIdParser::newFromBaseUri(
+                               'http://acme.test/entity/',
+                               new BasicEntityIdParser()
+                       ) );
 
                $actual = $linkFinder->findSnakLinks( $snaks );
 
diff --git a/lib/tests/phpunit/parsers/ExtractingEntityIdParserTest.php 
b/lib/tests/phpunit/parsers/ExtractingEntityIdParserTest.php
new file mode 100644
index 0000000..1408af4
--- /dev/null
+++ b/lib/tests/phpunit/parsers/ExtractingEntityIdParserTest.php
@@ -0,0 +1,66 @@
+<?php
+
+namespace Wikibase\Lib\Test;
+
+use Wikibase\DataModel\Entity\BasicEntityIdParser;
+use Wikibase\DataModel\Entity\ItemId;
+use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\Lib\Parsers\ExtractingEntityIdParser;
+
+/**
+ * @covers Wikibase\Lib\Parsers\ExtractingEntityIdParser
+ *
+ * @group ValueParsers
+ * @group WikibaseLib
+ * @group Wikibase
+ *
+ * @licence GNU GPL v2+
+ * @author Daniel Kinzler
+ */
+class ExtractingEntityIdParserTest extends \PHPUnit_Framework_TestCase {
+
+       public function provideParse() {
+               return array(
+                       array( '!^https?://acme.test/entity/(.*)$!', 
'http://acme.test/entity/Q14', new ItemId( 'Q14' ) ),
+                       array( '!^(?:https?)://acme.test/entity/(.*?)(#.*)?$!', 
'http://acme.test/entity/P14', new PropertyId( 'P14' ) ),
+               );
+       }
+
+       /**
+        * @dataProvider provideParse
+        */
+       public function testParse( $regexp, $input, $expected ) {
+               $parser = new ExtractingEntityIdParser( $regexp, new 
BasicEntityIdParser() );
+               $this->assertEquals( new ItemId( 'Q14' ), $parser->parse( 
'http://acme.test/entity/Q14' ) );
+       }
+
+       public function provideParse_invalid() {
+               return array(
+                       array( '!^https?://acme.test/entity/(.*)$!', 
'http://acme.test/Q14' ),
+                       array( '!^https?://acme.test/entity/(.*)$!', 
'http://acme.test/entity/XYYZ' ),
+                       array( '!^https?://acme.test/entity/(.*)$!', 
'http://acme.test/Q14#x' ),
+                       array( '!^https?://acme.test/entity/.*$!', 
'http://acme.test/entity/Q14' ),
+               );
+       }
+
+       /**
+        * @dataProvider provideParse_invalid
+        */
+       public function testParse_invalid( $regexp, $input ) {
+               $parser = new ExtractingEntityIdParser( $regexp, new 
BasicEntityIdParser() );
+
+               $this->setExpectedException( 
'Wikibase\DataModel\Entity\EntityIdParsingException' );
+               $parser->parse( $input );
+       }
+
+       public function testNewFromBaseUri() {
+               $parser = ExtractingEntityIdParser::newFromBaseUri( 
'http://acme.test/entity/', new BasicEntityIdParser() );
+
+               $this->assertEquals( new ItemId( 'Q14' ), $parser->parse( 
'http://acme.test/entity/Q14' ) );
+               $this->assertEquals( new ItemId( 'Q14' ), $parser->parse( 
'http://acme.test/entity/Q14' ), 'HTTPS' );
+
+               $this->setExpectedException( 
'Wikibase\DataModel\Entity\EntityIdParsingException' );
+               $parser->parse( 'http://acme.test/Q14' );
+       }
+
+}
diff --git a/repo/includes/EntityParserOutputGenerator.php 
b/repo/includes/EntityParserOutputGenerator.php
index 5b5c378..23b0371 100644
--- a/repo/includes/EntityParserOutputGenerator.php
+++ b/repo/includes/EntityParserOutputGenerator.php
@@ -93,6 +93,7 @@
                EntityInfoBuilderFactory $entityInfoBuilderFactory,
                LanguageFallbackChain $languageFallbackChain,
                $languageCode,
+               ReferencedEntitiesFinder $referencedEntitiesFinder,
                TemplateFactory $templateFactory
        ) {
                $this->entityViewFactory = $entityViewFactory;
@@ -102,8 +103,7 @@
                $this->entityInfoBuilderFactory = $entityInfoBuilderFactory;
                $this->languageFallbackChain = $languageFallbackChain;
                $this->languageCode = $languageCode;
-
-               $this->referencedEntitiesFinder = new 
ReferencedEntitiesFinder();
+               $this->referencedEntitiesFinder = $referencedEntitiesFinder;
                $this->templateFactory = $templateFactory;
        }
 
diff --git a/repo/includes/EntityParserOutputGeneratorFactory.php 
b/repo/includes/EntityParserOutputGeneratorFactory.php
index adc1ab2..fe3b5e9 100644
--- a/repo/includes/EntityParserOutputGeneratorFactory.php
+++ b/repo/includes/EntityParserOutputGeneratorFactory.php
@@ -44,6 +44,11 @@
        private $valuesFinder;
 
        /**
+        * @var ReferencedEntitiesFinder
+        */
+       private $referencedEntitiesFinder;
+
+       /**
         * @var LanguageFallbackChainFactory
         */
        private $languageFallbackChainFactory;
@@ -54,6 +59,7 @@
                EntityTitleLookup $entityTitleLookup,
                ValuesFinder $valuesFinder,
                LanguageFallbackChainFactory $languageFallbackChainFactory,
+               ReferencedEntitiesFinder $referencedEntitiesFinder,
                TemplateFactory $templateFactory
        ) {
                $this->entityViewFactory = $entityViewFactory;
@@ -61,6 +67,7 @@
                $this->entityTitleLookup = $entityTitleLookup;
                $this->valuesFinder = $valuesFinder;
                $this->languageFallbackChainFactory = 
$languageFallbackChainFactory;
+               $this->referencedEntitiesFinder = $referencedEntitiesFinder;
                $this->templateFactory = $templateFactory;
        }
 
@@ -82,6 +89,7 @@
                        $this->entityInfoBuilderFactory,
                        $this->getLanguageFallbackChain( $languageCode ),
                        $languageCode,
+                       $this->referencedEntitiesFinder,
                        $this->templateFactory
                );
        }
diff --git a/repo/includes/WikibaseRepo.php b/repo/includes/WikibaseRepo.php
index f71e551..47e955f 100644
--- a/repo/includes/WikibaseRepo.php
+++ b/repo/includes/WikibaseRepo.php
@@ -50,6 +50,7 @@
 use Wikibase\Lib\Localizer\ParseExceptionLocalizer;
 use Wikibase\Lib\OutputFormatSnakFormatterFactory;
 use Wikibase\Lib\OutputFormatValueFormatterFactory;
+use Wikibase\Lib\Parsers\ExtractingEntityIdParser;
 use Wikibase\Lib\PropertyInfoDataTypeLookup;
 use Wikibase\Lib\SnakConstructionService;
 use Wikibase\Lib\SnakFormatter;
@@ -64,6 +65,7 @@
 use Wikibase\Lib\WikibaseDataTypeBuilders;
 use Wikibase\Lib\WikibaseSnakFormatterBuilders;
 use Wikibase\Lib\WikibaseValueFormatterBuilders;
+use Wikibase\ReferencedEntitiesFinder;
 use Wikibase\Repo\Content\EntityContentFactory;
 use Wikibase\Repo\Content\ItemHandler;
 use Wikibase\Repo\Content\PropertyHandler;
@@ -574,6 +576,16 @@
        }
 
        /**
+        * @return EntityIdParser
+        */
+       private function getLocalEntityUriParser() {
+               return ExtractingEntityIdParser::newFrombaseUri(
+                       $this->getSettings()->getSetting( 'conceptBaseUri' ),
+                       $this->getEntityIdParser()
+               );
+       }
+
+       /**
         * @return OutputFormatSnakFormatterFactory
         */
        protected function newSnakFormatterFactory() {
@@ -1064,6 +1076,7 @@
                        $this->getEntityContentFactory(),
                        new ValuesFinder( $this->getPropertyDataTypeLookup() ),
                        $this->getLanguageFallbackChainFactory(),
+                       new ReferencedEntitiesFinder( 
$this->getLocalEntityUriParser() ),
                        $templateFactory
                );
        }
diff --git a/repo/tests/phpunit/includes/EntityParserOutputGeneratorTest.php 
b/repo/tests/phpunit/includes/EntityParserOutputGeneratorTest.php
index b87b1e8..38624e1 100644
--- a/repo/tests/phpunit/includes/EntityParserOutputGeneratorTest.php
+++ b/repo/tests/phpunit/includes/EntityParserOutputGeneratorTest.php
@@ -7,6 +7,7 @@
 use MediaWikiTestCase;
 use ParserOptions;
 use Title;
+use Wikibase\DataModel\Entity\BasicEntityIdParser;
 use Wikibase\DataModel\Entity\EntityId;
 use Wikibase\DataModel\Entity\InMemoryDataTypeLookup;
 use Wikibase\DataModel\Entity\Item;
@@ -16,6 +17,7 @@
 use Wikibase\EntityParserOutputGenerator;
 use Wikibase\EntityRevision;
 use Wikibase\Lib\Store\Sql\SqlEntityInfoBuilderFactory;
+use Wikibase\ReferencedEntitiesFinder;
 use Wikibase\ValuesFinder;
 use Wikibase\View\Template\TemplateFactory;
 
@@ -109,6 +111,7 @@
 
        private function newEntityParserOutputGenerator() {
                $templateFactory = TemplateFactory::getDefaultInstance();
+               $referencedEntitiesFinder = new ReferencedEntitiesFinder( new 
BasicEntityIdParser() );
 
                return new EntityParserOutputGenerator(
                        $this->getEntityViewFactory(),
@@ -118,6 +121,7 @@
                        new SqlEntityInfoBuilderFactory(),
                        $this->newLanguageFallbackChain(),
                        'en',
+                       $referencedEntitiesFinder,
                        $templateFactory
                );
        }

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Id86dba7dfa2a46c9c7b4a94457b4f8a04f58984e
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Daniel Kinzler <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to