Completed
Pull Request — master (#551)
by Maxence
02:49
created

Member::setJoined()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
6
/**
7
 * Circles - Bring cloud-users closer together.
8
 *
9
 * This file is licensed under the Affero General Public License version 3 or
10
 * later. See the COPYING file.
11
 *
12
 * @author Maxence Lange <[email protected]>
13
 * @copyright 2021
14
 * @license GNU AGPL version 3 or any later version
15
 *
16
 * This program is free software: you can redistribute it and/or modify
17
 * it under the terms of the GNU Affero General Public License as
18
 * published by the Free Software Foundation, either version 3 of the
19
 * License, or (at your option) any later version.
20
 *
21
 * This program is distributed in the hope that it will be useful,
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 * GNU Affero General Public License for more details.
25
 *
26
 * You should have received a copy of the GNU Affero General Public License
27
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
28
 *
29
 */
30
31
32
namespace OCA\Circles\Model;
33
34
use daita\MySmallPhpTools\Db\Nextcloud\nc21\INC21QueryRow;
35
use daita\MySmallPhpTools\Exceptions\InvalidItemException;
36
use daita\MySmallPhpTools\IDeserializable;
37
use daita\MySmallPhpTools\Traits\Nextcloud\nc21\TNC21Deserialize;
38
use daita\MySmallPhpTools\Traits\TArrayTools;
39
use DateTime;
40
use JsonSerializable;
41
use OCA\Circles\Exceptions\MemberLevelException;
42
use OCA\Circles\Exceptions\MemberNotFoundException;
43
use OCA\Circles\Exceptions\UserTypeNotFoundException;
44
use OCA\Circles\IFederatedUser;
45
46
47
/**
48
 * Class Member
49
 *
50
 * @package OCA\Circles\Model
51
 */
52
class Member extends ManagedModel implements IFederatedUser, IDeserializable, INC21QueryRow, JsonSerializable {
53
54
55
	use TArrayTools;
56
	use TNC21Deserialize;
57
58
59
	const LEVEL_NONE = 0;
60
	const LEVEL_MEMBER = 1;
61
	const LEVEL_MODERATOR = 4;
62
	const LEVEL_ADMIN = 8;
63
	const LEVEL_OWNER = 9;
64
65
	const TYPE_CIRCLE = 16;
66
	const TYPE_SINGLE = 8;
67
	const TYPE_USER = 1;
68
	const TYPE_GROUP = 2;
69
	const TYPE_MAIL = 3;
70
	const TYPE_CONTACT = 4;
71
72
	const STATUS_NONMEMBER = 'Unknown';
73
	const STATUS_INVITED = 'Invited';
74
	const STATUS_REQUEST = 'Requesting';
75
	const STATUS_MEMBER = 'Member';
76
	const STATUS_BLOCKED = 'Blocked';
77
	const STATUS_KICKED = 'Kicked';
78
79
80
	public static $DEF_LEVEL = [
81
		1 => 'Member',
82
		4 => 'Moderator',
83
		8 => 'Admin',
84
		9 => 'Owner'
85
	];
86
87
	public static $DEF_TYPE = [
88
		1  => 'user',
89
		16 => 'circle',
90
		8  => 'single',
91
		3  => 'mail',
92
		4  => 'contact',
93
	];
94
95
	/** @var string */
96
	private $id = '';
97
98
	/** @var string */
99
	private $circleId = '';
100
101
	/** @var string */
102
	private $singleId = '';
103
104
	/** @var string */
105
	private $userId = '';
106
107
	/** @var int */
108
	private $userType = self::TYPE_USER;
109
110
	/** @var string */
111
	private $instance = '';
112
113
	/** @var int */
114
	private $level = 0;
115
116
	/** @var string */
117
	private $status = 'Unknown';
118
119
	/** @var string */
120
	private $note = '';
121
122
	/** @var string */
123
	private $cachedName = '';
124
125
	/** @var int */
126
	private $cachedUpdate = 0;
127
128
	/** @var string */
129
	private $contactId = '';
130
131
	/** @var string */
132
	private $contactMeta = '';
133
134
	/** @var Circle */
135
	private $circle;
136
137
138
	/** @var int */
139
	private $joined = 0;
140
141
142
	/**
143
	 * Member constructor.
144
	 */
145
	public function __construct() {
146
	}
147
148
149
	/**
150
	 * @param string $id
151
	 *
152
	 * @return $this
153
	 */
154
	public function setId(string $id): self {
155
		$this->id = $id;
156
157
		return $this;
158
	}
159
160
	/**
161
	 * @return string
162
	 */
163
	public function getId(): string {
164
		return $this->id;
165
	}
166
167
168
	/**
169
	 * @param string $circleId
170
	 *
171
	 * @return Member
172
	 */
173
	public function setCircleId(string $circleId): self {
174
		$this->circleId = $circleId;
175
176
		return $this;
177
	}
178
179
	/**
180
	 * @return string
181
	 */
182
	public function getCircleId(): string {
183
		return $this->circleId;
184
	}
185
186
187
	/**
188
	 * This should replace user_id, user_type and instance; and will use the data from Circle with
189
	 * Config=CFG_SINGLE
190
	 *
191
	 * @param string $singleId
192
	 *
193
	 * @return $this
194
	 */
195
	public function setSingleId(string $singleId): self {
196
		$this->singleId = $singleId;
197
198
		return $this;
199
	}
200
201
	/**
202
	 * @return string
203
	 */
204
	public function getSingleId(): string {
205
		return $this->singleId;
206
	}
207
208
209
	/**
210
	 * @param string $userId
211
	 *
212
	 * @return Member
213
	 */
214
	public function setUserId(string $userId): self {
215
		$this->userId = $userId;
216
217
		return $this;
218
	}
219
220
	/**
221
	 * @return string
222
	 */
223
	public function getUserId(): string {
224
		return $this->userId;
225
	}
226
227
228
	/**
229
	 * @param int $userType
230
	 *
231
	 * @return Member
232
	 */
233
	public function setUserType(int $userType): self {
234
		$this->userType = $userType;
235
236
		return $this;
237
	}
238
239
	/**
240
	 * @return int
241
	 */
242
	public function getUserType(): int {
243
		return $this->userType;
244
	}
245
246
247
	/**
248
	 * @param string $instance
249
	 *
250
	 * @return Member
251
	 */
252
	public function setInstance(string $instance): self {
253
		$this->instance = $instance;
254
255
		return $this;
256
	}
257
258
	/**
259
	 * @return string
260
	 */
261
	public function getInstance(): string {
262
		return $this->instance;
263
	}
264
265
266
	/**
267
	 * @param int $level
268
	 *
269
	 * @return Member
270
	 */
271
	public function setLevel(int $level): self {
272
		$this->level = $level;
273
274
		return $this;
275
	}
276
277
	/**
278
	 * @return int
279
	 */
280
	public function getLevel(): int {
281
		return $this->level;
282
	}
283
284
285
	/**
286
	 * @param string $status
287
	 *
288
	 * @return Member
289
	 */
290
	public function setStatus(string $status): self {
291
		$this->status = $status;
292
293
		return $this;
294
	}
295
296
	/**
297
	 * @return string
298
	 */
299
	public function getStatus(): string {
300
		return $this->status;
301
	}
302
303
304
	/**
305
	 * @param string $note
306
	 *
307
	 * @return Member
308
	 */
309
	public function setNote(string $note): self {
310
		$this->note = $note;
311
312
		return $this;
313
	}
314
315
	/**
316
	 * @return string
317
	 */
318
	public function getNote(): string {
319
		return $this->note;
320
	}
321
322
323
	/**
324
	 * @param string $cachedName
325
	 *
326
	 * @return Member
327
	 */
328
	public function setCachedName(string $cachedName): self {
329
		$this->cachedName = $cachedName;
330
331
		return $this;
332
	}
333
334
335
	/**
336
	 * @param int $cachedUpdate
337
	 *
338
	 * @return Member
339
	 */
340
	public function setCachedUpdate(int $cachedUpdate): self {
341
		$this->cachedUpdate = $cachedUpdate;
342
343
		return $this;
344
	}
345
346
	/**
347
	 * @return int
348
	 */
349
	public function getCachedUpdate(): int {
350
		return $this->cachedUpdate;
351
	}
352
353
354
	/**
355
	 * @return string
356
	 */
357
	public function getCachedName(): string {
358
		return $this->cachedName;
359
	}
360
361
362
	/**
363
	 * @param string $contactId
364
	 *
365
	 * @return Member
366
	 */
367
	public function setContactId(string $contactId): self {
368
		$this->contactId = $contactId;
369
370
		return $this;
371
	}
372
373
	/**
374
	 * @return string
375
	 */
376
	public function getContactId(): string {
377
		return $this->contactId;
378
	}
379
380
381
	/**
382
	 * @param string $contactMeta
383
	 *
384
	 * @return Member
385
	 */
386
	public function setContactMeta(string $contactMeta): self {
387
		$this->contactMeta = $contactMeta;
388
389
		return $this;
390
	}
391
392
	/**
393
	 * @return string
394
	 */
395
	public function getContactMeta(): string {
396
		return $this->contactMeta;
397
	}
398
399
400
	/**
401
	 * @param Circle $circle
402
	 *
403
	 * @return self
404
	 */
405
	public function setCircle(Circle $circle): self {
406
		$this->circle = $circle;
407
408
		return $this;
409
	}
410
411
	/**
412
	 * @return Circle
413
	 */
414
	public function getCircle(): Circle {
415
		return $this->circle;
416
	}
417
418
	/**
419
	 * @return bool
420
	 */
421
	public function hasCircle(): bool {
422
		return (!is_null($this->circle));
423
	}
424
425
426
	/**
427
	 * @param int $joined
428
	 *
429
	 * @return Member
430
	 */
431
	public function setJoined(int $joined): self {
432
		$this->joined = $joined;
433
434
		return $this;
435
	}
436
437
	/**
438
	 * @return int
439
	 */
440
	public function getJoined(): int {
441
		return $this->joined;
442
	}
443
444
445
	/**
446
	 * @return bool
447
	 */
448
	public function isMember(): bool {
449
		return ($this->level > 0);
450
	}
451
452
453
	/**
454
	 * @param Member $member
455
	 * @param bool $full
456
	 *
457
	 * @return bool
458
	 */
459
	public function compareWith(Member $member, bool $full = true): bool {
460
		if ($this->getId() !== $member->getId()
461
			|| $this->getCircleId() !== $member->getCircleId()
462
			|| $this->getSingleId() !== $member->getSingleId()
463
			|| $this->getUserId() !== $member->getUserId()
464
			|| $this->getUserType() <> $member->getUserType()
465
			|| $this->getInstance() !== $member->getInstance()) {
466
			return false;
467
		}
468
469
		if ($full
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return !($full && ($this...$member->getStatus()));.
Loading history...
470
			&& ($this->getLevel() <> $member->getLevel()
471
				|| $this->getStatus() !== $member->getStatus())) {
472
			return false;
473
		}
474
475
		return true;
476
	}
477
478
479
	/**
480
	 * @param array $data
481
	 *
482
	 * @return $this
483
	 * @throws InvalidItemException
484
	 */
485
	public function import(array $data): IDeserializable {
486
		if ($this->get('user_id', $data) === '') {
487
			throw new InvalidItemException();
488
		}
489
490
		$this->setId($this->get('id', $data));
491
		$this->setCircleId($this->get('circle_id', $data));
492
		$this->setSingleId($this->get('single_id', $data));
493
		$this->setUserId($this->get('user_id', $data));
494
		$this->setUserType($this->getInt('user_type', $data));
495
		$this->setInstance($this->get('instance', $data));
496
		$this->setLevel($this->getInt('level', $data));
497
		$this->setStatus($this->get('status', $data));
498
		$this->setCachedName($this->get('cached_name', $data));
499
		$this->setCachedUpdate($this->getInt('cached_update', $data));
500
		$this->setNote($this->get('note', $data));
501
		$this->setContactId($this->get('contact_id', $data));
502
		$this->setContactMeta($this->get('contact_meta', $data));
503
		$this->setJoined($this->getInt('joined', $data));
504
505
		try {
506
			/** @var Circle $circle */
507
			$circle = $this->deserialize($this->getArray('circle', $data), Circle::class);
508
			$this->setCircle($circle);
509
		} catch (InvalidItemException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
510
		}
511
512
		return $this;
513
	}
514
515
516
	/**
517
	 * @return string[]
518
	 */
519
	public function jsonSerialize(): array {
520
		$arr = array_filter(
521
			[
522
				'id'            => $this->getId(),
523
				'circle_id'     => $this->getCircleId(),
524
				'single_id'     => $this->getSingleId(),
525
				'user_id'       => $this->getUserId(),
526
				'user_type'     => $this->getUserType(),
527
				'instance'      => $this->getInstance(),
528
				'level'         => $this->getLevel(),
529
				'status'        => $this->getStatus(),
530
				'cached_name'   => $this->getCachedName(),
531
				'cached_update' => $this->getCachedUpdate(),
532
				'note'          => $this->getNote(),
533
				'contact_id'    => $this->getContactId(),
534
				'contact_meta'  => $this->getContactMeta(),
535
				'joined'        => $this->getJoined()
536
			]
537
		);
538
539
		if ($this->hasCircle()) {
540
			$arr['circle'] = $this->getCircle();
541
		}
542
543
		return $arr;
544
	}
545
546
547
	/**
548
	 * @param array $data
549
	 * @param string $prefix
550
	 *
551
	 * @return INC21QueryRow
552
	 * @throws MemberNotFoundException
553
	 */
554
	public function importFromDatabase(array $data, string $prefix = ''): INC21QueryRow {
555
		if (!array_key_exists($prefix . 'member_id', $data)) {
556
			throw new MemberNotFoundException();
557
		}
558
559
		$this->setId($this->get($prefix . 'member_id', $data));
560
		$this->setCircleId($this->get($prefix . 'circle_id', $data));
561
		$this->setSingleId($this->get($prefix . 'single_id', $data));
562
		$this->setUserId($this->get($prefix . 'user_id', $data));
563
		$this->setUserType($this->getInt($prefix . 'user_type', $data));
564
		$this->setInstance($this->get($prefix . 'instance', $data));
565
		$this->setLevel($this->getInt($prefix . 'level', $data));
566
		$this->setStatus($this->get($prefix . 'status', $data));
567
		$this->setCachedName($this->get($prefix . 'cached_name', $data));
568
		$this->setNote($this->get($prefix . 'note', $data));
569
		$this->setContactId($this->get($prefix . 'contact_id', $data));
570
		$this->setContactMeta($this->get($prefix . 'contact_meta', $data));
571
572
		$cachedUpdate = $this->get($prefix . 'cached_update', $data);
573
		if ($cachedUpdate !== '') {
574
			$this->setCachedUpdate(DateTime::createFromFormat('Y-m-d H:i:s', $cachedUpdate)->getTimestamp());
575
		}
576
577
		$joined = $this->get($prefix . 'joined', $data);
578
		if ($joined !== '') {
579
			$this->setJoined(DateTime::createFromFormat('Y-m-d H:i:s', $joined)->getTimestamp());
580
		}
581
582
		if ($this->getInstance() === '') {
583
			$this->setInstance($this->get('_params.local', $data));
584
		}
585
586
		if ($prefix === '') {
587
			$this->getManager()->importCircleFromDatabase($this, $data);
588
		}
589
590
		return $this;
591
	}
592
593
594
	/**
595
	 * @param string $levelString
596
	 *
597
	 * @return int
598
	 * @throws MemberLevelException
599
	 */
600 View Code Duplication
	public static function parseLevelString(string $levelString): int {
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...
601
		$levelString = ucfirst(strtolower($levelString));
602
		$level = array_search($levelString, Member::$DEF_LEVEL);
603
604
		if (!$level) {
605
			$all = implode(', ', array_values(self::$DEF_LEVEL));
606
			throw new MemberLevelException('Available levels: ' . $all);
607
		}
608
609
		return (int)$level;
610
	}
611
612
	/**
613
	 * @param string $typeString
614
	 *
615
	 * @return int
616
	 * @throws UserTypeNotFoundException
617
	 */
618 View Code Duplication
	public static function parseTypeString(string $typeString): int {
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...
619
		$typeString = strtolower($typeString);
620
		$type = array_search($typeString, Member::$DEF_TYPE);
621
622
		if (!$type) {
623
			$all = implode(', ', array_values(self::$DEF_TYPE));
624
			throw new UserTypeNotFoundException('Available types: ' . $all);
625
		}
626
627
		return (int)$type;
628
	}
629
630
}
631
632