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 (#1038)
by Dan
11:47
created

array_rand_value()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 5
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
	$message = '';
7
	$delim = "\n\n-----------\n\n";
8
9
	$session = Smr\Session::getInstance();
10
11
	if ($session->hasAccount()) {
12
		$account = $session->getAccount();
13
		$message .= 'Login: ' . $account->getLogin() . "\n" .
14
			'E-Mail: ' . $account->getEmail() . "\n" .
15
			'Account ID: ' . $account->getAccountID() . "\n" .
16
			'Game ID: ' . $session->getGameID() . $delim;
17
	}
18
	$message .= 'Error Message: ' . $e . $delim;
19
20
	$message .= '$var: ' . var_export($session->getCurrentVar(), true);
21
22
	// Don't display passwords input by users in the log message!
23
	if (isset($_REQUEST['password'])) {
24
		$_REQUEST['password'] = '*****';
25
	}
26
	$message .= "\n\n" . '$_REQUEST: ' . var_export($_REQUEST, true);
27
	$message .= $delim;
28
29
	$message .=
30
		'User IP: ' . getIpAddress() . "\n" .
31
		'User Agent: ' . ($_SERVER['HTTP_USER_AGENT'] ?? 'undefined') . "\n" .
32
		'USING_AJAX: ' . (defined('USING_AJAX') ? var_export(USING_AJAX, true) : 'undefined') . "\n" .
33
		'URL: ' . (defined('URL') ? URL : 'undefined');
34
35
	try {
36
		if (function_exists('release_lock')) {
37
			release_lock(); //Try to release lock so they can carry on normally
38
		}
39
	} catch (Throwable $ee) {
40
		$message .= $delim .
41
					'Releasing Lock Failed' . "\n" .
42
					'Message: ' . $ee . "\n";
43
	}
44
45
	if (defined('SCRIPT_ID')) {
46
		$message = 'Script: ' . SCRIPT_ID . $delim . $message . "\n\n";
47
	}
48
49
	// Unconditionally send error message to the log
50
	error_log($message);
51
52
	if (ENABLE_DEBUG) {
53
		// Display error message on the page (redundant with error_log for CLI)
54
		if (php_sapi_name() !== 'cli') {
55
			echo nl2br($message);
56
		}
57
		// Skip remaining log methods (too disruptive during development)
58
		return;
59
	}
60
61
	// Send error message to the in-game auto bugs mailbox
62
	if ($session->hasPlayer()) {
0 ignored issues
show
Bug introduced by
The method hasPlayer() does not exist on Smr\Session. ( Ignorable by Annotation )

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

62
	if ($session->/** @scrutinizer ignore-call */ hasPlayer()) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
63
		$session->getPlayer()->sendMessageToBox(BOX_BUGS_AUTO, $message);
64
	} elseif ($session->hasAccount()) {
65
		// Will be logged without a game_id
66
		$session->getAccount()->sendMessageToBox(BOX_BUGS_AUTO, $message);
67
	} else {
68
		// Will be logged without a game_id or sender_id
69
		SmrAccount::doMessageSendingToBox(0, BOX_BUGS_AUTO, $message, 0);
70
	}
71
72
	// Send error message to e-mail so that we have a permanent record
73
	if (!empty(BUG_REPORT_TO_ADDRESSES)) {
0 ignored issues
show
introduced by
The condition empty(BUG_REPORT_TO_ADDRESSES) is always true.
Loading history...
74
		$mail = setupMailer();
75
		$mail->Subject = (defined('PAGE_PREFIX') ? PAGE_PREFIX : '??? ') .
76
		                 'Automatic Bug Report';
77
		$mail->setFrom('[email protected]');
78
		$mail->Body = $message;
79
		foreach (BUG_REPORT_TO_ADDRESSES as $toAddress) {
80
			$mail->addAddress($toAddress);
81
		}
82
		$mail->send();
83
	}
84
}
85
86
function handleException(Throwable $e) {
87
	// The real error message may display sensitive information, so we
88
	// need to catch any exceptions that are thrown while logging the error.
89
	try {
90
		logException($e);
91
		$errorType = 'Unexpected Error!';
92
	} catch (Throwable $e) {
93
		error_log('Exception during logException: ' . $e);
94
		$errorType = 'This error cannot be automatically reported. Please notify an admin!';
95
	}
96
97
	// If this is an ajax update, we don't really have a way to redirect
98
	// to an error page at this time.
99
	if (!ENABLE_DEBUG && (!defined('USING_AJAX') || !USING_AJAX)) {
100
		header('location: /error.php?msg=' . urlencode($errorType));
101
	}
102
}
103
104
/**
105
 * Can be used to convert any type of notice into an exception.
106
 */
