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

Ga4 Analytics Data Bundle Laravel Package

freema/ga4-analytics-data-bundle

Symfony bundle for pulling Google Analytics 4 Data API reports into your PHP application. It wraps GA4 credentials and reporting queries in configurable services, making it easier to fetch metrics and dimensions without boilerplate.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Recommendation: upgrade to 1.1.2 with high priority — this is a correctness and data-isolation release, not routine housekeeping.

Architecture fit

  • The package (freema/analytics-data-bundle) is a Symfony bundle, not a Laravel package. Its integration surface is Symfony Flex/DI, Symfony cache pools (cache.app), and Symfony's HTTP client/Guzzle stack. That is a material architectural mismatch against a Laravel target and should be the first thing validated before we invest further.
  • Functionally it is a thin read-through cache in front of the GA4 Data API: fetch report → cache by report + period → serve. That is a sensible shape for dashboards and scheduled reporting, and the 1.1.2 fixes harden exactly the layer we would depend on.
  • The release confirms the package is viable on the PHP side (Guzzle, PSR cache semantics) even where the framework wiring is not ours.

Integration feasibility

  • Low effort to adopt: no code changes required to upgrade, no API/signature breaks, and the changelog explicitly says earlier cache entries are simply not read.
  • The upgrade does change behaviour in three places that matter to us even though the API is stable — see risk below.

Technical risk (pre-1.1.2, i.e. what we avoid by upgrading)

  1. Cross-tenant data bleed (highest severity). Cache keys were built from report + period only, so with multiple clients/properties the first caller populated the entry and every other client read that property's numbers for up to 24 hours. In a multi-tenant or multi-brand deployment this is silently wrong analytics surfaced to the wrong stakeholder — a trust and possibly contractual problem, not just a bug. The configured cache.prefix was also ignored, so environments could collide.
  2. Negative-result caching. A failed isTransactionInAnalytics() check was cached as false for the full TTL, producing sustained false negatives in transaction/revenue reconciliation logic.
  3. Oversized blast radius on invalidation. AnalyticsCache::clear() flushed the entire cache.app pool — i.e. one client's cache refresh evicted unrelated application cache. Scoping it to one client is safer but is a semantic change for anyone relying on it as a big red button.

Residual risk after upgrade

  • Behavioural, not API, break: clear() no longer clears everything. Any runbook, admin endpoint, or deploy step that used it as a general flush must be re-pointed.
  • Orphaned cache entries: old-format keys are no longer read but are not purged; they linger until TTL expiry. Small memory cost, zero correctness cost.
  • Cold cache on first run: all clients will re-hit the GA4 API. Expect a one-off latency spike and quota consumption — worth scheduling.
  • Test suite no longer ships in the Composer package. We lose the ability to run the vendor test suite locally as a trust check; verification now depends on tagged source in GitHub and the published CI matrix. Acceptable, but it moves assurance to our own integration tests.
  • PHP 8.5 readiness is claimed but new: setAccessible() and the choose_handler() fallback were removed, which is good hygiene, but 8.5 is a fresh target. We should not treat 8.5 as certified until we've run it ourselves.

Key questions

  • Are we actually deploying Symfony, or do we need a Laravel adapter? If Laravel, is wrapping this bundle cheaper than a Laravel-native GA4 client, and who owns that bridge?
  • How many GA4 properties/clients are configured in one deployment? This determines whether bug #6 was a live data-integrity incident for us.
  • Which code paths call AnalyticsCache::clear() today, and does any of them assume a full-pool flush?
  • What is our GA4 API quota headroom for a full cold-cache warm-up across all properties?
  • Do we have integration tests asserting property isolation? That is the regression guard this release effectively asks for.

Integration Approach

