automapper-plus icon indicating copy to clipboard operation
automapper-plus copied to clipboard

Map to object where properties are in a single associative array

Open dingledorf opened this issue 1 year ago • 1 comments

Hey there,

I was wondering if there was an easy way to map to a destination object where all the properties are in a single associative array?

For example

class Employee
{
    private $id;
    private $firstName;
    private $lastName;
    private $birthYear;
    
    public function __construct($id, $firstName, $lastName, $birthYear)
    {
        $this->id = $id;
        $this->firstName = $firstName;
        $this->lastName = $lastName;
        $this->birthYear = $birthYear;
    }

    public function getId()
    {
        return $this->id;
    }

    // And so on...
}

and MapTo

class EmployeeEntity
{
    private $_propDict = [];
    
    public function getId()
    {
        return $_propDict['id'] ?? null;
    }

    public function setId($val)
    {
        $_propDict['id'] = $val;
    }

    // And so on...
}

dingledorf avatar Jul 27 '22 23:07 dingledorf

Hi @dingledorf, I don't believe there is an easy/straightforward way. One way to do this is by registering a mapping to an array, and then using that mapping to set the property using mapFrom. One caveat here is that mapping to arrays is not supported in v1, so a workaround is mapping to stdClass and casting to array. As I said, it's not straightforward :slightly_smiling_face:

// Register a mapping that dumps everything into a stdClass.
$config
    ->registerMapping(Employee::class, \stdClass::class)
    // This is optional, should the propDict use snake cased variable names.
    ->withNamingConventions(new CamelCaseNamingConvention(), new SnakeCaseNamingConvention());

// Use the previous mapping to set the propDict property.
$config
    ->registerMapping(Employee::class, EmployeeEntity::class)
    ->forMember(
        '_propDict',
        Operation::mapFrom(function (Employee $employee, AutoMapper $mapper) {
            return (array) $mapper->map($employee, \stdClass::class);
        })
    );

mark-gerarts avatar Jul 31 '22 11:07 mark-gerarts