Skip to content

Commit 3225ca1

Browse files
committed
Refactor array generation to be less complex
1 parent 2d8c6ec commit 3225ca1

File tree

3 files changed

+57
-60
lines changed

3 files changed

+57
-60
lines changed

src/Encoder/ArrayEncoder.php

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,49 @@ public function encode($value, $depth, array $options, callable $encode)
4040
implode(',', $this->getPairs($value, '', $options['array.omit'], $encode)),
4141
$options['array.short']
4242
);
43+
} elseif ($options['array.align']) {
44+
return $this->buildArray($this->getAlignedPairs($value, $encode), $depth, $options);
4345
}
4446

45-
if (is_string($lines = $this->getLines($value, $options, $encode))) {
46-
return $lines;
47+
return $this->getFormattedArray($value, $depth, $options, $encode);
48+
}
49+
50+
private function getFormattedArray(array $array, $depth, $options, $encode)
51+
{
52+
$lines = $this->getPairs($array, ' ', $options['array.omit'], $encode, $omitted);
53+
54+
if ($omitted && $options['array.inline'] !== false) {
55+
$output = $this->getInlineArray($lines, $options);
56+
57+
if ($output !== false) {
58+
return $output;
59+
}
60+
}
61+
62+
return $this->buildArray($lines, $depth, $options);
63+
}
64+
65+
private function getInlineArray($lines, $options)
66+
{
67+
$output = $this->wrap(implode(', ', $lines), $options['array.short']);
68+
69+
if (preg_match('/[\r\n\t]/', $output)) {
70+
return false;
71+
} elseif ($options['array.inline'] !== true && strlen($output) > (int) $options['array.inline']) {
72+
return false;
4773
}
4874

75+
return $output;
76+
}
77+
78+
private function buildArray(array $lines, $depth, array $options)
79+
{
4980
$indent = $this->buildIndent($options['array.base'], $options['array.indent'], $depth + 1);
5081
$last = $this->buildIndent($options['array.base'], $options['array.indent'], $depth);
5182
$eol = $options['array.eol'] === false ? PHP_EOL : (string) $options['array.eol'];
5283

5384
return $this->wrap(
54-
$eol . $indent . implode(',' . $eol .$indent, $lines) . ',' . $eol .$last,
85+
sprintf('%s%s%s,%1$s%s', $eol, $indent, implode(',' . $eol . $indent, $lines), $last),
5586
$options['array.short']
5687
);
5788
}
@@ -85,38 +116,10 @@ private function buildIndent($base, $indent, $depth)
85116
}
86117

87118
/**
88-
* Returns the code representation for the array values and keys.
89-
* @param array $array Array to convert into code
90-
* @param array $options List of encoder options
91-
* @param callable $encode Callback used to encode values
92-
* @return string|string[] Array encoded as strings or simple array as a string
93-
*/
94-
private function getLines(array $array, array $options, callable $encode)
95-
{
96-
if ($options['array.align']) {
97-
return $this->getAlignedPairs($array, $encode);
98-
}
99-
100-
$lines = $this->getPairs($array, ' ', $options['array.omit'], $encode, $inline);
101-
102-
if ($inline && $options['array.inline'] !== false) {
103-
$output = $this->wrap(implode(', ', $lines), $options['array.short']);
104-
105-
if (!preg_match('/[\r\n\t]/', $output) &&
106-
($options['array.inline'] === true || strlen($output) <= (int) $options['array.inline'])
107-
) {
108-
return $output;
109-
}
110-
}
111-
112-
return $lines;
113-
}
114-
115-
/**
116-
* Returns the array as aligned key and value pairs.
119+
* Returns each encoded key and value pair with aligned assignment operators.
117120
* @param array $array Array to convert into code
118121
* @param callable $encode Callback used to encode values
119-
* @return string[] List of array key and value pairs as strings
122+
* @return string[] Each of key and value pair encoded as php
120123
*/
121124
private function getAlignedPairs($array, callable $encode)
122125
{
@@ -139,27 +142,27 @@ private function getAlignedPairs($array, callable $encode)
139142
}
140143

