Passed
Push — dependabot/github_actions/shiv... ( d77982 )
by
unknown
24:09 queued 18:55
created
includes/WebStart.php 2 patches
Indentation   +209 added lines, -209 removed lines patch added patch discarded remove patch
@@ -35,213 +35,213 @@
 block discarded – undo
35 35
  */
36 36
 class WebStart extends ApplicationBase
37 37
 {
38
-    /**
39
-     * @var IRequestRouter $requestRouter The request router to use. Note that different entry points have different
40
-     *                                    routers and hence different URL mappings
41
-     */
42
-    private $requestRouter;
43
-    /**
44
-     * @var bool $isPublic Determines whether to use public interface objects or internal interface objects
45
-     */
46
-    private bool $isPublic = false;
47
-
48
-    /**
49
-     * WebStart constructor.
50
-     *
51
-     * @param SiteConfiguration $configuration The site configuration
52
-     * @param IRequestRouter    $router        The request router to use
53
-     */
54
-    public function __construct(SiteConfiguration $configuration, IRequestRouter $router)
55
-    {
56
-        parent::__construct($configuration);
57
-
58
-        $this->requestRouter = $router;
59
-    }
60
-
61
-    /**
62
-     * @param ITask             $page
63
-     * @param SiteConfiguration $siteConfiguration
64
-     * @param PdoDatabase       $database
65
-     *
66
-     * @return void
67
-     */
68
-    protected function setupHelpers(
69
-        ITask $page,
70
-        SiteConfiguration $siteConfiguration,
71
-        PdoDatabase $database
72
-    ) {
73
-        parent::setupHelpers($page, $siteConfiguration, $database);
74
-
75
-        if ($page instanceof PageBase) {
76
-            $page->setTokenManager(new TokenManager());
77
-            $page->setCspManager(new ContentSecurityPolicyManager($siteConfiguration));
78
-
79
-            if ($page instanceof InternalPageBase) {
80
-                $page->setTypeAheadHelper(new TypeAheadHelper());
81
-
82
-                $httpHelper = $page->getHttpHelper();
83
-
84
-                $userAccessLoader = new UserAccessLoader();
85
-                $domainAccessManager = new DomainAccessManager($userAccessLoader);
86
-
87
-                $identificationVerifier = new IdentificationVerifier($httpHelper, $siteConfiguration, $database);
88
-
89
-                $page->setSecurityManager(new SecurityManager($identificationVerifier, new RoleConfiguration(), $userAccessLoader));
90
-                $page->setDomainAccessManager($domainAccessManager);
91
-
92
-                if ($siteConfiguration->getTitleBlacklistEnabled()) {
93
-                    $page->setBlacklistHelper(new BlacklistHelper($httpHelper, $database, $siteConfiguration));
94
-                }
95
-                else {
96
-                    $page->setBlacklistHelper(new FakeBlacklistHelper());
97
-                }
98
-            }
99
-        }
100
-    }
101
-
102
-    /**
103
-     * Application entry point.
104
-     *
105
-     * Sets up the environment and runs the application, performing any global cleanup operations when done.
106
-     */
107
-    public function run()
108
-    {
109
-        try {
110
-            if ($this->setupEnvironment()) {
111
-                $this->main();
112
-            }
113
-        }
114
-        catch (EnvironmentException $ex) {
115
-            ob_end_clean();
116
-            print Offline::getOfflineMessage($this->isPublic(), $this->getConfiguration(), $ex->getMessage());
117
-        }
118
-            /** @noinspection PhpRedundantCatchClauseInspection */
119
-        catch (ReadableException $ex) {
120
-            ob_end_clean();
121
-            print $ex->getReadableError();
122
-        }
123
-        finally {
124
-            $this->cleanupEnvironment();
125
-        }
126
-    }
127
-
128
-    /**
129
-     * Environment setup
130
-     *
131
-     * This method initialises the tool environment. If the tool cannot be initialised correctly, it will return false
132
-     * and shut down prematurely.
133
-     *
134
-     * @return bool
135
-     * @throws EnvironmentException
136
-     */
137
-    protected function setupEnvironment()
138
-    {
139
-        // initialise global exception handler
140
-        set_exception_handler(array(ExceptionHandler::class, 'exceptionHandler'));
141
-        set_error_handler(array(ExceptionHandler::class, 'errorHandler'), E_RECOVERABLE_ERROR);
142
-
143
-        // start output buffering if necessary
144
-        if (ob_get_level() === 0) {
145
-            ob_start();
146
-        }
147
-
148
-        // initialise super-global providers
149
-        WebRequest::setGlobalStateProvider(new GlobalStateProvider());
150
-
151
-        if (Offline::isOffline($this->getConfiguration())) {
152
-            print Offline::getOfflineMessage($this->isPublic(), $this->getConfiguration());
153
-            ob_end_flush();
154
-
155
-            return false;
156
-        }
157
-
158
-        // Call parent setup
159
-        if (!parent::setupEnvironment()) {
160
-            return false;
161
-        }
162
-
163
-        // Start up sessions
164
-        ini_set('session.cookie_path', $this->getConfiguration()->getCookiePath());
165
-        ini_set('session.name', $this->getConfiguration()->getCookieSessionName());
166
-        Session::start();
167
-
168
-        // Check the user is allowed to be logged in still. This must be before we call any user-loading functions and
169
-        // get the current user cached.
170
-        // I'm not sure if this function call being here is particularly a good thing, but it's part of starting up a
171
-        // session I suppose.
172
-        $this->checkForceLogout();
173
-
174
-        // environment initialised!
175
-        return true;
176
-    }
177
-
178
-    /**
179
-     * Main application logic
180
-     */
181
-    protected function main()
182
-    {
183
-        // Get the right route for the request
184
-        $page = $this->requestRouter->route();
185
-
186
-        $siteConfiguration = $this->getConfiguration();
187
-        $database = PdoDatabase::getDatabaseConnection($this->getConfiguration());
188
-
189
-        $this->setupHelpers($page, $siteConfiguration, $database);
190
-
191
-        // run the route code for the request.
192
-        $page->execute();
193
-    }
194
-
195
-    /**
196
-     * Any cleanup tasks should go here
197
-     *
198
-     * Note that we need to be very careful here, as exceptions may have been thrown and handled.
199
-     * This should *only* be for cleaning up, no logic should go here.
200
-     */
201
-    protected function cleanupEnvironment()
202
-    {
203
-        // Clean up anything we splurged after sending the page.
204
-        if (ob_get_level() > 0) {
205
-            for ($i = ob_get_level(); $i > 0; $i--) {
206
-                ob_end_clean();
207
-            }
208
-        }
209
-    }
210
-
211
-    private function checkForceLogout()
212
-    {
213
-        $database = PdoDatabase::getDatabaseConnection($this->getConfiguration());
214
-
215
-        $sessionUserId = WebRequest::getSessionUserId();
216
-        iF ($sessionUserId === null) {
217
-            return;
218
-        }
219
-
220
-        // Note, User::getCurrent() caches it's result, which we *really* don't want to trigger.
221
-        $currentUser = User::getById($sessionUserId, $database);
222
-
223
-        if ($currentUser === false) {
224
-            // Umm... this user has a session cookie with a userId set, but no user exists...
225
-            Session::restart();
226
-
227
-            $currentUser = User::getCurrent($database);
228
-        }
229
-
230
-        if ($currentUser->getForceLogout()) {
231
-            Session::restart();
232
-
233
-            $currentUser->setForceLogout(false);
234
-            $currentUser->save();
235
-        }
236
-    }
237
-
238
-    public function isPublic(): bool
239
-    {
240
-        return $this->isPublic;
241
-    }
242
-
243
-    public function setPublic(bool $isPublic): void
244
-    {
245
-        $this->isPublic = $isPublic;
246
-    }
38
+	/**
39
+	 * @var IRequestRouter $requestRouter The request router to use. Note that different entry points have different
40
+	 *                                    routers and hence different URL mappings
41
+	 */
42
+	private $requestRouter;
43
+	/**
44
+	 * @var bool $isPublic Determines whether to use public interface objects or internal interface objects
45
+	 */
46
+	private bool $isPublic = false;
47
+
48
+	/**
49
+	 * WebStart constructor.
50
+	 *
51
+	 * @param SiteConfiguration $configuration The site configuration
52
+	 * @param IRequestRouter    $router        The request router to use
53
+	 */
54
+	public function __construct(SiteConfiguration $configuration, IRequestRouter $router)
55
+	{
56
+		parent::__construct($configuration);
57
+
58
+		$this->requestRouter = $router;
59
+	}
60
+
61
+	/**
62
+	 * @param ITask             $page
63
+	 * @param SiteConfiguration $siteConfiguration
64
+	 * @param PdoDatabase       $database
65
+	 *
66
+	 * @return void
67
+	 */
68
+	protected function setupHelpers(
69
+		ITask $page,
70
+		SiteConfiguration $siteConfiguration,
71
+		PdoDatabase $database
72
+	) {
73
+		parent::setupHelpers($page, $siteConfiguration, $database);
74
+
75
+		if ($page instanceof PageBase) {
76
+			$page->setTokenManager(new TokenManager());
77
+			$page->setCspManager(new ContentSecurityPolicyManager($siteConfiguration));
78
+
79
+			if ($page instanceof InternalPageBase) {
80
+				$page->setTypeAheadHelper(new TypeAheadHelper());
81
+
82
+				$httpHelper = $page->getHttpHelper();
83
+
84
+				$userAccessLoader = new UserAccessLoader();
85
+				$domainAccessManager = new DomainAccessManager($userAccessLoader);
86
+
87
+				$identificationVerifier = new IdentificationVerifier($httpHelper, $siteConfiguration, $database);
88
+
89
+				$page->setSecurityManager(new SecurityManager($identificationVerifier, new RoleConfiguration(), $userAccessLoader));
90
+				$page->setDomainAccessManager($domainAccessManager);
91
+
92
+				if ($siteConfiguration->getTitleBlacklistEnabled()) {
93
+					$page->setBlacklistHelper(new BlacklistHelper($httpHelper, $database, $siteConfiguration));
94
+				}
95
+				else {
96
+					$page->setBlacklistHelper(new FakeBlacklistHelper());
97
+				}
98
+			}
99
+		}
100
+	}
101
+
102
+	/**
103
+	 * Application entry point.
104
+	 *
105
+	 * Sets up the environment and runs the application, performing any global cleanup operations when done.
106
+	 */
107
+	public function run()
108
+	{
109
+		try {
110
+			if ($this->setupEnvironment()) {
111
+				$this->main();
112
+			}
113
+		}
114
+		catch (EnvironmentException $ex) {
115
+			ob_end_clean();
116
+			print Offline::getOfflineMessage($this->isPublic(), $this->getConfiguration(), $ex->getMessage());
117
+		}
118
+			/** @noinspection PhpRedundantCatchClauseInspection */
119
+		catch (ReadableException $ex) {
120
+			ob_end_clean();
121
+			print $ex->getReadableError();
122
+		}
123
+		finally {
124
+			$this->cleanupEnvironment();
125
+		}
126
+	}
127
+
128
+	/**
129
+	 * Environment setup
130
+	 *
131
+	 * This method initialises the tool environment. If the tool cannot be initialised correctly, it will return false
132
+	 * and shut down prematurely.
133
+	 *
134
+	 * @return bool
135
+	 * @throws EnvironmentException
136
+	 */
137
+	protected function setupEnvironment()
138
+	{
139
+		// initialise global exception handler
140
+		set_exception_handler(array(ExceptionHandler::class, 'exceptionHandler'));
141
+		set_error_handler(array(ExceptionHandler::class, 'errorHandler'), E_RECOVERABLE_ERROR);
142
+
143
+		// start output buffering if necessary
144
+		if (ob_get_level() === 0) {
145
+			ob_start();
146
+		}
147
+
148
+		// initialise super-global providers
149
+		WebRequest::setGlobalStateProvider(new GlobalStateProvider());
150
+
151
+		if (Offline::isOffline($this->getConfiguration())) {
152
+			print Offline::getOfflineMessage($this->isPublic(), $this->getConfiguration());
153
+			ob_end_flush();
154
+
155
+			return false;
156
+		}
157
+
158
+		// Call parent setup
159
+		if (!parent::setupEnvironment()) {
160
+			return false;
161
+		}
162
+
163
+		// Start up sessions
164
+		ini_set('session.cookie_path', $this->getConfiguration()->getCookiePath());
165
+		ini_set('session.name', $this->getConfiguration()->getCookieSessionName());
166
+		Session::start();
167
+
168
+		// Check the user is allowed to be logged in still. This must be before we call any user-loading functions and
169
+		// get the current user cached.
170
+		// I'm not sure if this function call being here is particularly a good thing, but it's part of starting up a
171
+		// session I suppose.
172
+		$this->checkForceLogout();
173
+
174
+		// environment initialised!
175
+		return true;
176
+	}
177
+
178
+	/**
179
+	 * Main application logic
180
+	 */
181
+	protected function main()
182
+	{
183
+		// Get the right route for the request
184
+		$page = $this->requestRouter->route();
185
+
186
+		$siteConfiguration = $this->getConfiguration();
187
+		$database = PdoDatabase::getDatabaseConnection($this->getConfiguration());
188
+
189
+		$this->setupHelpers($page, $siteConfiguration, $database);
190
+
191
+		// run the route code for the request.
192
+		$page->execute();
193
+	}
194
+
195
+	/**
196
+	 * Any cleanup tasks should go here
197
+	 *
198
+	 * Note that we need to be very careful here, as exceptions may have been thrown and handled.
199
+	 * This should *only* be for cleaning up, no logic should go here.
200
+	 */
201
+	protected function cleanupEnvironment()
202
+	{
203
+		// Clean up anything we splurged after sending the page.
204
+		if (ob_get_level() > 0) {
205
+			for ($i = ob_get_level(); $i > 0; $i--) {
206
+				ob_end_clean();
207
+			}
208
+		}
209
+	}
210
+
211
+	private function checkForceLogout()
212
+	{
213
+		$database = PdoDatabase::getDatabaseConnection($this->getConfiguration());
214
+
215
+		$sessionUserId = WebRequest::getSessionUserId();
216
+		iF ($sessionUserId === null) {
217
+			return;
218
+		}
219
+
220
+		// Note, User::getCurrent() caches it's result, which we *really* don't want to trigger.
221
+		$currentUser = User::getById($sessionUserId, $database);
222
+
223
+		if ($currentUser === false) {
224
+			// Umm... this user has a session cookie with a userId set, but no user exists...
225
+			Session::restart();
226
+
227
+			$currentUser = User::getCurrent($database);
228
+		}
229
+
230
+		if ($currentUser->getForceLogout()) {
231
+			Session::restart();
232
+
233
+			$currentUser->setForceLogout(false);
234
+			$currentUser->save();
235
+		}
236
+	}
237
+
238
+	public function isPublic(): bool
239
+	{
240
+		return $this->isPublic;
241
+	}
242
+
243
+	public function setPublic(bool $isPublic): void
244
+	{
245
+		$this->isPublic = $isPublic;
246
+	}
247 247
 }
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -91,8 +91,7 @@
 block discarded – undo
