Skip to content

Commit

Permalink
Class detection rework (#2)
Browse files Browse the repository at this point in the history
* Reworked mapper to support any class tree, no naming strategy used

* Some tests and refactor

* Fixed exceptions

* Updated readme

* Tested null array

* Added CI

* Removed nightly php support

* Fixes

Co-authored-by: Dimannn <[email protected]>
  • Loading branch information
DimanKuskov and Dimannn authored May 1, 2020
1 parent 283bd52 commit 2d6af60
Show file tree
Hide file tree
Showing 9 changed files with 332 additions and 127 deletions.
36 changes: 36 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
dist: trusty
sudo: false
language: php

cache:
directories:
- $HOME/.composer/cache

php:
- 7.4

install:
- travis_retry composer self-update
- travis_retry composer install --prefer-dist

script: ./vendor/bin/phpunit

jobs:
allow_failures:
- stage: Security
include:
- stage: Stan
php: 7.4
script: ./vendor/bin/phpstan analyze src -l 8 --memory-limit=512m

- stage: Security
php: 7.4
script: ./vendor/bin/security-checker security:check

- stage: Code Style
php: 7.4
script:
- composer show squizlabs/php_codesniffer
- composer show doctrine/coding-standard
- composer show slevomat/coding-standard
- ./vendor/bin/phpcs
57 changes: 54 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,26 @@

## About

This class helps to map any class or associative arrays tree into DTO class tree.
This class helps to map any class or associative array tree into DTO class tree.

It uses reflection to create DTOs but call getters or reads properties to get values
from source tree.
It uses reflection to create DTOs but calls getters or reads properties to get values
from source tree and only properties found in DTO will be fetched from source object.
This makes mapper work fine e.g. with doctrine lazy loads.

For object `object` if key property `property` is required, following sources will be
checked:
* `object->propery`
* `object[property]`
* `object->getPropery()`
* `object->isPropery()`
* `object->hasPropery()`
* `object->propery()`
* `object->__call('property')`

All method calls are case-insensitive.

DTOs must have all their properties typed and all array properties should have phpDoc
specifying item types.

## Installation

Expand All @@ -16,3 +32,38 @@ Run
```
composer require onmoon/dto-mapper
```

## Usage

```php
public function showPetById(int $petId) : ShowPetByIdResponseDto
{
$pet = $this->pets->getById($petId);

$mapper = new OnMoon\DtoMapper\DtoMapper();
return $mapper->map($pet, ShowPetByIdResponseDto::class);
}
```

## DateTime handling

`DateTime` class does not support creation with reflection. If DTO property is
subclass of `DateTimeInterface` then this property is set to new `\Safe\DateTime`
instance. Source values for `DateTime` can be both `DateTimeInterface` and `string`.

## Rewriting source properties

By default, mapper searches for the same property in source as in DTO.
If you want to read value for some property from another source property, you can
pass a callable object as third argument. This callable should always return mapped
property name.

```php
$mapper->map($pet, ShowPetByIdResponseDto::class, function ($propertyName, $context) {
$fullName = implode('->', [...$context, $propertyName]);
if ($fullName === 'subObject->s2->property1') {
return 'realProperty1';
}
return $propertyName;
});
```
9 changes: 4 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"minimum-stability": "stable",
"require": {
"php": "^7.4",
"thecodingmachine/safe": "^1.1"
"thecodingmachine/safe": "^1.1",
"symfony/property-info": "^4.0"
},
"autoload": {
"psr-4": {
Expand All @@ -27,19 +28,17 @@
"scripts": {
"cs": "phpcs",
"csfix": "phpcbf",
"psalm": "psalm",
"stan": "phpstan analyze src -l 8 --memory-limit=512m",
"sec": "security-checker security:check",
"test": "phpunit",
"all": "composer psalm && composer stan && composer test && composer cs && composer sec"
"all": "composer stan && composer test && composer cs && composer sec"
},
"require-dev": {
"doctrine/coding-standard": "^7.0",
"phpstan/phpstan": "^0.12.19",
"phpunit/phpunit": "^9.1",
"sensiolabs/security-checker": "^6.0",
"squizlabs/php_codesniffer": "^3.5",
"thecodingmachine/phpstan-safe-rule": "^1.0",
"vimeo/psalm": "^3.11"
"thecodingmachine/phpstan-safe-rule": "^1.0"
}
}
3 changes: 2 additions & 1 deletion phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
<arg value="nps"/>

<rule ref="Doctrine">
<exclude name="SlevomatCodingStandard.PHP.RequireExplicitAssertion.RequiredExplicitAssertion" />
<exclude name="SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingTraversableTypeHintSpecification" />
<exclude name="Generic.PHP.ForbiddenFunctions.Found" />
</rule>

<file>src/</file>
Expand Down
Loading

0 comments on commit 2d6af60

Please sign in to comment.