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 ArtificialOwl\MySmallPhpTools\Db\Nextcloud\nc22\NC22ExtendedQueryBuilder; |
36
|
|
|
use ArtificialOwl\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
|
|
|
use OCP\DB\QueryBuilder\IQueryBuilder; |
49
|
|
|
|
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* Class CoreQueryBuilder |
53
|
|
|
* |
54
|
|
|
* @package OCA\Circles\Db |
55
|
|
|
*/ |
56
|
|
|
class CoreQueryBuilder extends NC22ExtendedQueryBuilder { |
57
|
|
|
|
58
|
|
|
|
59
|
|
|
use TArrayTools; |
60
|
|
|
|
61
|
|
|
|
62
|
|
|
const SINGLE = 'single'; |
63
|
|
|
const CIRCLE = 'circle'; |
64
|
|
|
const MEMBER = 'member'; |
65
|
|
|
const MEMBER_COUNT = 'membercount'; |
66
|
|
|
const OWNER = 'owner'; |
67
|
|
|
const FEDERATED_EVENT = 'federatedevent'; |
68
|
|
|
const REMOTE = 'remote'; |
69
|
|
|
const BASED_ON = 'basedon'; |
70
|
|
|
const INITIATOR = 'initiator'; |
71
|
|
|
const DIRECT_INITIATOR = 'initiatordirect'; |
72
|
|
|
const MEMBERSHIPS = 'memberships'; |
73
|
|
|
const UPSTREAM_MEMBERSHIPS = 'upstreammemberships'; |
74
|
|
|
const INHERITANCE_FROM = 'inheritancefrom'; |
75
|
|
|
const INHERITED_BY = 'inheritedby'; |
76
|
|
|
const INVITED_BY = 'invitedby'; |
77
|
|
|
const MOUNT = 'mount'; |
78
|
|
|
const MOUNTPOINT = 'mountpoint'; |
79
|
|
|
const SHARE = 'share'; |
80
|
|
|
const FILE_CACHE = 'filecache'; |
81
|
|
|
const STORAGES = 'storages'; |
82
|
|
|
const OPTIONS = 'options'; |
83
|
|
|
const HELPER = 'circleshelper'; |
84
|
|
|
|
85
|
|
|
|
86
|
|
|
public static $SQL_PATH = [ |
87
|
|
|
self::SINGLE => [ |
88
|
|
|
self::MEMBER |
89
|
|
|
], |
90
|
|
|
self::CIRCLE => [ |
91
|
|
|
self::OPTIONS => [ |
92
|
|
|
'getPersonalCircle' => true |
93
|
|
|
], |
94
|
|
|
self::MEMBER, |
95
|
|
|
self::MEMBER_COUNT, |
96
|
|
|
self::OWNER => [ |
97
|
|
|
self::BASED_ON |
98
|
|
|
], |
99
|
|
|
self::MEMBERSHIPS, |
100
|
|
|
self::DIRECT_INITIATOR => [ |
101
|
|
|
self::BASED_ON |
102
|
|
|
], |
103
|
|
|
self::INITIATOR => [ |
104
|
|
|
self::BASED_ON, |
105
|
|
|
self::INHERITED_BY => [ |
106
|
|
|
self::MEMBERSHIPS |
107
|
|
|
] |
108
|
|
|
], |
109
|
|
|
self::REMOTE => [ |
110
|
|
|
self::MEMBER, |
111
|
|
|
self::CIRCLE => [ |
112
|
|
|
self::OWNER |
113
|
|
|
] |
114
|
|
|
] |
115
|
|
|
], |
116
|
|
|
self::MEMBER => [ |
117
|
|
|
self::MEMBERSHIPS, |
118
|
|
|
self::INHERITANCE_FROM, |
119
|
|
|
self::CIRCLE => [ |
120
|
|
|
self::OPTIONS => [ |
121
|
|
|
'getData' => true |
122
|
|
|
], |
123
|
|
|
self::OWNER, |
124
|
|
|
self::MEMBERSHIPS, |
125
|
|
|
self::INITIATOR => [ |
126
|
|
|
self::OPTIONS => [ |
127
|
|
|
'mustBeMember' => true, |
128
|
|
|
'canBeVisitor' => false |
129
|
|
|
], |
130
|
|
|
self::BASED_ON, |
131
|
|
|
self::INHERITED_BY => [ |
132
|
|
|
self::MEMBERSHIPS |
133
|
|
|
], |
134
|
|
|
self::INVITED_BY => [ |
135
|
|
|
self::OWNER, |
136
|
|
|
self::BASED_ON |
137
|
|
|
] |
138
|
|
|
] |
139
|
|
|
], |
140
|
|
|
self::BASED_ON => [ |
141
|
|
|
self::OWNER, |
142
|
|
|
self::MEMBERSHIPS, |
143
|
|
|
self::INITIATOR => [ |
144
|
|
|
self::BASED_ON, |
145
|
|
|
self::INHERITED_BY => [ |
146
|
|
|
self::MEMBERSHIPS |
147
|
|
|
] |
148
|
|
|
] |
149
|
|
|
], |
150
|
|
|
self::REMOTE => [ |
151
|
|
|
self::MEMBER, |
152
|
|
|
self::CIRCLE => [ |
153
|
|
|
self::OWNER |
154
|
|
|
] |
155
|
|
|
], |
156
|
|
|
self::INVITED_BY => [ |
157
|
|
|
self::OWNER, |
158
|
|
|
self::BASED_ON |
159
|
|
|
] |
160
|
|
|
], |
161
|
|
|
self::SHARE => [ |
162
|
|
|
self::SHARE, |
163
|
|
|
self::FILE_CACHE => [ |
164
|
|
|
self::STORAGES |
165
|
|
|
], |
166
|
|
|
self::UPSTREAM_MEMBERSHIPS => [ |
167
|
|
|
self::MEMBERSHIPS, |
168
|
|
|
self::INHERITED_BY => [ |
169
|
|
|
self::BASED_ON |
170
|
|
|
], |
171
|
|
|
self::SHARE, |
172
|
|
|
], |
173
|
|
|
self::MEMBERSHIPS, |
174
|
|
|
self::INHERITANCE_FROM, |
175
|
|
|
self::INHERITED_BY => [ |
176
|
|
|
self::BASED_ON |
177
|
|
|
], |
178
|
|
|
self::CIRCLE => [ |
179
|
|
|
self::OWNER |
180
|
|
|
], |
181
|
|
|
self::INITIATOR => [ |
182
|
|
|
self::BASED_ON, |
183
|
|
|
self::INHERITED_BY => [ |
184
|
|
|
self::MEMBERSHIPS |
185
|
|
|
] |
186
|
|
|
] |
187
|
|
|
], |
188
|
|
|
self::REMOTE => [ |
189
|
|
|
self::MEMBER |
190
|
|
|
], |
191
|
|
|
self::MOUNT => [ |
192
|
|
|
self::MEMBER => [ |
193
|
|
|
self::REMOTE |
194
|
|
|
], |
195
|
|
|
self::INITIATOR => [ |
196
|
|
|
self::INHERITED_BY => [ |
197
|
|
|
self::MEMBERSHIPS |
198
|
|
|
] |
199
|
|
|
], |
200
|
|
|
self::MOUNTPOINT, |
201
|
|
|
self::MEMBERSHIPS |
202
|
|
|
], |
203
|
|
|
self::HELPER => [ |
204
|
|
|
self::MEMBERSHIPS, |
205
|
|
|
self::INITIATOR => [ |
206
|
|
|
self::INHERITED_BY => [ |
207
|
|
|
self::MEMBERSHIPS |
208
|
|
|
] |
209
|
|
|
], |
210
|
|
|
self::CIRCLE => [ |
211
|
|
|
self::OPTIONS => [ |
212
|
|
|
'getPersonalCircle' => true |
213
|
|
|
], |
214
|
|
|
self::MEMBER, |
215
|
|
|
self::OWNER => [ |
216
|
|
|
self::BASED_ON |
217
|
|
|
] |
218
|
|
|
] |
219
|
|
|
] |
220
|
|
|
]; |
221
|
|
|
|
222
|
|
|
|
223
|
|
|
/** @var ConfigService */ |
224
|
|
|
private $configService; |
225
|
|
|
|
226
|
|
|
|
227
|
|
|
/** @var array */ |
228
|
|
|
private $options = []; |
229
|
|
|
|
230
|
|
|
|
231
|
|
|
/** |
232
|
|
|
* CoreQueryBuilder constructor. |
233
|
|
|
*/ |
234
|
|
|
public function __construct() { |
235
|
|
|
parent::__construct(); |
236
|
|
|
|
237
|
|
|
$this->configService = OC::$server->get(ConfigService::class); |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
|
241
|
|
|
/** |
242
|
|
|
* @param IFederatedModel $federatedModel |
243
|
|
|
* |
244
|
|
|
* @return string |
245
|
|
|
*/ |
246
|
|
|
public function getInstance(IFederatedModel $federatedModel): string { |
247
|
|
|
$instance = $federatedModel->getInstance(); |
248
|
|
|
|
249
|
|
|
return ($this->configService->isLocalInstance($instance)) ? '' : $instance; |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
|
253
|
|
|
/** |
254
|
|
|
* @param string $id |
255
|
|
|
*/ |
256
|
|
|
public function limitToCircleId(string $id): void { |
257
|
|
|
$this->limitToDBField('circle_id', $id, true); |
|
|
|
|
258
|
|
|
} |
259
|
|
|
|
260
|
|
|
/** |
261
|
|
|
* @param string $name |
262
|
|
|
*/ |
263
|
|
|
public function limitToName(string $name): void { |
264
|
|
|
$this->limit('name', $name); |
265
|
|
|
} |
266
|
|
|
|
267
|
|
|
/** |
268
|
|
|
* @param string $name |
269
|
|
|
*/ |
270
|
|
|
public function limitToDisplayName(string $name): void { |
271
|
|
|
$this->limit('display_name', $name, '', false); |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
/** |
275
|
|
|
* @param string $name |
276
|
|
|
*/ |
277
|
|
|
public function limitToSanitizedName(string $name): void { |
278
|
|
|
$this->limit('sanitized_name', $name, '', false); |
279
|
|
|
} |
280
|
|
|
|
281
|
|
|
/** |
282
|
|
|
* @param int $config |
283
|
|
|
*/ |
284
|
|
|
public function limitToConfig(int $config): void { |
285
|
|
|
$this->limitToDBFieldInt('config', $config); |
|
|
|
|
286
|
|
|
} |
287
|
|
|
|
288
|
|
|
/** |
289
|
|
|
* @param int $source |
290
|
|
|
*/ |
291
|
|
|
public function limitToSource(int $source): void { |
292
|
|
|
$this->limitToDBFieldInt('source', $source); |
|
|
|
|
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
/** |
296
|
|
|
* @param int $config |
297
|
|
|
* @param string $alias |
298
|
|
|
*/ |
299
|
|
|
public function limitToConfigFlag(int $config, string $alias = ''): void { |
300
|
|
|
$this->limitBitwise('config', $config, $alias); |
301
|
|
|
} |
302
|
|
|
|
303
|
|
|
|
304
|
|
|
/** |
305
|
|
|
* @param string $singleId |
306
|
|
|
*/ |
307
|
|
|
public function limitToSingleId(string $singleId): void { |
308
|
|
|
$this->limitToDBField('single_id', $singleId, true); |
|
|
|
|
309
|
|
|
} |
310
|
|
|
|
311
|
|
|
|
312
|
|
|
/** |
313
|
|
|
* @param string $itemId |
314
|
|
|
*/ |
315
|
|
|
public function limitToItemId(string $itemId): void { |
316
|
|
|
$this->limitToDBField('item_id', $itemId, true); |
|
|
|
|
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
|
320
|
|
|
/** |
321
|
|
|
* @param string $host |
322
|
|
|
*/ |
323
|
|
|
public function limitToInstance(string $host): void { |
324
|
|
|
$this->limitToDBField('instance', $host, false); |
|
|
|
|
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
|
328
|
|
|
/** |
329
|
|
|
* @param int $userType |
330
|
|
|
*/ |
331
|
|
|
public function limitToUserType(int $userType): void { |
332
|
|
|
$this->limitToDBFieldInt('user_type', $userType); |
|
|
|
|
333
|
|
|
} |
334
|
|
|
|
335
|
|
|
|
336
|
|
|
/** |
337
|
|
|
* @param int $shareType |
338
|
|
|
*/ |
339
|
|
|
public function limitToShareType(int $shareType): void { |
340
|
|
|
$this->limitToDBFieldInt('share_type', $shareType); |
|
|
|
|
341
|
|
|
} |
342
|
|
|
|
343
|
|
|
|
344
|
|
|
/** |
345
|
|
|
* @param string $shareWith |
346
|
|
|
*/ |
347
|
|
|
public function limitToShareWith(string $shareWith): void { |
348
|
|
|
$this->limitToDBField('share_with', $shareWith); |
|
|
|
|
349
|
|
|
} |
350
|
|
|
|
351
|
|
|
|
352
|
|
|
/** |
353
|
|
|
* @param int $nodeId |
354
|
|
|
*/ |
355
|
|
|
public function limitToFileSource(int $nodeId): void { |
356
|
|
|
$this->limitToDBFieldInt('file_source', $nodeId); |
|
|
|
|
357
|
|
|
} |
358
|
|
|
|
359
|
|
|
/** |
360
|
|
|
* @param array $files |
361
|
|
|
*/ |
362
|
|
|
public function limitToFileSourceArray(array $files): void { |
363
|
|
|
$this->limitToDBFieldInArray('file_source', $files); |
|
|
|
|
364
|
|
|
} |
365
|
|
|
|
366
|
|
|
|
367
|
|
|
/** |
368
|
|
|
* @param int $shareId |
369
|
|
|
*/ |
370
|
|
|
public function limitToShareParent(int $shareId): void { |
371
|
|
|
$this->limitToDBFieldInt('parent', $shareId); |
|
|
|
|
372
|
|
|
} |
373
|
|
|
|
374
|
|
|
|
375
|
|
|
/** |
376
|
|
|
* @param Circle $circle |
377
|
|
|
*/ |
378
|
|
|
public function filterCircle(Circle $circle): void { |
379
|
|
|
if ($this->getType() !== QueryBuilder::SELECT) { |
380
|
|
|
return; |
381
|
|
|
} |
382
|
|
|
|
383
|
|
|
if ($circle->getDisplayName() !== '') { |
384
|
|
|
$this->searchInDBField('display_name', '%' . $circle->getDisplayName() . '%'); |
385
|
|
|
} |
386
|
|
|
if ($circle->getConfig() > 0) { |
387
|
|
|
$this->limitBitwise('config', $circle->getConfig()); |
388
|
|
|
} |
389
|
|
|
} |
390
|
|
|
|
391
|
|
|
|
392
|
|
|
/** |
393
|
|
|
* left join RemoteInstance based on a Member |
394
|
|
|
*/ |
395
|
|
|
public function leftJoinRemoteInstance(string $alias): void { |
396
|
|
|
$expr = $this->expr(); |
397
|
|
|
|
398
|
|
|
try { |
399
|
|
|
$aliasRemoteInstance = $this->generateAlias($alias, self::REMOTE); |
400
|
|
|
$this->generateRemoteInstanceSelectAlias($aliasRemoteInstance) |
401
|
|
|
->leftJoin( |
402
|
|
|
$alias, CoreRequestBuilder::TABLE_REMOTE, $aliasRemoteInstance, |
403
|
|
|
$expr->eq($alias . '.instance', $aliasRemoteInstance . '.instance') |
404
|
|
|
); |
405
|
|
|
} catch (RequestBuilderException $e) { |
|
|
|
|
406
|
|
|
} |
407
|
|
|
} |
408
|
|
|
|
409
|
|
|
|
410
|
|
|
/** |
411
|
|
|
* @param string $alias |
412
|
|
|
* @param RemoteInstance $remoteInstance |
413
|
|
|
* @param bool $filterSensitiveData |
414
|
|
|
* @param string $aliasCircle |
415
|
|
|
* |
416
|
|
|
* @throws RequestBuilderException |
417
|
|
|
*/ |
418
|
|
|
public function limitToRemoteInstance( |
419
|
|
|
string $alias, |
420
|
|
|
RemoteInstance $remoteInstance, |
421
|
|
|
bool $filterSensitiveData = true, |
422
|
|
|
string $aliasCircle = '' |
423
|
|
|
): void { |
424
|
|
|
|
425
|
|
|
if ($aliasCircle === '') { |
426
|
|
|
$aliasCircle = $alias; |
427
|
|
|
} |
428
|
|
|
|
429
|
|
|
$this->leftJoinRemoteInstanceIncomingRequest($alias, $remoteInstance); |
430
|
|
|
$this->leftJoinMemberFromInstance($alias, $remoteInstance, $aliasCircle); |
431
|
|
|
$this->leftJoinMemberFromRemoteCircle($alias, $remoteInstance, $aliasCircle); |
432
|
|
|
$this->limitRemoteVisibility($alias, $filterSensitiveData, $aliasCircle); |
433
|
|
|
} |
434
|
|
|
|
435
|
|
|
|
436
|
|
|
/** |
437
|
|
|
* Left join RemoteInstance based on an incoming request |
438
|
|
|
* |
439
|
|
|
* @param string $alias |
440
|
|
|
* @param RemoteInstance $remoteInstance |
441
|
|
|
* |
442
|
|
|
* @throws RequestBuilderException |
443
|
|
|
*/ |
444
|
|
|
public function leftJoinRemoteInstanceIncomingRequest( |
445
|
|
|
string $alias, |
446
|
|
|
RemoteInstance $remoteInstance |
447
|
|
|
): void { |
448
|
|
|
if ($this->getType() !== QueryBuilder::SELECT) { |
449
|
|
|
return; |
450
|
|
|
} |
451
|
|
|
|
452
|
|
|
$aliasRemote = $this->generateAlias($alias, self::REMOTE); |
453
|
|
|
$expr = $this->expr(); |
454
|
|
|
$this->leftJoin( |
455
|
|
|
$this->getDefaultSelectAlias(), CoreRequestBuilder::TABLE_REMOTE, $aliasRemote, |
456
|
|
|
$expr->eq($aliasRemote . '.instance', $this->createNamedParameter($remoteInstance->getInstance())) |
457
|
|
|
); |
458
|
|
|
} |
459
|
|
|
|
460
|
|
|
|
461
|
|
|
/** |
462
|
|
|
* left join members to check memberships of someone from instance |
463
|
|
|
* |
464
|
|
|
* @param string $alias |
465
|
|
|
* @param RemoteInstance $remoteInstance |
466
|
|
|
* @param string $aliasCircle |
467
|
|
|
* |
468
|
|
|
* @throws RequestBuilderException |
469
|
|
|
*/ |
470
|
|
|
private function leftJoinMemberFromInstance( |
471
|
|
|
string $alias, RemoteInstance $remoteInstance, string $aliasCircle |
472
|
|
|
) { |
473
|
|
|
if ($this->getType() !== QueryBuilder::SELECT) { |
474
|
|
|
return; |
475
|
|
|
} |
476
|
|
|
|
477
|
|
|
$aliasRemote = $this->generateAlias($alias, self::REMOTE); |
478
|
|
|
$aliasRemoteMember = $this->generateAlias($aliasRemote, self::MEMBER); |
479
|
|
|
|
480
|
|
|
$expr = $this->expr(); |
481
|
|
|
$this->leftJoin( |
482
|
|
|
$this->getDefaultSelectAlias(), CoreRequestBuilder::TABLE_MEMBER, $aliasRemoteMember, |
483
|
|
|
$expr->andX( |
484
|
|
|
$expr->eq($aliasRemoteMember . '.circle_id', $aliasCircle . '.unique_id'), |
485
|
|
|
$expr->eq( |
486
|
|
|
$aliasRemoteMember . '.instance', |
487
|
|
|
$this->createNamedParameter($remoteInstance->getInstance()) |
488
|
|
|
), |
489
|
|
|
$expr->gte($aliasRemoteMember . '.level', $this->createNamedParameter(Member::LEVEL_MEMBER)) |
490
|
|
|
) |
491
|
|
|
); |
492
|
|
|
} |
493
|
|
|
|
494
|
|
|
|
495
|
|
|
/** |
496
|
|
|
* left join circle is member of a circle from remote instance |
497
|
|
|
* |
498
|
|
|
* @param string $alias |
499
|
|
|
* @param RemoteInstance $remoteInstance |
500
|
|
|
* @param string $aliasCircle |
501
|
|
|
* |
502
|
|
|
* @throws RequestBuilderException |
503
|
|
|
*/ |
504
|
|
|
private function leftJoinMemberFromRemoteCircle( |
505
|
|
|
string $alias, |
506
|
|
|
RemoteInstance $remoteInstance, |
507
|
|
|
string $aliasCircle |
508
|
|
|
) { |
509
|
|
|
if ($this->getType() !== QueryBuilder::SELECT) { |
510
|
|
|
return; |
511
|
|
|
} |
512
|
|
|
|
513
|
|
|
$aliasRemote = $this->generateAlias($alias, self::REMOTE); |
514
|
|
|
$aliasRemoteCircle = $this->generateAlias($aliasRemote, self::CIRCLE); |
515
|
|
|
$aliasRemoteCircleOwner = $this->generateAlias($aliasRemoteCircle, self::OWNER); |
516
|
|
|
|
517
|
|
|
$expr = $this->expr(); |
518
|
|
|
$this->leftJoin( |
519
|
|
|
$this->getDefaultSelectAlias(), CoreRequestBuilder::TABLE_MEMBER, $aliasRemoteCircle, |
520
|
|
|
$expr->andX( |
521
|
|
|
$expr->eq($aliasRemoteCircle . '.single_id', $aliasCircle . '.unique_id'), |
522
|
|
|
$expr->emptyString($aliasRemoteCircle . '.instance'), |
523
|
|
|
$expr->gte($aliasRemoteCircle . '.level', $this->createNamedParameter(Member::LEVEL_MEMBER)) |
524
|
|
|
) |
525
|
|
|
); |
526
|
|
|
$this->leftJoin( |
527
|
|
|
$this->getDefaultSelectAlias(), CoreRequestBuilder::TABLE_MEMBER, $aliasRemoteCircleOwner, |
528
|
|
|
$expr->andX( |
529
|
|
|
$expr->eq($aliasRemoteCircle . '.circle_id', $aliasRemoteCircleOwner . '.circle_id'), |
530
|
|
|
$expr->eq( |
531
|
|
|
$aliasRemoteCircleOwner . '.instance', |
532
|
|
|
$this->createNamedParameter($remoteInstance->getInstance()) |
533
|
|
|
), |
534
|
|
|
$expr->eq( |
535
|
|
|
$aliasRemoteCircleOwner . '.level', $this->createNamedParameter(Member::LEVEL_OWNER) |
536
|
|
|
) |
537
|
|
|
) |
538
|
|
|
); |
539
|
|
|
} |
540
|
|
|
|
541
|
|
|
|
542
|
|
|
/** |
543
|
|
|
* - global_scale: visibility on all Circles |
544
|
|
|
* - trusted: visibility on all FEDERATED Circle if owner is local |
545
|
|
|
* - external: visibility on all FEDERATED Circle if owner is local and: |
546
|
|
|
* - with if Circle contains at least one member from the remote instance |
547
|
|
|
* - one circle from the remote instance contains the local circle as member, and confirmed (using |
548
|
|
|
* sync locally) |
549
|
|
|
* - passive: like external, but the members list will only contains member from the local instance and |
550
|
|
|
* from the remote instance. |
551
|
|
|
* |
552
|
|
|
* @param string $alias |
553
|
|
|
* @param bool $sensitive |
554
|
|
|
* @param string $aliasCircle |
555
|
|
|
* |
556
|
|
|
* @throws RequestBuilderException |
557
|
|
|
*/ |
558
|
|
|
protected function limitRemoteVisibility(string $alias, bool $sensitive, string $aliasCircle) { |
559
|
|
|
$aliasRemote = $this->generateAlias($alias, self::REMOTE); |
560
|
|
|
$aliasOwner = $this->generateAlias($aliasCircle, self::OWNER); |
561
|
|
|
$aliasRemoteMember = $this->generateAlias($aliasRemote, self::MEMBER); |
562
|
|
|
$aliasRemoteCircle = $this->generateAlias($aliasRemote, self::CIRCLE); |
563
|
|
|
$aliasRemoteCircleOwner = $this->generateAlias($aliasRemoteCircle, self::OWNER); |
564
|
|
|
|
565
|
|
|
$expr = $this->expr(); |
566
|
|
|
$orX = $expr->orX(); |
567
|
|
|
$orX->add( |
568
|
|
|
$expr->eq($aliasRemote . '.type', $this->createNamedParameter(RemoteInstance::TYPE_GLOBALSCALE)) |
569
|
|
|
); |
570
|
|
|
|
571
|
|
|
$orExtOrPassive = $expr->orX(); |
572
|
|
|
$orExtOrPassive->add( |
573
|
|
|
$expr->eq($aliasRemote . '.type', $this->createNamedParameter(RemoteInstance::TYPE_EXTERNAL)) |
574
|
|
|
); |
575
|
|
|
if (!$sensitive) { |
576
|
|
|
$orExtOrPassive->add( |
577
|
|
|
$expr->eq($aliasRemote . '.type', $this->createNamedParameter(RemoteInstance::TYPE_PASSIVE)) |
578
|
|
|
); |
579
|
|
|
} else { |
580
|
|
|
if ($this->getDefaultSelectAlias() === CoreQueryBuilder::MEMBER) { |
581
|
|
|
$orExtOrPassive->add($this->limitRemoteVisibility_Sensitive_Members($aliasRemote)); |
582
|
|
|
} |
583
|
|
|
} |
584
|
|
|
|
585
|
|
|
$orInstance = $expr->orX(); |
586
|
|
|
$orInstance->add($expr->isNotNull($aliasRemoteMember . '.instance')); |
587
|
|
|
$orInstance->add($expr->isNotNull($aliasRemoteCircleOwner . '.instance')); |
588
|
|
|
|
589
|
|
|
$andExternal = $expr->andX(); |
590
|
|
|
$andExternal->add($orExtOrPassive); |
591
|
|
|
$andExternal->add($orInstance); |
592
|
|
|
|
593
|
|
|
$orExtOrTrusted = $expr->orX(); |
594
|
|
|
$orExtOrTrusted->add($andExternal); |
595
|
|
|
$orExtOrTrusted->add( |
596
|
|
|
$expr->eq($aliasRemote . '.type', $this->createNamedParameter(RemoteInstance::TYPE_TRUSTED)) |
597
|
|
|
); |
598
|
|
|
|
599
|
|
|
$andTrusted = $expr->andX(); |
600
|
|
|
$andTrusted->add($orExtOrTrusted); |
601
|
|
|
$andTrusted->add($this->exprLimitBitwise('config', Circle::CFG_FEDERATED, $aliasCircle)); |
602
|
|
|
$andTrusted->add($expr->emptyString($aliasOwner . '.instance')); |
603
|
|
|
$orX->add($andTrusted); |
604
|
|
|
|
605
|
|
|
$this->andWhere($orX); |
606
|
|
|
} |
607
|
|
|
|
608
|
|
|
|
609
|
|
|
/** |
610
|
|
|
* @param string $alias |
611
|
|
|
* @param Member $member |
612
|
|
|
* |
613
|
|
|
* @throws RequestBuilderException |
614
|
|
|
*/ |
615
|
|
|
public function limitToDirectMembership(string $alias, Member $member): void { |
616
|
|
|
if ($this->getType() !== QueryBuilder::SELECT) { |
617
|
|
|
return; |
618
|
|
|
} |
619
|
|
|
|
620
|
|
|
$aliasMember = $this->generateAlias($alias, self::MEMBER, $options); |
621
|
|
|
$getData = $this->getBool('getData', $options, false); |
622
|
|
|
|
623
|
|
|
$expr = $this->expr(); |
624
|
|
|
if ($getData) { |
625
|
|
|
$this->generateMemberSelectAlias($aliasMember); |
626
|
|
|
} |
627
|
|
|
$this->leftJoin( |
628
|
|
|
$this->getDefaultSelectAlias(), CoreRequestBuilder::TABLE_MEMBER, $aliasMember, |
629
|
|
|
$expr->eq($aliasMember . '.circle_id', $alias . '.unique_id') |
630
|
|
|
); |
631
|
|
|
|
632
|
|
|
$this->filterDirectMembership($aliasMember, $member); |
633
|
|
|
} |
634
|
|
|
|
635
|
|
|
|
636
|
|
|
/** |
637
|
|
|
* @param string $aliasMember |
638
|
|
|
* @param Member $member |
639
|
|
|
*/ |
640
|
|
|
public function filterDirectMembership(string $aliasMember, Member $member): void { |
641
|
|
|
if ($this->getType() !== QueryBuilder::SELECT) { |
642
|
|
|
return; |
643
|
|
|
} |
644
|
|
|
|
645
|
|
|
$expr = $this->expr(); |
646
|
|
|
$andX = $expr->andX(); |
647
|
|
|
|
648
|
|
|
if ($member->getUserId() !== '') { |
649
|
|
|
$andX->add( |
650
|
|
|
$expr->eq($aliasMember . '.user_id', $this->createNamedParameter($member->getUserId())) |
651
|
|
|
); |
652
|
|
|
} |
653
|
|
|
|
654
|
|
|
if ($member->getSingleId() !== '') { |
655
|
|
|
$andX->add( |
656
|
|
|
$expr->eq($aliasMember . '.single_id', $this->createNamedParameter($member->getSingleId())) |
657
|
|
|
); |
658
|
|
|
} |
659
|
|
|
|
660
|
|
|
if ($member->getUserType() > 0) { |
661
|
|
|
$andX->add( |
662
|
|
|
$expr->eq($aliasMember . '.user_type', $this->createNamedParameter($member->getUserType())) |
663
|
|
|
); |
664
|
|
|
} |
665
|
|
|
|
666
|
|
|
$andX->add( |
667
|
|
|
$expr->eq($aliasMember . '.instance', $this->createNamedParameter($this->getInstance($member))) |
668
|
|
|
); |
669
|
|
|
|
670
|
|
|
if ($member->getLevel() > 0) { |
671
|
|
|
$andX->add( |
672
|
|
|
$expr->gte( |
673
|
|
|
$aliasMember . '.level', |
674
|
|
|
$this->createNamedParameter($member->getLevel(), IQueryBuilder::PARAM_INT) |
675
|
|
|
) |
676
|
|
|
); |
677
|
|
|
} |
678
|
|
|
|
679
|
|
|
$this->andWhere($andX); |
680
|
|
|
} |
681
|
|
|
|
682
|
|
|
|
683
|
|
|
/** |
684
|
|
|
* @param string $alias |
685
|
|
|
*/ |
686
|
|
|
public function countMembers(string $alias): void { |
687
|
|
|
if ($this->getType() !== QueryBuilder::SELECT) { |
688
|
|
|
return; |
689
|
|
|
} |
690
|
|
|
|
691
|
|
|
try { |
692
|
|
|
$aliasMemberCount = $this->generateAlias($alias, self::MEMBER_COUNT, $options); |
693
|
|
|
} catch (RequestBuilderException $e) { |
694
|
|
|
return; |
695
|
|
|
} |
696
|
|
|
|
697
|
|
|
$getData = $this->getBool('getData', $options, false); |
698
|
|
|
if (!$getData) { |
699
|
|
|
return; |
700
|
|
|
} |
701
|
|
|
|
702
|
|
|
$expr = $this->expr(); |
703
|
|
|
$this->selectAlias( |
704
|
|
|
$this->createFunction('COUNT(`' . $aliasMemberCount . '`.`member_id`)'), |
705
|
|
|
(($alias !== $this->getDefaultSelectAlias()) ? $alias . '_' : '') . 'population' |
706
|
|
|
); |
707
|
|
|
$this->leftJoin( |
708
|
|
|
$alias, CoreRequestBuilder::TABLE_MEMBER, $aliasMemberCount, |
709
|
|
|
$expr->eq($alias . '.unique_id', $aliasMemberCount . '.circle_id') |
710
|
|
|
); |
711
|
|
|
} |
712
|
|
|
|
713
|
|
|
|
714
|
|
|
/** |
715
|
|
|
* @param string $alias |
716
|
|
|
* @param IFederatedUser|null $initiator |
717
|
|
|
* @param string $field |
718
|
|
|
* @param string $helperAlias |
719
|
|
|
* |
720
|
|
|
* @throws RequestBuilderException |
721
|
|
|
*/ |
722
|
|
|
public function leftJoinCircle( |
723
|
|
|
string $alias, |
724
|
|
|
?IFederatedUser $initiator = null, |
725
|
|
|
string $field = 'circle_id', |
726
|
|
|
string $helperAlias = '' |
727
|
|
|
): void { |
728
|
|
|
if ($this->getType() !== QueryBuilder::SELECT) { |
729
|
|
|
return; |
730
|
|
|
} |
731
|
|
|
|
732
|
|
|
$helperAlias = ($helperAlias !== '') ? $helperAlias : $alias; |
733
|
|
|
$aliasCircle = $this->generateAlias($alias, self::CIRCLE, $options); |
734
|
|
|
$getData = $this->getBool('getData', $options, false); |
735
|
|
|
$expr = $this->expr(); |
736
|
|
|
|
737
|
|
|
if ($getData) { |
738
|
|
|
$this->generateCircleSelectAlias($aliasCircle); |
739
|
|
|
} |
740
|
|
|
|
741
|
|
|
$this->leftJoin( |
742
|
|
|
$helperAlias, |
743
|
|
|
CoreRequestBuilder::TABLE_CIRCLE, |
744
|
|
|
$aliasCircle, |
745
|
|
|
$expr->eq($aliasCircle . '.unique_id', $helperAlias . '.' . $field) |
746
|
|
|
); |
747
|
|
|
|
748
|
|
|
if (!is_null($initiator)) { |
749
|
|
|
$this->limitToInitiator($aliasCircle, $initiator); |
750
|
|
|
} |
751
|
|
|
|
752
|
|
|
$this->leftJoinOwner($aliasCircle); |
753
|
|
|
} |
754
|
|
|
|
755
|
|
|
|
756
|
|
|
/** |
757
|
|
|
* @param string $aliasMember |
758
|
|
|
* |
759
|
|
|
* @throws RequestBuilderException |
760
|
|
|
*/ |
761
|
|
|
public function leftJoinInvitedBy(string $aliasMember): void { |
762
|
|
|
if ($this->getType() !== QueryBuilder::SELECT) { |
763
|
|
|
return; |
764
|
|
|
} |
765
|
|
|
|
766
|
|
|
try { |
767
|
|
|
$aliasInvitedBy = $this->generateAlias($aliasMember, self::INVITED_BY); |
768
|
|
|
} catch (RequestBuilderException $e) { |
769
|
|
|
return; |
770
|
|
|
} |
771
|
|
|
|
772
|
|
|
$expr = $this->expr(); |
773
|
|
|
$this->generateCircleSelectAlias($aliasInvitedBy) |
774
|
|
|
->leftJoin( |
775
|
|
|
$aliasMember, CoreRequestBuilder::TABLE_CIRCLE, $aliasInvitedBy, |
776
|
|
|
$expr->eq($aliasMember . '.invited_by', $aliasInvitedBy . '.unique_id') |
777
|
|
|
); |
778
|
|
|
|
779
|
|
|
$this->leftJoinOwner($aliasInvitedBy); |
780
|
|
|
} |
781
|
|
|
|
782
|
|
|
|
783
|
|
|
/** |
784
|
|
|
* @param string $aliasMember |
785
|
|
|
* @param IFederatedUser|null $initiator |
786
|
|
|
* |
787
|
|
|
* @throws RequestBuilderException |
788
|
|
|
*/ |
789
|
|
|
public function leftJoinBasedOn( |
790
|
|
|
string $aliasMember, |
791
|
|
|
?IFederatedUser $initiator = null |
792
|
|
|
): void { |
793
|
|
|
if ($this->getType() !== QueryBuilder::SELECT) { |
794
|
|
|
return; |
795
|
|
|
} |
796
|
|
|
|
797
|
|
|
try { |
798
|
|
|
$aliasBasedOn = $this->generateAlias($aliasMember, self::BASED_ON, $options); |
799
|
|
|
} catch (RequestBuilderException $e) { |
800
|
|
|
return; |
801
|
|
|
} |
802
|
|
|
|
803
|
|
|
$expr = $this->expr(); |
804
|
|
|
$this->generateCircleSelectAlias($aliasBasedOn) |
805
|
|
|
->leftJoin( |
806
|
|
|
$aliasMember, CoreRequestBuilder::TABLE_CIRCLE, $aliasBasedOn, |
807
|
|
|
$expr->eq($aliasBasedOn . '.unique_id', $aliasMember . '.single_id') |
808
|
|
|
); |
809
|
|
|
|
810
|
|
|
if (!is_null($initiator)) { |
811
|
|
|
$this->leftJoinInitiator($aliasBasedOn, $initiator); |
812
|
|
|
$this->leftJoinOwner($aliasBasedOn); |
813
|
|
|
} |
814
|
|
|
} |
815
|
|
|
|
816
|
|
|
|
817
|
|
|
/** |
818
|
|
|
* @param string $alias |
819
|
|
|
* @param string $field |
820
|
|
|
* |
821
|
|
|
* @throws RequestBuilderException |
822
|
|
|
*/ |
823
|
|
|
public function leftJoinOwner(string $alias, string $field = 'unique_id'): void { |
824
|
|
|
if ($this->getType() !== QueryBuilder::SELECT) { |
825
|
|
|
return; |
826
|
|
|
} |
827
|
|
|
|
828
|
|
|
try { |
829
|
|
|
$aliasMember = $this->generateAlias($alias, self::OWNER, $options); |
830
|
|
|
$getData = $this->getBool('getData', $options, false); |
|
|
|
|
831
|
|
|
} catch (RequestBuilderException $e) { |
832
|
|
|
return; |
833
|
|
|
} |
834
|
|
|
|
835
|
|
|
$expr = $this->expr(); |
836
|
|
|
$this->generateMemberSelectAlias($aliasMember) |
837
|
|
|
->leftJoin( |
838
|
|
|
$alias, CoreRequestBuilder::TABLE_MEMBER, $aliasMember, |
839
|
|
|
$expr->andX( |
840
|
|
|
$expr->eq($aliasMember . '.circle_id', $alias . '.' . $field), |
841
|
|
|
$expr->eq( |
842
|
|
|
$aliasMember . '.level', |
843
|
|
|
$this->createNamedParameter(Member::LEVEL_OWNER, self::PARAM_INT) |
844
|
|
|
) |
845
|
|
|
) |
846
|
|
|
); |
847
|
|
|
|
848
|
|
|
$this->leftJoinBasedOn($aliasMember); |
849
|
|
|
} |
850
|
|
|
|
851
|
|
|
|
852
|
|
|
/** |
853
|
|
|
* @param string $alias |
854
|
|
|
* @param string $fieldCircleId |
855
|
|
|
* @param string $fieldSingleId |
856
|
|
|
* |
857
|
|
|
* @throws RequestBuilderException |
858
|
|
|
*/ |
859
|
|
|
public function leftJoinMember( |
860
|
|
|
string $alias, |
861
|
|
|
string $fieldCircleId = 'circle_id', |
862
|
|
|
string $fieldSingleId = 'single_id' |
863
|
|
|
): void { |
864
|
|
|
if ($this->getType() !== QueryBuilder::SELECT) { |
865
|
|
|
return; |
866
|
|
|
} |
867
|
|
|
|
868
|
|
|
try { |
869
|
|
|
$aliasMember = $this->generateAlias($alias, self::MEMBER, $options); |
870
|
|
|
$getData = $this->getBool('getData', $options, false); |
|
|
|
|
871
|
|
|
} catch (RequestBuilderException $e) { |
872
|
|
|
return; |
873
|
|
|
} |
874
|
|
|
|
875
|
|
|
$expr = $this->expr(); |
876
|
|
|
$this->generateMemberSelectAlias($aliasMember) |
877
|
|
|
->leftJoin( |
878
|
|
|
$alias, CoreRequestBuilder::TABLE_MEMBER, $aliasMember, |
879
|
|
|
$expr->andX( |
880
|
|
|
$expr->eq($aliasMember . '.circle_id', $alias . '.' . $fieldCircleId), |
881
|
|
|
$expr->eq($aliasMember . '.single_id', $alias . '.' . $fieldSingleId), |
882
|
|
|
$expr->gte( |
883
|
|
|
$aliasMember . '.level', |
884
|
|
|
$this->createNamedParameter(Member::LEVEL_MEMBER, self::PARAM_INT) |
885
|
|
|
) |
886
|
|
|
) |
887
|
|
|
); |
888
|
|
|
|
889
|
|
|
$this->leftJoinRemoteInstance($aliasMember); |
890
|
|
|
$this->leftJoinBasedOn($aliasMember); |
891
|
|
|
} |
892
|
|
|
|
893
|
|
|
|
894
|
|
|
/** |
895
|
|
|
* if 'getData' is true, will returns 'inheritanceBy': the Member at the end of a sub-chain of |
896
|
|
|
* memberships (based on $field for Top Circle's singleId) |
897
|
|
|
* |
898
|
|
|
* @param string $alias |
899
|
|
|
* @param string $field |
900
|
|
|
* @param string $aliasInheritedBy |
901
|
|
|
* |
902
|
|
|
* @throws RequestBuilderException |
903
|
|
|
*/ |
904
|
|
|
public function leftJoinInheritedMembers( |
905
|
|
|
string $alias, |
906
|
|
|
string $field = '', |
907
|
|
|
string $aliasInheritedBy = '' |
908
|
|
|
): void { |
909
|
|
|
$expr = $this->expr(); |
910
|
|
|
|
911
|
|
|
$field = ($field === '') ? 'circle_id' : $field; |
912
|
|
|
$aliasMembership = $this->generateAlias($alias, self::MEMBERSHIPS, $options); |
913
|
|
|
|
914
|
|
|
$this->leftJoin( |
915
|
|
|
$alias, CoreRequestBuilder::TABLE_MEMBERSHIP, $aliasMembership, |
916
|
|
|
$expr->eq($aliasMembership . '.circle_id', $alias . '.' . $field) |
917
|
|
|
); |
918
|
|
|
|
919
|
|
|
// if (!$this->getBool('getData', $options, false)) { |
920
|
|
|
// return; |
921
|
|
|
// } |
922
|
|
|
|
923
|
|
|
if ($aliasInheritedBy === '') { |
924
|
|
|
$aliasInheritedBy = $this->generateAlias($alias, self::INHERITED_BY); |
925
|
|
|
} |
926
|
|
|
$this->generateMemberSelectAlias($aliasInheritedBy) |
927
|
|
|
->leftJoin( |
928
|
|
|
$alias, CoreRequestBuilder::TABLE_MEMBER, $aliasInheritedBy, |
929
|
|
|
$expr->andX( |
930
|
|
|
$expr->eq($aliasMembership . '.inheritance_last', $aliasInheritedBy . '.circle_id'), |
931
|
|
|
$expr->eq($aliasMembership . '.single_id', $aliasInheritedBy . '.single_id') |
932
|
|
|
) |
933
|
|
|
); |
934
|
|
|
|
935
|
|
|
$this->leftJoinBasedOn($aliasInheritedBy); |
936
|
|
|
} |
937
|
|
|
|
938
|
|
|
|
939
|
|
|
/** |
940
|
|
|
* @throws RequestBuilderException |
941
|
|
|
*/ |
942
|
|
|
public function limitToInheritedMemberships(string $alias, string $singleId, string $field = ''): void { |
943
|
|
|
$expr = $this->expr(); |
944
|
|
|
$field = ($field === '') ? 'circle_id' : $field; |
945
|
|
|
$aliasUpstreamMembership = $this->generateAlias($alias, self::UPSTREAM_MEMBERSHIPS, $options); |
946
|
|
|
$this->leftJoin( |
947
|
|
|
$alias, CoreRequestBuilder::TABLE_MEMBERSHIP, $aliasUpstreamMembership, |
948
|
|
|
$expr->eq($aliasUpstreamMembership . '.single_id', $this->createNamedParameter($singleId)) |
949
|
|
|
); |
950
|
|
|
|
951
|
|
|
$orX = $expr->orX( |
952
|
|
|
$expr->eq($aliasUpstreamMembership . '.circle_id', $alias . '.' . $field), |
953
|
|
|
$expr->eq($alias . '.' . $field, $this->createNamedParameter($singleId)) |
954
|
|
|
); |
955
|
|
|
|
956
|
|
|
$this->andWhere($orX); |
957
|
|
|
} |
958
|
|
|
|
959
|
|
|
|
960
|
|
|
/** |
961
|
|
|
* limit the request to Members and Sub Members of a Circle. |
962
|
|
|
* |
963
|
|
|
* @param string $alias |
964
|
|
|
* @param string $singleId |
965
|
|
|
* @param int $level |
966
|
|
|
* |
967
|
|
|
* @throws RequestBuilderException |
968
|
|
|
*/ |
969
|
|
|
public function limitToMembersByInheritance(string $alias, string $singleId, int $level = 0): void { |
970
|
|
|
$this->leftJoinMembersByInheritance($alias); |
971
|
|
|
|
972
|
|
|
$expr = $this->expr(); |
973
|
|
|
$aliasMembership = $this->generateAlias($alias, self::MEMBERSHIPS); |
974
|
|
|
$this->andWhere($expr->eq($aliasMembership . '.circle_id', $this->createNamedParameter($singleId))); |
975
|
|
|
if ($level > 1) { |
976
|
|
|
$this->andWhere( |
977
|
|
|
$expr->gte( |
978
|
|
|
$aliasMembership . '.level', |
979
|
|
|
$this->createNamedParameter($level, IQueryBuilder::PARAM_INT) |
980
|
|
|
) |
981
|
|
|
); |
982
|
|
|
} |
983
|
|
|
} |
984
|
|
|
|
985
|
|
|
|
986
|
|
|
/** |
987
|
|
|
* if 'getData' is true, will returns 'inheritanceFrom': the Circle-As-Member of the Top Circle |
988
|
|
|
* that explain the membership of a Member (based on $field for singleId) to a specific Circle |
989
|
|
|
* |
990
|
|
|
* // TODO: returns the link/path ? |
991
|
|
|
* |
992
|
|
|
* @param string $alias |
993
|
|
|
* @param string $field |
994
|
|
|
* |
995
|
|
|
* @throws RequestBuilderException |
996
|
|
|
*/ |
997
|
|
|
public function leftJoinMembersByInheritance(string $alias, string $field = ''): void { |
998
|
|
|
$expr = $this->expr(); |
999
|
|
|
|
1000
|
|
|
$field = ($field === '') ? 'circle_id' : $field; |
1001
|
|
|
$aliasMembership = $this->generateAlias($alias, self::MEMBERSHIPS, $options); |
1002
|
|
|
|
1003
|
|
|
$this->leftJoin( |
1004
|
|
|
$alias, CoreRequestBuilder::TABLE_MEMBERSHIP, $aliasMembership, |
1005
|
|
|
$expr->andX( |
1006
|
|
|
$expr->eq($aliasMembership . '.inheritance_last', $alias . '.' . $field), |
1007
|
|
|
$expr->eq($aliasMembership . '.single_id', $alias . '.single_id') |
1008
|
|
|
) |
1009
|
|
|
); |
1010
|
|
|
|
1011
|
|
|
if (!$this->getBool('getData', $options, false)) { |
1012
|
|
|
return; |
1013
|
|
|
} |
1014
|
|
|
|
1015
|
|
|
$aliasInheritanceFrom = $this->generateAlias($alias, self::INHERITANCE_FROM); |
1016
|
|
|
$this->generateMemberSelectAlias($aliasInheritanceFrom) |
1017
|
|
|
->leftJoin( |
1018
|
|
|
$aliasMembership, CoreRequestBuilder::TABLE_MEMBER, $aliasInheritanceFrom, |
1019
|
|
|
$expr->andX( |
1020
|
|
|
$expr->eq($aliasMembership . '.circle_id', $aliasInheritanceFrom . '.circle_id'), |
1021
|
|
|
$expr->eq($aliasMembership . '.inheritance_first', $aliasInheritanceFrom . '.single_id') |
1022
|
|
|
) |
1023
|
|
|
); |
1024
|
|
|
} |
1025
|
|
|
|
1026
|
|
|
|
1027
|
|
|
/** |
1028
|
|
|
* limit the result to the point of view of a FederatedUser |
1029
|
|
|
* |
1030
|
|
|
* @param string $alias |
1031
|
|
|
* @param IFederatedUser $user |
1032
|
|
|
* @param string $field |
1033
|
|
|
* @param string $helperAlias |
1034
|
|
|
* |
1035
|
|
|
* @return ICompositeExpression |
1036
|
|
|
* @throws RequestBuilderException |
1037
|
|
|
*/ |
1038
|
|
|
public function limitToInitiator( |
1039
|
|
|
string $alias, |
1040
|
|
|
IFederatedUser $user, |
1041
|
|
|
string $field = '', |
1042
|
|
|
string $helperAlias = '' |
1043
|
|
|
): ICompositeExpression { |
1044
|
|
|
$this->leftJoinInitiator($alias, $user, $field, $helperAlias); |
1045
|
|
|
$where = $this->limitInitiatorVisibility($alias); |
1046
|
|
|
|
1047
|
|
|
$aliasInitiator = $this->generateAlias($alias, self::INITIATOR, $options); |
1048
|
|
|
if ($this->getBool('getData', $options, false)) { |
1049
|
|
|
$this->leftJoinBasedOn($aliasInitiator); |
1050
|
|
|
} |
1051
|
|
|
|
1052
|
|
|
return $where; |
1053
|
|
|
} |
1054
|
|
|
|
1055
|
|
|
|
1056
|
|
|
/** |
1057
|
|
|
* Left join members to filter userId as initiator. |
1058
|
|
|
* |
1059
|
|
|
* @param string $alias |
1060
|
|
|
* @param IFederatedUser $initiator |
1061
|
|
|
* @param string $field |
1062
|
|
|
* @param string $helperAlias |
1063
|
|
|
* |
1064
|
|
|
* @throws RequestBuilderException |
1065
|
|
|
*/ |
1066
|
|
|
public function leftJoinInitiator( |
1067
|
|
|
string $alias, |
1068
|
|
|
IFederatedUser $initiator, |
1069
|
|
|
string $field = '', |
1070
|
|
|
string $helperAlias = '' |
1071
|
|
|
): void { |
1072
|
|
|
if ($this->getType() !== QueryBuilder::SELECT) { |
1073
|
|
|
return; |
1074
|
|
|
} |
1075
|
|
|
|
1076
|
|
|
$expr = $this->expr(); |
1077
|
|
|
$field = ($field === '') ? 'unique_id' : $field; |
1078
|
|
|
$helperAlias = ($helperAlias !== '') ? $helperAlias : $alias; |
1079
|
|
|
$aliasMembership = $this->generateAlias($alias, self::MEMBERSHIPS, $options); |
1080
|
|
|
|
1081
|
|
|
$this->leftJoin( |
1082
|
|
|
$helperAlias, |
1083
|
|
|
CoreRequestBuilder::TABLE_MEMBERSHIP, |
1084
|
|
|
$aliasMembership, |
1085
|
|
|
$expr->andX( |
1086
|
|
|
$this->exprLimit('single_id', $initiator->getSingleId(), $aliasMembership), |
1087
|
|
|
$expr->eq($aliasMembership . '.circle_id', $helperAlias . '.' . $field) |
1088
|
|
|
) |
1089
|
|
|
); |
1090
|
|
|
|
1091
|
|
|
if (!$this->getBool('getData', $options, false)) { |
1092
|
|
|
return; |
1093
|
|
|
} |
1094
|
|
|
|
1095
|
|
|
// bypass memberships |
1096
|
|
|
if ($this->getBool('initiatorDirectMember', $options, false)) { |
1097
|
|
|
try { |
1098
|
|
|
$aliasDirectInitiator = $this->generateAlias($alias, self::DIRECT_INITIATOR, $options); |
1099
|
|
|
$this->leftJoin( |
1100
|
|
|
$helperAlias, |
1101
|
|
|
CoreRequestBuilder::TABLE_MEMBER, |
1102
|
|
|
$aliasDirectInitiator, |
1103
|
|
|
$expr->andX( |
1104
|
|
|
$this->exprLimit('single_id', $initiator->getSingleId(), $aliasDirectInitiator), |
1105
|
|
|
$expr->eq($aliasDirectInitiator . '.circle_id', $helperAlias . '.' . $field) |
1106
|
|
|
) |
1107
|
|
|
); |
1108
|
|
|
} catch (RequestBuilderException $e) { |
|
|
|
|
1109
|
|
|
} |
1110
|
|
|
} |
1111
|
|
|
|
1112
|
|
|
|
1113
|
|
|
try { |
1114
|
|
|
$aliasInitiator = $this->generateAlias($alias, self::INITIATOR, $options); |
1115
|
|
|
$this->leftJoin( |
1116
|
|
|
$aliasMembership, CoreRequestBuilder::TABLE_MEMBER, $aliasInitiator, |
1117
|
|
|
$expr->andX( |
1118
|
|
|
$expr->eq($aliasMembership . '.inheritance_first', $aliasInitiator . '.single_id'), |
1119
|
|
|
$expr->eq($aliasMembership . '.circle_id', $aliasInitiator . '.circle_id') |
1120
|
|
|
) |
1121
|
|
|
); |
1122
|
|
|
|
1123
|
|
|
$aliasInheritedBy = $this->generateAlias($aliasInitiator, self::INHERITED_BY); |
1124
|
|
|
$this->leftJoin( |
1125
|
|
|
$aliasInitiator, CoreRequestBuilder::TABLE_MEMBER, $aliasInheritedBy, |
1126
|
|
|
$expr->andX( |
1127
|
|
|
$expr->eq($aliasMembership . '.single_id', $aliasInheritedBy . '.single_id'), |
1128
|
|
|
$expr->eq($aliasMembership . '.inheritance_last', $aliasInheritedBy . '.circle_id') |
1129
|
|
|
) |
1130
|
|
|
); |
1131
|
|
|
|
1132
|
|
|
$default = []; |
1133
|
|
|
if ($this->getBool('canBeVisitor', $options, false)) { |
1134
|
|
|
$default = [ |
1135
|
|
|
'user_id' => $initiator->getUserId(), |
1136
|
|
|
'single_id' => $initiator->getSingleId(), |
1137
|
|
|
'user_type' => $initiator->getUserType(), |
1138
|
|
|
'cached_name' => $initiator->getDisplayName(), |
1139
|
|
|
'instance' => $initiator->getInstance() |
1140
|
|
|
]; |
1141
|
|
|
} |
1142
|
|
|
$this->generateMemberSelectAlias($aliasInitiator, $default); |
1143
|
|
|
|
1144
|
|
|
$this->generateMemberSelectAlias($aliasInheritedBy); |
1145
|
|
|
$aliasInheritedByMembership = $this->generateAlias($aliasInheritedBy, self::MEMBERSHIPS); |
1146
|
|
|
$this->generateMembershipSelectAlias($aliasMembership, $aliasInheritedByMembership); |
1147
|
|
|
} catch (RequestBuilderException $e) { |
|
|
|
|
1148
|
|
|
} |
1149
|
|
|
} |
1150
|
|
|
|
1151
|
|
|
|
1152
|
|
|
/** |
1153
|
|
|
* @param string $alias |
1154
|
|
|
* |
1155
|
|
|
* @return ICompositeExpression |
1156
|
|
|
* @throws RequestBuilderException |
1157
|
|
|
*/ |
1158
|
|
|
protected function limitInitiatorVisibility(string $alias): ICompositeExpression { |
1159
|
|
|
$aliasMembership = $this->generateAlias($alias, self::MEMBERSHIPS, $options); |
1160
|
|
|
$levelCheck = [$aliasMembership]; |
1161
|
|
|
|
1162
|
|
|
if ($this->getBool('initiatorDirectMember', $options, false)) { |
1163
|
|
|
array_push($levelCheck, $this->generateAlias($alias, self::DIRECT_INITIATOR, $options)); |
1164
|
|
|
} |
1165
|
|
|
|
1166
|
|
|
$getPersonalCircle = $this->getBool('getPersonalCircle', $options, false); |
1167
|
|
|
|
1168
|
|
|
$expr = $this->expr(); |
1169
|
|
|
|
1170
|
|
|
// Visibility to non-member is |
1171
|
|
|
// - 0 (default), if initiator is member |
1172
|
|
|
// - 2 (Personal), if initiator is owner) |
1173
|
|
|
// - 4 (Visible to everyone) |
1174
|
|
|
$orX = $expr->orX(); |
1175
|
|
|
|
1176
|
|
|
$orXLevel = $expr->orX(); |
|
|
|
|
1177
|
|
|
$orX->add( |
1178
|
|
|
$expr->andX( |
1179
|
|
|
$this->orXCheckLevel($levelCheck, Member::LEVEL_MEMBER), |
1180
|
|
|
$this->exprFilterBitwise('config', Circle::CFG_PERSONAL, $alias) |
1181
|
|
|
) |
1182
|
|
|
); |
1183
|
|
|
|
1184
|
|
|
if ($getPersonalCircle) { |
1185
|
|
|
$orX->add( |
1186
|
|
|
$expr->andX( |
1187
|
|
|
$this->exprLimitBitwise('config', Circle::CFG_PERSONAL, $alias), |
1188
|
|
|
$this->orXCheckLevel($levelCheck, Member::LEVEL_OWNER) |
1189
|
|
|
) |
1190
|
|
|
); |
1191
|
|
|
} |
1192
|
|
|
|
1193
|
|
|
if (!$this->getBool('mustBeMember', $options, true)) { |
1194
|
|
|
$orX->add($this->exprLimitBitwise('config', Circle::CFG_VISIBLE, $alias)); |
1195
|
|
|
} |
1196
|
|
|
if ($this->getBool('canBeVisitor', $options, false)) { |
1197
|
|
|
// TODO: should find a better way, also filter on remote initiator on non-federated ? |
1198
|
|
|
$orX->add($expr->gte($alias . '.config', $this->createNamedParameter(0))); |
1199
|
|
|
} |
1200
|
|
|
if ($this->getBool('canBeVisitorOnOpen', $options, false)) { |
1201
|
|
|
$andOpen = $expr->andX(); |
1202
|
|
|
$andOpen->add($this->exprLimitBitwise('config', Circle::CFG_OPEN, $alias)); |
1203
|
|
|
$andOpen->add($this->exprFilterBitwise('config', Circle::CFG_REQUEST, $alias)); |
1204
|
|
|
$orX->add($andOpen); |
1205
|
|
|
} |
1206
|
|
|
|
1207
|
|
|
$this->andWhere($orX); |
1208
|
|
|
|
1209
|
|
|
return $orX; |
1210
|
|
|
// $orTypes = $this->generateLimit($qb, $circleUniqueId, $userId, $type, $name, $forceAll); |
1211
|
|
|
// if (sizeof($orTypes) === 0) { |
1212
|
|
|
// throw new ConfigNoCircleAvailableException( |
1213
|
|
|
// $this->l10n->t( |
1214
|
|
|
// 'You cannot use the Circles Application until your administrator has allowed at least one type of circles' |
1215
|
|
|
// ) |
1216
|
|
|
// ); |
1217
|
|
|
// } |
1218
|
|
|
|
1219
|
|
|
// $orXTypes = $this->expr() |
1220
|
|
|
// ->orX(); |
1221
|
|
|
// foreach ($orTypes as $orType) { |
1222
|
|
|
// $orXTypes->add($orType); |
1223
|
|
|
// } |
1224
|
|
|
// |
1225
|
|
|
// $qb->andWhere($orXTypes); |
1226
|
|
|
} |
1227
|
|
|
|
1228
|
|
|
|
1229
|
|
|
/** |
1230
|
|
|
* CFG_SINGLE, CFG_HIDDEN and CFG_BACKEND means hidden from listing. |
1231
|
|
|
* |
1232
|
|
|
* @param string $aliasCircle |
1233
|
|
|
* @param int $flag |
1234
|
|
|
*/ |
1235
|
|
|
public function filterCircles( |
1236
|
|
|
string $aliasCircle, |
1237
|
|
|
int $flag = Circle::CFG_SINGLE | Circle::CFG_HIDDEN | Circle::CFG_BACKEND |
1238
|
|
|
): void { |
1239
|
|
|
if ($flag === 0) { |
1240
|
|
|
return; |
1241
|
|
|
} |
1242
|
|
|
|
1243
|
|
|
$expr = $this->expr(); |
1244
|
|
|
$hide = $expr->andX(); |
1245
|
|
|
foreach (Circle::$DEF_CFG as $cfg => $v) { |
1246
|
|
|
if ($flag & $cfg) { |
1247
|
|
|
$hide->add($this->exprFilterBitwise('config', $cfg, $aliasCircle)); |
1248
|
|
|
} |
1249
|
|
|
} |
1250
|
|
|
|
1251
|
|
|
$this->andWhere($hide); |
1252
|
|
|
} |
1253
|
|
|
|
1254
|
|
|
|
1255
|
|
|
/** |
1256
|
|
|
* Limit visibility on Sensitive information when search for members. |
1257
|
|
|
* |
1258
|
|
|
* @param string $alias |
1259
|
|
|
* |
1260
|
|
|
* @return ICompositeExpression |
1261
|
|
|
*/ |
1262
|
|
|
private function limitRemoteVisibility_Sensitive_Members(string $alias): ICompositeExpression { |
1263
|
|
|
$expr = $this->expr(); |
1264
|
|
|
$andPassive = $expr->andX(); |
1265
|
|
|
$andPassive->add( |
1266
|
|
|
$expr->eq($alias . '.type', $this->createNamedParameter(RemoteInstance::TYPE_PASSIVE)) |
1267
|
|
|
); |
1268
|
|
|
|
1269
|
|
|
$orMemberOrLevel = $expr->orX(); |
1270
|
|
|
$orMemberOrLevel->add( |
1271
|
|
|
$expr->eq($this->getDefaultSelectAlias() . '.instance', $alias . '.instance') |
1272
|
|
|
); |
1273
|
|
|
// TODO: do we need this ? (display members from the local instance) |
1274
|
|
|
$orMemberOrLevel->add( |
1275
|
|
|
$expr->emptyString($this->getDefaultSelectAlias() . '.instance') |
1276
|
|
|
); |
1277
|
|
|
|
1278
|
|
|
$orMemberOrLevel->add( |
1279
|
|
|
$expr->eq( |
1280
|
|
|
$this->getDefaultSelectAlias() . '.level', |
1281
|
|
|
$this->createNamedParameter(Member::LEVEL_OWNER) |
1282
|
|
|
) |
1283
|
|
|
); |
1284
|
|
|
$andPassive->add($orMemberOrLevel); |
1285
|
|
|
|
1286
|
|
|
return $andPassive; |
1287
|
|
|
} |
1288
|
|
|
|
1289
|
|
|
|
1290
|
|
|
/** |
1291
|
|
|
* Link to storage/filecache |
1292
|
|
|
* |
1293
|
|
|
* @param string $aliasShare |
1294
|
|
|
* |
1295
|
|
|
* @throws RequestBuilderException |
1296
|
|
|
*/ |
1297
|
|
|
public function leftJoinFileCache(string $aliasShare) { |
1298
|
|
|
$expr = $this->expr(); |
1299
|
|
|
|
1300
|
|
|
$aliasFileCache = $this->generateAlias($aliasShare, self::FILE_CACHE); |
1301
|
|
|
$aliasStorages = $this->generateAlias($aliasFileCache, self::STORAGES); |
1302
|
|
|
|
1303
|
|
|
$this->generateSelectAlias( |
1304
|
|
|
CoreRequestBuilder::$outsideTables[CoreRequestBuilder::TABLE_FILE_CACHE], |
|
|
|
|
1305
|
|
|
$aliasFileCache, |
1306
|
|
|
$aliasFileCache, |
1307
|
|
|
[] |
1308
|
|
|
) |
1309
|
|
|
->generateSelectAlias( |
1310
|
|
|
CoreRequestBuilder::$outsideTables[CoreRequestBuilder::TABLE_STORAGES], |
|
|
|
|
1311
|
|
|
$aliasStorages, |
1312
|
|
|
$aliasStorages, |
1313
|
|
|
[] |
1314
|
|
|
) |
1315
|
|
|
->leftJoin( |
1316
|
|
|
$aliasShare, CoreRequestBuilder::TABLE_FILE_CACHE, $aliasFileCache, |
1317
|
|
|
$expr->eq($aliasShare . '.file_source', $aliasFileCache . '.fileid') |
1318
|
|
|
) |
1319
|
|
|
->leftJoin( |
1320
|
|
|
$aliasFileCache, CoreRequestBuilder::TABLE_STORAGES, $aliasStorages, |
1321
|
|
|
$expr->eq($aliasFileCache . '.storage', $aliasStorages . '.numeric_id') |
1322
|
|
|
); |
1323
|
|
|
} |
1324
|
|
|
|
1325
|
|
|
|
1326
|
|
|
/** |
1327
|
|
|
* @param string $aliasShare |
1328
|
|
|
* @param string $aliasShareMemberships |
1329
|
|
|
* |
1330
|
|
|
* @throws RequestBuilderException |
1331
|
|
|
*/ |
1332
|
|
|
public function leftJoinShareChild(string $aliasShare, string $aliasShareMemberships = '') { |
1333
|
|
|
$expr = $this->expr(); |
1334
|
|
|
|
1335
|
|
|
$aliasShareChild = $this->generateAlias($aliasShare, self::SHARE); |
1336
|
|
|
if ($aliasShareMemberships === '') { |
1337
|
|
|
$aliasShareMemberships = $this->generateAlias($aliasShare, self::MEMBERSHIPS, $options); |
1338
|
|
|
} |
1339
|
|
|
|
1340
|
|
|
$this->leftJoin( |
1341
|
|
|
$aliasShareMemberships, CoreRequestBuilder::TABLE_SHARE, $aliasShareChild, |
1342
|
|
|
$expr->andX( |
1343
|
|
|
$expr->eq($aliasShareChild . '.parent', $aliasShare . '.id'), |
1344
|
|
|
$expr->eq($aliasShareChild . '.share_with', $aliasShareMemberships . '.single_id') |
1345
|
|
|
) |
1346
|
|
|
); |
1347
|
|
|
|
1348
|
|
|
$this->generateSelectAlias( |
1349
|
|
|
['id', 'file_target', 'permissions'], |
1350
|
|
|
$aliasShareChild, |
1351
|
|
|
'child_', |
1352
|
|
|
[] |
1353
|
|
|
); |
1354
|
|
|
|
1355
|
|
|
// $this->selectAlias($aliasShareParent . '.permissions', 'parent_perms'); |
1356
|
|
|
} |
1357
|
|
|
|
1358
|
|
|
|
1359
|
|
|
/** |
1360
|
|
|
* @param string $alias |
1361
|
|
|
* @param FederatedUser $federatedUser |
1362
|
|
|
* @param bool $reshares |
1363
|
|
|
*/ |
1364
|
|
|
public function limitToShareOwner(string $alias, FederatedUser $federatedUser, bool $reshares): void { |
1365
|
|
|
$expr = $this->expr(); |
1366
|
|
|
|
1367
|
|
|
$orX = $expr->orX($this->exprLimit('uid_initiator', $federatedUser->getUserId(), $alias)); |
1368
|
|
|
|
1369
|
|
|
if ($reshares) { |
1370
|
|
|
$orX->add($this->exprLimit('uid_owner', $federatedUser->getUserId(), $alias)); |
1371
|
|
|
} |
1372
|
|
|
|
1373
|
|
|
$this->andWhere($orX); |
1374
|
|
|
} |
1375
|
|
|
|
1376
|
|
|
|
1377
|
|
|
/** |
1378
|
|
|
* @param string $aliasMount |
1379
|
|
|
* @param string $aliasMountMemberships |
1380
|
|
|
* |
1381
|
|
|
* @throws RequestBuilderException |
1382
|
|
|
*/ |
1383
|
|
|
public function leftJoinMountpoint(string $aliasMount, string $aliasMountMemberships = '') { |
1384
|
|
|
$expr = $this->expr(); |
1385
|
|
|
|
1386
|
|
|
$aliasMountpoint = $this->generateAlias($aliasMount, self::MOUNTPOINT); |
1387
|
|
|
if ($aliasMountMemberships === '') { |
1388
|
|
|
$aliasMountMemberships = $this->generateAlias($aliasMount, self::MEMBERSHIPS, $options); |
1389
|
|
|
} |
1390
|
|
|
|
1391
|
|
|
$this->leftJoin( |
1392
|
|
|
$aliasMountMemberships, CoreRequestBuilder::TABLE_MOUNTPOINT, $aliasMountpoint, |
1393
|
|
|
$expr->andX( |
1394
|
|
|
$expr->eq($aliasMountpoint . '.mount_id', $aliasMount . '.mount_id'), |
1395
|
|
|
$expr->eq($aliasMountpoint . '.single_id', $aliasMountMemberships . '.single_id') |
1396
|
|
|
) |
1397
|
|
|
); |
1398
|
|
|
|
1399
|
|
|
$this->selectAlias($aliasMountpoint . '.mountpoint', $aliasMountpoint . '_mountpoint'); |
1400
|
|
|
$this->selectAlias($aliasMountpoint . '.mountpoint_hash', $aliasMountpoint . '_mountpoint_hash'); |
1401
|
|
|
} |
1402
|
|
|
|
1403
|
|
|
|
1404
|
|
|
/** |
1405
|
|
|
* @param string $alias |
1406
|
|
|
* @param array $default |
1407
|
|
|
* |
1408
|
|
|
* @return CoreQueryBuilder |
1409
|
|
|
*/ |
1410
|
|
|
private function generateCircleSelectAlias(string $alias, array $default = []): self { |
1411
|
|
|
$this->generateSelectAlias( |
1412
|
|
|
CoreRequestBuilder::$tables[CoreRequestBuilder::TABLE_CIRCLE], |
|
|
|
|
1413
|
|
|
$alias, |
1414
|
|
|
$alias, |
1415
|
|
|
$default |
1416
|
|
|
); |
1417
|
|
|
|
1418
|
|
|
return $this; |
1419
|
|
|
} |
1420
|
|
|
|
1421
|
|
|
/** |
1422
|
|
|
* @param string $alias |
1423
|
|
|
* @param array $default |
1424
|
|
|
* |
1425
|
|
|
* @return $this |
1426
|
|
|
*/ |
1427
|
|
|
private function generateMemberSelectAlias(string $alias, array $default = []): self { |
1428
|
|
|
$this->generateSelectAlias( |
1429
|
|
|
CoreRequestBuilder::$tables[CoreRequestBuilder::TABLE_MEMBER], |
|
|
|
|
1430
|
|
|
$alias, |
1431
|
|
|
$alias, |
1432
|
|
|
$default |
1433
|
|
|
); |
1434
|
|
|
|
1435
|
|
|
return $this; |
1436
|
|
|
} |
1437
|
|
|
|
1438
|
|
|
|
1439
|
|
|
/** |
1440
|
|
|
* @param string $alias |
1441
|
|
|
* @param array $default |
1442
|
|
|
* @param string $prefix |
1443
|
|
|
* |
1444
|
|
|
* @return $this |
1445
|
|
|
*/ |
1446
|
|
|
private function generateMembershipSelectAlias( |
1447
|
|
|
string $alias, |
1448
|
|
|
string $prefix = '', |
1449
|
|
|
array $default = [] |
1450
|
|
|
): self { |
1451
|
|
|
$this->generateSelectAlias( |
1452
|
|
|
CoreRequestBuilder::$tables[CoreRequestBuilder::TABLE_MEMBERSHIP], |
|
|
|
|
1453
|
|
|
$alias, |
1454
|
|
|
($prefix === '') ? $alias : $prefix, |
1455
|
|
|
$default |
1456
|
|
|
); |
1457
|
|
|
|
1458
|
|
|
return $this; |
1459
|
|
|
} |
1460
|
|
|
|
1461
|
|
|
|
1462
|
|
|
/** |
1463
|
|
|
* @param string $alias |
1464
|
|
|
* @param array $default |
1465
|
|
|
* |
1466
|
|
|
* @return $this |
1467
|
|
|
*/ |
1468
|
|
|
private function generateRemoteInstanceSelectAlias(string $alias, array $default = []): self { |
1469
|
|
|
$this->generateSelectAlias( |
1470
|
|
|
CoreRequestBuilder::$tables[CoreRequestBuilder::TABLE_REMOTE], |
|
|
|
|
1471
|
|
|
$alias, |
1472
|
|
|
$alias, |
1473
|
|
|
$default |
1474
|
|
|
); |
1475
|
|
|
|
1476
|
|
|
return $this; |
1477
|
|
|
} |
1478
|
|
|
|
1479
|
|
|
|
1480
|
|
|
/** |
1481
|
|
|
* @param array $path |
1482
|
|
|
* @param array $options |
1483
|
|
|
*/ |
1484
|
|
|
public function setOptions(array $path, array $options): void { |
1485
|
|
|
$options = [self::OPTIONS => $options]; |
1486
|
|
|
foreach (array_reverse($path) as $item) { |
1487
|
|
|
$options = [$item => $options]; |
1488
|
|
|
} |
1489
|
|
|
|
1490
|
|
|
$this->options = $options; |
1491
|
|
|
} |
1492
|
|
|
|
1493
|
|
|
|
1494
|
|
|
/** |
1495
|
|
|
* @param string $base |
1496
|
|
|
* @param string $extension |
1497
|
|
|
* @param array|null $options |
1498
|
|
|
* |
1499
|
|
|
* @return string |
1500
|
|
|
* @throws RequestBuilderException |
1501
|
|
|
*/ |
1502
|
|
|
public function generateAlias(string $base, string $extension, ?array &$options = []): string { |
1503
|
|
|
$search = str_replace('_', '.', $base); |
1504
|
|
|
$path = $search . '.' . $extension; |
1505
|
|
|
if (!$this->validKey($path, self::$SQL_PATH) |
1506
|
|
|
&& !in_array($extension, $this->getArray($search, self::$SQL_PATH))) { |
1507
|
|
|
throw new RequestBuilderException($extension . ' not found in ' . $search); |
1508
|
|
|
} |
1509
|
|
|
|
1510
|
|
|
if (!is_array($options)) { |
1511
|
|
|
$options = []; |
1512
|
|
|
} |
1513
|
|
|
|
1514
|
|
|
$optionPath = ''; |
1515
|
|
|
foreach (explode('.', $path) as $p) { |
1516
|
|
|
$optionPath = trim($optionPath . '.' . $p, '.'); |
1517
|
|
|
$options = array_merge( |
1518
|
|
|
$options, |
1519
|
|
|
$this->getArray($optionPath . '.' . self::OPTIONS, self::$SQL_PATH), |
1520
|
|
|
$this->getArray($optionPath . '.' . self::OPTIONS, $this->options) |
1521
|
|
|
); |
1522
|
|
|
} |
1523
|
|
|
|
1524
|
|
|
return $base . '_' . $extension; |
1525
|
|
|
} |
1526
|
|
|
|
1527
|
|
|
|
1528
|
|
|
/** |
1529
|
|
|
* @param string $prefix |
1530
|
|
|
* |
1531
|
|
|
* @return array |
1532
|
|
|
*/ |
1533
|
|
|
public function getAvailablePath(string $prefix): array { |
1534
|
|
|
$prefix = trim($prefix, '_'); |
1535
|
|
|
$search = str_replace('_', '.', $prefix); |
1536
|
|
|
|
1537
|
|
|
$path = []; |
1538
|
|
|
foreach ($this->getArray($search, self::$SQL_PATH) as $arr => $item) { |
1539
|
|
|
if (is_numeric($arr)) { |
1540
|
|
|
$k = $item; |
1541
|
|
|
} else { |
1542
|
|
|
$k = $arr; |
1543
|
|
|
} |
1544
|
|
|
$path[$k] = $prefix . '_' . $k . '_'; |
1545
|
|
|
} |
1546
|
|
|
|
1547
|
|
|
return $path; |
1548
|
|
|
} |
1549
|
|
|
|
1550
|
|
|
|
1551
|
|
|
/** |
1552
|
|
|
* @param array $aliases |
1553
|
|
|
* @param int $level |
1554
|
|
|
* |
1555
|
|
|
* @return ICompositeExpression |
1556
|
|
|
*/ |
1557
|
|
|
private function orXCheckLevel(array $aliases, int $level): ICompositeExpression { |
1558
|
|
|
$expr = $this->expr(); |
1559
|
|
|
$orX = $expr->orX(); |
1560
|
|
|
foreach ($aliases as $alias) { |
1561
|
|
|
$orX->add($expr->gte($alias . '.level', $this->createNamedParameter($level))); |
1562
|
|
|
} |
1563
|
|
|
|
1564
|
|
|
return $orX; |
1565
|
|
|
} |
1566
|
|
|
|
1567
|
|
|
} |
1568
|
|
|
|
1569
|
|
|
|
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.