PerSiteLinkProvider   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 112
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 4
dl 0
loc 112
ccs 0
cts 42
cp 0
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getForSiteLink() 0 12 3
B loadFromSiteLinks() 0 15 6
A getFromWiki() 0 18 3
buildRequest() 0 1 ?
parseResult() 0 1 ?
A getApiFromWikiId() 0 7 2
A isWikiIdSupported() 0 3 1
1
<?php
2
3
namespace PPP\Wikidata\Wikipedia;
4
5
use InvalidArgumentException;
6
use Mediawiki\Api\MediawikiApi;
7
use Mediawiki\Api\SimpleRequest;
8
use OutOfBoundsException;
9
use PPP\Wikidata\Cache\PerSiteLinkCache;
10
use Wikibase\DataModel\SiteLink;
11
12
/**
13
 * @licence AGPLv3+
14
 * @author Thomas Pellissier Tanon
15
 */
16
abstract class PerSiteLinkProvider {
17
18
	/**
19
	 * @var PerSiteLinkCache
20
	 */
21
	private $cache;
22
23
	/**
24
	 * @var MediawikiApi[]
25
	 */
26
	private $apis;
27
28
	/**
29
	 * @param MediawikiApi[] $apis
30
	 * @param PerSiteLinkCache $cache
31
	 */
32
	public function __construct(array $apis, PerSiteLinkCache $cache) {
33
		$this->apis = $apis;
34
		$this->cache = $cache;
35
	}
36
37
	/**
38
	 * @param SiteLink $siteLink
39
	 * @return SiteLinkProvider
40
	 */
41
	protected function getForSiteLink(SiteLink $siteLink) {
42
		try {
43
			return $this->cache->fetch($siteLink);
44
		} catch(OutOfBoundsException $e) {
45
			$headers = $this->getFromWiki($siteLink->getSiteId(), array($siteLink->getPageName()));
46
			if(empty($headers)) {
47
				throw new OutOfBoundsException('The page ' . $siteLink->getPageName() . ' of ' . $siteLink->getSiteId() . ' does not exists');
48
			}
49
50
			return reset($headers);
51
		}
52
	}
53
54
	/**
55
	 * Makes sure that data are loaded into the cache
56
	 *
57
	 * @param SiteLink[] $titles
58
	 */
59
	public function loadFromSiteLinks(array $titles) {
60
		$titlesPerWiki = array();
61
62
		foreach($titles as $title) {
63
			if(!$this->cache->contains($title) && $this->isWikiIdSupported($title->getSiteId())) {
64
				$titlesPerWiki[$title->getSiteId()][] = $title->getPageName();
65
			}
66
		}
67
68
		foreach($titlesPerWiki as $wikiId => $titles) {
69
			foreach($this->getFromWiki($wikiId, $titles) as $articleHeader) {
70
				$this->cache->save($articleHeader);
71
			}
72
		}
73
	}
74
75
	private function getFromWiki($wikiId, $titles) {
76
		if(empty($titles)) {
77
			return array();
78
		}
79
80
		$request = $this->buildRequest($titles);
81
		$api = $this->getApiFromWikiId($wikiId);
82
		$finalResults = array();
83
		$result = array('continue' => '');
84
		do {
85
			$request['continue'] = $result['continue'];
86
			$result = $api->getRequest(new SimpleRequest($request['action'], $request));
87
			$finalResults = array_merge($finalResults, $this->parseResult($wikiId, $titles, $result));
88
89
		} while(array_key_exists('continue', $result));
90
91
		return $finalResults;
92
	}
93
94
	/**
95
	 * @param string[] $titles
96
	 * @return array
97
	 */
98
	protected abstract function buildRequest($titles);
99
100
	/**
101
	 * @param string $wikiId
102
	 * @param string[] $titles
103
	 * @param array $result
104
	 * @return SiteLinkProvider[]
105
	 */
106
	protected abstract function parseResult($wikiId, $titles, $result);
107
108
	/**
109
	 * @param string $wikiId
110
	 * @return MediawikiApi
111
	 */
112
	protected function getApiFromWikiId($wikiId) {
113
		if(!array_key_exists($wikiId, $this->apis)) {
114
			throw new InvalidArgumentException('Unknown wiki id: ' . $wikiId);
115
		}
116
117
		return $this->apis[$wikiId];
118
	}
119
120
	/**
121
	 * @param string $wikiId
122
	 * @return bool
123
	 */
124
	public function isWikiIdSupported($wikiId) {
125
		return array_key_exists($wikiId, $this->apis);
126
	}
127
}
128