Passed
Pull Request — master (#753)
by Matthew
04:17
created

PageViewRequest   A

Complexity

Total Complexity 42

Size/Duplication

Total Lines 306
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 5
Bugs 1 Features 0
Metric Value
wmc 42
eloc 170
c 5
b 1
f 0
dl 0
loc 306
ccs 0
cts 209
cp 0
rs 9.0399

6 Methods

Rating   Name   Duplication   Size   Complexity  
B setupCreationTypes() 0 43 8
A setupTitle() 0 13 3
C main() 0 91 11
A setupGeneralData() 0 28 1
A setupUsernameData() 0 15 2
F setupLogData() 0 83 17

How to fix   Complexity   

Complex Class

Complex classes like PageViewRequest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PageViewRequest, and based on these observations, apply Extract Interface, too.

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;
10
11
use Exception;
12
use DateTime;
13
use Waca\DataObjects\Comment;
14
use Waca\DataObjects\Domain;
15
use Waca\DataObjects\EmailTemplate;
16
use Waca\DataObjects\JobQueue;
17
use Waca\DataObjects\Log;
18
use Waca\DataObjects\Request;
19
use Waca\DataObjects\RequestQueue;
20
use Waca\DataObjects\User;
21
use Waca\Exceptions\ApplicationLogicException;
22
use Waca\Fragments\RequestData;
23
use Waca\Helpers\LogHelper;
24
use Waca\Helpers\OAuthUserHelper;
25
use Waca\Pages\RequestAction\PageManuallyConfirm;
26
use Waca\PdoDatabase;
27
use Waca\Security\RoleConfiguration;
28
use Waca\RequestStatus;
29
use Waca\Tasks\InternalPageBase;
30
use Waca\WebRequest;
31
32
class PageViewRequest extends InternalPageBase
33
{
34
    use RequestData;
35
    const STATUS_SYMBOL_OPEN = '&#927';
36
    const STATUS_SYMBOL_ACCEPTED = '&#x2611';
37
    const STATUS_SYMBOL_REJECTED = '&#x2612';
38
39
    /**
40
     * Main function for this page, when no specific actions are called.
41
     * @throws ApplicationLogicException
42
     */
43
    protected function main()
44
    {
45
        // set up csrf protection
46
        $this->assignCSRFToken();
47
48
        // get some useful objects
49
        $database = $this->getDatabase();
50
        $request = $this->getRequest($database, WebRequest::getInt('id'));
51
        $config = $this->getSiteConfiguration();
52
        $currentUser = User::getCurrent($database);
53
54
        // FIXME: domains!
55
        /** @var Domain $domain */
56
        $domain = Domain::getById(1, $this->getDatabase());
57
        $this->assign('mediawikiScriptPath', $domain->getWikiArticlePath());
58
59
        // Shows a page if the email is not confirmed.
60
        if ($request->getEmailConfirm() !== 'Confirmed') {
61
            // Show a banner if the user can manually confirm the request
62
            $viewConfirm = $this->barrierTest("main", $currentUser, PageManuallyConfirm::class);
63
64
            // Render
65
            $this->setTemplate("view-request/not-confirmed.tpl");
66
            $this->assign("requestId", $request->getId());
67
            $this->assign('canViewConfirmButton', $viewConfirm);
68
69
            // Make sure to return, to prevent the leaking of other information.
70
            return;
71
        }
72
73
        $this->setupBasicData($request, $config);
74
75
        $this->setupUsernameData($request);
76
77
        $this->setupTitle($request);
78
79
        $this->setupReservationDetails($request->getReserved(), $database, $currentUser);
80
        $this->setupGeneralData($database);
81
82
        $this->assign('requestDataCleared', false);
83
        if ($request->getEmail() === $this->getSiteConfiguration()->getDataClearEmail()) {
84
            $this->assign('requestDataCleared', true);
85
        }
86
87
        $allowedPrivateData = $this->isAllowedPrivateData($request, $currentUser);
88
89
        $this->setupCreationTypes($currentUser);
90
91
        $this->setupLogData($request, $database);
92
93
        $this->addJs("/api.php?action=templates&targetVariable=templateconfirms");
94
95
        $this->assign('showRevealLink', false);
96
        if ($request->getReserved() === $currentUser->getId() ||
97
            $this->barrierTest('alwaysSeeHash', $currentUser, 'RequestData')
98
        ) {
99
            $this->assign('showRevealLink', true);
100
            $this->assign('revealHash', $request->getRevealHash());
101
        }
102
103
        $this->assign('canSeeRelatedRequests', false);
104
        if ($allowedPrivateData || $this->barrierTest('seeRelatedRequests', $currentUser, 'RequestData')) {
105
            $this->setupRelatedRequests($request, $config, $database);
106
        }
107
108
        $this->assign('canCreateLocalAccount', $this->barrierTest('createLocalAccount', $currentUser, 'RequestData'));
109
            
110
        $closureDate = $request->getClosureDate();
111
        $date = new DateTime();
112
        $date->modify("-7 days");
113
        if ($request->getStatus() == "Closed" && $closureDate < $date) {
114
                $this->assign('isOldRequest', true);
115
        }
116
        $this->assign('canResetOldRequest', $this->barrierTest('reopenOldRequest', $currentUser, 'RequestData'));
117
        $this->assign('canResetPurgedRequest', $this->barrierTest('reopenClearedRequest', $currentUser, 'RequestData'));
118
119
        $this->assign('requestEmailSent', $request->getEmailSent());
120
121
        if ($allowedPrivateData) {
122
            $this->setTemplate('view-request/main-with-data.tpl');
123
            $this->setupPrivateData($request, $config);
124
            $this->assign('canSetBan', $this->barrierTest('set', $currentUser, PageBan::class));
125
            $this->assign('canSeeCheckuserData', $this->barrierTest('seeUserAgentData', $currentUser, 'RequestData'));
126
127
            if ($this->barrierTest('seeUserAgentData', $currentUser, 'RequestData')) {
128
                $this->setTemplate('view-request/main-with-checkuser-data.tpl');
129
                $this->setupCheckUserData($request);
130
            }
131
        }
132
        else {
133
            $this->setTemplate('view-request/main.tpl');
134
        }
135
    }
136
137
    /**
138
     * @param Request $request
139
     */
140
    protected function setupTitle(Request $request)
141
    {
142
        $statusSymbol = self::STATUS_SYMBOL_OPEN;
143
        if ($request->getStatus() === RequestStatus::CLOSED) {
144
            if ($request->getWasCreated()) {
145
                $statusSymbol = self::STATUS_SYMBOL_ACCEPTED;
146
            }
147
            else {
148
                $statusSymbol = self::STATUS_SYMBOL_REJECTED;
149
            }
150
        }
151
152
        $this->setHtmlTitle($statusSymbol . ' #' . $request->getId());
153
    }
154
155
    /**
156
     * Sets up data unrelated to the request, such as the email template information
157
     *
158
     * @param PdoDatabase $database
159
     */
160
    protected function setupGeneralData(PdoDatabase $database)
161
    {
162
        $this->assign('createAccountReason', 'Requested account at [[WP:ACC]], request #');
163
164
        // FIXME: domains
165
        /** @var Domain $domain */
166
        $domain = Domain::getById(1, $database);
167
        $this->assign('defaultRequestState', RequestQueue::getDefaultQueue($database, 1)->getApiName());
168
        $this->assign('activeRequestQueues', RequestQueue::getEnabledQueues($database));
169
170
        /** @var EmailTemplate $createdTemplate */
171
        $createdTemplate = EmailTemplate::getById($domain->getDefaultClose(), $database);
172
173
        $this->assign('createdHasJsQuestion', $createdTemplate->getJsquestion() != '');
174
        $this->assign('createdId', $createdTemplate->getId());
175
        $this->assign('createdName', $createdTemplate->getName());
176
177
        $createReasons = EmailTemplate::getActiveNonpreloadTemplates(EmailTemplate::ACTION_CREATED, $database, $domain->getDefaultClose());
178
        $this->assign("createReasons", $createReasons);
179
        $declineReasons = EmailTemplate::getActiveNonpreloadTemplates(EmailTemplate::ACTION_NOT_CREATED, $database);
180
        $this->assign("declineReasons", $declineReasons);
181
182
        $allCreateReasons = EmailTemplate::getAllActiveTemplates(EmailTemplate::ACTION_CREATED, $database);
183
        $this->assign("allCreateReasons", $allCreateReasons);
184
        $allDeclineReasons = EmailTemplate::getAllActiveTemplates(EmailTemplate::ACTION_NOT_CREATED, $database);
185
        $this->assign("allDeclineReasons", $allDeclineReasons);
186
        $allOtherReasons = EmailTemplate::getAllActiveTemplates(false, $database);
187
        $this->assign("allOtherReasons", $allOtherReasons);
188
    }
189
190
    private function setupLogData(Request $request, PdoDatabase $database)
191
    {
192
        $currentUser = User::getCurrent($database);
193
194
        $logs = LogHelper::getRequestLogsWithComments($request->getId(), $database, $this->getSecurityManager());
195
        $requestLogs = array();
196
197
        /** @var User[] $nameCache */
198
        $nameCache = array();
199
200
        $editableComments = $this->barrierTest('editOthers', $currentUser, PageEditComment::class);
201
202
        $canFlag = $this->barrierTest(RoleConfiguration::MAIN, $currentUser, PageFlagComment::class);
203
        $canUnflag = $this->barrierTest('unflag', $currentUser, PageFlagComment::class);
204
205
        /** @var Log|Comment $entry */
206
        foreach ($logs as $entry) {
207
            // both log and comment have a 'user' field
208
            if (!array_key_exists($entry->getUser(), $nameCache)) {
209
                $entryUser = User::getById($entry->getUser(), $database);
210
                $nameCache[$entry->getUser()] = $entryUser;
211
            }
212
213
            if ($entry instanceof Comment) {
214
                $requestLogs[] = array(
215
                    'type'          => 'comment',
216
                    'security'      => $entry->getVisibility(),
217
                    'user'          => $entry->getVisibility() == 'requester' ? $request->getName() : $nameCache[$entry->getUser()]->getUsername(),
218
                    'userid'        => $entry->getUser() == -1 ? null : $entry->getUser(),
219
                    'entry'         => null,
220
                    'time'          => $entry->getTime(),
221
                    'canedit'       => ($editableComments || $entry->getUser() == $currentUser->getId()),
222
                    'id'            => $entry->getId(),
223
                    'comment'       => $entry->getComment(),
224
                    'flagged'       => $entry->getFlagged(),
225
                    'canflag'       => $canFlag && (!$entry->getFlagged() || ($entry->getFlagged() && $canUnflag)),
226
                    'updateversion' => $entry->getUpdateVersion(),
227
                    'edited'        => $entry->getEdited()
228
                );
229
            }
230
231
            if ($entry instanceof Log) {
232
                $invalidUserId = $entry->getUser() === -1 || $entry->getUser() === 0;
233
                $entryUser = $invalidUserId ? User::getCommunity() : $nameCache[$entry->getUser()];
234
235
                $entryComment = $entry->getComment();
236
237
                if ($entry->getAction() === 'JobIssueRequest' || $entry->getAction() === 'JobCompletedRequest') {
238
                    $data = unserialize($entry->getComment());
0 ignored issues
show
Bug introduced by
It seems like $entry->getComment() can also be of type null; however, parameter $data of unserialize() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

238
                    $data = unserialize(/** @scrutinizer ignore-type */ $entry->getComment());
Loading history...
239
                    /** @var JobQueue $job */
240
                    $job = JobQueue::getById($data['job'], $database);
241
                    $requestLogs[] = array(
242
                        'type'     => 'joblog',
243
                        'security' => 'user',
244
                        'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
245
                        'user'     => $entryUser->getUsername(),
246
                        'entry'    => LogHelper::getLogDescription($entry),
247
                        'time'     => $entry->getTimestamp(),
248
                        'canedit'  => false,
249
                        'id'       => $entry->getId(),
250
                        'jobId'    => $job->getId(),
251
                        'jobDesc'  => JobQueue::getTaskDescriptions()[$job->getTask()],
252
                    );
253
                }
254
                else {
255
                    $requestLogs[] = array(
256
                        'type'     => 'log',
257
                        'security' => 'user',
258
                        'userid'   => $entry->getUser() == -1 ? null : $entry->getUser(),
259
                        'user'     => $entryUser->getUsername(),
260
                        'entry'    => LogHelper::getLogDescription($entry),
261
                        'time'     => $entry->getTimestamp(),
262
                        'canedit'  => false,
263
                        'id'       => $entry->getId(),
264
                        'comment'  => $entryComment,
265
                    );
266
                }
267
            }
268
        }
269
270
        $this->addJs("/api.php?action=users&targetVariable=typeaheaddata");
271
272
        $this->assign("requestLogs", $requestLogs);
273
    }
274
275
    /**
276
     * @param Request $request
277
     */
278
    protected function setupUsernameData(Request $request)
279
    {
280
        $blacklistData = $this->getBlacklistHelper()->isBlacklisted($request->getName());
281
282
        $this->assign('requestIsBlacklisted', $blacklistData !== false);
283
        $this->assign('requestBlacklist', $blacklistData);
284
285
        try {
286
            $spoofs = $this->getAntiSpoofProvider()->getSpoofs($request->getName());
287
        }
288
        catch (Exception $ex) {
289
            $spoofs = $ex->getMessage();
290
        }
291
292
        $this->assign("spoofs", $spoofs);
293
    }
294
295
    private function setupCreationTypes(User $user)
296
    {
297
        $this->assign('allowWelcomeSkip', false);
298
        $this->assign('forceWelcomeSkip', false);
299
300
        $oauth = new OAuthUserHelper($user, $this->getDatabase(), $this->getOAuthProtocolHelper(), $this->getSiteConfiguration());
301
302
        if ($user->getWelcomeTemplate() != 0) {
303
            $this->assign('allowWelcomeSkip', true);
304
305
            if (!$oauth->canWelcome()) {
306
                $this->assign('forceWelcomeSkip', true);
307
            }
308
        }
309
310
        // test credentials
311
        $canManualCreate = $this->barrierTest(User::CREATION_MANUAL, $user, 'RequestCreation');
312
        $canOauthCreate = $this->barrierTest(User::CREATION_OAUTH, $user, 'RequestCreation');
313
        $canBotCreate = $this->barrierTest(User::CREATION_BOT, $user, 'RequestCreation');
314
315
        $this->assign('canManualCreate', $canManualCreate);
316
        $this->assign('canOauthCreate', $canOauthCreate);
317
        $this->assign('canBotCreate', $canBotCreate);
318
319
        // show/hide the type radio buttons
320
        $creationHasChoice = count(array_filter([$canManualCreate, $canOauthCreate, $canBotCreate])) > 1;
321
322
        if (!$this->barrierTest($user->getCreationMode(), $user, 'RequestCreation')) {
323
            // user is not allowed to use their default. Force a choice.
324
            $creationHasChoice = true;
325
        }
326
327
        $this->assign('creationHasChoice', $creationHasChoice);
328
329
        // determine problems in creation types
330
        $this->assign('botProblem', false);
331
        if ($canBotCreate && $this->getSiteConfiguration()->getCreationBotPassword() === null) {
0 ignored issues
show
introduced by
The condition $this->getSiteConfigurat...nBotPassword() === null is always false.
Loading history...
332
            $this->assign('botProblem', true);
333
        }
334
335
        $this->assign('oauthProblem', false);
336
        if ($canOauthCreate && !$oauth->canCreateAccount()) {
337
            $this->assign('oauthProblem', true);
338
        }
339
    }
340
}
341