diff options
author | Anna <anna@nextcloud.com> | 2022-07-26 20:59:33 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-26 20:59:33 +0200 |
commit | 5671abd168b58348859acf068c25313992dfaa0b (patch) | |
tree | cf92d2a525fc3d9f7d2822431e5e168149c3d15f /apps | |
parent | 072a0c6227819bbee32e8499b616c01884478388 (diff) | |
parent | 9eb276b20b051c31b349671600961c60d94ad175 (diff) | |
download | nextcloud-server-5671abd168b58348859acf068c25313992dfaa0b.tar.gz nextcloud-server-5671abd168b58348859acf068c25313992dfaa0b.zip |
Merge pull request #33251 from cneukom/feature/birthday-calendar-reminder-settings
Birthday Calendar Reminder Setting
Diffstat (limited to 'apps')
-rw-r--r-- | apps/dav/lib/CalDAV/BirthdayService.php | 71 | ||||
-rw-r--r-- | apps/dav/tests/unit/CardDAV/BirthdayServiceTest.php | 69 |
2 files changed, 99 insertions, 41 deletions
diff --git a/apps/dav/lib/CalDAV/BirthdayService.php b/apps/dav/lib/CalDAV/BirthdayService.php index 6e60f9d932e..be6b0911538 100644 --- a/apps/dav/lib/CalDAV/BirthdayService.php +++ b/apps/dav/lib/CalDAV/BirthdayService.php @@ -14,6 +14,7 @@ declare(strict_types=1); * @author Sven Strickroth <email@cs-ware.de> * @author Thomas MΓΌller <thomas.mueller@tmit.eu> * @author Valdnet <47037905+Valdnet@users.noreply.github.com> + * @author CΓ©dric Neukom <github@webguy.ch> * * @license AGPL-3.0 * @@ -86,6 +87,9 @@ class BirthdayService { $targetPrincipals = $this->getAllAffectedPrincipals($addressBookId); $book = $this->cardDavBackEnd->getAddressBookById($addressBookId); + if ($book === null) { + return; + } $targetPrincipals[] = $book['principaluri']; $datesToSync = [ ['postfix' => '', 'field' => 'BDAY'], @@ -98,9 +102,14 @@ class BirthdayService { continue; } + $reminderOffset = $this->getReminderOffsetForUser($principalUri); + $calendar = $this->ensureCalendarExists($principalUri); + if ($calendar === null) { + return; + } foreach ($datesToSync as $type) { - $this->updateCalendar($cardUri, $cardData, $book, (int) $calendar['id'], $type); + $this->updateCalendar($cardUri, $cardData, $book, (int) $calendar['id'], $type, $reminderOffset); } } } @@ -148,12 +157,14 @@ class BirthdayService { * @param $cardData * @param $dateField * @param $postfix + * @param $reminderOffset * @return VCalendar|null * @throws InvalidDataException */ - public function buildDateFromContact(string $cardData, - string $dateField, - string $postfix):?VCalendar { + public function buildDateFromContact(string $cardData, + string $dateField, + string $postfix, + ?string $reminderOffset):?VCalendar { if (empty($cardData)) { return null; } @@ -258,11 +269,13 @@ class BirthdayService { if ($originalYear !== null) { $vEvent->{'X-NEXTCLOUD-BC-YEAR'} = (string) $originalYear; } - $alarm = $vCal->createComponent('VALARM'); - $alarm->add($vCal->createProperty('TRIGGER', '-PT0M', ['VALUE' => 'DURATION'])); - $alarm->add($vCal->createProperty('ACTION', 'DISPLAY')); - $alarm->add($vCal->createProperty('DESCRIPTION', $vEvent->{'SUMMARY'})); - $vEvent->add($alarm); + if ($reminderOffset) { + $alarm = $vCal->createComponent('VALARM'); + $alarm->add($vCal->createProperty('TRIGGER', $reminderOffset, ['VALUE' => 'DURATION'])); + $alarm->add($vCal->createProperty('ACTION', 'DISPLAY')); + $alarm->add($vCal->createProperty('DESCRIPTION', $vEvent->{'SUMMARY'})); + $vEvent->add($alarm); + } $vCal->add($vEvent); return $vCal; } @@ -344,6 +357,7 @@ class BirthdayService { * @param array $book * @param int $calendarId * @param array $type + * @param string $reminderOffset * @throws InvalidDataException * @throws \Sabre\DAV\Exception\BadRequest */ @@ -351,9 +365,10 @@ class BirthdayService { string $cardData, array $book, int $calendarId, - array $type):void { + array $type, + ?string $reminderOffset):void { $objectUri = $book['uri'] . '-' . $cardUri . $type['postfix'] . '.ics'; - $calendarData = $this->buildDateFromContact($cardData, $type['field'], $type['postfix']); + $calendarData = $this->buildDateFromContact($cardData, $type['field'], $type['postfix'], $reminderOffset); $existing = $this->calDavBackEnd->getCalendarObject($calendarId, $objectUri); if ($calendarData === null) { if ($existing !== null) { @@ -394,14 +409,27 @@ class BirthdayService { } /** + * Extracts the userId part of a principal + * + * @param string $userPrincipal + * @return string|null + */ + private function principalToUserId(string $userPrincipal):?string { + if (substr($userPrincipal, 0, 17) === 'principals/users/') { + return substr($userPrincipal, 17); + } + return null; + } + + /** * Checks if the user opted-out of birthday calendars * * @param string $userPrincipal The user principal to check for * @return bool */ private function isUserEnabled(string $userPrincipal):bool { - if (strpos($userPrincipal, 'principals/users/') === 0) { - $userId = substr($userPrincipal, 17); + $userId = $this->principalToUserId($userPrincipal); + if ($userId !== null) { $isEnabled = $this->config->getUserValue($userId, 'dav', 'generateBirthdayCalendar', 'yes'); return $isEnabled === 'yes'; } @@ -411,6 +439,23 @@ class BirthdayService { } /** + * Get the reminder offset value for a user. This is a duration string (e.g. + * PT9H) or null if no reminder is wanted. + * + * @param string $userPrincipal + * @return string|null + */ + private function getReminderOffsetForUser(string $userPrincipal):?string { + $userId = $this->principalToUserId($userPrincipal); + if ($userId !== null) { + return $this->config->getUserValue($userId, 'dav', 'birthdayCalendarReminderOffset', 'PT9H') ?: null; + } + + // not sure how we got here, just be on the safe side and return the default value + return 'PT9H'; + } + + /** * Formats title of Birthday event * * @param string $field Field name like BDAY, ANNIVERSARY, ... diff --git a/apps/dav/tests/unit/CardDAV/BirthdayServiceTest.php b/apps/dav/tests/unit/CardDAV/BirthdayServiceTest.php index bb45c88b10d..188b82843cd 100644 --- a/apps/dav/tests/unit/CardDAV/BirthdayServiceTest.php +++ b/apps/dav/tests/unit/CardDAV/BirthdayServiceTest.php @@ -34,6 +34,7 @@ use OCP\IConfig; use OCP\IDBConnection; use OCP\IL10N; use Sabre\VObject\Component\VCalendar; +use Sabre\VObject\Property\ICalendar\Duration; use Sabre\VObject\Reader; use Test\TestCase; @@ -82,11 +83,12 @@ class BirthdayServiceTest extends TestCase { * @param string $expectedFieldType * @param string $expectedUnknownYear * @param string $expectedOriginalYear + * @param string|null $expectedReminder * @param string | null $data */ - public function testBuildBirthdayFromContact($expectedSummary, $expectedDTStart, $expectedFieldType, $expectedUnknownYear, $expectedOriginalYear, $data, $fieldType, $prefix, $supports4Bytes) { + public function testBuildBirthdayFromContact($expectedSummary, $expectedDTStart, $expectedFieldType, $expectedUnknownYear, $expectedOriginalYear, $expectedReminder, $data, $fieldType, $prefix, $supports4Bytes, $configuredReminder) { $this->dbConnection->method('supports4ByteText')->willReturn($supports4Bytes); - $cal = $this->service->buildDateFromContact($data, $fieldType, $prefix); + $cal = $this->service->buildDateFromContact($data, $fieldType, $prefix, $configuredReminder); if ($expectedSummary === null) { $this->assertNull($cal); @@ -104,6 +106,11 @@ class BirthdayServiceTest extends TestCase { $this->assertEquals($expectedOriginalYear, $cal->VEVENT->{'X-NEXTCLOUD-BC-YEAR'}->getValue()); } + if ($expectedReminder) { + $this->assertEquals($expectedReminder, $cal->VEVENT->VALARM->TRIGGER->getValue()); + $this->assertEquals('DURATION', $cal->VEVENT->VALARM->TRIGGER->getValueType()); + } + $this->assertEquals('TRANSPARENT', $cal->VEVENT->TRANSP->getValue()); } } @@ -227,10 +234,13 @@ class BirthdayServiceTest extends TestCase { ->with('dav', 'generateBirthdayCalendar', 'yes') ->willReturn('yes'); - $this->config->expects($this->once()) + $this->config->expects($this->exactly(2)) ->method('getUserValue') - ->with('user01', 'dav', 'generateBirthdayCalendar', 'yes') - ->willReturn('yes'); + ->withConsecutive( + ['user01', 'dav', 'generateBirthdayCalendar', 'yes'], + ['user01', 'dav', 'birthdayCalendarReminderOffset', 'PT9H'], + ) + ->willReturnOnConsecutiveCalls('yes', 'PT9H'); $this->cardDav->expects($this->once())->method('getAddressBookById') ->with(666) @@ -402,29 +412,32 @@ class BirthdayServiceTest extends TestCase { public function providesVCards() { return [ - // $expectedSummary, $expectedDTStart, $expectedFieldType, $expectedUnknownYear, $expectedOriginalYear, $data, $fieldType, $prefix, $supports4Byte - [null, null, null, null, null, 'yasfewf', '', '', true], - [null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nEND:VCARD\r\n", 'BDAY', '', true], - [null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:\r\nEND:VCARD\r\n", 'BDAY', '', true], - [null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:someday\r\nEND:VCARD\r\n", 'BDAY', '', true], - ['π 12345 (1900)', '19700101', 'BDAY', '0', '1900', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19000101\r\nEND:VCARD\r\n", 'BDAY', '', true], - ['π 12345 (1900)', '19701231', 'BDAY', '0', '1900', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19001231\r\nEND:VCARD\r\n", 'BDAY', '', true], - ['Death of 12345 (1900)', '19701231', 'DEATHDATE', '0', '1900', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nDEATHDATE:19001231\r\nEND:VCARD\r\n", 'DEATHDATE', '-death', true], - ['Death of 12345 (1900)', '19701231', 'DEATHDATE', '0', '1900', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nDEATHDATE:19001231\r\nEND:VCARD\r\n", 'DEATHDATE', '-death', false], - ['π 12345 (1900)', '19701231', 'ANNIVERSARY', '0', '1900', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nANNIVERSARY:19001231\r\nEND:VCARD\r\n", 'ANNIVERSARY', '-anniversary', true], - ['12345 (β1900)', '19701231', 'ANNIVERSARY', '0', '1900', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nANNIVERSARY:19001231\r\nEND:VCARD\r\n", 'ANNIVERSARY', '-anniversary', false], - ['π 12345', '19701231', 'BDAY', '1', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:--1231\r\nEND:VCARD\r\n", 'BDAY', '', true], - ['π 12345', '19701231', 'BDAY', '1', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY;X-APPLE-OMIT-YEAR=1604:16041231\r\nEND:VCARD\r\n", 'BDAY', '', true], - [null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:;VALUE=text:circa 1800\r\nEND:VCARD\r\n", 'BDAY', '', true], - [null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nN:12345;;;;\r\nBDAY:20031231\r\nEND:VCARD\r\n", 'BDAY', '', true], - ['π 12345 (900)', '19701231', 'BDAY', '0', '900', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:09001231\r\nEND:VCARD\r\n", 'BDAY', '', true], - ['12345 (*1900)', '19700101', 'BDAY', '0', '1900', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19000101\r\nEND:VCARD\r\n", 'BDAY', '', false], - ['12345 (*1900)', '19701231', 'BDAY', '0', '1900', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19001231\r\nEND:VCARD\r\n", 'BDAY', '', false], - ['12345 *', '19701231', 'BDAY', '1', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:--1231\r\nEND:VCARD\r\n", 'BDAY', '', false], - ['12345 *', '19701231', 'BDAY', '1', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY;X-APPLE-OMIT-YEAR=1604:16041231\r\nEND:VCARD\r\n", 'BDAY', '', false], - [null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:;VALUE=text:circa 1800\r\nEND:VCARD\r\n", 'BDAY', '', false], - [null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nN:12345;;;;\r\nBDAY:20031231\r\nEND:VCARD\r\n", 'BDAY', '', false], - ['12345 (*900)', '19701231', 'BDAY', '0', '900', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:09001231\r\nEND:VCARD\r\n", 'BDAY', '', false], + // $expectedSummary, $expectedDTStart, $expectedFieldType, $expectedUnknownYear, $expectedOriginalYear, $expectedReminder, $data, $fieldType, $prefix, $supports4Byte, $configuredReminder + [null, null, null, null, null, null, 'yasfewf', '', '', true, null], + [null, null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nEND:VCARD\r\n", 'BDAY', '', true, null], + [null, null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:\r\nEND:VCARD\r\n", 'BDAY', '', true, null], + [null, null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:someday\r\nEND:VCARD\r\n", 'BDAY', '', true, null], + ['π 12345 (1900)', '19700101', 'BDAY', '0', '1900', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19000101\r\nEND:VCARD\r\n", 'BDAY', '', true, null], + ['π 12345 (1900)', '19701231', 'BDAY', '0', '1900', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19001231\r\nEND:VCARD\r\n", 'BDAY', '', true, null], + ['Death of 12345 (1900)', '19701231', 'DEATHDATE', '0', '1900', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nDEATHDATE:19001231\r\nEND:VCARD\r\n", 'DEATHDATE', '-death', true, null], + ['Death of 12345 (1900)', '19701231', 'DEATHDATE', '0', '1900', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nDEATHDATE:19001231\r\nEND:VCARD\r\n", 'DEATHDATE', '-death', false, null], + ['π 12345 (1900)', '19701231', 'ANNIVERSARY', '0', '1900', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nANNIVERSARY:19001231\r\nEND:VCARD\r\n", 'ANNIVERSARY', '-anniversary', true, null], + ['12345 (β1900)', '19701231', 'ANNIVERSARY', '0', '1900', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nANNIVERSARY:19001231\r\nEND:VCARD\r\n", 'ANNIVERSARY', '-anniversary', false, null], + ['π 12345', '19701231', 'BDAY', '1', null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:--1231\r\nEND:VCARD\r\n", 'BDAY', '', true, null], + ['π 12345', '19701231', 'BDAY', '1', null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY;X-APPLE-OMIT-YEAR=1604:16041231\r\nEND:VCARD\r\n", 'BDAY', '', true, null], + [null, null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:;VALUE=text:circa 1800\r\nEND:VCARD\r\n", 'BDAY', '', true, null], + [null, null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nN:12345;;;;\r\nBDAY:20031231\r\nEND:VCARD\r\n", 'BDAY', '', true, null], + ['π 12345 (900)', '19701231', 'BDAY', '0', '900', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:09001231\r\nEND:VCARD\r\n", 'BDAY', '', true, null], + ['12345 (*1900)', '19700101', 'BDAY', '0', '1900', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19000101\r\nEND:VCARD\r\n", 'BDAY', '', false, null], + ['12345 (*1900)', '19701231', 'BDAY', '0', '1900', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19001231\r\nEND:VCARD\r\n", 'BDAY', '', false, null], + ['12345 *', '19701231', 'BDAY', '1', null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:--1231\r\nEND:VCARD\r\n", 'BDAY', '', false, null], + ['12345 *', '19701231', 'BDAY', '1', null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY;X-APPLE-OMIT-YEAR=1604:16041231\r\nEND:VCARD\r\n", 'BDAY', '', false, null], + [null, null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:;VALUE=text:circa 1800\r\nEND:VCARD\r\n", 'BDAY', '', false, null], + [null, null, null, null, null, null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nN:12345;;;;\r\nBDAY:20031231\r\nEND:VCARD\r\n", 'BDAY', '', false, null], + ['12345 (*900)', '19701231', 'BDAY', '0', '900', null, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:09001231\r\nEND:VCARD\r\n", 'BDAY', '', false, null], + ['12345 (*1900)', '19701231', 'BDAY', '0', '1900', 'PT9H', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19001231\r\nEND:VCARD\r\n", 'BDAY', '', false, 'PT9H'], + ['12345 (*1900)', '19701231', 'BDAY', '0', '1900', '-PT15H', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19001231\r\nEND:VCARD\r\n", 'BDAY', '', false, '-PT15H'], + ['12345 (*1900)', '19701231', 'BDAY', '0', '1900', '-P6DT15H', "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 4.1.1//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:19001231\r\nEND:VCARD\r\n", 'BDAY', '', false, '-P6DT15H'], ]; } } |