Parse multiple vevent components with the same UID into one object with exceptions (#4733)
This commit is contained in:
parent
8f4fefe849
commit
83d3d016bd
3 changed files with 43 additions and 20 deletions
|
@ -305,6 +305,7 @@ class libvcalendar implements Iterator
|
|||
public function import_from_vobject($vobject)
|
||||
{
|
||||
$seen = array();
|
||||
$exceptions = array();
|
||||
|
||||
if ($vobject->name == 'VCALENDAR') {
|
||||
$this->method = strval($vobject->METHOD);
|
||||
|
@ -315,22 +316,11 @@ class libvcalendar implements Iterator
|
|||
// convert to hash array representation
|
||||
$object = $this->_to_array($ve);
|
||||
|
||||
if (!$seen[$object['uid']]++) {
|
||||
// parse recurrence exceptions
|
||||
if ($object['recurrence']) {
|
||||
$object['recurrence']['EXCEPTIONS'] = array();
|
||||
foreach ($vobject->children as $component) {
|
||||
if ($component->name == 'VEVENT' && isset($component->{'RECURRENCE-ID'})) {
|
||||
try {
|
||||
$object['recurrence']['EXCEPTIONS'][] = $this->_to_array($component);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
console("iCal data parse error: " . $e->getMessage(), $component->serialize());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// temporarily store this as exception
|
||||
if ($object['recurrence_date']) {
|
||||
$exceptions[] = $object;
|
||||
}
|
||||
else if (!$seen[$object['uid']]++) {
|
||||
$this->objects[] = $object;
|
||||
}
|
||||
}
|
||||
|
@ -338,6 +328,29 @@ class libvcalendar implements Iterator
|
|||
$this->objects[] = $this->_parse_freebusy($ve);
|
||||
}
|
||||
}
|
||||
|
||||
// add exceptions to the according master events
|
||||
foreach ($exceptions as $exception) {
|
||||
$uid = $exception['uid'];
|
||||
|
||||
// make this exception the master
|
||||
if (!$seen[$uid]++) {
|
||||
$this->objects[] = $exception;
|
||||
}
|
||||
else {
|
||||
foreach ($this->objects as $i => $object) {
|
||||
// add as exception to existing entry with a matching UID
|
||||
if ($object['uid'] == $uid) {
|
||||
$this->objects[$i]['exceptions'][] = $exception;
|
||||
|
||||
if (!empty($object['recurrence'])) {
|
||||
$this->objects[$i]['recurrence']['EXCEPTIONS'] = &$this->objects[$i]['exceptions'];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->objects;
|
||||
|
|
|
@ -112,8 +112,6 @@ class libvcalendar_test extends PHPUnit_Framework_TestCase
|
|||
|
||||
/**
|
||||
* Test some extended ical properties such as attendees, recurrence rules, alarms and attachments
|
||||
*
|
||||
* @depends test_import_from_file
|
||||
*/
|
||||
function test_extended()
|
||||
{
|
||||
|
@ -160,11 +158,15 @@ class libvcalendar_test extends PHPUnit_Framework_TestCase
|
|||
$this->assertEquals('libcalendaring tests', join(',', (array)$event['categories']), "Event categories");
|
||||
$this->assertEquals('confidential', $event['sensitivity'], "Class/sensitivity = confidential");
|
||||
|
||||
// parse a reccuence chain instance
|
||||
// parse a recurrence chain instance
|
||||
$events = $ical->import_from_file(__DIR__ . '/resources/recurrence-id.ics', 'UTF-8');
|
||||
$this->assertEquals(1, count($events), "Fall back to Component::getComponents() when getBaseComponents() is empty");
|
||||
$this->assertInstanceOf('DateTime', $events[0]['recurrence_date'], "Recurrence-ID as date");
|
||||
$this->assertTrue($events[0]['thisandfuture'], "Range=THISANDFUTURE");
|
||||
|
||||
$this->assertEquals(count($events[0]['exceptions']), 1, "Second VEVENT as exception");
|
||||
$this->assertEquals($events[0]['exceptions'][0]['uid'], $events[0]['uid'], "Exception UID match");
|
||||
$this->assertEquals($events[0]['exceptions'][0]['sequence'], '2', "Exception sequence");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,11 +21,19 @@ BEGIN:VEVENT
|
|||
DTSTART;TZID="W. Europe":20140230T150000
|
||||
DTEND;TZID="W. Europe":20140230T163000
|
||||
TRANSP:OPAQUE
|
||||
RDATE;TZID="W. Europe";VALUE=PERIOD:20140227T140000/20140227T153000
|
||||
RECURRENCE-ID;RANGE=THISANDFUTURE:20140227T130000Z
|
||||
SEQUENCE:0
|
||||
UID:7e93e8e8eef16f28aa33b78cd73613ebff
|
||||
DTSTAMP:20140120T105609Z
|
||||
SUMMARY:Invitation with Recurrence-ID
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
DTSTART;TZID="W. Europe":20140305T150000
|
||||
DTEND;TZID="W. Europe":20140305T163000
|
||||
RECURRENCE-ID;TZID="W. Europe":20140305T150000
|
||||
SEQUENCE:2
|
||||
UID:7e93e8e8eef16f28aa33b78cd73613ebff
|
||||
DTSTAMP:20140120T105609Z
|
||||
SUMMARY:Invitation with Recurrence-ID #2
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
|
|
Loading…
Add table
Reference in a new issue