Completed
Branch newinternal (104de7)
by Simon
10:16
created

Request   B

Complexity

Total Complexity 38

Size/Duplication

Total Lines 376
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 3

Importance

Changes 11
Bugs 1 Features 0
Metric Value
wmc 38
c 11
b 1
f 0
lcom 2
cbo 3
dl 0
loc 376
rs 8.3999

27 Methods

Rating   Name   Duplication   Size   Complexity  
B save() 0 65 5
A getIp() 0 4 1
A setIp() 0 4 1
A getName() 0 4 1
A setName() 0 4 1
A getComment() 0 4 1
A setComment() 0 4 1
A getStatus() 0 4 1
A setStatus() 0 4 1
A getDate() 0 4 1
A getEmailSent() 0 4 1
A setEmailSent() 0 4 2
A getReserved() 0 4 1
A setReserved() 0 9 2
A getUserAgent() 0 4 1
A setUserAgent() 0 4 1
A getForwardedIp() 0 4 1
A setForwardedIp() 0 4 1
A hasComments() 0 23 3
A getEmailConfirm() 0 4 1
A setEmailConfirm() 0 4 1
A generateEmailConfirmationHash() 0 4 1
A getEmail() 0 4 1
A setEmail() 0 4 1
B getClosureReason() 0 24 2
B getWasCreated() 0 30 3
A getClosureDate() 0 15 1
1
<?php
2
namespace Waca\DataObjects;
3
4
use DateTime;
5
use DateTimeImmutable;
6
use Exception;
7
use Waca\DataObject;
8
use Waca\Exceptions\OptimisticLockFailedException;
9
10
/**
11
 * Request data object
12
 *
13
 * This data object is the main request object.
14
 */
