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

DavService::manageRemoteContact()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 2
1
<?php
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\Service;
31
32
33
use OCA\Circles\Db\CirclesRequest;
34
use OCA\Circles\Db\MembersRequest;
35
use OCA\Circles\Exceptions\CircleAlreadyExistsException;
36
use OCA\Circles\Exceptions\CircleDoesNotExistException;
37
use OCA\Circles\Exceptions\MemberAlreadyExistsException;
38
use OCA\Circles\Exceptions\MemberDoesNotExistException;
39
use OCA\Circles\Exceptions\NotLocalMemberException;
40
use OCA\Circles\Model\Circle;
41
use OCA\Circles\Model\DavCard;
42
use OCA\Circles\Model\Member;
43
use OCP\IUserManager;
44
use Symfony\Component\EventDispatcher\GenericEvent;
45
46
47
/**
48
 * Class DavService
49
 *
50
 * @package OCA\Circles\Service
51
 */
52
class DavService {
53
54
55
	/** @var string */
56
	private $userId;
57
58
	/** @var IUserManager */
59
	private $userManager;
60
61
	/** @var CirclesRequest */
62
	private $circlesRequest;
63
64
	/** @var MembersRequest */
65
	private $membersRequest;
66
67
	/** @var ConfigService */
68
	private $configService;
69
70
	/** @var MiscService */
71
	private $miscService;
72
73
74
	/**
75
	 * TimezoneService constructor.
76
	 *
77
	 * @param string $userId
78
	 * @param IUserManager $userManager
79
	 * @param CirclesRequest $circlesRequest
80
	 * @param MembersRequest $membersRequest
81
	 * @param ConfigService $configService
82
	 * @param MiscService $miscService
83
	 */
84
	public function __construct(
85
		$userId, IUserManager $userManager, CirclesRequest $circlesRequest, MembersRequest $membersRequest,
86
		ConfigService $configService, MiscService $miscService
87
	) {
88
		$this->userId = $userId;
89
		$this->userManager = $userManager;
90
		$this->circlesRequest = $circlesRequest;
91
		$this->membersRequest = $membersRequest;
92
		$this->configService = $configService;
93
		$this->miscService = $miscService;
94
	}
95
96
97
	/**
98
	 * @param GenericEvent $event
99
	 */
100
	public function onCreateCard(GenericEvent $event) {
101
		$davCard = $this->generateDavCard($event);
102
		$this->updateDavCard($davCard);
103
	}
104
105
106
	/**
107
	 * @param GenericEvent $event
108
	 */
109
	public function onUpdateCard(GenericEvent $event) {
110
		$davCard = $this->generateDavCard($event);
111
		$this->updateDavCard($davCard);
112
	}
113
114
115
	/**
116
	 * @param GenericEvent $event
117
	 */
118
	public function onDeleteCard(GenericEvent $event) {
119
		$addressBookId = $event->getArgument('addressBookId');
0 ignored issues
show
Unused Code introduced by
$addressBookId is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
120
		$cardUri = $event->getArgument('cardUri');
0 ignored issues
show
Unused Code introduced by
$cardUri is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
121
	}
122
123
124
	/**
125
	 * @param GenericEvent $event
126
	 *
127
	 * @return DavCard
128
	 */
129
	private function generateDavCard(GenericEvent $event): DavCard {
130
		$addressBookId = $event->getArgument('addressBookId');
131
		$cardUri = $event->getArgument('cardUri');
132
		$cardData = $event->getArgument('cardData');
133
134
		$davCard = new DavCard();
135
		// TODO: set owner based on Address Book owner
136
		$davCard->setOwner($this->userId);
137
		$davCard->importFromDav($cardData);
138
		$davCard->setAddressBookId($addressBookId);
139
		$davCard->setCardUri($cardUri);
140
141
		return $davCard;
142
	}
143
144
145
	/**
146
	 * @param DavCard $davCard
147
	 */
148
	private function updateDavCard(DavCard $davCard) {
149
		$this->miscService->log('Updating Card: ' . json_encode($davCard));
150
		$this->manageCircles($davCard);
151
		$this->manageContact($davCard);
152
	}
153
154
155
	/**
156
	 * @param DavCard $davCard
157
	 */
158
	private function manageContact(DavCard $davCard) {
159
		$circles = array_map(
160
			function(Circle $circle) {
161
				return $circle->getUniqueId();
162
			}, $davCard->getCircles()
163
		);
164
165
		try {
166
			$userId = $this->isLocalMember($davCard);
167
168
			$this->manageLocalContact($circles, $davCard, $userId);
169
		} catch (NotLocalMemberException $e) {
170
			$this->manageRemoteContact($circles, $davCard);
171
		}
172
	}
173
174
175
	/**
176
	 * @param array $circles
177
	 * @param DavCard $davCard
178
	 * @param string $userId
179
	 */
180
	private function manageLocalContact(array $circles, DavCard $davCard, string $userId) {
0 ignored issues
show
Unused Code introduced by
The parameter $circles is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
181
		foreach ($davCard->getCircles() as $circle) {
182
			$this->manageMember($circle, $davCard, Member::TYPE_USER, $userId);
183
		}
184
185
	}
186
187
188
	/**
189
	 * @param array $circles
190
	 * @param DavCard $davCard
191
	 */
192
	private function manageRemoteContact(array $circles, DavCard $davCard) {
0 ignored issues
show
Unused Code introduced by
The parameter $circles is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
193
		foreach ($davCard->getCircles() as $circle) {
194
			$this->manageMember($circle, $davCard, Member::TYPE_CONTACT);
195
		}
196
	}
197
198
199
	/**
200
	 * @param Circle $circle
201
	 * @param DavCard $davCard
202
	 * @param int $type
203
	 * @param string $userId
204
	 */
205
	private function manageMember(Circle $circle, DavCard $davCard, int $type, string $userId = '') {
206
		if ($userId === '') {
207
			$userId = $davCard->getOwner() . ':' . $davCard->getContactId();
208
		}
209
210
		try {
211
			$member =
212
				$this->membersRequest->getContactMember($circle->getUniqueId(), $davCard->getContactId());
213
214
			if ($member->getType() !== $type) {
215
				$this->membersRequest->removeMember($member);
216
				throw new MemberDoesNotExistException();
217
			}
218
		} catch (MemberDoesNotExistException $e) {
219
			$member = new Member();
220
			$member->setLevel(Member::LEVEL_MEMBER);
221
			$member->setStatus(Member::STATUS_MEMBER);
222
			$member->setContactId($davCard->getContactId());
223
			$member->setType($type);
224
			$member->setCircleId($circle->getUniqueId());
225
			$member->setUserId($userId);
226
227
			try {
228
				$this->membersRequest->createMember($member);
229
			} catch (MemberAlreadyExistsException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
230
			}
231
		}
232
	}
233
234
235
	/**
236
	 * @param DavCard $davCard
237
	 *
238
	 * @return string
239
	 * @throws NotLocalMemberException
240
	 */
241
	private function isLocalMember(DavCard $davCard): string {
242
		foreach ($davCard->getEmails() as $email) {
243
			if (strpos($email, '@') === false) {
244
				continue;
245
			}
246
247
			list ($username, $domain) = explode('@', $email);
248
			if (in_array($domain, $this->configService->getAvailableHosts())) {
249
				$user = $this->userManager->get($username);
250
				if ($user !== null) {
251
					return $user->getUID();
252
				}
253
			}
254
		}
255
256
		throw new NotLocalMemberException();
257
	}
258
259
260
	/**
261
	 * @param DavCard $davCard
262
	 */
263
	private function manageCircles(DavCard $davCard) {
264
		$fromCard = $davCard->getGroups();
265
		$current = array_map(
266
			function(Circle $circle) {
267
				return $circle->getContactGroupName();
268
			}, $this->getCirclesFromBook($davCard->getAddressBookId())
269
		);
270
271
		$this->manageNewCircles($davCard, $fromCard, $current);
272
		$this->manageDeprecatedCircles($fromCard, $current);
0 ignored issues
show
Unused Code introduced by
The call to the method OCA\Circles\Service\DavS...nageDeprecatedCircles() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
273
274
		$this->assignCirclesToCard($davCard);
275
	}
276
277
278
	/**
279
	 * @param DavCard $davCard
280
	 * @param array $fromCard
281
	 * @param array $current
282
	 */
283
	private function manageNewCircles(DavCard $davCard, array $fromCard, array $current) {
284
		foreach ($fromCard as $group) {
285
			if (in_array($group, $current)) {
286
				continue;
287
			}
288
289
			$circle = new Circle(Circle::CIRCLES_PUBLIC, $group . ' - ' . $this->uuid(5));
0 ignored issues
show
Deprecated Code introduced by
The method OCA\Circles\Service\DavService::uuid() has been deprecated.

This method has been deprecated.

Loading history...
290
			$circle->setContactAddressBook($davCard->getAddressBookId());
291
			$circle->setContactGroupName($group);
292
293
			try {
294
				$this->circlesRequest->createCircle($circle, $davCard->getOwner());
295
				$member = new Member($davCard->getOwner(), Member::TYPE_USER, $circle->getUniqueId());
296
				$member->setLevel(Member::LEVEL_OWNER);
297
				$member->setStatus(Member::STATUS_MEMBER);
298
299
				try {
300
					$this->membersRequest->createMember($member);
301
				} catch (MemberAlreadyExistsException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
302
				}
303
			} catch (CircleAlreadyExistsException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
304
			}
305
306
		}
307
	}
308
309
310
	/**
311
	 * // TODO: Get all group from an addressbook
312
	 * // TODO: remove deprecated circles
313
	 *
314
	 * @param array $fromCard
315
	 * @param array $current
316
	 */
317
	private function manageDeprecatedCircles(array $fromCard, array $current) {
0 ignored issues
show
Unused Code introduced by
The parameter $fromCard is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $current is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
318
	}
319
320
321
	/**
322
	 * @param DavCard $davCard
323
	 */
324
	private function assignCirclesToCard(DavCard $davCard) {
325
		foreach ($davCard->getGroups() as $group) {
326
			try {
327
				$davCard->addCircle(
328
					$this->circlesRequest->getFromContactGroup($davCard->getAddressBookId(), $group)
329
				);
330
			} catch (CircleDoesNotExistException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
331
			}
332
		}
333
	}
334
335
336
	/**
337
	 * @param int $addressBookId
338
	 *
339
	 * @return Circle[]
340
	 */
341
	private function getCirclesFromBook(int $addressBookId): array {
342
		return $this->circlesRequest->getFromBook($addressBookId);
343
	}
344
345
346
	/**
347
	 * @param int $length
348
	 *
349
	 * @return string
350
	 * @deprecated
351
	 */
352
	protected function uuid(int $length = 0): string {
353
		$uuid = sprintf(
354
			'%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff),
355
			mt_rand(0, 0xffff), mt_rand(0, 0xfff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000,
356
			mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
357
		);
358
359
		if ($length > 0) {
360
			if ($length <= 16) {
361
				$uuid = str_replace('-', '', $uuid);
362
			}
363
364
			$uuid = substr($uuid, 0, $length);
365
		}
366
367
		return $uuid;
368
	}
369
370
371
}
372
373
374