Completed
Push — master ( 3071ad...3723f6 )
by Maxence
03:35 queued 01:12
created

CirclesRequest::isCircleUnique()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 21
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 21
rs 9.0534
cc 4
eloc 11
nc 4
nop 2
1
<?php
2
/**
3
 * Circles - Bring cloud-users closer together.
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Maxence Lange <[email protected]>
9
 * @copyright 2017
10
 * @license GNU AGPL version 3 or any later version
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License as
14
 * published by the Free Software Foundation, either version 3 of the
15
 * License, or (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24
 *
25
 */
26
27
28
namespace OCA\Circles\Db;
29
30
31
use OC\L10N\L10N;
32
use OCA\Circles\Exceptions\CircleAlreadyExistsException;
33
use OCA\Circles\Exceptions\CircleDoesNotExistException;
34
use OCA\Circles\Exceptions\FederatedLinkDoesNotExistException;
35
use OCA\Circles\Exceptions\SharingFrameDoesNotEXist;
36
use OCA\Circles\Model\Circle;
37
use OCA\Circles\Model\FederatedLink;
38
use OCA\Circles\Model\Member;
39
use OCA\Circles\Model\SharingFrame;
40
use OCA\Circles\Service\MiscService;
41
use OCP\IDBConnection;
42
43
class CirclesRequest extends CirclesRequestBuilder {
44
45
46
	/**
47
	 * forceGetCircle();
48
	 *
49
	 * returns data of a circle from its Id.
50
	 *
51
	 * WARNING: This function does not filters data regarding the current user/viewer.
52
	 *          In case of interaction with users, Please use getCircle() instead.
53
	 *
54
	 * @param int $circleId
55
	 *
56
	 * @return Circle
57
	 * @throws CircleDoesNotExistException
58
	 */
59
	public function forceGetCircle($circleId) {
60
		$qb = $this->getCirclesSelectSql();
61
62
		$this->limitToId($qb, $circleId);
63
64
		$cursor = $qb->execute();
65
		$data = $cursor->fetch();
66
		$cursor->closeCursor();
67
68
		if ($data === false) {
69
			throw new CircleDoesNotExistException($this->l10n->t('Circle not found'));
70
		}
71
72
		$entry = $this->parseCirclesSelectSql($data);
73
74
		return $entry;
75
	}
76
77
78
	/**
79
	 * forceGetCircleByName();
80
	 *
81
	 * returns data of a circle from its Name.
82
	 *
83
	 * WARNING: This function does not filters data regarding the current user/viewer.
84
	 *          In case of interaction with users, do not use this method.
85
	 *
86
	 * @param $name
87
	 *
88
	 * @return null|Circle
89
	 * @throws CircleDoesNotExistException
90
	 */
91
	public function forceGetCircleByName($name) {
92
93
		$qb = $this->getCirclesSelectSql();
94
95
		$this->limitToName($qb, $name);
96
97
		$cursor = $qb->execute();
98
		$data = $cursor->fetch();
99
		$cursor->closeCursor();
100
101
		if ($data === false) {
102
			throw new CircleDoesNotExistException($this->l10n->t('Circle not found'));
103
		}
104
105
		$entry = $this->parseCirclesSelectSql($data);
106
107
		return $entry;
108
	}
109
110
111
	public function getCircles($userId, $type = 0, $name = '', $level = 0) {
112
		if ($type === 0) {
113
			$type = Circle::CIRCLES_ALL;
114
		}
115
116
		$qb = $this->getCirclesSelectSql();
117
		$this->leftJoinUserIdAsViewer($qb, $userId);
118
		$this->leftJoinOwner($qb);
119
		$this->leftJoinGroups($qb, 'c.id');
120
		$this->leftJoinNCGroupAndUser($qb, 'g.group_id', $userId);
121
122
		if ($level > 0) {
123
			$this->limitToLevel($qb, $level, ['u', 'g']);
124
		}
125
		$this->limitRegardingCircleType($qb, $userId, -1, $type, $name);
126
127
		$result = [];
128
		$cursor = $qb->execute();
129
		while ($data = $cursor->fetch()) {
130
			if ($name === '' || stripos(strtolower($data['name']), strtolower($name)) !== false) {
131
				$result[] = $this->parseCirclesSelectSql($data);
132
			}
133
		}
134
		$cursor->closeCursor();
135
136
		return $result;
137
	}
138
139
140
	/**
141
	 *
142
	 * @param int $circleId
143
	 * @param string $viewerId
144
	 *
145
	 * @return Circle
146
	 * @throws CircleDoesNotExistException
147
	 */
148
	public function getCircle($circleId, $viewerId) {
149
		$qb = $this->getCirclesSelectSql();
150
151
		$this->limitToId($qb, $circleId);
152
153
		$this->leftJoinUserIdAsViewer($qb, $viewerId);
154
		$this->leftJoinOwner($qb);
155
		$this->leftJoinGroups($qb, 'c.id');
156
		$this->leftJoinNCGroupAndUser($qb, 'g.group_id', $viewerId);
157
158
		$this->limitRegardingCircleType($qb, $viewerId, $circleId, Circle::CIRCLES_ALL, '');
159
160
		$cursor = $qb->execute();
161
		$data = $cursor->fetch();
162
		$cursor->closeCursor();
163
164
		if ($data === false) {
165
			throw new CircleDoesNotExistException($this->l10n->t('Circle not found'));
166
		}
167
168
		$circle = $this->parseCirclesSelectSql($data);
169
		$circle->setGroupViewer(
170
			$this->membersRequest->forceGetHigherLevelGroupFromUser($circleId, $viewerId)
171
		);
172
173
		return $circle;
174
	}
175
176
177
	/**
178
	 * createCircle();
179
	 *
180
	 * Create a circle with $userId as its owner.
181
	 * Will returns the circle
182
	 *
183
	 * @param Circle $circle
184
	 * @param $userId
185
	 *
186
	 * @throws CircleAlreadyExistsException
187
	 */
188
	public function createCircle(Circle &$circle, $userId) {
189
190
		if (!$this->isCircleUnique($circle, $userId)) {
191
			throw new CircleAlreadyExistsException(
192
				$this->l10n->t('A circle with that name exists')
193
			);
194
		}
195
196
		$circle->generateUniqueId();
197
		$qb = $this->getCirclesInsertSql();
198
		$qb->setValue('unique_id', $qb->createNamedParameter($circle->getUniqueId(true)))
199
		   ->setValue('name', $qb->createNamedParameter($circle->getName()))
200
		   ->setValue('description', $qb->createNamedParameter($circle->getDescription()))
201
		   ->setValue('settings', $qb->createNamedParameter($circle->getSettings(true)))
202
		   ->setValue('type', $qb->createNamedParameter($circle->getType()));
203
		$qb->execute();
204
205
		$circle->setId($qb->getLastInsertId());
206
207
		$owner = new Member($this->l10n, $userId);
208
		$owner->setCircleId($circle->getId())
209
			  ->setLevel(Member::LEVEL_OWNER)
210
			  ->setStatus(Member::STATUS_MEMBER);
211
		$circle->setOwner($owner)
212
			   ->setViewer($owner);
213
	}
214
215
216
	/**
217
	 * remove a circle
218
	 *
219
	 * @param int $circleId
220
	 */
221
	public function destroyCircle($circleId) {
222
		$qb = $this->getCirclesDeleteSql();
223
		$qb->where(
224
			$qb->expr()
225
			   ->eq(
226
				   'id', $qb->createNamedParameter($circleId)
227
			   )
228
		);
229
230
		$qb->execute();
231
	}
232
233
234
	/**
235
	 * returns if the circle is already in database
236
	 *
237
	 * @param Circle $circle
238
	 * @param string $userId
239
	 *
240
	 * @return bool
241
	 */
242
	private function isCircleUnique(Circle $circle, $userId) {
243
244
		if ($circle->getType() === Circle::CIRCLES_PERSONAL) {
245
			return $this->isPersonalCircleUnique($circle, $userId);
246
		}
247
248
		$qb = $this->getCirclesSelectSql();
249
		$this->limitToNonPersonalCircle($qb);
250
		//	$this->limitToName($qb, $circle->getName());
0 ignored issues
show
Unused Code Comprehensibility introduced by
74% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
251
252
		$cursor = $qb->execute();
253
		while ($data = $cursor->fetch()) {
254
			// Welp, haven't found a way to do non-sensitive search in IQueryBuilder.
255
			if (strtolower($data['name']) === strtolower($circle->getName())) {
256
				return false;
257
			}
258
		}
259
		$cursor->closeCursor();
260
261
		return true;
262
	}
263
264
265
	/**
266
	 * return if the personal circle is unique
267
	 *
268
	 * @param Circle $circle
269
	 * @param string $userId
270
	 *
271
	 * @return bool
272
	 */
273
	private function isPersonalCircleUnique(Circle $circle, $userId) {
274
275
		$list = $this->getCircles(
276
			$userId, Circle::CIRCLES_PERSONAL, $circle->getName(),
277
			Member::LEVEL_OWNER
278
		);
279
280
		foreach ($list as $test) {
281
			if (strtolower($test->getName()) === strtolower($circle->getName())) {
282
				return false;
283
			}
284
		}
285
286
		return true;
287
	}
288
289
290
	/**
291
	 * saveFrame()
292
	 *
293
	 * Insert a new entry in the database to save the SharingFrame.
294
	 *
295
	 * @param SharingFrame $frame
296
	 */
297 View Code Duplication
	public function saveFrame(SharingFrame $frame) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
298
299
		$qb = $this->getSharesInsertSql();
300
		$qb->setValue('circle_id', $qb->createNamedParameter($frame->getCircleId()))
301
		   ->setValue('source', $qb->createNamedParameter($frame->getSource()))
302
		   ->setValue('type', $qb->createNamedParameter($frame->getType()))
303
		   ->setValue('headers', $qb->createNamedParameter($frame->getHeaders(true)))
304
		   ->setValue('author', $qb->createNamedParameter($frame->getAuthor()))
305
		   ->setValue('cloud_id', $qb->createNamedParameter($frame->getCloudId()))
306
		   ->setValue('unique_id', $qb->createNamedParameter($frame->getUniqueId()))
307
		   ->setValue('payload', $qb->createNamedParameter($frame->getPayload(true)));
308
309
		$qb->execute();
310
	}
