Passed
Push — master ( 0d8a9b...48a836 )
by f
12:20
created

Rar::isInstalled()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 1
cts 1
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
namespace wapmorgan\UnifiedArchive\Drivers;
3
4
use Exception;
5
use wapmorgan\UnifiedArchive\ArchiveEntry;
6
use wapmorgan\UnifiedArchive\ArchiveInformation;
7
use wapmorgan\UnifiedArchive\Drivers\Basic\BasicDriver;
8
use wapmorgan\UnifiedArchive\Drivers\Basic\BasicExtensionDriver;
9
use wapmorgan\UnifiedArchive\Formats;
10
11
class Rar extends BasicExtensionDriver
12
{
13
    const NONE_RAR_COMPRESSION = 48;
14
    const EXTENSION_NAME = 'rar';
15
16
    /** @var \RarArchive */
17
    protected $rar;
18
19
    /**
20
     * @inheritDoc
21
     */
22 1
    public static function getDescription()
23
    {
24
        return 'adapter for ext-rar' . (self::isInstalled() ? ' (' . phpversion('rar') . ')' : null);
25 1
    }
26
27
    /**
28
     * @inheritDoc
29
     */
30
    public static function getInstallationInstruction()
31
    {
32
        return 'install [rar] extension.' . "\n" . 'Can be installed with pecl: `pecl install rar`';
33
    }
34
35
    /**
36
     * @return array
37
     */
38
    public static function getSupportedFormats()
39
    {
40
        return [
41
            Formats::RAR,
42
        ];
43
    }
44
45
    /**
46
     * @param $format
47
     * @return array
48
     */
49
    public static function checkFormatSupport($format)
50
    {
51
        if (!static::isInstalled()) {
52
            return [];
53
        }
54
        switch ($format) {
55
            case Formats::RAR:
56
                return [
57
                    BasicDriver::OPEN,
58
                    BasicDriver::OPEN_ENCRYPTED,
59
                    BasicDriver::OPEN_VOLUMED,
60
                    BasicDriver::EXTRACT_CONTENT,
61
                    BasicDriver::STREAM_CONTENT,
62
                ];
63
        }
64
    }
65
66
    /**
67
     * @inheritDoc
68
     */
69
    public function __construct($archiveFileName, $format, $password = null)
70
    {
71
        parent::__construct($archiveFileName, $format);
72
        \RarException::setUsingExceptions(true);
73
        $this->open($archiveFileName, $password);
74
    }
75
76
    /**
77
     * @param $archiveFileName
78
     * @param $password
79
     * @throws Exception
80
     */
81
    protected function open($archiveFileName, $password)
82
    {
83
        $this->rar = \RarArchive::open($archiveFileName, $password, function ($vol) {
84
            var_dump($vol);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($vol) looks like debug code. Are you sure you do not want to remove it?
Loading history...
85
            return null;
86
        });
87
        $this->rar->setAllowBroken(true);
88
        if ($this->rar === false) {
89
            throw new Exception('Could not open Rar archive');
90
        }
91
    }
92
93
    /**
94
     * Rar format destructor
95
     */
96
    public function __destruct()
97
    {
98
        $this->rar->close();
99
    }
100
101
    /**
102
     * @return ArchiveInformation
103
     */
104
    public function getArchiveInformation()
105
    {
106
        $information = new ArchiveInformation();
107
        foreach ($this->rar->getEntries() as $i => $entry) {
108
            if ($entry->isDirectory()) continue;
109
            $information->files[] = $entry->getName();
110
            $information->compressedFilesSize += $entry->getPackedSize();
111
            $information->uncompressedFilesSize += $entry->getUnpackedSize();
112
        }
113
        return $information;
114
    }
115
116
    /**
117
     * @return string|null
118
     */
119
    public function getComment()
120
    {
121
        return $this->rar->getComment();
122
    }
123
124
    /**
125
     * @return array
126
     */
127
    public function getFileNames()
128
    {
129
        $files = [];
130
        foreach ($this->rar->getEntries() as $i => $entry) {
131
            if ($entry->isDirectory()) continue;
132
            $files[] = $entry->getName();
133
        }
134
        return $files;
135
    }
136
137
    /**
138
     * @param string $fileName
139
     *
140
     * @return bool
141
     */
142
    public function isFileExists($fileName)
143
    {
144
        return $this->rar->getEntry($fileName) !== false;
145
    }
146
147
    /**
148
     * @param string $fileName
149
     *
150
     * @return ArchiveEntry|false
151
     */
152
    public function getFileData($fileName)
153
    {
154
        $entry = $this->rar->getEntry($fileName);
155
        return new ArchiveEntry($fileName, $entry->getPackedSize(), $entry->getUnpackedSize(),
156
            strtotime($entry->getFileTime()), $entry->getMethod() != self::NONE_RAR_COMPRESSION);
157
    }
158
159
    /**
160
     * @param string $fileName
161
     *
162
     * @return string|false
163
     */
164
    public function getFileContent($fileName)
165
    {
166
        $entry = $this->rar->getEntry($fileName);
167
        if ($entry->isDirectory()) return false;
168
        return stream_get_contents($entry->getStream());
169
    }
170
171
    /**
172
     * @param string $fileName
173
     *
174
     * @return bool|resource|string
175
     */
176
    public function getFileStream($fileName)
177
    {
178
        $entry = $this->rar->getEntry($fileName);
179
        if ($entry->isDirectory()) return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the return type mandated by wapmorgan\UnifiedArchive...Driver::getFileStream() of resource.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
180
        return $entry->getStream();
181
    }
182
183
    /**
184
     * @param string $outputFolder
185
     * @param array  $files
186
     *
187
     * @return false|int
188
     */
189
    public function extractFiles($outputFolder, array $files)
190
    {
191
        $count = 0;
192
        foreach ($files as $file) {
193
            if ($this->rar->getEntry($file)->extract($outputFolder)) {
194
                $count++;
195
            }
196
        }
197
        return $count;
198
    }
199
200
    /**
201
     * @param string $outputFolder
202
     *
203
     * @return false|resource
204
     */
205
    public function extractArchive($outputFolder)
206
    {
207
        return $this->extractFiles($outputFolder, $this->getFileNames());
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->extractFil... $this->getFileNames()) returns the type integer which is incompatible with the documented return type false|resource.
Loading history...
208
    }
209
}
210