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

Completed
Push — master ( 2b5828...a7a342 )
by Dan
36s queued 18s
created

random_alphabetic_string()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
use Smr\Container\DiContainer;
4
5
function logException(Throwable $e) : void {
6
	global $account, $var, $player;
7
	$message = '';
8
	$delim = "\n\n-----------\n\n";
9
10
	if (is_object($account)) {
11
		$message .= 'Login: ' . $account->getLogin() . "\n" .
12
			'Account ID: ' . $account->getAccountID() . "\n" .
13
			'E-Mail: ' . $account->getEmail() . $delim;
14
	}
15
	$message .= 'Error Message: ' . $e . $delim;
16
17
	$message .= '$var: ' . var_export($var, true);
18
19
	// Don't display passwords input by users in the log message!
20
	if (isset($_REQUEST['password'])) {
21
		$_REQUEST['password'] = '*****';
22
	}
23
	$message .= "\n\n" . '$_REQUEST: ' . var_export($_REQUEST, true);
24
	$message .= $delim;
25
26
	$message .=
27
		'User IP: ' . getIpAddress() . "\n" .
28
		'User Agent: ' . ($_SERVER['HTTP_USER_AGENT'] ?? 'undefined') . "\n" .
29
		'USING_AJAX: ' . (defined('USING_AJAX') ? var_export(USING_AJAX, true) : 'undefined') . "\n" .
30
		'URL: ' . (defined('URL') ? URL : 'undefined');
31
32
	try {
33
		if (function_exists('release_lock')) {
34
			release_lock(); //Try to release lock so they can carry on normally
35
		}
36
	} catch (Throwable $ee) {
37
		$message .= $delim .
38
					'Releasing Lock Failed' . "\n" .
39
					'Message: ' . $ee . "\n";
40
	}
41
42
	if (defined('SCRIPT_ID')) {
43
		$message = 'Script: ' . SCRIPT_ID . $delim . $message . "\n\n";
44
	}
45
46
	// Unconditionally send error message to the log
47
	error_log($message);
48
49
	if (ENABLE_DEBUG) {
50
		// Display error message on the page (redundant with error_log for CLI)
51
		if (php_sapi_name() !== 'cli') {
52
			echo nl2br($message);
53
		}
54
		// Skip remaining log methods (too disruptive during development)
55
		return;
56
	}
57
58
	// Send error message to the in-game auto bugs mailbox
59
	if (is_object($player) && method_exists($player, 'sendMessageToBox')) {
60
		$player->sendMessageToBox(BOX_BUGS_AUTO, $message);
61
	} elseif (is_object($account) && method_exists($account, 'sendMessageToBox')) {
62
		// Will be logged without a game_id
63
		$account->sendMessageToBox(BOX_BUGS_AUTO, $message);
64
	} else {
65
		// Will be logged without a game_id or sender_id
66
		SmrAccount::doMessageSendingToBox(0, BOX_BUGS_AUTO, $message, 0);
67
	}
68
69
	// Send error message to e-mail so that we have a permanent record
70
	if (!empty(BUG_REPORT_TO_ADDRESSES)) {
0 ignored issues
show
introduced by
The condition empty(BUG_REPORT_TO_ADDRESSES) is always true.
Loading history...
71
		$mail = setupMailer();
72
		$mail->Subject = (defined('PAGE_PREFIX') ? PAGE_PREFIX : '??? ') .
73
		                 'Automatic Bug Report';
74
		$mail->setFrom('[email protected]');
75
		$mail->Body = $message;
76
		foreach (BUG_REPORT_TO_ADDRESSES as $toAddress) {
77
			$mail->addAddress($toAddress);
78
		}
79
		$mail->send();
80
	}
81
}
82
83
function handleException(Throwable $e) {
84
	// The real error message may display sensitive information, so we
85
	// need to catch any exceptions that are thrown while logging the error.
86
	try {
87
		logException($e);
88
		$errorType = 'Unexpected Error!';
89
	} catch (Throwable $e) {
90
		error_log('Exception during logException: ' . $e);
91
		$errorType = 'This error cannot be automatically reported. Please notify an admin!';
92
	}
93
94
	// If this is an ajax update, we don't really have a way to redirect
95
	// to an error page at this time.
96
	if (!ENABLE_DEBUG && (!defined('USING_AJAX') || !USING_AJAX)) {
97
		header('location: /error.php?msg=' . urlencode($errorType));
98
	}
99
}
100
101
/**
102
 * Can be used to convert any type of notice into an exception.
103
 */
