|
1 | 1 | # Data Mapper
|
2 | 2 | 
|
3 | 3 |
|
4 |
| -This package will map any raw data into a strong typed PHP object. |
5 |
| - |
6 |
| -- [Installation](#installation) |
7 |
| -- [Basic mapping](#basic-mapping) |
8 |
| - - [Typing properties](#typing-properties) |
9 |
| - - [Custom mapping](#custom-mapping) |
10 |
| - - [Post mapping](#post-mapping) |
11 |
| -- [Configuration](#configuration) |
12 |
| -- [Under the hood](#under-the-hood) |
| 4 | +This package will map any raw data into a predefined strong-typed PHP object. |
13 | 5 |
|
14 | 6 | ## Installation
|
15 | 7 | The mapper has no external dependencies apart from PHP8.1 or higher. It can be installed using composer:
|
@@ -50,94 +42,8 @@ $entity = $mapper->map(User::class, [
|
50 | 42 |
|
51 | 43 | This is a simple example, but the mapper can also map nested objects, arrays of objects, keyed arrays, and even multi-level arrays.
|
52 | 44 |
|
53 |
| -### Typing properties |
54 |
| -The type of the properties is checked from two places: |
55 |
| -1. The type of the property itself. This can be defined using typehints [introduced in PHP7.4](https://wiki.php.net/rfc/typed_properties_v2); |
56 |
| -2. [PHPDoc types](https://phpstan.org/writing-php-code/phpdoc-types) for properties and constructor parameters. |
57 |
| - |
58 |
| -First the native type of the property is checked, if this is defined and can be mapped the type will be used. |
59 |
| -If no type is provided or the type is a generic array, the mapper will check the PHPDoc for type of the property. |
60 |
| - |
61 |
| -When a property is typed using a [union type](https://wiki.php.net/rfc/union_types_v2), the mapper will try to map any |
62 |
| -of the provided types from first to last until one mapping succeeds. The only exception is that `null` is always tried |
63 |
| -last. |
64 |
| - |
65 |
| -If no valid type was found for a property, the provided data will be set to the property directly without any |
66 |
| -conversion. |
67 |
| - |
68 |
| -### Custom mapping |
69 |
| -Sometimes, classes have a constructor that cannot be mapped automatically. For these cases there is a |
70 |
| -[`MapsItself`](https://github.com/jerodev/data-mapper/blob/master/src/MapsItself.php) interface that defines one |
71 |
| -static function: `mapObject`. |
72 |
| -When the mapper comes across a class that implements this interface, instead of using the constructor, the mapper will |
73 |
| -call the `MapsItself` with the provided data and is expected to return an instance of the current class. |
74 |
| - |
75 |
| -### Post mapping |
76 |
| -The mapper also comes with a post mapping attribute. When adding the [`#[PostMapping]` attribute](https://github.com/jerodev/data-mapper/blob/master/src/Attributes/PostMapping.php) |
77 |
| -to a class with a string parameter, this function will be called directly after mapping the object. |
78 |
| - |
79 |
| -A class can have multiple of these attributes and the attributes will be called in the same order as they are defined. |
80 |
| - |
81 |
| -## Configuration |
82 |
| -The mapper comes with a few configuration options that can be set using the [`MapperConfig`](https://github.com/jerodev/data-mapper/blob/master/src/MapperConfig.php) |
83 |
| -object and passed to the mappers' constructor. This is not required, if no configuration is passed, the default config |
84 |
| -is used. |
| 45 | +## Documentation |
| 46 | +More information about mapping, configuration and best practices can be found in [the documentation](https://docs.deviaene.eu/data-mapper/). |
85 | 47 |
|
86 |
| -| Option | Type | Default | Description | |
87 |
| -|----------------------------|----------|----------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |
88 |
| -| `allowUninitializedFields` | `bool` | `true` | If disabled, the mapper will fail if one of the class properties that does not have a default value was not present in the data array. | |
89 |
| -| `classMapperDirectory` | `string` | `/tmp/mappers` | This is the location the mapper will create cached mapper functions for objects.<br />The default location is a mappers function in the operating system temporary folder. | |
90 |
| -| `debug` | `bool` | `false` | Enabling debug will clear all cached mapper functions after mapping has completed. | |
91 |
| -| `enumTryFrom` | `bool` | `false` | Enabling this will use the `::tryFrom()` method instead of `::from()` to parse strings to enums. | |
92 |
| -| `strictNullMapping` | `bool` | `true` | If enabled, the mapper will throw an error when a `null` value is passed for a property that was not typed as nullable. | |
93 |
| - |
94 |
| -## Under the hood |
95 |
| -For simple native types, the mapper will use casting to convert the data to the correct type. |
96 |
| - |
97 |
| -When requesting an array type, the mapper will call itself with the type of the array elements for each of the elements in the |
98 |
| -array. |
99 |
| - |
100 |
| -For object types, some magic happens. On the very first run for a certain class, the mapper will use reflection to |
101 |
| -gather information about the class and build a mapper function based on the properties of the class. |
102 |
| -The function will also take into account required and optional properties that are passed to the constructor. |
103 |
| - |
104 |
| -The goal is to have as much and as simple mapping as possible in these generated functions without having to go back |
105 |
| -to the mapper, to reach the best performance. For more information refer to the [class mapper function docs](./doc/class-mapper-function.md). |
106 |
| - |
107 |
| -As an example, this is one of the testing classes of this library and its generated mapper function: |
108 |
| - |
109 |
| -```php |
110 |
| -#[PostMapping('post')] |
111 |
| -class UserDto |
112 |
| -{ |
113 |
| - /** First name and last name */ |
114 |
| - public string $name; |
115 |
| - |
116 |
| - /** @var array<self> */ |
117 |
| - public array $friends = []; |
118 |
| - public ?SuitEnum $favoriteSuit = null; |
119 |
| - |
120 |
| - public function __construct(string $name) |
121 |
| - { |
122 |
| - $this->name = $name; |
123 |
| - } |
124 |
| - |
125 |
| - public function post(): void |
126 |
| - { |
127 |
| - $this->name = \ucfirst($this->name); |
128 |
| - } |
129 |
| -} |
130 |
| -``` |
131 |
| - |
132 |
| -```php |
133 |
| -function jmapper_8cf8f45dc33c7f58ab728699ac3ebec3(Jerodev\DataMapper\Mapper $mapper, array $data) |
134 |
| -{ |
135 |
| - $x = new Jerodev\DataMapper\Tests\_Mocks\UserDto((string) $data['name']); |
136 |
| - $x->friends = (\array_key_exists('friends', $data) ? \array_map(static fn ($x6462755ab00b1) => $mapper->map('Jerodev\DataMapper\Tests\_Mocks\UserDto', $x6462755ab00b1), $data['friends']) : []); |
137 |
| - $x->favoriteSuit = (\array_key_exists('favoriteSuit', $data) ? Jerodev\DataMapper\Tests\_Mocks\SuitEnum::from($data['favoriteSuit']) : NULL); |
138 |
| - |
139 |
| - $x->post($data, $x); |
140 |
| - |
141 |
| - return $x; |
142 |
| -} |
143 |
| -``` |
| 48 | +## License |
| 49 | +This library is licensed under the MIT License (MIT). Please see [License File](license.md) for more information. |
0 commit comments