Completed
Pull Request — master (#3)
by Harry
03:17
created

StreamWriter   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 89
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 9
c 1
b 0
f 0
lcom 1
cbo 3
dl 0
loc 89
ccs 32
cts 32
cp 1
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A insertAll() 0 20 3
A initialiseForWriting() 0 15 4
A insertOne() 0 4 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\IO;
15
16
use Graze\DataFile\Format\Formatter\FormatterInterface;
17
use Graze\DataFile\Helper\OptionalLoggerTrait;
18
use InvalidArgumentException;
19
use Psr\Http\Message\StreamInterface;
20
use Psr\Log\LoggerAwareInterface;
21
use Psr\Log\LogLevel;
22
use Traversable;
23
24
class StreamWriter implements WriterInterface, LoggerAwareInterface
25
{
26
    use OptionalLoggerTrait;
27
28
    /** @var FormatterInterface */
29
    private $formatter;
30
    /** @var StreamInterface */
31
    private $stream;
32
33
    /**
34
     * @param StreamInterface    $stream
35
     * @param FormatterInterface $formatter  Optional formatter, if not specified shall be determined based on the
36
     *                                       format of the file
37
     */
38 4
    public function __construct(StreamInterface $stream, FormatterInterface $formatter)
39
    {
40 4
        $this->stream = $stream;
41 4
        $this->formatter = $formatter;
42 4
    }
43
44
    /**
45
     * Adds multiple lines to the CSV document
46
     *
47
     * a simple wrapper method around insertOne
48
     *
49
     * @param Traversable|array $rows a multidimensional array or a Traversable object
50
     *
51
     * @throws InvalidArgumentException If the given rows format is invalid
52
     *
53
     * @return static
54
     */
55 4
    public function insertAll($rows)
56
    {
57 4
        $this->log(LogLevel::INFO, 'Writing {count} rows to file', ['count' => count($rows)]);
58
59 4
        $this->initialiseForWriting($this->stream);
60
61 4
        $first = true;
62 4
        foreach ($rows as $row) {
63 4
            if (!$first) {
64 3
                $this->stream->write($this->formatter->getRowSeparator());
65 3
            }
66 4
            $this->stream->write($this->formatter->format($row));
67 4
            $first = false;
68 4
        }
69 4
        $this->stream->write($this->formatter->getClosingBlock());
70
71 4
        $this->stream->close();
72
73 4
        return $this;
74
    }
75
76
    /**
77
     * Initialise the resource for writing.
78
     *
79
     * If we are at 0, then write initial block, otherwise, remove closing block and add a row separator
80
     *
81
     * This is so we can append a file with special characters at the beginning and end
82
     *
83
     * @param StreamInterface $stream
84
     */
85 4
    private function initialiseForWriting(StreamInterface $stream)
86
    {
87
        // move to the end of the file to always append
88 4
        $stream->seek(0, SEEK_END);
89
90 4
        if ($stream->tell() === 0) {
91 4
            $stream->write($this->formatter->getInitialBlock());
92 4
        } elseif (strlen($this->formatter->getClosingBlock()) > 0) {
93 1
            $endBlock = $this->formatter->getClosingBlock();
94 1
            $stream->seek(strlen($endBlock) * -1, SEEK_CUR);
95 1
            $stream->write($this->formatter->getRowSeparator());
96 2
        } elseif (strlen($this->formatter->getRowSeparator()) > 0) {
97 1
            $stream->write($this->formatter->getRowSeparator());
98 1
        }
99 4
    }
100
101
    /**
102
     * Adds a single line
103
     *
104
     * @param mixed $row an item to insert
105
     *
106
     * @return static
107
     */
108 2
    public function insertOne($row)
109
    {
110 2
        return $this->insertAll([$row]);
111
    }
112
}
113