104
function exception_error_handler($errno, $errstr, $errfile, $errline) {
105
	throw new ErrorException($errstr, $errno, E_ERROR, $errfile, $errline);
106
}
107
108
function setupMailer() {
109
	$mail = new \PHPMailer\PHPMailer\PHPMailer(true);
110
	if (!empty(SMTP_HOSTNAME)) {
0 ignored issues
show
introduced by
The condition empty(SMTP_HOSTNAME) is always false.
Loading history...
111
		$mail->isSMTP();
112
		$mail->Host = SMTP_HOSTNAME;
113
	}
114
	return $mail;
115
}
116
117
function getIpAddress() {
118
	foreach (['HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR'] as $key) {
119
		if (array_key_exists($key, $_SERVER) === true) {
120
			foreach (explode(',', $_SERVER[$key]) as $ip) {
121
				if (filter_var($ip, FILTER_VALIDATE_IP) !== false) {
122
					return $ip;
123
				}
124
			}
125
		}
126
	}
127
	return 'unknown';
128
}
129
130
/**
131
 * Wrapper around the floor() builtin for returning an integer type.
132
 */
133
function IFloor(float $val) : int {
134
	return (int)floor($val);
135
}
136
137
/**
138
 * Wrapper around the ceil() builtin for returning an integer type.
139
 */
140
function ICeil(float $val) : int {
141
	return (int)ceil($val);
142
}
143
144
/**
145
 * Wrapper around the round() builtin for returning an integer type.
146
 */
147
function IRound(float $val) : int {
148
	return (int)round($val);
149
}
150
151
/**
152
 * Convert a numeric string to an int with input validation.
153
 */
154
function str2int(string $val) : int {
155
	$result = filter_var($val, FILTER_VALIDATE_INT);
156
	if ($result === false) {
157
		throw new Exception('Input value is not an integer: ' . $val);
158
	}
159
	return $result;
160
}
161
162
/**
163
 * Generate a cryptographically strong random hexadecimal string.
164
 * The requested length must be a multiple of 2.
165
 */
166
function random_string(int $length) : string {
167
	if ($length % 2 != 0) {
168
		throw new Exception('Length must be a multiple of 2!');
169
	}
170
	return bin2hex(random_bytes($length / 2));
171
}
172
173
/**
174
 * Generate a (non-cryptographic) random alphabetic string.
175
 * This is slower for longer strings.
176
 */
177
function random_alphabetic_string(int $length) : string {
178
	$result = '';
179
	for ($i = 0; $i < $length; ++$i) {
180
		$result .= chr(rand(ord('a'), ord('z')));
181
	}
182
	return $result;
183
}
184
185
/**
186
 * Return the value of a random key from an array.
187
 */
188
function array_rand_value(array $arr) : mixed {
189
	if (empty($arr)) {
190
		throw new Exception('Cannot pick random value from empty array!');
191
	}
192
	return $arr[array_rand($arr)];
193
}
194
195
// Defines all constants
196
require_once('config.php');
197
198
// Set up vendor and class autoloaders
199
require_once(ROOT . 'vendor/autoload.php');
200
require_once(LIB . 'autoload.inc.php');
201
spl_autoload_register('get_class_loc');
202
203
// Set up dependency injection container
204
DiContainer::initializeContainer();
205