Completed
Pull Request — master (#257)
by Matthew
03:28
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
// Initialize the session data.
22
session_start();
23
24
// Get all the classes.
25
require_once 'functions.php';
26
require_once 'includes/PdoDatabase.php';
27
require_once 'includes/SmartyInit.php'; // this needs to be high up, but below config, functions, and database
28
require_once 'includes/session.php';
29
30
// Check to see if the database is unavailable.
31
// Uses the false variable as its the internal interface.
32
if (Offline::isOffline()) {
33
	echo Offline::getOfflineMessage(false);
34
	die();
35
}
36
37
// Initialize the class objects.
38
$session = new session();
39
$date = new DateTime();
40
41
// initialise providers
42
global $squidIpList;
43
/** @var ILocationProvider $locationProvider */
44
$locationProvider = new $locationProviderClass(gGetDb('acc'), $locationProviderApiKey);
45
/** @var IRDnsProvider $rdnsProvider */
46
$rdnsProvider = new $rdnsProviderClass(gGetDb('acc'));
47
/** @var IAntiSpoofProvider $antispoofProvider */
48
$antispoofProvider = new $antispoofProviderClass();
49
/** @var IXffTrustProvider $xffTrustProvider */
50
$xffTrustProvider = new $xffTrustProviderClass($squidIpList);
51
52
// Clears the action variable.
53
$action = '';
54
55
// Assign the correct value to the action variable.
56
// The value is retrieved from the $GET variable.
57
if (isset($_GET['action'])) {
58
	$action = $_GET['action'];
59
}
60
61
// Clear session before banner and logged in as message is generated on logout attempt - Prom3th3an
62
if ($action == "logout") {
63
	session_unset();
64
    
65
	BootstrapSkin::displayInternalHeader();
66
	echo showlogin();
67
	BootstrapSkin::displayInternalFooter();
68
	die();
69
}
70
71
// Checks whether the user is set - the user should first login.
72
if (!isset($_SESSION['user'])) {
73
	$suser = '';
74
	BootstrapSkin::displayInternalHeader();
75
76
	// Checks whether the user want to reset his password or register a new account.
77
	// Performs the clause when the action is not one of the above options.
78
	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...
79
		echo showlogin();
80
		BootstrapSkin::displayInternalFooter();
81
		die();
82
	}
83
	else {
84
		// A content block is created if the action is none of the above.
85
		// This block would later be used to keep all the HTML except the header and footer.
86
		$out = "<div id=\"content\">";
87
		echo $out;
88
	}
89
}
90
91
// Forces the current user to logout if necessary.
92
if (isset($_SESSION['userID'])) {
93
	$session->forceLogout($_SESSION['userID']);
94
}
95
96
BootstrapSkin::displayInternalHeader();
97
$session->checksecurity();
98
99
100
// When no action is specified the default Internal ACC are displayed.
101
// TODO: Improve way the method is called.
102
if ($action == '') {
103
	echo defaultpage();
104
	BootstrapSkin::displayInternalFooter();
105
	die();
106
}
107
elseif ($action == "sreg") {
108
	global $useOauthSignup, $smarty;
109
        
110
	// TODO: check blocked
111
	// TODO: check age.
112
    
113
	// check if user checked the "I have read and understand the interface guidelines" checkbox
114
	if (!isset($_REQUEST['guidelines'])) {
115
		$smarty->display("registration/alert-interfaceguidelines.tpl");
116
		BootstrapSkin::displayInternalFooter();
117
		die();
118
	}
119
	
120
	if (!filter_var($_REQUEST['email'], FILTER_VALIDATE_EMAIL)) {
121
		$smarty->display("registration/alert-invalidemail.tpl");
122
		BootstrapSkin::displayInternalFooter();
123
		die();
124
	}
125
    
126
	if ($_REQUEST['pass'] !== $_REQUEST['pass2']) {
127
		$smarty->display("registration/alert-passwordmismatch.tpl");
128
		BootstrapSkin::displayInternalFooter();
129
		die();
130
	}
131
    
132
	if (!$useOauthSignup) {
133
		if (!((string)(int)$_REQUEST['conf_revid'] === (string)$_REQUEST['conf_revid']) || $_REQUEST['conf_revid'] == "") {
134
			$smarty->display("registration/alert-confrevid.tpl");
135
			BootstrapSkin::displayInternalFooter();
136
			die();		
137
		}
138
	}
139
    
140
	if (User::getByUsername($_REQUEST['name'], gGetDb()) != false) {
141
		$smarty->display("registration/alert-usernametaken.tpl");
142
		BootstrapSkin::displayInternalFooter();
143
		die();
144
	}
145
    
146
	$query = gGetDb()->prepare("SELECT * FROM user WHERE email = :email LIMIT 1;");
147
	$query->execute(array(":email" => $_REQUEST['email']));
148
	if ($query->fetchObject("User") != false) {
149
		$smarty->display("registration/alert-emailtaken.tpl");
150
		BootstrapSkin::displayInternalFooter();
151
		die();
152
	}
153
	$query->closeCursor();
154
155
	$database = gGetDb();
156
    
157
	$database->transactionally(function() use ($database, $useOauthSignup)
158
	{
159
    
160
		$newUser = new User();
161
		$newUser->setDatabase($database);
162
    
163
		$newUser->setUsername($_REQUEST['name']);
164
		$newUser->setPassword($_REQUEST['pass']);
165
		$newUser->setEmail($_REQUEST['email']);
166
        
167
		if (!$useOauthSignup) {
168
			$newUser->setOnWikiName($_REQUEST['wname']);
169
			$newUser->setConfirmationDiff($_REQUEST['conf_revid']);
170
		}
171
        
172
		$newUser->save();
173
    
174
		global $oauthConsumerToken, $oauthSecretToken, $oauthBaseUrl, $oauthBaseUrlInternal, $useOauthSignup;
175
    
176
		if ($useOauthSignup) {
177
			try {
178
				// Get a request token for OAuth
179
				$util = new OAuthUtility($oauthConsumerToken, $oauthSecretToken, $oauthBaseUrl, $oauthBaseUrlInternal);
180
				$requestToken = $util->getRequestToken();
181
    
182
				// save the request token for later
183
				$newUser->setOAuthRequestToken($requestToken->key);
184
				$newUser->setOAuthRequestSecret($requestToken->secret);
185
				$newUser->save();
186
            
187
				Notification::userNew($newUser);
188
        
189
				$redirectUrl = $util->getAuthoriseUrl($requestToken);
190
            
191
				header("Location: {$redirectUrl}");
192
			}
193
			catch (Exception $ex) {
194
				throw new TransactionException(
195
					$ex->getMessage(), 
196
					"Connection to Wikipedia failed.", 
197
					"alert-error", 
198
					0, 
199
					$ex);
200
			}
201
		}
202
		else {
203
			global $baseurl;
204
			Notification::userNew($newUser);
205
			header("Location: {$baseurl}/acc.php?action=registercomplete");
206
		}
207
	});
208
    
209
	die();
210
}
211
elseif ($action == "register") {
212
	global $useOauthSignup, $smarty;
213
	$smarty->assign("useOauthSignup", $useOauthSignup);
214
	$smarty->display("registration/register.tpl");
215
	BootstrapSkin::displayInternalFooter();
216
	die();
217
}
218
elseif ($action == "registercomplete") {
219
	$smarty->display("registration/alert-registrationcomplete.tpl");
220
	BootstrapSkin::displayInternalFooter();
221
}
222
elseif ($action == "forgotpw") {
223
	global $baseurl, $smarty;
224
    
225
	if (isset ($_GET['si']) && isset ($_GET['id'])) {
226
		$user = User::getById($_GET['id'], gGetDb());
227
        
228
		if ($user === false) {
229
			BootstrapSkin::displayAlertBox("User not found.", "alert-error");
230
			BootstrapSkin::displayInternalFooter();
231
			die();
232
		}
233
        
234
		if (isset ($_POST['pw']) && isset ($_POST['pw2'])) {
235
			$hash = $user->getForgottenPasswordHash();
236
            
237
			if ($hash == $_GET['si']) {
238
				if ($_POST['pw'] == $_POST['pw2']) {
239
					$user->setPassword($_POST['pw2']);
240
					$user->save();
241
                    
242
					BootstrapSkin::displayAlertBox(
243
						"You may now <a href=\"$baseurl/acc.php\">Login</a>", 
244
						"alert-error", 
245
						"Password reset!", 
246
						true, 
247
						false);
248
                    
249
					BootstrapSkin::displayInternalFooter();
250
					die();
251
				}
252
				else {
253
					BootstrapSkin::displayAlertBox("Passwords did not match!", "alert-error", "Error", true, false);
254
					BootstrapSkin::displayInternalFooter();
255
					die();
256
				}
257
			}
258
			else {
259
				BootstrapSkin::displayAlertBox("Invalid request<!-- 1 -->", "alert-error", "Error", true, false);
260
				BootstrapSkin::displayInternalFooter();
261
				die();
262
			}
263
		}
264
        
265
		$hash = $user->getForgottenPasswordHash();
266
        
267
		if ($hash == $_GET['si']) {
268
			$smarty->assign('user', $user);
269
			$smarty->assign('si', $_GET['si']);
270
			$smarty->assign('id', $_GET['id']);
271
			$smarty->display('forgot-password/forgotpwreset.tpl');
272
		}
273
		else {
274
			BootstrapSkin::displayAlertBox(
275
				"The hash supplied in the link did not match the hash in the database!", 
276
				"alert-error", 
277
				"Invalid request", 
278
				true, 
279
				false);
280
		}
281
        
282
		BootstrapSkin::displayInternalFooter();
283
		die();
284
	}
285
    
286
	if (isset ($_POST['username'])) {
287
		$user = User::getByUsername($_POST['username'], gGetDb());
288
289
		if ($user == false) {
290
			BootstrapSkin::displayAlertBox(
291
				"Could not find user with that username and email address!", 
292
				"alert-error", 
293
				"Error", 
294
				true, 
295
				false);
296
            
297
			BootstrapSkin::displayInternalFooter();
298
			die();
299
		}
300
		elseif (strtolower($_POST['email']) != strtolower($user->getEmail())) {
301
			BootstrapSkin::displayAlertBox("Could not find user with that username and email address!", 
302
				"alert-error", 
303
				"Error", 
304
				true, 
305
				false);
306
            
307
			BootstrapSkin::displayInternalFooter();
308
			die();
309
		}
310
		else {
311
			$hash = $user->getForgottenPasswordHash();
312
                       
313
			$smarty->assign("user", $user);
314
			$smarty->assign("hash", $hash);
315
			$smarty->assign("remoteAddress", $_SERVER['REMOTE_ADDR']);
316
            
317
			$mailtxt = $smarty->fetch("forgot-password/reset-mail.tpl");
318
			$headers = 'From: [email protected]';
319
            
320
			mail(
321
				$user->getEmail(), 
322
				"English Wikipedia Account Request System - Forgotten password", 
323
				$mailtxt, 
324
				$headers);
325
            
326
			BootstrapSkin::displayAlertBox(
327
				"<strong>Your password reset request has been completed.</strong> Please check your e-mail.", 
328
				"alert-success", 
329
				"", 
330
				false, 
331
				false);
332
            
333
			BootstrapSkin::displayInternalFooter();
334
			die();
335
		}
336
	}
337
    
338
	$smarty->display('forgot-password/forgotpw.tpl');
339
340
	BootstrapSkin::displayInternalFooter();
341
	die();
342
}
343
elseif ($action == "login") {
344
	global $baseurl, $smarty;
345
    
346
	if (!isset($_POST['username'])) {
347
		header("Location: $baseurl/acc.php?error=authfail&tplUsername=");
348
		die();
349
	}
350
351
	$user = User::getByUsername($_POST['username'], gGetDb());
352
    
353
	if ($user == false || !$user->authenticate($_POST['password'])) {
354
		header("Location: $baseurl/acc.php?error=authfail&tplUsername=" . urlencode($_POST['username']));
355
		die();
356
	}
357
    
358
	if ($user->getStoredOnWikiName() == "##OAUTH##" && $user->getOAuthAccessToken() == null) {
359
		reattachOAuthAccount($user);   
360
	}
361
    
362
	if ($user->isOAuthLinked()) {
363
		try {
364
			// test retrieval of the identity
365
			$user->getOAuthIdentity();
366
		}
367
		catch (TransactionException $ex) {
368
			$user->setOAuthAccessToken(null);
369
			$user->setOAuthAccessSecret(null);
370
			$user->save();
371
            
372
			reattachOAuthAccount($user);
373
		}
374
	}
375
	else {
376
		global $enforceOAuth;
377
        
378
		if ($enforceOAuth) {
379
			reattachOAuthAccount($user);
380
		}
381
	}
382
    
383
	// At this point, the user has successfully authenticated themselves.
384
	// We now proceed to perform login-specific actions, and check the user actually has
385
	// the correct permissions to continue with the login.
386
    
387
	if ($user->getForcelogout()) {
388
		$user->setForcelogout(false);
389
		$user->save();
390
	}
391
    
392
	if ($user->isNew()) {
393
		header("Location: $baseurl/acc.php?error=newacct");
394
		die();
395
	}
396
    
397
	$database = gGetDb();
398
    
399
	$sqlText = <<<SQL
400
SELECT comment FROM log
401
WHERE action = :action AND objectid = :userid AND objecttype = 'User'
402
ORDER BY timestamp DESC LIMIT 1;
403
SQL;
404
    
405
	$suspendstatement = $database->prepare($sqlText);
406
    
407 View Code Duplication
	if ($user->isDeclined()) {
408
		$suspendAction = "Declined";
409
		$userid = $user->getId();
410
		$suspendstatement->bindValue(":action", $suspendAction);
411
		$suspendstatement->bindValue(":userid", $userid);
412
		$suspendstatement->execute();
413
        
414
		$suspendreason = $suspendstatement->fetchColumn();
415
        
416
		$suspendstatement->closeCursor();
417
        
418
		BootstrapSkin::displayInternalHeader();
419
		$smarty->assign("suspendreason", $suspendreason);
420
		$smarty->display("login/declined.tpl");
421
		BootstrapSkin::displayInternalFooter();
422
		die();
423
	}
424
    
425 View Code Duplication
	if ($user->isSuspended()) {
426
		$suspendAction = "Suspended";
427
		$userid = $user->getId();
428
		$suspendstatement->bindValue(":action", $suspendAction);
429
		$suspendstatement->bindValue(":userid", $userid);
430
		$suspendstatement->execute();
431
        
432
		$suspendreason = $suspendstatement->fetchColumn();
433
        
434
		$suspendstatement->closeCursor();
435
        
436
		BootstrapSkin::displayInternalHeader();
437
		$smarty->assign("suspendreason", $suspendreason);
438
		$smarty->display("login/suspended.tpl");
439
		BootstrapSkin::displayInternalFooter();
440
		die();
441
	}
442
    
443
	if (!$user->isIdentified() && $forceIdentification == 1) {
444
		header("Location: $baseurl/acc.php?error=noid");
445
		die();
446
	}
447
    
448
	// At this point, we've tested that the user is OK, so we set the login cookies.
449
    
450
	$_SESSION['user'] = $user->getUsername();
451
	$_SESSION['userID'] = $user->getId();
452
    
453
	if ($user->getOAuthAccessToken() == null && $user->getStoredOnWikiName() == "##OAUTH##") {
454
		reattachOAuthAccount($user);
455
	}
456
    
457
	header("Location: $baseurl/acc.php");
458
}
459
elseif ($action == "messagemgmt") {
460
	global $smarty;
461
    
462
	if (isset($_GET['view'])) {
463
		$message = InterfaceMessage::getById($_GET['view'], gGetDb());
464
                
465
		if ($message == false) {
466
			BootstrapSkin::displayAlertBox("Unable to find specified message", "alert-error", "Error", true, false);
467
			BootstrapSkin::displayInternalFooter();
468
			die();
469
		}
470
        
471
		$smarty->assign("message", $message);
472
		$smarty->assign("readonly", true);
473
		$smarty->display("message-management/editform.tpl");
474
		BootstrapSkin::displayInternalFooter();
475
		die();
476
	}
477
	if (isset($_GET['edit'])) {
478
		if (!(User::getCurrent()->isAdmin() || User::getCurrent()->isCheckuser())) {
479
			BootstrapSkin::displayAccessDenied();
480
			BootstrapSkin::displayInternalFooter();
481
			die();
482
		}
483
        
484
		$database = gGetDb();
485
        
486
		$database->transactionally(function() use ($database)
487
		{
488
			global $smarty;
489
            
490
			$message = InterfaceMessage::getById($_GET['edit'], $database);
491
            
492
			if ($message == false) {
493
				throw new TransactionException("Unable to find specified message", "Error");
494
			}
495
            
496
			if (isset($_GET['submit'])) {
497
				$message->setContent($_POST['mailtext']);
498
				$message->setDescription($_POST['maildesc']);
499
				$message->save();
500
            
501
				Logger::interfaceMessageEdited(gGetDb(), $message);
502
              
503
				$smarty->assign("message", $message);
504
				$smarty->display("message-management/alert-editsuccess.tpl");
505
                
506
				Notification::interfaceMessageEdited($message);
507
                
508
				BootstrapSkin::displayInternalFooter();
509
				return;
510
			}
511
            
512
			$smarty->assign("message", $message);
513
			$smarty->assign("readonly", false);
514
			$smarty->display("message-management/editform.tpl");
515
        
516
			BootstrapSkin::displayInternalFooter();
517
		});
518
        
519
		die();
520
	}
521
    
522
	$sqlText = <<<SQL
523
        SELECT * 
524
        FROM interfacemessage 
525
        WHERE type = :type 
526
            AND description NOT LIKE '%[deprecated]';
527
SQL;
528
    
529
	$fetchStatement = gGetDb()->prepare($sqlText);
530
	$data = array();
531
        
532
	//$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...
533
	//$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...
534
    
535
	$fetchStatement->execute(array(":type" => "Internal"));
536
	$data['Internal Interface messages'] = $fetchStatement->fetchAll(PDO::FETCH_CLASS, 'InterfaceMessage');
537
    
538
	$smarty->assign("data", $data);
539
	$smarty->display('message-management/view.tpl');
540
   
541
	BootstrapSkin::displayInternalFooter();
542
	die();
543
}
544
elseif ($action == "templatemgmt") {
545
	global $baseurl, $smarty;
546
    
547
	if (isset($_GET['view'])) {
548
		$template = WelcomeTemplate::getById($_GET['view'], gGetDb());
549
        
550
		if ($template === false) {
551
			SessionAlert::success("Something went wrong, we can't find the template you asked for! Please try again.");
552
			header("Location: {$baseurl}/acc.php?action=templatemgmt");
553
			die();
554
		}
555
        
556
		$smarty->assign("template", $template);
557
		$smarty->display("welcometemplate/view.tpl");
558
		BootstrapSkin::displayInternalFooter();
559
		die();
560
	}
561
    
562
	if (isset($_GET['add'])) {
563
		if (!User::getCurrent()->isAdmin() && !User::getCurrent()->isCheckuser()) {
564
			BootstrapSkin::displayAccessDenied();
565
            
566
			BootstrapSkin::displayInternalFooter();
567
			die();
568
		}
569
        
570
		if (isset($_POST['submit'])) {
571
			global $baseurl;
572
            
573
			$database = gGetDb();
574
            
575 View Code Duplication
			$database->transactionally(function() use ($database, $baseurl)
576
			{
577
				$template = new WelcomeTemplate();
578
				$template->setDatabase($database);
579
				$template->setUserCode($_POST['usercode']);
580
				$template->setBotCode($_POST['botcode']);
581
				$template->save();
582
            
583
				Logger::welcomeTemplateCreated($database, $template);
584
                            
585
				Notification::welcomeTemplateCreated($template);
586
            
587
				SessionAlert::success("Template successfully created.");
588
				header("Location: $baseurl/acc.php?action=templatemgmt");
589
			});
590
		}
591
		else {
592
			
593
			if (isset($_POST['preview'])) {
594
				$usercode = $_POST['usercode'];
595
				$botcode = $_POST['botcode'];
596
				echo displayPreview($usercode);
597
			}
598
			else {
599
				$usercode = '';
600
				$botcode = '';
601
			}
602
603
			$smarty->assign("usercode", $usercode);
604
			$smarty->assign("botcode", $botcode);
605
            
606
			$smarty->display("welcometemplate/add.tpl");
607
			BootstrapSkin::displayInternalFooter();
608
			die();
609
		}
610
        
611
		die();
612
	}
613
    
614
	if (isset($_GET['select'])) {
615
		$user = User::getCurrent();
616
        
617
		if ($_GET['select'] == 0) {
618
			$user->setWelcomeTemplate(null);
619
			$user->save();
620
            
621
			SessionAlert::success("Disabled automatic user welcoming.");
622
			header("Location: {$baseurl}/acc.php?action=templatemgmt");
623
			die();
624
		}
625
		else {
626
			$template = WelcomeTemplate::getById($_GET['select'], gGetDb());
627
			if ($template !== false) {
628
				$user->setWelcomeTemplate($template->getId());
629
				$user->save();
630
                
631
				SessionAlert::success("Updated selected welcome template for automatic welcoming.");
632
				header("Location: {$baseurl}/acc.php?action=templatemgmt");
633
				die();
634
			}
635
			else {
636
				SessionAlert::error("Something went wrong, we can't find the template you asked for!");
637
				header("Location: {$baseurl}/acc.php?action=templatemgmt");
638
				die();
639
			}
640
		}
641
	}
642
    
643
	if (isset($_GET['del'])) {
644
		global $baseurl;
645
        
646
		if (!User::getCurrent()->isAdmin() && !User::getCurrent()->isCheckuser()) {
647
			BootstrapSkin::displayAccessDenied();
648
			BootstrapSkin::displayInternalFooter();
649
			die();
650
		}
651
652
		$database = gGetDb();
653
        
654
		$template = WelcomeTemplate::getById($_GET['del'], $database);
655
		if ($template == false) {
656
			SessionAlert::error("Something went wrong, we can't find the template you asked for!");
657
			header("Location: {$baseurl}/acc.php?action=templatemgmt");
658
			die();
659
		}
660
        
661
		$database->transactionally(function() use($database, $template)
662
		{
663
			$tid = $template->getId();
664
            
665
			$database
666
				->prepare("UPDATE user SET welcome_template = NULL WHERE welcome_template = :id;")
667
				->execute(array(":id" => $tid));
668
            
669
			Logger::welcomeTemplateDeleted($database, $template);
670
            
671
			$template->delete();
672
            
673
			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...
674
			Notification::welcomeTemplateDeleted($tid);
675
		});
676
        
677
		header("Location: $baseurl/acc.php?action=templatemgmt");
678
		die();			
679
	}
680
    
681
	if (isset($_GET['edit'])) {
682
		if (!User::getCurrent()->isAdmin() && !User::getCurrent()->isCheckuser()) {
683
			BootstrapSkin::displayAccessDenied();
684
			BootstrapSkin::displayInternalFooter();
685
			die();
686
		}
687
688
		$database = gGetDb();
689
        
690
		$template = WelcomeTemplate::getById($_GET['edit'], $database);
691
		if ($template == false) {
692
			SessionAlert::success("Something went wrong, we can't find the template you asked for! Please try again.");
693
			header("Location: {$baseurl}/acc.php?action=templatemgmt");
694
			die();
695
		}
696
697
		if (isset($_POST['submit'])) {
698
			$database->transactionally(function() use($database, $template)
699
			{
700
				$template->setUserCode($_POST['usercode']);
701
				$template->setBotCode($_POST['botcode']);
702
				$template->save();
703
			
704
				Logger::welcomeTemplateEdited($database, $template);
705
                
706
				SessionAlert::success("Template updated.");
707
				Notification::welcomeTemplateEdited($template);
708
			});
709
            
710
			header("Location: $baseurl/acc.php?action=templatemgmt");
711
			die();
712
		}
713
		else {
714
			$smarty->assign("template", $template);
715
			$smarty->display("welcometemplate/edit.tpl");
716
            
717
			BootstrapSkin::displayInternalFooter();
718
			die();
719
		}
720
	}
721
    
722
	$templateList = WelcomeTemplate::getAll();
723
    
724
	$smarty->assign("templatelist", $templateList);
725
	$smarty->display("welcometemplate/list.tpl");
726
    
727
	BootstrapSkin::displayInternalFooter();
728
	die();
729
}
730
elseif ($action == "sban") {
731
	global $smarty;
732
    
733
	// Checks whether the current user is an admin.
734
	if (!User::getCurrent()->isAdmin() && !User::getCurrent()->isCheckuser()) {
735
		BootstrapSkin::displayAccessDenied();
736
		BootstrapSkin::displayInternalFooter();
737
		die();
738
	}
739
	
740
	// Checks whether there is a reason entered for ban.
741
	if (!isset($_POST['banreason']) || $_POST['banreason'] == "") {
742
		BootstrapSkin::displayAlertBox("You must specify a ban reason", "alert-error", "", false, false);
743
		BootstrapSkin::displayInternalFooter();
744
		die();
745
	}
746
	
747
	// Checks whether there is a target entered to ban.
748
	if (!isset($_POST['target']) || $_POST['target'] == "") {
749
		BootstrapSkin::displayAlertBox("You must specify a target to be banned", "alert-error", "", false, false);
750
		BootstrapSkin::displayInternalFooter();
751
		die();
752
	}
753
	
754
	$duration = $_POST['duration'];
755
    
756
	if ($duration == "-1") {
757
		$duration = -1;
758
	}
759
	elseif ($duration == "other") {
760
		$duration = strtotime($_POST['otherduration']);
761
		if (!$duration) {
762
			BootstrapSkin::displayAlertBox("Invalid ban time", "alert-error", "", false, false);
763
			BootstrapSkin::displayInternalFooter();
764
			die();
765
		}
766
		elseif (time() > $duration) {
767
			BootstrapSkin::displayAlertBox("Ban time has already expired!", "alert-error", "", false, false);
768
			BootstrapSkin::displayInternalFooter();
769
			die();
770
		}
771
	}
772
	else {
773
		$duration = $duration + time();
774
	}
775
    
776
	switch ($_POST['type']) {
777
		case 'IP':
778 View Code Duplication
			if (filter_var($_POST['target'], FILTER_VALIDATE_IP) === false) {
779
				BootstrapSkin::displayAlertBox("Invalid target - IP address expected.", "alert-error", "", false, false);
780
				BootstrapSkin::displayInternalFooter();
781
				die();
782
			}
783
            
784
			global $squidIpList;
785
			if (in_array($_POST['target'], $squidIpList)) {
786
				BootstrapSkin::displayAlertBox(
787
					"This IP address is on the protected list of proxies, and cannot be banned.", 
788
					"alert-error", 
789
					"", 
790
					false, 
791
					false);
792
				BootstrapSkin::displayInternalFooter();
793
				die();
794
			}
795
			break;
796
		case 'Name':
797
			break;
798
		case 'EMail':
799
			// TODO: cut this down to a bare-bones implementation so we don't accidentally reject a valid address.
800
			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...
801
				BootstrapSkin::displayAlertBox(
802
					"Invalid target - email address expected.", 
803
					"alert-error", 
804
					"", 
805
					false, 
806
					false);
807
                
808
				BootstrapSkin::displayInternalFooter();
809
				die();
810
			}
811
			break;
812
		default:
813
			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...
814
			BootstrapSkin::displayInternalFooter();
815
			die();
816
	}
