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 $iteratorkey = 0;
|
||||||
private $charset;
|
private $charset;
|
||||||
private $forward_exceptions;
|
private $forward_exceptions;
|
||||||
|
private $vhead;
|
||||||
private $fp;
|
private $fp;
|
||||||
|
|
||||||
public $method;
|
public $method;
|
||||||
|
@ -101,6 +102,7 @@ class libvcalendar implements Iterator
|
||||||
*/
|
*/
|
||||||
public function reset()
|
public function reset()
|
||||||
{
|
{
|
||||||
|
$this->vhead = '';
|
||||||
$this->method = '';
|
$this->method = '';
|
||||||
$this->objects = array();
|
$this->objects = array();
|
||||||
$this->freebusy = array();
|
$this->freebusy = array();
|
||||||
|
@ -202,16 +204,7 @@ class libvcalendar implements Iterator
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read vcalendar header (with timezone defintion)
|
|
||||||
$this->vhead = '';
|
|
||||||
fseek($this->fp, 0);
|
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();
|
return $this->_parse_next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,12 +262,33 @@ class libvcalendar implements Iterator
|
||||||
private function _next_component()
|
private function _next_component()
|
||||||
{
|
{
|
||||||
$buffer = '';
|
$buffer = '';
|
||||||
|
$vcalendar_head = false;
|
||||||
while (($line = fgets($this->fp, 1024)) !== 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;
|
$buffer .= $line;
|
||||||
if (preg_match('/END:(VEVENT|VTODO|VFREEBUSY)/i', $line)) {
|
if (preg_match('/END:(VEVENT|VTODO|VFREEBUSY)/i', $line)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $buffer;
|
return $buffer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,23 @@ class libvcalendar_test extends PHPUnit_Framework_TestCase
|
||||||
$this->assertEmpty($events);
|
$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()
|
function test_invalid_dates()
|
||||||
{
|
{
|
||||||
$ical = new libvcalendar();
|
$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