Completed
Branch newinternal (cdd491)
by Simon
04:39
created

PageCloseRequest::main()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

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 4
ccs 0
cts 4
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 0
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\Helpers\Logger;
17
use Waca\PdoDatabase;
18
use Waca\Security\SecurityConfiguration;
19
use Waca\SessionAlert;
20
use Waca\WebRequest;
21
22
class PageCloseRequest extends RequestActionBase
23
{
24
	/**
25
	 * Sets up the security for this page. If certain actions have different permissions, this should be reflected in
26
	 * the return value from this function.
27
	 *
28
	 * If this page even supports actions, you will need to check the route
29
	 *
30
	 * @return SecurityConfiguration
31
	 * @category Security-Critical
32
	 */
33
	protected function getSecurityConfiguration()
34
	{
35
		return $this->getSecurityManager()->configure()->asInternalPage();
36
	}
37
38
	protected function main()
39
	{
40
		$this->processClose();
41
	}
42
43
	/**
44
	 * Main function for this page, when no specific actions are called.
45
	 * @throws ApplicationLogicException
46
	 */
47
	final protected function processClose()
48
	{
49
		$this->checkPosted();
50
		$database = $this->getDatabase();
51
52
		$currentUser = User::getCurrent($database);
53
		$template = $this->getTemplate($database);
54
		$request = $this->getRequest($database);
55
56
		if ($request->getStatus() === 'Closed') {
57
			throw new ApplicationLogicException('Request is already closed');
58
		}
59
60
		if ($this->confirmEmailAlreadySent($request, $template)) {
61
			return;
62
		}
63
64
		if ($this->confirmReserveOverride($request, $template, $currentUser, $database)) {
65
			return;
66
		}
67
68
		if ($this->confirmAccountCreated($request, $template)) {
69
			return;
70
		}
71
72
		// I think we're good here...
73
		$request->setStatus('Closed');
74
		$request->setReserved(null);
75
76
		Logger::closeRequest($database, $request, $template->getId(), null);
77
78
		$request->setUpdateVersion(WebRequest::postInt('updateversion'));
79
		$request->save();
80
81
		// Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE and
82
		// be rolled back.
83
84
		$this->getNotificationHelper()->requestClosed($request, $template->getName());
85
		SessionAlert::success("Request {$request->getId()} has been closed");
86
87
		$this->sendMail($request, $template->getText(), $currentUser, false);
88
89
		$this->redirect();
90
	}
91
92
	/**
93
	 * @param PdoDatabase $database
94
	 *
95
	 * @return EmailTemplate
96
	 * @throws ApplicationLogicException
97
	 */
98 View Code Duplication
	protected function getTemplate(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...
99
	{
100
		$templateId = WebRequest::postInt('template');
101
		if ($templateId === null) {
102
			throw new ApplicationLogicException('No template specified');
103
		}
104
105
		/** @var EmailTemplate $template */
106
		$template = EmailTemplate::getById($templateId, $database);
107
		if ($template === false || !$template->getActive()) {
108
			throw new ApplicationLogicException('Invalid or inactive template specified');
109
		}
110
111
		return $template;
112
	}
113
114
	/**
115
	 * @param Request       $request
116
	 * @param EmailTemplate $template
117
	 *
118
	 * @return bool
119
	 */
120 View Code Duplication
	protected function confirmEmailAlreadySent(Request $request, EmailTemplate $template)
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...
121
	{
122
		if ($this->checkEmailAlreadySent($request)) {
123
			$this->showConfirmation($request, $template, 'close-confirmations/email-sent.tpl');
124
125
			return true;
126
		}
127
128
		return false;
129
	}
130
131
	protected function checkEmailAlreadySent(Request $request)
132
	{
133
		if ($request->getEmailSent() && !WebRequest::postBoolean('emailSentOverride')) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return $request->getEmai...n('emailSentOverride');.
Loading history...
134
			return true;
135
		}
136
137
		return false;
138
	}
139
140
	protected function checkReserveOverride(Request $request, User $currentUser)
141
	{
142
		$reservationId = $request->getReserved();
143
144
		if ($reservationId !== 0 && $reservationId !== null) {
145
			if (!WebRequest::postBoolean('reserveOverride')) {
146
				if ($currentUser->getId() !== $reservationId) {
147
					return true;
148
				}
149
			}
150
		}
151
152
		return false;
153
	}
154
155
	/**
156
	 * @param Request       $request
157
	 * @param EmailTemplate $template
158
	 * @param User          $currentUser
159
	 * @param PdoDatabase   $database
160
	 *
161
	 * @return bool
162
	 */
163
	protected function confirmReserveOverride(
164
		Request $request,
165
		EmailTemplate $template,
166
		User $currentUser,
167
		PdoDatabase $database
168
	) {
169
		if ($this->checkReserveOverride($request, $currentUser)) {
170
			$this->assign('reserveUser', User::getById($request->getReserved(), $database)->getUsername());
171
			$this->showConfirmation($request, $template, 'close-confirmations/reserve-override.tpl');
172
173
			return true;
174
		}
175
176
		return false;
177
	}
178
179
	/**
180
	 * @param Request       $request
181
	 * @param EmailTemplate $template
182
	 *
183
	 * @return bool
184
	 * @throws \Waca\Exceptions\CurlException
185
	 */
186 View Code Duplication
	protected function confirmAccountCreated(Request $request, EmailTemplate $template)
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...
187
	{
188
		if ($this->checkAccountCreated($request, $template)) {
189
			$this->showConfirmation($request, $template, 'close-confirmations/account-created.tpl');
190
191
			return true;
192
		}
193
194
		return false;
195
	}
196
197
	protected function checkAccountCreated(Request $request, EmailTemplate $template)
198
	{
199
		if ($template->getDefaultAction() === EmailTemplate::CREATED && !WebRequest::postBoolean('createOverride')) {
200
			$parameters = array(
201
				'action'  => 'query',
202
				'list'    => 'users',
203
				'format'  => 'php',
204
				'ususers' => $request->getName(),
205
			);
206
207
			$content = $this->getHttpHelper()->get($this->getSiteConfiguration()->getMediawikiWebServiceEndpoint(),
208
				$parameters);
209
210
			$apiResult = unserialize($content);
211
			$exists = !isset($apiResult['query']['users']['0']['missing']);
212
213
			if (!$exists) {
214
				return true;
215
			}
216
		}
217
218
		return false;
219
	}
220
221
	/**
222
	 * @param Request $request
223
	 * @param string  $mailText
224
	 * @param User    $currentUser
225
	 * @param boolean $ccMailingList
226
	 */
227
	protected function sendMail(Request $request, $mailText, User $currentUser, $ccMailingList)
228
	{
229
		$headers = array(
230
			'X-ACC-Request' => $request->getId(),
231
			'X-ACC-UserID'  => $currentUser->getId(),
232
		);
233
234
		if ($ccMailingList) {
235
			$headers['Cc'] = '[email protected]';
236
		}
237
238
		$helper = $this->getEmailHelper();
239
240
		$emailSig = $currentUser->getEmailSig();
241
		if ($emailSig !== '' || $emailSig !== null) {
242
			$emailSig = "\n\n" . $emailSig;
243
		}
244
245
		$subject = "RE: [ACC #{$request->getId()}] English Wikipedia Account Request";
246
		$content = $mailText . $emailSig;
247
248
		$helper->sendMail($request->getEmail(), $subject, $content, $headers);
249
250
		$request->setEmailSent(true);
251
	}
252
253
	/**
254
	 * @param Request       $request
255
	 * @param EmailTemplate $template
256
	 * @param string        $templateName
257
	 *
258
	 * @throws Exception
259
	 * @return void
260
	 */
261
	protected function showConfirmation(Request $request, EmailTemplate $template, $templateName)
262
	{
263
		$this->assignCSRFToken();
264
265
		$this->assign('request', $request->getId());
266
		$this->assign('template', $template->getId());
267
268
		$this->assign('emailSentOverride', WebRequest::postBoolean('emailSentOverride') ? 'true' : 'false');
269
		$this->assign('reserveOverride', WebRequest::postBoolean('reserveOverride') ? 'true' : 'false');
270
		$this->assign('createOverride', WebRequest::postBoolean('createOverride') ? 'true' : 'false');
271
272
		$this->setTemplate($templateName);
273
	}
274
}