Completed
Push — master ( cde7f5...cd12e2 )
by Joas
14:47
created

Comment::setParentId()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Arthur Schiwon <[email protected]>
6
 * @author Joas Schilling <[email protected]>
7
 * @author Thomas Müller <[email protected]>
8
 *
9
 * @license AGPL-3.0
10
 *
11
 * This code is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License, version 3,
13
 * as published by the Free Software Foundation.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU Affero General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Affero General Public License, version 3,
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
22
 *
23
 */
24
namespace OC\Comments;
25
26
use OCP\Comments\IComment;
27
use OCP\Comments\IllegalIDChangeException;
28
use OCP\Comments\MessageTooLongException;
29
30
class Comment implements IComment {
31
32
	protected $data = [
33
		'id'              => '',
34
		'parentId'        => '0',
35
		'topmostParentId' => '0',
36
		'childrenCount'   => '0',
37
		'message'         => '',
38
		'verb'            => '',
39
		'actorType'       => '',
40
		'actorId'         => '',
41
		'objectType'      => '',
42
		'objectId'        => '',
43
		'creationDT'      => null,
44
		'latestChildDT'   => null,
45
	];
46
47
	/**
48
	 * Comment constructor.
49
	 *
50
	 * @param array $data	optional, array with keys according to column names from
51
	 * 						the comments database scheme
52
	 */
53
	public function __construct(array $data = null) {
54
		if(is_array($data)) {
55
			$this->fromArray($data);
56
		}
57
	}
58
59
	/**
60
	 * returns the ID of the comment
61
	 *
62
	 * It may return an empty string, if the comment was not stored.
63
	 * It is expected that the concrete Comment implementation gives an ID
64
	 * by itself (e.g. after saving).
65
	 *
66
	 * @return string
67
	 * @since 9.0.0
68
	 */
69
	public function getId() {
70
		return $this->data['id'];
71
	}
72
73
	/**
74
	 * sets the ID of the comment and returns itself
75
	 *
76
	 * It is only allowed to set the ID only, if the current id is an empty
77
	 * string (which means it is not stored in a database, storage or whatever
78
	 * the concrete implementation does), or vice versa. Changing a given ID is
79
	 * not permitted and must result in an IllegalIDChangeException.
80
	 *
81
	 * @param string $id
82
	 * @return IComment
83
	 * @throws IllegalIDChangeException
84
	 * @since 9.0.0
85
	 */
86
	public function setId($id) {
87
		if(!is_string($id)) {
88
			throw new \InvalidArgumentException('String expected.');
89
		}
90
91
		$id = trim($id);
92
		if($this->data['id'] === '' || ($this->data['id'] !== '' && $id === '')) {
93
			$this->data['id'] = $id;
94
			return $this;
95
		}
96
97
		throw new IllegalIDChangeException('Not allowed to assign a new ID to an already saved comment.');
98
	}
99
100
	/**
101
	 * returns the parent ID of the comment
102
	 *
103
	 * @return string
104
	 * @since 9.0.0
105
	 */
106
	public function getParentId() {
107
		return $this->data['parentId'];
108
	}
109
110
	/**
111
	 * sets the parent ID and returns itself
112
	 *
113
	 * @param string $parentId
114
	 * @return IComment
115
	 * @since 9.0.0
116
	 */
117
	public function setParentId($parentId) {
118
		if(!is_string($parentId)) {
119
			throw new \InvalidArgumentException('String expected.');
120
		}
121
		$this->data['parentId'] = trim($parentId);
122
		return $this;
123
	}
124
125
	/**
126
	 * returns the topmost parent ID of the comment
127
	 *
128
	 * @return string
129
	 * @since 9.0.0
130
	 */
131
	public function getTopmostParentId() {
132
		return $this->data['topmostParentId'];
133
	}
134
135
136
	/**
137
	 * sets the topmost parent ID and returns itself
138
	 *
139
	 * @param string $id
140
	 * @return IComment
141
	 * @since 9.0.0
142
	 */
143 View Code Duplication
	public function setTopmostParentId($id) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
144
		if(!is_string($id)) {
145
			throw new \InvalidArgumentException('String expected.');
146
		}
147
		$this->data['topmostParentId'] = trim($id);
148
		return $this;
149
	}
