Issues (186)

includes/DataObjects/WelcomeTemplate.php (1 issue)

Labels
Severity
1
<?php
2
/******************************************************************************
3
 * Wikipedia Account Creation Assistance tool                                 *
4
 * ACC Development Team. Please see team.json for a list of contributors.     *
5
 *                                                                            *
6
 * This is free and unencumbered software released into the public domain.    *
7
 * Please see LICENSE.md for the full licencing statement.                    *
8
 ******************************************************************************/
9
10
namespace Waca\DataObjects;
11
12
use Exception;
13
use PDO;
14
use Waca\DataObject;
15
use Waca\Exceptions\OptimisticLockFailedException;
16
use Waca\Helpers\PreferenceManager;
17
use Waca\PdoDatabase;
18
19
/**
20
 * Welcome template data object
21
 */
22
class WelcomeTemplate extends DataObject
23
{
24
    /** @var string */
25
    private $usercode;
26
    /** @var string */
27
    private $botcode;
28
    private $usageCache;
29
    private $deleted = 0;
30
    /** @var int */
31
    private $domain;
32
33
    /**
34
     * Summary of getAll
35
     *
36
     * @param PdoDatabase $database
37
     *
38
     * @return WelcomeTemplate[]
39
     */
40
    public static function getAll(PdoDatabase $database, int $domain)
41
    {
42
        $statement = $database->prepare("SELECT * FROM welcometemplate WHERE deleted = 0 AND domain = :domain;");
43
44
        $statement->execute([':domain' => $domain]);
45
46
        $result = array();
47
        /** @var WelcomeTemplate $v */
48
        foreach ($statement->fetchAll(PDO::FETCH_CLASS, self::class) as $v) {
49
            $v->setDatabase($database);
50
            $result[] = $v;
51
        }
52
53
        return $result;
54
    }
55
56
    /**
57
     * @throws Exception
58
     */
59
    public function save()
60
    {
61
        if ($this->isNew()) {
62
            // insert
63
            $statement = $this->dbObject->prepare(<<<SQL
64
INSERT INTO welcometemplate (usercode, botcode, domain) VALUES (:usercode, :botcode, :domain);
65
SQL
66
            );
67
            $statement->bindValue(":usercode", $this->usercode);
68
            $statement->bindValue(":botcode", $this->botcode);
69
            $statement->bindValue(":domain", $this->domain);
70
71
            if ($statement->execute()) {
72
                $this->id = (int)$this->dbObject->lastInsertId();
73
            }
74
            else {
75
                throw new Exception($statement->errorInfo());
0 ignored issues
show
$statement->errorInfo() of type array is incompatible with the type string expected by parameter $message of Exception::__construct(). ( Ignorable by Annotation )

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

75
                throw new Exception(/** @scrutinizer ignore-type */ $statement->errorInfo());
Loading history...
76
            }
77
        }
78
        else {
79
            // update
80
            $statement = $this->dbObject->prepare(<<<SQL
81
UPDATE `welcometemplate`
82
SET usercode = :usercode, botcode = :botcode, updateversion = updateversion + 1
83
WHERE id = :id AND updateversion = :updateversion;
84
SQL
85
            );
86
87
            $statement->bindValue(':id', $this->id);
88
            $statement->bindValue(':updateversion', $this->updateversion);
89
90
            $statement->bindValue(':usercode', $this->usercode);
91
            $statement->bindValue(':botcode', $this->botcode);
92
93
            if (!$statement->execute()) {
94
                throw new Exception($statement->errorInfo());
95
            }
96
97
            if ($statement->rowCount() !== 1) {
98
                throw new OptimisticLockFailedException();
99
            }
100
101
            $this->updateversion++;
102
        }
103
    }
104
105
    /**
106
     * @return string
107
     */
108
    public function getUserCode()
109
    {
110
        return $this->usercode;
111
    }
112
113
    /**
114
     * @param string $usercode
115
     */
116
    public function setUserCode($usercode)
117
    {
118
        $this->usercode = $usercode;
119
    }
120
121
    /**
122
     * @return string
123
     */
124
    public function getBotCode()
125
    {
126
        return $this->botcode;
127
    }
128
129
    /**
130
     * @param string $botcode
131
     */
132
    public function setBotCode($botcode)
133
    {
134
        $this->botcode = $botcode;
135
    }
136
137
    /**
138
     * @return User[]
139
     */
140
    public function getUsersUsingTemplate()
141
    {
142
        if ($this->usageCache === null) {
143
            $statement = $this->dbObject->prepare("SELECT * FROM user WHERE id IN (SELECT DISTINCT user FROM userpreference WHERE preference = :pref AND value = :id);");
144
145
            $statement->execute([
146
                ':id' => $this->id,
147
                ':pref' => PreferenceManager::PREF_WELCOMETEMPLATE
148
            ]);
149
150
            $result = array();
151
            /** @var WelcomeTemplate $v */
152
            foreach ($statement->fetchAll(PDO::FETCH_CLASS, User::class) as $v) {
153
                $v->setDatabase($this->dbObject);
154
                $result[] = $v;
155
            }
156
157
            $this->usageCache = $result;
158
        }
159
160
        return $this->usageCache;
161
    }
162
163
    /**
164
     * Deletes the object from the database
165
     */
166
    public function delete()
167
    {
168
        if ($this->id === null) {
169
            // wtf?
170
            return;
171
        }
172
173
        $deleteQuery = "UPDATE welcometemplate SET deleted = 1, updateversion = updateversion + 1 WHERE id = :id AND updateversion = :updateversion;";
174
        $statement = $this->dbObject->prepare($deleteQuery);
175
176
        $statement->bindValue(":id", $this->id);
177
        $statement->bindValue(":updateversion", $this->updateversion);
178
        $statement->execute();
179
180
        if ($statement->rowCount() !== 1) {
181
            throw new OptimisticLockFailedException();
182
        }
183
    }
184
185
    /**
186
     * @return bool
187
     */
188
    public function isDeleted()
189
    {
190
        return ((int)$this->deleted) === 1;
191
    }
192
193
    public function getSectionHeader()
194
    {
195
        // Hard-coded for future update ability to change this per-template. This has beem moved from being hard-coded
196
        // directly in the welcome task, and safely permits us to show the header in the welcome template preview
197
        return "Welcome!";
198
    }
199
200
    public function getBotCodeForWikiSave(string $request, $creator)
201
    {
202
        $templateText = $this->getBotCode();
203
204
        $templateText = str_replace('$request', $request, $templateText);
205
        $templateText = str_replace('$creator', $creator, $templateText);
206
207
        // legacy; these have been removed in Prod for now, but I'm keeping them in case someone follows the
208
        // instructions in prod prior to deployment.
209
        $templateText = str_replace('$signature', '~~~~', $templateText);
210
        $templateText = str_replace('$username', $creator, $templateText);
211
212
        return $templateText;
213
    }
214
215
    public function getDomain(): int
216
    {
217
        return $this->domain;
218
    }
219
220
    public function setDomain(int $domain): void
221
    {
222
        $this->domain = $domain;
223
    }
224
}
225