91 91
 
92 92
                 if ($siteConfiguration->getTitleBlacklistEnabled()) {
93 93
                     $page->setBlacklistHelper(new BlacklistHelper($httpHelper, $database, $siteConfiguration));
94
-                }
95
-                else {
94
+                } else {
96 95
                     $page->setBlacklistHelper(new FakeBlacklistHelper());
97 96
                 }
98 97
             }
Please login to merge, or discard this patch.
includes/Router/ApiRequestRouter.php 1 patch
Indentation   +45 added lines, -45 removed lines patch added patch discarded remove patch
@@ -24,52 +24,52 @@
 block discarded – undo
24 24
 
25 25
 class ApiRequestRouter implements IRequestRouter
26 26
 {
27
-    /**
28
-     * @return string[]
29
-     */
30
-    public static function getActionList()
31
-    {
32
-        return array('count', 'status', 'stats', 'help', 'monitor', 'metrics');
33
-    }
27
+	/**
28
+	 * @return string[]
29
+	 */
30
+	public static function getActionList()
31
+	{
32
+		return array('count', 'status', 'stats', 'help', 'monitor', 'metrics');
33
+	}
34 34
 
35
-    /**
36
-     * @return IRoutedTask
37
-     * @throws Exception
38
-     */
39
-    public function route()
40
-    {
41
-        $requestAction = WebRequest::getString('action');
35
+	/**
36
+	 * @return IRoutedTask
37
+	 * @throws Exception
38
+	 */
39
+	public function route()
40
+	{
41
+		$requestAction = WebRequest::getString('action');
42 42
 
43
-        switch ($requestAction) {
44
-            case "count":
45
-                $result = new CountAction();
46
-                break;
47
-            case "status":
48
-                $result = new StatusAction();
49
-                break;
50
-            case "stats":
51
-                $result = new StatsAction();
52
-                break;
53
-            case "help":
54
-                $result = new HelpAction();
55
-                break;
56
-            case "monitor":
57
-                $result = new MonitorAction();
58
-                break;
59
-            case "users":
60
-                $result = new JsUsersAction();
61
-                break;
62
-            case "templates":
63
-                $result = new JsTemplateConfirmsAction();
64
-                break;
65
-            case 'metrics':
66
-                $result = new MetricsAction();
67
-                break;
68
-            default:
69
-                $result = new UnknownAction();
70
-                break;
71
-        }
43
+		switch ($requestAction) {
44
+			case "count":
45
+				$result = new CountAction();
46
+				break;
47
+			case "status":
48
+				$result = new StatusAction();
49
+				break;
50
+			case "stats":
51
+				$result = new StatsAction();
52
+				break;
53
+			case "help":
54
+				$result = new HelpAction();
55
+				break;
56
+			case "monitor":
57
+				$result = new MonitorAction();
58
+				break;
59
+			case "users":
60
+				$result = new JsUsersAction();
61
+				break;
62
+			case "templates":
63
+				$result = new JsTemplateConfirmsAction();
64
+				break;
65
+			case 'metrics':
66
+				$result = new MetricsAction();
67
+				break;
68
+			default:
69
+				$result = new UnknownAction();
70
+				break;
71
+		}
72 72
 
73
-        return $result;
74
-    }
73
+		return $result;
74
+	}
75 75
 }
Please login to merge, or discard this patch.
includes/ConsoleTasks/AutoFlagCommentsTask.php 1 patch
Indentation   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -17,11 +17,11 @@  discard block
 block discarded – undo
17 17
 
18 18
 class AutoFlagCommentsTask extends ConsoleTaskBase
19 19
 {
20
-    public function execute()
21
-    {
22
-        $database = $this->getDatabase();
20
+	public function execute()
21
+	{
22
+		$database = $this->getDatabase();
23 23
 
24
-        $query = $database->prepare(<<<'SQL'
24
+		$query = $database->prepare(<<<'SQL'
25 25
 select c.id, r.domain
26 26
 from comment c
27 27
 inner join request r on r.id = c.request
@@ -81,22 +81,22 @@  discard block
 block discarded – undo
81 81
 and c.comment not like '%[redacted]%'
82 82
 ;
83 83
 SQL
84
-        );
84
+		);
85 85
 
86
-        $success = $query->execute();
86
+		$success = $query->execute();
87 87
 
88
-        if (!$success) {
89
-            throw new Exception('Error in transaction: Could not load data.');
90
-        }
88
+		if (!$success) {
89
+			throw new Exception('Error in transaction: Could not load data.');
90
+		}
91 91
 
92
-        $data = $query->fetchAll(PDO::FETCH_ASSOC);
93
-        foreach ($data as $row) {
94
-            /** @var Comment $dataObject */
95
-            $dataObject = Comment::getById($row['id'], $database);
92
+		$data = $query->fetchAll(PDO::FETCH_ASSOC);
93
+		foreach ($data as $row) {
94
+			/** @var Comment $dataObject */
95
+			$dataObject = Comment::getById($row['id'], $database);
96 96
 
97
-            Logger::flaggedComment($database, $dataObject, $row['domain']);
98
-            $dataObject->setFlagged(true);
99
-            $dataObject->save();
100
-        }
101
-    }
97
+			Logger::flaggedComment($database, $dataObject, $row['domain']);
98
+			$dataObject->setFlagged(true);
99
+			$dataObject->save();
100
+		}
101
+	}
102 102
 }
103 103
\ No newline at end of file
Please login to merge, or discard this patch.
includes/Helpers/PreferenceManager.php 1 patch
Indentation   +186 added lines, -186 removed lines patch added patch discarded remove patch
@@ -18,172 +18,172 @@  discard block
 block discarded – undo
18 18
 
19 19
 class PreferenceManager
