Version 1
[yaffs-website] / vendor / consolidation / output-formatters / src / Formatters / CsvFormatter.php
1 <?php
2 namespace Consolidation\OutputFormatters\Formatters;
3
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;
10
11 /**
12  * Comma-separated value formatters
13  *
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
20  * with no header.
21  */
22 class CsvFormatter implements FormatterInterface, ValidDataTypesInterface, RenderDataInterface
23 {
24     use ValidDataTypesTrait;
25     use RenderTableDataTrait;
26
27     public function validDataTypes()
28     {
29         return
30             [
31                 new \ReflectionClass('\Consolidation\OutputFormatters\StructuredData\RowsOfFields'),
32                 new \ReflectionClass('\Consolidation\OutputFormatters\StructuredData\PropertyList'),
33                 new \ReflectionClass('\ArrayObject'),
34             ];
35     }
36
37     public function validate($structuredData)
38     {
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(
44                 $this,
45                 $structuredData,
46                 $this->validDataTypes()
47             );
48         }
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];
55             }
56         }
57         return $structuredData;
58     }
59
60     /**
61      * Return default values for formatter options
62      * @return array
63      */
64     protected function getDefaultFormatterOptions()
65     {
66         return [
67             FormatterOptions::INCLUDE_FIELD_LABELS => true,
68             FormatterOptions::DELIMITER => ',',
69         ];
70     }
71
72     /**
73      * @inheritdoc
74      */
75     public function write(OutputInterface $output, $data, FormatterOptions $options)
76     {
77         $defaults = $this->getDefaultFormatterOptions();
78
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);
83         }
84
85         foreach ($data as $line) {
86             $this->writeOneLine($output, $line, $options);
87         }
88     }
89
90     protected function writeOneLine(OutputInterface $output, $data, $options)
91     {
92         $defaults = $this->getDefaultFormatterOptions();
93         $delimiter = $options->get(FormatterOptions::DELIMITER, $defaults);
94
95         $output->write($this->csvEscape($data, $delimiter));
96     }
97
98     protected function csvEscape($data, $delimiter = ',')
99     {
100         $buffer = fopen('php://temp', 'r+');
101         fputcsv($buffer, $data, $delimiter);
102         rewind($buffer);
103         $csv = fgets($buffer);
104         fclose($buffer);
105         return $csv;
106     }
107 }