johngrogg / ics-parser
ICS Parser
Fund package maintenance!
u01jmg3
Installs: 2 638 700
Dependents: 23
Suggesters: 0
Security: 0
Stars: 453
Watchers: 33
Forks: 145
Open Issues: 8
Requires
- php: >=5.6.40
- ext-mbstring: *
Requires (Dev)
- phpunit/phpunit: ^5|^9|^10
- dev-master
- v3.4.1
- v3.4.0
- v3.3.1
- v3.3.0
- v3.2.1
- v3.2.0
- v3.1.1
- v3.1.0
- v3.0.0
- v2.2.2
- v2.2.1
- v2.1.20
- v2.1.19
- v2.1.18
- v2.1.17
- v2.1.16
- v2.1.15
- v2.1.14
- v2.1.13
- v2.1.12
- v2.1.11
- v2.1.10
- v2.1.9
- v2.1.8
- v2.1.7
- v2.1.6
- v2.1.5
- v2.1.4
- v2.1.3
- v2.1.2
- v2.1.1
- v2.1.0
- v2.0.7
- v2.0.6
- v2.0.5
- v2.0.4
- v2.0.3
- v2.0.2
- v2.0.1
- 2.0.0
- 1.0.4
- 1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
This package is auto-updated.
Last update: 2024-12-10 21:01:28 UTC
README
Installation
Requirements
- PHP 5 (≥ 5.6.40)
- Valid ICS (
.ics
,.ical
,.ifb
) file - IANA, Unicode CLDR or Windows Time Zones
Setup
- Install Composer
- Add the following dependency to
composer.json
- ⚠️ Note with Composer the owner is
johngrogg
and notu01jmg3
- ⚠️ Note with Composer the owner is
- To access the latest stable branch (
v3
) use the following-
To access new features you can require
dev-master
{ "require": { "johngrogg/ics-parser": "^3" } }
-
- Add the following dependency to
Running tests
composer test
How to use
How to instantiate the Parser
- Using the example script as a guide, refer to this code
What will the parser return?
-
Each key/value pair from the iCal file will be parsed creating an associative array for both the calendar and every event it contains.
-
Also injected will be content under
dtstart_tz
anddtend_tz
for accessing start and end dates with time zone data applied. -
Where possible
DateTime
objects are used and returned.- ℹ️ Note the parser is limited to relative date formats which can inhibit how complex recurrence rule parts are processed (e.g.
BYDAY
combined withBYSETPOS
)
// Dump the whole calendar var_dump($ical->cal); // Dump every event var_dump($ical->events());
- ℹ️ Note the parser is limited to relative date formats which can inhibit how complex recurrence rule parts are processed (e.g.
-
Also included are special
{property}_array
arrays which further resolve the contents of a key/value pair.// Dump a parsed event's start date var_dump($event->dtstart_array); // array (size=4) // 0 => // array (size=1) // 'TZID' => string 'America/Detroit' (length=15) // 1 => string '20160409T090000' (length=15) // 2 => int 1460192400 // 3 => string 'TZID=America/Detroit:20160409T090000' (length=36)
Are you using Outlook?
Outlook has a quirk where it requires the User Agent string to be set in your request headers.
We have done this for you by injecting a default User Agent string, if one has not been specified.
If you wish to provide your own User agent string you can do so by using the httpUserAgent
argument when creating your ICal object.
$ical = new ICal($url, array('httpUserAgent' => 'A Different User Agent'));
When Parsing an iCal Feed
Parsing iCal/iCalendar/ICS resources can pose several challenges. One challenge is that the specification is a moving target; the original RFC has only been updated four times in ten years. The other challenge is that vendors were both liberal (read: creative) in interpreting the specification and productive implementing proprietary extensions.
However, what impedes efficient parsing most directly are recurrence rules for events. This library parses the original
calendar into an easy to work with memory model. This requires that each recurring event is expanded or exploded. Hence,
a single event that occurs daily will generate a new event instance for each day as this parser processes the
calendar ($defaultSpan
limits this). To get an idea how this is done take a look at the
call graph.
As a consequence the entire calendar is parsed line-by-line, and thus loaded into memory, first. As you can imagine large calendars tend to get huge when exploded i.e. with all their recurrence rules evaluated. This is exacerbated when old calendars do not remove past events as they get fatter and fatter every year.
This limitation is particularly painful if you only need a window into the original calendar. It seems wasteful to parse
the entire fully exploded calendar into memory if you later are going to call the
eventsFromInterval()
or eventsFromRange()
on it.
In late 2018 #190 added the option to drop all events outside a given range very early in the parsing process at the cost of some precision (time zone calculations are not calculated at that point). This massively reduces the total time for parsing a calendar. The same goes for memory consumption. The precondition is that you know upfront that you don't care about events outside a given range.
Let's say you are only interested in events from yesterday, today and tomorrow. To compensate for the fact that the
tricky time zone transformations and calculations have not been executed yet by the time the parser has to decide whether
to keep or drop an event you can set it to filter for +-2d instead of +-1d. Once it is done you would then call
eventsFromRange()
with +-1d to get precisely the events in the window you are interested in. That is what the variables
$filterDaysBefore
and $filterDaysAfter
are for.
In Q1 2019 #213 further improved the performance by immediately
dropping non-recurring events once parsed if they are outside that fuzzy window. This greatly reduces the maximum
memory consumption for large calendars. PHP by default does not allocate more than 128MB heap and would otherwise crash
with Fatal error: Allowed memory size of 134217728 bytes exhausted
. It goes without saying that recurring events first
need to be evaluated before non-fitting events can be dropped.
API
ICal
API
Variables
Methods
Constants
Event
API (extends ICal
API)
Methods
Constants
Credits
- Jonathan Goode (programming, bug fixing, codebase enhancement, coding standard adoption)
- s0600204 (major enhancements to RRULE support, many bug fixes and other contributions)