PHPackages                             3slab/vdm-library-doctrine-transport-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. 3slab/vdm-library-doctrine-transport-bundle

ActiveSymfony-bundle[Database &amp; ORM](/categories/database)

3slab/vdm-library-doctrine-transport-bundle
===========================================

Vdm Doctrine Transport

3.0.0(4y ago)0348proprietaryPHP

Since Jun 8Pushed 4y ago2 watchersCompare

[ Source](https://github.com/3slab/VdmLibraryDoctrineTransportBundle)[ Packagist](https://packagist.org/packages/3slab/vdm-library-doctrine-transport-bundle)[ RSS](/packages/3slab-vdm-library-doctrine-transport-bundle/feed)WikiDiscussions 3.x-dev Synced 2d ago

READMEChangelog (1)Dependencies (3)Versions (2)Used By (0)

Vdm Library Doctrine Transport
==============================

[](#vdm-library-doctrine-transport)

[![Build Status](https://camo.githubusercontent.com/b19c11b0a5937d59dbc280950a282576ff85fae660f8e24817d0f0c567b4361c/68747470733a2f2f7472617669732d63692e636f6d2f33736c61622f56646d4c696272617279446f637472696e655472616e73706f727442756e646c652e7376673f6272616e63683d332e782d646576)](https://travis-ci.com/3slab/VdmLibraryDoctrineTransportBundle)

Installation
------------

[](#installation)

```
composer require 3slab/vdm-library-doctrine-transport-bundle
```

You need to have either (or both) doctrine ORM or ODM installed

```
composer require symfony/orm-pack
```

Or

```
composer require doctrine/mongodb-odm-bundle
```

Configuration reference
-----------------------

[](#configuration-reference)

There are two parts ton configure: the transport, and Doctrine's behaviour.

### Transport

[](#transport)

In `messenger.yaml`:

```
framework:
    messenger:
        transports:
            producer:
                dsn: vdm+doctrine_orm://mycustomconnection
                options:
                    doctrine_executor: ~
                    default_entity: ~
                    entities:
                        App\Entity\Demande:
                            selector: RefDemande
```

ConfigurationDescriptiondsnUse `vdm+doctrine_orm://` (if entity manager) or `vdm+doctrine_odm://` (if document manager). Optionnaly, you can specify the connection to use with `vdm+doctrine_orm://mycustomconnection` (fits into `doctrine.orm.xxx_entity_manager`).options.doctrine\_executorset the id (in the container of services) of a custom doctrine executor to use instead of the [DefaultDoctrineExecutor](./Executor/DefaultDoctrineExecutor.php)options.default\_entityset the class of default entity to populate if none passed in the message metadatasoptions.entitiesArray of entities to register. At least one entity must be declared.options.entities.FQCN.selector(optional) Define how the executor will try and fetch a pre-existing entity before persisting (see below)Fetching pre-existing entity
----------------------------

[](#fetching-pre-existing-entity)

Before persisting anything, this transport will always try to find an existing entity. You need to tell it how to proceed. You have several ways of doing it.

### The natural way

[](#the-natural-way)

It means that your entity bears a unique identifier value, such as:

```
    /**
     * @ORM\Id()
     */
    private $id;
```

If this value is carried by the incoming message, then you have nothing to configure. The only responsability on your end is making sure there is a public getter for this property (if there isn't you'll get a clear error message anyway).

**Note**: in this case, the sender will use the `find` method on the repository.

### Multifield with natural getters

[](#multifield-with-natural-getters)

In case you don't have a mono-column primary key (ex: no key at all or composite key), you can turn to another approach and tell the executor which fields should be used to retrieve a pre-existing entity. For instance, if your entity has two fields representing its identity (let's say `code` and `hash`), and they both have a natural getter (i.e. `getCode` and `getHash`), then you need to configure the options like this:

```
framework:
    messenger:
        transports:
            producer:
                dsn: vdm+doctrine://
                options:
                    entities:
                        App\Entity\Demande:
                            selector:
                                - code
                                - hash
```

Under the hood, the repository will be called like:

```
$repo->findOneBy([ 'code' => $yourEntity->getCode(), 'hash' => $yourEntity->getHash() ])
```

**Note**: Notice the `findOneBy`. The sender will use the first matching entity. It's your responsability to provide a unique set of filter.

### Multifield with non-natural getters

[](#multifield-with-non-natural-getters)

In case the fields related to the identity have unnatural getters (ex: legacy code, multilingual code), you can define which getter to use to fetch the appropriate property. Let's say the identity is made of two fields: `label`and `hash`, which respective getters are `getLibelle()` and `hash()`. You will need configure the sender as such:

```
framework:
    messenger:
        transports:
            producer:
                dsn: vdm+doctrine://
                options:
                    entities:
                        App\Entity\Demande:
                            selector:
                                label: getLibelle
                                hash: hash
```

Under the hood, the repository will be called like:

```
    $repo->findOneBy([ 'label' => $yourEntity->getLibelle(), 'hash' => $yourEntity->hash() ])
```

The same policy as natural getters apply: you have to make sure it returns something as unique as possible.

You can define several entities at once, and mix natural and non-natural getters. However, you will have to prefix your natural getters with integer keys. The key itself doesn't matter (as long as you don't create duplicates), it just needs to be an integer. If the key is an integer, the getter will be guessed. Otherwise, the getter will be what you provide

```
framework:
    messenger:
        transports:
            producer:
                dsn: vdm+doctrine://
                options:
                    entities:
                        App\Entity\Foo:
                            selector:
                                0: code # hack to mix natural and non-natural getters
                                label: getLibelle #non natural getter
                                hash: hash #non natural getter
                        App\Entity\Bar: ~ # Bar has a single-field identity (id) with natural getter, no configuration needed
                        App\Entity\Baz:
                            selector:
                                - reference # Baz uses a filter based on its reference with natural getter (getReference)
```

Under the hood, the repository will fetch the entities like this:

```
// Foo
$repo->findOneBy([ 'code' => $foo->getCode(), 'label' => $foo->getLibelle(), 'hash' => $foo->hash() ]);

// Bar
$repo->find($bar->getId());

// Baz
$repo->findOneBy([ 'reference' => $baz->getReference() ]);
```

Doctrine Executor
-----------------

[](#doctrine-executor)

Doctrine executor allows you to customize the behavior of the doctrine ORM transport per transport definition inside your `messenger.yaml` file.

If you don't set a custom `doctrine_executor` option when declaring the transport, the default [DefaultDoctrineExecutor](./Executor/DefaultDoctrineExecutor.php) is used.

You can override this behavior in your project by providing a class that extends `Vdm\Bundle\LibraryDoctrineTransportBundle\Executor\AbstractDoctrineExecutor`.

```
namespace App\Executor\Doctrine;

use Vdm\Bundle\LibraryDoctrineTransportBundle\Executor\AbstractDoctrineExecutor;
use Vdm\Bundle\LibraryBundle\Model\Message;

class CustomDoctrineExecutor extends AbstractDoctrineExecutor
{
    public function execute(Message $message): void
    {
        if (!$this->manager) {
            throw new NoConnectionException('No connection was defined.');
        }

        $entityMetadatas = $message->getMetadatasByKey('entity');
        $entityMetadata  = array_shift($entityMetadatas);
        $entityClass     = $entityMetadata->getValue();
        $entity          = $this->serializer->denormalize($message->getPayload(), $entityClass);
        $entity          = $this->matchEntity($entity);

        $this->manager->persist($entity);
        $this->manager->flush();
    }
}
```

Then references this custom executor in your transport definition in your project `messenger.yaml` :

```
framework:
    messenger:
        transports:
            store-entity:
                options:
                    doctrine_executor: App\Executor\Doctrine\CustomDoctrineExecutor
```

Entity/Document Matching
------------------------

[](#entitydocument-matching)

For the transport to know to which entities or documents the payload should be persisted, you can either :

- provide the entity's fully qualified class name in the message's metadata, with key `entity`. Example `new Metadata('entity', 'App\Entity\Foo')`.
- configure a default entity on the transport level

```
framework:
    messenger:
        transports:
            store-entity:
                options:
                    default_entity: App\Entity\Foo
```

Limitations
-----------

[](#limitations)

You cannot use different connections for different entities within one single transport. Should you have such a need, you should define one transport per connection, extends the library's Message (one per producer) and route the correct message to the correct producer.

###  Health Score

25

—

LowBetter than 37% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity13

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

1800d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/1c22c6eb06bd9de96a2a9391672ce4fee607a63c08c635b539dba8667be570f7?d=identicon)[3slab](/maintainers/3slab)

---

Top Contributors

[![jbouzekri](https://avatars.githubusercontent.com/u/880996?v=4)](https://github.com/jbouzekri "jbouzekri (2 commits)")

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/3slab-vdm-library-doctrine-transport-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/3slab-vdm-library-doctrine-transport-bundle/health.svg)](https://phpackages.com/packages/3slab-vdm-library-doctrine-transport-bundle)
```

###  Alternatives

[doctrine/orm

Object-Relational-Mapper for PHP

10.2k285.3M6.2k](/packages/doctrine-orm)[jdorn/sql-formatter

a PHP SQL highlighting library

3.9k115.1M102](/packages/jdorn-sql-formatter)[illuminate/database

The Illuminate Database package.

2.8k52.4M9.4k](/packages/illuminate-database)[mongodb/mongodb

MongoDB driver library

1.6k64.0M546](/packages/mongodb-mongodb)[ramsey/uuid-doctrine

Use ramsey/uuid as a Doctrine field type.

90340.3M211](/packages/ramsey-uuid-doctrine)[reliese/laravel

Reliese Components for Laravel Framework code generation.

1.7k3.4M16](/packages/reliese-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
