Passed
Push — rbac ( 82b65f...a43d05 )
by Michael
02:23
created

PageCustomClose::doCustomClose()   B

Complexity

Conditions 10
Paths 11

Size

Total Lines 56
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 29
c 2
b 0
f 0
dl 0
loc 56
rs 7.6666
cc 10
nc 11
nop 3

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\AccessDeniedException;
16
use Waca\Exceptions\ApplicationLogicException;
17
use Waca\Exceptions\OptimisticLockFailedException;
18
use Waca\Fragments\RequestData;
19
use Waca\Helpers\Logger;
20
use Waca\PdoDatabase;
21
use Waca\SessionAlert;
22
use Waca\WebRequest;
23
24
class PageCustomClose extends PageCloseRequest
25
{
26
    use RequestData;
27
28
    protected function main()
29
    {
30
        $database = $this->getDatabase();
31
32
        $request = $this->getRequest($database);
33
        $currentUser = User::getCurrent($this->getDatabase());
34
35
        if ($request->getStatus() === 'Closed') {
36
            throw new ApplicationLogicException('Request is already closed');
37
        }
38
39
        // Dual-mode page
40
        if (WebRequest::wasPosted()) {
41
            $this->validateCSRFToken();
42
            $this->doCustomClose($currentUser, $request, $database);
43
44
            $this->redirect();
45
        }
46
        else {
47
            $this->assignCSRFToken();
48
            $this->showCustomCloseForm($database, $request);
49
        }
50
    }
51
52
    /**
53
     * @param $database
54
     *
55
     * @return Request
56
     * @throws ApplicationLogicException
57
     */
58
    protected function getRequest(PdoDatabase $database)
59
    {
60
        $requestId = WebRequest::getInt('request');
61
        if ($requestId === null) {
62
            throw new ApplicationLogicException('Request ID not found');
63
        }
64
65
        /** @var Request $request */
66
        $request = Request::getById($requestId, $database);
67
68
        if ($request === false) {
69
            throw new ApplicationLogicException('Request not found');
70
        }
71
72
        return $request;
73
    }
74
75
    /**
76
     * @param PdoDatabase $database
77
     *
78
     * @return EmailTemplate|null
79
     */
80
    protected function getTemplate(PdoDatabase $database)
81
    {
82
        $templateId = WebRequest::getInt('template');
83
        if ($templateId === null) {
84
            return null;
85
        }
86
87
        /** @var EmailTemplate $template */
88
        $template = EmailTemplate::getById($templateId, $database);
89
        if ($template === false || !$template->getActive()) {
90
            return null;
91
        }
92
93
        return $template;
94
    }
95
96
    /**
97
     * @param $database
98
     * @param $request
99
     *
100
     * @throws Exception
101
     */
102
    protected function showCustomCloseForm(PdoDatabase $database, Request $request)
103
    {
104
        $currentUser = User::getCurrent($database);
105
        $config = $this->getSiteConfiguration();
106
107
        $allowedPrivateData = $this->isAllowedPrivateData($request, $currentUser);
108
        if (!$allowedPrivateData) {
109
            // we probably shouldn't be showing the user this form if they're not allowed to access private data...
110
            throw new AccessDeniedException($this->getSecurityManager());
111
        }
112
113
        $template = $this->getTemplate($database);
114
115
        // Preload data
116
        $this->assign('defaultAction', '');
117
        $this->assign('preloadText', '');
118
        $this->assign('preloadTitle', '');
119
120
        if ($template !== null) {
121
            $this->assign('defaultAction', $template->getDefaultAction());
122
            $this->assign('preloadText', $template->getText());
123
            $this->assign('preloadTitle', $template->getName());
124
        }
125
126
        // Static data
127
        $this->assign('requeststates', $config->getRequestStates());
128
129
        // request data
130
        $this->assign('requestId', $request->getIp());
131
        $this->assign('updateVersion', $request->getUpdateVersion());
132
        $this->setupBasicData($request, $config);
133
        $this->setupReservationDetails($request->getReserved(), $database, $currentUser);
134
        $this->setupPrivateData($request, $currentUser, $this->getSiteConfiguration(), $database);
135
136
        // IP location
137
        $trustedIp = $this->getXffTrustProvider()->getTrustedClientIp($request->getIp(), $request->getForwardedIp());
138
        $this->assign('iplocation', $this->getLocationProvider()->getIpLocation($trustedIp));
139
140
        // Confirmations
141
        $this->assign('confirmEmailAlreadySent', $this->checkEmailAlreadySent($request));
142
        $this->assign('confirmReserveOverride', $this->checkReserveOverride($request, $currentUser));
143
144
        $this->assign('canSkipCcMailingList', $this->barrierTest('skipCcMailingList', $currentUser));
145
146
        // template
147
        $this->setTemplate('custom-close.tpl');
148
    }
149
150
    /**
151
     * @param User        $currentUser
152
     * @param Request     $request
153
     * @param PdoDatabase $database
154
     *
155
     * @throws ApplicationLogicException
156
     */
157
    protected function doCustomClose(User $currentUser, Request $request, PdoDatabase $database)
158
    {
159
        $messageBody = WebRequest::postString('msgbody');
160
        if ($messageBody === null || trim($messageBody) === '') {
161
            throw new ApplicationLogicException('Message body cannot be blank');
162
        }
163
164
        $ccMailingList = true;
165
        if ($this->barrierTest('skipCcMailingList', $currentUser)) {
166
            $ccMailingList = WebRequest::postBoolean('ccMailingList');
167
        }
168
169
        if ($request->getStatus() === 'Closed') {
170
            throw new ApplicationLogicException('Request is already closed');
171
        }
172
173
        if (!(WebRequest::postBoolean('confirmEmailAlreadySent')
174
            && WebRequest::postBoolean('confirmReserveOverride'))
175
        ) {
176
            throw new ApplicationLogicException('Not all confirmations checked');
177
        }
178
179
        $action = WebRequest::postString('action');
180
        $availableRequestStates = $this->getSiteConfiguration()->getRequestStates();
181
182
        if ($action === EmailTemplate::CREATED || $action === EmailTemplate::NOT_CREATED) {
183
            // Close request
184
            $this->closeRequest($request, $database, $action, $messageBody);
185
186
            // Send the mail after the save, since save can be rolled back
187
            $this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
188
        }
189
        else {
190
            if (array_key_exists($action, $availableRequestStates)) {
191
                // Defer to other state
192
                $this->deferRequest($request, $database, $action, $availableRequestStates, $messageBody);
193
194
                // Send the mail after the save, since save can be rolled back
195
                $this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
196
            }
197
            else {
198
                $request->setReserved(null);
199
                $request->setUpdateVersion(WebRequest::postInt('updateversion'));
200
                $request->save();
201
202
                // Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE
203
                // and be rolled back.
204
205
                // Send mail
206
                $this->sendMail($request, $messageBody, $currentUser, $ccMailingList);
207
208
                Logger::sentMail($database, $request, $messageBody);
209
                Logger::unreserve($database, $request);
210
211
                $this->getNotificationHelper()->sentMail($request);
212
                SessionAlert::success("Sent mail to Request {$request->getId()}");
213
            }
214
        }
215
    }
216
217
    /**
218
     * @param Request     $request
219
     * @param PdoDatabase $database
220
     * @param string      $action
221
     * @param string      $messageBody
222
     *
223
     * @throws Exception
224
     * @throws OptimisticLockFailedException
225
     */
226
    protected function closeRequest(Request $request, PdoDatabase $database, $action, $messageBody)
227
    {
228
        $request->setStatus('Closed');
229
        $request->setReserved(null);
230
        $request->setUpdateVersion(WebRequest::postInt('updateversion'));
231
        $request->save();
232
233
        // Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE and
234
        // be rolled back.
235
236
        if ($action == EmailTemplate::CREATED) {
237
            $logCloseType = 'custom-y';
238
            $notificationCloseType = "Custom, Created";
239
        }
240
        else {
241
            $logCloseType = 'custom-n';
242
            $notificationCloseType = "Custom, Not Created";
243
        }
244
245
        Logger::closeRequest($database, $request, $logCloseType, $messageBody);
246
        $this->getNotificationHelper()->requestClosed($request, $notificationCloseType);
247
248
        $requestName = htmlentities($request->getName(), ENT_COMPAT, 'UTF-8');
249
        SessionAlert::success("Request {$request->getId()} ({$requestName}) marked as 'Done'.");
250
    }
251
252
    /**
253
     * @param Request     $request
254
     * @param PdoDatabase $database
255
     * @param string      $action
256
     * @param             $availableRequestStates
257
     * @param string      $messageBody
258
     *
259
     * @throws Exception
260
     * @throws OptimisticLockFailedException
261
     */
262
    protected function deferRequest(
263
        Request $request,
264
        PdoDatabase $database,
265
        $action,
266
        $availableRequestStates,
267
        $messageBody
268
    ) {
269
        $request->setStatus($action);
270
        $request->setReserved(null);
271
        $request->setUpdateVersion(WebRequest::postInt('updateversion'));
272
        $request->save();
273
274
        // Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE
275
        // and be rolled back.
276
277
        $deferToLog = $availableRequestStates[$action]['defertolog'];
278
        Logger::sentMail($database, $request, $messageBody);
279
        Logger::deferRequest($database, $request, $deferToLog);
280
281
        $this->getNotificationHelper()->requestDeferredWithMail($request);
282
283
        $deferTo = $availableRequestStates[$action]['deferto'];
284
        SessionAlert::success("Request {$request->getId()} deferred to $deferTo, sending an email.");
285
    }
286
}
287