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

Circle::setId()   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\Model\Nextcloud\nc21\INC21Convert;
37
use daita\MySmallPhpTools\Traits\Nextcloud\nc21\TNC21Convert;
38
use daita\MySmallPhpTools\Traits\TArrayTools;
39
use DateTime;
40
use JsonSerializable;
41
use OCA\Circles\Exceptions\OwnerNotFoundException;
42
43
44
/**
45
 * Class Circle
46
 *
47
 * ** examples of use of bitwise flags for members management:
48
 *      CFG_OPEN, CFG_REQUEST, CFG_INVITE, CFG_FRIEND
49
 *
50
 * - CFG_OPEN                             => everyone can enter. moderator can add members.
51
 * - CFG_OPEN | CFG_REQUEST               => anyone can initiate a request to join the circle, moderator can
52
 *                                           add members
53
 * - CFG_OPEN | CFG_INVITE                => every one can enter, moderator must send invitation.
54
 * - CFG_OPEN | CFG_INVITE | CFG_REQUEST  => every one send a request, moderator must send invitation.
55
 * - CFG_OPEN | CFG_FRIEND                => useless
56
 * - CFG_OPEN | CFG_FRIEND | *            => useless
57
 *
58
 * - CFG_CIRCLE                           => no one can enter, moderator can add members.
59
 *                                           default config, this is only for code readability.
60
 * - CFG_INVITE                           => no one can enter, moderator must send invitation.
61
 * - CFG_FRIEND                           => no one can enter, but all members can add new member.
62
 * - CFG_REQUEST                          => useless (use CFG_OPEN | CFG_REQUEST)
63
 * - CFG_FRIEND | CFG_REQUEST             => no one can join the circle, but all members can request a
64
 *                                           moderator to accept new member
65
 * - CFG_FRIEND | CFG_INVITE              => no one can join the circle, but all members can add new member.
66
 *                                           An invitation will be generated
67
 * - CFG_FRIEND | CFG_INVITE | CFG_REQUEST  => no one can join the circle, but all members can request a
68
 *                                             moderator to accept new member. An invitation will be generated
69
 *
70
 * @package OCA\Circles\Model
71
 */
