tttptd / laravel-doctrine-odm
Doctrine MongoDB ODM integration for Laravel
Requires
- php: ^8.2
- ext-mongodb: *
- doctrine/annotations: ^2.0
- doctrine/mongodb-odm: ^2.11.3
- gedmo/doctrine-extensions: ^3.15
- laravel/framework: ^11.0 || ^12.0
- predis/predis: ^3.2
- symfony/cache: ^7.3
- symfony/console: ^7.0
Requires (Dev)
- orchestra/testbench: ^9.0 || ^10.0
- phpunit/phpunit: ^11.0
README
| title | TTTPTD Laravel Doctrine ODM |
|---|---|
| description | Laravel package for Doctrine MongoDB ODM integration. |
TTTPTD Laravel Doctrine ODM
Laravel package for integrating Doctrine MongoDB ODM with Laravel applications.
This package started as a fork of chefsplate/laravel-doctrine-odm. The original project has not been maintained for a long time, so the fork was adapted for current Laravel applications and used privately in production projects for about a year and a half before being published. It is now public to make that work reusable, but the API and documentation are still being shaped around real project usage.
Table of Contents
- Background
- What It Solves
- Requirements
- Installation
- Configuration
- Usage
- Artisan Commands
- Testing
- Local Package Development
Background
This package is based on chefsplate/laravel-doctrine-odm. Since the upstream package appeared to be abandoned and no longer tracked modern Laravel and Doctrine ODM versions, this fork evolved as a private, project-driven continuation. It has been used in real applications for roughly eighteen months before this public release.
What It Solves
Laravel does not include first-party Doctrine MongoDB ODM integration. This package provides the Laravel bridge:
- registers Doctrine
DocumentManagerin the Laravel container; - publishes a MongoDB ODM config file;
- configures attribute metadata mapping;
- configures Doctrine proxies and hydrators;
- registers Gedmo Timestampable and Sluggable listeners;
- exposes Doctrine ODM console commands through Artisan;
- provides a small
PersistenceManagerabstraction for application code.
The package registers DocumentManager and PersistenceManager as scoped services. This is intentional: Doctrine DocumentManager is stateful and keeps an identity map/unit of work. In Laravel requests and queue jobs, one manager per lifecycle is the correct boundary; a singleton would leak stale documents between queue jobs.
Requirements
- PHP 8.2+
- Laravel 11 or 12
- MongoDB PHP extension
- MongoDB server
Install the MongoDB extension before installing the package:
pecl install mongodb
Then enable it in your PHP configuration if your environment does not do that automatically.
Installation
Install the package from Packagist:
composer require tttptd/laravel-doctrine-odm:^0.1
Laravel package discovery registers the service provider automatically:
Ys\LaravelOdm\DoctrineMongoDBServiceProvider::class
Publish the config:
php artisan vendor:publish --provider="Ys\LaravelOdm\DoctrineMongoDBServiceProvider"
This creates:
config/mongodb.php
Configuration
Minimal .env example:
DB_MONGO_SERVER=mongodb://localhost:27017 DB_MONGO_DATABASE=app DOCTRINE_METADATA_CACHE=array DOCTRINE_PROXY_AUTOGENERATE=2
Default document path:
'documents' => [ base_path('app/Documents'), ],
For modular applications, configure all document roots explicitly:
'documents' => [ base_path('app/Documents'), base_path('domain/Art'), base_path('domain/Commerce'), ],
If some directories must be skipped by the metadata driver, add exclude_documents:
'exclude_documents' => [ base_path('domain/Art/tests'), ],
Proxy and hydrator files are generated into:
'proxies' => [ 'namespace' => 'Proxies', 'path' => storage_path('mongo_proxies'), ], 'hydrators' => [ 'namespace' => 'Hydrators', 'path' => storage_path('mongo_hydrators'), ],
For production, disable automatic proxy generation and generate proxies during deploy:
DOCTRINE_PROXY_AUTOGENERATE=2
2 means Configuration::AUTOGENERATE_FILE_NOT_EXISTS. The package also supports 3, Configuration::AUTOGENERATE_EVAL, which is useful only for development.
Usage
Inject Doctrine DocumentManager directly when you need full ODM APIs:
use Doctrine\ODM\MongoDB\DocumentManager; final readonly class CreateArticleHandler { public function __construct( private DocumentManager $documentManager, ) { } public function handle(Article $article): void { $this->documentManager->persist($article); $this->documentManager->flush(); } }
Or inject the package abstraction when application code only needs persistence operations:
use Ys\LaravelOdm\ODM\PersistenceManager; final readonly class CreateArticleHandler { public function __construct( private PersistenceManager $persistenceManager, ) { } public function handle(Article $article): void { $this->persistenceManager->persist($article); $this->persistenceManager->flush(); } }
Example document:
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM; #[ODM\Document(collection: 'articles')] final class Article { #[ODM\Id] private ?string $id = null; #[ODM\Field(type: 'string')] private string $title; }
Artisan Commands
The package wraps common Doctrine ODM console commands as Artisan commands:
php artisan odm:generate:proxies php artisan odm:generate:hydrators php artisan odm:query php artisan odm:clear-cache:metadata php artisan odm:schema:create php artisan odm:schema:drop php artisan odm:schema:update php artisan odm:schema:shard
Run Artisan list in your application to see the exact command signatures:
php artisan list odm
Testing
Install development dependencies:
composer install
Run the test suite:
composer test
The package uses PHPUnit 11 and Orchestra Testbench. The current tests cover:
- Laravel service provider registration;
- config publishing path;
DocumentManagerFactorysingleton lifetime;- scoped
DocumentManagerlifecycle; PersistenceManagerbinding to the current scopedDocumentManager;- Doctrine metadata loading from configured document paths;
- cache adapter creation;
PersistenceManagerDoctrinedelegation to Doctrine ODM.
The integration tests do not require a running MongoDB server. They verify container/config/metadata behavior without opening a database connection.
Local Package Development
For active development inside a Laravel application, clone this package next to the application:
~/example/laravel-doctrine-odm
In the application composer.json, temporarily add a path repository before installing/updating the package:
{
"repositories": [
{
"type": "path",
"url": "/Users/user/example/laravel-doctrine-odm",
"options": {
"symlink": true
}
}
]
}
Then update only this dependency:
composer update tttptd/laravel-doctrine-odm -W
With symlink: true, changes in the package checkout are immediately visible in the Laravel application.
Before committing application changes meant for CI/production, make sure composer.lock does not lock the package to a local path repository unless that is intentional. Public projects should normally resolve this package from Packagist.