Passed
Push — master ( 125b29...554a92 )
by f
27:06 queued 12:02
created

Iso::addFileFromString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
ccs 0
cts 0
cp 0
crap 2
rs 10
c 0
b 0
f 0
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
     * @throws UnsupportedOperationException
82
     */
83
    public function __construct($archiveFileName, $format, $password = null)
84
    {
85
        parent::__construct($archiveFileName, $format);
86
        $this->open($archiveFileName);
87
        if ($password !== null)
88
            throw new UnsupportedOperationException('Iso archive does not support password!');
89
    }
90
91
    /**
92
     * Iso format destructor
93
     */
94
    public function __destruct()
95
    {
96
        $this->iso->close();
97
    }
98
99
    /**
100
     * @param $archiveFileName
101
     */
102
    protected function open($archiveFileName)
103
    {
104
        // load php-iso-files
105
        $this->iso = new \CISOFile;
106
        $this->iso->open($archiveFileName);
107
        $this->iso->ISOInit();
108
109
        /** @var \CVolumeDescriptor $usedDesc */
110
        $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...
111
        if (!$usedDesc)
0 ignored issues
show
introduced by
$usedDesc is of type CVolumeDescriptor, thus it always evaluated to true.
Loading history...
112
            $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...
113
        $this->blockSize = $usedDesc->iBlockSize;
114
        $directories = $usedDesc->LoadMPathTable($this->iso);
115
        // iterate over all directories
116
        /** @var \CPathTableRecord $Directory */
117
        foreach ($directories as $Directory) {
118
            $directory = $Directory->GetFullPath($directories);
119
            $directory = trim($directory, '/');
120
            if ($directory != '') {
121
                $directory .= '/';
122
//                $this->files[$Directory->Location] = $directory;
123
            }
124
//            $this->isoCatalogsStructure[$Directory->Location]
125
//                = $directory;
126
127
            /** @var \CFileDirDescriptors[] $files */
128
            $files = $Directory->LoadExtents($this->iso,
129
                $usedDesc->iBlockSize, true);
130
            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...
131
                /** @var \CFileDirDescriptors $file */
132
                foreach ($files as $file) {
133
                    if (in_array($file->strd_FileId, ['.', '..']) || $file->IsDirectory())
134
                        continue;
135
                    $this->files[$file->Location] = $directory.$file->strd_FileId;
136
                    $this->filesSize += $file->DataLen;
137
138
                    $this->filesData[$directory . $file->strd_FileId] =
139
                        [
140
                            'size' => $file->DataLen,
141
                            'mtime' =>
142
                                strtotime((string)$file->isoRecDate),
143
                        ];
144
                }
145
            }
146
            // break;
147
        }
148
    }
149
150
    /**
151
     * @return ArchiveInformation
152
     */
153
    public function getArchiveInformation()
154
    {
155
        $information = new ArchiveInformation();
156
        $information->files = array_values($this->files);
157
        $information->compressedFilesSize = $information->uncompressedFilesSize = $this->filesSize;
158
        return $information;
159
    }
160
161
    /**
162
     * @return array
163
     */
164
    public function getFileNames()
165
    {
166
        return array_values($this->files);
167
    }
168
169
    /**
170
     * @param string $fileName
171
     *
172
     * @return bool
173
     */
174
    public function isFileExists($fileName)
175
    {
176
        return array_key_exists($fileName, $this->filesData);
177
    }
178
179
    /**
180
     * @param string $fileName
181
     *
182
     * @return ArchiveEntry|false
183
     */
184
    public function getFileData($fileName)
185
    {
186
        if (!isset($this->filesData[$fileName]))
187
            return false;
188
189
        return new ArchiveEntry($fileName, $this->filesData[$fileName]['size'],
190
            $this->filesData[$fileName]['size'], $this->filesData[$fileName]['mtime'],false);
191
    }
192
193
    /**
194
     * @param string $fileName
195
     *
196
     * @return string|false
197
     */
198
    public function getFileContent($fileName)
199
    {
200
        $data = $this->prepareForFileExtracting($fileName);
201
        return $this->iso->Read($data['size']);
202
    }
203
204
    /**
205
     * @param string $fileName
206
     *
207
     * @return bool|resource|string
208
     */
209
    public function getFileStream($fileName)
210
    {
211
        $data = $this->prepareForFileExtracting($fileName);
212
        return self::wrapStringInStream($this->iso->Read($data['size']));
213
    }
214
215
    /**
216
     * @param string $fileName
217
     * @return array
218
     */
219
    protected function prepareForFileExtracting($fileName)
220
    {
221
        $Location = array_search($fileName, $this->files, true);
222
        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...
223
        $data = $this->filesData[$fileName];
224
        $Location_Real = $Location * $this->blockSize;
225
        if ($this->iso->Seek($Location_Real, SEEK_SET) === false)
226
            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...
227
        return $data;
228
    }
229
230
    /**
231
     * @param string $outputFolder
232
     * @param array $files
233
     * @return void
234
     * @throws UnsupportedOperationException
235
     * @todo Implement extracting with reading & writing to FS
236
     */
237
    public function extractFiles($outputFolder, array $files)
238
    {
239
        throw new UnsupportedOperationException();
240
    }
241
242
    /**
243
     * @param string $outputFolder
244
     * @return void
245
     * @throws UnsupportedOperationException
246
     * @todo Implement extracting with reading & writing to FS
247
     */
248
    public function extractArchive($outputFolder)
249
    {
250
        throw new UnsupportedOperationException();
251
    }
252
}