PageCloseRequest::processWelcome()   A
last analyzed

Complexity

Conditions 5
Paths 5

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 12
dl 0
loc 23
rs 9.5555
c 1
b 0
f 0
cc 5
nc 5
nop 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\Domain;
13
use Waca\DataObjects\EmailTemplate;
14
use Waca\DataObjects\Request;
15
use Waca\DataObjects\User;
16
use Waca\Exceptions\ApplicationLogicException;
17
use Waca\Helpers\Logger;
18
use Waca\Helpers\OAuthUserHelper;
19
use Waca\Helpers\RequestEmailHelper;
20
use Waca\PdoDatabase;
21
use Waca\RequestStatus;
22
use Waca\SessionAlert;
23
use Waca\WebRequest;
24
25
class PageCloseRequest extends RequestActionBase
26
{
27
    protected function main()
28
    {
29
        $this->processClose();
30
    }
31
32
    /**
33
     * Main function for this page, when no specific actions are called.
34
     * @throws ApplicationLogicException
35
     */
36
    final protected function processClose()
37
    {
38
        $this->checkPosted();
39
        $database = $this->getDatabase();
40
41
        $currentUser = User::getCurrent($database);
42
        $template = $this->getTemplate($database);
43
        $request = $this->getRequest($database);
44
        $request->setUpdateVersion(WebRequest::postInt('updateversion'));
45
46
        if ($request->getStatus() === RequestStatus::CLOSED) {
47
            throw new ApplicationLogicException('Request is already closed');
48
        }
49
50
        if ($this->confirmEmailAlreadySent($request, $template)) {
51
            return;
52
        }
53
54
        if ($this->checkReserveProtect($request, $currentUser)) {
55
            return;
56
        }
57
58
        if ($this->confirmAccountCreated($request, $template)) {
59
            return;
60
        }
61
62
        // I think we're good here...
63
        $request->setStatus(RequestStatus::CLOSED);
64
        $request->setQueue(null);
65
        $request->setReserved(null);
66
67
        Logger::closeRequest($database, $request, $template->getId(), null);
68
69
        $request->save();
70
71
        $this->processWelcome($template->getDefaultAction(), null);
72
73
        // Perform the notifications and stuff *after* we've successfully saved, since the save can throw an OLE and
74
        // be rolled back.
75
76
        $this->getNotificationHelper()->requestClosed($request, $template->getName());
77
        $sanitisedTemplateName = htmlentities($template->getName(), ENT_COMPAT, 'UTF-8');
78
        SessionAlert::success("Request {$request->getId()} has been closed as {$sanitisedTemplateName}");
79
80
        $this->sendMail($request, $template->getText(), $currentUser, false);
81
82
        $this->redirect();
83
    }
84
85
    /**
86
     * @param PdoDatabase $database
87
     *
88
     * @return EmailTemplate
89
     * @throws ApplicationLogicException
90
     */
91
    protected function getTemplate(PdoDatabase $database)
92
    {
93
        $templateId = WebRequest::postInt('template');
94
        if ($templateId === null) {
95
            throw new ApplicationLogicException('No template specified');
96
        }
97
98
        /** @var EmailTemplate $template */
99
        $template = EmailTemplate::getById($templateId, $database);
100
        if ($template === false || !$template->getActive()) {
101
            throw new ApplicationLogicException('Invalid or inactive template specified');
102
        }
103
104
        return $template;
105
    }
106
107
    /**
108
     * @param Request       $request
109
     * @param EmailTemplate $template
110
     *
111
     * @return bool
112
     */
113
    protected function confirmEmailAlreadySent(Request $request, EmailTemplate $template)
114
    {
115
        if ($this->checkEmailAlreadySent($request)) {
116
            $this->showConfirmation($request, $template, 'close-confirmations/email-sent.tpl');
117
118
            return true;
119
        }
120
121
        return false;
122
    }
123
124
    protected function checkEmailAlreadySent(Request $request)
125
    {
126
        if ($request->getEmailSent() && !WebRequest::postBoolean('emailSentOverride')) {
127
            return true;
128
        }
129
130
        return false;
131
    }
132
133
    protected function checkReserveProtect(Request $request, User $currentUser)
134
    {
135
        $reservationId = $request->getReserved();
136
137
        if ($reservationId !== 0 && $reservationId !== null) {
138
            if ($currentUser->getId() !== $reservationId) {
139
                SessionAlert::error("Request is reserved by someone else.");
140
                $this->redirect('/viewRequest', null, ['id' => $request->getId()]);
141
                return true;
142
            }
143
        }
144
145
        return false;
146
    }
147
148
    /**
149
     * @param Request       $request
150
     * @param EmailTemplate $template
151
     *
152
     * @return bool
153
     * @throws Exception
154
     */
155
    protected function confirmAccountCreated(Request $request, EmailTemplate $template)
156
    {
157
        if ($template->getDefaultAction() === EmailTemplate::ACTION_CREATED && $this->checkAccountCreated($request)) {
158
            $this->showConfirmation($request, $template, 'close-confirmations/account-created.tpl');
159
160
            return true;
161
        }
162
163
        return false;
164
    }
165
166
    protected function checkAccountCreated(Request $request)
167
    {
168
        if (!WebRequest::postBoolean('createOverride')) {
169
            $parameters = array(
170
                'action'  => 'query',
171
                'list'    => 'users',
172
                'format'  => 'php',
173
                'ususers' => $request->getName(),
174
            );
175
176
            // FIXME: domains!
177
            /** @var Domain $domain */
178
            $domain = Domain::getById(1, $this->getDatabase());
179
180
            $content = $this->getHttpHelper()->get($domain->getWikiApiPath(), $parameters);
181
182
            $apiResult = unserialize($content);
183
            $exists = !isset($apiResult['query']['users']['0']['missing']);
184
185
            if (!$exists) {
186
                return true;
187
            }
188
        }
189
190
        return false;
191
    }
192
193
    /**
194
     * @param Request $request
195
     * @param string  $mailText
196
     * @param User    $currentUser
197
     * @param boolean $ccMailingList
198
     */
199
    protected function sendMail(Request $request, $mailText, User $currentUser, $ccMailingList)
200
    {
201
        if (
202
        ($request->getEmail() != $this->getSiteConfiguration()->getDataClearEmail()) &&
203
        ($request->getIp() != $this->getSiteConfiguration()->getDataClearIp())
204
        ) {
205
            $requestEmailHelper = new RequestEmailHelper($this->getEmailHelper());
206
            $requestEmailHelper->sendMail($request, $mailText, $currentUser, $ccMailingList);
207
208
            $request->setEmailSent(true);
209
            $request->save();
210
        }
211
    }
212
213
    /**
214
     * @param Request       $request
215
     * @param EmailTemplate $template
216
     * @param string        $templateName
217
     *
218
     * @throws Exception
219
     * @return void
220
     */
221
    protected function showConfirmation(Request $request, EmailTemplate $template, $templateName)
222
    {
223
        $this->assignCSRFToken();
224
225
        $this->assign('request', $request->getId());
226
        $this->assign('template', $template->getId());
227
228
        $this->assign('updateversion', $request->getUpdateVersion());
229
230
        $this->assign('emailSentOverride', WebRequest::postBoolean('emailSentOverride') ? 'true' : 'false');
231
        $this->assign('reserveOverride', WebRequest::postBoolean('reserveOverride') ? 'true' : 'false');
232
        $this->assign('createOverride', WebRequest::postBoolean('createOverride') ? 'true' : 'false');
233
234
        $this->skipAlerts();
235
236
        $this->setTemplate($templateName);
237
    }
238
239
    /**
240
     * @param string $action
241
     * @param int|null   $parentTaskId
242
     *
243
     * @throws ApplicationLogicException
244
     */
245
    final protected function processWelcome(string $action, ?int $parentTaskId): void
246
    {
247
        $database = $this->getDatabase();
248
        $currentUser = User::getCurrent($database);
249
250
        if ($action !== EmailTemplate::ACTION_CREATED) {
251
            return;
252
        }
253
254
        if ($currentUser->getWelcomeTemplate() === null) {
0 ignored issues
show
introduced by
The condition $currentUser->getWelcomeTemplate() === null is always false.
Loading history...
255
            return;
256
        }
257
258
        $oauth = new OAuthUserHelper($currentUser, $database, $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
259
        if (!$oauth->canWelcome()) {
260
            return;
261
        }
262
263
        if (WebRequest::postBoolean('skipAutoWelcome')) {
264
            return;
265
        }
266
267
        $this->enqueueWelcomeTask($this->getRequest($database), $parentTaskId, $currentUser, $database);
268
    }
269
}
270