141144
/**
142-
* Encodes the array as code pairs according to given parameters
145+
* Returns each key and value pair encoded as array assignment.
143146
* @param array $array Array to convert into code
144147
* @param string $space Whitespace between array assignment operator
145148
* @param boolean $omit True to omit unnecessary keys, false to not
146149
* @param callable $encode Callback used to encode values
147-
* @param boolean $inline Set to true, if all the keys were omitted, false otherwise *
148-
* @return string[] List of array key and value pairs as strings
150+
* @param boolean $omitted Set to true, if all the keys were omitted, false otherwise
151+
* @return string[] Each of key and value pair encoded as php
149152
*/
150-
private function getPairs($array, $space, $omit, callable $encode, & $inline = true)
153+
private function getPairs($array, $space, $omit, callable $encode, & $omitted = true)
151154
{
152155
$pairs = [];
153156
$nextIndex = 0;
154-
$inline = true;
157+
$omitted = true;
155158
$format = '%s' . $space . '=>' . $space . '%s';
156159

157160
foreach ($array as $key => $value) {
158161
if ($key === $nextIndex && $omit) {
159162
$pairs[] = $encode($value, 1);
160163
} else {
161164
$pairs[] = sprintf($format, $encode($key, 1), $encode($value, 1));
162-
$inline = false;
165+
$omitted = false;
163166
}
164167

165168
if (is_int($key) && $key >= $nextIndex) {

tests/tests/ArrayEncodingTest.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,27 @@ public function testNoInline()
6565
$this->assertEncode([1, 2], "array(\n 1,\n 2,\n)", $encoder);
6666
}
6767

68-
public function atestAssociativeArray()
68+
public function testTooLongForInline()
69+
{
70+
$encoder = new PHPEncoder(['array.indent' => 1, 'array.inline' => 14, 'array.eol' => "\n"]);
71+
$this->assertEncode(['0123456789'], "['0123456789']", $encoder);
72+
73+
$encoder->setOption('array.inline', 13);
74+
$this->assertEncode(['0123456789'], "[\n '0123456789',\n]", $encoder);
75+
}
76+
77+
public function testAssociativeArray()
6978
{
7079
$encoder = new PHPEncoder(['whitespace' => false]);
7180
$this->assertEncode([1 => 1], "[1=>1]", $encoder);
7281
$this->assertEncode([1 => 1, 0 => 0], "[1=>1,0=>0]", $encoder);
7382
$this->assertEncode(['foo' => 'bar', 1 => true], "['foo'=>'bar',1=>true]", $encoder);
7483

75-
$encoder->setIndent("\t", ' ');
84+
$encoder->setOption('whitespace', true);
85+
$encoder->setOption('array.base', ' ');
86+
$encoder->setOption('array.indent', "\t");
87+
88+
$e = PHP_EOL;
7689
$this->assertEncode(
7790
['foo' => 'bar', 1 => true],
7891
"[$e \t'foo' => 'bar',$e \t1 => true,$e ]",

tests/tests/ObjectEncodingTest.php

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -53,25 +53,6 @@ public function testPHP()
5353
$this->assertSame('"Mocked"', $encoder->encode($mock));
5454
}
5555

56-
public function atestPropertiesArray()
57-
{
58-
$e = PHP_EOL;
59-
$encoder = new PHPEncoder();
60-
$obj = new \TestMockObject();
61-
62-
$encoder->setIndent(false);
63-
$encoder->setObjectFlags(PHPEncoder::OBJECT_PROPERTIES);
64-
$this->assertSame("['baz'=>'C']", $encoder->encode($obj));
65-
66-
$encoder->setIndent(1);
67-
$encoder->setObjectFlags(PHPEncoder::OBJECT_PROPERTIES | PHPEncoder::OBJECT_CAST);
68-
$this->assertSame("(object) [$e 'baz' => 'C',$e]", $encoder->encode($obj));
69-
70-
$std = new \stdClass();
71-
$std->baz = 'C';
72-
$this->assertEquals("(object) []", $encoder->encode($std));
73-
}
74-
7556
public function testObjectVarsArray()
7657
{
7758
$encoder = new PHPEncoder([

0 commit comments

Comments
 (0)