Passed
Push — 1.1.x ( 3d3019...6d4a67 )
by f
02:55 queued 01:04
created

SevenZip::checkFormatSupport()   D

Complexity

Conditions 18
Paths 34

Size

Total Lines 24
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 65.2329

Importance

Changes 0
Metric Value
eloc 19
c 0
b 0
f 0
dl 0
loc 24
ccs 9
cts 19
cp 0.4737
rs 4.8666
cc 18
nc 34
nop 1
crap 65.2329

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace wapmorgan\UnifiedArchive\Drivers;
3
4
use Exception;
5
use wapmorgan\UnifiedArchive\Archive7z;
6
use wapmorgan\UnifiedArchive\ArchiveEntry;
7
use wapmorgan\UnifiedArchive\ArchiveInformation;
8
use wapmorgan\UnifiedArchive\Drivers\BasicDriver;
9
use wapmorgan\UnifiedArchive\Exceptions\ArchiveCreationException;
10
use wapmorgan\UnifiedArchive\Exceptions\ArchiveExtractionException;
11
use wapmorgan\UnifiedArchive\Exceptions\ArchiveModificationException;
12
use wapmorgan\UnifiedArchive\Formats;
13
14
class SevenZip extends BasicDriver
15
{
16
    /** @var Archive7z */
17
    protected $sevenZip;
18
19
    /**
20
     * @var string
21
     */
22
    protected $format;
23
24
    /**
25
     * @return array
26
     */
27 1
    public static function getSupportedFormats()
28
    {
29
        return [
30 1
            Formats::SEVEN_ZIP,
31
            Formats::ZIP,
32
            Formats::RAR,
33
            Formats::TAR,
34
            // disabled
35
//            Formats::TAR_GZIP,
36
//            Formats::TAR_BZIP,
37
            Formats::CAB,
38
            Formats::ISO,
39
            Formats::ARJ,
40
            Formats::LZMA,
41
            Formats::UEFI,
42
            Formats::GPT,
43
            Formats::MBR,
44
            Formats::MSI,
45
            Formats::DMG,
46
            Formats::RPM,
47
            Formats::DEB,
48
            Formats::UDF,
49
        ];
50
    }
51
52
    /**
53
     * @param string $format
54
     * @return bool
55
     * @throws \Archive7z\Exception
56
     */
57 3
    public static function checkFormatSupport($format)
58
    {
59 3
        $available = class_exists('\Archive7z\Archive7z') && Archive7z::getBinaryVersion() !== false;
60
61
        switch ($format) {
62 3
            case Formats::SEVEN_ZIP:
63 3
            case Formats::ZIP:
64 2
            case Formats::RAR:
65 2
            case Formats::TAR:
66
//            case Formats::TAR_GZIP:
67
//            case Formats::TAR_BZIP:
68 1
            case Formats::CAB:
69 1
            case Formats::ISO:
70
            case Formats::ARJ:
71
            case Formats::LZMA:
72
            case Formats::UEFI:
73
            case Formats::GPT:
74
            case Formats::MBR:
75
            case Formats::MSI:
76
            case Formats::DMG:
77
            case Formats::RPM:
78
            case Formats::DEB:
79
            case Formats::UDF:
80 3
                return $available;
81
        }
82
    }
83
84
    /**
85
     * @inheritDoc
86
     */
87
    public static function getDescription()
88
    {
89
        return 'php-library and console program'
90
            .(class_exists('\Archive7z\Archive7z') && ($version = Archive7z::getBinaryVersion()) !== false
91
                ? ' ('.$version.')'
92
                : null);
93
    }
94
95
    /**
96
     * @inheritDoc
97
     */
98
    public static function getInstallationInstruction()
99
    {
100
        if (!class_exists('\Archive7z\Archive7z'))
101
            return 'install library `gemorroj/archive7z` and console program p7zip (7za)';
102
103
        if (Archive7z::getBinaryVersion() === false)
104
            return 'install console program p7zip (7za)';
105
106
        return null;
107
    }
108
109
    /**
110
     * @inheritDoc
111
     */
112 3
    public function __construct($archiveFileName, $format, $password = null)
113
    {
114
        try {
115 3
            $this->format = $format;
116 3
            $this->sevenZip = new Archive7z($archiveFileName, null, null);
117 3
            if ($password !== null)
118 3
                $this->sevenZip->setPassword($password);
119
        } catch (\Archive7z\Exception $e) {
0 ignored issues
show
Bug introduced by
The type Archive7z\Exception 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...
120
            throw new Exception('Could not open 7Zip archive: '.$e->getMessage(), $e->getCode(), $e);
121
        }
122 3
    }
123
124
    /**
125
     * @return ArchiveInformation
126
     */
127 3
    public function getArchiveInformation()
128
    {
129 3
        $information = new ArchiveInformation();
130
131 3
        foreach ($this->sevenZip->getEntries() as $entry) {
132 3
            if ($entry->isDirectory()) {
133
                continue;
134
            }
135
136 3
            if (!isset($can_get_unix_path))
137 3
                $can_get_unix_path = method_exists($entry, 'getUnixPath');
138
139 3
            $information->files[] = $can_get_unix_path
140 3
                ? $entry->getUnixPath()
141
                : str_replace('\\', '/', $entry->getPath());
142 3
            $information->compressedFilesSize += (int)$entry->getPackedSize();
143 3
            $information->uncompressedFilesSize += (int)$entry->getSize();
144
        }
145 3
        return $information;
146
    }
147
148
    /**
149
     * @return array
150
     */
151
    public function getFileNames()
152
    {
153
        $files = [];
154
        foreach ($this->sevenZip->getEntries() as $entry) {
155
            if ($entry->isDirectory())
156
                continue;
157
            $files[] = $entry->getPath();
158
        }
159
        return $files;
160
    }
161
162
    /**
163
     * @param string $fileName
164
     *
165
     * @return bool
166
     */
167
    public function isFileExists($fileName)
168
    {
169
        return $this->sevenZip->getEntry($fileName) !== null;
170
    }
171
172
    /**
173
     * @param string $fileName
174
     *
175
     * @return ArchiveEntry|false
176
     */
177 1
    public function getFileData($fileName)
178
    {
179 1
        $entry = $this->sevenZip->getEntry($fileName);
180 1
        return new ArchiveEntry($fileName, $entry->getPackedSize(), $entry->getSize(),
181 1
            strtotime($entry->getModified()));
182
    }
183
184
    /**
185
     * @param string $fileName
186
     *
187
     * @return string|false
188
     */
189 1
    public function getFileContent($fileName)
190
    {
191 1
        $entry = $this->sevenZip->getEntry($fileName);
192 1
        return $entry->getContent();
193
    }
194
195
    /**
196
     * @param string $fileName
197
     *
198
     * @return bool|resource|string
199
     */
200 1
    public function getFileStream($fileName)
201
    {
202 1
        $entry = $this->sevenZip->getEntry($fileName);
203 1
        return self::wrapStringInStream($entry->getContent());
204
    }
205
206
    /**
207
     * @param string $outputFolder
208
     * @param array $files
209
     * @return int
210
     * @throws ArchiveExtractionException
211
     */
212
    public function extractFiles($outputFolder, array $files)
213
    {
214
        $count = 0;
215
        try {
216
            $this->sevenZip->setOutputDirectory($outputFolder);
217
218
            foreach ($files as $file) {
219
                $this->sevenZip->extractEntry($file);
220
                $count++;
221
            }
222
            return $count;
223
        } catch (Exception $e) {
224
            throw new ArchiveExtractionException('Could not extract archive: '.$e->getMessage(), $e->getCode(), $e);
225
        }
226
    }
227
228
    /**
229
     * @param string $outputFolder
230
     *
231
     * @return bool
232
     * @throws ArchiveExtractionException
233
     */
234
    public function extractArchive($outputFolder)
235
    {
236
        try {
237
            $this->sevenZip->setOutputDirectory($outputFolder);
238
            $this->sevenZip->extract();
239
            return true;
0 ignored issues
show
Bug Best Practice introduced by
The expression return true returns the type true which is incompatible with the return type mandated by wapmorgan\UnifiedArchive...river::extractArchive() of integer.

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...
240
        } catch (Exception $e) {
241
            throw new ArchiveExtractionException('Could not extract archive: '.$e->getMessage(), $e->getCode(), $e);
242
        }
243
    }
244
245
    /**
246
     * @param array $files
247
     * @return int Number of deleted files
248
     * @throws ArchiveModificationException
249
     */
250
    public function deleteFiles(array $files)
251
    {
252
        $count = 0;
253
        try {
254
            foreach ($files as $file) {
255
                $this->sevenZip->delEntry($file);
256
                $count++;
257
            }
258
            return $count;
259
        } catch (Exception $e) {
260
            throw new ArchiveModificationException('Could not modify archive: '.$e->getMessage(), $e->getCode(), $e);
261
        }
262
    }
263
264
    /**
265
     * @param array $files
266
     *
267
     * @return int
268
     * @throws ArchiveModificationException
269
     */
270
    public function addFiles(array $files)
271
    {
272
        $added_files = 0;
273
        try {
274
            foreach ($files as $localName => $filename) {
275
                if (!is_null($filename)) {
276
                    $this->sevenZip->addEntry($filename);
277
                    $this->sevenZip->renameEntry($filename, $localName);
278
                    $added_files++;
279
                }
280
            }
281
            return $added_files;
282
        } catch (Exception $e) {
283
            throw new ArchiveModificationException('Could not modify archive: '.$e->getMessage(), $e->getCode(), $e);
284
        }
285
    }
286
287
    /**
288
     * @param string $inArchiveName
289
     * @param string $content
290
     * @return bool|void
291
     * @throws ArchiveModificationException
292
     * @throws \Archive7z\Exception
293
     */
294
    public function addFileFromString($inArchiveName, $content)
295
    {
296
        $tmp_file = tempnam(sys_get_temp_dir(), 'ua');
297
        if (!$tmp_file)
298
            throw new ArchiveModificationException('Could not create temporarily file');
299
300
        file_put_contents($tmp_file, $content);
301
        unset($content);
302
        $this->sevenZip->addEntry($tmp_file, true);
303
        $this->sevenZip->renameEntry($tmp_file, $inArchiveName);
304
        unlink($tmp_file);
305
        return true;
306
    }
307
308
    /**
309
     * @param array $files
310
     * @param string $archiveFileName
311
     * @param int $compressionLevel
312
     * @param null $password
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $password is correct as it would always require null to be passed?
Loading history...
313
     * @return int
314
     * @throws ArchiveCreationException
315
     */
316
    public static function createArchive(array $files, $archiveFileName, $compressionLevel = self::COMPRESSION_AVERAGE, $password = null)
317
    {
318
        static $compressionLevelMap = [
319
            self::COMPRESSION_NONE => 0,
320
            self::COMPRESSION_WEAK => 2,
321
            self::COMPRESSION_AVERAGE => 4,
322
            self::COMPRESSION_STRONG => 7,
323
            self::COMPRESSION_MAXIMUM => 9,
324
        ];
325
326
        try {
327
            $seven_zip = new Archive7z($archiveFileName);
328
            if ($password !== null)
0 ignored issues
show
introduced by
The condition $password !== null is always false.
Loading history...
329
                $seven_zip->setPassword($password);
330
            $seven_zip->setCompressionLevel($compressionLevelMap[$compressionLevel]);
331
            foreach ($files as $localName => $filename) {
332
                if ($filename !== null) {
333
                    $seven_zip->addEntry($filename, true);
334
                    $seven_zip->renameEntry($filename, $localName);
335
                }
336
            }
337
            unset($seven_zip);
338
        } catch (Exception $e) {
339
            throw new ArchiveCreationException('Could not create archive: '.$e->getMessage(), $e->getCode(), $e);
340
        }
341
        return count($files);
342
    }
343
344
    /**
345
     * @param $format
346
     * @return bool
347
     * @throws \Archive7z\Exception
348
     */
349
    public static function canCreateArchive($format)
350
    {
351
        if (in_array($format, [
352
            Formats::SEVEN_ZIP,
353
            Formats::BZIP,
354
            Formats::GZIP,
355
            Formats::TAR,
356
            Formats::LZMA,
357
            Formats::ZIP]
358
        ))
359
            return self::canRenameFiles();
360
361
        return false;
362
    }
363
364
    /**
365
     * @param $format
366
     * @return bool
367
     * @throws \Archive7z\Exception
368
     */
369
    public static function canAddFiles($format)
370
    {
371
        return self::canCreateArchive($format);
372
    }
373
374
    /**
375
     * @return bool
376
     * @throws \Archive7z\Exception
377
     */
378
    protected static function canRenameFiles()
379
    {
380
        $version = Archive7z::getBinaryVersion();
381
        return $version !== false && version_compare('9.30', $version, '<=');
382
    }
383
384
    /**
385
     * @param $format
386
     * @return bool
387
     * @throws \Archive7z\Exception
388
     */
389
    public static function canDeleteFiles($format)
390
    {
391
        return self::canCreateArchive($format);
392
    }
393
394
    /**
395
     * @param $format
396
     * @return bool
397
     * @throws \Archive7z\Exception
398
     */
399
    public static function canEncrypt($format)
400
    {
401
        return in_array($format, [Formats::ZIP, Formats::SEVEN_ZIP]) && self::canRenameFiles();
402
    }
403
}