Completed
Pull Request — master (#6)
by Harry
05:55 queued 01:49
created

CsvFormatter::getInitialBlock()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * This file is part of graze/data-file
4
 *
5
 * Copyright (c) 2016 Nature Delivered Ltd. <https://www.graze.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @license https://github.com/graze/data-file/blob/master/LICENSE.md
11
 * @link    https://github.com/graze/data-file
12
 */
13
14
namespace Graze\DataFile\Format\Formatter;
15
16
use Graze\DataFile\Format\CsvFormatInterface;
17
use Graze\DataFile\Format\Processor\BoolProcessor;
18
use Graze\DataFile\Format\Processor\DateTimeProcessor;
19
use Graze\DataFile\Format\Processor\ObjectToStringProcessor;
20
use Graze\DataFile\Format\Processor\RowProcessor;
21
22
class CsvFormatter implements FormatterInterface
23
{
24
    use RowProcessor;
25
    use InvokeFormatter;
26
27
    /**
28
     * @var CsvFormatInterface
29
     */
30
    private $csvFormat;
31
32
    /**
33
     * @var string[]
34
     */
35
    private $escapeChars;
36
37
    /**
38
     * @var string[]
39
     */
40
    private $replaceChars;
41
42
    /**
43
     * @var string
44
     */
45
    private $initial;
46
47
    /**
48
     * @param CsvFormatInterface $csvFormat
49
     */
50 15
    public function __construct(CsvFormatInterface $csvFormat)
51
    {
52 15
        $this->csvFormat = $csvFormat;
53
54 15
        if ($this->csvFormat->getEscapeCharacter()) {
55 13
            $this->escapeChars = [
56 13
                $this->csvFormat->getEscapeCharacter(), // escape escape first so that it doesn't re-escape later on
57 13
                $this->csvFormat->getDelimiter(),
58 13
                "\n",
59 13
                "\r",
60 13
                "\t",
61
            ];
62 13
            if ($this->csvFormat->hasQuotes() && !$this->csvFormat->isDoubleQuote()) {
63 10
                $this->escapeChars[] = $this->csvFormat->getQuoteCharacter();
64
            }
65
66 13
            $this->escapeChars = array_unique($this->escapeChars);
67
68 13
            $this->replaceChars = array_map(function ($char) {
69 13
                return $this->csvFormat->getEscapeCharacter() . $char;
70 13
            }, $this->escapeChars);
71
        }
72
73 15
        if ($this->csvFormat->hasQuotes() && $this->csvFormat->isDoubleQuote()) {
74 2
            $this->escapeChars[] = $this->csvFormat->getQuoteCharacter();
75 2
            $this->replaceChars[] = str_repeat($this->csvFormat->getQuoteCharacter(), 2);
76
        }
77
78 15
        $this->initial = (!is_null($this->csvFormat->getBom())) ? $this->csvFormat->getBom() : '';
79
80 15
        $this->addProcessor(new DateTimeProcessor());
81 15
        $this->addProcessor(new BoolProcessor());
82 15
        $this->addProcessor(new ObjectToStringProcessor());
83 15
    }
84
85
    /**
86
     * @param array $data
87
     *
88
     * @return string
89
     */
90 11
    public function format(array $data)
91
    {
92 11
        $data = $this->process($data);
93
94 11
        foreach ($data as &$element) {
95 11
            if (is_null($element)) {
96 4
                $element = $this->csvFormat->getNullOutput();
97
            } else {
98 11
                $element = $this->csvFormat->getQuoteCharacter() . $this->escape($element) . $this->csvFormat->getQuoteCharacter();
99
            }
100
        }
101
102 11
        return $this->encode(implode($this->csvFormat->getDelimiter(), $data));
103
    }
104
105
    /**
106
     * @param string $string
107
     *
108
     * @return string
109
     */
110 11
    protected function escape($string)
111
    {
112 11
        return str_replace($this->escapeChars, $this->replaceChars, $string);
113
    }
114
115
    /**
116
     * @param string $string
117
     *
118
     * @return string
119
     */
120 12
    private function encode($string)
121
    {
122 12
        return mb_convert_encoding($string, $this->csvFormat->getEncoding());
123
    }
124
125
    /**
126
     * Return an initial block if required
127
     *
128
     * @return string
129
     */
130 5
    public function getInitialBlock()
131
    {
132 5
        return $this->initial;
133
    }
134
135
    /**
136
     * Get a separator between each row
137
     *
138
     * @return string
139
     */
140 4
    public function getRowSeparator()
141
    {
142 4
        return $this->encode($this->csvFormat->getLineTerminator());
143
    }
144
145
    /**
146
     * Return a closing block if required
147
     *
148
     * @return string
149
     */
150 5
    public function getClosingBlock()
151
    {
152 5
        return '';
153
    }
154
}
155