Installation:
composer require aldaflux/ical-bundle
Ensure your composer.json requires php: "^8.0" and symfony/symfony: "^7.1".
Configuration:
Add to config/packages/aldaflux_ical.yaml (Symfony 6+):
aldaflux_ical:
default_timezone: "America/New_York" # Adjust to your timezone
default_prodid: "-//YourApp//YourCalendar//EN"
First Use Case:
Generate a simple .ics file for a single event in a controller:
use Aldaflux\IcalBundle\Factory\Factory;
use Symfony\Component\HttpFoundation\Response;
public function generateIcs(Factory $icalFactory): Response
{
$calendar = $icalFactory->createCalendar();
$event = $icalFactory->createCalendarEvent()
->setStart(new \DateTime('2023-12-25 10:00'))
->setEnd(new \DateTime('2023-12-25 12:00'))
->setSummary('Holiday Party')
->setUid('holiday-2023');
$calendar->addEvent($event);
return new Aldaflux\IcalBundle\Response\CalendarResponse($calendar);
}
Event Creation: Chain methods for clarity:
$event = $icalFactory->createCalendarEvent()
->setStart($startDateTime)
->setEnd($endDateTime)
->setSummary($title)
->setDescription($details)
->setLocation($venue)
->setUid(uniqid()); // Unique identifier
Attendees & Organizers: Use factories for consistency:
$attendee = $icalFactory->createAttendee()
->setValue('user@example.com')
->setName('John Doe')
->setRole('REQ-PARTICIPANT'); // Optional: CHAIR, OPT-PARTICIPANT, etc.
$event->addAttendee($attendee);
$organizer = $icalFactory->createOrganizer()
->setValue('admin@example.com')
->setName('Event Organizer')
->setLanguage('en');
$event->setOrganizer($organizer);
Recurring Events:
Leverage the underlying jsvrcek/ics library:
$event->setStart(new \DateTime('2023-10-01'))
->setEnd(new \DateTime('2023-10-02'))
->setSummary('Weekly Meeting')
->setRrule('FREQ=WEEKLY;UNTIL=20231231T235959Z'); // RFC 5545 rule
Response Handling:
Return the CalendarResponse for automatic .ics headers:
return new CalendarResponse($calendar, Response::HTTP_OK, [
'Content-Disposition' => 'attachment; filename="calendar.ics"',
]);
Entity Mapping: Map Doctrine entities to events in a service:
public function entityToEvent(Meeting $meeting): CalendarEvent
{
return $this->icalFactory->createCalendarEvent()
->setStart($meeting->getStart())
->setEnd($meeting->getEnd())
->setSummary($meeting->getTitle())
->setDescription($meeting->getNotes())
->setUid($meeting->getId());
}
Bulk Generation: Generate multiple events from a collection:
$calendar = $icalFactory->createCalendar();
$events = $this->eventRepository->findAll();
foreach ($events as $event) {
$calendar->addEvent($this->entityToEvent($event));
}
Reading .ics Files:
Use the Parser service (if extended in future versions):
// Hypothetical usage (check for updates)
$parser = $this->container->get('aldaflux_ical.parser');
$icalData = $parser->parse(file_get_contents('calendar.ics'));
API Endpoints:
GET /events/export → Return CalendarResponse.POST /events/import → Parse uploaded .ics file (if supported).Timezone Handling:
default_timezone in config to avoid ambiguous timestamps.DateTimeImmutable for immutable operations:
$event->setStart(new \DateTimeImmutable('2023-12-25 10:00', new \DateTimeZone('UTC')));
UID Uniqueness:
$event->setUid(Uuid::v4()->toString());
Rrule Complexity:
$event->setRrule('FREQ=MONTHLY;BYMONTHDAY=1');
Attendee Roles:
NEEDS-ACTION. Explicitly set if needed:
$attendee->setRole('CHAIR'); // For organizers
Bundle Maturity:
Factory class if missing features.Raw Output:
Inspect the generated .ics content:
$icsContent = $calendar->render();
file_put_contents('debug.ics', $icsContent);
Validation: Use icalendar.org validator to check syntax.
Logging: Log events before rendering:
$this->logger->debug('Generated event:', [
'uid' => $event->getUid(),
'summary' => $event->getSummary(),
'start' => $event->getStart()->format('Y-m-d H:i:s'),
]);
Custom Components:
Extend the Factory to add custom components (e.g., Todo):
// In a custom service
public function createTodo(): Todo
{
return new Todo($this->icalFactory->getIcal());
}
Event Listeners: Hook into event creation/updates to sync with external calendars:
// config/services.yaml
Aldaflux\IcalBundle\EventListener\SyncListener:
tags:
- { name: kernel.event_listener, event: your.event, method: onEventCreated }
Configuration Overrides: Override defaults per environment:
# config/packages/dev/aldaflux_ical.yaml
aldaflux_ical:
default_timezone: "%env(ICAL_TIMEZONE)%"
Parser Integration:
If reading .ics is needed, extend the bundle or use jsvrcek/ics directly:
use Jsvrcek\Ical\Calendar;
$calendar = Calendar::createFromString(file_get_contents('file.ics'));
How can I help you explore Laravel packages today?