Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Events Calendar Bundle Laravel Package

atoolo/events-calendar-bundle

Sitepark event calendar bundle for publishing and managing events on websites, with CMS entry, web forms, database imports, and filtered search by category, keyword, and time period.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit — low for a Laravel codebase. Despite the assessment framing, this is not a Laravel/PHP package in the general sense: it is a Symfony bundle (sitepark/atoolo-events-calendar-bundle), and the delivery mechanism is the Symfony full-stack framework. Adoption pulls in symfony/framework-bundle semantics that Illuminate does not provide: bundle classes and DependencyInjection/Extension config trees, compiler passes and tagged services, HTTP kernel event subscribers, Symfony routing/Request objects, and (likely) Twig templates and console commands. Laravel's container is PSR-11 compliant, so some constructor autowiring can be shimmed, but the configuration surface — YAML/PHP extension config, service tagging, bundle boot order — has no native Laravel equivalent. A service-provider wrapper is not a port; it is a compatibility layer with a long tail.

The bundle is not standalone. The release history shows hard coupling to sibling packages in the Atoolo family: atoolo/resource-bundle, atoolo/graphql-search-bundle, ResourceChannelFactory, "RCE" (remote content exchange) indexers. The events calendar behaves as an adapter over Sitepark's resource/content model and search index, not as a self-contained domain library. 1.18.1 reinforces this: one of its four commits is a dependency bump on the Atoolo GraphQL package, i.e. the bundle's release cadence is now partly dictated by a sibling package's cadence. Consumed without that stack, the meaningful surface area collapses to a much smaller subset. Any integration estimate must be based on that subset, not the README feature list.

What is genuinely reusable. The domain layer is the valuable asset and is comparatively framework-light: Scheduling, SchedulingBuilder, SchedulingManager, SchedulingResolver, EventDate→Scheduling DTOs, the iCal rendering/serialization path, and the GraphQL event-teaser shape. These can in principle be extracted behind a thin port (a CalendarService interface with an iCal writer and a scheduling resolver) and re-hosted inside a Laravel service provider. That is a fork-and-maintain decision, not an install decision, and it should be priced accordingly. Note that the 1.18.1 fix lands in the query/expansion layer rather than the domain core — a mild positive for the extraction path, since the extracted subset (scheduling + iCal) is untouched by this release and continues to look separable.

Technical risk — elevated, and mostly non-technical in origin.

  • Zero community validation. 0 stars, 0 dependents. No third-party production usage to point at, no Stack Overflow corpus, no blog posts. Every question routes to the vendor.
  • Bus factor. Commits are attributable to a small set of named Sitepark staff (1.18.1 is a single author). The project is a vendor product artifact published openly, not a community project. Continuity is tied to Sitepark's commercial roadmap.
  • Version churn in core correctness, now including patches. Renames landed in minor releases (EventDate→Scheduling, symbolicImage→symbolicAsset) and repeated fixes hit the same area — date/time semantics (gmdate vs date, endDate not falling back to beginDate, "set endDate null if endDate & endTime are unset", DST-adjacent scheduling). 1.18.1 extends the pattern to patch releases: "differentiate between expand and search by date" is a behavioural change to query semantics shipped as a patch. Consumers who had adapted to the conflated behaviour will see different result sets after a routine composer update. Repeated patching of small, critical modules at 1.6–1.7 and again at 1.18.1 signals the model is still settling well past 1.0. Timezone, recurrence, and date-window semantics are the highest-severity failure class in any calendar, and they are also the hardest to detect without exhaustive test data.
  • Toolchain is not settled either. "try with phpstan 2.3" and a phars.xml edit, with a typo in the commit subject ("upate"), indicate static-analysis configuration is still being experimented with rather than fixed. That is not a product risk by itself, but it weakens any inference you might draw from "PHPStan at level 9" as a stable quality guarantee — the analysis baseline itself moves between releases.
  • Release provenance to verify. The metadata on the prior release listed a date in the future; do not accept version strings or dates at face value — confirm tags, signed commits, Packagist provenance, and CI status on the exact commit you intend to depend on (here, dba438a).
  • License risk is low. MIT is clean for commercial use and modification. That is the single strongest data point in the package's favour and it materially de-risks the extract-and-fork path.