150
151
	/**
152
	 * returns the number of children
153
	 *
154
	 * @return int
155
	 * @since 9.0.0
156
	 */
157
	public function getChildrenCount() {
158
		return $this->data['childrenCount'];
159
	}
160
161
	/**
162
	 * sets the number of children
163
	 *
164
	 * @param int $count
165
	 * @return IComment
166
	 * @since 9.0.0
167
	 */
168
	public function setChildrenCount($count) {
169
		if(!is_int($count)) {
170
			throw new \InvalidArgumentException('Integer expected.');
171
		}
172
		$this->data['childrenCount'] = $count;
173
		return $this;
174
	}
175
176
	/**
177
	 * returns the message of the comment
178
	 *
179
	 * @return string
180
	 * @since 9.0.0
181
	 */
182
	public function getMessage() {
183
		return $this->data['message'];
184
	}
185
186
	/**
187
	 * sets the message of the comment and returns itself
188
	 *
189
	 * @param string $message
190
	 * @return IComment
191
	 * @throws MessageTooLongException
192
	 * @since 9.0.0
193
	 */
194
	public function setMessage($message) {
195
		if(!is_string($message)) {
196
			throw new \InvalidArgumentException('String expected.');
197
		}
198
		$message = trim($message);
199
		if(mb_strlen($message, 'UTF-8') > IComment::MAX_MESSAGE_LENGTH) {
200
			throw new MessageTooLongException('Comment message must not exceed ' . IComment::MAX_MESSAGE_LENGTH . ' characters');
201
		}
202
		$this->data['message'] = $message;
203
		return $this;
204
	}
205
206
	/**
207
	 * returns an array containing mentions that are included in the comment
208
	 *
209
	 * @return array each mention provides a 'type' and an 'id', see example below
210
	 * @since 9.2.0
211
	 *
212
	 * The return array looks like:
213
	 * [
214
	 *   [
215
	 *     'type' => 'user',
216
	 *     'id' => 'citizen4'
217
	 *   ],
218
	 *   [
219
	 *     'type' => 'group',
220
	 *     'id' => 'media'
221
	 *   ],
222
	 *   …
223
	 * ]
224
	 *
225
	 */
226
	public function getMentions() {
227
		$ok = preg_match_all('/\B@[a-z0-9_\-@\.\']+/i', $this->getMessage(), $mentions);
228
		if(!$ok || !isset($mentions[0]) || !is_array($mentions[0])) {
229
			return [];
230
		}
231
		$uids = array_unique($mentions[0]);
232
		$result = [];
233
		foreach ($uids as $uid) {
234
			// exclude author, no self-mentioning
235
			if($uid === '@' . $this->getActorId()) {
236
				continue;
237
			}
238
			$result[] = ['type' => 'user', 'id' => substr($uid, 1)];
239
		}
240
		return $result;
241
	}
242
243
	/**
244
	 * returns the verb of the comment
245
	 *
246
	 * @return string
247
	 * @since 9.0.0
248
	 */
249
	public function getVerb() {
250
		return $this->data['verb'];
251
	}
252
253
	/**
254
	 * sets the verb of the comment, e.g. 'comment' or 'like'
255
	 *
256
	 * @param string $verb
257
	 * @return IComment
258
	 * @since 9.0.0
259
	 */
260 View Code Duplication
	public function setVerb($verb) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
261
		if(!is_string($verb) || !trim($verb)) {
262
			throw new \InvalidArgumentException('Non-empty String expected.');
263
		}
264
		$this->data['verb'] = trim($verb);
265
		return $this;
266
	}
267
268
	/**
269
	 * returns the actor type
270
	 *
271
	 * @return string
272
	 * @since 9.0.0
273
	 */
274
	public function getActorType() {
275
		return $this->data['actorType'];
276
	}
277
278
	/**
279
	 * returns the actor ID
280
	 *
281
	 * @return string
282
	 * @since 9.0.0
283
	 */
284
	public function getActorId() {
285
		return $this->data['actorId'];
286
	}
