Failed Conditions
Push — php8 ( f7c5b0...7c6ccd )
by Simon
15:01
created
smarty-plugins/function.defaultsort.php 1 patch
Indentation   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -19,24 +19,24 @@
 block discarded – undo
19 19
  */
20 20
 function smarty_function_defaultsort($params, Template $template)
21 21
 {
22
-    if (empty($params['id'])) {
23
-        return "";
24
-    }
22
+	if (empty($params['id'])) {
23
+		return "";
24
+	}
25 25
 
26
-    $attr = 'data-sortname="' . htmlspecialchars($params['id'], ENT_QUOTES) . '"';
26
+	$attr = 'data-sortname="' . htmlspecialchars($params['id'], ENT_QUOTES) . '"';
27 27
 
28
-    if (empty($params['req'])) {
29
-        return $attr;
30
-    }
28
+	if (empty($params['req'])) {
29
+		return $attr;
30
+	}
31 31
 
32
-    if ($params['dir'] !== 'asc' && $params['dir'] !== 'desc') {
33
-        $params['dir'] = 'asc';
34
-    }
32
+	if ($params['dir'] !== 'asc' && $params['dir'] !== 'desc') {
33
+		$params['dir'] = 'asc';
34
+	}
35 35
 
36
-    $sort = '';
37
-    if ($params['req'] === $params['id']) {
38
-        $sort = ' data-defaultsort="' . htmlspecialchars($params['dir'], ENT_QUOTES) . '"';
39
-    }
36
+	$sort = '';
37
+	if ($params['req'] === $params['id']) {
38
+		$sort = ' data-defaultsort="' . htmlspecialchars($params['dir'], ENT_QUOTES) . '"';
39
+	}
40 40
 
41
-    return $attr . $sort;
41
+	return $attr . $sort;
42 42
 }
Please login to merge, or discard this patch.
includes/WebStart.php 2 patches
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.
Indentation   +210 added lines, -210 removed lines patch added patch discarded remove patch
@@ -35,214 +35,214 @@
 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
-                $roleConfiguration = new RoleConfiguration($siteConfiguration->getGlobalDenyRole());
90
-                $page->setSecurityManager(new SecurityManager($identificationVerifier, $roleConfiguration, $userAccessLoader));
91
-                $page->setDomainAccessManager($domainAccessManager);
92
-
93
-                if ($siteConfiguration->getTitleBlacklistEnabled()) {
94
-                    $page->setBlacklistHelper(new BlacklistHelper($httpHelper, $database, $siteConfiguration));
95
-                }
96
-                else {
97
-                    $page->setBlacklistHelper(new FakeBlacklistHelper());
98
-                }
99
-            }
100
-        }
101
-    }
102
-
103
-    /**
104
-     * Application entry point.
105
-     *
106
-     * Sets up the environment and runs the application, performing any global cleanup operations when done.
107
-     */
108
-    public function run()
109
-    {
110
-        try {
111
-            if ($this->setupEnvironment()) {
112
-                $this->main();
113
-            }
114
-        }
115
-        catch (EnvironmentException $ex) {
116
-            ob_end_clean();
117
-            print Offline::getOfflineMessage($this->isPublic(), $this->getConfiguration(), $ex->getMessage());
118
-        }
119
-            /** @noinspection PhpRedundantCatchClauseInspection */
120
-        catch (ReadableException $ex) {
121
-            ob_end_clean();
122
-            print $ex->getReadableError();
123
-        }
124
-        finally {
125
-            $this->cleanupEnvironment();
126
-        }
127
-    }
128
-
129
-    /**
130
-     * Environment setup
131
-     *
132
-     * This method initialises the tool environment. If the tool cannot be initialised correctly, it will return false
133
-     * and shut down prematurely.
134
-     *
135
-     * @return bool
136
-     * @throws EnvironmentException
137
-     */
138
-    protected function setupEnvironment()
139
-    {
140
-        // initialise global exception handler
141
-        set_exception_handler(array(ExceptionHandler::class, 'exceptionHandler'));
142
-        set_error_handler(array(ExceptionHandler::class, 'errorHandler'), E_RECOVERABLE_ERROR);
143
-
144
-        // start output buffering if necessary
145
-        if (ob_get_level() === 0) {
146
-            ob_start();
147
-        }
148
-
149
-        // initialise super-global providers
150
-        WebRequest::setGlobalStateProvider(new GlobalStateProvider());
151
-
152
-        if (Offline::isOffline($this->getConfiguration())) {
153
-            print Offline::getOfflineMessage($this->isPublic(), $this->getConfiguration());
154
-            ob_end_flush();
155
-
156
-            return false;
157
-        }
158
-
159
-        // Call parent setup
160
-        if (!parent::setupEnvironment()) {
161
-            return false;
162
-        }
163
-
164
-        // Start up sessions
165
-        ini_set('session.cookie_path', $this->getConfiguration()->getCookiePath());
166
-        ini_set('session.name', $this->getConfiguration()->getCookieSessionName());
167
-        Session::start();
168
-
169
-        // Check the user is allowed to be logged in still. This must be before we call any user-loading functions and
170
-        // get the current user cached.
171
-        // I'm not sure if this function call being here is particularly a good thing, but it's part of starting up a
172
-        // session I suppose.
173
-        $this->checkForceLogout();
174
-
175
-        // environment initialised!
176
-        return true;
177
-    }
178
-
179
-    /**
180
-     * Main application logic
181
-     */
182
-    protected function main()
183
-    {
184
-        // Get the right route for the request
185
-        $page = $this->requestRouter->route();
186
-
187
-        $siteConfiguration = $this->getConfiguration();
188
-        $database = PdoDatabase::getDatabaseConnection($this->getConfiguration());
189
-
190
-        $this->setupHelpers($page, $siteConfiguration, $database);
191
-
192
-        // run the route code for the request.
193
-        $page->execute();
194
-    }
195
-
196
-    /**
197
-     * Any cleanup tasks should go here
198
-     *
199
-     * Note that we need to be very careful here, as exceptions may have been thrown and handled.
200
-     * This should *only* be for cleaning up, no logic should go here.
201
-     */
202
-    protected function cleanupEnvironment()
203
-    {
204
-        // Clean up anything we splurged after sending the page.
205
-        if (ob_get_level() > 0) {
206
-            for ($i = ob_get_level(); $i > 0; $i--) {
207
-                ob_end_clean();
208
-            }
209
-        }
210
-    }
211
-
212
-    private function checkForceLogout()
213
-    {
214
-        $database = PdoDatabase::getDatabaseConnection($this->getConfiguration());
215
-
216
-        $sessionUserId = WebRequest::getSessionUserId();
217
-        iF ($sessionUserId === null) {
218
-            return;
219
-        }
220
-
221
-        // Note, User::getCurrent() caches it's result, which we *really* don't want to trigger.
222
-        $currentUser = User::getById($sessionUserId, $database);
223
-
224
-        if ($currentUser === false) {
225
-            // Umm... this user has a session cookie with a userId set, but no user exists...
226
-            Session::restart();
227
-
228
-            $currentUser = User::getCurrent($database);
229
-        }
230
-
231
-        if ($currentUser->getForceLogout()) {
232
-            Session::restart();
233
-
234
-            $currentUser->setForceLogout(false);
235
-            $currentUser->save();
236
-        }
237
-    }
238
-
239
-    public function isPublic(): bool
240
-    {
241
-        return $this->isPublic;
242
-    }
243
-
244
-    public function setPublic(bool $isPublic): void
245
-    {
246
-        $this->isPublic = $isPublic;
247
-    }
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
+				$roleConfiguration = new RoleConfiguration($siteConfiguration->getGlobalDenyRole());
90
+				$page->setSecurityManager(new SecurityManager($identificationVerifier, $roleConfiguration, $userAccessLoader));
91
+				$page->setDomainAccessManager($domainAccessManager);
92
+
93
+				if ($siteConfiguration->getTitleBlacklistEnabled()) {
94
+					$page->setBlacklistHelper(new BlacklistHelper($httpHelper, $database, $siteConfiguration));
95
+				}
96
+				else {
97
+					$page->setBlacklistHelper(new FakeBlacklistHelper());
98
+				}
99
+			}
100
+		}
101
+	}
102
+
103
+	/**
104
+	 * Application entry point.
105
+	 *
106
+	 * Sets up the environment and runs the application, performing any global cleanup operations when done.
107
+	 */
108
+	public function run()
109
+	{
110
+		try {
111
+			if ($this->setupEnvironment()) {
112
+				$this->main();
113
+			}
114
+		}
115
+		catch (EnvironmentException $ex) {
116
+			ob_end_clean();
117
+			print Offline::getOfflineMessage($this->isPublic(), $this->getConfiguration(), $ex->getMessage());
118
+		}
119
+			/** @noinspection PhpRedundantCatchClauseInspection */
120
+		catch (ReadableException $ex) {
121
+			ob_end_clean();
122
+			print $ex->getReadableError();
123
+		}
124
+		finally {
125
+			$this->cleanupEnvironment();
126
+		}
127
+	}
128
+
129
+	/**
130
+	 * Environment setup
131
+	 *
132
+	 * This method initialises the tool environment. If the tool cannot be initialised correctly, it will return false
133
+	 * and shut down prematurely.
134
+	 *
135
+	 * @return bool
136
+	 * @throws EnvironmentException
137
+	 */
138
+	protected function setupEnvironment()
139
+	{
140
+		// initialise global exception handler
141
+		set_exception_handler(array(ExceptionHandler::class, 'exceptionHandler'));
142
+		set_error_handler(array(ExceptionHandler::class, 'errorHandler'), E_RECOVERABLE_ERROR);
143
+
144
+		// start output buffering if necessary
145
+		if (ob_get_level() === 0) {
146
+			ob_start();
147
+		}
148
+
149
+		// initialise super-global providers
150
+		WebRequest::setGlobalStateProvider(new GlobalStateProvider());
151
+
152
+		if (Offline::isOffline($this->getConfiguration())) {
153
+			print Offline::getOfflineMessage($this->isPublic(), $this->getConfiguration());
154
+			ob_end_flush();
155
+
156
+			return false;
157
+		}
158
+
159
+		// Call parent setup
160
+		if (!parent::setupEnvironment()) {
161
+			return false;
162
+		}
163
+
164
+		// Start up sessions
165
+		ini_set('session.cookie_path', $this->getConfiguration()->getCookiePath());
166
+		ini_set('session.name', $this->getConfiguration()->getCookieSessionName());
167
+		Session::start();
168
+
169
+		// Check the user is allowed to be logged in still. This must be before we call any user-loading functions and
170
+		// get the current user cached.
171
+		// I'm not sure if this function call being here is particularly a good thing, but it's part of starting up a
172
+		// session I suppose.
173
+		$this->checkForceLogout();
174
+
175
+		// environment initialised!
176
+		return true;
177
+	}
178
+
179
+	/**
180
+	 * Main application logic
181
+	 */
182
+	protected function main()
183
+	{
184
+		// Get the right route for the request
185
+		$page = $this->requestRouter->route();
186
+
187
+		$siteConfiguration = $this->getConfiguration();
188
+		$database = PdoDatabase::getDatabaseConnection($this->getConfiguration());
189
+
190
+		$this->setupHelpers($page, $siteConfiguration, $database);
191
+
192
+		// run the route code for the request.
193
+		$page->execute();
194
+	}
195
+
196
+	/**
197
+	 * Any cleanup tasks should go here
198
+	 *
199
+	 * Note that we need to be very careful here, as exceptions may have been thrown and handled.
200
+	 * This should *only* be for cleaning up, no logic should go here.
201
+	 */
202
+	protected function cleanupEnvironment()
203
+	{
204
+		// Clean up anything we splurged after sending the page.
205
+		if (ob_get_level() > 0) {
206
+			for ($i = ob_get_level(); $i > 0; $i--) {
207
+				ob_end_clean();
208
+			}
209
+		}
210
+	}
211
+
212
+	private function checkForceLogout()
213
+	{
214
+		$database = PdoDatabase::getDatabaseConnection($this->getConfiguration());
215
+
216
+		$sessionUserId = WebRequest::getSessionUserId();
217
+		iF ($sessionUserId === null) {
218
+			return;
219
+		}
220
+
221
+		// Note, User::getCurrent() caches it's result, which we *really* don't want to trigger.
222
+		$currentUser = User::getById($sessionUserId, $database);
223
+
224
+		if ($currentUser === false) {
225
+			// Umm... this user has a session cookie with a userId set, but no user exists...
226
+			Session::restart();
227
+
228
+			$currentUser = User::getCurrent($database);
229
+		}
230
+
231
+		if ($currentUser->getForceLogout()) {
232
+			Session::restart();
233
+
234
+			$currentUser->setForceLogout(false);
235
+			$currentUser->save();
236
+		}
237
+	}
238
+
239
+	public function isPublic(): bool
240
+	{
241
+		return $this->isPublic;
242
+	}
243
+
244
+	public function setPublic(bool $isPublic): void
245
+	{
246
+		$this->isPublic = $isPublic;
247
+	}
248 248
 }
Please login to merge, or discard this patch.
includes/Router/RequestRouter.php 1 patch
Indentation   +483 added lines, -483 removed lines patch added patch discarded remove patch
@@ -73,487 +73,487 @@
 block discarded – undo
73 73
  */
74 74
 class RequestRouter implements IRequestRouter