311
312
313 View Code Duplication
	public function updateFrame(SharingFrame $frame) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
314
		$qb = $this->getSharesUpdateSql($frame->getUniqueId());
315
		$qb->set('circle_id', $qb->createNamedParameter($frame->getCircleId()))
316
		   ->set('source', $qb->createNamedParameter($frame->getSource()))
317
		   ->set('type', $qb->createNamedParameter($frame->getType()))
318
		   ->set('headers', $qb->createNamedParameter($frame->getHeaders(true)))
319
		   ->set('author', $qb->createNamedParameter($frame->getAuthor()))
320
		   ->set('cloud_id', $qb->createNamedParameter($frame->getCloudId()))
321
		   ->set('unique_id', $qb->createNamedParameter($frame->getUniqueId()))
322
		   ->set('payload', $qb->createNamedParameter($frame->getPayload(true)));
323
324
		$qb->execute();
325
	}
326
327
328
	public function updateCircle(Circle $circle) {
329
		$qb = $this->getCirclesUpdateSql($circle->getId());
330
		$qb->set('name', $qb->createNamedParameter($circle->getName()))
331
		   ->set('description', $qb->createNamedParameter($circle->getDescription()))
332
		   ->set('settings', $qb->createNamedParameter($circle->getSettings(true)));
333
334
		$qb->execute();
335
	}