Key questions to resolve before committing engineering time

  1. Does the bundle boot without atoolo/resource-bundle and atoolo/graphql-search-bundle, or are they hard requires? What is the real transitive dependency graph and its Symfony version constraints? The 1.18.1 graphQL dependency bump makes this more pressing, not less.
  2. What does "differentiate between expand and search by date" actually change? Which request parameters or GraphQL inputs are affected, is the new behaviour a fix or a contract change, and would a consumer pinned to 1.18.0 see different results for identical queries?
  3. Which search/index backend does it assume (Solr/Elasticsearch/other), and is that infrastructure already in our estate?
  4. Is the "RCE" import path mandatory for our use case, or can events be authored purely through the bundle's own model?
  5. What is Sitepark's stated support policy for the 1.x line, and will they accept external PRs / offer a support contract?
  6. Are the scheduling and iCal components separable without forking? Is there an interface boundary we can implement against?
  7. What is the actual test posture? PHPStan and Codecov badges are promising signals, but E2E tests live in a separate repo (atoolo-e2e-test), the analysis config is still being tuned, and the search-vs-date behaviour change in 1.18.1 is exactly the class of regression a contract test should have caught upstream. Validate this repo's own suite.
  8. Has anyone run this outside an Atoolo/Sitepark deployment? If not, we are the first — price that as R&D, not integration.

Integration Approach

