Skip to content

Commit e14b557

Browse files
committed
Move EntityIdParser back from DataModel Services
1 parent 94f7b23 commit e14b557

6 files changed

Lines changed: 309 additions & 0 deletions

File tree

src/Entity/BasicEntityIdParser.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace Wikibase\DataModel\Entity;
4+
5+
/**
6+
* Object that can parse the serializations of the EntityIds defined by the DataModel.
7+
*
8+
* @since 4.2
9+
*
10+
* @licence GNU GPL v2+
11+
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
12+
*/
13+
class BasicEntityIdParser implements EntityIdParser {
14+
15+
private $idParser;
16+
17+
public function __construct() {
18+
$this->idParser = new DispatchingEntityIdParser( self::getBuilders() );
19+
}
20+
21+
/**
22+
* @param string $idSerialization
23+
*
24+
* @return ItemId|PropertyId
25+
* @throws EntityIdParsingException
26+
*/
27+
public function parse( $idSerialization ) {
28+
return $this->idParser->parse( $idSerialization );
29+
}
30+
31+
/**
32+
* Returns an id builders array.
33+
* Keys are preg_match patterns, values are callables.
34+
* (See the DispatchingEntityIdParser constructor for more details.)
35+
*
36+
* This method returns builders for the ids of all entity types
37+
* defined by WikibaseDataModel. It is intended to be used by
38+
* applications that allow for registration of additional entity
39+
* types, and thus want to extend upon this list. The extended
40+
* list can then be used to construct a DispatchingEntityIdParser instance.
41+
*
42+
* @return callable[]
43+
*/
44+
public static function getBuilders() {
45+
return array(
46+
ItemId::PATTERN => function( $serialization ) {
47+
return new ItemId( $serialization );
48+
},
49+
PropertyId::PATTERN => function( $serialization ) {
50+
return new PropertyId( $serialization );
51+
},
52+
);
53+
}
54+
55+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
namespace Wikibase\DataModel\Entity;
4+
5+
use InvalidArgumentException;
6+
7+
/**
8+
* @since 4.2
9+
*
10+
* @licence GNU GPL v2+
11+
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
12+
*/
13+
class DispatchingEntityIdParser implements EntityIdParser {
14+
15+
/**
16+
* @var callable[]
17+
*/
18+
private $idBuilders;
19+
20+
/**
21+
* Takes an array in which each key is a preg_match pattern.
22+
* The first pattern the id matches against will be picked.
23+
* The value this key points to has to be a builder function
24+
* that takes as only required argument the id serialization
25+
* (string) and returns an EntityId instance.
26+
*
27+
* @param callable[] $idBuilders
28+
*/
29+
public function __construct( array $idBuilders ) {
30+
$this->idBuilders = $idBuilders;
31+
}
32+
33+
/**
34+
* @param string $idSerialization
35+
*
36+
* @throws EntityIdParsingException
37+
* @return EntityId
38+
*/
39+
public function parse( $idSerialization ) {
40+
$this->assertIdIsString( $idSerialization );
41+
42+
if ( empty( $this->idBuilders ) ) {
43+
throw new EntityIdParsingException( 'No id builders are configured' );
44+
}
45+
46+
foreach ( $this->idBuilders as $idPattern => $idBuilder ) {
47+
if ( preg_match( $idPattern, $idSerialization ) ) {
48+
return $this->buildId( $idBuilder, $idSerialization );
49+
}
50+
}
51+
52+
throw new EntityIdParsingException(
53+
"The serialization \"$idSerialization\" is not recognized by the configured id builders"
54+
);
55+
}
56+
57+
/**
58+
* @param string $idSerialization
59+
*
60+
* @throws EntityIdParsingException
61+
*/
62+
private function assertIdIsString( $idSerialization ) {
63+
if ( !is_string( $idSerialization ) ) {
64+
throw new EntityIdParsingException( '$idSerialization must be a string' );
65+
}
66+
}
67+
68+
/**
69+
* @param callable $idBuilder
70+
* @param string $idSerialization
71+
*
72+
* @throws EntityIdParsingException
73+
* @return EntityId
74+
*/
75+
private function buildId( $idBuilder, $idSerialization ) {
76+
try {
77+
return call_user_func( $idBuilder, $idSerialization );
78+
} catch ( InvalidArgumentException $ex ) {
79+
// Should not happen, but if it does, re-throw the original message
80+
throw new EntityIdParsingException( $ex->getMessage() );
81+
}
82+
}
83+
84+
}

src/Entity/EntityIdParser.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace Wikibase\DataModel\Entity;
4+
5+
/**
6+
* Interface for objects that can parse strings into EntityIds
7+
*
8+
* @since 4.2
9+
*
10+
* @licence GNU GPL v2+
11+
* @author Adam Shorland
12+
*/
13+
interface EntityIdParser {
14+
15+
/**
16+
* @since 1.0
17+
*
18+
* @param string $idSerialization
19+
*
20+
* @return EntityId
21+
* @throws EntityIdParsingException
22+
*/
23+
public function parse( $idSerialization );
24+
25+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Wikibase\DataModel\Entity;
4+
5+
/**
6+
* @since 4.2
7+
*
8+
* @licence GNU GPL v2+
9+
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
10+
*/
11+
class EntityIdParsingException extends \RuntimeException {
12+
13+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
namespace Wikibase\DataModel\Tests\Entity;
4+
5+
use Wikibase\DataModel\Entity\BasicEntityIdParser;
6+
use Wikibase\DataModel\Entity\EntityId;
7+
use Wikibase\DataModel\Entity\ItemId;
8+
use Wikibase\DataModel\Entity\PropertyId;
9+
10+
/**
11+
* @covers Wikibase\DataModel\Entity\BasicEntityIdParser
12+
*
13+
* @licence GNU GPL v2+
14+
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
15+
* @author Thiemo Mättig
16+
*/
17+
class BasicEntityIdParserTest extends \PHPUnit_Framework_TestCase {
18+
19+
/**
20+
* @dataProvider entityIdProvider
21+
*/
22+
public function testCanParseEntityId( $idString, EntityId $expected ) {
23+
$parser = new BasicEntityIdParser();
24+
$actual = $parser->parse( $idString );
25+
26+
$this->assertEquals( $actual, $expected );
27+
}
28+
29+
public function entityIdProvider() {
30+
return array(
31+
array( 'q42', new ItemId( 'q42' ) ),
32+
array( 'Q1337', new ItemId( 'Q1337' ) ),
33+
array( 'p1', new PropertyId( 'p1' ) ),
34+
array( 'P100000', new PropertyId( 'P100000' ) ),
35+
);
36+
}
37+
38+
/**
39+
* @dataProvider invalidIdSerializationProvider
40+
*/
41+
public function testCannotParseInvalidId( $invalidIdSerialization ) {
42+
$parser = new BasicEntityIdParser();
43+
44+
$this->setExpectedException( 'Wikibase\DataModel\Entity\EntityIdParsingException' );
45+
$parser->parse( $invalidIdSerialization );
46+
}
47+
48+
public function invalidIdSerializationProvider() {
49+
return array(
50+
array( 'FOO' ),
51+
array( null ),
52+
array( 42 ),
53+
array( array() ),
54+
array( '' ),
55+
array( 'q0' ),
56+
array( '1p' ),
57+
);
58+
}
59+
60+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
namespace Wikibase\DataModel\Tests\Entity;
4+
5+
use Wikibase\DataModel\Entity\BasicEntityIdParser;
6+
use Wikibase\DataModel\Entity\DispatchingEntityIdParser;
7+
use Wikibase\DataModel\Entity\EntityId;
8+
use Wikibase\DataModel\Entity\ItemId;
9+
use Wikibase\DataModel\Entity\PropertyId;
10+
11+
/**
12+
* @covers Wikibase\DataModel\Entity\DispatchingEntityIdParser
13+
*
14+
* @licence GNU GPL v2+
15+
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
16+
* @author Thiemo Mättig
17+
*/
18+
class DispatchingEntityIdParserTest extends \PHPUnit_Framework_TestCase {
19+
20+
private function getBasicParser() {
21+
return new DispatchingEntityIdParser( BasicEntityIdParser::getBuilders() );
22+
}
23+
24+
/**
25+
* @dataProvider entityIdProvider
26+
*/
27+
public function testCanParseEntityId( $idString, EntityId $expected ) {
28+
$parser = $this->getBasicParser();
29+
$actual = $parser->parse( $idString );
30+
31+
$this->assertEquals( $actual, $expected );
32+
}
33+
34+
public function entityIdProvider() {
35+
return array(
36+
array( 'q42', new ItemId( 'q42' ) ),
37+
array( 'Q1337', new ItemId( 'Q1337' ) ),
38+
array( 'p1', new PropertyId( 'p1' ) ),
39+
array( 'P100000', new PropertyId( 'P100000' ) ),
40+
);
41+
}
42+
43+
/**
44+
* @dataProvider invalidIdSerializationProvider
45+
*/
46+
public function testCannotParseInvalidId( $invalidIdSerialization ) {
47+
$parser = $this->getBasicParser();
48+
49+
$this->setExpectedException( 'Wikibase\DataModel\Entity\EntityIdParsingException' );
50+
$parser->parse( $invalidIdSerialization );
51+
}
52+
53+
public function invalidIdSerializationProvider() {
54+
return array(
55+
array( 'FOO' ),
56+
array( null ),
57+
array( 42 ),
58+
array( array() ),
59+
array( '' ),
60+
array( 'q0' ),
61+
array( '1p' ),
62+
);
63+
}
64+
65+
public function testCannotParseWithoutBuilders() {
66+
$parser = new DispatchingEntityIdParser( array() );
67+
68+
$this->setExpectedException( 'Wikibase\DataModel\Entity\EntityIdParsingException' );
69+
$parser->parse( 'Q1' );
70+
}
71+
72+
}

0 commit comments

Comments
 (0)