chetansingh / calendar-manager
Calendar management package for Google Calendar and Microsoft Outlook calendars.
Requires
- php: ^8.1
- google/apiclient: ^2.19
- guzzlehttp/guzzle: ^7.10
- microsoft/microsoft-graph: ^3.0
- nesbot/carbon: ^3.11
This package is not auto-updated.
Last update: 2026-04-29 13:25:12 UTC
README
Calendar Manager is a Composer package for working with Google Calendar and Microsoft Outlook calendars through one small PHP API.
Features
- Google Calendar OAuth URL and callback token exchange
- Google access token refresh helper
- Google Calendar event create, update, delete, get, list, reschedule, cancel
- Microsoft Graph Outlook event create, update, delete, get, list, reschedule, cancel
- Simple
quickCreateevent helper for Google and Outlook - Google Meet and Microsoft Teams online meeting helpers
- Search, date-range listing, and normalized event arrays
- Availability checks for Google free/busy and Microsoft Graph getSchedule
- Per-driver configuration with sensible defaults
Installation
composer require chetansingh/calendar-manager
Usage
<?php require __DIR__ . '/vendor/autoload.php'; use Chetansingh\CalendarManager\Services\CalendarManager; $calendar = new CalendarManager([ 'drivers' => [ 'google' => [ 'client_id' => 'google-client-id', 'client_secret' => 'google-client-secret', 'redirect_uri' => 'https://your-app.test/google/callback', 'access_token' => $googleAccessToken, 'calendar_id' => 'primary', ], 'outlook' => [ 'access_token' => $microsoftGraphAccessToken, 'user_email' => 'person@example.com', ], ], ]); echo $calendar->driver('google')->getAuthUrl();
The manager also accepts flat Google configuration for simple apps:
$calendar = new CalendarManager([ 'client_id' => 'google-client-id', 'client_secret' => 'google-client-secret', 'redirect_uri' => 'https://your-app.test/google/callback', ]);
Google OAuth Flow
First send the user to Google's consent screen:
<?php require __DIR__ . '/vendor/autoload.php'; use Chetansingh\CalendarManager\Services\CalendarManager; $calendar = new CalendarManager([ 'client_id' => 'google-client-id', 'client_secret' => 'google-client-secret', 'redirect_uri' => 'https://your-app.test/google-callback.php', ]); header('Location: ' . $calendar->driver('google')->getAuthUrl()); exit;
Then handle the callback URL configured in Google Cloud:
<?php session_start(); require __DIR__ . '/vendor/autoload.php'; use Chetansingh\CalendarManager\Services\CalendarManager; $calendar = new CalendarManager([ 'client_id' => 'google-client-id', 'client_secret' => 'google-client-secret', 'redirect_uri' => 'https://your-app.test/google-callback.php', ]); if (empty($_GET['code'])) { exit('Google authorization code missing.'); } $token = $calendar->driver('google')->handleCallback($_GET['code']); if (!empty($token['error'])) { exit('Google auth failed: ' . ($token['error_description'] ?? $token['error'])); } // Store this token for the logged-in user. // In production, save it in your database, encrypted if possible. $_SESSION['google_access_token'] = $token; header('Location: /calendar.php'); exit;
For real applications, store the token against your user record. You will need
the access_token for API calls and the refresh_token to get a new access
token when the old one expires. Google usually returns a refresh token only on
the first consent, so do not overwrite an existing stored refresh token with an
empty value.
Use the stored token when calling calendar APIs:
session_start(); $calendar = new CalendarManager([ 'client_id' => 'google-client-id', 'client_secret' => 'google-client-secret', 'redirect_uri' => 'https://your-app.test/google-callback.php', 'access_token' => $_SESSION['google_access_token'], ]); $events = $calendar->driver('google')->listEvents([ 'maxResults' => 10, 'singleEvents' => true, 'orderBy' => 'startTime', 'timeMin' => date('c'), ]);
Refresh an expired Google access token with the stored refresh token:
$newToken = $calendar->driver('google')->refreshAccessToken($storedRefreshToken); // Save the new access token details for the user. // Keep the old refresh token if Google does not return a new one.
Quick Create
$event = $calendar->driver('google')->quickCreate([ 'title' => 'Planning call', 'start' => '2026-05-01 10:00', 'end' => '2026-05-01 10:30', 'timezone' => 'Asia/Kolkata', 'description' => 'Discuss launch tasks', 'attendees' => ['person@example.com'], ]); $outlookEvent = $calendar->driver('outlook')->quickCreate([ 'title' => 'Planning call', 'start' => '2026-05-01 10:00', 'end' => '2026-05-01 10:30', 'timezone' => 'Asia/Kolkata', 'attendees' => ['person@example.com'], ]);
You can still call createEvent() directly with raw Google Calendar or
Microsoft Graph event arrays when you need full provider control.
Online Meeting
$googleMeet = $calendar->driver('google')->createEventWithMeet([ 'title' => 'Demo call', 'start' => '2026-05-01 15:00', 'end' => '2026-05-01 15:30', 'timezone' => 'Asia/Kolkata', ]); $teamsMeeting = $calendar->driver('outlook')->createEventWithMeet([ 'title' => 'Demo call', 'start' => '2026-05-01 15:00', 'end' => '2026-05-01 15:30', 'timezone' => 'Asia/Kolkata', ]);
List and Search
$events = $calendar->driver('google')->listNormalizedEvents([ 'maxResults' => 10, 'singleEvents' => true, 'orderBy' => 'startTime', 'timeMin' => date('c'), ]); $events = $calendar->driver('google')->eventsBetween( '2026-05-01 00:00', '2026-05-31 23:59', ['timezone' => 'Asia/Kolkata'] ); $events = $calendar->driver('google')->searchEvents('planning');
Normalized events return a common array shape:
[
'id' => '...',
'provider' => 'google',
'title' => 'Planning call',
'start' => '2026-05-01T10:00:00+05:30',
'end' => '2026-05-01T10:30:00+05:30',
'meeting_link' => 'https://...',
'raw' => $providerEvent,
]
Check Availability
$busy = $calendar->driver('google')->checkAvailability([ 'timeMin' => '2026-05-01T09:00:00+05:30', 'timeMax' => '2026-05-01T18:00:00+05:30', ]); $schedule = $calendar->driver('outlook')->checkAvailability([ 'schedules' => ['person@example.com'], 'startTime' => [ 'dateTime' => '2026-05-01T09:00:00', 'timeZone' => 'Asia/Kolkata', ], 'endTime' => [ 'dateTime' => '2026-05-01T18:00:00', 'timeZone' => 'Asia/Kolkata', ], ]);
Development
composer install composer check