Install the Bundle
composer require axi/mycalendar-bundle
For Symfony Flex projects, this auto-enables the bundle. For non-Flex projects, manually add to config/bundles.php:
Axi\MyCalendarBundle\AxiMyCalendarBundle::class => ['all' => true],
First Use Case: Fetching Events
Inject CalendarService into a controller and fetch events for a date:
use Axi\MyCalendar\Service\CalendarService;
use Symfony\Component\HttpFoundation\Response;
#[Route('/events', name: 'events')]
public function events(CalendarService $calendarService): Response {
$events = $calendarService->getEvents(new \DateTimeImmutable('1984-01-12'));
return $this->json($events);
}
Key Files to Review
config/packages/axi_my_calendar.yaml (default config)src/Controller/ (example usage)src/Recipe/ (custom recipes, if extending)Dependency Injection
Always inject CalendarService into controllers/services needing calendar logic. Avoid instantiating directly.
Date-Based Event Fetching
// Fetch events for a specific date
$events = $calendarService->getEvents($dateTimeImmutable);
// Fetch events from a starting date (e.g., birthdays from birthdate onward)
$events = $calendarService->getEventsFromDate($birthdate);
Recipe Customization
NowRecipe) in your app’s src/Recipe/ directory.RecipeInterface or extend AbstractRecipe:
class CustomRecipe extends AbstractRecipe {
public function getEvents(\DateTimeImmutable $basedOn): array {
return [new Event(new \DateTimeImmutable(), 'Custom Event')];
}
}
config/packages/axi_my_calendar.yaml:
axi_my_calendar:
only_recipes:
- App\CustomRecipe
except_recipes:
- Axi\MyCalendar\Recipe\PlanetsRevolutionsRecipe
Renderer Integration Use renderers to format events (e.g., JSON, iCal). Configure allowed renderers per recipe:
recipe_rendering:
exclude:
Axi\MyCalendar\Recipe\NowRecipe:
- Axi\MyCalendar\Renderer\JsonRenderer
Translation Support
Use TranslatableMessage for localized event summaries:
$event->setSummary(new TranslatableMessage('birthday|Birthday', ['%name%' => 'John']));
Recipe Autoloading
src/Recipe/). Place them elsewhere, and they won’t register automatically.composer.json includes the directory in autoload-dev or autoload.DateTimeImmutable Requirement
DateTimeImmutable. Passing DateTime will throw errors.$date = new \DateTime('now'); // ❌ Avoid
$date = new \DateTimeImmutable('now'); // ✅ Use
Configuration Overrides
config/packages/axi_my_calendar.yaml merges with defaults. Use only_recipes and except_recipes carefully to avoid unintended exclusions.php bin/console debug:config axi_my_calendar to verify loaded recipes.Renderer Conflicts
JsonRenderer) may break expected API responses if your app relies on it.only: to whitelist renderers instead of exclude: for stricter control.Performance with Many Recipes
RecipeInterface::supports(\DateTimeImmutable $date) to skip irrelevant recipes.CalendarService results if events are static (e.g., birthdays).List Loaded Recipes Dump the active recipes to verify configuration:
$recipes = $calendarService->getRecipes();
dump(array_map(fn($r) => get_class($r), $recipes));
Check Renderer Availability Inspect available renderers for a recipe:
$renderer = $calendarService->getRenderer('json');
if (!$renderer) {
throw new \RuntimeException('Renderer not configured!');
}
Event Debugging
Use dump() to inspect event properties:
foreach ($events as $event) {
dump([
'date' => $event->getDate(),
'summary' => $event->getSummary(),
'source' => $event->getSourceRecipe(),
]);
}
Custom Renderers
Extend Axi\MyCalendar\Renderer\AbstractRenderer to add new output formats (e.g., HTML tables, GraphQL).
Recipe Decorators
Decorate CalendarService to modify event logic without forking:
// src/Service/DecoratedCalendarService.php
class DecoratedCalendarService implements CalendarServiceInterface {
private $decorated;
public function __construct(CalendarService $decorated) {
$this->decorated = $decorated;
}
public function getEvents(\DateTimeImmutable $date): array {
$events = $this->decorated->getEvents($date);
// Add custom logic (e.g., filter events)
return array_filter($events, fn($e) => strpos($e->getSummary(), 'important') !== false);
}
}
Register as a service with decorates: Axi\MyCalendar\Service\CalendarService.
Event Modifiers
Use the Event object’s setters to alter data post-generation:
$events = $calendarService->getEvents($date);
foreach ($events as $event) {
$event->setDescription('Custom description');
$event->addCustomField('priority', 'high');
}
How can I help you explore Laravel packages today?