Completed
Push — newinternal-releasecandidate ( 410e59...fe35c3 )
by Simon
17s queued 14s
created
includes/ConsoleTasks/RefreshOAuthDataTask.php 1 patch
Indentation   +31 added lines, -31 removed lines patch added patch discarded remove patch
@@ -17,35 +17,35 @@
 block discarded – undo
17 17
 
18 18
 class RefreshOAuthDataTask extends ConsoleTaskBase
19 19
 {
20
-    public function execute()
21
-    {
22
-        $database = $this->getDatabase();
23
-
24
-        $idList = $database
25
-            ->query('SELECT user FROM oauthtoken WHERE type = \'access\' AND expiry IS NULL')
26
-            ->fetchAll(PDO::FETCH_COLUMN);
27
-
28
-        if (count($idList) > 0) {
29
-            /** @var User[] $users */
30
-            $users = UserSearchHelper::get($database)->inIds($idList)->fetch();
31
-
32
-            $expiredStatement = $database
33
-                ->prepare('UPDATE oauthtoken SET expiry = CURRENT_TIMESTAMP() WHERE user = :u AND type = \'access\'');
34
-
35
-            foreach ($users as $u) {
36
-                $oauth = new OAuthUserHelper($u, $database, $this->getOAuthProtocolHelper(),
37
-                    $this->getSiteConfiguration());
38
-
39
-                try {
40
-                    $oauth->refreshIdentity();
41
-                }
42
-                catch (OAuthException $ex) {
43
-                    $expiredStatement->execute(array(':u' => $u->getId()));
44
-                }
45
-            }
46
-        }
47
-
48
-        $this->getDatabase()
49
-            ->exec('DELETE FROM oauthtoken WHERE expiry IS NOT NULL AND expiry < NOW() AND type = \'request\'');
50
-    }
20
+	public function execute()
21
+	{
22
+		$database = $this->getDatabase();
23
+
24
+		$idList = $database
25
+			->query('SELECT user FROM oauthtoken WHERE type = \'access\' AND expiry IS NULL')
26
+			->fetchAll(PDO::FETCH_COLUMN);
27
+
28
+		if (count($idList) > 0) {
29
+			/** @var User[] $users */
30
+			$users = UserSearchHelper::get($database)->inIds($idList)->fetch();
31
+
32
+			$expiredStatement = $database
33
+				->prepare('UPDATE oauthtoken SET expiry = CURRENT_TIMESTAMP() WHERE user = :u AND type = \'access\'');
34
+
35
+			foreach ($users as $u) {
36
+				$oauth = new OAuthUserHelper($u, $database, $this->getOAuthProtocolHelper(),
37
+					$this->getSiteConfiguration());
38
+
39
+				try {
40
+					$oauth->refreshIdentity();
41
+				}
42
+				catch (OAuthException $ex) {
43
+					$expiredStatement->execute(array(':u' => $u->getId()));
44
+				}
45
+			}
46
+		}
47
+
48
+		$this->getDatabase()
49
+			->exec('DELETE FROM oauthtoken WHERE expiry IS NOT NULL AND expiry < NOW() AND type = \'request\'');
50
+	}
51 51
 }
52 52
\ No newline at end of file
Please login to merge, or discard this patch.
includes/ConsoleTasks/ClearOAuthDataTask.php 3 patches
Indentation   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -14,19 +14,19 @@
 block discarded – undo
14 14
 
15 15
 class ClearOAuthDataTask extends ConsoleTaskBase