336
337
338
	/**
339
	 * @param string $uniqueId
340
	 *
341
	 * @return Circle
342
	 * @throws CircleDoesNotExistException
343
	 */
344 View Code Duplication
	public function getCircleFromUniqueId($uniqueId) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
345
		$qb = $this->getCirclesSelectSql();
346
		$this->limitToUniqueId($qb, (string)$uniqueId);
347
348
		$cursor = $qb->execute();
349
		$data = $cursor->fetch();
350
		$cursor->closeCursor();
351
352
		if ($data === false) {
353
			throw new CircleDoesNotExistException($this->l10n->t('Circle not found'));
354
		}
355
356
		$entry = $this->parseCirclesSelectSql($data);
357
358
		return $entry;
359
	}
360
361
362
	/**
363
	 * @param int $circleId
364
	 * @param string $uniqueId
365
	 *
366
	 * @return SharingFrame
367
	 * @throws SharingFrameDoesNotEXist
368
	 */
369 View Code Duplication
	public function getFrame($circleId, $uniqueId) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
370
		$qb = $this->getSharesSelectSql();
371
		$this->limitToUniqueId($qb, (string)$uniqueId);
372
		$this->limitToCircleId($qb, (int)$circleId);
373
374
		$cursor = $qb->execute();
375
		$data = $cursor->fetch();
