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

Controller Bundle Laravel Package

imatic/controller-bundle

imatic/controller-bundle is a Laravel/PHP package that provides controller-focused utilities for organizing actions and streamlining common controller patterns. It aims to reduce boilerplate and keep controller code structured, making standard request-handling flows easier to build and maintain.

View on GitHub
Deep Wiki
Context7

Getting Started

The one thing to internalize first: imatic/controller-bundle is a Symfony bundle, not a Laravel package. There is no service provider, no config/controller-bundle.php, no facade, no artisan commands. If you are working in Laravel, there is nothing to install — Laravel's invokable controllers, resource controllers, Route::controller(), form requests and response()/redirect()/view() helpers already cover everything this bundle offers. The practical "day one" for a Laravel dev is to recognize the mismatch and stop. The guidance below applies to the real scenario in which you'd meet this package: a Symfony application (typically an Imatic-built stack alongside imatic/data-table-bundle and imatic/filter-bundle) where you've inherited or joined a codebase and are expected to write controllers the house way.

Minimal setup (Symfony)

composer require imatic/controller-bundle
// config/bundles.php
return [
    // ...
    Imatic\Bundle\ControllerBundle\ImaticControllerBundle::class => ['all' => true],
];

Verify registration, then look for the config keys:

bin/console debug:container | grep -i imatic
bin/console config:dump-reference imatic_controller

Where to look first

  1. The bundle's Controller/ directory — the abstract base controllers and their traits are the entire public API. They are short and are the real documentation. Read them before the README.
  2. DependencyInjection/Configuration.php — tells you the handful of imatic_controller.* keys that exist (usually serializer service id, default template naming, redirect target).
  3. An existing controller in the host app that already extends the base class. Copy its shape, not the docs. In a 1-star package the in-repo usage pattern is more authoritative than anything written down.

First use case

A CRUD edit/update action that would be ~10 lines of plain Symfony boilerplate collapses to a few:

// before (plain Symfony)
public function edit(Request $request, Product $product): Response
{
    $form = $this->createForm(ProductType::class, $product);
    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid()) {
        $this->entityManager->flush();
        return $this->redirectToRoute('product_index');
    }
    return $this->render('product/edit.html.twig', ['form' => $form->createView()]);
}

// after (bundle base controller — shape will vary by version, read the source)
public function edit(Request $request, Product $product): Response
{
    return $this->handleForm(
        $this->createForm(ProductType::class, $product),
        $request,
        'product_index',
        'product/edit.html.twig'
    );
}

Start by converting exactly one low-risk leaf controller (settings screen, admin list, simple resource) against the base class, run the full test suite and a manual smoke pass, and measure how much boilerplate actually disappears. Do not convert a critical-path controller first.

Implementation Patterns