Stack fit. PHP 8.2–8.4 is well aligned with modern Laravel, and PHP 8.1 is nominally supported but explicitly marked as no longer auto-checked — treat 8.1 as unsupported. The binding constraint is the Symfony component version range: Laravel 10/11 ship Symfony 6.x/7.x components, and installing symfony/framework-bundle alongside illuminate/* in the same application is technically possible but operationally unhealthy — competing kernels, competing routing, competing container compilation, and two config caches to invalidate. Do not co-host the bundle inside the Laravel app. Every viable path separates them.

Three viable paths, in order of preference for a Laravel shop:

  1. Sidecar service (recommended if you need this capability soon). Deploy the bundle as a minimal standalone Symfony application — its own container, its own deploy unit — exposing the surfaces it already provides: the iCal API (/api/ical/...), the GraphQL search/teaser, and read endpoints. Laravel consumes it over HTTP with a typed client, caches responses, and owns presentation, auth, and business rules. Benefits: no framework conflict, upgrade isolation, the vendor's own stack is exercised as designed, and a future replacement is a swap of one HTTP client. Costs: two runtimes, two deploy pipelines, an extra network hop, and shared-nothing caching to design.

  2. Domain extraction (recommended if the calendar is core to the product). Fork under MIT, lift Scheduling/SchedulingBuilder/SchedulingManager/SchedulingResolver and the iCal serializer into an internal package with a framework-agnostic facade; re-host in a Laravel service provider; implement persistence with Eloquent. This gets you the genuinely valuable 20% and discards the Atoolo-specific 80%. Costs: you own the code, the bugs, and the timezone test suite forever — budget for it explicitly.

  3. Specification only (recommended if the calendar is a differentiator). Treat the README, release notes, and GraphQL/iCal contracts as a requirements document and build natively. Fastest to a clean domain model for a Laravel team; slowest to first demo. Note that recurring-event semantics, DST handling, and RFC 5545 conformance are the parts people underestimate — the release history here, 1.18.1 included, is a useful map of exactly which edge cases bite.

Migration path. Whichever path you pick, the sequencing is the same: pin an exact tag after verifying it, wrap every vendor touchpoint behind an internal interface (CalendarGateway), and write contract tests against the external surface — iCal output validated against RFC 5545, scheduling resolved against a fixture set covering DST boundaries, all-day events, missing endTime, and multi-day spans, plus result-set fixtures for date-filtered search versus expanded occurrences. Those tests are the asset that makes any future re-platform cheap.

Compatibility notes. Assume multi-instance support (added in 1.1.0) means per-tenant configuration — verify how config is scoped before assuming a single global calendar. Assume the indexer is cron/console-driven and therefore needs a scheduler equivalent. Assume behaviour changes can land in patch releases: 1.18.1 alters expand-vs-date-search handling, so treat ~1.18.1 as unsafe as well as ^1.x. Pin to exact versions with a review gate that applies to patches too.

Sequencing

  1. Week 1–2 — dependency spike. Fresh Symfony skeleton, install the bundle, attempt a boot with sibling packages removed. Output: the true dependency graph, the true minimum feature set, go/no-go. Include a 1.18.0 → 1.18.1 result-set diff on the date/expand path while you are in there.
  2. Week 2–3 — surface contract. Document the iCal and GraphQL contracts, define the internal CalendarGateway interface, write contract tests — including parameterised cases that distinguish "expand occurrences" from "search by date".
  3. Week 3–5 — iCal path end-to-end. Highest value, smallest surface, cleanly separable, and untouched by 1.18.1. Ship export before authoring.
  4. Week 5–8 — read/search path. Listing, category/keyword/date filtering, expand-vs-search semantics, caching, pagination. This is where 1.18.1 landed; expect further churn here.
  5. Week 8+ — authoring and import. CMS-side management and RCE ingestion last; they are the most Atoolo-coupled and the least portable.

Do not start at step 5. The authoring/import layer is where the largest share of the bundle's complexity and the smallest share of your differentiation lives.

Operational Impact

Maintenance. You inherit a vendor's release cadence, not a community's. The 1.x line moves frequently and includes behaviour changes in both minor and patch releases — renames, config key substitutions (highlightCategory → simpleCategoryMap), semantics fixes in date handling, and now expand/date-search differentiation at 1.18.1. Pin exact versions, read every changelog including patch notes, and run the contract tests before any bump. Budget a recurring small but non-zero maintenance allocation (roughly 1–2 engineer-days per quarter for a sidecar deployment, plus a review gate on every upstream release; substantially more — effectively co-ownership — if you fork). The MIT license means the code will never disappear, but the maintenance is not free even when the code is.

Support. No community tier exists. Zero stars and zero dependents means no forum answers, no third-party tutorials, and no prior art when you hit an edge case. Documentation lives on the Sitepark docs site and is written for users of the Atoolo CMS, not for external integrators — expect to read source to answer configuration questions; 1.18.1's terse "differentiate between expand and search by date" is a live example of a changelog line that does not tell an integrator what actually changed. Escalation is a commercial conversation with the vendor, not a GitHub issue. If this capability is business-critical, negotiate a support arrangement before adoption, or accept that you are self-supporting from day one.

Scaling. The bundle is not the bottleneck; the search index behind it is. Indexing is batch-oriented (cron/console) and the RCE import path suggests periodic full or delta syncs — so scaling is about index freshness, job duration, and avoiding overlapping runs, not about request throughput. On the request path, iCal generation is comparatively expensive (serialization plus per-event scheduling resolution) and should be cached aggressively per query/occurrence-set, with cache keys covering language, the expand-vs-search mode, and the occurence parameter added in 1.9.0. The sidecar topology adds a network hop and a second cache to keep coherent — plan for a shared cache or short TTLs.

Failure modes to instrument from day one

  • Timezone and DST corruption. The most dangerous class, and directly evidenced by the changelog: date→gmdate migration, endDate incorrectly falling back to beginDate, and null-end-date handling. A wrong event date is a user-visible, trust-destroying defect. Assert on absolute timestamps in tests, never on formatted strings.
  • Expand vs. date-search confusion. The 1.18.1 fix class: events returned outside the requested window, or date filters silently ignored, because the two query modes were not distinguished. Symptom is a plausible-looking but wrong result set — no exception, no alert. Assert on result-set contents and boundaries, not just HTTP 200.
  • Stale or incomplete index. Events missing from listings, or the inverse — the 1.16.0 fix ("filter out inactive events during indexing") and 1.12.0 ("skip blacklisted event dates") show that the default failure mode has been over-inclusion. Check that your pinned version includes both, and monitor index counts against source counts.
  • Import pipeline failure. RCE sync silently stopping is invisible until listings go stale. Alert on "no successful import in N hours," not on import exceptions.
  • File/temp handling. 1.5.0 fixed a bug that "creates an empty tmp-file," and 1.9.0 fixed iCal filename sanitization — the latter is a security-adjacent surface. Audit how filenames are derived from user-supplied query strings and confirm the fix is present in your pinned version.
  • Upgrade-time breakage. Renames and config-key changes fail at container compile or, worse, silently at runtime; query-semantics changes like 1.18.1 fail only at runtime and only for some inputs. Contract tests are the mitigation, and they must run against every candidate upgrade, patches included.

Ramp-up. For an engineer already fluent in Symfony: roughly 1–2 weeks to productive, longer to confident on scheduling and query semantics. For a Laravel-only team: 3–5 weeks before they can debug the bundle rather than merely configure it — they must learn bundle extension config, tagged services, and the Atoolo resource model on top of an unfamiliar domain. The sidecar path reduces this substantially because the team can treat it as a black box with an HTTP contract. The extraction path shifts the cost from ramp-up to sustained ownership. Be honest in planning about which of those three costs you are actually signing up for: the license is free, the integration is not, and the cheapest-looking option (drop it into the Laravel app) is the one that will cost the most.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log