Skip to content
This repository was archived by the owner on Oct 3, 2021. It is now read-only.

Commit 5c16f0e

Browse files
authored
Merge pull request #3 from healerz/enhanceConvertersWithAllowSerializeEmpty
Enhance converters with allow serialize empty
2 parents 27d1b9e + 864db3d commit 5c16f0e

10 files changed

+147
-21
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
Through [Composer](http://getcomposer.org) as [saxulum/saxulum-elasticsearch-querybuilder][1].
2424

2525
```sh
26-
composer require saxulum/saxulum-elasticsearch-querybuilder "~3.2"
26+
composer require saxulum/saxulum-elasticsearch-querybuilder "~3.3"
2727
```
2828

2929
## Usage

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
},
2222
"extra": {
2323
"branch-alias": {
24-
"dev-master": "3.2-dev"
24+
"dev-master": "3.3-dev"
2525
}
2626
},
2727
"autoload": {
+72-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
# IteratableToNodeConverter
22

3-
## Bool value
3+
**Important**: By default empty nodes get not serialized. NullNode forces null value serialization.
4+
5+
* ArrayNode (no elements)
6+
* BoolNode (null)
7+
* ObjectNode (no elements)
8+
* FloatNode (null)
9+
* IntNode (null)
10+
* StringNode (null)
11+
12+
This works recursive, which means theoretically a multidimensional array can lead into an empty string return.
13+
14+
Check the `allowSerializeEmpty` argument to prevent this if needed.
15+
16+
## Example
417

518
```php
619
<?php
@@ -9,6 +22,62 @@ use Saxulum\ElasticSearchQueryBuilder\Converter\IteratableToNodeConverter;
922
use Saxulum\ElasticSearchQueryBuilder\Converter\ScalarToNodeConverter;
1023
use Saxulum\ElasticSearchQueryBuilder\Node\ObjectNode;
1124

12-
$iteratableConverter = new IteratableToNodeConverter(new ScalarToNodeConverter);
13-
$iteratableConverter->convert(['key' => [bool, 1.234, 1, null, 'string']]); // instanceof ObjectNode::class
25+
$iteratableConverter = new IteratableToNodeConverter(new ScalarToNodeConverter());
26+
$test = $iteratableConverter->convert(['key' => [true, 1.234, 1, null, 'string', []]])->serialize(); // instanceof ObjectNode::class
27+
var_dump($test);
28+
```
29+
30+
Returns
31+
```
32+
{
33+
["key"]=>
34+
array(5) {
35+
[0]=>
36+
bool(true)
37+
[1]=>
38+
float(1.234)
39+
[2]=>
40+
int(1)
41+
[3]=>
42+
NULL
43+
[4]=>
44+
string(6) "string"
45+
}
46+
}
47+
```
48+
49+
## Example with allowSerializeEmpty
50+
51+
```php
52+
<?php
53+
54+
use Saxulum\ElasticSearchQueryBuilder\Converter\IteratableToNodeConverter;
55+
use Saxulum\ElasticSearchQueryBuilder\Converter\ScalarToNodeConverter;
56+
use Saxulum\ElasticSearchQueryBuilder\Node\ObjectNode;
57+
58+
$iteratableConverter = new IteratableToNodeConverter(new ScalarToNodeConverter());
59+
$test = $iteratableConverter->convert(['key' => [true, 1.234, 1, null, 'string', []]], '', true)->serialize(); // instanceof ObjectNode::class
60+
var_dump($test);
61+
```
62+
63+
Returns
1464
```
65+
{
66+
["key"]=>
67+
array(6) {
68+
[0]=>
69+
bool(true)
70+
[1]=>
71+
float(1.234)
72+
[2]=>
73+
int(1)
74+
[3]=>
75+
NULL
76+
[4]=>
77+
string(6) "string"
78+
[5]=>
79+
array(0) {
80+
}
81+
}
82+
}
83+
```

doc/Converter/ScalarToNodeConverter.md

+11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# ScalarToNodeConverter
22

3+
**Important**: By default empty nodes get not serialized. NullNode forces null value serialization.
4+
5+
* ArrayNode (no elements)
6+
* BoolNode (null)
7+
* ObjectNode (no elements)
8+
* FloatNode (null)
9+
* IntNode (null)
10+
* StringNode (null)
11+
12+
Check the `allowSerializeEmpty` argument to prevent this if needed.
13+
314
## Bool value
415

516
```php

src/Converter/IteratableToNodeConverter.php

+22-12
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,23 @@ public function __construct(ScalarToNodeConverterInterface $scalarToNodeConverte
2727
/**
2828
* @param array|\Traversable $data
2929
* @param string $path
30+
* @param bool $allowSerializeEmpty
3031
*
3132
* @return AbstractParentNode
3233
*
3334
* @throws \InvalidArgumentException
3435
*/
35-
public function convert($data, string $path = ''): AbstractParentNode
36+
public function convert($data, string $path = '', bool $allowSerializeEmpty = false): AbstractParentNode
3637
{
3738
if (!is_array($data) && !$data instanceof \Traversable) {
3839
throw new \InvalidArgumentException(sprintf('Params need to be array or %s', \Traversable::class));
3940
}
4041

4142
$isArray = $this->isArray($data);
42-
$parentNode = $this->getParentNode($isArray);
43+
$parentNode = $this->getParentNode($isArray, $allowSerializeEmpty);
4344

4445
foreach ($data as $key => $value) {
45-
$this->addChildNode($parentNode, $key, $value, $path, $isArray);
46+
$this->addChildNode($parentNode, $key, $value, $path, $isArray, $allowSerializeEmpty);
4647
}
4748

4849
return $parentNode;
@@ -69,16 +70,17 @@ private function isArray($data): bool
6970

7071
/**
7172
* @param bool $isArray
73+
* @param bool $allowSerializeEmpty
7274
*
7375
* @return AbstractParentNode
7476
*/
75-
private function getParentNode(bool $isArray): AbstractParentNode
77+
private function getParentNode(bool $isArray, bool $allowSerializeEmpty): AbstractParentNode
7678
{
7779
if ($isArray) {
78-
return ArrayNode::create();
80+
return ArrayNode::create($allowSerializeEmpty);
7981
}
8082

81-
return ObjectNode::create();
83+
return ObjectNode::create($allowSerializeEmpty);
8284
}
8385

8486
/**
@@ -87,11 +89,18 @@ private function getParentNode(bool $isArray): AbstractParentNode
8789
* @param mixed $value
8890
* @param string $path
8991
* @param bool $isArray
92+
* @param bool $allowSerializeEmpty
9093
*/
91-
private function addChildNode(AbstractParentNode $parentNode, $key, $value, string $path, bool $isArray)
92-
{
94+
private function addChildNode(
95+
AbstractParentNode $parentNode,
96+
$key,
97+
$value,
98+
string $path,
99+
bool $isArray,
100+
bool $allowSerializeEmpty
101+
) {
93102
$subPath = $this->getSubPath($path, $key, $isArray);
94-
$node = $this->getNode($value, $subPath);
103+
$node = $this->getNode($value, $subPath, $allowSerializeEmpty);
95104

96105
if ($isArray) {
97106
$parentNode->add($node);
@@ -121,15 +130,16 @@ private function getSubPath(string $path, $key, bool $isArray): string
121130
/**
122131
* @param mixed $value
123132
* @param string $path
133+
* @param bool $allowSerializeEmpty
124134
*
125135
* @return AbstractNode
126136
*/
127-
private function getNode($value, string $path): AbstractNode
137+
private function getNode($value, string $path, bool $allowSerializeEmpty): AbstractNode
128138
{
129139
if (is_array($value) || $value instanceof \Traversable) {
130-
return $this->convert($value, $path);
140+
return $this->convert($value, $path, $allowSerializeEmpty);
131141
}
132142

133-
return $this->scalarToNodeConverter->convert($value, $path);
143+
return $this->scalarToNodeConverter->convert($value, $path, $allowSerializeEmpty);
134144
}
135145
}

src/Converter/IteratableToNodeConverterInterface.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@
99
interface IteratableToNodeConverterInterface
1010
{
1111
/**
12-
* @param array|\Traversable $params
12+
* @param array|\Traversable $data
1313
*
1414
* @return AbstractParentNode
1515
*
1616
* @throws \InvalidArgumentException
17+
*
18+
* @todo add $path to next major version
19+
* @todo add $allowSerializeEmpty to next major version
1720
*/
18-
public function convert($params): AbstractParentNode;
21+
public function convert($data): AbstractParentNode;
1922
}

src/Converter/ScalarToNodeConverter.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@ final class ScalarToNodeConverter implements ScalarToNodeConverterInterface
2626
/**
2727
* @param bool|float|int|null|string $value
2828
* @param string $path
29+
* @param bool $allowSerializeEmpty
2930
*
3031
* @return AbstractNode
3132
*
3233
* @throws \InvalidArgumentException
3334
*/
34-
public function convert($value, string $path = ''): AbstractNode
35+
public function convert($value, string $path = '', bool $allowSerializeEmpty = false): AbstractNode
3536
{
3637
if (null === $value) {
3738
return NullNode::create();
@@ -47,6 +48,6 @@ public function convert($value, string $path = ''): AbstractNode
4748

4849
$node = $this->typeMapping[$type];
4950

50-
return $node::create($value);
51+
return $node::create($value, $allowSerializeEmpty);
5152
}
5253
}

src/Converter/ScalarToNodeConverterInterface.php

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ interface ScalarToNodeConverterInterface
1515
* @return AbstractNode
1616
*
1717
* @throws \InvalidArgumentException
18+
*
19+
* @todo add $allowSerializeEmpty to next major version
1820
*/
1921
public function convert($value, string $path = ''): AbstractNode;
2022
}

tests/Converter/IteratableToNodeConverterTest.php

+16
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public function testConvert()
4646
5 => 'string',
4747
],
4848
0 => 'value',
49+
'emptyArray' => []
4950
]);
5051

5152
$expected = <<<EOD
@@ -79,6 +80,21 @@ public function testConvert()
7980
self::assertSame($expected, $node->json(true));
8081
}
8182

83+
public function testConvertWithAllowEmptySerialze()
84+
{
85+
$iteratableConverter = new IteratableToNodeConverter($this->getScalarToNodeConverter());
86+
87+
$node = $iteratableConverter->convert(['emptyArray' => []], '', true);
88+
89+
$expected = <<<EOD
90+
{
91+
"emptyArray": []
92+
}
93+
EOD;
94+
95+
self::assertEquals($expected, $node->json(true));
96+
}
97+
8298
public function testWithoutArrayOrTraversableExpectException()
8399
{
84100
self::expectException(\InvalidArgumentException::class);

tests/Converter/ScalarToNodeConverterTest.php

+14
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,20 @@ public function testConvertString()
5252
self::assertInstanceOf(StringNode::class, $valueConverter->convert('string'));
5353
}
5454

55+
public function testConvertSetsDefaultIsAllowSerializeEmpty()
56+
{
57+
$valueConverter = new ScalarToNodeConverter();
58+
59+
self::assertFalse($valueConverter->convert('string')->isAllowSerializeEmpty());
60+
}
61+
62+
public function testConvertSetsIsAllowSerializeEmpty()
63+
{
64+
$valueConverter = new ScalarToNodeConverter();
65+
66+
self::assertTrue($valueConverter->convert('string', '', true)->isAllowSerializeEmpty());
67+
}
68+
5569
public function testConvertWithUnsupportedValueExpectException()
5670
{
5771
self::expectException(\InvalidArgumentException::class);

0 commit comments

Comments
 (0)