2 namespace Consolidation\OutputFormatters\Formatters;
4 use Consolidation\OutputFormatters\Validate\ValidDataTypesInterface;
5 use Consolidation\OutputFormatters\Options\FormatterOptions;
6 use Consolidation\OutputFormatters\Validate\ValidDataTypesTrait;
7 use Consolidation\OutputFormatters\Transformations\TableTransformation;
8 use Consolidation\OutputFormatters\Exception\IncompatibleDataException;
9 use Symfony\Component\Console\Output\OutputInterface;
12 * Comma-separated value formatters
14 * Display the provided structured data in a comma-separated list. If
15 * there are multiple records provided, then they will be printed
16 * one per line. The primary data types accepted are RowsOfFields and
17 * PropertyList. The later behaves exactly like the former, save for
18 * the fact that it contains but a single row. This formmatter can also
19 * accept a PHP array; this is also interpreted as a single-row of data
22 class CsvFormatter implements FormatterInterface, ValidDataTypesInterface, RenderDataInterface
24 use ValidDataTypesTrait;
25 use RenderTableDataTrait;
27 public function validDataTypes()
31 new \ReflectionClass('\Consolidation\OutputFormatters\StructuredData\RowsOfFields'),
32 new \ReflectionClass('\Consolidation\OutputFormatters\StructuredData\PropertyList'),
33 new \ReflectionClass('\ArrayObject'),
37 public function validate($structuredData)
39 // If the provided data was of class RowsOfFields
40 // or PropertyList, it will be converted into
41 // a TableTransformation object.
42 if (!is_array($structuredData) && (!$structuredData instanceof TableTransformation)) {
43 throw new IncompatibleDataException(
46 $this->validDataTypes()
49 // If the data was provided to us as a single array, then
50 // convert it to a single row.
51 if (is_array($structuredData) && !empty($structuredData)) {
52 $firstRow = reset($structuredData);
53 if (!is_array($firstRow)) {
54 return [$structuredData];
57 return $structuredData;
61 * Return default values for formatter options
64 protected function getDefaultFormatterOptions()
67 FormatterOptions::INCLUDE_FIELD_LABELS => true,
68 FormatterOptions::DELIMITER => ',',
75 public function write(OutputInterface $output, $data, FormatterOptions $options)
77 $defaults = $this->getDefaultFormatterOptions();
79 $includeFieldLabels = $options->get(FormatterOptions::INCLUDE_FIELD_LABELS, $defaults);
80 if ($includeFieldLabels && ($data instanceof TableTransformation)) {
81 $headers = $data->getHeaders();
82 $this->writeOneLine($output, $headers, $options);
85 foreach ($data as $line) {
86 $this->writeOneLine($output, $line, $options);
90 protected function writeOneLine(OutputInterface $output, $data, $options)
92 $defaults = $this->getDefaultFormatterOptions();
93 $delimiter = $options->get(FormatterOptions::DELIMITER, $defaults);
95 $output->write($this->csvEscape($data, $delimiter));
98 protected function csvEscape($data, $delimiter = ',')
100 $buffer = fopen('php://temp', 'r+');
101 fputcsv($buffer, $data, $delimiter);
103 $csv = fgets($buffer);