Completed
Push — robots ( 3bce21 )
by Simon
02:59
created

functions.php ➔ displayPreview()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 1
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 32 and the first side effect is on line 15.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**************************************************************************
3
 **********      English Wikipedia Account Request Interface      **********
4
 ***************************************************************************
5
 ** Wikipedia Account Request Graphic Design by Charles Melbye,           **
6
 ** which is licensed under a Creative Commons                            **
7
 ** Attribution-Noncommercial-Share Alike 3.0 United States License.      **
8
 **                                                                       **
9
 ** All other code are released under the Public Domain                   **
10
 ** by the ACC Development Team.                                          **
11
 **                                                                       **
12
 ** See CREDITS for the list of developers.                               **
13
 ***************************************************************************/
14
15
global $ACC;
16
global $baseurl;
17
global $dontUseWikiDb;
18
19
if (!defined("ACC")) {
20
	die();
21
} // Invalid entry point
22
23
require_once 'queryBrowser.php';
24
require_once 'includes/session.php';
25
26
// Initialize the class objects.
27
$session = new session();
28
29
/**
30
 * Send a "close pend ticket" email to the end user. (created, taken, etc...)
31
 */
32
function sendemail($messageno, $target, $id)
33
{
34
	$template = EmailTemplate::getById($messageno, gGetDb());
35
	$headers = 'From: [email protected]';
36
	    
37
	// Get the closing user's Email signature and append it to the Email.
38
	if (User::getCurrent()->getEmailSig() != "") {
39
		$emailsig = html_entity_decode(User::getCurrent()->getEmailSig(), ENT_QUOTES, "UTF-8");
40
		mail($target, "RE: [ACC #$id] English Wikipedia Account Request", $template->getText() . "\n\n" . $emailsig, $headers);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 121 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
41
	}
42
	else {
43
		mail($target, "RE: [ACC #$id] English Wikipedia Account Request", $template->getText(), $headers);
44
	}
45
}
46
47
/**
48
 * Returns a value indicating whether the current request was issued over HTTPSs
49
 * @return bool true if HTTPS
50
 */
51
function isHttps()
0 ignored issues
show
Coding Style introduced by
isHttps uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
52
{
53 View Code Duplication
	if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
54
		if ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
0 ignored issues
show
Coding Style introduced by
The if-else statement can be simplified to return $_SERVER['HTTP_X_...ED_PROTO'] === 'https';.
Loading history...
55
			// Client <=> Proxy is encrypted
56
			return true;
57
		}
58
		else {
59
			// Proxy <=> Server link is encrypted, but not Client <=> Proxy.
60
			return false;
61
		}
62
	}