817
        
818
	if (count(Ban::getActiveBans($_POST['target'])) > 0) {
819
		BootstrapSkin::displayAlertBox("This target is already banned!", "alert-error", "", false, false);
820
		BootstrapSkin::displayInternalFooter();
821
		die();
822
	}
823
    
824
	$database = gGetDb();
825
    
826
	$ban = new Ban();
827
    
828
	$currentUsername = User::getCurrent()->getUsername();
829
    
830
	$database->transactionally(function() use ($database, $ban, $duration, $currentUsername)
831
	{
832
		$ban->setDatabase($database);
833
		$ban->setActive(1);
834
		$ban->setType($_POST['type']);
835
		$ban->setTarget($_POST['target']);
836
		$ban->setUser($currentUsername);
837
		$ban->setReason($_POST['banreason']);
838
		$ban->setDuration($duration);
839
    
840
		$ban->save();
841
        
842
		Logger::banned($database, $ban, $_POST['banreason']);
843
	});
844
    
845
	$smarty->assign("ban", $ban);
846
	BootstrapSkin::displayAlertBox($smarty->fetch("bans/bancomplete.tpl"), "alert-info", "", false, false);
847
        
848
	Notification::banned($ban);
849
    
850
	BootstrapSkin::displayInternalFooter();
851
	die();
