Completed
Push — master ( b4b3e8...fb5007 )
by Maxence
02:30 queued 42s
created

MembersRequest::updateMemberLevel()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.7998
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
/**
3
 * Circles - Bring cloud-users closer together.
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Maxence Lange <[email protected]>
9
 * @copyright 2017
10
 * @license GNU AGPL version 3 or any later version
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License as
14
 * published by the Free Software Foundation, either version 3 of the
15
 * License, or (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24
 *
25
 */
26
27
28
namespace OCA\Circles\Db;
29
30
31
use daita\MySmallPhpTools\Traits\TStringTools;
32
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
33
use Exception;
34
use OCA\Circles\Exceptions\MemberAlreadyExistsException;
35
use OCA\Circles\Exceptions\MemberDoesNotExistException;
36
use OCA\Circles\Model\Member;
37
use OCP\IGroup;
38
39
class MembersRequest extends MembersRequestBuilder {
40
41
42
	use TStringTools;
43
44
45
	/**
46
	 * Returns information about a member.
47
	 *
48
	 * WARNING: This function does not filters data regarding the current user/viewer.
49
	 *          In case of interaction with users, Please use MembersService->getMember() instead.
50
	 *
51
	 * @param string $circleUniqueId
52
	 * @param string $userId
53
	 * @param $type
54
	 *
55
	 * @param string $instance
56
	 *
57
	 * @return Member
58
	 * @throws MemberDoesNotExistException
59
	 */
60
	public function forceGetMember($circleUniqueId, $userId, $type, string $instance = '') {
61
		$qb = $this->getMembersSelectSql();
62
63
		if ($instance === $this->configService->getLocalCloudId()) {
64
			$instance = '';
65
		}
66
67
		$this->limitToUserId($qb, $userId);
68
		$this->limitToUserType($qb, $type);
69
		$this->limitToInstance($qb, $instance);
70
		$this->limitToCircleId($qb, $circleUniqueId);
71
72
		$cursor = $qb->execute();
73
		$data = $cursor->fetch();
74
		$cursor->closeCursor();
75
76
		if ($data === false) {
77
			throw new MemberDoesNotExistException($this->l10n->t('This member does not exist'));
78
		}
79
80
		return $this->parseMembersSelectSql($data);
81
	}
82
83
84
	/**
85
	 * @param string $memberId
86
	 *
87
	 * @return Member
88
	 * @throws MemberDoesNotExistException
89
	 */
90
	public function forceGetMemberById(string $memberId): Member {
91
		$qb = $this->getMembersSelectSql();
92
93
		$this->limitToMemberId($qb, $memberId);
94
95
		$cursor = $qb->execute();
96
		$data = $cursor->fetch();
97
		$cursor->closeCursor();
98
99
		if ($data === false) {
100
			throw new MemberDoesNotExistException($this->l10n->t('This member does not exist'));
101
		}
102
103
		return $this->parseMembersSelectSql($data);
104
	}
105
106
107
	/**
108
	 * Returns members list of a circle, based on their level.
109
	 *
110
	 * WARNING: This function does not filters data regarding the current user/viewer.
111
	 *          In case of interaction with users, Please use getMembers() instead.
112
	 *
113
	 * @param string $circleUniqueId
114
	 * @param int $level
115
	 * @param int $type
116
	 * @param bool $incGroup
117
	 *
118
	 * @return Member[]
119
	 */
120
	public function forceGetMembers(
121
		$circleUniqueId, $level = Member::LEVEL_MEMBER, int $type = 0, $incGroup = false
122
	) {
123
		$qb = $this->getMembersSelectSql();
124
		$this->limitToMembersAndAlmost($qb);
125
		$this->limitToLevel($qb, $level);
126
127
		if ($type > 0) {
128
			$this->limitToUserType($qb, $type);
129
		}
130
131
		$this->limitToCircleId($qb, $circleUniqueId);
132
133
		$members = [];
134
		$cursor = $qb->execute();
135
		while ($data = $cursor->fetch()) {
136
			$members[] = $this->parseMembersSelectSql($data);
137
		}
138
		$cursor->closeCursor();
139
140
		if ($this->configService->isLinkedGroupsAllowed() && $incGroup === true) {
141
			$this->includeGroupMembers($members, $circleUniqueId, $level);
142
		}
143
144
		return $members;
145
	}
146
147
148
	/**
149
	 * Returns all members.
150
	 *
151
	 * WARNING: This function does not filters data regarding the current user/viewer.
152
	 *          In case of interaction with users, Please use getMembers() instead.
153
	 *
154
	 *
155
	 * @return Member[]
156
	 */
157
	public function forceGetAllMembers() {
158
159
		$qb = $this->getMembersSelectSql();
160
161
		$members = [];
162
		$cursor = $qb->execute();
163
		while ($data = $cursor->fetch()) {
164
			$members[] = $this->parseMembersSelectSql($data);
165
		}
166
		$cursor->closeCursor();
167
168
		return $members;
169
	}
170
171
172
	/**
173
	 * Returns members generated from Contacts that are not 'checked' (as not sent existing shares).
174
	 *
175
	 *
176
	 * @return Member[]
177
	 */
178
	public function forceGetAllRecentContactEdit() {
179
		$qb = $this->getMembersSelectSql();
180
		$this->limitToUserType($qb, Member::TYPE_CONTACT);
181
182
		$expr = $qb->expr();
183
		$orX = $expr->orX();
184
		$orX->add($expr->isNull('contact_checked'));
185
		$orX->add($expr->neq('contact_checked', $qb->createNamedParameter('1')));
186
		$qb->andWhere($orX);
187
188
		$members = [];
189
		$cursor = $qb->execute();
190
		while ($data = $cursor->fetch()) {
191
			$members[] = $this->parseMembersSelectSql($data);
192
		}
193
		$cursor->closeCursor();
194
195
		return $members;
196
	}
197
198
199
	/**
200
	 * @param Member $member
201
	 * @param bool $check
202
	 */
203
	public function checkMember(Member $member, bool $check) {
204
		$qb = $this->getMembersUpdateSql(
205
			$member->getCircleId(), $member->getUserId(), $member->getInstance(), $member->getType()
206
		);
207
		$qb->set('contact_checked', $qb->createNamedParameter(($check) ? 1 : 0));
208
209
		$qb->execute();
210
	}
211
212
213
	/**
214
	 * @param string $circleUniqueId
215
	 * @param Member $viewer
216
	 * @param bool $force
217
	 *
218
	 * @return Member[]
219
	 */
220
	public function getMembers($circleUniqueId, ?Member $viewer, bool $force = false) {
221
		try {
222
			if ($force === false) {
223
				$viewer->hasToBeMember();
224
			}
225
226
			$members = $this->forceGetMembers($circleUniqueId, Member::LEVEL_NONE);
227
			if ($force === false) {
228
				if (!$viewer->isLevel(Member::LEVEL_MODERATOR)) {
229
					array_map(
230
						function(Member $m) {
231
							$m->setNote('');
232
						}, $members
233
					);
234
				}
235
			}
236
237
			return $members;
238
		} catch (Exception $e) {
239
			return [];
240
		}
241
	}
242
243
244
	/**
245
	 * forceGetGroup();
246
	 *
247
	 * returns group information as a member within a Circle.
248
	 *
249
	 * WARNING: This function does not filters data regarding the current user/viewer.
250
	 *          In case of interaction with users, Please use getGroup() instead.
251
	 *
252
	 * @param string $circleUniqueId
253
	 * @param string $groupId
254
	 * @param string $instance
255
	 *
256
	 * @return Member
257
	 * @throws MemberDoesNotExistException
258
	 */
259
	public function forceGetGroup(string $circleUniqueId, string $groupId, string $instance) {
260
		$qb = $this->getMembersSelectSql();
261
262
		$this->limitToUserId($qb, $groupId);
263
		$this->limitToUserType($qb, Member::TYPE_GROUP);
264
		$this->limitToInstance($qb, $instance);
265
		$this->limitToCircleId($qb, $circleUniqueId);
266
267
		$cursor = $qb->execute();
268
		$data = $cursor->fetch();
269
		$cursor->closeCursor();
270
		if ($data === false) {
271
			throw new MemberDoesNotExistException($this->l10n->t('This member does not exist'));
272
		}
273
274
		return $this->parseMembersSelectSql($data);
275
	}
276
277
278
	/**
279
	 * includeGroupMembers();
280
	 *
281
	 * This function will get members of a circle throw NCGroups and fill the result an existing
282
	 * Members List. In case of duplicate, higher level will be kept.
283
	 *
284
	 * @param Member[] $members
285
	 * @param string $circleUniqueId
286
	 * @param int $level
287
	 */
288
	private function includeGroupMembers(array &$members, $circleUniqueId, $level) {
289
		$groupMembers = $this->forceGetGroupMembers($circleUniqueId, $level);
290
		$this->avoidDuplicateMembers($members, $groupMembers);
291
	}
292
293
294
	/**
295
	 * avoidDuplicateMembers();
296
	 *
297
	 * Use this function to add members to the list (1st argument), keeping the higher level in case
298
	 * of duplicate
299
	 *
300
	 * @param Member[] $members
301
	 * @param Member[] $groupMembers
302
	 */
303
	public function avoidDuplicateMembers(array &$members, array $groupMembers) {
304
		foreach ($groupMembers as $member) {
305
			$index = $this->indexOfMember($members, $member->getUserId());
306
			if ($index === -1) {
307
				array_push($members, $member);
308
			} else if ($members[$index]->getLevel() < $member->getLevel()) {
309
				$members[$index] = $member;
310
			}
311
		}
312
	}
313
314
315
	/**
316
	 * returns the index of a specific UserID in a Members List
317
	 *
318
	 * @param array $members
319
	 * @param $userId
320
	 *
321
	 * @return int
322
	 */
323
	private function indexOfMember(array $members, $userId) {
324
325
		foreach ($members as $k => $member) {
326
			if ($member->getUserId() === $userId) {
327
				return intval($k);
328
			}
329
		}
330
331
		return -1;
332
	}
333
334
335
	/**
336
	 * Check if a fresh member can be generated (by addMember/joinCircle)
337
	 *
338
	 * @param string $circleUniqueId
339
	 * @param string $name
340
	 * @param int $type
341
	 *
342
	 * @param string $instance
343
	 *
344
	 * @return Member
345
	 */
346
	public function getFreshNewMember($circleUniqueId, string $name, int $type, string $instance) {
347
348
		try {
349
			$member = $this->forceGetMember($circleUniqueId, $name, $type, $instance);
350
		} catch (MemberDoesNotExistException $e) {
351
			$member = new Member($name, $type, $circleUniqueId);
352
			$member->setInstance($instance);
353
//			$member->setMemberId($this->token(14));
354
		}
355
356
//		if ($member->alreadyExistOrJoining()) {
357
//			throw new MemberAlreadyExistsException(
358
//				$this->l10n->t('This user is already a member of the circle')
359
//			);
360
//		}
361
362
		return $member;
363
	}
364
365
366
	/**
367
	 * Returns members list of all Group Members of a Circle. The Level of the linked group will be
368
	 * assigned to each entry
369
	 *
370
	 * NOTE: Can contains duplicate.
371
	 *
372
	 * WARNING: This function does not filters data regarding the current user/viewer.
373
	 *          Do not use in case of direct interaction with users.
374
	 *
375
	 * @param string $circleUniqueId
376
	 * @param int $level
377
	 *
378
	 * @return Member[]
379
	 */
380
	public function forceGetGroupMembers($circleUniqueId, $level = Member::LEVEL_MEMBER) {
381
		$qb = $this->getMembersSelectSql();
382
383
		$this->limitToUserType($qb, Member::TYPE_GROUP);
384
		$this->limitToLevel($qb, $level);
385
		$this->limitToCircleId($qb, $circleUniqueId);
386
		$this->limitToNCGroupUser($qb);
387
388
		$members = [];
389
		$cursor = $qb->execute();
390
		while ($data = $cursor->fetch()) {
391
			$members[] = $this->parseGroupsSelectSql($data);
392
		}
393
		$cursor->closeCursor();
394
395
		return $members;
396
	}
397
398
399
	/**
400
	 * returns all users from a Group as a list of Members.
401
	 *
402
	 * @param Member $group
403
	 *
404
	 * @return Member[]
405
	 */
406
	public function getGroupMemberMembers(Member $group) {
407
		/** @var IGroup $grp */
408
		$grp = $this->groupManager->get($group->getUserId());
409
		if ($grp === null) {
410
			return [];
411
		}
412
413
		$members = [];
414
		$users = $grp->getUsers();
415
		foreach ($users as $user) {
416
			$member = clone $group;
417
			//Member::fromJSON($this->l10n, json_encode($group));
418
			$member->setType(Member::TYPE_USER);
419
			$member->setUserId($user->getUID());
420
			$members[] = $member;
421
		}
422
423
		return $members;
424
	}
425
426
427
	/**
428
	 * return the higher level group linked to a circle, that include the userId.
429
	 *
430
	 * WARNING: This function does not filters data regarding the current user/viewer.
431
	 *          In case of direct interaction with users, Please don't use this.
432
	 *
433
	 * @param string $circleUniqueId
434
	 * @param string $userId
435
	 *
436
	 * @return Member
437
	 */
438
	public function forceGetHigherLevelGroupFromUser($circleUniqueId, $userId) {
439
		$qb = $this->getMembersSelectSql();
440
441
		$this->limitToUserType($qb, Member::TYPE_GROUP);
442
		$this->limitToInstance($qb, '');
443
		$this->limitToCircleId($qb, $circleUniqueId);
444
		$this->limitToNCGroupUser($qb);
445
446
		$this->limitToNCGroupUser($qb, $userId);
447
448
		/** @var Member $group */
449
		$group = null;
450
451
		$cursor = $qb->execute();
452
		while ($data = $cursor->fetch()) {
453
			$entry = $this->parseGroupsSelectSql($data);
454
			if ($group === null || $entry->getLevel() > $group->getLevel()) {
455
				$group = $entry;
456
			}
457
		}
458
		$cursor->closeCursor();
459
460
		return $group;
461
	}
462
463
464
	/**
465
	 * Insert Member into database.
466
	 *
467
	 * @param Member $member
468
	 *
469
	 * @throws MemberAlreadyExistsException
470
	 */
471
	public function createMember(Member $member) {
472
473
		if ($member->getMemberId() === '') {
474
			$member->setMemberId($this->token(14));
475
		}
476
477
		$instance = $member->getInstance();
478
		if ($instance === $this->configService->getLocalCloudId()) {
479
			$instance = '';
480
		}
481
482
		try {
483
			$qb = $this->getMembersInsertSql();
484
			$qb->setValue('circle_id', $qb->createNamedParameter($member->getCircleId()))
485
			   ->setValue('user_id', $qb->createNamedParameter($member->getUserId()))
486
			   ->setValue('member_id', $qb->createNamedParameter($member->getMemberId()))
487
			   ->setValue('user_type', $qb->createNamedParameter($member->getType()))
488
			   ->setValue('cached_name', $qb->createNamedParameter($member->getCachedName()))
489
			   ->setValue('instance', $qb->createNamedParameter($instance))
490
			   ->setValue('level', $qb->createNamedParameter($member->getLevel()))
491
			   ->setValue('status', $qb->createNamedParameter($member->getStatus()))
492
			   ->setValue('contact_id', $qb->createNamedParameter($member->getContactId()))
493
			   ->setValue('note', $qb->createNamedParameter($member->getNote()));
494
495
			$qb->execute();
496
		} catch (UniqueConstraintViolationException $e) {
0 ignored issues
show
Bug introduced by
The class Doctrine\DBAL\Exception\...raintViolationException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
497
			throw new MemberAlreadyExistsException(
498
				$this->l10n->t('This user is already a member of the circle')
499
			);
500
		}
501
	}
502
503
504
	/**
505
	 * @param string $circleUniqueId
506
	 * @param Member $viewer
507
	 *
508
	 * @return Member[]
509
	 */
510
	public function getGroupsFromCircle($circleUniqueId, Member $viewer) {
511
		if ($viewer->getLevel() < Member::LEVEL_MEMBER) {
512
			return [];
513
		}
514
515
		$qb = $this->getMembersSelectSql();
516
517
		$this->limitToUserType($qb, Member::TYPE_GROUP);
518
		$this->limitToLevel($qb, Member::LEVEL_MEMBER);
519
		$this->limitToInstance($qb, '');
520
		$this->limitToCircleId($qb, $circleUniqueId);
521
522
		$cursor = $qb->execute();
523
		$groups = [];
524
		while ($data = $cursor->fetch()) {
525
			if ($viewer->getLevel() < Member::LEVEL_MODERATOR) {
526
				$data['note'] = '';
527
			}
528
			$groups[] = $this->parseGroupsSelectSql($data);
529
		}
530
		$cursor->closeCursor();
531
532
		return $groups;
533
	}
534
535
536
	/**
537
	 * update database entry for a specific Member.
538
	 *
539
	 * @param Member $member
540
	 */
541
	public function updateMemberLevel(Member $member) {
542
		$instance = $member->getInstance();
543
		if ($instance === $this->configService->getLocalCloudId()) {
544
			$instance = '';
545
		}
546
547
		$qb = $this->getMembersUpdateSql(
548
			$member->getCircleId(), $member->getUserId(), $instance, $member->getType()
549
		);
550
		$qb->set('level', $qb->createNamedParameter($member->getLevel()))
551
		   ->set('status', $qb->createNamedParameter($member->getStatus()));
552
553
		$qb->execute();
554
	}
555
556
557
	/**
558
	 * update database entry for a specific Member.
559
	 *
560
	 * @param Member $member
561
	 */
562
	public function updateMemberInfo(Member $member) {
563
		$instance = $member->getInstance();
564
		if ($instance === $this->configService->getLocalCloudId()) {
565
			$instance = '';
566
		}
567
568
		$qb = $this->getMembersUpdateSql(
569
			$member->getCircleId(), $member->getUserId(), $instance, $member->getType()
570
		);
571
		$qb->set('note', $qb->createNamedParameter($member->getNote()))
572
		   ->set('cached_name', $qb->createNamedParameter($member->getCachedName()));
573
574
		$qb->execute();
575
	}
576
577
578
	/**
579
	 * update database entry for a specific Member.
580
	 *
581
	 * @param Member $member
582
	 */
583
	public function updateContactMeta(Member $member) {
584
		$qb = $this->getMembersUpdateSql(
585
			$member->getCircleId(), $member->getUserId(), $member->getInstance(), $member->getType()
586
		);
587
		$qb->set('contact_meta', $qb->createNamedParameter(json_encode($member->getContactMeta())));
588
589
		$qb->execute();
590
	}
591
592
593
	/**
594
	 * removeAllFromCircle();
595
	 *
596
	 * Remove All members from a Circle. Used when deleting a Circle.
597
	 *
598
	 * @param string $uniqueCircleId
599
	 */
600
	public function removeAllFromCircle($uniqueCircleId) {
601
		$qb = $this->getMembersDeleteSql();
602
		$expr = $qb->expr();
603
604
		$qb->where($expr->eq('circle_id', $qb->createNamedParameter($uniqueCircleId)));
605
		$qb->execute();
606
	}
607
608
609
	/**
610
	 * removeAllMembershipsFromUser();
611
	 *
612
	 * remove All membership from a User. Used when removing a User from the Cloud.
613
	 *
614
	 * @param Member $member
615
	 */
616
	public function removeAllMembershipsFromUser(Member $member) {
617
		if ($member->getUserId() === '') {
618
			return;
619
		}
620
621
		$instance = $member->getInstance();
622
		if ($instance === $this->configService->getLocalCloudId()) {
623
			$instance = '';
624
		}
625
626
		$qb = $this->getMembersDeleteSql();
627
		$expr = $qb->expr();
628
629
		$qb->where(
630
			$expr->andX(
631
				$expr->eq('user_id', $qb->createNamedParameter($member->getUserId())),
632
				$expr->eq('instance', $qb->createNamedParameter($instance)),
633
				$expr->eq('user_type', $qb->createNamedParameter(Member::TYPE_USER))
634
			)
635
		);
636
637
		$qb->execute();
638
	}
639
640
641
	/**
642
	 * remove member, identified by its id, type and circleId
643
	 *
644
	 * @param Member $member
645
	 */
646
	public function removeMember(Member $member) {
647
		$instance = $member->getInstance();
648
		if ($instance === $this->configService->getLocalCloudId()) {
649
			$instance = '';
650
		}
651
652
		$qb = $this->getMembersDeleteSql();
653
		$this->limitToCircleId($qb, $member->getCircleId());
654
		$this->limitToUserId($qb, $member->getUserId());
655
		$this->limitToInstance($qb, $instance);
656
		$this->limitToUserType($qb, $member->getType());
657
		if ($member->getContactId() !== '') {
658
			$this->limitToContactId($qb, $member->getContactId());
659
		}
660
661
		$qb->execute();
662
	}
663
664
	/**
665
	 * update database entry for a specific Group.
666
	 *
667
	 * @param Member $member
668
	 *
669
	 * @return bool
670
	 */
671
	public function updateGroup(Member $member) {
672
		$qb = $this->getMembersUpdateSql(
673
			$member->getCircleId(), $member->getUserId(), $member->getInstance(), $member->getType()
674
		);
675
		$qb->set('level', $qb->createNamedParameter($member->getLevel()));
676
		$qb->execute();
677
678
		return true;
679
	}
680
681
682
	public function unlinkAllFromGroup($groupId) {
683
		$qb = $this->getMembersDeleteSql();
684
685
		$this->limitToUserId($qb, $groupId);
686
		$this->limitToUserType($qb, Member::TYPE_GROUP);
687
		$this->limitToInstance($qb, '');
688
689
		$qb->execute();
690
	}
691
692
693
	/**
694
	 * @param string $contactId
695
	 *
696
	 * @return Member[]
697
	 */
698
	public function getMembersByContactId(string $contactId = ''): array {
699
		$qb = $this->getMembersSelectSql();
700
		if ($contactId === '') {
701
			$expr = $qb->expr();
702
			$qb->andWhere($expr->neq('contact_id', $qb->createNamedParameter('')));
703
		} else {
704
			$this->limitToContactId($qb, $contactId);
705
		}
706
707
		$members = [];
708
		$cursor = $qb->execute();
709
		while ($data = $cursor->fetch()) {
710
			$member = $this->parseMembersSelectSql($data);
711
			$members[] = $member;
712
		}
713
		$cursor->closeCursor();
714
715
		return $members;
716
	}
717
718
719
	/**
720
	 * @param string $circleId
721
	 * @param string $contactId
722
	 *
723
	 * @return Member
724
	 * @throws MemberDoesNotExistException
725
	 */
726
	public function getContactMember(string $circleId, string $contactId): Member {
727
		$qb = $this->getMembersSelectSql();
728
		$this->limitToContactId($qb, $contactId);
729
		$this->limitToCircleId($qb, $circleId);
730
731
		$cursor = $qb->execute();
732
		$data = $cursor->fetch();
733
		$cursor->closeCursor();
734
735
		if ($data === false) {
736
			throw new MemberDoesNotExistException($this->l10n->t('This member does not exist'));
737
		}
738
739
		return $this->parseMembersSelectSql($data);
740
	}
741
742
743
	/**
744
	 * @param string $contactId
745
	 *
746
	 * @return Member[]
747
	 */
748
	public function getLocalContactMembers(string $contactId): array {
749
		$qb = $this->getMembersSelectSql();
750
		$this->limitToContactId($qb, $contactId);
751
		$this->limitToUserType($qb, Member::TYPE_USER);
752
753
		$members = [];
754
		$cursor = $qb->execute();
755
		while ($data = $cursor->fetch()) {
756
			$members[] = $this->parseMembersSelectSql($data);
757
		}
758
		$cursor->closeCursor();
759
760
		return $members;
761
	}
762
763
764
	/**
765
	 * @param string $contactId
766
	 * @param int $type
767
	 */
768
	public function removeMembersByContactId(string $contactId, int $type = 0) {
769
		$this->miscService->log($contactId);
770
		if ($contactId === '') {
771
			return;
772
		}
773
774
		$qb = $this->getMembersDeleteSql();
775
		$this->limitToContactId($qb, $contactId);
776
		if ($type > 0) {
777
			$this->limitToUserType($qb, $type);
778
		}
779
780
		$qb->execute();
781
	}
782
783
784
}
785