Passed
Push — master ( e9611b...a3681d )
by f
13:07
created

Iso   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 250
Duplicated Lines 0 %

Test Coverage

Coverage 6.25%

Importance

Changes 0
Metric Value
eloc 72
c 0
b 0
f 0
dl 0
loc 250
rs 9.92
ccs 5
cts 80
cp 0.0625
wmc 31

18 Methods

Rating   Name   Duplication   Size   Complexity  
A getArchiveInformation() 0 6 1
A getFileContent() 0 4 1
A checkFormatSupport() 0 11 3
A getFileStream() 0 4 1
A prepareForFileExtracting() 0 9 3
A extractArchive() 0 3 1
A __construct() 0 5 2
A isInstalled() 0 3 1
A getInstallationInstruction() 0 3 1
A getSupportedFormats() 0 4 1
A __destruct() 0 3 1
A isFileExists() 0 3 1
A extractFiles() 0 3 1
A addFileFromString() 0 3 1
A getFileNames() 0 3 1
A getFileData() 0 7 2
A getDescription() 0 3 1
B open() 0 41 8
1
<?php
2
namespace wapmorgan\UnifiedArchive\Drivers;
3
4
use wapmorgan\UnifiedArchive\ArchiveEntry;
5
use wapmorgan\UnifiedArchive\ArchiveInformation;
6
use wapmorgan\UnifiedArchive\Drivers\BasicDriver;
7
use wapmorgan\UnifiedArchive\Exceptions\UnsupportedOperationException;
8
use wapmorgan\UnifiedArchive\Formats;
9
10
class Iso extends BasicDriver
11
{
12
    const TYPE = self::TYPE_PURE_PHP;
13
14
    /** @var \CISOFile */
0 ignored issues
show
Bug introduced by
The type CISOFile was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
    protected $iso;
16
17
    /** @var array List of files */
18
    protected $files = [];
19
20
    /** @var array  */
21
    protected $filesData = [];
22
23
    /** @var int */
24
    protected $filesSize = 0;
25
26
    /** @var null|int Size of block in ISO. Used to find real position of file in ISO */
27
    protected $blockSize;
28
29
    /**
30 1
     * @inheritDoc
31
     */
32
    public static function getDescription()
33 1
    {
34
        return 'iso archives reader';
35
    }
36
37
    public static function isInstalled()
38
    {
39
        return class_exists('\CISOFile');
40
    }
41 1
42
    /**
43
     * @inheritDoc
44 1
     */
45 1
    public static function getInstallationInstruction()
46
    {
47
        return 'install library [phpclasses/php-iso-file]: `composer require phpclasses/php-iso-file`';
48
    }
49
50
    /**
51
     * @return array
52
     */
53
    public static function getSupportedFormats()
54
    {
55
        return [
56
            Formats::ISO,
57
        ];
58
    }
59
60
    /**
61
     * @param $format
62
     * @return array
63
     */
64
    public static function checkFormatSupport($format)
65
    {
66
        if (!static::isInstalled()) {
67
            return [];
68
        }
69
70
        switch ($format) {
71
            case Formats::ISO:
72
                return [
73
                    BasicDriver::OPEN,
74
                    BasicDriver::EXTRACT_CONTENT,
75
                ];
76
        }
77
    }
78
79
    /**
80
     * @inheritDoc
81
     */
82
    public function __construct($archiveFileName, $format, $password = null)
83
    {
84
        $this->open($archiveFileName);
85
        if ($password !== null)
86
            throw new UnsupportedOperationException('Iso archive does not support password!');
87
    }
88
89
    /**
90
     * Iso format destructor
91
     */
92
    public function __destruct()
93
    {
94
        $this->iso->close();
95
    }
96
97
    /**
98
     * @param $archiveFileName
99
     */
100
    protected function open($archiveFileName)
101
    {
102
        // load php-iso-files
103
        $this->iso = new \CISOFile;
104
        $this->iso->open($archiveFileName);
105
        $this->iso->ISOInit();
106
107
        /** @var \CVolumeDescriptor $usedDesc */
108
        $usedDesc = $this->iso->GetDescriptor(SUPPLEMENTARY_VOLUME_DESC);
0 ignored issues
show
Bug introduced by
The constant wapmorgan\UnifiedArchive...PPLEMENTARY_VOLUME_DESC was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
109
        if (!$usedDesc)
0 ignored issues
show
introduced by
$usedDesc is of type CVolumeDescriptor, thus it always evaluated to true.
Loading history...
110
            $usedDesc = $this->iso->GetDescriptor(PRIMARY_VOLUME_DESC);
0 ignored issues
show
Bug introduced by
The constant wapmorgan\UnifiedArchive...ers\PRIMARY_VOLUME_DESC was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
111
        $this->blockSize = $usedDesc->iBlockSize;
112
        $directories = $usedDesc->LoadMPathTable($this->iso);
113
        // iterate over all directories
114
        /** @var \CPathTableRecord $Directory */
115
        foreach ($directories as $Directory) {
116
            $directory = $Directory->GetFullPath($directories);
117
            $directory = trim($directory, '/');
118
            if ($directory != '') {
119
                $directory .= '/';
120
//                $this->files[$Directory->Location] = $directory;
121
            }
122
//            $this->isoCatalogsStructure[$Directory->Location]
123
//                = $directory;
124
125
            /** @var \CFileDirDescriptors[] $files */
126
            $files = $Directory->LoadExtents($this->iso,
127
                $usedDesc->iBlockSize, true);
128
            if ($files) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $files of type CFileDirDescriptors[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
129
                /** @var \CFileDirDescriptors $file */
130
                foreach ($files as $file) {
131
                    if (in_array($file->strd_FileId, ['.', '..']) || $file->IsDirectory())
132
                        continue;
133
                    $this->files[$file->Location] = $directory.$file->strd_FileId;
134
                    $this->filesSize += $file->DataLen;
135
136
                    $this->filesData[$directory . $file->strd_FileId] =
137
                        [
138
                            'size' => $file->DataLen,
139
                            'mtime' =>
140
                                strtotime((string)$file->isoRecDate),
141
                        ];
142
                }
143
            }
144
            // break;
145
        }
146
    }
147
148
    /**
149
     * @return ArchiveInformation
150
     */
151
    public function getArchiveInformation()
152
    {
153
        $information = new ArchiveInformation();
154
        $information->files = array_values($this->files);
155
        $information->compressedFilesSize = $information->uncompressedFilesSize = $this->filesSize;
156
        return $information;
157
    }
158
159
    /**
160
     * @return array
161
     */
162
    public function getFileNames()
163
    {
164
        return array_values($this->files);
165
    }
166
167
    /**
168
     * @param string $fileName
169
     *
170
     * @return bool
171
     */
172
    public function isFileExists($fileName)
173
    {
174
        return array_key_exists($fileName, $this->filesData);
175
    }
176
177
    /**
178
     * @param string $fileName
179
     *
180
     * @return ArchiveEntry|false
181
     */
182
    public function getFileData($fileName)
183
    {
184
        if (!isset($this->filesData[$fileName]))
185
            return false;
186
187
        return new ArchiveEntry($fileName, $this->filesData[$fileName]['size'],
188
            $this->filesData[$fileName]['size'], $this->filesData[$fileName]['mtime'],false);
189
    }
190
191
    /**
192
     * @param string $fileName
193
     *
194
     * @return string|false
195
     */
196
    public function getFileContent($fileName)
197
    {
198
        $data = $this->prepareForFileExtracting($fileName);
199
        return $this->iso->Read($data['size']);
200
    }
201
202
    /**
203
     * @param string $fileName
204
     *
205
     * @return bool|resource|string
206
     */
207
    public function getFileStream($fileName)
208
    {
209
        $data = $this->prepareForFileExtracting($fileName);
210
        return self::wrapStringInStream($this->iso->Read($data['size']));
211
    }
212
213
    /**
214
     * @param string $fileName
215
     * @return array
216
     */
217
    protected function prepareForFileExtracting($fileName)
218
    {
219
        $Location = array_search($fileName, $this->files, true);
220
        if (!isset($this->filesData[$fileName])) return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type array.
Loading history...
221
        $data = $this->filesData[$fileName];
222
        $Location_Real = $Location * $this->blockSize;
223
        if ($this->iso->Seek($Location_Real, SEEK_SET) === false)
224
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type array.
Loading history...
225
        return $data;
226
    }
227
228
    /**
229
     * @param string $outputFolder
230
     * @param array $files
231
     * @return void
232
     * @throws UnsupportedOperationException
233
     * @todo Implement extracting with reading & writing to FS
234
     */
235
    public function extractFiles($outputFolder, array $files)
236
    {
237
        throw new UnsupportedOperationException();
238
    }
239
240
    /**
241
     * @param string $outputFolder
242
     * @return void
243
     * @throws UnsupportedOperationException
244
     * @todo Implement extracting with reading & writing to FS
245
     */
246
    public function extractArchive($outputFolder)
247
    {
248
        throw new UnsupportedOperationException();
249
    }
250
251
    /**
252
     * @param $inArchiveName
253
     * @param $content
254
     * @return void
255
     * @throws UnsupportedOperationException
256
     */
257
    public function addFileFromString($inArchiveName, $content)
258
    {
259
        throw new UnsupportedOperationException();
260
    }
261
}