63
64 View Code Duplication
	if (isset($_SERVER['HTTPS'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
65
		if ($_SERVER['HTTPS'] === 'off') {
66
			// ISAPI on IIS breaks the spec. :(
67
			return false;
68
		}
69
70
		if ($_SERVER['HTTPS'] !== '') {
71
			// Set to a non-empty value
72
			return true;
73
		}
74
	}
75
76
	return false;
77
}
78
79
/**
80
 * Show the login page
81
 */
82
function showlogin()
83
{
84
	global $smarty;
85
    
86
	// Check whether there are any errors.
87
	$errorbartext = "";
88
	if (isset($_GET['error'])) {
89
		if ($_GET['error'] == 'authfail') {
90
			$errorbartext = BootstrapSkin::displayAlertBox("Username and/or password incorrect. Please try again.", "alert-error", "Auth failure", true, false, true);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 157 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
91
		}
92
		elseif ($_GET['error'] == 'noid') {
93
			$errorbartext = BootstrapSkin::displayAlertBox("User account is not identified. Please email [email protected] if you believe this is in error.", "alert-error", "Auth failure", true, false, true);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 219 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
94
		}
95
		elseif ($_GET['error'] == 'newacct') {
96
			$errorbartext = BootstrapSkin::displayAlertBox("I'm sorry, but, your account has not been approved by a site administrator yet. Please stand by.", "alert-info", "Account pending", true, false, true);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 202 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
97
		}
98
	}
99
	$smarty->assign("errorbar", $errorbartext);   
100
101
	global $strictTransportSecurityExpiry;
102
	if ($strictTransportSecurityExpiry !== false) {
103
		if (isHttps()) {
104
			// Client can clearly use HTTPS, so let's enforce it for all connections.
105
			header("Strict-Transport-Security: max-age=15768000");
106
		}
107
		else {
108
			// This is the login form, not the request form. We need protection here.
109
			$path = 'https://' . $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"];
110
			header("Location: " . $path);
111
		}
112
	}
113
114
	$smarty->display("login.tpl");
115
}
116
117
function defaultpage()
118
{
119
	global $availableRequestStates, $defaultRequestStateKey, $requestLimitShowOnly, $enableEmailConfirm;
120
    
121
	$database = gGetDb();
122
    
123
	$requestSectionData = array();
124
    
125
	if ($enableEmailConfirm == 1) {
126
		$query = "SELECT * FROM request WHERE status = :type AND emailconfirm = 'Confirmed' LIMIT :lim;";
127
		$totalquery = "SELECT COUNT(*) FROM request WHERE status = :type AND emailconfirm = 'Confirmed';";
128
	}
129
	else {
130
		$query = "SELECT * FROM request WHERE status = :type LIMIT :lim;";
131
		$totalquery = "SELECT COUNT(*) FROM request WHERE status = :type;";
132
	}
133
    
134
	$statement = $database->prepare($query);
135
	$statement->bindValue(":lim", $requestLimitShowOnly, PDO::PARAM_INT);
136
    
137
	$totalRequestsStatement = $database->prepare($totalquery);
138
            
139
	// list requests in each section
140
	foreach ($availableRequestStates as $type => $v) {
141
		$statement->bindValue(":type", $type);
142
		$statement->execute();
143
        
144
		$requests = $statement->fetchAll(PDO::FETCH_CLASS, "Request");
145
		foreach ($requests as $req) {
146
			$req->setDatabase($database);   
147
		}
148
149
		$totalRequestsStatement->bindValue(":type", $type);
150
		$totalRequestsStatement->execute();
151
		$totalRequests = $totalRequestsStatement->fetchColumn();
152
		$totalRequestsStatement->closeCursor();
153
        
154
		$requestSectionData[$v['header']] = array(
155
			"requests" => $requests, 
156
			"total" => $totalRequests, 
157
			"api" => $v['api'],
158
            "type" => $type);
159
	}
160
    
161
	global $smarty;
162
	$smarty->assign("requestLimitShowOnly", $requestLimitShowOnly);
163
	
164
	$query = <<<SQL
165
		SELECT request.id, request.name, request.checksum
166
		FROM request 
167
		JOIN log ON log.objectid = request.id and log.objecttype = 'Request'
168
		WHERE log.action LIKE 'Closed%' 
169
		ORDER BY log.timestamp DESC 
170
		LIMIT 5;
171
SQL;
172
    
173
	$statement = $database->prepare($query);
174
	$statement->execute();
175
    
176
	$last5result = $statement->fetchAll(PDO::FETCH_ASSOC);
177
    
178
	$smarty->assign("lastFive", $last5result);
179
	$smarty->assign("requestSectionData", $requestSectionData);
180
	$html = $smarty->fetch("mainpage/mainpage.tpl");
181
    
182
	return $html;
183
}
184
185
function array_search_recursive($needle, $haystack, $path = array())
186
{
187
	foreach ($haystack as $id => $val) {
188
		$path2 = $path;
189
		$path2[] = $id;
190
191
		if ($val === $needle) {
192
				return $path2;
193
		}
194
		else if (is_array($val)) {
195
				if ($ret = array_search_recursive($needle, $val, $path2)) {
196
						return $ret;
197
				}
198
		}
199
	}
200
	return false;
201
}
202
203
require_once('zoompage.php');
204
205
function displayPreview($wikicode)
206
{
207
	$parseresult = unserialize(file_get_contents('http://en.wikipedia.org/w/api.php?action=parse&format=php&text=' . urlencode($wikicode)));
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 137 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
208
	$out = "<br />\n<h3>Preview</h3>\n<div style=\"border: 2px dashed rgb(26, 79, 133);\">\n<div style=\"margin: 20px;\">";
209
	$out .= $parseresult['parse']['text']['*'];
210
	$out .= '</div></div>';
211
	return $out;
212
}
213
214
/**
215
 * Parses an XFF header and client IP to find the last trusted client IP
216
 * 
217
 * @param string $dbip The IP address the request came from
218
 * @param string $dbproxyip The contents of the XFF header of the request
219
 * @return string
220
 */
221
function getTrustedClientIP($dbip, $dbproxyip)
222
{
223
	global $xffTrustProvider;
224
    
225
	$clientIpAddr = $dbip;
226
	if ($dbproxyip) {
227
		$ipList = explode(",", $dbproxyip);
228
		$ipList[] = $clientIpAddr;
229
		$ipList = array_reverse($ipList);
230
		
231
		foreach ($ipList as $ipnumber => $ip) {
232
			if ($xffTrustProvider->isTrusted(trim($ip)) && $ipnumber < (count($ipList) - 1)) {
233
				continue;
234
			}
235
			
236
			$clientIpAddr = $ip;
237
			break;
238
		}
239
	}
240
	
241
	return $clientIpAddr;
242
}
243
244
/**
245
 * Explodes a CIDR range into an array of addresses
246
 * 
247
 * @param string $range A CIDR-format range
248
 * @return array An array containing every IP address in the range
249
 */
250
function explodeCidr($range)
251
{
252
	$ip_arr = explode('/', $range);
253
254
	if (!isset($ip_arr[1])) {
255
		return array($range);
256
	}
257
	
258
	$blow = ( 
259
		str_pad(decbin(ip2long($ip_arr[0])), 32, "0", STR_PAD_LEFT) &
260
		str_pad(str_pad("", $ip_arr[1], "1"), 32, "0") 
261
		);
262
	$bhigh = ($blow | str_pad(str_pad("", $ip_arr[1], "0"), 32, "1"));
263
264
	$list = array();
265
266
	$bindecBHigh = bindec($bhigh);
267
	for ($x = bindec($blow); $x <= $bindecBHigh; $x++) {
268
		$list[] = long2ip($x);
269
	}
270
271
	return $list;
272
}
273
274
/**
275
 * Takes an array( "low" => "high" ) values, and returns true if $needle is in at least one of them.
276
 * @param string $ip
277
 * @param array $haystack
278
 */
279
function ipInRange($haystack, $ip)
280
{
281
	$needle = ip2long($ip);
282
283
	foreach ($haystack as $low => $high) {
284
		if (ip2long($low) <= $needle && ip2long($high) >= $needle) {
285
			return true;
286
		}
287
	}
288
    
289
	return false;
290
}
291
292
/**
293
 * @return string
294
 */
295
function welcomerbotRenderSig($creator, $sig)
296
{
297
	$signature = html_entity_decode($sig) . ' ~~~~~';
298
	if (!preg_match("/((\[\[[ ]*(w:)?[ ]*(en:)?)|(\{\{subst:))[ ]*User[ ]*:[ ]*" . $creator . "[ ]*(\]\]|\||\}\}|\/)/i", $signature)) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 132 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
299
		$signature = "--[[User:$creator|$creator]] ([[User talk:$creator|talk]]) ~~~~~";
300
	}
301
	return $signature;
302
}
303
304
/**
305
 * Transforms a date string into a relative representation of the date ("2 weeks ago").
306
 * @param string $input A string representing a date
307
 * @return string
308
 * @example {$variable|relativedate} from Smarty
309
 */