852
}
853
elseif ($action == "unban") {
854
	global $smarty;
855
    
856
	if (!isset($_GET['id']) || $_GET['id'] == "") {
857
		BootstrapSkin::displayAlertBox(
858
			"The ID parameter appears to be missing! This is probably a bug.", 
859
			"alert-error", 
860
			"Ahoy There! Something's not right...", 
861
			true, 
862
			false);
863
		BootstrapSkin::displayInternalFooter();
864
		die();
865
	}
866
    
867
	if (!User::getCurrent()->isAdmin() && !User::getCurrent()->isCheckuser()) {
868
		BootstrapSkin::displayAccessDenied();
869
		BootstrapSkin::displayInternalFooter();
870
		die();
871
	}
872
    
873
	$ban = Ban::getActiveId($_GET['id']);
874
        
875
	if ($ban == false) {
876
		BootstrapSkin::displayAlertBox(
877
			"The specified ban ID is not currently active or doesn't exist!", 
878
			"alert-error", 
879
			"", 
880
			false, 
881
			false);
882
        
883
		BootstrapSkin::displayInternalFooter();
884
		die();
885
	}
886
887
	if (isset($_GET['confirmunban']) && $_GET['confirmunban'] == "true") {
888
		if (!isset($_POST['unbanreason']) || $_POST['unbanreason'] == "") {
889
			BootstrapSkin::displayAlertBox("You must enter an unban reason!", "alert-error", "", false, false);
890
			BootstrapSkin::displayInternalFooter();
891
			die();
892
		}
893
		else {
894
			$database = gGetDb();
895
            
896
			$database->transactionally(function() use ($database, $ban)
897
			{
898
				$ban->setActive(0);
899
				$ban->save();
900
                
901
				$banId = $ban->getId();
902
				$currentUser = User::getCurrent()->getUsername();
903
                
904
				Logger::unbanned($database, $ban, $_POST['unbanreason']);
905
			});
906
        
907
			BootstrapSkin::displayAlertBox("Unbanned " . $ban->getTarget(), "alert-info", "", false, false);
908
			BootstrapSkin::displayInternalFooter();
909
			Notification::unbanned($ban, $_POST['unbanreason']);
910
			die();
911
		}
912
	}
913
	else {
914
		$smarty->assign("ban", $ban);
915
		$smarty->display("bans/unban.tpl");
916
        
917
		BootstrapSkin::displayInternalFooter();
918
	}
919
}
920
elseif ($action == "ban") {
921
	global $smarty;
922
    
923
	if (isset ($_GET['ip']) || isset ($_GET['email']) || isset ($_GET['name'])) {
924 View Code Duplication
		if (!User::getCurrent()->isAdmin() && !User::getCurrent()->isCheckuser()) {
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...
925
			BootstrapSkin::displayAlertBox("Only administrators or checkusers may ban users", "alert-error");
926
			BootstrapSkin::displayInternalFooter();
927
			die();
928
		}
929
        
930
		$database = gGetDb();
931
		// TODO: rewrite me!
932
		if (isset($_GET['ip'])) {
933
			$query = "SELECT ip, forwardedip FROM request WHERE id = :ip;";
934
			$statement = $database->prepare($query);
935
			$statement->bindValue(":ip", $_GET['ip']);
936
			$statement->execute();
937
			$row = $statement->fetch(PDO::FETCH_ASSOC);
938
			$target = getTrustedClientIP($row['ip'], $row['forwardedip']);
939
			$type = "IP";
940
		}
941 View Code Duplication
		elseif (isset($_GET['email'])) {
942
			$query = "SELECT email FROM request WHERE id = :ip;";
943
			$statement = $database->prepare($query);
944
			$statement->bindValue(":ip", $_GET['email']);
945
			$statement->execute();
946
			$row = $statement->fetch(PDO::FETCH_ASSOC);
947
			$target = $row['email'];
948
			$type = "EMail";
949
		}
950 View Code Duplication
		elseif (isset($_GET['name'])) {
951
			$query = "SELECT name FROM request WHERE id = :ip;";
952
			$statement = $database->prepare($query);
953
			$statement->bindValue(":ip", $_GET['name']);
954
			$statement->execute();
955
			$row = $statement->fetch(PDO::FETCH_ASSOC);
956
			$target = $row['name'];
957
			$type = "Name";
958
		}
959
		else {
960
			BootstrapSkin::displayAlertBox("Unknown ban type.", "alert-error");
961
			BootstrapSkin::displayInternalFooter();
962
			die();    
963
		}
964
        
965
		if (count(Ban::getActiveBans($target))) {
966
			BootstrapSkin::displayAlertBox("This target is already banned!", "alert-error");
967
			BootstrapSkin::displayInternalFooter();
968
			die();
969
		} 
970
        
971
		$smarty->assign("bantype", $type);
972
		$smarty->assign("bantarget", trim($target));
973
		$smarty->display("bans/banform.tpl");
974
	}
975
	else {
976
		$bans = Ban::getActiveBans();
977
  
978
		$smarty->assign("activebans", $bans);
979
		$smarty->display("bans/banlist.tpl");
980
	}
981
    
982
	BootstrapSkin::displayInternalFooter();
983
	die();
984
}
985
elseif ($action == "defer" && $_GET['id'] != "" && $_GET['sum'] != "") {
986
	global $availableRequestStates;
987
	
988
	if (array_key_exists($_GET['target'], $availableRequestStates)) {
989
		$request = Request::getById($_GET['id'], gGetDb());
990
		
991
		if ($request == false) {
992
			BootstrapSkin::displayAlertBox(
993
				"Could not find the specified request!", 
994
				"alert-error", 
995
				"Error!", 
996
				true, 
997
				false);
998
            
999
			BootstrapSkin::displayInternalFooter();
1000
			die();
1001
		}
1002
		
1003
		if ($request->getChecksum() != $_GET['sum']) {
1004
			SessionAlert::error(
1005
				"This is similar to an edit conflict on Wikipedia; it means that you have tried to perform an action "
1006
				. "on a request that someone else has performed an action on since you loaded the page",
1007
				"Invalid checksum");
1008
            
1009
			header("Location: acc.php?action=zoom&id={$request->getId()}");
1010
			die();
1011
		}
1012
        
1013
		$sqlText = <<<SQL
1014
SELECT timestamp FROM log
1015
WHERE objectid = :request and objecttype = 'Request' AND action LIKE 'Closed%'
1016
ORDER BY timestamp DESC LIMIT 1;
1017
SQL;
1018
        
1019
		$statement = gGetDb()->prepare($sqlText);
1020
		$statement->execute(array(":request" => $request->getId()));
1021
		$logTime = $statement->fetchColumn();
1022
		$statement->closeCursor();
1023
        
1024
		$date = new DateTime();
1025
		$date->modify("-7 days");
1026
		$oneweek = $date->format("Y-m-d H:i:s");
1027
        
1028
		if ($request->getStatus() == "Closed" 
1029
			&& $logTime < $oneweek 
1030
			&& !User::getCurrent()->isAdmin() 
1031
			&& !User::getCurrent()->isCheckuser()) {
1032
			SessionAlert::error("Only administrators and checkusers can reopen a request that has been closed for over a week.");
1033
			header("Location: acc.php?action=zoom&id={$request->getId()}");
1034
			die();
1035
		}
1036
        
1037
		if ($request->getStatus() == $_GET['target']) {
1038
			SessionAlert::error(
1039
				"Cannot set status, target already deferred to " . htmlentities($_GET['target']), 
1040
				"Error");
1041
			header("Location: acc.php?action=zoom&id={$request->getId()}");
1042
			die();
1043
		}
1044
        
1045
		$database = gGetDb();
1046
		$database->transactionally(function() use ($database, $request)
1047
		{
1048
			global $availableRequestStates;
1049
                
1050
			$request->setReserved(0);
1051
			$request->setStatus($_GET['target']);
1052
			$request->updateChecksum();
1053
			$request->save();
1054
            
1055
			$deto = $availableRequestStates[$_GET['target']]['deferto'];
1056
			$detolog = $availableRequestStates[$_GET['target']]['defertolog'];
1057
            
1058
			Logger::deferRequest($database, $request, $detolog);
1059
        
1060
			Notification::requestDeferred($request);
1061
			SessionAlert::success("Request {$request->getId()} deferred to $deto");
1062
			header("Location: acc.php");
1063
		});
1064
        
1065
		die();
1066
	}
1067
	else {
1068
		BootstrapSkin::displayAlertBox("Defer target not valid.", "alert-error", "Error", true, false);
1069
		BootstrapSkin::displayInternalFooter();
1070
		die();
1071
	}
1072
}
1073
elseif ($action == "prefs") {
1074
	global $smarty, $enforceOAuth;
1075
    
1076
	if (isset ($_POST['sig'])) {
1077
		$user = User::getCurrent();
1078
		$user->setWelcomeSig($_POST['sig']);
1079
		$user->setEmailSig($_POST['emailsig']);
1080
		$user->setAbortPref(isset($_POST['abortpref']) ? 1 : 0);
1081
        
1082
		if (isset($_POST['email'])) {
1083
			$mailisvalid = filter_var(trim($_POST['email']), FILTER_VALIDATE_EMAIL);
1084
            
1085
			if ($mailisvalid === false) {
1086
				BootstrapSkin::displayAlertBox("Invalid email address", "alert-error", "Error!");
1087
			}
1088
			else {
1089
				$user->setEmail(trim($_POST['email']));
1090
			}
1091
		}
1092
1093
		try {
1094
			$user->save();
1095
		}
1096
		catch (PDOException $ex) {
1097
			BootstrapSkin::displayAlertBox($ex->getMessage(), "alert-error", "Error saving Preferences", true, false);
1098
			BootstrapSkin::displayInternalFooter();
1099
			die();
1100
		}
1101
        
1102
		BootstrapSkin::displayAlertBox("Preferences updated!", "alert-info");
1103
	}
1104
    
1105
	$smarty->assign("enforceOAuth", $enforceOAuth);
1106
	$smarty->display("prefs.tpl");
1107
	BootstrapSkin::displayInternalFooter();
1108
	die();
1109
}
1110
elseif ($action == "done" && $_GET['id'] != "") {
1111
	// check for valid close reasons
1112
	global $messages, $baseurl, $smarty;
1113
	
1114
	if (isset($_GET['email'])) {
1115
		if ($_GET['email'] == 0 || $_GET['email'] == "custom") {
1116
			$validEmail = true;
1117
		}
1118
		else {
1119
			$validEmail = EmailTemplate::getById($_GET['email'], gGetDb()) != false;
1120
		}
1121
	}
1122
	else {
1123
		$validEmail = false;
1124
	}
1125
    
1126
	if ($validEmail == false) {
1127
		BootstrapSkin::displayAlertBox("Invalid close reason", "alert-error", "Error", true, false);
1128
		BootstrapSkin::displayInternalFooter();
1129
		die();
1130
	}
1131
	
1132
	// sanitise this input ready for inclusion in queries
1133
	$request = Request::getById($_GET['id'], gGetDb());
1134
    
1135
	if ($request == false) {
1136
		// Notifies the user and stops the script.
1137
		BootstrapSkin::displayAlertBox("The request ID supplied is invalid!", "alert-error", "Error", true, false);
1138
		BootstrapSkin::displayInternalFooter();
1139
		die();
1140
	}
1141
    
1142
	$gem = $_GET['email'];
1143
	
1144
	// check the checksum is valid
1145
	if ($request->getChecksum() != $_GET['sum']) {
1146
		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...
1147
		BootstrapSkin::displayInternalFooter();
1148
		die();
1149
	}
1150
	
1151
	// check if an email has already been sent
1152
	if ($request->getEmailSent() == "1" && !isset($_GET['override']) && $gem != 0) {
1153
		$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...
1154
		$alertContent .= "<div class=\"row-fluid\">";
1155
		$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...
1156
		$alertContent .= "<a class=\"btn btn-danger span3\" href=\"$baseurl/acc.php\">No</a>";
1157
		$alertContent .= "</div>";
1158
        
1159
		BootstrapSkin::displayAlertBox($alertContent, "alert-info", "Warning!", true, false, false, true);
1160
		BootstrapSkin::displayInternalFooter();
1161
		die();
1162
	}
1163
	
1164
	// check the request is not reserved by someone else
1165
	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...
1166
		$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...
1167
		$alertContent .= "<div class=\"row-fluid\">";
1168
		$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...
1169
		$alertContent .= "<a class=\"btn btn-danger span3\" href=\"$baseurl/acc.php\">No</a>";
1170
		$alertContent .= "</div>";
1171
        
1172
		BootstrapSkin::displayAlertBox($alertContent, "alert-info", "Warning!", true, false, false, true);
1173
		BootstrapSkin::displayInternalFooter();
1174
		die();
1175
	}
