|
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