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

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