Completed
Push — master ( d9f0cd...271a28 )
by Maxence
03:18 queued 01:12
created

generateLimitToLevelMultipleTableRequest()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 13
rs 9.8333
cc 4
nc 3
nop 3
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: maxence
5
 * Date: 7/4/17
6
 * Time: 5:01 PM
7
 */
8
9
namespace OCA\Circles\Db;
10
11
12
use Doctrine\DBAL\Query\QueryBuilder;
13
use OCA\Circles\Model\Circle;
14
use OCA\Circles\Model\Member;
15
use OCA\Circles\Service\ConfigService;
16
use OCA\Circles\Service\MiscService;
17
use OCA\Circles\Service\TimezoneService;
18
use OCP\DB\QueryBuilder\IQueryBuilder;
19
use OCP\IDBConnection;
20
use OCP\IL10N;
21
22
class CoreRequestBuilder {
23
24
	const TABLE_FILE_SHARES = 'share';
25
	const SHARE_TYPE = 7;
26
27
	const TABLE_CIRCLES = 'circles_circles';
28
	const TABLE_MEMBERS = 'circles_members';
29
	const TABLE_GROUPS = 'circles_groups';
30
	const TABLE_SHARES = 'circles_shares';
31
	const TABLE_LINKS = 'circles_links';
32
	const TABLE_TOKENS = 'circles_tokens';
33
34
	const NC_TABLE_GROUP_USER = 'group_user';
35
36
	/** @var IDBConnection */
37
	protected $dbConnection;
38
39
	/** @var IL10N */
40
	protected $l10n;
41
42
	/** @var ConfigService */
43
	protected $configService;
44
45
	/** @var TimezoneService */
46
	protected $timezoneService;
47
48
	/** @var MiscService */
49
	protected $miscService;
50
51
	/** @var string */
52
	protected $default_select_alias;
53
54
	/** @var bool */
55
	protected $leftJoinedNCGroupAndUser = false;
56
57
	/**
58
	 * RequestBuilder constructor.
59
	 *
60
	 * @param IL10N $l10n
61
	 * @param IDBConnection $connection
62
	 * @param ConfigService $configService
63
	 * @param TimezoneService $timezoneService
64
	 * @param MiscService $miscService
65
	 */
66
	public function __construct(
67
		IL10N $l10n, IDBConnection $connection, ConfigService $configService,
68
		TimezoneService $timezoneService, MiscService $miscService
69
	) {
70
		$this->l10n = $l10n;
71
		$this->dbConnection = $connection;
72
		$this->configService = $configService;
73
		$this->timezoneService = $timezoneService;
74
		$this->miscService = $miscService;
75
	}
76
77
78
	/**
79
	 * Limit the request by its Id.
80
	 *
81
	 * @param IQueryBuilder $qb
82
	 * @param int $id
83
	 */
84
	protected function limitToId(IQueryBuilder &$qb, $id) {
85
		$this->limitToDBField($qb, 'id', $id);
86
	}
87
88
89
	/**
90
	 * Limit the request by its UniqueId.
91
	 *
92
	 * @param IQueryBuilder $qb
93
	 * @param int $uniqueId
94
	 */
95
	protected function limitToUniqueId(IQueryBuilder &$qb, $uniqueId) {
96
		$this->limitToDBField($qb, 'unique_id', $uniqueId);
97
	}
98
99
100
	/**
101
	 * Limit the request by its addressbookId.
102
	 *
103
	 * @param IQueryBuilder $qb
104
	 * @param int $bookId
105
	 */
106
	protected function limitToAddressBookId(IQueryBuilder &$qb, $bookId) {
107
		$this->limitToDBField($qb, 'contact_addressbook', (string)$bookId);
108
	}
109
110
111
112
	/**
113
	 * Limit the request by its addressbookId.
114
	 *
115
	 * @param IQueryBuilder $qb
116
	 * @param string $groupName
117
	 */
118
	protected function limitToContactGroup(IQueryBuilder &$qb, $groupName) {
119
		$this->limitToDBField($qb, 'contact_groupname', $groupName);
120
	}
121
122
123
	/**
124
	 * Limit the request to the Circle by its Id.
125
	 *
126
	 * @param IQueryBuilder $qb
127
	 * @param string $contactId
128
	 */
129
	protected function limitToContactId(IQueryBuilder &$qb, $contactId) {
130
		$this->limitToDBField($qb, 'contact_id', $contactId);
131
	}
132
133
134
	/**
135
	 * Limit the request by its Token.
136
	 *
137
	 * @param IQueryBuilder $qb
138
	 * @param string $token
139
	 */
140
	protected function limitToToken(IQueryBuilder &$qb, $token) {
141
		$this->limitToDBField($qb, 'token', $token);
142
	}
143
144
145
	/**
146
	 * Limit the request to the User by its Id.
147
	 *
148
	 * @param IQueryBuilder $qb
149
	 * @param $userId
150
	 */
151
	protected function limitToUserId(IQueryBuilder &$qb, $userId) {
152
		$this->limitToDBField($qb, 'user_id', $userId);
153
	}
154
155
156
	/**
157
	 * Limit the request to the Type entry.
158
	 *
159
	 * @param IQueryBuilder $qb
160
	 * @param int $type
161
	 */
162
	protected function limitToUserType(IQueryBuilder &$qb, $type) {
163
		$this->limitToDBField($qb, 'user_type', $type);
164
	}
165
166
167
	/**
168
	 * Limit the request to the Circle by its Id.
169
	 *
170
	 * @param IQueryBuilder $qb
171
	 * @param string $circleUniqueId
172
	 */
173
	protected function limitToCircleId(IQueryBuilder &$qb, $circleUniqueId) {
174
		$this->limitToDBField($qb, 'circle_id', $circleUniqueId);
175
	}
176
177
178
	/**
179
	 * Limit the request to the Circle by its Id.
180
	 *
181
	 * @param IQueryBuilder $qb
182
	 * @param int $shareId
183
	 */
184
	protected function limitToShareId(IQueryBuilder &$qb, int $shareId) {
185
		$this->limitToDBField($qb, 'share_id', $shareId);
186
	}
187
188
189
	/**
190
	 * Limit the request to the Circle by its Shorten Unique Id.
191
	 *
192
	 * @param IQueryBuilder $qb
193
	 * @param string $circleUniqueId
194
	 * @param $length
195
	 */
196
	protected function limitToShortenUniqueId(IQueryBuilder &$qb, $circleUniqueId, $length) {
197
		$expr = $qb->expr();
198
		$pf = ($qb->getType() === QueryBuilder::SELECT) ? '`' . $this->default_select_alias . '`.' : '';
199
200
		$qb->andWhere(
201
			$expr->eq(
202
				$qb->createNamedParameter($circleUniqueId),
203
				$qb->createFunction('SUBSTR(' . $pf . '`unique_id`' . ', 1, ' . $length . ')')
204
			)
205
		);
206
207
	}
208
209
210
	/**
211
	 * Limit the request to the Group by its Id.
212
	 *
213
	 * @param IQueryBuilder $qb
214
	 * @param int $groupId
215
	 */
216
	protected function limitToGroupId(IQueryBuilder &$qb, $groupId) {
217
		$this->limitToDBField($qb, 'group_id', $groupId);
218
	}
219
220
221
	/**
222
	 * Limit the search by its Name
223
	 *
224
	 * @param IQueryBuilder $qb
225
	 * @param string $name
226
	 */
227
	protected function limitToName(IQueryBuilder &$qb, $name) {
228
		$this->limitToDBField($qb, 'name', $name);
229
	}
230
231
232
	/**
233
	 * Limit the search by its Status (or greater)
234
	 *
235
	 * @param IQueryBuilder $qb
236
	 * @param string $name
237
	 */
238
	protected function limitToStatus(IQueryBuilder &$qb, $name) {
239
		$this->limitToDBFieldOrGreater($qb, 'status', $name);
240
	}
241
242
243
	/**
244
	 * Limit the request by its Id.
245
	 *
246
	 * @param IQueryBuilder $qb
247
	 * @param string $type
248
	 */
249
	protected function limitToShareType(IQueryBuilder &$qb, string $type) {
250
		$this->limitToDBField($qb, 'share_type', $type);
251
	}
252
253
254
	/**
255
	 * Limit the request by its Id.
256
	 *
257
	 * @param IQueryBuilder $qb
258
	 * @param string $with
259
	 */
260
	protected function limitToShareWith(IQueryBuilder &$qb, string $with) {
261
		$this->limitToDBField($qb, 'share_with', $with);
262
	}
263
264
265
	/**
266
	 * Limit the request to a minimum member level.
267
	 *
268
	 * if $pf is an array, will generate an SQL OR request to limit level in multiple tables
269
	 *
270
	 * @param IQueryBuilder $qb
271
	 * @param int $level
272
	 * @param string|array $pf
273
	 */
274
	protected function limitToLevel(IQueryBuilder &$qb, $level, $pf = '') {
275
		$expr = $qb->expr();
276
277
		if ($pf === '') {
278
			$p = ($qb->getType() === QueryBuilder::SELECT) ? $this->default_select_alias . '.' : '';
279
			$qb->andWhere($expr->gte($p . 'level', $qb->createNamedParameter($level)));
280
281
			return;
282
		}
283
284
		if (!is_array($pf)) {
285
			$pf = [$pf];
286
		}
287
288
		$orX = $this->generateLimitToLevelMultipleTableRequest($qb, $level, $pf);
289
		$qb->andWhere($orX);
290
	}
291
292
293
	/**
294
	 * @param IQueryBuilder $qb
295
	 * @param array $pf
296
	 *
297
	 * @return mixed
298
	 */
299
	private function generateLimitToLevelMultipleTableRequest(IQueryBuilder $qb, $level, $pf) {
300
		$expr = $qb->expr();
301
		$orX = $expr->orX();
302
303
		foreach ($pf as $p) {
304
			if ($p === 'g' && !$this->leftJoinedNCGroupAndUser) {
305
				continue;
306
			}
307
			$orX->add($expr->gte($p . '.level', $qb->createNamedParameter($level)));
308
		}
309
310
		return $orX;
311
	}
312
313
314
	/**
315
	 * Limit the search to Members and Almost members
316
	 *
317
	 * @param IQueryBuilder $qb
318
	 */
319
	protected function limitToMembersAndAlmost(IQueryBuilder &$qb) {
320
		$expr = $qb->expr();
321
322
		$pf = ($qb->getType() === QueryBuilder::SELECT) ? $this->default_select_alias . '.' : '';
323
324
		$orX = $expr->orX();
325
		$orX->add($expr->eq($pf . 'status', $qb->createNamedParameter(Member::STATUS_MEMBER)));
326
		$orX->add($expr->eq($pf . 'status', $qb->createNamedParameter(Member::STATUS_INVITED)));
327
		$orX->add($expr->eq($pf . 'status', $qb->createNamedParameter(Member::STATUS_REQUEST)));
328
329
		$qb->andWhere($orX);
330
	}
331
332
333
	/**
334
	 * @param IQueryBuilder $qb
335
	 * @param string $field
336
	 * @param string|integer $value
337
	 */
338
	private function limitToDBField(IQueryBuilder &$qb, $field, $value) {
339
		$expr = $qb->expr();
340
		$pf = ($qb->getType() === QueryBuilder::SELECT) ? $this->default_select_alias . '.' : '';
341
		$qb->andWhere($expr->eq($pf . $field, $qb->createNamedParameter($value)));
342
	}
343
344
345
	/**
346
	 * @param IQueryBuilder $qb
347
	 * @param string $field
348
	 * @param string|integer $value
349
	 */
350
	private function limitToDBFieldOrGreater(IQueryBuilder &$qb, $field, $value) {
351
		$expr = $qb->expr();
352
		$pf = ($qb->getType() === QueryBuilder::SELECT) ? $this->default_select_alias . '.' : '';
353
		$qb->andWhere($expr->gte($pf . $field, $qb->createNamedParameter($value)));
354
	}
355
356
357
	/**
358
	 * link to the groupId/UserId of the NC DB.
359
	 * If userId is empty, we add the uid of the NCGroup Table in the select list with 'user_id'
360
	 * alias
361
	 *
362
	 * @param IQueryBuilder $qb
363
	 * @param string $userId
364
	 */
365
	protected function limitToNCGroupUser(IQueryBuilder $qb, $userId = '') {
366
		$expr = $qb->expr();
367
368
		$pf = ($qb->getType() === QueryBuilder::SELECT) ? $this->default_select_alias . '.' : '';
369
370
		$and = $expr->andX($expr->eq($pf . 'group_id', 'ncgu.gid'));
371
		if ($userId !== '') {
372
			$and->add($expr->eq('ncgu.uid', $qb->createNamedParameter($userId)));
373
		} else {
374
			$qb->selectAlias('ncgu.uid', 'user_id');
375
		}
376
377
		$qb->from(self::NC_TABLE_GROUP_USER, 'ncgu');
378
		$qb->andWhere($and);
379
	}
380
381
382
	/**
383
	 * Right Join the Circles table
384
	 *
385
	 * @param IQueryBuilder $qb
386
	 *
387
	 * @deprecated not used (14/07/17)
388
	 */
389
	protected function rightJoinCircles(IQueryBuilder &$qb) {
390
		$expr = $qb->expr();
391
		$pf = ($qb->getType() === QueryBuilder::SELECT) ? $this->default_select_alias . '.' : '';
392
393
		$qb->from(self::TABLE_CIRCLES, 'c')
394
		   ->andWhere(
395
			   $expr->eq(
396
				   $pf . 'circle_id',
397
				   $qb->createFunction(
398
					   'SUBSTR(`c`.`unique_id`, 1, ' . Circle::SHORT_UNIQUE_ID_LENGTH . ')'
399
				   )
400
			   )
401
		   );
402
	}
403
404
405
	/**
406
	 * Left Join circle table to get more information about the circle.
407
	 *
408
	 * @param IQueryBuilder $qb
409
	 */
410
	protected function leftJoinCircle(IQueryBuilder &$qb) {
411
		if ($qb->getType() !== QueryBuilder::SELECT) {
412
			return;
413
		}
414
415
		$expr = $qb->expr();
416
		$pf = $this->default_select_alias . '.';
417
418
		/** @noinspection PhpMethodParametersCountMismatchInspection */
419
		$qb->selectAlias('lc.type', 'circle_type')
420
		   ->selectAlias('lc.name', 'circle_name')
421
		   ->leftJoin(
422
			   $this->default_select_alias, CoreRequestBuilder::TABLE_CIRCLES, 'lc',
423
			   $expr->eq(
424
				   $pf . 'circle_id',
425
				   $qb->createFunction(
426
					   'SUBSTR(`lc`.`unique_id`, 1, ' . Circle::SHORT_UNIQUE_ID_LENGTH . ')'
427
				   )
428
			   )
429
		   );
430
	}
431
432
433
	/**
434
	 * link to the groupId/UserId of the NC DB.
435
	 *
436
	 * @param IQueryBuilder $qb
437
	 * @param string $userId
438
	 * @param string $field
439
	 */
440
	protected function leftJoinNCGroupAndUser(IQueryBuilder $qb, $userId, $field) {
441
		if (!$this->configService->isLinkedGroupsAllowed()) {
442
			return;
443
		}
444
445
		$expr = $qb->expr();
446
		$qb->leftJoin(
447
			$this->default_select_alias, self::NC_TABLE_GROUP_USER, 'ncgu',
448
			$expr->eq('ncgu.uid', $qb->createNamedParameter($userId))
449
		);
450
451
		/** @noinspection PhpMethodParametersCountMismatchInspection */
452
		$qb->leftJoin(
453
			$this->default_select_alias, CoreRequestBuilder::TABLE_GROUPS, 'g',
454
			$expr->andX(
455
				$expr->eq('ncgu.gid', 'g.group_id'),
456
				$expr->eq(
457
					'g.circle_id', $qb->createFunction(
458
					'SUBSTR(' . $field . ', 1, ' . Circle::SHORT_UNIQUE_ID_LENGTH . ')'
459
				)
460
				)
461
			)
462
		);
463
464
		$this->leftJoinedNCGroupAndUser = true;
465
	}
466
}
467
468
469
470