Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

Support mapped properties #224

Merged
merged 6 commits into from
Aug 12, 2021
Merged

Support mapped properties #224

merged 6 commits into from
Aug 12, 2021

Conversation

MaximeWillinger
Copy link
Contributor

@MaximeWillinger MaximeWillinger commented Jul 27, 2021

Description

This pull request adds the ability to map DTO properties from source properties with different names.

This approach goes against the philosophy of doing a 1:1 mapping of DTOs, but it is undoubtedly helpful in the several cases that I present below.

Use cases

1. Renaming a property when we have no control on the source data and/or for more clarity

class EventDTO extends DataTransferObject
{
    #[MapFrom('nbParticipants')]
    public string $participantCount;
}

$dto = new EventDTO([
    'nbParticipants' => 6,
]);

2. Mapping a nested property without using an additional DTO

class ProfileDTO extends DataTransferObject
{
    public string $name;

    #[MapFrom('address.city')]
    public string $city;
}

$dto = new ProfileDTO([
    'name' => 'John Doe',
    'address' => [
        'city' => 'London',
    ]
]);

3. Mapping properties from an indexed array

class UserDTO extends DataTransferObject
{
    #[MapFrom(0)]
    public string $firstName;

    #[MapFrom(1)]
    public string $lastName;
}

$dto = new UserDTO(['John', 'Doe']);

Notes

This PR only requires the addition of a resolveMappedProperty() method in DataTransferObjectProperty.

However, handling the dot notation requires two additional array helpers (Arr::get and Arr::accessible). (Arr::get has been simplified as default closure values are useless here.)

Despite the addition of these two methods, this PR is still lightweight but would significantly improve the DX for some cases without any significant constraint.

I'm open to change the name of the attribute if MapFrom doesn't suit you.

src/Attributes/MapFrom.php Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
Copy link
Contributor

@brendt brendt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an awesome PR, thanks! One remark on attribute usage, but that's all.

src/Attributes/MapFrom.php Outdated Show resolved Hide resolved
src/Reflection/DataTransferObjectProperty.php Outdated Show resolved Hide resolved
@MaximeWillinger
Copy link
Contributor Author

Thanks @brendt!
It should be good now.

@brendt brendt merged commit 8126d94 into spatie:master Aug 12, 2021
@brendt
Copy link
Contributor

brendt commented Aug 12, 2021

Thanks!

Tagged here: https://github.com/spatie/data-transfer-object/releases/tag/3.6.0

@MannikJ
Copy link

MannikJ commented Aug 12, 2021

Without looking into the implementation...Does this work as an additional mapping? I mean, does it ignore the mapping if the array I use for initialization already contains the specified attribute?

Because I would like to fill in a field from a separate location as fallback so to say. I validate accordingly that either one or the other can exist, but I want to have it only at one place in the DTO. Is this possible via mapping feature?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
5 participants