Passed
Push — master ( 3fb6e3...48681f )
by f
41:38 queued 26:41
created

Formats::detectArchiveFormat()   D

Complexity

Conditions 31
Paths 54

Size

Total Lines 72
Code Lines 60

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 145.1021

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 31
eloc 60
c 3
b 0
f 0
nc 54
nop 2
dl 0
loc 72
ccs 30
cts 59
cp 0.5084
crap 145.1021
rs 4.1666

How to fix   Long Method    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;
3
4
use wapmorgan\UnifiedArchive\Drivers\AlchemyZippy;
5
use wapmorgan\UnifiedArchive\Drivers\BasicDriver;
6
use wapmorgan\UnifiedArchive\Drivers\Cab;
7
use wapmorgan\UnifiedArchive\Drivers\Iso;
8
use wapmorgan\UnifiedArchive\Drivers\NelexaZip;
9
use wapmorgan\UnifiedArchive\Drivers\OneFile\Bzip;
10
use wapmorgan\UnifiedArchive\Drivers\OneFile\Gzip;
0 ignored issues
show
Bug introduced by
The type wapmorgan\UnifiedArchive\Drivers\OneFile\Gzip 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...
11
use wapmorgan\UnifiedArchive\Drivers\OneFile\Lzma;
12
use wapmorgan\UnifiedArchive\Drivers\Rar;
13
use wapmorgan\UnifiedArchive\Drivers\SevenZip;
14
use wapmorgan\UnifiedArchive\Drivers\TarByPear;
15
use wapmorgan\UnifiedArchive\Drivers\TarByPhar;
16
use wapmorgan\UnifiedArchive\Drivers\Zip;
17
use wapmorgan\UnifiedArchive\Exceptions\UnsupportedArchiveException;
18
use wapmorgan\UnifiedArchive\Formats\Tar;
0 ignored issues
show
Bug introduced by
The type wapmorgan\UnifiedArchive\Formats\Tar 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...
19
20
class Formats
21
{
22
    // archived and compressed
23
    const ZIP = 'zip';
24
    const SEVEN_ZIP = '7z';
25
    const RAR = 'rar';
26
    const CAB = 'cab';
27
    const TAR = 'tar';
28
    const TAR_GZIP = 'tgz';
29
    const TAR_BZIP = 'tbz2';
30
    const TAR_LZMA = 'txz';
31
    const TAR_LZW = 'tar.z';
32
    const ARJ = 'arj';
33
34
    // compressed
35
    const GZIP = 'gz';
36
    const BZIP = 'bz2';
37
    const LZMA = 'xz';
38
39
    // non-usual archives
40
    const UEFI = 'uefi';
41
    const GPT = 'gpt';
42
    const MBR = 'mbr';
43
    const MSI = 'msi';
44
    const ISO = 'iso';
45
    const DMG = 'dmg';
46
    const UDF = 'udf';
47
    const RPM = 'rpm';
48
    const DEB = 'deb';
49
50
    /**
51
     * @var string[] List of archive format drivers
52
     */
53
    public static $drivers = [
54
        Zip::class,
55
        Rar::class,
56
        Gzip::class,
57
        Bzip::class,
58
        Lzma::class,
59
        TarByPhar::class,
60
        SevenZip::class,
61
        AlchemyZippy::class,
62
        NelexaZip::class,
63
        TarByPear::class,
64
        Iso::class,
65
        Cab::class,
66
    ];
67
68
    /** @var array<string, array<string>> List of all available types with their drivers */
69
    protected static $declaredDriversFormats;
70
71
    /** @var array List of all drivers with formats and support-state */
72
    protected static $supportedDriversFormats;
73
74
    protected static $mimeTypes = [
75
        'application/zip' => Formats::ZIP,
76
        'application/x-7z-compressed' => Formats::SEVEN_ZIP,
77
        'application/x-rar' => Formats::RAR,
78
        'application/zlib' => Formats::GZIP,
79
        'application/gzip'  => Formats::GZIP,
80
        'application/x-gzip' => Formats::GZIP,
81
        'application/x-bzip2' => Formats::BZIP,
82
        'application/x-lzma' => Formats::LZMA,
83
        'application/x-iso9660-image' => Formats::ISO,
84
        'application/vnd.ms-cab-compressed' => Formats::CAB,
85
        'application/x-tar' => Formats::TAR,
86
        'application/x-gtar' => Formats::TAR_GZIP,
87
    ];
88
89
    /**
90
     * Detect archive type by its filename or content
91
     *
92
     * @param string $fileName Archive filename
93
     * @param bool $contentCheck Whether archive type can be detected by content
94 36
     * @return string|bool One of UnifiedArchive type constants OR false if type is not detected
95
     */
96
    public static function detectArchiveFormat($fileName, $contentCheck = true)
97 36
    {
98
        // by file name
99 36
        $ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
0 ignored issues
show
Bug introduced by
It seems like pathinfo($fileName, wapm...ive\PATHINFO_EXTENSION) can also be of type array; however, parameter $string of strtolower() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

99
        $ext = strtolower(/** @scrutinizer ignore-type */ pathinfo($fileName, PATHINFO_EXTENSION));
Loading history...
100 12
101 12
        if (stripos($fileName, '.tar.') !== false && preg_match('~\.(?<ext>tar\.(gz|bz2|xz|z))$~', strtolower($fileName), $match)) {
102 4
            switch ($match['ext']) {
103 8
                case 'tar.gz':
104 4
                    return Formats::TAR_GZIP;
105 4
                case 'tar.bz2':
106 4
                    return Formats::TAR_BZIP;
107
                case 'tar.xz':
108
                    return Formats::TAR_LZMA;
109
                case 'tar.z':
110
                    return Formats::TAR_LZW;
111
            }
112
        }
113 24
114 18
        switch ($ext) {
115 6
            case 'zip':
116 18
            case 'jar':
117 4
                return Formats::ZIP;
118 14
            case '7z':
119 1
                return Formats::SEVEN_ZIP;
120 13
            case 'rar':
121
                return Formats::RAR;
122 13
            case 'gz':
123
                return Formats::GZIP;
124 13
            case 'bz2':
125
                return Formats::BZIP;
126 13
            case 'xz':
127 4
                return Formats::LZMA;
128 9
            case 'iso':
129
                return Formats::ISO;
130 9
            case 'cab':
131 6
                return Formats::CAB;
132 3
            case 'tar':
133 1
                return Formats::TAR;
134 2
            case 'tgz':
135 1
                return Formats::TAR_GZIP;
136 1
            case 'tbz2':
137 1
                return Formats::TAR_BZIP;
138
            case 'txz':
139
                return Formats::TAR_LZMA;
140
            case 'arj':
141
                return Formats::ARJ;
142
            case 'efi':
143
                return Formats::UEFI;
144
            case 'gpt':
145
                return Formats::GPT;
146
            case 'mbr':
147
                return Formats::MBR;
148
            case 'msi':
149
                return Formats::MSI;
150
            case 'dmg':
151
                return Formats::DMG;
152
            case 'rpm':
153
                return Formats::RPM;
154
            case 'deb':
155
                return Formats::DEB;
156
            case 'udf':
157
                return Formats::UDF;
158
        }
159
160
        // by file content
161
        if ($contentCheck) {
162
            $mime_type = mime_content_type($fileName);
163
            if (isset(static::$mimeTypes[$mime_type]))
164
                return static::$mimeTypes[$mime_type];
165
        }
166
167
        return false;
168
    }
169
170
    /**
171
     * Checks whether specific archive type can be opened with current system configuration
172
     *
173
     * @param string $format One of predefined archive types (class constants)
174 25
     * @return bool
175
     */
176 25
    public static function canOpen($format)
177
    {
178 25
        return static::checkFormatSupportAbility($format, BasicDriver::OPEN);
179 6
    }
180
181 6
    /**
182 6
     * Checks whether specified archive can be streamed
183
     *
184 6
     * @param string $format One of predefined archive types (class constants)
185
     * @return bool
186
     */
187
    public static function canStream($format)
188 25
    {
189
        return static::checkFormatSupportAbility($format, BasicDriver::STREAM_CONTENT);
190
    }
191
192
    /**
193
     * Checks whether specified archive can be created
194
     *
195
     * @param string $format One of predefined archive types (class constants)
196
     * @return bool
197
     */
198
    public static function canCreate($format)
199
    {
200
        return static::checkFormatSupportAbility($format, BasicDriver::CREATE);
201
    }
202
203
    /**
204
     * Checks whether specified archive can be created
205
     *
206
     * @param string $format One of predefined archive types (class constants)
207
     * @return bool
208 2
     */
209
    public static function canAppend($format)
210 2
    {
211
        return static::checkFormatSupportAbility($format, BasicDriver::APPEND);
212
    }
213
214
    /**
215
     * Checks whether specified archive can be created
216
     *
217
     * @param string $format One of predefined archive types (class constants)
218
     * @return bool
219 2
     */
220
    public static function canUpdate($format)
221 2
    {
222
        return static::checkFormatSupportAbility($format, BasicDriver::DELETE);
223
    }
224
225
    /**
226
     * Checks whether specified archive can be created
227
     *
228
     * @param string $format One of predefined archive types (class constants)
229
     * @return bool
230 2
     */
231
    public static function canEncrypt($format)
232 2
    {
233
        return static::checkFormatSupportAbility($format, BasicDriver::CREATE_ENCRYPTED);
234
    }
235
236
    /**
237
     * @param $format
238
     * @return void
239
     */
240
    protected static function getFormatSupportStatus($format)
241
    {
242
        static::getAllPossibleFormatsAndDrivers();
243
244
        if (!isset(static::$supportedDriversFormats[$format])) {
245
            static::$supportedDriversFormats[$format] = [];
246
247
            if (!isset(static::$declaredDriversFormats[$format])) {
248
                return;
249
            }
250
            /** @var BasicDriver $format_driver */
251 4
            foreach (static::$declaredDriversFormats[$format] as $format_driver) {
252
                static::$supportedDriversFormats[$format][$format_driver] = $format_driver::checkFormatSupport($format);
253 4
            }
254 4
        }
255
    }
256
257 4
    /**
258 4
     * @param string $format
259 4
     * @param string $ability
260
     * @return bool
261
     */
262
    public static function checkFormatSupportAbility($format, $ability)
263
    {
264
        self::getFormatSupportStatus($format);
265
        foreach (static::$supportedDriversFormats[$format] as $driver => $driver_abilities) {
266
            if (in_array($ability, $driver_abilities, true)) {
267
                return true;
268
            }
269
        }
270 25
271
        return false;
272 25
    }
273
274 25
    /**
275
     * @param string $format
276
     * @param int[] $abilities
277 25
     * @return int|string|null
278 23
     */
279
    public static function getFormatDriver($format, array $abilities = [])
280 2
    {
281 2
        self::getFormatSupportStatus($format);
282 2
        foreach (static::$supportedDriversFormats[$format] as $driver => $driver_abilities) {
283
            if (count(array_intersect($driver_abilities, $abilities)) === count($abilities)) {
284
                return $driver;
285
            }
286
        }
287
288
        return null;
289
    }
290
291
    /**
292
     * @param array $ints
293
     * @return int|mixed
294
     */
295
    protected static function flatArrayToInt(array $ints)
296
    {
297
        $result = 0;
298
        foreach ($ints as $int) {
299
            $result |= $int;
300
        }
301
        return $result;
302
    }
303
304
    /**
305
     * @param $format
306
     * @return false|int|string
307
     */
308
    public static function getFormatMimeType($format)
309
    {
310
        return array_search($format, static::$mimeTypes, true);
311
    }
312
313
    public static function getDeclaredDriverFormats()
314
    {
315
        static::getAllPossibleFormatsAndDrivers();
316
        return static::$declaredDriversFormats;
317
    }
318
319
    public static function getSupportedDriverFormats()
320
    {
321
        foreach (self::getDeclaredDriverFormats() as $format => $formatDrivers) {
322
            self::getFormatSupportStatus($format);
323 25
        }
324
        return static::$supportedDriversFormats;
325 25
    }
326 1
327 1
    /**
328
     * Tests system configuration
329 1
     */
330 1
    protected static function getAllPossibleFormatsAndDrivers()
331
    {
332 1
        if (static::$declaredDriversFormats === null) {
0 ignored issues
show
introduced by
The condition static::declaredDriversFormats === null is always false.
Loading history...
333
            static::$declaredDriversFormats = [];
334
            foreach (static::$drivers as $handlerClass)
335
            {
336 25
                $handler_formats = $handlerClass::getSupportedFormats();
337
                foreach ($handler_formats as $handler_format)
338
                {
339
                    static::$declaredDriversFormats[$handler_format][] = $handlerClass;
340
                }
341
            }
342
        }
343
    }
344
}