Failed Conditions
Push — newinternal-releasecandidate ( 327c61...a30d14 )
by Simon
15:28 queued 05:26
created
includes/Tasks/InternalPageBase.php 1 patch
Indentation   +224 added lines, -224 removed lines patch added patch discarded remove patch
@@ -23,228 +23,228 @@
 block discarded – undo
23 23
 
24 24
 abstract class InternalPageBase extends PageBase
25 25
 {
26
-    use NavigationMenuAccessControl;
27
-
28
-    /** @var IdentificationVerifier */
29
-    private $identificationVerifier;
30
-    /** @var ITypeAheadHelper */
31
-    private $typeAheadHelper;
32
-    /** @var SecurityManager */
33
-    private $securityManager;
34
-    /** @var IBlacklistHelper */
35
-    private $blacklistHelper;
36
-
37
-    /**
38
-     * @return ITypeAheadHelper
39
-     */
40
-    public function getTypeAheadHelper()
41
-    {
42
-        return $this->typeAheadHelper;
43
-    }
44
-
45
-    /**
46
-     * Sets up the internal IdentificationVerifier instance.  Intended to be called from WebStart::setupHelpers().
47
-     *
48
-     * @param IdentificationVerifier $identificationVerifier
49
-     *
50
-     * @return void
51
-     */
52
-    public function setIdentificationVerifier(IdentificationVerifier $identificationVerifier)
53
-    {
54
-        $this->identificationVerifier = $identificationVerifier;
55
-    }
56
-
57
-    /**
58
-     * @param ITypeAheadHelper $typeAheadHelper
59
-     */
60
-    public function setTypeAheadHelper(ITypeAheadHelper $typeAheadHelper)
61
-    {
62
-        $this->typeAheadHelper = $typeAheadHelper;
63
-    }
64
-
65
-    /**
66
-     * Runs the page code
67
-     *
68
-     * @throws Exception
69
-     * @category Security-Critical
70
-     */
71
-    final public function execute()
72
-    {
73
-        if ($this->getRouteName() === null) {
74
-            throw new Exception("Request is unrouted.");
75
-        }
76
-
77
-        if ($this->getSiteConfiguration() === null) {
78
-            throw new Exception("Page has no configuration!");
79
-        }
80
-
81
-        $this->setupPage();
82
-
83
-        $this->touchUserLastActive();
84
-
85
-        $currentUser = User::getCurrent($this->getDatabase());
86
-
87
-        // Hey, this is also a security barrier, in addition to the below. Separated out for readability.
88
-        if (!$this->isProtectedPage()) {
89
-            // This page is /not/ a protected page, as such we can just run it.
90
-            $this->runPage();
91
-
92
-            return;
93
-        }
94
-
95
-        // Security barrier.
96
-        //
97
-        // This code essentially doesn't care if the user is logged in or not, as the security manager hides all that
98
-        // away for us
99
-        $securityResult = $this->getSecurityManager()->allows(get_called_class(), $this->getRouteName(), $currentUser);
100
-        if ($securityResult === SecurityManager::ALLOWED) {
101
-            // We're allowed to run the page, so let's run it.
102
-            $this->runPage();
103
-        }
104
-        else {
105
-            $this->handleAccessDenied($securityResult);
106
-
107
-            // Send the headers
108
-            $this->sendResponseHeaders();
109
-        }
110
-    }
111
-
112
-    /**
113
-     * Performs final tasks needed before rendering the page.
114
-     */
115
-    final public function finalisePage()
116
-    {
117
-        parent::finalisePage();
118
-
119
-        $database = $this->getDatabase();
120
-        $currentUser = User::getCurrent($database);
121
-
122
-        if ($this->barrierTest('viewSiteNotice', User::getCurrent($database), 'GlobalInfo')) {
123
-            $siteNoticeText = SiteNotice::get($this->getDatabase());
124
-            $this->assign('siteNoticeText', $siteNoticeText);
125
-        }
126
-
127
-        if ($this->barrierTest('viewOnlineUsers', User::getCurrent($database), 'GlobalInfo')) {
128
-            $sql = 'SELECT * FROM user WHERE lastactive > DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 5 MINUTE);';
129
-            $statement = $database->query($sql);
130
-            $activeUsers = $statement->fetchAll(PDO::FETCH_CLASS, User::class);
131
-            $this->assign('onlineusers', $activeUsers);
132
-        }
133
-
134
-        $this->setupNavMenuAccess($currentUser);
135
-    }
136
-
137
-    /**
138
-     * Configures whether the page respects roles or not. You probably want this to return true.
139
-     *
140
-     * Set to false for public pages. You probably want this to return true.
141
-     *
142
-     * This defaults to true unless you explicitly set it to false. Setting it to false means anybody can do anything
143
-     * on this page, so you probably want this to return true.
144
-     *
145
-     * @return bool
146
-     * @category Security-Critical
147
-     */
148
-    protected function isProtectedPage()
149
-    {
150
-        return true;
151
-    }
152
-
153
-    protected function handleAccessDenied($denyReason)
154
-    {
155
-        $currentUser = User::getCurrent($this->getDatabase());
156
-
157
-        // Not allowed to access this resource.
158
-        // Firstly, let's check if we're even logged in.
159
-        if ($currentUser->isCommunityUser()) {
160
-            // Not logged in, redirect to login page
161
-            WebRequest::setPostLoginRedirect();
162
-            $this->redirect("login");
163
-
164
-            return;
165
-        }
166
-        else {
167
-            // Decide whether this was a rights failure, or an identification failure.
168
-
169
-            if ($denyReason === SecurityManager::ERROR_NOT_IDENTIFIED) {
170
-                // Not identified
171
-                throw new NotIdentifiedException($this->getSecurityManager());
172
-            }
173
-            elseif ($denyReason === SecurityManager::ERROR_DENIED) {
174
-                // Nope, plain old access denied
175
-                throw new AccessDeniedException($this->getSecurityManager());
176
-            }
177
-            else {
178
-                throw new Exception('Unknown response from security manager.');
179
-            }
180
-        }
181
-    }
182
-
183
-    /**
184
-     * Tests the security barrier for a specified action.
185
-     *
186
-     * Don't use within templates
187
-     *
188
-     * @param string      $action
189
-     *
190
-     * @param User        $user
191
-     * @param null|string $pageName
192
-     *
193
-     * @return bool
194
-     * @category Security-Critical
195
-     */
196
-    final public function barrierTest($action, User $user, $pageName = null)
197
-    {
198
-        $page = get_called_class();
199
-        if ($pageName !== null) {
200
-            $page = $pageName;
201
-        }
202
-
203
-        $securityResult = $this->getSecurityManager()->allows($page, $action, $user);
204
-
205
-        return $securityResult === SecurityManager::ALLOWED;
206
-    }
207
-
208
-    /**
209
-     * Updates the lastactive timestamp
210
-     */
211
-    private function touchUserLastActive()
212
-    {
213
-        if (WebRequest::getSessionUserId() !== null) {
214
-            $query = 'UPDATE user SET lastactive = CURRENT_TIMESTAMP() WHERE id = :id;';
215
-            $this->getDatabase()->prepare($query)->execute(array(":id" => WebRequest::getSessionUserId()));
216
-        }
217
-    }
218
-
219
-    /**
220
-     * @return SecurityManager
221
-     */
222
-    public function getSecurityManager()
223
-    {
224
-        return $this->securityManager;
225
-    }
226
-
227
-    /**
228
-     * @param SecurityManager $securityManager
229
-     */
230
-    public function setSecurityManager(SecurityManager $securityManager)
231
-    {
232
-        $this->securityManager = $securityManager;
233
-    }
234
-
235
-    /**
236
-     * @return IBlacklistHelper
237
-     */
238
-    public function getBlacklistHelper()
239
-    {
240
-        return $this->blacklistHelper;
241
-    }
242
-
243
-    /**
244
-     * @param IBlacklistHelper $blacklistHelper
245
-     */
246
-    public function setBlacklistHelper(IBlacklistHelper $blacklistHelper)
247
-    {
248
-        $this->blacklistHelper = $blacklistHelper;
249
-    }
26
+	use NavigationMenuAccessControl;
27
+
28
+	/** @var IdentificationVerifier */
29
+	private $identificationVerifier;
30
+	/** @var ITypeAheadHelper */
31
+	private $typeAheadHelper;
32
+	/** @var SecurityManager */
33
+	private $securityManager;
34
+	/** @var IBlacklistHelper */
35
+	private $blacklistHelper;
36
+
37
+	/**
38
+	 * @return ITypeAheadHelper
39
+	 */
40
+	public function getTypeAheadHelper()
41
+	{
42
+		return $this->typeAheadHelper;
43
+	}
44
+
45
+	/**
46
+	 * Sets up the internal IdentificationVerifier instance.  Intended to be called from WebStart::setupHelpers().
47
+	 *
48
+	 * @param IdentificationVerifier $identificationVerifier
49
+	 *
50
+	 * @return void
51
+	 */
52
+	public function setIdentificationVerifier(IdentificationVerifier $identificationVerifier)
53
+	{
54
+		$this->identificationVerifier = $identificationVerifier;
55
+	}
56
+
57
+	/**
58
+	 * @param ITypeAheadHelper $typeAheadHelper
59
+	 */
60
+	public function setTypeAheadHelper(ITypeAheadHelper $typeAheadHelper)
61
+	{
62
+		$this->typeAheadHelper = $typeAheadHelper;
63
+	}
64
+
65
+	/**
66
+	 * Runs the page code
67
+	 *
68
+	 * @throws Exception
69
+	 * @category Security-Critical
70
+	 */
71
+	final public function execute()
72
+	{
73
+		if ($this->getRouteName() === null) {
74
+			throw new Exception("Request is unrouted.");
75
+		}
76
+
77
+		if ($this->getSiteConfiguration() === null) {
78
+			throw new Exception("Page has no configuration!");
79
+		}
80
+
81
+		$this->setupPage();
82
+
83
+		$this->touchUserLastActive();
84
+
85
+		$currentUser = User::getCurrent($this->getDatabase());
86
+
87
+		// Hey, this is also a security barrier, in addition to the below. Separated out for readability.
88
+		if (!$this->isProtectedPage()) {
89
+			// This page is /not/ a protected page, as such we can just run it.
90
+			$this->runPage();
91
+
92
+			return;
93
+		}
94
+
95
+		// Security barrier.
96
+		//
97
+		// This code essentially doesn't care if the user is logged in or not, as the security manager hides all that
98
+		// away for us
99
+		$securityResult = $this->getSecurityManager()->allows(get_called_class(), $this->getRouteName(), $currentUser);
100
+		if ($securityResult === SecurityManager::ALLOWED) {
101
+			// We're allowed to run the page, so let's run it.
102
+			$this->runPage();
103
+		}
104
+		else {
105
+			$this->handleAccessDenied($securityResult);
106
+
107
+			// Send the headers
108
+			$this->sendResponseHeaders();
109
+		}
110
+	}
111
+
112
+	/**
113
+	 * Performs final tasks needed before rendering the page.
114
+	 */
115
+	final public function finalisePage()
116
+	{
117
+		parent::finalisePage();
118
+
119
+		$database = $this->getDatabase();
120
+		$currentUser = User::getCurrent($database);
121
+
122
+		if ($this->barrierTest('viewSiteNotice', User::getCurrent($database), 'GlobalInfo')) {
123
+			$siteNoticeText = SiteNotice::get($this->getDatabase());
124
+			$this->assign('siteNoticeText', $siteNoticeText);
125
+		}
126
+
127
+		if ($this->barrierTest('viewOnlineUsers', User::getCurrent($database), 'GlobalInfo')) {
128
+			$sql = 'SELECT * FROM user WHERE lastactive > DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 5 MINUTE);';
129
+			$statement = $database->query($sql);
130
+			$activeUsers = $statement->fetchAll(PDO::FETCH_CLASS, User::class);
131
+			$this->assign('onlineusers', $activeUsers);
132
+		}
133
+
134
+		$this->setupNavMenuAccess($currentUser);
135
+	}
136
+
137
+	/**
138
+	 * Configures whether the page respects roles or not. You probably want this to return true.
139
+	 *
140
+	 * Set to false for public pages. You probably want this to return true.
141
+	 *
142
+	 * This defaults to true unless you explicitly set it to false. Setting it to false means anybody can do anything
143
+	 * on this page, so you probably want this to return true.
144
+	 *
145
+	 * @return bool
146
+	 * @category Security-Critical
147
+	 */
148
+	protected function isProtectedPage()
149
+	{
150
+		return true;
151
+	}
152
+
153
+	protected function handleAccessDenied($denyReason)
154
+	{
155
+		$currentUser = User::getCurrent($this->getDatabase());
156
+
157
+		// Not allowed to access this resource.
158
+		// Firstly, let's check if we're even logged in.
159
+		if ($currentUser->isCommunityUser()) {
160
+			// Not logged in, redirect to login page
161
+			WebRequest::setPostLoginRedirect();
162
+			$this->redirect("login");
163
+
164
+			return;
165
+		}
166
+		else {
167
+			// Decide whether this was a rights failure, or an identification failure.
168
+
169
+			if ($denyReason === SecurityManager::ERROR_NOT_IDENTIFIED) {
170
+				// Not identified
171
+				throw new NotIdentifiedException($this->getSecurityManager());
172
+			}
173
+			elseif ($denyReason === SecurityManager::ERROR_DENIED) {
174
+				// Nope, plain old access denied
175
+				throw new AccessDeniedException($this->getSecurityManager());
176
+			}
177
+			else {
178
+				throw new Exception('Unknown response from security manager.');
179
+			}
180
+		}
181
+	}
182
+
183
+	/**
184
+	 * Tests the security barrier for a specified action.
185
+	 *
186
+	 * Don't use within templates
187
+	 *
188
+	 * @param string      $action
189
+	 *
190
+	 * @param User        $user
191
+	 * @param null|string $pageName
192
+	 *
193
+	 * @return bool
194
+	 * @category Security-Critical
195
+	 */
196
+	final public function barrierTest($action, User $user, $pageName = null)
197
+	{
198
+		$page = get_called_class();
199
+		if ($pageName !== null) {
200
+			$page = $pageName;
201
+		}
202
+
203
+		$securityResult = $this->getSecurityManager()->allows($page, $action, $user);
204
+
205
+		return $securityResult === SecurityManager::ALLOWED;
206
+	}
207
+
208
+	/**
209
+	 * Updates the lastactive timestamp
210
+	 */
211
+	private function touchUserLastActive()
212
+	{
213
+		if (WebRequest::getSessionUserId() !== null) {
214
+			$query = 'UPDATE user SET lastactive = CURRENT_TIMESTAMP() WHERE id = :id;';
215
+			$this->getDatabase()->prepare($query)->execute(array(":id" => WebRequest::getSessionUserId()));
216
+		}
217
+	}
218
+
219
+	/**
220
+	 * @return SecurityManager
221
+	 */
222
+	public function getSecurityManager()
223
+	{
224
+		return $this->securityManager;
225
+	}
226
+
227
+	/**
228
+	 * @param SecurityManager $securityManager
229
+	 */
230
+	public function setSecurityManager(SecurityManager $securityManager)
231
+	{
232
+		$this->securityManager = $securityManager;
233
+	}
234
+
235
+	/**
236
+	 * @return IBlacklistHelper
237
+	 */
238
+	public function getBlacklistHelper()
239
+	{
240
+		return $this->blacklistHelper;
241
+	}
242
+
243
+	/**
244
+	 * @param IBlacklistHelper $blacklistHelper
245
+	 */
246
+	public function setBlacklistHelper(IBlacklistHelper $blacklistHelper)
247
+	{
248
+		$this->blacklistHelper = $blacklistHelper;
249
+	}
250 250
 }
Please login to merge, or discard this patch.
includes/Tasks/PageBase.php 1 patch
Indentation   +353 added lines, -353 removed lines patch added patch discarded remove patch
@@ -23,357 +23,357 @@
 block discarded – undo
23 23
 
24 24
 abstract class PageBase extends TaskBase implements IRoutedTask
