Completed
Push — master ( 5f0582...80bce5 )
by Sam
02:01
created
src/Item.php 2 patches
Indentation   +423 added lines, -423 removed lines patch added patch discarded remove patch
@@ -13,157 +13,157 @@  discard block
 block discarded – undo
13 13
 
14 14
 class Item {
15 15
 
16
-	const PROP_INSTANCE_OF = 'P31';
17
-	const PROP_TITLE = 'P1476';
18
-	const PROP_IMAGE = 'P18';
19
-	const PROP_AUTHOR = 'P50';
20
-
21
-	/** @var string */
22
-	protected $id;
23
-
24
-	/** @var MediawikiApi */
25
-	protected $wdApi;
26
-
27
-	/** @var string */
28
-	protected $lang;
29
-
30
-	/** @var CacheItemPoolInterface */
31
-	protected $cache;
32
-
33
-	/** @var string The base URL of Wikidata, with trailing slash. */
34
-	protected $wikidataUrlBase = 'https://www.wikidata.org/wiki/';
35
-
36
-	private function __construct( $id, $lang, CacheItemPoolInterface $cache ) {
37
-		if ( !is_string( $id ) || preg_match( '/[QP][0-9]*/i', $id ) !== 1 ) {
38
-			throw new Exception( "Not a valid ID: " . var_export( $id, true ) );
39
-		}
40
-		$this->id = $id;
41
-		$this->wdApi = new MediawikiApi( 'https://www.wikidata.org/w/api.php' );
42
-		$this->entities = [];
43
-		$this->lang = $lang;
44
-		$this->cache = $cache;
45
-	}
46
-
47
-	/**
48
-	 * Create a new Item object with class based on the item's 'instance of' statement.
49
-	 *
50
-	 * @param string $id The item ID (Q-number).
51
-	 * @param string $lang The language code.
52
-	 * @param CacheItemPoolInterface $cache The cache to use.
53
-	 * @return Item
54
-	 */
55
-	public static function factory( $id, $lang, CacheItemPoolInterface $cache ) {
56
-		$item = new Item( $id, $lang, $cache );
57
-		foreach ( $item->getPropertyOfTypeItem( self::PROP_INSTANCE_OF ) as $instanceOf ) {
58
-			// Try to find a class mating the 'instance of' name.
59
-			$possibleBaseClassName = Str::toCamelCase( $instanceOf->getItem()->getLabel() );
60
-			$possibleClassName = __NAMESPACE__ . '\\Items\\' . $possibleBaseClassName;
61
-			if ( class_exists( $possibleClassName ) ) {
62
-				// This won't re-request the metadata, because that's cached.
63
-				return new $possibleClassName( $id, $lang, $cache );
64
-			}
65
-		}
66
-
67
-		// If we're here, just leave it as a basic Item.
68
-		$item->setCache( $cache );
69
-		return $item;
70
-	}
71
-
72
-	/**
73
-	 * @param CacheItemPoolInterface $cache The cache to use.
74
-	 */
75
-	public function setCache( CacheItemPoolInterface $cache ) {
76
-		$this->cache = $cache;
77
-	}
78
-
79
-	/**
80
-	 * Get the ID (Q-number) of this item.
81
-	 * @return string|bool The ID or false if it couldn't be determined.
82
-	 */
83
-	public function getId() {
84
-		$entity = $this->getEntity( $this->id );
85
-		return isset( $entity['id'] ) ? $entity['id'] : false;
86
-	}
87
-
88
-	/**
89
-	 * Get this item's label.
90
-	 * @return string
91
-	 */
92
-	public function getLabel() {
93
-		$entity = $this->getEntity( $this->id );
94
-		if ( ! empty( $entity['labels'][ $this->lang ]['value'] ) ) {
95
-			// Use the label if there is one.
96
-			return $entity['labels'][ $this->lang ]['value'];
97
-		}
98
-		// Or just use the ID.
99
-		return $entity['id'];
100
-	}
101
-
102
-	/**
103
-	 * @return string The Wikidata.org URL for this item.
104
-	 */
105
-	public function getWikidataUrl() {
106
-		return $this->wikidataUrlBase.$this->id;
107
-	}
108
-
109
-	/**
110
-	 * Wikiprojects list their properties like this:
111
-	 *
112
-	 *     {{List of properties/Header}}
113
-	 *     {{List of properties/Row|id=31|example-subject=Q923767|example-object=Q3331189}}
114
-	 *     </table>
115
-	 *
116
-	 * @param string $wikiProject The name of the WikiProject (must exist as a Wikidata page e.g.
117
-	 * [[Wikidata:$wikiProject]]).
118
-	 * @param string $type
119
-	 * @return array
120
-	 */
121
-	public function getStandardProperties( $wikiProject = 'WikiProject_Books', $type = 'work' ) {
122
-		if ( $type !== 'work' ) {
123
-			$type = 'edition';
124
-		}
125
-		$cacheKey = $type . '_item_property_IDs';
126
-		if ( $this->cache->hasItem( $cacheKey ) ) {
127
-			$propIds = $this->cache->getItem( $cacheKey )->get();
128
-		} else {
129
-			$domCrawler = new Crawler();
130
-			$wikiProjectUrl = 'https://www.wikidata.org/wiki/Wikidata:' . $wikiProject;
131
-			$domCrawler->addHtmlContent( file_get_contents( $wikiProjectUrl ) );
132
-			$propAncors = "//h3/span[@id='" . ucfirst( $type ) . "_item_properties']/../following-sibling::table[1]//td[2]/a";
133
-			$propCells = $domCrawler->filterXPath( $propAncors );
134
-			$propIds = [];
135
-			$propCells->each( function ( Crawler $node, $i ) use ( &$propIds ) {
136
-				$propId = $node->text();
137
-				$propIds[] = $propId;
138
-			} );
139
-			$cacheItem = $this->cache->getItem( $cacheKey )
140
-				->expiresAfter( new DateInterval( 'PT1H' ) )
141
-				->set( $propIds );
142
-			$this->cache->save( $cacheItem );
143
-		}
144
-		$workProperties = [];
145
-		foreach ( $propIds as $propId ) {
146
-			$workProperties[] = self::factory( $propId, $this->lang, $this->cache );
147
-		}
148
-
149
-		return $workProperties;
150
-	}
151
-
152
-	/**
153
-	 * @param string $propertyId
154
-	 * @return bool|Time[]
155
-	 */
156
-	public function getPropertyOfTypeTime( $propertyId ) {
157
-		$times = [];
158
-		$entity = $this->getEntity();
159
-		if ( !isset( $entity['claims'][$propertyId] ) ) {
160
-			// No statements for this property.
161
-			return $times;
162
-		}
163
-		// print_r($entity['claims'][$propertyId]);exit();
164
-		foreach ( $entity['claims'][$propertyId] as $claim ) {
165
-			// print_r($claim);
166
-			$times[] = new Time( $claim, $this->lang, $this->cache );
16
+    const PROP_INSTANCE_OF = 'P31';
17
+    const PROP_TITLE = 'P1476';
18
+    const PROP_IMAGE = 'P18';
19
+    const PROP_AUTHOR = 'P50';
20
+
21
+    /** @var string */
22
+    protected $id;
23
+
24
+    /** @var MediawikiApi */
25
+    protected $wdApi;
26
+
27
+    /** @var string */
28
+    protected $lang;
29
+
30
+    /** @var CacheItemPoolInterface */
31
+    protected $cache;
32
+
33
+    /** @var string The base URL of Wikidata, with trailing slash. */
34
+    protected $wikidataUrlBase = 'https://www.wikidata.org/wiki/';
35
+
36
+    private function __construct( $id, $lang, CacheItemPoolInterface $cache ) {
37
+        if ( !is_string( $id ) || preg_match( '/[QP][0-9]*/i', $id ) !== 1 ) {
38
+            throw new Exception( "Not a valid ID: " . var_export( $id, true ) );
39
+        }
40
+        $this->id = $id;
41
+        $this->wdApi = new MediawikiApi( 'https://www.wikidata.org/w/api.php' );
42
+        $this->entities = [];
43
+        $this->lang = $lang;
44
+        $this->cache = $cache;
45
+    }
46
+
47
+    /**
48
+     * Create a new Item object with class based on the item's 'instance of' statement.
49
+     *
50
+     * @param string $id The item ID (Q-number).
51
+     * @param string $lang The language code.
52
+     * @param CacheItemPoolInterface $cache The cache to use.
53
+     * @return Item
54
+     */
55
+    public static function factory( $id, $lang, CacheItemPoolInterface $cache ) {
56
+        $item = new Item( $id, $lang, $cache );
57
+        foreach ( $item->getPropertyOfTypeItem( self::PROP_INSTANCE_OF ) as $instanceOf ) {
58
+            // Try to find a class mating the 'instance of' name.
59
+            $possibleBaseClassName = Str::toCamelCase( $instanceOf->getItem()->getLabel() );
60
+            $possibleClassName = __NAMESPACE__ . '\\Items\\' . $possibleBaseClassName;
61
+            if ( class_exists( $possibleClassName ) ) {
62
+                // This won't re-request the metadata, because that's cached.
63
+                return new $possibleClassName( $id, $lang, $cache );
64
+            }
65
+        }
66
+
67
+        // If we're here, just leave it as a basic Item.
68
+        $item->setCache( $cache );
69
+        return $item;
70
+    }
71
+
72
+    /**
73
+     * @param CacheItemPoolInterface $cache The cache to use.
74
+     */
75
+    public function setCache( CacheItemPoolInterface $cache ) {
76
+        $this->cache = $cache;
77
+    }
78
+
79
+    /**
80
+     * Get the ID (Q-number) of this item.
81
+     * @return string|bool The ID or false if it couldn't be determined.
82
+     */
83
+    public function getId() {
84
+        $entity = $this->getEntity( $this->id );
85
+        return isset( $entity['id'] ) ? $entity['id'] : false;
86
+    }
87
+
88
+    /**
89
+     * Get this item's label.
90
+     * @return string
91
+     */
92
+    public function getLabel() {
93
+        $entity = $this->getEntity( $this->id );
94
+        if ( ! empty( $entity['labels'][ $this->lang ]['value'] ) ) {
95
+            // Use the label if there is one.
96
+            return $entity['labels'][ $this->lang ]['value'];
97
+        }
98
+        // Or just use the ID.
99
+        return $entity['id'];
100
+    }
101
+
102
+    /**
103
+     * @return string The Wikidata.org URL for this item.
104
+     */
105
+    public function getWikidataUrl() {
106
+        return $this->wikidataUrlBase.$this->id;
107
+    }
108
+
109
+    /**
110
+     * Wikiprojects list their properties like this:
111
+     *
112
+     *     {{List of properties/Header}}
113
+     *     {{List of properties/Row|id=31|example-subject=Q923767|example-object=Q3331189}}
114
+     *     </table>
115
+     *
116
+     * @param string $wikiProject The name of the WikiProject (must exist as a Wikidata page e.g.
117
+     * [[Wikidata:$wikiProject]]).
118
+     * @param string $type
119
+     * @return array
120
+     */
121
+    public function getStandardProperties( $wikiProject = 'WikiProject_Books', $type = 'work' ) {
122
+        if ( $type !== 'work' ) {
123
+            $type = 'edition';
124
+        }
125
+        $cacheKey = $type . '_item_property_IDs';
126
+        if ( $this->cache->hasItem( $cacheKey ) ) {
127
+            $propIds = $this->cache->getItem( $cacheKey )->get();
128
+        } else {
129
+            $domCrawler = new Crawler();
130
+            $wikiProjectUrl = 'https://www.wikidata.org/wiki/Wikidata:' . $wikiProject;
131
+            $domCrawler->addHtmlContent( file_get_contents( $wikiProjectUrl ) );
132
+            $propAncors = "//h3/span[@id='" . ucfirst( $type ) . "_item_properties']/../following-sibling::table[1]//td[2]/a";
133
+            $propCells = $domCrawler->filterXPath( $propAncors );
134
+            $propIds = [];
135
+            $propCells->each( function ( Crawler $node, $i ) use ( &$propIds ) {
136
+                $propId = $node->text();
137
+                $propIds[] = $propId;
138
+            } );
139
+            $cacheItem = $this->cache->getItem( $cacheKey )
140
+                ->expiresAfter( new DateInterval( 'PT1H' ) )
141
+                ->set( $propIds );
142
+            $this->cache->save( $cacheItem );
143
+        }
144
+        $workProperties = [];
145
+        foreach ( $propIds as $propId ) {
146
+            $workProperties[] = self::factory( $propId, $this->lang, $this->cache );
147
+        }
148
+
149
+        return $workProperties;
150
+    }
151
+
152
+    /**
153
+     * @param string $propertyId
154
+     * @return bool|Time[]
155
+     */
156
+    public function getPropertyOfTypeTime( $propertyId ) {
157
+        $times = [];
158
+        $entity = $this->getEntity();
159
+        if ( !isset( $entity['claims'][$propertyId] ) ) {
160
+            // No statements for this property.
161
+            return $times;
162
+        }
163
+        // print_r($entity['claims'][$propertyId]);exit();
164
+        foreach ( $entity['claims'][$propertyId] as $claim ) {
165
+            // print_r($claim);
166
+            $times[] = new Time( $claim, $this->lang, $this->cache );
167 167
 //
168 168
 // $timeValue = $claim['datavalue']['value']['time'];
169 169
 // // Ugly workaround for imprecise dates. :-(
@@ -173,276 +173,276 @@  discard block
 block discarded – undo
173 173
 // }
174 174
 // $time = strtotime($timeValue);
175 175
 // return date($dateFormat, $time);
176
-			// }
177
-		}
178
-		return $times;
179
-	}
180
-
181
-	/**
182
-	 * Get the Item that is referred to by the specified item's property.
183
-	 *
184
-	 * @param string $propertyId
185
-	 *
186
-	 * @return \Samwilson\SimpleWikidata\Properties\Item[]
187
-	 */
188
-	public function getPropertyOfTypeItem( $propertyId ) {
189
-		$entity = $this->getEntity( $this->id );
190
-		if ( !isset( $entity['claims'][$propertyId] ) ) {
191
-			return [];
192
-		}
193
-		$items = [];
194
-		foreach ( $entity['claims'][$propertyId] as $claim ) {
195
-			$items[] = new Properties\Item( $claim, $this->lang, $this->cache );
196
-		}
197
-
198
-		return $items;
199
-	}
200
-
201
-	public function setPropertyOfTypeItem( $property, $itemId ) {
202
-		$itemIdNumeric = substr( $itemId, 1 );
203
-
204
-		// First see if this property already exists, and that it is different from what's being set.
205
-		$entity = $this->getEntity( $this->id );
206
-		if ( !empty( $entity['claims'][$property] ) ) {
207
-			// Get the first claim, and update it if necessary.
208
-			$claim = array_shift( $entity['claims'][$property] );
209
-			if ( $claim['mainsnak']['datavalue']['value']['id'] == $itemId ) {
210
-				// Already is the required value, no need to change.
211
-				return;
212
-			}
213
-			$claim['mainsnak']['datavalue']['value']['id'] = $itemId;
214
-			$claim['mainsnak']['datavalue']['value']['numeric-id'] = $itemIdNumeric;
215
-			$apiParams = [
216
-				'action' => 'wbsetclaim',
217
-				'claim' => json_encode( $claim ),
218
-			];
219
-		}
220
-
221
-		// If no claim was found (and modified) above, create a new claim.
222
-		if ( !isset( $apiParams ) ) {
223
-			$apiParams = [
224
-				'action' => 'wbcreateclaim',
225
-				'entity' => $this->getId(),
226
-				'property' => $property,
227
-				'snaktype' => 'value',
228
-				'value' => json_encode( [ 'entity-type' => 'item', 'numeric-id' => $itemIdNumeric ] ),
229
-			];
230
-		}
231
-
232
-		// @TODO Save the property.
233
-
234
-		// Clear the cache.
235
-		$this->cache->deleteItem( $this->getEntityCacheKey( $this->id ) );
236
-	}
237
-
238
-	public function getPropertyOfTypeUrl( $entityId, $propertyId ) {
239
-		$entity = $this->getEntity( $entityId );
240
-		if ( !isset( $entity['claims'][$propertyId] ) ) {
241
-			return false;
242
-		}
243
-		$urls = [];
244
-		foreach ( $entity['claims'][$propertyId] as $claim ) {
245
-			$urls[] = $claim['mainsnak']['datavalue']['value'];
246
-		}
247
-
248
-		return $urls;
249
-	}
250
-
251
-	public function getPropertyOfTypeExternalIdentifier( $entityId, $propertyId ) {
252
-		$entity = $this->getEntity( $entityId );
253
-		if ( !isset( $entity['claims'][$propertyId] ) ) {
254
-			return false;
255
-		}
256
-		$idents = [];
257
-		foreach ( $entity['claims'][$propertyId] as $claim ) {
258
-			$qualifiers = [];
259
-			if ( !isset( $claim['qualifiers'] ) ) {
260
-				continue;
261
-			}
262
-			foreach ( $claim['qualifiers'] as $qualsInfo ) {
263
-				foreach ( $qualsInfo as $qualInfo ) {
264
-					$qualProp = self::factory( $qualInfo['property'], $this->lang, $this->cache );
265
-					$propLabel = $qualProp->getLabel();
266
-					if ( !isset( $qualifiers[$propLabel] ) ) {
267
-						$qualifiers[$propLabel] = [];
268
-					}
269
-					$qualifiers[$propLabel][] = $qualInfo['datavalue']['value'];
270
-				}
271
-			}
272
-			$idents[] = [
273
-				'qualifiers' => $qualifiers,
274
-				'value' => $claim['mainsnak']['datavalue']['value'],
275
-			];
276
-		}
277
-
278
-		return $idents;
279
-	}
280
-
281
-	/**
282
-	 * Get a single-valued text property.
283
-	 * @param string $property One of the PROP_* constants.
284
-	 * @return string|bool The value, or false if it can't be found.
285
-	 */
286
-	public function getPropertyOfTypeText( $property ) {
287
-		$entity = $this->getEntity( $this->id );
288
-		if ( isset( $entity['claims'][$property] ) ) {
289
-			// Use the first title.
290
-			foreach ( $entity['claims'][$property] as $t ) {
291
-				if ( !isset( $t['mainsnak']['datavalue']['value']['language'] ) ) {
292
-					var_dump( $t['mainsnak']['datavalue']['value'] );
293
-					exit();
294
-				}
295
-				if ( $t['mainsnak']['datavalue']['value']['language'] == $this->lang
296
-					&& !empty( $t['mainsnak']['datavalue']['value']['text'] )
297
-				) {
298
-					return $t['mainsnak']['datavalue']['value']['text'];
299
-				}
300
-			}
301
-		}
302
-		return false;
303
-	}
304
-
305
-	/**
306
-	 * Literal data field for a quantity that relates to some kind of well-defined unit. The actual unit goes in the data values that is entered.
307
-	 *   - amount – implicit part of the string (mapping of unit prefix is unclear)
308
-	 *   - unit – implicit part of the string that defaults to "1" (mapping to standardizing body is unclear)
309
-	 *   - upperbound - quantity's upper bound
310
-	 *   - lowerbound - quantity's lower bound
311
-	 * @param $property
312
-	 * @return mixed[]|bool If it's not false it's an array with 'amount', 'unit', etc.
313
-	 */
314
-	public function getPropertyOfTypeQuantity( $property ) {
315
-		$quantities = [];
316
-		$entity = $this->getEntity( $this->id );
317
-		if ( !isset( $entity['claims'][$property] ) ) {
318
-			return false;
319
-		}
320
-		foreach ( $entity['claims'][$property] as $t ) {
321
-			$quantity = $t['mainsnak']['datavalue']['value'];
322
-			$unitId = substr( $quantity['unit'], strlen( $this->wikidataUrlBase ) + 1 );
323
-			$quantity['unit'] = self::factory( $unitId, $this->lang, $this->cache );
324
-			$quantities[] = $quantity;
325
-		}
326
-		return $quantities;
327
-	}
328
-
329
-	/**
330
-	 * Set a single-valued text property.
331
-	 * @param string $property One of the PROP_* constants.
332
-	 * @param string $value The value.
333
-	 */
334
-	public function setPropertyOfTypeText( $property, $value ) {
335
-		// First see if this property already exists, and that it is different from what's being set.
336
-		$entity = $this->getEntity( $this->id );
337
-		if ( !empty( $entity['claims'][$property] ) ) {
338
-			// Find this language's claim (if there is one).
339
-			foreach ( $entity['claims'][$property] as $claim ) {
340
-				if ( $claim['mainsnak']['datavalue']['value']['language'] == $this->lang ) {
341
-					// Modify this claim's text value.
342
-					$titleClaim = $claim;
343
-					$titleClaim['mainsnak']['datavalue']['value']['text'] = $value;
344
-					$setTitleParams = [
345
-						'action' => 'wbsetclaim',
346
-						'claim' => \GuzzleHttp\json_encode( $titleClaim ),
347
-					];
348
-					continue;
349
-				}
350
-			}
351
-		}
352
-
353
-		// If no claim was found (and modified) above, create a new claim.
354
-		if ( !isset( $setTitleParams ) ) {
355
-			$setTitleParams = [
356
-				'action' => 'wbcreateclaim',
357
-				'entity' => $this->getId(),
358
-				'property' => $property,
359
-				'snaktype' => 'value',
360
-				'value' => \GuzzleHttp\json_encode( [ 'text' => $value, 'language' => $this->lang ] ),
361
-			];
362
-		}
363
-
364
-		// Save the property.
365
-		$wdWpOauth = new WdWpOauth();
366
-		$wdWpOauth->makeCall( $setTitleParams, true );
367
-
368
-		// Clear the cache.
369
-		$this->cache->deleteItem( $this->getEntityCacheKey( $this->id ) );
370
-	}
371
-
372
-	/**
373
-	 * Does this item exist?
374
-	 * @return bool
375
-	 */
376
-	public function exists() {
377
-		return $this->getId() !== false;
378
-	}
379
-
380
-	public function getWikipediaIntro() {
381
-		$cacheKey = 'wikipedia-intro-' . $this->id . $this->lang;
382
-		if ( $this->cache->hasItem( $cacheKey ) ) {
383
-			return $this->cache->getItem( $cacheKey )->get();
384
-		}
385
-		$entity = $this->getEntity( $this->id );
386
-		if ( !isset( $entity['sitelinks'] ) ) {
387
-			return [];
388
-		}
389
-		foreach ( $entity['sitelinks'] as $sitelink ) {
390
-			if ( $sitelink['site'] == $this->lang . 'wiki' ) {
391
-				$api = new MediawikiApi( 'https://' . $this->lang . '.wikipedia.org/w/api.php' );
392
-				$req = new SimpleRequest( 'query', [
393
-					'prop' => 'extracts',
394
-					'exintro' => true,
395
-					'titles' => $sitelink['title'],
396
-				] );
397
-				$response = $api->getRequest( $req );
398
-				$page = array_shift( $response['query']['pages'] );
399
-				$out = [
400
-					'title' => $page['title'],
401
-					'html' => $page['extract'],
402
-				];
403
-				$cacheItem = $this->cache->getItem( $cacheKey )
404
-					->expiresAfter( new DateInterval( 'P1D' ) )
405
-					->set( $out );
406
-				$this->cache->save( $cacheItem );
407
-
408
-				return $out;
409
-			}
410
-		}
411
-
412
-		return [];
413
-	}
414
-
415
-	/**
416
-	 * Get the raw entity data from the 'wbgetentities' API call.
417
-	 * @param string $id The Q-number.
418
-	 * @param bool $ignoreCache
419
-	 * @return array|bool
420
-	 */
421
-	public function getEntity( $id = null, $ignoreCache = false ) {
422
-		$idActual = $id ?: $this->id;
423
-		$cacheKey = $this->getEntityCacheKey( $idActual );
424
-		if ( !$ignoreCache && $this->cache->hasItem( $cacheKey ) ) {
425
-			return $this->cache->getItem( $cacheKey )->get();
426
-		}
427
-		$metadataRequest = new SimpleRequest( 'wbgetentities', [ 'ids' => $idActual ] );
428
-		$itemResult = $this->wdApi->getRequest( $metadataRequest );
429
-		if ( !isset( $itemResult['success'] ) || !isset( $itemResult['entities'][$id] ) ) {
430
-			return false;
431
-		}
432
-		$metadata = $itemResult['entities'][$idActual];
433
-		$cacheItem = $this->cache->getItem( $cacheKey )
434
-			->expiresAfter( new DateInterval( 'PT10M' ) )
435
-			->set( $metadata );
436
-		$this->cache->save( $cacheItem );
437
-		return $metadata;
438
-	}
439
-
440
-	/**
441
-	 * @param $id
442
-	 *
443
-	 * @return string
444
-	 */
445
-	protected function getEntityCacheKey( $id ) {
446
-		return 'entities' . $id;
447
-	}
176
+            // }
177
+        }
178
+        return $times;
179
+    }
180
+
181
+    /**
182
+     * Get the Item that is referred to by the specified item's property.
183
+     *
184
+     * @param string $propertyId
185
+     *
186
+     * @return \Samwilson\SimpleWikidata\Properties\Item[]
187
+     */
188
+    public function getPropertyOfTypeItem( $propertyId ) {
189
+        $entity = $this->getEntity( $this->id );
190
+        if ( !isset( $entity['claims'][$propertyId] ) ) {
191
+            return [];
192
+        }
193
+        $items = [];
194
+        foreach ( $entity['claims'][$propertyId] as $claim ) {
195
+            $items[] = new Properties\Item( $claim, $this->lang, $this->cache );
196
+        }
197
+
198
+        return $items;
199
+    }
200
+
201
+    public function setPropertyOfTypeItem( $property, $itemId ) {
202
+        $itemIdNumeric = substr( $itemId, 1 );
203
+
204
+        // First see if this property already exists, and that it is different from what's being set.
205
+        $entity = $this->getEntity( $this->id );
206
+        if ( !empty( $entity['claims'][$property] ) ) {
207
+            // Get the first claim, and update it if necessary.
208
+            $claim = array_shift( $entity['claims'][$property] );
209
+            if ( $claim['mainsnak']['datavalue']['value']['id'] == $itemId ) {
210
+                // Already is the required value, no need to change.
211
+                return;
212
+            }
213
+            $claim['mainsnak']['datavalue']['value']['id'] = $itemId;
214
+            $claim['mainsnak']['datavalue']['value']['numeric-id'] = $itemIdNumeric;
215
+            $apiParams = [
216
+                'action' => 'wbsetclaim',
217
+                'claim' => json_encode( $claim ),
218
+            ];
219
+        }
220
+
221
+        // If no claim was found (and modified) above, create a new claim.
222
+        if ( !isset( $apiParams ) ) {
223
+            $apiParams = [
224
+                'action' => 'wbcreateclaim',
225
+                'entity' => $this->getId(),
226
+                'property' => $property,
227
+                'snaktype' => 'value',
228
+                'value' => json_encode( [ 'entity-type' => 'item', 'numeric-id' => $itemIdNumeric ] ),
229
+            ];
230
+        }
231
+
232
+        // @TODO Save the property.
233
+
234
+        // Clear the cache.
235
+        $this->cache->deleteItem( $this->getEntityCacheKey( $this->id ) );
236
+    }
237
+
238
+    public function getPropertyOfTypeUrl( $entityId, $propertyId ) {
239
+        $entity = $this->getEntity( $entityId );
240
+        if ( !isset( $entity['claims'][$propertyId] ) ) {
241
+            return false;
242
+        }
243
+        $urls = [];
244
+        foreach ( $entity['claims'][$propertyId] as $claim ) {
245
+            $urls[] = $claim['mainsnak']['datavalue']['value'];
246
+        }
247
+
248
+        return $urls;
249
+    }
250
+
251
+    public function getPropertyOfTypeExternalIdentifier( $entityId, $propertyId ) {
252
+        $entity = $this->getEntity( $entityId );
253
+        if ( !isset( $entity['claims'][$propertyId] ) ) {
254
+            return false;
255
+        }
256
+        $idents = [];
257
+        foreach ( $entity['claims'][$propertyId] as $claim ) {
258
+            $qualifiers = [];
259
+            if ( !isset( $claim['qualifiers'] ) ) {
260
+                continue;
261
+            }
262
+            foreach ( $claim['qualifiers'] as $qualsInfo ) {
263
+                foreach ( $qualsInfo as $qualInfo ) {
264
+                    $qualProp = self::factory( $qualInfo['property'], $this->lang, $this->cache );
265
+                    $propLabel = $qualProp->getLabel();
266
+                    if ( !isset( $qualifiers[$propLabel] ) ) {
267
+                        $qualifiers[$propLabel] = [];
268
+                    }
269
+                    $qualifiers[$propLabel][] = $qualInfo['datavalue']['value'];
270
+                }
271
+            }
272
+            $idents[] = [
273
+                'qualifiers' => $qualifiers,
274
+                'value' => $claim['mainsnak']['datavalue']['value'],
275
+            ];
276
+        }
277
+
278
+        return $idents;
279
+    }
280
+
281
+    /**
282
+     * Get a single-valued text property.
283
+     * @param string $property One of the PROP_* constants.
284
+     * @return string|bool The value, or false if it can't be found.
285
+     */
286
+    public function getPropertyOfTypeText( $property ) {
287
+        $entity = $this->getEntity( $this->id );
288
+        if ( isset( $entity['claims'][$property] ) ) {
289
+            // Use the first title.
290
+            foreach ( $entity['claims'][$property] as $t ) {
291
+                if ( !isset( $t['mainsnak']['datavalue']['value']['language'] ) ) {
292
+                    var_dump( $t['mainsnak']['datavalue']['value'] );
293
+                    exit();
294
+                }
295
+                if ( $t['mainsnak']['datavalue']['value']['language'] == $this->lang
296
+                    && !empty( $t['mainsnak']['datavalue']['value']['text'] )
297
+                ) {
298
+                    return $t['mainsnak']['datavalue']['value']['text'];
299
+                }
300
+            }
301
+        }
302
+        return false;
303
+    }
304
+
305
+    /**
306
+     * Literal data field for a quantity that relates to some kind of well-defined unit. The actual unit goes in the data values that is entered.
307
+     *   - amount – implicit part of the string (mapping of unit prefix is unclear)
308
+     *   - unit – implicit part of the string that defaults to "1" (mapping to standardizing body is unclear)
309
+     *   - upperbound - quantity's upper bound
310
+     *   - lowerbound - quantity's lower bound
311
+     * @param $property
312
+     * @return mixed[]|bool If it's not false it's an array with 'amount', 'unit', etc.
313
+     */
314
+    public function getPropertyOfTypeQuantity( $property ) {
315
+        $quantities = [];
316
+        $entity = $this->getEntity( $this->id );
317
+        if ( !isset( $entity['claims'][$property] ) ) {
318
+            return false;
319
+        }
320
+        foreach ( $entity['claims'][$property] as $t ) {
321
+            $quantity = $t['mainsnak']['datavalue']['value'];
322
+            $unitId = substr( $quantity['unit'], strlen( $this->wikidataUrlBase ) + 1 );
323
+            $quantity['unit'] = self::factory( $unitId, $this->lang, $this->cache );
324
+            $quantities[] = $quantity;
325
+        }
326
+        return $quantities;
327
+    }
328
+
329
+    /**
330
+     * Set a single-valued text property.
331
+     * @param string $property One of the PROP_* constants.
332
+     * @param string $value The value.
333
+     */
334
+    public function setPropertyOfTypeText( $property, $value ) {
335
+        // First see if this property already exists, and that it is different from what's being set.
336
+        $entity = $this->getEntity( $this->id );
337
+        if ( !empty( $entity['claims'][$property] ) ) {
338
+            // Find this language's claim (if there is one).
339
+            foreach ( $entity['claims'][$property] as $claim ) {
340
+                if ( $claim['mainsnak']['datavalue']['value']['language'] == $this->lang ) {
341
+                    // Modify this claim's text value.
342
+                    $titleClaim = $claim;
343
+                    $titleClaim['mainsnak']['datavalue']['value']['text'] = $value;
344
+                    $setTitleParams = [
345
+                        'action' => 'wbsetclaim',
346
+                        'claim' => \GuzzleHttp\json_encode( $titleClaim ),
347
+                    ];
348
+                    continue;
349
+                }
350
+            }
351
+        }
352
+
353
+        // If no claim was found (and modified) above, create a new claim.
354
+        if ( !isset( $setTitleParams ) ) {
355
+            $setTitleParams = [
356
+                'action' => 'wbcreateclaim',
357
+                'entity' => $this->getId(),
358
+                'property' => $property,
359
+                'snaktype' => 'value',
360
+                'value' => \GuzzleHttp\json_encode( [ 'text' => $value, 'language' => $this->lang ] ),
361
+            ];
362
+        }
363
+
364
+        // Save the property.
365
+        $wdWpOauth = new WdWpOauth();
366
+        $wdWpOauth->makeCall( $setTitleParams, true );
367
+
368
+        // Clear the cache.
369
+        $this->cache->deleteItem( $this->getEntityCacheKey( $this->id ) );
370
+    }
371
+
372
+    /**
373
+     * Does this item exist?
374
+     * @return bool
375
+     */
376
+    public function exists() {
377
+        return $this->getId() !== false;
378
+    }
379
+
380
+    public function getWikipediaIntro() {
381
+        $cacheKey = 'wikipedia-intro-' . $this->id . $this->lang;
382
+        if ( $this->cache->hasItem( $cacheKey ) ) {
383
+            return $this->cache->getItem( $cacheKey )->get();
384
+        }
385
+        $entity = $this->getEntity( $this->id );
386
+        if ( !isset( $entity['sitelinks'] ) ) {
387
+            return [];
388
+        }
389
+        foreach ( $entity['sitelinks'] as $sitelink ) {
390
+            if ( $sitelink['site'] == $this->lang . 'wiki' ) {
391
+                $api = new MediawikiApi( 'https://' . $this->lang . '.wikipedia.org/w/api.php' );
392
+                $req = new SimpleRequest( 'query', [
393
+                    'prop' => 'extracts',
394
+                    'exintro' => true,
395
+                    'titles' => $sitelink['title'],
396
+                ] );
397
+                $response = $api->getRequest( $req );
398
+                $page = array_shift( $response['query']['pages'] );
399
+                $out = [
400
+                    'title' => $page['title'],
401
+                    'html' => $page['extract'],
402
+                ];
403
+                $cacheItem = $this->cache->getItem( $cacheKey )
404
+                    ->expiresAfter( new DateInterval( 'P1D' ) )
405
+                    ->set( $out );
406
+                $this->cache->save( $cacheItem );
407
+
408
+                return $out;
409
+            }
410
+        }
411
+
412
+        return [];
413
+    }
414
+
415
+    /**
416
+     * Get the raw entity data from the 'wbgetentities' API call.
417
+     * @param string $id The Q-number.
418
+     * @param bool $ignoreCache
419
+     * @return array|bool
420
+     */
421
+    public function getEntity( $id = null, $ignoreCache = false ) {
422
+        $idActual = $id ?: $this->id;
423
+        $cacheKey = $this->getEntityCacheKey( $idActual );
424
+        if ( !$ignoreCache && $this->cache->hasItem( $cacheKey ) ) {
425
+            return $this->cache->getItem( $cacheKey )->get();
426
+        }
427
+        $metadataRequest = new SimpleRequest( 'wbgetentities', [ 'ids' => $idActual ] );
428
+        $itemResult = $this->wdApi->getRequest( $metadataRequest );
429
+        if ( !isset( $itemResult['success'] ) || !isset( $itemResult['entities'][$id] ) ) {
430
+            return false;
431
+        }
432
+        $metadata = $itemResult['entities'][$idActual];
433
+        $cacheItem = $this->cache->getItem( $cacheKey )
434
+            ->expiresAfter( new DateInterval( 'PT10M' ) )
435
+            ->set( $metadata );
436
+        $this->cache->save( $cacheItem );
437
+        return $metadata;
438
+    }
439
+
440
+    /**
441
+     * @param $id
442
+     *
443
+     * @return string
444
+     */
445
+    protected function getEntityCacheKey( $id ) {
446
+        return 'entities' . $id;
447
+    }
448 448
 }
