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

UploadSmrFileProcessor::build()   F
last analyzed

Complexity

Conditions 24
Paths 7810

Size

Total Lines 123
Code Lines 66

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 24
eloc 66
nc 7810
nop 1
dl 0
loc 123
rs 0
c 2
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types=1);
2
3
namespace Smr\Pages\Admin\UniGen;
4
5
use Exception;
6
use Smr\Page\AccountPageProcessor;
7
use Smr\TransactionType;
8
use SmrAccount;
9
use SmrGalaxy;
10
use SmrLocation;
11
use SmrPort;
12
use SmrSector;
13
14
class UploadSmrFileProcessor extends AccountPageProcessor {
15
16
	public function __construct(
17
		private readonly int $gameID
18
	) {}
19
20
	public function build(SmrAccount $account): never {
21
		if ($_FILES['smr_file']['error'] !== UPLOAD_ERR_OK) {
22
			create_error('Failed to upload SMR file!');
23
		}
24
25
		$ini_str = file_get_contents($_FILES['smr_file']['tmp_name']);
26
		if ($ini_str === false) {
27
			throw new Exception('Failed to read temporary file');
28
		}
29
30
		// We only care about the sections after [Metadata], and the earlier
31
		// sections have invalid INI key characters (e.g. Creonti "Big Daddy", Salvene
32
		// Supply & Plunder). For this reason, we simply remove the offending sections
33
		// instead of trying to encode all the special characters: ?{}|&~![()^"
34
		//
35
		// NOTE: these special characters are allowed in the ini-values, but only if
36
		// we use the "raw" scanner. We need this because of the "Location=" values.
37
		$ini_substr = strstr($ini_str, '[Metadata]');
38
		if ($ini_substr === false) {
39
			create_error('Could not find [Metadata] section in SMR file');
40
		}
41
		$data = parse_ini_string($ini_substr, true, INI_SCANNER_RAW);
42
		if ($data === false) {
43
			create_error('Failed to parse SMR file. Please check the file for errors.');
44
		}
45
46
		$version = $data['Metadata']['FileVersion'];
47
		if ($version !== SMR_FILE_VERSION) {
48
			create_error('Uploaded v' . $version . ' is incompatible with server expecting v' . SMR_FILE_VERSION);
49
		}
50
51
		// Create the galaxies
52
		foreach ($data['Galaxies'] as $galID => $details) {
53
			[$width, $height, $type, $name, $maxForceTime] = explode(',', $details);
54
			$galaxy = SmrGalaxy::createGalaxy($this->gameID, $galID);
55
			$galaxy->setWidth(str2int($width));
0 ignored issues
show
Bug introduced by
The function str2int was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

55
			$galaxy->setWidth(/** @scrutinizer ignore-call */ str2int($width));
Loading history...
56
			$galaxy->setHeight(str2int($height));
57
			$galaxy->setGalaxyType($type);
58
			$galaxy->setName($name);
59
			$galaxy->setMaxForceTime(str2int($maxForceTime));
60
		}
61
		// Workaround for SmrGalaxy::getStartSector depending on all other galaxies
62
		SmrGalaxy::saveGalaxies();
63
		foreach (SmrGalaxy::getGameGalaxies($this->gameID, true) as $galaxy) {
64
			$galaxy->generateSectors();
65
		}
66
67
		// Populate the sectors
68
		foreach ($data as $key => $vals) {
69
			if (!preg_match('/^Sector=(\d+)$/', $key, $matches)) {
70
				continue;
71
			}
72
73
			$sectorID = str2int($matches[1]);
74
			$editSector = SmrSector::getSector($this->gameID, $sectorID);
75
76
			// Sector connections (we assume link sectors are correct)
77
			foreach (['Up', 'Down', 'Left', 'Right'] as $dir) {
78
				if (isset($vals[$dir])) {
79
					$editSector->enableLink($dir);
80
				} else {
81
					$editSector->disableLink($dir);
82
				}
83
			}
84
85
			// Ports
86
			if (isset($vals['Port Level'])) {
87
				$port = $editSector->createPort();
88
				$port->setRaceID(str2int($vals['Port Race']));
89
				$port->setLevel(str2int($vals['Port Level']));
90
				$port->setCreditsToDefault();
91
				// SMR file indicates the port action Buys/Sells,
92
				// but SmrPort::addPortGood uses the player action.
93
				if (isset($vals['Buys'])) {
94
					foreach (explode(',', $vals['Buys']) as $goodID) {
95
						$port->addPortGood(str2int($goodID), TransactionType::Sell);
96
					}
97
				}
98
				if (isset($vals['Sells'])) {
99
					foreach (explode(',', $vals['Sells']) as $goodID) {
100
						$port->addPortGood(str2int($goodID), TransactionType::Buy);
101
					}
102
				}
103
			}
104
105
			// Locations
106
			$allLocs = SmrLocation::getAllLocations($this->gameID);
107
			if (isset($vals['Locations'])) {
108
				$locNames = explode(',', $vals['Locations']);
109
				foreach ($locNames as $locName) {
110
					// Since we only know the location name, we must search for it
111
					$found = false;
112
					foreach ($allLocs as $loc) {
113
						if ($locName == inify($loc->getName())) {
114
							$editSector->addLocation($loc);
115
							$found = true;
116
							break;
117
						}
118
					}
119
					if (!$found) {
120
						create_error('Could not find location named: ' . $locName);
121
					}
122
				}
123
			}
124
125
			// Warps
126
			if (isset($vals['Warp'])) {
127
				$editSector->setWarp(SmrSector::getSector($this->gameID, str2int($vals['Warp'])));
128
			}
129
130
			// Planets
131
			if (isset($vals['Planet'])) {
132
				$editSector->createPlanet(str2int($vals['Planet']));
133
			}
134
		}
135
136
		// Save so that sector links and ports persist
137
		// (otherwise they are overwritten somewhere while forwarding)
138
		SmrSector::saveSectors();
139
		SmrPort::savePorts();
140
141
		$container = new EditGalaxy($this->gameID);
142
		$container->go();
143
	}
144
145
}
146