Skip to content

Commit 88145c3

Browse files
committed
Consistently pass destination object & class in context
1 parent 0ca74fd commit 88145c3

File tree

3 files changed

+64
-27
lines changed

3 files changed

+64
-27
lines changed

src/AutoMapper.php

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
class AutoMapper implements AutoMapperInterface
2121
{
2222
public const DESTINATION_CONTEXT = '__destination';
23-
2423
public const DESTINATION_CLASS_CONTEXT = '__destination_class';
2524

2625
/**
@@ -68,15 +67,21 @@ public function map($source, string $destinationClass, array $context = [])
6867
}
6968
}
7069

70+
$context = array_merge(
71+
[self::DESTINATION_CLASS_CONTEXT => $destinationClass],
72+
$context
73+
);
7174
$mapping = $this->getMapping($sourceClass, $destinationClass);
7275
if ($mapping->providesCustomMapper()) {
7376
return $this->getCustomMapper($mapping)->map($source, $destinationClass);
7477
}
7578

7679
if ($mapping->hasCustomConstructor()) {
77-
$destinationObject = $mapping->getCustomConstructor()($source, $this, array_merge([
78-
self::DESTINATION_CLASS_CONTEXT => $destinationClass
79-
]));
80+
$destinationObject = $mapping->getCustomConstructor()(
81+
$source,
82+
$this,
83+
$context
84+
);
8085
}
8186
elseif (interface_exists($destinationClass)) {
8287
// If we're mapping to an interface a valid custom constructor has
@@ -89,6 +94,8 @@ public function map($source, string $destinationClass, array $context = [])
8994
$destinationObject = new $destinationClass;
9095
}
9196

97+
$context[self::DESTINATION_CONTEXT] = $destinationObject;
98+
9299
return $this->doMap($source, $destinationObject, $mapping, $context);
93100
}
94101

@@ -100,7 +107,6 @@ public function mapMultiple(
100107
string $destinationClass,
101108
array $context = []
102109
): array {
103-
104110
if(!is_iterable($sourceCollection)){
105111
throw new InvalidArgumentException(
106112
'The collection provided should be iterable.'
@@ -132,16 +138,29 @@ public function mapToObject($source, $destination, array $context = [])
132138

133139
$destinationClass = \get_class($destination);
134140

141+
$context = array_merge(
142+
[
143+
self::DESTINATION_CONTEXT => $destination,
144+
self::DESTINATION_CLASS_CONTEXT => $destinationClass
145+
],
146+
$context
147+
);
148+
135149
$mapping = $this->getMapping($sourceClass, $destinationClass);
136150
if ($mapping->providesCustomMapper()) {
137-
return $this->getCustomMapper($mapping)->mapToObject($source, $destination, [
138-
self::DESTINATION_CONTEXT => $destination,
139-
]);
151+
return $this->getCustomMapper($mapping)->mapToObject(
152+
$source,
153+
$destination,
154+
$context
155+
);
140156
}
141157

142-
return $this->doMap($source, $destination, $mapping, array_merge([
143-
self::DESTINATION_CONTEXT => $destination,
144-
], $context));
158+
return $this->doMap(
159+
$source,
160+
$destination,
161+
$mapping,
162+
$context
163+
);
145164
}
146165

147166
/**

test/AutoMapperTest.php

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -123,21 +123,6 @@ public function testMapToAnExistingObjectContext()
123123
;
124124
$mapper = new AutoMapper($this->config);
125125
$mapper->mapToObject($source, $destination);
126-
127-
// Make sure context added only for mapToObject method
128-
$this->config
129-
->getMappingFor(Source::class, Destination::class)
130-
->forMember('name', Operation::mapFrom(function(Source $source, AutoMapperInterface $mapper, array $context) {
131-
$this->assertArrayNotHasKey(AutoMapper::DESTINATION_CONTEXT, $context);
132-
133-
return $source->name;
134-
}))
135-
;
136-
$mapper = new AutoMapper($this->config);
137-
138-
$source = new Source();
139-
$source->name = 'Hello';
140-
$mapper->map($source, Destination::class);
141126
}
142127

143128
public function testSourceDoesntGetOverridden()
@@ -731,7 +716,7 @@ public function testAnExceptionIsThrownForNoIterableSourceInMultpleMappings()
731716
$mapper = new AutoMapper($this->config);
732717

733718
$sourceCollection = new \stdClass();
734-
719+
735720
$mapper->mapMultiple($sourceCollection, Destination::class);
736721
}
737722
}

test/Scenarios/ContextTest.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,37 @@ public function testMapToMergesTheParentContext()
129129

130130
$this->assertEquals('map-to-value', $result->source->name);
131131
}
132+
133+
public function testDestinationClassIsPassed()
134+
{
135+
$config = new AutoMapperConfig();
136+
$config->registerMapping(Source::class, Destination::class)
137+
->forMember('name', function ($source, $mapper, $context = []) {
138+
$this->assertArrayHasKey(
139+
AutoMapper::DESTINATION_CONTEXT,
140+
$context
141+
);
142+
$this->assertArrayHasKey(
143+
AutoMapper::DESTINATION_CLASS_CONTEXT,
144+
$context
145+
);
146+
$this->assertInstanceOf(
147+
Destination::class,
148+
$context[AutoMapper::DESTINATION_CONTEXT]
149+
);
150+
$this->assertEquals(
151+
Destination::class,
152+
$context[AutoMapper::DESTINATION_CLASS_CONTEXT]
153+
);
154+
155+
return 'some value';
156+
});
157+
$mapper = new AutoMapper($config);
158+
$source = new Source('a name');
159+
160+
$mapper->map(
161+
$source,
162+
Destination::class
163+
);
164+
}
132165
}

0 commit comments

Comments
 (0)