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

LogHelper::getLogDescription()   B

Complexity

Conditions 8
Paths 9

Size

Total Lines 75
Code Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 48
c 1
b 0
f 0
dl 0
loc 75
rs 7.8901
cc 8
nc 9
nop 1

How to fix   Long Method   

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\Helpers;
10
11
use Exception;
12
use PDO;
13
use Waca\DataObject;
14
use Waca\DataObjects\Ban;
15
use Waca\DataObjects\Comment;
16
use Waca\DataObjects\EmailTemplate;
17
use Waca\DataObjects\Log;
18
use Waca\DataObjects\Request;
19
use Waca\DataObjects\User;
20
use Waca\DataObjects\WelcomeTemplate;
21
use Waca\Helpers\SearchHelpers\LogSearchHelper;
22
use Waca\Helpers\SearchHelpers\UserSearchHelper;
23
use Waca\PdoDatabase;
24
use Waca\Security\SecurityManager;
25
use Waca\SiteConfiguration;
26
27
class LogHelper
28
{
29
    /**
30
     * Summary of getRequestLogsWithComments
31
     *
32
     * @param int             $requestId
33
     * @param PdoDatabase     $db
34
     * @param SecurityManager $securityManager
35
     *
36
     * @return \Waca\DataObject[]
37
     */
38
    public static function getRequestLogsWithComments($requestId, PdoDatabase $db, SecurityManager $securityManager)
39
    {
40
        $logs = LogSearchHelper::get($db)->byObjectType('Request')->byObjectId($requestId)->fetch();
41
42
        $currentUser = User::getCurrent($db);
43
        $securityResult = $securityManager->allows('RequestData', 'seeRestrictedComments', $currentUser);
44
        $showAllComments = $securityResult === SecurityManager::ALLOWED;
45
46
        $comments = Comment::getForRequest($requestId, $db, $showAllComments, $currentUser->getId());
47
48
        $items = array_merge($logs, $comments);
49
50
        /**
51
         * @param DataObject $item
52
         *
53
         * @return int
54
         */
55
        $sortKey = function(DataObject $item) {
56
            if ($item instanceof Log) {
57
                return $item->getTimestamp()->getTimestamp();
58
            }
59
60
            if ($item instanceof Comment) {
61
                return $item->getTime()->getTimestamp();
62
            }
63
64
            return 0;
65
        };
66
67
        do {
68
            $flag = false;
69
70
            $loopLimit = (count($items) - 1);
71
            for ($i = 0; $i < $loopLimit; $i++) {
72
                // are these two items out of order?
73
                if ($sortKey($items[$i]) > $sortKey($items[$i + 1])) {
74
                    // swap them
75
                    $swap = $items[$i];
76
                    $items[$i] = $items[$i + 1];
77
                    $items[$i + 1] = $swap;
78
79
                    // set a flag to say we've modified the array this time around
80
                    $flag = true;
81
                }
82
            }
83
        }
84
        while ($flag);
85
86
        return $items;
87
    }
88
89
    /**
90
     * Summary of getLogDescription
91
     *
92
     * @param Log $entry
93
     *
94
     * @return string
95
     */
96
    public static function getLogDescription(Log $entry)
97
    {
98
        $text = "Deferred to ";
99
        if (substr($entry->getAction(), 0, strlen($text)) == $text) {
100
            // Deferred to a different queue
101
            // This is exactly what we want to display.
102
            return $entry->getAction();
103
        }
104
105
        $text = "Closed custom-n";
106
        if ($entry->getAction() == $text) {
107
            // Custom-closed
108
            return "closed (custom reason - account not created)";
109
        }
110
111
        $text = "Closed custom-y";
112
        if ($entry->getAction() == $text) {
113
            // Custom-closed
114
            return "closed (custom reason - account created)";
115
        }
116
117
        $text = "Closed 0";
118
        if ($entry->getAction() == $text) {
119
            // Dropped the request - short-circuit the lookup
120
            return "dropped request";
121
        }
122
123
        $text = "Closed ";
124
        if (substr($entry->getAction(), 0, strlen($text)) == $text) {
125
            // Closed with a reason - do a lookup here.
126
            $id = substr($entry->getAction(), strlen($text));
127
            /** @var EmailTemplate $template */
128
            $template = EmailTemplate::getById((int)$id, $entry->getDatabase());
129
130
            if ($template != false) {
131
                return "closed (" . $template->getName() . ")";
132
            }
133
        }
134
135
        // Fall back to the basic stuff
136
        $lookup = array(
137
            'Reserved'        => 'reserved',
138
            'Email Confirmed' => 'email-confirmed',
139
            'Unreserved'      => 'unreserved',
140
            'Approved'        => 'approved',
141
            'Suspended'       => 'suspended',
142
            'RoleChange'      => 'changed roles',
143
            'Banned'          => 'banned',
144
            'Edited'          => 'edited interface message',
145
            'Declined'        => 'declined',
146
            'EditComment-c'   => 'edited a comment',
147
            'EditComment-r'   => 'edited a comment',
148
            'Unbanned'        => 'unbanned',
149
            'Promoted'        => 'promoted to tool admin',
150
            'BreakReserve'    => 'forcibly broke the reservation',
151
            'Prefchange'      => 'changed user preferences',
152
            'Renamed'         => 'renamed',
153
            'Demoted'         => 'demoted from tool admin',
154
            'ReceiveReserved' => 'received the reservation',
155
            'SendReserved'    => 'sent the reservation',
156
            'EditedEmail'     => 'edited email',
157
            'DeletedTemplate' => 'deleted template',
158
            'EditedTemplate'  => 'edited template',
159
            'CreatedEmail'    => 'created email',
160
            'CreatedTemplate' => 'created template',
161
            'SentMail'        => 'sent an email to the requestor',
162
            'Registered'      => 'registered a tool account',
163
        );
164
165
        if (array_key_exists($entry->getAction(), $lookup)) {
166
            return $lookup[$entry->getAction()];
167
        }
168
169
        // OK, I don't know what this is. Fall back to something sane.
170
        return "performed an unknown action ({$entry->getAction()})";
171
    }
172
173
    /**
174
     * @param PdoDatabase $database
175
     *
176
     * @return array
177
     */
178
    public static function getLogActions(PdoDatabase $database)
179
    {
180
        $lookup = array(
181
            'Reserved'        => 'reserved',
182
            'Email Confirmed' => 'email-confirmed',
183
            'Unreserved'      => 'unreserved',
184
            'Approved'        => 'approved',
185
            'Suspended'       => 'suspended',
186
            'RoleChange'      => 'changed roles',
187
            'Banned'          => 'banned',
188
            'Edited'          => 'edited interface message',
189
            'Declined'        => 'declined',
190
            'EditComment-c'   => 'edited a comment (by comment ID)',
191
            'EditComment-r'   => 'edited a comment (by request)',
192
            'Unbanned'        => 'unbanned',
193
            'Promoted'        => 'promoted to tool admin',
194
            'BreakReserve'    => 'forcibly broke the reservation',
195
            'Prefchange'      => 'changed user preferences',
196
            'Renamed'         => 'renamed',
197
            'Demoted'         => 'demoted from tool admin',
198
            'ReceiveReserved' => 'received the reservation',
199
            'SendReserved'    => 'sent the reservation',
200
            'EditedEmail'     => 'edited email',
201
            'DeletedTemplate' => 'deleted template',
202
            'EditedTemplate'  => 'edited template',
203
            'CreatedEmail'    => 'created email',
204
            'CreatedTemplate' => 'created template',
205
            'SentMail'        => 'sent an email to the requestor',
206
            'Registered'      => 'registered a tool account',
207
            'Closed 0'        => 'dropped request',
208
        );
209
210
        $statement = $database->query(<<<SQL
211
SELECT CONCAT('Closed ', id) AS k, CONCAT('closed (',name,')') AS v
212
FROM emailtemplate;
213
SQL
214
        );
215
        foreach ($statement->fetchAll(PDO::FETCH_ASSOC) as $row) {
216
            $lookup[$row['k']] = $row['v'];
217
        }
218
219
        return $lookup;
220
    }
221
222
    public static function getObjectTypes()
223
    {
224
        return array(
225
            'Ban'             => 'Ban',
226
            'Comment'         => 'Comment',
227
            'EmailTemplate'   => 'Email template',
228
            'Request'         => 'Request',
229
            'SiteNotice'      => 'Site notice',
230
            'User'            => 'User',
231
            'WelcomeTemplate' => 'Welcome template',
232
        );
233
    }
234
235
    /**
236
     * This returns a HTML
237
     *
238
     * @param string            $objectId
239
     * @param string            $objectType
240
     * @param PdoDatabase       $database
241
     * @param SiteConfiguration $configuration
242
     *
243
     * @return null|string
244
     * @category Security-Critical
245
     */
246
    private static function getObjectDescription(
247
        $objectId,
248
        $objectType,
249
        PdoDatabase $database,
250
        SiteConfiguration $configuration
251
    ) {
252
        if ($objectType == '') {
253
            return null;
254
        }
255
256
        $baseurl = $configuration->getBaseUrl();
257
258
        switch ($objectType) {
259
            case 'Ban':
260
                /** @var Ban $ban */
261
                $ban = Ban::getById($objectId, $database);
262
263
                if ($ban === false) {
264
                    return 'Ban #' . $objectId . "</a>";
265
                }
266
267
                return 'Ban #' . $objectId . " (" . htmlentities($ban->getTarget()) . ")</a>";
268
            case 'EmailTemplate':
269
                /** @var EmailTemplate $emailTemplate */
270
                $emailTemplate = EmailTemplate::getById($objectId, $database);
271
                $name = htmlentities($emailTemplate->getName(), ENT_COMPAT, 'UTF-8');
272
273
                return <<<HTML
274
<a href="{$baseurl}/internal.php/emailManagement/view?id={$objectId}">Email Template #{$objectId} ({$name})</a>
275
HTML;
276
            case 'SiteNotice':
277
                return "<a href=\"{$baseurl}/internal.php/siteNotice\">the site notice</a>";
278
            case 'Request':
279
                /** @var Request $request */
280
                $request = Request::getById($objectId, $database);
281
                $name = htmlentities($request->getName(), ENT_COMPAT, 'UTF-8');
282
283
                return <<<HTML
284
<a href="{$baseurl}/internal.php/viewRequest?id={$objectId}">Request #{$objectId} ({$name})</a>
285
HTML;
286
            case 'User':
287
                /** @var User $user */
288
                $user = User::getById($objectId, $database);
289
                $username = htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8');
290
291
                return "<a href=\"{$baseurl}/internal.php/statistics/users/detail?user={$objectId}\">{$username}</a>";
292
            case 'WelcomeTemplate':
293
                /** @var WelcomeTemplate $welcomeTemplate */
294
                $welcomeTemplate = WelcomeTemplate::getById($objectId, $database);
295
296
                // some old templates have been completely deleted and lost to the depths of time.
297
                if ($welcomeTemplate === false) {
298
                    return "Welcome template #{$objectId}";
299
                }
300
                else {
301
                    $userCode = htmlentities($welcomeTemplate->getUserCode(), ENT_COMPAT, 'UTF-8');
302
303
                    return "<a href=\"{$baseurl}/internal.php/welcomeTemplates/view?template={$objectId}\">{$userCode}</a>";
304
                }
305
            default:
306
                return '[' . $objectType . " " . $objectId . ']';
307
        }
308
    }
309
310
    /**
311
     * @param    Log[]          $logs
312
     * @param     PdoDatabase   $database
313
     * @param SiteConfiguration $configuration
314
     *
315
     * @return array
316
     * @throws Exception
317
     */
318
    public static function prepareLogsForTemplate($logs, PdoDatabase $database, SiteConfiguration $configuration)
319
    {
320
        $userIds = array();
321
322
        /** @var Log $logEntry */
323
        foreach ($logs as $logEntry) {
324
            if (!$logEntry instanceof Log) {
325
                // if this happens, we've done something wrong with passing back the log data.
326
                throw new Exception('Log entry is not an instance of a Log, this should never happen.');
327
            }
328
329
            $user = $logEntry->getUser();
330
            if ($user === -1) {
331
                continue;
332
            }
333
334
            if (!array_search($user, $userIds)) {
335
                $userIds[] = $user;
336
            }
337
        }
338
339
        $users = UserSearchHelper::get($database)->inIds($userIds)->fetchMap('username');
340
        $users[-1] = User::getCommunity()->getUsername();
341
342
        $logData = array();
343
344
        /** @var Log $logEntry */
345
        foreach ($logs as $logEntry) {
346
            $objectDescription = self::getObjectDescription($logEntry->getObjectId(), $logEntry->getObjectType(),
347
                $database, $configuration);
348
349
            switch ($logEntry->getAction()) {
350
                case 'Renamed':
351
                    $renameData = unserialize($logEntry->getComment());
352
                    $oldName = htmlentities($renameData['old'], ENT_COMPAT, 'UTF-8');
353
                    $newName = htmlentities($renameData['new'], ENT_COMPAT, 'UTF-8');
354
                    $comment = 'Renamed \'' . $oldName . '\' to \'' . $newName . '\'.';
355
                    break;
356
                case 'RoleChange':
357
                    $roleChangeData = unserialize($logEntry->getComment());
358
359
                    $removed = array();
360
                    foreach ($roleChangeData['removed'] as $r) {
361
                        $removed[] = htmlentities($r, ENT_COMPAT, 'UTF-8');
362
                    }
363
364
                    $added = array();
365
                    foreach ($roleChangeData['added'] as $r) {
366
                        $added[] = htmlentities($r, ENT_COMPAT, 'UTF-8');
367
                    }
368
369
                    $reason = htmlentities($roleChangeData['reason'], ENT_COMPAT, 'UTF-8');
370
371
                    $roleDelta = 'Removed [' . implode(', ', $removed) . '], Added [' . implode(', ', $added) . ']';
372
                    $comment = $roleDelta . ' with comment: ' . $reason;
373
                    break;
374
                default:
375
                    $comment = $logEntry->getComment();
376
                    break;
377
            }
378
379
            $logData[] = array(
380
                'timestamp'         => $logEntry->getTimestamp(),
381
                'userid'            => $logEntry->getUser(),
382
                'username'          => $users[$logEntry->getUser()],
383
                'description'       => self::getLogDescription($logEntry),
384
                'objectdescription' => $objectDescription,
385
                'comment'           => $comment,
386
            );
387
        }
388
389
        return array($users, $logData);
390
    }
391
}
392