75 75
 {
76
-    /**
77
-     * This is the core routing table for the application. The basic idea is:
78
-     *
79
-     *      array(
80
-     *          "foo" =>
81
-     *              array(
82
-     *                  "class"   => PageFoo::class,
83
-     *                  "actions" => array("bar", "other")
84
-     *              ),
85
-     * );
86
-     *
87
-     * Things to note:
88
-     *     - If no page is requested, we go to PageMain. PageMain can't have actions defined.
89
-     *
90
-     *     - If a page is defined and requested, but no action is requested, go to that page's main() method
91
-     *     - If a page is defined and requested, and an action is defined and requested, go to that action's method.
92
-     *     - If a page is defined and requested, and an action NOT defined and requested, go to Page404 and it's main()
93
-     *       method.
94
-     *     - If a page is NOT defined and requested, go to Page404 and it's main() method.
95
-     *
96
-     *     - Query parameters are ignored.
97
-     *
98
-     * The key point here is request routing with validation that this is allowed, before we start hitting the
99
-     * filesystem through the AutoLoader, and opening random files. Also, so that we validate the action requested
100
-     * before we start calling random methods through the web UI.
101
-     *
102
-     * Examples:
103
-     * /internal.php                => returns instance of PageMain, routed to main()
104
-     * /internal.php?query          => returns instance of PageMain, routed to main()
105
-     * /internal.php/foo            => returns instance of PageFoo, routed to main()
106
-     * /internal.php/foo?query      => returns instance of PageFoo, routed to main()
107
-     * /internal.php/foo/bar        => returns instance of PageFoo, routed to bar()
108
-     * /internal.php/foo/bar?query  => returns instance of PageFoo, routed to bar()
109
-     * /internal.php/foo/baz        => returns instance of Page404, routed to main()
110
-     * /internal.php/foo/baz?query  => returns instance of Page404, routed to main()
111
-     * /internal.php/bar            => returns instance of Page404, routed to main()
112
-     * /internal.php/bar?query      => returns instance of Page404, routed to main()
113
-     * /internal.php/bar/baz        => returns instance of Page404, routed to main()
114
-     * /internal.php/bar/baz?query  => returns instance of Page404, routed to main()
115
-     *
116
-     * Take care when changing this - a lot of places rely on the array key for redirects and other links. If you need
117
-     * to change the key, then you'll likely have to update a lot of files.
118
-     *
119
-     * @var array
120
-     */
121
-    private $routeMap = array(
122
-
123
-        //////////////////////////////////////////////////////////////////////////////////////////////////
124
-        // Login and registration
125
-        'logout'                      =>
126
-            array(
127
-                'class'   => PageLogout::class,
128
-                'actions' => array(),
129
-            ),
130
-        'login'                       =>
131
-            array(
132
-                'class'   => PagePasswordLogin::class,
133
-                'actions' => array(),
134
-            ),
135
-        'login/otp'                   =>
136
-            array(
137
-                'class'   => PageOtpLogin::class,
138
-                'actions' => array(),
139
-            ),
140
-        'forgotPassword'              =>
141
-            array(
142
-                'class'   => PageForgotPassword::class,
143
-                'actions' => array('reset'),
144
-            ),
145
-        'register'                    =>
146
-            array(
147
-                'class'   => PageRegisterOption::class,
148
-                'actions' => array(),
149
-            ),
150
-        'register/standard'           =>
151
-            array(
152
-                'class'   => PageRegisterStandard::class,
153
-                'actions' => array('done'),
154
-            ),
155
-        'domainSwitch'                =>
156
-            array(
157
-                'class'   => PageDomainSwitch::class,
158
-                'actions' => array(),
159
-            ),
160
-        'login/reactivate'            =>
161
-            array(
162
-                'class'   => PageUserReactivate::class,
163
-                'actions' => array(),
164
-            ),
165
-
166
-        //////////////////////////////////////////////////////////////////////////////////////////////////
167
-        // Discovery
168
-        'search'                      =>
169
-            array(
170
-                'class'   => PageSearch::class,
171
-                'actions' => array(),
172
-            ),
173
-        'logs'                        =>
174
-            array(
175
-                'class'   => PageLog::class,
176
-                'actions' => array(),
177
-            ),
178
-
179
-        //////////////////////////////////////////////////////////////////////////////////////////////////
180
-        // Administration
181
-        'bans'                        =>
182
-            array(
183
-                'class'   => PageBan::class,
184
-                'actions' => array('set', 'remove', 'show', 'replace'),
185
-            ),
186
-        'userManagement'              =>
187
-            array(
188
-                'class'   => PageUserManagement::class,
189
-                'actions' => array(
190
-                    'approve',
191
-                    'deactivate',
192
-                    'rename',
193
-                    'editUser',
194
-                    'editRoles',
195
-                ),
196
-            ),
197
-        'siteNotice'                  =>
198
-            array(
199
-                'class'   => PageSiteNotice::class,
200
-                'actions' => array(),
201
-            ),
202
-        'emailManagement'             =>
203
-            array(
204
-                'class'   => PageEmailManagement::class,
205
-                'actions' => array('create', 'edit', 'view'),
206
-            ),
207
-        'queueManagement'             =>
208
-            array(
209
-                'class'   => PageQueueManagement::class,
210
-                'actions' => array('create', 'edit'),
211
-            ),
212
-        'requestFormManagement'       =>
213
-            array(
214
-                'class'   => PageRequestFormManagement::class,
215
-                'actions' => array('create', 'edit', 'view', 'preview'),
216
-            ),
217
-        'jobQueue'                    =>
218
-            array(
219
-                'class'   => PageJobQueue::class,
220
-                'actions' => array('acknowledge', 'requeue', 'view', 'all', 'cancel'),
221
-            ),
222
-        'domainManagement'            =>
223
-            array(
224
-                'class'   => PageDomainManagement::class,
225
-                'actions' => array('create', 'edit'),
226
-            ),
227
-        'flaggedComments'             =>
228
-            array(
229
-                'class'   => PageListFlaggedComments::class,
230
-                'actions' => array(),
231
-            ),
232
-
233
-        //////////////////////////////////////////////////////////////////////////////////////////////////
234
-        // Personal preferences
235
-        'preferences'                 =>
236
-            array(
237
-                'class'   => PagePreferences::class,
238
-                'actions' => array(
239
-                    'refreshOAuth'
240
-                ),
241
-            ),
242
-        'changePassword'              =>
243
-            array(
244
-                'class'   => PageChangePassword::class,
245
-                'actions' => array(),
246
-            ),
247
-        'multiFactor'                 =>
248
-            array(
249
-                'class'   => PageMultiFactor::class,
250
-                'actions' => array(
251
-                    'scratch',
252
-                    'enableYubikeyOtp',
253
-                    'disableYubikeyOtp',
254
-                    'enableTotp',
255
-                    'disableTotp',
256
-                ),
257
-            ),
258
-        'oauth'                       =>
259
-            array(
260
-                'class'   => PageOAuth::class,
261
-                'actions' => array('detach', 'attach'),
262
-            ),
263
-        'oauth/callback'              =>
264
-            array(
265
-                'class'   => PageOAuthCallback::class,
266
-                'actions' => array('authorise', 'create'),
267
-            ),
268
-
269
-        //////////////////////////////////////////////////////////////////////////////////////////////////
270
-        // Welcomer configuration
271
-        'welcomeTemplates'            =>
272
-            array(
273
-                'class'   => PageWelcomeTemplateManagement::class,
274
-                'actions' => array('select', 'edit', 'delete', 'add', 'view'),
275
-            ),
276
-
277
-        //////////////////////////////////////////////////////////////////////////////////////////////////
278
-        // Statistics
279
-        'statistics'                  =>
280
-            array(
281
-                'class'   => StatsMain::class,
282
-                'actions' => array(),
283
-            ),
284
-        'statistics/fastCloses'       =>
285
-            array(
286
-                'class'   => StatsFastCloses::class,
287
-                'actions' => array(),
288
-            ),
289
-        'statistics/inactiveUsers'    =>
290
-            array(
291
-                'class'   => StatsInactiveUsers::class,
292
-                'actions' => array(),
293
-            ),
294
-        'statistics/monthlyStats'     =>
295
-            array(
296
-                'class'   => StatsMonthlyStats::class,
297
-                'actions' => array(),
298
-            ),
299
-        'statistics/reservedRequests' =>
300
-            array(
301
-                'class'   => StatsReservedRequests::class,
302
-                'actions' => array(),
303
-            ),
304
-        'statistics/templateStats'    =>
305
-            array(
306
-                'class'   => StatsTemplateStats::class,
307
-                'actions' => array(),
308
-            ),
309
-        'statistics/topCreators'      =>
310
-            array(
311
-                'class'   => StatsTopCreators::class,
312
-                'actions' => array(),
313
-            ),
314
-        'statistics/users'            =>
315
-            array(
316
-                'class'   => StatsUsers::class,
317
-                'actions' => array('detail'),
318
-            ),
319
-
320
-        //////////////////////////////////////////////////////////////////////////////////////////////////
321
-        // Zoom page
322
-        'viewRequest'                 =>
323
-            array(
324
-                'class'   => PageViewRequest::class,
325
-                'actions' => array(),
326
-            ),
327
-        'viewRequest/confirm'         =>
328
-            array(
329
-                'class'   => PageManuallyConfirm::class,
330
-                'actions' => array(),
331
-            ),
332
-        'viewRequest/reserve'         =>
333
-            array(
334
-                'class'   => PageReservation::class,
335
-                'actions' => array(),
336
-            ),
337
-        'viewRequest/breakReserve'    =>
338
-            array(
339
-                'class'   => PageBreakReservation::class,
340
-                'actions' => array(),
341
-            ),
342
-        'viewRequest/defer'           =>
343
-            array(
344
-                'class'   => PageDeferRequest::class,
345
-                'actions' => array(),
346
-            ),
347
-        'viewRequest/comment'         =>
348
-            array(
349
-                'class'   => PageComment::class,
350
-                'actions' => array(),
351
-            ),
352
-        'viewRequest/sendToUser'      =>
353
-            array(
354
-                'class'   => PageSendToUser::class,
355
-                'actions' => array(),
356
-            ),
357
-        'viewRequest/close'           =>
358
-            array(
359
-                'class'   => PageCloseRequest::class,
360
-                'actions' => array(),
361
-            ),
362
-        'viewRequest/create'          =>
363
-            array(
364
-                'class'   => PageCreateRequest::class,
365
-                'actions' => array(),
366
-            ),
367
-        'viewRequest/drop'            =>
368
-            array(
369
-                'class'   => PageDropRequest::class,
370
-                'actions' => array(),
371
-            ),
372
-        'viewRequest/custom'          =>
373
-            array(
374
-                'class'   => PageCustomClose::class,
375
-                'actions' => array(),
376
-            ),
377
-        'editComment'                 =>
378
-            array(
379
-                'class'   => PageEditComment::class,
380
-                'actions' => array(),
381
-            ),
382
-        'flagComment'                 =>
383
-            array(
384
-                'class'   => PageFlagComment::class,
385
-                'actions' => array(),
386
-            ),
387
-
388
-        //////////////////////////////////////////////////////////////////////////////////////////////////
389
-        // Misc stuff
390
-        'team'                        =>
391
-            array(
392
-                'class'   => PageTeam::class,
393
-                'actions' => array(),
394
-            ),
395
-        'requestList'                 =>
396
-            array(
397
-                'class'   => PageExpandedRequestList::class,
398
-                'actions' => array(),
399
-            ),
400
-        'xffdemo'                     =>
401
-            array(
402
-                'class'   => PageXffDemo::class,
403
-                'actions' => array(),
404
-            ),
405
-        'errorLog'                    =>
406
-            array(
407
-                'class'   => PageErrorLogViewer::class,
408
-                'actions' => array('remove', 'view'),
409
-            ),
410
-        'privacy'                     =>
411
-            array(
412
-                'class'   => PagePrivacy::class,
413
-                'actions' => array(),
414
-            ),
415
-    );
416
-
417
-    /**
418
-     * @return IRoutedTask
419
-     * @throws Exception
420
-     */
421
-    final public function route()
422
-    {
423
-        $pathInfo = WebRequest::pathInfo();
424
-
425
-        list($pageClass, $action) = $this->getRouteFromPath($pathInfo);
426
-
427
-        /** @var IRoutedTask $page */
428
-        $page = new $pageClass();
429
-
430
-        // Dynamic creation, so we've got to be careful here. We can't use built-in language type protection, so
431
-        // let's use our own.
432
-        if (!($page instanceof IRoutedTask)) {
433
-            throw new Exception('Expected a page, but this is not a page.');
434
-        }
435
-
436
-        // OK, I'm happy at this point that we know we're running a page, and we know it's probably what we want if it
437
-        // inherits PageBase and has been created from the routing map.
438
-        $page->setRoute($action);
439
-
440
-        return $page;
441
-    }
442
-
443
-    /**
444
-     * @param $pathInfo
445
-     *
446
-     * @return array
447
-     */
448
-    public function getRouteFromPath($pathInfo)
449
-    {
450
-        if (count($pathInfo) === 0) {
451
-            // No pathInfo, so no page to load. Load the main page.
452
-            return $this->getDefaultRoute();
453
-        }
454
-        elseif (count($pathInfo) === 1) {
455
-            // Exactly one path info segment, it's got to be a page.
456
-            $classSegment = $pathInfo[0];
457
-
458
-            return $this->routeSinglePathSegment($classSegment);
459
-        }
460
-
461
-        // OK, we have two or more segments now.
462
-        if (count($pathInfo) > 2) {
463
-            // Let's handle more than two, and collapse it down into two.
464
-            $requestedAction = array_pop($pathInfo);
465
-            $classSegment = implode('/', $pathInfo);
466
-        }
467
-        else {
468
-            // Two path info segments.
469
-            $classSegment = $pathInfo[0];
470
-            $requestedAction = $pathInfo[1];
471
-        }
472
-
473
-        $routeMap = $this->routePathSegments($classSegment, $requestedAction);
474
-
475
-        if ($routeMap[0] === Page404::class) {
476
-            $routeMap = $this->routeSinglePathSegment($classSegment . '/' . $requestedAction);
477
-        }
478
-
479
-        return $routeMap;
480
-    }
481
-
482
-    /**
483
-     * @param $classSegment
484
-     *
485
-     * @return array
486
-     */
487
-    final protected function routeSinglePathSegment($classSegment)
488
-    {
489
-        $routeMap = $this->getRouteMap();
490
-        if (array_key_exists($classSegment, $routeMap)) {
491
-            // Route exists, but we don't have an action in path info, so default to main.
492
-            $pageClass = $routeMap[$classSegment]['class'];
493
-            $action = 'main';
494
-
495
-            return array($pageClass, $action);
496
-        }
497
-        else {
498
-            // Doesn't exist in map. Fall back to 404
499
-            $pageClass = Page404::class;
500
-            $action = "main";
501
-
502
-            return array($pageClass, $action);
503
-        }
504
-    }
505
-
506
-    /**
507
-     * @param $classSegment
508
-     * @param $requestedAction
509
-     *
510
-     * @return array
511
-     */
512
-    final protected function routePathSegments($classSegment, $requestedAction)
513
-    {
514
-        $routeMap = $this->getRouteMap();
515
-        if (array_key_exists($classSegment, $routeMap)) {
516
-            // Route exists, but we don't have an action in path info, so default to main.
517
-
518
-            if (isset($routeMap[$classSegment]['actions'])
519
-                && array_search($requestedAction, $routeMap[$classSegment]['actions']) !== false
520
-            ) {
521
-                // Action exists in allowed action list. Allow both the page and the action
522
-                $pageClass = $routeMap[$classSegment]['class'];
523
-                $action = $requestedAction;
524
-
525
-                return array($pageClass, $action);
526
-            }
527
-            else {
528
-                // Valid page, invalid action. 404 our way out.
529
-                $pageClass = Page404::class;
530
-                $action = 'main';
531
-
532
-                return array($pageClass, $action);
533
-            }
534
-        }
535
-        else {
536
-            // Class doesn't exist in map. Fall back to 404
537
-            $pageClass = Page404::class;
538
-            $action = 'main';
539
-
540
-            return array($pageClass, $action);
541
-        }
542
-    }
543
-
544
-    /**
545
-     * @return array
546
-     */
547
-    protected function getRouteMap()
548
-    {
549
-        return $this->routeMap;
550
-    }
551
-
552
-    /**
553
-     * @return array
554
-     */
555
-    protected function getDefaultRoute()
556
-    {
557
-        return array(PageMain::class, "main");
558
-    }
76
+	/**
77
+	 * This is the core routing table for the application. The basic idea is:
78
+	 *
79
+	 *      array(
80
+	 *          "foo" =>
81
+	 *              array(
82
+	 *                  "class"   => PageFoo::class,
83
+	 *                  "actions" => array("bar", "other")
84
+	 *              ),
85
+	 * );
86
+	 *
87
+	 * Things to note:
88
+	 *     - If no page is requested, we go to PageMain. PageMain can't have actions defined.
89
+	 *
90
+	 *     - If a page is defined and requested, but no action is requested, go to that page's main() method
91
+	 *     - If a page is defined and requested, and an action is defined and requested, go to that action's method.
92
+	 *     - If a page is defined and requested, and an action NOT defined and requested, go to Page404 and it's main()
93
+	 *       method.
94
+	 *     - If a page is NOT defined and requested, go to Page404 and it's main() method.
95
+	 *
96
+	 *     - Query parameters are ignored.
97
+	 *
98
+	 * The key point here is request routing with validation that this is allowed, before we start hitting the
99
+	 * filesystem through the AutoLoader, and opening random files. Also, so that we validate the action requested
100
+	 * before we start calling random methods through the web UI.
101
+	 *
102
+	 * Examples:
103
+	 * /internal.php                => returns instance of PageMain, routed to main()
104
+	 * /internal.php?query          => returns instance of PageMain, routed to main()
105
+	 * /internal.php/foo            => returns instance of PageFoo, routed to main()
106
+	 * /internal.php/foo?query      => returns instance of PageFoo, routed to main()
107
+	 * /internal.php/foo/bar        => returns instance of PageFoo, routed to bar()
108
+	 * /internal.php/foo/bar?query  => returns instance of PageFoo, routed to bar()
109
+	 * /internal.php/foo/baz        => returns instance of Page404, routed to main()
110
+	 * /internal.php/foo/baz?query  => returns instance of Page404, routed to main()
111
+	 * /internal.php/bar            => returns instance of Page404, routed to main()
112
+	 * /internal.php/bar?query      => returns instance of Page404, routed to main()
113
+	 * /internal.php/bar/baz        => returns instance of Page404, routed to main()
114
+	 * /internal.php/bar/baz?query  => returns instance of Page404, routed to main()
115
+	 *
116
+	 * Take care when changing this - a lot of places rely on the array key for redirects and other links. If you need
117
+	 * to change the key, then you'll likely have to update a lot of files.
118
+	 *
119
+	 * @var array
120
+	 */
121
+	private $routeMap = array(
122
+
123
+		//////////////////////////////////////////////////////////////////////////////////////////////////
124
+		// Login and registration
125
+		'logout'                      =>
126
+			array(
127
+				'class'   => PageLogout::class,
128
+				'actions' => array(),
129
+			),
130
+		'login'                       =>
131
+			array(
132
+				'class'   => PagePasswordLogin::class,
133
+				'actions' => array(),
134
+			),
135
+		'login/otp'                   =>
136
+			array(
137
+				'class'   => PageOtpLogin::class,
138
+				'actions' => array(),
139
+			),
140
+		'forgotPassword'              =>
141
+			array(
142
+				'class'   => PageForgotPassword::class,
143
+				'actions' => array('reset'),
144
+			),
145
+		'register'                    =>
146
+			array(
147
+				'class'   => PageRegisterOption::class,
148
+				'actions' => array(),
149
+			),
150
+		'register/standard'           =>
151
+			array(
152
+				'class'   => PageRegisterStandard::class,
153
+				'actions' => array('done'),
154
+			),
155
+		'domainSwitch'                =>
156
+			array(
157
+				'class'   => PageDomainSwitch::class,
158
+				'actions' => array(),
159
+			),
160
+		'login/reactivate'            =>
161
+			array(
162
+				'class'   => PageUserReactivate::class,
163
+				'actions' => array(),
164
+			),
165
+
166
+		//////////////////////////////////////////////////////////////////////////////////////////////////
167
+		// Discovery
168
+		'search'                      =>
169
+			array(
170
+				'class'   => PageSearch::class,
171
+				'actions' => array(),
172
+			),
173
+		'logs'                        =>
174
+			array(
175
+				'class'   => PageLog::class,
176
+				'actions' => array(),
177
+			),
178
+
179
+		//////////////////////////////////////////////////////////////////////////////////////////////////
180
+		// Administration
181
+		'bans'                        =>
182
+			array(
183
+				'class'   => PageBan::class,
184
+				'actions' => array('set', 'remove', 'show', 'replace'),
185
+			),
186
+		'userManagement'              =>
187
+			array(
188
+				'class'   => PageUserManagement::class,
189
+				'actions' => array(
190
+					'approve',
191
+					'deactivate',
192
+					'rename',
193
+					'editUser',
194
+					'editRoles',
195
+				),
196
+			),
197
+		'siteNotice'                  =>
198
+			array(
199
+				'class'   => PageSiteNotice::class,
200
+				'actions' => array(),
201
+			),
202
+		'emailManagement'             =>
203
+			array(
204
+				'class'   => PageEmailManagement::class,
205
+				'actions' => array('create', 'edit', 'view'),
206
+			),
207
+		'queueManagement'             =>
208
+			array(
209
+				'class'   => PageQueueManagement::class,
210
+				'actions' => array('create', 'edit'),
211
+			),
212
+		'requestFormManagement'       =>
213
+			array(
214
+				'class'   => PageRequestFormManagement::class,
215
+				'actions' => array('create', 'edit', 'view', 'preview'),
216
+			),
217
+		'jobQueue'                    =>
218
+			array(
219
+				'class'   => PageJobQueue::class,
220
+				'actions' => array('acknowledge', 'requeue', 'view', 'all', 'cancel'),
221
+			),
222
+		'domainManagement'            =>
223
+			array(
224
+				'class'   => PageDomainManagement::class,
225
+				'actions' => array('create', 'edit'),
226
+			),
227
+		'flaggedComments'             =>
228
+			array(
229
+				'class'   => PageListFlaggedComments::class,
230
+				'actions' => array(),
231
+			),
232
+
233
+		//////////////////////////////////////////////////////////////////////////////////////////////////
234
+		// Personal preferences
235
+		'preferences'                 =>
236
+			array(
237
+				'class'   => PagePreferences::class,
238
+				'actions' => array(
239
+					'refreshOAuth'
240
+				),
241
+			),
242
+		'changePassword'              =>
243
+			array(
244
+				'class'   => PageChangePassword::class,
245
+				'actions' => array(),
246
+			),
247
+		'multiFactor'                 =>
248
+			array(
249
+				'class'   => PageMultiFactor::class,
250
+				'actions' => array(
251
+					'scratch',
252
+					'enableYubikeyOtp',
253
+					'disableYubikeyOtp',
254
+					'enableTotp',
255
+					'disableTotp',
256
+				),
257
+			),
258
+		'oauth'                       =>
259
+			array(
260
+				'class'   => PageOAuth::class,
261
+				'actions' => array('detach', 'attach'),
262
+			),
263
+		'oauth/callback'              =>
264
+			array(
265
+				'class'   => PageOAuthCallback::class,
266
+				'actions' => array('authorise', 'create'),
267
+			),
268
+
269
+		//////////////////////////////////////////////////////////////////////////////////////////////////
270
+		// Welcomer configuration
271
+		'welcomeTemplates'            =>
272
+			array(
273
+				'class'   => PageWelcomeTemplateManagement::class,
274
+				'actions' => array('select', 'edit', 'delete', 'add', 'view'),
275
+			),
276
+
277
+		//////////////////////////////////////////////////////////////////////////////////////////////////
278
+		// Statistics
279
+		'statistics'                  =>
280
+			array(
281
+				'class'   => StatsMain::class,
282
+				'actions' => array(),
283
+			),
284
+		'statistics/fastCloses'       =>
285
+			array(
286
+				'class'   => StatsFastCloses::class,
287
+				'actions' => array(),
288
+			),
289
+		'statistics/inactiveUsers'    =>
290
+			array(
291
+				'class'   => StatsInactiveUsers::class,
292
+				'actions' => array(),
293
+			),
294
+		'statistics/monthlyStats'     =>
295
+			array(
296
+				'class'   => StatsMonthlyStats::class,
297
+				'actions' => array(),
298
+			),
299
+		'statistics/reservedRequests' =>
300
+			array(
301
+				'class'   => StatsReservedRequests::class,
302
+				'actions' => array(),
303
+			),
304
+		'statistics/templateStats'    =>
305
+			array(
306
+				'class'   => StatsTemplateStats::class,
307
+				'actions' => array(),
308
+			),
309
+		'statistics/topCreators'      =>
310
+			array(
311
+				'class'   => StatsTopCreators::class,
312
+				'actions' => array(),
313
+			),
314
+		'statistics/users'            =>
315
+			array(
316
+				'class'   => StatsUsers::class,
317
+				'actions' => array('detail'),
318
+			),
319
+
320
+		//////////////////////////////////////////////////////////////////////////////////////////////////
321
+		// Zoom page
322
+		'viewRequest'                 =>
323
+			array(
324
+				'class'   => PageViewRequest::class,
325
+				'actions' => array(),
326
+			),
327
+		'viewRequest/confirm'         =>
328
+			array(
329
+				'class'   => PageManuallyConfirm::class,
330
+				'actions' => array(),
331
+			),
332
+		'viewRequest/reserve'         =>
333
+			array(
334
+				'class'   => PageReservation::class,
335
+				'actions' => array(),
336
+			),
337
+		'viewRequest/breakReserve'    =>
338
+			array(
339
+				'class'   => PageBreakReservation::class,
340
+				'actions' => array(),
341
+			),
342
+		'viewRequest/defer'           =>
343
+			array(
344
+				'class'   => PageDeferRequest::class,
345
+				'actions' => array(),
346
+			),
347
+		'viewRequest/comment'         =>
348
+			array(
349
+				'class'   => PageComment::class,
350
+				'actions' => array(),
351
+			),
352
+		'viewRequest/sendToUser'      =>
353
+			array(
354
+				'class'   => PageSendToUser::class,
355
+				'actions' => array(),
356
+			),
357
+		'viewRequest/close'           =>
358
+			array(
359
+				'class'   => PageCloseRequest::class,
360
+				'actions' => array(),
361
+			),
362
+		'viewRequest/create'          =>
363
+			array(
364
+				'class'   => PageCreateRequest::class,
365
+				'actions' => array(),
366
+			),
367
+		'viewRequest/drop'            =>
368
+			array(
369
+				'class'   => PageDropRequest::class,
370
+				'actions' => array(),
371
+			),
372
+		'viewRequest/custom'          =>
373
+			array(
374
+				'class'   => PageCustomClose::class,
375
+				'actions' => array(),
376
+			),
377
+		'editComment'                 =>
378
+			array(
379
+				'class'   => PageEditComment::class,
380
+				'actions' => array(),
381
+			),
382
+		'flagComment'                 =>
383
+			array(
384
+				'class'   => PageFlagComment::class,
385
+				'actions' => array(),
386
+			),
387
+
388
+		//////////////////////////////////////////////////////////////////////////////////////////////////
389
+		// Misc stuff
390
+		'team'                        =>
391
+			array(
392
+				'class'   => PageTeam::class,
393
+				'actions' => array(),
394
+			),
395
+		'requestList'                 =>
396
+			array(
397
+				'class'   => PageExpandedRequestList::class,
398
+				'actions' => array(),
399
+			),
400
+		'xffdemo'                     =>
401
+			array(
402
+				'class'   => PageXffDemo::class,
403
+				'actions' => array(),
404
+			),
405
+		'errorLog'                    =>
406
+			array(
407
+				'class'   => PageErrorLogViewer::class,
408
+				'actions' => array('remove', 'view'),
409
+			),
410
+		'privacy'                     =>
411
+			array(
412
+				'class'   => PagePrivacy::class,
413
+				'actions' => array(),
414
+			),
415
+	);
416
+
417
+	/**
418
+	 * @return IRoutedTask
419
+	 * @throws Exception
420
+	 */
421
+	final public function route()
422
+	{
423
+		$pathInfo = WebRequest::pathInfo();
424
+
425
+		list($pageClass, $action) = $this->getRouteFromPath($pathInfo);
426
+
427
+		/** @var IRoutedTask $page */
428
+		$page = new $pageClass();
429
+
430
+		// Dynamic creation, so we've got to be careful here. We can't use built-in language type protection, so
431
+		// let's use our own.
432
+		if (!($page instanceof IRoutedTask)) {
433
+			throw new Exception('Expected a page, but this is not a page.');
434
+		}
435
+
436
+		// OK, I'm happy at this point that we know we're running a page, and we know it's probably what we want if it
437
+		// inherits PageBase and has been created from the routing map.
438
+		$page->setRoute($action);
439
+
440
+		return $page;
441
+	}
442
+
443
+	/**
444
+	 * @param $pathInfo
445
+	 *
446
+	 * @return array
447
+	 */
448
+	public function getRouteFromPath($pathInfo)
449
+	{
450
+		if (count($pathInfo) === 0) {
451
+			// No pathInfo, so no page to load. Load the main page.
452
+			return $this->getDefaultRoute();
453
+		}
454
+		elseif (count($pathInfo) === 1) {
455
+			// Exactly one path info segment, it's got to be a page.
456
+			$classSegment = $pathInfo[0];
457
+
458
+			return $this->routeSinglePathSegment($classSegment);
459
+		}
460
+
461
+		// OK, we have two or more segments now.
462
+		if (count($pathInfo) > 2) {
463
+			// Let's handle more than two, and collapse it down into two.
464
+			$requestedAction = array_pop($pathInfo);
465
+			$classSegment = implode('/', $pathInfo);
466
+		}
467
+		else {
468
+			// Two path info segments.
469
+			$classSegment = $pathInfo[0];
470
+			$requestedAction = $pathInfo[1];
471
+		}
472
+
473
+		$routeMap = $this->routePathSegments($classSegment, $requestedAction);
474
+
475
+		if ($routeMap[0] === Page404::class) {
476
+			$routeMap = $this->routeSinglePathSegment($classSegment . '/' . $requestedAction);
477
+		}
478
+
479
+		return $routeMap;
480
+	}
481
+
482
+	/**
483
+	 * @param $classSegment
484
+	 *
485
+	 * @return array
486
+	 */
487
+	final protected function routeSinglePathSegment($classSegment)
488
+	{
489
+		$routeMap = $this->getRouteMap();
490
+		if (array_key_exists($classSegment, $routeMap)) {
491
+			// Route exists, but we don't have an action in path info, so default to main.
492
+			$pageClass = $routeMap[$classSegment]['class'];
493
+			$action = 'main';
494
+
495
+			return array($pageClass, $action);
496
+		}
497
+		else {
498
+			// Doesn't exist in map. Fall back to 404
499
+			$pageClass = Page404::class;
500
+			$action = "main";
501
+
502
+			return array($pageClass, $action);
503
+		}
504
+	}
505
+
506
+	/**
507
+	 * @param $classSegment
508
+	 * @param $requestedAction
509
+	 *
510
+	 * @return array
511
+	 */
512
+	final protected function routePathSegments($classSegment, $requestedAction)
513
+	{
514
+		$routeMap = $this->getRouteMap();
515
+		if (array_key_exists($classSegment, $routeMap)) {
516
+			// Route exists, but we don't have an action in path info, so default to main.
517
+
518
+			if (isset($routeMap[$classSegment]['actions'])
519
+				&& array_search($requestedAction, $routeMap[$classSegment]['actions']) !== false
520
+			) {
521
+				// Action exists in allowed action list. Allow both the page and the action
522
+				$pageClass = $routeMap[$classSegment]['class'];
523
+				$action = $requestedAction;
524
+
525
+				return array($pageClass, $action);
526
+			}
527
+			else {
528
+				// Valid page, invalid action. 404 our way out.
529
+				$pageClass = Page404::class;
530
+				$action = 'main';
531
+
532
+				return array($pageClass, $action);
533
+			}
534
+		}
535
+		else {
536
+			// Class doesn't exist in map. Fall back to 404
537
+			$pageClass = Page404::class;
538
+			$action = 'main';
539
+
540
+			return array($pageClass, $action);
541
+		}
542
+	}
543
+
544
+	/**
545
+	 * @return array
546
+	 */
547
+	protected function getRouteMap()
548
+	{
549
+		return $this->routeMap;
550
+	}
551
+
552
+	/**
553
+	 * @return array
554
+	 */
555
+	protected function getDefaultRoute()
556
+	{
557
+		return array(PageMain::class, "main");
558
+	}
559 559
 }
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/IrcNotificationHelper.php 1 patch
Indentation   +493 added lines, -493 removed lines patch added patch discarded remove patch
@@ -32,500 +32,500 @@
 block discarded – undo