1176
	    
1177
	if ($request->getStatus() == "Closed") {
1178
		BootstrapSkin::displayAlertBox("Cannot close this request. Already closed.", "alert-error", "Error", true, false);
1179
		BootstrapSkin::displayInternalFooter();
1180
		die();
1181
	}
1182
	
1183
	// Checks whether the username is already in use on Wikipedia.
1184
	$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...
1185
	$ue = unserialize($userexist);
1186
	if (!isset ($ue['query']['users']['0']['missing'])) {
1187
		$exists = true;
1188
	}
1189
	else {
1190
		$exists = false;
1191
	}
1192
1193
	/** @var EmailTemplate $emailTemplate */
1194
	$emailTemplate = EmailTemplate::getById($gem, gGetDb());
1195
	if ($emailTemplate instanceof EmailTemplate) {
1196
		$isForCreated = $emailTemplate->getDefaultAction() === EmailTemplate::CREATED;
1197
	} else {
1198
		$isForCreated = false;
1199
	}
1200
1201
	// check if a request being created does not already exist.
1202
	if ($isForCreated && !$exists && !isset($_GET['createoverride'])) {
1203
		$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...
1204
		$alertContent .= "<div class=\"row-fluid\">";
1205
		$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...
1206
		$alertContent .= "<a class=\"btn btn-danger span3\" href=\"$baseurl/acc.php\">No</a>";
1207
		$alertContent .= "</div>";
1208
        
1209
		BootstrapSkin::displayAlertBox($alertContent, "alert-info", "Warning!", true, false, false, true);
1210
		BootstrapSkin::displayInternalFooter();
1211
		die();
1212
	}
