Passed
Push — master ( 024ed9...a2a964 )
by Roeland
15:08 queued 11s
created

Converter::createCardFromUser()   C

Complexity

Conditions 15
Paths 42

Size

Total Lines 58
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 15
eloc 44
nc 42
nop 1
dl 0
loc 58
rs 5.9166
c 0
b 0
f 0

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 Bjoern Schiessle <[email protected]>
6
 * @author Christoph Wurst <[email protected]>
7
 * @author Joas Schilling <[email protected]>
8
 * @author Morris Jobke <[email protected]>
9
 * @author Roeland Jago Douma <[email protected]>
10
 * @author Thomas Müller <[email protected]>
11
 *
12
 * @license AGPL-3.0
13
 *
14
 * This code is free software: you can redistribute it and/or modify
15
 * it under the terms of the GNU Affero General Public License, version 3,
16
 * as published by the Free Software Foundation.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
 * GNU Affero General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU Affero General Public License, version 3,
24
 * along with this program. If not, see <http://www.gnu.org/licenses/>
25
 *
26
 */
27
28
namespace OCA\DAV\CardDAV;
29
30
use Exception;
31
use OCP\Accounts\IAccountManager;
32
use OCP\IImage;
33
use OCP\IUser;
34
use Sabre\VObject\Component\VCard;
35
use Sabre\VObject\Property\Text;
36
37
class Converter {
38
39
	/** @var IAccountManager */
40
	private $accountManager;
41
42
	public function __construct(IAccountManager $accountManager) {
43
		$this->accountManager = $accountManager;
44
	}
45
46
	public function createCardFromUser(IUser $user): ?VCard {
47
		$userProperties = $this->accountManager->getAccount($user)->getProperties();
48
49
		$uid = $user->getUID();
50
		$cloudId = $user->getCloudId();
51
		$image = $this->getAvatarImage($user);
52
53
		$vCard = new VCard();
54
		$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...
55
		$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...
56
57
		$publish = false;
58
59
		foreach ($userProperties as $property) {
60
			$shareWithTrustedServers =
61
				$property->getScope() === IAccountManager::SCOPE_FEDERATED ||
62
				$property->getScope() === IAccountManager::SCOPE_PUBLISHED;
63
64
			$emptyValue = $property->getValue() === '';
65
66
			if ($shareWithTrustedServers && !$emptyValue) {
67
				$publish = true;
68
				switch ($property->getName()) {
69
					case IAccountManager::PROPERTY_DISPLAYNAME:
70
						$vCard->add(new Text($vCard, 'FN', $property->getValue()));
71
						$vCard->add(new Text($vCard, 'N', $this->splitFullName($property->getValue())));
72
						break;
73
					case IAccountManager::PROPERTY_AVATAR:
74
						if ($image !== null) {
75
							$vCard->add('PHOTO', $image->data(), ['ENCODING' => 'b', 'TYPE' => $image->mimeType()]);
76
						}
77
						break;
78
					case IAccountManager::PROPERTY_EMAIL:
79
						$vCard->add(new Text($vCard, 'EMAIL', $property->getValue(), ['TYPE' => 'OTHER']));
80
						break;
81
					case IAccountManager::PROPERTY_WEBSITE:
82
						$vCard->add(new Text($vCard, 'URL', $property->getValue()));
83
						break;
84
					case IAccountManager::PROPERTY_PHONE:
85
						$vCard->add(new Text($vCard, 'TEL', $property->getValue(), ['TYPE' => 'OTHER']));
86
						break;
87
					case IAccountManager::PROPERTY_ADDRESS:
88
						$vCard->add(new Text($vCard, 'ADR', $property->getValue(), ['TYPE' => 'OTHER']));
89
						break;
90
					case IAccountManager::PROPERTY_TWITTER:
91
						$vCard->add(new Text($vCard, 'X-SOCIALPROFILE', $property->getValue(), ['TYPE' => 'TWITTER']));
92
						break;
93
				}
94
			}
95
		}
96
97
		if ($publish && !empty($cloudId)) {
98
			$vCard->add(new Text($vCard, 'CLOUD', $cloudId));
99
			$vCard->validate();
100
			return $vCard;
101
		}
102
103
		return null;
104
	}
105
106
	public function splitFullName(string $fullName): array {
107
		// Very basic western style parsing. I'm not gonna implement
108
		// https://github.com/android/platform_packages_providers_contactsprovider/blob/master/src/com/android/providers/contacts/NameSplitter.java ;)
109
110
		$elements = explode(' ', $fullName);
111
		$result = ['', '', '', '', ''];
112
		if (count($elements) > 2) {
113
			$result[0] = implode(' ', array_slice($elements, count($elements) - 1));
114
			$result[1] = $elements[0];
115
			$result[2] = implode(' ', array_slice($elements, 1, count($elements) - 2));
116
		} elseif (count($elements) === 2) {
117
			$result[0] = $elements[1];
118
			$result[1] = $elements[0];
119
		} else {
120
			$result[0] = $elements[0];
121
		}
122
123
		return $result;
124
	}
125
126
	private function getAvatarImage(IUser $user): ?IImage {
127
		try {
128
			return $user->getAvatarImage(-1);
129
		} catch (Exception $ex) {
130
			return null;
131
		}
132
	}
133
}
134