Stack fit

  • If Symfony: direct fit. Upgrade is a composer constraint bump; configure a distinct cache.prefix per environment and per tenant, and confirm each client is configured with its own GA4 property.
  • If Laravel: do not assume drop-in. The bundle's service definitions, Flex recipe, and cache.app assumptions do not exist in Laravel. Options are (a) a thin Laravel service provider that registers the underlying client and maps to Laravel's cache/HTTP contracts, or (b) a Laravel-native GA4 client. Note that the README's Flex recipe reference was removed in this release precisely because the recipe was never published — so there is no scaffolding shortcut. Pick (a) or (b) explicitly, with an owner.
  • If framework-agnostic PHP: the underlying client is usable directly; we'd supply our own PSR-6/PSR-16 cache and HTTP client and skip the bundle wiring entirely.

Migration path

  1. Bump to ^1.1.2 in a branch; no source changes expected.
  2. Add/verify explicit per-client property configuration and a unique cache.prefix per environment.
  3. Audit all call sites of AnalyticsCache::clear() and adjust any that assumed a full-pool flush.
  4. Run the cold-cache warm-up in a low-traffic window and observe GA4 quota.
  5. Ship behind the existing feature flag if the analytics surface is customer-facing.

Compatibility

  • PHP 8.1–8.5 and Symfony 5.4 / 6.4 / 7.4 are covered by CI. Confirm our PHP and Symfony versions fall inside that matrix — 5.4 is the EOL-adjacent end, so if we're on it, plan forward.
  • Guzzle: the removed choose_handler() fallback means very old Guzzle versions are effectively unsupported. Pin a current Guzzle.
  • Cache backend: any PSR cache works, but the bug history argues for a backend where key namespacing is explicit and observable.

Sequencing

  • Treat this as a single small change with an outsized payoff: dependency bump → configuration audit (prefix, per-client property) → clear() call-site audit → integration test for property isolation → deploy with cold-cache observation.
  • Do the isolation test before the deploy, not after; it is the cheapest possible insurance against bug #6 recurring in a refactor.

Operational Impact

Maintenance

  • Low ongoing burden: bugfix-only release, small dependency surface, stable public API.
  • One maintenance obligation created by this release: our runbooks must reflect that clear() is client-scoped. Undocumented, that becomes a future incident ("cache clear didn't work").
  • We now own the test coverage that no longer ships in the package — at minimum a property-isolation test and a "failed check is not cached" test.

Support

  • The fixes directly reduce support load: no more "two clients show identical numbers", no more "transactions missing for a day", no more "clearing analytics wiped the app cache".
  • If bug #6 was live, expect a short window of increased questions after upgrade as previously wrong numbers correct themselves. Brief the BI/dashboard owners before deploy so the change isn't mistaken for a regression.

Scaling

  • Per-client keyspace grows linearly with client count × report count × periods; fine, but worth monitoring cache size.
  • Cache hit path is cheap; the cold-cache event is the only scaling cliff, and it is bounded and one-off.
  • GA4 API quota is the real ceiling, not the package. With correct per-client scoping we should also confirm we aren't double-fetching the same property from multiple clients.

Failure modes

  • Pre-upgrade: silent cross-tenant wrong data; durable false negatives; collateral cache eviction. All three are "no error, wrong answer" failures — the worst kind, and the strongest argument for immediate upgrade.
  • Post-upgrade: cache miss → API call (graceful, quota-bounded); API failure → no longer poisons the cache, so it self-heals on the next call; scoped clear() → a stale entry for another client survives an operator's flush, which is by design but must be understood.
  • Packaging: tests absent from the dist means a compromised or broken tag cannot be caught by running vendor tests. Compensate with tag/commit pinning and our own smoke suite.

Ramp-up

  • For an engineer familiar with Symfony DI and PSR caches: well under a day to upgrade and verify.
  • For a Laravel team: budget the bridge work separately, and treat the framework-adapter decision as a design task with a named owner rather than an implementation detail.
  • TPM effort is mostly coordination, not deep technical work: one configuration audit, one call-site audit, one regression test, one comms note to dashboard stakeholders.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager