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 — main (#1473)
by Dan
04:50
created

Page::getCommonID()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
/**
4
 * A container that holds data needed to create a new page.
5
 *
6
 * This class acts like an array, whose keys define the page properties.
7
 * Then we can either create an HREF so that it can be accessed by a future
8
 * http request (via the Smr\Session), or forwarded to within the same request.
9
 *
10
 * @extends ArrayObject<string, mixed>
11
 */
12
class Page extends ArrayObject {
13
14
	private const ALWAYS_AVAILABLE = true;
15
16
	// Defines if the page is is always available, or if it is invalid after one
17
	// use (i.e. if you get a back button error when navigating back to it).
18
	public const ALWAYS_AVAILABLE_PAGES = [
19
			'album_edit.php' => self::ALWAYS_AVAILABLE,
20
			'alliance_broadcast.php' => self::ALWAYS_AVAILABLE,
21
			'alliance_forces.php' => self::ALWAYS_AVAILABLE,
22
			'alliance_list.php' => self::ALWAYS_AVAILABLE,
23
			'alliance_message_view.php' => self::ALWAYS_AVAILABLE,
24
			'alliance_message.php' => self::ALWAYS_AVAILABLE,
25
			'alliance_mod.php' => self::ALWAYS_AVAILABLE,
26
			'alliance_option.php' => self::ALWAYS_AVAILABLE,
27
			'alliance_pick.php' => self::ALWAYS_AVAILABLE,
28
			'alliance_remove_member.php' => self::ALWAYS_AVAILABLE,
29
			'alliance_roster.php' => self::ALWAYS_AVAILABLE,
30
			'beta_functions.php' => self::ALWAYS_AVAILABLE,
31
			'bug_report.php' => self::ALWAYS_AVAILABLE,
32
			'cargo_dump.php' => self::ALWAYS_AVAILABLE,
33
			'course_plot.php' => self::ALWAYS_AVAILABLE,
34
			'changelog_view.php' => self::ALWAYS_AVAILABLE,
35
			'chat_rules.php' => self::ALWAYS_AVAILABLE,
36
			'chess.php' => self::ALWAYS_AVAILABLE,
37
			'combat_log_list.php' => self::ALWAYS_AVAILABLE,
38
			'combat_log_viewer.php' => self::ALWAYS_AVAILABLE,
39
			'current_sector.php' => self::ALWAYS_AVAILABLE,
40
			'configure_hardware.php' => self::ALWAYS_AVAILABLE,
41
			'contact.php' => self::ALWAYS_AVAILABLE,
42
			'council_embassy.php' => self::ALWAYS_AVAILABLE,
43
			'council_list.php' => self::ALWAYS_AVAILABLE,
44
			'council_politics.php' => self::ALWAYS_AVAILABLE,
45
			'council_send_message.php' => self::ALWAYS_AVAILABLE,
46
			'council_vote.php' => self::ALWAYS_AVAILABLE,
47
			'current_players.php' => self::ALWAYS_AVAILABLE,
48
			'donation.php' => self::ALWAYS_AVAILABLE,
49
			'feature_request_comments.php' => self::ALWAYS_AVAILABLE,
50
			'feature_request.php' => self::ALWAYS_AVAILABLE,
51
			'forces_list.php' => self::ALWAYS_AVAILABLE,
52
			'forces_mass_refresh.php' => self::ALWAYS_AVAILABLE,
53
			'galactic_post_current.php' => self::ALWAYS_AVAILABLE,
54
			'hall_of_fame_new.php' => self::ALWAYS_AVAILABLE,
55
			'hall_of_fame_player_detail.php' => self::ALWAYS_AVAILABLE,
56
			'leave_newbie.php' => self::ALWAYS_AVAILABLE,
57
			'logoff.php' => self::ALWAYS_AVAILABLE,
58
			'map_local.php' => self::ALWAYS_AVAILABLE,
59
			'message_box.php' => self::ALWAYS_AVAILABLE,
60
			'message_view.php' => self::ALWAYS_AVAILABLE,
61
			'message_send.php' => self::ALWAYS_AVAILABLE,
62
			'news_read_advanced.php' => self::ALWAYS_AVAILABLE,
63
			'news_read_current.php' => self::ALWAYS_AVAILABLE,
64
			'news_read.php' => self::ALWAYS_AVAILABLE,
65
			'planet_construction.php' => self::ALWAYS_AVAILABLE,
66
			'planet_defense.php' => self::ALWAYS_AVAILABLE,
67
			'planet_financial.php' => self::ALWAYS_AVAILABLE,
68
			'planet_main.php' => self::ALWAYS_AVAILABLE,
69
			'planet_ownership.php' => self::ALWAYS_AVAILABLE,
70
			'planet_stockpile.php' => self::ALWAYS_AVAILABLE,
71
			'planet_list.php' => self::ALWAYS_AVAILABLE,
72
			'planet_list_financial.php' => self::ALWAYS_AVAILABLE,
73
			'preferences.php' => self::ALWAYS_AVAILABLE,
74
			'rankings_alliance_death.php' => self::ALWAYS_AVAILABLE,
75
			'rankings_alliance_experience.php' => self::ALWAYS_AVAILABLE,
76
			'rankings_alliance_kills.php' => self::ALWAYS_AVAILABLE,
77
			'rankings_alliance_vs_alliance.php' => self::ALWAYS_AVAILABLE,
78
			'rankings_player_death.php' => self::ALWAYS_AVAILABLE,
79
			'rankings_player_experience.php' => self::ALWAYS_AVAILABLE,
80
			'rankings_player_kills.php' => self::ALWAYS_AVAILABLE,
81
			'rankings_player_profit.php' => self::ALWAYS_AVAILABLE,
82
			'rankings_race_death.php' => self::ALWAYS_AVAILABLE,
83
			'rankings_race_kills.php' => self::ALWAYS_AVAILABLE,
84
			'rankings_race.php' => self::ALWAYS_AVAILABLE,
85
			'rankings_sector_kill.php' => self::ALWAYS_AVAILABLE,
86
			'rankings_view.php' => self::ALWAYS_AVAILABLE,
87
			'smr_file_create.php' => self::ALWAYS_AVAILABLE,
88
			'trader_bounties.php' => self::ALWAYS_AVAILABLE,
89
			'trader_relations.php' => self::ALWAYS_AVAILABLE,
90
			'trader_savings.php' => self::ALWAYS_AVAILABLE,
91
			'trader_search_result.php' => self::ALWAYS_AVAILABLE,
92
			'trader_search.php' => self::ALWAYS_AVAILABLE,
93
			'trader_status.php' => self::ALWAYS_AVAILABLE,
94
			'weapon_reorder.php' => self::ALWAYS_AVAILABLE,
95
			//Processing pages
96
			'alliance_message_add_processing.php' => self::ALWAYS_AVAILABLE,
97
			'alliance_message_delete_processing.php' => self::ALWAYS_AVAILABLE,
98
			'alliance_pick_processing.php' => self::ALWAYS_AVAILABLE,
99
			'game_leave_processing.php' => self::ALWAYS_AVAILABLE,
100
			'toggle_processing.php' => self::ALWAYS_AVAILABLE,
101
			//Admin pages
102
			'admin/account_edit.php' => self::ALWAYS_AVAILABLE,
103
			'admin/album_moderate.php' => self::ALWAYS_AVAILABLE,
104
			'admin/box_view.php' => self::ALWAYS_AVAILABLE,
105
			'admin/changelog.php' => self::ALWAYS_AVAILABLE,
106
			'admin/comp_share.php' => self::ALWAYS_AVAILABLE,
107
			'admin/form_open.php' => self::ALWAYS_AVAILABLE,
108
			'admin/ip_view_results.php' => self::ALWAYS_AVAILABLE,
109
			'admin/ip_view.php' => self::ALWAYS_AVAILABLE,
110
			'admin/permission_manage.php' => self::ALWAYS_AVAILABLE,
111
			'admin/word_filter.php' => self::ALWAYS_AVAILABLE,
112
			//Uni gen
113
			'admin/unigen/check_map.php' => self::ALWAYS_AVAILABLE,
114
			'admin/unigen/universe_create_locations.php' => self::ALWAYS_AVAILABLE,
115
			'admin/unigen/universe_create_planets.php' => self::ALWAYS_AVAILABLE,
116
			'admin/unigen/universe_create_ports.php' => self::ALWAYS_AVAILABLE,
117
			'admin/unigen/universe_create_sector_details.php' => self::ALWAYS_AVAILABLE,
118
			'admin/unigen/universe_create_sectors.php' => self::ALWAYS_AVAILABLE,
119
			'admin/unigen/universe_create_warps.php' => self::ALWAYS_AVAILABLE,
120
		];
121
122
	public readonly bool $reusable;
123
124
	/**
125
	 * @param array<string, mixed> $data
126
	 */
127
	protected function __construct(
128
		public readonly string $file,
129
		array $data,
130
		public readonly bool $skipRedirect // to skip redirect hooks at beginning of page processing
131
	) {
132
		parent::__construct($data);
133
134
		// Pages are single-use unless explicitly whitelisted
135
		$this->reusable = self::ALWAYS_AVAILABLE_PAGES[$file] ?? false;
0 ignored issues
show
Bug introduced by
The property reusable is declared read-only in Page.
Loading history...
136
	}
137
138
	/**
139
	 * Create a new Page object.
140
	 * This is the standard method to package linked pages and the data to
141
	 * accompany them.
142
	 *
143
	 * @param self|array<string, mixed> $data
144
	 */
145
	public static function create(string $file, self|array $data = [], bool $skipRedirect = false): self {
146
		if ($data instanceof self) {
0 ignored issues
show
introduced by
$data is never a sub-type of self.
Loading history...
147
			// Extract the data from the input Page
148
			$data = $data->getArrayCopy();
149
		}
150
		return new self($file, $data, $skipRedirect);
151
	}
152
153
	/**
154
	 * Create a copy of a Page object.
155
	 * This may be useful for reusing a Page object without modifying the
156
	 * original.
157
	 */
158
	public static function copy(Page $other): self {
159
		return clone $other;
160
	}
161
162
	/**
163
	 * Forward to the page identified by this container.
164
	 */
165
	public function go(): never {
166
		if (defined('OVERRIDE_FORWARD') && OVERRIDE_FORWARD === true) {
167
			overrideForward($this);
168
		}
169
		Smr\Session::getInstance()->setCurrentVar($this);
170
		do_voodoo();
171
	}
172
173
	/**
174
	 * Transfer $var[$source] into this container with new name $dest.
175
	 * If $dest is not specified, keep the index named $source.
176
	 */
177
	public function addVar(string $source, string $dest = null): void {
178
		$var = Smr\Session::getInstance()->getCurrentVar();
179
180
		// transfer this value to next container
181
		if (!isset($var[$source])) {
182
			throw new Exception('Could not find "' . $source . '" in var!');
183
		}
184
		if ($dest === null) {
185
			$dest = $source;
186
		}
187
		$this[$dest] = $var[$source];
188
	}
189
190
	/**
191
	 * Create an HREF (based on a random SN) to link to this page.
192
	 * The container is saved in the Smr\Session under this SN so that on
193
	 * the next request, we can grab the container out of the Smr\Session.
194
	 */
195
	public function href(bool $forceFullURL = false): string {
196
		// We need to clone this instance in case it is modified after being added
197
		// to the session links. This would not be necessary if Page was readonly.
198
		$sn = Smr\Session::getInstance()->addLink(self::copy($this));
199
200
		$href = '?sn=' . $sn;
201
		if ($forceFullURL === true || $_SERVER['SCRIPT_NAME'] !== LOADER_URI) {
202
			return LOADER_URI . $href;
203
		}
204
		return $href;
205
	}
206
207
	/**
208
	 * Process this page by executing the associated file.
209
	 */
210
	public function process(): void {
211
		require(get_file_loc($this->file));
212
	}
213
214
}
215