Extend the base, don't compose around it. The bundle's helpers are protected methods on an abstract controller; the intended pattern is inheritance. class ProductController extends AbstractController (from the bundle, not Symfony's) and call $this->renderSuccess(), $this->redirectSuccess(), $this->handleForm() and siblings directly. If you find yourself writing a wrapper service that calls the helpers, you're fighting the design and will end up with two abstractions.

One controller per resource, thin actions. The value is concentrated in the four CRUD verbs. Keep actions to a single form-handle-then-render branch and push everything else (queries, business rules, DTO mapping) out to a service injected into the constructor. The base class gives you container access; resist the temptation to use it as a service locator inside actions.

Use the redirect/response helpers consistently for flash messaging. The most-used day-to-day helpers are typically the redirect-with-flash variants (redirectSuccess, redirectError) that pair with Symfony's flash bag. Standardize on them across the codebase so flash keys and redirect targets don't drift between controllers — that consistency is a real code-review win and the strongest argument for the bundle in an otherwise thin feature set.

Form handling as the canonical pattern. handleForm-style helpers are where the boilerplate reduction is largest: create form → handle request → on valid, flush and redirect; on invalid, re-render with errors. Wire the redirect route name and template in the helper call (or via config defaults) rather than repeating the branch in every action.

Integrate at the routing layer as normal Symfony. This bundle does not own routing. Register controllers with standard Symfony route attributes/routes.yaml; there is no magic registration to learn. If your host app uses imatic/filter-bundle and imatic/data-table-bundle for list screens, the base controller is the expected front door to those — the list action typically builds a datatable/filtered query and hands it to a template.

Keep a native escape hatch per controller. Symfony's AbstractController still offers everything the bundle wraps. When a helper doesn't fit an edge case, call the native Symfony method directly rather than contorting the action to please the helper. Mixed usage inside one action is fine.

Pattern transfer if you're on Laravel. If a stakeholder asks for parity, the mapping is one-to-one and should be documented rather than vendored:

  • AbstractController → extend Illuminate\Routing\Controller (or nothing).
  • Redirect/response helpers → redirect()->route(...)->with(...), response()->json(...), view(...).
  • handleForm → FormRequest + $request->validated() + save + redirect.
  • List/datatable integration → Resource collections + paginate().
  • One action per resource → invokable controllers registered in routes/web.php.

This is the realistic "implementation pattern" for a Laravel team: write it once in a first-party base controller, ship it, and never carry the dependency.

Gotchas and Tips

The biggest gotcha is the category error. It is a Symfony bundle. It will not composer require cleanly into a Laravel app, and if it somehow resolves it will drag Symfony HTTP/Kernel components into your graph for a helper class. Any instinct to "just try it in Laravel" is a dead end — composer why imatic/controller-bundle before approving anything, and expect to reject.

Helper signatures are version-sensitive. With one star, zero dependents and no CI matrix, the public helper signatures and default config keys can and do shift between releases. Pin the exact version in composer.json, read the installed source (not the README, not blog posts) before relying on a helper, and treat upgrades as a reviewed change with the test suite run — not a routine composer update.

Config quirks live in one file. Almost all behavior is driven by the few imatic_controller.* keys in DependencyInjection/Configuration.php. When a redirect goes to the wrong route or a template resolves unexpectedly, dump the reference and check the config before debugging the action:

bin/console config:dump-reference imatic_controller
bin/console debug:config imatic_controller

Debugging a helper failure. The helpers funnel through Symfony's normal controller plumbing, so enable the profiler and inspect the request/response pair. If a form helper silently re-renders instead of redirecting, it's almost always validation failing or handleRequest not being called against the right request object — fall back to the explicit createForm/handleRequest/isValid sequence once to confirm which branch you're in.

No security or support process. There's no disclosed security contact, no advisory history, no community. For a convenience layer, the failure mode is "you're the maintainer now." Keep adoption confined to leaf controllers that are trivially repairable, and if an edge case bites, the pragmatic fix is often to inline the native Symfony call rather than wait for upstream.

Bus factor of one. Single-maintainer namespace, no downstream consumers. If the repository archives, your fork-or-remove decision is forced under time pressure. Mitigate by keeping the pattern reproducible: every controller you convert should be convertable back to plain Symfony in minutes. Treat the bundle as a style layer, not architecture.

Silent breakage on PHP minor upgrades is the real risk. No CI matrix means a PHP point release can surface as a fatal you didn't ask for. Pin PHP in your platform config, run the suite on upgrade, and keep the bundle out of the critical path so an outage is scoped.

Extension point: your own base controller. The intended extensibility is straightforward — subclass the bundle's abstract controller into an app-local App\Controller\BaseController and route all your controllers through it. That gives you a single seam to add cross-cutting helpers (audit logging, tenant resolution) and a single place to rip the bundle out later if needed. Do this from day one rather than extending the vendor class directly across dozens of controllers.

Onboarding cuts against adoption. New hires already know Laravel's or Symfony's native controller model; they don't know this bundle's conventions. Every helper you standardize on is one more thing to teach and later un-teach. If the team genuinely wants the convention, codify it in a first-party base controller and a short style guide — you'll capture the same velocity with none of the supply-chain risk.

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