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

Doctrine Orm Admin Bundle Laravel Package

rmzamora/doctrine-orm-admin-bundle

A Symfony bundle that generates admin interfaces for Doctrine ORM entities, giving you CRUD screens, list and form views, filters, and batch actions with minimal configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is a fork of sonata-project/doctrine-orm-admin-bundle; it is archived and carries no maintainers, so the first step in any greenfield work is to confirm you actually need the fork. If you do not depend on fork-specific patches, require the upstream package instead and treat everything below as applicable to both, since the public API is effectively identical.

Minimal setup:

  1. Require sonata-project/admin-bundle, doctrine/orm, and either this fork or the upstream ORM bridge.
  2. Register the bundle in your kernel (SonataDoctrineORMAdminBundle), and register SonataAdminBundle plus SonataBlockBundle if you have not already — the admin UI will not render without the block and twig dependencies.
  3. Configure doctrine.orm with at least one mapped entity, and point Sonata's sonata_admin config at your admin services.

First use case — a CRUD screen for a single entity:

final class PostAdmin extends AbstractAdmin
{
    protected function configureFormFields(FormMapper $form): void
    {
        $form->add('title', TextType::class)
             ->add('body', TextareaType::class);
    }

    protected function configureListFields(ListMapper $list): void
    {
        $list->addIdentifier('title')
             ->add('createdAt', null, ['format' => 'Y-m-d H:i']);
    }
}

Register it as a service tagged sonata.admin with manager_type: orm, then load /admin — the ORM bridge is what wires your entity into Sonata's ModelManager, datagrid, and form builder.

Look first at the Admin/ORMAdminBundle classes (AbstractAdmin, ModelManager, ProxyQuery, Form/DataTransformer), then at the upstream docs for the version you pinned.

Implementation Patterns

Admin-as-service. Every admin must be a service with the sonata.admin tag and the manager_type: orm attribute. Constructor-arg order is $code, $class, $baseControllerName. Omitting manager_type is the most common cause of "no model manager" exceptions.

Extending AbstractAdmin vs ORMAdminBundle\Admin\ORMAdmin. Extend AbstractAdmin unless you need ORM-specific behaviour in configureDatagridFilters or getNewInstance. The ORM bridge auto-detects the model manager from the entity's metadata, so most admins never touch ORM classes directly.

Datagrid and filters. Use configureDatagridFilters with field names matching your entity properties; the bridge translates them into Doctrine\ORM\QueryBuilder constraints through ProxyQuery. For associations, prefer doctrine_orm_choice (or the appropriate ModelType-backed filter) over string, otherwise you will get SQL errors on joined columns.

Custom queries. Override configureQuery(ProxyQueryInterface $query) on the admin to add leftJoin/where clauses. Do not mutate $query->getQueryBuilder() outside of that method — the datagrid reuses the proxy and your changes may be dropped or double-applied on pagination.

Formatters and templates. Register custom field types and sonata_type_* formatters in config.yml under sonata_admin if you need custom rendering; the bridge delegates form building to FormBuilder and expects standard Symfony form types. Custom DataTransformers belong in configureFormFields via addModelTransformer, not on the entity.

Programmatic admin operations. From a controller or console command, fetch the admin by service id ($container->get('app.admin.post')), call getNewInstance() and create() / update() on it, and let the ModelManager handle persistence. Do not call $em->persist() yourself and then expect the admin's batch actions or audit trail to line up.

Batch actions and exports. Add batch_actions and export_fields in configureBatchActions/configureExportFields; the bridge maps these straight to ORM updates and iterates with iterate() on a ProxyQuery, so keep your queries paginated for large entities.

Gotchas and Tips

  • Archived fork risk. There are no security releases, no fix for Doctrine DBAL/ORM version drift, and no compatibility guarantee with newer Symfony. Pin every sonata-project/* and doctrine/* version in composer.json, and plan a migration to upstream. If you only need the fork for one patch, cherry-pick it onto upstream instead of depending on this.
  • Entity identifiers. The ORM bridge assumes a single-column identifier for most datagrid and list operations. Composite keys work for basic CRUD but break addIdentifier ordering, batch deletes, and many filter types.
  • ProxyQuery quirks. ProxyQuery::execute() returns Doctrine\ORM\Query and hydration is controlled by the datagrid's hydrate setting. If you have custom QueryBuilder logic that mutates the SELECT, pagination counts will disagree with the displayed rows — override getCountQueryBuilder or use QueryBuilder::select('DISTINCT …') carefully.
  • Form type detection. The bridge guesses field mappings from Doctrine metadata; explicit add('field', Type::class) is almost always safer than relying on the guess, especially with embeddables, DateTimeInterface, and JSON columns.
  • Config caching. Bundle config is merged into the container at compile time; clearing the cache after changing sonata_admin config or service tags is mandatory. Stale admin routes are a classic symptom of a forgotten cache:clear.
  • Debugging. Sonata swallows exceptions in the admin UI. Enable sonata_admin.options debug settings, check the Symfony profiler's Doctrine panel for the actual query, and tail var/log/dev.log — the ProxyQuery wraps errors before they reach ExceptionListener.
  • Extension points. Before writing custom code, check whether a Doctrine ORM event listener, a ProxyQuery subclass, or a form DataTransformer already solves the problem. Most "I need to customize the list view" requests are solved by formatters and a custom template registered under sonata_admin.templates.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource