Completed
Pull Request — master (#141)
by Maxence
02:40
created

CirclesService::getFilesForCircles()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 6
nc 2
nop 3
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
 * @author Vinicius Cubas Brand <[email protected]>
10
 * @author Daniel Tygel <[email protected]>
11
 *
12
 * @copyright 2017
13
 * @license GNU AGPL version 3 or any later version
14
 *
15
 * This program is free software: you can redistribute it and/or modify
16
 * it under the terms of the GNU Affero General Public License as
17
 * published by the Free Software Foundation, either version 3 of the
18
 * License, or (at your option) any later version.
19
 *
20
 * This program is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 * GNU Affero General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU Affero General Public License
26
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
27
 *
28
 */
29
30
namespace OCA\Circles\Service;
31
32
33
use Exception;
34
use OCA\Circles\AppInfo\Application;
35
use OCA\Circles\Db\CircleProviderRequest;
36
use OCA\Circles\Db\CirclesRequest;
37
use OCA\Circles\Db\FederatedLinksRequest;
38
use OCA\Circles\Db\MembersRequest;
39
use OCA\Circles\Exceptions\CircleAlreadyExistsException;
40
use OCA\Circles\Exceptions\CircleTypeDisabledException;
41
use OCA\Circles\Exceptions\FederatedCircleNotAllowedException;
42
use OCA\Circles\Exceptions\MemberIsNotOwnerException;
43
use OCA\Circles\Model\Circle;
44
use OCA\Circles\Model\Member;
45
use OCA\Circles\ShareByCircleProvider;
46
use OCP\IL10N;
47
48
class CirclesService {
49
50
	/** @var string */
51
	private $userId;
52
53
	/** @var IL10N */
54
	private $l10n;
55
56
	/** @var ConfigService */
57
	private $configService;
58
59
	/** @var CirclesRequest */
60
	private $circlesRequest;
61
62
	/** @var MembersRequest */
63
	private $membersRequest;
64
65
	/** @var FederatedLinksRequest */
66
	private $federatedLinksRequest;
67
68
	/** @var EventsService */
69
	private $eventsService;
70
71
	/** @var CircleProviderRequest */
72
	private $circleProviderRequest;
73
74
	/** @var MiscService */
75
	private $miscService;
76
77
78
	/**
79
	 * CirclesService constructor.
80
	 *
81
	 * @param string $userId
82
	 * @param IL10N $l10n
83
	 * @param ConfigService $configService
84
	 * @param CirclesRequest $circlesRequest
85
	 * @param MembersRequest $membersRequest
86
	 * @param FederatedLinksRequest $federatedLinksRequest
87
	 * @param EventsService $eventsService
88
	 * @param CircleProviderRequest $circleProviderRequest
89
	 * @param MiscService $miscService
90
	 */
91 View Code Duplication
	public function __construct(
92
		$userId,
93
		IL10N $l10n,
94
		ConfigService $configService,
95
		CirclesRequest $circlesRequest,
96
		MembersRequest $membersRequest,
97
		FederatedLinksRequest $federatedLinksRequest,
98
		EventsService $eventsService,
99
		CircleProviderRequest $circleProviderRequest,
100
		MiscService $miscService
101
	) {
102
		$this->userId = $userId;
103
		$this->l10n = $l10n;
104
		$this->configService = $configService;
105
		$this->circlesRequest = $circlesRequest;
106
		$this->membersRequest = $membersRequest;
107
		$this->federatedLinksRequest = $federatedLinksRequest;
108
		$this->eventsService = $eventsService;
109
		$this->circleProviderRequest = $circleProviderRequest;
110
		$this->miscService = $miscService;
111
	}
112
113
114
	/**
115
	 * Create circle using this->userId as owner
116
	 *
117
	 * @param int|string $type
118
	 * @param string $name
119
	 *
120
	 * @return Circle
121
	 * @throws CircleTypeDisabledException
122
	 * @throws \Exception
123
	 */
124
	public function createCircle($type, $name) {
125
		$type = $this->convertTypeStringToBitValue($type);
126
		$type = (int)$type;
127
128
		if ($type === '') {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $type (integer) and '' (string) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
129
			throw new CircleTypeDisabledException(
130
				$this->l10n->t('You need a specify a type of circle')
131
			);
132
		}
133
134
		if (!$this->configService->isCircleAllowed($type)) {
135
			throw new CircleTypeDisabledException(
136
				$this->l10n->t('You cannot create this type of circle')
137
			);
138
		}
139
140
		$circle = new Circle($type, $name);
141
142
		try {
143
			$this->circlesRequest->createCircle($circle, $this->userId);
144
			$this->membersRequest->createMember($circle->getOwner());
145
		} catch (CircleAlreadyExistsException $e) {
146
			throw $e;
147
		}
148
149
		$this->eventsService->onCircleCreation($circle);
150
151
		return $circle;
152
	}
153
154
155
	/**
156
	 * list Circles depends on type (or all) and name (parts) and minimum level.
157
	 *
158
	 * @param string $userId
159
	 * @param mixed $type
160
	 * @param string $name
161
	 * @param int $level
162
	 *
163
	 * @return Circle[]
164
	 * @throws CircleTypeDisabledException
165
	 * @throws Exception
166
	 */
167
	public function listCircles($userId, $type, $name = '', $level = 0) {
168
		$type = $this->convertTypeStringToBitValue($type);
169
170
		if ($userId === '') {
171
			throw new Exception('UserID cannot be null');
172
		}
173
174
		if (!$this->configService->isCircleAllowed((int)$type)) {
175
			throw new CircleTypeDisabledException(
176
				$this->l10n->t('You cannot display this type of circle')
177
			);
178
		}
179
180
		$data = [];
181
		$result = $this->circlesRequest->getCircles($userId, $type, $name, $level);
182
		foreach ($result as $item) {
183
			$data[] = $item;
184
		}
185
186
		return $data;
187
	}
188
189
190
	/**
191
	 * returns details on circle and its members if this->userId is a member itself.
192
	 *
193
	 * @param string $circleUniqueId
194
	 *
195
	 * @return Circle
196
	 * @throws \Exception
197
	]	 */
198
	public function detailsCircle($circleUniqueId) {
199
200
		try {
201
			$circle = $this->circlesRequest->getCircle($circleUniqueId, $this->userId);
202
			if ($circle->getHigherViewer()
203
					   ->isLevel(Member::LEVEL_MEMBER)
204
			) {
205
				$this->detailsCircleMembers($circle);
206
				$this->detailsCircleLinkedGroups($circle);
207
				$this->detailsCircleFederatedCircles($circle);
208
			}
209
		} catch (\Exception $e) {
210
			throw $e;
211
		}
212
213
		return $circle;
214
	}
215
216
217
	/**
218
	 * get the Members list and add the result to the Circle.
219
	 *
220
	 * @param Circle $circle
221
	 */
222
	private function detailsCircleMembers(Circle &$circle) {
223
		$members =
224
			$this->membersRequest->getMembers($circle->getUniqueId(), $circle->getHigherViewer());
225
226
		$circle->setMembers($members);
227
	}
228
229
230
	/**
231
	 * get the Linked Group list and add the result to the Circle.
232
	 *
233
	 * @param Circle $circle
234
	 */
235
	private function detailsCircleLinkedGroups(Circle &$circle) {
236
		$groups = [];
237
		if ($this->configService->isLinkedGroupsAllowed()) {
238
			$groups =
239
				$this->membersRequest->getGroupsFromCircle(
240
					$circle->getUniqueId(), $circle->getHigherViewer()
241
				);
242
		}
243
244
		$circle->setGroups($groups);
245
	}
246
247
248
	/**
249
	 * get the Federated Circles list and add the result to the Circle.
250
	 *
251
	 * @param Circle $circle
252
	 */
253
	private function detailsCircleFederatedCircles(Circle &$circle) {
254
		$links = [];
255
256
		try {
257
			if ($this->configService->isFederatedCirclesAllowed()) {
258
				$circle->hasToBeFederated();
259
				$links = $this->federatedLinksRequest->getLinksFromCircle($circle->getUniqueId());
260
			}
261
		} catch (FederatedCircleNotAllowedException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
262
		}
263
264
		$circle->setLinks($links);
265
	}
266
267
268
	/**
269
	 * save new settings if current user is admin.
270
	 *
271
	 * @param string $circleUniqueId
272
	 * @param array $settings
273
	 *
274
	 * @return Circle
275
	 * @throws \Exception
276
	 */
277
	public function settingsCircle($circleUniqueId, $settings) {
278
279
		try {
280
			$circle = $this->circlesRequest->getCircle($circleUniqueId, $this->userId);
281
			$circle->getHigherViewer()
282
				   ->hasToBeOwner();
283
284
			$ak = array_keys($settings);
285
			foreach ($ak AS $k) {
286
				$circle->setSetting($k, $settings[$k]);
287
			}
288
289
			$this->circlesRequest->updateCircle($circle, $this->userId);
290
291
			$this->eventsService->onSettingsChange($circle);
292
		} catch (\Exception $e) {
293
			throw $e;
294
		}
295
296
		return $circle;
297
	}
298
299
300
	/**
301
	 * Join a circle.
302
	 *
303
	 * @param string $circleUniqueId
304
	 *
305
	 * @return null|Member
306
	 * @throws \Exception
307
	 */
308 View Code Duplication
	public function joinCircle($circleUniqueId) {
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...
309
310
		try {
311
			$circle = $this->circlesRequest->getCircle($circleUniqueId, $this->userId);
312
313
			$member = $this->membersRequest->getFreshNewMember(
314
				$circleUniqueId, $this->userId, Member::TYPE_USER
315
			);
316
			$member->hasToBeAbleToJoinTheCircle();
317
			$member->joinCircle($circle->getType());
318
			$this->membersRequest->updateMember($member);
319
320
			$this->eventsService->onMemberNew($circle, $member);
321
		} catch (\Exception $e) {
322
			throw $e;
323
		}
324
325
		return $member;
326
	}
327
328
329
	/**
330
	 * Leave a circle.
331
	 *
332
	 * @param string $circleUniqueId
333
	 *
334
	 * @return null|Member
335
	 * @throws \Exception
336
	 */
337 View Code Duplication
	public function leaveCircle($circleUniqueId) {
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...
338
339
		try {
340
			$circle = $this->circlesRequest->getCircle($circleUniqueId, $this->userId);
341
			$member = $circle->getViewer();
342
343
			$member->hasToBeMemberOrAlmost();
344
			$member->cantBeOwner();
345
346
			$this->eventsService->onMemberLeaving($circle, $member);
347
348
			$member->setStatus(Member::STATUS_NONMEMBER);
349
			$member->setLevel(Member::LEVEL_NONE);
350
			$this->membersRequest->updateMember($member);
351
		} catch (\Exception $e) {
352
			throw $e;
353
		}
354
355
		return $member;
356
	}
357
358
359
	/**
360
	 * destroy a circle.
361
	 *
362
	 * @param string $circleUniqueId
363
	 *
364
	 * @throws MemberIsNotOwnerException
365
	 */
366
	public function removeCircle($circleUniqueId) {
367
368
		try {
369
			$circle = $this->circlesRequest->getCircle($circleUniqueId, $this->userId);
370
			$circle->getHigherViewer()
371
				   ->hasToBeOwner();
372
373
			$this->eventsService->onCircleDestruction($circle);
374
375
			$this->membersRequest->removeAllFromCircle($circleUniqueId);
376
			$this->circlesRequest->destroyCircle($circleUniqueId);
377
378
		} catch (MemberIsNotOwnerException $e) {
379
			throw $e;
380
		}
381
	}
382
383
384
	/**
385
	 * @param $circleName
386
	 *
387
	 * @return Circle|null
388
	 */
389
	public function infoCircleByName($circleName) {
390
		return $this->circlesRequest->forceGetCircleByName($circleName);
391
	}
392
393
394
	/**
395
	 * When a user is removed.
396
	 * Before deleting a user from the cloud, we assign a new owner to his Circles.
397
	 * Remove the Circle if it has no admin.
398
	 *
399
	 * @param string $userId
400
	 */
401
	public function onUserRemoved($userId) {
402
		$circles = $this->circlesRequest->getCircles($userId, 0, '', Member::LEVEL_OWNER);
403
404
		foreach ($circles as $circle) {
405
406
			$members =
407
				$this->membersRequest->forceGetMembers($circle->getUniqueId(), Member::LEVEL_ADMIN);
408
409
			if (sizeof($members) === 1) {
410
				$this->circlesRequest->destroyCircle($circle->getUniqueId());
411
				continue;
412
			}
413
414
			$this->switchOlderAdminToOwner($circle, $members);
415
		}
416
	}
417
418
419
	/**
420
	 * switchOlderAdminToOwner();
421
	 *
422
	 * @param Member[] $members
423
	 */
424
	private function switchOlderAdminToOwner($circle, $members) {
425
426
		foreach ($members as $member) {
427
			if ($member->getLevel() === Member::LEVEL_ADMIN) {
428
				$member->setLevel(Member::LEVEL_OWNER);
429
				$this->membersRequest->updateMember($member);
430
				$this->eventsService->onMemberOwner($circle, $member);
431
432
				return;
433
			}
434
		}
435
436
	}
437
438
439
	/**
440
	 * Convert a Type in String to its Bit Value
441
	 *
442
	 * @param string $type
443
	 *
444
	 * @return int|mixed
445
	 */
446
	public function convertTypeStringToBitValue($type) {
447
		$strings = [
448
			'personal' => Circle::CIRCLES_PERSONAL,
449
			'secret'   => Circle::CIRCLES_SECRET,
450
			'closed'   => Circle::CIRCLES_CLOSED,
451
			'public'   => Circle::CIRCLES_PUBLIC,
452
			'all'      => Circle::CIRCLES_ALL
453
		];
454
455
		if (!key_exists(strtolower($type), $strings)) {
456
			return $type;
457
		}
458
459
		return $strings[strtolower($type)];
460
	}
461
462
463
	/**
464
	 * getCircleIcon()
465
	 *
466
	 * Return the right imagePath for a type of circle.
467
	 *
468
	 * @param string $type
469
	 * @param bool $png
470
	 *
471
	 * @return string
472
	 */
473
	public static function getCircleIcon($type, $png = false) {
474
475
		$ext = '.svg';
476
		if ($png === true) {
477
			$ext = '.png';
478
		}
479
480
		$urlGen = \OC::$server->getURLGenerator();
481
		switch ($type) {
482
			case Circle::CIRCLES_PERSONAL:
483
				return $urlGen->getAbsoluteURL(
484
					$urlGen->imagePath(Application::APP_NAME, 'personal' . $ext)
485
				);
486
			case Circle::CIRCLES_CLOSED:
487
				return $urlGen->getAbsoluteURL(
488
					$urlGen->imagePath(Application::APP_NAME, 'closed' . $ext)
489
				);
490
			case Circle::CIRCLES_SECRET:
491
				return $urlGen->getAbsoluteURL(
492
					$urlGen->imagePath(Application::APP_NAME, 'secret' . $ext)
493
				);
494
			case Circle::CIRCLES_PUBLIC:
495
				return $urlGen->getAbsoluteURL(
496
					$urlGen->imagePath(Application::APP_NAME, 'public' . $ext)
497
				);
498
		}
499
500
		return $urlGen->getAbsoluteURL($urlGen->imagePath(Application::APP_NAME, 'black_circle' . $ext));
501
	}
502
503
504
	/**
505
	 * @param string $circleUniqueIds
506
	 * @param int $limit
507
	 * @param int $offset
508
	 *
509
	 * @return array
510
	 */
511
	public function getFilesForCircles($circleUniqueIds, $limit = -1, $offset = 0) {
512
		if (!is_array($circleUniqueIds)) {
513
			$circleUniqueIds = [$circleUniqueIds];
514
		}
515
516
		$objectIds = $this->circleProviderRequest->getFilesForCircles(
517
			$this->userId, $circleUniqueIds, $limit, $offset
518
		);
519
520
		return $objectIds;
521
	}
522
523
}