RestrictedEntityLookup   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 112
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 3
dl 0
loc 112
ccs 25
cts 25
cp 1
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 3
A getEntity() 0 17 3
A hasEntity() 0 3 1
A getEntityAccessCount() 0 3 1
A reset() 0 4 1
A entityHasBeenAccessed() 0 5 1
1
<?php
2
3
namespace Wikibase\DataModel\Services\Lookup;
4
5
use InvalidArgumentException;
6
use Wikibase\DataModel\Entity\EntityDocument;
7
use Wikibase\DataModel\Entity\EntityId;
8
9
/**
10
 * EntityLookup that counts how many entities have been loaded through it and throws
11
 * an exception once to many entities have been loaded.
12
 *
13
 * This is needed to limit the number of entities that can be loaded via some
14
 * user controlled features, like entity access in Lua.
15
 *
16
 * @since 2.0
17
 *
18
 * @license GPL-2.0-or-later
19
 * @author Marius Hoch < [email protected] >
20
 */
21
class RestrictedEntityLookup implements EntityLookup {
22
23
	/**
24
	 * @var EntityLookup
25
	 */
26
	private $entityLookup;
27
28
	/**
29
	 * @var int
30
	 */
31
	private $entityAccessLimit;
32
33
	/**
34
	 * @var bool[] Entity id serialization => bool
35
	 */
36
	private $entitiesAccessed = [];
37
38
	/**
39
	 * @var int
40
	 */
41
	private $entityAccessCount = 0;
42
43
	/**
44
	 * @param EntityLookup $entityLookup
45
	 * @param int $entityAccessLimit
46
	 *
47
	 * @throws InvalidArgumentException
48
	 */
49 7
	public function __construct( EntityLookup $entityLookup, $entityAccessLimit ) {
50 7
		if ( !is_int( $entityAccessLimit ) || $entityAccessLimit < 1 ) {
51 1
			throw new InvalidArgumentException( '$entityAccessLimit must be a positive integer' );
52
		}
53
54 6
		$this->entityLookup = $entityLookup;
55 6
		$this->entityAccessLimit = $entityAccessLimit;
56 6
	}
57
58
	/**
59
	 * @see EntityLookup::getEntity
60
	 *
61
	 * @param EntityId $entityId
62
	 *
63
	 * @throws EntityAccessLimitException
64
	 * @return EntityDocument
65
	 */
66 4
	public function getEntity( EntityId $entityId ) {
67 4
		$entityIdSerialization = $entityId->getSerialization();
68
69 4
		if ( !array_key_exists( $entityIdSerialization, $this->entitiesAccessed ) ) {
70 4
			$this->entityAccessCount++;
71 4
			$this->entitiesAccessed[$entityIdSerialization] = true;
72 4
		}
73
74 4
		if ( $this->entityAccessCount > $this->entityAccessLimit ) {
75 1
			throw new EntityAccessLimitException(
76 1
				$entityId,
77 1
				'To many entities loaded, must not load more than ' . $this->entityAccessLimit . ' entities.'
78 1
			);
79
		}
80
81 4
		return $this->entityLookup->getEntity( $entityId );
82
	}
83
84
	/**
85
	 * @see EntityLookup::hasEntity
86
	 *
87
	 * @param EntityId $entityId
88
	 *
89
	 * @return bool
90
	 * @throws EntityLookupException
91
	 */
92 1
	public function hasEntity( EntityId $entityId ) {
93 1
		return $this->entityLookup->hasEntity( $entityId );
94
	}
95
96
	/**
97
	 * Returns the number of entities already loaded via this object.
98
	 *
99
	 * @since 2.0
100
	 *
101
	 * @return int
102
	 */
103 1
	public function getEntityAccessCount() {
104 1
		return $this->entityAccessCount;
105
	}
106
107
	/**
108
	 * Resets the number and list of entities loaded via this object.
109
	 *
110
	 * @since 3.4
111
	 */
112
	public function reset() {
113
		$this->entityAccessCount = 0;
114
		$this->entitiesAccessed = [];
115
	}
116 1
117 1
	/**
118
	 * Whether an entity has been accessed before via this RestrictedEntityLookup.
119 1
	 *
120
	 * @since 2.0
121
	 *
122
	 * @param EntityId $entityId
123
	 *
124
	 * @return bool
125
	 */
126
	public function entityHasBeenAccessed( EntityId $entityId ) {
127
		$entityIdSerialization = $entityId->getSerialization();
128
129
		return array_key_exists( $entityIdSerialization, $this->entitiesAccessed );
130
	}
131
132
}
133