IriValue::newFromArray()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace DataValues;
4
5
/**
6
 * Class representing a IRI value.
7
 *
8
 * This code is based on the SMWDIUri class
9
 * from Semantic MediaWiki, written by Markus Krötzsch.
10
 *
11
 * For info on IRI syntax, see https://en.wikipedia.org/wiki/URI_scheme#Generic_syntax
12
 *
13
 * @since 0.1
14
 *
15
 * @licence GNU GPL v2+
16
 * @author Jeroen De Dauw < [email protected] >
17
 */
18
class IriValue extends DataValueObject {
19
20
	/**
21
	 * The URI scheme of the IRI.
22
	 * For instance "http", "ssh" or "mailto".
23
	 *
24
	 * @since 0.1
25
	 *
26
	 * @var string
27
	 */
28
	protected $scheme;
29
30
	/**
31
	 * The hierarchical part of the IRI.
32
	 * Consists out of an authority and a path.
33
	 * For instance
34
	 * - //username:[email protected]:8042/over/there/index.dtb
35
	 * - //www.wikidata.org
36
	 *
37
	 * @since 0.1
38
	 *
39
	 * @var string
40
	 */
41
	protected $hierarchicalPart;
42
43
	/**
44
	 * The query of the IRI.
45
	 * For instance type=animal&name=narwhal
46
	 *
47
	 * @since 0.1
48
	 *
49
	 * @var string
50
	 */
51
	protected $query;
52
53
	/**
54
	 * The fragment of the IRI.
55
	 * For instance headerSection
56
	 *
57
	 * @since 0.1
58
	 *
59
	 * @var string
60
	 */
61
	protected $fragment;
62
63
	/**
64
	 * @since 0.1
65
	 *
66
	 * @param string $scheme
67
	 * @param string $hierarchicalPart
68
	 * @param string $query
69
	 * @param string $fragment
70
	 *
71
	 * @throws IllegalValueException
72
	 */
73
	public function __construct( $scheme, $hierarchicalPart, $query = '', $fragment = '' ) {
74
		foreach ( func_get_args() as $value ) {
75
			if ( !is_string( $value ) ) {
76
				throw new IllegalValueException( 'Can only construct IriValue from strings' );
77
			}
78
		}
79
80
		if ( $scheme === '' || preg_match( '/[^a-zA-Z]/u', $scheme ) ) {
81
			throw new IllegalValueException( "Illegal URI scheme '$scheme'." );
82
		}
83
84
		if ( $hierarchicalPart === '' ) {
85
			throw new IllegalValueException( "Illegal URI hierarchical part '$hierarchicalPart'." );
86
		}
87
88
		$this->scheme = $scheme;
89
		$this->hierarchicalPart = $hierarchicalPart;
90
		$this->query = $query;
91
		$this->fragment = $fragment;
92
	}
93
94
	/**
95
	 * @see Serializable::serialize
96
	 *
97
	 * @since 0.1
98
	 *
99
	 * @return string
100
	 */
101
	public function serialize() {
102
		return $this->getValue();
103
	}
104
105
	/**
106
	 * @see Serializable::unserialize
107
	 *
108
	 * @since 0.1
109
	 *
110
	 * @param string $value
111
	 *
112
	 * @return StringValue
113
	 */
114
	public function unserialize( $value ) {
115
		list( $scheme, $hierarchicalPart, $query, $fragment ) = self::getIriParts( $value );
116
		$this->__construct( $scheme, $hierarchicalPart, $query, $fragment );
117
	}
118
119
	/**
120
	 * @see DataValue::getType
121
	 *
122
	 * @since 0.1
123
	 *
124
	 * @return string
125
	 */
126
	public static function getType() {
127
		return 'iri';
128
	}
129
130
	/**
131
	 * @see DataValue::getSortKey
132
	 *
133
	 * @since 0.1
134
	 *
135
	 * @return string|float|int
136
	 */
137
	public function getSortKey() {
138
		return $this->getValue();
139
	}
140
141
	/**
142
	 * Returns the string.
143
	 * @see DataValue::getValue
144
	 *
145
	 * @since 0.1
146
	 *
147
	 * @return string
148
	 */
149
	public function getValue() {
150
		$uri = $this->scheme . ':'
151
			. $this->hierarchicalPart
152
			. ( $this->query ? '?' . $this->query : '' )
153
			. ( $this->fragment ? '#' . $this->fragment : '' );
154
155
		return $uri;
156
	}
157
158
	/**
159
	 * Returns the scheme or the IRI.
160
	 *
161
	 * @since 0.1
162
	 *
163
	 * @return string
164
	 */
165
	public function getScheme() {
166
		return $this->scheme;
167
	}
168
169
	/**
170
	 * Returns the hierarchical part of the IRI.
171
	 *
172
	 * @since 0.1
173
	 *
174
	 * @return string
175
	 */
176
	public function getHierarchicalPart() {
177
		return $this->hierarchicalPart;
178
	}
179
180
	/**
181
	 * Returns the query part of the IRI.
182
	 *
183
	 * @since 0.1
184
	 *
185
	 * @return string
186
	 */
187
	public function getQuery() {
188
		return $this->query;
189
	}
190
191
	/**
192
	 * Returns the fragment part of the IRI.
193
	 *
194
	 * @since 0.1
195
	 *
196
	 * @return string
197
	 */
198
	public function getFragment() {
199
		return $this->fragment;
200
	}
201
202
	/**
203
	 * @since 0.1
204
	 *
205
	 * @param string $serialization
206
	 *
207
	 * @return array
208
	 * @throws IllegalValueException
209
	 */
210
	public static function getIriParts( $serialization ) {
211
		if ( !is_string( $serialization ) ) {
212
			throw new IllegalValueException( 'IriValue::getIriParts expects a string value' );
213
		}
214
215
		$parts = explode( ':', $serialization, 2 ); // try to split "schema:rest"
216
217
		if ( count( $parts ) === 1 ) {
218
			throw new IllegalValueException( "Unserialization failed: the string \"$serialization\" is no valid URI." );
219
		}
220
221
		$scheme = $parts[0];
222
		$parts = explode( '?', $parts[1], 2 ); // try to split "hier-part?queryfrag"
223
224
		if ( count( $parts ) == 2 ) {
225
			$hierpart = $parts[0];
226
			$parts = explode( '#', $parts[1], 2 ); // try to split "query#frag"
227
			$query = $parts[0];
228
			$fragment = count( $parts ) == 2 ? $parts[1] : '';
229
		} else {
230
			$query = '';
231
			$parts = explode( '#', $parts[0], 2 ); // try to split "hier-part#frag"
232
			$hierpart = $parts[0];
233
			$fragment = count( $parts ) == 2 ? $parts[1] : '';
234
		}
235
236
		return array( $scheme, $hierpart, $query, $fragment );
237
	}
238
239
	/**
240
	 * @see DataValue::getArrayValue
241
	 *
242
	 * @since 0.1
243
	 *
244
	 * @return mixed
245
	 */
246
	public function getArrayValue() {
247
		return $this->getValue();
248
	}
249
250
	/**
251
	 * Constructs a new instance of the DataValue from the provided data.
252
	 * This can round-trip with @see getArrayValue
253
	 *
254
	 * @since 0.1
255
	 *
256
	 * @param mixed $data
257
	 *
258
	 * @return IriValue
259
	 * @throws IllegalValueException
260
	 */
261
	public static function newFromArray( $data ) {
262
		list( $scheme, $hierarchicalPart, $query, $fragment ) = self::getIriParts( $data );
263
		return new self( $scheme, $hierarchicalPart, $query, $fragment );
264
	}
265
266
}