1213
	
1214
	$messageBody = null;
1215
    
1216
	// custom close reasons
1217
	if ($gem == 'custom') {
1218
		if (!isset($_POST['msgbody']) or empty($_POST['msgbody'])) {
1219
			// Send it through htmlspecialchars so HTML validators don't complain. 
1220
			$querystring = htmlspecialchars($_SERVER["QUERY_STRING"], ENT_COMPAT, 'UTF-8'); 
1221
            
1222
			$template = false;
1223
			if (isset($_GET['preload'])) {
1224
				$template = EmailTemplate::getById($_GET['preload'], gGetDb());
1225
			}
1226
            
1227
			if ($template != false) {
1228
				$preloadTitle = $template->getName();
1229
				$preloadText = $template->getText();
1230
				$preloadAction = $template->getDefaultAction();
1231
			}
1232
			else {
1233
				$preloadText = "";
1234
				$preloadTitle = "";
1235
				$preloadAction = "";
1236
			}
1237
            
1238
			$smarty->assign("requeststates", $availableRequestStates);
1239
			$smarty->assign("defaultAction", $preloadAction);
1240
			$smarty->assign("preloadtext", $preloadText);
1241
			$smarty->assign("preloadtitle", $preloadTitle);
1242
			$smarty->assign("querystring", $querystring);
1243
			$smarty->assign("request", $request);
1244
			$smarty->assign("iplocation", $locationProvider->getIpLocation($request->getTrustedIp()));
1245
			$smarty->display("custom-close.tpl");
1246
			BootstrapSkin::displayInternalFooter();
1247
			die();
1248
		}
1249
1250
		$headers = 'From: [email protected]' . "\r\n";
1251
		if (!User::getCurrent()->isAdmin() || isset($_POST['ccmailist']) && $_POST['ccmailist'] == "on") {
1252
			$headers .= 'Cc: [email protected]' . "\r\n";
1253
		}
1254
1255
		$headers .= 'X-ACC-Request: ' . $request->getId() . "\r\n";
1256
		$headers .= 'X-ACC-UserID: ' . User::getCurrent()->getId() . "\r\n";
1257
1258
		// Get the closing user's Email signature and append it to the Email.
1259
		if (User::getCurrent()->getEmailSig() != "") {
1260
			$emailsig = html_entity_decode(User::getCurrent()->getEmailSig(), ENT_QUOTES, "UTF-8");
1261
			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...
1262
		}
1263
		else {
1264
			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...
1265
		}
1266
1267
		$request->setEmailSent(1);
1268
		$messageBody = $_POST['msgbody'];
1269
1270
		if ($_POST['action'] == EmailTemplate::CREATED || $_POST['action'] == EmailTemplate::NOT_CREATED) {
1271
			$request->setStatus('Closed');
1272
1273
			if ($_POST['action'] == EmailTemplate::CREATED) {
1274
				$gem  = 'custom-y';
1275
				$crea = "Custom, Created";
1276
			}
1277
			else {
1278
				$gem  = 'custom-n';
1279
				$crea = "Custom, Not Created";
1280
			}
1281
1282
			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...
1283
			
1284
			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...
1285
			BootstrapSkin::displayAlertBox(
1286
				"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...
1287
				"alert-success");
1288
		}
1289
		else if ($_POST['action'] == "mail") {
1290
			// no action other than send mail!
1291
			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...
1292
			Logger::unreserve(gGetDb(), $request);
1293
1294
			Notification::sentMail($request);
1295
			BootstrapSkin::displayAlertBox("Sent mail to Request {$request->getId()}", 
1296
				"alert-success");
1297
		}
1298
		else if (array_key_exists($_POST['action'], $availableRequestStates)) {
1299
			// Defer
1300
1301
			$request->setStatus($_POST['action']);
1302
			$deto = $availableRequestStates[$_POST['action']]['deferto'];
1303
			$detolog = $availableRequestStates[$_POST['action']]['defertolog'];
1304
1305
			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...
1306
			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...
1307
			
1308
			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...
1309
			BootstrapSkin::displayAlertBox("Request {$request->getId()} deferred to $deto, sending an email.", 
1310
				"alert-success");
1311
		}
1312
		else {
1313
			// hmm. not sure what happened. Log that we sent the mail anyway.
1314
			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...
1315
			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...
1316
1317
			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...
1318
			BootstrapSkin::displayAlertBox("Sent mail to Request {$request->getId()}", 
1319
				"alert-success");
1320
		}
1321
1322
		$request->setReserved(0);
1323
		$request->save();
1324
		
1325
		$request->updateChecksum();
1326
		$request->save();
1327
1328
		echo defaultpage();
1329
		BootstrapSkin::displayInternalFooter();
1330
		die();		
1331
	}