15
class Request extends DataObject
16
{
17
	private $email;
18
	private $ip;
19
	private $name;
20
	/** @var string|null */
21
	private $comment;
22
	private $status = "Open";
23
	private $date;
24
	private $emailsent = 0;
25
	private $emailconfirm;
26
	private $reserved = 0;
27
	private $useragent;
28
	private $forwardedip;
29
	private $hasComments = false;
30
	private $hasCommentsResolved = false;
31
32
	/**
33
	 * @throws Exception
34
	 */
35
	public function save()
36
	{
37
		if ($this->isNew()) {
38
			// insert
39
			$statement = $this->dbObject->prepare(<<<SQL
40
INSERT INTO `request` (
41
	email, ip, name, comment, status, date, emailsent,
42
	emailconfirm, reserved, useragent, forwardedip
43
) VALUES (
44
	:email, :ip, :name, :comment, :status, CURRENT_TIMESTAMP(), :emailsent,
45
	:emailconfirm, :reserved, :useragent, :forwardedip
46
);
47
SQL
48
			);
49
			$statement->bindValue(":email", $this->email);
50
			$statement->bindValue(":ip", $this->ip);
51
			$statement->bindValue(":name", $this->name);
52
			$statement->bindValue(":comment", $this->comment);
53
			$statement->bindValue(":status", $this->status);
54
			$statement->bindValue(":emailsent", $this->emailsent);
55
			$statement->bindValue(":emailconfirm", $this->emailconfirm);
56
			$statement->bindValue(":reserved", $this->reserved);
57
			$statement->bindValue(":useragent", $this->useragent);
58
			$statement->bindValue(":forwardedip", $this->forwardedip);
59
60
			if ($statement->execute()) {
61
				$this->id = (int)$this->dbObject->lastInsertId();
62
			}
63
			else {
64
				throw new Exception($statement->errorInfo());
65
			}
66
		}
67
		else {
68
			// update
69
			$statement = $this->dbObject->prepare(<<<SQL
70
UPDATE `request` SET
71
	status = :status,
72
	emailsent = :emailsent,
73
	emailconfirm = :emailconfirm,
74
	reserved = :reserved,
75
	updateversion = updateversion + 1
76
WHERE id = :id AND updateversion = :updateversion
77
LIMIT 1;
78
SQL
79
			);
80
81
			$statement->bindValue(':id', $this->id);
82
			$statement->bindValue(':updateversion', $this->updateversion);
83
84
			$statement->bindValue(':status', $this->status);
85
			$statement->bindValue(':emailsent', $this->emailsent);
86
			$statement->bindValue(':emailconfirm', $this->emailconfirm);
87
			$statement->bindValue(':reserved', $this->reserved);
88
89
			if (!$statement->execute()) {
90
				throw new Exception($statement->errorInfo());
91
			}
92
93
			if ($statement->rowCount() !== 1) {
94
				throw new OptimisticLockFailedException();
95
			}
96
97
			$this->updateversion++;
98
		}
99
	}
100
101
	/**
102
	 * @return string
103
	 */
104
	public function getIp()
105
	{
106
		return $this->ip;
107
	}
108
109
	/**
110
	 * @param string $ip
111
	 */
112
	public function setIp($ip)
113
	{
114
		$this->ip = $ip;
115
	}
116
117
	/**
118
	 * @return string
119
	 */
120
	public function getName()
121
	{
122
		return $this->name;
123
	}
124
125
	/**
126
	 * @param string $name
127
	 */
128
	public function setName($name)
129
	{
130
		$this->name = $name;
131
	}
132
133
	/**
134
	 * @return string|null
135
	 */
136
	public function getComment()
137
	{
138
		return $this->comment;
139
	}
140
141
	/**
142
	 * @param string $comment
143
	 */
144
	public function setComment($comment)
145
	{
146
		$this->comment = $comment;
147
	}
148
149
	/**
150
	 * @return string
151
	 */
152
	public function getStatus()
153
	{
154
		return $this->status;
155
	}
156
157
	/**
158
	 * @param string $status
159
	 */
160
	public function setStatus($status)
161
	{
162
		$this->status = $status;
163
	}
164
165
	/**
166
	 * Returns the time the request was first submitted
167
	 *
168
	 * @return DateTimeImmutable
169
	 */
170
	public function getDate()
171
	{
172
		return new DateTimeImmutable($this->date);
173
	}
174
175
	/**
176
	 * @return bool
177
	 */
178
	public function getEmailSent()
179
	{
180
		return $this->emailsent == "1";
181
	}
182
183
	/**
184
	 * @param bool $emailSent
185
	 */
186
	public function setEmailSent($emailSent)
187
	{
188
		$this->emailsent = $emailSent ? 1 : 0;
189
	}
190
191
	/**
192
	 * @todo allow this to return null instead
193
	 * @return int
194
	 */
195
	public function getReserved()
196
	{
197
		return $this->reserved;
198
	}
199
200
	/**
201
	 * @param int|null $reserved
202
	 */
203
	public function setReserved($reserved)
204
	{
205
		if ($reserved === null) {
206
			// @todo this shouldn't be needed!
207
			$reserved = 0;
208
		}
209
210
		$this->reserved = $reserved;
211
	}
212
213
	/**
214
	 * @return string
215
	 */
216
	public function getUserAgent()
217
	{
218
		return $this->useragent;
219
	}
220
221
	/**
222
	 * @param string $useragent
223
	 */
224
	public function setUserAgent($useragent)
225
	{
226
		$this->useragent = $useragent;
227
	}
228
229
	/**
230
	 * @return string|null
231
	 */
232
	public function getForwardedIp()
233
	{
234
		return $this->forwardedip;
235
	}
236
237
	/**
238
	 * @param string|null $forwardedip
239
	 */
240
	public function setForwardedIp($forwardedip)
241
	{
242
		$this->forwardedip = $forwardedip;
243
	}
244
245
	/**
246
	 * @return bool
247
	 */
248
	public function hasComments()
249
	{
250
		if ($this->hasCommentsResolved) {
251
			return $this->hasComments;
252
		}
253
254
		if ($this->comment != "") {
255
			$this->hasComments = true;
256
			$this->hasCommentsResolved = true;
257
258
			return true;
259
		}
260
261
		$commentsQuery = $this->dbObject->prepare("SELECT COUNT(*) AS num FROM comment WHERE request = :id;");
262
		$commentsQuery->bindValue(":id", $this->id);
263
264
		$commentsQuery->execute();
265
266
		$this->hasComments = ($commentsQuery->fetchColumn() != 0);
267
		$this->hasCommentsResolved = true;
268
269
		return $this->hasComments;
270
	}
271
272
	/**
273
	 * @return string
274
	 */
275
	public function getEmailConfirm()
276
	{
277
		return $this->emailconfirm;
278
	}
279
280
	/**
281
	 * @param string $emailconfirm
282
	 */
283
	public function setEmailConfirm($emailconfirm)
284
	{
285
		$this->emailconfirm = $emailconfirm;
286
	}
287
288
	public function generateEmailConfirmationHash()
289
	{
290
		$this->emailconfirm = bin2hex(openssl_random_pseudo_bytes(16));
291
	}
292
293
	/**
294
	 * @return string|null
295
	 */
296
	public function getEmail()
297
	{
298
		return $this->email;
299
	}
300
301
	/**
302
	 * @param string|null $email
303
	 */
304
	public function setEmail($email)
305
	{
306
		$this->email = $email;
307
	}
308
309
	/**
310
	 * @return string
311
	 * @throws Exception
312
	 */
313
	public function getClosureReason()
314
	{
315
		if ($this->status != 'Closed') {
316
			throw new Exception("Can't get closure reason for open request.");
317
		}
318
319
		$statement = $this->dbObject->prepare(<<<SQL
320
SELECT closes.mail_desc
321
FROM log
322
INNER JOIN closes ON log.action = closes.closes
323
WHERE log.objecttype = 'Request'
324
AND log.objectid = :requestId
325
AND log.action LIKE 'Closed%'
326
ORDER BY log.timestamp DESC
327
LIMIT 1;
328
SQL
329
		);
330
331
		$statement->bindValue(":requestId", $this->id);
332
		$statement->execute();
333
		$reason = $statement->fetchColumn();
334
335
		return $reason;
336
	}
337
338
	/**
339
	 * Gets a value indicating whether the request was closed as created or not.
340
	 */
341
	public function getWasCreated()
342
	{
343
		if ($this->status != 'Closed') {
344
			throw new Exception("Can't get closure reason for open request.");
345
		}
346
347
		$statement = $this->dbObject->prepare(<<<SQL
348
SELECT emailtemplate.oncreated, log.action
349
FROM log
350
LEFT JOIN emailtemplate ON CONCAT('Closed ', emailtemplate.id) = log.action
351
WHERE log.objecttype = 'Request'
352
AND log.objectid = :requestId
353
AND log.action LIKE 'Closed%'
354
ORDER BY log.timestamp DESC
355
LIMIT 1;
356
SQL
357
		);
358
359
		$statement->bindValue(":requestId", $this->id);
360
		$statement->execute();
361
		$onCreated = $statement->fetchColumn(0);
362
		$logAction = $statement->fetchColumn(1);
363
		$statement->closeCursor();
364
365
		if ($onCreated === null) {
366
			return $logAction === "Closed custom-y";
367
		}
368
369
		return (bool)$onCreated;
370
	}
371
372
	/**
373
	 * @return DateTime
374
	 */
375
	public function getClosureDate()
376
	{
377
		$logQuery = $this->dbObject->prepare(<<<SQL
378
SELECT timestamp FROM log
379
WHERE objectid = :request AND objecttype = 'Request' AND action LIKE 'Closed%'
380
ORDER BY timestamp DESC LIMIT 1;
381
SQL
382
		);
383
		$logQuery->bindValue(":request", $this->getId());
384
		$logQuery->execute();
385
		$logTime = $logQuery->fetchColumn();
386
		$logQuery->closeCursor();
387
388
		return new DateTime($logTime);
389
	}
390
}
391