1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Wikibase\Api\Service; |
4
|
|
|
|
5
|
|
|
use Deserializers\Deserializer; |
6
|
|
|
use InvalidArgumentException; |
7
|
|
|
use Mediawiki\Api\MediawikiApi; |
8
|
|
|
use Mediawiki\Api\SimpleRequest; |
9
|
|
|
use Mediawiki\DataModel\PageIdentifier; |
10
|
|
|
use Mediawiki\DataModel\Revision; |
11
|
|
|
use Mediawiki\DataModel\Revisions; |
12
|
|
|
use RuntimeException; |
13
|
|
|
use Wikibase\DataModel\Entity\EntityId; |
14
|
|
|
use Wikibase\DataModel\Entity\Item; |
15
|
|
|
use Wikibase\DataModel\Entity\Property; |
16
|
|
|
use Wikibase\DataModel\ItemContent; |
17
|
|
|
use Wikibase\DataModel\PropertyContent; |
18
|
|
|
use Wikibase\DataModel\SiteLink; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* @access private |
22
|
|
|
* |
23
|
|
|
* @author Addshore |
24
|
|
|
*/ |
25
|
|
|
class RevisionsGetter { |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* @var MediawikiApi |
29
|
|
|
*/ |
30
|
|
|
protected $api; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* @var Deserializer |
34
|
|
|
*/ |
35
|
|
|
private $entityDeserializer; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* @param MediawikiApi $api |
39
|
|
|
* @param Deserializer $entityDeserializer |
40
|
|
|
*/ |
41
|
|
|
public function __construct( MediawikiApi $api, Deserializer $entityDeserializer ) { |
42
|
|
|
$this->api = $api; |
43
|
|
|
$this->entityDeserializer = $entityDeserializer; |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* Get revisions for the entities identified using as few requests as possible. |
48
|
|
|
* |
49
|
|
|
* @param array $identifyingInfoArray Can include the following: |
50
|
|
|
* EntityId EntityId objects |
51
|
|
|
* SiteLink SiteLink objects |
52
|
|
|
* string Serialized entity ids (these are not validated before passing to the api) |
53
|
|
|
* |
54
|
|
|
* @since 0.4 |
55
|
|
|
* |
56
|
|
|
* @return Revisions |
57
|
|
|
*/ |
58
|
|
|
public function getRevisions( array $identifyingInfoArray ) { |
59
|
|
|
$entityIdStrings = []; |
60
|
|
|
$siteLinksStringMapping = []; |
61
|
|
|
|
62
|
|
|
foreach ( $identifyingInfoArray as $someInfo ) { |
63
|
|
|
if ( $someInfo instanceof EntityId ) { |
64
|
|
|
$entityIdStrings[] = $someInfo->getSerialization(); |
65
|
|
|
} elseif ( $someInfo instanceof SiteLink ) { |
66
|
|
|
$siteLinksStringMapping[ $someInfo->getSiteId() ][] = $someInfo->getPageName(); |
67
|
|
|
} elseif ( is_string( $someInfo ) ) { |
68
|
|
|
$entityIdStrings[] = $someInfo; |
69
|
|
|
} else { |
70
|
|
|
throw new InvalidArgumentException( 'Unexpected $identifyingInfoArray in RevisionsGetter::getRevisions' ); |
71
|
|
|
} |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
// The below makes as few requests as possible to get the Revisions required! |
75
|
|
|
$gotRevisionsFromIds = false; |
76
|
|
|
$revisions = new Revisions(); |
77
|
|
|
if ( !empty( $siteLinksStringMapping ) ) { |
78
|
|
|
foreach ( $siteLinksStringMapping as $site => $siteLinkStrings ) { |
79
|
|
|
$params = [ 'sites' => $site ]; |
80
|
|
|
if ( !$gotRevisionsFromIds && !empty( $entityIdStrings ) ) { |
81
|
|
|
$params['ids'] = implode( '|', $entityIdStrings ); |
82
|
|
|
$gotRevisionsFromIds = true; |
83
|
|
|
} |
84
|
|
|
$params['titles'] = implode( '|', $siteLinkStrings ); |
85
|
|
|
$result = $this->api->getRequest( new SimpleRequest( 'wbgetentities', $params ) ); |
86
|
|
|
$resultRevisions = $this->newRevisionsFromResult( $result['entities'] ); |
87
|
|
|
$revisions->addRevisions( $resultRevisions ); |
88
|
|
|
|
89
|
|
|
} |
90
|
|
|
} else { |
91
|
|
|
$params = [ 'ids' => implode( '|', $entityIdStrings ) ]; |
92
|
|
|
$result = $this->api->getRequest( new SimpleRequest( 'wbgetentities', $params ) ); |
93
|
|
|
$resultRevisions = $this->newRevisionsFromResult( $result['entities'] ); |
94
|
|
|
$revisions->addRevisions( $resultRevisions ); |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
return $revisions; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* @param array $entitiesResult |
102
|
|
|
* @return Revisions |
103
|
|
|
* @todo this could be factored into a different class? |
104
|
|
|
*/ |
105
|
|
|
private function newRevisionsFromResult( array $entitiesResult ) { |
106
|
|
|
$revisions = new Revisions(); |
107
|
|
|
foreach ( $entitiesResult as $entityResult ) { |
108
|
|
|
if ( array_key_exists( 'missing', $entityResult ) ) { |
109
|
|
|
continue; |
110
|
|
|
} |
111
|
|
|
$revisions->addRevision( new Revision( |
112
|
|
|
$this->getContentFromEntity( $this->entityDeserializer->deserialize( $entityResult ) ), |
113
|
|
|
new PageIdentifier( null, $entityResult['pageid'] ), |
114
|
|
|
$entityResult['lastrevid'], |
115
|
|
|
null, |
116
|
|
|
null, |
117
|
|
|
$entityResult['modified'] |
118
|
|
|
) ); |
119
|
|
|
} |
120
|
|
|
return $revisions; |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* @param Item|Property $entity |
125
|
|
|
* |
126
|
|
|
* @throws RuntimeException |
127
|
|
|
* @return ItemContent|PropertyContent |
128
|
|
|
* @todo this could be factored into a different class? |
129
|
|
|
*/ |
130
|
|
View Code Duplication |
private function getContentFromEntity( $entity ) { |
131
|
|
|
switch ( $entity->getType() ) { |
132
|
|
|
case Item::ENTITY_TYPE: |
133
|
|
|
return new ItemContent( $entity ); |
|
|
|
|
134
|
|
|
case Property::ENTITY_TYPE: |
135
|
|
|
return new PropertyContent( $entity ); |
|
|
|
|
136
|
|
|
default: |
137
|
|
|
throw new RuntimeException( 'I cant get a content for this type of entity' ); |
138
|
|
|
} |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
} |
142
|
|
|
|
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.