1332
	else {
1333
		// Not a custom close, just a normal close
1334
	    
1335
		$request->setStatus('Closed');
1336
		$request->setReserved(0);
1337
		
1338
		// TODO: make this transactional
1339
		$request->save();
1340
		
1341
		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...
1342
		
1343
		if ($gem == '0') {
1344
			$crea = "Dropped";
1345
		}
1346
		else {
1347
			$template = EmailTemplate::getById($gem, gGetDb());
1348
			$crea = $template->getName();
1349
		}
1350
1351
		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...
1352
		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...
1353
		
1354
		$towhom = $request->getEmail();
1355
		if ($gem != "0") {
1356
			sendemail($gem, $towhom, $request->getId());
1357
			$request->setEmailSent(1);
1358
		}
1359
		
1360
		$request->updateChecksum();
1361
		$request->save();
1362
		
1363
		echo defaultpage();
1364
		BootstrapSkin::displayInternalFooter();
1365
		die();
1366
	}
1367
}
1368
elseif ($action == "zoom") {
1369
	if (!isset($_GET['id'])) {
1370
		BootstrapSkin::displayAlertBox("No request specified!", "alert-error", "Error!", true, false);
1371
		BootstrapSkin::displayInternalFooter();
1372
		die();
1373
	}
1374
    
1375
	if (isset($_GET['hash'])) {
1376
		$urlhash = $_GET['hash'];
1377
	}
1378
	else {
1379
		$urlhash = "";
1380
	}
1381
	echo zoomPage($_GET['id'], $urlhash);
1382
1383
	$tailscript = getTypeaheadSource(User::getAllUsernames(gGetDb()));
1384
	BootstrapSkin::displayInternalFooter($tailscript);
1385
	die();
1386
}
1387
elseif ($action == "logs") {
1388
	global $baseurl;
1389
	
1390
	$filterUser = isset($_GET['filterUser']) && $_GET['filterUser'] != "" ? $_GET['filterUser'] : false;
1391
	$filterAction = isset($_GET['filterAction']) && $_GET['filterAction'] != "" ? $_GET['filterAction'] : false;
1392
	
1393
	$limit = 100;
1394
	if (isset($_GET['limit'])) {
1395
		$limit = (int)$_GET['limit'];
1396
	}
1397
	
1398
	$offset = 0;
1399
	$page = 1;
1400
	if (isset($_GET['page'])) {
1401
		$page = (int)$_GET['page'];
1402
		$offset = ($page - 1) * $limit;
1403
	}
1404
	
1405
	$logs = Logger::getLogs($filterUser, $filterAction, $limit, $offset);
1406
	if ($logs === false) {
1407
		$smarty->assign("logs", array());
1408
		$smarty->display("logs/main.tpl");
1409
		BootstrapSkin::displayInternalFooter();
1410
		die();
1411
	}
1412
	
1413
	$count = $logs['count'];
1414
	unset($logs['count']);
1415
	
1416
	// The number of pages on the pager to show. Must be odd
1417
	$pageLimit = 9;
1418
	
1419
	$pageData = array( 
1420
		'canprev' => $page != 1,
1421
		'cannext' => ($page * $limit) < $count,
1422
		'maxpage' => ceil($count / $limit),
1423
		'pagelimit' => $pageLimit,
1424
	);
1425
	
1426
	$pageMargin = (($pageLimit - 1) / 2);
1427
	$pageData['lowpage'] = max(1, $page - $pageMargin);
1428
	$pageData['hipage'] = min($pageData['maxpage'], $page + $pageMargin);
1429
	
1430
	$pageCount = ($pageData['hipage'] - $pageData['lowpage']) + 1;
1431
	
1432
	if ($pageCount < $pageLimit) {
1433
		if ($pageData['lowpage'] == 1 && $pageData['hipage'] == $pageData['maxpage']) {
1434
			// nothing to do, we're already at max range.	
1435
		}
1436 View Code Duplication
		elseif ($pageData['lowpage'] == 1 && $pageData['hipage'] < $pageData['maxpage']) {
1437
			$pageData['hipage'] = min($pageLimit, $pageData['maxpage']);
1438
		}
1439 View Code Duplication
		elseif ($pageData['lowpage'] > 1 && $pageData['hipage'] == $pageData['maxpage']) {
1440
			$pageData['lowpage'] = max(1, $pageData['maxpage'] - $pageLimit + 1);
1441
		}
1442
	}
1443
	
1444
	$pageData['pages'] = range($pageData['lowpage'], $pageData['hipage']);
1445
		
1446
	$smarty->assign("pagedata", $pageData);
1447
	
1448
	$smarty->assign("limit", $limit);
1449
	$smarty->assign("page", $page);
1450
1451
	$smarty->assign("logs", $logs);
1452
	
1453
	
1454
	$smarty->assign("filterUser", $filterUser);
1455
	$smarty->assign("filterAction", $filterAction);
1456
	$smarty->display("logs/main.tpl");
1457
1458
	$tailscript = getTypeaheadSource(User::getAllUsernames(gGetDb(), true));
1459
	
1460
	BootstrapSkin::displayInternalFooter($tailscript);
1461
	die();
1462
}
1463
elseif ($action == "reserve") {
1464
	$database = gGetDb();
1465
    
1466
	$database->transactionally(function() use ($database)
1467
	{
1468
		$request = Request::getById($_GET['resid'], $database);
1469
        
1470
		if ($request == false) {
1471
			throw new TransactionException("Request not found", "Error");
1472
		}
1473
        
1474
		global $enableEmailConfirm, $baseurl;
1475
		if ($enableEmailConfirm == 1) {
1476
			if ($request->getEmailConfirm() != "Confirmed") {
1477
				throw new TransactionException("Email address not yet confirmed for this request.", "Error");
1478
			}
1479
		}
1480
1481
		$logQuery = $database->prepare(<<<SQL
1482
SELECT timestamp FROM log
1483
WHERE objectid = :request AND objecttype = 'Request' AND action LIKE 'Closed%'
1484
ORDER BY timestamp DESC LIMIT 1;
1485
SQL
1486
		);
1487
		$logQuery->bindValue(":request", $request->getId());
1488
		$logQuery->execute();
1489
		$logTime = $logQuery->fetchColumn();
1490
		$logQuery->closeCursor();
1491
        
1492
		$date = new DateTime();
1493
		$date->modify("-7 days");
1494
		$oneweek = $date->format("Y-m-d H:i:s");
1495
        
1496
		if ($request->getStatus() == "Closed" && $logTime < $oneweek && !User::getCurrent($database)->isAdmin()) {
1497
			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...
1498
		}
1499
        
1500
	   	if ($request->getReserved() != 0 && $request->getReserved() != User::getCurrent($database)->getId()) {
1501
			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...
1502
		}
1503
           
1504
		if ($request->getReserved() == 0) {
1505
			// Check the number of requests a user has reserved already
1506
			$doubleReserveCountQuery = $database->prepare("SELECT COUNT(*) FROM request WHERE reserved = :userid;");
1507
			$doubleReserveCountQuery->bindValue(":userid", User::getCurrent($database)->getId());
1508
			$doubleReserveCountQuery->execute();
1509
			$doubleReserveCount = $doubleReserveCountQuery->fetchColumn();
1510
			$doubleReserveCountQuery->closeCursor();
1511
1512
			// User already has at least one reserved. 
1513
			if ($doubleReserveCount != 0) {
1514
				SessionAlert::warning("You have multiple requests reserved!");
1515
			}
1516
1517
			// Is the request closed?
1518
			if (!isset($_GET['confclosed'])) {
1519
				if ($request->getStatus() == "Closed") {
1520
					// FIXME: bootstrappify properly
1521
					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...
1522
				}
1523
			}	
1524
        
1525
			$request->setReserved(User::getCurrent($database)->getId());
1526
			$request->save();
1527
	
1528
			Logger::reserve($database, $request);
1529
                
1530
			Notification::requestReserved($request);
1531
                
1532
			SessionAlert::success("Reserved request {$request->getId()}.");
1533
		}
1534
        
1535
		header("Location: $baseurl/acc.php?action=zoom&id={$request->getId()}");
1536
	});
1537
	    
1538
	die();	
1539
}
1540
elseif ($action == "breakreserve") {
1541
	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...
1542
    
1543
	$database = gGetDb();
1544
    
1545
	$request = Request::getById($_GET['resid'], $database);
1546
        
1547
	if ($request == false) {
1548
		BootstrapSkin::displayAlertBox("Could not find request.", "alert-error", "Error", true, false);
1549
		BootstrapSkin::displayInternalFooter();
1550
		die();
1551
	}
1552
    
1553
	if ($request->getReserved() == 0) {
1554
		BootstrapSkin::displayAlertBox("Request is not reserved.", "alert-error", "Error", true, false);
1555
		BootstrapSkin::displayInternalFooter();
1556
		die();
1557
	}
1558
    
1559
	$reservedUser = $request->getReservedObject();
1560
    
1561
	if ($reservedUser == false) {
1562
		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...
1563
		BootstrapSkin::displayInternalFooter();
1564
		die();
1565
	}
1566
    
1567
	if ($reservedUser->getId() != User::getCurrent()->getId()) {
1568
		if (User::getCurrent()->isAdmin()) {
1569
			if (isset($_GET['confirm']) && $_GET['confirm'] == 1) {
1570
				$database->transactionally(function() use($database, $request)
1571
				{
1572
					$request->setReserved(0);
1573
					$request->save();
1574
1575
					Logger::breakReserve($database, $request);
1576
                
1577
					Notification::requestReserveBroken($request);
1578
					header("Location: acc.php");
1579
				});
1580
                
1581
				die();
1582
			}
1583
			else {
1584
				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...
1585
				$smarty->assign("reservedUser", $reservedUser);
1586
				$smarty->assign("request", $request);
1587
                
1588
				$smarty->display("confirmations/breakreserve.tpl");
1589
			}
1590
		}
1591
		else {
1592
			echo "You cannot break " . htmlentities($reservedUser->getUsername()) . "'s reservation";
1593
		}
1594
	}
1595
	else {
1596
		$database->transactionally(function() use ($database, $request)
1597
		{
1598
			$request->setReserved(0);
1599
			$request->save();
1600
1601
			Logger::unreserve($database, $request);
1602
        
1603
			Notification::requestUnreserved($request);
1604
			header("Location: acc.php");
1605
		});
1606
        
1607
		die();
1608
	}
1609
    
1610
	BootstrapSkin::displayInternalFooter();
1611
	die();		
1612
}
1613
elseif ($action == "comment") {
1614
	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...
1615
    
1616
	$request = Request::getById($_GET['id'], gGetDb());
1617
	$smarty->assign("request", $request);
1618
	$smarty->display("commentform.tpl");
1619
	BootstrapSkin::displayInternalFooter();
1620
	die();
1621
}
1622
elseif ($action == "comment-add") {
1623
	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...
1624
    
1625
	$request = Request::getById($_POST['id'], gGetDb());
1626
	if ($request == false) {
1627
		BootstrapSkin::displayAlertBox("Could not find request!", "alert-error", "Error", true, false);
1628
		BootstrapSkin::displayInternalFooter();
1629
		die();
1630
	}
1631
    
1632
	if (!isset($_POST['comment']) || $_POST['comment'] == "") {
1633
		BootstrapSkin::displayAlertBox("Comment must be supplied!", "alert-error", "Error", true, false);
1634
		BootstrapSkin::displayInternalFooter();
1635
		die(); 
1636
	}
1637
    
1638
	$visibility = 'user';
1639
	if (isset($_POST['visibility'])) {
1640
		// sanity check
1641
		$visibility = $_POST['visibility'] == 'user' ? 'user' : 'admin';
1642
	}
1643
    
1644
	//Look for and detect IPv4/IPv6 addresses in comment text, and warn the commenter.
1645 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...
1646
			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...
1647
			$smarty->assign("request", $request);
1648
			$smarty->assign("comment", $_POST['comment']);
1649
			$smarty->assign("actionLocation", "comment-add");
1650
			$smarty->display("privpol-warning.tpl");
1651
			BootstrapSkin::displayInternalFooter();
1652
			die();
1653
		}
