Test Failed
Push — master ( 05b030...31551e )
by Andy
02:05
created

CsvFileObject::getSize()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 10
ccs 0
cts 3
cp 0
rs 9.4285
cc 2
eloc 6
nc 2
nop 0
crap 6
1
<?php
2
3
namespace Palmtree\Csv;
4
5
class CsvFileObject extends \SplFileObject
6
{
7
    protected $bytesWritten = 0;
8
    protected $lineEnding = "\r\n";
9
10
    public function fwriteCsv(array $row, $delimiter = null, $enclosure = null)
11
    {
12
        $bytes = $this->fwrite($this->getCsvString($row, $delimiter, $enclosure));
13
14
        if ($bytes === false) {
15
            return false;
16
        }
17
18
        $this->bytesWritten += $bytes;
19
20
        return $bytes;
21
    }
22
23
    public function __destruct()
24
    {
25
        $this->trimFinalLineEnding();
26
    }
27
28
    /**
29
     * Returns a string representation of a row to be written
30
     * as a line in a CSV file.
31
     *
32
     * @param array $row
33
     *
34
     * @param       $delimiter
35
     * @param       $enclosure
36
     *
37
     * @return string
38
     */
39
    protected function getCsvString(array $row, $delimiter, $enclosure)
40
    {
41
        $csvControl = $this->getCsvControl();
42
43
        $delimiter = $delimiter ? : $csvControl[0];
44
        $enclosure = $enclosure ? : $csvControl[1];
45
46
        $result = $enclosure;
47
        $result .= implode($enclosure . $delimiter . $enclosure, self::escapeEnclosure($row, $enclosure));
48
        $result .= $enclosure;
49
50
        $result .= $this->getLineEnding();
51
52
        return $result;
53
    }
54
55
    /**
56
     * @return int
57
     */
58
    public function getBytesWritten()
59
    {
60
        return (int)$this->bytesWritten;
61
    }
62
63
    /**
64
     * @return string
65
     */
66
    public function getLineEnding()
67
    {
68
        return $this->lineEnding;
69
    }
70
71
    /**
72
     * @param string $lineEnding
73
     *
74
     * @return CsvFileObject
75
     */
76
    public function setLineEnding($lineEnding)
77
    {
78
        $this->lineEnding = $lineEnding;
79
80
        return $this;
81
    }
82
83
    public function getSize()
84
    {
85
        try {
86
            $size = parent::getSize();
87
        } catch (\RuntimeException $exception) {
88
            $size = parent::fstat()['size'];
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (fstat() instead of getSize()). Are you sure this is correct? If so, you might want to change this to $this->fstat().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
89
        }
90
91
        return $size;
92
    }
93
94
    /**
95
     * Trims the line ending delimiter from the end of the CSV file.
96
     * RFC-4180 states CSV files should not contain a trailing new line.
97
     */
98
    public function trimFinalLineEnding()
99
    {
100
        if ($this->getBytesWritten() > 0) {
101
            // Only trim the file if it ends with the line ending delimiter.
102
            $length = mb_strlen($this->getLineEnding());
103
104
            $this->fseek(-$length, SEEK_END);
105
106
            if ($this->fread($length) === $this->getLineEnding()) {
1 ignored issue
show
Bug introduced by
The method fread() does not seem to exist on object<Palmtree\Csv\CsvFileObject>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
107
                $this->ftruncate($this->getBytesWritten() - $length);
108
            }
109
        }
110
    }
111
112
    /**
113
     * Escapes the enclosure character recursively.
114
     * RFC-4180 states the enclosure character (usually double quotes) should be
115
     * escaped by itself, so " becomes "".
116
     *
117
     * @param mixed $data Array or string of data to escape.
118
     *
119
     * @param       $enclosure
120
     *
121
     * @return mixed Escaped data
122
     */
123
    protected static function escapeEnclosure($data, $enclosure)
124
    {
125
        if (is_array($data)) {
126
            foreach ($data as $key => $value) {
127
                $data[$key] = self::escapeEnclosure($value, $enclosure);
128
            }
129
        } else {
130
            $data = str_replace($enclosure, str_repeat($enclosure, 2), $data);
131
        }
132
133
        return $data;
134
    }
135
}
136