Handle multiple VCALENDAR blocks when reading ics files (#2884)
This commit is contained in:
parent
5602b5f3cd
commit
1ef785c8c6
3 changed files with 123 additions and 12 deletions
|
@ -48,6 +48,7 @@ class libvcalendar implements Iterator
|
|||
private $iteratorkey = 0;
|
||||
private $charset;
|
||||
private $forward_exceptions;
|
||||
private $vhead;
|
||||
private $fp;
|
||||
|
||||
public $method;
|
||||
|
@ -101,6 +102,7 @@ class libvcalendar implements Iterator
|
|||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->vhead = '';
|
||||
$this->method = '';
|
||||
$this->objects = array();
|
||||
$this->freebusy = array();
|
||||
|
@ -202,16 +204,7 @@ class libvcalendar implements Iterator
|
|||
return false;
|
||||
}
|
||||
|
||||
// read vcalendar header (with timezone defintion)
|
||||
$this->vhead = '';
|
||||
fseek($this->fp, 0);
|
||||
while (($line = fgets($this->fp, 512)) !== false) {
|
||||
if (preg_match('/BEGIN:(VEVENT|VTODO|VFREEBUSY)/i', $line))
|
||||
break;
|
||||
$this->vhead .= $line;
|
||||
}
|
||||
fseek($this->fp, -strlen($line), SEEK_CUR);
|
||||
|
||||
return $this->_parse_next();
|
||||
}
|
||||
|
||||
|
@ -269,12 +262,33 @@ class libvcalendar implements Iterator
|
|||
private function _next_component()
|
||||
{
|
||||
$buffer = '';
|
||||
$vcalendar_head = false;
|
||||
while (($line = fgets($this->fp, 1024)) !== false) {
|
||||
// ignore END:VCALENDAR lines
|
||||
if (preg_match('/END:VCALENDAR/i', $line)) {
|
||||
continue;
|
||||
}
|
||||
// read vcalendar header (with timezone defintion)
|
||||
if (preg_match('/BEGIN:VCALENDAR/i', $line)) {
|
||||
$this->vhead = '';
|
||||
$vcalendar_head = true;
|
||||
}
|
||||
|
||||
// end of VCALENDAR header part
|
||||
if ($vcalendar_head && preg_match('/BEGIN:(VEVENT|VTODO|VFREEBUSY)/i', $line)) {
|
||||
$vcalendar_head = false;
|
||||
}
|
||||
|
||||
if ($vcalendar_head) {
|
||||
$this->vhead .= $line;
|
||||
}
|
||||
else {
|
||||
$buffer .= $line;
|
||||
if (preg_match('/END:(VEVENT|VTODO|VFREEBUSY)/i', $line)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
|
|
@ -74,6 +74,23 @@ class libvcalendar_test extends PHPUnit_Framework_TestCase
|
|||
$this->assertEmpty($events);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parsing from files with multiple VCALENDAR blocks (#2884)
|
||||
*/
|
||||
function test_import_from_file_multiple()
|
||||
{
|
||||
$ical = new libvcalendar();
|
||||
$ical->fopen(__DIR__ . '/resources/multiple-rdate.ics', 'UTF-8');
|
||||
$events = array();
|
||||
foreach ($ical as $event) {
|
||||
$events[] = $event;
|
||||
}
|
||||
|
||||
$this->assertEquals(2, count($events));
|
||||
$this->assertEquals("AAAA6A8C3CCE4EE2C1257B5C00FFFFFF-Lotus_Notes_Generated", $events[0]['uid']);
|
||||
$this->assertEquals("AAAA1C572093EC3FC125799C004AFFFF-Lotus_Notes_Generated", $events[1]['uid']);
|
||||
}
|
||||
|
||||
function test_invalid_dates()
|
||||
{
|
||||
$ical = new libvcalendar();
|
||||
|
|
80
plugins/libcalendaring/tests/resources/multiple-rdate.ics
Normal file
80
plugins/libcalendaring/tests/resources/multiple-rdate.ics
Normal file
|
@ -0,0 +1,80 @@
|
|||
BEGIN:VCALENDAR
|
||||
X-LOTUS-CHARSET:UTF-8
|
||||
VERSION:2.0
|
||||
PRODID:-//Lotus Development Corporation//NONSGML Notes 8.5.3//EN_C
|
||||
METHOD:PUBLISH
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:W. Europe
|
||||
BEGIN:STANDARD
|
||||
DTSTART:19501029T020000
|
||||
TZOFFSETFROM:+0200
|
||||
TZOFFSETTO:+0100
|
||||
RRULE:FREQ=YEARLY;BYMINUTE=0;BYHOUR=2;BYDAY=-1SU;BYMONTH=10
|
||||
END:STANDARD
|
||||
BEGIN:DAYLIGHT
|
||||
DTSTART:19500326T020000
|
||||
TZOFFSETFROM:+0100
|
||||
TZOFFSETTO:+0200
|
||||
RRULE:FREQ=YEARLY;BYMINUTE=0;BYHOUR=2;BYDAY=-1SU;BYMONTH=3
|
||||
END:DAYLIGHT
|
||||
END:VTIMEZONE
|
||||
|
||||
BEGIN:VEVENT
|
||||
DTSTART;TZID="W. Europe":20140520T040000
|
||||
DTEND;TZID="W. Europe":20140520T200000
|
||||
TRANSP:TRANSPARENT
|
||||
RDATE;VALUE=PERIOD:20140520T020000Z/20140520T180000Z
|
||||
,PERIOD:20150520T020000Z/20150520T180000Z
|
||||
,20160520T020000Z/20160520T180000Z,20170520T020000Z/20170520T180000Z
|
||||
,20180520T020000Z/20180520T180000Z,20190520T020000Z/20190520T180000Z
|
||||
,20200520T020000Z/20200520T180000Z,20210520T020000Z/20210520T180000Z
|
||||
,20220520T020000Z/20220520T180000Z
|
||||
DTSTAMP:20140227T123549Z
|
||||
CLASS:PUBLIC
|
||||
SUMMARY:Feiertag - Pfingsmontag
|
||||
UID:AAAA6A8C3CCE4EE2C1257B5C00FFFFFF-Lotus_Notes_Generated
|
||||
X-LOTUS-PARITAL-REPEAT:TRUE
|
||||
X-LOTUS-NOTESVERSION:2
|
||||
X-LOTUS-APPTTYPE:1
|
||||
END:VEVENT
|
||||
|
||||
END:VCALENDAR
|
||||
|
||||
BEGIN:VCALENDAR
|
||||
X-LOTUS-CHARSET:UTF-8
|
||||
VERSION:2.0
|
||||
PRODID:-//Lotus Development Corporation//NONSGML Notes 8.5.3//EN_C
|
||||
METHOD:PUBLISH
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:W. Europe
|
||||
BEGIN:STANDARD
|
||||
DTSTART:19501029T020000
|
||||
TZOFFSETFROM:+0200
|
||||
TZOFFSETTO:+0100
|
||||
RRULE:FREQ=YEARLY;BYMINUTE=0;BYHOUR=2;BYDAY=-1SU;BYMONTH=10
|
||||
END:STANDARD
|
||||
BEGIN:DAYLIGHT
|
||||
DTSTART:19500326T020000
|
||||
TZOFFSETFROM:+0100
|
||||
TZOFFSETTO:+0200
|
||||
RRULE:FREQ=YEARLY;BYMINUTE=0;BYHOUR=2;BYDAY=-1SU;BYMONTH=3
|
||||
END:DAYLIGHT
|
||||
END:VTIMEZONE
|
||||
|
||||
BEGIN:VEVENT
|
||||
DTSTART;TZID="W. Europe":20120330T040000
|
||||
DTEND;TZID="W. Europe":20120330T200000
|
||||
TRANSP:TRANSPARENT
|
||||
RDATE;VALUE=PERIOD:20120330T020000Z/20120330T180000Z
|
||||
,20130330T030000Z/20130330T190000Z,20140330T020000Z/20140330T180000Z
|
||||
,20150330T020000Z/20150330T180000Z,20160330T020000Z/20160330T180000Z
|
||||
,20170330T020000Z/20170330T180000Z,20180330T020000Z/20180330T180000Z
|
||||
,20190330T030000Z/20190330T190000Z,20200330T020000Z/20200330T180000Z
|
||||
,20210330T020000Z/20210330T180000Z
|
||||
DTSTAMP:20140227T123547Z
|
||||
CLASS:PUBLIC
|
||||
SUMMARY:Another RDATE repeating event
|
||||
UID:AAAA1C572093EC3FC125799C004AFFFF-Lotus_Notes_Generated
|
||||
END:VEVENT
|
||||
|
||||
END:VCALENDAR
|
Loading…
Add table
Reference in a new issue