Completed
Pull Request — master (#208)
by Matthew
03:23
created
Severity

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