32 32
  */
33 33
 class IrcNotificationHelper
34 34
 {
35
-    /** @var bool $notificationsEnabled */
36
-    private $notificationsEnabled;
37
-    /** @var User $currentUser */
38
-    private $currentUser;
39
-    /** @var string $instanceName */
40
-    private $instanceName;
41
-    /** @var string */
42
-    private $baseUrl;
43
-    /** @var SiteConfiguration */
44
-    private $siteConfiguration;
45
-    /** @var PdoDatabase */
46
-    private $primaryDatabase;
47
-
48
-    /**
49
-     * IrcNotificationHelper constructor.
50
-     *
51
-     * @param SiteConfiguration $siteConfiguration
52
-     * @param PdoDatabase       $primaryDatabase
53
-     */
54
-    public function __construct(
55
-        SiteConfiguration $siteConfiguration,
56
-        PdoDatabase $primaryDatabase
57
-    ) {
58
-        $this->siteConfiguration = $siteConfiguration;
59
-        $this->primaryDatabase = $primaryDatabase;
60
-
61
-        $this->notificationsEnabled = $siteConfiguration->getIrcNotificationsEnabled();
62
-        $this->instanceName = $siteConfiguration->getIrcNotificationsInstance();
63
-        $this->baseUrl = $siteConfiguration->getBaseUrl();
64
-
65
-        $this->currentUser = User::getCurrent($primaryDatabase);
66
-    }
67
-
68
-    /**
69
-     * Send a notification
70
-     *
71
-     * This method does some *basic* filtering for IRC safety, and then delivers the message to an AMQP queue manager.
72
-     * It is the responsibility of the queue manager and consumer to handle message delivery to IRC, message routing to
73
-     * the correct channel, and message expiry.
74
-     *
75
-     * It's also arguably the responsibility of the consumer to ensure the message is *safe* for delivery to IRC.
76
-     *
77
-     * As of Feb 2022, the message consumer is stwalkerster's IRC bot Helpmebot.
78
-     *
79
-     * @param string $message The text to send
80
-     */
81
-    protected function send($message)
82
-    {
83
-        $instanceName = $this->instanceName;
84
-
85
-        if (!$this->notificationsEnabled) {
86
-            return;
87
-        }
88
-
89
-        $blacklist = array("DCC", "CCTP", "PRIVMSG");
90
-        $message = str_replace($blacklist, "(IRC Blacklist)", $message); // Lets stop DCC etc
91
-
92
-        $msg = $message;
93
-        if ($instanceName !== null && mb_strlen($instanceName) > 0) {
94
-            $msg = IrcColourCode::RESET . IrcColourCode::BOLD . "[$instanceName]" . IrcColourCode::RESET . ": $message";
95
-        }
96
-
97
-        // FIXME: domains!
98
-        /** @var Domain $domain */
99
-        $domain = Domain::getById(1, $this->primaryDatabase);
100
-
101
-        try {
102
-            $amqpSiteConfig = $this->siteConfiguration->getAmqpConfiguration();
103
-
104
-            $amqpConnectionConfig = new AMQPConnectionConfig();
105
-            $amqpConnectionConfig->setHost($amqpSiteConfig['host']);
106
-            $amqpConnectionConfig->setPort($amqpSiteConfig['port']);
107
-            $amqpConnectionConfig->setUser($amqpSiteConfig['user']);
108
-            $amqpConnectionConfig->setPassword($amqpSiteConfig['password']);
109
-            $amqpConnectionConfig->setVhost($amqpSiteConfig['vhost']);
110
-
111
-            if ($amqpSiteConfig['tls']) {
112
-                $amqpConnectionConfig->setIsSecure(true);
113
-                $amqpConnectionConfig->setSslVerify(true);
114
-            }
115
-            else {
116
-                $amqpConnectionConfig->setIsSecure(false);
117
-            }
118
-
119
-            $connection = AMQPConnectionFactory::create($amqpConnectionConfig);
120
-            $channel = $connection->channel();
121
-
122
-            $msg = new AMQPMessage(substr($msg, 0, 512));
123
-            $msg->set('user_id', $amqpSiteConfig['user']);
124
-            $msg->set('app_id', $this->siteConfiguration->getUserAgent());
125
-            $msg->set('content_type', 'text/plain');
35
+	/** @var bool $notificationsEnabled */
36
+	private $notificationsEnabled;
37
+	/** @var User $currentUser */
38
+	private $currentUser;
39
+	/** @var string $instanceName */
40
+	private $instanceName;
41
+	/** @var string */
42
+	private $baseUrl;
43
+	/** @var SiteConfiguration */
44
+	private $siteConfiguration;
45
+	/** @var PdoDatabase */
46
+	private $primaryDatabase;
47
+
48
+	/**
49
+	 * IrcNotificationHelper constructor.
50
+	 *
51
+	 * @param SiteConfiguration $siteConfiguration
52
+	 * @param PdoDatabase       $primaryDatabase
53
+	 */
54
+	public function __construct(
55
+		SiteConfiguration $siteConfiguration,
56
+		PdoDatabase $primaryDatabase
57
+	) {
58
+		$this->siteConfiguration = $siteConfiguration;
59
+		$this->primaryDatabase = $primaryDatabase;
60
+
61
+		$this->notificationsEnabled = $siteConfiguration->getIrcNotificationsEnabled();
62
+		$this->instanceName = $siteConfiguration->getIrcNotificationsInstance();
63
+		$this->baseUrl = $siteConfiguration->getBaseUrl();
64
+
65
+		$this->currentUser = User::getCurrent($primaryDatabase);
66
+	}
67
+
68
+	/**
69
+	 * Send a notification
70
+	 *
71
+	 * This method does some *basic* filtering for IRC safety, and then delivers the message to an AMQP queue manager.
72
+	 * It is the responsibility of the queue manager and consumer to handle message delivery to IRC, message routing to
73
+	 * the correct channel, and message expiry.
74
+	 *
75
+	 * It's also arguably the responsibility of the consumer to ensure the message is *safe* for delivery to IRC.
76
+	 *
77
+	 * As of Feb 2022, the message consumer is stwalkerster's IRC bot Helpmebot.
78
+	 *
79
+	 * @param string $message The text to send
80
+	 */
81
+	protected function send($message)
82
+	{
83
+		$instanceName = $this->instanceName;
84
+
85
+		if (!$this->notificationsEnabled) {
86
+			return;
87
+		}
88
+
89
+		$blacklist = array("DCC", "CCTP", "PRIVMSG");
90
+		$message = str_replace($blacklist, "(IRC Blacklist)", $message); // Lets stop DCC etc
91
+
92
+		$msg = $message;
93
+		if ($instanceName !== null && mb_strlen($instanceName) > 0) {
94
+			$msg = IrcColourCode::RESET . IrcColourCode::BOLD . "[$instanceName]" . IrcColourCode::RESET . ": $message";
95
+		}
96
+
97
+		// FIXME: domains!
98
+		/** @var Domain $domain */
99
+		$domain = Domain::getById(1, $this->primaryDatabase);
100
+
101
+		try {
102
+			$amqpSiteConfig = $this->siteConfiguration->getAmqpConfiguration();
103
+
104
+			$amqpConnectionConfig = new AMQPConnectionConfig();
105
+			$amqpConnectionConfig->setHost($amqpSiteConfig['host']);
106
+			$amqpConnectionConfig->setPort($amqpSiteConfig['port']);
107
+			$amqpConnectionConfig->setUser($amqpSiteConfig['user']);
108
+			$amqpConnectionConfig->setPassword($amqpSiteConfig['password']);
109
+			$amqpConnectionConfig->setVhost($amqpSiteConfig['vhost']);
110
+
111
+			if ($amqpSiteConfig['tls']) {
112
+				$amqpConnectionConfig->setIsSecure(true);
113
+				$amqpConnectionConfig->setSslVerify(true);
114
+			}
115
+			else {
116
+				$amqpConnectionConfig->setIsSecure(false);
117
+			}
118
+
119
+			$connection = AMQPConnectionFactory::create($amqpConnectionConfig);
120
+			$channel = $connection->channel();
121
+
122
+			$msg = new AMQPMessage(substr($msg, 0, 512));
123
+			$msg->set('user_id', $amqpSiteConfig['user']);
124
+			$msg->set('app_id', $this->siteConfiguration->getUserAgent());
125
+			$msg->set('content_type', 'text/plain');
126 126
             
127
-            $channel->basic_publish($msg, $amqpSiteConfig['exchange'], $domain->getNotificationTarget());
128
-            $channel->close();
129
-        }
130
-        catch (Exception $ex) {
131
-            // OK, so we failed to send the notification - that db might be down?
132
-            // This is non-critical, so silently fail.
133
-            ExceptionHandler::logExceptionToDisk($ex, $this->siteConfiguration);
134
-
135
-            // Disable notifications for remainder of request.
136
-            $this->notificationsEnabled = false;
137
-        }
138
-    }
139
-
140
-    #region user management
141
-
142
-    /**
143
-     * send a new user notification
144
-     *
145
-     * @param User $user
146
-     */
147
-    public function userNew(User $user)
148
-    {
149
-        $this->send("New user: {$user->getUsername()}");
150
-    }
151
-
152
-    /**
153
-     * send an approved notification
154
-     *
155
-     * @param User $user
156
-     */
157
-    public function userApproved(User $user)
158
-    {
159
-        $this->send("{$user->getUsername()} approved by " . $this->currentUser->getUsername());
160
-    }
161
-
162
-    /**
163
-     * send a deactivated notification
164
-     *
165
-     * @param User   $user
166
-     */
167
-    public function userDeactivated(User $user)
168
-    {
169
-        $this->send("{$user->getUsername()} deactivated by " . $this->currentUser->getUsername());
170
-    }
171
-
172
-    /**
173
-     * Send a preference change notification
174
-     *
175
-     * @param User $user
176
-     */
177
-    public function userPrefChange(User $user)
178
-    {
179
-        $this->send("{$user->getUsername()}'s preferences were changed by " . $this->currentUser->getUsername());
180
-    }
181
-
182
-    /**
183
-     * Send a user renamed notification
184
-     *
185
-     * @param User   $user
186
-     * @param string $old
187
-     */
188
-    public function userRenamed(User $user, $old)
189
-    {
190
-        $this->send($this->currentUser->getUsername() . " renamed $old to {$user->getUsername()}");
191
-    }
192
-
193
-    /**
194
-     * @param User   $user
195
-     * @param string $reason
196
-     */
197
-    public function userRolesEdited(User $user, $reason)
198
-    {
199
-        $currentUser = $this->currentUser->getUsername();
200
-        $this->send("Active roles for {$user->getUsername()} changed by " . $currentUser . " ($reason)");
201
-    }
202
-
203
-    #endregion
204
-
205
-    #region Site Notice
206
-
207
-    /**
208
-     * Summary of siteNoticeEdited
209
-     */
210
-    public function siteNoticeEdited()
211
-    {
212
-        $this->send("Site notice edited by " . $this->currentUser->getUsername());
213
-    }
214
-    #endregion
215
-
216
-    #region Welcome Templates
217
-    /**
218
-     * Summary of welcomeTemplateCreated
219
-     *
220
-     * @param WelcomeTemplate $template
221
-     */
222
-    public function welcomeTemplateCreated(WelcomeTemplate $template)
223
-    {
224
-        $this->send("Welcome template {$template->getId()} created by " . $this->currentUser->getUsername());
225
-    }
226
-
227
-    /**
228
-     * Summary of welcomeTemplateDeleted
229
-     *
230
-     * @param int $templateid
231
-     */
232
-    public function welcomeTemplateDeleted($templateid)
233
-    {
234
-        $this->send("Welcome template {$templateid} deleted by " . $this->currentUser->getUsername());
235
-    }
236
-
237
-    /**
238
-     * Summary of welcomeTemplateEdited
239
-     *
240
-     * @param WelcomeTemplate $template
241
-     */
242
-    public function welcomeTemplateEdited(WelcomeTemplate $template)
243
-    {
244
-        $this->send("Welcome template {$template->getId()} edited by " . $this->currentUser->getUsername());
245
-    }
246
-
247
-    #endregion
248
-
249
-    #region bans
250
-    /**
251
-     * Summary of banned
252
-     *
253
-     * @param Ban $ban
254
-     */
255
-    public function banned(Ban $ban)
256
-    {
257
-        if ($ban->getDuration() === null) {
258
-            $duration = "indefinitely";
259
-        }
260
-        else {
261
-            $duration = "until " . date("F j, Y, g:i a", $ban->getDuration());
262
-        }
263
-
264
-        $username = $this->currentUser->getUsername();
265
-
266
-        if ($ban->getVisibility() == 'user') {
267
-            $this->send("Ban {$ban->getId()} set by {$username} for '{$ban->getReason()}' {$duration}");
268
-        }
269
-        else {
270
-            $this->send("Ban {$ban->getId()} set by {$username} {$duration}");
271
-        }
272
-    }
273
-
274
-    /**
275
-     * Summary of unbanned
276
-     *
277
-     * @param Ban    $ban
278
-     * @param string $unbanReason
279
-     */
280
-    public function unbanned(Ban $ban, $unbanReason)
281
-    {
282
-        $this->send("Ban {$ban->getId()} unbanned by " . $this->currentUser
283
-                ->getUsername() . " (" . $unbanReason . ")");
284
-    }
285
-
286
-    #endregion
287
-
288
-    #region request management
289
-
290
-    /**
291
-     * Summary of requestReceived
292
-     *
293
-     * @param Request $request
294
-     */
295
-    public function requestReceived(Request $request)
296
-    {
297
-        $this->send(
298
-            IrcColourCode::DARK_GREY . "[["
299
-            . IrcColourCode::DARK_GREEN . "acc:"
300
-            . IrcColourCode::ORANGE . $request->getId()
301
-            . IrcColourCode::DARK_GREY . "]]"
302
-            . IrcColourCode::RED . " N "
303
-            . IrcColourCode::DARK_BLUE . $this->baseUrl . "/internal.php/viewRequest?id={$request->getId()} "
304
-            . IrcColourCode::DARK_RED . "* "
305
-            . IrcColourCode::DARK_GREEN . $request->getName()
306
-            . IrcColourCode::DARK_RED . " * "
307
-            . IrcColourCode::RESET
308
-        );
309
-    }
310
-
311
-    /**
312
-     * Summary of requestDeferred
313
-     *
314
-     * @param Request $request
315
-     */
316
-    public function requestDeferred(Request $request)
317
-    {
318
-        /** @var RequestQueue $queue */
319
-        $queue = RequestQueue::getById($request->getQueue(), $request->getDatabase());
320
-
321
-        $deferTo = $queue->getDisplayName();
322
-        $username = $this->currentUser->getUsername();
323
-
324
-        $this->send("Request {$request->getId()} ({$request->getName()}) deferred to {$deferTo} by {$username}");
325
-    }
326
-
327
-    /**
328
-     *
329
-     * Summary of requestDeferredWithMail
330
-     *
331
-     * @param Request $request
332
-     */
333
-    public function requestDeferredWithMail(Request $request)
334
-    {
335
-        /** @var RequestQueue $queue */
336
-        $queue = RequestQueue::getById($request->getQueue(), $request->getDatabase());
337
-
338
-        $deferTo = $queue->getDisplayName();
339
-        $username = $this->currentUser->getUsername();
340
-        $id = $request->getId();
341
-        $name = $request->getName();
342
-
343
-        $this->send("Request {$id} ({$name}) deferred to {$deferTo} with an email by {$username}");
344
-    }
345
-
346
-    /**
347
-     * Summary of requestClosed
348
-     *
349
-     * @param Request $request
350
-     * @param string  $closetype
351
-     */
352
-    public function requestClosed(Request $request, $closetype)
353
-    {
354
-        $username = $this->currentUser->getUsername();
355
-
356
-        $this->send("Request {$request->getId()} ({$request->getName()}) closed ($closetype) by {$username}");
357
-    }
358
-
359
-    /**
360
-     * Summary of requestClosed
361
-     *
362
-     * @param Request $request
363
-     * @param string  $closetype
364
-     */
365
-    public function requestCloseQueued(Request $request, $closetype)
366
-    {
367
-        $username = $this->currentUser->getUsername();
368
-
369
-        $this->send("Request {$request->getId()} ({$request->getName()}) queued for creation ($closetype) by {$username}");
370
-    }
371
-
372
-    /**
373
-     * Summary of requestClosed
374
-     *
375
-     * @param Request $request
376
-     * @param User    $triggerUser
377
-     */
378
-    public function requestCreationFailed(Request $request, User $triggerUser)
379
-    {
380
-        $this->send("Request {$request->getId()} ({$request->getName()}) failed auto-creation for {$triggerUser->getUsername()}, and was sent to the hospital queue.");
381
-    }
382
-
383
-    /**
384
-     * @param Request $request
385
-     * @param User    $triggerUser
386
-     */
387
-    public function requestWelcomeFailed(Request $request, User $triggerUser)
388
-    {
389
-        $this->send("Request {$request->getId()} ({$request->getName()}) failed welcome for {$triggerUser->getUsername()}.");
390
-    }
391
-
392
-    /**
393
-     * Summary of sentMail
394
-     *
395
-     * @param Request $request
396
-     */
397
-    public function sentMail(Request $request)
398
-    {
399
-        $this->send($this->currentUser->getUsername()
400
-            . " sent an email related to Request {$request->getId()} ({$request->getName()})");
401
-    }
402
-
403
-    #endregion
404
-
405
-    #region reservations
406
-
407
-    /**
408
-     * Summary of requestReserved
409
-     *
410
-     * @param Request $request
411
-     */
412
-    public function requestReserved(Request $request)
413
-    {
414
-        $username = $this->currentUser->getUsername();
415
-
416
-        $this->send("Request {$request->getId()} ({$request->getName()}) reserved by {$username}");
417
-    }
418
-
419
-    /**
420
-     * Summary of requestReserveBroken
421
-     *
422
-     * @param Request $request
423
-     */
424
-    public function requestReserveBroken(Request $request)
425
-    {
426
-        $username = $this->currentUser->getUsername();
427
-
428
-        $this->send("Reservation on request {$request->getId()} ({$request->getName()}) broken by {$username}");
429
-    }
430
-
431
-    /**
432
-     * Summary of requestUnreserved
433
-     *
434
-     * @param Request $request
435
-     */
436
-    public function requestUnreserved(Request $request)
437
-    {
438
-        $this->send("Request {$request->getId()} ({$request->getName()}) is no longer being handled.");
439
-    }
440
-
441
-    /**
442
-     * Summary of requestReservationSent
443
-     *
444
-     * @param Request $request
445
-     * @param User    $target
446
-     */
447
-    public function requestReservationSent(Request $request, User $target)
448
-    {
449
-        $username = $this->currentUser->getUsername();
450
-
451
-        $this->send(
452
-            "Reservation of request {$request->getId()} ({$request->getName()}) sent to {$target->getUsername()} by "
453
-            . $username);
454
-    }
455
-
456
-    #endregion
457
-
458
-    #region comments
459
-
460
-    /**
461
-     * Summary of commentCreated
462
-     *
463
-     * @param Comment $comment
464
-     * @param Request $request
465
-     */
466
-    public function commentCreated(Comment $comment, Request $request)
467
-    {
468
-        $username = $this->currentUser->getUsername();
469
-        switch ($comment->getVisibility()) {
470
-            case 'admin':
471
-                $visibility = " with visibility 'admin'";
472
-                break;
473
-            case 'checkuser':
474
-                $visibility = " with visibility 'checkuser'";
475
-                break;
476
-            default:
477
-                $visibility = "";
478
-                break;
479
-        }
480
-
481
-        $this->send("{$username} posted a comment on request {$request->getId()} ({$request->getName()}){$visibility}");
482
-    }
483
-
484
-    /**
485
-     * Summary of commentEdited
486
-     *
487
-     * @param Comment $comment
488
-     * @param Request $request
489
-     */
490
-    public function commentEdited(Comment $comment, Request $request)
491
-    {
492
-        $username = $this->currentUser->getUsername();
493
-
494
-        $this->send(<<<TAG
127
+			$channel->basic_publish($msg, $amqpSiteConfig['exchange'], $domain->getNotificationTarget());
128
+			$channel->close();
129
+		}
130
+		catch (Exception $ex) {
131
+			// OK, so we failed to send the notification - that db might be down?
132
+			// This is non-critical, so silently fail.
133
+			ExceptionHandler::logExceptionToDisk($ex, $this->siteConfiguration);
134
+
135
+			// Disable notifications for remainder of request.
136
+			$this->notificationsEnabled = false;
137
+		}
138
+	}
139
+
140
+	#region user management
141
+
142
+	/**
143
+	 * send a new user notification
144
+	 *
145
+	 * @param User $user
146
+	 */
147
+	public function userNew(User $user)
148
+	{
149
+		$this->send("New user: {$user->getUsername()}");
150
+	}
151
+
152
+	/**
153
+	 * send an approved notification
154
+	 *
155
+	 * @param User $user
156
+	 */
157
+	public function userApproved(User $user)
158
+	{
159
+		$this->send("{$user->getUsername()} approved by " . $this->currentUser->getUsername());
160
+	}
161
+
162
+	/**
163
+	 * send a deactivated notification
164
+	 *
165
+	 * @param User   $user
166
+	 */
167
+	public function userDeactivated(User $user)
168
+	{
169
+		$this->send("{$user->getUsername()} deactivated by " . $this->currentUser->getUsername());
170
+	}
171
+
172
+	/**
173
+	 * Send a preference change notification
174
+	 *
175
+	 * @param User $user
176
+	 */
177
+	public function userPrefChange(User $user)
178
+	{
179
+		$this->send("{$user->getUsername()}'s preferences were changed by " . $this->currentUser->getUsername());
180
+	}
181
+
182
+	/**
183
+	 * Send a user renamed notification
184
+	 *
185
+	 * @param User   $user
186
+	 * @param string $old
187
+	 */
188
+	public function userRenamed(User $user, $old)
189
+	{
190
+		$this->send($this->currentUser->getUsername() . " renamed $old to {$user->getUsername()}");
191
+	}
192
+
193
+	/**
194
+	 * @param User   $user
195
+	 * @param string $reason
196
+	 */
197
+	public function userRolesEdited(User $user, $reason)
198
+	{
199
+		$currentUser = $this->currentUser->getUsername();
200
+		$this->send("Active roles for {$user->getUsername()} changed by " . $currentUser . " ($reason)");
201
+	}
202
+
203
+	#endregion
204
+
205
+	#region Site Notice
206
+
207
+	/**
208
+	 * Summary of siteNoticeEdited
209
+	 */
210
+	public function siteNoticeEdited()
211
+	{
212
+		$this->send("Site notice edited by " . $this->currentUser->getUsername());
213
+	}
214
+	#endregion
215
+
216
+	#region Welcome Templates
217
+	/**
218
+	 * Summary of welcomeTemplateCreated
219
+	 *
220
+	 * @param WelcomeTemplate $template
221
+	 */
222
+	public function welcomeTemplateCreated(WelcomeTemplate $template)
223
+	{
224
+		$this->send("Welcome template {$template->getId()} created by " . $this->currentUser->getUsername());
225
+	}
226
+
227
+	/**
228
+	 * Summary of welcomeTemplateDeleted
229
+	 *
230
+	 * @param int $templateid
231
+	 */
232
+	public function welcomeTemplateDeleted($templateid)
233
+	{
234
+		$this->send("Welcome template {$templateid} deleted by " . $this->currentUser->getUsername());
235
+	}
236
+
237
+	/**
238
+	 * Summary of welcomeTemplateEdited
239
+	 *
240
+	 * @param WelcomeTemplate $template
241
+	 */
242
+	public function welcomeTemplateEdited(WelcomeTemplate $template)
243
+	{
244
+		$this->send("Welcome template {$template->getId()} edited by " . $this->currentUser->getUsername());
245
+	}
246
+
247
+	#endregion
248
+
249
+	#region bans
250
+	/**
251
+	 * Summary of banned
252
+	 *
253
+	 * @param Ban $ban
254
+	 */
255
+	public function banned(Ban $ban)
256
+	{
257
+		if ($ban->getDuration() === null) {
258
+			$duration = "indefinitely";
259
+		}
260
+		else {
261
+			$duration = "until " . date("F j, Y, g:i a", $ban->getDuration());
262
+		}
263
+
264
+		$username = $this->currentUser->getUsername();
265
+
266
+		if ($ban->getVisibility() == 'user') {
267
+			$this->send("Ban {$ban->getId()} set by {$username} for '{$ban->getReason()}' {$duration}");
268
+		}
269
+		else {
270
+			$this->send("Ban {$ban->getId()} set by {$username} {$duration}");
271
+		}
272
+	}
273
+
274
+	/**
275
+	 * Summary of unbanned
276
+	 *
277
+	 * @param Ban    $ban
278
+	 * @param string $unbanReason
279
+	 */
280
+	public function unbanned(Ban $ban, $unbanReason)
281
+	{
282
+		$this->send("Ban {$ban->getId()} unbanned by " . $this->currentUser
283
+				->getUsername() . " (" . $unbanReason . ")");
284
+	}
285
+
286
+	#endregion
287
+
288
+	#region request management
289
+
290
+	/**
291
+	 * Summary of requestReceived
292
+	 *
293
+	 * @param Request $request
294
+	 */
295
+	public function requestReceived(Request $request)
296
+	{
297
+		$this->send(
298
+			IrcColourCode::DARK_GREY . "[["
299
+			. IrcColourCode::DARK_GREEN . "acc:"
300
+			. IrcColourCode::ORANGE . $request->getId()
301
+			. IrcColourCode::DARK_GREY . "]]"
302
+			. IrcColourCode::RED . " N "
303
+			. IrcColourCode::DARK_BLUE . $this->baseUrl . "/internal.php/viewRequest?id={$request->getId()} "
304
+			. IrcColourCode::DARK_RED . "* "
305
+			. IrcColourCode::DARK_GREEN . $request->getName()
306
+			. IrcColourCode::DARK_RED . " * "
307
+			. IrcColourCode::RESET
308
+		);
309
+	}
310
+
311
+	/**
312
+	 * Summary of requestDeferred
313
+	 *
314
+	 * @param Request $request
315
+	 */
316
+	public function requestDeferred(Request $request)
317
+	{
318
+		/** @var RequestQueue $queue */
319
+		$queue = RequestQueue::getById($request->getQueue(), $request->getDatabase());
320
+
321
+		$deferTo = $queue->getDisplayName();
322
+		$username = $this->currentUser->getUsername();
323
+
324
+		$this->send("Request {$request->getId()} ({$request->getName()}) deferred to {$deferTo} by {$username}");
325
+	}
326
+
327
+	/**
328
+	 *
329
+	 * Summary of requestDeferredWithMail
330
+	 *
331
+	 * @param Request $request
332
+	 */
333
+	public function requestDeferredWithMail(Request $request)
334
+	{
335
+		/** @var RequestQueue $queue */
336
+		$queue = RequestQueue::getById($request->getQueue(), $request->getDatabase());
337
+
338
+		$deferTo = $queue->getDisplayName();
339
+		$username = $this->currentUser->getUsername();
340
+		$id = $request->getId();
341
+		$name = $request->getName();
342
+
343
+		$this->send("Request {$id} ({$name}) deferred to {$deferTo} with an email by {$username}");
344
+	}
345
+
346
+	/**
347
+	 * Summary of requestClosed
348
+	 *
349
+	 * @param Request $request
350
+	 * @param string  $closetype
351
+	 */
352
+	public function requestClosed(Request $request, $closetype)
353
+	{
354
+		$username = $this->currentUser->getUsername();
355
+
356
+		$this->send("Request {$request->getId()} ({$request->getName()}) closed ($closetype) by {$username}");
357
+	}
358
+
359
+	/**
360
+	 * Summary of requestClosed
361
+	 *
362
+	 * @param Request $request
363
+	 * @param string  $closetype
364
+	 */
365
+	public function requestCloseQueued(Request $request, $closetype)
366
+	{
367
+		$username = $this->currentUser->getUsername();
368
+
369
+		$this->send("Request {$request->getId()} ({$request->getName()}) queued for creation ($closetype) by {$username}");
370
+	}
371
+
372
+	/**
373
+	 * Summary of requestClosed
374
+	 *
375
+	 * @param Request $request
376
+	 * @param User    $triggerUser
377
+	 */
378
+	public function requestCreationFailed(Request $request, User $triggerUser)
379
+	{
380
+		$this->send("Request {$request->getId()} ({$request->getName()}) failed auto-creation for {$triggerUser->getUsername()}, and was sent to the hospital queue.");
381
+	}
382
+
383
+	/**
384
+	 * @param Request $request
385
+	 * @param User    $triggerUser
386
+	 */
387
+	public function requestWelcomeFailed(Request $request, User $triggerUser)
388
+	{
389
+		$this->send("Request {$request->getId()} ({$request->getName()}) failed welcome for {$triggerUser->getUsername()}.");
390
+	}
391
+
392
+	/**
393
+	 * Summary of sentMail
394
+	 *
395
+	 * @param Request $request
396
+	 */
397
+	public function sentMail(Request $request)
398
+	{
399
+		$this->send($this->currentUser->getUsername()
400
+			. " sent an email related to Request {$request->getId()} ({$request->getName()})");
401
+	}
402
+
403
+	#endregion
404
+
405
+	#region reservations
406
+
407
+	/**
408
+	 * Summary of requestReserved
409
+	 *
410
+	 * @param Request $request
411
+	 */
412
+	public function requestReserved(Request $request)
413
+	{
414
+		$username = $this->currentUser->getUsername();
415
+
416
+		$this->send("Request {$request->getId()} ({$request->getName()}) reserved by {$username}");
417
+	}
418
+
419
+	/**
420
+	 * Summary of requestReserveBroken
421
+	 *
422
+	 * @param Request $request
423
+	 */
424
+	public function requestReserveBroken(Request $request)
425
+	{
426
+		$username = $this->currentUser->getUsername();
427
+
428
+		$this->send("Reservation on request {$request->getId()} ({$request->getName()}) broken by {$username}");
429
+	}
430
+
431
+	/**
432
+	 * Summary of requestUnreserved
433
+	 *
434
+	 * @param Request $request
435
+	 */
436
+	public function requestUnreserved(Request $request)
437
+	{
438
+		$this->send("Request {$request->getId()} ({$request->getName()}) is no longer being handled.");
439
+	}
440
+
441
+	/**
442
+	 * Summary of requestReservationSent
443
+	 *
444
+	 * @param Request $request
445
+	 * @param User    $target
446
+	 */
447
+	public function requestReservationSent(Request $request, User $target)
448
+	{
449
+		$username = $this->currentUser->getUsername();
450
+
451
+		$this->send(
452
+			"Reservation of request {$request->getId()} ({$request->getName()}) sent to {$target->getUsername()} by "
453
+			. $username);
454
+	}
455
+
456
+	#endregion
457
+
458
+	#region comments
459
+
460
+	/**
461
+	 * Summary of commentCreated
462
+	 *
463
+	 * @param Comment $comment
464
+	 * @param Request $request
465
+	 */
466
+	public function commentCreated(Comment $comment, Request $request)
467
+	{
468
+		$username = $this->currentUser->getUsername();
469
+		switch ($comment->getVisibility()) {
470
+			case 'admin':
471
+				$visibility = " with visibility 'admin'";
472
+				break;
473
+			case 'checkuser':
474
+				$visibility = " with visibility 'checkuser'";
475
+				break;
476
+			default:
477
+				$visibility = "";
478
+				break;
479
+		}
480
+
481
+		$this->send("{$username} posted a comment on request {$request->getId()} ({$request->getName()}){$visibility}");
482
+	}
483
+
484
+	/**
485
+	 * Summary of commentEdited
486
+	 *
487
+	 * @param Comment $comment
488
+	 * @param Request $request
489
+	 */
490
+	public function commentEdited(Comment $comment, Request $request)
491
+	{
492
+		$username = $this->currentUser->getUsername();
493
+
494
+		$this->send(<<<TAG
495 495
 Comment {$comment->getId()} on request {$request->getId()} ({$request->getName()}) edited by {$username}
496 496
 TAG
497
-        );
498
-    }
499
-
500
-    public function alertFlaggedComments(int $count)
501
-    {
502
-        $this->send("There are ${count} flagged comments on closed requests currently awaiting redaction.");
503
-    }
504
-
505
-    #endregion
506
-
507
-    #region email management (close reasons)
508
-
509
-    /**
510
-     * Summary of emailCreated
511
-     *
512
-     * @param EmailTemplate $template
513
-     */
514
-    public function emailCreated(EmailTemplate $template)
515
-    {
516
-        $username = $this->currentUser->getUsername();
517
-        $this->send("Email {$template->getId()} ({$template->getName()}) created by " . $username);
518
-    }
519
-
520
-    /**
521
-     * Summary of emailEdited
522
-     *
523
-     * @param EmailTemplate $template
524
-     */
525
-    public function emailEdited(EmailTemplate $template)
526
-    {
527
-        $username = $this->currentUser->getUsername();
528
-        $this->send("Email {$template->getId()} ({$template->getName()}) edited by " . $username);
529
-    }
530
-    #endregion
497
+		);
498
+	}
499
+
500
+	public function alertFlaggedComments(int $count)
501
+	{
502
+		$this->send("There are ${count} flagged comments on closed requests currently awaiting redaction.");
503
+	}
504
+
505
+	#endregion
506
+
507
+	#region email management (close reasons)
508
+
509
+	/**
510
+	 * Summary of emailCreated
511
+	 *
512
+	 * @param EmailTemplate $template
513
+	 */
514
+	public function emailCreated(EmailTemplate $template)
515
+	{
516
+		$username = $this->currentUser->getUsername();
517
+		$this->send("Email {$template->getId()} ({$template->getName()}) created by " . $username);
518
+	}
519
+
520
+	/**
521
+	 * Summary of emailEdited
522
+	 *
523
+	 * @param EmailTemplate $template
524
+	 */
525
+	public function emailEdited(EmailTemplate $template)
526
+	{
527
+		$username = $this->currentUser->getUsername();
528
+		$this->send("Email {$template->getId()} ({$template->getName()}) edited by " . $username);
529
+	}
530
+	#endregion
531 531
 }