25 25
 {
26
-    use TemplateOutput;
27
-    /** @var string Smarty template to display */
28
-    protected $template = "base.tpl";
29
-    /** @var string HTML title. Currently unused. */
30
-    protected $htmlTitle;
31
-    /** @var bool Determines if the page is a redirect or not */
32
-    protected $isRedirecting = false;
33
-    /** @var array Queue of headers to be sent on successful completion */
34
-    protected $headerQueue = array();
35
-    /** @var string The name of the route to use, as determined by the request router. */
36
-    private $routeName = null;
37
-    /** @var TokenManager */
38
-    protected $tokenManager;
39
-    /** @var ContentSecurityPolicyManager */
40
-    private $cspManager;
41
-    /** @var string[] Extra JS files to include */
42
-    private $extraJs = array();
43
-
44
-    /**
45
-     * Sets the route the request will take. Only should be called from the request router or barrier test.
46
-     *
47
-     * @param string $routeName        The name of the route
48
-     * @param bool   $skipCallableTest Don't use this unless you know what you're doing, and what the implications are.
49
-     *
50
-     * @throws Exception
51
-     * @category Security-Critical
52
-     */
53
-    final public function setRoute($routeName, $skipCallableTest = false)
54
-    {
55
-        // Test the new route is callable before adopting it.
56
-        if (!$skipCallableTest && !is_callable(array($this, $routeName))) {
57
-            throw new Exception("Proposed route '$routeName' is not callable.");
58
-        }
59
-
60
-        // Adopt the new route
61
-        $this->routeName = $routeName;
62
-    }
63
-
64
-    /**
65
-     * Gets the name of the route that has been passed from the request router.
66
-     * @return string
67
-     */
68
-    final public function getRouteName()
69
-    {
70
-        return $this->routeName;
71
-    }
72
-
73
-    /**
74
-     * Performs generic page setup actions
75
-     */
76
-    final protected function setupPage()
77
-    {
78
-        $this->setUpSmarty();
79
-
80
-        $currentUser = User::getCurrent($this->getDatabase());
81
-        $this->assign('currentUser', $currentUser);
82
-        $this->assign('loggedIn', (!$currentUser->isCommunityUser()));
83
-    }
84
-
85
-    /**
86
-     * Runs the page logic as routed by the RequestRouter
87
-     *
88
-     * Only should be called after a security barrier! That means only from execute().
89
-     */
90
-    final protected function runPage()
91
-    {
92
-        $database = $this->getDatabase();
93
-
94
-        // initialise a database transaction
95
-        if (!$database->beginTransaction()) {
96
-            throw new Exception('Failed to start transaction on primary database.');
97
-        }
98
-
99
-        try {
100
-            // run the page code
101
-            $this->{$this->getRouteName()}();
102
-
103
-            $database->commit();
104
-        }
105
-        catch (ApplicationLogicException $ex) {
106
-            // it's an application logic exception, so nothing went seriously wrong with the site. We can use the
107
-            // standard templating system for this.
108
-
109
-            // Firstly, let's undo anything that happened to the database.
110
-            $database->rollBack();
111
-
112
-            // Reset smarty
113
-            $this->setupPage();
114
-
115
-            // Set the template
116
-            $this->setTemplate('exception/application-logic.tpl');
117
-            $this->assign('message', $ex->getMessage());
118
-
119
-            // Force this back to false
120
-            $this->isRedirecting = false;
121
-            $this->headerQueue = array();
122
-        }
123
-        catch (OptimisticLockFailedException $ex) {
124
-            // it's an optimistic lock failure exception, so nothing went seriously wrong with the site. We can use the
125
-            // standard templating system for this.
126
-
127
-            // Firstly, let's undo anything that happened to the database.
128
-            $database->rollBack();
129
-
130
-            // Reset smarty
131
-            $this->setupPage();
132
-
133
-            // Set the template
134
-            $this->setTemplate('exception/optimistic-lock-failure.tpl');
135
-            $this->assign('message', $ex->getMessage());
136
-
137
-            $this->assign('debugTrace', false);
138
-
139
-            if ($this->getSiteConfiguration()->getDebuggingTraceEnabled()) {
140
-                ob_start();
141
-                var_dump(ExceptionHandler::getExceptionData($ex));
142
-                $textErrorData = ob_get_contents();
143
-                ob_end_clean();
144
-
145
-                $this->assign('exceptionData', $textErrorData);
146
-                $this->assign('debugTrace', true);
147
-            }
148
-
149
-            // Force this back to false
150
-            $this->isRedirecting = false;
151
-            $this->headerQueue = array();
152
-        }
153
-        finally {
154
-            // Catch any hanging on transactions
155
-            if ($database->hasActiveTransaction()) {
156
-                $database->rollBack();
157
-            }
158
-        }
159
-
160
-        // run any finalisation code needed before we send the output to the browser.
161
-        $this->finalisePage();
162
-
163
-        // Send the headers
164
-        $this->sendResponseHeaders();
165
-
166
-        // Check we have a template to use!
167
-        if ($this->template !== null) {
168
-            $content = $this->fetchTemplate($this->template);
169
-            ob_clean();
170
-            print($content);
171
-            ob_flush();
172
-
173
-            return;
174
-        }
175
-    }
176
-
177
-    /**
178
-     * Performs final tasks needed before rendering the page.
179
-     */
180
-    protected function finalisePage()
181
-    {
182
-        if ($this->isRedirecting) {
183
-            $this->template = null;
184
-
185
-            return;
186
-        }
187
-
188
-        $this->assign('extraJs', $this->extraJs);
189
-
190
-        // If we're actually displaying content, we want to add the session alerts here!
191
-        $this->assign('alerts', SessionAlert::getAlerts());
192
-        SessionAlert::clearAlerts();
193
-
194
-        $this->assign('htmlTitle', $this->htmlTitle);
195
-    }
196
-
197
-    /**
198
-     * @return TokenManager
199
-     */
200
-    public function getTokenManager()
201
-    {
202
-        return $this->tokenManager;
203
-    }
204
-
205
-    /**
206
-     * @param TokenManager $tokenManager
207
-     */
208
-    public function setTokenManager($tokenManager)
209
-    {
210
-        $this->tokenManager = $tokenManager;
211
-    }
212
-
213
-    /**
214
-     * @return ContentSecurityPolicyManager
215
-     */
216
-    public function getCspManager(): ContentSecurityPolicyManager
217
-    {
218
-        return $this->cspManager;
219
-    }
220
-
221
-    /**
222
-     * @param ContentSecurityPolicyManager $cspManager
223
-     */
224
-    public function setCspManager(ContentSecurityPolicyManager $cspManager): void
225
-    {
226
-        $this->cspManager = $cspManager;
227
-    }
228
-
229
-    /**
230
-     * Sends the redirect headers to perform a GET at the destination page.
231
-     *
232
-     * Also nullifies the set template so Smarty does not render it.
233
-     *
234
-     * @param string      $page   The page to redirect requests to (as used in the UR)
235
-     * @param null|string $action The action to use on the page.
236
-     * @param null|array  $parameters
237
-     * @param null|string $script The script (relative to index.php) to redirect to
238
-     */
239
-    final protected function redirect($page = '', $action = null, $parameters = null, $script = null)
240
-    {
241
-        $currentScriptName = WebRequest::scriptName();
242
-
243
-        // Are we changing script?
244
-        if ($script === null || substr($currentScriptName, -1 * count($script)) === $script) {
245
-            $targetScriptName = $currentScriptName;
246
-        }
247
-        else {
248
-            $targetScriptName = $this->getSiteConfiguration()->getBaseUrl() . '/' . $script;
249
-        }
250
-
251
-        $pathInfo = array($targetScriptName);
252
-
253
-        $pathInfo[1] = $page;
254
-
255
-        if ($action !== null) {
256
-            $pathInfo[2] = $action;
257
-        }
258
-
259
-        $url = implode('/', $pathInfo);
260
-
261
-        if (is_array($parameters) && count($parameters) > 0) {
262
-            $url .= '?' . http_build_query($parameters);
263
-        }
264
-
265
-        $this->redirectUrl($url);
266
-    }
267
-
268
-    /**
269
-     * Sends the redirect headers to perform a GET at the new address.
270
-     *
271
-     * Also nullifies the set template so Smarty does not render it.
272
-     *
273
-     * @param string $path URL to redirect to
274
-     */
275
-    final protected function redirectUrl($path)
276
-    {
277
-        // 303 See Other = re-request at new address with a GET.
278
-        $this->headerQueue[] = 'HTTP/1.1 303 See Other';
279
-        $this->headerQueue[] = "Location: $path";
280
-
281
-        $this->setTemplate(null);
282
-        $this->isRedirecting = true;
283
-    }
284
-
285
-    /**
286
-     * Sets the name of the template this page should display.
287
-     *
288
-     * @param string $name
289
-     *
290
-     * @throws Exception
291
-     */
292
-    final protected function setTemplate($name)
293
-    {
294
-        if ($this->isRedirecting) {
295
-            throw new Exception('This page has been set as a redirect, no template can be displayed!');
296
-        }
297
-
298
-        $this->template = $name;
299
-    }
300
-
301
-    /**
302
-     * Adds an extra JS file to to the page
303
-     *
304
-     * @param string $path The path (relative to the application root) of the file
305
-     */
306
-    final protected function addJs($path){
307
-        if(in_array($path, $this->extraJs)){
308
-            // nothing to do
309
-            return;
310
-        }
311
-
312
-        $this->extraJs[] = $path;
313
-    }
314
-
315
-    /**
316
-     * Main function for this page, when no specific actions are called.
317
-     * @return void
318
-     */
319
-    abstract protected function main();
320
-
321
-    /**
322
-     * Takes a smarty template string and sets the HTML title to that value
323
-     *
324
-     * @param string $title
325
-     *
326
-     * @throws SmartyException
327
-     */
328
-    final protected function setHtmlTitle($title)
329
-    {
330
-        $this->htmlTitle = $this->smarty->fetch('string:' . $title);
331
-    }
332
-
333
-    public function execute()
334
-    {
335
-        if ($this->getRouteName() === null) {
336
-            throw new Exception('Request is unrouted.');
337
-        }
338
-
339
-        if ($this->getSiteConfiguration() === null) {
340
-            throw new Exception('Page has no configuration!');
341
-        }
342
-
343
-        $this->setupPage();
344
-
345
-        $this->runPage();
346
-    }
347
-
348
-    public function assignCSRFToken()
349
-    {
350
-        $token = $this->tokenManager->getNewToken();
351
-        $this->assign('csrfTokenData', $token->getTokenData());
352
-    }
353
-
354
-    public function validateCSRFToken()
355
-    {
356
-        if (!$this->tokenManager->validateToken(WebRequest::postString('csrfTokenData'))) {
357
-            throw new ApplicationLogicException('Form token is not valid, please reload and try again');
358
-        }
359
-    }
360
-
361
-    protected function sendResponseHeaders()
362
-    {
363
-        if (headers_sent()) {
364
-            throw new ApplicationLogicException('Headers have already been sent! This is likely a bug in the application.');
365
-        }
366
-
367
-        // send the CSP headers now
368
-        header($this->getCspManager()->getHeader());
369
-
370
-        foreach ($this->headerQueue as $item) {
371
-            if (mb_strpos($item, "\r") !== false || mb_strpos($item, "\n") !== false) {
372
-                // Oops. We're not allowed to do this.
373
-                throw new Exception('Unable to split header');
374
-            }
375
-
376
-            header($item);
377
-        }
378
-    }
26
+	use TemplateOutput;
27
+	/** @var string Smarty template to display */
28
+	protected $template = "base.tpl";
29
+	/** @var string HTML title. Currently unused. */
30
+	protected $htmlTitle;
31
+	/** @var bool Determines if the page is a redirect or not */
32
+	protected $isRedirecting = false;
33
+	/** @var array Queue of headers to be sent on successful completion */
34
+	protected $headerQueue = array();
35
+	/** @var string The name of the route to use, as determined by the request router. */
36
+	private $routeName = null;
37
+	/** @var TokenManager */
38
+	protected $tokenManager;
39
+	/** @var ContentSecurityPolicyManager */
40
+	private $cspManager;
41
+	/** @var string[] Extra JS files to include */
42
+	private $extraJs = array();
43
+
44
+	/**
45
+	 * Sets the route the request will take. Only should be called from the request router or barrier test.
46
+	 *
47
+	 * @param string $routeName        The name of the route
48
+	 * @param bool   $skipCallableTest Don't use this unless you know what you're doing, and what the implications are.
49
+	 *
50
+	 * @throws Exception
51
+	 * @category Security-Critical
52
+	 */
53
+	final public function setRoute($routeName, $skipCallableTest = false)
54
+	{
55
+		// Test the new route is callable before adopting it.
56
+		if (!$skipCallableTest && !is_callable(array($this, $routeName))) {
57
+			throw new Exception("Proposed route '$routeName' is not callable.");
58
+		}
59
+
60
+		// Adopt the new route
61
+		$this->routeName = $routeName;
62
+	}
63
+
64
+	/**
65
+	 * Gets the name of the route that has been passed from the request router.
66
+	 * @return string
67
+	 */
68
+	final public function getRouteName()
69
+	{
70
+		return $this->routeName;
71
+	}
72
+
73
+	/**
74
+	 * Performs generic page setup actions
75
+	 */
76
+	final protected function setupPage()
77
+	{
78
+		$this->setUpSmarty();
79
+
80
+		$currentUser = User::getCurrent($this->getDatabase());
81
+		$this->assign('currentUser', $currentUser);
82
+		$this->assign('loggedIn', (!$currentUser->isCommunityUser()));
83
+	}
84
+
85
+	/**
86
+	 * Runs the page logic as routed by the RequestRouter
87
+	 *
88
+	 * Only should be called after a security barrier! That means only from execute().
89
+	 */
90
+	final protected function runPage()
91
+	{
92
+		$database = $this->getDatabase();
93
+
94
+		// initialise a database transaction
95
+		if (!$database->beginTransaction()) {
96
+			throw new Exception('Failed to start transaction on primary database.');
97
+		}
98
+
99
+		try {
100
+			// run the page code
101
+			$this->{$this->getRouteName()}();
102
+
103
+			$database->commit();
104
+		}
105
+		catch (ApplicationLogicException $ex) {
106
+			// it's an application logic exception, so nothing went seriously wrong with the site. We can use the
107
+			// standard templating system for this.
108
+
109
+			// Firstly, let's undo anything that happened to the database.
110
+			$database->rollBack();
111
+
112
+			// Reset smarty
113
+			$this->setupPage();
114
+
115
+			// Set the template
116
+			$this->setTemplate('exception/application-logic.tpl');
117
+			$this->assign('message', $ex->getMessage());
118
+
119
+			// Force this back to false
120
+			$this->isRedirecting = false;
121
+			$this->headerQueue = array();
122
+		}
123
+		catch (OptimisticLockFailedException $ex) {
124
+			// it's an optimistic lock failure exception, so nothing went seriously wrong with the site. We can use the
125
+			// standard templating system for this.
126
+
127
+			// Firstly, let's undo anything that happened to the database.
128
+			$database->rollBack();
129
+
130
+			// Reset smarty
131
+			$this->setupPage();
132
+
133
+			// Set the template
134
+			$this->setTemplate('exception/optimistic-lock-failure.tpl');
135
+			$this->assign('message', $ex->getMessage());
136
+
137
+			$this->assign('debugTrace', false);
138
+
139
+			if ($this->getSiteConfiguration()->getDebuggingTraceEnabled()) {
140
+				ob_start();
141
+				var_dump(ExceptionHandler::getExceptionData($ex));
142
+				$textErrorData = ob_get_contents();
143
+				ob_end_clean();
144
+
145
+				$this->assign('exceptionData', $textErrorData);
146
+				$this->assign('debugTrace', true);
147
+			}
148
+
149
+			// Force this back to false
150
+			$this->isRedirecting = false;
151
+			$this->headerQueue = array();
152
+		}
153
+		finally {
154
+			// Catch any hanging on transactions
155
+			if ($database->hasActiveTransaction()) {
156
+				$database->rollBack();
157
+			}
158
+		}
159
+
160
+		// run any finalisation code needed before we send the output to the browser.
161
+		$this->finalisePage();
162
+
163
+		// Send the headers
164
+		$this->sendResponseHeaders();
165
+
166
+		// Check we have a template to use!
167
+		if ($this->template !== null) {
168
+			$content = $this->fetchTemplate($this->template);
169
+			ob_clean();
170
+			print($content);
171
+			ob_flush();
172
+
173
+			return;
174
+		}
175
+	}
176
+
177
+	/**
178
+	 * Performs final tasks needed before rendering the page.
179
+	 */
180
+	protected function finalisePage()
181
+	{
182
+		if ($this->isRedirecting) {
183
+			$this->template = null;
184
+
185
+			return;
186
+		}
187
+
188
+		$this->assign('extraJs', $this->extraJs);
189
+
190
+		// If we're actually displaying content, we want to add the session alerts here!
191
+		$this->assign('alerts', SessionAlert::getAlerts());
192
+		SessionAlert::clearAlerts();
193
+
194
+		$this->assign('htmlTitle', $this->htmlTitle);
195
+	}
196
+
197
+	/**
198
+	 * @return TokenManager
199
+	 */
200
+	public function getTokenManager()
201
+	{
202
+		return $this->tokenManager;
203
+	}
204
+
205
+	/**
206
+	 * @param TokenManager $tokenManager
207
+	 */
208
+	public function setTokenManager($tokenManager)
209
+	{
210
+		$this->tokenManager = $tokenManager;
211
+	}
212
+
213
+	/**
214
+	 * @return ContentSecurityPolicyManager
215
+	 */
216
+	public function getCspManager(): ContentSecurityPolicyManager
217
+	{
218
+		return $this->cspManager;
219
+	}
220
+
221
+	/**
222
+	 * @param ContentSecurityPolicyManager $cspManager
223
+	 */
224
+	public function setCspManager(ContentSecurityPolicyManager $cspManager): void
225
+	{
226
+		$this->cspManager = $cspManager;
227
+	}
228
+
229
+	/**
230
+	 * Sends the redirect headers to perform a GET at the destination page.
231
+	 *
232
+	 * Also nullifies the set template so Smarty does not render it.
233
+	 *
234
+	 * @param string      $page   The page to redirect requests to (as used in the UR)
235
+	 * @param null|string $action The action to use on the page.
236
+	 * @param null|array  $parameters
237
+	 * @param null|string $script The script (relative to index.php) to redirect to
238
+	 */
239
+	final protected function redirect($page = '', $action = null, $parameters = null, $script = null)
240
+	{
241
+		$currentScriptName = WebRequest::scriptName();
242
+
243
+		// Are we changing script?
244
+		if ($script === null || substr($currentScriptName, -1 * count($script)) === $script) {
245
+			$targetScriptName = $currentScriptName;
246
+		}
247
+		else {
248
+			$targetScriptName = $this->getSiteConfiguration()->getBaseUrl() . '/' . $script;
249
+		}
250
+
251
+		$pathInfo = array($targetScriptName);
252
+
253
+		$pathInfo[1] = $page;
254
+
255
+		if ($action !== null) {
256
+			$pathInfo[2] = $action;
257
+		}
258
+
259
+		$url = implode('/', $pathInfo);
260
+
261
+		if (is_array($parameters) && count($parameters) > 0) {
262
+			$url .= '?' . http_build_query($parameters);
263
+		}
264
+
265
+		$this->redirectUrl($url);
266
+	}
267
+
268
+	/**
269
+	 * Sends the redirect headers to perform a GET at the new address.
270
+	 *
271
+	 * Also nullifies the set template so Smarty does not render it.
272
+	 *
273
+	 * @param string $path URL to redirect to
274
+	 */
275
+	final protected function redirectUrl($path)
276
+	{
277
+		// 303 See Other = re-request at new address with a GET.
278
+		$this->headerQueue[] = 'HTTP/1.1 303 See Other';
279
+		$this->headerQueue[] = "Location: $path";
280
+
281
+		$this->setTemplate(null);
282
+		$this->isRedirecting = true;
283
+	}
284
+
285
+	/**
286
+	 * Sets the name of the template this page should display.
287
+	 *
288
+	 * @param string $name
289
+	 *
290
+	 * @throws Exception
291
+	 */
292
+	final protected function setTemplate($name)
293
+	{
294
+		if ($this->isRedirecting) {
295
+			throw new Exception('This page has been set as a redirect, no template can be displayed!');
296
+		}
297
+
298
+		$this->template = $name;
299
+	}
300
+
301
+	/**
302
+	 * Adds an extra JS file to to the page
303
+	 *
304
+	 * @param string $path The path (relative to the application root) of the file
305
+	 */
306
+	final protected function addJs($path){
307
+		if(in_array($path, $this->extraJs)){
308
+			// nothing to do
309
+			return;
310
+		}
311
+
312
+		$this->extraJs[] = $path;
313
+	}
314
+
315
+	/**
316
+	 * Main function for this page, when no specific actions are called.
317
+	 * @return void
318
+	 */
319
+	abstract protected function main();
320
+
321
+	/**
322
+	 * Takes a smarty template string and sets the HTML title to that value
323
+	 *
324
+	 * @param string $title
325
+	 *
326
+	 * @throws SmartyException
327
+	 */
328
+	final protected function setHtmlTitle($title)
329
+	{
330
+		$this->htmlTitle = $this->smarty->fetch('string:' . $title);
331
+	}
332
+
333
+	public function execute()
334
+	{
335
+		if ($this->getRouteName() === null) {
336
+			throw new Exception('Request is unrouted.');
337
+		}
338
+
339
+		if ($this->getSiteConfiguration() === null) {
340
+			throw new Exception('Page has no configuration!');
341
+		}
342
+
343
+		$this->setupPage();
344
+
345
+		$this->runPage();
346
+	}
347
+
348
+	public function assignCSRFToken()
349
+	{
350
+		$token = $this->tokenManager->getNewToken();
351
+		$this->assign('csrfTokenData', $token->getTokenData());
352
+	}
353
+
354
+	public function validateCSRFToken()
355
+	{
356
+		if (!$this->tokenManager->validateToken(WebRequest::postString('csrfTokenData'))) {
357
+			throw new ApplicationLogicException('Form token is not valid, please reload and try again');
358
+		}
359
+	}
360
+
361
+	protected function sendResponseHeaders()
362
+	{
363
+		if (headers_sent()) {
364
+			throw new ApplicationLogicException('Headers have already been sent! This is likely a bug in the application.');
365
+		}
366
+
367
+		// send the CSP headers now
368
+		header($this->getCspManager()->getHeader());
369
+
370
+		foreach ($this->headerQueue as $item) {
371
+			if (mb_strpos($item, "\r") !== false || mb_strpos($item, "\n") !== false) {
372
+				// Oops. We're not allowed to do this.
373
+				throw new Exception('Unable to split header');
374
+			}
375
+
376
+			header($item);
377
+		}
378
+	}
379 379
 }
