Skip to content

Commit

Permalink
Nested itemconverter for recursive arrays including documentation and…
Browse files Browse the repository at this point in the history
… tests. Fixes #77 #94
  • Loading branch information
gries committed Jul 15, 2014
1 parent 31c799f commit 84bff23
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 0 deletions.
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,59 @@ array(
);
```

#### NestedMappingItemConverter
Use the NestedMappingItemConverter to add mappings to your workflow if the input data contains nested arrays. Your keys from
the input data will be renamed according to these mappings. Say you have input data:

```php
$data = array(
'foo' => 'bar',
'baz' => array(
array(
'another' => 'thing'
),
array(
'another' => 'thing2'
),
)
);
```

You can map the keys `another` in the following way.

```php
use Ddeboer\DataImport\ItemConverter\NestedMappingItemConverter;

$mappings = array(
'foo' => 'foobar',
'baz' => array(
'another' => 'different_thing'
)
);

$converter = new NestedItemMappingConverter('baz');
$converter->addMapping($mappings);

$workflow->addItemConverter($converter)
->process();
```

Your output data will now be:
```php
array(
'foobar' => 'bar',
'baz' => array(
array(
'different_thing' => 'thing'
),
array(
'different_thing' => 'thing2'
),
)
);
```


#### Create an item converter

Implement `ItemConverterInterface` to create your own item converter:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php
namespace Ddeboer\DataImport\ItemConverter;

use Ddeboer\DataImport\ItemConverter\MappingItemConverter;

/**
* An item converter that takes an input containing nested arrays from a reader, and returns a modified item based on
* mapped keys.
*
* @author Adam Paterson <hello@adampaterson.co.uk>
*/
class NestedMappingItemConverter extends MappingItemConverter
{
/**
* @var string
*/
protected $nestKey;

/**
* @param array $mappings
* @param string $nestKey
*/
public function __construct($nestKey, array $mappings = array())
{
parent::__construct($mappings);
$this->nestKey = $nestKey;
}

/**
* @param array $item
* @param string $from
* @param string $to
* @return array
*/
protected function applyMapping(array $item, $from, $to)
{
if ($from !== $this->nestKey) {
return parent::applyMapping($item, $from, $to);
}

foreach ($item[$this->nestKey] as $key => $nestedItem) {
foreach ($to as $nestedFrom => $nestedTo) {
$nestedItem = parent::applyMapping($nestedItem, $nestedFrom, $nestedTo);
}

$item[$this->nestKey][$key] = $nestedItem;
}

return $item;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace Ddeboer\DataImport\ItemConverter;

class NestedMappingItemConverterTest extends \PHPUnit_Framework_TestCase
{
public function testConvertSimple()
{
$input = array(
'bar' => 'value',
'simple' => array('subsimple' => 'value'),
'simple-key' => array('foo' => 'bar'),
'nested' => array(
array('another' => 'thing', 'something' => 's1'),
array('another' => 'thing2', 'something' => 's2'),
),
);

$mappings = array(
'bar' => 'foo',
'simple' => array('subsimple' => 'subsimple-foo'),
'simple-key' => 'simple-key-foo',
'nested' => array(
'another' => 'different_thing',
'something' => 'else'
)
);

$converter = new NestedMappingItemConverter('nested', $mappings);
$output = $converter->convert($input);

$expected = array(
'foo' => 'value',
'simple' => array('subsimple-foo' => 'value'),
'simple-key-foo' => array('foo' => 'bar'),
'nested' => array(
array('different_thing' => 'thing', 'else' => 's1'),
array('different_thing' => 'thing2', 'else' => 's2'),
)
);
$this->assertEquals($expected, $output);
}
}

0 comments on commit 84bff23

Please sign in to comment.