376
		$cursor->closeCursor();
377
378
		if ($data === false) {
379
			throw new SharingFrameDoesNotEXist($this->l10n->t('Sharing Frame does not exist'));
380
		}
381
382
		$entry = $this->parseSharesSelectSql($data);
383
384
		return $entry;
385
	}
386
387
388
	/**
389
	 * return the FederatedLink identified by a remote Circle UniqueId and the Token of the link
390
	 *
391
	 * @param string $token
392
	 * @param string $uniqueId
393
	 *
394
	 * @return FederatedLink
395
	 * @throws FederatedLinkDoesNotExistException
396
	 */
397 View Code Duplication
	public function getLinkFromToken($token, $uniqueId) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
398
		$qb = $this->getLinksSelectSql();
399
		$this->limitToUniqueId($qb, (string)$uniqueId);
400
		$this->limitToToken($qb, (string)$token);
401
402
		$cursor = $qb->execute();
403
		$data = $cursor->fetch();
404
		$cursor->closeCursor();
405
406
		if ($data === false) {
407
			throw new FederatedLinkDoesNotExistException(
408
				$this->l10n->t('Federated Link not found')
409
			);
410
		}
411
412
		$entry = $this->parseLinksSelectSql($data);
413
414
		return $entry;
415
	}
416
417
418
	/**
419
	 * return the FederatedLink identified by a its Id
420
	 *
421
	 * @param int $linkId
422
	 *
423
	 * @return FederatedLink
424
	 * @throws FederatedLinkDoesNotExistException
425
	 */
426 View Code Duplication
	public function getLinkFromId($linkId) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
427
		$qb = $this->getLinksSelectSql();
428
		$this->limitToId($qb, (string)$linkId);
429
430
		$cursor = $qb->execute();
431
		$data = $cursor->fetch();
432
		$cursor->closeCursor();
433
434
		if ($data === false) {
435
			throw new FederatedLinkDoesNotExistException(
436
				$this->l10n->t('Federated Link not found')
437
			);
438
		}
439
440
		$entry = $this->parseLinksSelectSql($data);
441
442
		return $entry;
443
	}
444
445
446
	/**
447
	 * returns all FederatedLink from a circle
448
	 *
449
	 * @param int $circleId
450
	 *
451
	 * @return FederatedLink[]
452
	 */
453
	public function getLinksFromCircle($circleId) {
454
		$qb = $this->getLinksSelectSql();
455
		$this->limitToCircleId($qb, $circleId);
456
457
		$links = [];
458
		$cursor = $qb->execute();
459
		while ($data = $cursor->fetch()) {
460
			$links[] = $this->parseLinksSelectSql($data);
461
		}
462
		$cursor->closeCursor();
463
464
		return $links;
465
	}
466
467
468
}