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 (#1035)
by Dan
05:02
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
	function process() : void {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
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