Completed
Pull Request — master (#551)
by Maxence
02:18
created

DeprecatedCirclesRequest   A

Complexity

Total Complexity 40

Size/Duplication

Total Lines 402
Duplicated Lines 18.66 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
wmc 40
lcom 1
cbo 5
dl 75
loc 402
rs 9.2
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A forceGetCircle() 0 16 2
A forceGetCircles() 13 13 2
A forceGetCircleByName() 16 16 2
B getCircles() 0 33 7
A getCircle() 0 36 4
A createCircle() 0 17 1
A destroyCircle() 0 5 1
A isCircleUnique() 0 19 5
A isPersonalCircleUnique() 0 19 5
A updateCircle() 0 14 2
A getCircleFromUniqueId() 14 14 2
A getFromBook() 0 13 2
A getFromContactBook() 17 17 3
A getFromContactGroup() 15 15 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like DeprecatedCirclesRequest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use DeprecatedCirclesRequest, and based on these observations, apply Extract Interface, too.

1
<?php declare(strict_types=1);
2
3
4
/**
5
 * Circles - Bring cloud-users closer together.
6
 *
7
 * This file is licensed under the Affero General Public License version 3 or
8
 * later. See the COPYING file.
9
 *
10
 * @author Maxence Lange <[email protected]>
11
 * @copyright 2017
12
 * @license GNU AGPL version 3 or any later version
13
 *
14
 * This program is free software: you can redistribute it and/or modify
15
 * it under the terms of the GNU Affero General Public License as
16
 * published by the Free Software Foundation, either version 3 of the
17
 * License, or (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU Affero General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU Affero General Public License
25
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
26
 *
27
 */
28
29
30
namespace OCA\Circles\Db;
31
32
33
use OCA\Circles\Exceptions\CircleAlreadyExistsException;
34
use OCA\Circles\Exceptions\CircleDoesNotExistException;
35
use OCA\Circles\Exceptions\ConfigNoCircleAvailableException;
36
use OCA\Circles\Exceptions\GSStatusException;
37
use OCA\Circles\Model\DeprecatedCircle;
38
use OCA\Circles\Model\DeprecatedMember;
39
40
class DeprecatedCirclesRequest extends DeprecatedCirclesRequestBuilder {
41
42
43
	/**
44
	 * forceGetCircle();
45
	 *
46
	 * returns data of a circle from its Id.
47
	 *
48
	 * WARNING: This function does not filters data regarding the current user/viewer.
49
	 *          In case of interaction with users, Please use getCircle() instead.
50
	 *
51
	 * @param string $circleUniqueId
52
	 * @param bool $allSettings
53
	 *
54
	 * @return DeprecatedCircle
55
	 * @throws CircleDoesNotExistException
56
	 */
57
	public function forceGetCircle($circleUniqueId, bool $allSettings = false) {
58
		$qb = $this->getCirclesSelectSql();
59
60
		$this->leftJoinOwner($qb, '');
61
		$this->limitToUniqueId($qb, $circleUniqueId);
62
63
		$cursor = $qb->execute();
64
		$data = $cursor->fetch();
65
		$cursor->closeCursor();
66
67
		if ($data === false) {
68
			throw new CircleDoesNotExistException($this->l10n->t('Circle not found'));
0 ignored issues
show
Deprecated Code introduced by
The class OCA\Circles\Exceptions\CircleDoesNotExistException has been deprecated.

This class, trait or interface has been deprecated.

Loading history...
69
		}
70
71
		return $this->parseCirclesSelectSql($data, $allSettings);
72
	}
73
74
75
	/**
76
	 * forceGetCircles();
77
	 *
78
	 * returns data of a all circles.
79
	 *
80
	 * WARNING: This function does not filters data regarding the current user/viewer.
81
	 *          In case of interaction with users, Please use getCircles() instead.
82
	 *
83
	 * @param string $ownerId
84
	 *
85
	 * @return DeprecatedCircle[]
86
	 */
87 View Code Duplication
	public function forceGetCircles(string $ownerId = '') {
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...
88
		$qb = $this->getCirclesSelectSql();
89
		$this->leftJoinOwner($qb, $ownerId);
90
91
		$circles = [];
92
		$cursor = $qb->execute();
93
		while ($data = $cursor->fetch()) {
94
			$circles[] = $this->parseCirclesSelectSql($data, true);
95
		}
96
		$cursor->closeCursor();
97
98
		return $circles;
99
	}
100
101
102
	/**
103
	 * forceGetCircleByName();
104
	 *
105
	 * returns data of a circle from its Name.
106
	 *
107
	 * WARNING: This function does not filters data regarding the current user/viewer.
108
	 *          In case of interaction with users, do not use this method.
109
	 *
110
	 * @param $name
111
	 *
112
	 * @return null|DeprecatedCircle
113
	 * @throws CircleDoesNotExistException
114
	 */
115 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...
116
117
		$qb = $this->getCirclesSelectSql();
118
119
		$this->limitToName($qb, $name);
120
121
		$cursor = $qb->execute();
122
		$data = $cursor->fetch();
123
		$cursor->closeCursor();
124
125
		if ($data === false) {
126
			throw new CircleDoesNotExistException($this->l10n->t('Circle not found'));
0 ignored issues
show
Deprecated Code introduced by
The class OCA\Circles\Exceptions\CircleDoesNotExistException has been deprecated.

This class, trait or interface has been deprecated.

Loading history...
127
		}
128
129
		return $this->parseCirclesSelectSql($data);
130
	}
131
132
133
	/**
134
	 * @param string $userId
135
	 * @param int $circleType
136
	 * @param string $name
137
	 * @param int $level
138
	 * @param bool $forceAll
139
	 * @param string $ownerId
140
	 *
141
	 * @return DeprecatedCircle[]
142
	 * @throws ConfigNoCircleAvailableException
143
	 * @throws GSStatusException
144
	 */
145
	public function getCircles(
146
		string $userId, int $circleType = 0, string $name = '', int $level = 0, bool $forceAll = false,
147
		string $ownerId = ''
148
	) {
149
		if ($circleType === 0) {
150
			$circleType = DeprecatedCircle::CIRCLES_ALL;
151
		}
152
153
		// todo - make it works based on $type
154
		$typeViewer = DeprecatedMember::TYPE_USER;
155
156
		$qb = $this->getCirclesSelectSql();
157
		$this->leftJoinUserIdAsViewer($qb, $userId, $typeViewer, '');
158
		$this->leftJoinOwner($qb, $ownerId);
159
		$this->leftJoinNCGroupAndUser($qb, $userId, 'c.unique_id');
160
161
		if ($level > 0) {
162
			$this->limitToLevel($qb, $level, ['u', 'g']);
163
		}
164
		$this->limitRegardingCircleType($qb, $userId, -1, $circleType, $name, $forceAll);
165
166
		$circles = [];
167
		$cursor = $qb->execute();
168
		while ($data = $cursor->fetch()) {
169
			if ($name === '' || stripos(strtolower($data['name']), strtolower($name)) !== false
170
				|| stripos(strtolower($data['alt_name']), strtolower($name)) !== false) {
171
				$circles[] = $this->parseCirclesSelectSql($data);
172
			}
173
		}
174
		$cursor->closeCursor();
175
176
		return $circles;
177
	}
178
179
180
	/**
181
	 *
182
	 * @param string $circleUniqueId
183
	 * @param string $viewerId
184
	 * @param int $type
185
	 * @param string $instanceId
186
	 * @param bool $forceAll
187
	 *
188
	 * @return DeprecatedCircle
189
	 * @throws CircleDoesNotExistException
190
	 * @throws ConfigNoCircleAvailableException
191
	 */
192
	public function getCircle(
193
		string $circleUniqueId, string $viewerId, int $type = DeprecatedMember::TYPE_USER,
194
		string $instanceId = '',
195
		bool $forceAll = false
196
	) {
197
		$qb = $this->getCirclesSelectSql();
198
199
		$this->limitToUniqueId($qb, $circleUniqueId);
200
201
		$this->leftJoinUserIdAsViewer($qb, $viewerId, $type, $instanceId);
202
		$this->leftJoinOwner($qb);
203
		if ($instanceId === '') {
204
			$this->leftJoinNCGroupAndUser($qb, $viewerId, 'c.unique_id');
205
		}
206
207
		$this->limitRegardingCircleType(
208
			$qb, $viewerId, $circleUniqueId, DeprecatedCircle::CIRCLES_ALL, '', $forceAll
209
		);
210
211
		$cursor = $qb->execute();
212
		$data = $cursor->fetch();
213
		$cursor->closeCursor();
214
215
		if ($data === false) {
216
			throw new CircleDoesNotExistException($this->l10n->t('Circle not found ' . $circleUniqueId));
0 ignored issues
show
Deprecated Code introduced by
The class OCA\Circles\Exceptions\CircleDoesNotExistException has been deprecated.

This class, trait or interface has been deprecated.

Loading history...
217
		}
218
219
		$circle = $this->parseCirclesSelectSql($data);
220
		if ($instanceId === '') {
221
			$circle->setGroupViewer(
222
				$this->membersRequest->forceGetHigherLevelGroupFromUser($circleUniqueId, $viewerId)
223
			);
224
		}
225
226
		return $circle;
227
	}
228
229
230
	/**
231
	 * createCircle();
232
	 *
233
	 * Create a circle with $userId as its owner.
234
	 * Will returns the circle
235
	 *
236
	 * @param DeprecatedCircle $circle
237
	 */
238
	public function createCircle(DeprecatedCircle $circle) {
239
240
		$config = DeprecatedCircle::convertTypeToConfig($circle->getType());
241
242
		$qb = $this->getCirclesInsertSql();
243
		$qb->setValue('unique_id', $qb->createNamedParameter($circle->getUniqueId()))
244
		   ->setValue('long_id', $qb->createNamedParameter($circle->getUniqueId(true)))
245
		   ->setValue('name', $qb->createNamedParameter($circle->getName(true)))
246
		   ->setValue('alt_name', $qb->createNamedParameter($circle->getAltName()))
247
		   ->setValue('description', $qb->createNamedParameter($circle->getDescription()))
248
		   ->setValue('contact_addressbook', $qb->createNamedParameter($circle->getContactAddressBook()))
249
		   ->setValue('contact_groupname', $qb->createNamedParameter($circle->getContactGroupName()))
250
		   ->setValue('settings', $qb->createNamedParameter($circle->getSettings(true)))
251
		   ->setValue('type', $qb->createNamedParameter($circle->getType()))
252
		   ->setValue('config', $qb->createNamedParameter($config));
253
		$qb->execute();
254
	}
255
256
257
	/**
258
	 * remove a circle
259
	 *
260
	 * @param string $circleUniqueId
261
	 */
262
	public function destroyCircle($circleUniqueId) {
263
		$qb = $this->getCirclesDeleteSql($circleUniqueId);
264
265
		$qb->execute();
266
	}
267
268
269
	/**
270
	 * returns if the circle is already in database
271
	 *
272
	 * @param DeprecatedCircle $circle
273
	 * @param string $userId
274
	 *
275
	 * @return bool
276
	 * @throws ConfigNoCircleAvailableException
277
	 */
278
	public function isCircleUnique(DeprecatedCircle $circle, $userId = '') {
279
		if ($circle->getType() === DeprecatedCircle::CIRCLES_PERSONAL) {
280
			return $this->isPersonalCircleUnique($circle, $userId);
281
		}
282
283
		$qb = $this->getCirclesSelectSql();
284
		$this->limitToNonPersonalCircle($qb);
285
286
		$cursor = $qb->execute();
287
		while ($data = $cursor->fetch()) {
288
			if (strtolower($data['name']) === strtolower($circle->getName())
289
				&& $circle->getUniqueId(true) !== $data['unique_id']) {
290
				return false;
291
			}
292
		}
293
		$cursor->closeCursor();
294
295
		return true;
296
	}
297
298
299
	/**
300
	 * return if the personal circle is unique
301
	 *
302
	 * @param DeprecatedCircle $circle
303
	 * @param string $userId
304
	 *
305
	 * @return bool
306
	 * @throws ConfigNoCircleAvailableException
307
	 */
308
	private function isPersonalCircleUnique(DeprecatedCircle $circle, $userId = '') {
309
		if ($userId === '') {
310
			return true;
311
		}
312
313
		$list = $this->getCircles(
314
			$userId, DeprecatedCircle::CIRCLES_PERSONAL, $circle->getName(),
315
			DeprecatedMember::LEVEL_OWNER
316
		);
317
318
		foreach ($list as $test) {
319
			if (strtolower($test->getName()) === strtolower($circle->getName())
320
				&& $circle->getUniqueId(true) !== $test->getUniqueId(true)) {
321
				return false;
322
			}
323
		}
324
325
		return true;
326
	}
327
328
329
	/**
330
	 * @param DeprecatedCircle $circle
331
	 * @param string $userId
332
	 *
333
	 * @throws CircleAlreadyExistsException
334
	 * @throws ConfigNoCircleAvailableException
335
	 */
336
	public function updateCircle(DeprecatedCircle $circle, $userId = '') {
337
		if (!$this->isCircleUnique($circle, $userId)) {
338
			throw new CircleAlreadyExistsException(
339
				$this->l10n->t('A circle with that name exists')
340
			);
341
		}
342
343
		$qb = $this->getCirclesUpdateSql($circle->getUniqueId(true));
344
		$qb->set('name', $qb->createNamedParameter($circle->getName()))
345
		   ->set('description', $qb->createNamedParameter($circle->getDescription()))
346
		   ->set('settings', $qb->createNamedParameter($circle->getSettings(true)));
347
348
		$qb->execute();
349
	}
350
351
352
	/**
353
	 * @param string $uniqueId
354
	 *
355
	 * @return DeprecatedCircle
356
	 * @throws CircleDoesNotExistException
357
	 */
358 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...
359
		$qb = $this->getCirclesSelectSql();
360
		$this->limitToUniqueId($qb, (string)$uniqueId);
361
362
		$cursor = $qb->execute();
363
		$data = $cursor->fetch();
364
		$cursor->closeCursor();
365
366
		if ($data === false) {
367
			throw new CircleDoesNotExistException($this->l10n->t('Circle not found'));
0 ignored issues
show
Deprecated Code introduced by
The class OCA\Circles\Exceptions\CircleDoesNotExistException has been deprecated.

This class, trait or interface has been deprecated.

Loading history...
368
		}
369
370
		return $this->parseCirclesSelectSql($data);
371
	}
