Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions Tests/Unit/Tools/Mapper/MapperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -268,4 +268,107 @@ public function provideEmptyValues()
yield 'Empty allowed option' => [['name' => ''], '', $ctx];
yield 'Wrong type' => [null, null, $ctx];
}

/**
* @dataProvider provideMergeMappings
*/
public function testShouldMergeMappings($elements, $mappers, $mockedMapFunction, $mockedMapAllFunction, $expectedResult)
{
$mapperMock = $this->getMockBuilder(Mapper::class)
->setMethods(['mapAll', 'map'])
->getMock();

$mapperMock->method('map')->willReturn($mockedMapFunction);
$mapperMock->method('mapAll')->willReturn($mockedMapAllFunction);

$result = $mapperMock->mergeMapping($elements, 'mappingName', $mappers);

$this->assertSame($expectedResult, $result);
}

public function provideMergeMappings()
{
yield 'Merge mappings' => [
[
'packshot' => 'url://packshot.com',
'lengow' => null,
'eRetail' => [
'main' => 'url://main.com',
'nonBrand' => [
'url://nonBrand1.com',
'url://nonBrand2.com'
]
]
],
[
['map', 'packshot'],
['map', 'lengow'],
['map', 'maps'],
['map', 'eRetail.main'],
['mapAll', 'eRetail.nonBrand'],
],
['name' => 'singleLine', 'location' => 'https://media.com/1'],
[['name' => 'multipleLines', 'location' => 'https://media.com/2'],['name' => 'multipleLines', 'location' => 'https://media.com/3']],
[
['name' => 'singleLine', 'location' => 'https://media.com/1'],
['name' => 'singleLine', 'location' => 'https://media.com/1'],
['name' => 'multipleLines', 'location' => 'https://media.com/2'],
['name' => 'multipleLines', 'location' => 'https://media.com/3']
],
];
yield 'Merge mappings with null mapAll' => [
[
'line' => 'https://media.com/1',
'lines' => null
],
[
['map', 'line'],
['mapAll', 'lines'],
],
['name' => 'singleLine', 'location' => 'https://media.com/1'],
null,
[
['name' => 'singleLine', 'location' => 'https://media.com/1']
],
];
yield 'Merge mappings with null map' => [
[
'line' => null,
'lines' => [
'https://media.com/2',
'https://media.com/3'
]
],
[
['map', 'line'],
['mapAll', 'lines'],
],
null,
[['name' => 'multipleLines', 'location' => 'https://media.com/2'],['name' => 'multipleLines', 'location' => 'https://media.com/3']],
[
['name' => 'multipleLines', 'location' => 'https://media.com/2'],
['name' => 'multipleLines', 'location' => 'https://media.com/3']
],
];
}

/**
* @dataProvider provideInvalidMappersToMerge
*/
public function testShouldThrowExceptionIfMappersIsNotCorrect(array $mapper = null)
{
$this->expectException(\InvalidArgumentException::class);
$this->mapper->mergeMapping([
'line' => 'https://media.com/1',
'lines' => ['https://media.com/2','https://media.com/3']
], 'test', $mapper);
// $this->assertTrue(true);
}

public function provideInvalidMappersToMerge()
{
yield 'Null mappers parameter' => [null];
yield 'Map function is not mapped' => [[['invalid', 'line']]];
yield 'Map function is null' => [[[null, 'line']]];
}
}
60 changes: 60 additions & 0 deletions Tools/Mapper/Mapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,66 @@ public function map($obj, $mappingName, $context = [])
return $this->resolve($mapping, $obj, $context);
}

/**
* Merge multiples arrays values in a single mappingName
*
* @param array $elements
* @param string $mappingName
* @param array<array{mapFunction: string, object: array|null, context: string}> $mappers
*
* @return null|string
*/
public function mergeMapping($elements, $mappingName, $mappers)
{
if(empty($elements)) {
return null;
}

if (empty($mappers)) {
throw new \InvalidArgumentException('No mapper provided.');
}

$response = [];

foreach ($mappers as $mapper){
$object = $this->getObject($elements, $mapper[1]);
if(empty($object)){
continue;
}

$mapFunction = $mapper[0] ?? null;
$context = $mapper[2] ?? $mapper[1] ?? null;

if(empty($mapFunction) || empty($context) || !in_array($mapFunction, ['map', 'mapAll'])){
throw new \InvalidArgumentException('No mapper function or context informed');
}

$mappedObject = $this->$mapFunction($object, $mappingName, $context);
if (!empty($mappedObject)) {
$response = ($mapFunction === 'map')
? array_merge($response, [$mappedObject])
: array_merge($response, $mappedObject);
}
}

return $response;
}


private function getObject(array $elements, string $path) {
$keys = explode('.', $path);
$current = $elements;

foreach ($keys as $key) {
if (!isset($current[$key])) {
return null;
}
$current = $current[$key];
}

return $current;
}

/**
* @param $mapping
* @param $obj
Expand Down