Installation
composer require cmath10/mapper-bundle
Register the bundle in config/bundles.php:
return [
// ...
Cmath10\MapperBundle\Cmath10MapperBundle::class => ['all' => true],
];
Basic Usage
Define a mapper class (e.g., src/Mapper/UserMapper.php):
namespace App\Mapper;
use Cmath10\MapperBundle\Mapper\MapperInterface;
use App\Entity\User;
class UserMapper implements MapperInterface
{
public function map(array $data): User
{
return (new User())
->setName($data['name'])
->setEmail($data['email']);
}
}
First Use Case Inject the mapper via Symfony’s dependency injection:
use App\Mapper\UserMapper;
class UserController
{
public function __construct(private UserMapper $userMapper) {}
public function create(Request $request)
{
$data = $request->request->all();
$user = $this->userMapper->map($data);
// Persist $user...
}
}
DTO-to-Entity Mapping Useful for decoupling API input from domain models:
$dto = new UserDto($request->all());
$user = $this->userMapper->map($dto->toArray());
Collection Mapping
Extend MapperInterface to handle arrays of data:
public function mapCollection(array $data): array
{
return array_map([$this, 'map'], $data);
}
Service Integration
Combine with Symfony’s Serializer or Validator:
use Symfony\Component\Serializer\SerializerInterface;
class UserMapper implements MapperInterface
{
public function __construct(private SerializerInterface $serializer) {}
public function map(array $data): User
{
$entity = $this->serializer->deserialize(
json_encode($data),
User::class,
'json'
);
return $entity;
}
}
EntityNameMapper (e.g., ProductMapper).Validator, Serializer).ValidatorInterface).Circular References If mapping nested entities, ensure bidirectional relationships are handled:
// Avoid infinite loops in __toString() or getters.
Type Safety The package lacks built-in type hints for mapped properties. Add PHPDoc or runtime checks:
if (!isset($data['email'])) {
throw new \InvalidArgumentException('Email is required.');
}
Configuration Overrides
The bundle has minimal config. Override services in config/packages/cmath10_mapper.yaml if needed:
services:
App\Mapper\UserMapper:
tags: ['mapper']
\Log::debug('Mapping data:', $data);
var_dump(): For complex objects, dump intermediate states:
var_dump($this->mapper->map($data));
Custom Mapper Tags Tag mappers for autowiring (if extending the bundle):
# config/services.yaml
services:
App\Mapper\CustomMapper:
tags: ['mapper.custom']
Event Listeners Trigger events before/after mapping (e.g., for logging or transformations):
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class MappingSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
'mapper.pre_map' => 'onPreMap',
'mapper.post_map' => 'onPostMap',
];
}
}
Performance
For large datasets, cache mappers or use mapCollection with batch processing:
$batchSize = 100;
foreach (array_chunk($data, $batchSize) as $batch) {
$this->mapper->mapCollection($batch);
}
How can I help you explore Laravel packages today?