310
function relativedate($input)
311
{
312
	$now = new DateTime();
313
	$then = new DateTime($input);
314
    
315
	$secs = $now->getTimestamp() - $then->getTimestamp();
316
    
317
	$second = 1;
318
	$minute = 60 * $second;
319
	$minuteCut = 60 * $second;
320
	$hour = 60 * $minute;
321
	$hourCut = 60 * $minute;
322
	$day = 24 * $hour;
323
	$dayCut = 48 * $hour;
324
	$week = 7 * $day;
325
	$weekCut = 14 * $day;
326
	$month = 30 * $day;
327
	$year = 365 * $day;
328
    
329
	$pluralise = true;
330
    
331
	if ($secs <= 10) {
332
		$output = "just now";
333
		$pluralise = false;
334
	}
335
	elseif ($secs > 10 && $secs < $minuteCut) {
336
		$output = round($secs / $second) . " second";
337
	}
338
	elseif ($secs >= $minuteCut && $secs < $hourCut) {
339
		$output = round($secs / $minute) . " minute";
340
	}
341
	elseif ($secs >= $hourCut && $secs < $dayCut) {
342
		$output = round($secs / $hour) . " hour";
343
	}
344
	elseif ($secs >= $dayCut && $secs < $weekCut) {
345
		$output = round($secs / $day) . " day";
346
	}
347 View Code Duplication
	elseif ($secs >= $weekCut && $secs < $month) {
348
		$output = round($secs / $week) . " week";
349
	}
350 View Code Duplication
	elseif ($secs >= $month && $secs < $year) {
351
		$output = round($secs / $month) . " month";
352
	}
353
	elseif ($secs >= $year && $secs < $year * 10) {
354
		$output = round($secs / $year) . " year";
355
	}
356
	else {
357
		$output = "a long time ago";
358
		$pluralise = false;
359
	}
360
    
361
	if ($pluralise) {
362
		$output = (substr($output, 0, 2) <> "1 ") ? $output . "s ago" : $output . " ago";
363
	}
364
365
	return $output;
366
}
367
368
/**
369
 * Summary of reattachOAuthAccount
370
 * @param User $user 
371
 * @throws TransactionException 
372
 */
