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

Passed
Push — master ( a0da36...64adfe )
by Dan
04:27
created

Page::process()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 4
nop 0
dl 0
loc 7
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 SmrSession), or forwarded to within the same request.
9
 */
10
class Page extends ArrayObject {
11
12
	private const ALWAYS_AVAILABLE = 999999;
13
14
	// Defines the number of pages that can be loaded after
15
	// this page before the links on this page become invalid
16
	// (i.e. before you get a back button error).
17
	private const URL_DEFAULT_REMAINING_PAGE_LOADS = array(
18
			'alliance_broadcast.php' => self::ALWAYS_AVAILABLE,
19
			'alliance_forces.php' => self::ALWAYS_AVAILABLE,
20
			'alliance_list.php' => self::ALWAYS_AVAILABLE,
21
			'alliance_message_view.php' => self::ALWAYS_AVAILABLE,
22
			'alliance_message.php' => self::ALWAYS_AVAILABLE,
23
			'alliance_mod.php' => self::ALWAYS_AVAILABLE,
24
			'alliance_option.php' => self::ALWAYS_AVAILABLE,
25
			'alliance_pick.php' => self::ALWAYS_AVAILABLE,
26
			'alliance_remove_member.php' => self::ALWAYS_AVAILABLE,
27
			'alliance_roster.php' => self::ALWAYS_AVAILABLE,
28
			'beta_functions.php' => self::ALWAYS_AVAILABLE,
29
			'bug_report.php' => self::ALWAYS_AVAILABLE,
30
			'cargo_dump.php' => self::ALWAYS_AVAILABLE,
31
			'course_plot.php' => self::ALWAYS_AVAILABLE,
32
			'changelog_view.php' => self::ALWAYS_AVAILABLE,
33
			'chat_rules.php' => self::ALWAYS_AVAILABLE,
34
			'chess_play.php' => self::ALWAYS_AVAILABLE,
35
			'combat_log_list.php' => self::ALWAYS_AVAILABLE,
36
			'combat_log_viewer.php' => self::ALWAYS_AVAILABLE,
37
			'current_sector.php' => self::ALWAYS_AVAILABLE,
38
			'configure_hardware.php' => self::ALWAYS_AVAILABLE,
39
			'contact.php' => self::ALWAYS_AVAILABLE,
40
			'council_embassy.php' => self::ALWAYS_AVAILABLE,
41
			'council_list.php' => self::ALWAYS_AVAILABLE,
42
			'council_politics.php' => self::ALWAYS_AVAILABLE,
43
			'council_send_message.php' => self::ALWAYS_AVAILABLE,
44
			'council_vote.php' => self::ALWAYS_AVAILABLE,
45
			'current_players.php' => self::ALWAYS_AVAILABLE,
46
			'donation.php' => self::ALWAYS_AVAILABLE,
47
			'feature_request_comments.php' => self::ALWAYS_AVAILABLE,
48
			'feature_request.php' => self::ALWAYS_AVAILABLE,
49
			'forces_list.php' => self::ALWAYS_AVAILABLE,
50
			'forces_mass_refresh.php' => self::ALWAYS_AVAILABLE,
51
			'hall_of_fame_player_new.php' => self::ALWAYS_AVAILABLE,
52
			'hall_of_fame_player_detail.php' => self::ALWAYS_AVAILABLE,
53
			'leave_newbie.php' => self::ALWAYS_AVAILABLE,
54
			'logoff.php' => self::ALWAYS_AVAILABLE,
55
			'map_local.php' => self::ALWAYS_AVAILABLE,
56
			'message_view.php' => self::ALWAYS_AVAILABLE,
57
			'message_send.php' => self::ALWAYS_AVAILABLE,
58
			'news_read_advanced.php' => self::ALWAYS_AVAILABLE,
59
			'news_read_current.php' => self::ALWAYS_AVAILABLE,
60
			'news_read.php' => self::ALWAYS_AVAILABLE,
61
			'planet_construction.php' => self::ALWAYS_AVAILABLE,
62
			'planet_defense.php' => self::ALWAYS_AVAILABLE,
63
			'planet_financial.php' => self::ALWAYS_AVAILABLE,
64
			'planet_main.php' => self::ALWAYS_AVAILABLE,
65
			'planet_ownership.php' => self::ALWAYS_AVAILABLE,
66
			'planet_stockpile.php' => self::ALWAYS_AVAILABLE,
67
			'planet_list.php' => self::ALWAYS_AVAILABLE,
68
			'planet_list_financial.php' => self::ALWAYS_AVAILABLE,
69
			'preferences.php' => self::ALWAYS_AVAILABLE,
70
			'rankings_alliance_death.php' => self::ALWAYS_AVAILABLE,
71
			'rankings_alliance_experience.php' => self::ALWAYS_AVAILABLE,
72
			'rankings_alliance_kills.php' => self::ALWAYS_AVAILABLE,
73
			'rankings_alliance_vs_alliance.php' => self::ALWAYS_AVAILABLE,
74
			'rankings_player_death.php' => self::ALWAYS_AVAILABLE,
75
			'rankings_player_experience.php' => self::ALWAYS_AVAILABLE,
76
			'rankings_player_kills.php' => self::ALWAYS_AVAILABLE,
77
			'rankings_player_profit.php' => self::ALWAYS_AVAILABLE,
78
			'rankings_race_death.php' => self::ALWAYS_AVAILABLE,
79
			'rankings_race_kills.php' => self::ALWAYS_AVAILABLE,
80
			'rankings_race.php' => self::ALWAYS_AVAILABLE,
81
			'rankings_sector_kill.php' => self::ALWAYS_AVAILABLE,
82
			'rankings_view.php' => self::ALWAYS_AVAILABLE,
83
			'trader_bounties.php' => self::ALWAYS_AVAILABLE,
84
			'trader_relations.php' => self::ALWAYS_AVAILABLE,
85
			'trader_savings.php' => self::ALWAYS_AVAILABLE,
86
			'trader_search_result.php' => self::ALWAYS_AVAILABLE,
87
			'trader_search.php' => self::ALWAYS_AVAILABLE,
88
			'trader_status.php' => self::ALWAYS_AVAILABLE,
89
			'weapon_reorder.php' => self::ALWAYS_AVAILABLE,
90
			//Processing pages
91
			'alliance_message_add_processing.php' => self::ALWAYS_AVAILABLE,
92
			'alliance_message_delete_processing.php' => self::ALWAYS_AVAILABLE,
93
			'alliance_pick_processing.php' => self::ALWAYS_AVAILABLE,
94
			'chess_move_processing.php' => self::ALWAYS_AVAILABLE,
95
			'toggle_processing.php' => self::ALWAYS_AVAILABLE,
96
			//Admin pages
97
			'account_edit.php' => self::ALWAYS_AVAILABLE,
98
			'album_moderate.php' => self::ALWAYS_AVAILABLE,
99
			'box_view.php' => self::ALWAYS_AVAILABLE,
100
			'changelog.php' => self::ALWAYS_AVAILABLE,
101
			'comp_share.php' => self::ALWAYS_AVAILABLE,
102
			'form_open.php' => self::ALWAYS_AVAILABLE,
103
			'ip_view_results.php' => self::ALWAYS_AVAILABLE,
104
			'ip_view.php' => self::ALWAYS_AVAILABLE,
105
			'permission_manage.php' => self::ALWAYS_AVAILABLE,
106
			'word_filter.php' => self::ALWAYS_AVAILABLE,
107
			//Uni gen
108
			'1.6/check_map.php' => self::ALWAYS_AVAILABLE,
109
			'1.6/universe_create_locations.php' => self::ALWAYS_AVAILABLE,
110
			'1.6/universe_create_planets.php' => self::ALWAYS_AVAILABLE,
111
			'1.6/universe_create_ports.php' => self::ALWAYS_AVAILABLE,
112
			'1.6/universe_create_sector_details.php' => self::ALWAYS_AVAILABLE,
113
			'1.6/universe_create_sectors.php' => self::ALWAYS_AVAILABLE,
114
			'1.6/universe_create_warps.php' => self::ALWAYS_AVAILABLE,
115
		);
116
117
	/**
118
	 * Create a new Page object.
119
	 * This is the standard method to package linked pages and the data to
120
	 * accompany them.
121
	 */
122
	public static function create($file, $body = '', Page|array $extra = [], $remainingPageLoads = null) : self {
123
		if ($extra instanceof Page) {
0 ignored issues
show
introduced by
$extra is never a sub-type of Page.
Loading history...
124
			// to avoid making $container a reference to $extra
125
			$extra = $extra->getArrayCopy();
126
		}
127
		$container = new Page($extra);
128
		$container['url'] = $file;
129
		$container['body'] = $body;
130
		if ($remainingPageLoads !== null) {
131
			$container['RemainingPageLoads'] = $remainingPageLoads;
132
		}
133
		return $container;
134
	}
135
136
	/**
137
	 * Create a copy of a Page object.
138
	 * This may be useful for reusing a Page object without modifying the
139
	 * original.
140
	 */
141
	public static function copy(Page $other) : self {
142
		return clone $other;
143
	}
144
145
	/**
146
	 * Use this container as the global variable $var.
147
	 */
148
	public function useAsGlobalVar($sn = null) {
149
		global $var;
150
151
		// this sn identifies our container later
152
		if (!is_null($sn)) {
153
			SmrSession::resetLink($this, $sn);
154
		}
155
156
		// Note: if problems arise, maybe $this should be cloned.
157
		$var = $this;
158
	}
159
160
	/**
161
	 * Forward to the page identified by this container.
162
	 */
163
	public function go() : void {
164
		global $sn;
165
		if (defined('OVERRIDE_FORWARD') && OVERRIDE_FORWARD === true) {
166
			overrideForward($this);
167
			return;
168
		}
169
		$this->useAsGlobalVar($sn);
170
		do_voodoo();
171
	}
172
173
	/**
174
	 * Transfer data from $var into this container.
175
	 */
176
	public function addVar(string $what) : void {
177
		global $var;
178
179
		// transfer this value to next container
180
		if (isset($var[$what])) {
181
			$this[$what] = $var[$what];
182
		}
183
	}
184
185
	/**
186
	 * Create an HREF (based on a random SN) to link to this page.
187
	 * The container is saved in the SmrSession under this SN so that on
188
	 * the next request, we can grab the container out of the SmrSession.
189
	 */
190
	public function href(bool $forceFullURL = false) : string {
191
192
		// We need to make a clone of this object for two reasons:
193
		// 1. The object saved in the session is not modified if we use this
194
		//    object to create more links.
195
		// 2. Any additional links we create using this object do not inherit
196
		//    the metadata properties that we add here, which would falsely
197
		//    represent some other page.
198
		// Ideally this would not be necessary, but the usage of this method
199
		// would need to change globally first (no Page re-use).
200
		$copy = self::copy($this);
201
202
		if (!isset($copy['Expires'])) {
203
			$copy['Expires'] = 0; // Lasts forever
204
		}
205
		if (!isset($copy['RemainingPageLoads'])) {
206
			$pageURL = $copy['url'] == 'skeleton.php' ? $copy['body'] : $copy['url'];
207
			$copy['RemainingPageLoads'] = self::URL_DEFAULT_REMAINING_PAGE_LOADS[$pageURL] ?? 1; // Allow refreshing
208
		}
209
210
		// 'CommonID' MUST be unique to a specific action. If there will
211
		// be two different outcomes from containers given the same ID then
212
		// problems will likely arise.
213
		$copy['CommonID'] = $this->getCommonID();
214
		$sn = SmrSession::addLink($copy);
215
216
		if ($forceFullURL === true || stripos($_SERVER['REQUEST_URI'], 'loader.php') === false) {
217
			return '/loader.php?sn=' . $sn;
218
		}
219
		return '?sn=' . $sn;
220
	}
221
222
	/**
223
	 * Returns a hash of the contents of the container to identify when two
224
	 * containers are equivalent (apart from page-load tracking metadata, which
225
	 * we strip out to prevent false differences).
226
	 */
227
	private function getCommonID() : string {
228
		$commonContainer = $this->getArrayCopy();
229
		unset($commonContainer['Expires']);
230
		unset($commonContainer['RemainingPageLoads']);
231
		unset($commonContainer['PreviousRequestTime']);
232
		unset($commonContainer['CommonID']);
233
		// NOTE: This ID will change if the order of elements in the container
234
		// changes. If this causes unnecessary SN changes, sort the container!
235
		return md5(serialize($commonContainer));
236
	}
237
238
	/**
239
	 * Process this page by executing the 'url' and 'body' files.
240
	 * Global variables are included here for convenience (and should be
241
	 * synchronized with `do_voodoo`).
242
	 */
243
	public function process() : void {
244
		global $lock, $var, $player, $ship, $sector, $account, $db, $template;
245
		if ($this['url'] != 'skeleton.php') {
246
			require(get_file_loc($this['url']));
247
		}
248
		if ($this['body']) {
249
			require(get_file_loc($this['body']));
250
		}
251
	}
252
253
}
254