You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Converter.php 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Bjoern Schiessle <bjoern@schiessle.org>
  6. * @author Christoph Wurst <christoph@winzerhof-wurst.at>
  7. * @author Joas Schilling <coding@schilljs.com>
  8. * @author Morris Jobke <hey@morrisjobke.de>
  9. * @author Roeland Jago Douma <roeland@famdouma.nl>
  10. * @author Thomas Müller <thomas.mueller@tmit.eu>
  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. namespace OCA\DAV\CardDAV;
  28. use OC\Accounts\AccountManager;
  29. use OCP\Accounts\IAccountManager;
  30. use OCP\IImage;
  31. use OCP\IUser;
  32. use Sabre\VObject\Component\VCard;
  33. use Sabre\VObject\Property\Text;
  34. class Converter {
  35. /** @var AccountManager */
  36. private $accountManager;
  37. /**
  38. * Converter constructor.
  39. *
  40. * @param AccountManager $accountManager
  41. */
  42. public function __construct(AccountManager $accountManager) {
  43. $this->accountManager = $accountManager;
  44. }
  45. /**
  46. * @param IUser $user
  47. * @return VCard|null
  48. */
  49. public function createCardFromUser(IUser $user) {
  50. $userData = $this->accountManager->getUser($user);
  51. $uid = $user->getUID();
  52. $cloudId = $user->getCloudId();
  53. $image = $this->getAvatarImage($user);
  54. $vCard = new VCard();
  55. $vCard->VERSION = '3.0';
  56. $vCard->UID = $uid;
  57. $publish = false;
  58. if ($image !== null && isset($userData[IAccountManager::PROPERTY_AVATAR])) {
  59. $userData[IAccountManager::PROPERTY_AVATAR]['value'] = true;
  60. }
  61. foreach ($userData as $property => $value) {
  62. $shareWithTrustedServers =
  63. $value['scope'] === AccountManager::VISIBILITY_CONTACTS_ONLY ||
  64. $value['scope'] === AccountManager::VISIBILITY_PUBLIC;
  65. $emptyValue = !isset($value['value']) || $value['value'] === '';
  66. if ($shareWithTrustedServers && !$emptyValue) {
  67. $publish = true;
  68. switch ($property) {
  69. case IAccountManager::PROPERTY_DISPLAYNAME:
  70. $vCard->add(new Text($vCard, 'FN', $value['value']));
  71. $vCard->add(new Text($vCard, 'N', $this->splitFullName($value['value'])));
  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', $value['value'], ['TYPE' => 'OTHER']));
  80. break;
  81. case IAccountManager::PROPERTY_WEBSITE:
  82. $vCard->add(new Text($vCard, 'URL', $value['value']));
  83. break;
  84. case IAccountManager::PROPERTY_PHONE:
  85. $vCard->add(new Text($vCard, 'TEL', $value['value'], ['TYPE' => 'OTHER']));
  86. break;
  87. case IAccountManager::PROPERTY_ADDRESS:
  88. $vCard->add(new Text($vCard, 'ADR', $value['value'], ['TYPE' => 'OTHER']));
  89. break;
  90. case IAccountManager::PROPERTY_TWITTER:
  91. $vCard->add(new Text($vCard, 'X-SOCIALPROFILE', $value['value'], ['TYPE' => 'TWITTER']));
  92. break;
  93. }
  94. }
  95. }
  96. if ($publish && !empty($cloudId)) {
  97. $vCard->add(new Text($vCard, 'CLOUD', $cloudId));
  98. $vCard->validate();
  99. return $vCard;
  100. }
  101. return null;
  102. }
  103. /**
  104. * @param string $fullName
  105. * @return string[]
  106. */
  107. public function splitFullName($fullName) {
  108. // Very basic western style parsing. I'm not gonna implement
  109. // https://github.com/android/platform_packages_providers_contactsprovider/blob/master/src/com/android/providers/contacts/NameSplitter.java ;)
  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. return $result;
  123. }
  124. /**
  125. * @param IUser $user
  126. * @return null|IImage
  127. */
  128. private function getAvatarImage(IUser $user) {
  129. try {
  130. return $user->getAvatarImage(-1);
  131. } catch (\Exception $ex) {
  132. return null;
  133. }
  134. }
  135. }