From 805dd4927c01c0b801e9d045ad101c622a1df89d Mon Sep 17 00:00:00 2001 From: battye Date: Thu, 13 Jun 2019 08:42:28 +0000 Subject: [PATCH] [Serializer] Handle true/false/null appropriately in CSV encoder --- .../Serializer/Encoder/CsvEncoder.php | 29 ++++++++++++++++++- .../Tests/Encoder/CsvEncoderTest.php | 19 ++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php b/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php index 1e47d35f17c7f..926eb72d1ceaa 100644 --- a/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php +++ b/src/Symfony/Component/Serializer/Encoder/CsvEncoder.php @@ -189,11 +189,38 @@ private function flatten(array $array, array &$result, $keySeparator, $parentKey if (\is_array($value)) { $this->flatten($value, $result, $keySeparator, $parentKey.$key.$keySeparator); } else { - $result[$parentKey.$key] = $value; + $result[$parentKey.$key] = $this->cleanValueByType($value); } } } + /** + * Ensures an actual value is used instead of a blank value when dealing + * with true, false and null (like a nullable bool in a database). + * + * @param string $value + * + * @return string|int + */ + private function cleanValueByType($value) + { + if (false === $value) { + return 0; + } + + if (null === $value) { + // fputcsv will enclose a space + // https://github.com/php/php-src/blob/master/ext/standard/file.c + return ' '; + } + + if (true === $value) { + return 1; + } + + return $value; + } + private function getCsvOptions(array $context) { $delimiter = isset($context[self::DELIMITER_KEY]) ? $context[self::DELIMITER_KEY] : $this->delimiter; diff --git a/src/Symfony/Component/Serializer/Tests/Encoder/CsvEncoderTest.php b/src/Symfony/Component/Serializer/Tests/Encoder/CsvEncoderTest.php index 1eb673e8e21ba..a3a13f47f9edf 100644 --- a/src/Symfony/Component/Serializer/Tests/Encoder/CsvEncoderTest.php +++ b/src/Symfony/Component/Serializer/Tests/Encoder/CsvEncoderTest.php @@ -29,6 +29,25 @@ protected function setUp() $this->encoder = new CsvEncoder(); } + public function testTrueFalseNullValues() + { + $data = [ + 'string' => 'foo', + 'int' => 2, + 'false' => false, + 'true' => true, + 'null' => null, + ]; + + // Check that true, false and null are appropriately handled + $this->assertEquals(<<<'CSV' +string,int,false,true,null +foo,2,0,1," " + +CSV + , $this->encoder->encode($data, 'csv')); + } + public function testSupportEncoding() { $this->assertTrue($this->encoder->supportsEncoding('csv'));