PHPackages                             hostnet/entity-revision-component - 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. hostnet/entity-revision-component

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

hostnet/entity-revision-component
=================================

Listens to an event so revisions can be made

1.1.8(1mo ago)8124.1k↓15.4%3MITPHPPHP ^7.3|^8.0CI passing

Since Aug 12Pushed 1y ago5 watchersCompare

[ Source](https://github.com/hostnet/entity-revision-component)[ Packagist](https://packagist.org/packages/hostnet/entity-revision-component)[ RSS](/packages/hostnet-entity-revision-component/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (10)Versions (14)Used By (0)

README
======

[](#readme)

- [What is the Revision Component?](#what-is-the-entity-revision-component)
- [Requirements](#requirements)
- [Installation](#installation)

### Documentation

[](#documentation)

- [How does it work?](#how-does-it-work)
- [Setup](#setup)
    - [Registering the Events](#registering-the-events)
    - [Creating a Revision Entity](#creating-a-revision-entity)
    - [Configuring the Entity](#configuring-the-entity)
    - [Creating the AcmeRevisionFactory](#creating-the-acmerevisionfactory)
    - [What's Next?](#whats-next)

What is the Entity Revision Component?
--------------------------------------

[](#what-is-the-entity-revision-component)

The Entity Revision Component is a library that utilizes the [Entity Tracker Component](https://github.com/hostnet/entity-tracker-component/) and lets you hook in to the entityChanged event.

This component lets you automatically store revisions for a set of entities per flush.

Requirements
------------

[](#requirements)

The revision component requires a minimum of php 7.3 and runs on Doctrine2. For specific requirements, please check [composer.json](../master/composer.json).

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

[](#installation)

Installing is pretty easy, this package is available on [packagist](https://packagist.org/packages/hostnet/entity-revision-component). You can register the package locked to a major as we follow [Semantic Versioning 2.0.0](http://semver.org/).

#### Example

[](#example)

```
    "require" : {
        "hostnet/entity-revision-component" : "1.*"
    }
```

> Note: You can use dev-master if you want the latest changes, but this is not recommended for production code!

Documentation
=============

[](#documentation-1)

How does it work?
-----------------

[](#how-does-it-work)

It works by putting the `@Revision` annotation and RevisionableInterface on your Entity and registering the listener on the entityChanged event, assuming you have already configured the [Entity Tracker Component](https://github.com/hostnet/entity-tracker-component/#setup).

For a usage example, follow the setup below.

> Note: this component works very well with the [Entity Mutation Component](https://github.com/hostnet/entity-mutation-component). This combination is ideal to go back in time based on revisions.

Setup
-----

[](#setup)

- You have to add `@Revision` to your entity
- You have to add the RevisionableInterface to your entity
- You need a Revision Entity

#### Registering the events

[](#registering-the-events)

Here's an example of a very basic setup. Setting this up will be a lot easier if you use a framework that has a Dependency Injection Container.

It might look a bit complicated to set up, but it's pretty much setting up the tracker component for the most part. If you use it in a framework, it's recommended to create a framework specific configuration package for this to automate this away.

> Note: If you use Symfony2, you can take a look at the [hostnet/entity-tracker-bundle](https://github.com/hostnet/entity-tracker-bundle). This bundle is designed to configure the services for you.

```
use Acme\Bundle\AcmeBundle\AcmeRevisionFactory;
use Hostnet\Component\EntityRevision\Resolver\RevisionResolver;
use Hostnet\Component\EntityTracker\Listener\EntityChangedListener;
use Hostnet\Component\EntityTracker\Provider\EntityAnnotationMetadataProvider;
use Hostnet\Component\EntityTracker\Provider\EntityMutationMetadataProvider;

/* @var $em \Doctrine\ORM\EntityManager */
$event_manager = $em->getEventManager();

// default doctrine annotation reader
$annotation_reader = new AnnotationReader();

// setup required providers
$mutation_metadata_provider   = new EntityMutationMetadataProvider($annotation_reader);
$annotation_metadata_provider = new EntityAnnotationMetadataProvider($annotation_reader);
$logger = ...; // instance of LoggerInterface from the psr/log package, optional argument

// pre flush event listener that uses the @Revision annotation
$entity_changed_listener = new EntityChangedListener(
    $mutation_metadata_provider,
    $annotation_metadata_provider,
    $logger
);

// the resolver is used to find the correct annotation
$revision_resolver = new RevisionResolver($annotation_metadata_provider);

// this factory will provide the revision and as author Henk
$revision_factory = new AcmeRevisionFactory('Henk');

// creating the revision listener
$revision_listener = new RevisionListener($revision_resolver, $revision_factory);

$event_manager->addEventListener('preFlush', $entity_changed_listener);
$event_manager->addEventListener('postFlush', $revision_listener);
$event_manager->addEventListener('entityChanged', $revision_listener);
```

> Note: The RevisionListener must be registered on both the onFlush and entityChanged. Because the revisions are grouped per flush, you must also make sure that the RevisionListener is registered *before* the EntityChangedListener. If this is not done, you will recieve unexpected results.

#### Creating a Revision Entity

[](#creating-a-revision-entity)

Revisions are stored in the database, thus need an Entity. You're free to decide how to store it but you should implement the RevisionInterface on it.

```
use Doctrine\ORM\Mapping as ORM;
use Hostnet\Component\EntityRevision\RevisionInterface;

/**
 * @ORM\Entity
 */
class Revision implements RevisionInterface
{

    /**
     * @ORM\...
     */
    private $author;

    /**
     * @ORM\...
     */
    private $created_at;

    public function __construct($author, \DateTime $created_at)
    {
        $this->author     = $author;
        $this->created_at = $created_at;
    }

    public function getUser()
    {
        return $this->author;
    }

    public function getCreatedAt()
    {
        return $this->created_at;
    }
}
```

#### Configuring the Entity

[](#configuring-the-entity)

All we have to do now is put the `@Revision` annotation and RevisionableInterface on our Entity.

```
use Doctrine\ORM\Mapping as ORM;
use Hostnet\Component\EntityRevision\RevisionableInterface;

/**
 * @ORM\Entity
 * @Revision
 */
class MyEntity implements RevisionableInterface
{
    /**
     * The current revision of the contact person
     *
     * @ORM\ManyToOne(targetEntity="Revision")
     * @ORM\JoinColumn(name="revision_id", referencedColumnName="id")
     * @var Revision
     */
    private $revision;

    public function setRevision(RevisionInterface $revision)
    {
        $this->revision = $revision;
    }

    public function getRevision()
    {
        return $this->revision;
    }
}
```

#### Creating the AcmeRevisionFactory

[](#creating-the-acmerevisionfactory)

The factory is responsible for providing a revision Entity. You're free to fill in what you want and not obligated to using a constructor like in this example. The only requirement is that it creates a Revision.

```
namespace Acme\Bundle\AcmeBundle;

use Hostnet\Component\EntityRevision\Factory\RevisionFactoryInterface;

class AcmeRevisionFactory implements RevisionFactoryInterface
{
    private $author;

    public function __construct($author)
    {
        $this->author = $author;
    }

    public function createRevision(\DateTime $created_at)
    {
        return new Revision($this->author, $created_at);
    }
}
```

#### What's next?

[](#whats-next)

All you have to do now is change multiple entities with `@Revision` and they will be grouped by a Revision Entity.

```
// imagine all instances to be Revisionable
$user->setName('Henk');
$address->setNumber('42');
$em->flush();
var_dump($user->getRevision() === $address->getRevision()); // true
```

###  Health Score

53

—

FairBetter than 97% of packages

Maintenance63

Regular maintenance activity

Popularity38

Limited adoption so far

Community20

Small or concentrated contributor base

Maturity75

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

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 ~385 days

Recently: every ~609 days

Total

12

Last Release

54d ago

Major Versions

0.0.2 → 1.0.02014-09-10

PHP version history (4 changes)0.0.1PHP 5.\*, &gt;=5.4

1.1.1PHP 7.0.\*|&gt;=5.5

1.1.3PHP 5.\*,&gt;=5.6||7.\*

1.1.5PHP ^7.3|^8.0

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/5468127?v=4)[Yannick de Lange](/maintainers/yannickl88)[@yannickl88](https://github.com/yannickl88)

![](https://www.gravatar.com/avatar/65433e1ef6edb2e8f96e18614b6618c84eed20ad0de6de0d0da36a9032ec7a18?d=identicon)[hostnet](/maintainers/hostnet)

---

Top Contributors

[![janlam7](https://avatars.githubusercontent.com/u/5459235?v=4)](https://github.com/janlam7 "janlam7 (12 commits)")[![yannickl88](https://avatars.githubusercontent.com/u/5468127?v=4)](https://github.com/yannickl88 "yannickl88 (6 commits)")[![linaori](https://avatars.githubusercontent.com/u/1754678?v=4)](https://github.com/linaori "linaori (4 commits)")[![nicoschoenmaker](https://avatars.githubusercontent.com/u/1469323?v=4)](https://github.com/nicoschoenmaker "nicoschoenmaker (4 commits)")[![nutama](https://avatars.githubusercontent.com/u/9001392?v=4)](https://github.com/nutama "nutama (2 commits)")[![rickprent](https://avatars.githubusercontent.com/u/2202733?v=4)](https://github.com/rickprent "rickprent (1 commits)")[![stefanlenselink](https://avatars.githubusercontent.com/u/834562?v=4)](https://github.com/stefanlenselink "stefanlenselink (1 commits)")[![StijnKlopper2k](https://avatars.githubusercontent.com/u/198602351?v=4)](https://github.com/StijnKlopper2k "StijnKlopper2k (1 commits)")[![eddypouw](https://avatars.githubusercontent.com/u/8748009?v=4)](https://github.com/eddypouw "eddypouw (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/hostnet-entity-revision-component/health.svg)

```
[![Health](https://phpackages.com/badges/hostnet-entity-revision-component/health.svg)](https://phpackages.com/packages/hostnet-entity-revision-component)
```

###  Alternatives

[hautelook/alice-bundle

Symfony bundle to manage fixtures with Alice and Faker.

19519.4M34](/packages/hautelook-alice-bundle)[kimai/kimai

Kimai - Time Tracking

4.6k7.4k1](/packages/kimai-kimai)[scienta/doctrine-json-functions

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

58723.9M36](/packages/scienta-doctrine-json-functions)[sonata-project/entity-audit-bundle

Audit for Doctrine Entities

644989.8k1](/packages/sonata-project-entity-audit-bundle)[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)[baraja-core/doctrine-fulltext-search

Entity search engine, extremely easy to use.

2070.6k3](/packages/baraja-core-doctrine-fulltext-search)

PHPackages © 2026

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