1654
    
1655
	$comment = new Comment();
1656
	$comment->setDatabase(gGetDb());
1657
    
1658
	$comment->setRequest($request->getId());
1659
	$comment->setVisibility($visibility);
1660
	$comment->setUser(User::getCurrent()->getId());
1661
	$comment->setComment($_POST['comment']);
1662
    
1663
	$comment->save();
1664
    
1665
	if (isset($_GET['hash'])) {
1666
		$urlhash = urlencode(htmlentities($_GET['hash']));
1667
	}
1668
	else {
1669
		$urlhash = "";
1670
	}
1671
1672
	BootstrapSkin::displayAlertBox(
1673
		"<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...
1674
		"alert-success",
1675
		"Comment added Successfully!",
1676
		true, false);
1677
        
1678
	Notification::commentCreated($comment);
1679
        
1680
	BootstrapSkin::displayInternalFooter();
1681
	die();
1682
}
1683
elseif ($action == "comment-quick") {
1684
	$request = Request::getById($_POST['id'], gGetDb());
1685
	if ($request == false) {
1686
		BootstrapSkin::displayAlertBox("Could not find request!", "alert-error", "Error", true, false);
1687
		BootstrapSkin::displayInternalFooter();
1688
		die();
1689
	}
1690
    
1691
	if (!isset($_POST['comment']) || $_POST['comment'] == "") {
1692
		header("Location: acc.php?action=zoom&id=" . $request->getId());
1693
		die(); 
1694
	}
1695
    
1696
	$visibility = 'user';
1697
	if (isset($_POST['visibility'])) {
1698
		// sanity check
1699
		$visibility = $_POST['visibility'] == 'user' ? 'user' : 'admin';
1700
	}
1701
1702
	//Look for and detect IPv4/IPv6 addresses in comment text, and warn the commenter.
1703 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...
1704
			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...
1705
			$smarty->assign("request", $request);
1706
			$smarty->assign("comment", $_POST['comment']);
1707
			$smarty->assign("actionLocation", "comment-quick");
1708
			$smarty->display("privpol-warning.tpl");
1709
			BootstrapSkin::displayInternalFooter();
1710
			die();
1711
		}
1712
    
1713
	$comment = new Comment();
1714
	$comment->setDatabase(gGetDb());
1715
    
1716
	$comment->setRequest($request->getId());
1717
	$comment->setVisibility($visibility);
1718
	$comment->setUser(User::getCurrent()->getId());
1719
	$comment->setComment($_POST['comment']);
1720
    
1721
	$comment->save();
1722
    
1723
	Notification::commentCreated($comment);
1724
    
1725
	header("Location: acc.php?action=zoom&id=" . $request->getId());
1726
}
1727
elseif ($action == "changepassword") {
1728
	if ((!isset($_POST['oldpassword'])) || $_POST['oldpassword'] == "") {
1729
		//Throw an error if old password is not specified.
1730
		BootstrapSkin::displayAlertBox("You did not enter your old password.", "alert-error", "Error", true, false);
1731
		BootstrapSkin::displayInternalFooter();
1732
		die();
1733
	}
1734
	
1735 View Code Duplication
	if ((!isset($_POST['newpassword'])) || $_POST['newpassword'] == "") {
1736
		//Throw an error if new password is not specified.
1737
		BootstrapSkin::displayAlertBox("You did not enter your new password.", "alert-error", "Error", true, false);
1738
		BootstrapSkin::displayInternalFooter();
1739
		die();
1740
	}
1741
	
1742 View Code Duplication
	if ($_POST['newpassword'] != $_POST['newpasswordconfirm']) {
1743
		//Throw an error if new password does not match what is in the confirmation box.
1744
		BootstrapSkin::displayAlertBox("The 2 new passwords you entered do not match.", "alert-error", "Error", true, false);
1745
		BootstrapSkin::displayInternalFooter();
1746
		die();
1747
	}
1748
    
1749
	$user = User::getCurrent();
1750
	   
1751
	if (!$user->authenticate($_POST['oldpassword'])) {
1752
		//Throw an error if the old password field's value does not match the user's current password.
1753
		BootstrapSkin::displayAlertBox("The old password you entered is not correct.", "alert-error", "Error", true, false);
1754
		BootstrapSkin::displayInternalFooter();
1755
		die();
1756
	}
1757
    
1758
	$user->setPassword($_POST['newpassword']);
1759
	$user->save();
1760
    
1761
	BootstrapSkin::displayAlertBox("Password successfully changed!", "alert-success", "", false, false);
1762
	BootstrapSkin::displayInternalFooter();
1763
	die();
1764
}
1765
elseif ($action == "ec") {
1766
	// edit comment
1767
  
1768
	global $smarty, $baseurl;
1769
    
1770
	$comment = Comment::getById($_GET['id'], gGetDb());
1771
    
1772
	if ($comment == false) {
1773
		// Only using die("Message"); for errors looks ugly.
1774
		BootstrapSkin::displayAlertBox("Comment not found.", "alert-error", "Error", true, false);
1775
		BootstrapSkin::displayInternalFooter();
1776
		die();
1777
	}
1778
	
1779
	// Unauthorized if user is not an admin or the user who made the comment being edited.
1780
	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...
1781
		BootstrapSkin::displayAccessDenied();
1782
		BootstrapSkin::displayInternalFooter();
1783
		die();
1784
	}
1785
	
1786
	// get[id] is safe by this point.
1787
	
1788
	if ($_SERVER['REQUEST_METHOD'] == 'POST') {
1789
		$database = gGetDb();
1790 View Code Duplication
		$database->transactionally(function() use ($database, $comment, $baseurl)
1791
		{
1792
            
1793
			$comment->setComment($_POST['newcomment']);
1794
			$comment->setVisibility($_POST['visibility']);
1795
        
1796
			$comment->save();
1797
        
1798
			Logger::editComment($database, $comment);
1799
        
1800
			Notification::commentEdited($comment);
1801
        
1802
			SessionAlert::success("Comment has been saved successfully");
1803
			header("Location: $baseurl/acc.php?action=zoom&id=" . $comment->getRequest());
1804
		});
1805
        
1806
		die();    
1807
	}
1808
	else {
1809
		$smarty->assign("comment", $comment);
1810
		$smarty->display("edit-comment.tpl");
1811
		BootstrapSkin::displayInternalFooter();
1812
		die();
1813
	}