Please login to merge, or discard this patch.
includes/ConsoleTasks/RunJobQueueTask.php 3 patches
Indentation   +112 added lines, -112 removed lines patch added patch discarded remove patch
@@ -22,116 +22,116 @@
 block discarded – undo
22 22
 
23 23
 class RunJobQueueTask extends ConsoleTaskBase
24 24
 {
25
-    private $taskList = array(
26
-        WelcomeUserTask::class,
27
-        BotCreationTask::class,
28
-        UserCreationTask::class
29
-    );
30
-
31
-    public function execute()
32
-    {
33
-        $database = $this->getDatabase();
34
-
35
-        // ensure we're running inside a tx here.
36
-        if (!$database->hasActiveTransaction()) {
37
-            $database->beginTransaction();
38
-        }
39
-
40
-        $sql = 'SELECT * FROM jobqueue WHERE status = :status ORDER BY enqueue LIMIT :lim';
41
-        $statement = $database->prepare($sql);
42
-        $statement->execute(array(':status' => JobQueue::STATUS_READY, ':lim' => 10));
43
-        /** @var JobQueue[] $queuedJobs */
44
-        $queuedJobs = $statement->fetchAll(PDO::FETCH_CLASS, JobQueue::class);
45
-
46
-        // mark all the jobs as running, and commit the txn so we're not holding onto long-running transactions.
47
-        // We'll re-lock the row when we get to it.
48
-        foreach ($queuedJobs as $job) {
49
-            $job->setDatabase($database);
50
-            $job->setStatus(JobQueue::STATUS_WAITING);
51
-            $job->setError(null);
52
-            $job->setAcknowledged(null);
53
-            $job->save();
54
-        }
55
-
56
-        $database->commit();
57
-
58
-        set_error_handler(array(RunJobQueueTask::class, 'errorHandler'), E_ALL);
59
-
60
-        foreach ($queuedJobs as $job) {
61
-            try {
62
-                $database->beginTransaction();
63
-                $job->setStatus(JobQueue::STATUS_RUNNING);
64
-                $job->save();
65
-                $database->commit();
66
-
67
-                $database->beginTransaction();
68
-
69
-                // re-lock the job
70
-                $job->setStatus(JobQueue::STATUS_RUNNING);
71
-                $job->save();
72
-
73
-                // validate we're allowed to run the requested task (whitelist)
74
-                if (!in_array($job->getTask(), $this->taskList)) {
75
-                    throw new ApplicationLogicException('Job task not registered');
76
-                }
77
-
78
-                // Create a task.
79
-                $taskName = $job->getTask();
80
-
81
-                if(!class_exists($taskName)) {
82
-                    throw new ApplicationLogicException('Job task does not exist');
83
-                }
84
-
85
-                /** @var BackgroundTaskBase $task */
86
-                $task = new $taskName;
87
-
88
-                $this->setupTask($task, $job);
89
-                $task->run();
90
-            }
91
-            catch (Exception $ex) {
92
-                $database->rollBack();
93
-                $database->beginTransaction();
94
-
95
-                /** @var JobQueue $job */
96
-                $job = JobQueue::getById($job->getId(), $database);
97
-                $job->setDatabase($database);
98
-                $job->setStatus(JobQueue::STATUS_FAILED);
99
-                $job->setError($ex->getMessage());
100
-                $job->setAcknowledged(0);
101
-                $job->save();
102
-
103
-                /** @var Request $request */
104
-                $request = Request::getById($job->getRequest(), $database);
105
-                if ($request === false) {
106
-                    $request = null;
107
-                }
108
-
109
-                Logger::backgroundJobIssue($this->getDatabase(), $job);
110
-
111
-                $database->commit();
112
-            }
113
-            finally {
114
-                $database->commit();
115
-            }
116
-        }
117
-    }
118
-
119
-    /**
120
-     * @param BackgroundTaskBase $task
121
-     * @param JobQueue           $job
122
-     */
123
-    private function setupTask(BackgroundTaskBase $task, JobQueue $job)
124
-    {
125
-        $task->setJob($job);
126
-        $task->setDatabase($this->getDatabase());
127
-        $task->setHttpHelper($this->getHttpHelper());
128
-        $task->setOauthProtocolHelper($this->getOAuthProtocolHelper());
129
-        $task->setEmailHelper($this->getEmailHelper());
130
-        $task->setSiteConfiguration($this->getSiteConfiguration());
131
-        $task->setNotificationHelper($this->getNotificationHelper());
132
-    }
133
-
134
-    public static function errorHandler($errno, $errstr, $errfile, $errline) {
135
-        throw new Exception($errfile . "@" . $errline . ": " . $errstr);
136
-    }
25
+	private $taskList = array(
26
+		WelcomeUserTask::class,
27
+		BotCreationTask::class,
28
+		UserCreationTask::class
29
+	);
30
+
31
+	public function execute()
32
+	{
33
+		$database = $this->getDatabase();
34
+
35
+		// ensure we're running inside a tx here.
36
+		if (!$database->hasActiveTransaction()) {
37
+			$database->beginTransaction();
38
+		}
39
+
40
+		$sql = 'SELECT * FROM jobqueue WHERE status = :status ORDER BY enqueue LIMIT :lim';
41
+		$statement = $database->prepare($sql);
42
+		$statement->execute(array(':status' => JobQueue::STATUS_READY, ':lim' => 10));
43
+		/** @var JobQueue[] $queuedJobs */
44
+		$queuedJobs = $statement->fetchAll(PDO::FETCH_CLASS, JobQueue::class);
45
+
46
+		// mark all the jobs as running, and commit the txn so we're not holding onto long-running transactions.
47
+		// We'll re-lock the row when we get to it.
48
+		foreach ($queuedJobs as $job) {
49
+			$job->setDatabase($database);
50
+			$job->setStatus(JobQueue::STATUS_WAITING);
51
+			$job->setError(null);
52
+			$job->setAcknowledged(null);
53
+			$job->save();
54
+		}
55
+
56
+		$database->commit();
57
+
58
+		set_error_handler(array(RunJobQueueTask::class, 'errorHandler'), E_ALL);
59
+
60
+		foreach ($queuedJobs as $job) {
61
+			try {
62
+				$database->beginTransaction();
63
+				$job->setStatus(JobQueue::STATUS_RUNNING);
64
+				$job->save();
65
+				$database->commit();
66
+
67
+				$database->beginTransaction();
68
+
69
+				// re-lock the job
70
+				$job->setStatus(JobQueue::STATUS_RUNNING);
71
+				$job->save();
72
+
73
+				// validate we're allowed to run the requested task (whitelist)
74
+				if (!in_array($job->getTask(), $this->taskList)) {
75
+					throw new ApplicationLogicException('Job task not registered');
76
+				}
77
+
78
+				// Create a task.
79
+				$taskName = $job->getTask();
80
+
81
+				if(!class_exists($taskName)) {
82
+					throw new ApplicationLogicException('Job task does not exist');
83
+				}
84
+
85
+				/** @var BackgroundTaskBase $task */
86
+				$task = new $taskName;
87
+
88
+				$this->setupTask($task, $job);
89
+				$task->run();
90
+			}
91
+			catch (Exception $ex) {
92
+				$database->rollBack();
93
+				$database->beginTransaction();
94
+
95
+				/** @var JobQueue $job */
96
+				$job = JobQueue::getById($job->getId(), $database);
97
+				$job->setDatabase($database);
98
+				$job->setStatus(JobQueue::STATUS_FAILED);
99
+				$job->setError($ex->getMessage());
100
+				$job->setAcknowledged(0);
101
+				$job->save();
102
+
103
+				/** @var Request $request */
104
+				$request = Request::getById($job->getRequest(), $database);
105
+				if ($request === false) {
106
+					$request = null;
107
+				}
108
+
109
+				Logger::backgroundJobIssue($this->getDatabase(), $job);
110
+
111
+				$database->commit();
112
+			}
113
+			finally {
114
+				$database->commit();
115
+			}
116
+		}
117
+	}
118
+
119
+	/**
120
+	 * @param BackgroundTaskBase $task
121
+	 * @param JobQueue           $job
122
+	 */
123
+	private function setupTask(BackgroundTaskBase $task, JobQueue $job)
124
+	{
125
+		$task->setJob($job);
126
+		$task->setDatabase($this->getDatabase());
127
+		$task->setHttpHelper($this->getHttpHelper());
128
+		$task->setOauthProtocolHelper($this->getOAuthProtocolHelper());
129
+		$task->setEmailHelper($this->getEmailHelper());
130
+		$task->setSiteConfiguration($this->getSiteConfiguration());
131
+		$task->setNotificationHelper($this->getNotificationHelper());
132
+	}
133
+
134
+	public static function errorHandler($errno, $errstr, $errfile, $errline) {
135
+		throw new Exception($errfile . "@" . $errline . ": " . $errstr);
136
+	}
137 137
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -78,7 +78,7 @@  discard block
 block discarded – undo
78 78
                 // Create a task.
79 79
                 $taskName = $job->getTask();
80 80
 
81
-                if(!class_exists($taskName)) {
81
+                if (!class_exists($taskName)) {
82 82
                     throw new ApplicationLogicException('Job task does not exist');
83 83
                 }
84 84
 
@@ -132,6 +132,6 @@  discard block
 block discarded – undo
132 132
     }
133 133
 
134 134
     public static function errorHandler($errno, $errstr, $errfile, $errline) {
135
-        throw new Exception($errfile . "@" . $errline . ": " . $errstr);
135
+        throw new Exception($errfile."@".$errline.": ".$errstr);
136 136
     }
137 137
 }
Please login to merge, or discard this patch.
Braces   +2 added lines, -1 removed lines patch added patch discarded remove patch
@@ -131,7 +131,8 @@
 block discarded – undo
131 131
         $task->setNotificationHelper($this->getNotificationHelper());
