Completed
Pull Request — master (#13)
by Peter
02:38
created

RenderFileStream::count()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * GpsLab component.
6
 *
7
 * @author    Peter Gribanov <[email protected]>
8
 * @copyright Copyright (c) 2011, Peter Gribanov
9
 * @license   http://opensource.org/licenses/MIT
10
 */
11
12
namespace GpsLab\Component\Sitemap\Stream;
13
14
use GpsLab\Component\Sitemap\Render\SitemapRender;
15
use GpsLab\Component\Sitemap\Stream\Exception\FileAccessException;
16
use GpsLab\Component\Sitemap\Stream\Exception\LinksOverflowException;
17
use GpsLab\Component\Sitemap\Stream\Exception\SizeOverflowException;
18
use GpsLab\Component\Sitemap\Stream\Exception\StreamStateException;
19
use GpsLab\Component\Sitemap\Stream\State\StreamState;
20
use GpsLab\Component\Sitemap\Url\Url;
21
22
class RenderFileStream implements FileStream
23
{
24
    /**
25
     * @var SitemapRender
26
     */
27
    private $render;
28
29
    /**
30
     * @var StreamState
31
     */
32
    private $state;
33
34
    /**
35
     * @var resource|null
36
     */
37
    private $handle;
38
39
    /**
40
     * @var string
41
     */
42
    private $filename = '';
43
44
    /**
45
     * @var int
46
     */
47
    private $counter = 0;
48
49
    /**
50
     * @var string
51
     */
52
    private $end_string = '';
53
54
    /**
55
     * @var int
56
     */
57
    private $used_bytes = 0;
58
59
    /**
60
     * @param SitemapRender $render
61
     * @param string        $filename
62
     */
63 13
    public function __construct(SitemapRender $render, $filename)
64
    {
65 13
        $this->render = $render;
66 13
        $this->state = new StreamState();
67 13
        $this->filename = $filename;
68 13
    }
69
70
    /**
71
     * @return string
72
     */
73 3
    public function getFilename(): string
74
    {
75 3
        return $this->filename;
76
    }
77
78 10 View Code Duplication
    public function open(): void
79
    {
80 10
        $this->state->open();
81
82 10
        if ((file_exists($this->filename) && !is_writable($this->filename)) ||
83 10
            ($this->handle = @fopen($this->filename, 'wb')) === false
84
        ) {
85 1
            throw FileAccessException::notWritable($this->filename);
86
        }
87
88 9
        $this->write($this->render->start());
89
        // render end string only once
90 9
        $this->end_string = $this->render->end();
91 9
    }
92
93 10 View Code Duplication
    public function close(): void
94
    {
95 10
        $this->state->close();
96 9
        $this->write($this->end_string);
97 9
        fclose($this->handle);
98 9
        $this->counter = 0;
99 9
        $this->used_bytes = 0;
100 9
    }
101
102
    /**
103
     * @param Url $url
104
     */
105 6 View Code Duplication
    public function push(Url $url): void
106
    {
107 6
        if (!$this->state->isReady()) {
108 2
            throw StreamStateException::notReady();
109
        }
110
111 4
        if ($this->counter >= self::LINKS_LIMIT) {
112 2
            throw LinksOverflowException::withLimit(self::LINKS_LIMIT);
113
        }
114
115 4
        $render_url = $this->render->url($url);
116
117 4
        $expected_bytes = $this->used_bytes + strlen($render_url) + strlen($this->end_string);
118 4
        if ($expected_bytes > self::BYTE_LIMIT) {
119 1
            throw SizeOverflowException::withLimit(self::BYTE_LIMIT);
120
        }
121
122 4
        $this->write($render_url);
123 4
        ++$this->counter;
124 4
    }
125
126
    /**
127
     * @param string $string
128
     */
129 9
    private function write(string $string): void
130
    {
131 9
        fwrite($this->handle, $string);
132 9
        $this->used_bytes += strlen($string);
133 9
    }
134
}
135