Skip to content

Commit 2587765

Browse files
committed
Added content to the README.md file. Small fixes.
1 parent c2fcff5 commit 2587765

File tree

4 files changed

+178
-2
lines changed

4 files changed

+178
-2
lines changed

README.md

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,174 @@
44
[![License](https://poser.pugx.org/bluepsyduck/mapper-manager/license)](https://packagist.org/packages/bluepsyduck/mapper-manager)
55
[![Build Status](https://travis-ci.com/BluePsyduck/mapper-manager.svg?branch=master)](https://travis-ci.com/BluePsyduck/mapper-manager)
66
[![codecov](https://codecov.io/gh/BluePsyduck/mapper-manager/branch/master/graph/badge.svg)](https://codecov.io/gh/BluePsyduck/mapper-manager)
7+
8+
The Mapper Manager is, as the name already suggests, a manager of mappers between different types of objects.
9+
10+
## Mapper
11+
12+
The mapper supports different types of mappers, which have the difference in how they evaluate whether they can map
13+
a certain pair of objects or not. Each type of mapper comes with an interface and a corresponding adapter for the
14+
manager to handle this type of mappers. New types can always be added in the client code if there is a need for them.
15+
16+
### Static Mapper
17+
18+
A static mapper implementing the `StaticMapperInterface` knows the combination of source and destination object it
19+
supports based only on the classes, without knowing the actual instances of the objects. The support is evaluated once
20+
when the mapper is added to the manager.
21+
22+
Note: The classes of source and destination must match exactly, the static mapper does not check for any inheritance.
23+
For example, if there is a class `A` and a class `B extends A`, and the mapper returns `A` as supported class, it won't
24+
match if an instance of `B` is passed instead. If inheritance must be supported, use a dynamic mapper instead.
25+
26+
It is recommended to always use static mappers if possible, as matching the mapper in the manager is faster with
27+
static mappers than with dynamic ones.
28+
29+
#### Example
30+
31+
```php
32+
<?php
33+
34+
use BluePsyduck\MapperManager\Mapper\StaticMapperInterface;
35+
36+
class ExampleStaticMapper implements StaticMapperInterface
37+
{
38+
/**
39+
* Returns the source class supported by this mapper.
40+
* @return string
41+
*/
42+
public function getSupportedSourceClass(): string
43+
{
44+
return DatabaseItem::class;
45+
}
46+
47+
/**
48+
* Returns the destination class supported by this mapper.
49+
* @return string
50+
*/
51+
public function getSupportedDestinationClass(): string
52+
{
53+
return ResponseItem::class;
54+
}
55+
56+
/**
57+
* Maps the source object to the destination one.
58+
* @param DatabaseItem $source
59+
* @param ResponseItem $destination
60+
*/
61+
public function map($source, $destination): void
62+
{
63+
$destination->setName($source->getName())
64+
->setDescription($source->getDescription());
65+
}
66+
}
67+
```
68+
69+
### Dynamic Mapper
70+
71+
A dynamic mapper implementing the `DynamicMapperInterface` will decide whether a combination of source and destination
72+
object is supported on the actual instances of the objects. This allows to add additional criteria for support based
73+
on the two involved objects. The support is re-evaluated for each source and destination object passed to the mapper
74+
manager.
75+
76+
#### Example
77+
78+
```php
79+
<?php
80+
81+
use BluePsyduck\MapperManager\Mapper\DynamicMapperInterface;
82+
83+
class ExampleDynamicMapper implements DynamicMapperInterface
84+
{
85+
/**
86+
* Returns whether the mapper supports the combination of source and destination object.
87+
* @param object $source
88+
* @param object $destination
89+
* @return bool
90+
*/
91+
public function supports($source, $destination): bool
92+
{
93+
return $source instanceof DatabaseItem::class
94+
&& $destination instanceof ResponseItem::class
95+
&& $source->getType() === 'public'; // Additional condition not possible with a static mapper.
96+
}
97+
98+
/**
99+
* Maps the source object to the destination one.
100+
* @param DatabaseItem $source
101+
* @param ResponseItem $destination
102+
*/
103+
public function map($source, $destination): void
104+
{
105+
$destination->setName($source->getName())
106+
->setDescription($source->getDescription());
107+
}
108+
}
109+
```
110+
111+
## Usage
112+
113+
The usage of the mapper manager is rather straight forward: Create an instance of the `MapperManager` class, add some
114+
adapters, and afterwards add your actual mapper implementations.
115+
116+
```php
117+
<?php
118+
119+
use BluePsyduck\MapperManager\MapperManager;
120+
use BluePsyduck\MapperManager\Adapter\DynamicMapperAdapter;
121+
use BluePsyduck\MapperManager\Adapter\StaticMapperAdapter;
122+
123+
$mapperManager = new MapperManager();
124+
125+
// Add the default adapters included in the library.
126+
$mapperManager->addAdapter(new StaticMapperAdapter());
127+
$mapperManager->addAdapter(new DynamicMapperAdapter());
128+
129+
// Add your actual mappers.
130+
$mapperManager->addMapper(new ExampleStaticMapper());
131+
$mapperManager->addMapper(new ExampleDynamicMapper());
132+
133+
// Actually map objects.
134+
$mapperManager->map($databaseItem, $responseItem);
135+
```
136+
137+
### Zend Expressive
138+
139+
When using Zend Expressive, you can add the `ConfigProvider` of the library to your application config and access
140+
the already-initialized mapper manager through the container using `MapperManagerInterface::class` or
141+
`MapperManager::class` as alias.
142+
143+
Add the following config to your project to customize the manager:
144+
145+
```php
146+
<?php
147+
148+
use BluePsyduck\MapperManager\Constant\ConfigKey;
149+
150+
[
151+
ConfigKey::MAIN => [
152+
ConfigKey::ADAPTERS => [
153+
// The aliases of the adapters to add to the manager.
154+
// The adapters must be accessible through the container with these aliases.
155+
// The StaticMapperAdapter and DynamicMapperAdapter are added automatically.
156+
],
157+
ConfigKey::MAPPERS => [
158+
// The aliases of the mappers to add to the container.
159+
// The mappers must be accessible through the container with these aliases.
160+
],
161+
],
162+
];
163+
```
164+
165+
Then access the mapper manager through the container:
166+
167+
```php
168+
<?php
169+
170+
use BluePsyduck\MapperManager\MapperManagerInterface;
171+
172+
// Fetch the mapper manager from the container.
173+
$mapperManager = $container->get(MapperManagerInterface::class);
174+
175+
// Actually map objects.
176+
$mapperManager->map($databaseItem, $responseItem);
177+
```

config/dependencies.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313

1414
return [
1515
'dependencies' => [
16+
'aliases' => [
17+
MapperManager::class => MapperManagerInterface::class,
18+
],
1619
'factories' => [
1720
MapperManagerInterface::class => MapperManagerFactory::class,
1821
],

src/MapperManagerFactory.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ protected function addAdaptersToManager(
4848
ContainerInterface $container,
4949
array $config
5050
): void {
51-
foreach ($config[ConfigKey::MAIN][ConfigKey::ADAPTERS] ?? [] as $alias) {
51+
foreach (array_unique($config[ConfigKey::MAIN][ConfigKey::ADAPTERS] ?? []) as $alias) {
5252
$manager->addAdapter($container->get($alias));
5353
}
5454
}
@@ -65,7 +65,7 @@ protected function addMappersToManager(
6565
ContainerInterface $container,
6666
array $config
6767
): void {
68-
foreach ($config[ConfigKey::MAIN][ConfigKey::MAPPERS] ?? [] as $alias) {
68+
foreach (array_unique($config[ConfigKey::MAIN][ConfigKey::MAPPERS] ?? []) as $alias) {
6969
$manager->addMapper($container->get($alias));
7070
}
7171
}

test/src/MapperManagerFactoryTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ public function testAddAdaptersToManager(): void
7979
ConfigKey::ADAPTERS => [
8080
'foo',
8181
'bar',
82+
'foo',
8283
],
8384
],
8485
];
@@ -126,6 +127,7 @@ public function testAddMappersToManager(): void
126127
ConfigKey::MAPPERS => [
127128
'foo',
128129
'bar',
130+
'foo',
129131
],
130132
],
131133
];

0 commit comments

Comments
 (0)