Passed
Push — master ( 46459a...d2606a )
by Christoph
14:31 queued 14s
created

Converter::createCardFromUser()   D

Complexity

Conditions 19
Paths 162

Size

Total Lines 71
Code Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 19
eloc 56
c 2
b 0
f 0
nc 162
nop 1
dl 0
loc 71
rs 4

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Arthur Schiwon <[email protected]>
6
 * @author Bjoern Schiessle <[email protected]>
7
 * @author Christoph Wurst <[email protected]>
8
 * @author Joas Schilling <[email protected]>
9
 * @author Morris Jobke <[email protected]>
10
 * @author Roeland Jago Douma <[email protected]>
11
 * @author Thomas Müller <[email protected]>
12
 *
13
 * @license AGPL-3.0
14
 *
15
 * This code is free software: you can redistribute it and/or modify
16
 * it under the terms of the GNU Affero General Public License, version 3,
17
 * as published by the Free Software Foundation.
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, version 3,
25
 * along with this program. If not, see <http://www.gnu.org/licenses/>
26
 *
27
 */
28
namespace OCA\DAV\CardDAV;
29
30
use Exception;
31
use OCP\Accounts\IAccountManager;
32
use OCP\Accounts\PropertyDoesNotExistException;
33
use OCP\IImage;
34
use OCP\IUser;
35
use Sabre\VObject\Component\VCard;
36
use Sabre\VObject\Property\Text;
37
use function array_merge;
38
39
class Converter {
40
41
	/** @var IAccountManager */
42
	private $accountManager;
43
44
	public function __construct(IAccountManager $accountManager) {
45
		$this->accountManager = $accountManager;
46
	}
47
48
	public function createCardFromUser(IUser $user): ?VCard {
49
		$account = $this->accountManager->getAccount($user);
50
		$userProperties = $account->getProperties();
51
		try {
52
			$additionalEmailsCollection = $account->getPropertyCollection(IAccountManager::COLLECTION_EMAIL);
53
			$userProperties = array_merge($userProperties, $additionalEmailsCollection->getProperties());
54
		} catch (PropertyDoesNotExistException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
55
		}
56
57
		$uid = $user->getUID();
58
		$cloudId = $user->getCloudId();
59
		$image = $this->getAvatarImage($user);
60
61
		$vCard = new VCard();
62
		$vCard->VERSION = '3.0';
0 ignored issues
show
Bug Best Practice introduced by
The property VERSION does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
63
		$vCard->UID = $uid;
0 ignored issues
show
Bug Best Practice introduced by
The property UID does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
64
65
		$publish = false;
66
67
		foreach ($userProperties as $property) {
68
			$shareWithTrustedServers =
69
				$property->getScope() === IAccountManager::SCOPE_FEDERATED ||
70
				$property->getScope() === IAccountManager::SCOPE_PUBLISHED;
71
72
			$emptyValue = $property->getValue() === '';
73
74
			if ($shareWithTrustedServers && !$emptyValue) {
75
				$publish = true;
76
				switch ($property->getName()) {
77
					case IAccountManager::PROPERTY_DISPLAYNAME:
78
						$vCard->add(new Text($vCard, 'FN', $property->getValue()));
79
						$vCard->add(new Text($vCard, 'N', $this->splitFullName($property->getValue())));
80
						break;
81
					case IAccountManager::PROPERTY_AVATAR:
82
						if ($image !== null) {
83
							$vCard->add('PHOTO', $image->data(), ['ENCODING' => 'b', 'TYPE' => $image->mimeType()]);
84
						}
85
						break;
86
					case IAccountManager::COLLECTION_EMAIL:
87
					case IAccountManager::PROPERTY_EMAIL:
88
						$vCard->add(new Text($vCard, 'EMAIL', $property->getValue(), ['TYPE' => 'OTHER']));
89
						break;
90
					case IAccountManager::PROPERTY_WEBSITE:
91
						$vCard->add(new Text($vCard, 'URL', $property->getValue()));
92
						break;
93
					case IAccountManager::PROPERTY_PHONE:
94
						$vCard->add(new Text($vCard, 'TEL', $property->getValue(), ['TYPE' => 'OTHER']));
95
						break;
96
					case IAccountManager::PROPERTY_ADDRESS:
97
						$vCard->add(new Text($vCard, 'ADR', $property->getValue(), ['TYPE' => 'OTHER']));
98
						break;
99
					case IAccountManager::PROPERTY_TWITTER:
100
						$vCard->add(new Text($vCard, 'X-SOCIALPROFILE', $property->getValue(), ['TYPE' => 'TWITTER']));
101
						break;
102
					case IAccountManager::PROPERTY_ORGANISATION:
103
						$vCard->add(new Text($vCard, 'ORG', $property->getValue()));
104
						break;
105
					case IAccountManager::PROPERTY_ROLE:
106
						$vCard->add(new Text($vCard, 'TITLE', $property->getValue()));
107
						break;
108
				}
109
			}
110
		}
111
112
		if ($publish && !empty($cloudId)) {
113
			$vCard->add(new Text($vCard, 'CLOUD', $cloudId));
114
			$vCard->validate();
115
			return $vCard;
116
		}
117
118
		return null;
119
	}
120
121
	public function splitFullName(string $fullName): array {
122
		// Very basic western style parsing. I'm not gonna implement
123
		// https://github.com/android/platform_packages_providers_contactsprovider/blob/master/src/com/android/providers/contacts/NameSplitter.java ;)
124
125
		$elements = explode(' ', $fullName);
126
		$result = ['', '', '', '', ''];
127
		if (count($elements) > 2) {
128
			$result[0] = implode(' ', array_slice($elements, count($elements) - 1));
129
			$result[1] = $elements[0];
130
			$result[2] = implode(' ', array_slice($elements, 1, count($elements) - 2));
131
		} elseif (count($elements) === 2) {
132
			$result[0] = $elements[1];
133
			$result[1] = $elements[0];
134
		} else {
135
			$result[0] = $elements[0];
136
		}
137
138
		return $result;
139
	}
140
141
	private function getAvatarImage(IUser $user): ?IImage {
142
		try {
143
			return $user->getAvatarImage(-1);
144
		} catch (Exception $ex) {
145
			return null;
146
		}
147
	}
148
}
149