PHPackages                             magomogo/domain-model - 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. magomogo/domain-model

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

magomogo/domain-model
=====================

A way to make domain-specific models persistent

v3.0.0(3y ago)712.4k—3.3%6[1 issues](https://github.com/Magomogo/persisted-models/issues)MITPHPPHP ^7.1 || ^8.0CI failing

Since Dec 12Pushed 1y ago1 watchersCompare

[ Source](https://github.com/Magomogo/persisted-models)[ Packagist](https://packagist.org/packages/magomogo/domain-model)[ Docs](https://github.com/Magomogo/persisted-models)[ RSS](/packages/magomogo-domain-model/feed)WikiDiscussions master Synced 2d ago

READMEChangelog (3)Dependencies (5)Versions (18)Used By (0)

Persisted models
================

[](#persisted-models)

[![Build Status](https://camo.githubusercontent.com/75ae744054018ea251c4acb9dc5d06a4c232f0bac87b923511f5fc56510a8cc6/68747470733a2f2f7472617669732d63692e6f72672f4d61676f6d6f676f2f7065727369737465642d6d6f64656c732e706e673f6272616e63683d6d6173746572)](https://travis-ci.org/Magomogo/persisted-models)

Intro
-----

[](#intro)

- I don't like ActiveRecord because of tight coupling with the database,
- I am not so comfortable with Data mappers because a mapper breaks model encapsulation,
- I like the idea to keep **'The State'** separately from the logic.

Here is the way
---------------

[](#here-is-the-way)

### The concept

[](#the-concept)

To implement an entity, one should create two classes: **Model** and **Properties**. Model class contains domain-specific logic only. All **state** that should persist is located in **Properties**. Model has its Properties aggregated:

```
class Model implements ModelInterface
{
    /**
     * @var Properties
     */
    private $properties;

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

```

This library takes care about the **Properties**, all its public fields and also relations can be saved/loaded in the **Container**s. Currently there is SqlDb, CouchDb, and Memory container.

It is recommended to declare Model's constructor signature that doesn't allow to create an instance that makes no sense from the business logic point of view.

```
$person = new Person\Model($propertiesBag);
$employee = new Employee\Model($company, $propertiesBag);

```

source: [Person\\Model](//github.com/Magomogo/persisted-models/blob/master/test/_classes/Magomogo/Persisted/Test/Person/Model.php "Person model")| [Employee\\Model](//github.com/Magomogo/persisted-models/blob/master/test/_classes/Magomogo/Persisted/Test/Employee/Model.php "Employee model")

### Obvious responsibilities

[](#obvious-responsibilities)

To achieve persistency we don't need to store **A model**, it is necessary to store its properties.

```
// save/update
$dbContainer = new Persisted\Container\SqlDb($connection);
$person->save($dbContainer);

// load
$persistedPerson = Person\Model::load($dbContainer, $id);

```

source: [Persisted\\Container\\SqlDb](//github.com/Magomogo/persisted-models/blob/master/lib/Magomogo/Persisted/Container/SqlDb.php "Database container")

Handling user input with **'Editors'**, **'A Editor'** is kind of a Container.

```
$editor = new ProfileEditor($person);
// validation here
$editor->edit($userInput);

$editedPerson = Person\Model::load($editor);
$editedPerson->save($dbContainer);

```

### Strong separation between different types of object relations

[](#strong-separation-between-different-types-of-object-relations)

For example person properties can have contact info aggregated, it gets stored and updated together with person:

```
$contactInfoModel = new ContactInfo\Model($contactInfoProperties);

$personProperties = array(
    'name' => 'John',
    'contactInfo => $contactInfoModel
);

```

On the other hand, there is a person who's working in a company. These objects are connected by foreign key and created/updated separately.

```
$company->save($dbContainer);
$employee = new Employee\Model($company, $employeeProperties);

// this won't update the company, but create one-to-many reference company -> person in the container
$employee->save($dbContainer);

```

A model can have a list of another models connected. This so-called many-to-many relation is possible using Collections.

```
$collection = new Keymarker\Collection;
$collection['Example'] = new Keymarker\Model(new Keymarker\Properties(array('name' => 'Example'));

```

Examples
--------

[](#examples)

See test cases to learn recommended usage:

- Simply a Model with properties [Company/ModelTest.php](//github.com/Magomogo/persisted-models/blob/master/test/Company/ModelTest.php)
- A Person having CreditCard aggregated, a Person that can be tagged with Keymarkers [Person/ModelTest.php](//github.com/Magomogo/persisted-models/blob/master/test/Person/ModelTest.php)
- An Employee working in a Company [Employee/ModelTest.php](//github.com/Magomogo/persisted-models/blob/master/test/Employee/ModelTest.php)
- Keymarker model that has natural keys [Keymarker/ModelTest.php](//github.com/Magomogo/persisted-models/blob/master/test/Keymarker/ModelTest.php), [Keymarker/PropertiesTest.php](//github.com/Magomogo/persisted-models/blob/master/test/Keymarker/PropertiesTest.php)
- Load/Create/Update/Save a persistent model [ModelPersonEditorWorkflowTest.php](//github.com/Magomogo/persisted-models/blob/master/test/ModelPersonEditorWorkflowTest.php)

*...the work is in progress...*

###  Health Score

42

—

FairBetter than 88% of packages

Maintenance29

Infrequent updates — may be unmaintained

Popularity33

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity77

Established project with proven stability

 Bus Factor1

Top contributor holds 92.8% 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 ~285 days

Recently: every ~469 days

Total

14

Last Release

1194d ago

Major Versions

0.8.x-dev → v1.0.02016-09-10

v1.0.1 → v2.0.02018-08-03

v2.0.2 → v3.0.02023-03-28

PHP version history (3 changes)0.1.x-devPHP &gt;=5.3.0

v2.0.0PHP &gt;=5.6.0

v3.0.0PHP ^7.1 || ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/3b278f373383905fadd1bfdee771c682805638284672681cd5d912e74cb794ad?d=identicon)[Magomogo](/maintainers/Magomogo)

---

Top Contributors

[![Magomogo](https://avatars.githubusercontent.com/u/728657?v=4)](https://github.com/Magomogo "Magomogo (206 commits)")[![smoskalenko](https://avatars.githubusercontent.com/u/13538100?v=4)](https://github.com/smoskalenko "smoskalenko (10 commits)")[![zebooka](https://avatars.githubusercontent.com/u/2102717?v=4)](https://github.com/zebooka "zebooka (5 commits)")[![ZWalrus](https://avatars.githubusercontent.com/u/2705962?v=4)](https://github.com/ZWalrus "ZWalrus (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/magomogo-domain-model/health.svg)

```
[![Health](https://phpackages.com/badges/magomogo-domain-model/health.svg)](https://phpackages.com/packages/magomogo-domain-model)
```

###  Alternatives

[martin-georgiev/postgresql-for-doctrine

Extends Doctrine with native PostgreSQL support for arrays, JSONB, ranges, PostGIS geometries, text search, ltree, uuid, and 100+ PostgreSQL-specific functions.

4585.8M4](/packages/martin-georgiev-postgresql-for-doctrine)[flow-php/doctrine-dbal-bulk

Bulk inserts and updates for Doctrine DBAL

14385.8k4](/packages/flow-php-doctrine-dbal-bulk)[2lenet/crudit-bundle

The easy like Crud'it Bundle.

1616.4k14](/packages/2lenet-crudit-bundle)

PHPackages © 2026

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