1814
}
1815
elseif ($action == "sendtouser") {
1816
	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...
1817
    
1818
	$database = gGetDb();
1819
    
1820
	$requestObject = Request::getById($_POST['id'], $database);
1821
	if ($requestObject == false) {
1822
		BootstrapSkin::displayAlertBox("Request invalid", "alert-error", "Could not find request", true, false);
1823
		BootstrapSkin::displayInternalFooter();
1824
		die();
1825
	}
1826
    
1827
	$request = $requestObject->getId();
1828
    
1829
	$user = User::getByUsername($_POST['user'], $database);
1830
	$curuser = User::getCurrent()->getUsername();
1831
    
1832
	if ($user == false) {
1833
		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...
1834
		BootstrapSkin::displayInternalFooter();
1835
		die();
1836
	}
1837
    
1838
	$database->transactionally(function() use ($database, $user, $request, $curuser)
1839
	{
1840
		$updateStatement = $database->prepare("UPDATE request SET reserved = :userid WHERE id = :request LIMIT 1;");
1841
		$updateStatement->bindValue(":userid", $user->getId());
1842
		$updateStatement->bindValue(":request", $request);
1843
		if (!$updateStatement->execute()) {
1844
			throw new TransactionException("Error updating reserved status of request.");   
1845
		}
1846
        
1847
		Logger::sendReservation($database, Request::getById($request, $database), $user);
0 ignored issues
show
\Request::getById($request, $database) 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...
1848
	});
1849
    
1850
	Notification::requestReservationSent($request, $user);
1851
	SessionAlert::success("Reservation sent successfully");
1852
	header("Location: $baseurl/acc.php?action=zoom&id=$request");
1853
}
1854
elseif ($action == "emailmgmt") {
1855
	global $smarty, $createdid, $availableRequestStates;
1856
    
1857
	/* New page for managing Emails, since I would rather not be handling editing
1858
	interface messages (such as the Sitenotice) and the new Emails in the same place. */
1859
	if (isset($_GET['create'])) {
1860
		if (!User::getCurrent()->isAdmin()) {
1861
			BootstrapSkin::displayAccessDenied();
1862
			BootstrapSkin::displayInternalFooter();
1863
			die();
1864
		}
1865
		if (isset($_POST['submit'])) {
1866
			$database = gGetDb();
1867
			$database->transactionally(function() use ($database)
1868
			{
1869
				global $baseurl;
1870
                
1871
				$emailTemplate = new EmailTemplate();
1872
				$emailTemplate->setDatabase($database);
1873
            
1874
				$emailTemplate->setName($_POST['name']);
1875
				$emailTemplate->setText($_POST['text']);
1876
				$emailTemplate->setJsquestion($_POST['jsquestion']);
1877
				$emailTemplate->setDefaultAction($_POST['defaultaction']);
1878
				$emailTemplate->setActive(isset($_POST['active']));
1879
1880
				// 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...
1881
				// getByName(...) returns false on no records found.
1882
				if (EmailTemplate::getByName($_POST['name'], $database)) {
1883
					throw new TransactionException("That Email template name is already being used. Please choose another.");
1884
				}
1885
			
1886
				$emailTemplate->save();
1887
                
1888
				Logger::createEmail($database, $emailTemplate);
1889
                
1890
				Notification::emailCreated($emailTemplate);
1891
                
1892
				SessionAlert::success("Email template has been saved successfully.");
1893
				header("Location: $baseurl/acc.php?action=emailmgmt");
1894
			});
1895
            
1896
			die();
1897
		}
1898
        
1899
		$smarty->assign('id', null);
1900
		$smarty->assign('createdid', $createdid);
1901
		$smarty->assign('requeststates', $availableRequestStates);
1902
		$smarty->assign('emailTemplate', new EmailTemplate());
1903
		$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...
1904
		$smarty->display("email-management/edit.tpl");
1905
		BootstrapSkin::displayInternalFooter();
1906
		die();
1907
	}
1908
	if (isset($_GET['edit'])) {
1909
		global $createdid;
1910
        
1911
		$database = gGetDb();
1912
        
1913
		if (isset($_POST['submit'])) {
1914
			$emailTemplate = EmailTemplate::getById($_GET['edit'], $database);
1915
			// Allow the user to see the edit form (with read only fields) but not POST anything.
1916
			if (!User::getCurrent()->isAdmin()) {
1917
				BootstrapSkin::displayAccessDenied();
1918
				BootstrapSkin::displayInternalFooter();
1919
				die();
1920
			}
1921
            
1922
			$emailTemplate->setName($_POST['name']);
1923
			$emailTemplate->setText($_POST['text']);
1924
			$emailTemplate->setJsquestion($_POST['jsquestion']);
1925
			
1926
			if ($_GET['edit'] == $createdid) {
1927
				// Both checkboxes on the main created message should always be enabled.
1928
				$emailTemplate->setDefaultAction(EmailTemplate::CREATED);
1929
				$emailTemplate->setActive(1);
1930
				$emailTemplate->setPreloadOnly(0);
1931
			}
1932
			else {
1933
				$emailTemplate->setDefaultAction($_POST['defaultaction']);
1934
				$emailTemplate->setActive(isset($_POST['active']));
1935
				$emailTemplate->setPreloadOnly(isset($_POST['preloadonly']));
1936
			}
1937
				
1938
			// 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...
1939
			$nameCheck = EmailTemplate::getByName($_POST['name'], gGetDb());
1940
			if ($nameCheck != false && $nameCheck->getId() != $_GET['edit']) {
1941
				BootstrapSkin::displayAlertBox("That Email template name is already being used. Please choose another.");
1942
				BootstrapSkin::displayInternalFooter();
1943
				die();
1944
			}
1945
1946
			$database->transactionally(function() use ($database, $emailTemplate)
1947
			{
1948
				$emailTemplate->save();
1949
                
1950
				Logger::editedEmail($database, $emailTemplate);
1951
            
1952
				global $baseurl;
1953
                
1954
				Notification::emailEdited($emailTemplate);
1955
				SessionAlert::success("Email template has been saved successfully.");
1956
				header("Location: $baseurl/acc.php?action=emailmgmt");
1957
			});
1958
            
1959
			die();
1960
		}
1961
        
1962
		$emailTemplate = EmailTemplate::getById($_GET['edit'], gGetDb());
1963
		$smarty->assign('id', $emailTemplate->getId());
1964
		$smarty->assign('emailTemplate', $emailTemplate);
1965
		$smarty->assign('createdid', $createdid);
1966
		$smarty->assign('requeststates', $availableRequestStates);
1967
		$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...
1968
		$smarty->display("email-management/edit.tpl");
1969
		BootstrapSkin::displayInternalFooter();
1970
		die();
1971
	}
1972
    
1973
	$query = "SELECT * FROM emailtemplate WHERE active = 1";
1974
	$statement = gGetDb()->prepare($query);
1975
	$statement->execute();
1976
	$rows = $statement->fetchAll(PDO::FETCH_CLASS, "EmailTemplate");
1977
	$smarty->assign('activeemails', $rows);
1978
        
1979
	$query = "SELECT * FROM emailtemplate WHERE active = 0";
1980
	$statement = gGetDb()->prepare($query);
1981
	$statement->execute();
1982
	$inactiverows = $statement->fetchAll(PDO::FETCH_CLASS, "EmailTemplate");
1983
	$smarty->assign('inactiveemails', $inactiverows);
1984
 
1985
	if (count($inactiverows) > 0) {
1986
		$smarty->assign('displayinactive', true);
1987
	}
1988
	else {
1989
		$smarty->assign('displayinactive', false);
1990
	}
1991
    
1992
	$smarty->display("email-management/main.tpl");
1993
	BootstrapSkin::displayInternalFooter();
1994
	die();
1995
}
1996
elseif ($action == "oauthdetach") {
1997
	if ($enforceOAuth) {
1998
		BootstrapSkin::displayAccessDenied();
1999
		BootstrapSkin::displayInternalFooter();
2000
		die();
2001
	}
2002
    
2003
	global $baseurl;
2004
        
2005
	$currentUser = User::getCurrent();
2006
	$currentUser->detachAccount();
2007
        
2008
	header("Location: {$baseurl}/acc.php?action=logout");
2009
}
2010
elseif ($action == "oauthattach") {
2011
	$database = gGetDb();
2012 View Code Duplication
	$database->transactionally(function() use ($database)
2013
	{
2014
		try {
2015
			global $oauthConsumerToken, $oauthSecretToken, $oauthBaseUrl, $oauthBaseUrlInternal;
2016
            
2017
			$user = User::getCurrent();
2018
            
2019
			// Get a request token for OAuth
2020
			$util = new OAuthUtility($oauthConsumerToken, $oauthSecretToken, $oauthBaseUrl, $oauthBaseUrlInternal);
2021
			$requestToken = $util->getRequestToken();
2022
2023
			// save the request token for later
2024
			$user->setOAuthRequestToken($requestToken->key);
2025
			$user->setOAuthRequestSecret($requestToken->secret);
2026
			$user->save();
2027
        
2028
			$redirectUrl = $util->getAuthoriseUrl($requestToken);
2029
        
2030
			header("Location: {$redirectUrl}");
2031
        
2032
		}
2033
		catch (Exception $ex) {
2034
			throw new TransactionException($ex->getMessage(), "Connection to Wikipedia failed.", "alert-error", 0, $ex);
2035
		}
2036
	});
2037
}
2038
# If the action specified does not exist, goto the default page.
2039
else {
2040
	echo defaultpage();
2041
	BootstrapSkin::displayInternalFooter();
2042
	die();
2043
}
2044