Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Failed Conditions
Pull Request — master (#1101)
by Dan
05:32
created

AbstractSmrLocation::moveSectorLocation()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 2
eloc 9
c 1
b 1
f 0
nc 2
nop 4
dl 0
loc 16
rs 9.9666
1
<?php declare(strict_types=1);
2
3
class AbstractSmrLocation {
4
	protected static array $CACHE_ALL_LOCATIONS;
5
	protected static array $CACHE_LOCATIONS = [];
6
	protected static array $CACHE_SECTOR_LOCATIONS = [];
7
8
	protected Smr\Database $db;
9
	protected string $SQL;
10
11
	protected int $typeID;
12
	protected string $name;
13
	protected ?string $processor;
14
	protected string $image;
15
16
	protected bool $fed;
17
	protected bool $bank;
18
	protected bool $bar;
19
	protected bool $HQ;
20
	protected bool $UG;
21
22
	protected array $hardwareSold;
23
	protected array $shipsSold;
24
	protected array $weaponsSold;
25
26
	public static function clearCache() : void {
27
		self::$CACHE_ALL_LOCATIONS = [];
28
		self::$CACHE_LOCATIONS = [];
29
		self::$CACHE_SECTOR_LOCATIONS = [];
30
	}
31
32
	public static function getAllLocations(bool $forceUpdate = false) : array {
33
		if ($forceUpdate || !isset(self::$CACHE_ALL_LOCATIONS)) {
34
			$db = Smr\Database::getInstance();
35
			$dbResult = $db->read('SELECT * FROM location_type ORDER BY location_type_id');
36
			$locations = array();
37
			foreach ($dbResult->records() as $dbRecord) {
38
				$locationTypeID = $dbRecord->getInt('location_type_id');
39
				$locations[$locationTypeID] = SmrLocation::getLocation($locationTypeID, $forceUpdate, $dbRecord);
40
			}
41
			self::$CACHE_ALL_LOCATIONS = $locations;
42
		}
43
		return self::$CACHE_ALL_LOCATIONS;
44
	}
45
46
	public static function getGalaxyLocations(int $gameID, int $galaxyID, bool $forceUpdate = false) : array {
47
		$db = Smr\Database::getInstance();
48
		$dbResult = $db->read('SELECT location_type.*, sector_id FROM location LEFT JOIN sector USING(game_id, sector_id) LEFT JOIN location_type USING (location_type_id) WHERE game_id = ' . $db->escapeNumber($gameID) . ' AND galaxy_id = ' . $db->escapeNumber($galaxyID));
49
		$galaxyLocations = [];
50
		foreach ($dbResult->records() as $dbRecord) {
51
			$sectorID = $dbRecord->getInt('sector_id');
52
			$locationTypeID = $dbRecord->getInt('location_type_id');
53
			$location = self::getLocation($locationTypeID, $forceUpdate, $dbRecord);
54
			self::$CACHE_SECTOR_LOCATIONS[$gameID][$sectorID][$locationTypeID] = $location;
55
			$galaxyLocations[$sectorID][$locationTypeID] = $location;
56
		}
57
		return $galaxyLocations;
58
	}
59
60
	public static function getSectorLocations(int $gameID, int $sectorID, bool $forceUpdate = false) : array {
61
		if ($forceUpdate || !isset(self::$CACHE_SECTOR_LOCATIONS[$gameID][$sectorID])) {
62
			$db = Smr\Database::getInstance();
63
			$dbResult = $db->read('SELECT * FROM location LEFT JOIN location_type USING (location_type_id) WHERE sector_id = ' . $db->escapeNumber($sectorID) . ' AND game_id=' . $db->escapeNumber($gameID));
64
			$locations = array();
65
			foreach ($dbResult->records() as $dbRecord) {
66
				$locationTypeID = $dbRecord->getInt('location_type_id');
67
				$locations[$locationTypeID] = self::getLocation($locationTypeID, $forceUpdate, $dbRecord);
68
			}
69
			self::$CACHE_SECTOR_LOCATIONS[$gameID][$sectorID] = $locations;
70
		}
71
		return self::$CACHE_SECTOR_LOCATIONS[$gameID][$sectorID];
72
	}
73
74
	public static function addSectorLocation(int $gameID, int $sectorID, SmrLocation $location) : void {
75
		self::getSectorLocations($gameID, $sectorID); // make sure cache is populated
76
		$db = Smr\Database::getInstance();
77
		$db->write('INSERT INTO location (game_id, sector_id, location_type_id)
78
						values(' . $db->escapeNumber($gameID) . ',' . $db->escapeNumber($sectorID) . ',' . $db->escapeNumber($location->getTypeID()) . ')');
79
		self::$CACHE_SECTOR_LOCATIONS[$gameID][$sectorID][$location->getTypeID()] = $location;
80
	}
81
82
	public static function moveSectorLocation(int $gameID, int $oldSectorID, int $newSectorID, SmrLocation $location) : void {
83
		if ($oldSectorID === $newSectorID) {
84
			return;
85
		}
86
87
		// Make sure cache is populated
88
		self::getSectorLocations($gameID, $oldSectorID);
89
		self::getSectorLocations($gameID, $newSectorID);
90
91
		$db = Smr\Database::getInstance();
92
		$db->write('UPDATE location SET sector_id = ' . $db->escapeNumber($newSectorID) . ' WHERE game_id = ' . $db->escapeNumber($gameID) . ' AND sector_id = ' . $db->escapeNumber($oldSectorID) . ' AND location_type_id = ' . $location->getTypeID());
93
		unset(self::$CACHE_SECTOR_LOCATIONS[$gameID][$oldSectorID][$location->getTypeID()]);
94
		self::$CACHE_SECTOR_LOCATIONS[$gameID][$newSectorID][$location->getTypeID()] = $location;
95
96
		// Preserve the same element order that we'd have in getSectorLocations
97
		ksort(self::$CACHE_SECTOR_LOCATIONS[$gameID][$newSectorID]);
98
	}
99
100
	public static function removeSectorLocations(int $gameID, int $sectorID) : void {
101
		$db = Smr\Database::getInstance();
102
		$db->write('DELETE FROM location WHERE game_id = ' . $db->escapeNumber($gameID) . ' AND sector_id = ' . $db->escapeNumber($sectorID));
103
		self::$CACHE_SECTOR_LOCATIONS[$gameID][$sectorID] = [];
104
	}
105
106
	public static function getLocation(int $locationTypeID, bool $forceUpdate = false, Smr\DatabaseRecord $dbRecord = null) : SmrLocation {
107
		if ($forceUpdate || !isset(self::$CACHE_LOCATIONS[$locationTypeID])) {
108
			self::$CACHE_LOCATIONS[$locationTypeID] = new SmrLocation($locationTypeID, $dbRecord);
109
		}
110
		return self::$CACHE_LOCATIONS[$locationTypeID];
111
	}
112
113
	protected function __construct(int $locationTypeID, Smr\DatabaseRecord $dbRecord = null) {
114
		$this->db = Smr\Database::getInstance();
115
		$this->SQL = 'location_type_id = ' . $this->db->escapeNumber($locationTypeID);
116
117
		if ($dbRecord === null) {
118
			$dbResult = $this->db->read('SELECT * FROM location_type WHERE ' . $this->SQL . ' LIMIT 1');
119
			if ($dbResult->hasRecord()) {
120
				$dbRecord = $dbResult->record();
121
			}
122
		}
123
		$locationExists = $dbRecord !== null;
124
125
		if ($locationExists) {
126
			$this->typeID = $dbRecord->getInt('location_type_id');
127
			$this->name = $dbRecord->getField('location_name');
128
			$this->processor = $dbRecord->getField('location_processor');
129
			$this->image = $dbRecord->getField('location_image');
130
		} else {
131
			throw new Exception('Cannot find location: ' . $locationTypeID);
132
		}
133
	}
134
135
	public function getTypeID() : int {
136
		return $this->typeID;
137
	}
138
139
	public function getRaceID() : int {
140
		if ($this->isFed() && $this->getTypeID() != LOCATION_TYPE_FEDERAL_BEACON) {
141
			return $this->getTypeID() - LOCATION_GROUP_RACIAL_BEACONS;
142
		}
143
		if ($this->isHQ() && $this->getTypeID() != LOCATION_TYPE_FEDERAL_HQ) {
144
			return $this->getTypeID() - LOCATION_GROUP_RACIAL_HQS;
145
		}
146
		return RACE_NEUTRAL;
147
	}
148
149
	public function getName() : string {
150
		return $this->name;
151
	}
152
153
	public function setName(string $name) : void {
154
		$name = htmlentities($name, ENT_COMPAT, 'utf-8');
155
		if ($this->name === $name) {
156
			return;
157
		}
158
		$this->name = $name;
159
		$this->db->write('UPDATE location_type SET location_name=' . $this->db->escapeString($this->name) . ' WHERE ' . $this->SQL . ' LIMIT 1');
160
	}
161
162
	public function hasAction() : bool {
163
		return $this->processor !== null;
164
	}
165
166
	public function getAction() : ?string {
167
		return $this->processor;
168
	}
169
170
	public function getImage() : string {
171
		return $this->image;
172
	}
173
174
	public function isFed() : bool {
175
		if (!isset($this->fed)) {
176
			$dbResult = $this->db->read('SELECT 1 FROM location_is_fed WHERE ' . $this->SQL . ' LIMIT 1');
177
			$this->fed = $dbResult->hasRecord();
178
		}
179
		return $this->fed;
180
	}
181
182
	public function setFed(bool $bool) : void {
183
		if ($this->fed === $bool) {
184
			return;
185
		}
186
		if ($bool) {
187
			$this->db->write('INSERT IGNORE INTO location_is_fed (location_type_id) values (' . $this->db->escapeNumber($this->getTypeID()) . ')');
188
		} else {
189
			$this->db->write('DELETE FROM location_is_fed WHERE ' . $this->SQL . ' LIMIT 1');
190
		}
191
		$this->fed = $bool;
192
	}
193
194
	public function isBank() : bool {
195
		if (!isset($this->bank)) {
196
			$dbResult = $this->db->read('SELECT 1 FROM location_is_bank WHERE ' . $this->SQL . ' LIMIT 1');
197
			$this->bank = $dbResult->hasRecord();
198
		}
199
		return $this->bank;
200
	}
201
202
	public function setBank(bool $bool) : void {
203
		if ($this->bank === $bool) {
204
			return;
205
		}
206
		if ($bool) {
207
			$this->db->write('INSERT INTO location_is_bank (location_type_id) values (' . $this->db->escapeNumber($this->getTypeID()) . ')');
208
		} else {
209
			$this->db->write('DELETE FROM location_is_bank WHERE ' . $this->SQL . ' LIMIT 1');
210
		}
211
		$this->bank = $bool;
212
	}
213
214
	public function isBar() : bool {
215
		if (!isset($this->bar)) {
216
			$dbResult = $this->db->read('SELECT 1 FROM location_is_bar WHERE ' . $this->SQL . ' LIMIT 1');
217
			$this->bar = $dbResult->hasRecord();
218
		}
219
		return $this->bar;
220
	}
221
222
	public function setBar(bool $bool) : void {
223
		if ($this->bar === $bool) {
224
			return;
225
		}
226
		if ($bool) {
227
			$this->db->write('INSERT IGNORE INTO location_is_bar (location_type_id) values (' . $this->db->escapeNumber($this->getTypeID()) . ')');
228
		} else {
229
			$this->db->write('DELETE FROM location_is_bar WHERE ' . $this->SQL . ' LIMIT 1');
230
		}
231
		$this->bar = $bool;
232
	}
233
234
	public function isHQ() : bool {
235
		if (!isset($this->HQ)) {
236
			$dbResult = $this->db->read('SELECT * FROM location_is_hq WHERE ' . $this->SQL . ' LIMIT 1');
237
			$this->HQ = $dbResult->hasRecord();
238
		}
239
		return $this->HQ;
240
	}
241
242
	public function setHQ(bool $bool) : void {
243
		if ($this->HQ === $bool) {
244
			return;
245
		}
246
		if ($bool) {
247
			$this->db->write('INSERT IGNORE INTO location_is_hq (location_type_id) values (' . $this->db->escapeNumber($this->getTypeID()) . ')');
248
		} else {
249
			$this->db->write('DELETE FROM location_is_hq WHERE ' . $this->SQL . ' LIMIT 1');
250
		}
251
		$this->HQ = $bool;
252
	}
253
254
	public function isUG() : bool {
255
		if (!isset($this->UG)) {
256
			$dbResult = $this->db->read('SELECT * FROM location_is_ug WHERE ' . $this->SQL . ' LIMIT 1');
257
			$this->UG = $dbResult->hasRecord();
258
		}
259
		return $this->UG;
260
	}
261
262
	public function setUG(bool $bool) : void {
263
		if ($this->UG === $bool) {
264
			return;
265
		}
266
		if ($bool) {
267
			$this->db->write('INSERT INTO location_is_ug (location_type_id) values (' . $this->db->escapeNumber($this->getTypeID()) . ')');
268
		} else {
269
			$this->db->write('DELETE FROM location_is_ug WHERE ' . $this->SQL . ' LIMIT 1');
270
		}
271
		$this->UG = $bool;
272
	}
273
274
	public function getHardwareSold() : array {
275
		if (!isset($this->hardwareSold)) {
276
			$this->hardwareSold = array();
277
			$dbResult = $this->db->read('SELECT hardware_type_id FROM location_sells_hardware WHERE ' . $this->SQL);
278
			foreach ($dbResult->records() as $dbRecord) {
279
				$this->hardwareSold[$dbRecord->getInt('hardware_type_id')] = Globals::getHardwareTypes($dbRecord->getInt('hardware_type_id'));
280
			}
281
		}
282
		return $this->hardwareSold;
283
	}
284
285
	public function isHardwareSold(int $hardwareTypeID = null) : bool {
286
		$hardware = $this->getHardwareSold();
287
		if ($hardwareTypeID === null) {
288
			return count($hardware) != 0;
289
		}
290
		return isset($hardware[$hardwareTypeID]);
291
	}
292
293
	public function addHardwareSold(int $hardwareTypeID) : void {
294
		if ($this->isHardwareSold($hardwareTypeID)) {
295
			return;
296
		}
297
		$dbResult = $this->db->read('SELECT 1 FROM hardware_type WHERE hardware_type_id = ' . $this->db->escapeNumber($hardwareTypeID) . ' LIMIT 1');
298
		if (!$dbResult->hasRecord()) {
299
			throw new Exception('Invalid hardware type id given');
300
		}
301
		$this->db->write('INSERT INTO location_sells_hardware (location_type_id,hardware_type_id) values (' . $this->db->escapeNumber($this->getTypeID()) . ',' . $this->db->escapeNumber($hardwareTypeID) . ')');
302
		$this->hardwareSold[$hardwareTypeID] = Globals::getHardwareTypes($hardwareTypeID);
303
	}
304
305
	public function removeHardwareSold(int $hardwareTypeID) : void {
306
		if (!$this->isHardwareSold($hardwareTypeID)) {
307
			return;
308
		}
309
		$this->db->write('DELETE FROM location_sells_hardware WHERE ' . $this->SQL . ' AND hardware_type_id = ' . $this->db->escapeNumber($hardwareTypeID) . ' LIMIT 1');
310
		unset($this->hardwareSold[$hardwareTypeID]);
311
	}
312
313
	public function getShipsSold() : array {
314
		if (!isset($this->shipsSold)) {
315
			$this->shipsSold = array();
316
			$dbResult = $this->db->read('SELECT * FROM location_sells_ships JOIN ship_type USING (ship_type_id) WHERE ' . $this->SQL);
317
			foreach ($dbResult->records() as $dbRecord) {
318
				$shipTypeID = $dbRecord->getInt('ship_type_id');
319
				$this->shipsSold[$shipTypeID] = SmrShipType::get($shipTypeID, $dbRecord);
320
			}
321
		}
322
		return $this->shipsSold;
323
	}
324
325
	public function isShipSold(int $shipTypeID = null) : bool {
326
		$ships = $this->getShipsSold();
327
		if ($shipTypeID === null) {
328
			return count($ships) != 0;
329
		}
330
		return isset($ships[$shipTypeID]);
331
	}
332
333
	public function addShipSold(int $shipTypeID) : void {
334
		if ($this->isShipSold($shipTypeID)) {
335
			return;
336
		}
337
		$ship = SmrShipType::get($shipTypeID);
338
		$this->db->write('INSERT INTO location_sells_ships (location_type_id,ship_type_id) values (' . $this->db->escapeNumber($this->getTypeID()) . ',' . $this->db->escapeNumber($shipTypeID) . ')');
339
		$this->shipsSold[$shipTypeID] = $ship;
340
	}
341
342
	public function removeShipSold(int $shipTypeID) : void {
343
		if (!$this->isShipSold($shipTypeID)) {
344
			return;
345
		}
346
		$this->db->write('DELETE FROM location_sells_ships WHERE ' . $this->SQL . ' AND ship_type_id = ' . $this->db->escapeNumber($shipTypeID) . ' LIMIT 1');
347
		unset($this->shipsSold[$shipTypeID]);
348
	}
349
350
	public function getWeaponsSold() : array {
351
		if (!isset($this->weaponsSold)) {
352
			$this->weaponsSold = array();
353
			$dbResult = $this->db->read('SELECT * FROM location_sells_weapons JOIN weapon_type USING (weapon_type_id) WHERE ' . $this->SQL);
354
			foreach ($dbResult->records() as $dbRecord) {
355
				$weaponTypeID = $dbRecord->getInt('weapon_type_id');
356
				$this->weaponsSold[$weaponTypeID] = SmrWeapon::getWeapon($weaponTypeID, $dbRecord);
357
			}
358
		}
359
		return $this->weaponsSold;
360
	}
361
362
	public function isWeaponSold(int $weaponTypeID = null) : bool {
363
		$weapons = $this->getWeaponsSold();
364
		if ($weaponTypeID === null) {
365
			return count($weapons) != 0;
366
		}
367
		return isset($weapons[$weaponTypeID]);
368
	}
369
370
	public function addWeaponSold(int $weaponTypeID) : void {
371
		if ($this->isWeaponSold($weaponTypeID)) {
372
			return;
373
		}
374
		$weapon = SmrWeapon::getWeapon($weaponTypeID);
375
		$this->db->write('INSERT INTO location_sells_weapons (location_type_id,weapon_type_id) values (' . $this->db->escapeNumber($this->getTypeID()) . ',' . $this->db->escapeNumber($weaponTypeID) . ')');
376
		$this->weaponsSold[$weaponTypeID] = $weapon;
377
	}
378
379
	public function removeWeaponSold(int $weaponTypeID) : void {
380
		if (!$this->isWeaponSold($weaponTypeID)) {
381
			return;
382
		}
383
		$this->db->write('DELETE FROM location_sells_weapons WHERE ' . $this->SQL . ' AND weapon_type_id = ' . $this->db->escapeNumber($weaponTypeID) . ' LIMIT 1');
384
		unset($this->weaponsSold[$weaponTypeID]);
385
	}
386
387
	public function getLinkedLocations() : array {
388
		$linkedLocations = array();
389
		if ($this->isHQ()) {
390
			if ($this->getTypeID() == LOCATION_TYPE_FEDERAL_HQ) {
391
				$linkedLocations[] = SmrLocation::getLocation(LOCATION_TYPE_FEDERAL_BEACON);
392
				$linkedLocations[] = SmrLocation::getLocation(LOCATION_TYPE_FEDERAL_MINT);
393
			} else {
394
				$raceID = $this->getRaceID();
395
				$linkedLocations[] = SmrLocation::getLocation(LOCATION_GROUP_RACIAL_BEACONS + $raceID);
396
				$linkedLocations[] = SmrLocation::getLocation(LOCATION_GROUP_RACIAL_SHIPS + $raceID);
397
				$linkedLocations[] = SmrLocation::getLocation(LOCATION_GROUP_RACIAL_SHOPS + $raceID);
398
			}
399
		}
400
		return $linkedLocations;
401
	}
402
403
	public function getExamineHREF() : string {
404
		$container = Page::create('skeleton.php', $this->getAction());
0 ignored issues
show
Bug introduced by
It seems like $this->getAction() can also be of type null; however, parameter $body of Page::create() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

404
		$container = Page::create('skeleton.php', /** @scrutinizer ignore-type */ $this->getAction());
Loading history...
405
		$container['LocationID'] = $this->getTypeID();
406
		return $container->href();
407
	}
408
409
	public function getEditHREF() : string {
410
		$container = Page::create('skeleton.php', 'location_edit.php');
411
		$container['location_type_id'] = $this->getTypeID();
412
		return $container->href();
413
	}
414
415
	public function equals(SmrLocation $otherLocation) : bool {
416
		return $this->getTypeID() == $otherLocation->getTypeID();
417
	}
418
419
	public function hasX(mixed $x, AbstractSmrPlayer $player = null) : bool {
420
		if ($x instanceof SmrWeaponType) {
421
			return $this->isWeaponSold($x->getWeaponTypeID());
422
		}
423
		if ($x instanceof SmrShipType) {
424
			return $this->isShipSold($x->getTypeID());
425
		}
426
		if (is_array($x) && $x['Type'] == 'Hardware') { // instanceof ShipEquipment)
427
			return $this->isHardwareSold($x['ID']);
428
		}
429
		if (is_string($x)) {
430
			if ($x == 'Bank') {
431
				return $this->isBank();
432
			}
433
			if ($x == 'Bar') {
434
				return $this->isBar();
435
			}
436
			if ($x == 'Fed') {
437
				return $this->isFed();
438
			}
439
			if ($x == 'SafeFed') {
440
				return $player != null && $this->isFed() && $player->canBeProtectedByRace($this->getRaceID());
441
			}
442
			if ($x == 'HQ') {
443
				return $this->isHQ();
444
			}
445
			if ($x == 'UG') {
446
				return $this->isUG();
447
			}
448
			if ($x == 'Hardware') {
449
				return $this->isHardwareSold();
450
			}
451
			if ($x == 'Ship') {
452
				return $this->isShipSold();
453
			}
454
			if ($x == 'Weapon') {
455
				return $this->isWeaponSold();
456
			}
457
		}
458
		return false;
459
	}
460
}
461