atoolo/events-calendar-bundle
Install the Bundle:
composer require sitepark/atoolo-events-calendar-bundle
Ensure your config/bundles.php includes:
Sitepark\AtooloEventsCalendarBundle\AtooloEventsCalendarBundle::class => ['all' => true],
Configure Database & CMS:
config/packages/atoolo_events_calendar.yaml:
atoolo_events_calendar:
rce:
enabled: true
blacklisted_dates: ['2024-12-25'] # Example: Skip holidays
ical:
base_url: '%env(ICAL_BASE_URL)%'
First Use Case:
use Sitepark\AtooloEventsCalendarBundle\Service\EventService;
public function showEvents(EventService $eventService)
{
$events = $eventService->findBy(['active' => true], ['startDate' => 'ASC']);
return view('events.index', compact('events'));
}
{% for event in events %}
<div class="event">
<h3>{{ event.title }}</h3>
<p>{{ event.startDate|date('F j, Y') }} - {{ event.endDate|date('F j, Y') }}</p>
</div>
{% endfor %}
Key Documentation:
EventService for CRUD operations.SchedulingFactory for date/time handling./api/ical/{eventId}).Create/Update Events:
Use the EventManager service to handle event lifecycle:
$event = $eventManager->create([
'title' => 'Tech Conference',
'startDate' => '2024-10-15T09:00:00',
'endDate' => '2024-10-17T18:00:00',
'categories' => ['tech', 'conference'],
'venue' => 'Online',
]);
$eventManager->save($event);
SchedulingFactory to parse raw date strings (e.g., "2024-10-15 09:00").Bulk Operations:
Leverage the RceIndexer for external event imports (e.g., from CSV or third-party APIs):
$indexer = $container->get('atoolo_events_calendar.rce_indexer');
$indexer->indexEvents($externalEventsData);
$events = $eventService->findByDateRange(
new \DateTime('2024-01-01'),
new \DateTime('2024-12-31')
);
EventRepository:
$events = $eventRepository->findBy(['categories' => 'tech']);
query {
eventsTeaser(filter: {categories: ["tech"]}) {
title
startDate
}
}
$icalContent = $icalService->generateForEvent($eventId, $occurrence = null);
return response($icalContent, 200, [
'Content-Type' => 'text/calendar',
'Content-Disposition' => 'attachment; filename="event.ics"',
]);
/api/ical/search/{query} for dynamic iCal generation (e.g., filter by keyword).$scheduling = $schedulingFactory->createRecurring(
'2024-01-01T10:00:00',
'2024-12-31T11:00:00',
'P1W' // Weekly recurrence
);
$event->setScheduling($scheduling);
endDate is explicitly set for recurring events to avoid infinite loops.config/packages/atoolo_events_calendar.yaml:
rce:
theme_anchor: 'events' # Customize theme anchor for RCE
simple_category_map: true # Simplify category handling
RceIndexer to sync events with the CMS:
$indexer->index(); // Runs on schedule or manually
Service Container:
Bind the bundle’s services to Laravel’s container in AppServiceProvider:
public function register()
{
$this->app->bind('atoolo_events_calendar.event_service', function ($app) {
return new \Sitepark\AtooloEventsCalendarBundle\Service\EventService(
$app->make('atoolo_events_calendar.event_repository')
);
});
}
Routing: Extend Laravel’s routes to include iCal endpoints:
Route::get('/ical/{eventId}', [IcalController::class, 'generate'])->name('events.ical');
Blade Templates:
Share Twig templates with Blade by creating a custom view resolver or using twig directives in Blade:
// In AppServiceProvider
Blade::directive('event', function ($expression) {
return "<?php echo \$this->renderEvent($expression); ?>";
});
Event Listeners: Hook into Laravel’s event system for post-save actions:
Event::listen('eloquent.saved: App\Models\Event', function ($event) {
// Trigger RCE indexing or send notifications
$this->app->get('atoolo_events_calendar.rce_indexer')->index();
});
$events = Cache::remember('events_active', now()->addHours(1), function () {
return $eventService->findBy(['active' => true]);
});
startDate, endDate, and categories are indexed in your events table.Event entity or use traits:
use Sitepark\AtooloEventsCalendarBundle\Entity\Event as BaseEvent;
class CustomEvent extends BaseEvent
{
#[ORM\Column(type: 'json')]
private array $customFields = [];
}
use Illuminate\Validation\Rule;
$validator = Validator::make($data, [
'startDate' => ['required', 'date', Rule::unique('events')->ignore($event)],
'endDate' => ['required', 'date', 'after:startDate'],
]);
Date Handling Quirks:
gmdate for scheduling. Ensure your config/app.php timezone matches expectations:
'timezone' => 'UTC', // Recommended for consistency
endDate is missing, the bundle may default to startDate. Explicitly set endDate to null for single-day events:
$scheduling->setEndDate(null);
RCE Indexing:
blacklisted_dates config:
rce:
blacklisted_dates: ['2024-12-25', '2024-12-26']
active flag is correctly set.iCal Generation:
$ical
How can I help you explore Laravel packages today?