Completed
Pull Request — master (#551)
by Maxence
01:54
created

Circle::jsonSerialize()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 9.568
c 0
b 0
f 0
cc 3
nc 4
nop 0
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 string $name
229
	 *
230
	 * @return self
231
	 */
232
	public function setName(string $name): self {
233
		$this->name = $name;
234
235
		return $this;
236
	}
237
238
	/**
239
	 * @return string
240
	 */
241
	public function getName(): string {
242
		return $this->name;
243
	}
244
245
246
	/**
247
	 * @param string $altName
248
	 *
249
	 * @return self
250
	 */
251
	public function setAltName(string $altName): self {
252
		$this->altName = $altName;
253
254
		return $this;
255
	}
256
257
	/**
258
	 * @return string
259
	 */
260
	public function getAltName(): string {
261
		return $this->altName;
262
	}
263
264
265
	/**
266
	 * @param Member $owner
267
	 *
268
	 * @return self
269
	 */
270
	public function setOwner(Member $owner): self {
271
		$this->owner = $owner;
272
273
		return $this;
274
	}
275
276
	/**
277
	 * @return Member
278
	 */
279
	public function getOwner(): Member {
280
		return $this->owner;
281
	}
282
283
	/**
284
	 * @return bool
285
	 */
286
	public function hasOwner(): bool {
287
		return ($this->owner !== null);
288
	}
289
290
291
	/**
292
	 * @param array $members
293
	 *
294
	 * @return self
295
	 */
296
	public function setMembers(array $members): self {
297
		$this->members = $members;
298
299
		return $this;
300
	}
301
302
	/**
303
	 * @return array
304
	 */
305
	public function getMembers(): array {
306
		if (empty($this->members)) {
307
			$this->getManager()->getMembers($this);
308
		}
309
310
		return $this->members;
311
	}
312
313
314
	/**
315
	 * @param Member $viewer
316
	 *
317
	 * @return Circle
318
	 */
319
	public function setViewer(Member $viewer): self {
320
		$this->viewer = $viewer;
321
322
		return $this;
323
	}
324
325
	/**
326
	 * @return Member
327
	 */
328
	public function getViewer(): Member {
329
		return $this->viewer;
330
	}
331
332
	/**
333
	 * @return bool
334
	 */
335
	public function hasViewer(): bool {
336
		return ($this->viewer !== null);
337
	}
338
339
	/**
340
	 * @param string $instance
341
	 *
342
	 * @return Circle
343
	 */
344
	public function setInstance(string $instance): self {
345
		if ($this->isConfig(self::CFG_NO_OWNER)) {
346
			$this->instance = $instance;
347
		}
348
349
		return $this;
350
	}
351
352
	/**
353
	 * @return string
354
	 * @throws OwnerNotFoundException
355
	 */
356
	public function getInstance(): string {
357
		if ($this->isConfig(self::CFG_NO_OWNER)) {
358
			return $this->instance;
359
		}
360
361
		if (!$this->hasOwner()) {
362
			throw new OwnerNotFoundException('circle has no owner, or not set to have no owner');
363
		}
364
365
		return $this->getOwner()->getInstance();
366
	}
367
368
369
	/**
370
	 * @param array $settings
371
	 *
372
	 * @return self
373
	 */
374
	public function setSettings(array $settings): self {
375
		$this->settings = $settings;
376
377
		return $this;
378
	}
379
380
	/**
381
	 * @return array
382
	 */
383
	public function getSettings(): array {
384
		return $this->settings;
385
	}
386
387
388
	/**
389
	 * @param string $description
390
	 *
391
	 * @return self
392
	 */
393
	public function setDescription(string $description): self {
394
		$this->description = $description;
395
396
		return $this;
397
	}
398
399
	/**
400
	 * @return string
401
	 */
402
	public function getDescription(): string {
403
		return $this->description;
404
	}
405
406
407
	/**
408
	 * @param int $contactAddressBook
409
	 *
410
	 * @return self
411
	 */
412
	public function setContactAddressBook(int $contactAddressBook): self {
413
		$this->contactAddressBook = $contactAddressBook;
414
415
		return $this;
416
	}
417
418
	/**
419
	 * @return int
420
	 */
421
	public function getContactAddressBook(): int {
422
		return $this->contactAddressBook;
423
	}
424
425
426
	/**
427
	 * @param string $contactGroupName
428
	 *
429
	 * @return self
430
	 */
431
	public function setContactGroupName(string $contactGroupName): self {
432
		$this->contactGroupName = $contactGroupName;
433
434
		return $this;
435
	}
436
437
	/**
438
	 * @return string
439
	 */
440
	public function getContactGroupName(): string {
441
		return $this->contactGroupName;
442
	}
443
444
445
//	/**
446
//	 * @param bool $hidden
447
//	 *
448
//	 * @return Circle
449
//	 */
450
//	public function setHidden(bool $hidden): self {
451
//		$this->hidden = $hidden;
452
//
453
//		return $this;
454
//	}
455
//
456
//	/**
457
//	 * @return bool
458
//	 */
459
//	public function isHidden(): bool {
460
//		return $this->hidden;
461
//	}
462
463
464
	/**
465
	 * @param array $memberOf
466
	 *
467
	 * @return $this
468
	 */
469
	public function setMemberOf(array $memberOf): self {
470
		$this->memberOf = $memberOf;
471
472
		return $this;
473
	}
474
475
	/**
476
	 * @return Circle[]
477
	 */
478
	public function memberOf(): array {
479
		if ($this->memberOf === null) {
480
			$this->getManager()->memberOf($this);
481
		}
482
483
		return $this->memberOf;
484
	}
485
486
487
	/**
488
	 * @param int $creation
489
	 *
490
	 * @return self
491
	 */
492
	public function setCreation(int $creation): self {
493
		$this->creation = $creation;
494
495
		return $this;
496
	}
497
498
	/**
499
	 * @return int
500
	 */
501
	public function getCreation(): int {
502
		return $this->creation;
503
	}
504
505
506
	/**
507
	 * @param array $data
508
	 *
509
	 * @return $this
510
	 */
511
	public function import(array $data): INC21Convert {
512
		$this->setId($this->get('id', $data))
513
			 ->setName($this->get('name', $data))
514
			 ->setAltName($this->get('alt_name', $data))
515
			 ->setConfig($this->getInt('config', $data))
516
			 ->setSettings($this->getArray('settings', $data))
517
//			 ->setContactAddressBook($this->get('contact_addressbook', $data))
518
//			 ->setContactGroupName($this->get('contact_groupname', $data))
519
			 ->setDescription($this->get('description', $data))
520
			 ->setCreation($this->getInt('creation', $data));
521
522
		try {
523
			/** @var Member $owner */
524
			$owner = $this->convert($this->getArray('owner', $data), Member::class);
525
			$this->setOwner($owner);
526
		} catch (InvalidItemException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
527
		}
528
529
		return $this;
530
	}
531
532
533
	/**
534
	 * @return array
535
	 */
536
	public function jsonSerialize(): array {
537
		$arr = [
538
			'id'          => $this->getId(),
539
			'name'        => $this->getName(),
540
			'alt_name'    => $this->getAltName(),
541
			'config'      => $this->getConfig(),
542
			'description' => $this->getDescription(),
543
			'settings'    => $this->getSettings(),
544
			//			'hidden'      => $this->isHidden(),
545
			'creation'    => $this->getCreation()
546
		];
547
548
		if ($this->hasOwner()) {
549
			$arr['owner'] = $this->getOwner();
550
		}
551
552
		if ($this->getManager()->isFullDetails()) {
553
			$arr['memberOf'] = $this->memberOf();
554
		}
555
556
		return array_filter($arr);
557
	}
558
559
560
	/**
561
	 * @param array $data
562
	 *
563
	 * @return INC21QueryRow
564
	 */
565
	public function importFromDatabase(array $data): INC21QueryRow {
566
		$this->setId($this->get('unique_id', $data))
567
			 ->setName($this->get('name', $data))
568
			 ->setAltName($this->get('alt_name', $data))
569
			 ->setConfig($this->getInt('config', $data))
570
			 ->setInstance($this->get('instance', $data))
571
			 ->setSettings($this->getArray('settings', $data))
572
			 ->setContactAddressBook($this->getInt('contact_addressbook', $data))
573
			 ->setContactGroupName($this->get('contact_groupname', $data))
574
			 ->setDescription($this->get('description', $data));
575
576
		$creation = $this->get('creation', $data);
577
		$this->setCreation(DateTime::createFromFormat('Y-m-d H:i:s', $creation)->getTimestamp());
578
579
		$this->getManager()->importOwnerFromDatabase($this, $data);
580
		$this->getManager()->importViewerFromDatabase($this, $data);
581
582
		return $this;
583
	}
584
585
586
	/**
587
	 * @param Circle $circle
588
	 *
589
	 * @return bool
590
	 */
591
	public function compareWith(Circle $circle): bool {
592
		if ($this->getId() !== $circle->getId()
593
			|| $this->getConfig() !== $circle->getConfig()) {
594
			return false;
595
		}
596
597
		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...
598
			&& (!$circle->hasOwner()
599
				|| !$this->getOwner()->compareWith($circle->getOwner()))) {
600
			return false;
601
		}
602
603
		return true;
604
	}
605
606
}
607