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

Kissmetrics Bundle Laravel Package

ricbra/kissmetrics-bundle

Symfony bundle that integrates KISSmetrics analytics into your app, exposing the KISSmetrics client as a service so you can identify users and track events from controllers, services, or templates.

View on GitHub
Deep Wiki
Context7

Getting Started

Read three files in this order before writing any code. The bundle is ~100 lines of glue, so a 10-minute read tells you everything:

  1. DependencyInjection/Configuration.php — reveals the exact config root key (ricbra_kiss_metrics) and that the only real node is api_key (plus endpoint override).
  2. Resources/config/services.xml — gives you the service id you'll inject everywhere. Confirm whether an alias exists (e.g. ricbra.kiss_metrics vs ricbra_kiss_metrics) rather than trusting a blog post.
  3. The Client class in ricbra/php-kissmetrics-api — this is the object you actually call. Its public surface is identify, alias, record, set, clear. Everything else in the bundle is wiring.

Framework reality check first. This is a Symfony 2.x bundle, not a Laravel package. If you're on Laravel or Symfony 3+, Composer will refuse the constraint and the service container conventions differ. Do not fight it — treat the bundle as a reference implementation of how to wire the Kissmetrics client, and reproduce the wiring natively (see Implementation Patterns). Only install the bundle directly if you are on a genuine Symfony 2.x app.

Configure the key once, outside VCS.

# app/config/config.yml
ricbra_kiss_metrics:
    api_key: "%kissmetrics_api_key%"

Put the value in parameters.yml / environment config. Never commit it.

First use case — record a signup. Inject the client (confirm the id from services.xml) into a listener or controller and emit an event:

$km->identify($user->getEmail());
$km->record('Signed Up', ['plan' => 'trial']);

Then open Client::record() in php-kissmetrics-api to see the actual _k/_p/_n parameters transmitted. Understanding that mapping early prevents schema surprises later — Kissmetrics treats _p (properties) as the payload, and you want to know exactly what leaves your server.

Implementation Patterns

Inject, don't get(). For a Symfony 2 app, constructor-inject the service into your listeners/services. The underlying client is a plain object with no container dependencies:

app.registration_tracker:
    class: AppBundle\Analytics\RegistrationTracker
    arguments: ['@ricbra_kiss_metrics']

Wrap the client behind a domain-oriented tracker. The raw API is a generic event recorder. Do not scatter $km->record(...) calls across controllers. Introduce one small class (App\Analytics\Tracker) exposing domain methods — signedUp(User $u), upgraded(User $u, $plan), trialExpired(User $u) — so consent checks, property normalization, logging, and a no-op driver for dev/test live in exactly one place. This is the single most valuable thing you'll do, because it isolates the one place that knows about Kissmetrics from the many places that know about your product.

Identify on login, alias on registration. The canonical flow:

  1. Anonymous visitor: Kissmetrics JS assigns a generated identity.
  2. On signup, call alias($newIdentity) before identify($canonicalIdentity) so pre-conversion behavior is stitched to the account.
  3. Call identify($canonicalIdentity) (usually email or your stable user id) and then set([...]) for durable, slowly-changing properties (plan, company size, acquisition source).

Keep the identity choice stable and boring. Changing it later invalidates cohorts.

Emit authoritative events server-side; use JS for enrichment only. Backend calls are the trustworthy channel for money- and lifecycle-related events (order completed, refund, upgrade, cancellation) because they can't be spoofed and aren't blocked by ad blockers. Let the client-side snippet handle pageviews and UI-level hints. Don't try to make the SDK do both jobs.

Run through a queue for anything on a hot path. A synchronous call inside a request couples user-facing latency to Kissmetrics' availability. In a legacy Symfony 2 app, dispatch a job (old-school JMSJobQueueBundle, a DB-backed queue table, or at minimum a kernel.terminate listener) and have the worker call the tracker. This is also where retry/backoff and idempotency keys belong — the SDK won't provide them.

Integration tips:

  • Register a no-op/log driver for test and dev so the tracker never makes network calls in CI. Bind the real client only in prod.
  • Keep the underlying php-kissmetrics-api client behind your Tracker interface so it can be replaced by a direct HTTP adapter or a different vendor without touching call sites.
  • Log the parameters you send at debug level (redacting user-identifying fields) so you can compare what you emitted against Kissmetrics' event view — this is how you'll diagnose "event not appearing" tickets.

Gotchas and Tips

The Symfony 2 constraint is a hard blocker, not a warning. On Symfony 3+ / Laravel, Composer will error on install. The bundle is too thin to justify forking for its service wiring alone — reimplement the ~50 lines natively (one service provider, one config file, one bind). If you're on Legacy Symfony 2, pin the dependency and document that decision; it is unmaintained (1 star, 0 dependents).

The config root key is easy to get wrong. It's ricbra_kiss_metrics (underscored), not ricbra_kissmetrics or ricbra.kiss_metrics. Read Configuration.php rather than guessing from the package name — this is the #1 first-hour trap.

Service id ambiguity. There may or may not be an alias. Always open services.xml and use the id you find there; a wrong id yields a confusing ServiceNotFoundException, not a useful hint.

The client is thin, so reliability is your job. The SDK sends HTTP and (at best) returns an error on failure. It does not give you retry/backoff, dead-letter handling, batching guarantees, or idempotency. Duplicate events on retry are a real risk — attach an idempotency key (e.g. event_id in properties) so Kissmetrics can reconcile, and put retries in your queue layer, not around the client call.

PII and consent are not handled. The wrapper sends whatever properties you give it. If you send raw emails, addresses, or free-text, they leave your boundary and land in a vendor's system. Redact/whitelist properties inside your Tracker, gate on consent at the boundary, and check the vendor DPA before sending anything sensitive. A bare SDK wrapper provides no deletion flow — plan for GDPR/CCPA erasure requests separately.

TLS and HTTP transport may be stale. Symfony 2-era code often sits on old Guzzle/cURL configs. Verify that outbound calls work on your runtime — modern PHP versions may reject legacy TLS negotiation or deprecate the transport. Test with a real staging call to a KISSmetrics endpoint, not just a unit test with a mock.

Failure modes to instrument. API downtime, rate limiting (429), invalid credentials (401), TLS/network errors, queue exhaustion (dropped events), and identity/alias mismatches. Add counters and alerts around queue depth and error rate — otherwise "the funnel looks wrong" becomes an expensive debugging exercise.

Debugging checklist when events vanish:

  1. Is the api_key correct and is the endpoint right (staging vs prod)?
  2. Did the call reach Client::record() at all, or did a wrapper/guard swallow it?
  3. Are _k/_p/_n values what Kissmetrics expects? Inspect outgoing parameters via a network log or a local HTTP interceptor.
  4. Did alias fire before identify? Wrong ordering produces orphaned identities that never merge in cohorts.
  5. Did you accidentally call clear() and drop identifying state before your event?

Extension points are minimal — plan accordingly. You can swap the service binding, wrap the client, or provide your own implementation behind your Tracker interface, but don't expect the bundle itself to grow. Treat it as a starting scaffold; own the fork or the replacement. For a longer-lived integration, the correct end state is a small internal client (Laravel Http/Symfony HttpClient + a queued job, ~one engineer-day) that talks directly to the Kissmetrics HTTP API and lets you route to another vendor behind the same interface.

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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums