diff options
author | Roeland Jago Douma <rullzer@users.noreply.github.com> | 2016-08-31 16:09:18 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-08-31 16:09:18 +0300 |
commit | c04163b9d9c019726bf8d20a8d3a4f98a31b4299 (patch) | |
tree | b4cacc921f6bd352897a897024ea1c7a969f2fea | |
parent | d2a96a69a466f08be9ac1836937d621a1f3a8f71 (diff) | |
parent | 4bb1e42687373438351ec55ed2be966942836adb (diff) |
Merge pull request #1208 from nextcloud/backport-1190-addressbook-correctly-handle-multi-values-9
[stable9] Correctly handle multi-values when converting VCards to array
-rw-r--r-- | apps/dav/lib/carddav/addressbookimpl.php | 44 | ||||
-rw-r--r-- | apps/dav/tests/unit/carddav/addressbookimpltest.php | 65 |
2 files changed, 107 insertions, 2 deletions
diff --git a/apps/dav/lib/carddav/addressbookimpl.php b/apps/dav/lib/carddav/addressbookimpl.php index ccbafd5ba96..009f0d62ae3 100644 --- a/apps/dav/lib/carddav/addressbookimpl.php +++ b/apps/dav/lib/carddav/addressbookimpl.php @@ -26,6 +26,7 @@ namespace OCA\DAV\CardDAV; 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 @@ class AddressBookImpl implements IAddressBook { 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 7f5a6c853c1..4db3188d221 100644 --- a/apps/dav/tests/unit/carddav/addressbookimpltest.php +++ b/apps/dav/tests/unit/carddav/addressbookimpltest.php @@ -54,7 +54,9 @@ class AddressBookImplTest extends TestCase { $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 @@ class AddressBookImplTest extends TestCase { $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); + } } |