|
21 | 21 | class CsvEncoder implements EncoderInterface, DecoderInterface
|
22 | 22 | {
|
23 | 23 | const FORMAT = 'csv';
|
| 24 | + const DELIMITER_KEY = 'csv_delimiter'; |
| 25 | + const ENCLOSURE_KEY = 'csv_enclosure'; |
| 26 | + const ESCAPE_CHAR_KEY = 'csv_escape_char'; |
| 27 | + const KEY_SEPARATOR_KEY = 'csv_key_separator'; |
24 | 28 |
|
25 | 29 | private $delimiter;
|
26 | 30 | private $enclosure;
|
@@ -65,19 +69,21 @@ public function encode($data, $format, array $context = array())
|
65 | 69 | }
|
66 | 70 | }
|
67 | 71 |
|
| 72 | + list($delimiter, $enclosure, $escapeChar, $keySeparator) = $this->getCsvOptions($context); |
| 73 | + |
68 | 74 | $headers = null;
|
69 | 75 | foreach ($data as $value) {
|
70 | 76 | $result = array();
|
71 |
| - $this->flatten($value, $result); |
| 77 | + $this->flatten($value, $result, $keySeparator); |
72 | 78 |
|
73 | 79 | if (null === $headers) {
|
74 | 80 | $headers = array_keys($result);
|
75 |
| - fputcsv($handle, $headers, $this->delimiter, $this->enclosure, $this->escapeChar); |
| 81 | + fputcsv($handle, $headers, $delimiter, $enclosure, $escapeChar); |
76 | 82 | } elseif (array_keys($result) !== $headers) {
|
77 | 83 | throw new InvalidArgumentException('To use the CSV encoder, each line in the data array must have the same structure. You may want to use a custom normalizer class to normalize the data format before passing it to the CSV encoder.');
|
78 | 84 | }
|
79 | 85 |
|
80 |
| - fputcsv($handle, $result, $this->delimiter, $this->enclosure, $this->escapeChar); |
| 86 | + fputcsv($handle, $result, $delimiter, $enclosure, $escapeChar); |
81 | 87 | }
|
82 | 88 |
|
83 | 89 | rewind($handle);
|
@@ -108,14 +114,16 @@ public function decode($data, $format, array $context = array())
|
108 | 114 | $nbHeaders = 0;
|
109 | 115 | $result = array();
|
110 | 116 |
|
111 |
| - while (false !== ($cols = fgetcsv($handle, 0, $this->delimiter, $this->enclosure, $this->escapeChar))) { |
| 117 | + list($delimiter, $enclosure, $escapeChar, $keySeparator) = $this->getCsvOptions($context); |
| 118 | + |
| 119 | + while (false !== ($cols = fgetcsv($handle, 0, $delimiter, $enclosure, $escapeChar))) { |
112 | 120 | $nbCols = count($cols);
|
113 | 121 |
|
114 | 122 | if (null === $headers) {
|
115 | 123 | $nbHeaders = $nbCols;
|
116 | 124 |
|
117 | 125 | foreach ($cols as $col) {
|
118 |
| - $headers[] = explode($this->keySeparator, $col); |
| 126 | + $headers[] = explode($keySeparator, $col); |
119 | 127 | }
|
120 | 128 |
|
121 | 129 | continue;
|
@@ -166,16 +174,27 @@ public function supportsDecoding($format)
|
166 | 174 | *
|
167 | 175 | * @param array $array
|
168 | 176 | * @param array $result
|
| 177 | + * @param string $keySeparator |
169 | 178 | * @param string $parentKey
|
170 | 179 | */
|
171 |
| - private function flatten(array $array, array &$result, $parentKey = '') |
| 180 | + private function flatten(array $array, array &$result, $keySeparator, $parentKey = '') |
172 | 181 | {
|
173 | 182 | foreach ($array as $key => $value) {
|
174 | 183 | if (is_array($value)) {
|
175 |
| - $this->flatten($value, $result, $parentKey.$key.$this->keySeparator); |
| 184 | + $this->flatten($value, $result, $keySeparator, $parentKey.$key.$keySeparator); |
176 | 185 | } else {
|
177 | 186 | $result[$parentKey.$key] = $value;
|
178 | 187 | }
|
179 | 188 | }
|
180 | 189 | }
|
| 190 | + |
| 191 | + private function getCsvOptions(array $context) |
| 192 | + { |
| 193 | + $delimiter = isset($context[self::DELIMITER_KEY]) ? $context[self::DELIMITER_KEY] : $this->delimiter; |
| 194 | + $enclosure = isset($context[self::ENCLOSURE_KEY]) ? $context[self::ENCLOSURE_KEY] : $this->enclosure; |
| 195 | + $escapeChar = isset($context[self::ESCAPE_CHAR_KEY]) ? $context[self::ESCAPE_CHAR_KEY] : $this->escapeChar; |
| 196 | + $keySeparator = isset($context[self::KEY_SEPARATOR_KEY]) ? $context[self::KEY_SEPARATOR_KEY] : $this->keySeparator; |
| 197 | + |
| 198 | + return array($delimiter, $enclosure, $escapeChar, $keySeparator); |
| 199 | + } |
181 | 200 | }
|
0 commit comments