Installation
composer require jsvrcek/ics
Add the namespace to your composer.json autoload or use it directly in your code.
First Use Case: Create a Simple Event
use Jsvrcek\ICS\Model\Calendar;
use Jsvrcek\ICS\Model\CalendarEvent;
$event = new CalendarEvent();
$event->setStart(new \DateTime())
->setSummary('Team Meeting')
->setUid('meeting-2023-10-01');
$calendar = new Calendar();
$calendar->setProdId('-//MyApp//EN')
->addEvent($event);
$stream = new \Jsvrcek\ICS\CalendarStream($calendar);
header('Content-Type: text/calendar');
header('Content-Disposition: attachment; filename="meeting.ics"');
echo $stream->render();
Where to Look First
src/Jsvrcek/ICS/Model/: Core models like Calendar, CalendarEvent, Attendee, and Organizer.src/Jsvrcek/ICS/Utility/Formatter.php: For handling date/time formatting and localization.src/Jsvrcek/ICS/CalendarStream.php and CalendarExport.php: For exporting calendars to ICS format.Event Creation Chain methods for fluent configuration:
$event = (new CalendarEvent())
->setStart(new \DateTime('2023-12-25 14:00'))
->setEnd(new \DateTime('2023-12-25 15:30'))
->setSummary('Holiday Party')
->setDescription('Celebrate with the team!')
->setLocation('Office - 3rd Floor')
->setUid('holiday-party-2023');
Relationships (Attendees/Organizers)
Use Attendee and Organizer with a Formatter for proper encoding:
$attendee = new \Jsvrcek\ICS\Model\Relationship\Attendee(new \Jsvrcek\ICS\Utility\Formatter());
$attendee->setValue('john.doe@example.com')
->setName('John Doe')
->setRole('REQ-PARTICIPANT'); // Optional: PARTICIPANT, OPT-PARTICIPANT, etc.
$event->addAttendee($attendee);
Recurring Events
Use RecurrenceRule for periodic events:
use Jsvrcek\ICS\Model\RecurrenceRule;
$recurrence = new RecurrenceRule();
$recurrence->setFrequency('WEEKLY')
->setInterval(2)
->setByDay(['MO', 'WE', 'FR']); // Days of the week
$event->setRecurrence($recurrence);
Calendar Export Stream directly to a response or save to a file:
$calendarStream = new \Jsvrcek\ICS\CalendarStream($calendar);
$export = new \Jsvrcek\ICS\CalendarExport($calendarStream);
// Stream to browser
header('Content-Type: text/calendar');
header('Content-Disposition: attachment; filename="calendar.ics"');
echo $export->render();
// Or save to file
file_put_contents('calendar.ics', $export->render());
Localization
Pass a Formatter with locale settings:
$formatter = new \Jsvrcek\ICS\Utility\Formatter('de_DE');
$event->setStart(new \DateTime(), $formatter);
Laravel Controllers: Use the package in controllers to generate ICS files dynamically:
public function exportCalendar(Request $request) {
$calendar = $this->buildCalendarFromRequest($request);
$export = new CalendarExport(new CalendarStream($calendar));
return response($export->render())
->header('Content-Type', 'text/calendar');
}
Queued Jobs: Generate ICS files asynchronously for bulk operations (e.g., sending reminders):
class SendCalendarReminder implements ShouldQueue {
public function handle() {
$calendar = $this->generateCalendar();
$ics = (new CalendarExport(new CalendarStream($calendar)))->render();
Mail::raw($ics, function ($message) {
$message->to('user@example.com')
->subject('Your Calendar Invitation')
->attachData($ics, 'calendar.ics', ['mime' => 'text/calendar']);
});
}
}
Validation: Validate UIDs and dates before creating events to avoid duplicates or conflicts:
$uid = Str::uuid()->toString(); // Ensure unique UIDs
$event->setUid($uid);
Testing:
Mock CalendarStream and CalendarExport for unit tests:
$mockStream = Mockery::mock(\Jsvrcek\ICS\CalendarStream::class);
$mockStream->shouldReceive('render')->andReturn('ICS_CONTENT');
$export = new CalendarExport($mockStream);
$this->assertEquals('ICS_CONTENT', $export->render());
Character Encoding
Formatter is initialized with the correct locale:
$formatter = new \Jsvrcek\ICS\Utility\Formatter('en_US.UTF-8');
Formatter when setting values:
$attendee->setName('José García', $formatter); // Pass formatter explicitly
Timezones
DateTime objects. Ensure they are timezone-aware:
$event->setStart(new \DateTime('2023-10-01 10:00', new \DateTimeZone('America/New_York')));
Recurrence Rules
RecurrenceRule class supports basic rules (e.g., FREQ=WEEKLY), but complex rules (e.g., EXDATE, RDATE) may require manual construction via the setRRule() method.UID Uniqueness
$event->setUid('event-' . now()->timestamp . '-' . Str::random(4));
Attendee Roles
PARTICIPANT. Explicitly set roles like CHAIR, REQ-PARTICIPANT, or OPT-PARTICIPANT if needed:
$attendee->setRole('REQ-PARTICIPANT');
Large Calendars
Invalid ICS Output
BEGIN:VCALENDAR/END:VCALENDAR or BEGIN:VEVENT/END:VEVENT lines.Logging
Formatter to log issues:
$formatter = new \Jsvrcek\ICS\Utility\Formatter('en_US', true); // Enable debug
Deprecated Methods
CalendarEvent or Calendar class to add custom properties (e.g., X-PROPERTY):
class CustomCalendarEvent extends \Jsvrcek\ICS\Model\CalendarEvent {
public function setCustomProperty($name, $value
How can I help you explore Laravel packages today?