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\nc22\INC22QueryRow; |
35
|
|
|
use daita\MySmallPhpTools\Exceptions\InvalidItemException; |
36
|
|
|
use daita\MySmallPhpTools\IDeserializable; |
37
|
|
|
use daita\MySmallPhpTools\Traits\Nextcloud\nc22\TNC22Deserialize; |
38
|
|
|
use daita\MySmallPhpTools\Traits\TArrayTools; |
39
|
|
|
use DateTime; |
40
|
|
|
use JsonSerializable; |
41
|
|
|
use OCA\Circles\AppInfo\Capabilities; |
42
|
|
|
use OCA\Circles\Exceptions\MemberNotFoundException; |
43
|
|
|
use OCA\Circles\Exceptions\ParseMemberLevelException; |
44
|
|
|
use OCA\Circles\Exceptions\UnknownInterfaceException; |
45
|
|
|
use OCA\Circles\Exceptions\UserTypeNotFoundException; |
46
|
|
|
use OCA\Circles\IFederatedUser; |
47
|
|
|
use OCA\Circles\IMemberships; |
48
|
|
|
use OCA\Circles\Model\Federated\RemoteInstance; |
49
|
|
|
|
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* Class Member |
53
|
|
|
* |
54
|
|
|
* @package OCA\Circles\Model |
55
|
|
|
*/ |
56
|
|
|
class Member extends ManagedModel implements |
57
|
|
|
IMemberships, |
58
|
|
|
IFederatedUser, |
59
|
|
|
IDeserializable, |
60
|
|
|
INC22QueryRow, |
61
|
|
|
JsonSerializable { |
62
|
|
|
|
63
|
|
|
|
64
|
|
|
use TArrayTools; |
65
|
|
|
use TNC22Deserialize; |
66
|
|
|
|
67
|
|
|
|
68
|
|
|
const LEVEL_NONE = 0; |
69
|
|
|
const LEVEL_MEMBER = 1; |
70
|
|
|
const LEVEL_MODERATOR = 4; |
71
|
|
|
const LEVEL_ADMIN = 8; |
72
|
|
|
const LEVEL_OWNER = 9; |
73
|
|
|
|
74
|
|
|
const TYPE_SINGLE = 0; |
75
|
|
|
const TYPE_USER = 1; |
76
|
|
|
const TYPE_GROUP = 2; |
77
|
|
|
const TYPE_MAIL = 4; |
78
|
|
|
const TYPE_CONTACT = 8; |
79
|
|
|
const TYPE_CIRCLE = 16; |
80
|
|
|
const TYPE_APP = 10000; |
81
|
|
|
|
82
|
|
|
const APP_CIRCLES = 10001; |
83
|
|
|
const APP_OCC = 10002; |
84
|
|
|
|
85
|
|
|
|
86
|
|
|
public static $TYPE = [ |
87
|
|
|
0 => 'single', |
88
|
|
|
1 => 'user', |
89
|
|
|
2 => 'group', |
90
|
|
|
4 => 'mail', |
91
|
|
|
8 => 'contact', |
92
|
|
|
16 => 'circle', |
93
|
|
|
10000 => 'app' |
94
|
|
|
]; |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* Note: When editing those values, update lib/Application/Capabilities.php |
98
|
|
|
* |
99
|
|
|
* @see Capabilities::generateConstantsMember() |
100
|
|
|
*/ |
101
|
|
|
const STATUS_INVITED = 'Invited'; |
102
|
|
|
const STATUS_REQUEST = 'Requesting'; |
103
|
|
|
const STATUS_MEMBER = 'Member'; |
104
|
|
|
const STATUS_BLOCKED = 'Blocked'; |
105
|
|
|
|
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* Note: When editing those values, update lib/Application/Capabilities.php |
109
|
|
|
* |
110
|
|
|
* @see Capabilities::generateConstantsMember() |
111
|
|
|
* @var array |
112
|
|
|
*/ |
113
|
|
|
public static $DEF_LEVEL = [ |
114
|
|
|
1 => 'Member', |
115
|
|
|
4 => 'Moderator', |
116
|
|
|
8 => 'Admin', |
117
|
|
|
9 => 'Owner' |
118
|
|
|
]; |
119
|
|
|
|
120
|
|
|
|
121
|
|
|
public static $DEF_TYPE_MAX = 31; |
122
|
|
|
|
123
|
|
|
|
124
|
|
|
/** @var string */ |
125
|
|
|
private $id = ''; |
126
|
|
|
|
127
|
|
|
/** @var string */ |
128
|
|
|
private $circleId = ''; |
129
|
|
|
|
130
|
|
|
/** @var string */ |
131
|
|
|
private $singleId = ''; |
132
|
|
|
|
133
|
|
|
/** @var string */ |
134
|
|
|
private $userId = ''; |
135
|
|
|
|
136
|
|
|
/** @var int */ |
137
|
|
|
private $userType = 0; |
138
|
|
|
|
139
|
|
|
/** @var Circle */ |
140
|
|
|
private $basedOn; |
141
|
|
|
|
142
|
|
|
/** @var Member */ |
143
|
|
|
private $inheritanceFrom; |
144
|
|
|
|
145
|
|
|
/** @var FederatedUser */ |
146
|
|
|
private $inheritedBy; |
147
|
|
|
|
148
|
|
|
/** @var string */ |
149
|
|
|
private $instance = ''; |
150
|
|
|
|
151
|
|
|
/** @var FederatedUser */ |
152
|
|
|
private $invitedBy; |
153
|
|
|
|
154
|
|
|
/** @var RemoteInstance */ |
155
|
|
|
private $remoteInstance; |
156
|
|
|
|
157
|
|
|
/** @var bool */ |
158
|
|
|
private $local = false; |
159
|
|
|
|
160
|
|
|
/** @var int */ |
161
|
|
|
private $level = 0; |
162
|
|
|
|
163
|
|
|
/** @var string */ |
164
|
|
|
private $status = 'Unknown'; |
165
|
|
|
|
166
|
|
|
/** @var array */ |
167
|
|
|
private $notes = []; |
168
|
|
|
|
169
|
|
|
/** @var string */ |
170
|
|
|
private $displayName = ''; |
171
|
|
|
|
172
|
|
|
/** @var int */ |
173
|
|
|
private $displayUpdate = 0; |
174
|
|
|
|
175
|
|
|
/** @var string */ |
176
|
|
|
private $contactId = ''; |
177
|
|
|
|
178
|
|
|
/** @var string */ |
179
|
|
|
private $contactMeta = ''; |
180
|
|
|
|
181
|
|
|
/** @var Circle */ |
182
|
|
|
private $circle; |
183
|
|
|
|
184
|
|
|
/** @var int */ |
185
|
|
|
private $joined = 0; |
186
|
|
|
|
187
|
|
|
/** @var Membership[] */ |
188
|
|
|
private $memberships = null; |
189
|
|
|
|
190
|
|
|
|
191
|
|
|
/** |
192
|
|
|
* Member constructor. |
193
|
|
|
*/ |
194
|
|
|
public function __construct() { |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
|
198
|
|
|
/** |
199
|
|
|
* @param string $id |
200
|
|
|
* |
201
|
|
|
* @return $this |
202
|
|
|
*/ |
203
|
|
|
public function setId(string $id): self { |
204
|
|
|
$this->id = $id; |
205
|
|
|
|
206
|
|
|
return $this; |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
/** |
210
|
|
|
* @return string |
211
|
|
|
*/ |
212
|
|
|
public function getId(): string { |
213
|
|
|
return $this->id; |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
|
217
|
|
|
/** |
218
|
|
|
* @param string $circleId |
219
|
|
|
* |
220
|
|
|
* @return Member |
221
|
|
|
*/ |
222
|
|
|
public function setCircleId(string $circleId): self { |
223
|
|
|
$this->circleId = $circleId; |
224
|
|
|
|
225
|
|
|
return $this; |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
/** |
229
|
|
|
* @return string |
230
|
|
|
*/ |
231
|
|
|
public function getCircleId(): string { |
232
|
|
|
return $this->circleId; |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
|
236
|
|
|
/** |
237
|
|
|
* This should replace user_id, user_type and instance; and will use the data from Circle with |
238
|
|
|
* Config=CFG_SINGLE |
239
|
|
|
* |
240
|
|
|
* @param string $singleId |
241
|
|
|
* |
242
|
|
|
* @return $this |
243
|
|
|
*/ |
244
|
|
|
public function setSingleId(string $singleId): self { |
245
|
|
|
$this->singleId = $singleId; |
246
|
|
|
|
247
|
|
|
return $this; |
248
|
|
|
} |
249
|
|
|
|
250
|
|
|
/** |
251
|
|
|
* @return string |
252
|
|
|
*/ |
253
|
|
|
public function getSingleId(): string { |
254
|
|
|
return $this->singleId; |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
|
258
|
|
|
/** |
259
|
|
|
* @param string $userId |
260
|
|
|
* |
261
|
|
|
* @return Member |
262
|
|
|
*/ |
263
|
|
|
public function setUserId(string $userId): self { |
264
|
|
|
$this->userId = $userId; |
265
|
|
|
if ($this->displayName === '') { |
266
|
|
|
$this->displayName = $userId; |
267
|
|
|
} |
268
|
|
|
|
269
|
|
|
return $this; |
270
|
|
|
} |
271
|
|
|
|
272
|
|
|
/** |
273
|
|
|
* @return string |
274
|
|
|
*/ |
275
|
|
|
public function getUserId(): string { |
276
|
|
|
return $this->userId; |
277
|
|
|
} |
278
|
|
|
|
279
|
|
|
|
280
|
|
|
/** |
281
|
|
|
* @param int $userType |
282
|
|
|
* |
283
|
|
|
* @return Member |
284
|
|
|
*/ |
285
|
|
|
public function setUserType(int $userType): self { |
286
|
|
|
$this->userType = $userType; |
287
|
|
|
|
288
|
|
|
return $this; |
289
|
|
|
} |
290
|
|
|
|
291
|
|
|
/** |
292
|
|
|
* @return int |
293
|
|
|
*/ |
294
|
|
|
public function getUserType(): int { |
295
|
|
|
return $this->userType; |
296
|
|
|
} |
297
|
|
|
|
298
|
|
|
|
299
|
|
|
/** |
300
|
|
|
* @param string $instance |
301
|
|
|
* |
302
|
|
|
* @return Member |
303
|
|
|
*/ |
304
|
|
|
public function setInstance(string $instance): self { |
305
|
|
|
$this->instance = $instance; |
306
|
|
|
|
307
|
|
|
return $this; |
308
|
|
|
} |
309
|
|
|
|
310
|
|
|
/** |
311
|
|
|
* @return string |
312
|
|
|
*/ |
313
|
|
|
public function getInstance(): string { |
314
|
|
|
return $this->instance; |
315
|
|
|
} |
316
|
|
|
|
317
|
|
|
|
318
|
|
|
/** |
319
|
|
|
* @return bool |
320
|
|
|
*/ |
321
|
|
|
public function isLocal(): bool { |
322
|
|
|
return $this->getManager()->isLocalInstance($this->getInstance()); |
323
|
|
|
} |
324
|
|
|
|
325
|
|
|
|
326
|
|
|
/** |
327
|
|
|
* @param FederatedUser $invitedBy |
328
|
|
|
* |
329
|
|
|
* @return Member |
330
|
|
|
*/ |
331
|
|
|
public function setInvitedBy(FederatedUser $invitedBy): Member { |
332
|
|
|
$this->invitedBy = $invitedBy; |
333
|
|
|
|
334
|
|
|
return $this; |
335
|
|
|
} |
336
|
|
|
|
337
|
|
|
/** |
338
|
|
|
* @return FederatedUser |
339
|
|
|
*/ |
340
|
|
|
public function getInvitedBy(): FederatedUser { |
341
|
|
|
return $this->invitedBy; |
342
|
|
|
} |
343
|
|
|
|
344
|
|
|
/** |
345
|
|
|
* @return bool |
346
|
|
|
*/ |
347
|
|
|
public function hasInvitedBy(): bool { |
348
|
|
|
return !is_null($this->invitedBy); |
349
|
|
|
} |
350
|
|
|
|
351
|
|
|
|
352
|
|
|
/** |
353
|
|
|
* @return bool |
354
|
|
|
*/ |
355
|
|
|
public function hasRemoteInstance(): bool { |
356
|
|
|
return !is_null($this->remoteInstance); |
357
|
|
|
} |
358
|
|
|
|
359
|
|
|
/** |
360
|
|
|
* @param RemoteInstance $remoteInstance |
361
|
|
|
* |
362
|
|
|
* @return Member |
363
|
|
|
*/ |
364
|
|
|
public function setRemoteInstance(RemoteInstance $remoteInstance): self { |
365
|
|
|
$this->remoteInstance = $remoteInstance; |
366
|
|
|
|
367
|
|
|
return $this; |
368
|
|
|
} |
369
|
|
|
|
370
|
|
|
/** |
371
|
|
|
* @return RemoteInstance |
372
|
|
|
*/ |
373
|
|
|
public function getRemoteInstance(): RemoteInstance { |
374
|
|
|
return $this->remoteInstance; |
375
|
|
|
} |
376
|
|
|
|
377
|
|
|
|
378
|
|
|
/** |
379
|
|
|
* @return bool |
380
|
|
|
*/ |
381
|
|
|
public function hasBasedOn(): bool { |
382
|
|
|
return !is_null($this->basedOn); |
383
|
|
|
} |
384
|
|
|
|
385
|
|
|
/** |
386
|
|
|
* @param Circle $basedOn |
387
|
|
|
* |
388
|
|
|
* @return $this |
389
|
|
|
*/ |
390
|
|
|
public function setBasedOn(Circle $basedOn): self { |
391
|
|
|
$this->basedOn = $basedOn; |
392
|
|
|
|
393
|
|
|
return $this; |
394
|
|
|
} |
395
|
|
|
|
396
|
|
|
/** |
397
|
|
|
* @return Circle |
398
|
|
|
*/ |
399
|
|
|
public function getBasedOn(): Circle { |
400
|
|
|
return $this->basedOn; |
401
|
|
|
} |
402
|
|
|
|
403
|
|
|
|
404
|
|
|
/** |
405
|
|
|
* @return bool |
406
|
|
|
*/ |
407
|
|
|
public function hasInheritedBy(): bool { |
408
|
|
|
return !is_null($this->inheritedBy); |
409
|
|
|
} |
410
|
|
|
|
411
|
|
|
/** |
412
|
|
|
* @param FederatedUser $inheritedBy |
413
|
|
|
* |
414
|
|
|
* @return $this |
415
|
|
|
*/ |
416
|
|
|
public function setInheritedBy(FederatedUser $inheritedBy): self { |
417
|
|
|
$this->inheritedBy = $inheritedBy; |
418
|
|
|
|
419
|
|
|
return $this; |
420
|
|
|
} |
421
|
|
|
|
422
|
|
|
/** |
423
|
|
|
* @return FederatedUser |
424
|
|
|
*/ |
425
|
|
|
public function getInheritedBy(): FederatedUser { |
426
|
|
|
return $this->inheritedBy; |
427
|
|
|
} |
428
|
|
|
|
429
|
|
|
|
430
|
|
|
/** |
431
|
|
|
* @return bool |
432
|
|
|
*/ |
433
|
|
|
public function hasInheritanceFrom(): bool { |
434
|
|
|
return !is_null($this->inheritanceFrom); |
435
|
|
|
} |
436
|
|
|
|
437
|
|
|
/** |
438
|
|
|
* @param Member $inheritanceFrom |
439
|
|
|
* |
440
|
|
|
* @return $this |
441
|
|
|
*/ |
442
|
|
|
public function setInheritanceFrom(Member $inheritanceFrom): self { |
443
|
|
|
$this->inheritanceFrom = $inheritanceFrom; |
444
|
|
|
|
445
|
|
|
return $this; |
446
|
|
|
} |
447
|
|
|
|
448
|
|
|
/** |
449
|
|
|
* @return Member|null |
450
|
|
|
*/ |
451
|
|
|
public function getInheritanceFrom(): ?Member { |
452
|
|
|
return $this->inheritanceFrom; |
453
|
|
|
} |
454
|
|
|
|
455
|
|
|
|
456
|
|
|
/** |
457
|
|
|
* @param int $level |
458
|
|
|
* |
459
|
|
|
* @return Member |
460
|
|
|
*/ |
461
|
|
|
public function setLevel(int $level): self { |
462
|
|
|
$this->level = $level; |
463
|
|
|
|
464
|
|
|
return $this; |
465
|
|
|
} |
466
|
|
|
|
467
|
|
|
/** |
468
|
|
|
* @return int |
469
|
|
|
*/ |
470
|
|
|
public function getLevel(): int { |
471
|
|
|
return $this->level; |
472
|
|
|
} |
473
|
|
|
|
474
|
|
|
|
475
|
|
|
/** |
476
|
|
|
* @param string $status |
477
|
|
|
* |
478
|
|
|
* @return Member |
479
|
|
|
*/ |
480
|
|
|
public function setStatus(string $status): self { |
481
|
|
|
$this->status = $status; |
482
|
|
|
|
483
|
|
|
return $this; |
484
|
|
|
} |
485
|
|
|
|
486
|
|
|
/** |
487
|
|
|
* @return string |
488
|
|
|
*/ |
489
|
|
|
public function getStatus(): string { |
490
|
|
|
return $this->status; |
491
|
|
|
} |
492
|
|
|
|
493
|
|
|
|
494
|
|
|
/** |
495
|
|
|
* @param array $notes |
496
|
|
|
* |
497
|
|
|
* @return Member |
498
|
|
|
*/ |
499
|
|
|
public function setNotes(array $notes): self { |
500
|
|
|
$this->notes = $notes; |
501
|
|
|
|
502
|
|
|
return $this; |
503
|
|
|
} |
504
|
|
|
|
505
|
|
|
/** |
506
|
|
|
* @return array |
507
|
|
|
*/ |
508
|
|
|
public function getNotes(): array { |
509
|
|
|
return $this->notes; |
510
|
|
|
} |
511
|
|
|
|
512
|
|
|
|
513
|
|
|
/** |
514
|
|
|
* @param string $key |
515
|
|
|
* |
516
|
|
|
* @return string |
517
|
|
|
*/ |
518
|
|
|
public function getNote(string $key): string { |
519
|
|
|
return $this->get($key, $this->notes); |
520
|
|
|
} |
521
|
|
|
|
522
|
|
|
/** |
523
|
|
|
* @param string $key |
524
|
|
|
* |
525
|
|
|
* @return array |
526
|
|
|
*/ |
527
|
|
|
public function getNoteArray(string $key): array { |
528
|
|
|
return $this->getArray($key, $this->notes); |
529
|
|
|
} |
530
|
|
|
|
531
|
|
|
/** |
532
|
|
|
* @param string $key |
533
|
|
|
* @param string $note |
534
|
|
|
* |
535
|
|
|
* @return $this |
536
|
|
|
*/ |
537
|
|
|
public function setNote(string $key, string $note): self { |
538
|
|
|
$this->notes[$key] = $note; |
539
|
|
|
|
540
|
|
|
return $this; |
541
|
|
|
} |
542
|
|
|
|
543
|
|
|
/** |
544
|
|
|
* @param string $key |
545
|
|
|
* @param array $note |
546
|
|
|
* |
547
|
|
|
* @return $this |
548
|
|
|
*/ |
549
|
|
|
public function setNoteArray(string $key, array $note): self { |
550
|
|
|
$this->notes[$key] = $note; |
551
|
|
|
|
552
|
|
|
return $this; |
553
|
|
|
} |
554
|
|
|
|
555
|
|
|
/** |
556
|
|
|
* @param string $key |
557
|
|
|
* @param JsonSerializable $obj |
558
|
|
|
* |
559
|
|
|
* @return $this |
560
|
|
|
*/ |
561
|
|
|
public function setNoteObj(string $key, JsonSerializable $obj): self { |
562
|
|
|
$this->notes[$key] = $obj; |
563
|
|
|
|
564
|
|
|
return $this; |
565
|
|
|
} |
566
|
|
|
|
567
|
|
|
|
568
|
|
|
/** |
569
|
|
|
* @param string $displayName |
570
|
|
|
* |
571
|
|
|
* @return Member |
572
|
|
|
*/ |
573
|
|
|
public function setDisplayName(string $displayName): self { |
574
|
|
|
if ($displayName !== '') { |
575
|
|
|
$this->displayName = $displayName; |
576
|
|
|
} |
577
|
|
|
|
578
|
|
|
return $this; |
579
|
|
|
} |
580
|
|
|
|
581
|
|
|
|
582
|
|
|
/** |
583
|
|
|
* @param int $displayUpdate |
584
|
|
|
* |
585
|
|
|
* @return Member |
586
|
|
|
*/ |
587
|
|
|
public function setDisplayUpdate(int $displayUpdate): self { |
588
|
|
|
$this->displayUpdate = $displayUpdate; |
589
|
|
|
|
590
|
|
|
return $this; |
591
|
|
|
} |
592
|
|
|
|
593
|
|
|
/** |
594
|
|
|
* @return int |
595
|
|
|
*/ |
596
|
|
|
public function getDisplayUpdate(): int { |
597
|
|
|
return $this->displayUpdate; |
598
|
|
|
} |
599
|
|
|
|
600
|
|
|
|
601
|
|
|
/** |
602
|
|
|
* @return string |
603
|
|
|
*/ |
604
|
|
|
public function getDisplayName(): string { |
605
|
|
|
return $this->displayName; |
606
|
|
|
} |
607
|
|
|
|
608
|
|
|
|
609
|
|
|
/** |
610
|
|
|
* @param string $contactId |
611
|
|
|
* |
612
|
|
|
* @return Member |
613
|
|
|
*/ |
614
|
|
|
public function setContactId(string $contactId): self { |
615
|
|
|
$this->contactId = $contactId; |
616
|
|
|
|
617
|
|
|
return $this; |
618
|
|
|
} |
619
|
|
|
|
620
|
|
|
/** |
621
|
|
|
* @return string |
622
|
|
|
*/ |
623
|
|
|
public function getContactId(): string { |
624
|
|
|
return $this->contactId; |
625
|
|
|
} |
626
|
|
|
|
627
|
|
|
|
628
|
|
|
/** |
629
|
|
|
* @param string $contactMeta |
630
|
|
|
* |
631
|
|
|
* @return Member |
632
|
|
|
*/ |
633
|
|
|
public function setContactMeta(string $contactMeta): self { |
634
|
|
|
$this->contactMeta = $contactMeta; |
635
|
|
|
|
636
|
|
|
return $this; |
637
|
|
|
} |
638
|
|
|
|
639
|
|
|
/** |
640
|
|
|
* @return string |
641
|
|
|
*/ |
642
|
|
|
public function getContactMeta(): string { |
643
|
|
|
return $this->contactMeta; |
644
|
|
|
} |
645
|
|
|
|
646
|
|
|
|
647
|
|
|
/** |
648
|
|
|
* @param Circle $circle |
649
|
|
|
* |
650
|
|
|
* @return self |
651
|
|
|
*/ |
652
|
|
|
public function setCircle(Circle $circle): self { |
653
|
|
|
$this->circle = $circle; |
654
|
|
|
|
655
|
|
|
return $this; |
656
|
|
|
} |
657
|
|
|
|
658
|
|
|
/** |
659
|
|
|
* @return Circle |
660
|
|
|
*/ |
661
|
|
|
public function getCircle(): Circle { |
662
|
|
|
return $this->circle; |
663
|
|
|
} |
664
|
|
|
|
665
|
|
|
/** |
666
|
|
|
* @return bool |
667
|
|
|
*/ |
668
|
|
|
public function hasCircle(): bool { |
669
|
|
|
return (!is_null($this->circle)); |
670
|
|
|
} |
671
|
|
|
|
672
|
|
|
|
673
|
|
|
/** |
674
|
|
|
* @param int $joined |
675
|
|
|
* |
676
|
|
|
* @return Member |
677
|
|
|
*/ |
678
|
|
|
public function setJoined(int $joined): self { |
679
|
|
|
$this->joined = $joined; |
680
|
|
|
|
681
|
|
|
return $this; |
682
|
|
|
} |
683
|
|
|
|
684
|
|
|
/** |
685
|
|
|
* @return int |
686
|
|
|
*/ |
687
|
|
|
public function getJoined(): int { |
688
|
|
|
return $this->joined; |
689
|
|
|
} |
690
|
|
|
|
691
|
|
|
|
692
|
|
|
/** |
693
|
|
|
* @return bool |
694
|
|
|
*/ |
695
|
|
|
public function hasMemberships(): bool { |
696
|
|
|
return !is_null($this->memberships); |
697
|
|
|
} |
698
|
|
|
|
699
|
|
|
/** |
700
|
|
|
* @param array $memberships |
701
|
|
|
* |
702
|
|
|
* @return self |
703
|
|
|
*/ |
704
|
|
|
public function setMemberships(array $memberships): IMemberships { |
705
|
|
|
$this->memberships = $memberships; |
706
|
|
|
|
707
|
|
|
return $this; |
|
|
|
|
708
|
|
|
} |
709
|
|
|
|
710
|
|
|
/** |
711
|
|
|
* @return Membership[] |
712
|
|
|
*/ |
713
|
|
|
public function getMemberships(): array { |
714
|
|
|
if (is_null($this->memberships)) { |
715
|
|
|
$this->getManager()->getMemberships($this); |
716
|
|
|
} |
717
|
|
|
|
718
|
|
|
return $this->memberships; |
719
|
|
|
} |
720
|
|
|
|
721
|
|
|
|
722
|
|
|
/** |
723
|
|
|
* @param Member $member |
724
|
|
|
* @param bool $full |
725
|
|
|
* |
726
|
|
|
* @return bool |
727
|
|
|
*/ |
728
|
|
|
public function compareWith(Member $member, bool $full = true): bool { |
729
|
|
|
if ($this->getId() !== $member->getId() |
730
|
|
|
|| $this->getCircleId() !== $member->getCircleId() |
731
|
|
|
|| $this->getSingleId() !== $member->getSingleId() |
732
|
|
|
|| $this->getUserId() !== $member->getUserId() |
733
|
|
|
|| $this->getUserType() <> $member->getUserType() |
734
|
|
|
|| $this->getInstance() !== $member->getInstance()) { |
735
|
|
|
return false; |
736
|
|
|
} |
737
|
|
|
|
738
|
|
|
if ($full |
739
|
|
|
&& ($this->getLevel() <> $member->getLevel() |
740
|
|
|
|| $this->getStatus() !== $member->getStatus())) { |
741
|
|
|
return false; |
742
|
|
|
} |
743
|
|
|
|
744
|
|
|
return true; |
745
|
|
|
} |
746
|
|
|
|
747
|
|
|
|
748
|
|
|
/** |
749
|
|
|
* @param array $data |
750
|
|
|
* |
751
|
|
|
* @return $this |
752
|
|
|
* @throws InvalidItemException |
753
|
|
|
*/ |
754
|
|
|
public function import(array $data): IDeserializable { |
755
|
|
|
if ($this->get('userId', $data) === '') { |
756
|
|
|
throw new InvalidItemException(); |
757
|
|
|
} |
758
|
|
|
|
759
|
|
|
$this->setId($this->get('id', $data)); |
760
|
|
|
$this->setCircleId($this->get('circleId', $data)); |
761
|
|
|
$this->setSingleId($this->get('singleId', $data)); |
762
|
|
|
$this->setUserId($this->get('userId', $data)); |
763
|
|
|
$this->setUserType($this->getInt('userType', $data)); |
764
|
|
|
$this->setInstance($this->get('instance', $data)); |
765
|
|
|
$this->setLevel($this->getInt('level', $data)); |
766
|
|
|
$this->setStatus($this->get('status', $data)); |
767
|
|
|
$this->setDisplayName($this->get('displayName', $data)); |
768
|
|
|
$this->setDisplayUpdate($this->getInt('displayUpdate', $data)); |
769
|
|
|
$this->setNotes($this->getArray('notes', $data)); |
770
|
|
|
$this->setContactId($this->get('contactId', $data)); |
771
|
|
|
$this->setContactMeta($this->get('contactMeta', $data)); |
772
|
|
|
$this->setJoined($this->getInt('joined', $data)); |
773
|
|
|
|
774
|
|
|
try { |
775
|
|
|
/** @var Circle $circle */ |
776
|
|
|
$circle = $this->deserialize($this->getArray('circle', $data), Circle::class); |
777
|
|
|
$this->setCircle($circle); |
778
|
|
|
} catch (InvalidItemException $e) { |
|
|
|
|
779
|
|
|
} |
780
|
|
|
|
781
|
|
|
try { |
782
|
|
|
/** @var Circle $circle */ |
783
|
|
|
$circle = $this->deserialize($this->getArray('basedOn', $data), Circle::class); |
784
|
|
|
$this->setBasedOn($circle); |
785
|
|
|
} catch (InvalidItemException $e) { |
|
|
|
|
786
|
|
|
} |
787
|
|
|
|
788
|
|
|
try { |
789
|
|
|
/** @var FederatedUser $invitedBy */ |
790
|
|
|
$invitedBy = $this->deserialize($this->getArray('invitedBy', $data), FederatedUser::class); |
791
|
|
|
$this->setInvitedBy($invitedBy); |
792
|
|
|
} catch (InvalidItemException $e) { |
|
|
|
|
793
|
|
|
} |
794
|
|
|
|
795
|
|
|
try { |
796
|
|
|
/** @var FederatedUSer $inheritedBy */ |
797
|
|
|
$inheritedBy = $this->deserialize($this->getArray('inheritedBy', $data), Membership::class); |
798
|
|
|
$this->setInheritedBy($inheritedBy); |
799
|
|
|
} catch (InvalidItemException $e) { |
|
|
|
|
800
|
|
|
} |
801
|
|
|
|
802
|
|
|
return $this; |
|
|
|
|
803
|
|
|
} |
804
|
|
|
|
805
|
|
|
|
806
|
|
|
/** |
807
|
|
|
* @param array $data |
808
|
|
|
* @param string $prefix |
809
|
|
|
* |
810
|
|
|
* @return INC22QueryRow |
811
|
|
|
* @throws MemberNotFoundException |
812
|
|
|
*/ |
813
|
|
|
public function importFromDatabase(array $data, string $prefix = ''): INC22QueryRow { |
814
|
|
|
if ($this->get($prefix . 'single_id', $data) === '') { |
815
|
|
|
throw new MemberNotFoundException(); |
816
|
|
|
} |
817
|
|
|
|
818
|
|
|
$this->setId($this->get($prefix . 'member_id', $data)); |
819
|
|
|
$this->setCircleId($this->get($prefix . 'circle_id', $data)); |
820
|
|
|
$this->setSingleId($this->get($prefix . 'single_id', $data)); |
821
|
|
|
$this->setUserId($this->get($prefix . 'user_id', $data)); |
822
|
|
|
$this->setUserType($this->getInt($prefix . 'user_type', $data)); |
823
|
|
|
$this->setInstance($this->get($prefix . 'instance', $data)); |
824
|
|
|
$this->setLevel($this->getInt($prefix . 'level', $data)); |
825
|
|
|
$this->setStatus($this->get($prefix . 'status', $data)); |
826
|
|
|
$this->setDisplayName($this->get($prefix . 'cached_name', $data)); |
827
|
|
|
$this->setNotes($this->getArray($prefix . 'note', $data)); |
828
|
|
|
$this->setContactId($this->get($prefix . 'contact_id', $data)); |
829
|
|
|
$this->setContactMeta($this->get($prefix . 'contact_meta', $data)); |
830
|
|
|
|
831
|
|
|
$cachedUpdate = $this->get($prefix . 'cached_update', $data); |
832
|
|
|
if ($cachedUpdate !== '') { |
833
|
|
|
$this->setDisplayUpdate(DateTime::createFromFormat('Y-m-d H:i:s', $cachedUpdate)->getTimestamp()); |
834
|
|
|
} |
835
|
|
|
|
836
|
|
|
$joined = $this->get($prefix . 'joined', $data); |
837
|
|
|
if ($joined !== '') { |
838
|
|
|
$this->setJoined(DateTime::createFromFormat('Y-m-d H:i:s', $joined)->getTimestamp()); |
839
|
|
|
} |
840
|
|
|
|
841
|
|
|
if ($this->getInstance() === '') { |
842
|
|
|
$this->setInstance($this->getManager()->getLocalInstance()); |
843
|
|
|
} |
844
|
|
|
|
845
|
|
|
$this->getManager()->manageImportFromDatabase($this, $data, $prefix); |
846
|
|
|
|
847
|
|
|
// in case invitedBy is not obtainable from 'invited_by', we reach data from 'note' |
848
|
|
|
if (!$this->hasInvitedBy()) { |
849
|
|
|
$invitedByArray = $this->getNoteArray('invitedBy'); |
850
|
|
|
if (!empty($invitedByArray)) { |
851
|
|
|
try { |
852
|
|
|
$invitedBy = new FederatedUser(); |
853
|
|
|
$this->setInvitedBy($invitedBy->import($invitedByArray)); |
854
|
|
|
} catch (InvalidItemException $e) { |
|
|
|
|
855
|
|
|
} |
856
|
|
|
} |
857
|
|
|
} |
858
|
|
|
|
859
|
|
|
return $this; |
|
|
|
|
860
|
|
|
} |
861
|
|
|
|
862
|
|
|
|
863
|
|
|
/** |
864
|
|
|
* @return string[] |
865
|
|
|
* @throws UnknownInterfaceException |
866
|
|
|
*/ |
867
|
|
|
public function jsonSerialize(): array { |
868
|
|
|
$arr = [ |
869
|
|
|
'id' => $this->getId(), |
870
|
|
|
'circleId' => $this->getCircleId(), |
871
|
|
|
'singleId' => $this->getSingleId(), |
872
|
|
|
'userId' => $this->getUserId(), |
873
|
|
|
'userType' => $this->getUserType(), |
874
|
|
|
'instance' => $this->getManager()->fixInstance($this->getInstance()), |
875
|
|
|
'local' => $this->isLocal(), |
876
|
|
|
'level' => $this->getLevel(), |
877
|
|
|
'status' => $this->getStatus(), |
878
|
|
|
'displayName' => $this->getDisplayName(), |
879
|
|
|
'displayUpdate' => $this->getDisplayUpdate(), |
880
|
|
|
'notes' => $this->getNotes(), |
881
|
|
|
'contactId' => $this->getContactId(), |
882
|
|
|
'contactMeta' => $this->getContactMeta(), |
883
|
|
|
'joined' => $this->getJoined() |
884
|
|
|
]; |
885
|
|
|
|
886
|
|
|
if ($this->hasInvitedBy()) { |
887
|
|
|
$arr['invitedBy'] = $this->getInvitedBy(); |
888
|
|
|
} |
889
|
|
|
|
890
|
|
|
if ($this->hasBasedOn()) { |
891
|
|
|
$arr['basedOn'] = $this->getBasedOn(); |
892
|
|
|
} |
893
|
|
|
|
894
|
|
|
if ($this->hasInheritedBy()) { |
895
|
|
|
$arr['inheritedBy'] = $this->getInheritedBy(); |
896
|
|
|
} |
897
|
|
|
|
898
|
|
|
if ($this->hasInheritanceFrom()) { |
899
|
|
|
$arr['inheritanceFrom'] = $this->getInheritanceFrom(); |
900
|
|
|
} |
901
|
|
|
|
902
|
|
|
if ($this->hasCircle()) { |
903
|
|
|
$arr['circle'] = $this->getCircle(); |
904
|
|
|
} |
905
|
|
|
|
906
|
|
|
if ($this->hasMemberships()) { |
907
|
|
|
$arr['memberships'] = $this->getMemberships(); |
908
|
|
|
} |
909
|
|
|
|
910
|
|
|
if ($this->hasRemoteInstance()) { |
911
|
|
|
$arr['remoteInstance'] = $this->getRemoteInstance(); |
912
|
|
|
} |
913
|
|
|
|
914
|
|
|
return $arr; |
915
|
|
|
} |
916
|
|
|
|
917
|
|
|
|
918
|
|
|
/** |
919
|
|
|
* @param int $level |
920
|
|
|
* |
921
|
|
|
* @return int |
922
|
|
|
* @throws ParseMemberLevelException |
923
|
|
|
*/ |
924
|
|
|
public static function parseLevelInt(int $level): int { |
925
|
|
|
if (!array_key_exists($level, self::$DEF_LEVEL)) { |
926
|
|
|
$all = implode(', ', array_keys(self::$DEF_LEVEL)); |
927
|
|
|
throw new ParseMemberLevelException('Available levels: ' . $all, 121); |
928
|
|
|
} |
929
|
|
|
|
930
|
|
|
return $level; |
931
|
|
|
} |
932
|
|
|
|
933
|
|
|
|
934
|
|
|
/** |
935
|
|
|
* @param string $levelString |
936
|
|
|
* |
937
|
|
|
* @return int |
938
|
|
|
* @throws ParseMemberLevelException |
939
|
|
|
*/ |
940
|
|
|
public static function parseLevelString(string $levelString): int { |
941
|
|
|
$levelString = ucfirst(strtolower($levelString)); |
942
|
|
|
$level = array_search($levelString, Member::$DEF_LEVEL); |
943
|
|
|
|
944
|
|
|
if (!$level) { |
945
|
|
|
$all = implode(', ', array_values(self::$DEF_LEVEL)); |
946
|
|
|
throw new ParseMemberLevelException('Available levels: ' . $all, 121); |
947
|
|
|
} |
948
|
|
|
|
949
|
|
|
return (int)$level; |
950
|
|
|
} |
951
|
|
|
|
952
|
|
|
/** |
953
|
|
|
* @param string $typeString |
954
|
|
|
* |
955
|
|
|
* @return int |
956
|
|
|
* @throws UserTypeNotFoundException |
957
|
|
|
*/ |
958
|
|
|
public static function parseTypeString(string $typeString): int { |
959
|
|
|
$typeString = strtolower($typeString); |
960
|
|
|
if (array_key_exists($typeString, Member::$TYPE)) { |
961
|
|
|
return (int)$typeString; |
962
|
|
|
} |
963
|
|
|
|
964
|
|
|
$type = array_search($typeString, Member::$TYPE); |
965
|
|
|
if ($type === false) { |
966
|
|
|
$all = implode(', ', array_values(self::$TYPE)); |
967
|
|
|
throw new UserTypeNotFoundException('Available types: ' . $all); |
968
|
|
|
} |
969
|
|
|
|
970
|
|
|
return (int)$type; |
971
|
|
|
} |
972
|
|
|
|
973
|
|
|
} |
974
|
|
|
|
975
|
|
|
|
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_function
expects aPost
object, and outputs the author of the post. The base classPost
returns a simple string and outputting a simple string will work just fine. However, the child classBlogPost
which is a sub-type ofPost
instead decided to return anobject
, and is therefore violating the SOLID principles. If aBlogPost
were passed tomy_function
, PHP would not complain, but ultimately fail when executing thestrtoupper
call in its body.