CreationTaskBase   A
last analyzed

Complexity

Total Complexity 21

Size/Duplication

Total Lines 153
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 21
eloc 67
c 2
b 0
f 0
dl 0
loc 153
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A markFailed() 0 13 1
A performCreation() 0 18 3
C execute() 0 73 13
A checkAccountExists() 0 3 1
A getCreationReason() 0 3 1
A getMediaWikiHelper() 0 7 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\Background;
10
11
use Exception;
12
use Waca\DataObjects\Request;
13
use Waca\DataObjects\User;
14
use Waca\ExceptionHandler;
15
use Waca\Exceptions\ApplicationLogicException;
16
use Waca\Helpers\Interfaces\IMediaWikiClient;
17
use Waca\Helpers\Logger;
18
use Waca\Helpers\MediaWikiHelper;
19
use Waca\Helpers\RequestEmailHelper;
20
use Waca\RequestStatus;
21
22
abstract class CreationTaskBase extends BackgroundTaskBase
23
{
24
    /** @var Request */
25
    private $request;
26
    /**
27
     * @var MediaWikiHelper
28
     * Don't use this directly.
29
     */
30
    private $mwHelper = null;
31
32
    public function execute()
33
    {
34
        $this->request = $this->getRequest();
35
        $user = $this->getTriggerUser();
36
        $parameters = $this->getParameters();
37
38
        if ($this->request->getStatus() !== RequestStatus::JOBQUEUE) {
39
            $this->markCancelled('Request is not deferred to the job queue');
40
41
            return;
42
        }
43
44
        if ($this->request->getEmailSent() != 0 && !isset($parameters->emailText)) {
45
            $this->markFailed('Request has already been sent a templated email');
46
47
            return;
48
        }
49
50
        if ($this->request->getEmail() === $this->getSiteConfiguration()->getDataClearEmail()) {
51
            $this->markFailed('Private data of request has been purged.');
52
53
            return;
54
        }
55
56
        $emailText = null;
57
        $ccMailingList = null;
58
        $logTarget = null;
59
60
        if (isset($parameters->emailText) && isset($parameters->ccMailingList)) {
61
            $emailText = $parameters->emailText;
62
            $ccMailingList = $parameters->ccMailingList;
63
            $logTarget = "custom-y";
64
        }
65
66
        if ($this->getEmailTemplate() !== null) {
67
            $emailText = $this->getEmailTemplate()->getText();
68
            $ccMailingList = false;
69
            $logTarget = $this->getEmailTemplate()->getId();
70
        }
71
72
        if ($emailText === null || $ccMailingList === null) {
73
            $this->markFailed('Unable to get closure email text');
74
75
            return;
76
        }
77
78
        try {
79
            $this->performCreation($user);
80
81
            $this->request->setStatus(RequestStatus::CLOSED);
82
            $this->request->setQueue(null);
83
            $this->request->setReserved(null);
84
            $this->request->setEmailSent(true);
85
            $this->request->save();
86
87
            // Log the closure as the user
88
            $logComment = $this->getEmailTemplate() === null ? $emailText : null;
89
            Logger::closeRequest($this->getDatabase(), $this->request, $logTarget, $logComment, $this->getTriggerUser());
0 ignored issues
show
Bug introduced by
It seems like $logTarget can also be of type string; however, parameter $target of Waca\Helpers\Logger::closeRequest() does only seem to accept integer, 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

89
            Logger::closeRequest($this->getDatabase(), $this->request, /** @scrutinizer ignore-type */ $logTarget, $logComment, $this->getTriggerUser());
Loading history...
90
91
            $requestEmailHelper = new RequestEmailHelper($this->getEmailHelper());
92
            $requestEmailHelper->sendMail($this->request, $emailText, $this->getTriggerUser(), $ccMailingList);
93
        }
94
        catch (Exception $ex) {
95
            if (mb_strlen($ex->getMessage()) > 255) {
96
                ExceptionHandler::logExceptionToDisk($ex, $this->getSiteConfiguration());
97
            }
98
99
            $this->markFailed(substr($ex->getMessage(), 0, 255));
100
101
            return;
102
        }
103
104
        $this->markComplete();
105
    }
106
107
    /**
108
     * @return IMediaWikiClient
109
     */
110
    protected abstract function getMediaWikiClient();
111
112
    protected function getMediaWikiHelper()
113
    {
114
        if ($this->mwHelper === null) {
115
            $this->mwHelper = new MediaWikiHelper($this->getMediaWikiClient(), $this->getSiteConfiguration());
116
        }
117
118
        return $this->mwHelper;
119
    }
120
121
    /** @noinspection PhpUnusedParameterInspection */
122
    protected function getCreationReason(Request $request, User $user)
123
    {
124
        return 'Requested account at [[WP:ACC]], request #' . $request->getId();
125
    }
126
127
    /**
128
     * @param string $name
129
     *
130
     * @return bool
131
     */
132
    protected function checkAccountExists($name)
133
    {
134
        return $this->getMediaWikiHelper()->checkAccountExists($name);
135
    }
136
137
    protected function markFailed($reason = null, bool $acknowledged = false)
138
    {
139
        $this->request->setStatus(RequestStatus::HOSPITAL);
140
        $this->request->setQueue(null);
141
        $this->request->save();
142
143
        $this->getNotificationHelper()->requestCreationFailed($this->request, $this->getTriggerUser());
144
145
        Logger::hospitalised($this->getDatabase(), $this->request);
146
147
        // auto-acknowledge failed creation tasks, as these land in the hospital queue anyway.
148
        parent::markFailed($reason, true);
149
        Logger::backgroundJobAcknowledged($this->getDatabase(), $this->getJob(), "Auto-acknowledged due to request deferral to hospital queue");
150
    }
151
152
    /**
153
     * @param $user
154
     *
155
     * @throws ApplicationLogicException
156
     */
157
    protected function performCreation($user)
158
    {
159
        $mw = $this->getMediaWikiHelper();
160
161
        $reason = $this->getCreationReason($this->request, $user);
162
163
        if ($this->checkAccountExists($this->request->getName())) {
164
            throw new ApplicationLogicException('Account already exists');
165
        }
166
167
        $mw->createAccount($this->request->getName(), $this->request->getEmail(), $reason);
168
169
        if (!$this->checkAccountExists($this->request->getName())) {
170
            throw new ApplicationLogicException('Account creation appeared to succeed but account does not exist.');
171
        }
172
173
        $this->request->setStatus(RequestStatus::CLOSED);
174
        $this->request->save();
175
    }
176
}