Skip to content

Commit 6e31ee2

Browse files
authored
Merge pull request #6 from intelliapps/fix_reverse_conversion
Implement Nested Reverse Conversion Method - fixes issue #5
2 parents a6bc412 + 3c4ac65 commit 6e31ee2

File tree

4 files changed

+135
-5
lines changed

4 files changed

+135
-5
lines changed

src/File/Csv.php

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ class Csv extends AbstractFile
1515
'options' => 0,
1616
'delimiter' => ',',
1717
'enclosure' => '"',
18-
'escape' => '\\'
18+
'escape' => '\\',
19+
'join' => '_',
20+
'numbers' => 'strings'
1921
];
2022

2123
/**
@@ -25,9 +27,40 @@ public function convert(): string
2527
{
2628
$data = $this->parseData();
2729
$keys = $this->parseCsv(array_shift($data));
28-
return json_encode(array_map(function ($line) use ($keys) {
29-
return array_combine($keys, $this->parseCsv($line));
30-
}, $data), $this->conversion['options']);
30+
$splitKeys = array_map(function ($key) {
31+
return explode($this->conversion['join'], $key);
32+
}, $keys);
33+
34+
$jsonObjects = array_map(function ($line) use ($splitKeys) {
35+
$values = $this->parseCsv($line);
36+
$jsonObject = [];
37+
for ($valueIndex = 0, $count = count($values); $valueIndex < $count; $valueIndex++) {
38+
if ($values[$valueIndex] == "") {
39+
continue;
40+
}
41+
$this->setJsonValue($splitKeys[$valueIndex], 0, $jsonObject, $values[$valueIndex]);
42+
}
43+
return $jsonObject;
44+
}, $data);
45+
46+
return json_encode($jsonObjects, $this->conversion['options']);
47+
}
48+
49+
private function setJsonValue($splitKey, $splitKeyIndex, &$jsonObject, $value)
50+
{
51+
$keyPart = $splitKey[$splitKeyIndex];
52+
53+
if (count($splitKey) > $splitKeyIndex+1) {
54+
if (!array_key_exists($keyPart, $jsonObject)) {
55+
$jsonObject[$keyPart] = [];
56+
}
57+
$this->setJsonValue($splitKey, $splitKeyIndex+1, $jsonObject[$keyPart], $value);
58+
} else {
59+
if ($this->conversion['numbers'] == 'numbers' && is_numeric($value)) {
60+
$value = 0 + $value;
61+
}
62+
$jsonObject[$keyPart] = $value;
63+
}
3164
}
3265

3366
private function parseCsv($line)

src/File/Json.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class Json extends AbstractFile
1515
'delimiter' => ',',
1616
'enclosure' => '"',
1717
'escape' => '\\',
18+
'join' => '_',
1819
'null' => null
1920
];
2021

@@ -63,7 +64,7 @@ protected function flatten(array $array = [], $prefix = '', array $result = []):
6364
{
6465
foreach ($array as $key => $value) {
6566
if (\is_array($value)) {
66-
$result = array_merge($result, $this->flatten($value, $prefix . $key . '_'));
67+
$result = array_merge($result, $this->flatten($value, $prefix . $key . $this->conversion['join']));
6768
} else {
6869
$result[$prefix . $key] = $value;
6970
}

tests/JsonReverseTest.php

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
namespace OzdemirBurak\JsonCsv\Tests;
4+
5+
use OzdemirBurak\JsonCsv\Tests\Traits\TestTrait;
6+
use PHPUnit\Framework\TestCase;
7+
8+
class JsonReverseTest extends TestCase
9+
{
10+
use TestTrait;
11+
12+
/**
13+
* @param string $file
14+
* @param string $join
15+
*/
16+
private function checkReverseConversion($file, $join = '_')
17+
{
18+
$pathCsvOut = $this->path($file . '.out', 'csv');
19+
20+
$jsonConverter = $this->initJson($file);
21+
$jsonConverter->setConversionKey('join', $join);
22+
$jsonConverter->convertAndSave($pathCsvOut);
23+
24+
$pathJsonOut = $this->path($file . '.out', 'json');
25+
26+
$csvConverter = $this->initCsv($file . '.out');
27+
$csvConverter->setConversionKey('join', $join);
28+
$csvConverter->setConversionKey('numbers', 'numbers');
29+
$csvConverter->convertAndSave($pathJsonOut);
30+
31+
try {
32+
$this->assertJsonFileEqualsJsonFile($this->path($file, 'json'), $pathJsonOut);
33+
} finally {
34+
unlink($pathCsvOut);
35+
$this->assertFileNotExists($pathCsvOut);
36+
unlink($pathJsonOut);
37+
$this->assertFileNotExists($pathJsonOut);
38+
}
39+
}
40+
41+
/**
42+
* @group json-conversion-test
43+
*/
44+
public function testWhatever()
45+
{
46+
$this->checkReverseConversion('example');
47+
}
48+
49+
/**
50+
* @group json-conversion-test
51+
*/
52+
public function testPeople()
53+
{
54+
$this->checkReverseConversion('people', '-');
55+
}
56+
57+
/**
58+
* @group json-conversion-test
59+
*/
60+
public function testProperties()
61+
{
62+
$this->checkReverseConversion('properties');
63+
}
64+
65+
/**
66+
* @group json-conversion-test
67+
*/
68+
/**
69+
* @TODO resolve issues which cause this test to fail
70+
*
71+
public function testStats()
72+
{
73+
$this->checkReverseConversion('stats');
74+
}
75+
*/
76+
}

tests/data/example.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[
2+
{
3+
"name": {
4+
"common": "Turkey",
5+
"official": "Republic of Turkey",
6+
"native": "T\u00fcrkiye"
7+
},
8+
"area": 783562,
9+
"latlng": [39, 35]
10+
},
11+
{
12+
"name": {
13+
"common": "Israel",
14+
"official": "State of Israel",
15+
"native": "\u05d9\u05e9\u05e8\u05d0\u05dc"
16+
},
17+
"area": 20770,
18+
"latlng": [31.30, 34.45]
19+
}
20+
]

0 commit comments

Comments
 (0)