132 132
     }
133 133
 
134
-    public static function errorHandler($errno, $errstr, $errfile, $errline) {
134
+    public static function errorHandler($errno, $errstr, $errfile, $errline)
135
+    {
135 136
         throw new Exception($errfile . "@" . $errline . ": " . $errstr);
136 137
     }
137 138
 }
Please login to merge, or discard this patch.
config.inc.php 1 patch
Indentation   +87 added lines, -87 removed lines patch added patch discarded remove patch
@@ -202,27 +202,27 @@  discard block
 block discarded – undo
202 202
 
203 203
 // request states
204 204
 $availableRequestStates = array(
205
-    'Open'          => array(
206
-        'defertolog' => 'users', // don't change or you'll break old logs
207
-        'deferto'    => 'users',
208
-        'header'     => 'Open requests',
209
-        'api'        => "open",
210
-        'queuehelp'  => null
211
-    ),
212
-    'Flagged users' => array(
213
-        'defertolog' => 'flagged users', // don't change or you'll break old logs
214
-        'deferto'    => 'flagged users',
215
-        'header'     => 'Flagged user needed',
216
-        'api'        => "admin",
217
-        'queuehelp'  => 'This queue lists the requests which require a user with the <code>accountcreator</code> flag to create.<br />If creation is determined to be the correct course of action, requests here will require the overriding the AntiSpoof checks or the title blacklist in order to create. It is recommended to try to create the account <em>without</em> checking the flags to validate the results of the AntiSpoof and/or title blacklist hits.'
218
-    ),
219
-    'Checkuser'     => array(
220
-        'defertolog' => 'checkusers', // don't change or you'll break old logs
221
-        'deferto'    => 'checkusers',
222
-        'header'     => 'Checkuser needed',
223
-        'api'        => "checkuser",
224
-        'queuehelp'  => null
225
-    ),
205
+	'Open'          => array(
206
+		'defertolog' => 'users', // don't change or you'll break old logs
207
+		'deferto'    => 'users',
208
+		'header'     => 'Open requests',
209
+		'api'        => "open",
210
+		'queuehelp'  => null
211
+	),
212
+	'Flagged users' => array(
213
+		'defertolog' => 'flagged users', // don't change or you'll break old logs
214
+		'deferto'    => 'flagged users',
215
+		'header'     => 'Flagged user needed',
216
+		'api'        => "admin",
217
+		'queuehelp'  => 'This queue lists the requests which require a user with the <code>accountcreator</code> flag to create.<br />If creation is determined to be the correct course of action, requests here will require the overriding the AntiSpoof checks or the title blacklist in order to create. It is recommended to try to create the account <em>without</em> checking the flags to validate the results of the AntiSpoof and/or title blacklist hits.'
218
+	),
219
+	'Checkuser'     => array(
220
+		'defertolog' => 'checkusers', // don't change or you'll break old logs
221
+		'deferto'    => 'checkusers',
222
+		'header'     => 'Checkuser needed',
223
+		'api'        => "checkuser",
224
+		'queuehelp'  => null
225
+	),
226 226
 );
227 227
 
228 228
 $defaultRequestStateKey = 'Open';
@@ -272,24 +272,24 @@  discard block
 block discarded – undo
272 272
 require_once('config.local.inc.php');
273 273
 
274 274
 $cDatabaseConfig = array(
275
-    "acc"           => array(
276
-        "dsrcname" => "mysql:host=" . $toolserver_host . ";dbname=" . $toolserver_database,
277
-        "username" => $toolserver_username,
278
-        "password" => $toolserver_password,
275
+	"acc"           => array(
276
+		"dsrcname" => "mysql:host=" . $toolserver_host . ";dbname=" . $toolserver_database,
277
+		"username" => $toolserver_username,
278
+		"password" => $toolserver_password,
279 279
 		"options"  => array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4'),
280
-    ),
281
-    "wikipedia"     => array(
282
-        "dsrcname" => "mysql:host=" . $antispoof_host . ";dbname=" . $antispoof_db,
283
-        "username" => $toolserver_username,
284
-        "password" => $toolserver_password,
285
-        "options"  => array(),
286
-    ),
287
-    "notifications" => array(
288
-        "dsrcname" => "mysql:host=" . $toolserver_notification_dbhost . ";dbname=" . $toolserver_notification_database,
289
-        "username" => $notifications_username,
290
-        "password" => $notifications_password,
291
-        "options"  => array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4'),
292
-    ),
280
+	),
281
+	"wikipedia"     => array(
282
+		"dsrcname" => "mysql:host=" . $antispoof_host . ";dbname=" . $antispoof_db,
283
+		"username" => $toolserver_username,
284
+		"password" => $toolserver_password,
285
+		"options"  => array(),
286
+	),
287
+	"notifications" => array(
288
+		"dsrcname" => "mysql:host=" . $toolserver_notification_dbhost . ";dbname=" . $toolserver_notification_database,
289
+		"username" => $notifications_username,
290
+		"password" => $notifications_password,
291
+		"options"  => array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4'),
292
+	),
293 293
 );
294 294
 
295 295
 // //Keep the included files from being executed.
@@ -301,18 +301,18 @@  discard block
 block discarded – undo
301 301
 ini_set('user_agent', $toolUserAgent);
302 302
 
303 303
 foreach (array(
304
-    "mbstring", // unicode and stuff
305
-    "pdo",
306
-    "pdo_mysql", // new database module
307
-    "session",
308
-    "date",
309
-    "pcre", // core stuff
310
-    "curl", // mediawiki api access etc
311
-    "openssl", // token generation
304
+	"mbstring", // unicode and stuff
305
+	"pdo",
306
+	"pdo_mysql", // new database module
307
+	"session",
308
+	"date",
309
+	"pcre", // core stuff
310
+	"curl", // mediawiki api access etc
311
+	"openssl", // token generation
312 312
 ) as $x) {
313
-    if (!extension_loaded($x)) {
314
-        die("extension $x is required.");
315
-    }
313
+	if (!extension_loaded($x)) {
314
+		die("extension $x is required.");
315
+	}
316 316
 }
317 317
 
318 318
 // Set up the AutoLoader
@@ -339,41 +339,41 @@  discard block
 block discarded – undo
339 339
 $siteConfiguration = new \Waca\SiteConfiguration();
340 340
 
341 341
 $siteConfiguration->setBaseUrl($baseurl)
342
-    ->setFilePath(__DIR__)
343
-    ->setDebuggingTraceEnabled($enableErrorTrace)
344
-    ->setForceIdentification($forceIdentification)
345
-    ->setIdentificationCacheExpiry($identificationCacheExpiry)
346
-    ->setMediawikiScriptPath($mediawikiScriptPath)
347
-    ->setMediawikiWebServiceEndpoint($mediawikiWebServiceEndpoint)
348
-    ->setMetaWikimediaWebServiceEndpoint($metaWikimediaWebServiceEndpoint)
349
-    ->setEnforceOAuth($enforceOAuth)
350
-    ->setEmailConfirmationEnabled($enableEmailConfirm == 1)
351
-    ->setEmailConfirmationExpiryDays($emailConfirmationExpiryDays)
352
-    ->setMiserModeLimit($requestLimitShowOnly)
353
-    ->setRequestStates($availableRequestStates)
354
-    ->setSquidList($squidIpList)
355
-    ->setDefaultCreatedTemplateId($createdid)
356
-    ->setDefaultRequestStateKey($defaultRequestStateKey)
357
-    ->setUseStrictTransportSecurity($strictTransportSecurityExpiry)
358
-    ->setUserAgent($toolUserAgent)
359
-    ->setCurlDisableVerifyPeer($curlDisableSSLVerifyPeer)
360
-    ->setUseOAuthSignup($useOauthSignup)
361
-    ->setOAuthBaseUrl($oauthBaseUrl)
362
-    ->setOAuthConsumerToken($oauthConsumerToken)
363
-    ->setOAuthConsumerSecret($oauthSecretToken)
364
-    ->setOauthMediaWikiCanonicalServer($oauthMediaWikiCanonicalServer)
365
-    ->setDataClearInterval($dataclear_interval)
366
-    ->setXffTrustedHostsFile($xff_trusted_hosts_file)
367
-    ->setIrcNotificationsEnabled($ircBotNotificationsEnabled == 1)
368
-    ->setIrcNotificationType($ircBotNotificationType)
369
-    ->setIrcNotificationsInstance($whichami)
370
-    ->setTitleBlacklistEnabled($enableTitleblacklist == 1)
371
-    ->setTorExitPaths(array_merge(gethostbynamel('en.wikipedia.org'), gethostbynamel('accounts.wmflabs.org')))
372
-    ->setCreationBotUsername($creationBotUsername)
373
-    ->setCreationBotPassword($creationBotPassword)
374
-    ->setCurlCookieJar($curlCookieJar)
375
-    ->setYubicoApiId($yubicoApiId)
376
-    ->setYubicoApiKey($yubicoApiKey)
377
-    ->setTotpEncryptionKey($totpEncryptionKey)
378
-    ->setRegistrationAllowed($allowRegistration)
379
-    ->setCspReportUri($cspReportUri);
342
+	->setFilePath(__DIR__)
343
+	->setDebuggingTraceEnabled($enableErrorTrace)
344
+	->setForceIdentification($forceIdentification)
345
+	->setIdentificationCacheExpiry($identificationCacheExpiry)
346
+	->setMediawikiScriptPath($mediawikiScriptPath)
347
+	->setMediawikiWebServiceEndpoint($mediawikiWebServiceEndpoint)
348
+	->setMetaWikimediaWebServiceEndpoint($metaWikimediaWebServiceEndpoint)
349
+	->setEnforceOAuth($enforceOAuth)
350
+	->setEmailConfirmationEnabled($enableEmailConfirm == 1)
351
+	->setEmailConfirmationExpiryDays($emailConfirmationExpiryDays)
352
+	->setMiserModeLimit($requestLimitShowOnly)
353
+	->setRequestStates($availableRequestStates)
354
+	->setSquidList($squidIpList)
355
+	->setDefaultCreatedTemplateId($createdid)
356
+	->setDefaultRequestStateKey($defaultRequestStateKey)
357
+	->setUseStrictTransportSecurity($strictTransportSecurityExpiry)
358
+	->setUserAgent($toolUserAgent)
359
+	->setCurlDisableVerifyPeer($curlDisableSSLVerifyPeer)
360
+	->setUseOAuthSignup($useOauthSignup)
361
+	->setOAuthBaseUrl($oauthBaseUrl)
362
+	->setOAuthConsumerToken($oauthConsumerToken)
363
+	->setOAuthConsumerSecret($oauthSecretToken)
364
+	->setOauthMediaWikiCanonicalServer($oauthMediaWikiCanonicalServer)
365
+	->setDataClearInterval($dataclear_interval)
366
+	->setXffTrustedHostsFile($xff_trusted_hosts_file)
367
+	->setIrcNotificationsEnabled($ircBotNotificationsEnabled == 1)
368
+	->setIrcNotificationType($ircBotNotificationType)
369
+	->setIrcNotificationsInstance($whichami)
370
+	->setTitleBlacklistEnabled($enableTitleblacklist == 1)
371
+	->setTorExitPaths(array_merge(gethostbynamel('en.wikipedia.org'), gethostbynamel('accounts.wmflabs.org')))
372
+	->setCreationBotUsername($creationBotUsername)
373
+	->setCreationBotPassword($creationBotPassword)
374
+	->setCurlCookieJar($curlCookieJar)
375
+	->setYubicoApiId($yubicoApiId)
376
+	->setYubicoApiKey($yubicoApiKey)
377
+	->setTotpEncryptionKey($totpEncryptionKey)
378
+	->setRegistrationAllowed($allowRegistration)
379
+	->setCspReportUri($cspReportUri);
Please login to merge, or discard this patch.
includes/API/Actions/JsTemplateConfirmsAction.php 2 patches
Indentation   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -17,20 +17,20 @@
 block discarded – undo
17 17
 
18 18
 class JsTemplateConfirmsAction extends JsonApiPageBase implements IJsonApiAction
