opifer/crud-bundle
OpiferCrudBundle provides configurable CRUD screens for Symfony applications, generating list, create, edit, and delete actions for Doctrine entities from bundle configuration. It can speed up simple admin interfaces, but expect limited documentation and community support.
Read this first: the package is archived (last release 2015-09-15), MIT, two stars, zero dependents, and built for Symfony 2.x / PHP 5.x. Treat it as legacy code you may inherit, not as a dependency you pick. For anything greenfield, a hand-rolled controller + Doctrine is less work than resurrecting this bundle.
If you're onboarding to a project that already uses it, get productive in this order:
Resources/config/services.yml and DependencyInjection/Configuration.php — this is the real API surface: which services you can override and which config keys exist.Controller/ directory — the base CRUD controller and its action methods define the contract you'll subclass.Crud* / *Manager class — the object that turns your config (entity class, form type, list columns) into queries and views.Tests/ if present — tests are the only reliable spec for edge-case behaviour.app/AppKernel.php (new Opifer\CrudBundle\OpiferCrudBundle()) and import its routing in app/config/routing.yml under a prefix.composer.json, not dev-master. There is no security process behind this package.index/new/edit, and confirm create → list → update → delete works end to end.That single vertical slice tells you more about the bundle's assumptions than any amount of config reading.
Config-driven CRUD definitions. The bundle's core idea is that each entity gets a declarative definition (entity class, form type, list fields, route names) consumed by a generic controller/manager. Keep these definitions in one place — app/config/crud.yml or a dedicated Crud/ directory — rather than scattering them. When you need per-entity behaviour, prefer adding a key to the definition over subclassing.
Subclass or compose, deliberately. Two viable styles:
getRepository(), createForm(), redirect targets). Cheap, but couples you to its request/response assumptions.Override templates through the app, never in vendor. Copy the bundle's Resources/views/ into app/Resources/OpiferCrudBundle/views/ and edit there. The directory name must match the bundle name exactly, and Symfony 2's override resolution is positional — a typo silently falls back to the vendor template.
Route hygiene. Every CRUD definition should generate its routes with a distinct prefix and name pattern (admin_product_index, not index). With multiple CRUDs registered, unprefixed route names collide and you'll debug the wrong controller.
Custom actions. Add non-CRUD operations by declaring an extra route pointing at a method on your subclass rather than bending the generic actions. Reuse the manager's repository access so your custom action participates in the same filtering/pagination logic.
Filtering and pagination as query-builder callbacks. If the definition supports a query-builder hook, put all filtering there instead of in the template. It's the one place the bundle expects you to intervene in persistence.
Lifecycle hooks over event listeners. On a bundle this old, the extension points are usually protected methods you override (prePersist, postUpdate-style), not dispatcher events. Override them, then call the parent — don't reimplement the flow.
Use it as a reference, not a dependency. If you like the declarative CRUD definition idea, copy the ~few hundred lines that matter into your app and own them. That removes the archived-dependency risk entirely and is usually the correct call for a two-star 2015 bundle.
$this->get('service') in controllers, getRequest()/getDefinition() signature changes, untyped setContainer, and isGranted vs. isGranted-in-templates differences. If the host app is on a modern Symfony, budget rework time — the bundle will not "just install."symfony/symfony: ~2.3 or nothing at all. Expect to fork and rewrite the require block, or vendor the source directly.::class, and scalar type hints may be absent; conversely, code may use functions removed in PHP 8 (each(), string offsets as arrays). Run a static check before assuming it loads.DependencyInjection/ and the manager — don't trust the README.rm -rf app/cache/*) — Symfony 2 caches template lookups aggressively.bin/console debug:router to confirm which controller actually owns a route, bin/console debug:container to see which service instance you're getting (and whether your override won), and the profiler's Doctrine panel to inspect the generated query. Most "CRUD is broken" reports are a route collision or a service override that didn't take.app/config/services.yml after the bundle's config is loaded, or use bundle inheritance. Verify with debug:container — a silently-missing override is indistinguishable from a bug.How can I help you explore Laravel packages today?