372
373
374
	/**
375
	 * @param int $addressBookId
376
	 *
377
	 * @return array
378
	 */
379
	public function getFromBook(int $addressBookId) {
380
		$qb = $this->getCirclesSelectSql();
381
		$this->limitToAddressBookId($qb, $addressBookId);
382
383
		$circles = [];
384
		$cursor = $qb->execute();
385
		while ($data = $cursor->fetch()) {
386
			$circles[] = $this->parseCirclesSelectSql($data);
387
		}
388
		$cursor->closeCursor();
389
390
		return $circles;
391
	}
392
393
394
	/**
395
	 * @param int $addressBookId
396
	 *
397
	 * @return DeprecatedCircle[]
398
	 */
399 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...
400
		$qb = $this->getCirclesSelectSql();
401
402
		if ($addressBookId > 0) {
403
			$this->limitToAddressBookId($qb, $addressBookId);
404
		}
405
406
407
		$circles = [];
408
		$cursor = $qb->execute();
409
		while ($data = $cursor->fetch()) {
410
			$circles[] = $this->parseCirclesSelectSql($data);
411
		}
412
		$cursor->closeCursor();
413
414
		return $circles;
415
	}
416
417
418
	/**
419
	 * @param int $addressBookId
420
	 * @param string $group
421
	 *
422
	 * @return DeprecatedCircle
423
	 * @throws CircleDoesNotExistException
424
	 */
425 View Code Duplication
	public function getFromContactGroup(int $addressBookId, string $group): DeprecatedCircle {
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...
426
		$qb = $this->getCirclesSelectSql();
427
		$this->limitToAddressBookId($qb, $addressBookId);
428
		$this->limitToContactGroup($qb, $group);
429
430
		$cursor = $qb->execute();
431
		$data = $cursor->fetch();
432
		$cursor->closeCursor();
433
434
		if ($data === false) {
435
			throw new CircleDoesNotExistException($this->l10n->t('Circle not found'));
0 ignored issues
show
Deprecated Code introduced by
The class OCA\Circles\Exceptions\CircleDoesNotExistException has been deprecated.

This class, trait or interface has been deprecated.

Loading history...
436
		}
437
438
		return $this->parseCirclesSelectSql($data);
439
	}
440
441
}
442