Completed
Push — master ( 0d3592...0bb29a )
by Peter
06:28
created

RenderFileStream::getFilename()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
dl 0
loc 4
rs 10
c 1
b 0
f 1
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/**
3
 * GpsLab component.
4
 *
5
 * @author    Peter Gribanov <[email protected]>
6
 * @copyright Copyright (c) 2011, Peter Gribanov
7
 * @license   http://opensource.org/licenses/MIT
8
 */
9
10
namespace GpsLab\Component\Sitemap\Stream;
11
12
use GpsLab\Component\Sitemap\Render\SitemapRender;
13
use GpsLab\Component\Sitemap\Stream\Exception\FileAccessException;
14
use GpsLab\Component\Sitemap\Stream\Exception\LinksOverflowException;
15
use GpsLab\Component\Sitemap\Stream\Exception\SizeOverflowException;
16
use GpsLab\Component\Sitemap\Stream\Exception\StreamStateException;
17
use GpsLab\Component\Sitemap\Stream\State\StreamState;
18
use GpsLab\Component\Sitemap\Url\Url;
19
20
class RenderFileStream implements FileStream
21
{
22
    const LINKS_LIMIT = 50000;
23
24
    const BYTE_LIMIT = 52428800; // 50 Mb
25
26
    /**
27
     * @var SitemapRender
28
     */
29
    private $render;
30
31
    /**
32
     * @var StreamState
33
     */
34
    private $state;
35
36
    /**
37
     * @var resource|null
38
     */
39
    private $handle;
40
41
    /**
42
     * @var string
43
     */
44
    private $filename = '';
45
46
    /**
47
     * @var int
48
     */
49
    private $counter = 0;
50
51
    /**
52
     * @var string
53
     */
54
    private $end_string = '';
55
56
    /**
57
     * @var int
58
     */
59
    private $used_bytes = 0;
60
61
    /**
62
     * @param SitemapRender $render
63
     * @param string        $filename
64
     */
65
    public function __construct(SitemapRender $render, $filename)
66
    {
67
        $this->render = $render;
68
        $this->state = new StreamState();
69
        $this->filename = $filename;
70
    }
71
72
    /**
73
     * @return string
74
     */
75
    public function getFilename()
76
    {
77
        return $this->filename;
78
    }
79
80 View Code Duplication
    public function open()
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
81
    {
82
        $this->state->open();
83
84
        if ((file_exists($this->filename) && !is_writable($this->filename)) ||
85
            ($this->handle = @fopen($this->filename, 'wb')) === false
86
        ) {
87
            throw FileAccessException::notWritable($this->filename);
88
        }
89
90
        $this->write($this->render->start());
91
        // render end string only once
92
        $this->end_string = $this->render->end();
93
    }
94
95
    public function close()
96
    {
97
        $this->state->close();
98
        $this->write($this->end_string);
99
        fclose($this->handle);
100
    }
101
102
    /**
103
     * @param Url $url
104
     */
105 View Code Duplication
    public function push(Url $url)
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
106
    {
107
        if (!$this->state->isReady()) {
108
            throw StreamStateException::notReady();
109
        }
110
111
        if ($this->counter >= self::LINKS_LIMIT) {
112
            throw LinksOverflowException::withLimit(self::LINKS_LIMIT);
113
        }
114
115
        $render_url = $this->render->url($url);
116
117
        $expected_bytes = $this->used_bytes + strlen($render_url) + strlen($this->end_string);
118
        if ($expected_bytes > self::BYTE_LIMIT) {
119
            throw SizeOverflowException::withLimit(self::BYTE_LIMIT);
120
        }
121
122
        $this->write($render_url);
123
        ++$this->counter;
124
    }
125
126
    /**
127
     * @return int
128
     */
129
    public function count()
130
    {
131
        return $this->counter;
132
    }
133
134
    /**
135
     * @param string $string
136
     */
137
    private function write($string)
138
    {
139
        fwrite($this->handle, $string);
140
        $this->used_bytes += strlen($string);
141
    }
142
}
143