16 16
 {
17
-    public function execute()
18
-    {
19
-        $database = $this->getDatabase();
17
+	public function execute()
18
+	{
19
+		$database = $this->getDatabase();
20 20
 
21
-        $users = UserSearchHelper::get($database)->inIds(
22
-            $database->query('SELECT user FROM oauthtoken WHERE type = \'access\'')->fetchColumn());
21
+		$users = UserSearchHelper::get($database)->inIds(
22
+			$database->query('SELECT user FROM oauthtoken WHERE type = \'access\'')->fetchColumn());
23 23
 
24
-        foreach ($users as $u){
25
-            $oauth = new OAuthUserHelper($u, $database, $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
26
-            $oauth->detach();
27
-        }
24
+		foreach ($users as $u){
25
+			$oauth = new OAuthUserHelper($u, $database, $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
26
+			$oauth->detach();
27
+		}
28 28
 
29
-        $database->exec('DELETE FROM oauthtoken');
30
-        $database->exec('DELETE FROM oauthidentity');
31
-    }
29
+		$database->exec('DELETE FROM oauthtoken');
30
+		$database->exec('DELETE FROM oauthidentity');
31
+	}
32 32
 }
33 33
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -21,7 +21,7 @@
 block discarded – undo
21 21
         $users = UserSearchHelper::get($database)->inIds(
22 22
             $database->query('SELECT user FROM oauthtoken WHERE type = \'access\'')->fetchColumn());
23 23
 
24
-        foreach ($users as $u){
24
+        foreach ($users as $u) {
25 25
             $oauth = new OAuthUserHelper($u, $database, $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
26 26
             $oauth->detach();
27 27
         }
Please login to merge, or discard this patch.
Braces   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -21,7 +21,7 @@
 block discarded – undo
21 21
         $users = UserSearchHelper::get($database)->inIds(
22 22
             $database->query('SELECT user FROM oauthtoken WHERE type = \'access\'')->fetchColumn());
23 23
 
24
-        foreach ($users as $u){
24
+        foreach ($users as $u) {
25 25
             $oauth = new OAuthUserHelper($u, $database, $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
26 26
             $oauth->detach();
27 27
         }
Please login to merge, or discard this patch.
includes/ConsoleTasks/RunJobQueueTask.php 3 patches
Indentation   +107 added lines, -107 removed lines patch added patch discarded remove patch
@@ -22,111 +22,111 @@
 block discarded – undo
22 22
 
23 23
 class RunJobQueueTask extends ConsoleTaskBase
24 24
 {
25
-    private $taskList = array(
26
-        WelcomeUserTask::class,
27
-        BotCreationTask::class,
28
-        UserCreationTask::class
29
-    );
30
-
31
-    public function execute()
32
-    {
33
-        $database = $this->getDatabase();
34
-
35
-        // ensure we're running inside a tx here.
36
-        if (!$database->hasActiveTransaction()) {
37
-            $database->beginTransaction();
38
-        }
39
-
40
-        $sql = 'SELECT * FROM jobqueue WHERE status = :status ORDER BY enqueue LIMIT :lim';
41
-        $statement = $database->prepare($sql);
42
-        $statement->execute(array(':status' => JobQueue::STATUS_READY, ':lim' => 10));
43
-        /** @var JobQueue[] $queuedJobs */
44
-        $queuedJobs = $statement->fetchAll(PDO::FETCH_CLASS, JobQueue::class);
45
-
46
-        // mark all the jobs as running, and commit the txn so we're not holding onto long-running transactions.
47
-        // We'll re-lock the row when we get to it.
48
-        foreach ($queuedJobs as $job) {
49
-            $job->setDatabase($database);
50
-            $job->setStatus(JobQueue::STATUS_WAITING);
51
-            $job->setError(null);
52
-            $job->setAcknowledged(null);
53
-            $job->save();
54
-        }
55
-
56
-        $database->commit();
57
-
58
-        set_error_handler(array(RunJobQueueTask::class, 'errorHandler'), E_ALL);
59
-
60
-        foreach ($queuedJobs as $job) {
61
-            try {
62
-                $database->beginTransaction();
63
-
64
-                // re-lock the job
65
-                $job->setStatus(JobQueue::STATUS_RUNNING);
66
-                $job->save();
67
-
68
-                // validate we're allowed to run the requested task (whitelist)
69
-                if (!in_array($job->getTask(), $this->taskList)) {
70
-                    throw new ApplicationLogicException('Job task not registered');
71
-                }
72
-
73
-                // Create a task.
74
-                $taskName = $job->getTask();
75
-
76
-                if(!class_exists($taskName)) {
77
-                    throw new ApplicationLogicException('Job task does not exist');
78
-                }
79
-
80
-                /** @var BackgroundTaskBase $task */
81
-                $task = new $taskName;
82
-
83
-                $this->setupTask($task, $job);
84
-                $task->run();
85
-            }
86
-            catch (Exception $ex) {
87
-                $database->rollBack();
88
-                $database->beginTransaction();
89
-
90
-                /** @var JobQueue $job */
91
-                $job = JobQueue::getById($job->getId(), $database);
92
-                $job->setDatabase($database);
93
-                $job->setStatus(JobQueue::STATUS_FAILED);
94
-                $job->setError($ex->getMessage());
95
-                $job->setAcknowledged(0);
96
-                $job->save();
97
-
98
-                /** @var Request $request */
99
-                $request = Request::getById($job->getRequest(), $database);
100
-                if ($request === false) {
101
-                    $request = null;
102
-                }
103
-
104
-                Logger::backgroundJobIssue($this->getDatabase(), $job);
105
-
106
-                $database->commit();
107
-            }
108
-            finally {
109
-                $database->commit();
110
-            }
111
-        }
112
-    }
113
-
114
-    /**
115
-     * @param BackgroundTaskBase $task
116
-     * @param JobQueue           $job
117
-     */
118
-    private function setupTask(BackgroundTaskBase $task, JobQueue $job)
119
-    {
120
-        $task->setJob($job);
121
-        $task->setDatabase($this->getDatabase());
122
-        $task->setHttpHelper($this->getHttpHelper());
123
-        $task->setOauthProtocolHelper($this->getOAuthProtocolHelper());
124
-        $task->setEmailHelper($this->getEmailHelper());
125
-        $task->setSiteConfiguration($this->getSiteConfiguration());
126
-        $task->setNotificationHelper($this->getNotificationHelper());
127
-    }
128
-
129
-    public static function errorHandler($errno, $errstr, $errfile, $errline) {
130
-        throw new Exception($errfile . "@" . $errline . ": " . $errstr);
131
-    }
25
+	private $taskList = array(
26
+		WelcomeUserTask::class,
27
+		BotCreationTask::class,
28
+		UserCreationTask::class
29
+	);
30
+
31
+	public function execute()
32
+	{
33
+		$database = $this->getDatabase();
34
+
35
+		// ensure we're running inside a tx here.
36
+		if (!$database->hasActiveTransaction()) {
37
+			$database->beginTransaction();
38
+		}
39
+
40
+		$sql = 'SELECT * FROM jobqueue WHERE status = :status ORDER BY enqueue LIMIT :lim';
41
+		$statement = $database->prepare($sql);
42
+		$statement->execute(array(':status' => JobQueue::STATUS_READY, ':lim' => 10));
43
+		/** @var JobQueue[] $queuedJobs */
44
+		$queuedJobs = $statement->fetchAll(PDO::FETCH_CLASS, JobQueue::class);
45
+
46
+		// mark all the jobs as running, and commit the txn so we're not holding onto long-running transactions.
47
+		// We'll re-lock the row when we get to it.
48
+		foreach ($queuedJobs as $job) {
49
+			$job->setDatabase($database);
50
+			$job->setStatus(JobQueue::STATUS_WAITING);
51
+			$job->setError(null);
52
+			$job->setAcknowledged(null);
53
+			$job->save();
54
+		}
55
+
56
+		$database->commit();
57
+
58
+		set_error_handler(array(RunJobQueueTask::class, 'errorHandler'), E_ALL);
59
+
60
+		foreach ($queuedJobs as $job) {
61
+			try {
62
+				$database->beginTransaction();
63
+
64
+				// re-lock the job
65
+				$job->setStatus(JobQueue::STATUS_RUNNING);
66
+				$job->save();
67
+
68
+				// validate we're allowed to run the requested task (whitelist)
69
+				if (!in_array($job->getTask(), $this->taskList)) {
70
+					throw new ApplicationLogicException('Job task not registered');
71
+				}
72
+
73
+				// Create a task.
74
+				$taskName = $job->getTask();
75
+
76
+				if(!class_exists($taskName)) {
77
+					throw new ApplicationLogicException('Job task does not exist');
78
+				}
79
+
80
+				/** @var BackgroundTaskBase $task */
81
+				$task = new $taskName;
82
+
83
+				$this->setupTask($task, $job);
84
+				$task->run();
85
+			}
86
+			catch (Exception $ex) {
87
+				$database->rollBack();
88
+				$database->beginTransaction();
89
+
90
+				/** @var JobQueue $job */
91
+				$job = JobQueue::getById($job->getId(), $database);
92
+				$job->setDatabase($database);
93
+				$job->setStatus(JobQueue::STATUS_FAILED);
94
+				$job->setError($ex->getMessage());
95
+				$job->setAcknowledged(0);
96
+				$job->save();
97
+
98
+				/** @var Request $request */
99
+				$request = Request::getById($job->getRequest(), $database);
100
+				if ($request === false) {
101
+					$request = null;
102
+				}
103
+
104
+				Logger::backgroundJobIssue($this->getDatabase(), $job);
105
+
106
+				$database->commit();
107
+			}
108
+			finally {
109
+				$database->commit();
110
+			}
111
+		}
112
+	}
113
+
114
+	/**
115
+	 * @param BackgroundTaskBase $task
116
+	 * @param JobQueue           $job
117
+	 */
118
+	private function setupTask(BackgroundTaskBase $task, JobQueue $job)
119
+	{
120
+		$task->setJob($job);
121
+		$task->setDatabase($this->getDatabase());
122
+		$task->setHttpHelper($this->getHttpHelper());
123
+		$task->setOauthProtocolHelper($this->getOAuthProtocolHelper());
124
+		$task->setEmailHelper($this->getEmailHelper());
125
+		$task->setSiteConfiguration($this->getSiteConfiguration());
126
+		$task->setNotificationHelper($this->getNotificationHelper());
127
+	}
128
+
129
+	public static function errorHandler($errno, $errstr, $errfile, $errline) {
130
+		throw new Exception($errfile . "@" . $errline . ": " . $errstr);
131
+	}
132 132
 }
133 133
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -73,7 +73,7 @@  discard block
 block discarded – undo
73 73
                 // Create a task.
74 74
                 $taskName = $job->getTask();
75 75
 
76
-                if(!class_exists($taskName)) {
76
+                if (!class_exists($taskName)) {
77 77
                     throw new ApplicationLogicException('Job task does not exist');
78 78
                 }
79 79
 
@@ -127,6 +127,6 @@  discard block
 block discarded – undo
127 127
     }
128 128
 
129 129
     public static function errorHandler($errno, $errstr, $errfile, $errline) {
130
-        throw new Exception($errfile . "@" . $errline . ": " . $errstr);
130
+        throw new Exception($errfile."@".$errline.": ".$errstr);
131 131
     }
132 132
 }
133 133
\ No newline at end of file
Please login to merge, or discard this patch.
Braces   +2 added lines, -1 removed lines patch added patch discarded remove patch
@@ -126,7 +126,8 @@
 block discarded – undo
126 126
         $task->setNotificationHelper($this->getNotificationHelper());
127 127
     }
128 128
 
129
-    public static function errorHandler($errno, $errstr, $errfile, $errline) {
129
+    public static function errorHandler($errno, $errstr, $errfile, $errline)
130
+    {
130 131
         throw new Exception($errfile . "@" . $errline . ": " . $errstr);
131 132
     }
132 133
 }
133 134
\ No newline at end of file
Please login to merge, or discard this patch.
includes/Pages/RequestAction/RequestActionBase.php 1 patch
Indentation   +44 added lines, -44 removed lines patch added patch discarded remove patch
@@ -19,54 +19,54 @@
 block discarded – undo
19 19
 
20 20
 abstract class RequestActionBase extends InternalPageBase
21 21
 {
22
-    /**
23
-     * @param PdoDatabase $database
24
-     *
25
-     * @return Request
26
-     * @throws ApplicationLogicException
27
-     */
28
-    protected function getRequest(PdoDatabase $database)
29
-    {
30
-        $requestId = WebRequest::postInt('request');
31
-        if ($requestId === null) {
32
-            throw new ApplicationLogicException('Request ID not found');
33
-        }
22
+	/**
23
+	 * @param PdoDatabase $database
24
+	 *
25
+	 * @return Request
26
+	 * @throws ApplicationLogicException
27
+	 */
28
+	protected function getRequest(PdoDatabase $database)
29
+	{
30
+		$requestId = WebRequest::postInt('request');
31
+		if ($requestId === null) {
32
+			throw new ApplicationLogicException('Request ID not found');
33
+		}
34 34
 
35
-        /** @var Request $request */
36
-        $request = Request::getById($requestId, $database);
35
+		/** @var Request $request */
36
+		$request = Request::getById($requestId, $database);
37 37
 
38
-        if ($request === false) {
39
-            throw new ApplicationLogicException('Request not found');
40
-        }
38
+		if ($request === false) {
39
+			throw new ApplicationLogicException('Request not found');
40
+		}
41 41
 
42
-        return $request;
43
-    }
42
+		return $request;
43
+	}
44 44
 
45
-    final protected function checkPosted()
46
-    {
47
-        // if the request was not posted, send the user away.
48
-        if (!WebRequest::wasPosted()) {
49
-            throw new ApplicationLogicException('This page does not support GET methods.');
50
-        }
45
+	final protected function checkPosted()
46
+	{
47
+		// if the request was not posted, send the user away.
48
+		if (!WebRequest::wasPosted()) {
49
+			throw new ApplicationLogicException('This page does not support GET methods.');
50
+		}
51 51
 
52
-        // validate the CSRF token
53
-        $this->validateCSRFToken();
54
-    }
52
+		// validate the CSRF token
53
+		$this->validateCSRFToken();
54
+	}
55 55
 
56
-    /**
57
-     * @param Request     $request
58
-     * @param             $parentTaskId
59
-     * @param User        $user
60
-     * @param PdoDatabase $database
61
-     */
62
-    protected function enqueueWelcomeTask(Request $request, $parentTaskId, User $user, PdoDatabase $database)
63
-    {
64
-        $welcomeTask = new JobQueue();
65
-        $welcomeTask->setTask(WelcomeUserTask::class);
66
-        $welcomeTask->setRequest($request->getId());
67
-        $welcomeTask->setParent($parentTaskId);
68
-        $welcomeTask->setTriggerUserId($user->getId());
69
-        $welcomeTask->setDatabase($database);
70
-        $welcomeTask->save();
71
-    }
56
+	/**
57
+	 * @param Request     $request
58
+	 * @param             $parentTaskId
59
+	 * @param User        $user
60
+	 * @param PdoDatabase $database
61
+	 */
62
+	protected function enqueueWelcomeTask(Request $request, $parentTaskId, User $user, PdoDatabase $database)
63
+	{
64
+		$welcomeTask = new JobQueue();
65
+		$welcomeTask->setTask(WelcomeUserTask::class);
66
+		$welcomeTask->setRequest($request->getId());
67
+		$welcomeTask->setParent($parentTaskId);
68
+		$welcomeTask->setTriggerUserId($user->getId());
69
+		$welcomeTask->setDatabase($database);
70
+		$welcomeTask->save();
71
+	}
72 72
 }
73 73
\ No newline at end of file
Please login to merge, or discard this patch.
includes/Pages/RequestAction/PageDropRequest.php 1 patch
Indentation   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -15,22 +15,22 @@
 block discarded – undo
15 15
 
16 16
 class PageDropRequest extends PageCloseRequest
17 17
 {
18
-    protected function getTemplate(PdoDatabase $database)
19
-    {
20
-        return EmailTemplate::getDroppedTemplate();
21
-    }
18
+	protected function getTemplate(PdoDatabase $database)
19
+	{
20
+		return EmailTemplate::getDroppedTemplate();
21
+	}
22 22
 
23
-    protected function confirmEmailAlreadySent(Request $request, EmailTemplate $template)
24
-    {
25
-        return false;
26
-    }
23
+	protected function confirmEmailAlreadySent(Request $request, EmailTemplate $template)
24
+	{
25
+		return false;
26
+	}
27 27
 
28
-    protected function confirmAccountCreated(Request $request, EmailTemplate $template)
29
-    {
30
-        return false;
31
-    }
28
+	protected function confirmAccountCreated(Request $request, EmailTemplate $template)
29
+	{
30
+		return false;
31
+	}
32 32
 
33
-    protected function sendMail(Request $request, $mailText, User $currentUser, $ccMailingList)
34
-    {
35
-    }
33
+	protected function sendMail(Request $request, $mailText, User $currentUser, $ccMailingList)
34
+	{
35
+	}
36 36
 }
37 37
\ No newline at end of file
Please login to merge, or discard this patch.
includes/Pages/RequestAction/PageCreateRequest.php 1 patch
Indentation   +147 added lines, -147 removed lines patch added patch discarded remove patch
@@ -34,151 +34,151 @@
 block discarded – undo
34 34
  */
35 35
 class PageCreateRequest extends RequestActionBase
36 36
 {
37
-    /**
38
-     * Main function for this page, when no specific actions are called.
39
-     * @return void
40
-     * @throws AccessDeniedException
41
-     * @throws ApplicationLogicException
42
-     */
43
-    protected function main()
44
-    {
45
-        $this->checkPosted();
46
-
47
-        $database = $this->getDatabase();
48
-
49
-        $request = $this->getRequest($database);
50
-        $template = $this->getTemplate($database);
51
-        $creationMode = $this->getCreationMode();
52
-        $user = User::getCurrent($database);
53
-
54
-        $secMgr = $this->getSecurityManager();
55
-        if ($secMgr->allows('RequestCreation', User::CREATION_BOT, $user) !== SecurityManager::ALLOWED
56
-            && $creationMode === 'bot'
57
-        ) {
58
-            throw new AccessDeniedException($secMgr);
59
-        }
60
-        elseif ($secMgr->allows('RequestCreation', User::CREATION_OAUTH, $user) !== SecurityManager::ALLOWED
61
-            && $creationMode === 'oauth'
62
-        ) {
63
-            throw new AccessDeniedException($secMgr);
64
-        }
65
-
66
-        if ($request->getEmailSent()) {
67
-            throw new ApplicationLogicException('This requester has already had an email sent to them. Please fall back to manual creation');
68
-        }
69
-
70
-        $request->setStatus(RequestStatus::JOBQUEUE);
71
-        $request->setReserved(null);
72
-        $request->save();
73
-
74
-        Logger::enqueuedJobQueue($database, $request);
75
-
76
-        $creationTaskId = $this->enqueueCreationTask($creationMode, $request, $template, $user, $database);
77
-
78
-        if ($user->getWelcomeTemplate() !== null) {
79
-            $this->enqueueWelcomeTask($request, $creationTaskId, $user, $database);
80
-        }
81
-
82
-        SessionAlert::success("Request {$request->getId()} has been queued for autocreation");
83
-
84
-        $this->redirect();
85
-    }
86
-
87
-    protected function getCreationMode()
88
-    {
89
-        $creationMode = WebRequest::postString('mode');
90
-        if ($creationMode !== 'oauth' && $creationMode !== 'bot') {
91
-            throw new ApplicationLogicException('Unknown creation mode');
92
-        }
93
-
94
-        return $creationMode;
95
-    }
96
-
97
-    /**
98
-     * @param PdoDatabase $database
99
-     *
100
-     * @return EmailTemplate
101
-     * @throws ApplicationLogicException
102
-     */
103
-    protected function getTemplate(PdoDatabase $database)
104
-    {
105
-        $templateId = WebRequest::postInt('template');
106
-        if ($templateId === null) {
107
-            throw new ApplicationLogicException('No template specified');
108
-        }
109
-
110
-        /** @var EmailTemplate $template */
111
-        $template = EmailTemplate::getById($templateId, $database);
112
-        if ($template === false || !$template->getActive()) {
113
-            throw new ApplicationLogicException('Invalid or inactive template specified');
114
-        }
115
-
116
-        if ($template->getDefaultAction() !== EmailTemplate::CREATED) {
117
-            throw new ApplicationLogicException('Specified template is not a creation template!');
118
-        }
119
-
120
-        return $template;
121
-    }
122
-
123
-    /**
124
-     * @param PdoDatabase $database
125
-     *
126
-     * @return Request
127
-     * @throws ApplicationLogicException
128
-     */
129
-    protected function getRequest(PdoDatabase $database)
130
-    {
131
-        $request = parent::getRequest($database);
132
-
133
-        if ($request->getStatus() == RequestStatus::CLOSED) {
134
-            throw new ApplicationLogicException('Request is already closed');
135
-        }
136
-
137
-        return $request;
138
-    }
139
-
140
-    /**
141
-     * @param               $creationMode
142
-     * @param Request       $request
143
-     * @param EmailTemplate $template
144
-     * @param User          $user
145
-     *
146
-     * @param PdoDatabase   $database
147
-     *
148
-     * @return int
149
-     * @throws ApplicationLogicException
150
-     */
151
-    protected function enqueueCreationTask(
152
-        $creationMode,
153
-        Request $request,
154
-        EmailTemplate $template,
155
-        User $user,
156
-        PdoDatabase $database
157
-    ) {
158
-        $creationTaskClass = null;
159
-
160
-        if ($creationMode == "oauth") {
161
-            $creationTaskClass = UserCreationTask::class;
162
-        }
163
-
164
-        if ($creationMode == "bot") {
165
-            $creationTaskClass = BotCreationTask::class;
166
-        }
167
-
168
-        if ($creationTaskClass === null) {
169
-            throw new ApplicationLogicException('Cannot determine creation mode');
170
-        }
171
-
172
-        $creationTask = new JobQueue();
173
-        $creationTask->setTask($creationTaskClass);
174
-        $creationTask->setRequest($request->getId());
175
-        $creationTask->setEmailTemplate($template->getId());
176
-        $creationTask->setTriggerUserId($user->getId());
177
-        $creationTask->setDatabase($database);
178
-        $creationTask->save();
179
-
180
-        $creationTaskId = $creationTask->getId();
181
-
182
-        return $creationTaskId;
183
-    }
37
+	/**
38
+	 * Main function for this page, when no specific actions are called.
39
+	 * @return void
40
+	 * @throws AccessDeniedException
41
+	 * @throws ApplicationLogicException
42
+	 */
43
+	protected function main()
44
+	{
45
+		$this->checkPosted();
46
+
47
+		$database = $this->getDatabase();
48
+
49
+		$request = $this->getRequest($database);
50
+		$template = $this->getTemplate($database);
51
+		$creationMode = $this->getCreationMode();
52
+		$user = User::getCurrent($database);
53
+
54
+		$secMgr = $this->getSecurityManager();
55
+		if ($secMgr->allows('RequestCreation', User::CREATION_BOT, $user) !== SecurityManager::ALLOWED
56
+			&& $creationMode === 'bot'
57
+		) {
58
+			throw new AccessDeniedException($secMgr);
59
+		}
60
+		elseif ($secMgr->allows('RequestCreation', User::CREATION_OAUTH, $user) !== SecurityManager::ALLOWED
61
+			&& $creationMode === 'oauth'
62
+		) {
63
+			throw new AccessDeniedException($secMgr);
64
+		}
65
+
66
+		if ($request->getEmailSent()) {
67
+			throw new ApplicationLogicException('This requester has already had an email sent to them. Please fall back to manual creation');
68
+		}
69
+
70
+		$request->setStatus(RequestStatus::JOBQUEUE);
71
+		$request->setReserved(null);
72
+		$request->save();
73
+
74
+		Logger::enqueuedJobQueue($database, $request);
75
+
76
+		$creationTaskId = $this->enqueueCreationTask($creationMode, $request, $template, $user, $database);
77
+
78
+		if ($user->getWelcomeTemplate() !== null) {
79
+			$this->enqueueWelcomeTask($request, $creationTaskId, $user, $database);
80
+		}
81
+
82
+		SessionAlert::success("Request {$request->getId()} has been queued for autocreation");
83
+
84
+		$this->redirect();
85
+	}
86
+
87
+	protected function getCreationMode()
88
+	{
89
+		$creationMode = WebRequest::postString('mode');
90
+		if ($creationMode !== 'oauth' && $creationMode !== 'bot') {
91
+			throw new ApplicationLogicException('Unknown creation mode');
92
+		}
93
+
94
+		return $creationMode;
95
+	}
96
+
97
+	/**
98
+	 * @param PdoDatabase $database
99
+	 *
100
+	 * @return EmailTemplate
101
+	 * @throws ApplicationLogicException
102
+	 */
103
+	protected function getTemplate(PdoDatabase $database)
104
+	{
105
+		$templateId = WebRequest::postInt('template');
106
+		if ($templateId === null) {
107
+			throw new ApplicationLogicException('No template specified');
108
+		}
109
+
110
+		/** @var EmailTemplate $template */
111
+		$template = EmailTemplate::getById($templateId, $database);
112
+		if ($template === false || !$template->getActive()) {
113
+			throw new ApplicationLogicException('Invalid or inactive template specified');
114
+		}
115
+
116
+		if ($template->getDefaultAction() !== EmailTemplate::CREATED) {
117
+			throw new ApplicationLogicException('Specified template is not a creation template!');
118
+		}
119
+
120
+		return $template;
121
+	}
122
+
123
+	/**
124
+	 * @param PdoDatabase $database
125
+	 *
126
+	 * @return Request
127
+	 * @throws ApplicationLogicException
128
+	 */
129
+	protected function getRequest(PdoDatabase $database)
130
+	{
131
+		$request = parent::getRequest($database);
132
+
133
+		if ($request->getStatus() == RequestStatus::CLOSED) {
134
+			throw new ApplicationLogicException('Request is already closed');
135
+		}
136
+
137
+		return $request;
138
+	}
139
+
140
+	/**
141
+	 * @param               $creationMode
142
+	 * @param Request       $request
143
+	 * @param EmailTemplate $template
144
+	 * @param User          $user
145
+	 *
146
+	 * @param PdoDatabase   $database
147
+	 *
148
+	 * @return int
149
+	 * @throws ApplicationLogicException
150
+	 */
151
+	protected function enqueueCreationTask(
152
+		$creationMode,
153
+		Request $request,
154
+		EmailTemplate $template,
155
+		User $user,
156
+		PdoDatabase $database
157
+	) {
158
+		$creationTaskClass = null;
159
+
160
+		if ($creationMode == "oauth") {
161
+			$creationTaskClass = UserCreationTask::class;
162
+		}
163
+
164
+		if ($creationMode == "bot") {
165
+			$creationTaskClass = BotCreationTask::class;
166
+		}
167
+
168
+		if ($creationTaskClass === null) {
169
+			throw new ApplicationLogicException('Cannot determine creation mode');
170
+		}
171
+
172
+		$creationTask = new JobQueue();
173
+		$creationTask->setTask($creationTaskClass);
174
+		$creationTask->setRequest($request->getId());
175
+		$creationTask->setEmailTemplate($template->getId());
176
+		$creationTask->setTriggerUserId($user->getId());
177
+		$creationTask->setDatabase($database);
178
+		$creationTask->save();
179
+
180
+		$creationTaskId = $creationTask->getId();
181
+
182
+		return $creationTaskId;
183
+	}
184 184
 }
185 185
\ No newline at end of file
Please login to merge, or discard this patch.
includes/Pages/PageMain.php 2 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -111,7 +111,7 @@  discard block
 block discarded – undo
111 111
 
112 112
         $results = $search->getRecordCount($requestCount)->fetch();
113 113
 
114
-        if($requestCount > 0) {
114
+        if ($requestCount > 0) {
115 115
             $requestSectionData['Hospital - Requests failed auto-creation'] = array(
116 116
                 'requests' => $results,
117 117
                 'total'    => $requestCount,
@@ -143,7 +143,7 @@  discard block
 block discarded – undo
143 143
 
144 144
         $results = $search->getRecordCount($requestCount)->fetch();
145 145
 
146
-        if($requestCount > 0) {
146
+        if ($requestCount > 0) {
147 147
             $requestSectionData['Requests queued in the Job Queue'] = array(
148 148
                 'requests' => $results,
149 149
                 'total'    => $requestCount,
Please login to merge, or discard this patch.
Indentation   +159 added lines, -159 removed lines patch added patch discarded remove patch
@@ -20,62 +20,62 @@  discard block
 block discarded – undo
20 20
 
21 21
 class PageMain extends InternalPageBase
22 22
 {
23
-    /**
24
-     * Main function for this page, when no actions are called.
25
-     */
26
-    protected function main()
27
-    {
28
-        $this->assignCSRFToken();
29
-
30
-        $config = $this->getSiteConfiguration();
31
-        $database = $this->getDatabase();
32
-        $currentUser = User::getCurrent($database);
33
-
34
-        // general template configuration
35
-        $this->assign('defaultRequestState', $config->getDefaultRequestStateKey());
36
-        $this->assign('requestLimitShowOnly', $config->getMiserModeLimit());
37
-
38
-        // Get map of possible usernames
39
-        $userList = UserSearchHelper::get($database)->withReservedRequest();
40
-        $this->assign('userList', $userList);
41
-
42
-        $seeAllRequests = $this->barrierTest('seeAllRequests', $currentUser, PageViewRequest::class);
43
-
44
-        // Fetch request data
45
-        $requestSectionData = array();
46
-        if ($seeAllRequests) {
47
-            $this->setupStatusSections($database, $config, $requestSectionData);
48
-            $this->setupHospitalQueue($database, $config, $requestSectionData);
49
-            $this->setupJobQueue($database, $config, $requestSectionData);
50
-        }
51
-        $this->setupLastFiveClosedData($database, $seeAllRequests);
52
-
53
-        // Assign data to template
54
-        $this->assign('requestSectionData', $requestSectionData);
55
-
56
-        // Extra rights
57
-        $this->assign('canBan', $this->barrierTest('set', $currentUser, PageBan::class));
58
-        $this->assign('canBreakReservation', $this->barrierTest('force', $currentUser, PageBreakReservation::class));
59
-
60
-        $this->addCss('/resources/mainpage.css');
61
-
62
-        $this->setTemplate('mainpage/mainpage.tpl');
63
-    }
64
-
65
-    /**
66
-     * @param PdoDatabase $database
67
-     * @param bool        $seeAllRequests
68
-     *
69
-     * @internal param User $currentUser
70
-     */
71
-    private function setupLastFiveClosedData(PdoDatabase $database, $seeAllRequests)
72
-    {
73
-        $this->assign('showLastFive', $seeAllRequests);
74
-        if (!$seeAllRequests) {
75
-            return;
76
-        }
77
-
78
-        $query = <<<SQL
23
+	/**
24
+	 * Main function for this page, when no actions are called.
25
+	 */
26
+	protected function main()
27
+	{
28
+		$this->assignCSRFToken();
29
+
30
+		$config = $this->getSiteConfiguration();
31
+		$database = $this->getDatabase();
32
+		$currentUser = User::getCurrent($database);
33
+
34
+		// general template configuration
35
+		$this->assign('defaultRequestState', $config->getDefaultRequestStateKey());
36
+		$this->assign('requestLimitShowOnly', $config->getMiserModeLimit());
37
+
38
+		// Get map of possible usernames
39
+		$userList = UserSearchHelper::get($database)->withReservedRequest();
40
+		$this->assign('userList', $userList);
41
+
42
+		$seeAllRequests = $this->barrierTest('seeAllRequests', $currentUser, PageViewRequest::class);
43
+
44
+		// Fetch request data
45
+		$requestSectionData = array();
46
+		if ($seeAllRequests) {
47
+			$this->setupStatusSections($database, $config, $requestSectionData);
48
+			$this->setupHospitalQueue($database, $config, $requestSectionData);
49
+			$this->setupJobQueue($database, $config, $requestSectionData);
50
+		}
51
+		$this->setupLastFiveClosedData($database, $seeAllRequests);
52
+
53
+		// Assign data to template
54
+		$this->assign('requestSectionData', $requestSectionData);
55
+
56
+		// Extra rights
57
+		$this->assign('canBan', $this->barrierTest('set', $currentUser, PageBan::class));
58
+		$this->assign('canBreakReservation', $this->barrierTest('force', $currentUser, PageBreakReservation::class));
59
+
60
+		$this->addCss('/resources/mainpage.css');
61
+
62
+		$this->setTemplate('mainpage/mainpage.tpl');
63
+	}
64
+
65
+	/**
66
+	 * @param PdoDatabase $database
67
+	 * @param bool        $seeAllRequests
68
+	 *
69
+	 * @internal param User $currentUser
70
+	 */
71
+	private function setupLastFiveClosedData(PdoDatabase $database, $seeAllRequests)
72
+	{
73
+		$this->assign('showLastFive', $seeAllRequests);
74
+		if (!$seeAllRequests) {
75
+			return;
76
+		}
77
+
78
+		$query = <<<SQL
79 79
 		SELECT request.id, request.name, request.updateversion
80 80
 		FROM request /* PageMain::main() */
81 81
 		JOIN log ON log.objectid = request.id AND log.objecttype = 'Request'
@@ -84,107 +84,107 @@  discard block
 block discarded – undo
84 84
 		LIMIT 5;
85 85
 SQL;
86 86
 
87
-        $statement = $database->prepare($query);
88
-        $statement->execute();
89
-
90
-        $last5result = $statement->fetchAll(PDO::FETCH_ASSOC);
91
-
92
-        $this->assign('lastFive', $last5result);
93
-    }
94
-
95
-    /**
96
-     * @param PdoDatabase       $database
97
-     * @param SiteConfiguration $config
98
-     * @param                   $requestSectionData
99
-     */
100
-    private function setupHospitalQueue(
101
-        PdoDatabase $database,
102
-        SiteConfiguration $config,
103
-        &$requestSectionData
104
-    ) {
105
-        $search = RequestSearchHelper::get($database)
106
-            ->limit($config->getMiserModeLimit())
107
-            ->excludingStatus('Closed')
108
-            ->isHospitalised();
109
-
110
-        if ($config->getEmailConfirmationEnabled()) {
111
-            $search->withConfirmedEmail();
112
-        }
113
-
114
-        $results = $search->getRecordCount($requestCount)->fetch();
115
-
116
-        if($requestCount > 0) {
117
-            $requestSectionData['Hospital - Requests failed auto-creation'] = array(
118
-                'requests' => $results,
119
-                'total'    => $requestCount,
120
-                'api'      => 'hospital',
121
-                'type'     => 'hospital',
122
-                'special'  => 'Job Queue',
123
-                'help'     => 'This queue lists all the requests which have been attempted to be created in the background, but for which this has failed for one reason or another. Check the job queue to find the error. Requests here may need to be created manually, or it may be possible to re-queue the request for auto-creation by the tool, or it may have been created already. Use your own technical discretion here.'
124
-            );
125
-        }
126
-    }
127
-
128
-    /**
129
-     * @param PdoDatabase       $database
130
-     * @param SiteConfiguration $config
131
-     * @param                   $requestSectionData
132
-     */
133
-    private function setupJobQueue(
134
-        PdoDatabase $database,
135
-        SiteConfiguration $config,
136
-        &$requestSectionData
137
-    ) {
138
-        $search = RequestSearchHelper::get($database)
139
-            ->limit($config->getMiserModeLimit())
140
-            ->byStatus(RequestStatus::JOBQUEUE);
141
-
142
-        if ($config->getEmailConfirmationEnabled()) {
143
-            $search->withConfirmedEmail();
144
-        }
145
-
146
-        $results = $search->getRecordCount($requestCount)->fetch();
147
-
148
-        if($requestCount > 0) {
149
-            $requestSectionData['Requests queued in the Job Queue'] = array(
150
-                'requests' => $results,
151
-                'total'    => $requestCount,
152
-                'api'      => 'JobQueue',
153
-                'type'     => 'JobQueue',
154
-                'special'  => 'Job Queue',
155
-                'help'     => 'This section lists all the requests which are currently waiting to be created by the tool. Requests should automatically disappear from here within a few minutes.'
156
-            );
157
-        }
158
-    }
159
-
160
-    /**
161
-     * @param PdoDatabase       $database
162
-     * @param SiteConfiguration $config
163
-     * @param                   $requestSectionData
164
-     */
165
-    private function setupStatusSections(
166
-        PdoDatabase $database,
167
-        SiteConfiguration $config,
168
-        &$requestSectionData
169
-    ) {
170
-        $search = RequestSearchHelper::get($database)->limit($config->getMiserModeLimit())->notHospitalised();
171
-
172
-        if ($config->getEmailConfirmationEnabled()) {
173
-            $search->withConfirmedEmail();
174
-        }
175
-
176
-        $requestStates = $config->getRequestStates();
177
-        $requestsByStatus = $search->fetchByStatus(array_keys($requestStates));
178
-
179
-        foreach ($requestStates as $type => $v) {
180
-            $requestSectionData[$v['header']] = array(
181
-                'requests' => $requestsByStatus[$type]['data'],
182
-                'total'    => $requestsByStatus[$type]['count'],
183
-                'api'      => $v['api'],
184
-                'type'     => $type,
185
-                'special'  => null,
186
-                'help'     => $v['queuehelp'],
187
-            );
188
-        }
189
-    }
87
+		$statement = $database->prepare($query);
88
+		$statement->execute();
89
+
90
+		$last5result = $statement->fetchAll(PDO::FETCH_ASSOC);
91
+
92
+		$this->assign('lastFive', $last5result);
93
+	}
94
+
95
+	/**
96
+	 * @param PdoDatabase       $database
97
+	 * @param SiteConfiguration $config
98
+	 * @param                   $requestSectionData
99
+	 */
100
+	private function setupHospitalQueue(
101
+		PdoDatabase $database,
102
+		SiteConfiguration $config,
103
+		&$requestSectionData
104
+	) {
105
+		$search = RequestSearchHelper::get($database)
106
+			->limit($config->getMiserModeLimit())
107
+			->excludingStatus('Closed')
108
+			->isHospitalised();
109
+
110
+		if ($config->getEmailConfirmationEnabled()) {
111
+			$search->withConfirmedEmail();
112
+		}
113
+
114
+		$results = $search->getRecordCount($requestCount)->fetch();
115
+
116
+		if($requestCount > 0) {
117
+			$requestSectionData['Hospital - Requests failed auto-creation'] = array(
118
+				'requests' => $results,
119
+				'total'    => $requestCount,
120
+				'api'      => 'hospital',
121
+				'type'     => 'hospital',
122
+				'special'  => 'Job Queue',
123
+				'help'     => 'This queue lists all the requests which have been attempted to be created in the background, but for which this has failed for one reason or another. Check the job queue to find the error. Requests here may need to be created manually, or it may be possible to re-queue the request for auto-creation by the tool, or it may have been created already. Use your own technical discretion here.'
124
+			);
125
+		}
126
+	}
127
+
128
+	/**
129
+	 * @param PdoDatabase       $database
130
+	 * @param SiteConfiguration $config
131
+	 * @param                   $requestSectionData
132
+	 */
133
+	private function setupJobQueue(
134
+		PdoDatabase $database,
135
+		SiteConfiguration $config,
136
+		&$requestSectionData
137
+	) {
138
+		$search = RequestSearchHelper::get($database)
139
+			->limit($config->getMiserModeLimit())
140
+			->byStatus(RequestStatus::JOBQUEUE);
141
+
142
+		if ($config->getEmailConfirmationEnabled()) {
143
+			$search->withConfirmedEmail();
144
+		}
145
+
146
+		$results = $search->getRecordCount($requestCount)->fetch();
147
+
148
+		if($requestCount > 0) {
149
+			$requestSectionData['Requests queued in the Job Queue'] = array(
150
+				'requests' => $results,
151
+				'total'    => $requestCount,
152
+				'api'      => 'JobQueue',
153
+				'type'     => 'JobQueue',
154
+				'special'  => 'Job Queue',
155
+				'help'     => 'This section lists all the requests which are currently waiting to be created by the tool. Requests should automatically disappear from here within a few minutes.'
156
+			);
157
+		}
158
+	}
159
+
160
+	/**
161
+	 * @param PdoDatabase       $database
162
+	 * @param SiteConfiguration $config
163
+	 * @param                   $requestSectionData
164
+	 */
165
+	private function setupStatusSections(
166
+		PdoDatabase $database,
167
+		SiteConfiguration $config,
168
+		&$requestSectionData
169
+	) {
170
+		$search = RequestSearchHelper::get($database)->limit($config->getMiserModeLimit())->notHospitalised();
171
+
172
+		if ($config->getEmailConfirmationEnabled()) {
173
+			$search->withConfirmedEmail();
174
+		}
175
+
176
+		$requestStates = $config->getRequestStates();
177
+		$requestsByStatus = $search->fetchByStatus(array_keys($requestStates));
178
+
179
+		foreach ($requestStates as $type => $v) {
180
+			$requestSectionData[$v['header']] = array(
181
+				'requests' => $requestsByStatus[$type]['data'],
182
+				'total'    => $requestsByStatus[$type]['count'],
183
+				'api'      => $v['api'],
184
+				'type'     => $type,
185
+				'special'  => null,
186
+				'help'     => $v['queuehelp'],
187
+			);
188
+		}
189
+	}
190 190
 }
Please login to merge, or discard this patch.
includes/Pages/PageUserManagement.php 2 patches
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -127,7 +127,7 @@  discard block
 block discarded – undo
127 127
                     continue;
128 128
                 }
129 129
 
130
-                $newValue = WebRequest::postBoolean('role-' . $name) ? 1 : 0;
130
+                $newValue = WebRequest::postBoolean('role-'.$name) ? 1 : 0;
131 131
                 if ($newValue !== $r['active']) {
132 132
                     if ($newValue === 0) {
133 133
                         $delete[] = $r['object'];
@@ -170,7 +170,7 @@  discard block
 block discarded – undo
170 170
             $user->save();
171 171
 
172 172
             $this->getNotificationHelper()->userRolesEdited($user, $reason);
173
-            SessionAlert::quick('Roles changed for user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
173
+            SessionAlert::quick('Roles changed for user '.htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
174 174
 
175 175
             $this->redirect('statistics/users', 'detail', array('user' => $user->getId()));
176 176
 
@@ -223,7 +223,7 @@  discard block
 block discarded – undo
223 223
             Logger::suspendedUser($database, $user, $reason);
224 224
 
225 225
             $this->getNotificationHelper()->userSuspended($user, $reason);
226
-            SessionAlert::quick('Suspended user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
226
+            SessionAlert::quick('Suspended user '.htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
227 227
 
228 228
             // send email
229 229
             $this->sendStatusChangeEmail(
@@ -284,7 +284,7 @@  discard block
 block discarded – undo
284 284
             Logger::declinedUser($database, $user, $reason);
285 285
 
286 286
             $this->getNotificationHelper()->userDeclined($user, $reason);
287
-            SessionAlert::quick('Declined user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
287
+            SessionAlert::quick('Declined user '.htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
288 288
 
289 289
             // send email
290 290
             $this->sendStatusChangeEmail(
@@ -339,7 +339,7 @@  discard block
 block discarded – undo
339 339
             Logger::approvedUser($database, $user);
340 340
 
341 341
             $this->getNotificationHelper()->userApproved($user);
342
-            SessionAlert::quick('Approved user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
342
+            SessionAlert::quick('Approved user '.htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
343 343
 
344 344
             // send email
345 345
             $this->sendStatusChangeEmail(
Please login to merge, or discard this patch.
Indentation   +539 added lines, -539 removed lines patch added patch discarded remove patch
@@ -24,543 +24,543 @@
 block discarded – undo
24 24
  */
25 25
 class PageUserManagement extends InternalPageBase
26 26
 {
27
-    /** @var string */
28
-    private $adminMailingList = '[email protected]';
29
-
30
-    /**
31
-     * Main function for this page, when no specific actions are called.
32
-     */
33
-    protected function main()
34
-    {
35
-        $this->setHtmlTitle('User Management');
36
-
37
-        $database = $this->getDatabase();
38
-        $currentUser = User::getCurrent($database);
39
-
40
-        // A bit hacky, but it's better than my last solution of creating an object for each user and passing that to
41
-        // the template. I still don't have a particularly good way of handling this.
42
-        OAuthUserHelper::prepareTokenCountStatement($database);
43
-
44
-        if (WebRequest::getBoolean("showAll")) {
45
-            $this->assign("showAll", true);
46
-
47
-            $suspendedUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_SUSPENDED)->fetch();
48
-            $this->assign("suspendedUsers", $suspendedUsers);
49
-
50
-            $declinedUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_DECLINED)->fetch();
51
-            $this->assign("declinedUsers", $declinedUsers);
52
-
53
-            UserSearchHelper::get($database)->getRoleMap($roleMap);
54
-        }
55
-        else {
56
-            $this->assign("showAll", false);
57
-            $this->assign("suspendedUsers", array());
58
-            $this->assign("declinedUsers", array());
59
-
60
-            UserSearchHelper::get($database)->statusIn(array('New', 'Active'))->getRoleMap($roleMap);
61
-        }
62
-
63
-        $newUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_NEW)->fetch();
64
-        $normalUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_ACTIVE)->byRole('user')->fetch();
65
-        $adminUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_ACTIVE)->byRole('admin')->fetch();
66
-        $checkUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_ACTIVE)->byRole('checkuser')->fetch();
67
-        $toolRoots = UserSearchHelper::get($database)->byStatus(User::STATUS_ACTIVE)->byRole('toolRoot')->fetch();
68
-        $this->assign('newUsers', $newUsers);
69
-        $this->assign('normalUsers', $normalUsers);
70
-        $this->assign('adminUsers', $adminUsers);
71
-        $this->assign('checkUsers', $checkUsers);
72
-        $this->assign('toolRoots', $toolRoots);
73
-
74
-        $this->assign('roles', $roleMap);
75
-
76
-        $this->addJs("/api.php?action=users&all=true&targetVariable=typeaheaddata");
77
-
78
-        $this->assign('canApprove', $this->barrierTest('approve', $currentUser));
79
-        $this->assign('canDecline', $this->barrierTest('decline', $currentUser));
80
-        $this->assign('canRename', $this->barrierTest('rename', $currentUser));
81
-        $this->assign('canEditUser', $this->barrierTest('editUser', $currentUser));
82
-        $this->assign('canSuspend', $this->barrierTest('suspend', $currentUser));
83
-        $this->assign('canEditRoles', $this->barrierTest('editRoles', $currentUser));
84
-
85
-        $this->setTemplate("usermanagement/main.tpl");
86
-    }
87
-
88
-    #region Access control
89
-
90
-    /**
91
-     * Action target for editing the roles assigned to a user
92
-     */
93
-    protected function editRoles()
94
-    {
95
-        $this->setHtmlTitle('User Management');
96
-        $database = $this->getDatabase();
97
-        $userId = WebRequest::getInt('user');
98
-
99
-        /** @var User $user */
100
-        $user = User::getById($userId, $database);
101
-
102
-        if ($user === false) {
103
-            throw new ApplicationLogicException('Sorry, the user you are trying to edit could not be found.');
104
-        }
105
-
106
-        $roleData = $this->getRoleData(UserRole::getForUser($user->getId(), $database));
107
-
108
-        // Dual-mode action
109
-        if (WebRequest::wasPosted()) {
110
-            $this->validateCSRFToken();
111
-
112
-            $reason = WebRequest::postString('reason');
113
-            if ($reason === false || trim($reason) === '') {
114
-                throw new ApplicationLogicException('No reason specified for roles change');
115
-            }
116
-
117
-            /** @var UserRole[] $delete */
118
-            $delete = array();
119
-            /** @var string[] $delete */
120
-            $add = array();
121
-
122
-            foreach ($roleData as $name => $r) {
123
-                if ($r['allowEdit'] !== 1) {
124
-                    // not allowed, to touch this, so ignore it
125
-                    continue;
126
-                }
127
-
128
-                $newValue = WebRequest::postBoolean('role-' . $name) ? 1 : 0;
129
-                if ($newValue !== $r['active']) {
130
-                    if ($newValue === 0) {
131
-                        $delete[] = $r['object'];
132
-                    }
133
-
134
-                    if ($newValue === 1) {
135
-                        $add[] = $name;
136
-                    }
137
-                }
138
-            }
139
-
140
-            // Check there's something to do
141
-            if ((count($add) + count($delete)) === 0) {
142
-                $this->redirect('statistics/users', 'detail', array('user' => $user->getId()));
143
-                SessionAlert::warning('No changes made to roles.');
144
-
145
-                return;
146
-            }
147
-
148
-            $removed = array();
149
-
150
-            /** @var UserRole $d */
151
-            foreach ($delete as $d) {
152
-                $removed[] = $d->getRole();
153
-                $d->delete();
154
-            }
155
-
156
-            foreach ($add as $x) {
157
-                $a = new UserRole();
158
-                $a->setUser($user->getId());
159
-                $a->setRole($x);
160
-                $a->setDatabase($database);
161
-                $a->save();
162
-            }
163
-
164
-            Logger::userRolesEdited($database, $user, $reason, $add, $removed);
165
-
166
-            // dummy save for optimistic locking. If this fails, the entire txn will roll back.
167
-            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
168
-            $user->save();
169
-
170
-            $this->getNotificationHelper()->userRolesEdited($user, $reason);
171
-            SessionAlert::quick('Roles changed for user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
172
-
173
-            $this->redirect('statistics/users', 'detail', array('user' => $user->getId()));
174
-
175
-            return;
176
-        }
177
-        else {
178
-            $this->assignCSRFToken();
179
-            $this->setTemplate('usermanagement/roleedit.tpl');
180
-            $this->assign('user', $user);
181
-            $this->assign('roleData', $roleData);
182
-        }
183
-    }
184
-
185
-    /**
186
-     * Action target for suspending users
187
-     *
188
-     * @throws ApplicationLogicException
189
-     */
190
-    protected function suspend()
191
-    {
192
-        $this->setHtmlTitle('User Management');
193
-
194
-        $database = $this->getDatabase();
195
-
196
-        $userId = WebRequest::getInt('user');
197
-
198
-        /** @var User $user */
199
-        $user = User::getById($userId, $database);
200
-
201
-        if ($user === false) {
202
-            throw new ApplicationLogicException('Sorry, the user you are trying to suspend could not be found.');
203
-        }
204
-
205
-        if ($user->isSuspended()) {
206
-            throw new ApplicationLogicException('Sorry, the user you are trying to suspend is already suspended.');
207
-        }
208
-
209
-        // Dual-mode action
210
-        if (WebRequest::wasPosted()) {
211
-            $this->validateCSRFToken();
212
-            $reason = WebRequest::postString('reason');
213
-
214
-            if ($reason === null || trim($reason) === "") {
215
-                throw new ApplicationLogicException('No reason provided');
216
-            }
217
-
218
-            $user->setStatus(User::STATUS_SUSPENDED);
219
-            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
220
-            $user->save();
221
-            Logger::suspendedUser($database, $user, $reason);
222
-
223
-            $this->getNotificationHelper()->userSuspended($user, $reason);
224
-            SessionAlert::quick('Suspended user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
225
-
226
-            // send email
227
-            $this->sendStatusChangeEmail(
228
-                'Your WP:ACC account has been suspended',
229
-                'usermanagement/emails/suspended.tpl',
230
-                $reason,
231
-                $user,
232
-                User::getCurrent($database)->getUsername()
233
-            );
234
-
235
-            $this->redirect('userManagement');
236
-
237
-            return;
238
-        }
239
-        else {
240
-            $this->assignCSRFToken();
241
-            $this->setTemplate('usermanagement/changelevel-reason.tpl');
242
-            $this->assign('user', $user);
243
-            $this->assign('status', 'Suspended');
244
-            $this->assign("showReason", true);
245
-        }
246
-    }
247
-
248
-    /**
249
-     * Entry point for the decline action
250
-     *
251
-     * @throws ApplicationLogicException
252
-     */
253
-    protected function decline()
254
-    {
255
-        $this->setHtmlTitle('User Management');
256
-
257
-        $database = $this->getDatabase();
258
-
259
-        $userId = WebRequest::getInt('user');
260
-        $user = User::getById($userId, $database);
261
-
262
-        if ($user === false) {
263
-            throw new ApplicationLogicException('Sorry, the user you are trying to decline could not be found.');
264
-        }
265
-
266
-        if (!$user->isNewUser()) {
267
-            throw new ApplicationLogicException('Sorry, the user you are trying to decline is not new.');
268
-        }
269
-
270
-        // Dual-mode action
271
-        if (WebRequest::wasPosted()) {
272
-            $this->validateCSRFToken();
273
-            $reason = WebRequest::postString('reason');
274
-
275
-            if ($reason === null || trim($reason) === "") {
276
-                throw new ApplicationLogicException('No reason provided');
277
-            }
278
-
279
-            $user->setStatus(User::STATUS_DECLINED);
280
-            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
281
-            $user->save();
282
-            Logger::declinedUser($database, $user, $reason);
283
-
284
-            $this->getNotificationHelper()->userDeclined($user, $reason);
285
-            SessionAlert::quick('Declined user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
286
-
287
-            // send email
288
-            $this->sendStatusChangeEmail(
289
-                'Your WP:ACC account has been declined',
290
-                'usermanagement/emails/declined.tpl',
291
-                $reason,
292
-                $user,
293
-                User::getCurrent($database)->getUsername()
294
-            );
295
-
296
-            $this->redirect('userManagement');
297
-
298
-            return;
299
-        }
300
-        else {
301
-            $this->assignCSRFToken();
302
-            $this->setTemplate('usermanagement/changelevel-reason.tpl');
303
-            $this->assign('user', $user);
304
-            $this->assign('status', 'Declined');
305
-            $this->assign("showReason", true);
306
-        }
307
-    }
308
-
309
-    /**
310
-     * Entry point for the approve action
311
-     *
312
-     * @throws ApplicationLogicException
313
-     */
314
-    protected function approve()
315
-    {
316
-        $this->setHtmlTitle('User Management');
317
-
318
-        $database = $this->getDatabase();
319
-
320
-        $userId = WebRequest::getInt('user');
321
-        $user = User::getById($userId, $database);
322
-
323
-        if ($user === false) {
324
-            throw new ApplicationLogicException('Sorry, the user you are trying to approve could not be found.');
325
-        }
326
-
327
-        if ($user->isActive()) {
328
-            throw new ApplicationLogicException('Sorry, the user you are trying to approve is already an active user.');
329
-        }
330
-
331
-        // Dual-mode action
332
-        if (WebRequest::wasPosted()) {
333
-            $this->validateCSRFToken();
334
-            $user->setStatus(User::STATUS_ACTIVE);
335
-            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
336
-            $user->save();
337
-            Logger::approvedUser($database, $user);
338
-
339
-            $this->getNotificationHelper()->userApproved($user);
340
-            SessionAlert::quick('Approved user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
341
-
342
-            // send email
343
-            $this->sendStatusChangeEmail(
344
-                'Your WP:ACC account has been approved',
345
-                'usermanagement/emails/approved.tpl',
346
-                null,
347
-                $user,
348
-                User::getCurrent($database)->getUsername()
349
-            );
350
-
351
-            $this->redirect("userManagement");
352
-
353
-            return;
354
-        }
355
-        else {
356
-            $this->assignCSRFToken();
357
-            $this->setTemplate("usermanagement/changelevel-reason.tpl");
358
-            $this->assign("user", $user);
359
-            $this->assign("status", "Active");
360
-            $this->assign("showReason", false);
361
-        }
362
-    }
363
-
364
-    #endregion
365
-
366
-    #region Renaming / Editing
367
-
368
-    /**
369
-     * Entry point for the rename action
370
-     *
371
-     * @throws ApplicationLogicException
372
-     */
373
-    protected function rename()
374
-    {
375
-        $this->setHtmlTitle('User Management');
376
-
377
-        $database = $this->getDatabase();
378
-
379
-        $userId = WebRequest::getInt('user');
380
-        $user = User::getById($userId, $database);
381
-
382
-        if ($user === false) {
383
-            throw new ApplicationLogicException('Sorry, the user you are trying to rename could not be found.');
384
-        }
385
-
386
-        // Dual-mode action
387
-        if (WebRequest::wasPosted()) {
388
-            $this->validateCSRFToken();
389
-            $newUsername = WebRequest::postString('newname');
390
-
391
-            if ($newUsername === null || trim($newUsername) === "") {
392
-                throw new ApplicationLogicException('The new username cannot be empty');
393
-            }
394
-
395
-            if (User::getByUsername($newUsername, $database) != false) {
396
-                throw new ApplicationLogicException('The new username already exists');
397
-            }
398
-
399
-            $oldUsername = $user->getUsername();
400
-            $user->setUsername($newUsername);
401
-            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
402
-
403
-            $user->save();
404
-
405
-            $logEntryData = serialize(array(
406
-                'old' => $oldUsername,
407
-                'new' => $newUsername,
408
-            ));
409
-
410
-            Logger::renamedUser($database, $user, $logEntryData);
411
-
412
-            SessionAlert::quick("Changed User "
413
-                . htmlentities($oldUsername, ENT_COMPAT, 'UTF-8')
414
-                . " name to "
415
-                . htmlentities($newUsername, ENT_COMPAT, 'UTF-8'));
416
-
417
-            $this->getNotificationHelper()->userRenamed($user, $oldUsername);
418
-
419
-            // send an email to the user.
420
-            $this->assign('targetUsername', $user->getUsername());
421
-            $this->assign('toolAdmin', User::getCurrent($database)->getUsername());
422
-            $this->assign('oldUsername', $oldUsername);
423
-            $this->assign('mailingList', $this->adminMailingList);
424
-
425
-            $this->getEmailHelper()->sendMail(
426
-                $user->getEmail(),
427
-                'Your username on WP:ACC has been changed',
428
-                $this->fetchTemplate('usermanagement/emails/renamed.tpl'),
429
-                array('Reply-To' => $this->adminMailingList)
430
-            );
431
-
432
-            $this->redirect("userManagement");
433
-
434
-            return;
435
-        }
436
-        else {
437
-            $this->assignCSRFToken();
438
-            $this->setTemplate('usermanagement/renameuser.tpl');
439
-            $this->assign('user', $user);
440
-        }
441
-    }
442
-
443
-    /**
444
-     * Entry point for the edit action
445
-     *
446
-     * @throws ApplicationLogicException
447
-     */
448
-    protected function editUser()
449
-    {
450
-        $this->setHtmlTitle('User Management');
451
-
452
-        $database = $this->getDatabase();
453
-
454
-        $userId = WebRequest::getInt('user');
455
-        $user = User::getById($userId, $database);
456
-        $oauth = new OAuthUserHelper($user, $database, $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
457
-
458
-        if ($user === false) {
459
-            throw new ApplicationLogicException('Sorry, the user you are trying to edit could not be found.');
460
-        }
461
-
462
-        // Dual-mode action
463
-        if (WebRequest::wasPosted()) {
464
-            $this->validateCSRFToken();
465
-            $newEmail = WebRequest::postEmail('user_email');
466
-            $newOnWikiName = WebRequest::postString('user_onwikiname');
467
-
468
-            if ($newEmail === null) {
469
-                throw new ApplicationLogicException('Invalid email address');
470
-            }
471
-
472
-            if (!$oauth->isFullyLinked()) {
473
-                if (trim($newOnWikiName) == "") {
474
-                    throw new ApplicationLogicException('New on-wiki username cannot be blank');
475
-                }
476
-
477
-                $user->setOnWikiName($newOnWikiName);
478
-            }
479
-
480
-            $user->setEmail($newEmail);
481
-
482
-            $user->setUpdateVersion(WebRequest::postInt('updateversion'));
483
-
484
-            $user->save();
485
-
486
-            Logger::userPreferencesChange($database, $user);
487
-            $this->getNotificationHelper()->userPrefChange($user);
488
-            SessionAlert::quick('Changes to user\'s preferences have been saved');
489
-
490
-            $this->redirect("userManagement");
491
-
492
-            return;
493
-        }
494
-        else {
495
-            $this->assignCSRFToken();
496
-            $oauth = new OAuthUserHelper($user, $database, $this->getOAuthProtocolHelper(),
497
-                $this->getSiteConfiguration());
498
-            $this->setTemplate('usermanagement/edituser.tpl');
499
-            $this->assign('user', $user);
500
-            $this->assign('oauth', $oauth);
501
-        }
502
-    }
503
-
504
-    #endregion
505
-
506
-    /**
507
-     * Sends a status change email to the user.
508
-     *
509
-     * @param string      $subject           The subject of the email
510
-     * @param string      $template          The smarty template to use
511
-     * @param string|null $reason            The reason for performing the status change
512
-     * @param User        $user              The user affected
513
-     * @param string      $toolAdminUsername The tool admin's username who is making the edit
514
-     */
515
-    private function sendStatusChangeEmail($subject, $template, $reason, $user, $toolAdminUsername)
516
-    {
517
-        $this->assign('targetUsername', $user->getUsername());
518
-        $this->assign('toolAdmin', $toolAdminUsername);
519
-        $this->assign('actionReason', $reason);
520
-        $this->assign('mailingList', $this->adminMailingList);
521
-
522
-        $this->getEmailHelper()->sendMail(
523
-            $user->getEmail(),
524
-            $subject,
525
-            $this->fetchTemplate($template),
526
-            array('Reply-To' => $this->adminMailingList)
527
-        );
528
-    }
529
-
530
-    /**
531
-     * @param UserRole[] $activeRoles
532
-     *
533
-     * @return array
534
-     */
535
-    private function getRoleData($activeRoles)
536
-    {
537
-        $availableRoles = $this->getSecurityManager()->getRoleConfiguration()->getAvailableRoles();
538
-
539
-        $currentUser = User::getCurrent($this->getDatabase());
540
-        $this->getSecurityManager()->getActiveRoles($currentUser, $userRoles, $inactiveRoles);
541
-
542
-        $initialValue = array('active' => 0, 'allowEdit' => 0, 'description' => '???', 'object' => null);
543
-
544
-        $roleData = array();
545
-        foreach ($availableRoles as $role => $data) {
546
-            $intersection = array_intersect($data['editableBy'], $userRoles);
547
-
548
-            $roleData[$role] = $initialValue;
549
-            $roleData[$role]['allowEdit'] = count($intersection) > 0 ? 1 : 0;
550
-            $roleData[$role]['description'] = $data['description'];
551
-        }
552
-
553
-        foreach ($activeRoles as $role) {
554
-            if (!isset($roleData[$role->getRole()])) {
555
-                // This value is no longer available in the configuration, allow changing (aka removing) it.
556
-                $roleData[$role->getRole()] = $initialValue;
557
-                $roleData[$role->getRole()]['allowEdit'] = 1;
558
-            }
559
-
560
-            $roleData[$role->getRole()]['object'] = $role;
561
-            $roleData[$role->getRole()]['active'] = 1;
562
-        }
563
-
564
-        return $roleData;
565
-    }
27
+	/** @var string */
28
+	private $adminMailingList = '[email protected]';
29
+
30
+	/**
31
+	 * Main function for this page, when no specific actions are called.
32
+	 */
33
+	protected function main()
34
+	{
35
+		$this->setHtmlTitle('User Management');
36
+
37
+		$database = $this->getDatabase();
38
+		$currentUser = User::getCurrent($database);
39
+
40
+		// A bit hacky, but it's better than my last solution of creating an object for each user and passing that to
41
+		// the template. I still don't have a particularly good way of handling this.
42
+		OAuthUserHelper::prepareTokenCountStatement($database);
43
+
44
+		if (WebRequest::getBoolean("showAll")) {
45
+			$this->assign("showAll", true);
46
+
47
+			$suspendedUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_SUSPENDED)->fetch();
48
+			$this->assign("suspendedUsers", $suspendedUsers);
49
+
50
+			$declinedUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_DECLINED)->fetch();
51
+			$this->assign("declinedUsers", $declinedUsers);
52
+
53
+			UserSearchHelper::get($database)->getRoleMap($roleMap);
54
+		}
55
+		else {
56
+			$this->assign("showAll", false);
57
+			$this->assign("suspendedUsers", array());
58
+			$this->assign("declinedUsers", array());
59
+
60
+			UserSearchHelper::get($database)->statusIn(array('New', 'Active'))->getRoleMap($roleMap);
61
+		}
62
+
63
+		$newUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_NEW)->fetch();
64
+		$normalUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_ACTIVE)->byRole('user')->fetch();
65
+		$adminUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_ACTIVE)->byRole('admin')->fetch();
66
+		$checkUsers = UserSearchHelper::get($database)->byStatus(User::STATUS_ACTIVE)->byRole('checkuser')->fetch();
67
+		$toolRoots = UserSearchHelper::get($database)->byStatus(User::STATUS_ACTIVE)->byRole('toolRoot')->fetch();
68
+		$this->assign('newUsers', $newUsers);
69
+		$this->assign('normalUsers', $normalUsers);
70
+		$this->assign('adminUsers', $adminUsers);
71
+		$this->assign('checkUsers', $checkUsers);
72
+		$this->assign('toolRoots', $toolRoots);
73
+
74
+		$this->assign('roles', $roleMap);
75
+
76
+		$this->addJs("/api.php?action=users&all=true&targetVariable=typeaheaddata");
77
+
78
+		$this->assign('canApprove', $this->barrierTest('approve', $currentUser));
79
+		$this->assign('canDecline', $this->barrierTest('decline', $currentUser));
80
+		$this->assign('canRename', $this->barrierTest('rename', $currentUser));
81
+		$this->assign('canEditUser', $this->barrierTest('editUser', $currentUser));
82
+		$this->assign('canSuspend', $this->barrierTest('suspend', $currentUser));
83
+		$this->assign('canEditRoles', $this->barrierTest('editRoles', $currentUser));
84
+
85
+		$this->setTemplate("usermanagement/main.tpl");
86
+	}
87
+
88
+	#region Access control
89
+
90
+	/**
91
+	 * Action target for editing the roles assigned to a user
92
+	 */
93
+	protected function editRoles()
94
+	{
95
+		$this->setHtmlTitle('User Management');
96
+		$database = $this->getDatabase();
97
+		$userId = WebRequest::getInt('user');
98
+
99
+		/** @var User $user */
100
+		$user = User::getById($userId, $database);
101
+
102
+		if ($user === false) {
103
+			throw new ApplicationLogicException('Sorry, the user you are trying to edit could not be found.');
104
+		}
105
+
106
+		$roleData = $this->getRoleData(UserRole::getForUser($user->getId(), $database));
107
+
108
+		// Dual-mode action
109
+		if (WebRequest::wasPosted()) {
110
+			$this->validateCSRFToken();
111
+
112
+			$reason = WebRequest::postString('reason');
113
+			if ($reason === false || trim($reason) === '') {
114
+				throw new ApplicationLogicException('No reason specified for roles change');
115
+			}
116
+
117
+			/** @var UserRole[] $delete */
118
+			$delete = array();
119
+			/** @var string[] $delete */
120
+			$add = array();
121
+
122
+			foreach ($roleData as $name => $r) {
123
+				if ($r['allowEdit'] !== 1) {
124
+					// not allowed, to touch this, so ignore it
125
+					continue;
126
+				}
127
+
128
+				$newValue = WebRequest::postBoolean('role-' . $name) ? 1 : 0;
129
+				if ($newValue !== $r['active']) {
130
+					if ($newValue === 0) {
131
+						$delete[] = $r['object'];
132
+					}
133
+
134
+					if ($newValue === 1) {
135
+						$add[] = $name;
136
+					}
137
+				}
138
+			}
139
+
140
+			// Check there's something to do
141
+			if ((count($add) + count($delete)) === 0) {
142
+				$this->redirect('statistics/users', 'detail', array('user' => $user->getId()));
143
+				SessionAlert::warning('No changes made to roles.');
144
+
145
+				return;
146
+			}
147
+
148
+			$removed = array();
149
+
150
+			/** @var UserRole $d */
151
+			foreach ($delete as $d) {
152
+				$removed[] = $d->getRole();
153
+				$d->delete();
154
+			}
155
+
156
+			foreach ($add as $x) {
157
+				$a = new UserRole();
158
+				$a->setUser($user->getId());
159
+				$a->setRole($x);
160
+				$a->setDatabase($database);
161
+				$a->save();
162
+			}
163
+
164
+			Logger::userRolesEdited($database, $user, $reason, $add, $removed);
165
+
166
+			// dummy save for optimistic locking. If this fails, the entire txn will roll back.
167
+			$user->setUpdateVersion(WebRequest::postInt('updateversion'));
168
+			$user->save();
169
+
170
+			$this->getNotificationHelper()->userRolesEdited($user, $reason);
171
+			SessionAlert::quick('Roles changed for user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
172
+
173
+			$this->redirect('statistics/users', 'detail', array('user' => $user->getId()));
174
+
175
+			return;
176
+		}
177
+		else {
178
+			$this->assignCSRFToken();
179
+			$this->setTemplate('usermanagement/roleedit.tpl');
180
+			$this->assign('user', $user);
181
+			$this->assign('roleData', $roleData);
182
+		}
183
+	}
184
+
185
+	/**
186
+	 * Action target for suspending users
187
+	 *
188
+	 * @throws ApplicationLogicException
189
+	 */
190
+	protected function suspend()
191
+	{
192
+		$this->setHtmlTitle('User Management');
193
+
194
+		$database = $this->getDatabase();
195
+
196
+		$userId = WebRequest::getInt('user');
197
+
198
+		/** @var User $user */
199
+		$user = User::getById($userId, $database);
200
+
201
+		if ($user === false) {
202
+			throw new ApplicationLogicException('Sorry, the user you are trying to suspend could not be found.');
203
+		}
204
+
205
+		if ($user->isSuspended()) {
206
+			throw new ApplicationLogicException('Sorry, the user you are trying to suspend is already suspended.');
207
+		}
208
+
209
+		// Dual-mode action
210
+		if (WebRequest::wasPosted()) {
211
+			$this->validateCSRFToken();
212
+			$reason = WebRequest::postString('reason');
213
+
214
+			if ($reason === null || trim($reason) === "") {
215
+				throw new ApplicationLogicException('No reason provided');
216
+			}
217
+
218
+			$user->setStatus(User::STATUS_SUSPENDED);
219
+			$user->setUpdateVersion(WebRequest::postInt('updateversion'));
220
+			$user->save();
221
+			Logger::suspendedUser($database, $user, $reason);
222
+
223
+			$this->getNotificationHelper()->userSuspended($user, $reason);
224
+			SessionAlert::quick('Suspended user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
225
+
226
+			// send email
227
+			$this->sendStatusChangeEmail(
228
+				'Your WP:ACC account has been suspended',
229
+				'usermanagement/emails/suspended.tpl',
230
+				$reason,
231
+				$user,
232
+				User::getCurrent($database)->getUsername()
233
+			);
234
+
235
+			$this->redirect('userManagement');
236
+
237
+			return;
238
+		}
239
+		else {
240
+			$this->assignCSRFToken();
241
+			$this->setTemplate('usermanagement/changelevel-reason.tpl');
242
+			$this->assign('user', $user);
243
+			$this->assign('status', 'Suspended');
244
+			$this->assign("showReason", true);
245
+		}
246
+	}
247
+
248
+	/**
249
+	 * Entry point for the decline action
250
+	 *
251
+	 * @throws ApplicationLogicException
252
+	 */
253
+	protected function decline()
254
+	{
255
+		$this->setHtmlTitle('User Management');
256
+
257
+		$database = $this->getDatabase();
258
+
259
+		$userId = WebRequest::getInt('user');
260
+		$user = User::getById($userId, $database);
261
+
262
+		if ($user === false) {
263
+			throw new ApplicationLogicException('Sorry, the user you are trying to decline could not be found.');
264
+		}
265
+
266
+		if (!$user->isNewUser()) {
267
+			throw new ApplicationLogicException('Sorry, the user you are trying to decline is not new.');
268
+		}
269
+
270
+		// Dual-mode action
271
+		if (WebRequest::wasPosted()) {
272
+			$this->validateCSRFToken();
273
+			$reason = WebRequest::postString('reason');
274
+
275
+			if ($reason === null || trim($reason) === "") {
276
+				throw new ApplicationLogicException('No reason provided');
277
+			}
278
+
279
+			$user->setStatus(User::STATUS_DECLINED);
280
+			$user->setUpdateVersion(WebRequest::postInt('updateversion'));
281
+			$user->save();
282
+			Logger::declinedUser($database, $user, $reason);
283
+
284
+			$this->getNotificationHelper()->userDeclined($user, $reason);
285
+			SessionAlert::quick('Declined user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
286
+
287
+			// send email
288
+			$this->sendStatusChangeEmail(
289
+				'Your WP:ACC account has been declined',
290
+				'usermanagement/emails/declined.tpl',
291
+				$reason,
292
+				$user,
293
+				User::getCurrent($database)->getUsername()
294
+			);
295
+
296
+			$this->redirect('userManagement');
297
+
298
+			return;
299
+		}
300
+		else {
301
+			$this->assignCSRFToken();
302
+			$this->setTemplate('usermanagement/changelevel-reason.tpl');
303
+			$this->assign('user', $user);
304
+			$this->assign('status', 'Declined');
305
+			$this->assign("showReason", true);
306
+		}
307
+	}
308
+
309
+	/**
310
+	 * Entry point for the approve action
311
+	 *
312
+	 * @throws ApplicationLogicException
313
+	 */
314
+	protected function approve()
315
+	{
316
+		$this->setHtmlTitle('User Management');
317
+
318
+		$database = $this->getDatabase();
319
+
320
+		$userId = WebRequest::getInt('user');
321
+		$user = User::getById($userId, $database);
322
+
323
+		if ($user === false) {
324
+			throw new ApplicationLogicException('Sorry, the user you are trying to approve could not be found.');
325
+		}
326
+
327
+		if ($user->isActive()) {
328
+			throw new ApplicationLogicException('Sorry, the user you are trying to approve is already an active user.');
329
+		}
330
+
331
+		// Dual-mode action
332
+		if (WebRequest::wasPosted()) {
333
+			$this->validateCSRFToken();
334
+			$user->setStatus(User::STATUS_ACTIVE);
335
+			$user->setUpdateVersion(WebRequest::postInt('updateversion'));
336
+			$user->save();
337
+			Logger::approvedUser($database, $user);
338
+
339
+			$this->getNotificationHelper()->userApproved($user);
340
+			SessionAlert::quick('Approved user ' . htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8'));
341
+
342
+			// send email
343
+			$this->sendStatusChangeEmail(
344
+				'Your WP:ACC account has been approved',
345
+				'usermanagement/emails/approved.tpl',
346
+				null,
347
+				$user,
348
+				User::getCurrent($database)->getUsername()
349
+			);
350
+
351
+			$this->redirect("userManagement");
352
+
353
+			return;
354
+		}
355
+		else {
356
+			$this->assignCSRFToken();
357
+			$this->setTemplate("usermanagement/changelevel-reason.tpl");
358
+			$this->assign("user", $user);
359
+			$this->assign("status", "Active");
360
+			$this->assign("showReason", false);
361
+		}
362
+	}
363
+
364
+	#endregion
365
+
366
+	#region Renaming / Editing
367
+
368
+	/**
369
+	 * Entry point for the rename action
370
+	 *
371
+	 * @throws ApplicationLogicException
372
+	 */
373
+	protected function rename()
374
+	{
375
+		$this->setHtmlTitle('User Management');
376
+
377
+		$database = $this->getDatabase();
378
+
379
+		$userId = WebRequest::getInt('user');
380
+		$user = User::getById($userId, $database);
381
+
382
+		if ($user === false) {
383
+			throw new ApplicationLogicException('Sorry, the user you are trying to rename could not be found.');
384
+		}
385
+
386
+		// Dual-mode action
387
+		if (WebRequest::wasPosted()) {
388
+			$this->validateCSRFToken();
389
+			$newUsername = WebRequest::postString('newname');
390
+
391
+			if ($newUsername === null || trim($newUsername) === "") {
392
+				throw new ApplicationLogicException('The new username cannot be empty');
393
+			}
394
+
395
+			if (User::getByUsername($newUsername, $database) != false) {
396
+				throw new ApplicationLogicException('The new username already exists');
397
+			}
398
+
399
+			$oldUsername = $user->getUsername();
400
+			$user->setUsername($newUsername);
401
+			$user->setUpdateVersion(WebRequest::postInt('updateversion'));
402
+
403
+			$user->save();
404
+
405
+			$logEntryData = serialize(array(
406
+				'old' => $oldUsername,
407
+				'new' => $newUsername,
408
+			));
409
+
410
+			Logger::renamedUser($database, $user, $logEntryData);
411
+
412
+			SessionAlert::quick("Changed User "
413
+				. htmlentities($oldUsername, ENT_COMPAT, 'UTF-8')
414
+				. " name to "
415
+				. htmlentities($newUsername, ENT_COMPAT, 'UTF-8'));
416
+
417
+			$this->getNotificationHelper()->userRenamed($user, $oldUsername);
418
+
419
+			// send an email to the user.
420
+			$this->assign('targetUsername', $user->getUsername());
421
+			$this->assign('toolAdmin', User::getCurrent($database)->getUsername());
422
+			$this->assign('oldUsername', $oldUsername);
423
+			$this->assign('mailingList', $this->adminMailingList);
424
+
425
+			$this->getEmailHelper()->sendMail(
426
+				$user->getEmail(),
427
+				'Your username on WP:ACC has been changed',
428
+				$this->fetchTemplate('usermanagement/emails/renamed.tpl'),
429
+				array('Reply-To' => $this->adminMailingList)
430
+			);
431
+
432
+			$this->redirect("userManagement");
433
+
434
+			return;
435
+		}
436
+		else {
437
+			$this->assignCSRFToken();
438
+			$this->setTemplate('usermanagement/renameuser.tpl');
439
+			$this->assign('user', $user);
440
+		}
441
+	}
442
+
443
+	/**
444
+	 * Entry point for the edit action
445
+	 *
446
+	 * @throws ApplicationLogicException
447
+	 */
448
+	protected function editUser()
449
+	{
450
+		$this->setHtmlTitle('User Management');
451
+
452
+		$database = $this->getDatabase();
453
+
454
+		$userId = WebRequest::getInt('user');
455
+		$user = User::getById($userId, $database);
456
+		$oauth = new OAuthUserHelper($user, $database, $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
457
+
458
+		if ($user === false) {
459
+			throw new ApplicationLogicException('Sorry, the user you are trying to edit could not be found.');
460
+		}
461
+
462
+		// Dual-mode action
463
+		if (WebRequest::wasPosted()) {
464
+			$this->validateCSRFToken();
465
+			$newEmail = WebRequest::postEmail('user_email');
466
+			$newOnWikiName = WebRequest::postString('user_onwikiname');
467
+
468
+			if ($newEmail === null) {
469
+				throw new ApplicationLogicException('Invalid email address');
470
+			}
471
+
472
+			if (!$oauth->isFullyLinked()) {
473
+				if (trim($newOnWikiName) == "") {
474
+					throw new ApplicationLogicException('New on-wiki username cannot be blank');
475
+				}
476
+
477
+				$user->setOnWikiName($newOnWikiName);
478
+			}
479
+
480
+			$user->setEmail($newEmail);
481
+
482
+			$user->setUpdateVersion(WebRequest::postInt('updateversion'));
483
+
484
+			$user->save();
485
+
486
+			Logger::userPreferencesChange($database, $user);
487
+			$this->getNotificationHelper()->userPrefChange($user);
488
+			SessionAlert::quick('Changes to user\'s preferences have been saved');
489
+
490
+			$this->redirect("userManagement");
491
+
492
+			return;
493
+		}
494
+		else {
495
+			$this->assignCSRFToken();
496
+			$oauth = new OAuthUserHelper($user, $database, $this->getOAuthProtocolHelper(),
497
+				$this->getSiteConfiguration());
498
+			$this->setTemplate('usermanagement/edituser.tpl');
499
+			$this->assign('user', $user);
500
+			$this->assign('oauth', $oauth);
501
+		}
502
+	}
503
+
504
+	#endregion
505
+
506
+	/**
507
+	 * Sends a status change email to the user.
508
+	 *
509
+	 * @param string      $subject           The subject of the email
510
+	 * @param string      $template          The smarty template to use
511
+	 * @param string|null $reason            The reason for performing the status change
512
+	 * @param User        $user              The user affected
513
+	 * @param string      $toolAdminUsername The tool admin's username who is making the edit
514
+	 */
515
+	private function sendStatusChangeEmail($subject, $template, $reason, $user, $toolAdminUsername)
516
+	{
517
+		$this->assign('targetUsername', $user->getUsername());
518
+		$this->assign('toolAdmin', $toolAdminUsername);
519
+		$this->assign('actionReason', $reason);
520
+		$this->assign('mailingList', $this->adminMailingList);
521
+
522
+		$this->getEmailHelper()->sendMail(
523
+			$user->getEmail(),
524
+			$subject,
525
+			$this->fetchTemplate($template),
526
+			array('Reply-To' => $this->adminMailingList)
527
+		);
528
+	}
529
+
530
+	/**
531
+	 * @param UserRole[] $activeRoles
532
+	 *
533
+	 * @return array
534
+	 */
535
+	private function getRoleData($activeRoles)
536
+	{
537
+		$availableRoles = $this->getSecurityManager()->getRoleConfiguration()->getAvailableRoles();
538
+
539
+		$currentUser = User::getCurrent($this->getDatabase());
540
+		$this->getSecurityManager()->getActiveRoles($currentUser, $userRoles, $inactiveRoles);
541
+
542
+		$initialValue = array('active' => 0, 'allowEdit' => 0, 'description' => '???', 'object' => null);
543
+
544
+		$roleData = array();
545
+		foreach ($availableRoles as $role => $data) {
546
+			$intersection = array_intersect($data['editableBy'], $userRoles);
547
+
548
+			$roleData[$role] = $initialValue;
549
+			$roleData[$role]['allowEdit'] = count($intersection) > 0 ? 1 : 0;
550
+			$roleData[$role]['description'] = $data['description'];
551
+		}
552
+
553
+		foreach ($activeRoles as $role) {
554
+			if (!isset($roleData[$role->getRole()])) {
555
+				// This value is no longer available in the configuration, allow changing (aka removing) it.
556
+				$roleData[$role->getRole()] = $initialValue;
557
+				$roleData[$role->getRole()]['allowEdit'] = 1;
558
+			}
559
+
560
+			$roleData[$role->getRole()]['object'] = $role;
561
+			$roleData[$role->getRole()]['active'] = 1;
562
+		}
563
+
564
+		return $roleData;
565
+	}
566 566
 }
Please login to merge, or discard this patch.
includes/Pages/PageViewRequest.php 3 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -130,7 +130,7 @@  discard block
 block discarded – undo
130 130
             }
131 131
         }
132 132
 
133
-        $this->setHtmlTitle($statusSymbol . ' #' . $request->getId());
133
+        $this->setHtmlTitle($statusSymbol.' #'.$request->getId());
134 134
     }
135 135
 
136 136
     /**
@@ -227,7 +227,7 @@  discard block
 block discarded – undo
227 227
 
228 228
                 $entryComment = $entry->getComment();
229 229
 
230
-                if($entry->getAction() === 'JobIssueRequest' || $entry->getAction() === 'JobCompletedRequest'){
230
+                if ($entry->getAction() === 'JobIssueRequest' || $entry->getAction() === 'JobCompletedRequest') {
231 231
                     $data = unserialize($entry->getComment());
232 232
                     /** @var JobQueue $job */
233 233
                     $job = JobQueue::getById($data['job'], $database);
Please login to merge, or discard this patch.
Braces   +3 added lines, -2 removed lines patch added patch discarded remove patch
@@ -227,7 +227,7 @@  discard block
 block discarded – undo
227 227
 
228 228
                 $entryComment = $entry->getComment();
229 229
 
230
-                if($entry->getAction() === 'JobIssueRequest' || $entry->getAction() === 'JobCompletedRequest'){
230
+                if($entry->getAction() === 'JobIssueRequest' || $entry->getAction() === 'JobCompletedRequest') {
231 231
                     $data = unserialize($entry->getComment());
232 232
                     /** @var JobQueue $job */
233 233
                     $job = JobQueue::getById($data['job'], $database);
@@ -243,7 +243,8 @@  discard block
 block discarded – undo
243 243
                         'jobId'    => $job->getId(),
244 244
                         'jobDesc'  => JobQueue::getTaskDescriptions()[$job->getTask()],
245 245
                     );
246
-                } else {
246
+                }
247
+                else {
247 248
                     $requestLogs[] = array(
248 249
                         'type'     => 'log',
249 250
                         'security' => 'user',
Please login to merge, or discard this patch.
Indentation   +249 added lines, -249 removed lines patch added patch discarded remove patch
@@ -25,253 +25,253 @@
 block discarded – undo
25 25
 
26 26
 class PageViewRequest extends InternalPageBase
27 27
 {
28
-    use RequestData;
29
-    const STATUS_SYMBOL_OPEN = '&#x2610';
30
-    const STATUS_SYMBOL_ACCEPTED = '&#x2611';
31
-    const STATUS_SYMBOL_REJECTED = '&#x2612';
32
-
33
-    /**
34
-     * Main function for this page, when no specific actions are called.
35
-     * @throws ApplicationLogicException
36
-     */
37
-    protected function main()
38
-    {
39
-        // set up csrf protection
40
-        $this->assignCSRFToken();
41
-
42
-        // get some useful objects
43
-        $database = $this->getDatabase();
44
-        $request = $this->getRequest($database, WebRequest::getInt('id'));
45
-        $config = $this->getSiteConfiguration();
46
-        $currentUser = User::getCurrent($database);
47
-
48
-        // Test we should be able to look at this request
49
-        if ($config->getEmailConfirmationEnabled()) {
50
-            if ($request->getEmailConfirm() !== 'Confirmed') {
51
-                // Not allowed to look at this yet.
52
-                throw new ApplicationLogicException('The email address has not yet been confirmed for this request.');
53
-            }
54
-        }
55
-
56
-        $this->setupBasicData($request, $config);
57
-
58
-        $this->setupUsernameData($request);
59
-
60
-        $this->setupTitle($request);
61
-
62
-        $this->setupReservationDetails($request->getReserved(), $database, $currentUser);
63
-        $this->setupGeneralData($database);
64
-
65
-        $this->assign('requestDataCleared', false);
66
-        if ($request->getEmail() === $this->getSiteConfiguration()->getDataClearEmail()) {
67
-            $this->assign('requestDataCleared', true);
68
-        }
69
-
70
-        $allowedPrivateData = $this->isAllowedPrivateData($request, $currentUser);
71
-
72
-        $this->setupCreationTypes($currentUser);
73
-
74
-        $this->setupLogData($request, $database);
75
-
76
-        if ($allowedPrivateData) {
77
-            $this->setTemplate('view-request/main-with-data.tpl');
78
-            $this->setupPrivateData($request, $currentUser, $this->getSiteConfiguration(), $database);
79
-
80
-            $this->assign('canSetBan', $this->barrierTest('set', $currentUser, PageBan::class));
81
-            $this->assign('canSeeCheckuserData', $this->barrierTest('seeUserAgentData', $currentUser, 'RequestData'));
82
-
83
-            if ($this->barrierTest('seeUserAgentData', $currentUser, 'RequestData')) {
84
-                $this->setTemplate('view-request/main-with-checkuser-data.tpl');
85
-                $this->setupCheckUserData($request);
86
-            }
87
-        }
88
-        else {
89
-            $this->setTemplate('view-request/main.tpl');
90
-        }
91
-    }
92
-
93
-    /**
94
-     * @param Request $request
95
-     */
96
-    protected function setupTitle(Request $request)
97
-    {
98
-        $statusSymbol = self::STATUS_SYMBOL_OPEN;
99
-        if ($request->getStatus() === 'Closed') {
100
-            if ($request->getWasCreated()) {
101
-                $statusSymbol = self::STATUS_SYMBOL_ACCEPTED;
102
-            }
103
-            else {
104
-                $statusSymbol = self::STATUS_SYMBOL_REJECTED;
105
-            }
106
-        }
107
-
108
-        $this->setHtmlTitle($statusSymbol . ' #' . $request->getId());
109
-    }
110
-
111
-    /**
112
-     * Sets up data unrelated to the request, such as the email template information
113
-     *
114
-     * @param PdoDatabase $database
115
-     */
116
-    protected function setupGeneralData(PdoDatabase $database)
117
-    {
118
-        $config = $this->getSiteConfiguration();
119
-
120
-        $this->assign('createAccountReason', 'Requested account at [[WP:ACC]], request #');
121
-
122
-        $this->assign('defaultRequestState', $config->getDefaultRequestStateKey());
123
-
124
-        $this->assign('requestStates', $config->getRequestStates());
125
-
126
-        /** @var EmailTemplate $createdTemplate */
127
-        $createdTemplate = EmailTemplate::getById($config->getDefaultCreatedTemplateId(), $database);
128
-
129
-        $this->assign('createdHasJsQuestion', $createdTemplate->getJsquestion() != '');
130
-        $this->assign('createdJsQuestion', $createdTemplate->getJsquestion());
131
-        $this->assign('createdId', $createdTemplate->getId());
132
-        $this->assign('createdName', $createdTemplate->getName());
133
-
134
-        $createReasons = EmailTemplate::getActiveTemplates(EmailTemplate::CREATED, $database);
135
-        $this->assign("createReasons", $createReasons);
136
-        $declineReasons = EmailTemplate::getActiveTemplates(EmailTemplate::NOT_CREATED, $database);
137
-        $this->assign("declineReasons", $declineReasons);
138
-
139
-        $allCreateReasons = EmailTemplate::getAllActiveTemplates(EmailTemplate::CREATED, $database);
140
-        $this->assign("allCreateReasons", $allCreateReasons);
141
-        $allDeclineReasons = EmailTemplate::getAllActiveTemplates(EmailTemplate::NOT_CREATED, $database);
142
-        $this->assign("allDeclineReasons", $allDeclineReasons);
143
-        $allOtherReasons = EmailTemplate::getAllActiveTemplates(false, $database);
144
-        $this->assign("allOtherReasons", $allOtherReasons);
145
-    }
146
-
147
-    private function setupLogData(Request $request, PdoDatabase $database)
148
-    {
149
-        $currentUser = User::getCurrent($database);
150
-
151
-        $logs = LogHelper::getRequestLogsWithComments($request->getId(), $database, $this->getSecurityManager());
152
-        $requestLogs = array();
153
-
154
-        if (trim($request->getComment()) !== "") {
155
-            $requestLogs[] = array(
156
-                'type'     => 'comment',
157
-                'security' => 'user',
158
-                'userid'   => null,
159
-                'user'     => $request->getName(),
160
-                'entry'    => null,
161
-                'time'     => $request->getDate(),
162
-                'canedit'  => false,
163
-                'id'       => $request->getId(),
164
-                'comment'  => $request->getComment(),
165
-            );
166
-        }
167
-
168
-        /** @var User[] $nameCache */
169
-        $nameCache = array();
170
-
171
-        $editableComments = $this->barrierTest('editOthers', $currentUser, PageEditComment::class);
172
-
173
-        /** @var Log|Comment $entry */
174
-        foreach ($logs as $entry) {
175
-            // both log and comment have a 'user' field
176
-            if (!array_key_exists($entry->getUser(), $nameCache)) {
177
-                $entryUser = User::getById($entry->getUser(), $database);
178
-                $nameCache[$entry->getUser()] = $entryUser;
179
-            }
180
-
181
-            if ($entry instanceof Comment) {
182
-                $requestLogs[] = array(
183
-                    'type'     => 'comment',
184
-                    'security' => $entry->getVisibility(),
185
-                    'user'     => $nameCache[$entry->getUser()]->getUsername(),
186
-                    'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
187
-                    'entry'    => null,
188
-                    'time'     => $entry->getTime(),
189
-                    'canedit'  => ($editableComments || $entry->getUser() == $currentUser->getId()),
190
-                    'id'       => $entry->getId(),
191
-                    'comment'  => $entry->getComment(),
192
-                );
193
-            }
194
-
195
-            if ($entry instanceof Log) {
196
-                $invalidUserId = $entry->getUser() === -1 || $entry->getUser() === 0;
197
-                $entryUser = $invalidUserId ? User::getCommunity() : $nameCache[$entry->getUser()];
198
-
199
-                $entryComment = $entry->getComment();
200
-
201
-                if($entry->getAction() === 'JobIssueRequest' || $entry->getAction() === 'JobCompletedRequest'){
202
-                    $data = unserialize($entry->getComment());
203
-                    /** @var JobQueue $job */
204
-                    $job = JobQueue::getById($data['job'], $database);
205
-                    $requestLogs[] = array(
206
-                        'type'     => 'joblog',
207
-                        'security' => 'user',
208
-                        'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
209
-                        'user'     => $entryUser->getUsername(),
210
-                        'entry'    => LogHelper::getLogDescription($entry),
211
-                        'time'     => $entry->getTimestamp(),
212
-                        'canedit'  => false,
213
-                        'id'       => $entry->getId(),
214
-                        'jobId'    => $job->getId(),
215
-                        'jobDesc'  => JobQueue::getTaskDescriptions()[$job->getTask()],
216
-                    );
217
-                } else {
218
-                    $requestLogs[] = array(
219
-                        'type'     => 'log',
220
-                        'security' => 'user',
221
-                        'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
222
-                        'user'     => $entryUser->getUsername(),
223
-                        'entry'    => LogHelper::getLogDescription($entry),
224
-                        'time'     => $entry->getTimestamp(),
225
-                        'canedit'  => false,
226
-                        'id'       => $entry->getId(),
227
-                        'comment'  => $entryComment,
228
-                    );
229
-                }
230
-            }
231
-        }
232
-
233
-        $this->addJs("/api.php?action=users&targetVariable=typeaheaddata");
234
-
235
-        $this->assign("requestLogs", $requestLogs);
236
-    }
237
-
238
-    /**
239
-     * @param Request $request
240
-     */
241
-    protected function setupUsernameData(Request $request)
242
-    {
243
-        $blacklistData = $this->getBlacklistHelper()->isBlacklisted($request->getName());
244
-
245
-        $this->assign('requestIsBlacklisted', $blacklistData !== false);
246
-        $this->assign('requestBlacklist', $blacklistData);
247
-
248
-        try {
249
-            $spoofs = $this->getAntiSpoofProvider()->getSpoofs($request->getName());
250
-        }
251
-        catch (Exception $ex) {
252
-            $spoofs = $ex->getMessage();
253
-        }
254
-
255
-        $this->assign("spoofs", $spoofs);
256
-    }
257
-
258
-    private function setupCreationTypes(User $user)
259
-    {
260
-        $canManualCreate = $this->barrierTest(User::CREATION_MANUAL, $user, 'RequestCreation');
261
-        $canOauthCreate = $this->barrierTest(User::CREATION_OAUTH, $user, 'RequestCreation');
262
-        $canBotCreate = $this->barrierTest(User::CREATION_BOT, $user, 'RequestCreation');
263
-
264
-        $this->assign('canManualCreate', $canManualCreate);
265
-        $this->assign('canOauthCreate', $canOauthCreate);
266
-        $this->assign('canBotCreate', $canBotCreate);
267
-
268
-        $creationHasChoice = count(array_filter([$canManualCreate, $canOauthCreate, $canBotCreate])) > 1;
269
-
270
-        if (!$this->barrierTest($user->getCreationMode(), $user, 'RequestCreation')) {
271
-            // user is not allowed to use their default. Force a choice.
272
-            $creationHasChoice = true;
273
-        }
274
-
275
-        $this->assign('creationHasChoice', $creationHasChoice);
276
-    }
28
+	use RequestData;
29
+	const STATUS_SYMBOL_OPEN = '&#x2610';
30
+	const STATUS_SYMBOL_ACCEPTED = '&#x2611';
31
+	const STATUS_SYMBOL_REJECTED = '&#x2612';
32
+
33
+	/**
34
+	 * Main function for this page, when no specific actions are called.
35
+	 * @throws ApplicationLogicException
36
+	 */
37
+	protected function main()
38
+	{
39
+		// set up csrf protection
40
+		$this->assignCSRFToken();
41
+
42
+		// get some useful objects
43
+		$database = $this->getDatabase();
44
+		$request = $this->getRequest($database, WebRequest::getInt('id'));
45
+		$config = $this->getSiteConfiguration();
46
+		$currentUser = User::getCurrent($database);
47
+
48
+		// Test we should be able to look at this request
49
+		if ($config->getEmailConfirmationEnabled()) {
50
+			if ($request->getEmailConfirm() !== 'Confirmed') {
51
+				// Not allowed to look at this yet.
52
+				throw new ApplicationLogicException('The email address has not yet been confirmed for this request.');
53
+			}
54
+		}
55
+
56
+		$this->setupBasicData($request, $config);
57
+
58
+		$this->setupUsernameData($request);
59
+
60
+		$this->setupTitle($request);
61
+
62
+		$this->setupReservationDetails($request->getReserved(), $database, $currentUser);
63
+		$this->setupGeneralData($database);
64
+
65
+		$this->assign('requestDataCleared', false);
66
+		if ($request->getEmail() === $this->getSiteConfiguration()->getDataClearEmail()) {
67
+			$this->assign('requestDataCleared', true);
68
+		}
69
+
70
+		$allowedPrivateData = $this->isAllowedPrivateData($request, $currentUser);
71
+
72
+		$this->setupCreationTypes($currentUser);
73
+
74
+		$this->setupLogData($request, $database);
75
+
76
+		if ($allowedPrivateData) {
77
+			$this->setTemplate('view-request/main-with-data.tpl');
78
+			$this->setupPrivateData($request, $currentUser, $this->getSiteConfiguration(), $database);
79
+
80
+			$this->assign('canSetBan', $this->barrierTest('set', $currentUser, PageBan::class));
81
+			$this->assign('canSeeCheckuserData', $this->barrierTest('seeUserAgentData', $currentUser, 'RequestData'));
82
+
83
+			if ($this->barrierTest('seeUserAgentData', $currentUser, 'RequestData')) {
84
+				$this->setTemplate('view-request/main-with-checkuser-data.tpl');
85
+				$this->setupCheckUserData($request);
86
+			}
87
+		}
88
+		else {
89
+			$this->setTemplate('view-request/main.tpl');
90
+		}
91
+	}
92
+
93
+	/**
94
+	 * @param Request $request
95
+	 */
96
+	protected function setupTitle(Request $request)
97
+	{
98
+		$statusSymbol = self::STATUS_SYMBOL_OPEN;
99
+		if ($request->getStatus() === 'Closed') {
100
+			if ($request->getWasCreated()) {
101
+				$statusSymbol = self::STATUS_SYMBOL_ACCEPTED;
102
+			}
103
+			else {
104
+				$statusSymbol = self::STATUS_SYMBOL_REJECTED;
105
+			}
106
+		}
107
+
108
+		$this->setHtmlTitle($statusSymbol . ' #' . $request->getId());
109
+	}
110
+
111
+	/**
112
+	 * Sets up data unrelated to the request, such as the email template information
113
+	 *
114
+	 * @param PdoDatabase $database
115
+	 */
116
+	protected function setupGeneralData(PdoDatabase $database)
117
+	{
118
+		$config = $this->getSiteConfiguration();
119
+
120
+		$this->assign('createAccountReason', 'Requested account at [[WP:ACC]], request #');
121
+
122
+		$this->assign('defaultRequestState', $config->getDefaultRequestStateKey());
123
+
124
+		$this->assign('requestStates', $config->getRequestStates());
125
+
126
+		/** @var EmailTemplate $createdTemplate */
127
+		$createdTemplate = EmailTemplate::getById($config->getDefaultCreatedTemplateId(), $database);
128
+
129
+		$this->assign('createdHasJsQuestion', $createdTemplate->getJsquestion() != '');
130
+		$this->assign('createdJsQuestion', $createdTemplate->getJsquestion());
131
+		$this->assign('createdId', $createdTemplate->getId());
132
+		$this->assign('createdName', $createdTemplate->getName());
133
+
134
+		$createReasons = EmailTemplate::getActiveTemplates(EmailTemplate::CREATED, $database);
135
+		$this->assign("createReasons", $createReasons);
136
+		$declineReasons = EmailTemplate::getActiveTemplates(EmailTemplate::NOT_CREATED, $database);
137
+		$this->assign("declineReasons", $declineReasons);
138
+
139
+		$allCreateReasons = EmailTemplate::getAllActiveTemplates(EmailTemplate::CREATED, $database);
140
+		$this->assign("allCreateReasons", $allCreateReasons);
141
+		$allDeclineReasons = EmailTemplate::getAllActiveTemplates(EmailTemplate::NOT_CREATED, $database);
142
+		$this->assign("allDeclineReasons", $allDeclineReasons);
143
+		$allOtherReasons = EmailTemplate::getAllActiveTemplates(false, $database);
144
+		$this->assign("allOtherReasons", $allOtherReasons);
145
+	}
146
+
147
+	private function setupLogData(Request $request, PdoDatabase $database)
148
+	{
149
+		$currentUser = User::getCurrent($database);
150
+
151
+		$logs = LogHelper::getRequestLogsWithComments($request->getId(), $database, $this->getSecurityManager());
152
+		$requestLogs = array();
153
+
154
+		if (trim($request->getComment()) !== "") {
155
+			$requestLogs[] = array(
156
+				'type'     => 'comment',
157
+				'security' => 'user',
158
+				'userid'   => null,
159
+				'user'     => $request->getName(),
160
+				'entry'    => null,
161
+				'time'     => $request->getDate(),
162
+				'canedit'  => false,
163
+				'id'       => $request->getId(),
164
+				'comment'  => $request->getComment(),
165
+			);
166
+		}
167
+
168
+		/** @var User[] $nameCache */
169
+		$nameCache = array();
170
+
171
+		$editableComments = $this->barrierTest('editOthers', $currentUser, PageEditComment::class);
172
+
173
+		/** @var Log|Comment $entry */
174
+		foreach ($logs as $entry) {
175
+			// both log and comment have a 'user' field
176
+			if (!array_key_exists($entry->getUser(), $nameCache)) {
177
+				$entryUser = User::getById($entry->getUser(), $database);
178
+				$nameCache[$entry->getUser()] = $entryUser;
179
+			}
180
+
181
+			if ($entry instanceof Comment) {
182
+				$requestLogs[] = array(
183
+					'type'     => 'comment',
184
+					'security' => $entry->getVisibility(),
185
+					'user'     => $nameCache[$entry->getUser()]->getUsername(),
186
+					'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
187
+					'entry'    => null,
188
+					'time'     => $entry->getTime(),
189
+					'canedit'  => ($editableComments || $entry->getUser() == $currentUser->getId()),
190
+					'id'       => $entry->getId(),
191
+					'comment'  => $entry->getComment(),
192
+				);
193
+			}
194
+
195
+			if ($entry instanceof Log) {
196
+				$invalidUserId = $entry->getUser() === -1 || $entry->getUser() === 0;
197
+				$entryUser = $invalidUserId ? User::getCommunity() : $nameCache[$entry->getUser()];
198
+
199
+				$entryComment = $entry->getComment();
200
+
201
+				if($entry->getAction() === 'JobIssueRequest' || $entry->getAction() === 'JobCompletedRequest'){
202
+					$data = unserialize($entry->getComment());
203
+					/** @var JobQueue $job */
204
+					$job = JobQueue::getById($data['job'], $database);
205
+					$requestLogs[] = array(
206
+						'type'     => 'joblog',
207
+						'security' => 'user',
208
+						'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
209
+						'user'     => $entryUser->getUsername(),
210
+						'entry'    => LogHelper::getLogDescription($entry),
211
+						'time'     => $entry->getTimestamp(),
212
+						'canedit'  => false,
213
+						'id'       => $entry->getId(),
214
+						'jobId'    => $job->getId(),
215
+						'jobDesc'  => JobQueue::getTaskDescriptions()[$job->getTask()],
216
+					);
217
+				} else {
218
+					$requestLogs[] = array(
219
+						'type'     => 'log',
220
+						'security' => 'user',
221
+						'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
222
+						'user'     => $entryUser->getUsername(),
223
+						'entry'    => LogHelper::getLogDescription($entry),
224
+						'time'     => $entry->getTimestamp(),
225
+						'canedit'  => false,
226
+						'id'       => $entry->getId(),
227
+						'comment'  => $entryComment,
228
+					);
229
+				}
230
+			}
231
+		}
232
+
233
+		$this->addJs("/api.php?action=users&targetVariable=typeaheaddata");
234
+
235
+		$this->assign("requestLogs", $requestLogs);
236
+	}
237
+
238
+	/**
239
+	 * @param Request $request
240
+	 */
241
+	protected function setupUsernameData(Request $request)
242
+	{
243
+		$blacklistData = $this->getBlacklistHelper()->isBlacklisted($request->getName());
244
+
245
+		$this->assign('requestIsBlacklisted', $blacklistData !== false);
246
+		$this->assign('requestBlacklist', $blacklistData);
247
+
248
+		try {
249
+			$spoofs = $this->getAntiSpoofProvider()->getSpoofs($request->getName());
250
+		}
251
+		catch (Exception $ex) {
252
+			$spoofs = $ex->getMessage();
253
+		}
254
+
255
+		$this->assign("spoofs", $spoofs);
256
+	}
257
+
258
+	private function setupCreationTypes(User $user)
259
+	{
260
+		$canManualCreate = $this->barrierTest(User::CREATION_MANUAL, $user, 'RequestCreation');
261
+		$canOauthCreate = $this->barrierTest(User::CREATION_OAUTH, $user, 'RequestCreation');
262
+		$canBotCreate = $this->barrierTest(User::CREATION_BOT, $user, 'RequestCreation');
263
+
264
+		$this->assign('canManualCreate', $canManualCreate);
265
+		$this->assign('canOauthCreate', $canOauthCreate);
266
+		$this->assign('canBotCreate', $canBotCreate);
267
+
268
+		$creationHasChoice = count(array_filter([$canManualCreate, $canOauthCreate, $canBotCreate])) > 1;
269
+
270
+		if (!$this->barrierTest($user->getCreationMode(), $user, 'RequestCreation')) {
271
+			// user is not allowed to use their default. Force a choice.
272
+			$creationHasChoice = true;
273
+		}
274
+
275
+		$this->assign('creationHasChoice', $creationHasChoice);
276
+	}
277 277
 }
Please login to merge, or discard this patch.