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

Base Controller Bundle Laravel Package

kematjaya/base-controller-bundle

Reusable base controller classes for Symfony/PHP applications, helping reduce boilerplate around common CRUD, form, and service workflows. Extend the provided controllers to standardize actions and keep application code lean.

View on GitHub
Deep Wiki
Context7

Getting Started

Start by reading the bundle's src/ directory and its README.md — this is a tiny, low-traffic package (3 stars, no dependents), so the source is the documentation. Look for:

  • The abstract/base controller class(es) you're expected to extend (commonly AbstractCrudController or similar).
  • Any abstract methods you must implement (entity class, form type, template prefix, repository method).
  • DependencyInjection/ and Resources/config/ for what services and parameters get registered automatically.
  • composer.json for the supported Symfony/PHP versions — pin accordingly before installing.

Install it and register the bundle (Symfony Flex may or may not auto-register given the package's age; check config/bundles.php):

composer require kematjaya/base-controller-bundle

First use case: take one existing, boring CRUD controller (list + show + create + edit + delete for a single Doctrine entity) and rewrite it to extend the bundle's base controller. Keep the original alongside it until you've diffed behavior — this is the fastest way to learn exactly which conventions (route names, template paths, redirect targets) the base class assumes.

Expect to write a thin concrete controller:

class ProductController extends AbstractCrudController
{
    protected function getEntityClass(): string { return Product::class; }
    protected function getFormType(): string { return ProductType::class; }
    protected function getTemplatePrefix(): string { return 'product'; }
}

…and then compare what routes/actions appear versus your hand-written version.

Implementation Patterns

Thin controllers, fat base. The whole point of this pattern is that your concrete controllers become declarative: you supply the entity, form type, and template prefix, and inherit the index/show/new/edit/delete actions. Adopt this uniformly across entities so every CRUD screen behaves the same way — consistency is the only real payoff for a package this small.

Override, don't fork. When an entity needs special behavior (custom query for the index, a filtered repository, a different redirect after save), override the single protected method rather than copying the whole action. Common override points to look for and lean on:

  • getRepository() / query builder used for the index listing (add filters, ordering, soft-delete scoping).
  • getRedirectRoute() after create/edit.
  • getFormOptions() to pass entity-specific options.
  • Template variables passed to the view.

Template convention. Base controllers almost always infer templates from the prefix (e.g. product/index.html.twig, product/_form.html.twig). Standardize your Twig layout early: create the expected template tree under templates/ before wiring controllers, so you get immediate feedback on which variables the base actions pass.

Integration with security. Annotate or attribute your concrete controllers (#[IsGranted('ROLE_ADMIN')] on the class, per-action overrides where needed). Because the actions live in the parent, class-level security is usually the cleanest layer — but verify the base actions aren't declared final in a way that blocks attribute inheritance.

Flash messages and PRG. Most such bundles implement post/redirect/get with flash messages. Centralize flash handling in your base layout so both bundle-driven and custom controllers render them identically.

Testing. Since the actions are inherited, an integration test suite that hits each route once per entity gives outsized value: it catches regressions in the base class's assumptions (route names, form field names, redirect targets) that unit tests won't.

Gotchas and Tips

  • Bus factor. 3 stars, 0 dependents, and an apparently idle repo. Treat this as vendored code you own: pin the exact version in composer.json, and be prepared to fork or copy the base class into your app if a Symfony upgrade breaks it. Do not build your architecture around it without a fallback.
  • Symfony version drift. Small bundles like this are often written against an older Symfony (4.x/5.x). Check for deprecated patterns — $this->getDoctrine(), @Route annotations instead of attributes, ContainerAware — before assuming compatibility with a current Symfony release.
  • Implicit conventions bite. The base class assumes route names and template paths you didn't write. If a page 500s with "template not found" or a redirect loops, it's almost always a naming mismatch, not a bug. Read the parent method body rather than guessing.
  • Method visibility and final. Some base controllers mark actions final to force the override-method pattern. If you find yourself unable to change one action, that's the reason — work through the designated extension points instead of fighting it.
  • Entity manager state. Inherited actions often call flush() and redirect. If you add listeners or lifecycle callbacks that expect a second flush, verify the order. Debug with $em->getUnitOfWork()->getScheduledEntityUpdates() when saves seem to be silently skipped.
  • Form options are easy to lose. Overriding createForm() wholesale is a common shortcut that drops options the base class passes. Override the narrowest hook available.
  • Config quirks. If the bundle exposes a config/packages/*.yaml tree, run bin/console config:dump-reference <bundle_alias> and debug:container --tag=... to see what's actually registered — small bundles frequently ship config that's never read.
  • Extension points to prefer: constructor injection of a repository or service over static helper calls; a base Twig template you control over editing vendor templates (never edit vendor/).
  • Escape hatch. If the abstraction starts costing more than it saves for non-trivial entities (state machines, multi-step forms, API endpoints), graduate those to conventional controllers rather than bending the base class. Keeping both styles in one app is fine and is often the pragmatic outcome with a package this thin.
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.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
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