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

Cookies Bundle Laravel Package

ongr/cookies-bundle

ONGR Cookies Bundle is a Symfony bundle for GDPR-friendly cookie consent: define cookie categories, render a consent banner, store visitor choices, and conditionally load analytics or tracking scripts only after users opt in.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Install and register. The bundle targets the Symfony 2.x/3.x kernel style, so on any modern Symfony you'll be pinning old framework versions (or forking):

composer require ongr/cookies-bundle
// app/AppKernel.php
$bundles = [
    // ...
    new Ongr\CookiesBundle\OngrCookiesBundle(),
];

If the constraint resolver fights you, check the composer.json in the repo for its symfony/symfony range before assuming the package is broken — it's a 2016 codebase and simply hasn't kept up.

2. Look at these three files first, in this order:

File Why
DependencyInjection/Configuration.php The authoritative list of config keys — don't trust blog posts, the README drifts from the code.
Resources/config/services.yml Gives you the real service IDs (manager, cookie model, listeners). Copy them verbatim.
The Cookie model class Tells you which properties are mutable and what the setters are called.

3. Declare one cookie and use it. The core idea is that a cookie is configuration, not a new Cookie(...) call scattered through controllers:

# app/config/config.yml
ongr_cookies:
    cookies:
        tracking:
            name: tracking_id
            max_age: 2592000   # 30 days
            path: /
            http_only: true
            secure: true
// Any controller — grab the manager by its ID from services.yml
$manager = $this->get('ongr_cookies.cookie_manager');
$cookie  = $manager->getCookie('tracking');

$cookie->setValue($someId);
$manager->updateCookie($cookie);   // queues it for the response

First use case: tracking/consent IDs, locale preference, A/B bucket assignment — small, non-sensitive, non-authoritative values where losing the cookie is harmless.

Implementation Patterns

Declare cookies centrally, read them by logical alias. The value of the bundle is that tracking is a stable internal name while tracking_id is the wire name. Controllers never hardcode cookie strings; renaming a cookie is a one-line config change.

Flush mutated cookies in a kernel.response listener. This is the pattern that makes the bundle usable day-to-day. Cookies must be attached to the Response after the controller returns, so either call the manager's update method inside a listener or wrap it yourself:

class CookieFlushListener
{
    public function onKernelResponse(FilterResponseEvent $event)
    {
        $this->manager->flushCookies($event->getResponse());
    }
}

Once this is in place, any service can mutate a cookie model without caring about the response lifecycle — that's the whole point of "cookies as services."

Inject the manager, don't fetch from the container. Wire ongr_cookies.cookie_manager into your own services so cookie state is testable and doesn't leak container awareness into domain code.

Read via the model, not $request->cookies->get(). Mixing the two is the fastest way to get a bug where the request says one thing and the model says another. If you must read raw (e.g. in a Twig template), go through app.request.cookies and accept that you've bypassed the abstraction.

Test with the cookie jar, not headers. Functional tests:

$client->request('GET', '/');
$jar = $client->getCookieJar();
$this->assertSame('abc', $jar->get('tracking_id')->getValue());

// or assert at the header layer for expiry/flags
$cookies = $client->getResponse()->headers->getCookies();

Migration insurance. Wrap the manager in your own PreferenceStore interface with get()/set()/forget(). If (when) you migrate to native Symfony\Component\HttpFoundation\Cookie or a maintained consent library, you swap one adapter and leave call sites untouched. Given the package's age, treat this as mandatory rather than optional.

Integration tip — caching. Anything that sets a cookie makes the response uncacheable in Varnish/Symfony HttpCache. Be explicit about which cookies are set on which responses; a stray tracking write on a product listing page will silently nuke your edge cache hit rate.

Gotchas and Tips

It's unmaintained. Last release June 2016, four stars, zero dependents. Budget for a fork. The realistic plan is: use it to learn the model, then reimplement the ~100 lines you actually need on top of HttpFoundation.

Symfony's own Cookie API moved under it. In Symfony 3.2+, the expires constructor argument became DateTimeInterface instead of an integer timestamp, and later versions added sameSite and raw. The bundle's model predates all of that. Expect setcookie()-style integer handling and no SameSite support — which modern browsers now default to Lax, so cross-site flows will break in ways that look like session bugs. Patch the model or set the header manually.

Cookies you set are invisible until the next request. $request->cookies was populated before your code ran. If you write a preference and immediately read it back through the manager, you're reading request state, not the new value. Carry the value in a local variable for the rest of the request.

Deleting needs a matching fingerprint. To remove a cookie you must reproduce the same path and domain and send a past expiry. A delete that "doesn't work" is almost always a path/domain mismatch producing a second, differently-scoped cookie alongside the original.

max_age: 0 means session cookie, not "expire immediately." And secure: true will silently drop the cookie when you're testing over plain HTTP on localhost — check the scheme before blaming the bundle.

The container is compiled. You cannot create a cookie whose name is dynamic through the bundle; the alias must exist in YAML at build time. For per-request/dynamic names, bypass the manager and use new Cookie(...) directly for that one case.

Debugging checklist:

  • bin/console debug:container ongr_cookies — find the real service IDs (names differ across versions).
  • $response->headers->all('set-cookie') — verify what actually shipped; the model mutating correctly proves nothing.
  • Check for a listener registered after yours overwriting headers, or a StreamedResponse where headers are already sent.
  • 4 KB per cookie, ~50 per domain: browsers silently drop extras.

Extension points, cheapest first: decorate the manager service → add a kernel.response listener → subclass the Cookie model to add missing flags (SameSite, Partitioned) → fork. Don't patch the vendor directory.

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.
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle