Completed
Push — master ( d47b87...74095d )
by Peter
29s queued 11s
created

RenderGzipFileStream::open()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14

Duplication

Lines 14
Ratio 100 %

Code Coverage

Tests 8
CRAP Score 2.0054

Importance

Changes 0
Metric Value
dl 14
loc 14
ccs 8
cts 9
cp 0.8889
rs 9.7998
c 0
b 0
f 0
cc 2
nc 2
nop 0
crap 2.0054
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\CompressionLevelException;
14
use GpsLab\Component\Sitemap\Stream\Exception\FileAccessException;
15
use GpsLab\Component\Sitemap\Stream\Exception\LinksOverflowException;
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 RenderGzipFileStream implements FileStream
21
{
22
    /**
23
     * @var SitemapRender
24
     */
25
    private $render;
26
27
    /**
28
     * @var StreamState
29
     */
30
    private $state;
31
32
    /**
33
     * @var resource|null
34
     */
35
    private $handle;
36
37
    /**
38
     * @var string
39
     */
40
    private $filename = '';
41
42
    /**
43
     * @var string
44
     */
45
    private $tmp_filename = '';
46
47
    /**
48
     * @var int
49
     */
50
    private $compression_level = 9;
51
52
    /**
53
     * @var int
54
     */
55
    private $counter = 0;
56
57
    /**
58
     * @var string
59
     */
60
    private $end_string = '';
61
62
    /**
63
     * @param SitemapRender $render
64
     * @param string        $filename
65
     * @param int           $compression_level
66
     */
67 14
    public function __construct(SitemapRender $render, $filename, $compression_level = 9)
68
    {
69 14
        if (!is_numeric($compression_level) || $compression_level < 1 || $compression_level > 9) {
70 4
            throw CompressionLevelException::invalid($compression_level, 1, 9);
71
        }
72
73 14
        $this->render = $render;
74 14
        $this->state = new StreamState();
75 14
        $this->filename = $filename;
76 14
        $this->compression_level = $compression_level;
77 14
    }
78
79
    /**
80
     * @return string
81
     */
82 1
    public function getFilename()
83
    {
84 1
        return $this->filename;
85
    }
86
87 7 View Code Duplication
    public function open()
88
    {
89 7
        $this->state->open();
90
91 7
        $mode = 'wb'.$this->compression_level;
92 7
        $this->tmp_filename = tempnam(sys_get_temp_dir(), 'sitemap');
93 7
        if (($this->handle = @gzopen($this->tmp_filename, $mode)) === false) {
94
            throw FileAccessException::notWritable($this->tmp_filename);
95
        }
96
97 7
        $this->write($this->render->start());
98
        // render end string only once
99 7
        $this->end_string = $this->render->end();
100 7
    }
101
102 14 View Code Duplication
    public function close()
103
    {
104 14
        $this->state->close();
105 7
        $this->write($this->end_string);
106 7
        gzclose($this->handle);
107
108 7
        if (!rename($this->tmp_filename, $this->filename)) {
109
            unlink($this->tmp_filename);
110
111
            throw FileAccessException::failedOverwrite($this->tmp_filename, $this->filename);
112
        }
113
114 7
        $this->handle = null;
115 7
        $this->tmp_filename = '';
116 7
        $this->counter = 0;
117 7
    }
118
119
    /**
120
     * @param Url $url
121
     */
122 5 View Code Duplication
    public function push(Url $url)
123
    {
124 5
        if (!$this->state->isReady()) {
125 2
            throw StreamStateException::notReady();
126
        }
127
128 3
        if ($this->counter >= self::LINKS_LIMIT) {
129 1
            throw LinksOverflowException::withLimit(self::LINKS_LIMIT);
130
        }
131
132 3
        $render_url = $this->render->url($url);
133
134 3
        $this->write($render_url);
135 3
        ++$this->counter;
136 3
    }
137
138
    /**
139
     * @return int
140
     */
141 2
    public function count()
142
    {
143 2
        return $this->counter;
144
    }
145
146
    /**
147
     * @param string $string
148
     */
149 7
    private function write($string)
150
    {
151 7
        gzwrite($this->handle, $string);
152 7
    }
153
}
154