Completed
Branch master (e3f4c4)
by Maxence
02:21
created

CirclesService::isAllowedToJoin()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 11
rs 9.4285
cc 3
eloc 5
nc 3
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
namespace OCA\Circles\Service;
28
29
30
use OCA\Circles\Exceptions\CircleAlreadyExistsException;
31
use OCA\Circles\Exceptions\CircleCreationException;
32
use OCA\Circles\Exceptions\CircleDoesNotExistException;
33
use OCA\Circles\Exceptions\CircleTypeDisabledException;
34
use OCA\Circles\Exceptions\ConfigNoCircleAvailable;
35
use OCA\Circles\Exceptions\MemberAlreadyExistsException;
36
use OCA\Circles\Exceptions\MemberCantJoinPersonalCircle;
37
use OCA\Circles\Exceptions\MemberDoesNotExistException;
38
use OCA\Circles\Exceptions\MemberIsBlockedException;
39
use OCA\Circles\Exceptions\MemberIsNotInvitedException;
40
use OCA\Circles\Exceptions\MemberIsOwnerException;
41
use \OCA\Circles\Model\Circle;
42
use \OCA\Circles\Model\Member;
43
use OCP\IL10N;
44
45
class CirclesService {
46
47
	private $userId;
48
	private $l10n;
49
	private $configService;
50
	private $databaseService;
51
	private $miscService;
52
53 View Code Duplication
	public function __construct(
54
		$userId,
55
		IL10N $l10n,
56
		ConfigService $configService,
57
		DatabaseService $databaseService,
58
		MiscService $miscService
59
	) {
60
		$this->userId = $userId;
61
		$this->l10n = $l10n;
62
		$this->configService = $configService;
63
		$this->databaseService = $databaseService;
64
		$this->miscService = $miscService;
65
	}
66
67
68
	/**
69
	 * Create circle using this->userId as owner
70
	 *
71
	 * @param $type
72
	 * @param $name
73
	 *
74
	 * @return Circle
75
	 * @throws CircleAlreadyExistsException
76
	 * @throws CircleCreationException
77
	 * @throws CircleTypeDisabledException
78
	 * @throws ConfigNoCircleAvailable
79
	 */
80
	public function createCircle($type, $name) {
81
82
		self::convertTypeStringToBitValue($type);
83
84
		if (!$this->configService->isCircleAllowed((int)$type)) {
85
			throw new CircleTypeDisabledException();
86
		}
87
88
		$owner = new Member();
89
		$owner->setUserId($this->userId)
90
			  ->setStatus(Member::STATUS_MEMBER);
91
92
		$circle = new Circle();
93
		$circle->setName($name)
94
			   ->setType($type)
95
			   ->setMembers([$owner]);
96
97
		try {
98
			$this->databaseService->getCirclesMapper()
99
								  ->create($circle, $owner);
100
			$this->databaseService->getMembersMapper()
101
								  ->add($owner);
102
103
104
		} catch (ConfigNoCircleAvailable $e) {
105
			throw $e;
106
		} catch (CircleAlreadyExistsException $e) {
107
			$this->databaseService->getCirclesMapper()
108
								  ->destroy($circle);
109
			throw $e;
110
		} catch (CircleCreationException $e) {
111
			$this->databaseService->getCirclesMapper()
112
								  ->destroy($circle);
113
			throw $e;
114
		}
115
116
		return $circle;
117
	}
118
119
120
	/**
121
	 * list Circles depends on type (or all) and name (parts) and minimum level.
122
	 *
123
	 * @param $type
124
	 * @param string $name
125
	 * @param int $level
126
	 *
127
	 * @return array
128
	 * @throws CircleTypeDisabledException
129
	 */
130
	public function listCircles($type, $name = '', $level = 0) {
131
132
		self::convertTypeStringToBitValue($type);
133
134
		if (!$this->configService->isCircleAllowed((int)$type)) {
135
			throw new CircleTypeDisabledException();
136
		}
137
138
		$result = $this->databaseService->getCirclesMapper()
139
										->findCirclesByUser($this->userId, $type, $name, $level);
140
141
		$data = [];
142
		foreach ($result as $item) {
143
			if ($name === '' || stripos($item->getName(), $name) !== false) {
144
				$data[] = $item;
145
			}
146
		}
147
148
		return $data;
149
	}
150
151
152
	/**
153
	 * returns details on circle and its members if this->userId is a member itself.
154
	 *
155
	 * @param $circleId
156
	 *
157
	 * @return Circle
158
	 * @throws CircleDoesNotExistException
159
	 * @throws ConfigNoCircleAvailable
160
	 * @internal param $circleId
161
	 * @internal param string $iError
162
	 */
163
	public function detailsCircle($circleId) {
164
165
		try {
166
			$circle = $this->databaseService->getCirclesMapper()
167
											->getDetailsFromCircle($this->userId, $circleId);
168
169
			if ($circle->getUser()
170
					   ->getLevel() >= Member::LEVEL_MEMBER
171
			) {
172
				$members = $this->databaseService->getMembersMapper()
173
												 ->getMembersFromCircle(
174
													 $circleId, ($circle->getUser()
175
																		->getLevel()
176
																 >= Member::LEVEL_MODERATOR)
177
												 );
178
				$circle->setMembers($members);
179
			}
180
		} catch (ConfigNoCircleAvailable $e) {
181
			throw $e;
182
		} catch (CircleDoesNotExistException $e) {
183
			throw $e;
184
		}
185
186
		return $circle;
187
188
	}
189
190
	/**
191
	 * Join a circle.
192
	 *
193
	 * @param $circleId
194
	 *
195
	 * @return null|Member
196
	 * @throws \Exception
197
	 */
198
	public function joinCircle($circleId) {
199
200
		try {
201
202
			$circle = $this->databaseService->getCirclesMapper()
203
											->getDetailsFromCircle(
204
												$this->userId, $circleId
205
											);
206
207
			try {
208
				$member = $this->databaseService->getMembersMapper()
209
												->getMemberFromCircle(
210
													$circle->getId(), $this->userId,
211
													false
212
												);
213
214
			} catch (MemberDoesNotExistException $m) {
215
				$member = new Member();
216
				$member->setCircleId($circle->getId());
217
				$member->setUserId($this->userId);
218
				$member->setLevel(Member::LEVEL_NONE);
219
				$member->setStatus(Member::STATUS_NONMEMBER);
220
221
				$this->databaseService->getMembersMapper()
222
									  ->add($member);
223
			}
224
225
226
			$member->hasToBeAbleToJoinTheCircle();
227
228
			switch ($circle->getType()) {
229
				case Circle::CIRCLES_HIDDEN:
230
				case Circle::CIRCLES_PUBLIC:
231
					$this->memberJoinOpenCircle($member);
232
					break;
233
234
				case Circle::CIRCLES_PRIVATE:
235
					$this->memberJoinPrivateCircle($member);
236
					break;
237
238
				case Circle::CIRCLES_PERSONAL:
239
					throw new MemberCantJoinPersonalCircle();
240
					break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
241
			}
242
243
			$this->databaseService->getMembersMapper()
244
								  ->editMember($member);
245
246
		} catch (\Exception $e) {
247
			throw $e;
248
		}
249
250
		return $member;
251
	}
252
253
254
255
256 View Code Duplication
	private function memberJoinOpenCircle(&$member) {
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...
257
258
		if ($member->getStatus() === Member::STATUS_NONMEMBER
259
			|| $member->getStatus() === Member::STATUS_KICKED
260
		) {
261
			$member->setStatus(Member::STATUS_MEMBER);
262
			$member->setLevel(Member::LEVEL_MEMBER);
263
		}
264
	}
265
266
267
	private function memberJoinPrivateCircle(&$member) {
268
269
		switch ($member->getStatus()) {
270
			case Member::STATUS_NONMEMBER:
271
			case Member::STATUS_KICKED:
272
				$member->setStatus(Member::STATUS_REQUEST);
273
				break;
274
275
			case Member::STATUS_INVITED:
276
				$member->setStatus(Member::STATUS_MEMBER);
277
				$member->setLevel(Member::LEVEL_MEMBER);
278
				break;
279
		}
280
	}
281
282
283
	/**
284
	 * Leave a circle.
285
	 *
286
	 * @param $circleId
287
	 *
288
	 * @return null|Member
289
	 * @throws CircleDoesNotExistException
290
	 * @throws ConfigNoCircleAvailable
291
	 * @throws MemberDoesNotExistException
292
	 * @throws MemberIsOwnerException
293
	 */
294
	public function leaveCircle($circleId) {
295
296
		try {
297
			$circle = $this->databaseService->getCirclesMapper()
298
											->getDetailsFromCircle(
299
												$this->userId, $circleId
300
											);
301
302
			$member = $this->databaseService->getMembersMapper()
303
											->getMemberFromCircle(
304
												$circle->getId(), $this->userId,
305
												($circle->getUser()
306
														->getLevel()
307
												 >= Member::LEVEL_MODERATOR)
308
											);
309
310
			if ($member === null || $member->getLevel() === 0) {
311
				throw new MemberDoesNotExistException("You are not member of this circle");
312
			}
313
314
315
			$member->cantBeOwner();
316
317
318
			$member->setStatus(Member::STATUS_NONMEMBER);
319
			$member->setLevel(Member::LEVEL_NONE);
320
321
			$this->databaseService->getMembersMapper()
322
								  ->editMember(
323
									  $member
324
								  );
325
326
		} catch (\Exception $e) {
327
			throw $e;
328
		}
329
330
		return $member;
331
	}
332
333
334
	/**
335
	 * destroy a circle.
336
	 *
337
	 * @param $circle
338
	 */
339
	public function removeCircle($circle) {
340
341
		$this->databaseService->getMembersMapper()
342
							  ->removeAllFromCircle($circle);
343
		$this->databaseService->getCirclesMapper()
344
							  ->destroy($circle);
345
	}
346
347
348
	/**
349
	 * Convert a Type in String to its Bit Value
350
	 *
351
	 * @param $type
352
	 */
353
	public static function convertTypeStringToBitValue(&$type) {
354
		if (strtolower($type) === 'personal') {
355
			$type = Circle::CIRCLES_PERSONAL;
356
		}
357
		if (strtolower($type) === 'hidden') {
358
			$type = Circle::CIRCLES_HIDDEN;
359
		}
360
		if (strtolower($type) === 'private') {
361
			$type = Circle::CIRCLES_PRIVATE;
362
		}
363
		if (strtolower($type) === 'public') {
364
			$type = Circle::CIRCLES_PUBLIC;
365
		}
366
		if (strtolower($type) === 'all') {
367
			$type = Circle::CIRCLES_ALL;
368
		}
369
	}
370
371
}