107
function exception_error_handler($errno, $errstr, $errfile, $errline) {
108
	throw new ErrorException($errstr, $errno, E_ERROR, $errfile, $errline);
109
}
110
111
function setupMailer() {
112
	$mail = new \PHPMailer\PHPMailer\PHPMailer(true);
113
	if (!empty(SMTP_HOSTNAME)) {
0 ignored issues
show
introduced by
The condition empty(SMTP_HOSTNAME) is always false.
Loading history...
114
		$mail->isSMTP();
115
		$mail->Host = SMTP_HOSTNAME;
116
	}
117
	return $mail;
118
}
119
120
function getIpAddress() {
121
	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) {
122
		if (array_key_exists($key, $_SERVER) === true) {
123
			foreach (explode(',', $_SERVER[$key]) as $ip) {
124
				if (filter_var($ip, FILTER_VALIDATE_IP) !== false) {
125
					return $ip;
126
				}
127
			}
128
		}
129
	}
130
	return 'unknown';
131
}
132
133
/**
134
 * Wrapper around the floor() builtin for returning an integer type.
135
 */
136
function IFloor(float $val) : int {
137
	return (int)floor($val);
138
}
139
140
/**
141
 * Wrapper around the ceil() builtin for returning an integer type.
142
 */
143
function ICeil(float $val) : int {
144
	return (int)ceil($val);
145
}
146
147
/**
148
 * Wrapper around the round() builtin for returning an integer type.
149
 */
150
function IRound(float $val) : int {
151
	return (int)round($val);
152
}
153
154
/**
155
 * Convert a numeric string to an int with input validation.
156
 */
157
function str2int(string $val) : int {
158
	$result = filter_var($val, FILTER_VALIDATE_INT);
159
	if ($result === false) {
160
		throw new Exception('Input value is not an integer: ' . $val);
161
	}
162
	return $result;
163
}
164
165
/**
166
 * Generate a cryptographically strong random hexadecimal string.
167
 * The requested length must be a multiple of 2.
168
 */
169
function random_string(int $length) : string {
170
	if ($length % 2 != 0) {
171
		throw new Exception('Length must be a multiple of 2!');
172
	}
173
	return bin2hex(random_bytes($length / 2));
174
}
175
176
/**
177
 * Generate a (non-cryptographic) random alphabetic string.
178
 * This is slower for longer strings.
179
 */
180
function random_alphabetic_string(int $length) : string {
181
	$result = '';
182
	for ($i = 0; $i < $length; ++$i) {
183
		$result .= chr(rand(ord('a'), ord('z')));
184
	}
185
	return $result;
186
}
187
188
/**
189
 * Return the value of a random key from an array.
190
 */
191
function array_rand_value(array $arr) : mixed {
192
	if (empty($arr)) {
193
		throw new Exception('Cannot pick random value from empty array!');
194
	}
195
	return $arr[array_rand($arr)];
196
}
197
198
// Defines all constants
199
require_once('config.php');
200
201
// Set up vendor and class autoloaders
202
require_once(ROOT . 'vendor/autoload.php');
203
require_once(LIB . 'autoload.inc.php');
204
spl_autoload_register('get_class_loc');
205
206
// Set up dependency injection container
207
DiContainer::initializeContainer();
208