Completed
Pull Request — master (#679)
by Leszek
03:16
created

DispatchingEntityIdParser::parse()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 24
ccs 12
cts 12
cp 1
rs 8.5125
c 0
b 0
f 0
cc 5
eloc 13
nc 5
nop 1
crap 5
1
<?php
2
3
namespace Wikibase\DataModel\Entity;
4
5
use InvalidArgumentException;
6
7
/**
8
 * @since 4.2
9
 *
10
 * @license GPL-2.0+
11
 * @author Jeroen De Dauw < [email protected] >
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 12
	public function __construct( array $idBuilders ) {
30 12
		$this->idBuilders = $idBuilders;
31 12
	}
32
33
	/**
34
	 * @param string $idSerialization
35
	 *
36
	 * @throws EntityIdParsingException
37
	 * @return EntityId
38
	 */
39 12
	public function parse( $idSerialization ) {
40 12
		$this->assertIdIsString( $idSerialization );
41
42 9
		if ( empty( $this->idBuilders ) ) {
43 1
			throw new EntityIdParsingException( 'No id builders are configured' );
44
		}
45
46 8
		foreach ( $this->idBuilders as $idPattern => $idBuilder ) {
47 8
			try {
48 4
				list( , , $localId ) = EntityId::splitSerialization( $idSerialization );
49
			} catch ( InvalidArgumentException $ex ) {
50 6
				// EntityId::splitSerialization performs some sanity checks which
51
				// might result in an exception. Should this happen, re-throw the exception message
52 4
				throw new EntityIdParsingException( $ex->getMessage() );
53 4
			}
54 4
			if ( preg_match( $idPattern, $localId ) ) {
55
				return $this->buildId( $idBuilder, $idSerialization );
56
			}
57
		}
58
59
		throw new EntityIdParsingException(
60
			"The serialization \"$idSerialization\" is not recognized by the configured id builders"
61
		);
62 12
	}
63 12
64 3
	/**
65
	 * @param string $idSerialization
66 9
	 *
67
	 * @throws EntityIdParsingException
68
	 */
69
	private function assertIdIsString( $idSerialization ) {
70
		if ( !is_string( $idSerialization ) ) {
71
			throw new EntityIdParsingException( '$idSerialization must be a string' );
72
		}
73
	}
74
75 4
	/**
76
	 * @param callable $idBuilder
77 4
	 * @param string $idSerialization
78
	 *
79
	 * @throws EntityIdParsingException
80
	 * @return EntityId
81
	 */
82
	private function buildId( $idBuilder, $idSerialization ) {
83
		try {
84
			return call_user_func( $idBuilder, $idSerialization );
85
		} catch ( InvalidArgumentException $ex ) {
86
			// Should not happen, but if it does, re-throw the original message
87
			throw new EntityIdParsingException( $ex->getMessage() );
88
		}
89
	}
90
91
}
92