Please login to merge, or discard this patch.
Spacing   +115 added lines, -115 removed lines patch added patch discarded remove patch
@@ -33,12 +33,12 @@  discard block
 block discarded – undo
33 33
 	/** @var string The base URL of Wikidata, with trailing slash. */
34 34
 	protected $wikidataUrlBase = 'https://www.wikidata.org/wiki/';
35 35
 
36
-	private function __construct( $id, $lang, CacheItemPoolInterface $cache ) {
37
-		if ( !is_string( $id ) || preg_match( '/[QP][0-9]*/i', $id ) !== 1 ) {
38
-			throw new Exception( "Not a valid ID: " . var_export( $id, true ) );
36
+	private function __construct($id, $lang, CacheItemPoolInterface $cache) {
37
+		if (!is_string($id) || preg_match('/[QP][0-9]*/i', $id) !== 1) {
38
+			throw new Exception("Not a valid ID: " . var_export($id, true));
39 39
 		}
40 40
 		$this->id = $id;
41
-		$this->wdApi = new MediawikiApi( 'https://www.wikidata.org/w/api.php' );
41
+		$this->wdApi = new MediawikiApi('https://www.wikidata.org/w/api.php');
42 42
 		$this->entities = [];
43 43
 		$this->lang = $lang;
44 44
 		$this->cache = $cache;
@@ -52,27 +52,27 @@  discard block
 block discarded – undo
52 52
 	 * @param CacheItemPoolInterface $cache The cache to use.
53 53
 	 * @return Item
54 54
 	 */
55
-	public static function factory( $id, $lang, CacheItemPoolInterface $cache ) {
56
-		$item = new Item( $id, $lang, $cache );
57
-		foreach ( $item->getPropertyOfTypeItem( self::PROP_INSTANCE_OF ) as $instanceOf ) {
55
+	public static function factory($id, $lang, CacheItemPoolInterface $cache) {
56
+		$item = new Item($id, $lang, $cache);
57
+		foreach ($item->getPropertyOfTypeItem(self::PROP_INSTANCE_OF) as $instanceOf) {
58 58
 			// Try to find a class mating the 'instance of' name.
59
-			$possibleBaseClassName = Str::toCamelCase( $instanceOf->getItem()->getLabel() );
59
+			$possibleBaseClassName = Str::toCamelCase($instanceOf->getItem()->getLabel());
60 60
 			$possibleClassName = __NAMESPACE__ . '\\Items\\' . $possibleBaseClassName;
61
-			if ( class_exists( $possibleClassName ) ) {
61
+			if (class_exists($possibleClassName)) {
62 62
 				// This won't re-request the metadata, because that's cached.
63
-				return new $possibleClassName( $id, $lang, $cache );
63
+				return new $possibleClassName($id, $lang, $cache);
64 64
 			}
65 65
 		}
66 66
 
67 67
 		// If we're here, just leave it as a basic Item.
68
-		$item->setCache( $cache );
68
+		$item->setCache($cache);
69 69
 		return $item;
70 70
 	}
71 71
 
72 72
 	/**
73 73
 	 * @param CacheItemPoolInterface $cache The cache to use.
74 74
 	 */
75
-	public function setCache( CacheItemPoolInterface $cache ) {
75
+	public function setCache(CacheItemPoolInterface $cache) {
76 76
 		$this->cache = $cache;
77 77
 	}
78 78
 
@@ -81,8 +81,8 @@  discard block
 block discarded – undo
81 81
 	 * @return string|bool The ID or false if it couldn't be determined.
82 82
 	 */
83 83
 	public function getId() {
84
-		$entity = $this->getEntity( $this->id );
85
-		return isset( $entity['id'] ) ? $entity['id'] : false;
84
+		$entity = $this->getEntity($this->id);
85
+		return isset($entity['id']) ? $entity['id'] : false;
86 86
 	}
87 87
 
88 88
 	/**
@@ -90,10 +90,10 @@  discard block
 block discarded – undo
90 90
 	 * @return string
91 91
 	 */
92 92
 	public function getLabel() {
93
-		$entity = $this->getEntity( $this->id );
94
-		if ( ! empty( $entity['labels'][ $this->lang ]['value'] ) ) {
93
+		$entity = $this->getEntity($this->id);
94
+		if (!empty($entity['labels'][$this->lang]['value'])) {
95 95
 			// Use the label if there is one.
96
-			return $entity['labels'][ $this->lang ]['value'];
96
+			return $entity['labels'][$this->lang]['value'];
97 97
 		}
98 98
 		// Or just use the ID.
99 99
 		return $entity['id'];
@@ -103,7 +103,7 @@  discard block
 block discarded – undo
103 103
 	 * @return string The Wikidata.org URL for this item.
104 104
 	 */
105 105
 	public function getWikidataUrl() {
106
-		return $this->wikidataUrlBase.$this->id;
106
+		return $this->wikidataUrlBase . $this->id;
107 107
 	}
108 108
 
109 109
 	/**
@@ -118,32 +118,32 @@  discard block
 block discarded – undo
118 118
 	 * @param string $type
119 119
 	 * @return array
120 120
 	 */
121
-	public function getStandardProperties( $wikiProject = 'WikiProject_Books', $type = 'work' ) {
122
-		if ( $type !== 'work' ) {
121
+	public function getStandardProperties($wikiProject = 'WikiProject_Books', $type = 'work') {
122
+		if ($type !== 'work') {
123 123
 			$type = 'edition';
124 124
 		}
125 125
 		$cacheKey = $type . '_item_property_IDs';
126
-		if ( $this->cache->hasItem( $cacheKey ) ) {
127
-			$propIds = $this->cache->getItem( $cacheKey )->get();
126
+		if ($this->cache->hasItem($cacheKey)) {
127
+			$propIds = $this->cache->getItem($cacheKey)->get();
128 128
 		} else {
129 129
 			$domCrawler = new Crawler();
130 130
 			$wikiProjectUrl = 'https://www.wikidata.org/wiki/Wikidata:' . $wikiProject;
131
-			$domCrawler->addHtmlContent( file_get_contents( $wikiProjectUrl ) );
132
-			$propAncors = "//h3/span[@id='" . ucfirst( $type ) . "_item_properties']/../following-sibling::table[1]//td[2]/a";
133
-			$propCells = $domCrawler->filterXPath( $propAncors );
131
+			$domCrawler->addHtmlContent(file_get_contents($wikiProjectUrl));
132
+			$propAncors = "//h3/span[@id='" . ucfirst($type) . "_item_properties']/../following-sibling::table[1]//td[2]/a";
133
+			$propCells = $domCrawler->filterXPath($propAncors);
134 134
 			$propIds = [];
135
-			$propCells->each( function ( Crawler $node, $i ) use ( &$propIds ) {
135
+			$propCells->each(function(Crawler $node, $i) use (&$propIds) {
136 136
 				$propId = $node->text();
137 137
 				$propIds[] = $propId;
138 138
 			} );
139
-			$cacheItem = $this->cache->getItem( $cacheKey )
140
-				->expiresAfter( new DateInterval( 'PT1H' ) )
141
-				->set( $propIds );
142
-			$this->cache->save( $cacheItem );
139
+			$cacheItem = $this->cache->getItem($cacheKey)
140
+				->expiresAfter(new DateInterval('PT1H'))
141
+				->set($propIds);
142
+			$this->cache->save($cacheItem);
143 143
 		}
144 144
 		$workProperties = [];
145
-		foreach ( $propIds as $propId ) {
146
-			$workProperties[] = self::factory( $propId, $this->lang, $this->cache );
145
+		foreach ($propIds as $propId) {
146
+			$workProperties[] = self::factory($propId, $this->lang, $this->cache);
147 147
 		}
148 148
 
149 149
 		return $workProperties;
@@ -153,17 +153,17 @@  discard block
 block discarded – undo
153 153
 	 * @param string $propertyId
154 154
 	 * @return bool|Time[]
155 155
 	 */
156
-	public function getPropertyOfTypeTime( $propertyId ) {
156
+	public function getPropertyOfTypeTime($propertyId) {
157 157
 		$times = [];
158 158
 		$entity = $this->getEntity();
159
-		if ( !isset( $entity['claims'][$propertyId] ) ) {
159
+		if (!isset($entity['claims'][$propertyId])) {
160 160
 			// No statements for this property.
161 161
 			return $times;
162 162
 		}
163 163
 		// print_r($entity['claims'][$propertyId]);exit();
164
-		foreach ( $entity['claims'][$propertyId] as $claim ) {
164
+		foreach ($entity['claims'][$propertyId] as $claim) {
165 165
 			// print_r($claim);
166
-			$times[] = new Time( $claim, $this->lang, $this->cache );
166
+			$times[] = new Time($claim, $this->lang, $this->cache);
167 167
 //
168 168
 // $timeValue = $claim['datavalue']['value']['time'];
169 169
 // // Ugly workaround for imprecise dates. :-(
@@ -185,28 +185,28 @@  discard block
 block discarded – undo
185 185
 	 *
186 186
 	 * @return \Samwilson\SimpleWikidata\Properties\Item[]
187 187
 	 */
188
-	public function getPropertyOfTypeItem( $propertyId ) {
189
-		$entity = $this->getEntity( $this->id );
190
-		if ( !isset( $entity['claims'][$propertyId] ) ) {
188
+	public function getPropertyOfTypeItem($propertyId) {
189
+		$entity = $this->getEntity($this->id);
190
+		if (!isset($entity['claims'][$propertyId])) {
191 191
 			return [];
192 192
 		}
193 193
 		$items = [];
194
-		foreach ( $entity['claims'][$propertyId] as $claim ) {
195
-			$items[] = new Properties\Item( $claim, $this->lang, $this->cache );
194
+		foreach ($entity['claims'][$propertyId] as $claim) {
195
+			$items[] = new Properties\Item($claim, $this->lang, $this->cache);
196 196
 		}
197 197
 
198 198
 		return $items;
199 199
 	}
200 200
 
201
-	public function setPropertyOfTypeItem( $property, $itemId ) {
202
-		$itemIdNumeric = substr( $itemId, 1 );
201
+	public function setPropertyOfTypeItem($property, $itemId) {
202
+		$itemIdNumeric = substr($itemId, 1);
203 203
 
204 204
 		// First see if this property already exists, and that it is different from what's being set.
205
-		$entity = $this->getEntity( $this->id );
206
-		if ( !empty( $entity['claims'][$property] ) ) {
205
+		$entity = $this->getEntity($this->id);
206
+		if (!empty($entity['claims'][$property])) {
207 207
 			// Get the first claim, and update it if necessary.
208
-			$claim = array_shift( $entity['claims'][$property] );
209
-			if ( $claim['mainsnak']['datavalue']['value']['id'] == $itemId ) {
208
+			$claim = array_shift($entity['claims'][$property]);
209
+			if ($claim['mainsnak']['datavalue']['value']['id'] == $itemId) {
210 210
 				// Already is the required value, no need to change.
211 211
 				return;
212 212
 			}
@@ -214,56 +214,56 @@  discard block
 block discarded – undo
214 214
 			$claim['mainsnak']['datavalue']['value']['numeric-id'] = $itemIdNumeric;
215 215
 			$apiParams = [
216 216
 				'action' => 'wbsetclaim',
217
-				'claim' => json_encode( $claim ),
217
+				'claim' => json_encode($claim),
218 218
 			];
219 219
 		}
220 220
 
221 221
 		// If no claim was found (and modified) above, create a new claim.
222
-		if ( !isset( $apiParams ) ) {
222
+		if (!isset($apiParams)) {
223 223
 			$apiParams = [
224 224
 				'action' => 'wbcreateclaim',
225 225
 				'entity' => $this->getId(),
226 226
 				'property' => $property,
227 227
 				'snaktype' => 'value',
228
-				'value' => json_encode( [ 'entity-type' => 'item', 'numeric-id' => $itemIdNumeric ] ),
228
+				'value' => json_encode(['entity-type' => 'item', 'numeric-id' => $itemIdNumeric]),
229 229
 			];
230 230
 		}
231 231
 
232 232
 		// @TODO Save the property.
233 233
 
234 234
 		// Clear the cache.
235
-		$this->cache->deleteItem( $this->getEntityCacheKey( $this->id ) );
235
+		$this->cache->deleteItem($this->getEntityCacheKey($this->id));
236 236
 	}
237 237
 
238
-	public function getPropertyOfTypeUrl( $entityId, $propertyId ) {
239
-		$entity = $this->getEntity( $entityId );
240
-		if ( !isset( $entity['claims'][$propertyId] ) ) {
238
+	public function getPropertyOfTypeUrl($entityId, $propertyId) {
239
+		$entity = $this->getEntity($entityId);
240
+		if (!isset($entity['claims'][$propertyId])) {
241 241
 			return false;
242 242
 		}
243 243
 		$urls = [];
244
-		foreach ( $entity['claims'][$propertyId] as $claim ) {
244
+		foreach ($entity['claims'][$propertyId] as $claim) {
245 245
 			$urls[] = $claim['mainsnak']['datavalue']['value'];
246 246
 		}
247 247
 
248 248
 		return $urls;
249 249
 	}
250 250
 
251
-	public function getPropertyOfTypeExternalIdentifier( $entityId, $propertyId ) {
252
-		$entity = $this->getEntity( $entityId );
253
-		if ( !isset( $entity['claims'][$propertyId] ) ) {
251
+	public function getPropertyOfTypeExternalIdentifier($entityId, $propertyId) {
252
+		$entity = $this->getEntity($entityId);
253
+		if (!isset($entity['claims'][$propertyId])) {
254 254
 			return false;
255 255
 		}
256 256
 		$idents = [];
257
-		foreach ( $entity['claims'][$propertyId] as $claim ) {
257
+		foreach ($entity['claims'][$propertyId] as $claim) {
258 258
 			$qualifiers = [];
259
-			if ( !isset( $claim['qualifiers'] ) ) {
259
+			if (!isset($claim['qualifiers'])) {
260 260
 				continue;
261 261
 			}
262
-			foreach ( $claim['qualifiers'] as $qualsInfo ) {
263
-				foreach ( $qualsInfo as $qualInfo ) {
264
-					$qualProp = self::factory( $qualInfo['property'], $this->lang, $this->cache );
262
+			foreach ($claim['qualifiers'] as $qualsInfo) {
263
+				foreach ($qualsInfo as $qualInfo) {
264
+					$qualProp = self::factory($qualInfo['property'], $this->lang, $this->cache);
265 265
 					$propLabel = $qualProp->getLabel();
266
-					if ( !isset( $qualifiers[$propLabel] ) ) {
266
+					if (!isset($qualifiers[$propLabel])) {
267 267
 						$qualifiers[$propLabel] = [];
268 268
 					}
269 269
 					$qualifiers[$propLabel][] = $qualInfo['datavalue']['value'];
@@ -283,17 +283,17 @@  discard block
 block discarded – undo
283 283
 	 * @param string $property One of the PROP_* constants.
284 284
 	 * @return string|bool The value, or false if it can't be found.
285 285
 	 */
286
-	public function getPropertyOfTypeText( $property ) {
287
-		$entity = $this->getEntity( $this->id );
288
-		if ( isset( $entity['claims'][$property] ) ) {
286
+	public function getPropertyOfTypeText($property) {
287
+		$entity = $this->getEntity($this->id);
288
+		if (isset($entity['claims'][$property])) {
289 289
 			// Use the first title.
290
-			foreach ( $entity['claims'][$property] as $t ) {
291
-				if ( !isset( $t['mainsnak']['datavalue']['value']['language'] ) ) {
292
-					var_dump( $t['mainsnak']['datavalue']['value'] );
290
+			foreach ($entity['claims'][$property] as $t) {
291
+				if (!isset($t['mainsnak']['datavalue']['value']['language'])) {
292
+					var_dump($t['mainsnak']['datavalue']['value']);
293 293
 					exit();
294 294
 				}
295
-				if ( $t['mainsnak']['datavalue']['value']['language'] == $this->lang
296
-					&& !empty( $t['mainsnak']['datavalue']['value']['text'] )
295
+				if ($t['mainsnak']['datavalue']['value']['language'] == $this->lang
296
+					&& !empty($t['mainsnak']['datavalue']['value']['text'])
297 297
 				) {
298 298
 					return $t['mainsnak']['datavalue']['value']['text'];
299 299
 				}
@@ -311,16 +311,16 @@  discard block
 block discarded – undo
311 311
 	 * @param $property
312 312
 	 * @return mixed[]|bool If it's not false it's an array with 'amount', 'unit', etc.
313 313
 	 */
314
-	public function getPropertyOfTypeQuantity( $property ) {
314
+	public function getPropertyOfTypeQuantity($property) {
315 315
 		$quantities = [];
316
-		$entity = $this->getEntity( $this->id );
317
-		if ( !isset( $entity['claims'][$property] ) ) {
316
+		$entity = $this->getEntity($this->id);
317
+		if (!isset($entity['claims'][$property])) {
318 318
 			return false;
319 319
 		}
320
-		foreach ( $entity['claims'][$property] as $t ) {
320
+		foreach ($entity['claims'][$property] as $t) {
321 321
 			$quantity = $t['mainsnak']['datavalue']['value'];
322
-			$unitId = substr( $quantity['unit'], strlen( $this->wikidataUrlBase ) + 1 );
323
-			$quantity['unit'] = self::factory( $unitId, $this->lang, $this->cache );
322
+			$unitId = substr($quantity['unit'], strlen($this->wikidataUrlBase) + 1);
323
+			$quantity['unit'] = self::factory($unitId, $this->lang, $this->cache);
324 324
 			$quantities[] = $quantity;
325 325
 		}
326 326
 		return $quantities;
@@ -331,19 +331,19 @@  discard block
 block discarded – undo
331 331
 	 * @param string $property One of the PROP_* constants.
332 332
 	 * @param string $value The value.
333 333
 	 */
334
-	public function setPropertyOfTypeText( $property, $value ) {
334
+	public function setPropertyOfTypeText($property, $value) {
335 335
 		// First see if this property already exists, and that it is different from what's being set.
336
-		$entity = $this->getEntity( $this->id );
337
-		if ( !empty( $entity['claims'][$property] ) ) {
336
+		$entity = $this->getEntity($this->id);
337
+		if (!empty($entity['claims'][$property])) {
338 338
 			// Find this language's claim (if there is one).
339
-			foreach ( $entity['claims'][$property] as $claim ) {
340
-				if ( $claim['mainsnak']['datavalue']['value']['language'] == $this->lang ) {
339
+			foreach ($entity['claims'][$property] as $claim) {
340
+				if ($claim['mainsnak']['datavalue']['value']['language'] == $this->lang) {
341 341
 					// Modify this claim's text value.
342 342
 					$titleClaim = $claim;
343 343
 					$titleClaim['mainsnak']['datavalue']['value']['text'] = $value;
344 344
 					$setTitleParams = [
345 345
 						'action' => 'wbsetclaim',
346
-						'claim' => \GuzzleHttp\json_encode( $titleClaim ),
346
+						'claim' => \GuzzleHttp\json_encode($titleClaim),
347 347
 					];
348 348
 					continue;
349 349
 				}
@@ -351,22 +351,22 @@  discard block
 block discarded – undo
351 351
 		}
352 352
 
353 353
 		// If no claim was found (and modified) above, create a new claim.
354
-		if ( !isset( $setTitleParams ) ) {
354
+		if (!isset($setTitleParams)) {
355 355
 			$setTitleParams = [
356 356
 				'action' => 'wbcreateclaim',
357 357
 				'entity' => $this->getId(),
358 358
 				'property' => $property,
359 359
 				'snaktype' => 'value',
360
-				'value' => \GuzzleHttp\json_encode( [ 'text' => $value, 'language' => $this->lang ] ),
360
+				'value' => \GuzzleHttp\json_encode(['text' => $value, 'language' => $this->lang]),
361 361
 			];
362 362
 		}
363 363
 
364 364
 		// Save the property.
365 365
 		$wdWpOauth = new WdWpOauth();
366
-		$wdWpOauth->makeCall( $setTitleParams, true );
366
+		$wdWpOauth->makeCall($setTitleParams, true);
367 367
 
368 368
 		// Clear the cache.
369
-		$this->cache->deleteItem( $this->getEntityCacheKey( $this->id ) );
369
+		$this->cache->deleteItem($this->getEntityCacheKey($this->id));
370 370
 	}
371 371
 
372 372
 	/**
@@ -379,31 +379,31 @@  discard block
 block discarded – undo
379 379
 
380 380
 	public function getWikipediaIntro() {
381 381
 		$cacheKey = 'wikipedia-intro-' . $this->id . $this->lang;
382
-		if ( $this->cache->hasItem( $cacheKey ) ) {
383
-			return $this->cache->getItem( $cacheKey )->get();
382
+		if ($this->cache->hasItem($cacheKey)) {
383
+			return $this->cache->getItem($cacheKey)->get();
384 384
 		}
385
-		$entity = $this->getEntity( $this->id );
386
-		if ( !isset( $entity['sitelinks'] ) ) {
385
+		$entity = $this->getEntity($this->id);
386
+		if (!isset($entity['sitelinks'])) {
387 387
 			return [];
388 388
 		}
389
-		foreach ( $entity['sitelinks'] as $sitelink ) {
390
-			if ( $sitelink['site'] == $this->lang . 'wiki' ) {
391
-				$api = new MediawikiApi( 'https://' . $this->lang . '.wikipedia.org/w/api.php' );
392
-				$req = new SimpleRequest( 'query', [
389
+		foreach ($entity['sitelinks'] as $sitelink) {
390
+			if ($sitelink['site'] == $this->lang . 'wiki') {
391
+				$api = new MediawikiApi('https://' . $this->lang . '.wikipedia.org/w/api.php');
392
+				$req = new SimpleRequest('query', [
393 393
 					'prop' => 'extracts',
394 394
 					'exintro' => true,
395 395
 					'titles' => $sitelink['title'],
396
-				] );
397
-				$response = $api->getRequest( $req );
398
-				$page = array_shift( $response['query']['pages'] );
396
+				]);
397
+				$response = $api->getRequest($req);
398
+				$page = array_shift($response['query']['pages']);
399 399
 				$out = [
400 400
 					'title' => $page['title'],
401 401
 					'html' => $page['extract'],
402 402
 				];
403
-				$cacheItem = $this->cache->getItem( $cacheKey )
404
-					->expiresAfter( new DateInterval( 'P1D' ) )
405
-					->set( $out );
406
-				$this->cache->save( $cacheItem );
403
+				$cacheItem = $this->cache->getItem($cacheKey)
404
+					->expiresAfter(new DateInterval('P1D'))
405
+					->set($out);
406
+				$this->cache->save($cacheItem);
407 407
 
408 408
 				return $out;
409 409
 			}
@@ -418,22 +418,22 @@  discard block
 block discarded – undo
418 418
 	 * @param bool $ignoreCache
419 419
 	 * @return array|bool
420 420
 	 */
421
-	public function getEntity( $id = null, $ignoreCache = false ) {
421
+	public function getEntity($id = null, $ignoreCache = false) {
422 422
 		$idActual = $id ?: $this->id;
423
-		$cacheKey = $this->getEntityCacheKey( $idActual );
424
-		if ( !$ignoreCache && $this->cache->hasItem( $cacheKey ) ) {
425
-			return $this->cache->getItem( $cacheKey )->get();
423
+		$cacheKey = $this->getEntityCacheKey($idActual);
424
+		if (!$ignoreCache && $this->cache->hasItem($cacheKey)) {
425
+			return $this->cache->getItem($cacheKey)->get();
426 426
 		}
427
-		$metadataRequest = new SimpleRequest( 'wbgetentities', [ 'ids' => $idActual ] );
428
-		$itemResult = $this->wdApi->getRequest( $metadataRequest );
429
-		if ( !isset( $itemResult['success'] ) || !isset( $itemResult['entities'][$id] ) ) {
427
+		$metadataRequest = new SimpleRequest('wbgetentities', ['ids' => $idActual]);
428
+		$itemResult = $this->wdApi->getRequest($metadataRequest);
429
+		if (!isset($itemResult['success']) || !isset($itemResult['entities'][$id])) {
430 430
 			return false;
431 431
 		}
432 432
 		$metadata = $itemResult['entities'][$idActual];
433
-		$cacheItem = $this->cache->getItem( $cacheKey )
434
-			->expiresAfter( new DateInterval( 'PT10M' ) )
435
-			->set( $metadata );
436
-		$this->cache->save( $cacheItem );
433
+		$cacheItem = $this->cache->getItem($cacheKey)
434
+			->expiresAfter(new DateInterval('PT10M'))
435
+			->set($metadata);
436
+		$this->cache->save($cacheItem);
437 437
 		return $metadata;
438 438
 	}
439 439
 
@@ -442,7 +442,7 @@  discard block
 block discarded – undo
442 442
 	 *
443 443
 	 * @return string
444 444
 	 */
445
-	protected function getEntityCacheKey( $id ) {
445
+	protected function getEntityCacheKey($id) {
446 446
 		return 'entities' . $id;
447 447
 	}
448 448
 }
Please login to merge, or discard this patch.