Completed
Push — master ( 6428d8...2f66fb )
by Greg
03:32
created

CsvFormatter::writeCsvLine()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 2
Bugs 0 Features 2
Metric Value
c 2
b 0
f 2
dl 0
loc 4
ccs 4
cts 4
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 3
crap 1
1
<?php
2
namespace Consolidation\OutputFormatters\Formatters;
3
4
use Consolidation\OutputFormatters\FormatterInterface;
5
use Consolidation\OutputFormatters\ValidationInterface;
6
use Consolidation\OutputFormatters\FormatterOptions;
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
 * AssociativeList. 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, ValidationInterface, RenderDataInterface
23
{
24
    use RenderTableDataTrait;
25 12
26
    public function validDataTypes()
27
    {
28
        return
29
            [
30 12
                new \ReflectionClass('\Consolidation\OutputFormatters\StructuredData\RowsOfFields'),
31 1
                new \ReflectionClass('\Consolidation\OutputFormatters\StructuredData\AssociativeList'),
32 1
                new \ReflectionClass('\ArrayObject'),
33 1
            ];
34
    }
35 1
36 1
    public function validate($structuredData)
37 1
    {
38
        // If the provided data was of class RowsOfFields
39 1
        // or AssociativeList, it will be converted into
40
        // a TableTransformation object.
41
        if (!is_array($structuredData) && (!$structuredData instanceof TableTransformation)) {
42
            throw new IncompatibleDataException(
43 11
                $this,
44 6
                $structuredData,
45 6
                $this->validDataTypes()
46 5
            );
47
        }
48 1
        // If the data was provided to us as a single array, then
49 6
        // convert it to a single row.
50
        if (is_array($structuredData) && !empty($structuredData)) {
51
            $firstRow = reset($structuredData);
52
            if (!is_array($firstRow)) {
53
                return [$structuredData];
54
            }
55 11
        }
56
        return $structuredData;
57
    }
58 11
59
    /**
60
     * Return default values for formatter options
61 11
     * @return array
62 5
     */
63 5
    protected function getDefaultFormatterOptions()
64 5
    {
65
        return [
66 11
            FormatterOptions::INCLUDE_FIELD_LABELS => true,
67 11
            FormatterOptions::DELIMITER => ',',
68 11
        ];
69 11
    }
70
71 11
    /**
72
     * @inheritdoc
73 11
     */
74 11
    public function write(OutputInterface $output, $data, FormatterOptions $options)
75
    {
76 11
        $defaults = $this->getDefaultFormatterOptions();
77
78 11
        if ($options->get(FormatterOptions::INCLUDE_FIELD_LABELS, $defaults) && ($data instanceof TableTransformation)) {
79 11
            $headers = $data->getHeaders();
80 11
            $this->writeOneLine($output, $headers, $options);
81 11
        }
82 11
83 11
        foreach ($data as $line) {
84
            $this->writeOneLine($output, $line, $options);
85
        }
86
    }
87
88
    protected function writeOneLine(OutputInterface $output, $data, $options)
89
    {
90
        $defaults = $this->getDefaultFormatterOptions();
91
        $delimiter = $options->get(FormatterOptions::DELIMITER, $defaults);
92
93
        $output->write($this->csvEscape($data, $delimiter));
94
    }
95
96
    protected function csvEscape($data, $delimiter = ',')
97
    {
98
        $buffer = fopen('php://temp', 'r+');
99
        fputcsv($buffer, $data, $delimiter);
100
        rewind($buffer);
101
        $csv = fgets($buffer);
102
        fclose($buffer);
103
        return $csv;
104
    }
105
}
106