19 19
 {
20
-    public function executeApiAction()
21
-    {
22
-        $this->getDatabase();
20
+	public function executeApiAction()
21
+	{
22
+		$this->getDatabase();
23 23
 
24
-        /** @var EmailTemplate[] $templates */
25
-        $templates = EmailTemplate::getAllActiveTemplates(null, $this->getDatabase());
24
+		/** @var EmailTemplate[] $templates */
25
+		$templates = EmailTemplate::getAllActiveTemplates(null, $this->getDatabase());
26 26
 
27
-        $dataset = [];
28
-        foreach ($templates as $tpl) {
29
-            if($tpl->getJsquestion() != "") {
30
-                $dataset[$tpl->getId()] = $tpl->getJsquestion();
31
-            }
32
-        }
27
+		$dataset = [];
28
+		foreach ($templates as $tpl) {
29
+			if($tpl->getJsquestion() != "") {
30
+				$dataset[$tpl->getId()] = $tpl->getJsquestion();
31
+			}
32
+		}
33 33
 
34
-        return $dataset;
35
-    }
34
+		return $dataset;
35
+	}
36 36
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -26,7 +26,7 @@
 block discarded – undo
26 26
 
27 27
         $dataset = [];
28 28
         foreach ($templates as $tpl) {
29
-            if($tpl->getJsquestion() != "") {
29
+            if ($tpl->getJsquestion() != "") {
30 30
                 $dataset[$tpl->getId()] = $tpl->getJsquestion();
31 31
             }
32 32
         }
Please login to merge, or discard this patch.
includes/Pages/PageViewRequest.php 1 patch
Indentation   +276 added lines, -276 removed lines patch added patch discarded remove patch
@@ -25,280 +25,280 @@
 block discarded – undo
25 25
 
26 26
 class PageViewRequest extends InternalPageBase
27 27
 {
28
-    use RequestData;
29
-    const STATUS_SYMBOL_OPEN = '&#x2610';
30
-    const STATUS_SYMBOL_ACCEPTED = '&#x2611';
31
-    const STATUS_SYMBOL_REJECTED = '&#x2612';
32
-
33
-    /**
34
-     * Main function for this page, when no specific actions are called.
35
-     * @throws ApplicationLogicException
36
-     */
37
-    protected function main()
38
-    {
39
-        // set up csrf protection
40
-        $this->assignCSRFToken();
41
-
42
-        // get some useful objects
43
-        $database = $this->getDatabase();
44
-        $request = $this->getRequest($database, WebRequest::getInt('id'));
45
-        $config = $this->getSiteConfiguration();
46
-        $currentUser = User::getCurrent($database);
47
-
48
-        // Test we should be able to look at this request
49
-        if ($config->getEmailConfirmationEnabled()) {
50
-            if ($request->getEmailConfirm() !== 'Confirmed') {
51
-                // Not allowed to look at this yet.
52
-                throw new ApplicationLogicException('The email address has not yet been confirmed for this request.');
53
-            }
54
-        }
55
-
56
-        $this->setupBasicData($request, $config);
57
-
58
-        $this->setupUsernameData($request);
59
-
60
-        $this->setupTitle($request);
61
-
62
-        $this->setupReservationDetails($request->getReserved(), $database, $currentUser);
63
-        $this->setupGeneralData($database);
64
-
65
-        $this->assign('requestDataCleared', false);
66
-        if ($request->getEmail() === $this->getSiteConfiguration()->getDataClearEmail()) {
67
-            $this->assign('requestDataCleared', true);
68
-        }
69
-
70
-        $allowedPrivateData = $this->isAllowedPrivateData($request, $currentUser);
71
-
72
-        $this->setupCreationTypes($currentUser);
73
-
74
-        $this->setupLogData($request, $database);
75
-
76
-        $this->addJs("/api.php?action=templates&targetVariable=templateconfirms");
77
-
78
-        if ($allowedPrivateData) {
79
-            $this->setTemplate('view-request/main-with-data.tpl');
80
-            $this->setupPrivateData($request, $currentUser, $this->getSiteConfiguration(), $database);
81
-
82
-            $this->assign('canSetBan', $this->barrierTest('set', $currentUser, PageBan::class));
83
-            $this->assign('canSeeCheckuserData', $this->barrierTest('seeUserAgentData', $currentUser, 'RequestData'));
84
-
85
-            if ($this->barrierTest('seeUserAgentData', $currentUser, 'RequestData')) {
86
-                $this->setTemplate('view-request/main-with-checkuser-data.tpl');
87
-                $this->setupCheckUserData($request);
88
-            }
89
-        }
90
-        else {
91
-            $this->setTemplate('view-request/main.tpl');
92
-        }
93
-    }
94
-
95
-    /**
96
-     * @param Request $request
97
-     */
98
-    protected function setupTitle(Request $request)
99
-    {
100
-        $statusSymbol = self::STATUS_SYMBOL_OPEN;
101
-        if ($request->getStatus() === 'Closed') {
102
-            if ($request->getWasCreated()) {
103
-                $statusSymbol = self::STATUS_SYMBOL_ACCEPTED;
104
-            }
105
-            else {
106
-                $statusSymbol = self::STATUS_SYMBOL_REJECTED;
107
-            }
108
-        }
109
-
110
-        $this->setHtmlTitle($statusSymbol . ' #' . $request->getId());
111
-    }
112
-
113
-    /**
114
-     * Sets up data unrelated to the request, such as the email template information
115
-     *
116
-     * @param PdoDatabase $database
117
-     */
118
-    protected function setupGeneralData(PdoDatabase $database)
119
-    {
120
-        $config = $this->getSiteConfiguration();
121
-
122
-        $this->assign('createAccountReason', 'Requested account at [[WP:ACC]], request #');
123
-
124
-        $this->assign('defaultRequestState', $config->getDefaultRequestStateKey());
125
-
126
-        $this->assign('requestStates', $config->getRequestStates());
127
-
128
-        /** @var EmailTemplate $createdTemplate */
129
-        $createdTemplate = EmailTemplate::getById($config->getDefaultCreatedTemplateId(), $database);
130
-
131
-        $this->assign('createdHasJsQuestion', $createdTemplate->getJsquestion() != '');
132
-        $this->assign('createdId', $createdTemplate->getId());
133
-        $this->assign('createdName', $createdTemplate->getName());
134
-
135
-        $createReasons = EmailTemplate::getActiveTemplates(EmailTemplate::CREATED, $database);
136
-        $this->assign("createReasons", $createReasons);
137
-        $declineReasons = EmailTemplate::getActiveTemplates(EmailTemplate::NOT_CREATED, $database);
138
-        $this->assign("declineReasons", $declineReasons);
139
-
140
-        $allCreateReasons = EmailTemplate::getAllActiveTemplates(EmailTemplate::CREATED, $database);
141
-        $this->assign("allCreateReasons", $allCreateReasons);
142
-        $allDeclineReasons = EmailTemplate::getAllActiveTemplates(EmailTemplate::NOT_CREATED, $database);
143
-        $this->assign("allDeclineReasons", $allDeclineReasons);
144
-        $allOtherReasons = EmailTemplate::getAllActiveTemplates(false, $database);
145
-        $this->assign("allOtherReasons", $allOtherReasons);
146
-    }
147
-
148
-    private function setupLogData(Request $request, PdoDatabase $database)
149
-    {
150
-        $currentUser = User::getCurrent($database);
151
-
152
-        $logs = LogHelper::getRequestLogsWithComments($request->getId(), $database, $this->getSecurityManager());
153
-        $requestLogs = array();
154
-
155
-        if (trim($request->getComment()) !== "") {
156
-            $requestLogs[] = array(
157
-                'type'     => 'comment',
158
-                'security' => 'user',
159
-                'userid'   => null,
160
-                'user'     => $request->getName(),
161
-                'entry'    => null,
162
-                'time'     => $request->getDate(),
163
-                'canedit'  => false,
164
-                'id'       => $request->getId(),
165
-                'comment'  => $request->getComment(),
166
-            );
167
-        }
168
-
169
-        /** @var User[] $nameCache */
170
-        $nameCache = array();
171
-
172
-        $editableComments = $this->barrierTest('editOthers', $currentUser, PageEditComment::class);
173
-
174
-        /** @var Log|Comment $entry */
175
-        foreach ($logs as $entry) {
176
-            // both log and comment have a 'user' field
177
-            if (!array_key_exists($entry->getUser(), $nameCache)) {
178
-                $entryUser = User::getById($entry->getUser(), $database);
179
-                $nameCache[$entry->getUser()] = $entryUser;
180
-            }
181
-
182
-            if ($entry instanceof Comment) {
183
-                $requestLogs[] = array(
184
-                    'type'     => 'comment',
185
-                    'security' => $entry->getVisibility(),
186
-                    'user'     => $nameCache[$entry->getUser()]->getUsername(),
187
-                    'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
188
-                    'entry'    => null,
189
-                    'time'     => $entry->getTime(),
190
-                    'canedit'  => ($editableComments || $entry->getUser() == $currentUser->getId()),
191
-                    'id'       => $entry->getId(),
192
-                    'comment'  => $entry->getComment(),
193
-                );
194
-            }
195
-
196
-            if ($entry instanceof Log) {
197
-                $invalidUserId = $entry->getUser() === -1 || $entry->getUser() === 0;
198
-                $entryUser = $invalidUserId ? User::getCommunity() : $nameCache[$entry->getUser()];
199
-
200
-                $entryComment = $entry->getComment();
201
-
202
-                if($entry->getAction() === 'JobIssueRequest' || $entry->getAction() === 'JobCompletedRequest'){
203
-                    $data = unserialize($entry->getComment());
204
-                    /** @var JobQueue $job */
205
-                    $job = JobQueue::getById($data['job'], $database);
206
-                    $requestLogs[] = array(
207
-                        'type'     => 'joblog',
208
-                        'security' => 'user',
209
-                        'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
210
-                        'user'     => $entryUser->getUsername(),
211
-                        'entry'    => LogHelper::getLogDescription($entry),
212
-                        'time'     => $entry->getTimestamp(),
213
-                        'canedit'  => false,
214
-                        'id'       => $entry->getId(),
215
-                        'jobId'    => $job->getId(),
216
-                        'jobDesc'  => JobQueue::getTaskDescriptions()[$job->getTask()],
217
-                    );
218
-                } else {
219
-                    $requestLogs[] = array(
220
-                        'type'     => 'log',
221
-                        'security' => 'user',
222
-                        'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
223
-                        'user'     => $entryUser->getUsername(),
224
-                        'entry'    => LogHelper::getLogDescription($entry),
225
-                        'time'     => $entry->getTimestamp(),
226
-                        'canedit'  => false,
227
-                        'id'       => $entry->getId(),
228
-                        'comment'  => $entryComment,
229
-                    );
230
-                }
231
-            }
232
-        }
233
-
234
-        $this->addJs("/api.php?action=users&targetVariable=typeaheaddata");
235
-
236
-        $this->assign("requestLogs", $requestLogs);
237
-    }
238
-
239
-    /**
240
-     * @param Request $request
241
-     */
242
-    protected function setupUsernameData(Request $request)
243
-    {
244
-        $blacklistData = $this->getBlacklistHelper()->isBlacklisted($request->getName());
245
-
246
-        $this->assign('requestIsBlacklisted', $blacklistData !== false);
247
-        $this->assign('requestBlacklist', $blacklistData);
248
-
249
-        try {
250
-            $spoofs = $this->getAntiSpoofProvider()->getSpoofs($request->getName());
251
-        }
252
-        catch (Exception $ex) {
253
-            $spoofs = $ex->getMessage();
254
-        }
255
-
256
-        $this->assign("spoofs", $spoofs);
257
-    }
258
-
259
-    private function setupCreationTypes(User $user)
260
-    {
261
-        $this->assign('allowWelcomeSkip', false);
262
-        $this->assign('forceWelcomeSkip', false);
263
-
264
-        $oauth = new OAuthUserHelper($user, $this->getDatabase(), $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
265
-
266
-        if ($user->getWelcomeTemplate() != 0) {
267
-            $this->assign('allowWelcomeSkip', true);
268
-
269
-            if (!$oauth->canWelcome()) {
270
-                $this->assign('forceWelcomeSkip', true);
271
-            }
272
-        }
273
-
274
-        // test credentials
275
-        $canManualCreate = $this->barrierTest(User::CREATION_MANUAL, $user, 'RequestCreation');
276
-        $canOauthCreate = $this->barrierTest(User::CREATION_OAUTH, $user, 'RequestCreation');
277
-        $canBotCreate = $this->barrierTest(User::CREATION_BOT, $user, 'RequestCreation');
278
-
279
-        $this->assign('canManualCreate', $canManualCreate);
280
-        $this->assign('canOauthCreate', $canOauthCreate);
281
-        $this->assign('canBotCreate', $canBotCreate);
282
-
283
-        // show/hide the type radio buttons
284
-        $creationHasChoice = count(array_filter([$canManualCreate, $canOauthCreate, $canBotCreate])) > 1;
285
-
286
-        if (!$this->barrierTest($user->getCreationMode(), $user, 'RequestCreation')) {
287
-            // user is not allowed to use their default. Force a choice.
288
-            $creationHasChoice = true;
289
-        }
290
-
291
-        $this->assign('creationHasChoice', $creationHasChoice);
292
-
293
-        // determine problems in creation types
294
-        $this->assign('botProblem', false);
295
-        if ($canBotCreate && $this->getSiteConfiguration()->getCreationBotPassword() === null) {
296
-            $this->assign('botProblem', true);
297
-        }
298
-
299
-        $this->assign('oauthProblem', false);
300
-        if ($canOauthCreate && !$oauth->canCreateAccount()) {
301
-            $this->assign('oauthProblem', true);
302
-        }
303
-    }
28
+	use RequestData;
29
+	const STATUS_SYMBOL_OPEN = '&#x2610';
30
+	const STATUS_SYMBOL_ACCEPTED = '&#x2611';
31
+	const STATUS_SYMBOL_REJECTED = '&#x2612';
32
+
33
+	/**
34
+	 * Main function for this page, when no specific actions are called.
35
+	 * @throws ApplicationLogicException
36
+	 */
37
+	protected function main()
38
+	{
39
+		// set up csrf protection
40
+		$this->assignCSRFToken();
41
+
42
+		// get some useful objects
43
+		$database = $this->getDatabase();
44
+		$request = $this->getRequest($database, WebRequest::getInt('id'));
45
+		$config = $this->getSiteConfiguration();
46
+		$currentUser = User::getCurrent($database);
47
+
48
+		// Test we should be able to look at this request
49
+		if ($config->getEmailConfirmationEnabled()) {
50
+			if ($request->getEmailConfirm() !== 'Confirmed') {
51
+				// Not allowed to look at this yet.
52
+				throw new ApplicationLogicException('The email address has not yet been confirmed for this request.');
53
+			}
54
+		}
55
+
56
+		$this->setupBasicData($request, $config);
57
+
58
+		$this->setupUsernameData($request);
59
+
60
+		$this->setupTitle($request);
61
+
62
+		$this->setupReservationDetails($request->getReserved(), $database, $currentUser);
63
+		$this->setupGeneralData($database);
64
+
65
+		$this->assign('requestDataCleared', false);
66
+		if ($request->getEmail() === $this->getSiteConfiguration()->getDataClearEmail()) {
67
+			$this->assign('requestDataCleared', true);
68
+		}
69
+
70
+		$allowedPrivateData = $this->isAllowedPrivateData($request, $currentUser);
71
+
72
+		$this->setupCreationTypes($currentUser);
73
+
74
+		$this->setupLogData($request, $database);
75
+
76
+		$this->addJs("/api.php?action=templates&targetVariable=templateconfirms");
77
+
78
+		if ($allowedPrivateData) {
79
+			$this->setTemplate('view-request/main-with-data.tpl');
80
+			$this->setupPrivateData($request, $currentUser, $this->getSiteConfiguration(), $database);
81
+
82
+			$this->assign('canSetBan', $this->barrierTest('set', $currentUser, PageBan::class));
83
+			$this->assign('canSeeCheckuserData', $this->barrierTest('seeUserAgentData', $currentUser, 'RequestData'));
84
+
85
+			if ($this->barrierTest('seeUserAgentData', $currentUser, 'RequestData')) {
86
+				$this->setTemplate('view-request/main-with-checkuser-data.tpl');
87
+				$this->setupCheckUserData($request);
88
+			}
89
+		}
90
+		else {
91
+			$this->setTemplate('view-request/main.tpl');
92
+		}
93
+	}
94
+
95
+	/**
96
+	 * @param Request $request
97
+	 */
98
+	protected function setupTitle(Request $request)
99
+	{
100
+		$statusSymbol = self::STATUS_SYMBOL_OPEN;
101
+		if ($request->getStatus() === 'Closed') {
102
+			if ($request->getWasCreated()) {
103
+				$statusSymbol = self::STATUS_SYMBOL_ACCEPTED;
104
+			}
105
+			else {
106
+				$statusSymbol = self::STATUS_SYMBOL_REJECTED;
107
+			}
108
+		}
109
+
110
+		$this->setHtmlTitle($statusSymbol . ' #' . $request->getId());
111
+	}
112
+
113
+	/**
114
+	 * Sets up data unrelated to the request, such as the email template information
115
+	 *
116
+	 * @param PdoDatabase $database
117
+	 */
118
+	protected function setupGeneralData(PdoDatabase $database)
119
+	{
120
+		$config = $this->getSiteConfiguration();
121
+
122
+		$this->assign('createAccountReason', 'Requested account at [[WP:ACC]], request #');
123
+
124
+		$this->assign('defaultRequestState', $config->getDefaultRequestStateKey());
125
+
126
+		$this->assign('requestStates', $config->getRequestStates());
127
+
128
+		/** @var EmailTemplate $createdTemplate */
129
+		$createdTemplate = EmailTemplate::getById($config->getDefaultCreatedTemplateId(), $database);
130
+
131
+		$this->assign('createdHasJsQuestion', $createdTemplate->getJsquestion() != '');
132
+		$this->assign('createdId', $createdTemplate->getId());
133
+		$this->assign('createdName', $createdTemplate->getName());
134
+
135
+		$createReasons = EmailTemplate::getActiveTemplates(EmailTemplate::CREATED, $database);
136
+		$this->assign("createReasons", $createReasons);
137
+		$declineReasons = EmailTemplate::getActiveTemplates(EmailTemplate::NOT_CREATED, $database);
138
+		$this->assign("declineReasons", $declineReasons);
139
+
140
+		$allCreateReasons = EmailTemplate::getAllActiveTemplates(EmailTemplate::CREATED, $database);
141
+		$this->assign("allCreateReasons", $allCreateReasons);
142
+		$allDeclineReasons = EmailTemplate::getAllActiveTemplates(EmailTemplate::NOT_CREATED, $database);
143
+		$this->assign("allDeclineReasons", $allDeclineReasons);
144
+		$allOtherReasons = EmailTemplate::getAllActiveTemplates(false, $database);
145
+		$this->assign("allOtherReasons", $allOtherReasons);
146
+	}
147
+
148
+	private function setupLogData(Request $request, PdoDatabase $database)
149
+	{
150
+		$currentUser = User::getCurrent($database);
151
+
152
+		$logs = LogHelper::getRequestLogsWithComments($request->getId(), $database, $this->getSecurityManager());
153
+		$requestLogs = array();
154
+
155
+		if (trim($request->getComment()) !== "") {
156
+			$requestLogs[] = array(
157
+				'type'     => 'comment',
158
+				'security' => 'user',
159
+				'userid'   => null,
160
+				'user'     => $request->getName(),
161
+				'entry'    => null,
162
+				'time'     => $request->getDate(),
163
+				'canedit'  => false,
164
+				'id'       => $request->getId(),
165
+				'comment'  => $request->getComment(),
166
+			);
167
+		}
168
+
169
+		/** @var User[] $nameCache */
170
+		$nameCache = array();
171
+
172
+		$editableComments = $this->barrierTest('editOthers', $currentUser, PageEditComment::class);
173
+
174
+		/** @var Log|Comment $entry */
175
+		foreach ($logs as $entry) {
176
+			// both log and comment have a 'user' field
177
+			if (!array_key_exists($entry->getUser(), $nameCache)) {
178
+				$entryUser = User::getById($entry->getUser(), $database);
179
+				$nameCache[$entry->getUser()] = $entryUser;
180
+			}
181
+
182
+			if ($entry instanceof Comment) {
183
+				$requestLogs[] = array(
184
+					'type'     => 'comment',
185
+					'security' => $entry->getVisibility(),
186
+					'user'     => $nameCache[$entry->getUser()]->getUsername(),
187
+					'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
188
+					'entry'    => null,
189
+					'time'     => $entry->getTime(),
190
+					'canedit'  => ($editableComments || $entry->getUser() == $currentUser->getId()),
191
+					'id'       => $entry->getId(),
192
+					'comment'  => $entry->getComment(),
193
+				);
194
+			}
195
+
196
+			if ($entry instanceof Log) {
197
+				$invalidUserId = $entry->getUser() === -1 || $entry->getUser() === 0;
198
+				$entryUser = $invalidUserId ? User::getCommunity() : $nameCache[$entry->getUser()];
199
+
200
+				$entryComment = $entry->getComment();
201
+
202
+				if($entry->getAction() === 'JobIssueRequest' || $entry->getAction() === 'JobCompletedRequest'){
203
+					$data = unserialize($entry->getComment());
204
+					/** @var JobQueue $job */
205
+					$job = JobQueue::getById($data['job'], $database);
206
+					$requestLogs[] = array(
207
+						'type'     => 'joblog',
208
+						'security' => 'user',
209
+						'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
210
+						'user'     => $entryUser->getUsername(),
211
+						'entry'    => LogHelper::getLogDescription($entry),
212
+						'time'     => $entry->getTimestamp(),
213
+						'canedit'  => false,
214
+						'id'       => $entry->getId(),
215
+						'jobId'    => $job->getId(),
216
+						'jobDesc'  => JobQueue::getTaskDescriptions()[$job->getTask()],
217
+					);
218
+				} else {
219
+					$requestLogs[] = array(
220
+						'type'     => 'log',
221
+						'security' => 'user',
222
+						'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
223
+						'user'     => $entryUser->getUsername(),
224
+						'entry'    => LogHelper::getLogDescription($entry),
225
+						'time'     => $entry->getTimestamp(),
226
+						'canedit'  => false,
227
+						'id'       => $entry->getId(),
228
+						'comment'  => $entryComment,
229
+					);
230
+				}
231
+			}
232
+		}
233
+
234
+		$this->addJs("/api.php?action=users&targetVariable=typeaheaddata");
235
+
236
+		$this->assign("requestLogs", $requestLogs);
237
+	}
238
+
239
+	/**
240
+	 * @param Request $request
241
+	 */
242
+	protected function setupUsernameData(Request $request)
243
+	{
244
+		$blacklistData = $this->getBlacklistHelper()->isBlacklisted($request->getName());
245
+
246
+		$this->assign('requestIsBlacklisted', $blacklistData !== false);
247
+		$this->assign('requestBlacklist', $blacklistData);
248
+
249
+		try {
250
+			$spoofs = $this->getAntiSpoofProvider()->getSpoofs($request->getName());
251
+		}
252
+		catch (Exception $ex) {
253
+			$spoofs = $ex->getMessage();
254
+		}
255
+
256
+		$this->assign("spoofs", $spoofs);
257
+	}
258
+
259
+	private function setupCreationTypes(User $user)
260
+	{
261
+		$this->assign('allowWelcomeSkip', false);
262
+		$this->assign('forceWelcomeSkip', false);
263
+
264
+		$oauth = new OAuthUserHelper($user, $this->getDatabase(), $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
265
+
266
+		if ($user->getWelcomeTemplate() != 0) {
267
+			$this->assign('allowWelcomeSkip', true);
268
+
269
+			if (!$oauth->canWelcome()) {
270
+				$this->assign('forceWelcomeSkip', true);
271
+			}
272
+		}
273
+
274
+		// test credentials
275
+		$canManualCreate = $this->barrierTest(User::CREATION_MANUAL, $user, 'RequestCreation');
276
+		$canOauthCreate = $this->barrierTest(User::CREATION_OAUTH, $user, 'RequestCreation');
277
+		$canBotCreate = $this->barrierTest(User::CREATION_BOT, $user, 'RequestCreation');
278
+
279
+		$this->assign('canManualCreate', $canManualCreate);
280
+		$this->assign('canOauthCreate', $canOauthCreate);
281
+		$this->assign('canBotCreate', $canBotCreate);
282
+
283
+		// show/hide the type radio buttons
284
+		$creationHasChoice = count(array_filter([$canManualCreate, $canOauthCreate, $canBotCreate])) > 1;
285
+
286
+		if (!$this->barrierTest($user->getCreationMode(), $user, 'RequestCreation')) {
287
+			// user is not allowed to use their default. Force a choice.
288
+			$creationHasChoice = true;
289
+		}
290
+
291
+		$this->assign('creationHasChoice', $creationHasChoice);
292
+
293
+		// determine problems in creation types
294
+		$this->assign('botProblem', false);
295
+		if ($canBotCreate && $this->getSiteConfiguration()->getCreationBotPassword() === null) {
296
+			$this->assign('botProblem', true);
297
+		}
298
+
299
+		$this->assign('oauthProblem', false);
300
+		if ($canOauthCreate && !$oauth->canCreateAccount()) {
301
+			$this->assign('oauthProblem', true);
302
+		}
303
+	}
304 304
 }
Please login to merge, or discard this patch.
includes/Pages/UserAuth/PagePreferences.php 1 patch
Indentation   +90 added lines, -90 removed lines patch added patch discarded remove patch
@@ -16,94 +16,94 @@
 block discarded – undo
16 16
 
17 17
 class PagePreferences extends InternalPageBase
18 18
 {
19
-    /**
20
-     * Main function for this page, when no specific actions are called.
21
-     * @return void
22
-     */
23
-    protected function main()
24
-    {
25
-        $this->setHtmlTitle('Preferences');
26
-
27
-        $enforceOAuth = $this->getSiteConfiguration()->getEnforceOAuth();
28
-        $database = $this->getDatabase();
29
-        $user = User::getCurrent($database);
30
-
31
-        // Dual mode
32
-        if (WebRequest::wasPosted()) {
33
-            $this->validateCSRFToken();
34
-            $user->setWelcomeSig(WebRequest::postString('sig'));
35
-            $user->setEmailSig(WebRequest::postString('emailsig'));
36
-            $user->setAbortPref(WebRequest::postBoolean('abortpref') ? 1 : 0);
37
-            $this->setCreationMode($user);
38
-            $user->setSkin(WebRequest::postBoolean('skintype') ? 'alt' : 'main');
39
-
40
-            $email = WebRequest::postEmail('email');
41
-            if ($email !== null) {
42
-                $user->setEmail($email);
43
-            }
44
-
45
-            $user->save();
46
-            SessionAlert::success("Preferences updated!");
47
-
48
-            $this->redirect('');
49
-        }
50
-        else {
51
-            $this->assignCSRFToken();
52
-            $this->setTemplate('preferences/prefs.tpl');
53
-            $this->assign("enforceOAuth", $enforceOAuth);
54
-
55
-            $this->assign('canManualCreate',
56
-                $this->barrierTest(User::CREATION_MANUAL, $user, 'RequestCreation'));
57
-            $this->assign('canOauthCreate',
58
-                $this->barrierTest(User::CREATION_OAUTH, $user, 'RequestCreation'));
59
-            $this->assign('canBotCreate',
60
-                $this->barrierTest(User::CREATION_BOT, $user, 'RequestCreation'));
61
-
62
-            $oauth = new OAuthUserHelper($user, $database, $this->getOAuthProtocolHelper(),
63
-                $this->getSiteConfiguration());
64
-            $this->assign('oauth', $oauth);
65
-
66
-            $identity = null;
67
-            if ($oauth->isFullyLinked()) {
68
-                $identity = $oauth->getIdentity();
69
-            }
70
-
71
-            $this->assign('identity', $identity);
72
-            $this->assign('graceTime', $this->getSiteConfiguration()->getOauthIdentityGraceTime());
73
-        }
74
-    }
75
-
76
-    protected function refreshOAuth()
77
-    {
78
-        if (!WebRequest::wasPosted()) {
79
-            $this->redirect('preferences');
80
-
81
-            return;
82
-        }
83
-
84
-        $database = $this->getDatabase();
85
-        $oauth = new OAuthUserHelper(User::getCurrent($database), $database, $this->getOAuthProtocolHelper(),
86
-            $this->getSiteConfiguration());
87
-        if ($oauth->isFullyLinked()) {
88
-            $oauth->refreshIdentity();
89
-        }
90
-
91
-        $this->redirect('preferences');
92
-
93
-        return;
94
-    }
95
-
96
-    /**
97
-     * @param User $user
98
-     */
99
-    protected function setCreationMode(User $user)
100
-    {
101
-        // if the user is selecting a creation mode that they are not allowed, do nothing.
102
-        // this has the side effect of allowing them to keep a selected mode that either has been changed for them,
103
-        // or that they have kept from when they previously had certain access.
104
-        $creationMode = WebRequest::postInt('creationmode');
105
-        if ($this->barrierTest($creationMode, $user, 'RequestCreation')) {
106
-            $user->setCreationMode($creationMode);
107
-        }
108
-    }
19
+	/**
20
+	 * Main function for this page, when no specific actions are called.
21
+	 * @return void
22
+	 */
23
+	protected function main()
24
+	{
25
+		$this->setHtmlTitle('Preferences');
26
+
27
+		$enforceOAuth = $this->getSiteConfiguration()->getEnforceOAuth();
28
+		$database = $this->getDatabase();
29
+		$user = User::getCurrent($database);
30
+
31
+		// Dual mode
32
+		if (WebRequest::wasPosted()) {
33
+			$this->validateCSRFToken();
34
+			$user->setWelcomeSig(WebRequest::postString('sig'));
35
+			$user->setEmailSig(WebRequest::postString('emailsig'));
36
+			$user->setAbortPref(WebRequest::postBoolean('abortpref') ? 1 : 0);
37
+			$this->setCreationMode($user);
38
+			$user->setSkin(WebRequest::postBoolean('skintype') ? 'alt' : 'main');
39
+
40
+			$email = WebRequest::postEmail('email');
41
+			if ($email !== null) {
42
+				$user->setEmail($email);
43
+			}
44
+
45
+			$user->save();
46
+			SessionAlert::success("Preferences updated!");
47
+
48
+			$this->redirect('');
49
+		}
50
+		else {
51
+			$this->assignCSRFToken();
52
+			$this->setTemplate('preferences/prefs.tpl');
53
+			$this->assign("enforceOAuth", $enforceOAuth);
54
+
55
+			$this->assign('canManualCreate',
56
+				$this->barrierTest(User::CREATION_MANUAL, $user, 'RequestCreation'));
57
+			$this->assign('canOauthCreate',
58
+				$this->barrierTest(User::CREATION_OAUTH, $user, 'RequestCreation'));
59
+			$this->assign('canBotCreate',
60
+				$this->barrierTest(User::CREATION_BOT, $user, 'RequestCreation'));
61
+
62
+			$oauth = new OAuthUserHelper($user, $database, $this->getOAuthProtocolHelper(),
63
+				$this->getSiteConfiguration());
64
+			$this->assign('oauth', $oauth);
65
+
66
+			$identity = null;
67
+			if ($oauth->isFullyLinked()) {
68
+				$identity = $oauth->getIdentity();
69
+			}
70
+
71
+			$this->assign('identity', $identity);
72
+			$this->assign('graceTime', $this->getSiteConfiguration()->getOauthIdentityGraceTime());
73
+		}
74
+	}
75
+
76
+	protected function refreshOAuth()
77
+	{
78
+		if (!WebRequest::wasPosted()) {
79
+			$this->redirect('preferences');
80
+
81
+			return;
82
+		}
83
+
84
+		$database = $this->getDatabase();
85
+		$oauth = new OAuthUserHelper(User::getCurrent($database), $database, $this->getOAuthProtocolHelper(),
86
+			$this->getSiteConfiguration());
87
+		if ($oauth->isFullyLinked()) {
88
+			$oauth->refreshIdentity();
89
+		}
90
+
91
+		$this->redirect('preferences');
92
+
93
+		return;
94
+	}
95
+
96
+	/**
97
+	 * @param User $user
98
+	 */
99
+	protected function setCreationMode(User $user)
100
+	{
101
+		// if the user is selecting a creation mode that they are not allowed, do nothing.
102
+		// this has the side effect of allowing them to keep a selected mode that either has been changed for them,
103
+		// or that they have kept from when they previously had certain access.
104
+		$creationMode = WebRequest::postInt('creationmode');
105
+		if ($this->barrierTest($creationMode, $user, 'RequestCreation')) {
106
+			$user->setCreationMode($creationMode);
107
+		}
108
+	}
109 109
 }
Please login to merge, or discard this patch.
includes/Pages/RequestAction/PageCustomClose.php 1 patch
Indentation   +274 added lines, -274 removed lines patch added patch discarded remove patch
@@ -24,278 +24,278 @@
 block discarded – undo
24 24
 
25 25
 class PageCustomClose extends PageCloseRequest
26 26
 {
27
-    use RequestData;
28
-
29
-    protected function main()
30
-    {
31
-        $database = $this->getDatabase();
32
-
33
-        $request = $this->getRequest($database);
34
-        $currentUser = User::getCurrent($this->getDatabase());
35
-
36
-        if ($request->getStatus() === 'Closed') {
37
-            throw new ApplicationLogicException('Request is already closed');
38
-        }
39
-
40
-        // Dual-mode page
41
-        if (WebRequest::wasPosted()) {
42
-            $this->validateCSRFToken();
43
-            $this->doCustomClose($currentUser, $request, $database);
44
-
45
-            $this->redirect();
46
-        }
47
-        else {
48
-            $this->assignCSRFToken();
49
-            $this->showCustomCloseForm($database, $request);
50
-        }
51
-    }
52
-
53
-    /**
54
-     * @param $database
55
-     *
56
-     * @return Request
57
-     * @throws ApplicationLogicException
58
-     */
59
-    protected function getRequest(PdoDatabase $database)
60
-    {
61
-        $requestId = WebRequest::getInt('request');
62
-        if ($requestId === null) {
63
-            throw new ApplicationLogicException('Request ID not found');
64
-        }
65
-
66
-        /** @var Request $request */
67
-        $request = Request::getById($requestId, $database);
68
-
69
-        if ($request === false) {
70
-            throw new ApplicationLogicException('Request not found');
71
-        }
72
-
73
-        return $request;
74
-    }
75
-
76
-    /**
77
-     * @param PdoDatabase $database
78
-     *
79
-     * @return EmailTemplate|null
80
-     */
81
-    protected function getTemplate(PdoDatabase $database)
82
-    {
83
-        $templateId = WebRequest::getInt('template');
84
-        if ($templateId === null) {
85
-            return null;
86
-        }
87
-
88
-        /** @var EmailTemplate $template */
89
-        $template = EmailTemplate::getById($templateId, $database);
90
-        if ($template === false || !$template->getActive()) {
91
-            return null;
92
-        }
93
-
94
-        return $template;
95
-    }
96
-
97
-    /**
98
-     * @param $database
99
-     * @param $request
100
-     *
101
-     * @throws Exception
102
-     */
103
-    protected function showCustomCloseForm(PdoDatabase $database, Request $request)
104
-    {
105
-        $currentUser = User::getCurrent($database);
106
-        $config = $this->getSiteConfiguration();
107
-
108
-        $allowedPrivateData = $this->isAllowedPrivateData($request, $currentUser);
109
-        if (!$allowedPrivateData) {
110
-            // we probably shouldn't be showing the user this form if they're not allowed to access private data...
111
-            throw new AccessDeniedException($this->getSecurityManager());
112
-        }
113
-
114
-        $template = $this->getTemplate($database);
115
-
116
-        // Preload data
117
-        $this->assign('defaultAction', '');
118
-        $this->assign('preloadText', '');
119
-        $this->assign('preloadTitle', '');
120
-
121
-        if ($template !== null) {
122
-            $this->assign('defaultAction', $template->getDefaultAction());
123
-            $this->assign('preloadText', $template->getText());
124
-            $this->assign('preloadTitle', $template->getName());
125
-        }
126
-
127
-        // Static data
128
-        $this->assign('requeststates', $config->getRequestStates());
129
-
130
-        // request data
131
-        $this->assign('requestId', $request->getIp());
132
-        $this->assign('updateVersion', $request->getUpdateVersion());
133
-        $this->setupBasicData($request, $config);
134
-        $this->setupReservationDetails($request->getReserved(), $database, $currentUser);
135
-        $this->setupPrivateData($request, $currentUser, $this->getSiteConfiguration(), $database);
136
-
137
-        // IP location
138
-        $trustedIp = $this->getXffTrustProvider()->getTrustedClientIp($request->getIp(), $request->getForwardedIp());
139
-        $this->assign('iplocation', $this->getLocationProvider()->getIpLocation($trustedIp));
140
-
141
-        // Confirmations
142
-        $this->assign('confirmEmailAlreadySent', $this->checkEmailAlreadySent($request));
143
-
144
-        $this->assign('canSkipCcMailingList', $this->barrierTest('skipCcMailingList', $currentUser));
145
-
146
-        $this->assign('allowWelcomeSkip', false);
147
-        $this->assign('forceWelcomeSkip', false);
148
-
149
-        $oauth = new OAuthUserHelper($currentUser, $this->getDatabase(), $this->getOAuthProtocolHelper(), $config);
150
-
151
-        if ($currentUser->getWelcomeTemplate() != 0) {
152
-            $this->assign('allowWelcomeSkip', true);
153
-
154
-            if (!$oauth->canWelcome()) {
155
-                $this->assign('forceWelcomeSkip', true);
156
-            }
157
-        }
158
-
159
-
160
-        // template
161
-        $this->setTemplate('custom-close.tpl');
162
-    }
163
-
164
-    /**
165
-     * @param User        $currentUser
166
-     * @param Request     $request
167
-     * @param PdoDatabase $database
168
-     *
169
-     * @throws ApplicationLogicException
170
-     */
171
-    protected function doCustomClose(User $currentUser, Request $request, PdoDatabase $database)
172
-    {
173
-        $messageBody = WebRequest::postString('msgbody');
174
-        if ($messageBody === null || trim($messageBody) === '') {
175
-            throw new ApplicationLogicException('Message body cannot be blank');
176
-        }
177
-
178
-        $ccMailingList = true;
179
-        if ($this->barrierTest('skipCcMailingList', $currentUser)) {
180
-            $ccMailingList = WebRequest::postBoolean('ccMailingList');
181
-        }
182
-
183
-        if ($request->getStatus() === 'Closed') {
184
-            throw new ApplicationLogicException('Request is already closed');
185
-        }
186
-
187
-        if (!(WebRequest::postBoolean('confirmEmailAlreadySent'))
188
-        ) {
189
-            throw new ApplicationLogicException('Not all confirmations checked');
190
-        }
191
-
192
-        $action = WebRequest::postString('action');
193
-        $availableRequestStates = $this->getSiteConfiguration()->getRequestStates();
194
-
195
-        if ($action === EmailTemplate::CREATED || $action === EmailTemplate::NOT_CREATED) {
196
-            // Close request
197
-            $this->closeRequest($request, $database, $action, $messageBody);
198
-
199
-            $this->processWelcome($action);
200
-
201
-            // Send the mail after the save, since save can be rolled back
202
-            $this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
203
-        }
204
-        else {
205
-            if (array_key_exists($action, $availableRequestStates)) {
206
-                // Defer to other state
207
-                $this->deferRequest($request, $database, $action, $availableRequestStates, $messageBody);
208
-
209
-                // Send the mail after the save, since save can be rolled back
210
-                $this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
211
-            }
212
-            else {
213
-                $request->setReserved(null);
214
-                $request->setUpdateVersion(WebRequest::postInt('updateversion'));
215
-                $request->save();
216
-
217
-                // Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE
218
-                // and be rolled back.
219
-
220
-                // Send mail
221
-                $this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
222
-
223
-                Logger::sentMail($database, $request, $messageBody);
224
-                Logger::unreserve($database, $request);
225
-
226
-                $this->getNotificationHelper()->sentMail($request);
227
-                SessionAlert::success("Sent mail to Request {$request->getId()}");
228
-            }
229
-        }
230
-    }
231
-
232
-    /**
233
-     * @param Request     $request
234
-     * @param PdoDatabase $database
235
-     * @param string      $action
236
-     * @param string      $messageBody
237
-     *
238
-     * @throws Exception
239
-     * @throws OptimisticLockFailedException
240
-     */
241
-    protected function closeRequest(Request $request, PdoDatabase $database, $action, $messageBody)
242
-    {
243
-        $request->setStatus('Closed');
244
-        $request->setReserved(null);
245
-        $request->setUpdateVersion(WebRequest::postInt('updateversion'));
246
-        $request->save();
247
-
248
-        // Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE and
249
-        // be rolled back.
250
-
251
-        if ($action == EmailTemplate::CREATED) {
252
-            $logCloseType = 'custom-y';
253
-            $notificationCloseType = "Custom, Created";
254
-        }
255
-        else {
256
-            $logCloseType = 'custom-n';
257
-            $notificationCloseType = "Custom, Not Created";
258
-        }
259
-
260
-        Logger::closeRequest($database, $request, $logCloseType, $messageBody);
261
-        $this->getNotificationHelper()->requestClosed($request, $notificationCloseType);
262
-
263
-        $requestName = htmlentities($request->getName(), ENT_COMPAT, 'UTF-8');
264
-        SessionAlert::success("Request {$request->getId()} ({$requestName}) closed as {$notificationCloseType}.");
265
-    }
266
-
267
-    /**
268
-     * @param Request     $request
269
-     * @param PdoDatabase $database
270
-     * @param string      $action
271
-     * @param             $availableRequestStates
272
-     * @param string      $messageBody
273
-     *
274
-     * @throws Exception
275
-     * @throws OptimisticLockFailedException
276
-     */
277
-    protected function deferRequest(
278
-        Request $request,
279
-        PdoDatabase $database,
280
-        $action,
281
-        $availableRequestStates,
282
-        $messageBody
283
-    ) {
284
-        $request->setStatus($action);
285
-        $request->setReserved(null);
286
-        $request->setUpdateVersion(WebRequest::postInt('updateversion'));
287
-        $request->save();
288
-
289
-        // Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE
290
-        // and be rolled back.
291
-
292
-        $deferToLog = $availableRequestStates[$action]['defertolog'];
293
-        Logger::sentMail($database, $request, $messageBody);
294
-        Logger::deferRequest($database, $request, $deferToLog);
295
-
296
-        $this->getNotificationHelper()->requestDeferredWithMail($request);
297
-
298
-        $deferTo = $availableRequestStates[$action]['deferto'];
299
-        SessionAlert::success("Request {$request->getId()} deferred to $deferTo, sending an email.");
300
-    }
27
+	use RequestData;
28
+
29
+	protected function main()
30
+	{
31
+		$database = $this->getDatabase();
32
+
33
+		$request = $this->getRequest($database);
34
+		$currentUser = User::getCurrent($this->getDatabase());
35
+
36
+		if ($request->getStatus() === 'Closed') {
37
+			throw new ApplicationLogicException('Request is already closed');
38
+		}
39
+
40
+		// Dual-mode page
41
+		if (WebRequest::wasPosted()) {
42
+			$this->validateCSRFToken();
43
+			$this->doCustomClose($currentUser, $request, $database);
44
+
45
+			$this->redirect();
46
+		}
47
+		else {
48
+			$this->assignCSRFToken();
49
+			$this->showCustomCloseForm($database, $request);
50
+		}
51
+	}
52
+
53
+	/**
54
+	 * @param $database
55
+	 *
56
+	 * @return Request
57
+	 * @throws ApplicationLogicException
58
+	 */
59
+	protected function getRequest(PdoDatabase $database)
60
+	{
61
+		$requestId = WebRequest::getInt('request');
62
+		if ($requestId === null) {
63
+			throw new ApplicationLogicException('Request ID not found');
64
+		}
65
+
66
+		/** @var Request $request */
67
+		$request = Request::getById($requestId, $database);
68
+
69
+		if ($request === false) {
70
+			throw new ApplicationLogicException('Request not found');
71
+		}
72
+
73
+		return $request;
74
+	}
75
+
76
+	/**
77
+	 * @param PdoDatabase $database
78
+	 *
79
+	 * @return EmailTemplate|null
80
+	 */
81
+	protected function getTemplate(PdoDatabase $database)
82
+	{
83
+		$templateId = WebRequest::getInt('template');
84
+		if ($templateId === null) {
85
+			return null;
86
+		}
87
+
88
+		/** @var EmailTemplate $template */
89
+		$template = EmailTemplate::getById($templateId, $database);
90
+		if ($template === false || !$template->getActive()) {
91
+			return null;
92
+		}
93
+
94
+		return $template;
95
+	}
96
+
97
+	/**
98
+	 * @param $database
99
+	 * @param $request
100
+	 *
101
+	 * @throws Exception
102
+	 */
103
+	protected function showCustomCloseForm(PdoDatabase $database, Request $request)
104
+	{
105
+		$currentUser = User::getCurrent($database);
106
+		$config = $this->getSiteConfiguration();
107
+
108
+		$allowedPrivateData = $this->isAllowedPrivateData($request, $currentUser);
109
+		if (!$allowedPrivateData) {
110
+			// we probably shouldn't be showing the user this form if they're not allowed to access private data...
111
+			throw new AccessDeniedException($this->getSecurityManager());
112
+		}
113
+
114
+		$template = $this->getTemplate($database);
115
+
116
+		// Preload data
117
+		$this->assign('defaultAction', '');
118
+		$this->assign('preloadText', '');
119
+		$this->assign('preloadTitle', '');
120
+
121
+		if ($template !== null) {
122
+			$this->assign('defaultAction', $template->getDefaultAction());
123
+			$this->assign('preloadText', $template->getText());
124
+			$this->assign('preloadTitle', $template->getName());
125
+		}
126
+
127
+		// Static data
128
+		$this->assign('requeststates', $config->getRequestStates());
129
+
130
+		// request data
131
+		$this->assign('requestId', $request->getIp());
132
+		$this->assign('updateVersion', $request->getUpdateVersion());
133
+		$this->setupBasicData($request, $config);
134
+		$this->setupReservationDetails($request->getReserved(), $database, $currentUser);
135
+		$this->setupPrivateData($request, $currentUser, $this->getSiteConfiguration(), $database);
136
+
137
+		// IP location
138
+		$trustedIp = $this->getXffTrustProvider()->getTrustedClientIp($request->getIp(), $request->getForwardedIp());
139
+		$this->assign('iplocation', $this->getLocationProvider()->getIpLocation($trustedIp));
140
+
141
+		// Confirmations
142
+		$this->assign('confirmEmailAlreadySent', $this->checkEmailAlreadySent($request));
143
+
144
+		$this->assign('canSkipCcMailingList', $this->barrierTest('skipCcMailingList', $currentUser));
145
+
146
+		$this->assign('allowWelcomeSkip', false);
147
+		$this->assign('forceWelcomeSkip', false);
148
+
149
+		$oauth = new OAuthUserHelper($currentUser, $this->getDatabase(), $this->getOAuthProtocolHelper(), $config);
150
+
151
+		if ($currentUser->getWelcomeTemplate() != 0) {
152
+			$this->assign('allowWelcomeSkip', true);
153
+
154
+			if (!$oauth->canWelcome()) {
155
+				$this->assign('forceWelcomeSkip', true);
156
+			}
157
+		}
158
+
159
+
160
+		// template
161
+		$this->setTemplate('custom-close.tpl');
162
+	}
163
+
164
+	/**
165
+	 * @param User        $currentUser
166
+	 * @param Request     $request
167
+	 * @param PdoDatabase $database
168
+	 *
169
+	 * @throws ApplicationLogicException
170
+	 */
171
+	protected function doCustomClose(User $currentUser, Request $request, PdoDatabase $database)
172
+	{
173
+		$messageBody = WebRequest::postString('msgbody');
174
+		if ($messageBody === null || trim($messageBody) === '') {
175
+			throw new ApplicationLogicException('Message body cannot be blank');
176
+		}
177
+
178
+		$ccMailingList = true;
179
+		if ($this->barrierTest('skipCcMailingList', $currentUser)) {
180
+			$ccMailingList = WebRequest::postBoolean('ccMailingList');
181
+		}
182
+
183
+		if ($request->getStatus() === 'Closed') {
184
+			throw new ApplicationLogicException('Request is already closed');
185
+		}
186
+
187
+		if (!(WebRequest::postBoolean('confirmEmailAlreadySent'))
188
+		) {
189
+			throw new ApplicationLogicException('Not all confirmations checked');
190
+		}
191
+
192
+		$action = WebRequest::postString('action');
193
+		$availableRequestStates = $this->getSiteConfiguration()->getRequestStates();
194
+
195
+		if ($action === EmailTemplate::CREATED || $action === EmailTemplate::NOT_CREATED) {
196
+			// Close request
197
+			$this->closeRequest($request, $database, $action, $messageBody);
198
+
199
+			$this->processWelcome($action);
200
+
201
+			// Send the mail after the save, since save can be rolled back
202
+			$this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
203
+		}
204
+		else {
205
+			if (array_key_exists($action, $availableRequestStates)) {
206
+				// Defer to other state
207
+				$this->deferRequest($request, $database, $action, $availableRequestStates, $messageBody);
208
+
209
+				// Send the mail after the save, since save can be rolled back
210
+				$this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
211
+			}
212
+			else {
213
+				$request->setReserved(null);
214
+				$request->setUpdateVersion(WebRequest::postInt('updateversion'));
215
+				$request->save();
216
+
217
+				// Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE
218
+				// and be rolled back.
219
+
220
+				// Send mail
221
+				$this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
222
+
223
+				Logger::sentMail($database, $request, $messageBody);
224
+				Logger::unreserve($database, $request);
225
+
226
+				$this->getNotificationHelper()->sentMail($request);
227
+				SessionAlert::success("Sent mail to Request {$request->getId()}");
228
+			}
229
+		}
230
+	}
231
+
232
+	/**
233
+	 * @param Request     $request
234
+	 * @param PdoDatabase $database
235
+	 * @param string      $action
236
+	 * @param string      $messageBody
237
+	 *
238
+	 * @throws Exception
239
+	 * @throws OptimisticLockFailedException
240
+	 */
241
+	protected function closeRequest(Request $request, PdoDatabase $database, $action, $messageBody)
242
+	{
243
+		$request->setStatus('Closed');
244
+		$request->setReserved(null);
245
+		$request->setUpdateVersion(WebRequest::postInt('updateversion'));
246
+		$request->save();
247
+
248
+		// Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE and
249
+		// be rolled back.
250
+
251
+		if ($action == EmailTemplate::CREATED) {
252
+			$logCloseType = 'custom-y';
253
+			$notificationCloseType = "Custom, Created";
254
+		}
255
+		else {
256
+			$logCloseType = 'custom-n';
257
+			$notificationCloseType = "Custom, Not Created";
258
+		}
259
+
260
+		Logger::closeRequest($database, $request, $logCloseType, $messageBody);
261
+		$this->getNotificationHelper()->requestClosed($request, $notificationCloseType);
262
+
263
+		$requestName = htmlentities($request->getName(), ENT_COMPAT, 'UTF-8');
264
+		SessionAlert::success("Request {$request->getId()} ({$requestName}) closed as {$notificationCloseType}.");
265
+	}
266
+
267
+	/**
268
+	 * @param Request     $request
269
+	 * @param PdoDatabase $database
270
+	 * @param string      $action
271
+	 * @param             $availableRequestStates
272
+	 * @param string      $messageBody
273
+	 *
274
+	 * @throws Exception
275
+	 * @throws OptimisticLockFailedException
276
+	 */
277
+	protected function deferRequest(
278
+		Request $request,
279
+		PdoDatabase $database,
280
+		$action,
281
+		$availableRequestStates,
282
+		$messageBody
283
+	) {
284
+		$request->setStatus($action);
285
+		$request->setReserved(null);
286
+		$request->setUpdateVersion(WebRequest::postInt('updateversion'));
287
+		$request->save();
288
+
289
+		// Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE
290
+		// and be rolled back.
291
+
292
+		$deferToLog = $availableRequestStates[$action]['defertolog'];
293
+		Logger::sentMail($database, $request, $messageBody);
294
+		Logger::deferRequest($database, $request, $deferToLog);
295
+
296
+		$this->getNotificationHelper()->requestDeferredWithMail($request);
297
+
298
+		$deferTo = $availableRequestStates[$action]['deferto'];
299
+		SessionAlert::success("Request {$request->getId()} deferred to $deferTo, sending an email.");
300
+	}
301 301
 }
Please login to merge, or discard this patch.
includes/Pages/RequestAction/PageCloseRequest.php 2 patches
Indentation   +225 added lines, -225 removed lines patch added patch discarded remove patch
@@ -21,229 +21,229 @@
 block discarded – undo
21 21
 
22 22
 class PageCloseRequest extends RequestActionBase
23 23
 {
24
-    protected function main()
25
-    {
26
-        $this->processClose();
27
-    }
28
-
29
-    /**
30
-     * Main function for this page, when no specific actions are called.
31
-     * @throws ApplicationLogicException
32
-     */
33
-    final protected function processClose()
34
-    {
35
-        $this->checkPosted();
36
-        $database = $this->getDatabase();
37
-
38
-        $currentUser = User::getCurrent($database);
39
-        $template = $this->getTemplate($database);
40
-        $request = $this->getRequest($database);
41
-        $request->setUpdateVersion(WebRequest::postInt('updateversion'));
42
-
43
-        if ($request->getStatus() === 'Closed') {
44
-            throw new ApplicationLogicException('Request is already closed');
45
-        }
46
-
47
-        if ($this->confirmEmailAlreadySent($request, $template)) {
48
-            return;
49
-        }
50
-
51
-        if ($this->checkReserveProtect($request, $currentUser)) {
52
-            return;
53
-        }
54
-
55
-        if ($this->confirmAccountCreated($request, $template)) {
56
-            return;
57
-        }
58
-
59
-        // I think we're good here...
60
-        $request->setStatus('Closed');
61
-        $request->setReserved(null);
62
-
63
-        Logger::closeRequest($database, $request, $template->getId(), null);
64
-
65
-        $request->save();
66
-
67
-        $this->processWelcome($template->getDefaultAction());
68
-
69
-        // Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE and
70
-        // be rolled back.
71
-
72
-        $this->getNotificationHelper()->requestClosed($request, $template->getName());
73
-        $sanitisedTemplateName = htmlentities($template->getName(), ENT_COMPAT, 'UTF-8');
74
-        SessionAlert::success("Request {$request->getId()} has been closed as {$sanitisedTemplateName}");
75
-
76
-        $this->sendMail($request, $template->getText(), $currentUser, false);
77
-
78
-        $this->redirect();
79
-    }
80
-
81
-    /**
82
-     * @param PdoDatabase $database
83
-     *
84
-     * @return EmailTemplate
85
-     * @throws ApplicationLogicException
86
-     */
87
-    protected function getTemplate(PdoDatabase $database)
88
-    {
89
-        $templateId = WebRequest::postInt('template');
90
-        if ($templateId === null) {
91
-            throw new ApplicationLogicException('No template specified');
92
-        }
93
-
94
-        /** @var EmailTemplate $template */
95
-        $template = EmailTemplate::getById($templateId, $database);
96
-        if ($template === false || !$template->getActive()) {
97
-            throw new ApplicationLogicException('Invalid or inactive template specified');
98
-        }
99
-
100
-        return $template;
101
-    }
102
-
103
-    /**
104
-     * @param Request       $request
105
-     * @param EmailTemplate $template
106
-     *
107
-     * @return bool
108
-     */
109
-    protected function confirmEmailAlreadySent(Request $request, EmailTemplate $template)
110
-    {
111
-        if ($this->checkEmailAlreadySent($request)) {
112
-            $this->showConfirmation($request, $template, 'close-confirmations/email-sent.tpl');
113
-
114
-            return true;
115
-        }
116
-
117
-        return false;
118
-    }
119
-
120
-    protected function checkEmailAlreadySent(Request $request)
121
-    {
122
-        if ($request->getEmailSent() && !WebRequest::postBoolean('emailSentOverride')) {
123
-            return true;
124
-        }
125
-
126
-        return false;
127
-    }
128
-
129
-    protected function checkReserveProtect(Request $request, User $currentUser)
130
-    {
131
-        $reservationId = $request->getReserved();
132
-
133
-        if ($reservationId !== 0 && $reservationId !== null) {
134
-            if ($currentUser->getId() !== $reservationId) {
135
-                SessionAlert::error("Request is reserved by someone else.");
136
-                $this->redirect('/viewRequest', null, ['id' => $request->getId()] );
137
-                return true;
138
-            }
139
-        }
140
-
141
-        return false;
142
-    }
143
-
144
-    /**
145
-     * @param Request       $request
146
-     * @param EmailTemplate $template
147
-     *
148
-     * @return bool
149
-     * @throws \Waca\Exceptions\CurlException
150
-     */
151
-    protected function confirmAccountCreated(Request $request, EmailTemplate $template)
152
-    {
153
-        if ($this->checkAccountCreated($request, $template)) {
154
-            $this->showConfirmation($request, $template, 'close-confirmations/account-created.tpl');
155
-
156
-            return true;
157
-        }
158
-
159
-        return false;
160
-    }
161
-
162
-    protected function checkAccountCreated(Request $request, EmailTemplate $template)
163
-    {
164
-        if ($template->getDefaultAction() === EmailTemplate::CREATED && !WebRequest::postBoolean('createOverride')) {
165
-            $parameters = array(
166
-                'action'  => 'query',
167
-                'list'    => 'users',
168
-                'format'  => 'php',
169
-                'ususers' => $request->getName(),
170
-            );
171
-
172
-            $content = $this->getHttpHelper()->get($this->getSiteConfiguration()->getMediawikiWebServiceEndpoint(),
173
-                $parameters);
174
-
175
-            $apiResult = unserialize($content);
176
-            $exists = !isset($apiResult['query']['users']['0']['missing']);
177
-
178
-            if (!$exists) {
179
-                return true;
180
-            }
181
-        }
182
-
183
-        return false;
184
-    }
185
-
186
-    /**
187
-     * @param Request $request
188
-     * @param string  $mailText
189
-     * @param User    $currentUser
190
-     * @param boolean $ccMailingList
191
-     */
192
-    protected function sendMail(Request $request, $mailText, User $currentUser, $ccMailingList)
193
-    {
194
-        $requestEmailHelper = new RequestEmailHelper($this->getEmailHelper());
195
-        $requestEmailHelper->sendMail($request, $mailText, $currentUser, $ccMailingList);
196
-
197
-        $request->setEmailSent(true);
198
-        $request->save();
199
-    }
200
-
201
-    /**
202
-     * @param Request       $request
203
-     * @param EmailTemplate $template
204
-     * @param string        $templateName
205
-     *
206
-     * @throws Exception
207
-     * @return void
208
-     */
209
-    protected function showConfirmation(Request $request, EmailTemplate $template, $templateName)
210
-    {
211
-        $this->assignCSRFToken();
212
-
213
-        $this->assign('request', $request->getId());
214
-        $this->assign('template', $template->getId());
215
-
216
-        $this->assign('updateversion', $request->getUpdateVersion());
217
-
218
-        $this->assign('emailSentOverride', WebRequest::postBoolean('emailSentOverride') ? 'true' : 'false');
219
-        $this->assign('reserveOverride', WebRequest::postBoolean('reserveOverride') ? 'true' : 'false');
220
-        $this->assign('createOverride', WebRequest::postBoolean('createOverride') ? 'true' : 'false');
221
-
222
-        $this->setTemplate($templateName);
223
-    }
224
-
225
-    /**
226
-     * @param string $action
227
-     *
228
-     * @throws ApplicationLogicException
229
-     */
230
-    final protected function processWelcome(string $action): void
231
-    {
232
-        $database = $this->getDatabase();
233
-        $currentUser = User::getCurrent($database);
234
-
235
-        if ($action !== EmailTemplate::CREATED) {
236
-            return;
237
-        }
238
-
239
-        if ($currentUser->getWelcomeTemplate() === null) {
240
-            return;
241
-        }
242
-
243
-        if (WebRequest::postBoolean('skipAutoWelcome')) {
244
-            return;
245
-        }
246
-
247
-        $this->enqueueWelcomeTask($this->getRequest($database), null, $currentUser, $database);
248
-    }
24
+	protected function main()
25
+	{
26
+		$this->processClose();
27
+	}
28
+
29
+	/**
30
+	 * Main function for this page, when no specific actions are called.
31
+	 * @throws ApplicationLogicException
32
+	 */
33
+	final protected function processClose()
34
+	{
35
+		$this->checkPosted();
36
+		$database = $this->getDatabase();
37
+
38
+		$currentUser = User::getCurrent($database);
39
+		$template = $this->getTemplate($database);
40
+		$request = $this->getRequest($database);
41
+		$request->setUpdateVersion(WebRequest::postInt('updateversion'));
42
+
43
+		if ($request->getStatus() === 'Closed') {
44
+			throw new ApplicationLogicException('Request is already closed');
45
+		}
46
+
47
+		if ($this->confirmEmailAlreadySent($request, $template)) {
48
+			return;
49
+		}
50
+
51
+		if ($this->checkReserveProtect($request, $currentUser)) {
52
+			return;
53
+		}
54
+
55
+		if ($this->confirmAccountCreated($request, $template)) {
56
+			return;
57
+		}
58
+
59
+		// I think we're good here...
60
+		$request->setStatus('Closed');
61
+		$request->setReserved(null);
62
+
63
+		Logger::closeRequest($database, $request, $template->getId(), null);
64
+
65
+		$request->save();
66
+
67
+		$this->processWelcome($template->getDefaultAction());
68
+
69
+		// Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE and
70
+		// be rolled back.
71
+
72
+		$this->getNotificationHelper()->requestClosed($request, $template->getName());
73
+		$sanitisedTemplateName = htmlentities($template->getName(), ENT_COMPAT, 'UTF-8');
74
+		SessionAlert::success("Request {$request->getId()} has been closed as {$sanitisedTemplateName}");
75
+
76
+		$this->sendMail($request, $template->getText(), $currentUser, false);
77
+
78
+		$this->redirect();
79
+	}
80
+
81
+	/**
82
+	 * @param PdoDatabase $database
83
+	 *
84
+	 * @return EmailTemplate
85
+	 * @throws ApplicationLogicException
86
+	 */
87
+	protected function getTemplate(PdoDatabase $database)
88
+	{
89
+		$templateId = WebRequest::postInt('template');
90
+		if ($templateId === null) {
91
+			throw new ApplicationLogicException('No template specified');
92
+		}
93
+
94
+		/** @var EmailTemplate $template */
95
+		$template = EmailTemplate::getById($templateId, $database);
96
+		if ($template === false || !$template->getActive()) {
97
+			throw new ApplicationLogicException('Invalid or inactive template specified');
98
+		}
99
+
100
+		return $template;
101
+	}
102
+
103
+	/**
104
+	 * @param Request       $request
105
+	 * @param EmailTemplate $template
106
+	 *
107
+	 * @return bool
108
+	 */
109
+	protected function confirmEmailAlreadySent(Request $request, EmailTemplate $template)
110
+	{
111
+		if ($this->checkEmailAlreadySent($request)) {
112
+			$this->showConfirmation($request, $template, 'close-confirmations/email-sent.tpl');
113
+
114
+			return true;
115
+		}
116
+
117
+		return false;
118
+	}
119
+
120
+	protected function checkEmailAlreadySent(Request $request)
121
+	{
122
+		if ($request->getEmailSent() && !WebRequest::postBoolean('emailSentOverride')) {
123
+			return true;
124
+		}
125
+
126
+		return false;
127
+	}
128
+
129
+	protected function checkReserveProtect(Request $request, User $currentUser)
130
+	{
131
+		$reservationId = $request->getReserved();
132
+
133
+		if ($reservationId !== 0 && $reservationId !== null) {
134
+			if ($currentUser->getId() !== $reservationId) {
135
+				SessionAlert::error("Request is reserved by someone else.");
136
+				$this->redirect('/viewRequest', null, ['id' => $request->getId()] );
137
+				return true;
138
+			}
139
+		}
140
+
141
+		return false;
142
+	}
143
+
144
+	/**
145
+	 * @param Request       $request
146
+	 * @param EmailTemplate $template
147
+	 *
148
+	 * @return bool
149
+	 * @throws \Waca\Exceptions\CurlException
150
+	 */
151
+	protected function confirmAccountCreated(Request $request, EmailTemplate $template)
152
+	{
153
+		if ($this->checkAccountCreated($request, $template)) {
154
+			$this->showConfirmation($request, $template, 'close-confirmations/account-created.tpl');
155
+
156
+			return true;
157
+		}
158
+
159
+		return false;
160
+	}
161
+
162
+	protected function checkAccountCreated(Request $request, EmailTemplate $template)
163
+	{
164
+		if ($template->getDefaultAction() === EmailTemplate::CREATED && !WebRequest::postBoolean('createOverride')) {
165
+			$parameters = array(
166
+				'action'  => 'query',
167
+				'list'    => 'users',
168
+				'format'  => 'php',
169
+				'ususers' => $request->getName(),
170
+			);
171
+
172
+			$content = $this->getHttpHelper()->get($this->getSiteConfiguration()->getMediawikiWebServiceEndpoint(),
173
+				$parameters);
174
+
175
+			$apiResult = unserialize($content);
176
+			$exists = !isset($apiResult['query']['users']['0']['missing']);
177
+
178
+			if (!$exists) {
179
+				return true;
180
+			}
181
+		}
182
+
183
+		return false;
184
+	}
185
+
186
+	/**
187
+	 * @param Request $request
188
+	 * @param string  $mailText
189
+	 * @param User    $currentUser
190
+	 * @param boolean $ccMailingList
191
+	 */
192
+	protected function sendMail(Request $request, $mailText, User $currentUser, $ccMailingList)
193
+	{
194
+		$requestEmailHelper = new RequestEmailHelper($this->getEmailHelper());
195
+		$requestEmailHelper->sendMail($request, $mailText, $currentUser, $ccMailingList);
196
+
197
+		$request->setEmailSent(true);
198
+		$request->save();
199
+	}
200
+
201
+	/**
202
+	 * @param Request       $request
203
+	 * @param EmailTemplate $template
204
+	 * @param string        $templateName
205
+	 *
206
+	 * @throws Exception
207
+	 * @return void
208
+	 */
209
+	protected function showConfirmation(Request $request, EmailTemplate $template, $templateName)
210
+	{
211
+		$this->assignCSRFToken();
212
+
213
+		$this->assign('request', $request->getId());
214
+		$this->assign('template', $template->getId());
215
+
216
+		$this->assign('updateversion', $request->getUpdateVersion());
217
+
218
+		$this->assign('emailSentOverride', WebRequest::postBoolean('emailSentOverride') ? 'true' : 'false');
219
+		$this->assign('reserveOverride', WebRequest::postBoolean('reserveOverride') ? 'true' : 'false');
220
+		$this->assign('createOverride', WebRequest::postBoolean('createOverride') ? 'true' : 'false');
221
+
222
+		$this->setTemplate($templateName);
223
+	}
224
+
225
+	/**
226
+	 * @param string $action
227
+	 *
228
+	 * @throws ApplicationLogicException
229
+	 */
230
+	final protected function processWelcome(string $action): void
231
+	{
232
+		$database = $this->getDatabase();
233
+		$currentUser = User::getCurrent($database);
234
+
235
+		if ($action !== EmailTemplate::CREATED) {
236
+			return;
237
+		}
238
+
239
+		if ($currentUser->getWelcomeTemplate() === null) {
240
+			return;
241
+		}
242
+
243
+		if (WebRequest::postBoolean('skipAutoWelcome')) {
244
+			return;
245
+		}
246
+
247
+		$this->enqueueWelcomeTask($this->getRequest($database), null, $currentUser, $database);
248
+	}
249 249
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -133,7 +133,7 @@
 block discarded – undo
133 133
         if ($reservationId !== 0 && $reservationId !== null) {
134 134
             if ($currentUser->getId() !== $reservationId) {
135 135
                 SessionAlert::error("Request is reserved by someone else.");
136
-                $this->redirect('/viewRequest', null, ['id' => $request->getId()] );
136
+                $this->redirect('/viewRequest', null, ['id' => $request->getId()]);
137 137
                 return true;
138 138
             }
139 139
         }
Please login to merge, or discard this patch.