admin-project/doctrine-orm-admin-bundle
Laravel admin bundle integrating Doctrine ORM: manage entities, CRUD screens, listings, and forms from your model metadata. Designed to add an admin panel to Doctrine-based apps with minimal setup and configurable UI and actions.
Installation
composer require admin-project/doctrine-orm-admin-bundle
Add to config/bundles.php (Symfony):
AdminProject\DoctrineOrmAdminBundle\AdminProjectDoctrineOrmAdminBundle::class => ['all' => true],
Basic Configuration
Register the bundle in config/packages/admin_project_doctrine_orm_admin.yaml:
admin_project_doctrine_orm_admin:
orm:
enabled: true
entities:
- App\Entity\YourEntity
First Use Case Create a CRUD admin interface for an entity:
// src/Admin/YourEntityAdmin.php
namespace App\Admin;
use AdminProject\DoctrineOrmAdminBundle\Admin\AbstractAdmin;
use App\Entity\YourEntity;
class YourEntityAdmin extends AbstractAdmin
{
protected static $entity = YourEntity::class;
}
Auto-Discovery
The bundle auto-discovers Admin/ classes in src/. No manual registration needed.
Customizing Fields
Override configureFields() to modify displayed fields:
protected function configureFields(string $pageName): iterable
{
return [
'id' => 'Id',
'name' => 'Name',
'createdAt' => 'Created At',
];
}
Filtering
Add filters in configureFilters():
protected function configureFilters(string $pageName): iterable
{
return [
'name' => 'Name',
'active' => 'Active (Boolean)',
];
}
Actions Add custom actions (e.g., bulk delete):
protected function configureActions(): iterable
{
return [
'delete' => [
'label' => 'Delete',
'icon' => 'delete',
'type' => 'delete',
],
];
}
Form Customization
Override configureFormFields() for edit/create forms:
protected function configureFormFields(string $pageName): iterable
{
return [
'name' => 'Name',
'description' => 'Description (Textarea)',
];
}
Entity Relationships
Handle relationships (e.g., ManyToOne):
protected function configureFields(string $pageName): iterable
{
return [
'user.name' => 'User',
'posts.count' => 'Post Count',
];
}
Symfony Forms Integration
Use Symfony’s FormBuilder for complex fields:
public function configureFormFields(string $pageName): iterable
{
return [
'tags' => 'Tags (Collection)',
'settings' => 'Settings (Form)',
];
}
Doctrine Lifecycle Callbacks
Leverage Doctrine events (e.g., @PrePersist) via the entity, not the admin class.
Translation Use Symfony’s translation system for labels:
# config/packages/admin_project_doctrine_orm_admin.yaml
admin_project_doctrine_orm_admin:
translation_domain: 'admin'
Security Restrict access via Symfony’s voters or ACLs:
public function configurePermissions(): array
{
return ['ROLE_ADMIN'];
}
API Integration
Extend with API endpoints by combining with Symfony’s Serializer or ApiPlatform.
Entity Not Found
Class "App\Entity\YourEntity" is not mapped.@ORM\Entity).php bin/console doctrine:schema:validate.Field Not Displaying
user.name) fail silently.Caching Issues
php bin/console cache:clear
Overriding Defaults
configureFields() doesn’t override defaults.parent::configureFields() and merge:
$fields = parent::configureFields($pageName);
$fields['custom'] = 'Custom Field';
return $fields;
Performance with Large Datasets
DQL or QueryBuilder in configureDatagrid():
protected function configureDatagridFilters(string $pageName): iterable
{
return [
'query' => function (DatagridMapper $datagridMapper) {
$datagridMapper->add('e.name', 'Name');
$datagridMapper->add('COUNT(p.id)', 'Post Count');
},
];
}
Enable Debug Mode
Set APP_DEBUG=true in .env to see detailed errors.
Log Queries
Enable Doctrine logging in config/packages/doctrine.yaml:
doctrine:
dbal:
logging: true
profiling: true
Check Admin Routes List all admin routes:
php bin/console debug:router | grep admin
Inspect Generated HTML Use browser dev tools to verify rendered fields/actions.
Custom Templates
Override Twig templates in templates/admin/:
{# templates/admin/YourEntity/index_content.html.twig #}
{% extends '@AdminProjectDoctrineOrmAdmin/admin/crud/index_content.html.twig' %}
Event Listeners Subscribe to admin events:
// src/EventListener/AdminListener.php
namespace App\EventListener;
use AdminProject\DoctrineOrmAdminBundle\Event\AdminEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class AdminListener implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
AdminEvent::PRE_SAVE => 'onPreSave',
];
}
public function onPreSave(AdminEvent $event): void
{
$entity = $event->getEntity();
// Modify entity before save
}
}
Custom Field Types Create a custom field type:
namespace App\Admin\Field;
use AdminProject\DoctrineOrmAdminBundle\Field\AbstractField;
class CustomField extends AbstractField
{
public function getBlockPrefix(): string
{
return 'custom_field';
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'label' => 'Custom Field',
]);
}
}
Register in services.yaml:
services:
App\Admin\Field\CustomField:
tags: [admin_project.doctrine_orm_admin.field]
Bulk Actions
Extend bulk actions via configureActions():
protected function configureActions(): iterable
{
return [
'export' => [
'label' => 'Export',
'type' => 'export',
'handler' => [$this, 'exportHandler'],
],
];
}
public function exportHandler(): void
{
// Custom export logic
}
Internationalization Use Symfony’s translation system for dynamic labels:
protected function configureFields(string $pageName): iterable
{
return [
'name' => $this->translator->trans('admin.your_entity.name'),
];
}
How can I help you explore Laravel packages today?