diff --git a/apps/dav/lib/carddav/addressbookimpl.php b/apps/dav/lib/carddav/addressbookimpl.php index ccbafd5ba96b9..009f0d62ae3e4 100644 --- a/apps/dav/lib/carddav/addressbookimpl.php +++ b/apps/dav/lib/carddav/addressbookimpl.php @@ -26,6 +26,7 @@ use OCP\Constants; use OCP\IAddressBook; use Sabre\VObject\Component\VCard; +use Sabre\VObject\Property; use Sabre\VObject\Property\Text; use Sabre\VObject\Reader; use Sabre\VObject\UUIDUtil; @@ -214,12 +215,53 @@ protected function createEmptyVCard($uid) { protected function vCard2Array(VCard $vCard) { $result = []; foreach ($vCard->children as $property) { - $result[$property->name] = $property->getValue(); + /** @var \Sabre\VObject\Property\Unknown $property */ + if ($property->name === 'X-SOCIALPROFILE') { + $type = $this->getTypeFromProperty($property); + + // Type is the social network, when it's empty we don't need this. + if ($type !== null) { + if (!isset($result[$property->name])) { + $result[$property->name] = []; + } + $result[$property->name][$type] = $property->getValue(); + } + + // The following properties can be set multiple times + } else if (in_array($property->name, ['CLOUD', 'EMAIL', 'IMPP', 'TEL', 'URL'])) { + if (!isset($result[$property->name])) { + $result[$property->name] = []; + } + + $result[$property->name][] = $property->getValue(); + + } else { + $result[$property->name] = $property->getValue(); + } } + if ($this->addressBookInfo['principaluri'] === 'principals/system/system' && $this->addressBookInfo['uri'] === 'system') { $result['isLocalSystemBook'] = true; } return $result; } + + /** + * Get the type of the current property + * + * @param Property $property + * @return null|string + */ + protected function getTypeFromProperty(Property $property) { + $parameters = $property->parameters(); + // Type is the social network, when it's empty we don't need this. + if (isset($parameters['TYPE'])) { + /** @var \Sabre\VObject\Parameter $type */ + $type = $parameters['TYPE']; + return $type->getValue(); + } + + return null; + } } diff --git a/apps/dav/tests/unit/carddav/addressbookimpltest.php b/apps/dav/tests/unit/carddav/addressbookimpltest.php index 7f5a6c853c1bb..4db3188d2212b 100644 --- a/apps/dav/tests/unit/carddav/addressbookimpltest.php +++ b/apps/dav/tests/unit/carddav/addressbookimpltest.php @@ -54,7 +54,9 @@ public function setUp() { $this->addressBookInfo = [ 'id' => 42, - '{DAV:}displayname' => 'display name' + 'uri' => 'system', + 'principaluri' => 'principals/system/system', + '{DAV:}displayname' => 'display name', ]; $this->addressBook = $this->getMockBuilder('OCA\DAV\CardDAV\AddressBook') ->disableOriginalConstructor()->getMock(); @@ -286,4 +288,65 @@ public function testCreateEmptyVCard() { $this->assertSame($expectedVCardSerialized, $resultSerialized); } + + public function testVCard2Array() { + $vCard = new VCard(); + + $vCard->add($vCard->createProperty('FN', 'Full Name')); + + // Multi-value properties + $vCard->add($vCard->createProperty('CLOUD', 'cloud-user1@localhost')); + $vCard->add($vCard->createProperty('CLOUD', 'cloud-user2@example.tld')); + $vCard->add($vCard->createProperty('EMAIL', 'email-user1@localhost')); + $vCard->add($vCard->createProperty('EMAIL', 'email-user2@example.tld')); + $vCard->add($vCard->createProperty('IMPP', 'impp-user1@localhost')); + $vCard->add($vCard->createProperty('IMPP', 'impp-user2@example.tld')); + $vCard->add($vCard->createProperty('TEL', '+49 123456789')); + $vCard->add($vCard->createProperty('TEL', '+1 555 123456789')); + $vCard->add($vCard->createProperty('URL', 'https://localhost')); + $vCard->add($vCard->createProperty('URL', 'https://example.tld')); + + // Type depending properties + $property = $vCard->createProperty('X-SOCIALPROFILE', 'tw-example'); + $property->add('TYPE', 'twitter'); + $vCard->add($property); + $property = $vCard->createProperty('X-SOCIALPROFILE', 'fb-example'); + $property->add('TYPE', 'facebook'); + $vCard->add($property); + + $array = $this->invokePrivate($this->addressBookImpl, 'vCard2Array', [$vCard]); + unset($array['PRODID']); + + $this->assertEquals([ + 'VERSION' => '3.0', + 'FN' => 'Full Name', + 'CLOUD' => [ + 'cloud-user1@localhost', + 'cloud-user2@example.tld', + ], + 'EMAIL' => [ + 'email-user1@localhost', + 'email-user2@example.tld', + ], + 'IMPP' => [ + 'impp-user1@localhost', + 'impp-user2@example.tld', + ], + 'TEL' => [ + '+49 123456789', + '+1 555 123456789', + ], + 'URL' => [ + 'https://localhost', + 'https://example.tld', + ], + + 'X-SOCIALPROFILE' => [ + 'twitter'=> 'tw-example', + 'facebook'=> 'fb-example', + ], + + 'isLocalSystemBook' => true, + ], $array); + } }