Failed Conditions
Branch newinternal (286d66)
by Simon
03:46
created

PageCustomClose::deferRequest()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 24
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 24
ccs 0
cts 18
cp 0
rs 8.9713
cc 1
eloc 16
nc 1
nop 5
crap 2
1
<?php
2
/******************************************************************************
3
 * Wikipedia Account Creation Assistance tool                                 *
4
 *                                                                            *
5
 * All code in this file is released into the public domain by the ACC        *
6
 * Development Team. Please see team.json for a list of contributors.         *
7
 ******************************************************************************/
8
9
namespace Waca\Pages\RequestAction;
10
11
use Exception;
12
use Waca\DataObjects\EmailTemplate;
13
use Waca\DataObjects\Request;
14
use Waca\DataObjects\User;
15
use Waca\Exceptions\ApplicationLogicException;
16
use Waca\Exceptions\OptimisticLockFailedException;
17
use Waca\Helpers\Logger;
18
use Waca\PdoDatabase;
19
use Waca\SessionAlert;
20
use Waca\WebRequest;
21
22
class PageCustomClose extends PageCloseRequest
23
{
24
	protected function main()
25
	{
26
		$database = $this->getDatabase();
27
28
		$request = $this->getRequest($database);
29
		$currentUser = User::getCurrent($this->getDatabase());
30
31
		if ($request->getStatus() === 'Closed') {
32
			throw new ApplicationLogicException('Request is already closed');
33
		}
34
35
		// @todo: checks for reservation, already created, etc - do this as checkboxes on custom page if detected to avoid
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
36
		//        the user having to click through prompts, unless it's somethig that's happened very recently.
37
38
		// Dual-mode page
39
		if (WebRequest::wasPosted()) {
40
			$this->validateCSRFToken();
41
			$this->doCustomClose($currentUser, $request, $database);
42
43
			$this->redirect();
44
		}
45
		else {
46
			$this->assignCSRFToken();
47
			$this->showCustomCloseForm($database, $request);
48
		}
49
	}
50
51
	/**
52
	 * @param $database
53
	 *
54
	 * @return Request
55
	 * @throws ApplicationLogicException
56
	 */
57 View Code Duplication
	protected function getRequest(PdoDatabase $database)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
58
	{
59
		$requestId = WebRequest::getInt('request');
60
		if ($requestId === null) {
61
			throw new ApplicationLogicException('Request ID not found');
62
		}
63
64
		/** @var Request $request */
65
		$request = Request::getById($requestId, $database);
66
67
		if ($request === false) {
68
			throw new ApplicationLogicException('Request not found');
69
		}
70
71
		return $request;
72
	}
73
74
	/**
75
	 * @param PdoDatabase $database
76
	 *
77
	 * @return EmailTemplate|null
78
	 */
79
	protected function getTemplate(PdoDatabase $database)
80
	{
81
		$templateId = WebRequest::getInt('template');
82
		if ($templateId === null) {
83
			return null;
84
		}
85
86
		/** @var EmailTemplate $template */
87
		$template = EmailTemplate::getById($templateId, $database);
88
		if ($template === false || !$template->getActive()) {
89
			return null;
90
		}
91
92
		return $template;
93
	}
94
95
	/**
96
	 * @param $database
97
	 * @param $request
98
	 *
99
	 * @throws Exception
100
	 */
101
	protected function showCustomCloseForm(PdoDatabase $database, Request $request)
102
	{
103
		$template = $this->getTemplate($database);
104
105
		$this->assign('defaultAction', '');
106
		$this->assign('preloadText', '');
107
		$this->assign('preloadTitle', '');
108
109
		if ($template !== null) {
110
			$this->assign('defaultAction', $template->getDefaultAction());
111
			$this->assign('preloadText', $template->getText());
112
			$this->assign('preloadTitle', $template->getName());
113
		}
114
115
		$this->assign('requeststates', $this->getSiteConfiguration()->getRequestStates());
116
117
		$this->assign('requestId', $request->getIp());
118
		$this->assign('updateVersion', $request->getUpdateVersion());
119
120
		// @todo request info on form - we need to do this slightly better than it was before.
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
121
		// $this->assign("request", $request);
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
122
123
		$trustedIp = $this->getXffTrustProvider()->getTrustedClientIp($request->getIp(), $request->getForwardedIp());
124
		$this->assign('iplocation', $this->getLocationProvider()->getIpLocation($trustedIp));
125
126
		$this->setTemplate('custom-close.tpl');
127
	}
128
129
	/**
130
	 * @param User        $currentUser
131
	 * @param Request     $request
132
	 * @param PdoDatabase $database
133
	 *
134
	 * @throws ApplicationLogicException
135
	 */
136
	protected function doCustomClose(User $currentUser, Request $request, PdoDatabase $database)
137
	{
138
		$messageBody = WebRequest::postString('msgbody');
139
		if ($messageBody === null || trim($messageBody) === '') {
140
			throw new ApplicationLogicException('Message body cannot be blank');
141
		}
142
143
		$ccMailingList = true;
144
		if ($currentUser->isAdmin() || $currentUser->isCheckuser()) {
145
			$ccMailingList = WebRequest::postBoolean('ccMailingList');
146
		}
147
148
		$this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
149
150
		$action = WebRequest::postString('action');
151
		$availableRequestStates = $this->getSiteConfiguration()->getRequestStates();
152
153
		if ($action === EmailTemplate::CREATED || $action === EmailTemplate::NOT_CREATED) {
154
			// Close request
155
			$this->closeRequest($request, $database, $action, $messageBody);
156
		}
157
		else {
158
			if (array_key_exists($action, $availableRequestStates)) {
159
				// Defer to other state
160
				$this->deferRequest($request, $database, $action, $availableRequestStates, $messageBody);
161
			}
162
			else {
163
				$request->setReserved(0);
164
				$request->setUpdateVersion(WebRequest::postInt('updateversion'));
165
				$request->save();
166
167
				// Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE
168
				// and be rolled back.
169
170
				// Send mail
171
				Logger::sentMail($database, $request, $messageBody);
172
				Logger::unreserve($database, $request);
173
174
				$this->getNotificationHelper()->sentMail($request);
175
				SessionAlert::success("Sent mail to Request {$request->getId()}");
176
			}
177
		}
178
	}
179
180
	/**
181
	 * @param Request     $request
182
	 * @param PdoDatabase $database
183
	 * @param string      $action
184
	 * @param string      $messageBody
185
	 *
186
	 * @throws Exception
187
	 * @throws OptimisticLockFailedException
188
	 */
189
	protected function closeRequest(Request $request, PdoDatabase $database, $action, $messageBody)
190
	{
191
		$request->setStatus('Closed');
192
		$request->setReserved(0);
193
		$request->setUpdateVersion(WebRequest::postInt('updateversion'));
194
		$request->save();
195
196
		// Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE and
197
		// be rolled back.
198
199
		if ($action == EmailTemplate::CREATED) {
200
			$logCloseType = 'custom-y';
201
			$notificationCloseType = "Custom, Created";
202
		}
203
		else {
204
			$logCloseType = 'custom-n';
205
			$notificationCloseType = "Custom, Not Created";
206
		}
207
208
		Logger::closeRequest($database, $request, $logCloseType, $messageBody);
209
		$this->getNotificationHelper()->requestClosed($request, $notificationCloseType);
210
211
		$requestName = htmlentities($request->getName(), ENT_COMPAT, 'UTF-8');
212
		SessionAlert::success("Request {$request->getId()} ({$requestName}) marked as 'Done'.");
213
	}
214
215
	/**
216
	 * @param Request $request
217
	 * @param PdoDatabase $database
218
	 * @param string      $action
219
	 * @param             $availableRequestStates
220
	 * @param string      $messageBody
221
	 *
222
	 * @throws Exception
223
	 * @throws OptimisticLockFailedException
224
	 */
225
	protected function deferRequest(
226
		Request $request,
227
		PdoDatabase $database,
228
		$action,
229
		$availableRequestStates,
230
		$messageBody
231
	) {
232
		$request->setStatus($action);
233
		$request->setReserved(0);
234
		$request->setUpdateVersion(WebRequest::postInt('updateversion'));
235
		$request->save();
236
237
		// Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE
238
		// and be rolled back.
239
240
		$deferToLog = $availableRequestStates[$action]['defertolog'];
241
		Logger::sentMail($database, $request, $messageBody);
242
		Logger::deferRequest($database, $request, $deferToLog);
243
244
		$this->getNotificationHelper()->requestDeferredWithMail($request);
245
246
		$deferTo = $availableRequestStates[$action]['deferto'];
247
		SessionAlert::success("Request {$request->getId()} deferred to $deferTo, sending an email.");
248
	}
249
}