20 20
 {
21
-    const PREF_WELCOMETEMPLATE = 'welcomeTemplate';
22
-    const PREF_SKIP_JS_ABORT = 'skipJsAbort';
23
-    const PREF_EMAIL_SIGNATURE = 'emailSignature';
24
-    const PREF_CREATION_MODE = 'creationMode';
25
-    const PREF_SKIN = 'skin';
26
-    const PREF_DEFAULT_DOMAIN = 'defaultDomain';
27
-    const PREF_QUEUE_HELP = 'showQueueHelp';
28
-
29
-    const ADMIN_PREF_PREVENT_REACTIVATION = 'preventReactivation';
30
-
31
-    const CREATION_MANUAL = 0;
32
-    const CREATION_OAUTH = 1;
33
-    const CREATION_BOT = 2;
34
-    /** @var PdoDatabase */
35
-    private $database;
36
-    /** @var int */
37
-    private $user;
38
-    /** @var ?int */
39
-    private $domain;
40
-    /** @var PreferenceManager|null */
41
-    private static $currentUser = null;
42
-    private $cachedPreferences = null;
43
-
44
-    public function __construct(PdoDatabase $database, int $user, ?int $domain)
45
-    {
46
-        $this->database = $database;
47
-        $this->user = $user;
48
-        $this->domain = $domain;
49
-    }
50
-
51
-    public static function getForCurrent(PdoDatabase $database): PreferenceManager
52
-    {
53
-        if (self::$currentUser === null) {
54
-            $user = User::getCurrent($database)->getId();
55
-            $domain = WebRequest::getSessionDomain();
56
-
57
-            self::$currentUser = new self($database, $user, $domain);
58
-        }
59
-
60
-        return self::$currentUser;
61
-    }
62
-
63
-    public function setLocalPreference(string $preference, $value): void
64
-    {
65
-        if ($this->cachedPreferences === null) {
66
-            $this->loadPreferences();
67
-        }
68
-
69
-        if ($this->cachedPreferences[$preference]['value'] == $value
70
-            && $this->cachedPreferences[$preference]['global'] === false) {
71
-            return;
72
-        }
73
-
74
-        $localPreference = UserPreference::getLocalPreference($this->database, $this->user, $preference, $this->domain);
75
-        if ($localPreference === false) {
76
-            $localPreference = new UserPreference();
77
-            $localPreference->setDatabase($this->database);
78
-            $localPreference->setDomain($this->domain);
79
-            $localPreference->setUser($this->user);
80
-            $localPreference->setPreference($preference);
81
-        }
82
-
83
-        $localPreference->setValue($value);
84
-        $localPreference->save();
85
-
86
-        $this->cachedPreferences[$preference] = [
87
-            'value'  => $value,
88
-            'global' => false,
89
-        ];
90
-    }
91
-
92
-    public function setGlobalPreference(string $preference, $value): void
93
-    {
94
-        if ($this->cachedPreferences === null) {
95
-            $this->loadPreferences();
96
-        }
97
-
98
-        if ($this->cachedPreferences[$preference]['value'] == $value
99
-            && $this->cachedPreferences[$preference]['global'] === true) {
100
-            return;
101
-        }
102
-
103
-        $this->deleteLocalPreference($preference);
104
-
105
-        $globalPreference = UserPreference::getGlobalPreference($this->database, $this->user, $preference);
106
-        if ($globalPreference === false) {
107
-            $globalPreference = new UserPreference();
108
-            $globalPreference->setDatabase($this->database);
109
-            $globalPreference->setDomain(null);
110
-            $globalPreference->setUser($this->user);
111
-            $globalPreference->setPreference($preference);
112
-        }
113
-
114
-        $globalPreference->setValue($value);
115
-        $globalPreference->save();
116
-
117
-        $this->cachedPreferences[$preference] = [
118
-            'value'  => $value,
119
-            'global' => true,
120
-        ];
121
-    }
122
-
123
-    public function getPreference(string $preference)
124
-    {
125
-        if ($this->cachedPreferences === null) {
126
-            $this->loadPreferences();
127
-        }
128
-
129
-        if (!isset($this->cachedPreferences[$preference])) {
130
-            return null;
131
-        }
132
-
133
-        return $this->cachedPreferences[$preference]['value'];
134
-    }
135
-
136
-    public function isGlobalPreference(string $preference) : ?bool
137
-    {
138
-        if ($this->cachedPreferences === null) {
139
-            $this->loadPreferences();
140
-        }
141
-
142
-        if (!isset($this->cachedPreferences[$preference])) {
143
-            return null;
144
-        }
145
-
146
-        return $this->cachedPreferences[$preference]['global'];
147
-    }
148
-
149
-    protected function deleteLocalPreference(string $preference): void
150
-    {
151
-        $getStatement = $this->database->prepare('SELECT * FROM userpreference WHERE preference = :preference AND USER = :user AND domain = :domain');
152
-        $getStatement->execute([
153
-            ':user'       => $this->user,
154
-            ':preference' => $preference,
155
-            ':domain'     => $this->domain
156
-        ]);
157
-
158
-        $localPreference = $getStatement->fetchObject(UserPreference::class);
159
-        if ($localPreference !== false) {
160
-            $localPreference->setDatabase($this->database);
161
-            $localPreference->delete();
162
-        }
163
-    }
164
-
165
-    protected function loadPreferences(): void
166
-    {
167
-        /**
168
-         * OK, this is a bit of a complicated query.
169
-         * It's designed to get all the preferences defined for a user in a specified domain, falling back to globally
170
-         * defined preferences if a local preference isn't set. As such, this query is the *heart* of how global
171
-         * preferences work.
172
-         *
173
-         * Starting with the WHERE, we filter rows:
174
-         *   a) where the row's domain is the domain we're looking for
175
-         *   b) where the row's domain is null, thus it's a global setting
176
-         *   c) if we don't have a domain we're looking for, fall back to global only
177
-         *
178
-         * The MAX(...) OVER(...) is a window function, *not* an aggregate. It basically takes the max of all selected
179
-         * rows' domain columns, grouped by the preference column. Since any number N < null, this highlights all the
180
-         * correct settings (local has precedence over global) such that prefpart == domain.
181
-         *
182
-         * -1 is used to represent null in the COALESCE() calls, since domain.id is an unsigned int hence -1 is an
183
-         * impossible value
184
-         */
185
-        $sql = /** @lang SQL */
186
-            <<<'EOF'
21
+	const PREF_WELCOMETEMPLATE = 'welcomeTemplate';
22
+	const PREF_SKIP_JS_ABORT = 'skipJsAbort';
23
+	const PREF_EMAIL_SIGNATURE = 'emailSignature';
24
+	const PREF_CREATION_MODE = 'creationMode';
25
+	const PREF_SKIN = 'skin';
26
+	const PREF_DEFAULT_DOMAIN = 'defaultDomain';
27
+	const PREF_QUEUE_HELP = 'showQueueHelp';
28
+
29
+	const ADMIN_PREF_PREVENT_REACTIVATION = 'preventReactivation';
30
+
31
+	const CREATION_MANUAL = 0;
32
+	const CREATION_OAUTH = 1;
33
+	const CREATION_BOT = 2;
34
+	/** @var PdoDatabase */
35
+	private $database;
36
+	/** @var int */
37
+	private $user;
38
+	/** @var ?int */
39
+	private $domain;
40
+	/** @var PreferenceManager|null */
41
+	private static $currentUser = null;
42
+	private $cachedPreferences = null;
43
+
44
+	public function __construct(PdoDatabase $database, int $user, ?int $domain)
45
+	{
46
+		$this->database = $database;
47
+		$this->user = $user;
48
+		$this->domain = $domain;
49
+	}
50
+
51
+	public static function getForCurrent(PdoDatabase $database): PreferenceManager
52
+	{
53
+		if (self::$currentUser === null) {
54
+			$user = User::getCurrent($database)->getId();
55
+			$domain = WebRequest::getSessionDomain();
56
+
57
+			self::$currentUser = new self($database, $user, $domain);
58
+		}
59
+
60
+		return self::$currentUser;
61
+	}
62
+
63
+	public function setLocalPreference(string $preference, $value): void
64
+	{
65
+		if ($this->cachedPreferences === null) {
66
+			$this->loadPreferences();
67
+		}
68
+
69
+		if ($this->cachedPreferences[$preference]['value'] == $value
70
+			&& $this->cachedPreferences[$preference]['global'] === false) {
71
+			return;
72
+		}
73
+
74
+		$localPreference = UserPreference::getLocalPreference($this->database, $this->user, $preference, $this->domain);
75
+		if ($localPreference === false) {
76
+			$localPreference = new UserPreference();
77
+			$localPreference->setDatabase($this->database);
78
+			$localPreference->setDomain($this->domain);
79
+			$localPreference->setUser($this->user);
80
+			$localPreference->setPreference($preference);
81
+		}
82
+
83
+		$localPreference->setValue($value);
84
+		$localPreference->save();
85
+
86
+		$this->cachedPreferences[$preference] = [
87
+			'value'  => $value,
88
+			'global' => false,
89
+		];
90
+	}
91
+
92
+	public function setGlobalPreference(string $preference, $value): void
93
+	{
94
+		if ($this->cachedPreferences === null) {
95
+			$this->loadPreferences();
96
+		}
97
+
98
+		if ($this->cachedPreferences[$preference]['value'] == $value
99
+			&& $this->cachedPreferences[$preference]['global'] === true) {
100
+			return;
101
+		}
102
+
103
+		$this->deleteLocalPreference($preference);
104
+
105
+		$globalPreference = UserPreference::getGlobalPreference($this->database, $this->user, $preference);
106
+		if ($globalPreference === false) {
107
+			$globalPreference = new UserPreference();
108
+			$globalPreference->setDatabase($this->database);
109
+			$globalPreference->setDomain(null);
110
+			$globalPreference->setUser($this->user);
111
+			$globalPreference->setPreference($preference);
112
+		}
113
+
114
+		$globalPreference->setValue($value);
115
+		$globalPreference->save();
116
+
117
+		$this->cachedPreferences[$preference] = [
118
+			'value'  => $value,
119
+			'global' => true,
120
+		];
121
+	}
122
+
123
+	public function getPreference(string $preference)
124
+	{
125
+		if ($this->cachedPreferences === null) {
126
+			$this->loadPreferences();
127
+		}
128
+
129
+		if (!isset($this->cachedPreferences[$preference])) {
130
+			return null;
131
+		}
132
+
133
+		return $this->cachedPreferences[$preference]['value'];
134
+	}
135
+
136
+	public function isGlobalPreference(string $preference) : ?bool
137
+	{
138
+		if ($this->cachedPreferences === null) {
139
+			$this->loadPreferences();
140
+		}
141
+
142
+		if (!isset($this->cachedPreferences[$preference])) {
143
+			return null;
144
+		}
145
+
146
+		return $this->cachedPreferences[$preference]['global'];
147
+	}
148
+
149
+	protected function deleteLocalPreference(string $preference): void
150
+	{
151
+		$getStatement = $this->database->prepare('SELECT * FROM userpreference WHERE preference = :preference AND USER = :user AND domain = :domain');
152
+		$getStatement->execute([
153
+			':user'       => $this->user,
154
+			':preference' => $preference,
155
+			':domain'     => $this->domain
156
+		]);
157
+
158
+		$localPreference = $getStatement->fetchObject(UserPreference::class);
159
+		if ($localPreference !== false) {
160
+			$localPreference->setDatabase($this->database);
161
+			$localPreference->delete();
162
+		}
163
+	}
164
+
165
+	protected function loadPreferences(): void
166
+	{
167
+		/**
168
+		 * OK, this is a bit of a complicated query.
169
+		 * It's designed to get all the preferences defined for a user in a specified domain, falling back to globally
170
+		 * defined preferences if a local preference isn't set. As such, this query is the *heart* of how global
171
+		 * preferences work.
172
+		 *
173
+		 * Starting with the WHERE, we filter rows:
174
+		 *   a) where the row's domain is the domain we're looking for
175
+		 *   b) where the row's domain is null, thus it's a global setting
176
+		 *   c) if we don't have a domain we're looking for, fall back to global only
177
+		 *
178
+		 * The MAX(...) OVER(...) is a window function, *not* an aggregate. It basically takes the max of all selected
179
+		 * rows' domain columns, grouped by the preference column. Since any number N < null, this highlights all the
180
+		 * correct settings (local has precedence over global) such that prefpart == domain.
181
+		 *
182
+		 * -1 is used to represent null in the COALESCE() calls, since domain.id is an unsigned int hence -1 is an
183
+		 * impossible value
184
+		 */
185
+		$sql = /** @lang SQL */
186
+			<<<'EOF'
187 187
 WITH allprefs AS (
188 188
     SELECT up.domain, up.preference, MAX(up.domain) OVER (PARTITION BY up.preference) AS prefpart, up.value, CASE WHEN up.domain IS NULL THEN 1 END AS isglobal
189 189
     FROM userpreference up
@@ -194,24 +194,24 @@  discard block
 block discarded – undo
194 194
 FROM allprefs p
195 195
 WHERE COALESCE(p.prefpart, -1) = COALESCE(p.domain, -1);
196 196
 EOF;
197
-        $statement = $this->database->prepare($sql);
198
-
199
-        $statement->execute([
200
-            ':domain'  => $this->domain,
201
-            ':domainc' => $this->domain,
202
-            ':user'    => $this->user,
203
-        ]);
204
-
205
-        $rawPrefs = $statement->fetchAll(PDO::FETCH_ASSOC);
206
-        $prefs = [];
207
-
208
-        foreach ($rawPrefs as $p) {
209
-            $prefs[$p['preference']] = [
210
-                'value'  => $p['value'],
211
-                'global' => $p['isglobal'] == 1,
212
-            ];
213
-        }
214
-
215
-        $this->cachedPreferences = $prefs;
216
-    }
197
+		$statement = $this->database->prepare($sql);
198
+
199
+		$statement->execute([
200
+			':domain'  => $this->domain,
201
+			':domainc' => $this->domain,
202
+			':user'    => $this->user,
203
+		]);
204
+
205
+		$rawPrefs = $statement->fetchAll(PDO::FETCH_ASSOC);
206
+		$prefs = [];
207
+
208
+		foreach ($rawPrefs as $p) {
209
+			$prefs[$p['preference']] = [
210
+				'value'  => $p['value'],
211
+				'global' => $p['isglobal'] == 1,
212
+			];
213
+		}
214
+
215
+		$this->cachedPreferences = $prefs;
216
+	}
217 217
 }
Please login to merge, or discard this patch.
includes/Helpers/BanHelper.php 2 patches
Indentation   +161 added lines, -161 removed lines patch added patch discarded remove patch
@@ -21,64 +21,64 @@  discard block
 block discarded – undo
21 21
 
22 22
 class BanHelper implements IBanHelper
23 23
 {
24
-    /** @var PdoDatabase */
25
-    private $database;
26
-    /** @var IXffTrustProvider */
27
-    private $xffTrustProvider;
28
-    /** @var Ban[][] */
29
-    private $banCache = [];
30
-
31
-    private ?ISecurityManager $securityManager;
32
-
33
-    public function __construct(
34
-        PdoDatabase $database,
35
-        IXffTrustProvider $xffTrustProvider,
36
-        ?ISecurityManager $securityManager
37
-    ) {
38
-        $this->database = $database;
39
-        $this->xffTrustProvider = $xffTrustProvider;
40
-        $this->securityManager = $securityManager;
41
-    }
42
-
43
-    public function isBlockBanned(Request $request): bool
44
-    {
45
-        if (!isset($this->banCache[$request->getId()])) {
46
-            $this->banCache[$request->getId()] = $this->getBansForRequestFromDatabase($request);
47
-        }
48
-
49
-        foreach ($this->banCache[$request->getId()] as $ban) {
50
-            if ($ban->getAction() === Ban::ACTION_BLOCK) {
51
-                return true;
52
-            }
53
-        }
54
-
55
-        return false;
56
-    }
57
-
58
-    /**
59
-     * @param Request $request
60
-     *
61
-     * @return Ban[]
62
-     */
63
-    public function getBans(Request $request): array
64
-    {
65
-        if (!isset($this->banCache[$request->getId()])) {
66
-            $this->banCache[$request->getId()] = $this->getBansForRequestFromDatabase($request);
67
-        }
68
-
69
-        return $this->banCache[$request->getId()];
70
-    }
71
-
72
-    public function getBansByTarget(
73
-        ?string $name,
74
-        ?string $email,
75
-        ?string $ip,
76
-        ?int $mask,
77
-        ?string $useragent,
78
-        int $domain
79
-    ) {
80
-        /** @noinspection SqlConstantCondition */
81
-        $query = <<<SQL
24
+	/** @var PdoDatabase */
25
+	private $database;
26
+	/** @var IXffTrustProvider */
27
+	private $xffTrustProvider;
28
+	/** @var Ban[][] */
29
+	private $banCache = [];
30
+
31
+	private ?ISecurityManager $securityManager;
32
+
33
+	public function __construct(
34
+		PdoDatabase $database,
35
+		IXffTrustProvider $xffTrustProvider,
36
+		?ISecurityManager $securityManager
37
+	) {
38
+		$this->database = $database;
39
+		$this->xffTrustProvider = $xffTrustProvider;
40
+		$this->securityManager = $securityManager;
41
+	}
42
+
43
+	public function isBlockBanned(Request $request): bool
44
+	{
45
+		if (!isset($this->banCache[$request->getId()])) {
46
+			$this->banCache[$request->getId()] = $this->getBansForRequestFromDatabase($request);
47
+		}
48
+
49
+		foreach ($this->banCache[$request->getId()] as $ban) {
50
+			if ($ban->getAction() === Ban::ACTION_BLOCK) {
51
+				return true;
52
+			}
53
+		}
54
+
55
+		return false;
56
+	}
57
+
58
+	/**
59
+	 * @param Request $request
60
+	 *
61
+	 * @return Ban[]
62
+	 */
63
+	public function getBans(Request $request): array
64
+	{
65
+		if (!isset($this->banCache[$request->getId()])) {
66
+			$this->banCache[$request->getId()] = $this->getBansForRequestFromDatabase($request);
67
+		}
68
+
69
+		return $this->banCache[$request->getId()];
70
+	}
71
+
72
+	public function getBansByTarget(
73
+		?string $name,
74
+		?string $email,
75
+		?string $ip,
76
+		?int $mask,
77
+		?string $useragent,
78
+		int $domain
79
+	) {
80
+		/** @noinspection SqlConstantCondition */
81
+		$query = <<<SQL
82 82
 SELECT * FROM ban 
83 83
 WHERE 1 = 1
84 84
   AND ((name IS NULL AND :nname IS NULL) OR name = :name)
@@ -91,85 +91,85 @@  discard block
 block discarded – undo
91 91
   AND (domain IS NULL OR domain = :domain);
92 92
 SQL;
93 93
 
94
-        $statement = $this->database->prepare($query);
95
-        $statement->execute([
96
-            ':name'       => $name,
97
-            ':nname'      => $name,
98
-            ':email'      => $email,
99
-            ':nemail'     => $email,
100
-            ':ip'         => $ip,
101
-            ':nip'        => $ip,
102
-            ':ipmask'     => $mask,
103
-            ':nipmask'    => $mask,
104
-            ':useragent'  => $useragent,
105
-            ':nuseragent' => $useragent,
106
-            ':domain'     => $domain,
107
-        ]);
108
-
109
-        $result = array();
110
-
111
-        /** @var Ban $v */
112
-        foreach ($statement->fetchAll(PDO::FETCH_CLASS, Ban::class) as $v) {
113
-            $v->setDatabase($this->database);
114
-            $result[] = $v;
115
-        }
116
-
117
-        return $result;
118
-    }
119
-
120
-    public function isActive(Ban $ban): bool
121
-    {
122
-        if (!$ban->isActive()) {
123
-            return false;
124
-        }
125
-
126
-        if ($ban->getDuration() !== null && $ban->getDuration() < time()) {
127
-            return false;
128
-        }
129
-
130
-        return true;
131
-    }
132
-
133
-    public function canUnban(Ban $ban): bool
134
-    {
135
-        if ($this->securityManager === null) {
136
-            return false;
137
-        }
138
-
139
-        if (!$this->isActive($ban)) {
140
-            return false;
141
-        }
142
-
143
-        $user = User::getCurrent($this->database);
144
-
145
-        $allowed = true;
146
-        $allowed = $allowed && ($ban->getName() === null || $this->securityManager->allows('BanType', 'name', $user) === ISecurityManager::ALLOWED);
147
-        $allowed = $allowed && ($ban->getEmail() === null || $this->securityManager->allows('BanType', 'email', $user) === ISecurityManager::ALLOWED);
148
-        $allowed = $allowed && ($ban->getIp() === null || $this->securityManager->allows('BanType', 'ip', $user) === ISecurityManager::ALLOWED);
149
-        $allowed = $allowed && ($ban->getUseragent() === null || $this->securityManager->allows('BanType', 'useragent', $user) === ISecurityManager::ALLOWED);
150
-
151
-        if ($ban->getDomain() === null) {
152
-            $allowed &= $this->securityManager->allows('BanType', 'global', $user) === ISecurityManager::ALLOWED;
153
-        }
154
-        else {
155
-            $currentDomain = Domain::getCurrent($this->database);
156
-            $allowed &= $currentDomain->getId() === $ban->getDomain();
157
-        }
158
-
159
-        $allowed = $allowed && $this->securityManager->allows('BanVisibility', $ban->getVisibility(), $user) === ISecurityManager::ALLOWED;
160
-
161
-        return $allowed;
162
-    }
163
-
164
-    /**
165
-     * @param Request $request
166
-     *
167
-     * @return Ban[]
168
-     */
169
-    private function getBansForRequestFromDatabase(Request $request): array
170
-    {
171
-        /** @noinspection SqlConstantCondition - included for clarity of code */
172
-        $query = <<<SQL
94
+		$statement = $this->database->prepare($query);
95
+		$statement->execute([
96
+			':name'       => $name,
97
+			':nname'      => $name,
98
+			':email'      => $email,
99
+			':nemail'     => $email,
100
+			':ip'         => $ip,
101
+			':nip'        => $ip,
102
+			':ipmask'     => $mask,
103
+			':nipmask'    => $mask,
104
+			':useragent'  => $useragent,
105
+			':nuseragent' => $useragent,
106
+			':domain'     => $domain,
107
+		]);
108
+
109
+		$result = array();
110
+
111
+		/** @var Ban $v */
112
+		foreach ($statement->fetchAll(PDO::FETCH_CLASS, Ban::class) as $v) {
113
+			$v->setDatabase($this->database);
114
+			$result[] = $v;
115
+		}
116
+
117
+		return $result;
118
+	}
119
+
120
+	public function isActive(Ban $ban): bool
121
+	{
122
+		if (!$ban->isActive()) {
123
+			return false;
124
+		}
125
+
126
+		if ($ban->getDuration() !== null && $ban->getDuration() < time()) {
127
+			return false;
128
+		}
129
+
130
+		return true;
131
+	}
132
+
133
+	public function canUnban(Ban $ban): bool
134
+	{
135
+		if ($this->securityManager === null) {
136
+			return false;
137
+		}
138
+
139
+		if (!$this->isActive($ban)) {
140
+			return false;
141
+		}
142
+
143
+		$user = User::getCurrent($this->database);
144
+
145
+		$allowed = true;
146
+		$allowed = $allowed && ($ban->getName() === null || $this->securityManager->allows('BanType', 'name', $user) === ISecurityManager::ALLOWED);
147
+		$allowed = $allowed && ($ban->getEmail() === null || $this->securityManager->allows('BanType', 'email', $user) === ISecurityManager::ALLOWED);
148
+		$allowed = $allowed && ($ban->getIp() === null || $this->securityManager->allows('BanType', 'ip', $user) === ISecurityManager::ALLOWED);
149
+		$allowed = $allowed && ($ban->getUseragent() === null || $this->securityManager->allows('BanType', 'useragent', $user) === ISecurityManager::ALLOWED);
150
+
151
+		if ($ban->getDomain() === null) {
152
+			$allowed &= $this->securityManager->allows('BanType', 'global', $user) === ISecurityManager::ALLOWED;
153
+		}
154
+		else {
155
+			$currentDomain = Domain::getCurrent($this->database);
156
+			$allowed &= $currentDomain->getId() === $ban->getDomain();
157
+		}
158
+
159
+		$allowed = $allowed && $this->securityManager->allows('BanVisibility', $ban->getVisibility(), $user) === ISecurityManager::ALLOWED;
160
+
161
+		return $allowed;
162
+	}
163
+
164
+	/**
165
+	 * @param Request $request
166
+	 *
167
+	 * @return Ban[]
168
+	 */
169
+	private function getBansForRequestFromDatabase(Request $request): array
170
+	{
171
+		/** @noinspection SqlConstantCondition - included for clarity of code */
172
+		$query = <<<SQL
173 173
 SELECT b.* FROM ban b
174 174
 LEFT JOIN netmask n ON 1 = 1
175 175
     AND n.cidr = b.ipmask
@@ -191,28 +191,28 @@  discard block
 block discarded – undo
191 191
     AND (b.domain IS NULL OR b.domain = :domain)
192 192
 SQL;
193 193
 
194
-        $statement = $this->database->prepare($query);
195
-        $trustedIp = $this->xffTrustProvider->getTrustedClientIp($request->getIp(), $request->getForwardedIp());
196
-
197
-        $statement->execute([
198
-            ':name'      => $request->getName(),
199
-            ':email'     => $request->getEmail(),
200
-            ':useragent' => $request->getUserAgent(),
201
-            ':domain'    => $request->getDomain(),
202
-            ':ip4'       => $trustedIp,
203
-            ':ip6h'      => $trustedIp,
204
-            ':ip6l'      => $trustedIp,
205
-        ]);
206
-
207
-        /** @var Ban[] $result */
208
-        $result = [];
209
-
210
-        /** @var Ban $v */
211
-        foreach ($statement->fetchAll(PDO::FETCH_CLASS, Ban::class) as $v) {
212
-            $v->setDatabase($this->database);
213
-            $result[] = $v;
214
-        }
215
-
216
-        return $result;
217
-    }
194
+		$statement = $this->database->prepare($query);
195
+		$trustedIp = $this->xffTrustProvider->getTrustedClientIp($request->getIp(), $request->getForwardedIp());
196
+
197
+		$statement->execute([
198
+			':name'      => $request->getName(),
199
+			':email'     => $request->getEmail(),
200
+			':useragent' => $request->getUserAgent(),
201
+			':domain'    => $request->getDomain(),
202
+			':ip4'       => $trustedIp,
203
+			':ip6h'      => $trustedIp,
204
+			':ip6l'      => $trustedIp,
205
+		]);
206
+
207
+		/** @var Ban[] $result */
208
+		$result = [];
209
+
210
+		/** @var Ban $v */
211
+		foreach ($statement->fetchAll(PDO::FETCH_CLASS, Ban::class) as $v) {
212
+			$v->setDatabase($this->database);
213
+			$result[] = $v;
214
+		}
215
+
216
+		return $result;
217
+	}
218 218
 }
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -150,8 +150,7 @@
 block discarded – undo
150 150
 
151 151
         if ($ban->getDomain() === null) {
152 152
             $allowed &= $this->securityManager->allows('BanType', 'global', $user) === ISecurityManager::ALLOWED;
153
-        }
154
-        else {
153
+        } else {
155 154
             $currentDomain = Domain::getCurrent($this->database);
156 155
             $allowed &= $currentDomain->getId() === $ban->getDomain();
157 156
         }
Please login to merge, or discard this patch.
includes/Helpers/LogHelper.php 2 patches
Indentation   +523 added lines, -523 removed lines patch added patch discarded remove patch
@@ -31,543 +31,543 @@
 block discarded – undo
31 31
 
32 32
 class LogHelper
33 33
 {
34
-    /**
35
-     * @param int             $requestId
36
-     *
37
-     * @return DataObject[]
38
-     */
39
-    public static function getRequestLogsWithComments(
40
-        $requestId,
41
-        PdoDatabase $db,
42
-        ISecurityManager $securityManager
43
-    ): array {
44
-        // FIXME: domains
45
-        $logs = LogSearchHelper::get($db, 1)->byObjectType('Request')->byObjectId($requestId)->fetch();
46
-
47
-        $currentUser = User::getCurrent($db);
48
-        $showRestrictedComments = $securityManager->allows('RequestData', 'seeRestrictedComments', $currentUser) === ISecurityManager::ALLOWED;
49
-        $showCheckuserComments = $securityManager->allows('RequestData', 'seeCheckuserComments', $currentUser) === ISecurityManager::ALLOWED;
50
-
51
-        $comments = Comment::getForRequest($requestId, $db, $showRestrictedComments, $showCheckuserComments, $currentUser->getId());
52
-
53
-        $items = array_merge($logs, $comments);
54
-
55
-        $sortKey = function(DataObject $item): int {
56
-            if ($item instanceof Log) {
57
-                return $item->getTimestamp()->getTimestamp();
58
-            }
59
-
60
-            if ($item instanceof Comment) {
61
-                return $item->getTime()->getTimestamp();
62
-            }
63
-
64
-            return 0;
65
-        };
66
-
67
-        do {
68
-            $flag = false;
69
-
70
-            $loopLimit = (count($items) - 1);
71
-            for ($i = 0; $i < $loopLimit; $i++) {
72
-                // are these two items out of order?
73
-                if ($sortKey($items[$i]) > $sortKey($items[$i + 1])) {
74
-                    // swap them
75
-                    $swap = $items[$i];
76
-                    $items[$i] = $items[$i + 1];
77
-                    $items[$i + 1] = $swap;
78
-
79
-                    // set a flag to say we've modified the array this time around
80
-                    $flag = true;
81
-                }
82
-            }
83
-        }
84
-        while ($flag);
85
-
86
-        return $items;
87
-    }
88
-
89
-    public static function getLogDescription(Log $entry): string
90
-    {
91
-        $text = "Deferred to ";
92
-        if (substr($entry->getAction(), 0, strlen($text)) == $text) {
93
-            // Deferred to a different queue
94
-            // This is exactly what we want to display.
95
-            return $entry->getAction();
96
-        }
97
-
98
-        $text = "Closed custom-n";
99
-        if ($entry->getAction() == $text) {
100
-            // Custom-closed
101
-            return "closed (custom reason - account not created)";
102
-        }
103
-
104
-        $text = "Closed custom-y";
105
-        if ($entry->getAction() == $text) {
106
-            // Custom-closed
107
-            return "closed (custom reason - account created)";
108
-        }
109
-
110
-        $text = "Closed 0";
111
-        if ($entry->getAction() == $text) {
112
-            // Dropped the request - short-circuit the lookup
113
-            return "dropped request";
114
-        }
115
-
116
-        $text = "Closed ";
117
-        if (substr($entry->getAction(), 0, strlen($text)) == $text) {
118
-            // Closed with a reason - do a lookup here.
119
-            $id = substr($entry->getAction(), strlen($text));
120
-            /** @var EmailTemplate|false $template */
121
-            $template = EmailTemplate::getById((int)$id, $entry->getDatabase());
122
-
123
-            if ($template !== false) {
124
-                return 'closed (' . $template->getName() . ')';
125
-            }
126
-        }
127
-
128
-        // Fall back to the basic stuff
129
-        $lookup = array(
130
-            'Reserved'            => 'reserved',
131
-            'Email Confirmed'     => 'email-confirmed',
132
-            'Manually Confirmed'  => 'manually confirmed the request',
133
-            'Unreserved'          => 'unreserved',
134
-            'Approved'            => 'approved',
135
-            'DeactivatedUser'     => 'deactivated user',
136
-            'RoleChange'          => 'changed roles',
137
-            'GlobalRoleChange'    => 'changed global roles',
138
-            'RequestedReactivation' => 'requested reactivation',
139
-            'Banned'              => 'banned',
140
-            'Edited'              => 'edited interface message',
141
-            'EditComment-c'       => 'edited a comment',
142
-            'EditComment-r'       => 'edited a comment',
143
-            'FlaggedComment'      => 'flagged a comment',
144
-            'UnflaggedComment'    => 'unflagged a comment',
145
-            'Unbanned'            => 'unbanned',
146
-            'BanReplaced'         => 'replaced ban',
147
-            'Promoted'            => 'promoted to tool admin',
148
-            'BreakReserve'        => 'forcibly broke the reservation',
149
-            'Prefchange'          => 'changed user preferences',
150
-            'Renamed'             => 'renamed',
151
-            'Demoted'             => 'demoted from tool admin',
152
-            'ReceiveReserved'     => 'received the reservation',
153
-            'SendReserved'        => 'sent the reservation',
154
-            'EditedEmail'         => 'edited email',
155
-            'DeletedTemplate'     => 'deleted template',
156
-            'EditedTemplate'      => 'edited template',
157
-            'CreatedEmail'        => 'created email',
158
-            'CreatedTemplate'     => 'created template',
159
-            'SentMail'            => 'sent an email to the requester',
160
-            'Registered'          => 'registered a tool account',
161
-            'JobIssue'            => 'ran a background job unsuccessfully',
162
-            'JobCompleted'        => 'completed a background job',
163
-            'JobAcknowledged'     => 'acknowledged a job failure',
164
-            'JobRequeued'         => 'requeued a job for re-execution',
165
-            'JobCancelled'        => 'cancelled execution of a job',
166
-            'EnqueuedJobQueue'    => 'scheduled for creation',
167
-            'Hospitalised'        => 'sent to the hospital',
168
-            'QueueCreated'        => 'created a request queue',
169
-            'QueueEdited'         => 'edited a request queue',
170
-            'DomainCreated'       => 'created a domain',
171
-            'DomainEdited'        => 'edited a domain',
172
-            'RequestFormCreated'  => 'created a request form',
173
-            'RequestFormEdited'   => 'edited a request form',
174
-        );
175
-
176
-        if (array_key_exists($entry->getAction(), $lookup)) {
177
-            return $lookup[$entry->getAction()];
178
-        }
179
-
180
-        // OK, I don't know what this is. Fall back to something sane.
181
-        return "performed an unknown action ({$entry->getAction()})";
182
-    }
183
-
184
-    public static function getLogActions(PdoDatabase $database): array
185
-    {
186
-        $lookup = array(
187
-            "Requests" => [
188
-                'Reserved'            => 'reserved',
189
-                'Email Confirmed'     => 'email-confirmed',
190
-                'Manually Confirmed'  => 'manually confirmed',
191
-                'Unreserved'          => 'unreserved',
192
-                'EditComment-c'       => 'edited a comment (by comment ID)',
193
-                'EditComment-r'       => 'edited a comment (by request)',
194
-                'FlaggedComment'      => 'flagged a comment',
195
-                'UnflaggedComment'    => 'unflagged a comment',
196
-                'BreakReserve'        => 'forcibly broke the reservation',
197
-                'ReceiveReserved'     => 'received the reservation',
198
-                'SendReserved'        => 'sent the reservation',
199
-                'SentMail'            => 'sent an email to the requester',
200
-                'Closed 0'            => 'dropped request',
201
-                'Closed custom-y'     => 'closed (custom reason - account created)',
202
-                'Closed custom-n'     => 'closed (custom reason - account not created)',
203
-            ],
204
-            'Users' => [
205
-                'Approved'            => 'approved',
206
-                'DeactivatedUser'     => 'deactivated user',
207
-                'RoleChange'          => 'changed roles',
208
-                'GlobalRoleChange'    => 'changed global roles',
209
-                'Prefchange'          => 'changed user preferences',
210
-                'Renamed'             => 'renamed',
211
-                'Promoted'            => 'promoted to tool admin',
212
-                'Demoted'             => 'demoted from tool admin',
213
-                'Registered'          => 'registered a tool account',
214
-                'RequestedReactivation' => 'requested reactivation',
215
-            ],
216
-            "Bans" => [
217
-                'Banned'              => 'banned',
218
-                'Unbanned'            => 'unbanned',
219
-                'BanReplaced'         => 'replaced ban',
220
-            ],
221
-            "Site notice" => [
222
-                'Edited'              => 'edited interface message',
223
-            ],
224
-            "Email close templates" => [
225
-                'EditedEmail'         => 'edited email',
226
-                'CreatedEmail'        => 'created email',
227
-            ],
228
-            "Welcome templates" => [
229
-                'DeletedTemplate'     => 'deleted template',
230
-                'EditedTemplate'      => 'edited template',
231
-                'CreatedTemplate'     => 'created template',
232
-            ],
233
-            "Job queue" => [
234
-                'JobIssue'            => 'ran a background job unsuccessfully',
235
-                'JobCompleted'        => 'completed a background job',
236
-                'JobAcknowledged'     => 'acknowledged a job failure',
237
-                'JobRequeued'         => 'requeued a job for re-execution',
238
-                'JobCancelled'        => 'cancelled execution of a job',
239
-                'EnqueuedJobQueue'    => 'scheduled for creation',
240
-                'Hospitalised'        => 'sent to the hospital',
241
-            ],
242
-            "Request queues" => [
243
-                'QueueCreated'        => 'created a request queue',
244
-                'QueueEdited'         => 'edited a request queue',
245
-            ],
246
-            "Domains" => [
247
-                'DomainCreated'       => 'created a domain',
248
-                'DomainEdited'        => 'edited a domain',
249
-            ],
250
-            "Request forms" => [
251
-                'RequestFormCreated'        => 'created a request form',
252
-                'RequestFormEdited'         => 'edited a request form',
253
-            ],
254
-        );
255
-
256
-        $databaseDrivenLogKeys = $database->query(<<<SQL
34
+	/**
35
+	 * @param int             $requestId
36
+	 *
37
+	 * @return DataObject[]
38
+	 */
39
+	public static function getRequestLogsWithComments(
40
+		$requestId,
41
+		PdoDatabase $db,
42
+		ISecurityManager $securityManager
43
+	): array {
44
+		// FIXME: domains
45
+		$logs = LogSearchHelper::get($db, 1)->byObjectType('Request')->byObjectId($requestId)->fetch();
46
+
47
+		$currentUser = User::getCurrent($db);
48
+		$showRestrictedComments = $securityManager->allows('RequestData', 'seeRestrictedComments', $currentUser) === ISecurityManager::ALLOWED;
49
+		$showCheckuserComments = $securityManager->allows('RequestData', 'seeCheckuserComments', $currentUser) === ISecurityManager::ALLOWED;
50
+
51
+		$comments = Comment::getForRequest($requestId, $db, $showRestrictedComments, $showCheckuserComments, $currentUser->getId());
52
+
53
+		$items = array_merge($logs, $comments);
54
+
55
+		$sortKey = function(DataObject $item): int {
56
+			if ($item instanceof Log) {
57
+				return $item->getTimestamp()->getTimestamp();
58
+			}
59
+
60
+			if ($item instanceof Comment) {
61
+				return $item->getTime()->getTimestamp();
62
+			}
63
+
64
+			return 0;
65
+		};
66
+
67
+		do {
68
+			$flag = false;
69
+
70
+			$loopLimit = (count($items) - 1);
71
+			for ($i = 0; $i < $loopLimit; $i++) {
72
+				// are these two items out of order?
73
+				if ($sortKey($items[$i]) > $sortKey($items[$i + 1])) {
74
+					// swap them
75
+					$swap = $items[$i];
76
+					$items[$i] = $items[$i + 1];
77
+					$items[$i + 1] = $swap;
78
+
79
+					// set a flag to say we've modified the array this time around
80
+					$flag = true;
81
+				}
82
+			}
83
+		}
84
+		while ($flag);
85
+
86
+		return $items;
87
+	}
88
+
89
+	public static function getLogDescription(Log $entry): string
90
+	{
91
+		$text = "Deferred to ";
92
+		if (substr($entry->getAction(), 0, strlen($text)) == $text) {
93
+			// Deferred to a different queue
94
+			// This is exactly what we want to display.
95
+			return $entry->getAction();
96
+		}
97
+
98
+		$text = "Closed custom-n";
99
+		if ($entry->getAction() == $text) {
100
+			// Custom-closed
101
+			return "closed (custom reason - account not created)";
102
+		}
103
+
104
+		$text = "Closed custom-y";
105
+		if ($entry->getAction() == $text) {
106
+			// Custom-closed
107
+			return "closed (custom reason - account created)";
108
+		}
109
+
110
+		$text = "Closed 0";
111
+		if ($entry->getAction() == $text) {
112
+			// Dropped the request - short-circuit the lookup
113
+			return "dropped request";
114
+		}
115
+
116
+		$text = "Closed ";
117
+		if (substr($entry->getAction(), 0, strlen($text)) == $text) {
118
+			// Closed with a reason - do a lookup here.
119
+			$id = substr($entry->getAction(), strlen($text));
120
+			/** @var EmailTemplate|false $template */
121
+			$template = EmailTemplate::getById((int)$id, $entry->getDatabase());
122
+
123
+			if ($template !== false) {
124
+				return 'closed (' . $template->getName() . ')';
125
+			}
126
+		}
127
+
128
+		// Fall back to the basic stuff
129
+		$lookup = array(
130
+			'Reserved'            => 'reserved',
131
+			'Email Confirmed'     => 'email-confirmed',
132
+			'Manually Confirmed'  => 'manually confirmed the request',
133
+			'Unreserved'          => 'unreserved',
134
+			'Approved'            => 'approved',
135
+			'DeactivatedUser'     => 'deactivated user',
136
+			'RoleChange'          => 'changed roles',
137
+			'GlobalRoleChange'    => 'changed global roles',
138
+			'RequestedReactivation' => 'requested reactivation',
139
+			'Banned'              => 'banned',
140
+			'Edited'              => 'edited interface message',
141
+			'EditComment-c'       => 'edited a comment',
142
+			'EditComment-r'       => 'edited a comment',
143
+			'FlaggedComment'      => 'flagged a comment',
144
+			'UnflaggedComment'    => 'unflagged a comment',
145
+			'Unbanned'            => 'unbanned',
146
+			'BanReplaced'         => 'replaced ban',
147
+			'Promoted'            => 'promoted to tool admin',
148
+			'BreakReserve'        => 'forcibly broke the reservation',
149
+			'Prefchange'          => 'changed user preferences',
150
+			'Renamed'             => 'renamed',
151
+			'Demoted'             => 'demoted from tool admin',
152
+			'ReceiveReserved'     => 'received the reservation',
153
+			'SendReserved'        => 'sent the reservation',
154
+			'EditedEmail'         => 'edited email',
155
+			'DeletedTemplate'     => 'deleted template',
156
+			'EditedTemplate'      => 'edited template',
157
+			'CreatedEmail'        => 'created email',
158
+			'CreatedTemplate'     => 'created template',
159
+			'SentMail'            => 'sent an email to the requester',
160
+			'Registered'          => 'registered a tool account',
161
+			'JobIssue'            => 'ran a background job unsuccessfully',
162
+			'JobCompleted'        => 'completed a background job',
163
+			'JobAcknowledged'     => 'acknowledged a job failure',
164
+			'JobRequeued'         => 'requeued a job for re-execution',
165
+			'JobCancelled'        => 'cancelled execution of a job',
166
+			'EnqueuedJobQueue'    => 'scheduled for creation',
167
+			'Hospitalised'        => 'sent to the hospital',
168
+			'QueueCreated'        => 'created a request queue',
169
+			'QueueEdited'         => 'edited a request queue',
170
+			'DomainCreated'       => 'created a domain',
171
+			'DomainEdited'        => 'edited a domain',
172
+			'RequestFormCreated'  => 'created a request form',
173
+			'RequestFormEdited'   => 'edited a request form',
174
+		);
175
+
176
+		if (array_key_exists($entry->getAction(), $lookup)) {
177
+			return $lookup[$entry->getAction()];
178
+		}
179
+
180
+		// OK, I don't know what this is. Fall back to something sane.
181
+		return "performed an unknown action ({$entry->getAction()})";
182
+	}
183
+
184
+	public static function getLogActions(PdoDatabase $database): array
185
+	{
186
+		$lookup = array(
187
+			"Requests" => [
188
+				'Reserved'            => 'reserved',
189
+				'Email Confirmed'     => 'email-confirmed',
190
+				'Manually Confirmed'  => 'manually confirmed',
191
+				'Unreserved'          => 'unreserved',
192
+				'EditComment-c'       => 'edited a comment (by comment ID)',
193
+				'EditComment-r'       => 'edited a comment (by request)',
194
+				'FlaggedComment'      => 'flagged a comment',
195
+				'UnflaggedComment'    => 'unflagged a comment',
196
+				'BreakReserve'        => 'forcibly broke the reservation',
197
+				'ReceiveReserved'     => 'received the reservation',
198
+				'SendReserved'        => 'sent the reservation',
199
+				'SentMail'            => 'sent an email to the requester',
200
+				'Closed 0'            => 'dropped request',
201
+				'Closed custom-y'     => 'closed (custom reason - account created)',
202
+				'Closed custom-n'     => 'closed (custom reason - account not created)',
203
+			],
204
+			'Users' => [
205
+				'Approved'            => 'approved',
206
+				'DeactivatedUser'     => 'deactivated user',
207
+				'RoleChange'          => 'changed roles',
208
+				'GlobalRoleChange'    => 'changed global roles',
209
+				'Prefchange'          => 'changed user preferences',
210
+				'Renamed'             => 'renamed',
211
+				'Promoted'            => 'promoted to tool admin',
212
+				'Demoted'             => 'demoted from tool admin',
213
+				'Registered'          => 'registered a tool account',
214
+				'RequestedReactivation' => 'requested reactivation',
215
+			],
216
+			"Bans" => [
217
+				'Banned'              => 'banned',
218
+				'Unbanned'            => 'unbanned',
219
+				'BanReplaced'         => 'replaced ban',
220
+			],
221
+			"Site notice" => [
222
+				'Edited'              => 'edited interface message',
223
+			],
224
+			"Email close templates" => [
225
+				'EditedEmail'         => 'edited email',
226
+				'CreatedEmail'        => 'created email',
227
+			],
228
+			"Welcome templates" => [
229
+				'DeletedTemplate'     => 'deleted template',
230
+				'EditedTemplate'      => 'edited template',
231
+				'CreatedTemplate'     => 'created template',
232
+			],
233
+			"Job queue" => [
234
+				'JobIssue'            => 'ran a background job unsuccessfully',
235
+				'JobCompleted'        => 'completed a background job',
236
+				'JobAcknowledged'     => 'acknowledged a job failure',
237
+				'JobRequeued'         => 'requeued a job for re-execution',
238
+				'JobCancelled'        => 'cancelled execution of a job',
239
+				'EnqueuedJobQueue'    => 'scheduled for creation',
240
+				'Hospitalised'        => 'sent to the hospital',
241
+			],
242
+			"Request queues" => [
243
+				'QueueCreated'        => 'created a request queue',
244
+				'QueueEdited'         => 'edited a request queue',
245
+			],
246
+			"Domains" => [
247
+				'DomainCreated'       => 'created a domain',
248
+				'DomainEdited'        => 'edited a domain',
249
+			],
250
+			"Request forms" => [
251
+				'RequestFormCreated'        => 'created a request form',
252
+				'RequestFormEdited'         => 'edited a request form',
253
+			],
254
+		);
255
+
256
+		$databaseDrivenLogKeys = $database->query(<<<SQL
257 257
 SELECT CONCAT('Closed ', id) AS k, CONCAT('closed (',name,')') AS v FROM emailtemplate
258 258
 UNION ALL
259 259
 SELECT CONCAT('Deferred to ', logname) AS k, CONCAT('deferred to ', displayname) AS v FROM requestqueue;
260 260
 SQL
261
-        );
262
-        foreach ($databaseDrivenLogKeys->fetchAll(PDO::FETCH_ASSOC) as $row) {
263
-            $lookup["Requests"][$row['k']] = $row['v'];
264
-        }
265
-
266
-        return $lookup;
267
-    }
268
-
269
-    public static function getObjectTypes(): array
270
-    {
271
-        return array(
272
-            'Ban'             => 'Ban',
273
-            'Comment'         => 'Comment',
274
-            'EmailTemplate'   => 'Email template',
275
-            'JobQueue'        => 'Job queue item',
276
-            'Request'         => 'Request',
277
-            'SiteNotice'      => 'Site notice',
278
-            'User'            => 'User',
279
-            'WelcomeTemplate' => 'Welcome template',
280
-            'RequestQueue'    => 'Request queue',
281
-            'Domain'          => 'Domain',
282
-            'RequestForm'     => 'Request form'
283
-        );
284
-    }
285
-
286
-    /**
287
-     * This returns an HTML representation of the object
288
-     *
289
-     * @param int               $objectId
290
-     * @param string            $objectType
291
-     *
292
-     * @category Security-Critical
293
-     */
294
-    private static function getObjectDescription(
295
-        $objectId,
296
-        $objectType,
297
-        PdoDatabase $database,
298
-        SiteConfiguration $configuration
299
-    ): ?string {
300
-        if ($objectType == '') {
301
-            return null;
302
-        }
303
-
304
-        $baseurl = $configuration->getBaseUrl();
305
-
306
-        switch ($objectType) {
307
-            case 'Ban':
308
-                /** @var Ban $ban */
309
-                $ban = Ban::getById($objectId, $database);
310
-
311
-                if ($ban === false) {
312
-                    return 'Ban #' . $objectId;
313
-                }
314
-
315
-                return <<<HTML
261
+		);
262
+		foreach ($databaseDrivenLogKeys->fetchAll(PDO::FETCH_ASSOC) as $row) {
263
+			$lookup["Requests"][$row['k']] = $row['v'];
264
+		}
265
+
266
+		return $lookup;
267
+	}
268
+
269
+	public static function getObjectTypes(): array
270
+	{
271
+		return array(
272
+			'Ban'             => 'Ban',
273
+			'Comment'         => 'Comment',
274
+			'EmailTemplate'   => 'Email template',
275
+			'JobQueue'        => 'Job queue item',
276
+			'Request'         => 'Request',
277
+			'SiteNotice'      => 'Site notice',
278
+			'User'            => 'User',
279
+			'WelcomeTemplate' => 'Welcome template',
280
+			'RequestQueue'    => 'Request queue',
281
+			'Domain'          => 'Domain',
282
+			'RequestForm'     => 'Request form'
283
+		);
284
+	}
285
+
286
+	/**
287
+	 * This returns an HTML representation of the object
288
+	 *
289
+	 * @param int               $objectId
290
+	 * @param string            $objectType
291
+	 *
292
+	 * @category Security-Critical
293
+	 */
294
+	private static function getObjectDescription(
295
+		$objectId,
296
+		$objectType,
297
+		PdoDatabase $database,
298
+		SiteConfiguration $configuration
299
+	): ?string {
300
+		if ($objectType == '') {
301
+			return null;
302
+		}
303
+
304
+		$baseurl = $configuration->getBaseUrl();
305
+
306
+		switch ($objectType) {
307
+			case 'Ban':
308
+				/** @var Ban $ban */
309
+				$ban = Ban::getById($objectId, $database);
310
+
311
+				if ($ban === false) {
312
+					return 'Ban #' . $objectId;
313
+				}
314
+
315
+				return <<<HTML
316 316
 <a href="{$baseurl}/internal.php/bans/show?id={$objectId}">Ban #{$objectId}</a>
317 317
 HTML;
318
-            case 'EmailTemplate':
319
-                /** @var EmailTemplate $emailTemplate */
320
-                $emailTemplate = EmailTemplate::getById($objectId, $database);
318
+			case 'EmailTemplate':
319
+				/** @var EmailTemplate $emailTemplate */
320
+				$emailTemplate = EmailTemplate::getById($objectId, $database);
321 321
 
322
-                if ($emailTemplate === false) {
323
-                    return 'Email Template #' . $objectId;
324
-                }
322
+				if ($emailTemplate === false) {
323
+					return 'Email Template #' . $objectId;
324
+				}
325 325
 
326
-                $name = htmlentities($emailTemplate->getName(), ENT_COMPAT, 'UTF-8');
326
+				$name = htmlentities($emailTemplate->getName(), ENT_COMPAT, 'UTF-8');
327 327
 
328
-                return <<<HTML
328
+				return <<<HTML
329 329
 <a href="{$baseurl}/internal.php/emailManagement/view?id={$objectId}">Email Template #{$objectId} ({$name})</a>
330 330
 HTML;
331
-            case 'SiteNotice':
332
-                return "<a href=\"{$baseurl}/internal.php/siteNotice\">the site notice</a>";
333
-            case 'Request':
334
-                /** @var Request $request */
335
-                $request = Request::getById($objectId, $database);
331
+			case 'SiteNotice':
332
+				return "<a href=\"{$baseurl}/internal.php/siteNotice\">the site notice</a>";
333
+			case 'Request':
334
+				/** @var Request $request */
335
+				$request = Request::getById($objectId, $database);
336 336
 
337
-                if ($request === false) {
338
-                    return 'Request #' . $objectId;
339
-                }
337
+				if ($request === false) {
338
+					return 'Request #' . $objectId;
339
+				}
340 340
 
341
-                $name = htmlentities($request->getName(), ENT_COMPAT, 'UTF-8');
341
+				$name = htmlentities($request->getName(), ENT_COMPAT, 'UTF-8');
342 342
 
343
-                return <<<HTML
343
+				return <<<HTML
344 344
 <a href="{$baseurl}/internal.php/viewRequest?id={$objectId}">Request #{$objectId} ({$name})</a>
345 345
 HTML;
346
-            case 'User':
347
-                /** @var User $user */
348
-                $user = User::getById($objectId, $database);
349
-
350
-                // Some users were merged out of existence
351
-                if ($user === false) {
352
-                    return 'User #' . $objectId;
353
-                }
354
-
355
-                $username = htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8');
356
-
357
-                return "<a href=\"{$baseurl}/internal.php/statistics/users/detail?user={$objectId}\">{$username}</a>";
358
-            case 'WelcomeTemplate':
359
-                /** @var WelcomeTemplate $welcomeTemplate */
360
-                $welcomeTemplate = WelcomeTemplate::getById($objectId, $database);
361
-
362
-                // some old templates have been completely deleted and lost to the depths of time.
363
-                if ($welcomeTemplate === false) {
364
-                    return "Welcome template #{$objectId}";
365
-                }
366
-                else {
367
-                    $userCode = htmlentities($welcomeTemplate->getUserCode(), ENT_COMPAT, 'UTF-8');
368
-
369
-                    return "<a href=\"{$baseurl}/internal.php/welcomeTemplates/view?template={$objectId}\">{$userCode}</a>";
370
-                }
371
-            case 'JobQueue':
372
-                /** @var JobQueue $job */
373
-                $job = JobQueue::getById($objectId, $database);
374
-
375
-                $taskDescriptions = JobQueue::getTaskDescriptions();
376
-
377
-                if ($job === false) {
378
-                    return 'Job Queue Task #' . $objectId;
379
-                }
380
-
381
-                $task = $job->getTask();
382
-                if (isset($taskDescriptions[$task])) {
383
-                    $description = $taskDescriptions[$task];
384
-                }
385
-                else {
386
-                    $description = 'Unknown task';
387
-                }
388
-
389
-                return "<a href=\"{$baseurl}/internal.php/jobQueue/view?id={$objectId}\">Job #{$job->getId()} ({$description})</a>";
390
-            case 'RequestQueue':
391
-                /** @var RequestQueue $queue */
392
-                $queue = RequestQueue::getById($objectId, $database);
393
-
394
-                if ($queue === false) {
395
-                    return "Request Queue #{$objectId}";
396
-                }
397
-
398
-                $queueHeader = htmlentities($queue->getHeader(), ENT_COMPAT, 'UTF-8');
399
-
400
-                return "<a href=\"{$baseurl}/internal.php/queueManagement/edit?queue={$objectId}\">{$queueHeader}</a>";
401
-            case 'Domain':
402
-                /** @var Domain $domain */
403
-                $domain = Domain::getById($objectId, $database);
404
-
405
-                if ($domain === false) {
406
-                    return "Domain #{$objectId}";
407
-                }
408
-
409
-                $domainName = htmlentities($domain->getShortName(), ENT_COMPAT, 'UTF-8');
410
-                return "<a href=\"{$baseurl}/internal.php/domainManagement/edit?domain={$objectId}\">{$domainName}</a>";
411
-            case 'RequestForm':
412
-                /** @var RequestForm $queue */
413
-                $queue = RequestForm::getById($objectId, $database);
414
-
415
-                if ($queue === false) {
416
-                    return "Request Form #{$objectId}";
417
-                }
418
-
419
-                $formName = htmlentities($queue->getName(), ENT_COMPAT, 'UTF-8');
420
-
421
-                return "<a href=\"{$baseurl}/internal.php/requestFormManagement/edit?form={$objectId}\">{$formName}</a>";
422
-            case 'Comment':
423
-                /** @var Comment $comment */
424
-                $comment = Comment::getById($objectId, $database);
425
-                /** @var Request $request */
426
-                $request = Request::getById($comment->getRequest(), $database);
427
-                $requestName = htmlentities($request->getName(), ENT_COMPAT, 'UTF-8');
428
-
429
-                return "<a href=\"{$baseurl}/internal.php/editComment?id={$objectId}\">Comment {$objectId}</a> on request <a href=\"{$baseurl}/internal.php/viewRequest?id={$comment->getRequest()}#comment-{$objectId}\">#{$comment->getRequest()} ({$requestName})</a>";
430
-            default:
431
-                return '[' . $objectType . " " . $objectId . ']';
432
-        }
433
-    }
434
-
435
-    /**
436
-     * @param Log[] $logs
437
-     * @throws Exception
438
-     *
439
-     * @returns User[]
440
-     */
441
-    private static function loadUsersFromLogs(array $logs, PdoDatabase $database): array
442
-    {
443
-        $userIds = array();
444
-
445
-        foreach ($logs as $logEntry) {
446
-            if (!$logEntry instanceof Log) {
447
-                // if this happens, we've done something wrong with passing back the log data.
448
-                throw new Exception('Log entry is not an instance of a Log, this should never happen.');
449
-            }
450
-
451
-            $user = $logEntry->getUser();
452
-            if ($user === -1) {
453
-                continue;
454
-            }
455
-
456
-            if (!array_search($user, $userIds)) {
457
-                $userIds[] = $user;
458
-            }
459
-        }
460
-
461
-        $users = UserSearchHelper::get($database)->inIds($userIds)->fetchMap('username');
462
-        $users[-1] = User::getCommunity()->getUsername();
463
-
464
-        return $users;
465
-    }
466
-
467
-    /**
468
-     * @param Log[] $logs
469
-     *
470
-     * @throws Exception
471
-     */
472
-    public static function prepareLogsForTemplate(
473
-        array $logs,
474
-        PdoDatabase $database,
475
-        SiteConfiguration $configuration,
476
-        ISecurityManager $securityManager
477
-    ): array {
478
-        $users = self::loadUsersFromLogs($logs, $database);
479
-        $currentUser = User::getCurrent($database);
480
-
481
-        $allowAccountLogSelf = $securityManager->allows('UserData', 'accountLogSelf', $currentUser) === ISecurityManager::ALLOWED;
482
-        $allowAccountLog = $securityManager->allows('UserData', 'accountLog', $currentUser) === ISecurityManager::ALLOWED;
483
-
484
-        $protectedLogActions = [
485
-            'RequestedReactivation',
486
-            'DeactivatedUser',
487
-        ];
488
-
489
-        $logData = array();
490
-        foreach ($logs as $logEntry) {
491
-            $objectDescription = self::getObjectDescription($logEntry->getObjectId(), $logEntry->getObjectType(),
492
-                $database, $configuration);
493
-
494
-            // initialise to sane default
495
-            $comment = null;
496
-
497
-            switch ($logEntry->getAction()) {
498
-                case 'Renamed':
499
-                    $renameData = unserialize($logEntry->getComment());
500
-                    $oldName = htmlentities($renameData['old'], ENT_COMPAT, 'UTF-8');
501
-                    $newName = htmlentities($renameData['new'], ENT_COMPAT, 'UTF-8');
502
-                    $comment = 'Renamed \'' . $oldName . '\' to \'' . $newName . '\'.';
503
-                    break;
504
-                case 'RoleChange':
505
-                case 'GlobalRoleChange':
506
-                    $roleChangeData = unserialize($logEntry->getComment());
507
-
508
-                    $removed = array();
509
-                    foreach ($roleChangeData['removed'] as $r) {
510
-                        $removed[] = htmlentities($r, ENT_COMPAT, 'UTF-8');
511
-                    }
512
-
513
-                    $added = array();
514
-                    foreach ($roleChangeData['added'] as $r) {
515
-                        $added[] = htmlentities($r, ENT_COMPAT, 'UTF-8');
516
-                    }
517
-
518
-                    $reason = htmlentities($roleChangeData['reason'], ENT_COMPAT, 'UTF-8');
519
-
520
-                    $roleDelta = 'Removed [' . implode(', ', $removed) . '], Added [' . implode(', ', $added) . ']';
521
-                    $comment = $roleDelta . ' with comment: ' . $reason;
522
-                    break;
523
-                case 'JobIssue':
524
-                    $jobIssueData = unserialize($logEntry->getComment());
525
-                    $errorMessage = $jobIssueData['error'];
526
-                    $status = $jobIssueData['status'];
527
-
528
-                    $comment = 'Job ' . htmlentities($status, ENT_COMPAT, 'UTF-8') . ': ';
529
-                    $comment .= htmlentities($errorMessage, ENT_COMPAT, 'UTF-8');
530
-                    break;
531
-                case 'JobIssueRequest':
532
-                case 'JobCompletedRequest':
533
-                    $jobData = unserialize($logEntry->getComment());
534
-
535
-                    /** @var JobQueue $job */
536
-                    $job = JobQueue::getById($jobData['job'], $database);
537
-                    $descs = JobQueue::getTaskDescriptions();
538
-                    $comment = htmlentities($descs[$job->getTask()], ENT_COMPAT, 'UTF-8');
539
-                    break;
540
-
541
-                case 'JobCompleted':
542
-                    break;
543
-
544
-                default:
545
-                    $comment = $logEntry->getComment();
546
-                    break;
547
-            }
548
-
549
-            if (in_array($logEntry->getAction(), $protectedLogActions) && $logEntry->getObjectType() === 'User') {
550
-                if ($allowAccountLog) {
551
-                    // do nothing, allowed to see all account logs
552
-                }
553
-                else if ($allowAccountLogSelf && $currentUser->getId() === $logEntry->getObjectId()) {
554
-                    // do nothing, allowed to see own account log
555
-                }
556
-                else {
557
-                    $comment = null;
558
-                }
559
-            }
560
-
561
-            $logData[] = array(
562
-                'timestamp'         => $logEntry->getTimestamp(),
563
-                'userid'            => $logEntry->getUser(),
564
-                'username'          => $users[$logEntry->getUser()],
565
-                'description'       => self::getLogDescription($logEntry),
566
-                'objectdescription' => $objectDescription,
567
-                'comment'           => $comment,
568
-            );
569
-        }
570
-
571
-        return array($users, $logData);
572
-    }
346
+			case 'User':
347
+				/** @var User $user */
348
+				$user = User::getById($objectId, $database);
349
+
350
+				// Some users were merged out of existence
351
+				if ($user === false) {
352
+					return 'User #' . $objectId;
353
+				}
354
+
355
+				$username = htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8');
356
+
357
+				return "<a href=\"{$baseurl}/internal.php/statistics/users/detail?user={$objectId}\">{$username}</a>";
358
+			case 'WelcomeTemplate':
359
+				/** @var WelcomeTemplate $welcomeTemplate */
360
+				$welcomeTemplate = WelcomeTemplate::getById($objectId, $database);
361
+
362
+				// some old templates have been completely deleted and lost to the depths of time.
363
+				if ($welcomeTemplate === false) {
364
+					return "Welcome template #{$objectId}";
365
+				}
366
+				else {
367
+					$userCode = htmlentities($welcomeTemplate->getUserCode(), ENT_COMPAT, 'UTF-8');
368
+
369
+					return "<a href=\"{$baseurl}/internal.php/welcomeTemplates/view?template={$objectId}\">{$userCode}</a>";
370
+				}
371
+			case 'JobQueue':
372
+				/** @var JobQueue $job */
373
+				$job = JobQueue::getById($objectId, $database);
374
+
375
+				$taskDescriptions = JobQueue::getTaskDescriptions();
376
+
377
+				if ($job === false) {
378
+					return 'Job Queue Task #' . $objectId;
379
+				}
380
+
381
+				$task = $job->getTask();
382
+				if (isset($taskDescriptions[$task])) {
383
+					$description = $taskDescriptions[$task];
384
+				}
385
+				else {
386
+					$description = 'Unknown task';
387
+				}
388
+
389
+				return "<a href=\"{$baseurl}/internal.php/jobQueue/view?id={$objectId}\">Job #{$job->getId()} ({$description})</a>";
390
+			case 'RequestQueue':
391
+				/** @var RequestQueue $queue */
392
+				$queue = RequestQueue::getById($objectId, $database);
393
+
394
+				if ($queue === false) {
395
+					return "Request Queue #{$objectId}";
396
+				}
397
+
398
+				$queueHeader = htmlentities($queue->getHeader(), ENT_COMPAT, 'UTF-8');
399
+
400
+				return "<a href=\"{$baseurl}/internal.php/queueManagement/edit?queue={$objectId}\">{$queueHeader}</a>";
401
+			case 'Domain':
402
+				/** @var Domain $domain */
403
+				$domain = Domain::getById($objectId, $database);
404
+
405
+				if ($domain === false) {
406
+					return "Domain #{$objectId}";
407
+				}
408
+
409
+				$domainName = htmlentities($domain->getShortName(), ENT_COMPAT, 'UTF-8');
410
+				return "<a href=\"{$baseurl}/internal.php/domainManagement/edit?domain={$objectId}\">{$domainName}</a>";
411
+			case 'RequestForm':
412
+				/** @var RequestForm $queue */
413
+				$queue = RequestForm::getById($objectId, $database);
414
+
415
+				if ($queue === false) {
416
+					return "Request Form #{$objectId}";
417
+				}
418
+
419
+				$formName = htmlentities($queue->getName(), ENT_COMPAT, 'UTF-8');
420
+
421
+				return "<a href=\"{$baseurl}/internal.php/requestFormManagement/edit?form={$objectId}\">{$formName}</a>";
422
+			case 'Comment':
423
+				/** @var Comment $comment */
424
+				$comment = Comment::getById($objectId, $database);
425
+				/** @var Request $request */
426
+				$request = Request::getById($comment->getRequest(), $database);
427
+				$requestName = htmlentities($request->getName(), ENT_COMPAT, 'UTF-8');
428
+
429
+				return "<a href=\"{$baseurl}/internal.php/editComment?id={$objectId}\">Comment {$objectId}</a> on request <a href=\"{$baseurl}/internal.php/viewRequest?id={$comment->getRequest()}#comment-{$objectId}\">#{$comment->getRequest()} ({$requestName})</a>";
430
+			default:
431
+				return '[' . $objectType . " " . $objectId . ']';
432
+		}
433
+	}
434
+
435
+	/**
436
+	 * @param Log[] $logs
437
+	 * @throws Exception
438
+	 *
439
+	 * @returns User[]
440
+	 */
441
+	private static function loadUsersFromLogs(array $logs, PdoDatabase $database): array
442
+	{
443
+		$userIds = array();
444
+
445
+		foreach ($logs as $logEntry) {
446
+			if (!$logEntry instanceof Log) {
447
+				// if this happens, we've done something wrong with passing back the log data.
448
+				throw new Exception('Log entry is not an instance of a Log, this should never happen.');
449
+			}
450
+
451
+			$user = $logEntry->getUser();
452
+			if ($user === -1) {
453
+				continue;
454
+			}
455
+
456
+			if (!array_search($user, $userIds)) {
457
+				$userIds[] = $user;
458
+			}
459
+		}
460
+
461
+		$users = UserSearchHelper::get($database)->inIds($userIds)->fetchMap('username');
462
+		$users[-1] = User::getCommunity()->getUsername();
463
+
464
+		return $users;
465
+	}
466
+
467
+	/**
468
+	 * @param Log[] $logs
469
+	 *
470
+	 * @throws Exception
471
+	 */
472
+	public static function prepareLogsForTemplate(
473
+		array $logs,
474
+		PdoDatabase $database,
475
+		SiteConfiguration $configuration,
476
+		ISecurityManager $securityManager
477
+	): array {
478
+		$users = self::loadUsersFromLogs($logs, $database);
479
+		$currentUser = User::getCurrent($database);
480
+
481
+		$allowAccountLogSelf = $securityManager->allows('UserData', 'accountLogSelf', $currentUser) === ISecurityManager::ALLOWED;
482
+		$allowAccountLog = $securityManager->allows('UserData', 'accountLog', $currentUser) === ISecurityManager::ALLOWED;
483
+
484
+		$protectedLogActions = [
485
+			'RequestedReactivation',
486
+			'DeactivatedUser',
487
+		];
488
+
489
+		$logData = array();
490
+		foreach ($logs as $logEntry) {
491
+			$objectDescription = self::getObjectDescription($logEntry->getObjectId(), $logEntry->getObjectType(),
492
+				$database, $configuration);
493
+
494
+			// initialise to sane default
495
+			$comment = null;
496
+
497
+			switch ($logEntry->getAction()) {
498
+				case 'Renamed':
499
+					$renameData = unserialize($logEntry->getComment());
500
+					$oldName = htmlentities($renameData['old'], ENT_COMPAT, 'UTF-8');
501
+					$newName = htmlentities($renameData['new'], ENT_COMPAT, 'UTF-8');
502
+					$comment = 'Renamed \'' . $oldName . '\' to \'' . $newName . '\'.';
503
+					break;
504
+				case 'RoleChange':
505
+				case 'GlobalRoleChange':
506
+					$roleChangeData = unserialize($logEntry->getComment());
507
+
508
+					$removed = array();
509
+					foreach ($roleChangeData['removed'] as $r) {
510
+						$removed[] = htmlentities($r, ENT_COMPAT, 'UTF-8');
511
+					}
512
+
513
+					$added = array();
514
+					foreach ($roleChangeData['added'] as $r) {
515
+						$added[] = htmlentities($r, ENT_COMPAT, 'UTF-8');
516
+					}
517
+
518
+					$reason = htmlentities($roleChangeData['reason'], ENT_COMPAT, 'UTF-8');
519
+
520
+					$roleDelta = 'Removed [' . implode(', ', $removed) . '], Added [' . implode(', ', $added) . ']';
521
+					$comment = $roleDelta . ' with comment: ' . $reason;
522
+					break;
523
+				case 'JobIssue':
524
+					$jobIssueData = unserialize($logEntry->getComment());
525
+					$errorMessage = $jobIssueData['error'];
526
+					$status = $jobIssueData['status'];
527
+
528
+					$comment = 'Job ' . htmlentities($status, ENT_COMPAT, 'UTF-8') . ': ';
529
+					$comment .= htmlentities($errorMessage, ENT_COMPAT, 'UTF-8');
530
+					break;
531
+				case 'JobIssueRequest':
532
+				case 'JobCompletedRequest':
533
+					$jobData = unserialize($logEntry->getComment());
534
+
535
+					/** @var JobQueue $job */
536
+					$job = JobQueue::getById($jobData['job'], $database);
537
+					$descs = JobQueue::getTaskDescriptions();
538
+					$comment = htmlentities($descs[$job->getTask()], ENT_COMPAT, 'UTF-8');
539
+					break;
540
+
541
+				case 'JobCompleted':
542
+					break;
543
+
544
+				default:
545
+					$comment = $logEntry->getComment();
546
+					break;
547
+			}
548
+
549
+			if (in_array($logEntry->getAction(), $protectedLogActions) && $logEntry->getObjectType() === 'User') {
550
+				if ($allowAccountLog) {
551
+					// do nothing, allowed to see all account logs
552
+				}
553
+				else if ($allowAccountLogSelf && $currentUser->getId() === $logEntry->getObjectId()) {
554
+					// do nothing, allowed to see own account log
555
+				}
556
+				else {
557
+					$comment = null;
558
+				}
559
+			}
560
+
561
+			$logData[] = array(
562
+				'timestamp'         => $logEntry->getTimestamp(),
563
+				'userid'            => $logEntry->getUser(),
564
+				'username'          => $users[$logEntry->getUser()],
565
+				'description'       => self::getLogDescription($logEntry),
566
+				'objectdescription' => $objectDescription,
567
+				'comment'           => $comment,
568
+			);
569
+		}
570
+
571
+		return array($users, $logData);
572
+	}
573 573
 }
Please login to merge, or discard this patch.
Braces   +4 added lines, -8 removed lines patch added patch discarded remove patch
@@ -362,8 +362,7 @@  discard block
 block discarded – undo
362 362
                 // some old templates have been completely deleted and lost to the depths of time.
363 363
                 if ($welcomeTemplate === false) {
364 364
                     return "Welcome template #{$objectId}";
365
-                }
366
-                else {
365
+                } else {
367 366
                     $userCode = htmlentities($welcomeTemplate->getUserCode(), ENT_COMPAT, 'UTF-8');
368 367
 
369 368
                     return "<a href=\"{$baseurl}/internal.php/welcomeTemplates/view?template={$objectId}\">{$userCode}</a>";
@@ -381,8 +380,7 @@  discard block
 block discarded – undo
381 380
                 $task = $job->getTask();
382 381
                 if (isset($taskDescriptions[$task])) {
383 382
                     $description = $taskDescriptions[$task];
384
-                }
385
-                else {
383
+                } else {
386 384
                     $description = 'Unknown task';
387 385
                 }
388 386
 
@@ -549,11 +547,9 @@  discard block
 block discarded – undo
549 547
             if (in_array($logEntry->getAction(), $protectedLogActions) && $logEntry->getObjectType() === 'User') {
550 548
                 if ($allowAccountLog) {
551 549
                     // do nothing, allowed to see all account logs
552
-                }
553
-                else if ($allowAccountLogSelf && $currentUser->getId() === $logEntry->getObjectId()) {
550
+                } else if ($allowAccountLogSelf && $currentUser->getId() === $logEntry->getObjectId()) {
554 551
                     // do nothing, allowed to see own account log
555
-                }
556
-                else {
552
+                } else {
557 553
                     $comment = null;
558 554
                 }
559 555
             }
Please login to merge, or discard this patch.
includes/Fragments/LogEntryLookup.php 1 patch
Indentation   +14 added lines, -14 removed lines patch added patch discarded remove patch
@@ -16,20 +16,20 @@
 block discarded – undo
16 16
 
17 17
 trait LogEntryLookup
18 18
 {
19
-    protected function getLogEntry(string $action, User $user, PdoDatabase $database): ?string
20
-    {
21
-        /** @var Log[] $logs */
22
-        $logs = LogSearchHelper::get($database, null)
23
-            ->byAction($action)
24
-            ->byObjectType('User')
25
-            ->byObjectId($user->getId())
26
-            ->limit(1)
27
-            ->fetch();
19
+	protected function getLogEntry(string $action, User $user, PdoDatabase $database): ?string
20
+	{
21
+		/** @var Log[] $logs */
22
+		$logs = LogSearchHelper::get($database, null)
23
+			->byAction($action)
24
+			->byObjectType('User')
25
+			->byObjectId($user->getId())
26
+			->limit(1)
27
+			->fetch();
28 28
 
29
-        if (count($logs) > 0) {
30
-            return $logs[0]->getComment();
31
-        }
29
+		if (count($logs) > 0) {
30
+			return $logs[0]->getComment();
31
+		}
32 32
 
33
-        return null;
34
-    }
33
+		return null;
34
+	}
35 35
 }
36 36
\ No newline at end of file
Please login to merge, or discard this patch.
includes/Tasks/InternalPageBase.php 2 patches
Indentation   +228 added lines, -228 removed lines patch added patch discarded remove patch
@@ -24,232 +24,232 @@
 block discarded – undo
24 24
 
25 25
 abstract class InternalPageBase extends PageBase
26 26
 {
27
-    use NavigationMenuAccessControl;
28
-
29
-    /** @var ITypeAheadHelper */
30
-    private $typeAheadHelper;
31
-    private ISecurityManager $securityManager;
32
-    /** @var IBlacklistHelper */
33
-    private $blacklistHelper;
34
-
35
-    private IDomainAccessManager $domainAccessManager;
36
-
37
-    /**
38
-     * @return ITypeAheadHelper
39
-     */
40
-    public function getTypeAheadHelper()
41
-    {
42
-        return $this->typeAheadHelper;
43
-    }
44
-
45
-    /**
46
-     * @param ITypeAheadHelper $typeAheadHelper
47
-     */
48
-    public function setTypeAheadHelper(ITypeAheadHelper $typeAheadHelper)
49
-    {
50
-        $this->typeAheadHelper = $typeAheadHelper;
51
-    }
52
-
53
-    /**
54
-     * Runs the page code
55
-     *
56
-     * @throws Exception
57
-     * @category Security-Critical
58
-     */
59
-    final public function execute()
60
-    {
61
-        if ($this->getRouteName() === null) {
62
-            throw new Exception("Request is unrouted.");
63
-        }
64
-
65
-        if ($this->getSiteConfiguration() === null) {
66
-            throw new Exception("Page has no configuration!");
67
-        }
68
-
69
-        $this->setupPage();
70
-
71
-        $this->touchUserLastActive();
72
-
73
-        $currentUser = User::getCurrent($this->getDatabase());
74
-
75
-        // Hey, this is also a security barrier, in addition to the below. Separated out for readability.
76
-        if (!$this->isProtectedPage()) {
77
-            // This page is /not/ a protected page, as such we can just run it.
78
-            $this->runPage();
79
-
80
-            return;
81
-        }
82
-
83
-        // Security barrier.
84
-        //
85
-        // This code essentially doesn't care if the user is logged in or not, as the security manager hides all that
86
-        // away for us
87
-        $securityResult = $this->getSecurityManager()->allows(get_called_class(), $this->getRouteName(), $currentUser);
88
-        if ($securityResult === ISecurityManager::ALLOWED) {
89
-            // We're allowed to run the page, so let's run it.
90
-            $this->runPage();
91
-        }
92
-        else {
93
-            $this->handleAccessDenied($securityResult);
94
-
95
-            // Send the headers
96
-            $this->sendResponseHeaders();
97
-        }
98
-    }
99
-
100
-    /**
101
-     * Performs final tasks needed before rendering the page.
102
-     */
103
-    final public function finalisePage()
104
-    {
105
-        parent::finalisePage();
106
-
107
-        $database = $this->getDatabase();
108
-        $currentUser = User::getCurrent($database);
109
-
110
-        // Load in the badges for the navbar
111
-        $this->setUpNavBarBadges($currentUser, $database);
112
-
113
-        if ($this->barrierTest('viewSiteNotice', User::getCurrent($database), 'GlobalInfo')) {
114
-            $siteNotice = SiteNotice::get($this->getDatabase());
115
-            $siteNoticeHash = sha1($siteNotice);
116
-
117
-            if (WebRequest::testSiteNoticeCookieValue($siteNoticeHash)) {
118
-                $this->assign('siteNoticeState', 'd-none');
119
-            }
120
-            else {
121
-                $this->assign('siteNoticeState', 'd-block');
122
-            }
123
-
124
-            $this->assign('siteNoticeText', $siteNotice);
125
-            $this->assign('siteNoticeVersion', $siteNoticeHash);
126
-        }
127
-
128
-        if ($this->barrierTest('viewOnlineUsers', User::getCurrent($database), 'GlobalInfo')) {
129
-            $sql = 'SELECT * FROM user WHERE lastactive > DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 5 MINUTE);';
130
-            $statement = $database->query($sql);
131
-            $activeUsers = $statement->fetchAll(PDO::FETCH_CLASS, User::class);
132
-            $this->assign('onlineusers', $activeUsers);
133
-        }
134
-
135
-        $this->setupNavMenuAccess($currentUser);
136
-    }
137
-
138
-    /**
139
-     * Configures whether the page respects roles or not. You probably want this to return true.
140
-     *
141
-     * Set to false for public pages. You probably want this to return true.
142
-     *
143
-     * This defaults to true unless you explicitly set it to false. Setting it to false means anybody can do anything
144
-     * on this page, so you probably want this to return true.
145
-     *
146
-     * @return bool
147
-     * @category Security-Critical
148
-     */
149
-    protected function isProtectedPage()
150
-    {
151
-        return true;
152
-    }
153
-
154
-    protected function handleAccessDenied($denyReason)
155
-    {
156
-        $currentUser = User::getCurrent($this->getDatabase());
157
-
158
-        // Not allowed to access this resource.
159
-        // Firstly, let's check if we're even logged in.
160
-        if ($currentUser->isCommunityUser()) {
161
-            // Not logged in, redirect to login page
162
-            WebRequest::setPostLoginRedirect();
163
-            $this->redirect("login");
164
-
165
-            return;
166
-        }
167
-        else {
168
-            // Decide whether this was a rights failure, or an identification failure.
169
-
170
-            if ($denyReason === ISecurityManager::ERROR_NOT_IDENTIFIED) {
171
-                // Not identified
172
-                throw new NotIdentifiedException($this->getSecurityManager(), $this->getDomainAccessManager());
173
-            }
174
-            elseif ($denyReason === ISecurityManager::ERROR_DENIED) {
175
-                // Nope, plain old access denied
176
-                throw new AccessDeniedException($this->getSecurityManager(), $this->getDomainAccessManager());
177
-            }
178
-            else {
179
-                throw new Exception('Unknown response from security manager.');
180
-            }
181
-        }
182
-    }
183
-
184
-    /**
185
-     * Tests the security barrier for a specified action.
186
-     *
187
-     * Don't use within templates
188
-     *
189
-     * @param string      $action
190
-     *
191
-     * @param User        $user
192
-     * @param null|string $pageName
193
-     *
194
-     * @return bool
195
-     * @category Security-Critical
196
-     */
197
-    final public function barrierTest($action, User $user, $pageName = null)
198
-    {
199
-        $page = get_called_class();
200
-        if ($pageName !== null) {
201
-            $page = $pageName;
202
-        }
203
-
204
-        $securityResult = $this->getSecurityManager()->allows($page, $action, $user);
205
-
206
-        return $securityResult === ISecurityManager::ALLOWED;
207
-    }
208
-
209
-    /**
210
-     * Updates the lastactive timestamp
211
-     */
212
-    private function touchUserLastActive()
213
-    {
214
-        if (WebRequest::getSessionUserId() !== null) {
215
-            $query = 'UPDATE user SET lastactive = CURRENT_TIMESTAMP() WHERE id = :id;';
216
-            $this->getDatabase()->prepare($query)->execute(array(":id" => WebRequest::getSessionUserId()));
217
-        }
218
-    }
219
-
220
-    public function getSecurityManager(): ISecurityManager
221
-    {
222
-        return $this->securityManager;
223
-    }
224
-
225
-    public function setSecurityManager(ISecurityManager $securityManager)
226
-    {
227
-        $this->securityManager = $securityManager;
228
-    }
229
-
230
-    /**
231
-     * @return IBlacklistHelper
232
-     */
233
-    public function getBlacklistHelper()
234
-    {
235
-        return $this->blacklistHelper;
236
-    }
237
-
238
-    /**
239
-     * @param IBlacklistHelper $blacklistHelper
240
-     */
241
-    public function setBlacklistHelper(IBlacklistHelper $blacklistHelper)
242
-    {
243
-        $this->blacklistHelper = $blacklistHelper;
244
-    }
245
-
246
-    public function getDomainAccessManager(): IDomainAccessManager
247
-    {
248
-        return $this->domainAccessManager;
249
-    }
250
-
251
-    public function setDomainAccessManager(IDomainAccessManager $domainAccessManager): void
252
-    {
253
-        $this->domainAccessManager = $domainAccessManager;
254
-    }
27
+	use NavigationMenuAccessControl;
28
+
29
+	/** @var ITypeAheadHelper */
30
+	private $typeAheadHelper;
31
+	private ISecurityManager $securityManager;
32
+	/** @var IBlacklistHelper */
33
+	private $blacklistHelper;
34
+
35
+	private IDomainAccessManager $domainAccessManager;
36
+
37
+	/**
38
+	 * @return ITypeAheadHelper
39
+	 */
40
+	public function getTypeAheadHelper()
41
+	{
42
+		return $this->typeAheadHelper;
43
+	}
44
+
45
+	/**
46
+	 * @param ITypeAheadHelper $typeAheadHelper
47
+	 */
48
+	public function setTypeAheadHelper(ITypeAheadHelper $typeAheadHelper)
49
+	{
50
+		$this->typeAheadHelper = $typeAheadHelper;
51
+	}
52
+
53
+	/**
54
+	 * Runs the page code
55
+	 *
56
+	 * @throws Exception
57
+	 * @category Security-Critical
58
+	 */
59
+	final public function execute()
60
+	{
61
+		if ($this->getRouteName() === null) {
62
+			throw new Exception("Request is unrouted.");
63
+		}
64
+
65
+		if ($this->getSiteConfiguration() === null) {
66
+			throw new Exception("Page has no configuration!");
67
+		}
68
+
69
+		$this->setupPage();
70
+
71
+		$this->touchUserLastActive();
72
+
73
+		$currentUser = User::getCurrent($this->getDatabase());
74
+
75
+		// Hey, this is also a security barrier, in addition to the below. Separated out for readability.
76
+		if (!$this->isProtectedPage()) {
77
+			// This page is /not/ a protected page, as such we can just run it.
78
+			$this->runPage();
79
+
80
+			return;
81
+		}
82
+
83
+		// Security barrier.
84
+		//
85
+		// This code essentially doesn't care if the user is logged in or not, as the security manager hides all that
86
+		// away for us
87
+		$securityResult = $this->getSecurityManager()->allows(get_called_class(), $this->getRouteName(), $currentUser);
88
+		if ($securityResult === ISecurityManager::ALLOWED) {
89
+			// We're allowed to run the page, so let's run it.
90
+			$this->runPage();
91
+		}
92
+		else {
93
+			$this->handleAccessDenied($securityResult);
94
+
95
+			// Send the headers
96
+			$this->sendResponseHeaders();
97
+		}
98
+	}
99
+
100
+	/**
101
+	 * Performs final tasks needed before rendering the page.
102
+	 */
103
+	final public function finalisePage()
104
+	{
105
+		parent::finalisePage();
106
+
107
+		$database = $this->getDatabase();
108
+		$currentUser = User::getCurrent($database);
109
+
110
+		// Load in the badges for the navbar
111
+		$this->setUpNavBarBadges($currentUser, $database);
112
+
113
+		if ($this->barrierTest('viewSiteNotice', User::getCurrent($database), 'GlobalInfo')) {
114
+			$siteNotice = SiteNotice::get($this->getDatabase());
115
+			$siteNoticeHash = sha1($siteNotice);
116
+
117
+			if (WebRequest::testSiteNoticeCookieValue($siteNoticeHash)) {
118
+				$this->assign('siteNoticeState', 'd-none');
119
+			}
120
+			else {
121
+				$this->assign('siteNoticeState', 'd-block');
122
+			}
123
+
124
+			$this->assign('siteNoticeText', $siteNotice);
125
+			$this->assign('siteNoticeVersion', $siteNoticeHash);
126
+		}
127
+
128
+		if ($this->barrierTest('viewOnlineUsers', User::getCurrent($database), 'GlobalInfo')) {
129
+			$sql = 'SELECT * FROM user WHERE lastactive > DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 5 MINUTE);';
130
+			$statement = $database->query($sql);
131
+			$activeUsers = $statement->fetchAll(PDO::FETCH_CLASS, User::class);
132
+			$this->assign('onlineusers', $activeUsers);
133
+		}
134
+
135
+		$this->setupNavMenuAccess($currentUser);
136
+	}
137
+
138
+	/**
139
+	 * Configures whether the page respects roles or not. You probably want this to return true.
140
+	 *
141
+	 * Set to false for public pages. You probably want this to return true.
142
+	 *
143
+	 * This defaults to true unless you explicitly set it to false. Setting it to false means anybody can do anything
144
+	 * on this page, so you probably want this to return true.
145
+	 *
146
+	 * @return bool
147
+	 * @category Security-Critical
148
+	 */
149
+	protected function isProtectedPage()
150
+	{
151
+		return true;
152
+	}
153
+
154
+	protected function handleAccessDenied($denyReason)
155
+	{
156
+		$currentUser = User::getCurrent($this->getDatabase());
157
+
158
+		// Not allowed to access this resource.
159
+		// Firstly, let's check if we're even logged in.
160
+		if ($currentUser->isCommunityUser()) {
161
+			// Not logged in, redirect to login page
162
+			WebRequest::setPostLoginRedirect();
163
+			$this->redirect("login");
164
+
165
+			return;
166
+		}
167
+		else {
168
+			// Decide whether this was a rights failure, or an identification failure.
169
+
170
+			if ($denyReason === ISecurityManager::ERROR_NOT_IDENTIFIED) {
171
+				// Not identified
172
+				throw new NotIdentifiedException($this->getSecurityManager(), $this->getDomainAccessManager());
173
+			}
174
+			elseif ($denyReason === ISecurityManager::ERROR_DENIED) {
175
+				// Nope, plain old access denied
176
+				throw new AccessDeniedException($this->getSecurityManager(), $this->getDomainAccessManager());
177
+			}
178
+			else {
179
+				throw new Exception('Unknown response from security manager.');
180
+			}
181
+		}
182
+	}
183
+
184
+	/**
185
+	 * Tests the security barrier for a specified action.
186
+	 *
187
+	 * Don't use within templates
188
+	 *
189
+	 * @param string      $action
190
+	 *
191
+	 * @param User        $user
192
+	 * @param null|string $pageName
193
+	 *
194
+	 * @return bool
195
+	 * @category Security-Critical
196
+	 */
197
+	final public function barrierTest($action, User $user, $pageName = null)
198
+	{
199
+		$page = get_called_class();
200
+		if ($pageName !== null) {
201
+			$page = $pageName;
202
+		}
203
+
204
+		$securityResult = $this->getSecurityManager()->allows($page, $action, $user);
205
+
206
+		return $securityResult === ISecurityManager::ALLOWED;
207
+	}
208
+
209
+	/**
210
+	 * Updates the lastactive timestamp
211
+	 */
212
+	private function touchUserLastActive()
213
+	{
214
+		if (WebRequest::getSessionUserId() !== null) {
215
+			$query = 'UPDATE user SET lastactive = CURRENT_TIMESTAMP() WHERE id = :id;';
216
+			$this->getDatabase()->prepare($query)->execute(array(":id" => WebRequest::getSessionUserId()));
217
+		}
218
+	}
219
+
220
+	public function getSecurityManager(): ISecurityManager
221
+	{
222
+		return $this->securityManager;
223
+	}
224
+
225
+	public function setSecurityManager(ISecurityManager $securityManager)
226
+	{
227
+		$this->securityManager = $securityManager;
228
+	}
229
+
230
+	/**
231
+	 * @return IBlacklistHelper
232
+	 */
233
+	public function getBlacklistHelper()
234
+	{
235
+		return $this->blacklistHelper;
236
+	}
237
+
238
+	/**
239
+	 * @param IBlacklistHelper $blacklistHelper
240
+	 */
241
+	public function setBlacklistHelper(IBlacklistHelper $blacklistHelper)
242
+	{
243
+		$this->blacklistHelper = $blacklistHelper;
244
+	}
245
+
246
+	public function getDomainAccessManager(): IDomainAccessManager
247
+	{
248
+		return $this->domainAccessManager;
249
+	}
250
+
251
+	public function setDomainAccessManager(IDomainAccessManager $domainAccessManager): void
252
+	{
253
+		$this->domainAccessManager = $domainAccessManager;
254
+	}
255 255
 }
Please login to merge, or discard this patch.
Braces   +5 added lines, -10 removed lines patch added patch discarded remove patch
@@ -88,8 +88,7 @@  discard block
 block discarded – undo
88 88
         if ($securityResult === ISecurityManager::ALLOWED) {
89 89
             // We're allowed to run the page, so let's run it.
90 90
             $this->runPage();
91
-        }
92
-        else {
91
+        } else {
93 92
             $this->handleAccessDenied($securityResult);
94 93
 
95 94
             // Send the headers
@@ -116,8 +115,7 @@  discard block
 block discarded – undo
116 115
 
117 116
             if (WebRequest::testSiteNoticeCookieValue($siteNoticeHash)) {
118 117
                 $this->assign('siteNoticeState', 'd-none');
119
-            }
120
-            else {
118
+            } else {
121 119
                 $this->assign('siteNoticeState', 'd-block');
122 120
             }
123 121
 
@@ -163,19 +161,16 @@  discard block
 block discarded – undo
163 161
             $this->redirect("login");
164 162
 
165 163
             return;
166
-        }
167
-        else {
164
+        } else {
168 165
             // Decide whether this was a rights failure, or an identification failure.
169 166
 
170 167
             if ($denyReason === ISecurityManager::ERROR_NOT_IDENTIFIED) {
171 168
                 // Not identified
172 169
                 throw new NotIdentifiedException($this->getSecurityManager(), $this->getDomainAccessManager());
173
-            }
174
-            elseif ($denyReason === ISecurityManager::ERROR_DENIED) {
170
+            } elseif ($denyReason === ISecurityManager::ERROR_DENIED) {
175 171
                 // Nope, plain old access denied
176 172
                 throw new AccessDeniedException($this->getSecurityManager(), $this->getDomainAccessManager());
177
-            }
178
-            else {
173
+            } else {
179 174
                 throw new Exception('Unknown response from security manager.');
180 175
             }
181 176
         }
Please login to merge, or discard this patch.
includes/Tasks/TextApiPageBase.php 1 patch
Indentation   +16 added lines, -16 removed lines patch added patch discarded remove patch
@@ -13,23 +13,23 @@
 block discarded – undo
13 13
 
14 14
 abstract class TextApiPageBase extends ApiPageBase implements IRoutedTask
15 15
 {
16
-    final protected function main()
17
-    {
18
-        if (headers_sent()) {
19
-            throw new ApiException('Headers have already been sent - this indicates a bug in the application!');
20
-        }
16
+	final protected function main()
17
+	{
18
+		if (headers_sent()) {
19
+			throw new ApiException('Headers have already been sent - this indicates a bug in the application!');
20
+		}
21 21
 
22
-        try {
23
-            $responseData = $this->runApiPage();
24
-        }
25
-        catch (ApiException $ex) {
26
-            $responseData = $ex->getMessage();
27
-        }
22
+		try {
23
+			$responseData = $this->runApiPage();
24
+		}
25
+		catch (ApiException $ex) {
26
+			$responseData = $ex->getMessage();
27
+		}
28 28
 
29
-        header('Content-Type: text/plain');
29
+		header('Content-Type: text/plain');
30 30
 
31
-        ob_end_clean();
32
-        print($responseData);
33
-        ob_start();
34
-    }
31
+		ob_end_clean();
32
+		print($responseData);
33
+		ob_start();
34
+	}
35 35
 }
Please login to merge, or discard this patch.