PHPackages                             inwebo/doctrine-event-sourcing - 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. inwebo/doctrine-event-sourcing

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

inwebo/doctrine-event-sourcing
==============================

Simple Event sourcing pattern implementation with DoctrineListener

1.0.3(1y ago)112GPL-3.0-or-laterPHPPHP ^8.3CI passing

Since Apr 11Pushed 1y ago1 watchersCompare

[ Source](https://github.com/inwebo/doctrine-event-sourcing)[ Packagist](https://packagist.org/packages/inwebo/doctrine-event-sourcing)[ Docs](https://github.com/inwebo/doctrine-event-sourcing)[ RSS](/packages/inwebo-doctrine-event-sourcing/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (7)Versions (6)Used By (0)

Doctrine-event-sourcing
=======================

[](#doctrine-event-sourcing)

[![GitHub Actions Workflow Status](https://camo.githubusercontent.com/8190806f5bcc657652c48369d7f96bf2460fa52c9888663852f0c49b395859b4/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f696e7765626f2f646f637472696e652d6576656e742d736f757263696e672f2e676974687562253246776f726b666c6f777325324673796d666f6e792e796d6c3f6272616e63683d6d6173746572267374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/8190806f5bcc657652c48369d7f96bf2460fa52c9888663852f0c49b395859b4/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f696e7765626f2f646f637472696e652d6576656e742d736f757263696e672f2e676974687562253246776f726b666c6f777325324673796d666f6e792e796d6c3f6272616e63683d6d6173746572267374796c653d666c61742d737175617265)[![Packagist Version](https://camo.githubusercontent.com/990301643cb53c660c00dfbe49a31439a2e5ef1c6820ba84dd63566ba79b5ea1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f696e7765626f2f646f637472696e652d6576656e742d736f757263696e673f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/990301643cb53c660c00dfbe49a31439a2e5ef1c6820ba84dd63566ba79b5ea1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f696e7765626f2f646f637472696e652d6576656e742d736f757263696e673f7374796c653d666c61742d737175617265)[![Packagist Downloads](https://camo.githubusercontent.com/fa5358fe88dee205452bf49038b669a475864d0748268e7e33d3ab2473c055c5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64642f696e7765626f2f646f637472696e652d6576656e742d736f757263696e673f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/fa5358fe88dee205452bf49038b669a475864d0748268e7e33d3ab2473c055c5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64642f696e7765626f2f646f637472696e652d6576656e742d736f757263696e673f7374796c653d666c61742d737175617265)[![Packagist Dependency Version](https://camo.githubusercontent.com/c2e3fe92a0f16e21b743f18031d44790e957412db79702fcb25bf4bc2bab90a4/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646570656e64656e63792d762f696e7765626f2f646f637472696e652d6576656e742d736f757263696e672f7068703f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/c2e3fe92a0f16e21b743f18031d44790e957412db79702fcb25bf4bc2bab90a4/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646570656e64656e63792d762f696e7765626f2f646f637472696e652d6576656e742d736f757263696e672f7068703f7374796c653d666c61742d737175617265)[![Packagist Dependency Version](https://camo.githubusercontent.com/4257dbed6cbfcb0eb923f68781a92e24301b4d488780f3e32ccf872e275b2fed/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646570656e64656e63792d762f696e7765626f2f646f637472696e652d6576656e742d736f757263696e672f646f637472696e652532466f726d3f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/4257dbed6cbfcb0eb923f68781a92e24301b4d488780f3e32ccf872e275b2fed/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646570656e64656e63792d762f696e7765626f2f646f637472696e652d6576656e742d736f757263696e672f646f637472696e652532466f726d3f7374796c653d666c61742d737175617265)

Simple Event sourcing pattern implementation with DoctrineListener

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

[](#installation)

```
  composer req inwebo/doctrine-event-sourcing
```

Tests
-----

[](#tests)

```
  composer phpunit
```

PhpStan
-------

[](#phpstan)

```
  composer phpstan
```

> Level 10

Core Concepts
-------------

[](#core-concepts)

- **[\#\[AggregateRoot\]](./src/Mapping/AggregateRoot.php)**: A Doctrine entity whose state changes are tracked. Marked with the #\[AggregateRoot\] attribute. It must implement HasStatesInterface.
- **[\#\[AggregateSource\]](./src/Mapping/AggregateSource.php)**: A property within an Aggregate Root whose changes should be tracked. Marked with the #\[AggregateSource\] attribute. Requires getter and setter methods in both the Aggregate Root and the associated State entity.
- **[State](./src/Model/Interface/StateInterface.php)**: A separate Doctrine entity designed to store a snapshot of the tracked properties of an Aggregate Root at a specific point in time. It must implement StateInterface and have a ManyToOne relationship back to its Aggregate Root.
- **[StoreListener](./src/Listener/StoreListener.php)**: A Doctrine Entity Listener (e.g., StoreListener) that hooks into prePersist and preUpdate events. It uses the Aggregator to create and persist new State entities whenever an Aggregate Root is created or modified.
- **[MappingFactory](./src/Model/MappingFactory.php)**: Responsible for parsing the #\[AggregateRoot\] and #\[AggregateSource\] attributes on a subject class, validating the configuration, and creating Mapping objects that define how properties are transferred between the subject and its state.
- **[MappingFactory](./src/Model/Aggregator.php)**: Uses the mapping information provided by MappingFactory to create new State entities from an Aggregate Root or apply a specific State back onto an Aggregate Root.
- **[HistoricResolver](src/Resolver/DiffResolver.php)**: Enables querying the history of changes for an Aggregate Root by comparing consecutive State entities.

Setup and Usage
---------------

[](#setup-and-usage)

### 1. Installation:

[](#1-installation)

```
  composer req inwebo/doctrine-event-sourcing
```

### 2. Define the Aggregate Root (Subject):

[](#2-define-the-aggregate-root-subject)

- This is your main Doctrine entity.
- Annotate the class with #\[ORM\\EntityListeners(\[StoreListener::class\])\] (or your custom listener).
- Annotate the class with #\[AggregateRoot\], providing the stateClass (FQCN of your State entity) and subjectSetter (the method name in the State entity used to set the relationship back to this Aggregate Root).
- Implement the HasStatesInterface. Typically, you'll need a OneToMany relationship to store the states.
- Annotate the properties you want to track with #\[AggregateSource\], specifying the getter and setter method names. These methods must exist in both the Aggregate Root and the State entity.

```
