Completed
Branch newinternal (ffe884)
by Simon
04:07
created

LogHelper::getObjectDescription()   C

Complexity

Conditions 8
Paths 8

Size

Total Lines 48
Code Lines 32

Duplication

Lines 28
Ratio 58.33 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 3
Bugs 0 Features 0
Metric Value
dl 28
loc 48
ccs 0
cts 36
cp 0
rs 5.9322
c 3
b 0
f 0
cc 8
eloc 32
nc 8
nop 4
crap 72
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
/**
10
 * Created by PhpStorm.
11
 * User: stwalkerster
12
 * Date: 26/03/2016
13
 * Time: 02:55
14
 */
15
16
namespace Waca\Helpers;
17
18
use Exception;
19
use PDO;
20
use Waca\DataObject;
21
use Waca\DataObjects\Ban;
22
use Waca\DataObjects\Comment;
23
use Waca\DataObjects\EmailTemplate;
24
use Waca\DataObjects\Log;
25
use Waca\DataObjects\Request;
26
use Waca\DataObjects\User;
27
use Waca\DataObjects\WelcomeTemplate;
28
use Waca\Helpers\SearchHelpers\LogSearchHelper;
29
use Waca\PdoDatabase;
30
use Waca\SiteConfiguration;
31
32
class LogHelper
33
{
34
	/**
35
	 * Summary of getRequestLogsWithComments
36
	 *
37
	 * @param int         $requestId
38
	 * @param PdoDatabase $db
39
	 *
40
	 * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use DataObject[].

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
41
	 */
42
	public static function getRequestLogsWithComments($requestId, PdoDatabase $db)
43
	{
44
		$logs = LogSearchHelper::get($db)->byObjectType('Request')->byObjectId($requestId)->fetch();
45
		$comments = Comment::getForRequest($requestId, $db);
46
47
		$items = array_merge($logs, $comments);
48
49
		/**
50
		 * @param DataObject $item
51
		 *
52
		 * @return int
53
		 */
54
		$sortKey = function(DataObject $item) {
55
			if ($item instanceof Log) {
56
				return $item->getTimestamp()->getTimestamp();
57
			}
58
59
			if ($item instanceof Comment) {
60
				return $item->getTime()->getTimestamp();
61
			}
62
63
			return 0;
64
		};
65
66
		do {
67
			$flag = false;
68
69
			$loopLimit = (count($items) - 1);
70
			for ($i = 0; $i < $loopLimit; $i++) {
71
				// are these two items out of order?
72
				if ($sortKey($items[$i]) > $sortKey($items[$i + 1])) {
73
					// swap them
74
					$swap = $items[$i];
75
					$items[$i] = $items[$i + 1];
76
					$items[$i + 1] = $swap;
77
78
					// set a flag to say we've modified the array this time around
79
					$flag = true;
80
				}
81
			}
82
		}
83
		while ($flag);
84
85
		return $items;
86
	}
87
88
	/**
89
	 * Summary of getLogDescription
90
	 *
91
	 * @param Log $entry
92
	 *
93
	 * @return string
94
	 */
95
	public static function getLogDescription(Log $entry)
96
	{
97
		$text = "Deferred to ";
98
		if (substr($entry->getAction(), 0, strlen($text)) == $text) {
99
			// Deferred to a different queue
100
			// This is exactly what we want to display.
101
			return $entry->getAction();
102
		}
103
104
		$text = "Closed custom-n";
105
		if ($entry->getAction() == $text) {
106
			// Custom-closed
107
			return "closed (custom reason - account not created)";
108
		}
109
110
		$text = "Closed custom-y";
111
		if ($entry->getAction() == $text) {
112
			// Custom-closed
113
			return "closed (custom reason - account created)";
114
		}
115
116
		$text = "Closed 0";
117
		if ($entry->getAction() == $text) {
118
			// Dropped the request - short-circuit the lookup
119
			return "dropped request";
120
		}
121
122
		$text = "Closed ";
123
		if (substr($entry->getAction(), 0, strlen($text)) == $text) {
124
			// Closed with a reason - do a lookup here.
125
			$id = substr($entry->getAction(), strlen($text));
126
			/** @var EmailTemplate $template */
127
			$template = EmailTemplate::getById((int)$id, $entry->getDatabase());
128
129
			if ($template != false) {
130
				return "closed (" . $template->getName() . ")";
131
			}
132
		}
133
134
		// Fall back to the basic stuff
135
		$lookup = array(
136
			'Reserved'        => 'reserved',
137
			'Email Confirmed' => 'email-confirmed',
138
			'Unreserved'      => 'unreserved',
139
			'Approved'        => 'approved',
140
			'Suspended'       => 'suspended',
141
			'Banned'          => 'banned',
142
			'Edited'          => 'edited interface message',
143
			'Declined'        => 'declined',
144
			'EditComment-c'   => 'edited a comment',
145
			'EditComment-r'   => 'edited a comment',
146
			'Unbanned'        => 'unbanned',
147
			'Promoted'        => 'promoted to tool admin',
148
			'BreakReserve'    => 'forcibly broke the reservation',
149
			'Prefchange'      => 'changed user preferences',
150
			'Renamed'         => 'renamed',
151
			'Demoted'         => 'demoted from tool admin',
152
			'ReceiveReserved' => 'received the reservation',
153
			'SendReserved'    => 'sent the reservation',
154
			'EditedEmail'     => 'edited email',
155
			'DeletedTemplate' => 'deleted template',
156
			'EditedTemplate'  => 'edited template',
157
			'CreatedEmail'    => 'created email',
158
			'CreatedTemplate' => 'created template',
159
			'SentMail'        => 'sent an email to the requestor',
160
			'Registered'      => 'registered a tool account',
161
		);
162
163
		if (array_key_exists($entry->getAction(), $lookup)) {
164
			return $lookup[$entry->getAction()];
165
		}
166
167
		// OK, I don't know what this is. Fall back to something sane.
168
		return "performed an unknown action ({$entry->getAction()})";
169
	}
170
171
	/**
172
	 * @param PdoDatabase $database
173
	 *
174
	 * @return array
175
	 */
176
	public static function getLogActions(PdoDatabase $database)
177
	{
178
		$lookup = array(
179
			'Reserved'        => 'reserved',
180
			'Email Confirmed' => 'email-confirmed',
181
			'Unreserved'      => 'unreserved',
182
			'Approved'        => 'approved',
183
			'Suspended'       => 'suspended',
184
			'Banned'          => 'banned',
185
			'Edited'          => 'edited interface message',
186
			'Declined'        => 'declined',
187
			'EditComment-c'   => 'edited a comment',
188
			'EditComment-r'   => 'edited a comment',
189
			'Unbanned'        => 'unbanned',
190
			'Promoted'        => 'promoted to tool admin',
191
			'BreakReserve'    => 'forcibly broke the reservation',
192
			'Prefchange'      => 'changed user preferences',
193
			'Renamed'         => 'renamed',
194
			'Demoted'         => 'demoted from tool admin',
195
			'ReceiveReserved' => 'received the reservation',
196
			'SendReserved'    => 'sent the reservation',
197
			'EditedEmail'     => 'edited email',
198
			'DeletedTemplate' => 'deleted template',
199
			'EditedTemplate'  => 'edited template',
200
			'CreatedEmail'    => 'created email',
201
			'CreatedTemplate' => 'created template',
202
			'SentMail'        => 'sent an email to the requestor',
203
			'Registered'      => 'registered a tool account',
204
		);
205
206
		$statement = $database->query(<<<SQL
207
SELECT CONCAT('Closed ', id) AS k, CONCAT('closed (',name,')') AS v
208
FROM emailtemplate;
209
SQL
210
		);
211
		foreach ($statement->fetchAll(PDO::FETCH_ASSOC) as $row) {
212
			$lookup[$row['k']] = $row['v'];
213
		}
214
215
		return $lookup;
216
	}
217
218
	/**
219
	 * This returns a HTML
220
	 *
221
	 * @param string            $objectId
222
	 * @param string            $objectType
223
	 * @param PdoDatabase       $database
224
	 * @param SiteConfiguration $configuration
225
	 *
226
	 * @return null|string
227
	 * @category Security-Critical
228
	 */
229
	private static function getObjectDescription($objectId, $objectType, PdoDatabase $database, SiteConfiguration $configuration)
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 126 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
230
	{
231
		if ($objectType == '') {
232
			return null;
233
		}
234
235
		$baseurl = $configuration->getBaseUrl();
236
237
		switch ($objectType) {
238
			case 'Ban':
239
				/** @var Ban $ban */
240
				$ban = Ban::getById($objectId, $database);
241
242
				return 'Ban #' . $objectId . " (" . htmlentities($ban->getTarget()) . ")</a>";
243 View Code Duplication
			case 'EmailTemplate':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
244
				/** @var EmailTemplate $emailTemplate */
245
				$emailTemplate = EmailTemplate::getById($objectId, $database);
246
				$name = htmlentities($emailTemplate->getName(), ENT_COMPAT, 'UTF-8');
247
248
				return <<<HTML
249
<a href="{$baseurl}/internal.php/emailManagement/view?id={$objectId}">Email Template #{$objectId} ({$name})</a>
250
HTML;
251
			case 'SiteNotice':
252
				return "<a href=\"{$baseurl}/internal.php/siteNotice\">the site notice</a>";
253 View Code Duplication
			case 'Request':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
254
				/** @var Request $request */
255
				$request = Request::getById($objectId, $database);
256
				$name = htmlentities($request->getName(), ENT_COMPAT, 'UTF-8');
257
258
				return <<<HTML
259
<a href="{$baseurl}/internal.php/viewRequest?id={$objectId}">Request #{$objectId} ({$name})</a>
260
HTML;
261 View Code Duplication
			case 'User':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
262
				/** @var User $user */
263
				$user = User::getById($objectId, $database);
264
				$username = htmlentities($user->getUsername(), ENT_COMPAT, 'UTF-8');
265
266
				return "<a href=\"{$baseurl}/internal.php/statistics/users/detail?user={$objectId}\">{$username}</a>";
267 View Code Duplication
			case 'WelcomeTemplate':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
268
				/** @var WelcomeTemplate $welcomeTemplate */
269
				$welcomeTemplate = WelcomeTemplate::getById($objectId, $database);
270
				$userCode = htmlentities($welcomeTemplate->getUserCode(), ENT_COMPAT, 'UTF-8');
271
272
				return "<a href=\"{$baseurl}/internal.php/welcomeTemplates/view?id={$objectId}\">{$userCode}</a>";
273
			default:
274
				return '[' . $objectType . " " . $objectId . ']';
275
		}
276
	}
277
278
	/**
279
	 * @param    Log[]          $logs
280
	 * @param     PdoDatabase   $database
281
	 * @param SiteConfiguration $configuration
282
	 *
283
	 * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array[].

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
284
	 * @throws Exception
285
	 */
286
	public static function prepareLogsForTemplate($logs, PdoDatabase $database, SiteConfiguration $configuration)
287
	{
288
		$userIds = array();
289
290
		/** @var Log $logEntry */
291
		foreach ($logs as $logEntry) {
292
			if (!$logEntry instanceof Log) {
293
				// if this happens, we've done something wrong with passing back the log data.
294
				throw new Exception('Log entry is not an instance of a Log, this should never happen.');
295
			}
296
297
			$user = $logEntry->getUser();
298
			if ($user === -1) {
299
				continue;
300
			}
301
302
			if (!array_search($user, $userIds)) {
303
				$userIds[] = $user;
304
			}
305
		}
306
307
		$users = User::getUsernames($userIds, $database);
308
		$users[-1] = User::getCommunity()->getUsername();
309
310
		$logData = array();
311
312
		/** @var Log $logEntry */
313
		foreach ($logs as $logEntry) {
314
			$objectDescription = self::getObjectDescription($logEntry->getObjectId(), $logEntry->getObjectType(),
315
				$database, $configuration);
316
317
			if($logEntry->getAction() === 'Renamed'){
318
				$renameData = unserialize($logEntry->getComment());
319
				$oldName = htmlentities($renameData['old'], ENT_COMPAT, 'UTF-8');
320
				$newName = htmlentities($renameData['new'], ENT_COMPAT, 'UTF-8');
321
				$comment = 'Renamed \'' . $oldName . '\' to \'' . $newName . '\'.';
322
			}
323
			else{
324
				$comment = $logEntry->getComment();
325
			}
326
327
			$logData[] = array(
328
				'timestamp'         => $logEntry->getTimestamp(),
329
				'userid'            => $logEntry->getUser(),
330
				'username'          => $users[$logEntry->getUser()],
331
				'description'       => self::getLogDescription($logEntry),
332
				'objectdescription' => $objectDescription,
333
				'comment'           => $comment,
334
			);
335
		}
336
337
		return array($users, $logData);
338
	}
339
}