Completed
Push — main ( b55b92...e8d442 )
by
unknown
05:41
created

RevisionsGetter::getRevisions()   B

Complexity

Conditions 9
Paths 9

Size

Total Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 41
rs 7.7084
c 0
b 0
f 0
cc 9
nc 9
nop 1
1
<?php
2
3
namespace Addwiki\Wikibase\Api\Service;
4
5
use Addwiki\Mediawiki\Api\Client\MediawikiApi;
6
use Addwiki\Mediawiki\Api\Client\SimpleRequest;
7
use Addwiki\Mediawiki\DataModel\PageIdentifier;
8
use Addwiki\Mediawiki\DataModel\Revision;
9
use Addwiki\Mediawiki\DataModel\Revisions;
10
use Addwiki\Wikibase\DataModel\ItemContent;
11
use Addwiki\Wikibase\DataModel\PropertyContent;
12
use Deserializers\Deserializer;
13
use InvalidArgumentException;
14
use RuntimeException;
15
use Wikibase\DataModel\Entity\EntityId;
16
use Wikibase\DataModel\Entity\Item;
17
use Wikibase\DataModel\Entity\Property;
18
use Wikibase\DataModel\SiteLink;
19
20
/**
21
 * @access private
22
 *
23
 * @author Addshore
24
 */
25
class RevisionsGetter {
26
27
	protected MediawikiApi $api;
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_STRING, expecting T_FUNCTION or T_CONST
Loading history...
28
29
	private \Deserializers\Deserializer $entityDeserializer;
30
31
	/**
32
	 * @param MediawikiApi $api
33
	 * @param Deserializer $entityDeserializer
34
	 */
35
	public function __construct( MediawikiApi $api, Deserializer $entityDeserializer ) {
36
		$this->api = $api;
37
		$this->entityDeserializer = $entityDeserializer;
38
	}
39
40
	/**
41
	 * Get revisions for the entities identified using as few requests as possible.
42
	 *
43
	 * @param array $identifyingInfoArray Can include the following:
44
	 *     EntityId EntityId objects
45
	 *     SiteLink SiteLink objects
46
	 *     string Serialized entity ids (these are not validated before passing to the api)
47
	 *
48
	 * @since 0.4
49
	 */
50
	public function getRevisions( array $identifyingInfoArray ): Revisions {
51
		$entityIdStrings = [];
52
		$siteLinksStringMapping = [];
53
54
		foreach ( $identifyingInfoArray as $someInfo ) {
55
			if ( $someInfo instanceof EntityId ) {
56
				$entityIdStrings[] = $someInfo->getSerialization();
57
			} elseif ( $someInfo instanceof SiteLink ) {
58
				$siteLinksStringMapping[ $someInfo->getSiteId() ][] = $someInfo->getPageName();
59
			} elseif ( is_string( $someInfo ) ) {
60
				$entityIdStrings[] = $someInfo;
61
			} else {
62
				throw new InvalidArgumentException( 'Unexpected $identifyingInfoArray in RevisionsGetter::getRevisions' );
63
			}
64
		}
65
66
		// The below makes as few requests as possible to get the Revisions required!
67
		$gotRevisionsFromIds = false;
68
		$revisions = new Revisions();
69
		if ( !empty( $siteLinksStringMapping ) ) {
70
			foreach ( $siteLinksStringMapping as $site => $siteLinkStrings ) {
71
				$params = [ 'sites' => $site ];
72
				if ( !$gotRevisionsFromIds && !empty( $entityIdStrings ) ) {
73
					$params['ids'] = implode( '|', $entityIdStrings );
74
					$gotRevisionsFromIds = true;
75
				}
76
				$params['titles'] = implode( '|', $siteLinkStrings );
77
				$result = $this->api->getRequest( new SimpleRequest( 'wbgetentities', $params ) );
78
				$resultRevisions = $this->newRevisionsFromResult( $result['entities'] );
79
				$revisions->addRevisions( $resultRevisions );
80
81
			}
82
		} else {
83
			$params = [ 'ids' => implode( '|', $entityIdStrings ) ];
84
			$result = $this->api->getRequest( new SimpleRequest( 'wbgetentities', $params ) );
85
			$resultRevisions = $this->newRevisionsFromResult( $result['entities'] );
86
			$revisions->addRevisions( $resultRevisions );
87
		}
88
89
		return $revisions;
90
	}
91
92
	/**
93
	 * @param array $entitiesResult
94
	 * @todo this could be factored into a different class?
95
	 */
96
	private function newRevisionsFromResult( array $entitiesResult ): Revisions {
97
		$revisions = new Revisions();
98
		foreach ( $entitiesResult as $entityResult ) {
99
			if ( array_key_exists( 'missing', $entityResult ) ) {
100
				continue;
101
			}
102
			$revisions->addRevision( new Revision(
103
				$this->getContentFromEntity( $this->entityDeserializer->deserialize( $entityResult ) ),
104
				new PageIdentifier( null, $entityResult['pageid'] ),
105
				$entityResult['lastrevid'],
106
				null,
107
				null,
108
				$entityResult['modified']
109
			) );
110
		}
111
		return $revisions;
112
	}
113
114
	/**
115
	 * @param Item|Property $entity
116
	 *
117
	 * @throws RuntimeException
118
	 * @return ItemContent|PropertyContent|void
119
	 * @todo this could be factored into a different class?
120
	 */
121
	private function getContentFromEntity( $entity ) {
122
		switch ( $entity->getType() ) {
123
			case Item::ENTITY_TYPE:
124
				return new ItemContent( $entity );
125
			case Property::ENTITY_TYPE:
126
				return new PropertyContent( $entity );
127
			default:
128
				throw new RuntimeException( 'I cant get a content for this type of entity' );
129
		}
130
	}
131
132
}
133