373 View Code Duplication
function reattachOAuthAccount(User $user)
374
{
375
	global $oauthConsumerToken, $oauthSecretToken, $oauthBaseUrl, $oauthBaseUrlInternal;
376
377
	try {
378
		// Get a request token for OAuth
379
		$util = new OAuthUtility($oauthConsumerToken, $oauthSecretToken, $oauthBaseUrl, $oauthBaseUrlInternal);
380
		$requestToken = $util->getRequestToken();
381
382
		// save the request token for later
383
		$user->setOAuthRequestToken($requestToken->key);
384
		$user->setOAuthRequestSecret($requestToken->secret);
385
		$user->save();
386
            
387
		$redirectUrl = $util->getAuthoriseUrl($requestToken);
388
            
389
		header("Location: {$redirectUrl}");
390
		die();
391
	}
392
	catch (Exception $ex) {
393
		throw new TransactionException($ex->getMessage(), "Connection to Wikipedia failed.", "alert-error", 0, $ex);
394
	}     
395
}
396
397
/**
398
 * Generates the JavaScript source for XSS-safe typeahead autocompletion for usernames.  This output is expected to be
399
 * passed as the $tailscript argument to \BootstrapSkin::displayInternalFooter().
400
 *
401
 * @param $users string[] Array of usernames as strings
402
 * @return string
403
 */
404
function getTypeaheadSource($users)
405
{
406
	$userList = "";
407
	foreach ($users as $v) {
408
		$userList .= "\"" . htmlentities($v) . "\", ";
409
	}
410
	$userList = "[" . rtrim($userList, ", ") . "]";
411
	$tailscript = <<<JS
412
$('.username-typeahead').typeahead({
413
	source: {$userList}
414
});
415
JS;
416
	return $tailscript;
417
}
418