Completed
Pull Request — master (#347)
by Maxence
01:46
created

CirclesRequest::getFromContactBook()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13

Duplication

Lines 13
Ratio 100 %

Importance

Changes 0
Metric Value
dl 13
loc 13
rs 9.8333
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
/**
3
 * Circles - Bring cloud-users closer together.
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Maxence Lange <[email protected]>
9
 * @copyright 2017
10
 * @license GNU AGPL version 3 or any later version
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License as
14
 * published by the Free Software Foundation, either version 3 of the
15
 * License, or (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24
 *
25
 */
26
27
28
namespace OCA\Circles\Db;
29
30
31
use OCA\Circles\Exceptions\CircleAlreadyExistsException;
32
use OCA\Circles\Exceptions\CircleDoesNotExistException;
33
use OCA\Circles\Exceptions\ConfigNoCircleAvailableException;
34
use OCA\Circles\Model\Circle;
35
use OCA\Circles\Model\Member;
36
37
class CirclesRequest extends CirclesRequestBuilder {
38
39
40
	/**
41
	 * forceGetCircle();
42
	 *
43
	 * returns data of a circle from its Id.
44
	 *
45
	 * WARNING: This function does not filters data regarding the current user/viewer.
46
	 *          In case of interaction with users, Please use getCircle() instead.
47
	 *
48
	 * @param string $circleUniqueId
49
	 *
50
	 * @return Circle
51
	 * @throws CircleDoesNotExistException
52
	 */
53
	public function forceGetCircle($circleUniqueId) {
54
		$qb = $this->getCirclesSelectSql();
55
56
		$this->limitToShortenUniqueId($qb, $circleUniqueId, Circle::SHORT_UNIQUE_ID_LENGTH);
57
58
		$cursor = $qb->execute();
59
		$data = $cursor->fetch();
60
		$cursor->closeCursor();
61
62
		if ($data === false) {
63
			throw new CircleDoesNotExistException($this->l10n->t('Circle not found'));
64
		}
65
66
		$entry = $this->parseCirclesSelectSql($data);
67
68
		return $entry;
69
	}
70
71
72
	/**
73
	 * forceGetCircles();
74
	 *
75
	 * returns data of a all circles.
76
	 *
77
	 * WARNING: This function does not filters data regarding the current user/viewer.
78
	 *          In case of interaction with users, Please use getCircles() instead.
79
	 *
80
	 * @return Circle[]
81
	 */
82 View Code Duplication
	public function forceGetCircles() {
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...
83
84
		$qb = $this->getCirclesSelectSql();
85
		$this->leftJoinOwner($qb);
86
87
		$circles = [];
88
		$cursor = $qb->execute();
89
		while ($data = $cursor->fetch()) {
90
			$circles[] = $this->parseCirclesSelectSql($data);
91
		}
92
		$cursor->closeCursor();
93
94
		return $circles;
95
	}
96
97
98
	/**
99
	 * forceGetCircleByName();
100
	 *
101
	 * returns data of a circle from its Name.
102
	 *
103
	 * WARNING: This function does not filters data regarding the current user/viewer.
104
	 *          In case of interaction with users, do not use this method.
105
	 *
106
	 * @param $name
107
	 *
108
	 * @return null|Circle
109
	 * @throws CircleDoesNotExistException
110
	 */
111 View Code Duplication
	public function forceGetCircleByName($name) {
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...
112
113
		$qb = $this->getCirclesSelectSql();
114
115
		$this->limitToName($qb, $name);
116
117
		$cursor = $qb->execute();
118
		$data = $cursor->fetch();
119
		$cursor->closeCursor();
120
121
		if ($data === false) {
122
			throw new CircleDoesNotExistException($this->l10n->t('Circle not found'));
123
		}
124
125
		$entry = $this->parseCirclesSelectSql($data);
126
127
		return $entry;
128
	}
129
130
131
	/**
132
	 * @param string $userId
133
	 * @param int $type
134
	 * @param string $name
135
	 * @param int $level
136
	 * @param bool $forceAll
137
	 *
138
	 * @return Circle[]
139
	 * @throws ConfigNoCircleAvailableException
140
	 */
141
	public function getCircles($userId, $type = 0, $name = '', $level = 0, $forceAll = false) {
142
		if ($type === 0) {
143
			$type = Circle::CIRCLES_ALL;
144
		}
145
146
		$qb = $this->getCirclesSelectSql();
147
		$this->leftJoinUserIdAsViewer($qb, $userId);
148
		$this->leftJoinOwner($qb);
149
		$this->leftJoinNCGroupAndUser($qb, $userId, '`c`.`unique_id`');
150
151
		if ($level > 0) {
152
			$this->limitToLevel($qb, $level, ['u', 'g']);
153
		}
154
		$this->limitRegardingCircleType($qb, $userId, -1, $type, $name, $forceAll);
155
156
		$circles = [];
157
		$cursor = $qb->execute();
158
		while ($data = $cursor->fetch()) {
159
			if ($name === '' || stripos(strtolower($data['name']), strtolower($name)) !== false) {
160
				$circles[] = $this->parseCirclesSelectSql($data);
161
			}
162
		}
163
		$cursor->closeCursor();
164
165
		return $circles;
166
	}
167
168
169
	/**
170
	 *
171
	 * @param string $circleUniqueId
172
	 * @param string $viewerId
173
	 * @param bool $forceAll
174
	 *
175
	 * @return Circle
176
	 * @throws CircleDoesNotExistException
177
	 * @throws ConfigNoCircleAvailableException
178
	 */
179
	public function getCircle($circleUniqueId, $viewerId, $forceAll = false) {
180
		$qb = $this->getCirclesSelectSql();
181
182
		$this->limitToShortenUniqueId($qb, $circleUniqueId, Circle::SHORT_UNIQUE_ID_LENGTH);
183
184
		$this->leftJoinUserIdAsViewer($qb, $viewerId);
185
		$this->leftJoinOwner($qb);
186
		$this->leftJoinNCGroupAndUser($qb, $viewerId, '`c`.`unique_id`');
187
188
		$this->limitRegardingCircleType($qb, $viewerId, $circleUniqueId, Circle::CIRCLES_ALL, '', $forceAll);
189
190
		$cursor = $qb->execute();
191
		$data = $cursor->fetch();
192
		$cursor->closeCursor();
193
194
		if ($data === false) {
195
			throw new CircleDoesNotExistException($this->l10n->t('Circle not found'));
196
		}
197
198
		$circle = $this->parseCirclesSelectSql($data);
199
		$circle->setGroupViewer(
200
			$this->membersRequest->forceGetHigherLevelGroupFromUser($circleUniqueId, $viewerId)
201
		);
202
203
		return $circle;
204
	}
205
206
207
	/**
208
	 * createCircle();
209
	 *
210
	 * Create a circle with $userId as its owner.
211
	 * Will returns the circle
212
	 *
213
	 * @param Circle $circle
214
	 * @param $userId
215
	 *
216
	 * @throws CircleAlreadyExistsException
217
	 */
218
	public function createCircle(Circle &$circle, $userId) {
219
220
		if (!$this->isCircleUnique($circle, $userId)) {
221
			throw new CircleAlreadyExistsException(
222
				$this->l10n->t('A circle with that name exists')
223
			);
224
		}
225
226
		$circle->generateUniqueId();
227
		$qb = $this->getCirclesInsertSql();
228
		$qb->setValue('unique_id', $qb->createNamedParameter($circle->getUniqueId(true)))
229
		   ->setValue('name', $qb->createNamedParameter($circle->getName()))
230
		   ->setValue('description', $qb->createNamedParameter($circle->getDescription()))
231
		   ->setValue('contact_addressbook', $qb->createNamedParameter($circle->getContactAddressBook()))
232
		   ->setValue('contact_groupname', $qb->createNamedParameter($circle->getContactGroupName()))
233
		   ->setValue('settings', $qb->createNamedParameter($circle->getSettings(true)))
234
		   ->setValue('type', $qb->createNamedParameter($circle->getType()));
235
		$qb->execute();
236
237
		$owner = new Member($userId, Member::TYPE_USER);
238
		$owner->setCircleId($circle->getUniqueId())
239
			  ->setLevel(Member::LEVEL_OWNER)
240
			  ->setStatus(Member::STATUS_MEMBER);
241
		$circle->setOwner($owner)
242
			   ->setViewer($owner);
243
	}
244
245
246
	/**
247
	 * remove a circle
248
	 *
249
	 * @param string $circleUniqueId
250
	 */
251
	public function destroyCircle($circleUniqueId) {
252
		$qb = $this->getCirclesDeleteSql($circleUniqueId);
253
254
255
		$qb->execute();
256
	}
257
258
259
	/**
260
	 * returns if the circle is already in database
261
	 *
262
	 * @param Circle $circle
263
	 * @param string $userId
264
	 *
265
	 * @return bool
266
	 */
267
	private function isCircleUnique(Circle $circle, $userId) {
268
269
		if ($circle->getType() === Circle::CIRCLES_PERSONAL) {
270
			return $this->isPersonalCircleUnique($circle, $userId);
271
		}
272
273
		$qb = $this->getCirclesSelectSql();
274
		$this->limitToNonPersonalCircle($qb);
275
276
		$cursor = $qb->execute();
277
		while ($data = $cursor->fetch()) {
278
			if (strtolower($data['name']) === strtolower($circle->getName())
279
				&& $circle->getUniqueId(true) !== $data['unique_id']) {
280
				return false;
281
			}
282
		}
283
		$cursor->closeCursor();
284
285
		return true;
286
	}
287
288
289
	/**
290
	 * return if the personal circle is unique
291
	 *
292
	 * @param Circle $circle
293
	 * @param string $userId
294
	 *
295
	 * @return bool
296
	 */
297
	private function isPersonalCircleUnique(Circle $circle, $userId) {
298
299
		$list = $this->getCircles(
300
			$userId, Circle::CIRCLES_PERSONAL, $circle->getName(),
301
			Member::LEVEL_OWNER
302
		);
303
304
		foreach ($list as $test) {
305
			if (strtolower($test->getName()) === strtolower($circle->getName())
306
				&& $circle->getUniqueId(true) !== $test->getUniqueId(true)) {
307
				return false;
308
			}
309
		}
310
311
		return true;
312
	}
313
314
315
	/**
316
	 * @param Circle $circle
317
	 * @param string $userId
318
	 *
319
	 * @throws CircleAlreadyExistsException
320
	 */
321
	public function updateCircle(Circle $circle, $userId) {
322
323
		if (!$this->isCircleUnique($circle, $userId)) {
324
			throw new CircleAlreadyExistsException(
325
				$this->l10n->t('A circle with that name exists')
326
			);
327
		}
328
329
		$qb = $this->getCirclesUpdateSql($circle->getUniqueId(true));
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 $addressBookId
364
	 *
365
	 * @return array
366
	 */
367 View Code Duplication
	public function getFromBook(int $addressBookId) {
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...
368
		$qb = $this->getCirclesSelectSql();
369
		$this->limitToAddressBookId($qb, $addressBookId);
370
371
		$circles = [];
372
		$cursor = $qb->execute();
373
		while ($data = $cursor->fetch()) {
374
			$circles[] = $this->parseCirclesSelectSql($data);
375
		}
376
		$cursor->closeCursor();
377
378
		return $circles;
379
	}
380
381
382
	/**
383
	 * @param int $addressBookId
384
	 *
385
	 * @return Circle[]
386
	 */
387 View Code Duplication
	public function getFromContactBook(int $addressBookId): array {
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...
388
		$qb = $this->getCirclesSelectSql();
389
		$this->limitToAddressBookId($qb, $addressBookId);
390
391
		$circles = [];
392
		$cursor = $qb->execute();
393
		while ($data = $cursor->fetch()) {
394
			$circles[] = $this->parseCirclesSelectSql($data);
395
		}
396
		$cursor->closeCursor();
397
398
		return $circles;
399
	}
400
401
402
	/**
403
	 * @param int $addressBookId
404
	 * @param string $group
405
	 *
406
	 * @return Circle
407
	 * @throws CircleDoesNotExistException
408
	 */
409
	public function getFromContactGroup(int $addressBookId, string $group): Circle {
410
		$qb = $this->getCirclesSelectSql();
411
		$this->limitToAddressBookId($qb, $addressBookId);
412
		$this->limitToContactGroup($qb, $group);
413
414
		$cursor = $qb->execute();
415
		$data = $cursor->fetch();
416
		$cursor->closeCursor();
417
418
		if ($data === false) {
419
			throw new CircleDoesNotExistException($this->l10n->t('Circle not found'));
420
		}
421
422
		return $this->parseCirclesSelectSql($data);
423
	}
424
425
}
426