Please login to merge, or discard this patch.
includes/Helpers/Logger.php 1 patch
Indentation   +423 added lines, -423 removed lines patch added patch discarded remove patch
@@ -35,427 +35,427 @@
 block discarded – undo
35 35
  */
36 36
 class Logger
37 37
 {
38
-    /**
39
-     * @param PdoDatabase $database
40
-     * @param Request     $object
41
-     */
42
-    public static function emailConfirmed(PdoDatabase $database, Request $object)
43
-    {
44
-        self::createLogEntry($database, $object, "Email Confirmed", null, User::getCommunity());
45
-    }
46
-
47
-    /**
48
-     * @param PdoDatabase $database
49
-     * @param DataObject  $object
50
-     * @param string      $logAction
51
-     * @param null|string $comment
52
-     * @param User|null   $user
53
-     * @param int|null    $domain
54
-     *
55
-     * @throws Exception
56
-     */
57
-    private static function createLogEntry(
58
-        PdoDatabase $database,
59
-        DataObject $object,
60
-        $logAction,
61
-        $comment = null,
62
-        $user = null,
63
-        ?int $domain = null
64
-    ) {
65
-        if ($user == null) {
66
-            $user = User::getCurrent($database);
67
-        }
68
-
69
-        $objectType = get_class($object);
70
-        if (strpos($objectType, 'Waca\\DataObjects\\') !== false) {
71
-            $objectType = str_replace('Waca\\DataObjects\\', '', $objectType);
72
-        }
73
-
74
-        $log = new Log();
75
-
76
-        if ($domain !== null) {
77
-            $log->setDomain($domain);
78
-        }
79
-        elseif (method_exists($object, 'getDomain')) {
80
-            $log->setDomain($object->getDomain());
81
-        }
82
-
83
-        $log->setDatabase($database);
84
-        $log->setAction($logAction);
85
-        $log->setObjectId($object->getId());
86
-        $log->setObjectType($objectType);
87
-        $log->setUser($user);
88
-        $log->setComment($comment);
89
-        $log->save();
90
-    }
91
-
92
-    #region Users
93
-
94
-    /**
95
-     * @throws Exception
96
-     */
97
-    public static function newUser(PdoDatabase $database, User $user)
98
-    {
99
-        self::createLogEntry($database, $user, 'Registered', null, User::getCommunity());
100
-    }
101
-
102
-    /**
103
-     * @throws Exception
104
-     */
105
-    public static function approvedUser(PdoDatabase $database, User $object)
106
-    {
107
-        self::createLogEntry($database, $object, "Approved");
108
-    }
109
-
110
-    /**
111
-     * @throws Exception
112
-     */
113
-    public static function deactivatedUser(PdoDatabase $database, User $object, string $comment)
114
-    {
115
-        self::createLogEntry($database, $object, 'DeactivatedUser', $comment);
116
-    }
117
-
118
-    /**
119
-     * @throws Exception
120
-     */
121
-    public static function requestedReactivation(PdoDatabase $database, User $object, string $comment)
122
-    {
123
-        self::createLogEntry($database, $object, 'RequestedReactivation', $comment);
124
-    }
125
-
126
-    /**
127
-     * @throws Exception
128
-     */
129
-    public static function renamedUser(PdoDatabase $database, User $object, string $comment)
130
-    {
131
-        self::createLogEntry($database, $object, "Renamed", $comment);
132
-    }
133
-
134
-    /**
135
-     * @throws Exception
136
-     */
137
-    public static function userPreferencesChange(PdoDatabase $database, User $object)
138
-    {
139
-        self::createLogEntry($database, $object, "Prefchange");
140
-    }
141
-
142
-    /**
143
-     * @throws Exception
144
-     */
145
-    public static function userRolesEdited(
146
-        PdoDatabase $database,
147
-        User $object,
148
-        string $reason,
149
-        array $added,
150
-        array $removed,
151
-        int $domain
152
-    ) {
153
-        $logData = serialize(array(
154
-            'added'   => $added,
155
-            'removed' => $removed,
156
-            'reason'  => $reason,
157
-        ));
158
-
159
-        self::createLogEntry($database, $object, "RoleChange", $logData, null, $domain);
160
-    }
161
-
162
-    /**
163
-     * @throws Exception
164
-     */
165
-    public static function userGlobalRolesEdited(
166
-        PdoDatabase $database,
167
-        User $object,
168
-        string $reason,
169
-        array $added,
170
-        array $removed
171
-    ): void {
172
-        $logData = serialize(array(
173
-            'added' => $added,
174
-            'removed' => $removed,
175
-            'reason' => $reason,
176
-        ));
177
-
178
-        self::createLogEntry($database, $object, "GlobalRoleChange", $logData);
179
-    }
180
-
181
-    #endregion
182
-
183
-    /**
184
-     * @param PdoDatabase $database
185
-     * @param SiteNotice  $object
186
-     */
187
-    public static function siteNoticeEdited(PdoDatabase $database, SiteNotice $object)
188
-    {
189
-        self::createLogEntry($database, $object, "Edited");
190
-    }
191
-
192
-    #region Welcome Templates
193
-
194
-    /**
195
-     * @param PdoDatabase     $database
196
-     * @param WelcomeTemplate $object
197
-     */
198
-    public static function welcomeTemplateCreated(PdoDatabase $database, WelcomeTemplate $object)
199
-    {
200
-        self::createLogEntry($database, $object, "CreatedTemplate");
201
-    }
202
-
203
-    /**
204
-     * @param PdoDatabase     $database
205
-     * @param WelcomeTemplate $object
206
-     */
207
-    public static function welcomeTemplateEdited(PdoDatabase $database, WelcomeTemplate $object)
208
-    {
209
-        self::createLogEntry($database, $object, "EditedTemplate");
210
-    }
211
-
212
-    /**
213
-     * @param PdoDatabase     $database
214
-     * @param WelcomeTemplate $object
215
-     */
216
-    public static function welcomeTemplateDeleted(PdoDatabase $database, WelcomeTemplate $object)
217
-    {
218
-        self::createLogEntry($database, $object, "DeletedTemplate");
219
-    }
220
-
221
-    #endregion
222
-
223
-    #region Bans
224
-
225
-    /**
226
-     * @param PdoDatabase $database
227
-     * @param Ban         $object
228
-     * @param string      $reason
229
-     */
230
-    public static function banned(PdoDatabase $database, Ban $object, $reason)
231
-    {
232
-        self::createLogEntry($database, $object, "Banned", $reason);
233
-    }
234
-
235
-    /**
236
-     * @param PdoDatabase $database
237
-     * @param Ban         $object
238
-     * @param string      $reason
239
-     */
240
-    public static function unbanned(PdoDatabase $database, Ban $object, $reason)
241
-    {
242
-        self::createLogEntry($database, $object, "Unbanned", $reason);
243
-    }
244
-
245
-    public static function banReplaced(PdoDatabase $database, Ban $object)
246
-    {
247
-        self::createLogEntry($database, $object, "BanReplaced");
248
-    }
249
-
250
-    #endregion
251
-
252
-    #region Requests
253
-
254
-    /**
255
-     * @param PdoDatabase $database
256
-     * @param Request     $object
257
-     * @param string      $target
258
-     */
259
-    public static function deferRequest(PdoDatabase $database, Request $object, $target)
260
-    {
261
-        self::createLogEntry($database, $object, "Deferred to $target");
262
-    }
263
-
264
-    /**
265
-     * @param PdoDatabase $database
266
-     * @param Request     $object
267
-     * @param integer     $target
268
-     * @param string      $comment
269
-     * @param User|null   $logUser
270
-     */
271
-    public static function closeRequest(PdoDatabase $database, Request $object, $target, $comment, User $logUser = null)
272
-    {
273
-        self::createLogEntry($database, $object, "Closed $target", $comment, $logUser);
274
-    }
275
-
276
-    public static function manuallyConfirmRequest(PdoDatabase $database, Request $object)
277
-    {
278
-        self::createLogEntry($database, $object, "Manually Confirmed");
279
-    }
280
-
281
-    /**
282
-     * @param PdoDatabase $database
283
-     * @param Request     $object
284
-     */
285
-    public static function reserve(PdoDatabase $database, Request $object)
286
-    {
287
-        self::createLogEntry($database, $object, "Reserved");
288
-    }
289
-
290
-    /**
291
-     * @param PdoDatabase $database
292
-     * @param Request     $object
293
-     */
294
-    public static function breakReserve(PdoDatabase $database, Request $object)
295
-    {
296
-        self::createLogEntry($database, $object, "BreakReserve");
297
-    }
298
-
299
-    /**
300
-     * @param PdoDatabase $database
301
-     * @param Request     $object
302
-     */
303
-    public static function unreserve(PdoDatabase $database, Request $object)
304
-    {
305
-        self::createLogEntry($database, $object, "Unreserved");
306
-    }
307
-
308
-    /**
309
-     * @param PdoDatabase $database
310
-     * @param Comment     $object
311
-     * @param Request     $request
312
-     */
313
-    public static function editComment(PdoDatabase $database, Comment $object, Request $request)
314
-    {
315
-        self::createLogEntry($database, $request, "EditComment-r");
316
-        self::createLogEntry($database, $object, "EditComment-c", null, null, $request->getDomain());
317
-    }
318
-
319
-    /**
320
-     * @param PdoDatabase $database
321
-     * @param Comment     $object
322
-     */
323
-    public static function flaggedComment(PdoDatabase $database, Comment $object, int $domain)
324
-    {
325
-        self::createLogEntry($database, $object, "FlaggedComment", null, null, $domain);
326
-    }
327
-
328
-    /**
329
-     * @param PdoDatabase $database
330
-     * @param Comment     $object
331
-     */
332
-    public static function unflaggedComment(PdoDatabase $database, Comment $object, int $domain)
333
-    {
334
-        self::createLogEntry($database, $object, "UnflaggedComment", null, null, $domain);
335
-    }
336
-
337
-    /**
338
-     * @param PdoDatabase $database
339
-     * @param Request     $object
340
-     * @param User        $target
341
-     */
342
-    public static function sendReservation(PdoDatabase $database, Request $object, User $target)
343
-    {
344
-        self::createLogEntry($database, $object, "SendReserved");
345
-        self::createLogEntry($database, $object, "ReceiveReserved", null, $target);
346
-    }
347
-
348
-    /**
349
-     * @param PdoDatabase $database
350
-     * @param Request     $object
351
-     * @param string      $comment
352
-     */
353
-    public static function sentMail(PdoDatabase $database, Request $object, $comment)
354
-    {
355
-        self::createLogEntry($database, $object, "SentMail", $comment);
356
-    }
357
-
358
-    /**
359
-     * @param PdoDatabase $database
360
-     * @param Request     $object
361
-     */
362
-    public static function enqueuedJobQueue(PdoDatabase $database, Request $object)
363
-    {
364
-        self::createLogEntry($database, $object, 'EnqueuedJobQueue');
365
-    }
366
-
367
-    public static function hospitalised(PdoDatabase $database, Request $object)
368
-    {
369
-        self::createLogEntry($database, $object, 'Hospitalised');
370
-    }
371
-    #endregion
372
-
373
-    #region Email templates
374
-
375
-    /**
376
-     * @param PdoDatabase   $database
377
-     * @param EmailTemplate $object
378
-     */
379
-    public static function createEmail(PdoDatabase $database, EmailTemplate $object)
380
-    {
381
-        self::createLogEntry($database, $object, "CreatedEmail");
382
-    }
383
-
384
-    /**
385
-     * @param PdoDatabase   $database
386
-     * @param EmailTemplate $object
387
-     */
388
-    public static function editedEmail(PdoDatabase $database, EmailTemplate $object)
389
-    {
390
-        self::createLogEntry($database, $object, "EditedEmail");
391
-    }
392
-
393
-    #endregion
394
-
395
-    #region Display
396
-
397
-    #endregion
398
-
399
-    #region Automation
400
-
401
-    public static function backgroundJobComplete(PdoDatabase $database, JobQueue $job)
402
-    {
403
-        self::createLogEntry($database, $job, 'JobCompleted', null, User::getCommunity());
404
-    }
405
-
406
-    public static function backgroundJobIssue(PdoDatabase $database, JobQueue $job)
407
-    {
408
-        $data = array('status' => $job->getStatus(), 'error' => $job->getError());
409
-        self::createLogEntry($database, $job, 'JobIssue', serialize($data), User::getCommunity());
410
-    }
411
-
412
-    public static function backgroundJobCancelled(PdoDatabase $database, JobQueue $job)
413
-    {
414
-        self::createLogEntry($database, $job, 'JobCancelled', $job->getError());
415
-    }
416
-
417
-    public static function backgroundJobRequeued(PdoDatabase $database, JobQueue $job)
418
-    {
419
-        self::createLogEntry($database, $job, 'JobRequeued');
420
-    }
421
-
422
-    public static function backgroundJobAcknowledged(PdoDatabase $database, JobQueue $job, $comment = null)
423
-    {
424
-        self::createLogEntry($database, $job, 'JobAcknowledged', $comment);
425
-    }
426
-    #endregion
427
-
428
-    #region Request Queues
429
-    public static function requestQueueCreated(PdoDatabase $database, RequestQueue $queue)
430
-    {
431
-        self::createLogEntry($database, $queue, 'QueueCreated');
432
-    }
433
-
434
-    public static function requestQueueEdited(PdoDatabase $database, RequestQueue $queue)
435
-    {
436
-        self::createLogEntry($database, $queue, 'QueueEdited');
437
-    }
438
-    #endregion
439
-    #region Domains
440
-    public static function domainCreated(PdoDatabase $database, Domain $domain)
441
-    {
442
-        self::createLogEntry($database, $domain, 'DomainCreated');
443
-    }
444
-
445
-    public static function domainEdited(PdoDatabase $database, Domain $domain)
446
-    {
447
-        self::createLogEntry($database, $domain, 'DomainEdited');
448
-    }
449
-    #endregion
450
-    #region Request Forms
451
-    public static function requestFormCreated(PdoDatabase $database, RequestForm $requestForm)
452
-    {
453
-        self::createLogEntry($database, $requestForm, 'RequestFormCreated');
454
-    }
455
-
456
-    public static function requestFormEdited(PdoDatabase $database, RequestForm $requestForm)
457
-    {
458
-        self::createLogEntry($database, $requestForm, 'RequestFormEdited');
459
-    }
460
-    #endregion
38
+	/**
39
+	 * @param PdoDatabase $database
40
+	 * @param Request     $object
41
+	 */
42
+	public static function emailConfirmed(PdoDatabase $database, Request $object)
43
+	{
44
+		self::createLogEntry($database, $object, "Email Confirmed", null, User::getCommunity());
45
+	}
46
+
47
+	/**
48
+	 * @param PdoDatabase $database
49
+	 * @param DataObject  $object
50
+	 * @param string      $logAction
51
+	 * @param null|string $comment
52
+	 * @param User|null   $user
53
+	 * @param int|null    $domain
54
+	 *
55
+	 * @throws Exception
56
+	 */
57
+	private static function createLogEntry(
58
+		PdoDatabase $database,
59
+		DataObject $object,
60
+		$logAction,
61
+		$comment = null,
62
+		$user = null,
63
+		?int $domain = null
64
+	) {
65
+		if ($user == null) {
66
+			$user = User::getCurrent($database);
67
+		}
68
+
69
+		$objectType = get_class($object);
70
+		if (strpos($objectType, 'Waca\\DataObjects\\') !== false) {
71
+			$objectType = str_replace('Waca\\DataObjects\\', '', $objectType);
72
+		}
73
+
74
+		$log = new Log();
75
+
76
+		if ($domain !== null) {
77
+			$log->setDomain($domain);
78
+		}
79
+		elseif (method_exists($object, 'getDomain')) {
80
+			$log->setDomain($object->getDomain());
81
+		}
82
+
83
+		$log->setDatabase($database);
84
+		$log->setAction($logAction);
85
+		$log->setObjectId($object->getId());
86
+		$log->setObjectType($objectType);
87
+		$log->setUser($user);
88
+		$log->setComment($comment);
89
+		$log->save();
90
+	}
91
+
92
+	#region Users
93
+
94
+	/**
95
+	 * @throws Exception
96
+	 */
97
+	public static function newUser(PdoDatabase $database, User $user)
98
+	{
99
+		self::createLogEntry($database, $user, 'Registered', null, User::getCommunity());
100
+	}
101
+
102
+	/**
103
+	 * @throws Exception
104
+	 */
105
+	public static function approvedUser(PdoDatabase $database, User $object)
106
+	{
107
+		self::createLogEntry($database, $object, "Approved");
108
+	}
109
+
110
+	/**
111
+	 * @throws Exception
112
+	 */
113
+	public static function deactivatedUser(PdoDatabase $database, User $object, string $comment)
114
+	{
115
+		self::createLogEntry($database, $object, 'DeactivatedUser', $comment);
116
+	}
117
+
118
+	/**
119
+	 * @throws Exception
120
+	 */
121
+	public static function requestedReactivation(PdoDatabase $database, User $object, string $comment)
122
+	{
123
+		self::createLogEntry($database, $object, 'RequestedReactivation', $comment);
124
+	}
125
+
126
+	/**
127
+	 * @throws Exception
128
+	 */
129
+	public static function renamedUser(PdoDatabase $database, User $object, string $comment)
130
+	{
131
+		self::createLogEntry($database, $object, "Renamed", $comment);
132
+	}
133
+
134
+	/**
135
+	 * @throws Exception
136
+	 */
137
+	public static function userPreferencesChange(PdoDatabase $database, User $object)
138
+	{
139
+		self::createLogEntry($database, $object, "Prefchange");
140
+	}
141
+
142
+	/**
143
+	 * @throws Exception
144
+	 */
145
+	public static function userRolesEdited(
146
+		PdoDatabase $database,
147
+		User $object,
148
+		string $reason,
149
+		array $added,
150
+		array $removed,
151
+		int $domain
152
+	) {
153
+		$logData = serialize(array(
154
+			'added'   => $added,
155
+			'removed' => $removed,
156
+			'reason'  => $reason,
157
+		));
158
+
159
+		self::createLogEntry($database, $object, "RoleChange", $logData, null, $domain);
160
+	}
161
+
162
+	/**
163
+	 * @throws Exception
164
+	 */
165
+	public static function userGlobalRolesEdited(
166
+		PdoDatabase $database,
167
+		User $object,
168
+		string $reason,
169
+		array $added,
170
+		array $removed
171
+	): void {
172
+		$logData = serialize(array(
173
+			'added' => $added,
174
+			'removed' => $removed,
175
+			'reason' => $reason,
176
+		));
177
+
178
+		self::createLogEntry($database, $object, "GlobalRoleChange", $logData);
179
+	}
180
+
181
+	#endregion
182
+
183
+	/**
184
+	 * @param PdoDatabase $database
185
+	 * @param SiteNotice  $object
186
+	 */
187
+	public static function siteNoticeEdited(PdoDatabase $database, SiteNotice $object)
188
+	{
189
+		self::createLogEntry($database, $object, "Edited");
190
+	}
191
+
192
+	#region Welcome Templates
193
+
194
+	/**
195
+	 * @param PdoDatabase     $database
196
+	 * @param WelcomeTemplate $object
197
+	 */
198
+	public static function welcomeTemplateCreated(PdoDatabase $database, WelcomeTemplate $object)
199
+	{
200
+		self::createLogEntry($database, $object, "CreatedTemplate");
201
+	}
202
+
203
+	/**
204
+	 * @param PdoDatabase     $database
205
+	 * @param WelcomeTemplate $object
206
+	 */
207
+	public static function welcomeTemplateEdited(PdoDatabase $database, WelcomeTemplate $object)
208
+	{
209
+		self::createLogEntry($database, $object, "EditedTemplate");
210
+	}
211
+
212
+	/**
213
+	 * @param PdoDatabase     $database
214
+	 * @param WelcomeTemplate $object
215
+	 */
216
+	public static function welcomeTemplateDeleted(PdoDatabase $database, WelcomeTemplate $object)
217
+	{
218
+		self::createLogEntry($database, $object, "DeletedTemplate");
219
+	}
220
+
221
+	#endregion
222
+
223
+	#region Bans
224
+
225
+	/**
226
+	 * @param PdoDatabase $database
227
+	 * @param Ban         $object
228
+	 * @param string      $reason
229
+	 */
230
+	public static function banned(PdoDatabase $database, Ban $object, $reason)
231
+	{
232
+		self::createLogEntry($database, $object, "Banned", $reason);
233
+	}
234
+
235
+	/**
236
+	 * @param PdoDatabase $database
237
+	 * @param Ban         $object
238
+	 * @param string      $reason
239
+	 */
240
+	public static function unbanned(PdoDatabase $database, Ban $object, $reason)
241
+	{
242
+		self::createLogEntry($database, $object, "Unbanned", $reason);
243
+	}
244
+
245
+	public static function banReplaced(PdoDatabase $database, Ban $object)
246
+	{
247
+		self::createLogEntry($database, $object, "BanReplaced");
248
+	}
249
+
250
+	#endregion
251
+
252
+	#region Requests
253
+
254
+	/**
255
+	 * @param PdoDatabase $database
256
+	 * @param Request     $object
257
+	 * @param string      $target
258
+	 */
259
+	public static function deferRequest(PdoDatabase $database, Request $object, $target)
260
+	{
261
+		self::createLogEntry($database, $object, "Deferred to $target");
262
+	}
263
+
264
+	/**
265
+	 * @param PdoDatabase $database
266
+	 * @param Request     $object
267
+	 * @param integer     $target
268
+	 * @param string      $comment
269
+	 * @param User|null   $logUser
270
+	 */
271
+	public static function closeRequest(PdoDatabase $database, Request $object, $target, $comment, User $logUser = null)
272
+	{
273
+		self::createLogEntry($database, $object, "Closed $target", $comment, $logUser);
274
+	}
275
+
276
+	public static function manuallyConfirmRequest(PdoDatabase $database, Request $object)
277
+	{
278
+		self::createLogEntry($database, $object, "Manually Confirmed");
279
+	}
280
+
281
+	/**
282
+	 * @param PdoDatabase $database
283
+	 * @param Request     $object
284
+	 */
285
+	public static function reserve(PdoDatabase $database, Request $object)
286
+	{
287
+		self::createLogEntry($database, $object, "Reserved");
288
+	}
289
+
290
+	/**
291
+	 * @param PdoDatabase $database
292
+	 * @param Request     $object
293
+	 */
294
+	public static function breakReserve(PdoDatabase $database, Request $object)
295
+	{
296
+		self::createLogEntry($database, $object, "BreakReserve");
297
+	}
298
+
299
+	/**
300
+	 * @param PdoDatabase $database
301
+	 * @param Request     $object
302
+	 */
303
+	public static function unreserve(PdoDatabase $database, Request $object)
304
+	{
305
+		self::createLogEntry($database, $object, "Unreserved");
306
+	}
307
+
308
+	/**
309
+	 * @param PdoDatabase $database
310
+	 * @param Comment     $object
311
+	 * @param Request     $request
312
+	 */
313
+	public static function editComment(PdoDatabase $database, Comment $object, Request $request)
314
+	{
315
+		self::createLogEntry($database, $request, "EditComment-r");
316
+		self::createLogEntry($database, $object, "EditComment-c", null, null, $request->getDomain());
317
+	}
318
+
319
+	/**
320
+	 * @param PdoDatabase $database
321
+	 * @param Comment     $object
322
+	 */
323
+	public static function flaggedComment(PdoDatabase $database, Comment $object, int $domain)
324
+	{
325
+		self::createLogEntry($database, $object, "FlaggedComment", null, null, $domain);
326
+	}
327
+
328
+	/**
329
+	 * @param PdoDatabase $database
330
+	 * @param Comment     $object
331
+	 */
332
+	public static function unflaggedComment(PdoDatabase $database, Comment $object, int $domain)
333
+	{
334
+		self::createLogEntry($database, $object, "UnflaggedComment", null, null, $domain);
335
+	}
336
+
337
+	/**
338
+	 * @param PdoDatabase $database
339
+	 * @param Request     $object
340
+	 * @param User        $target
341
+	 */
342
+	public static function sendReservation(PdoDatabase $database, Request $object, User $target)
343
+	{
344
+		self::createLogEntry($database, $object, "SendReserved");
345
+		self::createLogEntry($database, $object, "ReceiveReserved", null, $target);
346
+	}
347
+
348
+	/**
349
+	 * @param PdoDatabase $database
350
+	 * @param Request     $object
351
+	 * @param string      $comment
352
+	 */
353
+	public static function sentMail(PdoDatabase $database, Request $object, $comment)
354
+	{
355
+		self::createLogEntry($database, $object, "SentMail", $comment);
356
+	}
357
+
358
+	/**
359
+	 * @param PdoDatabase $database
360
+	 * @param Request     $object
361
+	 */
362
+	public static function enqueuedJobQueue(PdoDatabase $database, Request $object)
363
+	{
364
+		self::createLogEntry($database, $object, 'EnqueuedJobQueue');
365
+	}
366
+
367
+	public static function hospitalised(PdoDatabase $database, Request $object)
368
+	{
369
+		self::createLogEntry($database, $object, 'Hospitalised');
370
+	}
371
+	#endregion
372
+
373
+	#region Email templates
374
+
375
+	/**
376
+	 * @param PdoDatabase   $database
377
+	 * @param EmailTemplate $object
378
+	 */
379
+	public static function createEmail(PdoDatabase $database, EmailTemplate $object)
380
+	{
381
+		self::createLogEntry($database, $object, "CreatedEmail");
382
+	}
383
+
384
+	/**
385
+	 * @param PdoDatabase   $database
386
+	 * @param EmailTemplate $object
387
+	 */
388
+	public static function editedEmail(PdoDatabase $database, EmailTemplate $object)
389
+	{
390
+		self::createLogEntry($database, $object, "EditedEmail");
391
+	}
392
+
393
+	#endregion
394
+
395
+	#region Display
396
+
397
+	#endregion
398
+
399
+	#region Automation
400
+
401
+	public static function backgroundJobComplete(PdoDatabase $database, JobQueue $job)
402
+	{
403
+		self::createLogEntry($database, $job, 'JobCompleted', null, User::getCommunity());
404
+	}
405
+
406
+	public static function backgroundJobIssue(PdoDatabase $database, JobQueue $job)
407
+	{
408
+		$data = array('status' => $job->getStatus(), 'error' => $job->getError());
409
+		self::createLogEntry($database, $job, 'JobIssue', serialize($data), User::getCommunity());
410
+	}
411
+
412
+	public static function backgroundJobCancelled(PdoDatabase $database, JobQueue $job)
413
+	{
414
+		self::createLogEntry($database, $job, 'JobCancelled', $job->getError());
415
+	}
416
+
417
+	public static function backgroundJobRequeued(PdoDatabase $database, JobQueue $job)
418
+	{
419
+		self::createLogEntry($database, $job, 'JobRequeued');
420
+	}
421
+
422
+	public static function backgroundJobAcknowledged(PdoDatabase $database, JobQueue $job, $comment = null)
423
+	{
424
+		self::createLogEntry($database, $job, 'JobAcknowledged', $comment);
425
+	}
426
+	#endregion
427
+
428
+	#region Request Queues
429
+	public static function requestQueueCreated(PdoDatabase $database, RequestQueue $queue)
430
+	{
431
+		self::createLogEntry($database, $queue, 'QueueCreated');
432
+	}
433
+
434
+	public static function requestQueueEdited(PdoDatabase $database, RequestQueue $queue)
435
+	{
436
+		self::createLogEntry($database, $queue, 'QueueEdited');
437
+	}
438
+	#endregion
439
+	#region Domains
440
+	public static function domainCreated(PdoDatabase $database, Domain $domain)
441
+	{
442
+		self::createLogEntry($database, $domain, 'DomainCreated');
443
+	}
444
+
445
+	public static function domainEdited(PdoDatabase $database, Domain $domain)
446
+	{
447
+		self::createLogEntry($database, $domain, 'DomainEdited');
448
+	}
449
+	#endregion
450
+	#region Request Forms
451
+	public static function requestFormCreated(PdoDatabase $database, RequestForm $requestForm)
452
+	{
453
+		self::createLogEntry($database, $requestForm, 'RequestFormCreated');
454
+	}
455
+
456
+	public static function requestFormEdited(PdoDatabase $database, RequestForm $requestForm)
457
+	{
458
+		self::createLogEntry($database, $requestForm, 'RequestFormEdited');
459
+	}
460
+	#endregion
461 461
 }
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.