PHPackages                             t4web/infrastructure - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. t4web/infrastructure

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

t4web/infrastructure
====================

Infrastructure layer realization for DDD.

2.0.1(8y ago)22.7k14BSD-3-ClausePHPPHP &gt;=5.5.0

Since Nov 3Pushed 7y ago3 watchersCompare

[ Source](https://github.com/t4web/Infrastructure)[ Packagist](https://packagist.org/packages/t4web/infrastructure)[ Docs](https://github.com/t4web/Infrastructure)[ RSS](/packages/t4web-infrastructure/feed)WikiDiscussions master Synced today

READMEChangelog (10)Dependencies (5)Versions (54)Used By (4)

Infrastructure
==============

[](#infrastructure)

Master: [![Build Status](https://camo.githubusercontent.com/78239efbf593407e24825768a20be501f7ede38890cff7686f11ad6b0cfb68bf/68747470733a2f2f7472617669732d63692e6f72672f74347765622f496e6672617374727563747572652e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/t4web/Infrastructure)[![codecov.io](https://camo.githubusercontent.com/d7dd66fe8b31abb15e9533b87722984d835eb6790b082b83323283f7293bd7cc/687474703a2f2f636f6465636f762e696f2f6769746875622f74347765622f496e6672617374727563747572652f636f7665726167652e7376673f6272616e63683d6d6173746572)](http://codecov.io/github/t4web/Infrastructure?branch=master)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/807b9e5d7ccf5b5ee4472600e5667276015c3a16a9abff656f7b33fd0ff6589f/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f74347765622f496e6672617374727563747572652f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/t4web/Infrastructure/?branch=master)[![SensioLabsInsight](https://camo.githubusercontent.com/47925908b48df701ee77907fd91c0aff4d53e0245c461ca5c45989a9023e6682/68747470733a2f2f696e73696768742e73656e73696f6c6162732e636f6d2f70726f6a656374732f39373361653234362d633961372d346139332d623834622d3234666263616664336364612f6d696e692e706e67)](https://insight.sensiolabs.com/projects/973ae246-c9a7-4a93-b84b-24fbcafd3cda)[![Dependency Status](https://camo.githubusercontent.com/dfea65f84b870ee1c65bc4111f3c60e13881372e8bad16e07a3327cb64ded229/68747470733a2f2f7777772e76657273696f6e6579652e636f6d2f757365722f70726f6a656374732f3536333966386166316434376434303031393030303161362f62616467652e7376673f7374796c653d666c6174)](https://www.versioneye.com/user/projects/5639f8af1d47d400190001a6)

Infrastructure layer for Domain, implementation by [t4web\\domain-interface](https://github.com/t4web/DomainInterface)

Contents
--------

[](#contents)

- [Installation](#instalation)
- [Quick start](#quick-start)
- [Components](#components)
- [Build criteria from array](#build-criteria-from-array)
- [Configuring](#configuring)
- [Events](#events)

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

[](#installation)

Add this project in your composer.json:

```
"require": {
    "t4web/infrastructure": "~1.3.0"
}
```

Now tell composer to download Domain by running the command:

```
$ php composer.phar update
```

Quick start
-----------

[](#quick-start)

You can use `Repository` with Domain implementation [t4web\\domain](https://github.com/t4web/Domain). This implementation build on [Zend\\Db](https://github.com/zendframework/zend-db) and [Zend\\EventManager](https://github.com/zendframework/zend-eventmanager)

Components
----------

[](#components)

- `Criteria` - for creating fetch expression

    ```
    $criteria = new T4webInfrastructure\Criteria('Task');
    $criteria->equalTo('id', 2);
    $criteria->in('type', [1,2,3]);
    $criteria->limit(20);
    $criteria->offset(10);
    $criteria->relation('Photos')
        ->equalTo('status', 3)
        ->greaterThan('created_dt', '2015-10-30');
    ```
- `CriteriaFactory` - for creating complex criteria from array

    ```
    $criteriaFactory = new T4webInfrastructure\CriteriaFactory();
    $criteria = $criteriaFactory->build(
        'Task',
        [
            'status.equalTo' => 2,
            'dateCreate.greaterThan' => '2015-10-30',

            'relations' => [
                'User' => [
                    'status.in' => [2, 3, 4],
                    'name.like' => 'gor'
                ]
            ]
        ]
    );
    ```
- `Mapper` - for translate `Entity` to table row (array), and filter table row according `columnsAsAttributesMap`

    ```
    $columnsAsAttributesMap = [
        'id' => 'id',
        'project_id' => 'projectId',
        'name' => 'name',
        'assignee_id' => 'assigneeId',
        'status' => 'status',
        'type' => 'type',
    ];
    $tableRow = [
        'id' => 22,
        'project_id' => 33,
        'name' => 'Some name',
        'assignee_id' => 44,
        'status' => 2,
        'type' => 1,
    ];
    $mapper = new T4webInfrastructure\Mapper($columnsAsAttributesMap);
    $filteredTableRow = $mapper->fromTableRow($tableRow);
    $tableRow = $mapper->toTableRow($entity);
    ```
- `QueryBuilder` - for build SQL query

    ```
    $queryBuilder = new T4webInfrastructure\QueryBuilder();

    $criteria = new T4webInfrastructure\Criteria('Task');
    $criteria->equalTo('id', 2);
    $criteria->relation('Photos')
        ->equalTo('status', 3);

    /** @var Zend\Db\Sql\Select $select */
    $select = $queryBuilder->getSelect($criteria);

    $tableGateway = new Zend\Db\TableGateway\TableGateway('tasks', $dbAdapter);
    $rows = $this->tableGateway->selectWith($select);

    $sql = $select->getSqlString($this->dbAdapter->getPlatform());
    // $sql = SELECT `tasks`.*
    //        FROM `tasks`
    //        INNER JOIN `photos` ON `photos`.`task_id` = `tasks`.`id`
    //        WHERE `tasks`.id = 2 AND `photos`.`status` = 3
    ```
- `Repository` - for store entities and restore from storage

    ```
    $repository = $serviceLocator->get('Task\Infrastructure\Repository');
    /** @var Tasks\Task\Task $task */
    $task = $repository->findById(123);

    $repository = $serviceLocator->get('Task\Infrastructure\FinderAggregateRepository');
    $task = $repository->findWith('User')->findById(123);
    /** @var Users\User\User $assignee */
    $assignee = $task->getAssignee();
    ```

Build criteria from array
-------------------------

[](#build-criteria-from-array)

You can use `CriteriaFactory::build()` for building criteria from array (for example: from input filter, post\\get request)

```
$inputData = $_GET;

$criteriaFactory = new T4webInfrastructure\CriteriaFactory();
$criteria = $criteriaFactory->build(
    'Task',
    $inputData
);
```

`$inputData` must be structured like this:

```
$inputData = [
     'status.equalTo' => 2,
     'dateCreate.greaterThan' => '2015-10-30',
     // ...
     'ATTRIBUTE.METHOD' => VALUE
 ]
```

where `ATTRIBUTE` - criteria field, `METHOD` - one of `equalTo`, `notEqualTo`, `lessThan`, `greaterThan`, `greaterThanOrEqualTo`, `lessThanOrEqualTo`, `like`, `in`

for `isNull`, `isNotNull` use

```
$inputData = [
  'ATTRIBUTE.isNull' => TRUE_EXPRESSION,
  'ATTRIBUTE.isNotNull' => TRUE_EXPRESSION,

  // example
  'status.isNull' => true,
  'dateCreate.isNotNull' => 1,
]
```

where `TRUE_EXPRESSION` can be any true expression: `true`, `1`, `'a'` etc.

for `between` use array as value

```
$inputData = [
   'ATTRIBUTE.between' => [MIN_VALUE, MAX_VALUE],

   // example
   'dateCreate.between' => ['2015-10-01', '2015-11-01'],
]
```

for `limit`, `offset` use

```
$inputData = [
   'limit' => VALUE,
   'offset' => VALUE,

   // example
   'limit' => 20,
   'offset' => 10,
]
```

for `order` use SQL-like order expression

```
$inputData = [
   'order' => EXPRESSION,

   // example
   'order' => 'dateCreate DESC',
   'order' => 'dateCreate DESC, status ASC',
]
```

Custom criteria - grouping and reusing criteria

```
$inputData = [
    'Users\User\Criteria\Active' => true,
]
```

`Users\User\Criteria\Active` - must be invokable class (`__invoke(CriteriaInterface $criteria, $value)`)

Configuring
-----------

[](#configuring)

For configuring `Repository` you must specify config, and use `Config` object for parsing config. `QueryBuilder`use `Config` for building SQL query.

```
$entityMapConfig = [
    // Entity name
    'Task' => [

        // table name
        'table' => 'tasks',

        // use for short namespace
        'entityClass' => 'Tasks\Task\Task',

        // map for entity attribute  table fields
        'columnsAsAttributesMap' => [

            // attribute => table field
            'id' => 'id',
            'project_id' => 'projectId',
            'name' => 'name',
            'assignee_id' => 'assigneeId',
            'status' => 'status',
            'type' => 'type',
            'extras' => 'extras',
        ],

        // foreign relation
        'relations' => [

            // relation entity name + table.field for building JOIN
            // name => [FK in cur. entity, PK in related entity]
            'User' => ['tasks.assignee_id', 'user.id'],

            // relation entity name + table.field for building JOIN
            // name => [link-tabe, link-table field for cur. entity, link-table field for related entity]
            'Tag' => ['tasks_tags_link', 'task_id', 'tag_id'],
        ],

        // for aliasing long\ugly criterias
        'criteriaMap' => [
            // alias => criteria
            'date_more' => 'dateCreate.greaterThan',
        ],

        // for serializing persisting data
        'serializedColumns' => [
            'extras' => 'json',
        ],
    ],
]
```

`relations` argument order - very important, `Task['relations']['User'][0]` - must be field from current entity, `Task['relations']['User'][1]` - must be field from related entity.

For many-to-many relation related entity must contain 3 arguments. For example we have table `tasks` (see config), table `tags` with fields `id`, `name` and table `tasks_tags_link` with fields `task_id` and `tag_id`. For relation Task &lt;=&gt; Tag we must describe many-to-many relation: `Task['relations']['Tag'][0]` - link-table name, `Task['relations']['Tag'][1]` - field PK current entity in link-table and `Task['relations']['Tag'][2]` - field PK in related entity in link-table.

Events
------

[](#events)

`Repository` rise events when entity created or updated.

```
$eventManager = new EventManager();
$eventManager->getSharedManager()->attach(
     REPOSITORY_IDENTIFIER,
     'entity:ENTITY_CLASS:changed',
     function(T4webInfrastructure\Event\EntityChangedEvent $e){
        $changedEntity = $e->getChangedEntity();
        $originalEntity = $e->getOriginalEntity();
        // ...
     },
     $priority
);
```

Where `REPOSITORY_IDENTIFIER` - depends from entity, builds: EntityName\\Infrastructure\\Repository
`ENTITY_CLASS` - get\_class() from you $enity object

Now `Repository` can rise:

- `entity:ModuleName\EntityName\EntityName:created` - rise after Entity just created in DB. In context event subscriber receive Zend\\EventManager\\Event.
- `entity:ModuleName\EntityName\EntityName:changed:pre` - rise before Entity update in DB. In context event subscriber receive T4webInfrastructure\\Event\\EntityChangedEvent.
- `entity:ModuleName\EntityName\EntityName:changed` - rise after Entity just updated in DB. In context event subscriber receive T4webInfrastructure\\Event\\EntityChangedEvent.
- `attribute:ModuleName\EntityName\EntityName:attribute:changed` - rise after Entity attribute updated in DB. In context event subscriber receive T4webInfrastructure\\Event\\EntityChangedEvent.

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity21

Limited adoption so far

Community19

Small or concentrated contributor base

Maturity72

Established project with proven stability

 Bus Factor1

Top contributor holds 77.6% 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 ~23 days

Recently: every ~90 days

Total

52

Last Release

2682d ago

Major Versions

1.3.7 → 2.0.02018-03-03

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/208688?v=4)[max](/maintainers/maxgu)[@maxgu](https://github.com/maxgu)

---

Top Contributors

[![maxgu](https://avatars.githubusercontent.com/u/208688?v=4)](https://github.com/maxgu "maxgu (90 commits)")[![sebaks](https://avatars.githubusercontent.com/u/9897880?v=4)](https://github.com/sebaks "sebaks (24 commits)")[![kipaut](https://avatars.githubusercontent.com/u/20888806?v=4)](https://github.com/kipaut "kipaut (1 commits)")[![scrutinizer-auto-fixer](https://avatars.githubusercontent.com/u/6253494?v=4)](https://github.com/scrutinizer-auto-fixer "scrutinizer-auto-fixer (1 commits)")

---

Tags

ddd

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/t4web-infrastructure/health.svg)

```
[![Health](https://phpackages.com/badges/t4web-infrastructure/health.svg)](https://phpackages.com/packages/t4web-infrastructure)
```

###  Alternatives

[prooph/service-bus

PHP Enterprise Service Bus Implementation supporting CQRS and DDD

4451.4M32](/packages/prooph-service-bus)[ecotone/ecotone

Enterprise architecture layer for Laravel and Symfony — CQRS, Event Sourcing, Durable Workflows (Sagas, Orchestrators), Projections, and Outbox messaging via PHP attributes.

564576.7k51](/packages/ecotone-ecotone)[prooph/event-sourcing

PHP EventSourcing library

266824.6k18](/packages/prooph-event-sourcing)[phpmentors/domain-kata

Kata for domain models

73448.1k9](/packages/phpmentors-domain-kata)[aura/payload

A Domain Payload implementation.

55381.8k9](/packages/aura-payload)[bruli/php-value-objects

PHP Value objects to use for DDD domains.

43321.9k8](/packages/bruli-php-value-objects)

PHPackages © 2026

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