PHP code example of mark-gerarts / auto-mapper-plus
1. Go to this page and download the library: Download mark-gerarts/auto-mapper-plus library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
mark-gerarts / auto-mapper-plus example snippets
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...
}
class EmployeeDto
{
// While the properties are public for this example, we can map to private
// or protected properties just the same.
public $firstName;
public $lastName;
public $age;
}
use AutoMapperPlus\Configuration\AutoMapperConfig;
use AutoMapperPlus\AutoMapper;
$config = new AutoMapperConfig();
// Simply registering the mapping is enough to convert properties with the same
// name. Custom actions can be registered for each individual property.
$config
->registerMapping(Employee::class, EmployeeDto::class)
->forMember('age', function (Employee $source) {
return date('Y') - $source->getBirthYear();
})
->reverseMap(); // Register the reverse mapping as well.
$mapper = new AutoMapper($config);
// With this configuration we can start converting our objects.
$john = new Employee(10, "John", "Doe", 1980);
$dto = $mapper->map($john, EmployeeDto::class);
echo $dto->firstName; // => "John"
echo $dto->lastName; // => "Doe"
echo $dto->age; // => 37
use AutoMapperPlus\Configuration\AutoMapperConfig;
use AutoMapperPlus\AutoMapper;
$config = new AutoMapperConfig();
$config->registerMapping(Source::class, Destination::class);
$mapper = new AutoMapper($config);
$john = new Employee("John", "Doe", 1980);
// Map the source object to a new instance of the destination class.
$mapper->map($john, EmployeeDto::class);
// Mapping to an existing object is possible as well.
$mapper->mapToObject($john, new EmployeeDto());
// Map a collection using mapMultiple
$mapper->mapMultiple($employees, EmployeeDto::class);
$getName = function ($source, AutoMapperInterface $mapper) { return 'John'; };
$mapping->forMember('name', $getName);
// The above is a shortcut for the following:
$mapping->forMember('name', Operation::mapFrom($getName));
// Which in turn is equivalent to:
$mapping->forMember('name', new MapFrom($getName));
// Other examples:
// Ignore this property.
$mapping->forMember('id', Operation::ignore());
// Map this property to the given class.
$mapping->forMember('employee', Operation::mapTo(EmployeeDto::class));
// Explicitly state what the property name is of the source object.
$mapping->forMember('name', Operation::fromProperty('unconventially_named_property'));
// The `FromProperty` operation can be chained with `MapTo`, allowing a
// differently named property to be mapped to a class.
$mapping->forMember(
'address',
Operation::fromProperty('adres')->mapTo(Address::class)
);
// SetTo sets the property to the given value.
$mapping->forMember('type', Operation::setTo('employee'));
// An extended example showing you can access the mapper in `MapFrom`.
$getColorPalette = function(SimpleXMLElement $XMLElement, AutoMapperInterface $mapper) {
/** @var SimpleXMLElement $palette */
$palette = $XMLElement->xpath('/product/specification/palette/colour');
return $mapper->mapMultiple($palette, Color::class);
};
$mapping->forMember('palette', $getColorPalette);
// This assumes address is an object, or a collection of mappable
// objects if the source is an array/iterable.
$mapping->forMember('address', Operation::mapTo(Address::class));
// This is equivalent to:
$mapping->forMember('address', Operation::mapTo(Address::class, false));
// If you want to be very specific about the source being a collection, you
// can use `mapCollectionTo`. This is purely syntactic sugar; it is equivalent
// to the declarations above as well.
$mapping->forMember('addresses', Operation::mapCollectionTo(Address::class));
// On the other hand, if the source is an array that represents an object, you
// can use the following:
$mapping->forMember('address', Operation::mapTo(Address::class, true));
// Or nicer
$mapping->forMember('address', Operation::mapArrayTo(Address::class));
// This iterates over every property of the source property
// 'polymorphicChildren'. Each value will be mapped to the first existing
// mapping from the value to one of the given classes.
$config->createMapping(ChildA::class, ChildADto::class);
$config->createMapping(ChildB::class, ChildBDto::class);
$config->createMapping(Parent::class, ParentDto::class)
->forMember(
'polymorphicChildren',
Operation::mapToAnyOf([ChildADto::class, ChildBDto::class]
));
// Either set it in the options:
$config->getOptions()->skipConstructor();
$mapper = new AutoMapper($config);
// Or set it on the mapping directly:
$config->registerMapping(Source::class, Destination::class)->skipConstructor();
// reverseMap() returns the new mapping, allowing to continue configuring the
// new mapping.
$config->registerMapping(Employee::class, EmployeeDto::class)
->reverseMap()
->forMember('id', Operation::ignore());
$config->hasMappingFor(Employee::class, EmployeeDto::class); // => True
$config->hasMappingFor(EmployeeDto::class, Employee::class); // => True
// Source class properties: Destination class properties:
// - 'some_property', - 'some_property'
// - 'some_alternative_property' - 'some_other_property'
// - 'the_last_property' - 'the_last_property'
//
$config->registerMapping(Source::class, Destination::class)
->forMember('some_property', Operation::ignore())
->forMember('some_other_property', Operation::fromProperty('some_alternative_property'))
->reverseMap();
// When mapping from Source to Destination, the following will happen:
// - some_property gets ignored
// - some_other_property gets mapped by using the value form some_alternative_property
// - the_last_property gets mapped because the names are equal.
//
// Now, when we go in the reverse direction things are different:
// - some_property gets mapped, because Ignore is not reversible
// - some_alternative_property gets mapped because FromProperty is reversible
// - the_last_property gets mapped as well
$detailMapping = $config->registerMapping(Employee::class, EmployeeDetailView::class)
// Define operations and options ...
->forMember('age', function () {
return 20;
});
// You can copy a mapping by passing source and destination class. This will
// search the config for the relevant mapping.
$listMapping = $config->registerMapping(Employee::class, EmployeeListView::class)
->copyFrom(Employee::class, EmployeeDetailView::class)
// Alternatively, copy a mapping by passing it directly.
// ->copyFromMapping($detailMapping)
//
// You can now go ahead and define new operations, or override existing
// ones.
->forMember('name', Operation::ignore())
->skipConstructor();
use AutoMapperPlus\NameConverter\NamingConvention\CamelCaseNamingConvention;
use AutoMapperPlus\NameConverter\NamingConvention\SnakeCaseNamingConvention;
$config->registerMapping(CamelCaseSource::class, SnakeCaseDestination::class)
->withNamingConventions(
new CamelCaseNamingConvention(), // The naming convention of the source class.
new SnakeCaseNamingConvention() // The naming convention of the destination class.
);
$source = new CamelCaseSource();
$source->propertyName = 'camel';
$result = $mapper->map($source, SnakeCaseDestination::class);
echo $result->property_name; // => "camel"
$config = new AutoMapperConfig();
$config->getOptions()->dontSkipConstructor();
// This will set the options for this specific mapping.
$config = new AutoMapperConfig(function (Options $options) {
$options->dontSkipConstructor();
$options->setDefaultMappingOperation(Operation::ignore());
// ...
});
// Operations can still be registered.
$config->registerMapping(Employee::class, \stdClass::class)
->forMember('id', Operation::ignore());
$mapper = new AutoMapper($config);
$employee = new Employee(5, 'John', 'Doe', 1978);
$result = $mapper->map($employee, \stdClass::class);
echo $result->firstName; // => "John"
echo $result->lastName; // => "Doe"
var_dump(isset($result->id)); // => bool(false)
$config->registerMapping(CamelCaseSource::class, \stdClass::class)
->withNamingConventions(
new CamelCaseNamingConvention(),
new SnakeCaseNamingConvention()
)
// Operations have to be defined using the target property name.
->forMember('some_property', function () { return 'new value'; });
$mapper = new AutoMapper($config);
$source = new CamelCaseSource();
$source->someProperty = 'original value';
$source->anotherProperty = 'Another value';
$result = $mapper->map($employee, \stdClass::class);
var_dump(isset($result->someProperty)); // => bool(false)
echo $result->some_property; // => "new value"
echo $result->another_property; // => "Another value"
class YourObjectCrate { }
$config = new AutoMapperConfig(); // (Or pass a callable to the constructor)
$config->getOptions()->registerObjectCrate(YourObjectCrate::class);
$config->registerMapping(Employee::class, YourObjectCrate::class);
$mapper = new AutoMapper($config);
$employee = new Employee(5, 'John', 'Doe', 1978);
$result = $mapper->map($employee, YourObjectCrate::class);
echo $result->firstName; // => "John"
echo $result->lastName; // => "Doe"
echo get_class($result); // => "YourObjectCrate"
$config->registerMapping('array', Employee::class); // Alternatively, use the enum DataType::ARRAY
// Adding operations works just as you would expect.
$config->registerMapping(DataType::ARRAY, Employee::class)
->forMember('id', Operation::ignore())
->forMember('type', Operation::setTo('employee'))
// Since arrays are oftentimes snake_case'd.
->withNamingConventions(
new SnakeCaseNamingConvention(),
new CamelCaseNamingConvention()
);
// It is now possible to map an array to an employee:
$employee = [
'id' => 5,
'first_name' => 'John',
'last_name' => 'Doe'
];
$result = $mapper->map($employee, Employee::class);
echo $result->firstName; // => "John"
echo $result->id; // => null
echo $result->type; // => "employee"
// You can either extend the CustomMapper, or just implement the MapperInterface
// directly.
class EmployeeMapper extends CustomMapper
{
/**
* @param Employee $source
* @param EmployeeDto $destination
* @return EmployeeDto
*/
public function mapToObject($source, $destination)
{
$destination->id = $source->getId();
$destination->firstName = $source->getFirstName();
$destination->lastName = $source->getLastName();
$destination->age = date('Y') - $source->getBirthYear();
return $destination;
}
}
$config->registerMapping(Employee::class, EmployeeDto::class)
->useCustomMapper(new EmployeeMapper());
$mapper = new AutoMapper($config);
// The AutoMapper can now be used as usual, but your custom mapper class will be
// called to do the actual mapping.
$employee = new Employee(10, 'John', 'Doe', 1980);
$result = $mapper->map($employee, EmployeeDto::class);
// This example shows how for example the current locale can be passed to alter
// the mapping behaviour.
$config->registerMapping(Employee::class, EmployeeDto::class)
->forMember(
'honorific',
function ($source, AutoMapperInterface $mapper, array $context): string {
$translationKey = "honorific.{$source->getGender()}";
return $this->translator->trans($translationKey, $context['locale']);
}
);
// Usage:
$mapper->map($employee, EmployeeDto::class, ['locale' => $request->getLocale()]);
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.