Completed
Push — sessionstart ( 52a658 )
by Simon
03:37
created

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
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
// stop all output until we want it
16
ob_start();
17
18
// load the configuration
19
require_once 'config.inc.php';
20
21
// Get all the classes.
22
require_once 'functions.php';
23
initialiseSession();
24
require_once 'includes/PdoDatabase.php';
25
require_once 'includes/SmartyInit.php'; // this needs to be high up, but below config, functions, database and session init
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 123 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...
26
require_once 'includes/session.php';
27
28
// Check to see if the database is unavailable.
29
// Uses the false variable as its the internal interface.
30
if (Offline::isOffline()) {
31
	echo Offline::getOfflineMessage(false);
32
	die();
33
}
34
35
// Initialize the class objects.
36
$session = new session();
37
$date = new DateTime();
38
39
// initialise providers
40
global $squidIpList;
41
/** @var ILocationProvider $locationProvider */
42
$locationProvider = new $locationProviderClass(gGetDb('acc'), $locationProviderApiKey);
43
/** @var IRDnsProvider $rdnsProvider */
44
$rdnsProvider = new $rdnsProviderClass(gGetDb('acc'));
45
/** @var IAntiSpoofProvider $antispoofProvider */
46
$antispoofProvider = new $antispoofProviderClass();
47
/** @var IXffTrustProvider $xffTrustProvider */
48
$xffTrustProvider = new $xffTrustProviderClass($squidIpList);
49
50
// Clears the action variable.
51
$action = '';
52
53
// Assign the correct value to the action variable.
54
// The value is retrieved from the $GET variable.
55
if (isset($_GET['action'])) {
56
	$action = $_GET['action'];
57
}
58
59
// Clear session before banner and logged in as message is generated on logout attempt - Prom3th3an
60
if ($action == "logout") {
61
	session_unset();
62
    
63
	BootstrapSkin::displayInternalHeader();
64
	echo showlogin();
65
	BootstrapSkin::displayInternalFooter();
66
	die();
67
}
68
69
// Checks whether the user is set - the user should first login.
70
if (!isset($_SESSION['user'])) {
71
	$suser = '';
72
	BootstrapSkin::displayInternalHeader();
73
74
	// Checks whether the user want to reset his password or register a new account.
75
	// Performs the clause when the action is not one of the above options.
76
	if ($action != 'register' && $action != 'forgotpw' && $action != 'sreg' && $action != "registercomplete" && $action != "login") {
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 130 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...
77
		echo showlogin();
78
		BootstrapSkin::displayInternalFooter();
79
		die();
80
	}
81
	else {
82
		// A content block is created if the action is none of the above.
83
		// This block would later be used to keep all the HTML except the header and footer.
84
		$out = "<div id=\"content\">";
85
		echo $out;
86
	}
87
}
88
89
// Forces the current user to logout if necessary.
90
if (isset($_SESSION['userID'])) {
91
	$session->forceLogout($_SESSION['userID']);
92
}
93
94
BootstrapSkin::displayInternalHeader();
95
$session->checksecurity();
0 ignored issues
show
Deprecated Code introduced by
The method session::checksecurity() has been deprecated.

This method has been deprecated.

