CsvFileObject   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 78
Duplicated Lines 0 %

Test Coverage

Coverage 77.42%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 11
eloc 26
c 2
b 0
f 0
dl 0
loc 78
ccs 24
cts 31
cp 0.7742
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __destruct() 0 3 1
A getLineEnding() 0 3 1
A getBytesWritten() 0 3 1
A fwriteCsv() 0 7 1
A getCsvString() 0 8 1
A setLineEnding() 0 5 1
A getSize() 0 9 2
A trimFinalLineEnding() 0 10 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Palmtree\Csv;
6
7
use Palmtree\Csv\Util\StringUtil;
8
9
class CsvFileObject extends \SplFileObject
10
{
11
    private int $bytesWritten = 0;
12
    private string $lineEnding = "\r\n";
13
14 3
    public function fwriteCsv(array $row): int
15
    {
16 3
        $bytes = $this->fwrite($this->getCsvString($row));
17
18 3
        $this->bytesWritten += $bytes;
19
20 3
        return $bytes;
21
    }
22
23 6
    public function __destruct()
24
    {
25 6
        $this->trimFinalLineEnding();
26 6
    }
27
28
    public function getBytesWritten(): int
29
    {
30
        return $this->bytesWritten;
31
    }
32
33
    public function getLineEnding(): string
34
    {
35
        return $this->lineEnding;
36
    }
37
38
    public function setLineEnding(string $lineEnding): self
39
    {
40
        $this->lineEnding = $lineEnding;
41
42
        return $this;
43
    }
44
45 4
    public function getSize(): int
46
    {
47
        try {
48 4
            $size = parent::getSize();
49 4
        } catch (\RuntimeException $exception) {
50 4
            $size = $this->fstat()['size'];
51
        }
52
53 4
        return $size;
54
    }
55
56
    /**
57
     * Trims the line ending delimiter from the end of the CSV file.
58
     * RFC-4180 states CSV files should not contain a trailing new line.
59
     *
60
     * @see https://tools.ietf.org/html/rfc4180#section-2
61
     */
62 6
    public function trimFinalLineEnding(): void
63
    {
64 6
        if ($this->bytesWritten > 0) {
65
            // Only trim the file if it ends with the line ending delimiter.
66 3
            $length = \strlen($this->lineEnding);
67
68 3
            $this->fseek(-$length, \SEEK_END);
69
70 3
            if ($this->fread($length) === $this->lineEnding) {
71 3
                $this->ftruncate($this->bytesWritten - $length);
72
            }
73
        }
74 6
    }
75
76
    /**
77
     * Returns a string representation of a row to be written as a line in a CSV file.
78
     */
79 3
    private function getCsvString(array $row): string
80
    {
81 3
        list($delimiter, $enclosure) = $this->getCsvControl();
82
83
        return $enclosure .
84 3
               implode($enclosure . $delimiter . $enclosure, StringUtil::escapeEnclosure($row, $enclosure)) .
85 3
               $enclosure .
86 3
               $this->lineEnding;
87
    }
88
}
89