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

Framework Extra Bundle Laravel Package

widop/framework-extra-bundle

A Symfony bundle that adds extra annotations and attributes for controller configuration, covering caching, security and routing conveniences. It reduces boilerplate by letting you declare HTTP behavior directly in your controllers.

View on GitHub
Deep Wiki
Context7

Getting Started

What it is (and isn't): widop/framework-extra-bundle is a small Symfony 2.x bundle that lets you configure controller behaviour with Doctrine annotations — chiefly HTTP cache headers via a @Cache annotation on action methods. It is not a Laravel package: there is no service provider, facade, or config file to publish. Treat it as something you'd encounter inside a legacy Symfony app you're maintaining, not something you'd pull into a Laravel project.

Minimal setup (Symfony 2.x):

composer require widop/framework-extra-bundle
// app/AppKernel.php
public function registerBundles()
{
    return array(
        // ...
        new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
        new Widop\FrameworkExtraBundle\WidopFrameworkExtraBundle(),
    );
}

Because the bundle uses annotations, make sure sensio/framework-extra-bundle and doctrine/annotations are installed — the Widop bundle leans on Sensio's controller listener to actually act on the annotations.

Where to look first: the README for the exact annotation names/options, then the Configuration/ directory (the annotation classes, e.g. Cache) and the EventListener/ directory (the listener that reads the annotation and mutates the Response). The listener is where the real behaviour lives.

First use case — cache an anonymous, read-heavy page for a shared cache:

use Widop\FrameworkExtraBundle\Configuration\Cache;

class PostController extends Controller
{
    /**
     * @Cache(smaxage=3600, public=true)
     */
    public function showAction($id)
    {
        // ...
    }
}

Hit the action, inspect the response with curl -I, and confirm Cache-Control: public, s-maxage=3600.

Implementation Patterns

1. Keep cache policy declarative on the action. Set @Cache next to the route and @Template/@Route from Sensio, so a reader can see the cache contract of the endpoint without chasing service config:

/**
 * @Route("/posts/{id}", name="post_show")
 * @Cache(smaxage=600, public=true)
 */
public function showAction($id) { ... }

2. Split by content class. Use long smaxage for public marketing/listing pages and public=false (or no annotation at all) for anything rendered per-session. Don't annotate a page that reads $this->getUser() and then wonder why users see each other's data — the cache layer doesn't know about session variance.

3. Combine with conditional requests. Annotate @Cache and also set Last-Modified/ETag on the response in the controller. The annotation gives the shared cache a TTL; the validators let proxies revalidate cheaply. This is the pattern that actually pays off day-to-day.

4. Centralise defaults, override on the action. If you find yourself repeating smaxage=3600, public=true, set a sane default via the framework's cache config and use the annotation only for the exceptions. Annotations are excellent for the 10% case, painful as a global policy mechanism.

5. Test the headers, not the annotation. In functional tests, assert on Cache-Control and ETag rather than trying to test the annotation itself:

$client->request('GET', '/posts/1');
$this->assertTrue($client->getResponse()->headers->has('Cache-Control'));

6. Laravel translation of the same idea. In a Laravel codebase the equivalents are: response cache headers via $response->header('Cache-Control', ...) or middleware, and Cache::remember() for the application cache. There is no annotation layer, and you shouldn't try to bolt one on — route middleware is the idiomatic integration point. If you're porting a Symfony app that uses this bundle, map @Cache → a small CacheHeaders middleware, action by action.

Gotchas and Tips

  • Abandoned / very old. 11 stars, 0 dependents, Symfony 2-era code targeting PHP 5.3+. Expect it to fight modern PHPStan/Psalm and to break on PHP 8. Pin it, or better, replace it. For new work the @Cache feature is subsumed by Sensio's own @Cache and by Symfony's HttpCache. Do a feature audit before adopting.
  • Not a Laravel package. No service provider, no facades, doesn't run under Laravel's container. Installing it in a Laravel app does nothing useful. The pattern to copy is "declarative cache headers per endpoint," implemented as middleware.
  • Annotation typos fail silently. Misspell @Cache, forget the use Widop\FrameworkExtraBundle\Configuration\Cache; import, or lose the docblock, and the annotation reader simply doesn't see it — no error, no cache headers. First debugging step is always: confirm the docblock is present, the use is correct, and the listener is registered.
  • Bundle ordering matters. Register after SensioFrameworkExtraBundle, since the Widop listener hooks into the controller-event machinery Sensio sets up.
  • Clear the cache after annotation changes. Symfony 2 caches annotation metadata; edits to docblocks won't take effect until php app/console cache:clear (or you delete app/cache/*). This is the #1 source of "my annotation isn't working."
  • Caching a session-sensitive response is a security bug, not a performance win. Any endpoint that varies by cookie/user must not be public. Audit @Cache(public=true) annotations before putting a shared proxy in front of the app.
  • Check the request method. Only annotate safe/idempotent GET actions. Caching POST/PUT responses via headers is meaningless at best and confusing at worst.
  • Extension points are thin. You can subclass the annotation or decorate the listener to add options (e.g. must-revalidate), but the listener API is old and untyped. If you need richer cache semantics, writing ~30 lines of your own kernel.response listener is usually cleaner than extending this bundle.
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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo