Skip to content

Commit 5ebd2cf

Browse files
authored
Merge pull request #102 from holywise/fix-bom-in-all-rows
fix bom appears in all rows if _bom is enabled. #101
2 parents fa3729e + b4cff01 commit 5ebd2cf

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

src/View/CsvView.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,13 @@ class CsvView extends View
106106
*/
107107
protected $bomMap;
108108

109+
/**
110+
* BOM first appearance
111+
*
112+
* @var bool
113+
*/
114+
protected $isFirstBom;
115+
109116
/**
110117
* List of special view vars.
111118
*
@@ -153,6 +160,7 @@ public function __construct(
153160
parent::__construct($request, $response, $eventManager, $viewOptions);
154161

155162
$this->response = $this->response->withType('csv');
163+
$this->isFirstBom = true;
156164
}
157165

158166
/**
@@ -456,8 +464,9 @@ protected function _generateRow($row = null)
456464
}
457465

458466
//bom must be added after encoding
459-
if ($this->viewVars['_bom']) {
467+
if ($this->viewVars['_bom'] && $this->isFirstBom) {
460468
$csv = $this->getBom($this->viewVars['_csvEncoding']) . $csv;
469+
$this->isFirstBom = false;
461470
}
462471

463472
return $csv;

tests/TestCase/View/CsvViewTest.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,58 @@ public function testBom()
6262
$this->assertSame($expected, $output);
6363
}
6464

65+
/**
66+
* Test BOM appears only in the first row.
67+
*
68+
* @return void
69+
*/
70+
public function testBomMultipleContentRows()
71+
{
72+
if (!extension_loaded('mbstring')) {
73+
$this->markTestSkipped(
74+
'The mbstring extension is not available.'
75+
);
76+
}
77+
78+
$data = [
79+
['test'],
80+
['test2'],
81+
['test3'],
82+
];
83+
$this->view->set(['data' => $data, '_serialize' => 'data', '_bom' => true, '_csvEncoding' => 'UTF-8']);
84+
$output = $this->view->render(false);
85+
86+
$bom = chr(0xEF) . chr(0xBB) . chr(0xBF);
87+
$expected = $bom . 'test' . PHP_EOL . 'test2' . PHP_EOL . 'test3' . PHP_EOL;
88+
$this->assertSame($expected, $output);
89+
}
90+
91+
/**
92+
* Test BOM appears only in the first row even it has a header.
93+
*
94+
* @return void
95+
*/
96+
public function testBomMultipleContentRowsWithHeader()
97+
{
98+
if (!extension_loaded('mbstring')) {
99+
$this->markTestSkipped(
100+
'The mbstring extension is not available.'
101+
);
102+
}
103+
104+
$header = ['column1'];
105+
$data = [
106+
['test'],
107+
['test2'],
108+
];
109+
$this->view->set(['data' => $data, '_header' => $header, '_serialize' => 'data', '_bom' => true, '_csvEncoding' => 'UTF-8']);
110+
$output = $this->view->render(false);
111+
112+
$bom = chr(0xEF) . chr(0xBB) . chr(0xBF);
113+
$expected = $bom . 'column1' . PHP_EOL . 'test' . PHP_EOL . 'test2' . PHP_EOL;
114+
$this->assertSame($expected, $output);
115+
}
116+
65117
/**
66118
* Test render with an array in _serialize
67119
*

0 commit comments

Comments
 (0)