fungio/outlook-calendar-bundle
Symfony bundle that connects PHP applications to Microsoft Outlook calendars via the Microsoft Graph API. Manage events, sync schedules, and authenticate users with OAuth 2.0 for clean, reliable access to Office 365 calendar data.
Architecture fit — poor, and partly a category error.
The brief frames this as a "Laravel/PHP package," but fungio/outlook-calendar-bundle is a Symfony bundle, not a Laravel package. It ships a Bundle class, a DependencyInjection/*Extension, and YAML service definitions intended to be registered in a Symfony kernel's AppKernel. Laravel's service container has no concept of bundles or container extensions, so there is no supported way to install this and have it "just work" — you would be importing a foreign framework's bootstrapping model into a Laravel app. That is the single largest architectural objection and it is not fixable by configuration.
What is reusable is the underlying domain logic: an HTTP client (typically Guzzle) that authenticates against Microsoft's Outlook REST endpoints (outlook.office.com/api/v2.0/me/events and friends) and maps JSON into event entities. That logic is thin and portable; the bundle scaffolding around it is not.
Integration feasibility — feasible only as a strip-mine, not as a dependency.
symfony/framework-bundle: ^3.0, symfony/dependency-injection: ^3.0, and probably hwi/oauth-bundle: ^1.0. Modern Laravel (10/11/12) pins Symfony components at ^6.4/^7.x. Those constraints are mutually unsatisfiable, so the package cannot coexist in the same vendor/ tree without --ignore-platform-reqs hackery that defers the breakage to runtime.declare(strict_types=1). Dropping it into a PHP 8.2+ Laravel app invites deprecation noise at minimum and hard failures where the code touches removed behaviours.Technical risk — high, concentrated in three places.
Key questions to resolve before committing engineering time.
Calendars.ReadWrite application permissions? These drive entirely different library choices.Stack fit — do not integrate this package; integrate its problem domain.
The correct target is the official microsoft/microsoft-graph PHP SDK (or a thin typed Guzzle client over Graph's /me/events and /users/{id}/calendar/events), wrapped in:
ServiceProvider registering a singleton client bound to a config block (tenant_id, client_id, client_secret, redirect_uri, scopes).Facade for ergonomic call sites.CalendarProvider) with the Graph implementation behind them, so a second provider (Google, ICS) is a later swap rather than a rewrite.oauth_tokens table with an encrypted refresh_token column — the bundle's session/token handling is not something we want to inherit.Migration path — use the bundle as a specification, not a dependency.
composer require it.@odata.nextLink, delta queries for sync, error taxonomy.Compatibility — the honest answer is "none, by construction."
There is no version of Laravel for which this bundle's dependency graph resolves cleanly. If a stakeholder insists on trying, budget a day for a composer require attempt purely to produce the failure output as evidence, then proceed with the port. The port itself is cheap: the portable logic is a few hundred lines of HTTP-and-mapping code, not a subsystem.
Sequencing
| Phase | Work | Exit criteria |
|---|---|---|
| 0 | Source review of the bundle | Endpoint inventory + field map documented |
| 1 | API/permission decision | Written decision: Graph, delegated vs app-only, scopes approved by tenant admin |
| 2 | Adapter build behind contract | Read-only event fetch working in staging tenant |
| 3 | Token lifecycle + queue/backoff | Refresh survives a forced expiry; 429 handled |
| 4 | Sync strategy | Polling or delta subscriptions selected and implemented |
| 5 | Production cutover | Feature flag off legacy path, monitoring live |
The critical dependency is phase 1 — tenant admin consent is an organisational gate that routinely costs a week or more and cannot be compressed by engineering effort. Start it in week one.
Maintenance — a fork, not a dependency. Because the package cannot be installed, there is nothing to "maintain" in the ordinary sense. What we own is the adapter we wrote, which is a deliberate upside: it is modern PHP, typed, tested, and readable by the current team. The downside is that the reference implementation will never receive upstream fixes, so we should treat the original repository as frozen documentation and archive a copy of the source at the commit we reviewed, with a note in the repo explaining why.
Support — self-support only. 5 stars and 0 dependents means no community to escalate to, no Stack Overflow corpus, and no author responsiveness to assume. Any question about behaviour is answered by reading the code. Budget for that: it is a few hours, not a few days, given the codebase size, but it should be scheduled rather than discovered mid-sprint.
Scaling — governed by Microsoft's throttling, not ours.
Graph and the legacy Outlook endpoints enforce per-app and per-user rate limits and return 429 with Retry-After. Calendar sync is bursty by nature (a nightly reconciliation across all users, or a backfill after an outage). Design implications:
Failure modes to instrument explicitly.
Ramp-up — low for engineers, medium for the organisation.
Code ramp-up is genuinely small: the portable surface is narrow and a mid-level Laravel engineer can own it inside a sprint. The real ramp-up cost is domain and organisational — Azure AD app registration, permission scopes, admin consent workflow, and tenant policy. That knowledge lives with whoever owns the identity relationship, often outside the engineering team, and should be treated as a stakeholder dependency with its own timeline.
Recommendation. Reject fungio/outlook-calendar-bundle as a dependency on technical grounds (framework mismatch, unsatisfiable constraints, EOL platform, abandoned status) — this is a defensible, evidence-backed "no." Approve a time-boxed spike to harvest its domain knowledge, then build a first-party Graph-backed adapter behind a provider contract. Estimated engineering cost: 4–6 weeks including hardening, with the largest schedule risk sitting in tenant admin consent rather than in code.
How can I help you explore Laravel packages today?