sonata-project/doctrine-mongodb-admin-bundle
Symfony bundle that integrates Doctrine MongoDB ODM with SonataAdminBundle, providing admin services, mappers, and datagrid support to manage MongoDB documents via Sonata’s admin UI. Includes docs, CI, and versioned releases.
Installation:
composer require sonata-project/doctrine-mongodb-admin-bundle
Ensure SonataDoctrineMongoDBAdminBundle is enabled in config/bundles.php:
return [
// ...
SonataDoctrineMongoDBAdminBundle\SonataDoctrineMongoDBAdminBundle::class => ['all' => true],
];
Configure MongoDB ODM:
Add MongoDB connection to config/packages/doctrine_mongodb.yaml:
doctrine_mongodb:
connections:
default:
servers: ['mongodb://localhost:27017']
options: {}
default_database: app_db
document_managers:
default:
auto_mapping: true
Create a Basic Admin Class:
// src/Admin/PostAdmin.php
namespace App\Admin;
use Sonata\DoctrineMongoDBAdminBundle\Admin\AbstractAdmin;
use Sonata\DoctrineMongoDBAdminBundle\Datagrid\DatagridMapper;
use Sonata\DoctrineMongoDBAdminBundle\Form\FormMapper;
class PostAdmin extends AbstractAdmin
{
protected $datagridValues = [
'_page' => 1,
'_per_page' => 10,
];
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper->add('title');
}
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->tab('General')
->with('Content')
->add('title')
->add('content')
->end()
->end();
}
}
Register Admin in Services:
# config/services.yaml
services:
App\Admin\PostAdmin:
tags: [sonata.admin]
arguments: ['App\Entity\Post', App\Admin\PostAdmin, 'SonataDoctrineMongoDBAdminBundle:CRUD', 'Post', 'Post']
Access Admin Panel:
Visit /admin/app_post_post to see the generated CRUD interface.
Post documents with fields like title and content.Override configureFormFields to customize form rendering:
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('title', 'text', [
'label' => 'Post Title',
'attr' => ['class' => 'form-control'],
])
->add('publishedAt', 'sonata_type_datetime_picker', [
'dp_options' => ['format' => 'YYYY-MM-DD HH:mm:ss'],
]);
}
Customize list views with filters and sorting:
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
->add('title', null, [
'label' => 'Title',
'field_type' => 'string',
])
->add('publishedAt', 'doctrine_odm_mongodb_date', [
'field_type' => 'date',
'label' => 'Published At',
]);
}
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->add('title', null, [
'template' => 'SonataDoctrineMongoDBAdminBundle:CRUD:list_field.html.twig',
])
->add('publishedAt', null, ['template' => 'SonataDoctrineMongoDBAdminBundle:CRUD:list_date.html.twig']);
}
Handle nested documents (e.g., Author embedded in Post):
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->tab('Author')
->with('Details')
->add('author.name', 'text')
->add('author.bio', 'textarea')
->end()
->end();
}
Add bulk operations:
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->add('_action', 'actions', [
'actions' => [
'edit' => [],
'delete' => [],
'publish' => ['template' => 'SonataDoctrineMongoDBAdminBundle:CRUD:list__action_publish.html.twig'],
],
]);
}
public function preBatchAction($action, QueryBuilder $query)
{
if ('publish' === $action) {
$query->update(['publishedAt' => new \DateTime()]);
}
}
Override Sonata’s templates:
{# templates/admin/PostAdmin/edit.html.twig #}
{% extends 'SonataDoctrineMongoDBAdminBundle:CRUD:edit.html.twig' %}
{% block sonata_form_buttons %}
{{ parent() }}
<button type="button" class="btn btn-primary">Custom Action</button>
{% endblock %}
Use Symfony’s form types directly:
$formMapper->add('tags', 'sonata_type_collection', [
'by_reference' => false,
'type_options' => ['delete_empty' => true],
]);
Hook into lifecycle events:
public function prePersist($post)
{
$post->setCreatedAt(new \DateTime());
}
public function preUpdate($post)
{
$post->setUpdatedAt(new \DateTime());
}
Restrict access to admins:
# config/packages/security.yaml
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
Localize labels and placeholders:
# config/packages/sonata_admin.yaml
sonata_admin:
templates:
layout: 'SonataAdminBundle::standard_layout.html.twig'
translations:
- 'en'
- 'fr'
Expose admin actions as API endpoints:
public function generateRouteName()
{
return 'api_post';
}
public function getRoutePrefix()
{
return 'api';
}
ModelManager::getMetadata()). Use updated APIs:
// Old (deprecated)
$metadata = $this->getModelManager()->getMetadata();
// New
$metadata = $this->getModelManager()->getClassMetadata(get_class($this->getSubject()));
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* @MongoDB\EmbedOne(targetDocument="Author")
*/
private $author;
ReferenceMany or ReferenceOne for relationships:
/**
* @MongoDB\ReferenceMany(targetDocument="Comment")
*/
private $comments;
php bin/console cache:clear
php bin/console sonata:admin:cache:clear
FieldDescription; use the factory:
// Old (deprecated)
$fieldDescription = new FieldDescription('title', 'string');
// New
$fieldDescription = $this->getModelManager()->getFieldDescriptionFactory()->createFieldDescription('title');
Criteria for complex queries:
$query = $this->getModelManager()->createQueryBuilder('Post')
->field('title')->equals('Hello')
->field('publishedAt')->gte(new \DateTime('-1 year'));
# config/packages/dev/sonata_admin.yaml
sonata_admin:
debug: true
How can I help you explore Laravel packages today?