72
class Circle extends ManagedModel implements INC21Convert, INC21QueryRow, JsonSerializable {
73
74
75
	use TArrayTools;
76
	use TNC21Convert;
77
78
79
	// specific value
80
	const CFG_CIRCLE = 0;        // only for code readability. Circle is locked by default.
81
	const CFG_SINGLE = 1;        // Circle with only one single member.
82
	const CFG_PERSONAL = 2;      // Personal circle, only the owner can see it.
83
84
	// bitwise
85
	const CFG_VISIBLE = 8;        // Visible to everyone, if not visible, people have to know its name to be able to find it
86
	const CFG_OPEN = 16;          // Circle is open, people can join
87
	const CFG_INVITE = 32;        // Adding a member generate an invitation that needs to be accepted
88
	const CFG_REQUEST = 64;       // Request to join Circles needs to be confirmed by a moderator
89
	const CFG_FRIEND = 128;       // Members of the circle can invite their friends
90
	const CFG_PROTECTED = 256;    // Password protected to join/request
91
	const CFG_NO_OWNER = 512;     // no owner, only members
92
	const CFG_HIDDEN = 1024;      // Fully hidden, only backend Circles
93
	const CFG_ROOT = 2048;        // Circle cannot be inside another Circle
94
	const CFG_FEDERATED = 4096;   // Federated
95
96
	const ID_LENGTH = 14;
97
98
	static $DEF = [
99
		1    => 'S|Single',
100
		2    => 'P|Personal',
101
		8    => 'V|Visible',
102
		16   => 'O|Open',
103
		32   => 'I|Invite',
104
		64   => 'JR|Join Request',
105
		128  => 'F|Friends',
106
		256  => 'PP|Password Protected',
107
		512  => 'NO|No Owner',
108
		1024 => 'H|Hidden',
109
		2048 => 'T|Root',
110
		4096 => 'F|Federated'
111
	];
112
113
114
	/** @var string */
115
	private $id = '';
116
117
	/** @var int */
118
	private $config = 0;
119
120
	/** @var int */
121
	private $type = 0;
122
123
	/** @var string */
124
	private $name = '';
125
126
	/** @var string */
127
	private $altName = '';
128
129
	/** @var Member */
130
	private $owner;
131
132
	/** @var array */
133
	private $members = [];
134
135
	/** @var Member */
136
	private $viewer;
137
138
	/** @var array */
139
	private $settings = [];
140
141
	/** @var string */
142
	private $description = '';
143
144
	/** @var int */
145
	private $contactAddressBook = 0;
146
147
	/** @var string */
148
	private $contactGroupName = '';
149
150
	/** @var string */
151
	private $instance = '';
152
153
//	/** @var bool */
154
//	private $hidden = false;
155
156
	/** @var int */
157
	private $creation = 0;
158
159
160
	/** @var Circle[] */
161
	private $memberOf = null;
162
163
	private $completeJson = false;
164
165
166
	/**
167
	 * Circle constructor.
168
	 */
169
	public function __construct() {
170
	}
171
172
	/**
173
	 * @param string $id
174
	 *
175
	 * @return self
176
	 */
177
	public function setId(string $id): self {
178
		$this->id = $id;
179
180
		return $this;
181
	}
182
183
	/**
184
	 * @return string
185
	 */
186
	public function getId(): string {
187
		return $this->id;
188
	}
189
190
191
	/**
192
	 * @param int $config
193
	 *
194
	 * @return self
195
	 */
196
	public function setConfig(int $config): self {
197
		$this->config = $config;
198
199
//		$this->hidden = false;
200
//		foreach (array_keys(self::$DEF) as $def) {
201
//			if ($this->isType($def) && substr(self::$DEF[$def], 0, 1) === '*') {
202
//				$this->setHidden(true);
203
//				break;
204
//			}
205
//		}
206
207
		return $this;
208
	}
209
210
	/**
211
	 * @return int
212
	 */
213
	public function getConfig(): int {
214
		return $this->config;
215
	}
216
217
	/**
218
	 * @param int $flag
219
	 *
220
	 * @return bool
221
	 */
222
	public function isConfig(int $flag): bool {
223
		return (($this->getConfig() & $flag) !== 0);
224
	}
225
226
227
	/**
228
	 * @param int $type
229
	 *
230
	 * @deprecated
231
	 */
232
	public function setType(int $type): void {
233
		$this->type = $type;
234
	}
235
236
	/**
237
	 * @return int
238
	 * @deprecated
239
	 */
240
	public function getType(): int {
241
		return $this->type;
242
	}
243
244
245
	/**
246
	 * @param string $name
247
	 *
248
	 * @return self
249
	 */
250
	public function setName(string $name): self {
251
		$this->name = $name;
252
253
		return $this;
254
	}
255
256
	/**
257
	 * @return string
258
	 */
259
	public function getName(): string {
260
		return $this->name;
261
	}
262
263
264
	/**
265
	 * @param string $altName
266
	 *
267
	 * @return self
268
	 */
269
	public function setAltName(string $altName): self {
270
		$this->altName = $altName;
271
272
		return $this;
273
	}
274
275
	/**
276
	 * @return string
277
	 */
278
	public function getAltName(): string {
279
		return $this->altName;
280
	}
281
282
283
	/**
284
	 * @param Member $owner
285
	 */
286
	public function setOwner(Member $owner): void {
287
		$this->owner = $owner;
288
	}
289
290
	/**
291
	 * @return Member
292
	 */
293
	public function getOwner(): Member {
294
		return $this->owner;
295
	}
296
297
	/**
298
	 * @return bool
299
	 */
300
	public function hasOwner(): bool {
301
		return ($this->owner !== null);
302
	}
303
304
305
	/**
306
	 * @param array $members
307
	 *
308
	 * @return self
309
	 */
310
	public function setMembers(array $members): self {
311
		$this->members = $members;
312
313
		return $this;
314
	}
315
316
	/**
317
	 * @return array
318
	 */
319
	public function getMembers(): array {
320
		if (empty($this->members)) {
321
			$this->getManager()->getMembers($this);
322
		}
323
324
		return $this->members;
325
	}
326
327
328
	/**
329
	 * @param Member $viewer
330
	 */
331
	public function setViewer(Member $viewer): void {
332
		$this->viewer = $viewer;
333
	}
334
335
	/**
336
	 * @return Member
337
	 */
338
	public function getViewer(): Member {
339
		return $this->viewer;
340
	}
341
342
	/**
343
	 * @return bool
344
	 */
345
	public function hasViewer(): bool {
346
		return ($this->viewer !== null);
347
	}
348
349
	/**
350
	 * @param string $instance
351
	 *
352
	 * @return Circle
353
	 */
354
	public function setInstance(string $instance): self {
355
		if ($this->isConfig(self::CFG_NO_OWNER)) {
356
			$this->instance = $instance;
357
		}
358
359
		return $this;
360
	}
361
362
	/**
363
	 * @return string
364
	 * @throws OwnerNotFoundException
365
	 */
366
	public function getInstance(): string {
367
		if ($this->isConfig(self::CFG_NO_OWNER)) {
368
			return $this->instance;
369
		}
370
371
		if (!$this->hasOwner()) {
372
			throw new OwnerNotFoundException('circle has no owner, or not set to have no owner');
373
		}
374
375
		return $this->getOwner()->getInstance();
376
	}
377
378
379
	/**
380
	 * @param array $settings
381
	 *
382
	 * @return self
383
	 */
384
	public function setSettings(array $settings): self {
385
		$this->settings = $settings;
386
387
		return $this;
388
	}
389
390
	/**
391
	 * @return array
392
	 */
393
	public function getSettings(): array {
394
		return $this->settings;
395
	}
396
397
398
	/**
399
	 * @param string $description
400
	 *
401
	 * @return self
402
	 */
403
	public function setDescription(string $description): self {
404
		$this->description = $description;
405
406
		return $this;
407
	}
408
409
	/**
410
	 * @return string
411
	 */
412
	public function getDescription(): string {
413
		return $this->description;
414
	}
415
416
417
	/**
418
	 * @param int $contactAddressBook
419
	 *
420
	 * @return self
421
	 */
422
	public function setContactAddressBook(int $contactAddressBook): self {
423
		$this->contactAddressBook = $contactAddressBook;
424
425
		return $this;
426
	}
427
428
	/**
429
	 * @return int
430
	 */
431
	public function getContactAddressBook(): int {
432
		return $this->contactAddressBook;
433
	}
434
435
436
	/**
437
	 * @param string $contactGroupName
438
	 *
439
	 * @return self
440
	 */
441
	public function setContactGroupName(string $contactGroupName): self {
442
		$this->contactGroupName = $contactGroupName;
443
444
		return $this;
445
	}
446
447
	/**
448
	 * @return string
449
	 */
450
	public function getContactGroupName(): string {
451
		return $this->contactGroupName;
452
	}
453
454
455
//	/**
456
//	 * @param bool $hidden
457
//	 *
458
//	 * @return Circle
459
//	 */
460
//	public function setHidden(bool $hidden): self {
461
//		$this->hidden = $hidden;
462
//
463
//		return $this;
464
//	}
465
//
466
//	/**
467
//	 * @return bool
468
//	 */
469
//	public function isHidden(): bool {
470
//		return $this->hidden;
471
//	}
472
473
474
	/**
475
	 * @param array $memberOf
476
	 *
477
	 * @return $this
478
	 */
479
	public function setMemberOf(array $memberOf): self {
480
		$this->memberOf = $memberOf;
481
482
		return $this;
483
	}
484
485
	/**
486
	 * @return Circle[]
487
	 */
488
	public function memberOf(): array {
489
		if ($this->memberOf === null) {
490
			$this->getManager()->memberOf($this);
491
		}
492
493
		return $this->memberOf;
494
	}
495
496
497
	/**
498
	 * @param int $creation
499
	 *
500
	 * @return self
501
	 */
502
	public function setCreation(int $creation): self {
503
		$this->creation = $creation;
504
505
		return $this;
506
	}
507
508
	/**
509
	 * @return int
510
	 */
511
	public function getCreation(): int {
512
		return $this->creation;
513
	}
514
515
516
	/**
517
	 * @param array $data
518
	 *
519
	 * @return $this
520
	 */
521
	public function import(array $data): INC21Convert {
522
		$this->setId($this->get('id', $data))
523
			 ->setName($this->get('name', $data))
524
			 ->setAltName($this->get('alt_name', $data))
525
			 ->setConfig($this->getInt('config', $data))
526
			 ->setSettings($this->getArray('settings', $data))
527
//			 ->setContactAddressBook($this->get('contact_addressbook', $data))
528
//			 ->setContactGroupName($this->get('contact_groupname', $data))
529
			 ->setDescription($this->get('description', $data))
530
			 ->setCreation($this->getInt('creation', $data));
531
532
		try {
533
			/** @var Member $owner */
534
			$owner = $this->convert($this->getArray('owner', $data), Member::class);
535
			$this->setOwner($owner);
536
		} catch (InvalidItemException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
537
		}
538
539
		return $this;
540
	}
541
542
543
	/**
544
	 * @return array
545
	 */
546
	public function jsonSerialize(): array {
547
		$arr = [
548
			'id'          => $this->getId(),
549
			'name'        => $this->getName(),
550
			'alt_name'    => $this->getAltName(),
551
			'config'      => $this->getConfig(),
552
			'description' => $this->getDescription(),
553
			'settings'    => $this->getSettings(),
554
			//			'hidden'      => $this->isHidden(),
555
			'creation'    => $this->getCreation()
556
		];
557
558
		if ($this->hasOwner()) {
559
			$arr['owner'] = $this->getOwner();
560
		}
561
562
		if ($this->getManager()->isFullDetails()) {
563
			$arr['memberOf'] = $this->memberOf();
564
		}
565
566
		return array_filter($arr);
567
	}
568
569
570
	/**
571
	 * @param array $data
572
	 *
573
	 * @return INC21QueryRow
574
	 */
575
	public function importFromDatabase(array $data): INC21QueryRow {
576
		$this->setId($this->get('unique_id', $data))
577
			 ->setName($this->get('name', $data))
578
			 ->setAltName($this->get('alt_name', $data))
579
			 ->setConfig($this->getInt('config', $data))
580
			 ->setInstance($this->get('instance', $data))
581
			 ->setSettings($this->getArray('settings', $data))
582
			 ->setContactAddressBook($this->getInt('contact_addressbook', $data))
583
			 ->setContactGroupName($this->get('contact_groupname', $data))
584
			 ->setDescription($this->get('description', $data));
585
586
		$creation = $this->get('creation', $data);
587
		$this->setCreation(DateTime::createFromFormat('Y-m-d H:i:s', $creation)->getTimestamp());
588
589
		$this->getManager()->importOwnerFromDatabase($this, $data);
590
		$this->getManager()->importViewerFromDatabase($this, $data);
591
592
		return $this;
593
	}
594
595
596
	/**
597
	 * @param Circle $circle
598
	 *
599
	 * @return bool
600
	 */
601
	public function compareWith(Circle $circle): bool {
602
		if ($this->getId() !== $circle->getId()
603
			|| $this->getConfig() !== $circle->getConfig()) {
604
			return false;
605
		}
606
607
		if ($this->hasOwner()
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return !($this->hasOwner...$circle->getOwner())));.
Loading history...
608
			&& (!$circle->hasOwner()
609
				|| !$this->getOwner()->compareWith($circle->getOwner()))) {
610
			return false;
611
		}
612
613
		return true;
614
	}
615
616
}
617