Search code examples
phpregexicalendar

How to parse Ical file from Facebook Events in PHP Regex?


I am trying to parse the Summary and DTSTART fields in this data and thought about using regex. Also tried reading line by line but couldn't work around the logic to implement it.

Anyone help out?

There are already made parsers out there but my requirements are abit unique and require a different targeted implementation.

BEGIN:VCALENDAR
PRODID:-//Facebook//NONSGML Facebook Events V1.0//EN
X-WR-CALNAME:Friends' birthdays
X-PUBLISHED-TTL:PT12H
X-ORIGINAL-URL:/events/birthdays/
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
BEGIN:VEVENT
DTSTART:20170106
SUMMARY:Gys's birthday
RRULE:FREQ=YEARLY
DURATION:P1D
UID:[email protected]
END:VEVENT
BEGIN:VEVENT
DTSTART:20130406
SUMMARY:Geo's birthday
RRULE:FREQ=YEARLY
DURATION:P1D
UID:[email protected]
END:VEVENT
BEGIN:VEVENT
DTSTART:20120602
SUMMARY:Flo's birthday
RRULE:FREQ=YEARLY
DURATION:P1D
UID:[email protected]
END:VEVENT

Solution

  • This code reads all of the file into an array (using file()) and then processes each line at a time. Each line is split into the tag and the content parts and then depending on what tag it is, it will either store the data temporarily or add the accumulated content into the overall calendar array. ...

    $file = "a.txt";
    $calendar = [];
    $lines = file($file, FILE_IGNORE_NEW_LINES);
    $temp = [];
    $type = "";
    foreach ( $lines as $line ) {
        list($tag,$content) = explode(":", $line);
        if ( $tag == "END" )    {
            $calendar[$type][] = $temp;
            $temp = [];
        }
        else if ( $tag == "BEGIN" )   {
            // If already some content, then store it in calendar and reset
            if ( count($temp) > 0 ) {
                $calendar[$type][] = $temp;
                $temp = [];
            }
            $type = $content;
        }
        else    {
            $temp[$tag] = $content;
        }
    }
    

    It uses the BEGIN tag content to store the events of the various parts of the file together, with the sample data file it will give...

    Array
    (
        [VCALENDAR] => Array
            (
                [0] => Array
                    (
                        [PRODID] => -//Facebook//NONSGML Facebook Events V1.0//EN
                        [X-WR-CALNAME] => Friends' birthdays
                        [X-PUBLISHED-TTL] => PT12H
                        [X-ORIGINAL-URL] => /events/birthdays/
                        [VERSION] => 2.0
                        [CALSCALE] => GREGORIAN
                        [METHOD] => PUBLISH
                    )
    
            )
    
        [VEVENT] => Array
            (
                [0] => Array
                    (
                        [DTSTART] => 20170106
                        [SUMMARY] => Gys's birthday
                        [RRULE] => FREQ=YEARLY
                        [DURATION] => P1D
                        [UID] => [email protected]
                    )
    
                [1] => Array
                    (
                        [DTSTART] => 20130406
                        [SUMMARY] => Geo's birthday
                        [RRULE] => FREQ=YEARLY
                        [DURATION] => P1D
                        [UID] => [email protected]
                    )
    
                [2] => Array
                    (
                        [DTSTART] => 20120602
                        [SUMMARY] => Flo's birthday
                        [RRULE] => FREQ=YEARLY
                        [DURATION] => P1D
                        [UID] => [email protected]
                    )
    
            )
    
    )