PHPackages                             alexandrebulete/ddd-doctrine-bridge - 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. alexandrebulete/ddd-doctrine-bridge

ActiveLibrary[Database &amp; ORM](/categories/database)

alexandrebulete/ddd-doctrine-bridge
===================================

Doctrine ORM bridge for DDD Foundation - Pure PHP, no framework dependency

1.1.3(3mo ago)12↓33.3%1MITPHPPHP ^8.2

Since Dec 27Pushed 3mo agoCompare

[ Source](https://github.com/AlexandreBulete/ddd-doctrine-bridge)[ Packagist](https://packagist.org/packages/alexandrebulete/ddd-doctrine-bridge)[ RSS](/packages/alexandrebulete-ddd-doctrine-bridge/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (4)Versions (6)Used By (1)

DDD Doctrine Bridge
===================

[](#ddd-doctrine-bridge)

Doctrine ORM bridge for DDD Foundation. This package provides repository and paginator implementations using Doctrine, plus custom DBAL types for Value Objects.

**Pure PHP** - No framework dependency. Use with any PHP framework.

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

[](#installation)

```
composer require alexandrebulete/ddd-doctrine-bridge
```

For Symfony integration, also install:

```
composer require alexandrebulete/ddd-doctrine-bundle
```

Structure
---------

[](#structure)

```
src/
├── DoctrineRepository.php
├── DoctrinePaginator.php
├── DispatchesDomainEvents.php
├── Capability/
│   ├── AsReadable.php          # CanFindById + CanFindAll
│   ├── AsMutable.php           # CanPersist + CanRemove + DispatchesDomainEvents
│   └── AsCrudable.php          # AsReadable + AsMutable
├── Operation/
│   ├── CanPersist.php          # persistAndFlush()
│   ├── CanRemove.php           # removeAndFlush()
│   ├── CanFindById.php         # findEntityById()
│   └── CanFindAll.php          # findAllEntities()
├── Enum/
│   └── WhenDispatchDomainEventsEnum.php
└── Type/
    ├── BaseType.php
    ├── GuidType.php
    ├── TextType.php
    ├── VarcharType.php
    └── Convertor/
        ├── AsIdentifierConvertor.php
        └── AsStringConvertor.php

```

Repository Traits
-----------------

[](#repository-traits)

Granular traits to compose your repositories with only the capabilities you need.

### Capability Traits (High-level)

[](#capability-traits-high-level)

TraitIncludesUse case`AsReadable`CanFindById, CanFindAllRead-only repositories`AsMutable`CanPersist, CanRemove, DispatchesDomainEventsWrite-only repositories`AsCrudable`AsReadable, AsMutableFull CRUD repositories### Operation Traits (Atomic)

[](#operation-traits-atomic)

TraitMethodDescription`CanPersist``persistAndFlush()`Persist and flush entity`CanRemove``removeAndFlush()`Remove and flush entity`CanFindById``findEntityById()`Find entity by ID`CanFindAll``findAllEntities()`Find all entities### Usage Examples

[](#usage-examples)

#### Full CRUD Repository

[](#full-crud-repository)

```
use AlexandreBulete\DddDoctrineBridge\DoctrineRepository;
use AlexandreBulete\DddDoctrineBridge\Capability\AsCrudable;
use AlexandreBulete\DddFoundation\Application\Event\EventDispatcherInterface;

class DoctrinePostRepository extends DoctrineRepository implements PostRepositoryInterface
{
    use AsCrudable;

    public function __construct(
        EntityManagerInterface $em,
        private readonly EventDispatcherInterface $eventDispatcher,
    ) {
        parent::__construct($em, Post::class, 'post');
    }

    public function save(Post $post): void
    {
        $this->persistAndFlush(
            entity: $post,
            dispatchEvents: true,
            whenDispatchEvents: WhenDispatchDomainEventsEnum::AFTER,
        );
    }

    public function delete(Post $post): void
    {
        $this->removeAndFlush($post);
    }

    public function findById(IdentifierVO $id): ?Post
    {
        return $this->findEntityById(Post::class, $id->toRfc4122());
    }

    public function findAll(): array
    {
        return $this->findAllEntities();
    }
}
```

#### Read-Only Repository

[](#read-only-repository)

```
use AlexandreBulete\DddDoctrineBridge\DoctrineRepository;
use AlexandreBulete\DddDoctrineBridge\Capability\AsReadable;

class DoctrineCountryRepository extends DoctrineRepository
{
    use AsReadable;

    public function __construct(EntityManagerInterface $em)
    {
        parent::__construct($em, Country::class, 'country');
    }

    public function findById(IdentifierVO $id): ?Country
    {
        return $this->findEntityById(Country::class, $id->value());
    }

    public function findAll(): array
    {
        return $this->findAllEntities();
    }
}
```

#### Custom Mix (Persist without Delete)

[](#custom-mix-persist-without-delete)

```
use AlexandreBulete\DddDoctrineBridge\DoctrineRepository;
use AlexandreBulete\DddDoctrineBridge\Capability\AsReadable;
use AlexandreBulete\DddDoctrineBridge\Operation\CanPersist;
use AlexandreBulete\DddDoctrineBridge\DispatchesDomainEvents;

class DoctrineAuditLogRepository extends DoctrineRepository
{
    use AsReadable;
    use CanPersist;
    use DispatchesDomainEvents;

    // Can read and create, but NOT delete
}
```

Domain Events
-------------

[](#domain-events)

Dispatch domain events from your aggregates after persistence.

### When to Dispatch

[](#when-to-dispatch)

```
use AlexandreBulete\DddDoctrineBridge\Enum\WhenDispatchDomainEventsEnum;

// Dispatch AFTER flush (recommended - ensures transaction committed)
$this->persistAndFlush($entity, dispatchEvents: true, whenDispatchEvents: WhenDispatchDomainEventsEnum::AFTER);

// Dispatch BEFORE flush (rare - event dispatched even if flush fails)
$this->persistAndFlush($entity, dispatchEvents: true, whenDispatchEvents: WhenDispatchDomainEventsEnum::BEFORE);
```

### Requirements

[](#requirements)

Your entity must use the `RecordsEvents` trait from `ddd-foundation`:

```
use AlexandreBulete\DddFoundation\Domain\Model\RecordsEvents;

class Post
{
    use RecordsEvents;

    public function publish(): void
    {
        $this->status = 'published';
        $this->recordEvent(new PostPublished($this->id));
    }
}
```

Custom Doctrine Types
---------------------

[](#custom-doctrine-types)

Create custom Doctrine types for your Value Objects:

```
use AlexandreBulete\DddDoctrineBridge\Type\GuidType;
use App\Post\Domain\ValueObject\PostId;

class PostIdType extends GuidType
{
    protected string $name = 'post_id';
    protected string $voClass = PostId::class;
}
```

### Available Base Types

[](#available-base-types)

- **GuidType**: For UUID/ULID identifier value objects
- **VarcharType**: For string value objects (VARCHAR)
- **TextType**: For string value objects (TEXT/CLOB)

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance82

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 82.4% 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

Every ~10 days

Total

5

Last Release

97d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/15733a17c9dd08fc7def3be016f324453d4f0de828438858d13f63e7c3388353?d=identicon)[Alexandre Buleté](/maintainers/Alexandre%20Bulet%C3%A9)

---

Top Contributors

[![AlexandreBulete](https://avatars.githubusercontent.com/u/40428152?v=4)](https://github.com/AlexandreBulete "AlexandreBulete (14 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (3 commits)")

### Embed Badge

![Health badge](/badges/alexandrebulete-ddd-doctrine-bridge/health.svg)

```
[![Health](https://phpackages.com/badges/alexandrebulete-ddd-doctrine-bridge/health.svg)](https://phpackages.com/packages/alexandrebulete-ddd-doctrine-bridge)
```

###  Alternatives

[scienta/doctrine-json-functions

A set of extensions to Doctrine that add support for json query functions.

58523.9M36](/packages/scienta-doctrine-json-functions)[laravel-doctrine/orm

An integration library for Laravel and Doctrine ORM

8425.3M87](/packages/laravel-doctrine-orm)[damienharper/auditor-bundle

Integrate auditor library in your Symfony projects.

4542.8M](/packages/damienharper-auditor-bundle)[sonata-project/entity-audit-bundle

Audit for Doctrine Entities

644989.8k1](/packages/sonata-project-entity-audit-bundle)[ahmed-bhs/doctrine-doctor

Runtime analysis tool for Doctrine ORM integrated into Symfony Web Profiler. Unlike static linters, it analyzes actual query execution at runtime to detect performance bottlenecks, security vulnerabilities, and best practice violations during development with real execution context and data.

813.1k](/packages/ahmed-bhs-doctrine-doctor)[bartlett/php-compatinfo-db

Reference Database of all functions, constants, classes, interfaces on PHP standard distribution and about 110 extensions

1183.0k1](/packages/bartlett-php-compatinfo-db)

PHPackages © 2026

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