Loading history...
96
97
98
// When no action is specified the default Internal ACC are displayed.
99
// TODO: Improve way the method is called.
100
if ($action == '') {
101
	echo defaultpage();
102
	BootstrapSkin::displayInternalFooter();
103
	die();
104
}
105
elseif ($action == "sreg") {
106
	global $useOauthSignup, $smarty;
107
        
108
	// TODO: check blocked
109
	// TODO: check age.
110
    
111
	// check if user checked the "I have read and understand the interface guidelines" checkbox
112
	if (!isset($_REQUEST['guidelines'])) {
113
		$smarty->display("registration/alert-interfaceguidelines.tpl");
114
		BootstrapSkin::displayInternalFooter();
115
		die();
116
	}
117
	
118
	if (!filter_var($_REQUEST['email'], FILTER_VALIDATE_EMAIL)) {
119
		$smarty->display("registration/alert-invalidemail.tpl");
120
		BootstrapSkin::displayInternalFooter();
121
		die();
122
	}
123
    
124
	if ($_REQUEST['pass'] !== $_REQUEST['pass2']) {
125
		$smarty->display("registration/alert-passwordmismatch.tpl");
126
		BootstrapSkin::displayInternalFooter();
127
		die();
128
	}
129
    
130
	if (!$useOauthSignup) {
131
		if (!((string)(int)$_REQUEST['conf_revid'] === (string)$_REQUEST['conf_revid']) || $_REQUEST['conf_revid'] == "") {
132
			$smarty->display("registration/alert-confrevid.tpl");
133
			BootstrapSkin::displayInternalFooter();
134
			die();		
135
		}
136
	}
137
    
138
	if (User::getByUsername($_REQUEST['name'], gGetDb()) != false) {
139
		$smarty->display("registration/alert-usernametaken.tpl");
140
		BootstrapSkin::displayInternalFooter();
141
		die();
142
	}
143
    
144
	$query = gGetDb()->prepare("SELECT * FROM user WHERE email = :email LIMIT 1;");
145
	$query->execute(array(":email" => $_REQUEST['email']));
146
	if ($query->fetchObject("User") != false) {
147
		$smarty->display("registration/alert-emailtaken.tpl");
148
		BootstrapSkin::displayInternalFooter();
149
		die();
150
	}
151
	$query->closeCursor();
152
153
	$database = gGetDb();
154
    
155
	$database->transactionally(function() use ($database, $useOauthSignup)
156
	{
157
    
158
		$newUser = new User();
159
		$newUser->setDatabase($database);
160
    
161
		$newUser->setUsername($_REQUEST['name']);
162
		$newUser->setPassword($_REQUEST['pass']);
163
		$newUser->setEmail($_REQUEST['email']);
164
        
165
		if (!$useOauthSignup) {
166
			$newUser->setOnWikiName($_REQUEST['wname']);
167
			$newUser->setConfirmationDiff($_REQUEST['conf_revid']);
168
		}
169
        
170
		$newUser->save();
171
    
172
		global $oauthConsumerToken, $oauthSecretToken, $oauthBaseUrl, $oauthBaseUrlInternal, $useOauthSignup;
173
    
174
		if ($useOauthSignup) {
175
			try {
176
				// Get a request token for OAuth
177
				$util = new OAuthUtility($oauthConsumerToken, $oauthSecretToken, $oauthBaseUrl, $oauthBaseUrlInternal);
178
				$requestToken = $util->getRequestToken();
179
    
180
				// save the request token for later
181
				$newUser->setOAuthRequestToken($requestToken->key);
182
				$newUser->setOAuthRequestSecret($requestToken->secret);
183
				$newUser->save();
184
            
185
				Notification::userNew($newUser);
186
        
187
				$redirectUrl = $util->getAuthoriseUrl($requestToken);
188
            
189
				header("Location: {$redirectUrl}");
190
			}
191
			catch (Exception $ex) {
192
				throw new TransactionException(
193
					$ex->getMessage(), 
194
					"Connection to Wikipedia failed.", 
195
					"alert-error", 
196
					0, 
197
					$ex);
198
			}
199
		}
200
		else {
201
			global $baseurl;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
202
			Notification::userNew($newUser);
203
			header("Location: {$baseurl}/acc.php?action=registercomplete");
204
		}
205
	});
206
    
207
	die();
208
}
209
elseif ($action == "register") {
210
	global $useOauthSignup, $smarty;
211
	$smarty->assign("useOauthSignup", $useOauthSignup);
212
	$smarty->display("registration/register.tpl");
213
	BootstrapSkin::displayInternalFooter();
214
	die();
215
}
216
elseif ($action == "registercomplete") {
217
	$smarty->display("registration/alert-registrationcomplete.tpl");
218
	BootstrapSkin::displayInternalFooter();
219
}
220
elseif ($action == "forgotpw") {
221
	global $baseurl, $smarty;
222
    
223
	if (isset ($_GET['si']) && isset ($_GET['id'])) {
224
		$user = User::getById($_GET['id'], gGetDb());
225
        
226
		if ($user === false) {
227
			BootstrapSkin::displayAlertBox("User not found.", "alert-error");
228
			BootstrapSkin::displayInternalFooter();
229
			die();
230
		}
231
        
232
		if (isset ($_POST['pw']) && isset ($_POST['pw2'])) {
233
			$hash = $user->getForgottenPasswordHash();
234
            
235
			if ($hash == $_GET['si']) {
236
				if ($_POST['pw'] == $_POST['pw2']) {
237
					$user->setPassword($_POST['pw2']);
238
					$user->save();
239
                    
240
					BootstrapSkin::displayAlertBox(
241
						"You may now <a href=\"$baseurl/acc.php\">Login</a>", 
242
						"alert-error", 
243
						"Password reset!", 
244
						true, 
245
						false);
246
                    
247
					BootstrapSkin::displayInternalFooter();
248
					die();
249
				}
250
				else {
251
					BootstrapSkin::displayAlertBox("Passwords did not match!", "alert-error", "Error", true, false);
252
					BootstrapSkin::displayInternalFooter();
253
					die();
254
				}
255
			}
256
			else {
257
				BootstrapSkin::displayAlertBox("Invalid request<!-- 1 -->", "alert-error", "Error", true, false);
258
				BootstrapSkin::displayInternalFooter();
259
				die();
260
			}
261
		}
262
        
263
		$hash = $user->getForgottenPasswordHash();
264
        
265
		if ($hash == $_GET['si']) {
266
			$smarty->assign('user', $user);
267
			$smarty->assign('si', $_GET['si']);
268
			$smarty->assign('id', $_GET['id']);
269
			$smarty->display('forgot-password/forgotpwreset.tpl');
270
		}
271
		else {
272
			BootstrapSkin::displayAlertBox(
273
				"The hash supplied in the link did not match the hash in the database!", 
274
				"alert-error", 
275
				"Invalid request", 
276
				true, 
277
				false);
278
		}
279
        
280
		BootstrapSkin::displayInternalFooter();
281
		die();
282
	}
283
    
284
	if (isset ($_POST['username'])) {
285
		$user = User::getByUsername($_POST['username'], gGetDb());
286
287
		if ($user == false) {
288
			BootstrapSkin::displayAlertBox(
289
				"Could not find user with that username and email address!", 
290
				"alert-error", 
291
				"Error", 
292
				true, 
293
				false);
294
            
295
			BootstrapSkin::displayInternalFooter();
296
			die();
297
		}
298
		elseif (strtolower($_POST['email']) != strtolower($user->getEmail())) {
299
			BootstrapSkin::displayAlertBox("Could not find user with that username and email address!", 
300
				"alert-error", 
301
				"Error", 
302
				true, 
303
				false);
304
            
305
			BootstrapSkin::displayInternalFooter();
306
			die();
307
		}
308
		else {
309
			$hash = $user->getForgottenPasswordHash();
310
                       
311
			$smarty->assign("user", $user);
312
			$smarty->assign("hash", $hash);
313
			$smarty->assign("remoteAddress", $_SERVER['REMOTE_ADDR']);
314
            
315
			$mailtxt = $smarty->fetch("forgot-password/reset-mail.tpl");
316
			$headers = 'From: [email protected]';
317
            
318
			mail(
319
				$user->getEmail(), 
320
				"English Wikipedia Account Request System - Forgotten password", 
321
				$mailtxt, 
322
				$headers);
323
            
324
			BootstrapSkin::displayAlertBox(
325
				"<strong>Your password reset request has been completed.</strong> Please check your e-mail.", 
326
				"alert-success", 
327
				"", 
328
				false, 
329
				false);
330
            
331
			BootstrapSkin::displayInternalFooter();
332
			die();
333
		}
334
	}
335
    
336
	$smarty->display('forgot-password/forgotpw.tpl');
337
338
	BootstrapSkin::displayInternalFooter();
339
	die();
340
}
341
elseif ($action == "login") {
342
	global $baseurl, $smarty;
343
    
344
	if (!isset($_POST['username'])) {
345
		header("Location: $baseurl/acc.php?error=authfail&tplUsername=");
346
		die();
347
	}
348
349
	$user = User::getByUsername($_POST['username'], gGetDb());
350
    
351
	if ($user == false || !$user->authenticate($_POST['password'])) {
352
		header("Location: $baseurl/acc.php?error=authfail&tplUsername=" . urlencode($_POST['username']));
353
		die();
354
	}
355
    
356
	if ($user->getStoredOnWikiName() == "##OAUTH##" && $user->getOAuthAccessToken() == null) {
357
		reattachOAuthAccount($user);   
358
	}
359
    
360
	if ($user->isOAuthLinked()) {
361
		try {
362
			// test retrieval of the identity
363
			$user->getOAuthIdentity();
364
		}
365
		catch (TransactionException $ex) {
366
			$user->setOAuthAccessToken(null);
367
			$user->setOAuthAccessSecret(null);
368
			$user->save();
369
            
370
			reattachOAuthAccount($user);
371
		}
372
	}
373
	else {
374
		global $enforceOAuth;
375
        
376
		if ($enforceOAuth) {
377
			reattachOAuthAccount($user);
378
		}
379
	}
380
    
381
	// At this point, the user has successfully authenticated themselves.
382
	// We now proceed to perform login-specific actions, and check the user actually has
383
	// the correct permissions to continue with the login.
384
    
385
	if ($user->getForcelogout()) {
386
		$user->setForcelogout(false);
387
		$user->save();
388
	}
389
    
390
	if ($user->isNew()) {
391
		header("Location: $baseurl/acc.php?error=newacct");
392
		die();
393
	}
394
    
395
	$database = gGetDb();
396
    
397
	$sqlText = <<<SQL
398
SELECT comment FROM log
399
WHERE action = :action AND objectid = :userid AND objecttype = 'User'
400
ORDER BY timestamp DESC LIMIT 1;
401
SQL;
402
    
403
	$suspendstatement = $database->prepare($sqlText);
404
    
405 View Code Duplication
	if ($user->isDeclined()) {
406
		$suspendAction = "Declined";
407
		$userid = $user->getId();
408
		$suspendstatement->bindValue(":action", $suspendAction);
409
		$suspendstatement->bindValue(":userid", $userid);
410
		$suspendstatement->execute();
411
        
412
		$suspendreason = $suspendstatement->fetchColumn();
413
        
414
		$suspendstatement->closeCursor();
415
        
416
		BootstrapSkin::displayInternalHeader();
417
		$smarty->assign("suspendreason", $suspendreason);
418
		$smarty->display("login/declined.tpl");
419
		BootstrapSkin::displayInternalFooter();
420
		die();
421
	}
422
    
423 View Code Duplication
	if ($user->isSuspended()) {
424
		$suspendAction = "Suspended";
425
		$userid = $user->getId();
426
		$suspendstatement->bindValue(":action", $suspendAction);
427
		$suspendstatement->bindValue(":userid", $userid);
428
		$suspendstatement->execute();
429
        
430
		$suspendreason = $suspendstatement->fetchColumn();
431
        
432
		$suspendstatement->closeCursor();
433
        
434
		BootstrapSkin::displayInternalHeader();
435
		$smarty->assign("suspendreason", $suspendreason);
436
		$smarty->display("login/suspended.tpl");
437
		BootstrapSkin::displayInternalFooter();
438
		die();
439
	}
440
    
441
	if (!$user->isIdentified() && $forceIdentification == 1) {
442
		header("Location: $baseurl/acc.php?error=noid");
443
		die();
444
	}
445
    
446
	// At this point, we've tested that the user is OK, so we set the login cookies.
447
    
448
	$_SESSION['user'] = $user->getUsername();
449
	$_SESSION['userID'] = $user->getId();
450
    
451
	if ($user->getOAuthAccessToken() == null && $user->getStoredOnWikiName() == "##OAUTH##") {
452
		reattachOAuthAccount($user);
453
	}
454
    
455
	header("Location: $baseurl/acc.php");
456
}
457
elseif ($action == "messagemgmt") {
458
	global $smarty;
459
    
460
	if (isset($_GET['view'])) {
461
		$message = InterfaceMessage::getById($_GET['view'], gGetDb());
462
                
463
		if ($message == false) {
464
			BootstrapSkin::displayAlertBox("Unable to find specified message", "alert-error", "Error", true, false);
465
			BootstrapSkin::displayInternalFooter();
466
			die();
467
		}
468
        
469
		$smarty->assign("message", $message);
470
		$smarty->assign("readonly", true);
471
		$smarty->display("message-management/editform.tpl");
472
		BootstrapSkin::displayInternalFooter();
473
		die();
474
	}
475
	if (isset($_GET['edit'])) {
476
		if (!(User::getCurrent()->isAdmin() || User::getCurrent()->isCheckuser())) {
477
			BootstrapSkin::displayAccessDenied();
478
			BootstrapSkin::displayInternalFooter();
479
			die();
480
		}
481
        
482
		$database = gGetDb();
483
        
484
		$database->transactionally(function() use ($database)
485
		{
486
			global $smarty;
487
            
488
			$message = InterfaceMessage::getById($_GET['edit'], $database);
489
            
490
			if ($message == false) {
491
				throw new TransactionException("Unable to find specified message", "Error");
492
			}
493
            
494
			if (isset($_GET['submit'])) {
495
				$message->setContent($_POST['mailtext']);
496
				$message->setDescription($_POST['maildesc']);
497
				$message->save();
498
            
499
				Logger::interfaceMessageEdited(gGetDb(), $message);
500
              
501
				$smarty->assign("message", $message);
502
				$smarty->display("message-management/alert-editsuccess.tpl");
503
                
504
				Notification::interfaceMessageEdited($message);
505
                
506
				BootstrapSkin::displayInternalFooter();
507
				return;
508
			}
509
            
510
			$smarty->assign("message", $message);
511
			$smarty->assign("readonly", false);
512
			$smarty->display("message-management/editform.tpl");
513
        
514
			BootstrapSkin::displayInternalFooter();
515
		});
516
        
517
		die();
518
	}
519
    
520
	$sqlText = <<<SQL
521
        SELECT * 
522
        FROM interfacemessage 
523
        WHERE type = :type 
524
            AND description NOT LIKE '%[deprecated]';
525
SQL;
526
    
527
	$fetchStatement = gGetDb()->prepare($sqlText);
528
	$data = array();
529
        
530
	//$fetchStatement->execute(array(":type" => "Interface"));
0 ignored issues
show
Unused Code Comprehensibility introduced by
79% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
531
	//$data['Public Interface messages'] = $fetchStatement->fetchAll(PDO::FETCH_CLASS, 'InterfaceMessage');
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
532
    
533
	$fetchStatement->execute(array(":type" => "Internal"));
534
	$data['Internal Interface messages'] = $fetchStatement->fetchAll(PDO::FETCH_CLASS, 'InterfaceMessage');
535
    
536
	$smarty->assign("data", $data);
537
	$smarty->display('message-management/view.tpl');
538
   
539
	BootstrapSkin::displayInternalFooter();
540
	die();
541
}
542
elseif ($action == "templatemgmt") {
543
	global $baseurl, $smarty;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
544
    
545
	if (isset($_GET['view'])) {
546
		$template = WelcomeTemplate::getById($_GET['view'], gGetDb());
547
        
548
		if ($template === false) {
549
			SessionAlert::success("Something went wrong, we can't find the template you asked for! Please try again.");
550
			header("Location: {$baseurl}/acc.php?action=templatemgmt");
551
			die();
552
		}
553
        
554
		$smarty->assign("template", $template);
555
		$smarty->display("welcometemplate/view.tpl");
556
		BootstrapSkin::displayInternalFooter();
557
		die();
558
	}
559
    
560
	if (isset($_GET['add'])) {
561
		if (!User::getCurrent()->isAdmin() && !User::getCurrent()->isCheckuser()) {
562
			BootstrapSkin::displayAccessDenied();
563
            
564
			BootstrapSkin::displayInternalFooter();
565
			die();
566
		}
567
        
568
		if (isset($_POST['submit'])) {
569
			global $baseurl;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
570
            
571
			$database = gGetDb();
572
            
573 View Code Duplication
			$database->transactionally(function() use ($database, $baseurl)
574
			{
575
				$template = new WelcomeTemplate();
576
				$template->setDatabase($database);
577
				$template->setUserCode($_POST['usercode']);
578
				$template->setBotCode($_POST['botcode']);
579
				$template->save();
580
            
581
				Logger::welcomeTemplateCreated($database, $template);
582
                            
583
				Notification::welcomeTemplateCreated($template);
584
            
585
				SessionAlert::success("Template successfully created.");
586
				header("Location: $baseurl/acc.php?action=templatemgmt");
587
			});
588
		}
589
		else {
590
			
591
			if (isset($_POST['preview'])) {
592
				$usercode = $_POST['usercode'];
593
				$botcode = $_POST['botcode'];
594
				echo displayPreview($usercode);
595
			}
596
			else {
597
				$usercode = '';
598
				$botcode = '';
599
			}
600
601
			$smarty->assign("usercode", $usercode);
602
			$smarty->assign("botcode", $botcode);
603
            
604
			$smarty->display("welcometemplate/add.tpl");
605
			BootstrapSkin::displayInternalFooter();
606
			die();
607
		}
608
        
609
		die();
610
	}
611
    
612
	if (isset($_GET['select'])) {
613
		$user = User::getCurrent();
614
        
615
		if ($_GET['select'] == 0) {
616
			$user->setWelcomeTemplate(null);
617
			$user->save();
618
            
619
			SessionAlert::success("Disabled automatic user welcoming.");
620
			header("Location: {$baseurl}/acc.php?action=templatemgmt");
621
			die();
622
		}
623
		else {
624
			$template = WelcomeTemplate::getById($_GET['select'], gGetDb());
625
			if ($template !== false) {
626
				$user->setWelcomeTemplate($template->getId());
627
				$user->save();
628
                
629
				SessionAlert::success("Updated selected welcome template for automatic welcoming.");
630
				header("Location: {$baseurl}/acc.php?action=templatemgmt");
631
				die();
632
			}
633
			else {
634
				SessionAlert::error("Something went wrong, we can't find the template you asked for!");
635
				header("Location: {$baseurl}/acc.php?action=templatemgmt");
636
				die();
637
			}
638
		}
639
	}
640
    
641
	if (isset($_GET['del'])) {
642
		global $baseurl;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
643
        
644
		if (!User::getCurrent()->isAdmin() && !User::getCurrent()->isCheckuser()) {
645
			BootstrapSkin::displayAccessDenied();
646
			BootstrapSkin::displayInternalFooter();
647
			die();
648
		}
649
650
		$database = gGetDb();
651
        
652
		$template = WelcomeTemplate::getById($_GET['del'], $database);
653
		if ($template == false) {
654
			SessionAlert::error("Something went wrong, we can't find the template you asked for!");
655
			header("Location: {$baseurl}/acc.php?action=templatemgmt");
656
			die();
657
		}
658
        
659
		$database->transactionally(function() use($database, $template)
660
		{
661
			$tid = $template->getId();
662
            
663
			$database
664
				->prepare("UPDATE user SET welcome_template = NULL WHERE welcome_template = :id;")
665
				->execute(array(":id" => $tid));
666
            
667
			Logger::welcomeTemplateDeleted($database, $template);
668
            
669
			$template->delete();
670
            
671
			SessionAlert::success("Template deleted. Any users who were using this template have had automatic welcoming disabled.");
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 124 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...
672
			Notification::welcomeTemplateDeleted($tid);
673
		});
674
        
675
		header("Location: $baseurl/acc.php?action=templatemgmt");
676
		die();			
677
	}
678
    
679
	if (isset($_GET['edit'])) {
680
		if (!User::getCurrent()->isAdmin() && !User::getCurrent()->isCheckuser()) {
681
			BootstrapSkin::displayAccessDenied();
682
			BootstrapSkin::displayInternalFooter();
683
			die();
684
		}
685
686
		$database = gGetDb();
687
        
688
		$template = WelcomeTemplate::getById($_GET['edit'], $database);
689
		if ($template == false) {
690
			SessionAlert::success("Something went wrong, we can't find the template you asked for! Please try again.");
691
			header("Location: {$baseurl}/acc.php?action=templatemgmt");
692
			die();
693
		}
694
695
		if (isset($_POST['submit'])) {
696
			$database->transactionally(function() use($database, $template)
697
			{
698
				$template->setUserCode($_POST['usercode']);
699
				$template->setBotCode($_POST['botcode']);
700
				$template->save();
701
			
702
				Logger::welcomeTemplateEdited($database, $template);
703
                
704
				SessionAlert::success("Template updated.");
705
				Notification::welcomeTemplateEdited($template);
706
			});
707
            
708
			header("Location: $baseurl/acc.php?action=templatemgmt");
709
			die();
710
		}
711
		else {
712
			$smarty->assign("template", $template);
713
			$smarty->display("welcometemplate/edit.tpl");
714
            
715
			BootstrapSkin::displayInternalFooter();
716
			die();
717
		}
718
	}
719
    
720
	$templateList = WelcomeTemplate::getAll();
721
    
722
	$smarty->assign("templatelist", $templateList);
723
	$smarty->display("welcometemplate/list.tpl");
724
    
725
	BootstrapSkin::displayInternalFooter();
726
	die();
727
}
728
elseif ($action == "sban") {
729
	global $smarty;
730
    
731
	// Checks whether the current user is an admin.
732
	if (!User::getCurrent()->isAdmin() && !User::getCurrent()->isCheckuser()) {
733
		BootstrapSkin::displayAccessDenied();
734
		BootstrapSkin::displayInternalFooter();
735
		die();
736
	}
737
	
738
	// Checks whether there is a reason entered for ban.
739
	if (!isset($_POST['banreason']) || $_POST['banreason'] == "") {
740
		BootstrapSkin::displayAlertBox("You must specify a ban reason", "alert-error", "", false, false);
741
		BootstrapSkin::displayInternalFooter();
742
		die();
743
	}
744
	
745
	// Checks whether there is a target entered to ban.
746
	if (!isset($_POST['target']) || $_POST['target'] == "") {
747
		BootstrapSkin::displayAlertBox("You must specify a target to be banned", "alert-error", "", false, false);
748
		BootstrapSkin::displayInternalFooter();
749
		die();
750
	}
751
	
752
	$duration = $_POST['duration'];
753
    
754
	if ($duration == "-1") {
755
		$duration = -1;
756
	}
757
	elseif ($duration == "other") {
758
		$duration = strtotime($_POST['otherduration']);
759
		if (!$duration) {
760
			BootstrapSkin::displayAlertBox("Invalid ban time", "alert-error", "", false, false);
761
			BootstrapSkin::displayInternalFooter();
762
			die();
763
		}
764
		elseif (time() > $duration) {
765
			BootstrapSkin::displayAlertBox("Ban time has already expired!", "alert-error", "", false, false);
766
			BootstrapSkin::displayInternalFooter();
767
			die();
768
		}
769
	}
770
	else {
771
		$duration = $duration + time();
772
	}
773
    
774
	switch ($_POST['type']) {
775
		case 'IP':
776 View Code Duplication
			if (filter_var($_POST['target'], FILTER_VALIDATE_IP) === false) {
777
				BootstrapSkin::displayAlertBox("Invalid target - IP address expected.", "alert-error", "", false, false);
778
				BootstrapSkin::displayInternalFooter();
779
				die();
780
			}
781
            
782
			global $squidIpList;
783
			if (in_array($_POST['target'], $squidIpList)) {
784
				BootstrapSkin::displayAlertBox(
785
					"This IP address is on the protected list of proxies, and cannot be banned.", 
786
					"alert-error", 
787
					"", 
788
					false, 
789
					false);
790
				BootstrapSkin::displayInternalFooter();
791
				die();
792
			}
793
			break;
794
		case 'Name':
795
			break;
796
		case 'EMail':
797
			// TODO: cut this down to a bare-bones implementation so we don't accidentally reject a valid address.
798
			if (!preg_match(';^(?:[A-Za-z0-9!#$%&\'*+/=?^_`{|}~-]+(?:\.[A-Za-z0-9!#$%&\'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?\.)+[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[A-Za-z0-9-]*[A-Za-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$;', $_POST['target'])) {
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 505 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...
799
				BootstrapSkin::displayAlertBox(
800
					"Invalid target - email address expected.", 
801
					"alert-error", 
802
					"", 
803
					false, 
804
					false);
805
                
806
				BootstrapSkin::displayInternalFooter();
807
				die();
808
			}
809
			break;
810
		default:
811
			BootstrapSkin::displayAlertBox("I don't know what type of target you want to ban! You'll need to choose from email address, IP, or requested name.", "alert-error", "", false, false);
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 185 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...
812
			BootstrapSkin::displayInternalFooter();
813
			die();
814
	}
815
        
816
	if (count(Ban::getActiveBans($_POST['target'])) > 0) {
817
		BootstrapSkin::displayAlertBox("This target is already banned!", "alert-error", "", false, false);
818
		BootstrapSkin::displayInternalFooter();
819
		die();
820
	}
821
    
822
	$database = gGetDb();
823
    
824
	$ban = new Ban();
825
    
826
	$currentUsername = User::getCurrent()->getUsername();
827
    
828
	$database->transactionally(function() use ($database, $ban, $duration, $currentUsername)
829
	{
830
		$ban->setDatabase($database);
831
		$ban->setActive(1);
832
		$ban->setType($_POST['type']);
833
		$ban->setTarget($_POST['target']);
834
		$ban->setUser($currentUsername);
835
		$ban->setReason($_POST['banreason']);
836
		$ban->setDuration($duration);
837
    
838
		$ban->save();
839
        
840
		Logger::banned($database, $ban, $_POST['banreason']);
841
	});
842
    
843
	$smarty->assign("ban", $ban);
844
	BootstrapSkin::displayAlertBox($smarty->fetch("bans/bancomplete.tpl"), "alert-info", "", false, false);
845
        
846
	Notification::banned($ban);
847
    
848
	BootstrapSkin::displayInternalFooter();
849
	die();
850
}
851
elseif ($action == "unban") {
852
	global $smarty;
853
    
854
	if (!isset($_GET['id']) || $_GET['id'] == "") {
855
		BootstrapSkin::displayAlertBox(
856
			"The ID parameter appears to be missing! This is probably a bug.", 
857
			"alert-error", 
858
			"Ahoy There! Something's not right...", 
859
			true, 
860
			false);
861
		BootstrapSkin::displayInternalFooter();
862
		die();
863
	}
864
    
865
	if (!User::getCurrent()->isAdmin() && !User::getCurrent()->isCheckuser()) {
866
		BootstrapSkin::displayAccessDenied();
867
		BootstrapSkin::displayInternalFooter();
868
		die();
869
	}
870
    
871
	$ban = Ban::getActiveId($_GET['id']);
872
        
873
	if ($ban == false) {
874
		BootstrapSkin::displayAlertBox(
875
			"The specified ban ID is not currently active or doesn't exist!", 
876
			"alert-error", 
877
			"", 
878
			false, 
879
			false);
880
        
881
		BootstrapSkin::displayInternalFooter();
882
		die();
883
	}
884
885
	if (isset($_GET['confirmunban']) && $_GET['confirmunban'] == "true") {
886
		if (!isset($_POST['unbanreason']) || $_POST['unbanreason'] == "") {
887
			BootstrapSkin::displayAlertBox("You must enter an unban reason!", "alert-error", "", false, false);
888
			BootstrapSkin::displayInternalFooter();
889
			die();
890
		}
891
		else {
892
			$database = gGetDb();
893
            
894
			$database->transactionally(function() use ($database, $ban)
895
			{
896
				$ban->setActive(0);
897
				$ban->save();
898
                
899
				$banId = $ban->getId();
900
				$currentUser = User::getCurrent()->getUsername();
901
                
902
				Logger::unbanned($database, $ban, $_POST['unbanreason']);
903
			});
904
        
905
			BootstrapSkin::displayAlertBox("Unbanned " . $ban->getTarget(), "alert-info", "", false, false);
906
			BootstrapSkin::displayInternalFooter();
907
			Notification::unbanned($ban, $_POST['unbanreason']);
908
			die();
909
		}
910
	}
911
	else {
912
		$smarty->assign("ban", $ban);
913
		$smarty->display("bans/unban.tpl");
914
        
915
		BootstrapSkin::displayInternalFooter();
916
	}
917
}
918
elseif ($action == "ban") {
919
	global $smarty;
920
    
921
	if (isset ($_GET['ip']) || isset ($_GET['email']) || isset ($_GET['name'])) {
922
		if (!User::getCurrent()->isAdmin() && !User::getCurrent()->isCheckuser()) {
923
			BootstrapSkin::displayAlertBox("Only administrators or checkusers may ban users", "alert-error");
924
			BootstrapSkin::displayInternalFooter();
925
			die();
926
		}
927
        
928
		$database = gGetDb();
929
		// TODO: rewrite me!
930
		if (isset($_GET['ip'])) {
931
			$query = "SELECT ip, forwardedip FROM request WHERE id = :ip;";
932
			$statement = $database->prepare($query);
933
			$statement->bindValue(":ip", $_GET['ip']);
934
			$statement->execute();
935
			$row = $statement->fetch(PDO::FETCH_ASSOC);
936
			$target = getTrustedClientIP($row['ip'], $row['forwardedip']);
937
			$type = "IP";
938
		}
939 View Code Duplication
		elseif (isset($_GET['email'])) {
940
			$query = "SELECT email FROM request WHERE id = :ip;";
941
			$statement = $database->prepare($query);
942
			$statement->bindValue(":ip", $_GET['email']);
943
			$statement->execute();
944
			$row = $statement->fetch(PDO::FETCH_ASSOC);
945
			$target = $row['email'];
946
			$type = "EMail";
947
		}
948 View Code Duplication
		elseif (isset($_GET['name'])) {
949
			$query = "SELECT name FROM request WHERE id = :ip;";
950
			$statement = $database->prepare($query);
951
			$statement->bindValue(":ip", $_GET['name']);
952
			$statement->execute();
953
			$row = $statement->fetch(PDO::FETCH_ASSOC);
954
			$target = $row['name'];
955
			$type = "Name";
956
		}
957
		else {
958
			BootstrapSkin::displayAlertBox("Unknown ban type.", "alert-error");
959
			BootstrapSkin::displayInternalFooter();
960
			die();    
961
		}
962
        
963
		if (count(Ban::getActiveBans($target))) {
964
			BootstrapSkin::displayAlertBox("This target is already banned!", "alert-error");
965
			BootstrapSkin::displayInternalFooter();
966
			die();
967
		} 
968
        
969
		$smarty->assign("bantype", $type);
970
		$smarty->assign("bantarget", trim($target));
971
		$smarty->display("bans/banform.tpl");
972
	}
973
	else {
974
		$bans = Ban::getActiveBans();
975
  
976
		$smarty->assign("activebans", $bans);
977
		$smarty->display("bans/banlist.tpl");
978
	}
979
    
980
	BootstrapSkin::displayInternalFooter();
981
	die();
982
}
983
elseif ($action == "defer" && $_GET['id'] != "" && $_GET['sum'] != "") {
984
	global $availableRequestStates;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
985
	
986
	if (array_key_exists($_GET['target'], $availableRequestStates)) {
987
		$request = Request::getById($_GET['id'], gGetDb());
988
		
989
		if ($request == false) {
990
			BootstrapSkin::displayAlertBox(
991
				"Could not find the specified request!", 
992
				"alert-error", 
993
				"Error!", 
994
				true, 
995
				false);
996
            
997
			BootstrapSkin::displayInternalFooter();
998
			die();
999
		}
1000
		
1001
		if ($request->getChecksum() != $_GET['sum']) {
1002
			SessionAlert::error(
1003
				"This is similar to an edit conflict on Wikipedia; it means that you have tried to perform an action "
1004
				. "on a request that someone else has performed an action on since you loaded the page",
1005
				"Invalid checksum");
1006
            
1007
			header("Location: acc.php?action=zoom&id={$request->getId()}");
1008
			die();
1009
		}
1010
        
1011
		$sqlText = <<<SQL
1012
SELECT timestamp FROM log
1013
WHERE objectid = :request and objecttype = 'Request' AND action LIKE 'Closed%'
1014
ORDER BY timestamp DESC LIMIT 1;
1015
SQL;
1016
        
1017
		$statement = gGetDb()->prepare($sqlText);
1018
		$statement->execute(array(":request" => $request->getId()));
1019
		$logTime = $statement->fetchColumn();
1020
		$statement->closeCursor();
1021
        
1022
		$date = new DateTime();
1023
		$date->modify("-7 days");
1024
		$oneweek = $date->format("Y-m-d H:i:s");
1025
        
1026
		if ($request->getStatus() == "Closed" 
1027
			&& $logTime < $oneweek 
1028
			&& !User::getCurrent()->isAdmin() 
1029
			&& !User::getCurrent()->isCheckuser()) {
1030
			SessionAlert::error("Only administrators and checkusers can reopen a request that has been closed for over a week.");
1031
			header("Location: acc.php?action=zoom&id={$request->getId()}");
1032
			die();
1033
		}
1034
        
1035
		if ($request->getStatus() == $_GET['target']) {
1036
			SessionAlert::error(
1037
				"Cannot set status, target already deferred to " . htmlentities($_GET['target']), 
1038
				"Error");
1039
			header("Location: acc.php?action=zoom&id={$request->getId()}");
1040
			die();
1041
		}
1042
        
1043
		$database = gGetDb();
1044
		$database->transactionally(function() use ($database, $request)
1045
		{
1046
			global $availableRequestStates;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1047
                
1048
			$request->setReserved(0);
1049
			$request->setStatus($_GET['target']);
1050
			$request->updateChecksum();
1051
			$request->save();
1052
            
1053
			$deto = $availableRequestStates[$_GET['target']]['deferto'];
1054
			$detolog = $availableRequestStates[$_GET['target']]['defertolog'];
1055
            
1056
			Logger::deferRequest($database, $request, $detolog);
1057
        
1058
			Notification::requestDeferred($request);
1059
			SessionAlert::success("Request {$request->getId()} deferred to $deto");
1060
			header("Location: acc.php");
1061
		});
1062
        
1063
		die();
1064
	}
1065
	else {
1066
		BootstrapSkin::displayAlertBox("Defer target not valid.", "alert-error", "Error", true, false);
1067
		BootstrapSkin::displayInternalFooter();
1068
		die();
1069
	}
1070
}
1071
elseif ($action == "prefs") {
1072
	global $smarty, $enforceOAuth;
1073
    
1074
	if (isset ($_POST['sig'])) {
1075
		$user = User::getCurrent();
1076
		$user->setWelcomeSig($_POST['sig']);
1077
		$user->setEmailSig($_POST['emailsig']);
1078
		$user->setAbortPref(isset($_POST['abortpref']) ? 1 : 0);
1079
        
1080
		if (isset($_POST['email'])) {
1081
			$mailisvalid = filter_var(trim($_POST['email']), FILTER_VALIDATE_EMAIL);
1082
            
1083
			if ($mailisvalid === false) {
1084
				BootstrapSkin::displayAlertBox("Invalid email address", "alert-error", "Error!");
1085
			}
1086
			else {
1087
				$user->setEmail(trim($_POST['email']));
1088
			}
1089
		}
1090
1091
		try {
1092
			$user->save();
1093
		}
1094
		catch (PDOException $ex) {
1095
			BootstrapSkin::displayAlertBox($ex->getMessage(), "alert-error", "Error saving Preferences", true, false);
1096
			BootstrapSkin::displayInternalFooter();
1097
			die();
1098
		}
1099
        
1100
		BootstrapSkin::displayAlertBox("Preferences updated!", "alert-info");
1101
	}
1102
    
1103
	$smarty->assign("enforceOAuth", $enforceOAuth);
1104
	$smarty->display("prefs.tpl");
1105
	BootstrapSkin::displayInternalFooter();
1106
	die();
1107
}
1108
elseif ($action == "done" && $_GET['id'] != "") {
1109
	// check for valid close reasons
1110
	global $messages, $baseurl, $smarty;
1111
	
1112
	if (isset($_GET['email'])) {
1113
		if ($_GET['email'] == 0 || $_GET['email'] == "custom") {
1114
			$validEmail = true;
1115
		}
1116
		else {
1117
			$validEmail = EmailTemplate::getById($_GET['email'], gGetDb()) != false;
1118
		}
1119
	}
1120
	else {
1121
		$validEmail = false;
1122
	}
1123
    
1124
	if ($validEmail == false) {
1125
		BootstrapSkin::displayAlertBox("Invalid close reason", "alert-error", "Error", true, false);
1126
		BootstrapSkin::displayInternalFooter();
1127
		die();
1128
	}
1129
	
1130
	// sanitise this input ready for inclusion in queries
1131
	$request = Request::getById($_GET['id'], gGetDb());
1132
    
1133
	if ($request == false) {
1134
		// Notifies the user and stops the script.
1135
		BootstrapSkin::displayAlertBox("The request ID supplied is invalid!", "alert-error", "Error", true, false);
1136
		BootstrapSkin::displayInternalFooter();
1137
		die();
1138
	}
1139
    
1140
	$gem = $_GET['email'];
1141
	
1142
	// check the checksum is valid
1143
	if ($request->getChecksum() != $_GET['sum']) {
1144
		BootstrapSkin::displayAlertBox("This is similar to an edit conflict on Wikipedia; it means that you have tried to perform an action on a request that someone else has performed an action on since you loaded the page.", "alert-error", "Invalid Checksum", true, false);
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 269 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...
1145
		BootstrapSkin::displayInternalFooter();
1146
		die();
1147
	}
1148
	
1149
	// check if an email has already been sent
1150
	if ($request->getEmailSent() == "1" && !isset($_GET['override']) && $gem != 0) {
1151
		$alertContent = "<p>This request has already been closed in a manner that has generated an e-mail to the user, Proceed?</p><br />";
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 133 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...
1152
		$alertContent .= "<div class=\"row-fluid\">";
1153
		$alertContent .= "<a class=\"btn btn-success offset3 span3\"  href=\"$baseurl/acc.php?sum=" . $_GET['sum'] . "&amp;action=done&amp;id=" . $_GET['id'] . "&amp;override=yes&amp;email=" . $_GET['email'] . "\">Yes</a>";
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 217 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...
1154
		$alertContent .= "<a class=\"btn btn-danger span3\" href=\"$baseurl/acc.php\">No</a>";
1155
		$alertContent .= "</div>";
1156
        
1157
		BootstrapSkin::displayAlertBox($alertContent, "alert-info", "Warning!", true, false, false, true);
1158
		BootstrapSkin::displayInternalFooter();
1159
		die();
1160
	}
1161
	
1162
	// check the request is not reserved by someone else
1163
	if ($request->getReserved() != 0 && !isset($_GET['reserveoverride']) && $request->getReserved() != User::getCurrent()->getId()) {
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 130 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...
1164
		$alertContent = "<p>This request is currently marked as being handled by " . $request->getReservedObject()->getUsername() . ", Proceed?</p><br />";
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 149 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...
1165
		$alertContent .= "<div class=\"row-fluid\">";
1166
		$alertContent .= "<a class=\"btn btn-success offset3 span3\"  href=\"$baseurl/acc.php?" . $_SERVER["QUERY_STRING"] . "&reserveoverride=yes\">Yes</a>";
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 152 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...
1167
		$alertContent .= "<a class=\"btn btn-danger span3\" href=\"$baseurl/acc.php\">No</a>";
1168
		$alertContent .= "</div>";
1169
        
1170
		BootstrapSkin::displayAlertBox($alertContent, "alert-info", "Warning!", true, false, false, true);
1171
		BootstrapSkin::displayInternalFooter();
1172
		die();
1173
	}
1174
	    
1175
	if ($request->getStatus() == "Closed") {
1176
		BootstrapSkin::displayAlertBox("Cannot close this request. Already closed.", "alert-error", "Error", true, false);
1177
		BootstrapSkin::displayInternalFooter();
1178
		die();
1179
	}
1180
	
1181
	// Checks whether the username is already in use on Wikipedia.
1182
	$userexist = file_get_contents("http://en.wikipedia.org/w/api.php?action=query&list=users&ususers=" . urlencode($request->getName()) . "&format=php");
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 151 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...
1183
	$ue = unserialize($userexist);
1184
	if (!isset ($ue['query']['users']['0']['missing'])) {
1185
		$exists = true;
1186
	}
1187
	else {
1188
		$exists = false;
1189
	}
1190
1191
	/** @var EmailTemplate $emailTemplate */
1192
	$emailTemplate = EmailTemplate::getById($gem, gGetDb());
1193
	if ($emailTemplate instanceof EmailTemplate) {
1194
		$isForCreated = $emailTemplate->getDefaultAction() === EmailTemplate::CREATED;
1195
	} else {
1196
		$isForCreated = false;
1197
	}
1198
1199
	// check if a request being created does not already exist.
1200
	if ($isForCreated && !$exists && !isset($_GET['createoverride'])) {
1201
		$alertContent = "<p>You have chosen to mark this request as \"created\", but the account does not exist on the English Wikipedia, proceed?</p><br />";
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 152 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...
1202
		$alertContent .= "<div class=\"row-fluid\">";
1203
		$alertContent .= "<a class=\"btn btn-success offset3 span3\"  href=\"$baseurl/acc.php?" . $_SERVER["QUERY_STRING"] . "&amp;createoverride=yes\">Yes</a>";
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 155 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...
1204
		$alertContent .= "<a class=\"btn btn-danger span3\" href=\"$baseurl/acc.php\">No</a>";
1205
		$alertContent .= "</div>";
1206
        
1207
		BootstrapSkin::displayAlertBox($alertContent, "alert-info", "Warning!", true, false, false, true);
1208
		BootstrapSkin::displayInternalFooter();
1209
		die();
1210
	}
1211
	
1212
	$messageBody = null;
1213
    
1214
	// custom close reasons
1215
	if ($gem == 'custom') {
1216
		if (!isset($_POST['msgbody']) or empty($_POST['msgbody'])) {
1217
			// Send it through htmlspecialchars so HTML validators don't complain. 
1218
			$querystring = htmlspecialchars($_SERVER["QUERY_STRING"], ENT_COMPAT, 'UTF-8'); 
1219
            
1220
			$template = false;
1221
			if (isset($_GET['preload'])) {
1222
				$template = EmailTemplate::getById($_GET['preload'], gGetDb());
1223
			}
1224
            
1225
			if ($template != false) {
1226
				$preloadTitle = $template->getName();
1227
				$preloadText = $template->getText();
1228
				$preloadAction = $template->getDefaultAction();
1229
			}
1230
			else {
1231
				$preloadText = "";
1232
				$preloadTitle = "";
1233
				$preloadAction = "";
1234
			}
1235
            
1236
			$smarty->assign("requeststates", $availableRequestStates);
1237
			$smarty->assign("defaultAction", $preloadAction);
1238
			$smarty->assign("preloadtext", $preloadText);
1239
			$smarty->assign("preloadtitle", $preloadTitle);
1240
			$smarty->assign("querystring", $querystring);
1241
			$smarty->assign("request", $request);
1242
			$smarty->assign("iplocation", $locationProvider->getIpLocation($request->getTrustedIp()));
1243
			$smarty->display("custom-close.tpl");
1244
			BootstrapSkin::displayInternalFooter();
1245
			die();
1246
		}
1247
1248
		$headers = 'From: [email protected]' . "\r\n";
1249
		if (!User::getCurrent()->isAdmin() || isset($_POST['ccmailist']) && $_POST['ccmailist'] == "on") {
1250
			$headers .= 'Cc: [email protected]' . "\r\n";
1251
		}
1252
1253
		$headers .= 'X-ACC-Request: ' . $request->getId() . "\r\n";
1254
		$headers .= 'X-ACC-UserID: ' . User::getCurrent()->getId() . "\r\n";
1255
1256
		// Get the closing user's Email signature and append it to the Email.
1257
		if (User::getCurrent()->getEmailSig() != "") {
1258
			$emailsig = html_entity_decode(User::getCurrent()->getEmailSig(), ENT_QUOTES, "UTF-8");
1259
			mail($request->getEmail(), "RE: [ACC #{$request->getId()}] English Wikipedia Account Request", $_POST['msgbody'] . "\n\n" . $emailsig, $headers);
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 148 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...
1260
		}
1261
		else {
1262
			mail($request->getEmail(), "RE: [ACC #{$request->getId()}] English Wikipedia Account Request", $_POST['msgbody'], $headers);
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 127 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...
1263
		}
1264
1265
		$request->setEmailSent(1);
1266
		$messageBody = $_POST['msgbody'];
1267
1268
		if ($_POST['action'] == EmailTemplate::CREATED || $_POST['action'] == EmailTemplate::NOT_CREATED) {
1269
			$request->setStatus('Closed');
1270
1271
			if ($_POST['action'] == EmailTemplate::CREATED) {
1272
				$gem  = 'custom-y';
1273
				$crea = "Custom, Created";
1274
			}
1275
			else {
1276
				$gem  = 'custom-n';
1277
				$crea = "Custom, Not Created";
1278
			}
1279
1280
			Logger::closeRequest(gGetDb(), $request, $gem, $messageBody);
0 ignored issues
show
$request is of type object<DataObject>|null, but the function expects a object<Request>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1281
			
1282
			Notification::requestClosed($request, $crea);
0 ignored issues
show
$request is of type object<DataObject>|null, but the function expects a object<Request>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1283
			BootstrapSkin::displayAlertBox(
1284
				"Request " . $request->getId() . " (" . htmlentities($request->getName(), ENT_COMPAT, 'UTF-8') . ") marked as 'Done'.", 
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 124 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...
1285
				"alert-success");
1286
		}
1287
		else if ($_POST['action'] == "mail") {
1288
			// no action other than send mail!
1289
			Logger::sentMail(gGetDb(), $request, $messageBody);
0 ignored issues
show
$request is of type object<DataObject>|null, but the function expects a object<Request>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1290
			Logger::unreserve(gGetDb(), $request);
0 ignored issues
show
$request is of type object<DataObject>|null, but the function expects a object<Request>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1291
1292
			Notification::sentMail($request);
0 ignored issues
show
$request is of type object<DataObject>|null, but the function expects a object<Request>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1293
			BootstrapSkin::displayAlertBox("Sent mail to Request {$request->getId()}", 
1294
				"alert-success");
1295
		}
1296
		else if (array_key_exists($_POST['action'], $availableRequestStates)) {
1297
			// Defer
1298
1299
			$request->setStatus($_POST['action']);
1300
			$deto = $availableRequestStates[$_POST['action']]['deferto'];
1301
			$detolog = $availableRequestStates[$_POST['action']]['defertolog'];
1302
1303
			Logger::sentMail(gGetDb(), $request, $messageBody);
0 ignored issues
show
$request is of type object<DataObject>|null, but the function expects a object<Request>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1304
			Logger::deferRequest(gGetDb(), $request, $detolog);
0 ignored issues
show
$request is of type object<DataObject>|null, but the function expects a object<Request>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1305
			
1306
			Notification::requestDeferredWithMail($request);
0 ignored issues
show
$request is of type object<DataObject>|null, but the function expects a object<Request>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1307
			BootstrapSkin::displayAlertBox("Request {$request->getId()} deferred to $deto, sending an email.", 
1308
				"alert-success");
1309
		}
1310
		else {
1311
			// hmm. not sure what happened. Log that we sent the mail anyway.
1312
			Logger::sentMail(gGetDb(), $request, $messageBody);
0 ignored issues
show
$request is of type object<DataObject>|null, but the function expects a object<Request>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1313
			Logger::unreserve(gGetDb(), $request);
0 ignored issues
show
$request is of type object<DataObject>|null, but the function expects a object<Request>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1314
1315
			Notification::sentMail($request);
0 ignored issues
show
$request is of type object<DataObject>|null, but the function expects a object<Request>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1316
			BootstrapSkin::displayAlertBox("Sent mail to Request {$request->getId()}", 
1317
				"alert-success");
1318
		}
1319
1320
		$request->setReserved(0);
1321
		$request->save();
1322
		
1323
		$request->updateChecksum();
1324
		$request->save();
1325
1326
		echo defaultpage();
1327
		BootstrapSkin::displayInternalFooter();
1328
		die();		
1329
	}
1330
	else {
1331
		// Not a custom close, just a normal close
1332
	    
1333
		$request->setStatus('Closed');
1334
		$request->setReserved(0);
1335
		
1336
		// TODO: make this transactional
1337
		$request->save();
1338
		
1339
		Logger::closeRequest(gGetDb(), $request, $gem, $messageBody);
0 ignored issues
show
$request is of type object<DataObject>|null, but the function expects a object<Request>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1340
		
1341
		if ($gem == '0') {
1342
			$crea = "Dropped";
1343
		}
1344
		else {
1345
			$template = EmailTemplate::getById($gem, gGetDb());
1346
			$crea = $template->getName();
1347
		}
1348
1349
		Notification::requestClosed($request, $crea);
0 ignored issues
show
$request is of type object<DataObject>|null, but the function expects a object<Request>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1350
		BootstrapSkin::displayAlertBox("Request " . $request->getId() . " (" . htmlentities($request->getName(), ENT_COMPAT, 'UTF-8') . ") marked as 'Done'.", "alert-success");
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 170 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...
1351
		
1352
		$towhom = $request->getEmail();
1353
		if ($gem != "0") {
1354
			sendemail($gem, $towhom, $request->getId());
1355
			$request->setEmailSent(1);
1356
		}
1357
		
1358
		$request->updateChecksum();
1359
		$request->save();
1360
		
1361
		echo defaultpage();
1362
		BootstrapSkin::displayInternalFooter();
1363
		die();
1364
	}
1365
}
1366
elseif ($action == "zoom") {
1367
	if (!isset($_GET['id'])) {
1368
		BootstrapSkin::displayAlertBox("No request specified!", "alert-error", "Error!", true, false);
1369
		BootstrapSkin::displayInternalFooter();
1370
		die();
1371
	}
1372
    
1373
	if (isset($_GET['hash'])) {
1374
		$urlhash = $_GET['hash'];
1375
	}
1376
	else {
1377
		$urlhash = "";
1378
	}
1379
	echo zoomPage($_GET['id'], $urlhash);
1380
1381
	$tailscript = getTypeaheadSource(User::getAllUsernames(gGetDb()));
1382
	BootstrapSkin::displayInternalFooter($tailscript);
1383
	die();
1384
}
1385
elseif ($action == "logs") {
1386
	global $baseurl;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1387
	
1388
	$filterUser = isset($_GET['filterUser']) && $_GET['filterUser'] != "" ? $_GET['filterUser'] : false;
1389
	$filterAction = isset($_GET['filterAction']) && $_GET['filterAction'] != "" ? $_GET['filterAction'] : false;
1390
	
1391
	$limit = 100;
1392
	if (isset($_GET['limit'])) {
1393
		$limit = (int)$_GET['limit'];
1394
	}
1395
	
1396
	$offset = 0;
1397
	$page = 1;
1398
	if (isset($_GET['page'])) {
1399
		$page = (int)$_GET['page'];
1400
		$offset = ($page - 1) * $limit;
1401
	}
1402
	
1403
	$logs = Logger::getLogs($filterUser, $filterAction, $limit, $offset);
1404
	if ($logs === false) {
1405
		$smarty->assign("logs", array());
1406
		$smarty->display("logs/main.tpl");
1407
		BootstrapSkin::displayInternalFooter();
1408
		die();
1409
	}
1410
	
1411
	$count = $logs['count'];
1412
	unset($logs['count']);
1413
	
1414
	// The number of pages on the pager to show. Must be odd
1415
	$pageLimit = 9;
1416
	
1417
	$pageData = array( 
1418
		'canprev' => $page != 1,
1419
		'cannext' => ($page * $limit) < $count,
1420
		'maxpage' => ceil($count / $limit),
1421
		'pagelimit' => $pageLimit,
1422
	);
1423
	
1424
	$pageMargin = (($pageLimit - 1) / 2);
1425
	$pageData['lowpage'] = max(1, $page - $pageMargin);
1426
	$pageData['hipage'] = min($pageData['maxpage'], $page + $pageMargin);
1427
	
1428
	$pageCount = ($pageData['hipage'] - $pageData['lowpage']) + 1;
1429
	
1430
	if ($pageCount < $pageLimit) {
1431
		if ($pageData['lowpage'] == 1 && $pageData['hipage'] == $pageData['maxpage']) {
1432
			// nothing to do, we're already at max range.	
1433
		}
1434 View Code Duplication
		elseif ($pageData['lowpage'] == 1 && $pageData['hipage'] < $pageData['maxpage']) {
1435
			$pageData['hipage'] = min($pageLimit, $pageData['maxpage']);
1436
		}
1437 View Code Duplication
		elseif ($pageData['lowpage'] > 1 && $pageData['hipage'] == $pageData['maxpage']) {
1438
			$pageData['lowpage'] = max(1, $pageData['maxpage'] - $pageLimit + 1);
1439
		}
1440
	}
1441
	
1442
	$pageData['pages'] = range($pageData['lowpage'], $pageData['hipage']);
1443
		
1444
	$smarty->assign("pagedata", $pageData);
1445
	
1446
	$smarty->assign("limit", $limit);
1447
	$smarty->assign("page", $page);
1448
1449
	$smarty->assign("logs", $logs);
1450
	
1451
	
1452
	$smarty->assign("filterUser", $filterUser);
1453
	$smarty->assign("filterAction", $filterAction);
1454
	$smarty->display("logs/main.tpl");
1455
1456
	$tailscript = getTypeaheadSource(User::getAllUsernames(gGetDb(), true));
1457
	
1458
	BootstrapSkin::displayInternalFooter($tailscript);
1459
	die();
1460
}
1461
elseif ($action == "reserve") {
1462
	$database = gGetDb();
1463
    
1464
	$database->transactionally(function() use ($database)
1465
	{
1466
		$request = Request::getById($_GET['resid'], $database);
1467
        
1468
		if ($request == false) {
1469
			throw new TransactionException("Request not found", "Error");
1470
		}
1471
        
1472
		global $enableEmailConfirm, $baseurl;
1473
		if ($enableEmailConfirm == 1) {
1474
			if ($request->getEmailConfirm() != "Confirmed") {
1475
				throw new TransactionException("Email address not yet confirmed for this request.", "Error");
1476
			}
1477
		}
1478
1479
		$logQuery = $database->prepare(<<<SQL
1480
SELECT timestamp FROM log
1481
WHERE objectid = :request AND objecttype = 'Request' AND action LIKE 'Closed%'
1482
ORDER BY timestamp DESC LIMIT 1;
1483
SQL
1484
		);
1485
		$logQuery->bindValue(":request", $request->getId());
1486
		$logQuery->execute();
1487
		$logTime = $logQuery->fetchColumn();
1488
		$logQuery->closeCursor();
1489
        
1490
		$date = new DateTime();
1491
		$date->modify("-7 days");
1492
		$oneweek = $date->format("Y-m-d H:i:s");
1493
        
1494
		if ($request->getStatus() == "Closed" && $logTime < $oneweek && !User::getCurrent($database)->isAdmin()) {
1495
			throw new TransactionException("Only administrators and checkusers can reserve a request that has been closed for over a week.", "Error");
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 141 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...
1496
		}
1497
        
1498
	   	if ($request->getReserved() != 0 && $request->getReserved() != User::getCurrent($database)->getId()) {
1499
			throw new TransactionException("Request is already reserved by {$request->getReservedObject()->getUsername()}.", "Error");
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 125 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...
1500
		}
1501
           
1502
		if ($request->getReserved() == 0) {
1503
			// Check the number of requests a user has reserved already
1504
			$doubleReserveCountQuery = $database->prepare("SELECT COUNT(*) FROM request WHERE reserved = :userid;");
1505
			$doubleReserveCountQuery->bindValue(":userid", User::getCurrent($database)->getId());
1506
			$doubleReserveCountQuery->execute();
1507
			$doubleReserveCount = $doubleReserveCountQuery->fetchColumn();
1508
			$doubleReserveCountQuery->closeCursor();
1509
1510
			// User already has at least one reserved. 
1511
			if ($doubleReserveCount != 0) {
1512
				SessionAlert::warning("You have multiple requests reserved!");
1513
			}
1514
1515
			// Is the request closed?
1516
			if (!isset($_GET['confclosed'])) {
1517
				if ($request->getStatus() == "Closed") {
1518
					// FIXME: bootstrappify properly
1519
					throw new TransactionException('This request is currently closed. Are you sure you wish to reserve it?<br /><ul><li><a href="' . $_SERVER["REQUEST_URI"] . '&confclosed=yes">Yes, reserve this closed request</a></li><li><a href="' . $baseurl . '/acc.php">No, return to main request interface</a></li></ul>', "Request closed", "alert-info");
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 343 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...
1520
				}
1521
			}	
1522
        
1523
			$request->setReserved(User::getCurrent($database)->getId());
1524
			$request->save();
1525
	
1526
			Logger::reserve($database, $request);
1527
                
1528
			Notification::requestReserved($request);
1529
                
1530
			SessionAlert::success("Reserved request {$request->getId()}.");
1531
		}
1532
        
1533
		header("Location: $baseurl/acc.php?action=zoom&id={$request->getId()}");
1534
	});
1535
	    
1536
	die();	
1537
}
1538
elseif ($action == "breakreserve") {
1539
	global $smarty;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1540
    
1541
	$database = gGetDb();
1542
    
1543
	$request = Request::getById($_GET['resid'], $database);
1544
        
1545
	if ($request == false) {
1546
		BootstrapSkin::displayAlertBox("Could not find request.", "alert-error", "Error", true, false);
1547
		BootstrapSkin::displayInternalFooter();
1548
		die();
1549
	}
1550
    
1551
	if ($request->getReserved() == 0) {
1552
		BootstrapSkin::displayAlertBox("Request is not reserved.", "alert-error", "Error", true, false);
1553
		BootstrapSkin::displayInternalFooter();
1554
		die();
1555
	}
1556
    
1557
	$reservedUser = $request->getReservedObject();
1558
    
1559
	if ($reservedUser == false) {
1560
		BootstrapSkin::displayAlertBox("Could not find user who reserved the request (!!).", "alert-error", "Error", true, false);
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 124 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...
1561
		BootstrapSkin::displayInternalFooter();
1562
		die();
1563
	}
1564
    
1565
	if ($reservedUser->getId() != User::getCurrent()->getId()) {
1566
		if (User::getCurrent()->isAdmin()) {
1567
			if (isset($_GET['confirm']) && $_GET['confirm'] == 1) {
1568
				$database->transactionally(function() use($database, $request)
1569
				{
1570
					$request->setReserved(0);
1571
					$request->save();
1572
1573
					Logger::breakReserve($database, $request);
1574
                
1575
					Notification::requestReserveBroken($request);
1576
					header("Location: acc.php");
1577
				});
1578
                
1579
				die();
1580
			}
1581
			else {
1582
				global $baseurl;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1583
				$smarty->assign("reservedUser", $reservedUser);
1584
				$smarty->assign("request", $request);
1585
                
1586
				$smarty->display("confirmations/breakreserve.tpl");
1587
			}
1588
		}
1589
		else {
1590
			echo "You cannot break " . htmlentities($reservedUser->getUsername()) . "'s reservation";
1591
		}
1592
	}
1593
	else {
1594
		$database->transactionally(function() use ($database, $request)
1595
		{
1596
			$request->setReserved(0);
1597
			$request->save();
1598
1599
			Logger::unreserve($database, $request);
1600
        
1601
			Notification::requestUnreserved($request);
1602
			header("Location: acc.php");
1603
		});
1604
        
1605
		die();
1606
	}
1607
    
1608
	BootstrapSkin::displayInternalFooter();
1609
	die();		
1610
}
1611
elseif ($action == "comment") {
1612
	global $smarty;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1613
    
1614
	$request = Request::getById($_GET['id'], gGetDb());
1615
	$smarty->assign("request", $request);
1616
	$smarty->display("commentform.tpl");
1617
	BootstrapSkin::displayInternalFooter();
1618
	die();
1619
}
1620
elseif ($action == "comment-add") {
1621
	global $baseurl, $smarty;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1622
    
1623
	$request = Request::getById($_POST['id'], gGetDb());
1624
	if ($request == false) {
1625
		BootstrapSkin::displayAlertBox("Could not find request!", "alert-error", "Error", true, false);
1626
		BootstrapSkin::displayInternalFooter();
1627
		die();
1628
	}
1629
    
1630
	if (!isset($_POST['comment']) || $_POST['comment'] == "") {
1631
		BootstrapSkin::displayAlertBox("Comment must be supplied!", "alert-error", "Error", true, false);
1632
		BootstrapSkin::displayInternalFooter();
1633
		die(); 
1634
	}
1635
    
1636
	$visibility = 'user';
1637
	if (isset($_POST['visibility'])) {
1638
		// sanity check
1639
		$visibility = $_POST['visibility'] == 'user' ? 'user' : 'admin';
1640
	}
1641
    
1642
	//Look for and detect IPv4/IPv6 addresses in comment text, and warn the commenter.
1643 View Code Duplication
	if ((preg_match('/\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/', $_POST['comment']) || preg_match('/(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/', $_POST['comment'])) && $_POST['privpol-check-override'] != "override") {
0 ignored issues
show
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...
This line exceeds maximum limit of 120 characters; contains 886 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...
1644
			BootstrapSkin::displayAlertBox("IP address detected in comment text.  Warning acknowledgement checkbox must be checked.", "alert-error", "Error", true, false);
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 162 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...
1645
			$smarty->assign("request", $request);
1646
			$smarty->assign("comment", $_POST['comment']);
1647
			$smarty->assign("actionLocation", "comment-add");
1648
			$smarty->display("privpol-warning.tpl");
1649
			BootstrapSkin::displayInternalFooter();
1650
			die();
1651
		}
1652
    
1653
	$comment = new Comment();
1654
	$comment->setDatabase(gGetDb());
1655
    
1656
	$comment->setRequest($request->getId());
1657
	$comment->setVisibility($visibility);
1658
	$comment->setUser(User::getCurrent()->getId());
1659
	$comment->setComment($_POST['comment']);
1660
    
1661
	$comment->save();
1662
    
1663
	if (isset($_GET['hash'])) {
1664
		$urlhash = urlencode(htmlentities($_GET['hash']));
1665
	}
1666
	else {
1667
		$urlhash = "";
1668
	}
1669
1670
	BootstrapSkin::displayAlertBox(
1671
		"<a href='$baseurl/acc.php?action=zoom&amp;id={$request->getId()}&amp;hash=$urlhash'>Return to request #{$request->getId()}</a>",
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 131 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...
1672
		"alert-success",
1673
		"Comment added Successfully!",
1674
		true, false);
1675
        
1676
	Notification::commentCreated($comment);
1677
        
1678
	BootstrapSkin::displayInternalFooter();
1679
	die();
1680
}
1681
elseif ($action == "comment-quick") {
1682
	$request = Request::getById($_POST['id'], gGetDb());
1683
	if ($request == false) {
1684
		BootstrapSkin::displayAlertBox("Could not find request!", "alert-error", "Error", true, false);
1685
		BootstrapSkin::displayInternalFooter();
1686
		die();
1687
	}
1688
    
1689
	if (!isset($_POST['comment']) || $_POST['comment'] == "") {
1690
		header("Location: acc.php?action=zoom&id=" . $request->getId());
1691
		die(); 
1692
	}
1693
    
1694
	$visibility = 'user';
1695
	if (isset($_POST['visibility'])) {
1696
		// sanity check
1697
		$visibility = $_POST['visibility'] == 'user' ? 'user' : 'admin';
1698
	}
1699
1700
	//Look for and detect IPv4/IPv6 addresses in comment text, and warn the commenter.
1701 View Code Duplication
	if ((preg_match('/\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/', $_POST['comment']) || preg_match('/(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/', $_POST['comment'])) && $_POST['privpol-check-override'] != "override") {
0 ignored issues
show
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...
This line exceeds maximum limit of 120 characters; contains 886 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...
1702
			BootstrapSkin::displayAlertBox("IP address detected in comment text.  Warning acknowledgement checkbox must be checked.", "alert-error", "Error", true, false);
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 162 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...
1703
			$smarty->assign("request", $request);
1704
			$smarty->assign("comment", $_POST['comment']);
1705
			$smarty->assign("actionLocation", "comment-quick");
1706
			$smarty->display("privpol-warning.tpl");
1707
			BootstrapSkin::displayInternalFooter();
1708
			die();
1709
		}
1710
    
1711
	$comment = new Comment();
1712
	$comment->setDatabase(gGetDb());
1713
    
1714
	$comment->setRequest($request->getId());
1715
	$comment->setVisibility($visibility);
1716
	$comment->setUser(User::getCurrent()->getId());
1717
	$comment->setComment($_POST['comment']);
1718
    
1719
	$comment->save();
1720
    
1721
	Notification::commentCreated($comment);
1722
    
1723
	header("Location: acc.php?action=zoom&id=" . $request->getId());
1724
}
1725
elseif ($action == "changepassword") {
1726
	if ((!isset($_POST['oldpassword'])) || $_POST['oldpassword'] == "") {
1727
		//Throw an error if old password is not specified.
1728
		BootstrapSkin::displayAlertBox("You did not enter your old password.", "alert-error", "Error", true, false);
1729
		BootstrapSkin::displayInternalFooter();
1730
		die();
1731
	}
1732
	
1733 View Code Duplication
	if ((!isset($_POST['newpassword'])) || $_POST['newpassword'] == "") {
1734
		//Throw an error if new password is not specified.
1735
		BootstrapSkin::displayAlertBox("You did not enter your new password.", "alert-error", "Error", true, false);
1736
		BootstrapSkin::displayInternalFooter();
1737
		die();
1738
	}
1739
	
1740 View Code Duplication
	if ($_POST['newpassword'] != $_POST['newpasswordconfirm']) {
1741
		//Throw an error if new password does not match what is in the confirmation box.
1742
		BootstrapSkin::displayAlertBox("The 2 new passwords you entered do not match.", "alert-error", "Error", true, false);
1743
		BootstrapSkin::displayInternalFooter();
1744
		die();
1745
	}
1746
    
1747
	$user = User::getCurrent();
1748
	   
1749
	if (!$user->authenticate($_POST['oldpassword'])) {
1750
		//Throw an error if the old password field's value does not match the user's current password.
1751
		BootstrapSkin::displayAlertBox("The old password you entered is not correct.", "alert-error", "Error", true, false);
1752
		BootstrapSkin::displayInternalFooter();
1753
		die();
1754
	}
1755
    
1756
	$user->setPassword($_POST['newpassword']);
1757
	$user->save();
1758
    
1759
	BootstrapSkin::displayAlertBox("Password successfully changed!", "alert-success", "", false, false);
1760
	BootstrapSkin::displayInternalFooter();
1761
	die();
1762
}
1763
elseif ($action == "ec") {
1764
	// edit comment
1765
  
1766
	global $smarty, $baseurl;
1767
    
1768
	$comment = Comment::getById($_GET['id'], gGetDb());
1769
    
1770
	if ($comment == false) {
1771
		// Only using die("Message"); for errors looks ugly.
1772
		BootstrapSkin::displayAlertBox("Comment not found.", "alert-error", "Error", true, false);
1773
		BootstrapSkin::displayInternalFooter();
1774
		die();
1775
	}
1776
	
1777
	// Unauthorized if user is not an admin or the user who made the comment being edited.
1778
	if (!User::getCurrent()->isAdmin() && !User::getCurrent()->isCheckuser() && $comment->getUser() != User::getCurrent()->getId()) {
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 130 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...
1779
		BootstrapSkin::displayAccessDenied();
1780
		BootstrapSkin::displayInternalFooter();
1781
		die();
1782
	}
1783
	
1784
	// get[id] is safe by this point.
1785
	
1786
	if ($_SERVER['REQUEST_METHOD'] == 'POST') {
1787
		$database = gGetDb();
1788 View Code Duplication
		$database->transactionally(function() use ($database, $comment, $baseurl)
1789
		{
1790
            
1791
			$comment->setComment($_POST['newcomment']);
1792
			$comment->setVisibility($_POST['visibility']);
1793
        
1794
			$comment->save();
1795
        
1796
			Logger::editComment($database, $comment);
1797
        
1798
			Notification::commentEdited($comment);
1799
        
1800
			SessionAlert::success("Comment has been saved successfully");
1801
			header("Location: $baseurl/acc.php?action=zoom&id=" . $comment->getRequest());
1802
		});
1803
        
1804
		die();    
1805
	}
1806
	else {
1807
		$smarty->assign("comment", $comment);
1808
		$smarty->display("edit-comment.tpl");
1809
		BootstrapSkin::displayInternalFooter();
1810
		die();
1811
	}
1812
}
1813
elseif ($action == "sendtouser") {
1814
	global $baseurl;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1815
    
1816
	$database = gGetDb();
1817
1818
	/** @var Request $requestObject */
1819
	$requestObject = Request::getById($_POST['id'], $database);
1820
	if ($requestObject == false) {
1821
		BootstrapSkin::displayAlertBox("Request invalid", "alert-error", "Could not find request", true, false);
1822
		BootstrapSkin::displayInternalFooter();
1823
		die();
1824
	}
1825
    
1826
	$request = $requestObject->getId();
1827
    
1828
	$user = User::getByUsername($_POST['user'], $database);
1829
	$curuser = User::getCurrent()->getUsername();
1830
    
1831
	if ($user == false) {
1832
		BootstrapSkin::displayAlertBox("We couldn't find the user you wanted to send the reservation to. Please check that this user exists and is an active user on the tool.", "alert-error", "Could not find user", true, false);
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 222 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...
1833
		BootstrapSkin::displayInternalFooter();
1834
		die();
1835
	}
1836
    
1837
	$database->transactionally(function() use ($database, $user, $requestObject, $curuser)
1838
	{
1839
		$updateStatement = $database->prepare("UPDATE request SET reserved = :userid WHERE id = :request LIMIT 1;");
1840
		$updateStatement->bindValue(":userid", $user->getId());
1841
		$updateStatement->bindValue(":request", $requestObject->getId());
1842
		if (!$updateStatement->execute()) {
1843
			throw new TransactionException("Error updating reserved status of request.");   
1844
		}
1845
        
1846
		Logger::sendReservation($database, $requestObject, $user);
1847
	});
1848
    
1849
	Notification::requestReservationSent($requestObject, $user);
1850
	SessionAlert::success("Reservation sent successfully");
1851
	header("Location: $baseurl/acc.php?action=zoom&id=$request");
1852
}
1853
elseif ($action == "emailmgmt") {
1854
	global $smarty, $createdid, $availableRequestStates;
1855
    
1856
	/* New page for managing Emails, since I would rather not be handling editing
1857
	interface messages (such as the Sitenotice) and the new Emails in the same place. */
1858
	if (isset($_GET['create'])) {
1859
		if (!User::getCurrent()->isAdmin()) {
1860
			BootstrapSkin::displayAccessDenied();
1861
			BootstrapSkin::displayInternalFooter();
1862
			die();
1863
		}
1864
		if (isset($_POST['submit'])) {
1865
			$database = gGetDb();
1866
			$database->transactionally(function() use ($database)
1867
			{
1868
				global $baseurl;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1869
                
1870
				$emailTemplate = new EmailTemplate();
1871
				$emailTemplate->setDatabase($database);
1872
            
1873
				$emailTemplate->setName($_POST['name']);
1874
				$emailTemplate->setText($_POST['text']);
1875
				$emailTemplate->setJsquestion($_POST['jsquestion']);
1876
				$emailTemplate->setDefaultAction($_POST['defaultaction']);
1877
				$emailTemplate->setActive(isset($_POST['active']));
1878
1879
				// Check if the entered name already exists (since these names are going to be used as the labels for buttons on the zoom page).
0 ignored issues
show
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...
1880
				// getByName(...) returns false on no records found.
1881
				if (EmailTemplate::getByName($_POST['name'], $database)) {
1882
					throw new TransactionException("That Email template name is already being used. Please choose another.");
1883
				}
1884
			
1885
				$emailTemplate->save();
1886
                
1887
				Logger::createEmail($database, $emailTemplate);
1888
                
1889
				Notification::emailCreated($emailTemplate);
1890
                
1891
				SessionAlert::success("Email template has been saved successfully.");
1892
				header("Location: $baseurl/acc.php?action=emailmgmt");
1893
			});
1894
            
1895
			die();
1896
		}
1897
        
1898
		$smarty->assign('id', null);
1899
		$smarty->assign('createdid', $createdid);
1900
		$smarty->assign('requeststates', $availableRequestStates);
1901
		$smarty->assign('emailTemplate', new EmailTemplate());
1902
		$smarty->assign('emailmgmtpage', 'Create'); //Use a variable so we don't need two Smarty templates for creating and editing.
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 126 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...
1903
		$smarty->display("email-management/edit.tpl");
1904
		BootstrapSkin::displayInternalFooter();
1905
		die();
1906
	}
1907
	if (isset($_GET['edit'])) {
1908
		global $createdid;
1909
        
1910
		$database = gGetDb();
1911
        
1912
		if (isset($_POST['submit'])) {
1913
			$emailTemplate = EmailTemplate::getById($_GET['edit'], $database);
1914
			// Allow the user to see the edit form (with read only fields) but not POST anything.
1915
			if (!User::getCurrent()->isAdmin()) {
1916
				BootstrapSkin::displayAccessDenied();
1917
				BootstrapSkin::displayInternalFooter();
1918
				die();
1919
			}
1920
            
1921
			$emailTemplate->setName($_POST['name']);
1922
			$emailTemplate->setText($_POST['text']);
1923
			$emailTemplate->setJsquestion($_POST['jsquestion']);
1924
			
1925
			if ($_GET['edit'] == $createdid) {
1926
				// Both checkboxes on the main created message should always be enabled.
1927
				$emailTemplate->setDefaultAction(EmailTemplate::CREATED);
1928
				$emailTemplate->setActive(1);
1929
				$emailTemplate->setPreloadOnly(0);
1930
			}
1931
			else {
1932
				$emailTemplate->setDefaultAction($_POST['defaultaction']);
1933
				$emailTemplate->setActive(isset($_POST['active']));
1934
				$emailTemplate->setPreloadOnly(isset($_POST['preloadonly']));
1935
			}
1936
				
1937
			// Check if the entered name already exists (since these names are going to be used as the labels for buttons on the zoom page).
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 131 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...
1938
			$nameCheck = EmailTemplate::getByName($_POST['name'], gGetDb());
1939
			if ($nameCheck != false && $nameCheck->getId() != $_GET['edit']) {
1940
				BootstrapSkin::displayAlertBox("That Email template name is already being used. Please choose another.");
1941
				BootstrapSkin::displayInternalFooter();
1942
				die();
1943
			}
1944
1945
			$database->transactionally(function() use ($database, $emailTemplate)
1946
			{
1947
				$emailTemplate->save();
1948
                
1949
				Logger::editedEmail($database, $emailTemplate);
1950
            
1951
				global $baseurl;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1952
                
1953
				Notification::emailEdited($emailTemplate);
1954
				SessionAlert::success("Email template has been saved successfully.");
1955
				header("Location: $baseurl/acc.php?action=emailmgmt");
1956
			});
1957
            
1958
			die();
1959
		}
1960
        
1961
		$emailTemplate = EmailTemplate::getById($_GET['edit'], gGetDb());
1962
		$smarty->assign('id', $emailTemplate->getId());
1963
		$smarty->assign('emailTemplate', $emailTemplate);
1964
		$smarty->assign('createdid', $createdid);
1965
		$smarty->assign('requeststates', $availableRequestStates);
1966
		$smarty->assign('emailmgmtpage', 'Edit'); // Use a variable so we don't need two Smarty templates for creating and editing.
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 125 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...
1967
		$smarty->display("email-management/edit.tpl");
1968
		BootstrapSkin::displayInternalFooter();
1969
		die();
1970
	}
1971
    
1972
	$query = "SELECT * FROM emailtemplate WHERE active = 1";
1973
	$statement = gGetDb()->prepare($query);
1974
	$statement->execute();
1975
	$rows = $statement->fetchAll(PDO::FETCH_CLASS, "EmailTemplate");
1976
	$smarty->assign('activeemails', $rows);
1977
        
1978
	$query = "SELECT * FROM emailtemplate WHERE active = 0";
1979
	$statement = gGetDb()->prepare($query);
1980
	$statement->execute();
1981
	$inactiverows = $statement->fetchAll(PDO::FETCH_CLASS, "EmailTemplate");
1982
	$smarty->assign('inactiveemails', $inactiverows);
1983
 
1984
	if (count($inactiverows) > 0) {
1985
		$smarty->assign('displayinactive', true);
1986
	}
1987
	else {
1988
		$smarty->assign('displayinactive', false);
1989
	}
1990
    
1991
	$smarty->display("email-management/main.tpl");
1992
	BootstrapSkin::displayInternalFooter();
1993
	die();
1994
}
1995
elseif ($action == "oauthdetach") {
1996
	if ($enforceOAuth) {
1997
		BootstrapSkin::displayAccessDenied();
1998
		BootstrapSkin::displayInternalFooter();
1999
		die();
2000
	}
2001
    
2002
	global $baseurl;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
2003
        
2004
	$currentUser = User::getCurrent();
2005
	$currentUser->detachAccount();
2006
        
2007
	header("Location: {$baseurl}/acc.php?action=logout");
2008
}
2009
elseif ($action == "oauthattach") {
2010
	$database = gGetDb();
2011 View Code Duplication
	$database->transactionally(function() use ($database)
2012
	{
2013
		try {
2014
			global $oauthConsumerToken, $oauthSecretToken, $oauthBaseUrl, $oauthBaseUrlInternal;
2015
            
2016
			$user = User::getCurrent();
2017
            
2018
			// Get a request token for OAuth
2019
			$util = new OAuthUtility($oauthConsumerToken, $oauthSecretToken, $oauthBaseUrl, $oauthBaseUrlInternal);
2020
			$requestToken = $util->getRequestToken();
2021
2022
			// save the request token for later
2023
			$user->setOAuthRequestToken($requestToken->key);
2024
			$user->setOAuthRequestSecret($requestToken->secret);
2025
			$user->save();
2026
        
2027
			$redirectUrl = $util->getAuthoriseUrl($requestToken);
2028
        
2029
			header("Location: {$redirectUrl}");
2030
        
2031
		}
2032
		catch (Exception $ex) {
2033
			throw new TransactionException($ex->getMessage(), "Connection to Wikipedia failed.", "alert-error", 0, $ex);
2034
		}
2035
	});
2036
}
2037
elseif ($action == "listall") {
2038
    global $availableRequestStates, $enableEmailConfirm;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
2039
2040
	if (isset($_GET['status']) && isset($availableRequestStates[$_GET['status']])) {
2041
		$type = $_GET['status']; // safe, we've verified it's sane in the above if statement.
2042
2043
	    $database = gGetDb();
2044
2045
	    if ($enableEmailConfirm == 1) {
2046
	        $query = "SELECT * FROM request WHERE status = :type AND emailconfirm = 'Confirmed';";
2047
	    } else {
2048
	        $query = "SELECT * FROM request WHERE status = :type;";
2049
	    }
2050
2051
	    $statement = $database->prepare($query);
2052
2053
        $statement->bindValue(":type", $type);
2054
        $statement->execute();
2055
2056
        $requests = $statement->fetchAll(PDO::FETCH_CLASS, "Request");
2057
        foreach ($requests as $req) {
2058
        	/** @var Request $req */
2059
            $req->setDatabase($database);
2060
        }
2061
2062
        global $smarty;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
2063
        $smarty->assign("requests", $requests);
2064
        $smarty->assign("showStatus", false);
2065
        $html = $smarty->fetch("mainpage/requesttable.tpl");
2066
        echo $html;
2067
    } else {
2068
        echo defaultpage();
2069
    }
2070
2071
    BootstrapSkin::displayInternalFooter();
2072
    die();
2073
}
2074
# If the action specified does not exist, goto the default page.
2075
else {
2076
	echo defaultpage();
2077
	BootstrapSkin::displayInternalFooter();
2078
	die();
2079
}
2080