Passed
Push — master ( 087559...2f7326 )
by f
11:35
created

SplitbrainPhpArchive::createArchiveInString()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
c 0
b 0
f 0
nc 2
nop 5
dl 0
loc 12
rs 10
1
<?php
2
3
namespace wapmorgan\UnifiedArchive\Drivers;
4
5
use splitbrain\PHPArchive\Archive;
0 ignored issues
show
Bug introduced by
The type splitbrain\PHPArchive\Archive 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...
6
use splitbrain\PHPArchive\ArchiveCorruptedException;
0 ignored issues
show
Bug introduced by
The type splitbrain\PHPArchive\ArchiveCorruptedException 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...
7
use splitbrain\PHPArchive\ArchiveIllegalCompressionException;
0 ignored issues
show
Bug introduced by
The type splitbrain\PHPArchive\Ar...galCompressionException 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...
8
use splitbrain\PHPArchive\ArchiveIOException;
0 ignored issues
show
Bug introduced by
The type splitbrain\PHPArchive\ArchiveIOException 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...
9
use splitbrain\PHPArchive\FileInfo;
0 ignored issues
show
Bug introduced by
The type splitbrain\PHPArchive\FileInfo 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...
10
use splitbrain\PHPArchive\FileInfoException;
0 ignored issues
show
Bug introduced by
The type splitbrain\PHPArchive\FileInfoException 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 splitbrain\PHPArchive\Tar;
0 ignored issues
show
Bug introduced by
The type splitbrain\PHPArchive\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...
12
use splitbrain\PHPArchive\Zip;
0 ignored issues
show
Bug introduced by
The type splitbrain\PHPArchive\Zip 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...
Bug introduced by
This use statement conflicts with another class in this namespace, wapmorgan\UnifiedArchive\Drivers\Zip. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
13
use wapmorgan\UnifiedArchive\ArchiveEntry;
14
use wapmorgan\UnifiedArchive\ArchiveInformation;
15
use wapmorgan\UnifiedArchive\Drivers\Basic\BasicDriver;
16
use wapmorgan\UnifiedArchive\Drivers\Basic\BasicPureDriver;
17
use wapmorgan\UnifiedArchive\Exceptions\ArchiveCreationException;
18
use wapmorgan\UnifiedArchive\Exceptions\UnsupportedOperationException;
19
use wapmorgan\UnifiedArchive\Formats;
20
21
class SplitbrainPhpArchive extends BasicPureDriver
22
{
23
    const PACKAGE_NAME = 'splitbrain/php-archive';
24
    const MAIN_CLASS = '\\splitbrain\\PHPArchive\\Archive';
25
26
    /**
27
     * @var \splitbrain\PHPArchive\Zip|Tar
28
     */
29
    protected $archive;
30
    /**
31
     * @var array
32
     */
33
    protected $files;
34
35
    /** @var FileInfo[] */
36
    protected $members;
37
38
    /**
39
     * @inheritDoc
40
     */
41
    public static function getDescription()
42
    {
43
        return 'php-library for zip/tar (with gzip/bzip-compression)';
44
    }
45
46
    /**
47
     * @inheritDoc
48
     */
49
    public static function getSupportedFormats()
50
    {
51
        return [
52
            Formats::ZIP,
53
            Formats::TAR,
54
            Formats::TAR_GZIP,
55
            Formats::TAR_BZIP,
56
        ];
57
    }
58
59
    /**
60
     * @inheritDoc
61
     */
62
    public static function checkFormatSupport($format)
63
    {
64
        if (!static::isInstalled()) {
65
            return [];
66
        }
67
68
        if (
69
            ($format === Formats::TAR_BZIP && !extension_loaded('bz2'))
70
            || ($format === Formats::TAR_GZIP && !extension_loaded('zlib'))
71
        ) {
72
            return [];
73
        }
74
75
        switch ($format) {
76
            case Formats::ZIP:
77
            case Formats::TAR:
78
            case Formats::TAR_GZIP;
79
            case Formats::TAR_BZIP;
80
                return [
81
                    BasicDriver::OPEN,
82
//                    BasicDriver::EXTRACT_CONTENT,
83
                    BasicDriver::APPEND,
84
                    BasicDriver::CREATE,
85
//                    BasicDriver::CREATE_ENCRYPTED,
86
                    BasicDriver::CREATE_IN_STRING,
87
                ];
88
        }
89
    }
90
91
    /**
92
     * @throws ArchiveIllegalCompressionException
93
     * @throws ArchiveIOException
94
     */
95
    public function __construct($archiveFileName, $format, $password = null)
96
    {
97
        parent::__construct($archiveFileName, $format, $password);
98
        if ($format === Formats::ZIP) {
99
            $this->archive = new \splitbrain\PHPArchive\Zip();
100
        } else {
101
            $this->archive = new Tar();
102
        }
103
        $this->archive->open($archiveFileName);
104
    }
105
106
    /**
107
     * @inheritDoc
108
     */
109
    public function getArchiveInformation()
110
    {
111
        $this->files = [];
112
        $information = new ArchiveInformation();
113
114
        foreach ($this->archive->contents() as $member) {
115
            if ($member->getIsdir()) {
116
                continue;
117
            }
118
119
            $this->files[] = $information->files[] = str_replace('\\', '/', $member->getPath());
120
            $this->members[str_replace('\\', '/', $member->getPath())] = $member;
121
            $information->compressedFilesSize += (int)$member->getCompressedSize();
122
            $information->uncompressedFilesSize += (int)$member->getSize();
123
        }
124
        return $information;
125
    }
126
127
    /**
128
     * @inheritDoc
129
     */
130
    public function getFileNames()
131
    {
132
        return $this->files;
133
    }
134
135
    /**
136
     * @inheritDoc
137
     */
138
    public function isFileExists($fileName)
139
    {
140
        return array_key_exists($fileName, $this->members);
141
    }
142
143
    /**
144
     * @inheritDoc
145
     */
146
    public function getFileData($fileName)
147
    {
148
        $entry = $this->members[$fileName];
149
        return new ArchiveEntry(
150
            $fileName,
151
            $entry->getCompressedSize(),
152
            $entry->getSize(),
153
            strtotime($entry->getMtime()),
154
            $entry->getSize() !== $entry->getCompressedSize(),
155
            $entry->getComment(),
156
            null
157
        );
158
    }
159
160
    /**
161
     * @inheritDoc
162
     * @throws UnsupportedOperationException
163
     */
164
    public function getFileContent($fileName)
165
    {
166
        throw new UnsupportedOperationException('Getting file content is not supported by ' . __CLASS__);
167
    }
168
169
    /**
170
     * @inheritDoc
171
     * @throws UnsupportedOperationException
172
     */
173
    public function getFileStream($fileName)
174
    {
175
        throw new UnsupportedOperationException('Getting file stream is not supported by ' . __CLASS__);
176
    }
177
178
    /**
179
     * @inheritDoc
180
     * @throws UnsupportedOperationException
181
     */
182
    public function extractFiles($outputFolder, array $files)
183
    {
184
        throw new UnsupportedOperationException('Extract specific files is not supported by ' . __CLASS__);
185
    }
186
187
    /**
188
     * @inheritDoc
189
     */
190
    public function extractArchive($outputFolder)
191
    {
192
        $this->archive->extract($outputFolder);
193
    }
194
195
    /**
196
     * @param array $files
197
     * @param string $archiveFileName
198
     * @param int $archiveFormat
199
     * @param int $compressionLevel
200
     * @param string|null $password
201
     * @param callable|null $fileProgressCallable
202
     * @return int Number of archived files
203
     * @throws ArchiveCorruptedException
204
     * @throws ArchiveIOException
205
     * @throws ArchiveIllegalCompressionException
206
     * @throws FileInfoException
207
     * @throws UnsupportedOperationException
208
     */
209
    public static function createArchive(
210
        array $files,
211
        $archiveFileName,
212
        $archiveFormat,
213
        $compressionLevel = self::COMPRESSION_AVERAGE,
214
        $password = null,
215
        $fileProgressCallable = null
216
    ) {
217
        if ($password !== null) {
218
            throw new UnsupportedOperationException(__CLASS__ . ' could not encrypt an archive');
219
        }
220
        $archive = static::createArchiveInternal($files, $archiveFileName, $archiveFormat, $compressionLevel, $fileProgressCallable);
0 ignored issues
show
Bug introduced by
It seems like $fileProgressCallable can also be of type callable; however, parameter $fileProgressCallable of wapmorgan\UnifiedArchive...createArchiveInternal() does only seem to accept null, 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

220
        $archive = static::createArchiveInternal($files, $archiveFileName, $archiveFormat, $compressionLevel, /** @scrutinizer ignore-type */ $fileProgressCallable);
Loading history...
221
        $archive->save($archiveFileName);
222
        return count($files);
223
    }
224
225
    /**
226
     * @param array $files
227
     * @param string $archiveFormat
228
     * @param int $compressionLevel
229
     * @param string $password
230
     * @param callable|null $fileProgressCallable
231
     * @return string Content of archive
232
     * @throws ArchiveCorruptedException
233
     * @throws ArchiveIOException
234
     * @throws ArchiveIllegalCompressionException
235
     * @throws FileInfoException
236
     * @throws UnsupportedOperationException
237
     */
238
    public static function createArchiveInString(
239
        array $files,
240
        $archiveFormat,
241
        $compressionLevel = self::COMPRESSION_AVERAGE,
242
        $password = null,
243
        $fileProgressCallable = null
244
    ) {
245
        if ($password !== null) {
246
            throw new UnsupportedOperationException(__CLASS__ . ' could not encrypt an archive');
247
        }
248
        $archive = static::createArchiveInternal($files, null, $archiveFormat, $compressionLevel, $fileProgressCallable);
0 ignored issues
show
Bug introduced by
It seems like $fileProgressCallable can also be of type callable; however, parameter $fileProgressCallable of wapmorgan\UnifiedArchive...createArchiveInternal() does only seem to accept null, 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

248
        $archive = static::createArchiveInternal($files, null, $archiveFormat, $compressionLevel, /** @scrutinizer ignore-type */ $fileProgressCallable);
Loading history...
249
        return $archive->getArchive();
250
    }
251
252
    /**
253
     * @param array $files
254
     * @param $archiveFileName
255
     * @param $archiveFormat
256
     * @param int $compressionLevel
257
     * @param null $fileProgressCallable
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $fileProgressCallable is correct as it would always require null to be passed?
Loading history...
258
     * @return Tar|Zip
259
     * @throws ArchiveCorruptedException
260
     * @throws ArchiveIOException
261
     * @throws ArchiveIllegalCompressionException
262
     * @throws FileInfoException
263
     */
264
    public static function createArchiveInternal(
265
        array $files,
266
        $archiveFileName,
267
        $archiveFormat,
268
        $compressionLevel = self::COMPRESSION_AVERAGE,
269
        $fileProgressCallable = null
270
    ) {
271
        static $compressionLevelMap = [
272
            self::COMPRESSION_NONE => 0,
273
            self::COMPRESSION_WEAK => 2,
274
            self::COMPRESSION_AVERAGE => 4,
275
            self::COMPRESSION_STRONG => 7,
276
            self::COMPRESSION_MAXIMUM => 9,
277
        ];
278
279
        if ($archiveFormat === Formats::ZIP) {
280
            $archive = new \splitbrain\PHPArchive\Zip();
281
            $archive->setCompression($compressionLevelMap[$compressionLevel], Archive::COMPRESS_AUTO);
282
        } else {
283
            $archive = new Tar();
284
            $archive->setCompression($compressionLevelMap[$compressionLevel], ($archiveFormat === Formats::TAR_BZIP
285
                ? Archive::COMPRESS_BZIP
286
                : ($archiveFormat === Formats::TAR_GZIP ? Archive::COMPRESS_GZIP : Archive::COMPRESS_NONE)));
287
        }
288
        $archive->create($archiveFileName);
289
290
        $current_file = 0;
291
        $total_files = count($files);
292
        foreach ($files as $inArchiveName => $localName) {
293
            $archive->addFile($localName, $inArchiveName);
294
            if ($fileProgressCallable !== null) {
295
                call_user_func_array($fileProgressCallable, [$current_file++, $total_files, $localName, $inArchiveName]);
0 ignored issues
show
Bug introduced by
$fileProgressCallable of type null is incompatible with the type callable expected by parameter $callback of call_user_func_array(). ( Ignorable by Annotation )

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

295
                call_user_func_array(/** @scrutinizer ignore-type */ $fileProgressCallable, [$current_file++, $total_files, $localName, $inArchiveName]);
Loading history...
296
            }
297
        }
298
        return $archive;
299
    }
300
}
301