287
288
	/**
289
	 * sets (overwrites) the actor type and id
290
	 *
291
	 * @param string $actorType e.g. 'users'
292
	 * @param string $actorId e.g. 'zombie234'
293
	 * @return IComment
294
	 * @since 9.0.0
295
	 */
296
	public function setActor($actorType, $actorId) {
297
		if(
298
		       !is_string($actorType) || !trim($actorType)
299
		    || !is_string($actorId)   || !trim($actorId)
300
		) {
301
			throw new \InvalidArgumentException('String expected.');
302
		}
303
		$this->data['actorType'] = trim($actorType);
304
		$this->data['actorId']   = trim($actorId);
305
		return $this;
306
	}
307
308
	/**
309
	 * returns the creation date of the comment.
310
	 *
311
	 * If not explicitly set, it shall default to the time of initialization.
312
	 *
313
	 * @return \DateTime
314
	 * @since 9.0.0
315
	 */
316
	public function getCreationDateTime() {
317
		return $this->data['creationDT'];
318
	}
319
320
	/**
321
	 * sets the creation date of the comment and returns itself
322
	 *
323
	 * @param \DateTime $timestamp
324
	 * @return IComment
325
	 * @since 9.0.0
326
	 */
327
	public function setCreationDateTime(\DateTime $timestamp) {
328
		$this->data['creationDT'] = $timestamp;
329
		return $this;
330
	}
331
332
	/**
333
	 * returns the DateTime of the most recent child, if set, otherwise null
334
	 *
335
	 * @return \DateTime|null
336
	 * @since 9.0.0
337
	 */
338
	public function getLatestChildDateTime() {
339
		return $this->data['latestChildDT'];
340
	}
341
342
	/**
343
	 * sets the date of the most recent child
344
	 *
345
	 * @param \DateTime $dateTime
346
	 * @return IComment
347
	 * @since 9.0.0
348
	 */
349
	public function setLatestChildDateTime(\DateTime $dateTime = null) {
350
		$this->data['latestChildDT'] = $dateTime;
351
		return $this;
352
	}
353
354
	/**
355
	 * returns the object type the comment is attached to
356
	 *
357
	 * @return string
358
	 * @since 9.0.0
359
	 */
360
	public function getObjectType() {
361
		return $this->data['objectType'];
362
	}
363
364
	/**
365
	 * returns the object id the comment is attached to
366
	 *
367
	 * @return string
368
	 * @since 9.0.0
369
	 */
370
	public function getObjectId() {
371
		return $this->data['objectId'];
372
	}
373
374
	/**
375
	 * sets (overwrites) the object of the comment
376
	 *
377
	 * @param string $objectType e.g. 'files'
378
	 * @param string $objectId e.g. '16435'
379
	 * @return IComment
380
	 * @since 9.0.0
381
	 */
382
	public function setObject($objectType, $objectId) {
383
		if(
384
		       !is_string($objectType) || !trim($objectType)
385
		    || !is_string($objectId)   || !trim($objectId)
386
		) {
387
			throw new \InvalidArgumentException('String expected.');
388
		}
389
		$this->data['objectType'] = trim($objectType);
390
		$this->data['objectId']   = trim($objectId);
391
		return $this;
392
	}
393
394
	/**
395
	 * sets the comment data based on an array with keys as taken from the
396
	 * database.
397
	 *
398
	 * @param array $data
399
	 * @return IComment
400
	 */
401
	protected function fromArray($data) {
402
		foreach(array_keys($data) as $key) {
403
			// translate DB keys to internal setter names
404
			$setter = 'set' . implode('', array_map('ucfirst', explode('_', $key)));
405
			$setter = str_replace('Timestamp', 'DateTime', $setter);
406
407
			if(method_exists($this, $setter)) {
408
				$this->$setter($data[$key]);
409
			}
410
		}
411
412
		foreach(['actor', 'object'] as $role) {
413
			if(isset($data[$role . '_type']) && isset($data[$role . '_id'])) {
414
				$setter = 'set' . ucfirst($role);
415
				$this->$setter($data[$role . '_type'], $data[$role . '_id']);
416
			}
417
		}
418
419
		return $this;
420
	}
421
}
422