Completed
Push — master ( 8dabac...269796 )
by Maxence
02:53 queued 11s
created

CoreQueryBuilder::leftJoinBasedOn()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 26
rs 9.504
c 0
b 0
f 0
cc 4
nc 4
nop 2
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\Db;
33
34
35
use daita\MySmallPhpTools\Db\Nextcloud\nc22\NC22ExtendedQueryBuilder;
36
use daita\MySmallPhpTools\Traits\TArrayTools;
37
use Doctrine\DBAL\Query\QueryBuilder;
38
use OC;
39
use OCA\Circles\Exceptions\RequestBuilderException;
40
use OCA\Circles\IFederatedModel;
41
use OCA\Circles\IFederatedUser;
42
use OCA\Circles\Model\Circle;
43
use OCA\Circles\Model\Federated\RemoteInstance;
44
use OCA\Circles\Model\FederatedUser;
45
use OCA\Circles\Model\Member;
46
use OCA\Circles\Service\ConfigService;
47
use OCP\DB\QueryBuilder\ICompositeExpression;
48
49
50
/**
51
 * Class CoreRequestBuilder
52
 *
53
 * @package OCA\Circles\Db
54
 */
55
class CoreQueryBuilder extends NC22ExtendedQueryBuilder {
56
57
58
	use TArrayTools;
59
60
61
	const SINGLE = 'single';
62
	const CIRCLE = 'circle';
63
	const MEMBER = 'member';
64
	const OWNER = 'owner';
65
	const FEDERATED_EVENT = 'federatedEvent';
66
	const REMOTE = 'remote';
67
	const BASED_ON = 'basedOn';
68
	const INITIATOR = 'initiator';
69
	const MEMBERSHIPS = 'memberships';
70
	const UPSTREAM_MEMBERSHIPS = 'upstreamMemberships';
71
	const INHERITANCE_FROM = 'inheritanceFrom';
72
	const INHERITED_BY = 'inheritedBy';
73
	const MOUNT = 'mount';
74
	const MOUNTPOINT = 'mountpoint';
75
	const SHARE = 'share';
76
	const FILE_CACHE = 'fileCache';
77
	const STORAGES = 'storages';
78
	const OPTIONS = 'options';
79
80
81
	public static $SQL_PATH = [
82
		self::SINGLE => [
83
			self::MEMBER
84
		],
85
		self::CIRCLE => [
86
			self::OPTIONS   => [
87
				'getPersonalCircle' => true
88
			],
89
			self::MEMBER,
90
			self::OWNER     => [
91
				self::BASED_ON
92
			],
93
			self::MEMBERSHIPS,
94
			self::INITIATOR => [
95
				self::BASED_ON,
96
				self::INHERITED_BY => [
97
					self::MEMBERSHIPS
98
				]
99
			],
100
			self::REMOTE    => [
101
				self::MEMBER,
102
				self::CIRCLE => [
103
					self::OWNER
104
				]
105
			]
106
		],
107
		self::MEMBER => [
108
			self::MEMBERSHIPS,
109
			self::INHERITANCE_FROM,
110
			self::CIRCLE   => [
111
				self::OPTIONS   => [
112
					'getData' => true
113
				],
114
				self::OWNER,
115
				self::MEMBERSHIPS,
116
				self::INITIATOR => [
117
					self::OPTIONS      => [
118
						'mustBeMember' => true,
119
						'canBeVisitor' => false
120
					],
121
					self::BASED_ON,
122
					self::INHERITED_BY => [
123
						self::MEMBERSHIPS
124
					]
125
				]
126
			],
127
			self::BASED_ON => [
128
				self::OWNER,
129
				self::MEMBERSHIPS,
130
				self::INITIATOR => [
131
					self::BASED_ON,
132
					self::INHERITED_BY => [
133
						self::MEMBERSHIPS
134
					]
135
				]
136
			],
137
			self::REMOTE   => [
138
				self::MEMBER,
139
				self::CIRCLE => [
140
					self::OWNER
141
				]
142
			]
143
		],
144
		self::SHARE  => [
145
			self::SHARE,
146
			self::FILE_CACHE           => [
147
				self::STORAGES
148
			],
149
			self::UPSTREAM_MEMBERSHIPS => [
150
				self::MEMBERSHIPS,
151
				self::INHERITED_BY => [
152
					self::BASED_ON
153
				],
154
				self::SHARE,
155
			],
156
			self::MEMBERSHIPS,
157
			self::INHERITANCE_FROM,
158
			self::INHERITED_BY         => [
159
				self::BASED_ON
160
			],
161
			self::CIRCLE               => [
162
				self::OWNER
163
			],
164
			self::INITIATOR            => [
165
				self::BASED_ON,
166
				self::INHERITED_BY => [
167
					self::MEMBERSHIPS
168
				]
169
			]
170
		],
171
		self::REMOTE => [
172
			self::MEMBER
173
		],
174
		self::MOUNT  => [
175
			self::MEMBER    => [
176
				self::REMOTE
177
			],
178
			self::INITIATOR => [
179
				self::INHERITED_BY => [
180
					self::MEMBERSHIPS
181
				]
182
			],
183
			self::MOUNTPOINT,
184
			self::MEMBERSHIPS
185
		]
186
	];
187
188
189
	/** @var ConfigService */
190
	private $configService;
191
192
193
	/** @var array */
194
	private $options = [];
195
196
197
	/**
198
	 * CoreRequestBuilder constructor.
199
	 */
200
	public function __construct() {
201
		parent::__construct();
202
203
		$this->configService = OC::$server->get(ConfigService::class);
204
	}
205
206
207
	/**
208
	 * @param IFederatedModel $federatedModel
209
	 *
210
	 * @return string
211
	 */
212
	public function getInstance(IFederatedModel $federatedModel): string {
213
		$instance = $federatedModel->getInstance();
214
215
		return ($this->configService->isLocalInstance($instance)) ? '' : $instance;
216
	}
217
218
219
	/**
220
	 * @param string $id
221
	 */
222
	public function limitToCircleId(string $id): void {
223
		$this->limitToDBField('circle_id', $id, true);
224
	}
225
226
	/**
227
	 * @param string $name
228
	 */
229
	public function limitToName(string $name): void {
230
		$this->limitToDBField('name', $name);
231
	}
232
233
	/**
234
	 * @param int $config
235
	 */
236
	public function limitToConfig(int $config): void {
237
		$this->limitToDBFieldInt('config', $config);
238
	}
239
240
	/**
241
	 * @param int $source
242
	 */
243
	public function limitToSource(int $source): void {
244
		$this->limitToDBFieldInt('source', $source);
245
	}
246
247
	/**
248
	 * @param int $config
249
	 */
250
	public function limitToConfigFlag(int $config): void {
251
		$this->andWhere($this->expr()->bitwiseAnd($this->getDefaultSelectAlias() . '.config', $config));
252
	}
253
254
255
	/**
256
	 * @param string $singleId
257
	 */
258
	public function limitToSingleId(string $singleId): void {
259
		$this->limitToDBField('single_id', $singleId, true);
260
	}
261
262
263
	/**
264
	 * @param string $itemId
265
	 */
266
	public function limitToItemId(string $itemId): void {
267
		$this->limitToDBField('item_id', $itemId, true);
268
	}
269
270
271
	/**
272
	 * @param string $host
273
	 */
274
	public function limitToInstance(string $host): void {
275
		$this->limitToDBField('instance', $host, false);
276
	}
277
278
279
	/**
280
	 * @param int $userType
281
	 */
282
	public function limitToUserType(int $userType): void {
283
		$this->limitToDBFieldInt('user_type', $userType);
284
	}
285
286
287
	/**
288
	 * @param int $shareType
289
	 */
290
	public function limitToShareType(int $shareType): void {
291
		$this->limitToDBFieldInt('share_type', $shareType);
292
	}
293
294
295
	/**
296
	 * @param string $shareWith
297
	 */
298
	public function limitToShareWith(string $shareWith): void {
299
		$this->limitToDBField('share_with', $shareWith);
300
	}
301
302
303
	/**
304
	 * @param int $nodeId
305
	 */
306
	public function limitToFileSource(int $nodeId): void {
307
		$this->limitToDBFieldInt('file_source', $nodeId);
308
	}
309
310
	/**
311
	 * @param array $files
312
	 */
313
	public function limitToFileSourceArray(array $files): void {
314
		$this->limitToDBFieldInArray('file_source', $files);
315
	}
316
317
318
	/**
319
	 * @param int $shareId
320
	 */
321
	public function limitToShareParent(int $shareId): void {
322
		$this->limitToDBFieldInt('parent', $shareId);
323
	}
324
325
326
	/**
327
	 * @param Circle $circle
328
	 */
329
	public function filterCircle(Circle $circle): void {
330
		if ($this->getType() !== QueryBuilder::SELECT) {
331
			return;
332
		}
333
334
		if ($circle->getDisplayName() !== '') {
335
			$this->searchInDBField('display_name', '%' . $circle->getDisplayName() . '%');
336
		}
337
	}
338
339
340
	/**
341
	 * left join RemoteInstance based on a Member
342
	 */
343
	public function leftJoinRemoteInstance(string $alias): void {
344
		$expr = $this->expr();
345
346
		try {
347
			$aliasRemoteInstance = $this->generateAlias($alias, self::REMOTE);
348
			$this->generateRemoteInstanceSelectAlias($aliasRemoteInstance)
349
				 ->leftJoin(
350
					 $alias, CoreRequestBuilder::TABLE_REMOTE, $aliasRemoteInstance,
351
					 $expr->eq($alias . '.instance', $aliasRemoteInstance . '.instance')
352
				 );
353
		} catch (RequestBuilderException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
354
		}
355
	}
356
357
358
	/**
359
	 * @param string $alias
360
	 * @param RemoteInstance $remoteInstance
361
	 * @param bool $filterSensitiveData
362
	 * @param string $aliasCircle
363
	 *
364
	 * @throws RequestBuilderException
365
	 */
366
	public function limitToRemoteInstance(
367
		string $alias,
368
		RemoteInstance $remoteInstance,
369
		bool $filterSensitiveData = true,
370
		string $aliasCircle = ''
371
	): void {
372
373
		if ($aliasCircle === '') {
374
			$aliasCircle = $alias;
375
		}
376
377
		$this->leftJoinRemoteInstanceIncomingRequest($alias, $remoteInstance);
378
		$this->leftJoinMemberFromInstance($alias, $remoteInstance, $aliasCircle);
379
		$this->leftJoinMemberFromRemoteCircle($alias, $remoteInstance, $aliasCircle);
380
		$this->limitRemoteVisibility($alias, $filterSensitiveData, $aliasCircle);
381
	}
382
383
384
	/**
385
	 * Left join RemoteInstance based on an incoming request
386
	 *
387
	 * @param string $alias
388
	 * @param RemoteInstance $remoteInstance
389
	 *
390
	 * @throws RequestBuilderException
391
	 */
392
	public function leftJoinRemoteInstanceIncomingRequest(
393
		string $alias,
394
		RemoteInstance $remoteInstance
395
	): void {
396
		if ($this->getType() !== QueryBuilder::SELECT) {
397
			return;
398
		}
399
400
		$aliasRemote = $this->generateAlias($alias, self::REMOTE);
401
		$expr = $this->expr();
402
		$this->leftJoin(
403
			$this->getDefaultSelectAlias(), CoreRequestBuilder::TABLE_REMOTE, $aliasRemote,
404
			$expr->eq($aliasRemote . '.instance', $this->createNamedParameter($remoteInstance->getInstance()))
405
		);
406
	}
407
408
409
	/**
410
	 * left join members to check memberships of someone from instance
411
	 *
412
	 * @param string $alias
413
	 * @param RemoteInstance $remoteInstance
414
	 * @param string $aliasCircle
415
	 *
416
	 * @throws RequestBuilderException
417
	 */
418
	private function leftJoinMemberFromInstance(
419
		string $alias, RemoteInstance $remoteInstance, string $aliasCircle
420
	) {
421
		if ($this->getType() !== QueryBuilder::SELECT) {
422
			return;
423
		}
424
425
		$aliasRemote = $this->generateAlias($alias, self::REMOTE);
426
		$aliasRemoteMember = $this->generateAlias($aliasRemote, self::MEMBER);
427
428
		$expr = $this->expr();
429
		$this->leftJoin(
430
			$this->getDefaultSelectAlias(), CoreRequestBuilder::TABLE_MEMBER, $aliasRemoteMember,
431
			$expr->andX(
432
				$expr->eq($aliasRemoteMember . '.circle_id', $aliasCircle . '.unique_id'),
433
				$expr->eq(
434
					$aliasRemoteMember . '.instance',
435
					$this->createNamedParameter($remoteInstance->getInstance())
436
				),
437
				$expr->gte($aliasRemoteMember . '.level', $this->createNamedParameter(Member::LEVEL_MEMBER))
438
			)
439
		);
440
	}
441
442
443
	/**
444
	 * left join circle is member of a circle from remote instance
445
	 *
446
	 * @param string $alias
447
	 * @param RemoteInstance $remoteInstance
448
	 * @param string $aliasCircle
449
	 *
450
	 * @throws RequestBuilderException
451
	 */
452
	private function leftJoinMemberFromRemoteCircle(
453
		string $alias,
454
		RemoteInstance $remoteInstance,
455
		string $aliasCircle
456
	) {
457
		if ($this->getType() !== QueryBuilder::SELECT) {
458
			return;
459
		}
460
461
		$aliasRemote = $this->generateAlias($alias, self::REMOTE);
462
		$aliasRemoteCircle = $this->generateAlias($aliasRemote, self::CIRCLE);
463
		$aliasRemoteCircleOwner = $this->generateAlias($aliasRemoteCircle, self::OWNER);
464
465
		$expr = $this->expr();
466
		$this->leftJoin(
467
			$this->getDefaultSelectAlias(), CoreRequestBuilder::TABLE_MEMBER, $aliasRemoteCircle,
468
			$expr->andX(
469
				$expr->eq($aliasRemoteCircle . '.single_id', $aliasCircle . '.unique_id'),
470
				$expr->emptyString($aliasRemoteCircle . '.instance'),
471
				$expr->gte($aliasRemoteCircle . '.level', $this->createNamedParameter(Member::LEVEL_MEMBER))
472
			)
473
		);
474
		$this->leftJoin(
475
			$this->getDefaultSelectAlias(), CoreRequestBuilder::TABLE_MEMBER, $aliasRemoteCircleOwner,
476
			$expr->andX(
477
				$expr->eq($aliasRemoteCircle . '.circle_id', $aliasRemoteCircleOwner . '.circle_id'),
478
				$expr->eq(
479
					$aliasRemoteCircleOwner . '.instance',
480
					$this->createNamedParameter($remoteInstance->getInstance())
481
				),
482
				$expr->eq(
483
					$aliasRemoteCircleOwner . '.level', $this->createNamedParameter(Member::LEVEL_OWNER)
484
				)
485
			)
486
		);
487
	}
488
489
490
	/**
491
	 * - global_scale: visibility on all Circles
492
	 * - trusted: visibility on all FEDERATED Circle if owner is local
493
	 * - external: visibility on all FEDERATED Circle if owner is local and:
494
	 *    - with if Circle contains at least one member from the remote instance
495
	 *    - one circle from the remote instance contains the local circle as member, and confirmed (using
496
	 *      sync locally)
497
	 * - passive: like external, but the members list will only contains member from the local instance and
498
	 * from the remote instance.
499
	 *
500
	 * @param string $alias
501
	 * @param bool $sensitive
502
	 * @param string $aliasCircle
503
	 *
504
	 * @throws RequestBuilderException
505
	 */
506
	protected function limitRemoteVisibility(string $alias, bool $sensitive, string $aliasCircle) {
507
		$aliasRemote = $this->generateAlias($alias, self::REMOTE);
508
		$aliasOwner = $this->generateAlias($aliasCircle, self::OWNER);
509
		$aliasRemoteMember = $this->generateAlias($aliasRemote, self::MEMBER);
510
		$aliasRemoteCircle = $this->generateAlias($aliasRemote, self::CIRCLE);
511
		$aliasRemoteCircleOwner = $this->generateAlias($aliasRemoteCircle, self::OWNER);
512
513
		$expr = $this->expr();
514
		$orX = $expr->orX();
515
		$orX->add(
516
			$expr->eq($aliasRemote . '.type', $this->createNamedParameter(RemoteInstance::TYPE_GLOBALSCALE))
517
		);
518
519
		$orExtOrPassive = $expr->orX();
520
		$orExtOrPassive->add(
521
			$expr->eq($aliasRemote . '.type', $this->createNamedParameter(RemoteInstance::TYPE_EXTERNAL))
522
		);
523
		if (!$sensitive) {
524
			$orExtOrPassive->add(
525
				$expr->eq($aliasRemote . '.type', $this->createNamedParameter(RemoteInstance::TYPE_PASSIVE))
526
			);
527
		} else {
528
			if ($this->getDefaultSelectAlias() === CoreQueryBuilder::MEMBER) {
529
				$orExtOrPassive->add($this->limitRemoteVisibility_Sensitive_Members($aliasRemote));
530
			}
531
		}
532
533
		$orInstance = $expr->orX();
534
		$orInstance->add($expr->isNotNull($aliasRemoteMember . '.instance'));
535
		$orInstance->add($expr->isNotNull($aliasRemoteCircleOwner . '.instance'));
536
537
		$andExternal = $expr->andX();
538
		$andExternal->add($orExtOrPassive);
539
		$andExternal->add($orInstance);
540
541
		$orExtOrTrusted = $expr->orX();
542
		$orExtOrTrusted->add($andExternal);
543
		$orExtOrTrusted->add(
544
			$expr->eq($aliasRemote . '.type', $this->createNamedParameter(RemoteInstance::TYPE_TRUSTED))
545
		);
546
547
		$andTrusted = $expr->andX();
548
		$andTrusted->add($orExtOrTrusted);
549
		$andTrusted->add($expr->bitwiseAnd($aliasCircle . '.config', Circle::CFG_FEDERATED));
550
		$andTrusted->add($expr->emptyString($aliasOwner . '.instance'));
551
		$orX->add($andTrusted);
552
553
		$this->andWhere($orX);
554
	}
555
556
557
	/**
558
	 * @param string $alias
559
	 * @param Member $member
560
	 *
561
	 * @throws RequestBuilderException
562
	 */
563
	public function limitToDirectMembership(string $alias, Member $member): void {
564
		if ($this->getType() !== QueryBuilder::SELECT) {
565
			return;
566
		}
567
568
		$aliasMember = $this->generateAlias($alias, self::MEMBER, $options);
569
		$getData = $this->getBool('getData', $options, false);
570
571
		$expr = $this->expr();
572
		if ($getData) {
573
			$this->generateMemberSelectAlias($aliasMember);
574
		}
575
		$this->leftJoin(
576
			$this->getDefaultSelectAlias(), CoreRequestBuilder::TABLE_MEMBER, $aliasMember,
577
			$expr->eq($aliasMember . '.circle_id', $alias . '.unique_id')
578
		);
579
580
		$this->filterDirectMembership($aliasMember, $member);
581
	}
582
583
584
	/**
585
	 * @param string $aliasMember
586
	 * @param Member $member
587
	 */
588
	public function filterDirectMembership(string $aliasMember, Member $member): void {
589
		if ($this->getType() !== QueryBuilder::SELECT) {
590
			return;
591
		}
592
593
		$expr = $this->expr();
594
		$andX = $expr->andX();
595
596
		if ($member->getUserId() !== '') {
597
			$andX->add(
598
				$expr->eq($aliasMember . '.user_id', $this->createNamedParameter($member->getUserId()))
599
			);
600
		}
601
602
		if ($member->getSingleId() !== '') {
603
			$andX->add(
604
				$expr->eq($aliasMember . '.single_id', $this->createNamedParameter($member->getSingleId()))
605
			);
606
		}
607
608
		if ($member->getUserType() > 0) {
609
			$andX->add(
610
				$expr->eq($aliasMember . '.user_type', $this->createNamedParameter($member->getUserType()))
611
			);
612
		}
613
614
		$andX->add(
615
			$expr->eq($aliasMember . '.instance', $this->createNamedParameter($this->getInstance($member)))
616
		);
617
618
		if ($member->getLevel() > 0) {
619
			$andX->add($expr->gte($aliasMember . '.level', $this->createNamedParameter($member->getLevel())));
620
		}
621
622
		$this->andWhere($andX);
623
	}
624
625
626
	/**
627
	 * @param string $alias
628
	 * @param IFederatedUser|null $initiator
629
	 * @param string $field
630
	 *
631
	 * @throws RequestBuilderException
632
	 */
633
	public function leftJoinCircle(
634
		string $alias,
635
		?IFederatedUser $initiator = null,
636
		string $field = 'circle_id'
637
	): void {
638
		if ($this->getType() !== QueryBuilder::SELECT) {
639
			return;
640
		}
641
642
		$aliasCircle = $this->generateAlias($alias, self::CIRCLE, $options);
643
		$getData = $this->getBool('getData', $options, false);
644
		$expr = $this->expr();
645
646
		if ($getData) {
647
			$this->generateCircleSelectAlias($aliasCircle);
648
		}
649
650
		$this->leftJoin(
651
			$alias, CoreRequestBuilder::TABLE_CIRCLE, $aliasCircle,
652
			$expr->eq($aliasCircle . '.unique_id', $alias . '.' . $field)
653
		);
654
655
		if (!is_null($initiator)) {
656
			$this->limitToInitiator($aliasCircle, $initiator);
657
		}
658
659
		$this->leftJoinOwner($aliasCircle);
660
	}
661
662
663
	/**
664
	 * @param string $aliasMember
665
	 * @param IFederatedUser|null $initiator
666
	 *
667
	 * @throws RequestBuilderException
668
	 */
669
	public function leftJoinBasedOn(
670
		string $aliasMember,
671
		?IFederatedUser $initiator = null
672
	): void {
673
		if ($this->getType() !== QueryBuilder::SELECT) {
674
			return;
675
		}
676
677
		try {
678
			$aliasBasedOn = $this->generateAlias($aliasMember, self::BASED_ON, $options);
679
		} catch (RequestBuilderException $e) {
680
			return;
681
		}
682
683
		$expr = $this->expr();
684
		$this->generateCircleSelectAlias($aliasBasedOn)
685
			 ->leftJoin(
686
				 $aliasMember, CoreRequestBuilder::TABLE_CIRCLE, $aliasBasedOn,
687
				 $expr->eq($aliasBasedOn . '.unique_id', $aliasMember . '.single_id')
688
			 );
689
690
		if (!is_null($initiator)) {
691
			$this->leftJoinInitiator($aliasBasedOn, $initiator);
692
			$this->leftJoinOwner($aliasBasedOn);
693
		}
694
	}
695
696
697
	/**
698
	 * @param string $alias
699
	 * @param string $field
700
	 *
701
	 * @throws RequestBuilderException
702
	 */
703
	public function leftJoinOwner(string $alias, string $field = 'unique_id'): void {
704
		if ($this->getType() !== QueryBuilder::SELECT) {
705
			return;
706
		}
707
708
		try {
709
			$aliasMember = $this->generateAlias($alias, self::OWNER, $options);
710
			$getData = $this->getBool('getData', $options, false);
0 ignored issues
show
Unused Code introduced by
$getData is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
711
		} catch (RequestBuilderException $e) {
712
			return;
713
		}
714
715
		$expr = $this->expr();
716
		$this->generateMemberSelectAlias($aliasMember)
717
			 ->leftJoin(
718
				 $alias, CoreRequestBuilder::TABLE_MEMBER, $aliasMember,
719
				 $expr->andX(
720
					 $expr->eq($aliasMember . '.circle_id', $alias . '.' . $field),
721
					 $expr->eq(
722
						 $aliasMember . '.level',
723
						 $this->createNamedParameter(Member::LEVEL_OWNER, self::PARAM_INT)
724
					 )
725
				 )
726
			 );
727
728
		$this->leftJoinBasedOn($aliasMember);
729
	}
730
731
732
	/**
733
	 * @param string $alias
734
	 * @param string $fieldCircleId
735
	 * @param string $fieldSingleId
736
	 *
737
	 * @throws RequestBuilderException
738
	 */
739
	public function leftJoinMember(
740
		string $alias,
741
		string $fieldCircleId = 'circle_id',
742
		string $fieldSingleId = 'single_id'
743
	): void {
744
		if ($this->getType() !== QueryBuilder::SELECT) {
745
			return;
746
		}
747
748
		try {
749
			$aliasMember = $this->generateAlias($alias, self::MEMBER, $options);
750
			$getData = $this->getBool('getData', $options, false);
0 ignored issues
show
Unused Code introduced by
$getData is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
751
		} catch (RequestBuilderException $e) {
752
			return;
753
		}
754
755
		$expr = $this->expr();
756
		$this->generateMemberSelectAlias($aliasMember)
757
			 ->leftJoin(
758
				 $alias, CoreRequestBuilder::TABLE_MEMBER, $aliasMember,
759
				 $expr->andX(
760
					 $expr->eq($aliasMember . '.circle_id', $alias . '.' . $fieldCircleId),
761
					 $expr->eq($aliasMember . '.single_id', $alias . '.' . $fieldSingleId),
762
					 $expr->gte(
763
						 $aliasMember . '.level',
764
						 $this->createNamedParameter(Member::LEVEL_MEMBER, self::PARAM_INT)
765
					 )
766
				 )
767
			 );
768
769
		$this->leftJoinRemoteInstance($aliasMember);
770
		$this->leftJoinBasedOn($aliasMember);
771
	}
772
773
774
	/**
775
	 * if 'getData' is true, will returns 'inheritanceBy': the Member at the end of a sub-chain of
776
	 * memberships (based on $field for Top Circle's singleId)
777
	 *
778
	 * @param string $alias
779
	 * @param string $field
780
	 * @param string $aliasInheritedBy
781
	 *
782
	 * @throws RequestBuilderException
783
	 */
784
	public function leftJoinInheritedMembers(string $alias, string $field = '', string $aliasInheritedBy = ''
785
	): void {
786
		$expr = $this->expr();
787
788
		$field = ($field === '') ? 'circle_id' : $field;
789
		$aliasMembership = $this->generateAlias($alias, self::MEMBERSHIPS, $options);
790
791
		$this->leftJoin(
792
			$alias, CoreRequestBuilder::TABLE_MEMBERSHIP, $aliasMembership,
793
			$expr->eq($aliasMembership . '.circle_id', $alias . '.' . $field)
794
		);
795
796
//		if (!$this->getBool('getData', $options, false)) {
797
//			return;
798
//		}
799
800
		if ($aliasInheritedBy === '') {
801
			$aliasInheritedBy = $this->generateAlias($alias, self::INHERITED_BY);
802
		}
803
		$this->generateMemberSelectAlias($aliasInheritedBy)
804
			 ->leftJoin(
805
				 $alias, CoreRequestBuilder::TABLE_MEMBER, $aliasInheritedBy,
806
				 $expr->andX(
807
					 $expr->eq($aliasMembership . '.inheritance_last', $aliasInheritedBy . '.circle_id'),
808
					 $expr->eq($aliasMembership . '.single_id', $aliasInheritedBy . '.single_id')
809
				 )
810
			 );
811
812
		$this->leftJoinBasedOn($aliasInheritedBy);
813
	}
814
815
816
	/**
817
	 * @throws RequestBuilderException
818
	 */
819
	public function limitToInheritedMemberships(string $alias, string $singleId, string $field = ''): void {
820
		$expr = $this->expr();
821
		$field = ($field === '') ? 'circle_id' : $field;
822
		$aliasUpstreamMembership = $this->generateAlias($alias, self::UPSTREAM_MEMBERSHIPS, $options);
823
		$this->leftJoin(
824
			$alias, CoreRequestBuilder::TABLE_MEMBERSHIP, $aliasUpstreamMembership,
825
			$expr->eq($aliasUpstreamMembership . '.single_id', $this->createNamedParameter($singleId))
826
		);
827
828
		$orX = $expr->orX(
829
			$expr->eq($aliasUpstreamMembership . '.circle_id', $alias . '.' . $field),
830
			$expr->eq($alias . '.' . $field, $this->createNamedParameter($singleId))
831
		);
832
833
		$this->andWhere($orX);
834
	}
835
836
837
	/**
838
	 * limit the request to Members and Sub Members of a Circle.
839
	 *
840
	 * @param string $alias
841
	 * @param string $singleId
842
	 *
843
	 * @throws RequestBuilderException
844
	 */
845
	public function limitToMembersByInheritance(string $alias, string $singleId): void {
846
		$this->leftJoinMembersByInheritance($alias);
847
848
		$expr = $this->expr();
849
		$aliasMembership = $this->generateAlias($alias, self::MEMBERSHIPS);
850
		$this->andWhere($expr->eq($aliasMembership . '.circle_id', $this->createNamedParameter($singleId)));
851
	}
852
853
854
	/**
855
	 * if 'getData' is true, will returns 'inheritanceFrom': the Circle-As-Member of the Top Circle
856
	 * that explain the membership of a Member (based on $field for singleId) to a specific Circle
857
	 *
858
	 * // TODO: returns the link/path ?
859
	 *
860
	 * @param string $alias
861
	 * @param string $field
862
	 *
863
	 * @throws RequestBuilderException
864
	 */
865
	public function leftJoinMembersByInheritance(string $alias, string $field = ''): void {
866
		$expr = $this->expr();
867
868
		$field = ($field === '') ? 'circle_id' : $field;
869
		$aliasMembership = $this->generateAlias($alias, self::MEMBERSHIPS, $options);
870
871
		$this->leftJoin(
872
			$alias, CoreRequestBuilder::TABLE_MEMBERSHIP, $aliasMembership,
873
//			$expr->andX(
874
			$expr->eq($aliasMembership . '.inheritance_last', $alias . '.' . $field)
875
//				$expr->eq($aliasMembership . '.single_id', $alias . '.single_id')
876
//			)
877
		);
878
879
		if (!$this->getBool('getData', $options, false)) {
880
			return;
881
		}
882
883
		$aliasInheritanceFrom = $this->generateAlias($alias, self::INHERITANCE_FROM);
884
		$this->generateMemberSelectAlias($aliasInheritanceFrom)
885
			 ->leftJoin(
886
				 $aliasMembership, CoreRequestBuilder::TABLE_MEMBER, $aliasInheritanceFrom,
887
				 $expr->andX(
888
					 $expr->eq($aliasMembership . '.circle_id', $aliasInheritanceFrom . '.circle_id'),
889
					 $expr->eq($aliasMembership . '.inheritance_first', $aliasInheritanceFrom . '.single_id')
890
				 )
891
			 );
892
	}
893
894
895
	/**
896
	 * limit the result to the point of view of a FederatedUser
897
	 *
898
	 * @param string $alias
899
	 * @param IFederatedUser $user
900
	 * @param string $field
901
	 *
902
	 * @throws RequestBuilderException
903
	 */
904
	public function limitToInitiator(string $alias, IFederatedUser $user, string $field = ''): void {
905
		$this->leftJoinInitiator($alias, $user, $field);
906
		$this->limitInitiatorVisibility($alias);
907
908
		$aliasInitiator = $this->generateAlias($alias, self::INITIATOR, $options);
909
		if ($this->getBool('getData', $options, false)) {
910
			$this->leftJoinBasedOn($aliasInitiator);
911
		}
912
	}
913
914
915
	/**
916
	 * Left join members to filter userId as initiator.
917
	 *
918
	 * @param string $alias
919
	 * @param IFederatedUser $initiator
920
	 * @param string $field
921
	 *
922
	 * @throws RequestBuilderException
923
	 */
924
	public function leftJoinInitiator(string $alias, IFederatedUser $initiator, string $field = ''): void {
925
		if ($this->getType() !== QueryBuilder::SELECT) {
926
			return;
927
		}
928
929
		$expr = $this->expr();
930
		$field = ($field === '') ? 'unique_id' : $field;
931
		$aliasMembership = $this->generateAlias($alias, self::MEMBERSHIPS, $options);
932
933
		$this->leftJoin(
934
			$alias, CoreRequestBuilder::TABLE_MEMBERSHIP, $aliasMembership,
935
			$expr->andX(
936
				$expr->eq(
937
					$aliasMembership . '.single_id',
938
					$this->createNamedParameter($initiator->getSingleId())
939
				),
940
				$expr->eq($aliasMembership . '.circle_id', $alias . '.' . $field)
941
			)
942
		);
943
944
		if (!$this->getBool('getData', $options, false)) {
945
			return;
946
		}
947
948
		try {
949
			$aliasInitiator = $this->generateAlias($alias, self::INITIATOR, $options);
950
			$this->leftJoin(
951
				$aliasMembership, CoreRequestBuilder::TABLE_MEMBER, $aliasInitiator,
952
				$expr->andX(
953
					$expr->eq($aliasMembership . '.inheritance_first', $aliasInitiator . '.single_id'),
954
					$expr->eq($aliasMembership . '.circle_id', $aliasInitiator . '.circle_id')
955
				)
956
			);
957
958
			$aliasInheritedBy = $this->generateAlias($aliasInitiator, self::INHERITED_BY);
959
			$this->leftJoin(
960
				$aliasInitiator, CoreRequestBuilder::TABLE_MEMBER, $aliasInheritedBy,
961
				$expr->andX(
962
					$expr->eq($aliasMembership . '.single_id', $aliasInheritedBy . '.single_id'),
963
					$expr->eq($aliasMembership . '.inheritance_last', $aliasInheritedBy . '.circle_id')
964
				)
965
			);
966
967
			$default = [];
968
			if ($this->getBool('canBeVisitor', $options, false)) {
969
				$default = [
970
					'user_id'   => $initiator->getUserId(),
971
					'single_id' => $initiator->getSingleId(),
972
					'user_type' => $initiator->getUserType(),
973
					'instance'  => $initiator->getInstance()
974
				];
975
			}
976
			$this->generateMemberSelectAlias($aliasInitiator, $default);
977
978
			$this->generateMemberSelectAlias($aliasInheritedBy);
979
			$aliasInheritedByMembership = $this->generateAlias($aliasInheritedBy, self::MEMBERSHIPS);
980
			$this->generateMembershipSelectAlias($aliasMembership, $aliasInheritedByMembership);
981
		} catch (RequestBuilderException $e) {
982
			\OC::$server->getLogger()->log(3, '-- ' . $e->getMessage());
983
		}
984
	}
985
986
987
	/**
988
	 * @param string $alias
989
	 *
990
	 * @throws RequestBuilderException
991
	 */
992
	protected function limitInitiatorVisibility(string $alias) {
993
		$aliasMembership = $this->generateAlias($alias, self::MEMBERSHIPS, $options);
994
		$getPersonalCircle = $this->getBool('getPersonalCircle', $options, false);
995
996
		$expr = $this->expr();
997
998
		// Visibility to non-member is
999
		// - 0 (default), if initiator is member
1000
		// - 2 (Personal), if initiator is owner)
1001
		// - 4 (Visible to everyone)
1002
		$orX = $expr->orX();
1003
		$orX->add(
1004
			$expr->andX(
1005
				$expr->gte($aliasMembership . '.level', $this->createNamedParameter(Member::LEVEL_MEMBER))
1006
			)
1007
		);
1008
1009
		if ($getPersonalCircle) {
1010
			$orX->add(
1011
				$expr->andX(
1012
					$expr->bitwiseAnd($alias . '.config', Circle::CFG_PERSONAL),
1013
					$expr->eq($aliasMembership . '.level', $this->createNamedParameter(Member::LEVEL_OWNER))
1014
				)
1015
			);
1016
		}
1017
		if (!$this->getBool('mustBeMember', $options, true)) {
1018
			$orX->add($expr->bitwiseAnd($alias . '.config', Circle::CFG_VISIBLE));
1019
		}
1020
		if ($this->getBool('canBeVisitor', $options, false)) {
1021
			// TODO: should find a better way, also filter on remote initiator on non-federated ?
1022
			$orX->add($expr->gte($alias . '.config', $this->createNamedParameter(0)));
1023
		}
1024
		if ($this->getBool('canBeVisitorOnOpen', $options, false)) {
1025
			echo '!!!!';
1026
			$andOpen = $expr->andX();
1027
			$andOpen->add($expr->bitwiseAnd($alias . '.config', Circle::CFG_OPEN));
1028
			$andOpen->add(
1029
				$this->createFunction('NOT') . $expr->bitwiseAnd($alias . '.config', Circle::CFG_REQUEST)
1030
			);
1031
			$orX->add($andOpen);
1032
		}
1033
		$this->andWhere($orX);
1034
1035
1036
//		$orTypes = $this->generateLimit($qb, $circleUniqueId, $userId, $type, $name, $forceAll);
1037
//		if (sizeof($orTypes) === 0) {
1038
//			throw new ConfigNoCircleAvailableException(
1039
//				$this->l10n->t(
1040
//					'You cannot use the Circles Application until your administrator has allowed at least one type of circles'
1041
//				)
1042
//			);
1043
//		}
1044
1045
//		$orXTypes = $this->expr()
1046
//						 ->orX();
1047
//		foreach ($orTypes as $orType) {
1048
//			$orXTypes->add($orType);
1049
//		}
1050
//
1051
//		$qb->andWhere($orXTypes);
1052
	}
1053
1054
1055
	/**
1056
	 * CFG_SINGLE, CFG_HIDDEN and CFG_BACKEND means hidden from listing.
1057
	 *
1058
	 * @param string $aliasCircle
1059
	 * @param int $flag
1060
	 */
1061
	public function filterCircles(
1062
		string $aliasCircle,
1063
		int $flag = Circle::CFG_SINGLE | Circle::CFG_HIDDEN | Circle::CFG_BACKEND
1064
	): void {
1065
		if ($flag === 0) {
1066
			return;
1067
		}
1068
1069
		$expr = $this->expr();
1070
		$hide = $expr->andX();
1071
		foreach (Circle::$DEF_CFG as $cfg => $v) {
1072
			if ($flag & $cfg) {
1073
				$hide->add($this->createFunction('NOT') . $expr->bitwiseAnd($aliasCircle . '.config', $cfg));
1074
			}
1075
		}
1076
1077
		$this->andWhere($hide);
1078
	}
1079
1080
1081
	/**
1082
	 * Limit visibility on Sensitive information when search for members.
1083
	 *
1084
	 * @param string $alias
1085
	 *
1086
	 * @return ICompositeExpression
1087
	 */
1088
	private function limitRemoteVisibility_Sensitive_Members(string $alias): ICompositeExpression {
1089
		$expr = $this->expr();
1090
		$andPassive = $expr->andX();
1091
		$andPassive->add(
1092
			$expr->eq($alias . '.type', $this->createNamedParameter(RemoteInstance::TYPE_PASSIVE))
1093
		);
1094
1095
		$orMemberOrLevel = $expr->orX();
1096
		$orMemberOrLevel->add(
1097
			$expr->eq($this->getDefaultSelectAlias() . '.instance', $alias . '.instance')
1098
		);
1099
		// TODO: do we need this ? (display members from the local instance)
1100
		$orMemberOrLevel->add(
1101
			$expr->emptyString($this->getDefaultSelectAlias() . '.instance')
1102
		);
1103
1104
		$orMemberOrLevel->add(
1105
			$expr->eq(
1106
				$this->getDefaultSelectAlias() . '.level',
1107
				$this->createNamedParameter(Member::LEVEL_OWNER)
1108
			)
1109
		);
1110
		$andPassive->add($orMemberOrLevel);
1111
1112
		return $andPassive;
1113
	}
1114
1115
1116
	/**
1117
	 *
1118
	 * @param string $aliasCircle
1119
	 * @param int $flag
1120
	 */
1121
	public function filterConfig(string $aliasCircle, int $flag): void {
1122
		$this->andWhere($this->expr()->bitwiseAnd($aliasCircle . '.config', $flag));
1123
	}
1124
1125
1126
	/**
1127
	 * Link to storage/filecache
1128
	 *
1129
	 * @param string $aliasShare
1130
	 *
1131
	 * @throws RequestBuilderException
1132
	 */
1133
	public function leftJoinFileCache(string $aliasShare) {
1134
		$expr = $this->expr();
1135
1136
		$aliasFileCache = $this->generateAlias($aliasShare, self::FILE_CACHE);
1137
		$aliasStorages = $this->generateAlias($aliasFileCache, self::STORAGES);
1138
1139
		$this->generateSelectAlias(
1140
			CoreRequestBuilder::$outsideTables[CoreRequestBuilder::TABLE_FILE_CACHE],
0 ignored issues
show
Bug introduced by
The property outsideTables cannot be accessed from this context as it is declared private in class OCA\Circles\Db\CoreRequestBuilder.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1141
			$aliasFileCache,
1142
			$aliasFileCache,
1143
			[]
1144
		)
1145
			 ->generateSelectAlias(
1146
				 CoreRequestBuilder::$outsideTables[CoreRequestBuilder::TABLE_STORAGES],
0 ignored issues
show
Bug introduced by
The property outsideTables cannot be accessed from this context as it is declared private in class OCA\Circles\Db\CoreRequestBuilder.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1147
				 $aliasStorages,
1148
				 $aliasStorages,
1149
				 []
1150
			 )
1151
			 ->leftJoin(
1152
				 $aliasShare, CoreRequestBuilder::TABLE_FILE_CACHE, $aliasFileCache,
1153
				 $expr->eq($aliasShare . '.file_source', $aliasFileCache . '.fileid')
1154
			 )
1155
			 ->leftJoin(
1156
				 $aliasFileCache, CoreRequestBuilder::TABLE_STORAGES, $aliasStorages,
1157
				 $expr->eq($aliasFileCache . '.storage', $aliasStorages . '.numeric_id')
1158
			 );
1159
	}
1160
1161
1162
	/**
1163
	 * @param string $aliasShare
1164
	 * @param string $aliasShareMemberships
1165
	 *
1166
	 * @throws RequestBuilderException
1167
	 */
1168
	public function leftJoinShareChild(string $aliasShare, string $aliasShareMemberships = '') {
1169
		$expr = $this->expr();
1170
1171
		$aliasShareChild = $this->generateAlias($aliasShare, self::SHARE);
1172
		if ($aliasShareMemberships === '') {
1173
			$aliasShareMemberships = $this->generateAlias($aliasShare, self::MEMBERSHIPS, $options);
1174
		}
1175
1176
		$this->leftJoin(
1177
			$aliasShareMemberships, CoreRequestBuilder::TABLE_SHARE, $aliasShareChild,
1178
			$expr->andX(
1179
				$expr->eq($aliasShareChild . '.parent', $aliasShare . '.id'),
1180
				$expr->eq($aliasShareChild . '.share_with', $aliasShareMemberships . '.single_id')
1181
			)
1182
		);
1183
1184
		$this->generateSelectAlias(
1185
			['id', 'file_target', 'permissions'],
1186
			$aliasShareChild,
1187
			'child_',
1188
			[]
1189
		);
1190
1191
//		$this->selectAlias($aliasShareParent . '.permissions', 'parent_perms');
1192
	}
1193
1194
1195
	/**
1196
	 * @param string $alias
1197
	 * @param FederatedUser $federatedUser
1198
	 * @param bool $reshares
1199
	 */
1200
	public function limitToShareOwner(string $alias, FederatedUser $federatedUser, bool $reshares): void {
1201
		$expr = $this->expr();
1202
1203
		$orX = $expr->orX($this->exprLimit('uid_initiator', $federatedUser->getUserId(), $alias));
1204
1205
		if ($reshares) {
1206
			$orX->add($this->exprLimit('uid_owner', $federatedUser->getUserId(), $alias));
1207
		}
1208
1209
		$this->andWhere($orX);
1210
	}
1211
1212
1213
	/**
1214
	 * @param string $aliasMount
1215
	 * @param string $aliasMountMemberships
1216
	 *
1217
	 * @throws RequestBuilderException
1218
	 */
1219
	public function leftJoinMountpoint(string $aliasMount, string $aliasMountMemberships = '') {
1220
		$expr = $this->expr();
1221
1222
		$aliasMountpoint = $this->generateAlias($aliasMount, self::MOUNTPOINT);
1223
		if ($aliasMountMemberships === '') {
1224
			$aliasMountMemberships = $this->generateAlias($aliasMount, self::MEMBERSHIPS, $options);
1225
		}
1226
1227
		$this->leftJoin(
1228
			$aliasMountMemberships, CoreRequestBuilder::TABLE_MOUNTPOINT, $aliasMountpoint,
1229
			$expr->andX(
1230
				$expr->eq($aliasMountpoint . '.mount_id', $aliasMount . '.mount_id'),
1231
				$expr->eq($aliasMountpoint . '.single_id', $aliasMountMemberships . '.single_id')
1232
			)
1233
		);
1234
1235
		$this->selectAlias($aliasMountpoint . '.mountpoint', $aliasMountpoint . '_mountpoint');
1236
		$this->selectAlias($aliasMountpoint . '.mountpoint_hash', $aliasMountpoint . '_mountpoint_hash');
1237
	}
1238
1239
1240
	/**
1241
	 * @param string $alias
1242
	 * @param array $default
1243
	 *
1244
	 * @return CoreQueryBuilder
1245
	 */
1246
	private function generateCircleSelectAlias(string $alias, array $default = []): self {
1247
		$this->generateSelectAlias(
1248
			CoreRequestBuilder::$tables[CoreRequestBuilder::TABLE_CIRCLE],
0 ignored issues
show
Bug introduced by
The property tables cannot be accessed from this context as it is declared private in class OCA\Circles\Db\CoreRequestBuilder.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1249
			$alias,
1250
			$alias,
1251
			$default
1252
		);
1253
1254
		return $this;
1255
	}
1256
1257
	/**
1258
	 * @param string $alias
1259
	 * @param array $default
1260
	 *
1261
	 * @return $this
1262
	 */
1263
	private function generateMemberSelectAlias(string $alias, array $default = []): self {
1264
		$this->generateSelectAlias(
1265
			CoreRequestBuilder::$tables[CoreRequestBuilder::TABLE_MEMBER],
0 ignored issues
show
Bug introduced by
The property tables cannot be accessed from this context as it is declared private in class OCA\Circles\Db\CoreRequestBuilder.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1266
			$alias,
1267
			$alias,
1268
			$default
1269
		);
1270
1271
		return $this;
1272
	}
1273
1274
1275
	/**
1276
	 * @param string $alias
1277
	 * @param array $default
1278
	 * @param string $prefix
1279
	 *
1280
	 * @return $this
1281
	 */
1282
	private function generateMembershipSelectAlias(
1283
		string $alias,
1284
		string $prefix = '',
1285
		array $default = []
1286
	): self {
1287
		$this->generateSelectAlias(
1288
			CoreRequestBuilder::$tables[CoreRequestBuilder::TABLE_MEMBERSHIP],
0 ignored issues
show
Bug introduced by
The property tables cannot be accessed from this context as it is declared private in class OCA\Circles\Db\CoreRequestBuilder.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1289
			$alias,
1290
			($prefix === '') ? $alias : $prefix,
1291
			$default
1292
		);
1293
1294
		return $this;
1295
	}
1296
1297
1298
	/**
1299
	 * @param string $alias
1300
	 * @param array $default
1301
	 *
1302
	 * @return $this
1303
	 */
1304
	private function generateRemoteInstanceSelectAlias(string $alias, array $default = []): self {
1305
		$this->generateSelectAlias(
1306
			CoreRequestBuilder::$tables[CoreRequestBuilder::TABLE_REMOTE],
0 ignored issues
show
Bug introduced by
The property tables cannot be accessed from this context as it is declared private in class OCA\Circles\Db\CoreRequestBuilder.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1307
			$alias,
1308
			$alias,
1309
			$default
1310
		);
1311
1312
		return $this;
1313
	}
1314
1315
1316
	/**
1317
	 * @param array $path
1318
	 * @param array $options
1319
	 */
1320
	public function setOptions(array $path, array $options): void {
1321
		$options = [self::OPTIONS => $options];
1322
		foreach (array_reverse($path) as $item) {
1323
			$options = [$item => $options];
1324
		}
1325
1326
		$this->options = $options;
1327
	}
1328
1329
1330
	/**
1331
	 * @param string $base
1332
	 * @param string $extension
1333
	 * @param array|null $options
1334
	 *
1335
	 * @return string
1336
	 * @throws RequestBuilderException
1337
	 */
1338
	public function generateAlias(string $base, string $extension, ?array &$options = []): string {
1339
		$search = str_replace('_', '.', $base);
1340
		$path = $search . '.' . $extension;
1341
		if (!$this->validKey($path, self::$SQL_PATH)
1342
			&& !in_array($extension, $this->getArray($search, self::$SQL_PATH))) {
1343
			throw new RequestBuilderException($extension . ' not found in ' . $search);
1344
		}
1345
1346
		if (!is_array($options)) {
1347
			$options = [];
1348
		}
1349
1350
		$optionPath = '';
1351
		foreach (explode('.', $path) as $p) {
1352
			$optionPath = trim($optionPath . '.' . $p, '.');
1353
			$options = array_merge(
1354
				$options,
1355
				$this->getArray($optionPath . '.' . self::OPTIONS, self::$SQL_PATH),
1356
				$this->getArray($optionPath . '.' . self::OPTIONS, $this->options)
1357
			);
1358
		}
1359
1360
		return $base . '_' . $extension;
1361
	}
1362
1363
1364
	/**
1365
	 * @param string $prefix
1366
	 *
1367
	 * @return array
1368
	 */
1369
	public function getAvailablePath(string $prefix): array {
1370
		$prefix = trim($prefix, '_');
1371
		$search = str_replace('_', '.', $prefix);
1372
1373
		$path = [];
1374
		foreach ($this->getArray($search, self::$SQL_PATH) as $arr => $item) {
1375
			if (is_numeric($arr)) {
1376
				$k = $item;
1377
			} else {
1378
				$k = $arr;
1379
			}
1380
			$path[$k] = $prefix . '_' . $k . '_';
1381
		}
1382
1383
		return $path;
1384
	}
1385
1386
}
1387
1388